diff --git a/config.cc b/config.cc index 4c1033b8a..361879701 100644 --- a/config.cc +++ b/config.cc @@ -1966,6 +1966,14 @@ QString getLocDir() throw() return QCoreApplication::applicationDirPath() + "/locale"; } +QString getHelpDir() throw() +{ + if ( QDir( getProgramDataDir() ).cd( "help" ) ) + return getProgramDataDir() + "/help"; + else + return QCoreApplication::applicationDirPath() + "/help"; +} + bool isPortableVersion() throw() { struct IsPortable diff --git a/config.hh b/config.hh index 81cf7784e..9c6591825 100644 --- a/config.hh +++ b/config.hh @@ -641,6 +641,9 @@ QString getProgramDataDir() throw(); /// Returns the directory storing program localizized files (.qm). QString getLocDir() throw(); +/// Returns the directory storing program help files (.qch). +QString getHelpDir() throw(); + /// Returns true if the program is configured as a portable version. In that /// mode, all the settings and indices are kept in the program's directory. bool isPortableVersion() throw(); diff --git a/dictheadwords.cc b/dictheadwords.cc index 26b038f01..8867448c9 100644 --- a/dictheadwords.cc +++ b/dictheadwords.cc @@ -3,6 +3,7 @@ #include "dictheadwords.hh" #include "gddebug.hh" +#include "mainwindow.hh" #include #include @@ -17,6 +18,7 @@ DictHeadwords::DictHeadwords( QWidget *parent, Config::Class & cfg_, QDialog(parent) , cfg( cfg_ ) , dict( dict_ ) +, helpAction( this ) { ui.setupUi( this ); @@ -83,6 +85,17 @@ DictHeadwords::DictHeadwords( QWidget *parent, Config::Class & cfg_, connect( proxy, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( showHeadwordsNumber() ) ); + connect( ui.helpButton, SIGNAL( clicked() ), + this, SLOT( helpRequested() ) ); + + helpAction.setShortcut( QKeySequence( "F1" ) ); + helpAction.setShortcutContext( Qt::WidgetWithChildrenShortcut ); + + connect( &helpAction, SIGNAL( triggered() ), + this, SLOT( helpRequested() ) ); + + addAction( &helpAction ); + ui.headersListView->installEventFilter( this ); setup( dict_ ); @@ -304,3 +317,10 @@ void DictHeadwords::saveHeadersToFile() gdWarning( "Headers export error: %s", file.errorString().toUtf8().data() ); file.close(); } + +void DictHeadwords::helpRequested() +{ + MainWindow * mainWindow = qobject_cast< MainWindow * >( parentWidget() ); + if( mainWindow ) + mainWindow->showGDHelpForID( "Dictionary headwords" ); +} diff --git a/dictheadwords.hh b/dictheadwords.hh index aa4383b4d..28c7de3f5 100644 --- a/dictheadwords.hh +++ b/dictheadwords.hh @@ -7,11 +7,13 @@ #include #include #include +#include #include "config.hh" #include "ui_dictheadwords.h" #include "dictionary.hh" #include "delegate.hh" +#include "helpwindow.hh" class DictHeadwords : public QDialog { @@ -32,6 +34,8 @@ protected: QSortFilterProxyModel * proxy; WordListItemDelegate * delegate; + QAction helpAction; + void saveHeadersToFile(); bool eventFilter( QObject * obj, QEvent * ev ); @@ -47,6 +51,7 @@ private slots: void autoApplyStateChanged( int state ); void showHeadwordsNumber(); virtual void reject(); + void helpRequested(); signals: void headwordSelected( QString const & ); diff --git a/dictheadwords.ui b/dictheadwords.ui index 6f2f4346b..4989edac2 100644 --- a/dictheadwords.ui +++ b/dictheadwords.ui @@ -73,6 +73,16 @@ + + + + Help + + + false + + + diff --git a/editdictionaries.cc b/editdictionaries.cc index 89471fb24..38712048a 100644 --- a/editdictionaries.cc +++ b/editdictionaries.cc @@ -4,6 +4,7 @@ #include "editdictionaries.hh" #include "loaddictionaries.hh" #include "dictinfo.hh" +#include "mainwindow.hh" #include using std::vector; @@ -23,6 +24,8 @@ EditDictionaries::EditDictionaries( QWidget * parent, Config::Class & cfg_, dictionariesChanged( false ), groupsChanged( false ), lastCurrentTab( 0 ) +, helpWindow( 0 ) +, helpAction( this ) { // Some groups may have contained links to non-existnent dictionaries. We // would like to preserve them if no edits were done. To that end, we save @@ -52,6 +55,18 @@ EditDictionaries::EditDictionaries( QWidget * parent, Config::Class & cfg_, connect( orderAndProps.get(), SIGNAL( showDictionaryHeadwords( QString const & ) ), this, SIGNAL( showDictionaryHeadwords( QString const & ) ) ); + + connect( ui.buttons, SIGNAL( helpRequested() ), + this, SLOT( helpRequested() ) ); + + helpAction.setShortcut( QKeySequence( "F1" ) ); + helpAction.setShortcutContext( Qt::WidgetWithChildrenShortcut ); + + connect( &helpAction, SIGNAL( triggered() ), + this, SLOT( helpRequested() ) ); + + addAction( &helpAction ); + } void EditDictionaries::editGroup( unsigned id ) @@ -241,3 +256,38 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups ) origCfg.inactiveDictionaries = orderAndProps->getCurrentInactiveDictionaries(); } } + +void EditDictionaries::helpRequested() +{ + if( !helpWindow ) + { + MainWindow * mainWindow = qobject_cast< MainWindow * >( parentWidget() ); + if( mainWindow ) + mainWindow->closeGDHelp(); + + helpWindow = new Help::HelpWindow( this, cfg ); + + if( helpWindow ) + { + helpWindow->setWindowFlags( Qt::Window ); + + connect( helpWindow, SIGNAL( needClose() ), + this, SLOT( closeHelp() ) ); + helpWindow->showHelpFor( "Manage dictionaries" ); + helpWindow->show(); + } + } + else + { + if( !helpWindow->isVisible() ) + helpWindow->show(); + + helpWindow->activateWindow(); + } +} + +void EditDictionaries::closeHelp() +{ + if( helpWindow ) + helpWindow->hide(); +} diff --git a/editdictionaries.hh b/editdictionaries.hh index 42fd1338a..14affb183 100644 --- a/editdictionaries.hh +++ b/editdictionaries.hh @@ -11,7 +11,9 @@ #include "orderandprops.hh" #include "groups.hh" #include "instances.hh" +#include "helpwindow.hh" #include +#include class EditDictionaries: public QDialog { @@ -24,6 +26,9 @@ public: Instances::Groups & groupInstances, // We only clear those on rescan QNetworkAccessManager & dictNetMgr ); + ~EditDictionaries() + { if( helpWindow ) delete helpWindow; } + /// Instructs the dialog to position itself on editing the given group. void editGroup( unsigned id ); @@ -47,6 +52,9 @@ private slots: void rescanSources(); + void helpRequested(); + void closeHelp(); + signals: void showDictionaryInfo( QString const & dictId ); @@ -79,7 +87,10 @@ private: bool dictionariesChanged; bool groupsChanged; - int lastCurrentTab; + int lastCurrentTab; + + Help::HelpWindow * helpWindow; + QAction helpAction; }; #endif diff --git a/editdictionaries.ui b/editdictionaries.ui index 3e40ded8b..4553d6926 100644 --- a/editdictionaries.ui +++ b/editdictionaries.ui @@ -32,7 +32,7 @@ Qt::Horizontal - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok diff --git a/fulltextsearch.cc b/fulltextsearch.cc index baf603c59..e043bf0dd 100644 --- a/fulltextsearch.cc +++ b/fulltextsearch.cc @@ -4,6 +4,7 @@ #include "fulltextsearch.hh" #include "ftshelpers.hh" #include "gddebug.hh" +#include "mainwindow.hh" #include #include @@ -126,6 +127,7 @@ FullTextSearchDialog::FullTextSearchDialog( QWidget * parent, groups( groups_ ), group( 0 ), ftsIdx( ftsidx ) +, helpAction( this ) { ui.setupUi( this ); @@ -192,6 +194,17 @@ FullTextSearchDialog::FullTextSearchDialog( QWidget * parent, connect( ui.OKButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); connect( ui.cancelButton, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( ui.helpButton, SIGNAL( clicked() ), + this, SLOT( helpRequested() ) ); + + helpAction.setShortcut( QKeySequence( "F1" ) ); + helpAction.setShortcutContext( Qt::WidgetWithChildrenShortcut ); + + connect( &helpAction, SIGNAL( triggered() ), + this, SLOT( helpRequested() ) ); + + addAction( &helpAction ); + ui.headwordsView->installEventFilter( this ); delegate = new WordListItemDelegate( ui.headwordsView->itemDelegate() ); @@ -483,6 +496,13 @@ bool FullTextSearchDialog::eventFilter( QObject * obj, QEvent * ev ) return QDialog::eventFilter( obj, ev ); } +void FullTextSearchDialog::helpRequested() +{ + MainWindow * mainWindow = qobject_cast< MainWindow * >( parentWidget() ); + if( mainWindow ) + mainWindow->showGDHelpForID( "Full-text search" ); +} + /// HeadwordsListModel int HeadwordsListModel::rowCount( QModelIndex const & ) const diff --git a/fulltextsearch.hh b/fulltextsearch.hh index 6f5b27ad5..36ef077f8 100644 --- a/fulltextsearch.hh +++ b/fulltextsearch.hh @@ -200,6 +200,7 @@ private: QList< FtsHeadword > results; HeadwordsListModel * model; WordListItemDelegate * delegate; + QAction helpAction; void showDictNumbers(); @@ -212,6 +213,7 @@ private slots: void reject(); void itemClicked( QModelIndex const & idx ); void updateDictionaries(); + void helpRequested(); signals: void showTranslationFor( QString const &, QStringList const & dictIDs, diff --git a/fulltextsearch.ui b/fulltextsearch.ui index 0d92d7bb0..b4b97cd96 100644 --- a/fulltextsearch.ui +++ b/fulltextsearch.ui @@ -216,6 +216,26 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Help + + + diff --git a/help/gdhelp_en.qch b/help/gdhelp_en.qch index 034da710f..d8c7fb5f1 100644 Binary files a/help/gdhelp_en.qch and b/help/gdhelp_en.qch differ diff --git a/help/gdhelp_ru.qch b/help/gdhelp_ru.qch index 528a836b5..823fef161 100644 Binary files a/help/gdhelp_ru.qch and b/help/gdhelp_ru.qch differ diff --git a/helpwindow.cc b/helpwindow.cc index 14cfb0846..29c751d0a 100644 --- a/helpwindow.cc +++ b/helpwindow.cc @@ -93,11 +93,14 @@ HelpWindow::HelpWindow( QWidget * parent, Config::Class & cfg_ ) : if( localeName.isEmpty() ) localeName = QLocale::system().name(); - helpFile = QDir::toNativeSeparators( Config::getProgramDataDir() + "/help/gdhelp_" - + localeName.left( 2 ) + ".qch" ); + QString helpDir = Config::getHelpDir(); + helpFile = QDir::toNativeSeparators( helpDir + "/gdhelp_" + localeName + ".qch" ); if( !QFileInfo( helpFile ).isFile() ) - helpFile = QDir::toNativeSeparators( Config::getProgramDataDir() + "/help/gdhelp_en.qch" ); + helpFile = QDir::toNativeSeparators( helpDir + "/gdhelp_" + localeName.left( 2 ) + ".qch" ); + + if( !QFileInfo( helpFile ).isFile() ) + helpFile = QDir::toNativeSeparators( helpDir + "/gdhelp_en.qch" ); helpCollectionFile = QDir::toNativeSeparators( Config::getConfigDir() + "gdhelp.qhc" ); @@ -195,6 +198,11 @@ void HelpWindow::accept() emit needClose(); } +void HelpWindow::showHelpFor( QString const & keyword ) +{ + helpBrowser->showHelpForKeyword( keyword ); +} + void HelpWindow::forwardEnabled( bool enabled ) { navForward->setEnabled( enabled ); diff --git a/helpwindow.hh b/helpwindow.hh index fcfb2d2d3..279b82afa 100644 --- a/helpwindow.hh +++ b/helpwindow.hh @@ -57,6 +57,8 @@ public: QHelpEngine const * getHelpEngine() { return helpEngine; } + void showHelpFor( QString const & keyword ); + public slots: virtual void reject(); virtual void accept(); diff --git a/mainwindow.cc b/mainwindow.cc index d2b08398e..ec0bbee17 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -1893,7 +1893,7 @@ void MainWindow::editPreferences() ftsIndexing.stopIndexing(); ftsIndexing.clearDictionaries(); - Preferences preferences( this, cfg.preferences ); + Preferences preferences( this, cfg ); preferences.show(); @@ -4049,17 +4049,25 @@ void MainWindow::closeFullTextSearchDialog() void MainWindow::showGDHelp() { if( !helpWindow ) + { helpWindow = new Help::HelpWindow( this, cfg ); - if( helpWindow->getHelpEngine() ) - { - connect( helpWindow, SIGNAL( needClose() ), this, SLOT( hideGDHelp() ) ); - helpWindow->show(); + if( helpWindow->getHelpEngine() ) + { + connect( helpWindow, SIGNAL( needClose() ), this, SLOT( hideGDHelp() ) ); + helpWindow->showHelpFor( "Content" ); + helpWindow->show(); + } + else + { + delete helpWindow; + helpWindow = 0; + } } else { - delete helpWindow; - helpWindow = 0; + helpWindow->show(); + helpWindow->activateWindow(); } } @@ -4069,6 +4077,31 @@ void MainWindow::hideGDHelp() helpWindow->hide(); } +void MainWindow::showGDHelpForID( QString const & id ) +{ + if( !helpWindow ) + showGDHelp(); + + if( helpWindow ) + { + helpWindow->showHelpFor( id ); + if( !helpWindow->isVisible() ) + { + helpWindow->show(); + helpWindow->activateWindow(); + } + } +} + +void MainWindow::closeGDHelp() +{ + if( helpWindow ) + { + delete helpWindow; + helpWindow = 0; + } +} + #ifdef Q_OS_WIN32 bool MainWindow::handleGDMessage( MSG * message, long * result ) diff --git a/mainwindow.hh b/mainwindow.hh index 1fd337045..c803d471f 100644 --- a/mainwindow.hh +++ b/mainwindow.hh @@ -69,6 +69,9 @@ public: virtual void commitData( QSessionManager & ); + void showGDHelpForID( QString const & id ); + void closeGDHelp(); + public slots: void messageFromAnotherInstanceReceived( QString const & ); diff --git a/preferences.cc b/preferences.cc index b98c02166..fea43294a 100644 --- a/preferences.cc +++ b/preferences.cc @@ -4,11 +4,16 @@ #include "langcoder.hh" #include #include "broken_xrecord.hh" +#include "mainwindow.hh" -Preferences::Preferences( QWidget * parent, Config::Preferences const & p ): +Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ): QDialog( parent ), prevInterfaceLanguage( 0 ) +, helpWindow( 0 ) +, cfg( cfg_ ) +, helpAction( this ) { + Config::Preferences const & p = cfg_.preferences; ui.setupUi( this ); connect( ui.enableScanPopup, SIGNAL( toggled( bool ) ), @@ -37,6 +42,17 @@ Preferences::Preferences( QWidget * parent, Config::Preferences const & p ): connect( ui.rightShift, SIGNAL( clicked( bool ) ), this, SLOT( sideShiftClicked( bool ) ) ); + connect( ui.buttonBox, SIGNAL( helpRequested() ), + this, SLOT( helpRequested() ) ); + + helpAction.setShortcut( QKeySequence( "F1" ) ); + helpAction.setShortcutContext( Qt::WidgetWithChildrenShortcut ); + + connect( &helpAction, SIGNAL( triggered() ), + this, SLOT( helpRequested() ) ); + + addAction( &helpAction ); + // Load values into form ui.interfaceLanguage->addItem( tr( "System default" ), QString() ); @@ -491,3 +507,38 @@ void Preferences::customProxyToggled( bool ) ui.customSettingsGroup->setEnabled( ui.customProxy->isChecked() && ui.useProxyServer->isChecked() ); } + +void Preferences::helpRequested() +{ + if( !helpWindow ) + { + MainWindow * mainWindow = qobject_cast< MainWindow * >( parentWidget() ); + if( mainWindow ) + mainWindow->closeGDHelp(); + + helpWindow = new Help::HelpWindow( this, cfg ); + + if( helpWindow ) + { + helpWindow->setWindowFlags( Qt::Window ); + + connect( helpWindow, SIGNAL( needClose() ), + this, SLOT( closeHelp() ) ); + helpWindow->showHelpFor( "Preferences" ); + helpWindow->show(); + } + } + else + { + if( !helpWindow->isVisible() ) + helpWindow->show(); + + helpWindow->activateWindow(); + } +} + +void Preferences::closeHelp() +{ + if( helpWindow ) + helpWindow->hide(); +} diff --git a/preferences.hh b/preferences.hh index 26d855f14..c922b7676 100644 --- a/preferences.hh +++ b/preferences.hh @@ -3,6 +3,7 @@ #include #include "config.hh" +#include "helpwindow.hh" #include "ui_preferences.h" /// Preferences dialog -- allows changing various program options. @@ -12,9 +13,15 @@ class Preferences: public QDialog int prevInterfaceLanguage; + Help::HelpWindow * helpWindow; + Config::Class & cfg; + QAction helpAction; + public: - Preferences( QWidget * parent, Config::Preferences const & ); + Preferences( QWidget * parent, Config::Class & cfg_ ); + ~Preferences() + { if( helpWindow ) delete helpWindow; } Config::Preferences getPreferences(); @@ -43,6 +50,9 @@ private slots: void on_useExternalPlayer_toggled( bool enabled ); void customProxyToggled( bool ); + + void helpRequested(); + void closeHelp(); }; #endif diff --git a/preferences.ui b/preferences.ui index efb66b62b..1b1c3a812 100644 --- a/preferences.ui +++ b/preferences.ui @@ -1566,7 +1566,7 @@ It is not needed to select this option if you don't use such programs. Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok