From ad8008c37bb18ff99aa58e0a5ab4a9a809b5d484 Mon Sep 17 00:00:00 2001 From: sunwxg Date: Mon, 5 Jun 2017 21:15:38 +0800 Subject: [PATCH] Add scan popup flag After select a word, show a flag window, click the flag to show popup window. --- config.cc | 12 +++++++ config.hh | 3 ++ goldendict.pro | 10 ++++-- preferences.cc | 20 +++++++++++ preferences.hh | 1 + preferences.ui | 10 ++++++ scanflag.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ scanflag.hh | 33 ++++++++++++++++++ scanflag.ui | 38 +++++++++++++++++++++ scanpopup.cc | 35 +++++++++++++++++--- scanpopup.hh | 15 +++++++++ 11 files changed, 260 insertions(+), 7 deletions(-) create mode 100644 scanflag.cc create mode 100644 scanflag.hh create mode 100644 scanflag.ui diff --git a/config.cc b/config.cc index 604dd82b..c170b2c1 100644 --- a/config.cc +++ b/config.cc @@ -109,6 +109,9 @@ Preferences::Preferences(): scanPopupUseIAccessibleEx( true ), scanPopupUseGDMessage( true ), scanToMainWindow( false ), +#ifdef HAVE_X11 + showScanFlag( false ), +#endif pronounceOnLoadMain( false ), pronounceOnLoadPopup( false ), #ifndef DISABLE_INTERNAL_PLAYER @@ -758,6 +761,9 @@ Class load() throw( exError ) if ( !preferences.namedItem( "scanPopupAltModeSecs" ).isNull() ) c.preferences.scanPopupAltModeSecs = preferences.namedItem( "scanPopupAltModeSecs" ).toElement().text().toUInt(); c.preferences.scanToMainWindow = ( preferences.namedItem( "scanToMainWindow" ).toElement().text() == "1" ); +#ifdef HAVE_X11 + c.preferences.showScanFlag= ( preferences.namedItem( "showScanFlag" ).toElement().text() == "1" ); +#endif c.preferences.scanPopupUseUIAutomation = ( preferences.namedItem( "scanPopupUseUIAutomation" ).toElement().text() == "1" ); c.preferences.scanPopupUseIAccessibleEx = ( preferences.namedItem( "scanPopupUseIAccessibleEx" ).toElement().text() == "1" ); c.preferences.scanPopupUseGDMessage = ( preferences.namedItem( "scanPopupUseGDMessage" ).toElement().text() == "1" ); @@ -1622,6 +1628,12 @@ void save( Class const & c ) throw( exError ) opt.appendChild( dd.createTextNode( c.preferences.scanToMainWindow ? "1":"0" ) ); preferences.appendChild( opt ); +#ifdef HAVE_X11 + opt = dd.createElement( "showScanFlag" ); + opt.appendChild( dd.createTextNode( c.preferences.showScanFlag? "1":"0" ) ); + preferences.appendChild( opt ); +#endif + opt = dd.createElement( "scanPopupUseUIAutomation" ); opt.appendChild( dd.createTextNode( c.preferences.scanPopupUseUIAutomation ? "1":"0" ) ); preferences.appendChild( opt ); diff --git a/config.hh b/config.hh index 39302699..342db9e5 100644 --- a/config.hh +++ b/config.hh @@ -214,6 +214,9 @@ struct Preferences bool scanPopupUseIAccessibleEx; bool scanPopupUseGDMessage; bool scanToMainWindow; +#ifdef HAVE_X11 + bool showScanFlag; +#endif // Whether the word should be pronounced on page load, in main window/popup bool pronounceOnLoadMain, pronounceOnLoadPopup; diff --git a/goldendict.pro b/goldendict.pro index 6fcfdbee..cfe9ba5e 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -79,8 +79,8 @@ win32 { LIBS += -L$${PWD}/winlibs/lib } !x64:QMAKE_LFLAGS += -Wl,--large-address-aware - - isEmpty(HUNSPELL_LIB) { + + isEmpty(HUNSPELL_LIB) { CONFIG(gcc48) { LIBS += -lhunspell-1.3.2 } else { @@ -514,6 +514,12 @@ mac { SOURCES += texttospeechsource.cc } +unix:!mac { + HEADERS += scanflag.hh + FORMS += scanflag.ui + SOURCES += scanflag.cc +} + CONFIG( zim_support ) { DEFINES += MAKE_ZIM_SUPPORT LIBS += -llzma diff --git a/preferences.cc b/preferences.cc index 4e431cba..2e8f2259 100644 --- a/preferences.cc +++ b/preferences.cc @@ -22,6 +22,9 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ): connect( ui.enableScanPopupModifiers, SIGNAL( toggled( bool ) ), this, SLOT( enableScanPopupModifiersToggled( bool ) ) ); + connect( ui.showScanFlag, SIGNAL( toggled( bool ) ), + this, SLOT( showScanFlagToggled( bool ) ) ); + connect( ui.altKey, SIGNAL( clicked( bool ) ), this, SLOT( wholeAltClicked( bool ) ) ); connect( ui.ctrlKey, SIGNAL( clicked( bool ) ), @@ -229,6 +232,12 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ): // ui.tabWidget->removeTab( 5 ); #endif +#ifdef HAVE_X11 + ui.showScanFlag->setChecked( p.showScanFlag); +#else + ui.showScanFlag->hide(); +#endif + // Sound ui.pronounceOnLoadMain->setChecked( p.pronounceOnLoadMain ); @@ -366,6 +375,9 @@ Config::Preferences Preferences::getPreferences() p.scanPopupAltMode = ui.scanPopupAltMode->isChecked(); p.scanPopupAltModeSecs = ui.scanPopupAltModeSecs->value(); p.scanToMainWindow = ui.scanToMainWindow->isChecked(); +#ifdef HAVE_X11 + p.showScanFlag= ui.showScanFlag->isChecked(); +#endif p.scanPopupUseUIAutomation = ui.scanPopupUseUIAutomation->isChecked(); p.scanPopupUseIAccessibleEx = ui.scanPopupUseIAccessibleEx->isChecked(); p.scanPopupUseGDMessage = ui.scanPopupUseGDMessage->isChecked(); @@ -507,6 +519,14 @@ void Preferences::enableScanPopupToggled( bool b ) void Preferences::enableScanPopupModifiersToggled( bool b ) { ui.scanPopupModifiers->setEnabled( b && ui.enableScanPopup->isChecked() ); + if( b ) + ui.showScanFlag->setChecked( false ); +} + +void Preferences::showScanFlagToggled( bool b ) +{ + if( b ) + ui.enableScanPopupModifiers->setChecked( false ); } void Preferences::wholeAltClicked( bool b ) diff --git a/preferences.hh b/preferences.hh index c922b767..c25b4caa 100644 --- a/preferences.hh +++ b/preferences.hh @@ -33,6 +33,7 @@ private slots: void enableScanPopupToggled( bool ); void enableScanPopupModifiersToggled( bool ); + void showScanFlagToggled( bool b ); void wholeAltClicked( bool ); void wholeCtrlClicked( bool ); diff --git a/preferences.ui b/preferences.ui index 929d926a..f2077238 100644 --- a/preferences.ui +++ b/preferences.ui @@ -679,6 +679,16 @@ seconds, which is specified here. + + + + Show a flag window before showing popup window, click the flag to show popup window. + + + Show scan flag when word is selected + + + diff --git a/scanflag.cc b/scanflag.cc new file mode 100644 index 00000000..723349af --- /dev/null +++ b/scanflag.cc @@ -0,0 +1,90 @@ +#include +#include + +#include "scanflag.hh" +#include "ui_scanflag.h" + +static Qt::WindowFlags popupWindowFlags = + +Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint +#if QT_VERSION >= 0x050000 + | Qt::WindowDoesNotAcceptFocus +#endif +; + +ScanFlag::ScanFlag(QWidget *parent) : + QMainWindow(parent) +{ + ui.setupUi( this ); + + setWindowFlags( popupWindowFlags ); + + setAttribute(Qt::WA_X11DoNotAcceptFocus); + + hideTimer.setSingleShot( true ); + hideTimer.setInterval( 1500 ); + + connect( &hideTimer, SIGNAL( timeout() ), + this, SLOT( hideWindow() ) ); + + connect( ui.pushButton, SIGNAL( clicked( bool ) ), + this, SLOT( pushButtonClicked() ) ); +} + +ScanFlag::~ScanFlag() +{ +} + +void ScanFlag::pushButtonClicked() +{ + hideTimer.stop(); + hide(); + emit showScanPopup(); +} + +void ScanFlag::hideWindow() +{ + if ( isVisible() ) + hide(); +} + +void ScanFlag::showScanFlag() +{ + if ( isVisible() ) + hide(); + + QPoint currentPos = QCursor::pos(); + + QRect desktop = QApplication::desktop()->screenGeometry(); + + QSize windowSize = geometry().size(); + + int x, y; + + /// Try the to-the-right placement + if ( currentPos.x() + 4 + windowSize.width() <= desktop.topRight().x() ) + x = currentPos.x() + 4; + else + /// Try the to-the-left placement + if ( currentPos.x() - 4 - windowSize.width() >= desktop.x() ) + x = currentPos.x() - 4 - windowSize.width(); + else + // Center it + x = desktop.x() + ( desktop.width() - windowSize.width() ) / 2; + + /// Try the to-the-top placement + if ( currentPos.y() - 15 - windowSize.height() >= desktop.y() ) + y = currentPos.y() - 15 - windowSize.height(); + else + /// Try the to-the-bottom placement + if ( currentPos.y() + 15 + windowSize.height() <= desktop.bottomLeft().y() ) + y = currentPos.y() + 15; + else + // Center it + y = desktop.y() + ( desktop.height() - windowSize.height() ) / 2; + + move( x, y ); + + show(); + hideTimer.start(); +} diff --git a/scanflag.hh b/scanflag.hh new file mode 100644 index 00000000..71eb0a57 --- /dev/null +++ b/scanflag.hh @@ -0,0 +1,33 @@ +#ifndef SCAN_FLAG_H +#define SCAN_FLAG_H + + +#include "config.hh" +#include +#include +#include "ui_scanflag.h" + +class ScanFlag : public QMainWindow +{ + Q_OBJECT + +public: + ScanFlag( QWidget *parent ); + + ~ScanFlag(); + +signals: + void showScanPopup (); + +private: + Ui::ScanFlag ui; + QTimer hideTimer; + +private slots: + void showScanFlag(); + void pushButtonClicked(); + void hideWindow(); + +}; + +#endif // SCAN_FLAG_H diff --git a/scanflag.ui b/scanflag.ui new file mode 100644 index 00000000..17142838 --- /dev/null +++ b/scanflag.ui @@ -0,0 +1,38 @@ + + + ScanFlag + + + + 0 + 0 + 30 + 30 + + + + MainWindow + + + + + + 0 + 0 + 30 + 30 + + + + + + + + :/icons/programicon.png:/icons/programicon.png + + + + + + + diff --git a/scanpopup.cc b/scanpopup.cc index b2c0c03b..3c645823 100644 --- a/scanpopup.cc +++ b/scanpopup.cc @@ -35,7 +35,7 @@ Qt::Popup ScanPopup::ScanPopup( QWidget * parent, Config::Class & cfg_, - ArticleNetworkAccessManager & articleNetMgr, + ArticleNetworkAccessManager & articleNetMgr, std::vector< sptr< Dictionary::Class > > const & allDictionaries_, Instances::Groups const & groups_, History & history_ ): @@ -92,7 +92,7 @@ ScanPopup::ScanPopup( QWidget * parent, this, SLOT( typingEvent( QString const & ) ) ); applyZoomFactor(); - + ui.mainLayout->addWidget( definition ); ui.translateBox->wordList()->attachFinder( &wordFinder ); @@ -270,6 +270,16 @@ ScanPopup::ScanPopup( QWidget * parent, grabGesture( Gestures::GDPinchGestureType ); grabGesture( Gestures::GDSwipeGestureType ); #endif + +#ifdef HAVE_X11 + scanFlag = new ScanFlag( 0 ); + + connect( this, SIGNAL( showScanFlag( bool ) ), + scanFlag, SLOT( showScanFlag() ) ); + + connect( scanFlag, SIGNAL( showScanPopup() ), + this, SLOT( showEngagePopup() ) ); +#endif } ScanPopup::~ScanPopup() @@ -362,7 +372,7 @@ void ScanPopup::clipboardChanged( QClipboard::Mode m ) { if ( !isScanningEnabled ) return; - + GD_DPRINTF( "clipboard changed\n" ); QString subtype = "plain"; @@ -400,6 +410,14 @@ void ScanPopup::handleInputWord( QString const & str, bool forcePopup ) return; } +#ifdef HAVE_X11 + if ( cfg.preferences.showScanFlag ) { + inputWord = pendingInputWord; + emit showScanFlag( forcePopup ); + return; + } +#endif + // Check key modifiers if ( cfg.preferences.enableScanPopupModifiers && !checkModifiersPressed( cfg.preferences.scanPopupModifiers ) ) @@ -417,6 +435,13 @@ void ScanPopup::handleInputWord( QString const & str, bool forcePopup ) engagePopup( forcePopup ); } +#ifdef HAVE_X11 +void ScanPopup::showEngagePopup() +{ + engagePopup(false); +} +#endif + void ScanPopup::engagePopup( bool forcePopup, bool giveFocus ) { if( cfg.preferences.scanToMainWindow && !forcePopup ) @@ -745,7 +770,7 @@ void ScanPopup::mouseMoveEvent( QMouseEvent * event ) move( pos() + delta ); } - + QMainWindow::mouseMoveEvent( event ); } @@ -808,7 +833,7 @@ void ScanPopup::showEvent( QShowEvent * ev ) QMainWindow::showEvent( ev ); QTimer::singleShot(100, this, SLOT( requestWindowFocus() ) ); - + if ( groups.size() <= 1 ) // Only the default group? Hide then. ui.groupList->hide(); diff --git a/scanpopup.hh b/scanpopup.hh index 4dcde887..e7e8f7a2 100644 --- a/scanpopup.hh +++ b/scanpopup.hh @@ -15,6 +15,9 @@ #include "history.hh" #include "dictionarybar.hh" #include "mainstatusbar.hh" +#ifdef HAVE_X11 +#include "scanflag.hh" +#endif /// This is a popup dialog to show translations when clipboard scanning mode /// is enabled. @@ -70,6 +73,10 @@ signals: /// Put translated word into Favorites void sendWordToFavorites( QString const & word, unsigned groupId ); +#ifdef HAVE_X11 + void showScanFlag( bool forcePopup ); +#endif + #ifdef Q_OS_WIN32 /// Ask for source window is current translate tab bool isGoldenDictWindow( HWND hwnd ); @@ -87,6 +94,10 @@ public slots: void setGroupByName( QString const & name ); +#ifdef HAVE_X11 + void showEngagePopup(); +#endif + private: // Translates the word from the clipboard or the clipboard selection @@ -118,6 +129,10 @@ private: DictionaryBar dictionaryBar; MainStatusBar * mainStatusBar; +#ifdef HAVE_X11 + ScanFlag * scanFlag; +#endif + bool mouseEnteredOnce; bool mouseIntercepted;