File indexing completed on 2025-04-20 06:32:00
0001 /* 0002 This file is part of Kiten, a KDE Japanese Reference Tool... 0003 SPDX-FileCopyrightText: 2001 Jason Katz-Brown <jason@katzbrown.com> 0004 SPDX-FileCopyrightText: 2005 Paul Temple <paul.temple@gmx.net> 0005 SPDX-FileCopyrightText: 2006 Joseph Kerian <jkerian@gmail.com> 0006 SPDX-FileCopyrightText: 2006 Eric Kjeldergaard <kjelderg@gmail.com> 0007 SPDX-FileCopyrightText: 2011 Daniel E. Moctezuma <democtezuma@gmail.com> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include "kiten.h" 0013 0014 #include <KActionCollection> 0015 #include <KConfigGui> 0016 #include <KEditToolBar> 0017 #include <KLocalizedString> 0018 #include <KProcess> 0019 #include <KStandardAction> 0020 #include <KStandardGuiItem> 0021 #include <KToggleAction> 0022 #include <KXMLGUIFactory> 0023 0024 #include <QAction> 0025 #include <QApplication> 0026 #include <QClipboard> 0027 #include <QDockWidget> 0028 #include <QList> 0029 #include <QPair> 0030 #include <QScrollBar> 0031 #include <QStandardPaths> 0032 #include <QStatusBar> 0033 #include <QTimer> 0034 #include <QVBoxLayout> 0035 0036 #include "configuredialog.h" 0037 #include "dictionaryupdatemanager.h" 0038 #include "entrylist.h" 0039 #include "entrylistmodel.h" 0040 #include "entrylistview.h" 0041 #include "kitenconfig.h" 0042 #include "resultsview.h" 0043 #include "searchstringinput.h" 0044 0045 using namespace Qt::StringLiterals; 0046 0047 Kiten::Kiten(QWidget *parent, const char *name) 0048 : KXmlGuiWindow(parent) 0049 , _lastQuery(DictQuery()) 0050 , _radselect_proc(new KProcess(this)) 0051 , _kanjibrowser_proc(new KProcess(this)) 0052 { 0053 _radselect_proc->setProgram(QStandardPaths::findExecutable(QStringLiteral("kitenradselect"))); 0054 _kanjibrowser_proc->setProgram(QStandardPaths::findExecutable(QStringLiteral("kitenkanjibrowser"))); 0055 setStandardToolBarMenuEnabled(true); 0056 setObjectName(QLatin1String(name)); 0057 0058 /* Set up the config */ 0059 _config = KitenConfigSkeleton::self(); 0060 _config->load(); 0061 0062 /* ResultsView is our main widget, displaying the results of a search */ 0063 _mainView = new ResultsView(this, "mainView"); 0064 0065 /* Create the export list */ 0066 // setupExportListDock(); 0067 0068 /* TODO: have a look at this idea 0069 detachedView = new ResultsView( NULL, "detachedView" ); 0070 */ 0071 0072 setCentralWidget(_mainView); 0073 0074 setupActions(); 0075 // Be sure to create this manager before creating the GUI 0076 // as it needs to add a KAction to it. 0077 _dictionaryUpdateManager = new DictionaryUpdateManager(this); 0078 0079 createGUI(); 0080 0081 _statusBar = statusBar(); 0082 _optionDialog = nullptr; 0083 0084 /* Set things as they were (as told in the config) */ 0085 _autoSearchToggle->setChecked(_config->autosearch()); 0086 _inputManager->setDefaultsFromConfig(); 0087 updateConfiguration(); 0088 applyMainWindowSettings(KSharedConfig::openStateConfig()->group(QStringLiteral("kitenWindow"))); 0089 0090 /* What happens when links are clicked or things are selected in the clipboard */ 0091 connect(_mainView, &ResultsView::urlClicked, this, &Kiten::searchText); 0092 connect(QApplication::clipboard(), &QClipboard::selectionChanged, this, &Kiten::searchClipboard); 0093 connect(_inputManager, &SearchStringInput::search, this, &Kiten::searchFromEdit); 0094 0095 connect(_mainView->verticalScrollBar(), &QAbstractSlider::valueChanged, this, &Kiten::setCurrentScrollValue); 0096 /* We need to know when to reload our dictionaries if the user updated them. */ 0097 connect(_dictionaryUpdateManager, &DictionaryUpdateManager::updateFinished, this, &Kiten::loadDictionaries); 0098 0099 /* See below for what else needs to be done */ 0100 QTimer::singleShot(10, this, &Kiten::finishInit); 0101 } 0102 0103 // Destructor to clean up the little bits 0104 Kiten::~Kiten() 0105 { 0106 if (_radselect_proc->state() != QProcess::NotRunning) { 0107 _radselect_proc->kill(); 0108 } 0109 if (_kanjibrowser_proc->state() != QProcess::NotRunning) { 0110 _kanjibrowser_proc->kill(); 0111 } 0112 _dictionaryManager.removeAllDictionaries(); 0113 delete _optionDialog; 0114 _optionDialog = nullptr; 0115 } 0116 0117 KitenConfigSkeleton *Kiten::getConfig() 0118 { 0119 return _config; 0120 } 0121 0122 void Kiten::setupActions() 0123 { 0124 /* Add the basic quit/print/prefs actions, use the gui factory for keybindings */ 0125 (void)KStandardAction::quit(this, SLOT(close()), actionCollection()); 0126 // Why the heck is KSA:print adding it's own toolbar!? 0127 // (void) KStandardAction::print(this, SLOT(print()), actionCollection()); 0128 (void)KStandardAction::preferences(this, SLOT(slotConfigure()), actionCollection()); 0129 // old style cast seems needed here, (const QObject*) 0130 KStandardAction::keyBindings(guiFactory(), &KXMLGUIFactory::showConfigureShortcutsDialog, actionCollection()); 0131 0132 QAction *radselect = actionCollection()->addAction(QStringLiteral("radselect")); 0133 radselect->setText(i18n("Radical Selector")); 0134 actionCollection()->setDefaultShortcut(radselect, Qt::CTRL | Qt::Key_R); 0135 connect(radselect, &QAction::triggered, this, &Kiten::radicalSearch); 0136 0137 QAction *kanjibrowser = actionCollection()->addAction(QStringLiteral("kanjibrowser")); 0138 kanjibrowser->setText(i18n("Kanji Browser")); 0139 actionCollection()->setDefaultShortcut(kanjibrowser, Qt::CTRL | Qt::Key_K); 0140 connect(kanjibrowser, &QAction::triggered, this, &Kiten::kanjiBrowserSearch); 0141 0142 /* Setup the Search Actions and our custom Edit Box */ 0143 _inputManager = new SearchStringInput(this); 0144 0145 QAction *searchButton = actionCollection()->addAction(QStringLiteral("search")); 0146 searchButton->setText(i18n("S&earch")); 0147 // Set the search button to search 0148 connect(searchButton, &QAction::triggered, this, &Kiten::searchFromEdit); 0149 searchButton->setIcon(KStandardGuiItem::find().icon()); 0150 0151 // That's not it, that's "find as you type"... 0152 // connect( Edit, SIGNAL(completion(QString)), 0153 // this, SLOT(searchFromEdit()) ); 0154 0155 /* Setup our widgets that handle preferences */ 0156 // deinfCB = new KToggleAction( i18n( "&Deinflect Verbs in Regular Search" ) 0157 // , 0 0158 // , this 0159 // , SLOT(kanjiDictChange()) 0160 // , actionCollection() 0161 // , "deinf_toggle" ); 0162 0163 _autoSearchToggle = actionCollection()->add<KToggleAction>(QStringLiteral("autosearch_toggle")); 0164 _autoSearchToggle->setText(i18n("&Automatically Search Clipboard Selections")); 0165 0166 _irAction = actionCollection()->add<QAction>(QStringLiteral("search_in_results")); 0167 _irAction->setText(i18n("Search &in Results")); 0168 connect(_irAction, &QAction::triggered, this, &Kiten::searchInResults); 0169 0170 QAction *actionFocusResultsView; 0171 actionFocusResultsView = actionCollection()->addAction(QStringLiteral("focusresultview"), this, SLOT(focusResultsView())); 0172 actionCollection()->setDefaultShortcut(actionFocusResultsView, Qt::Key_Escape); 0173 actionFocusResultsView->setText(i18n("Focus result view")); 0174 0175 (void)KStandardAction::configureToolbars(this, SLOT(configureToolBars()), actionCollection()); 0176 0177 _backAction = KStandardAction::back(this, SLOT(back()), actionCollection()); 0178 _backAction->setWhatsThis(i18n("Go to the previous search query.")); 0179 _forwardAction = KStandardAction::forward(this, SLOT(forward()), actionCollection()); 0180 _forwardAction->setWhatsThis(i18n("Go to the next search query.")); 0181 _backAction->setEnabled(false); 0182 _forwardAction->setEnabled(false); 0183 } 0184 0185 void Kiten::setupExportListDock() 0186 { 0187 _exportListDock = new QDockWidget(i18n("Export List"), this); 0188 _exportListDockContents = new QWidget(_exportListDock); 0189 _exportListDock->setWidget(_exportListDockContents); 0190 addDockWidget(Qt::RightDockWidgetArea, _exportListDock); 0191 0192 auto layout = new QVBoxLayout(_exportListDockContents); 0193 _exportListDockContents->setLayout(layout); 0194 0195 _exportList = new EntryListView(_exportListDockContents); 0196 0197 layout->addWidget(_exportList); 0198 0199 _exportList->setModel(new EntryListModel(EntryList())); 0200 } 0201 0202 void Kiten::addExportListEntry(int index) 0203 { 0204 auto model = qobject_cast<EntryListModel *>(_exportList->model()); 0205 if (!model) 0206 return; 0207 0208 EntryList list = model->entryList(); 0209 0210 list << _historyList.current()->at(index)->clone(); 0211 model->setEntryList(list); 0212 } 0213 0214 // This is the latter part of the initialization 0215 void Kiten::finishInit() 0216 { 0217 _statusBar->showMessage(i18n("Initializing Dictionaries")); 0218 0219 // if it's the application's first time starting, 0220 // the app group won't exist and we show demo 0221 if (_config->initialSearch()) { 0222 if (!KConfigGui::hasSessionConfig() || !KConfigGui::sessionConfig()->hasGroup(QStringLiteral("app"))) { 0223 searchTextAndRaise(QStringLiteral("辞書")); 0224 // Note to future tinkerers... DO NOT EDIT OR TRANSLATE THAT 0225 // it's an embedded unicode search string to find "dictionary" in japanese 0226 } 0227 } 0228 0229 _inputManager->focusInput(); 0230 _statusBar->showMessage(i18n("Welcome to Kiten")); 0231 setCaption(QString()); 0232 } 0233 0234 void Kiten::focusResultsView() 0235 { 0236 _mainView->verticalScrollBar()->setFocus(); 0237 } 0238 0239 // This function is run on program window close. 0240 // It saves the settings in the config. 0241 bool Kiten::queryClose() 0242 { 0243 _config->setAutosearch(_autoSearchToggle->isChecked()); 0244 _config->save(); 0245 0246 KConfigGroup configGroup = KSharedConfig::openStateConfig()->group(QStringLiteral("kitenWindow")); 0247 saveMainWindowSettings(configGroup); 0248 return true; 0249 } 0250 0251 ////////////////////////////////////////////////////////////////////////////// 0252 // SEARCHING METHODS 0253 ////////////////////////////////////////////////////////////////////////////// 0254 0255 /** 0256 * This function searches for the contents of the Edit field in the mainwindow. 0257 * Any gui choices will also be included here. 0258 */ 0259 void Kiten::searchFromEdit() 0260 { 0261 qDebug() << "SEARCH FROM EDIT CALLED"; 0262 DictQuery query = _inputManager->getSearchQuery(); 0263 if (query != _lastQuery) { 0264 _lastQuery = query; 0265 searchAndDisplay(query); 0266 } 0267 } 0268 0269 /** 0270 * This function is called when a kanji is clicked in the result view 0271 * or any other time in which we want to search for something that didn't 0272 * come from the input box. 0273 */ 0274 void Kiten::searchText(const QString &text) 0275 { 0276 searchAndDisplay(DictQuery(text)); 0277 } 0278 0279 /** 0280 * This should change the Edit text to be appropriate and then begin a search 0281 * of the dictionaries' entries. 0282 */ 0283 void Kiten::searchTextAndRaise(const QString &str) 0284 { 0285 /* Do the search */ 0286 searchText(str); 0287 /* get the window as we'd like it */ 0288 raise(); 0289 } 0290 0291 /** 0292 * This function will search things as they are put in the clipboard. 0293 * It checks each time to see if the autoSearchToggle is set. 0294 * This function searches for the contents of the clipboard 0295 * filter out long selections and selections that are contained in our 0296 * current search (alleviates problem where research occurs because of 0297 * X's auto-add-to-clipboard-on-select feature. 0298 */ 0299 void Kiten::searchClipboard() 0300 { 0301 if (_autoSearchToggle->isChecked()) { 0302 QString clipboard = QApplication::clipboard()->text(QClipboard::Selection).simplified(); 0303 0304 // Only search if the clipboard selection was less than 20 characters wide 0305 if (clipboard.length() < 20) { 0306 DictQuery potentialQuery(clipboard); 0307 // Make sure that we're not looking for a substring of the current string (needed?) 0308 if (!(potentialQuery < _inputManager->getSearchQuery())) { 0309 searchTextAndRaise(clipboard); 0310 } 0311 0312 qDebug() << "Clipboard item is a substring (rejected)"; 0313 } else { 0314 qDebug() << "Clipboard entry too long"; 0315 } 0316 } 0317 } 0318 0319 /** 0320 * This method performs the search and displays 0321 * the result to the screen. 0322 */ 0323 void Kiten::searchAndDisplay(const DictQuery &query) 0324 { 0325 /* keep the user informed of what we are doing */ 0326 _statusBar->showMessage(i18n("Searching...")); 0327 0328 /* This gorgeous incantation is all that's necessary to fill a DictQuery 0329 with a query and an Entrylist with all of the results form all of the 0330 requested dictionaries */ 0331 EntryList *results = _dictionaryManager.doSearch(query); 0332 0333 /* if there are no results */ 0334 if (results->empty()) // TODO: check here if the user actually prefers this 0335 { 0336 // create a modifiable copy of the original query 0337 DictQuery newQuery(query); 0338 0339 bool tryAgain = false; 0340 0341 do { 0342 // by default we don't try again 0343 tryAgain = false; 0344 0345 // but if the matchtype is changed we try again 0346 if (newQuery.getMatchType() == DictQuery::Exact) { 0347 newQuery.setMatchType(DictQuery::Beginning); 0348 tryAgain = true; 0349 } else if (newQuery.getMatchType() == DictQuery::Beginning) { 0350 newQuery.setMatchType(DictQuery::Anywhere); 0351 tryAgain = true; 0352 } 0353 0354 // try another search 0355 if (tryAgain) { 0356 delete results; 0357 results = _dictionaryManager.doSearch(newQuery); 0358 0359 // results means all is ok; don't try again 0360 if (!results->empty()) { 0361 tryAgain = false; 0362 } 0363 } 0364 } while (tryAgain); 0365 } 0366 0367 /* synchronize the history (and store this pointer there) */ 0368 addHistory(results); 0369 0370 /* Add the current search to our drop down list */ 0371 _inputManager->setSearchQuery(results->getQuery()); 0372 0373 /* suppose it's about time to show the users the results. */ 0374 displayResults(results); 0375 } 0376 0377 /** 0378 * Search in the previous results, identical to 0379 * searchAndDisplay except for the one call. 0380 */ 0381 void Kiten::searchInResults() 0382 { 0383 _statusBar->showMessage(i18n("Searching...")); 0384 0385 DictQuery searchQuery = _inputManager->getSearchQuery(); 0386 EntryList *results = _dictionaryManager.doSearchInList(searchQuery, _historyList.current()); 0387 0388 addHistory(results); 0389 _inputManager->setSearchQuery(searchQuery); 0390 displayResults(results); 0391 } 0392 0393 /** 0394 * Given a set of Search Results items, this function does all that's needed 0395 * to put the interface into an appropriate state for those searchResults. 0396 */ 0397 void Kiten::displayResults(EntryList *results) 0398 { 0399 QString infoStr; 0400 /* synchronize the statusbar */ 0401 if (results->count() > 0) { 0402 infoStr = i18np("Found 1 result", "Found %1 results", results->count()); 0403 } else { 0404 infoStr = i18n("No results found"); 0405 } 0406 _statusBar->showMessage(infoStr); 0407 setCaption(infoStr); 0408 0409 /* sort the results */ 0410 /* synchronize the results window */ 0411 if (results->count() > 0) { 0412 QStringList dictSort; 0413 QStringList fieldSort = _config->field_sortlist(); 0414 if (_config->dictionary_enable() == QLatin1String("true")) { 0415 dictSort = _config->dictionary_sortlist(); 0416 } 0417 results->sort(fieldSort, dictSort); 0418 _mainView->setContents(results->toHTML()); 0419 } else { 0420 _mainView->setContents("<html><body>"_L1 + infoStr + "</body></html>"_L1); 0421 } 0422 0423 _mainView->setLaterScrollValue(results->scrollValue()); 0424 0425 /* //Debuggery: to print the html results to file: 0426 QFile file( "/tmp/lala" ); 0427 file.open( QIODevice::WriteOnly ); 0428 file.write( results->toHTML().toUtf8() ); 0429 file.close(); 0430 */ 0431 } 0432 0433 void Kiten::radicalSearch() 0434 { 0435 // Radselect is a KUniqueApplication, so we don't 0436 // need to worry about opening more than one copy 0437 _radselect_proc->start(); 0438 } 0439 0440 void Kiten::kanjiBrowserSearch() 0441 { 0442 // KanjiBrowser is a KUniqueApplication, so we don't 0443 // need to worry about opening more than one copy 0444 _kanjibrowser_proc->start(); 0445 } 0446 0447 ////////////////////////////////////////////////////////////////////////////// 0448 // PREFERENCES RELATED METHODS 0449 ////////////////////////////////////////////////////////////////////////////// 0450 void Kiten::slotConfigure() 0451 { 0452 // If the settings dialog is open and obscured/hidden/cached, show it 0453 if (ConfigureDialog::showDialog(QStringLiteral("settings"))) { 0454 return; 0455 } 0456 0457 // ConfigureDialog didn't find an instance of this dialog, so lets create it : 0458 _optionDialog = new ConfigureDialog(this, _config); 0459 connect(_optionDialog, &ConfigureDialog::settingsChanged, this, &Kiten::updateConfiguration); 0460 0461 _optionDialog->show(); 0462 } 0463 0464 void Kiten::configureToolBars() 0465 { 0466 KConfigGroup configGroup = KSharedConfig::openStateConfig()->group(QStringLiteral("kitenWindow")); 0467 saveMainWindowSettings(configGroup); 0468 KEditToolBar dlg(actionCollection()); 0469 connect(&dlg, &KEditToolBar::newToolBarConfig, this, &Kiten::newToolBarConfig); 0470 dlg.exec(); 0471 } 0472 0473 void Kiten::newToolBarConfig() 0474 { 0475 createGUI(QStringLiteral("kitenui.rc")); 0476 KConfigGroup configGroup = KSharedConfig::openStateConfig()->group(QStringLiteral("kitenWindow")); 0477 applyMainWindowSettings(configGroup); 0478 } 0479 0480 /** 0481 * This function, as the name says, updates the configuration file. 0482 * It should be called in EVERY case where the configuration files change. 0483 */ 0484 void Kiten::updateConfiguration() 0485 { 0486 loadDictionaries(); 0487 0488 // Update the HTML/CSS for our fonts 0489 displayHistoryItem(); 0490 0491 _inputManager->updateFontFromConfig(); 0492 0493 // Reset the content of the last query. This is because in case the user adds 0494 // new dictionaries and wants to execute the same last search, the output 0495 // will contain results of the new dictionary/dictionaries added. 0496 _lastQuery = DictQuery(); 0497 0498 /*: TODO: have a look at this as well 0499 detachedView->updateFont(); 0500 */ 0501 } 0502 0503 /** 0504 * Loads the dictionaries, their settings and updates general 0505 * options for the display manager. 0506 */ 0507 void Kiten::loadDictionaries() 0508 { 0509 // Avoid duplicates (this makes it easy when we need to reload the dictionaries). 0510 _dictionaryManager.removeAllDictionaries(); 0511 0512 // Load the dictionaries of each type that we can adjust in prefs 0513 for (const QString &it : _config->dictionary_list()) { 0514 loadDictConfig(it); 0515 } 0516 0517 // Load settings for each dictionary type 0518 for (const QString &it : _dictionaryManager.listDictFileTypes()) { 0519 _dictionaryManager.loadDictSettings(it, _config); 0520 } 0521 0522 // Update general options for the display manager (sorting by dict, etc) 0523 _dictionaryManager.loadSettings(*_config->config()); 0524 qDebug() << "Dictionaries loaded!"; 0525 } 0526 0527 /** 0528 * This function loads the dictionaries from the config file for the program 0529 * to use via the dictionaryManager object. 0530 */ 0531 void Kiten::loadDictConfig(const QString &dictType) 0532 { 0533 KConfigGroup group = _config->config()->group("dicts_"_L1 + dictType.toLower()); 0534 0535 // A list of QPair's Name->Path 0536 QList<QPair<QString, QString>> dictionariesToLoad; 0537 0538 // If we need to load the global 0539 if (group.readEntry("__useGlobal", true)) { 0540 QString dictionary = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kiten/") + dictType.toLower()); 0541 dictionariesToLoad.append(qMakePair(dictType, dictionary)); 0542 } 0543 0544 QStringList dictNames = group.readEntry<QStringList>("__NAMES", QStringList()); 0545 for (const QString &name : dictNames) { 0546 QString dictPath = group.readEntry(name, QString()); 0547 if (!dictPath.isEmpty() && !name.isEmpty()) { 0548 dictionariesToLoad.append(qMakePair(name, dictPath)); 0549 } 0550 } 0551 0552 QStringList loadedDictionaries = _dictionaryManager.listDictionariesOfType(dictType.toLower()); 0553 0554 for (const auto &it : dictionariesToLoad) { 0555 // Remove from the loadedDictionaries list all the dicts that we are supposed to load 0556 // This will leave only those that need to be unloaded at the end 0557 if (loadedDictionaries.removeAll(it.first) == 0) { 0558 _dictionaryManager.addDictionary(it.second, it.first, dictType.toLower()); 0559 } 0560 } 0561 0562 for (const QString &it : loadedDictionaries) { 0563 _dictionaryManager.removeDictionary(it); 0564 } 0565 0566 /* 0567 #define PERSONALDictionaryLocation( __X ) KGlobal::dirs()->saveLocation(__X, \ 0568 "kiten/dictionaries/",true).append("personal") 0569 if(!isKanji) { //Don't load personal dicts as kanji dicts 0570 QString personalDict(PERSONALDictionaryLocation("data")); 0571 if (QFile::exists(personalDict) && 0572 loadedDicts.find(personalDict) == loadedDicts.end()) 0573 { 0574 dictionaryManager.addDictionary(personalDict,"Personal",dictType.lower()); 0575 } 0576 } 0577 */ 0578 } 0579 0580 /** 0581 * This function allows one to print out the currently displayed result 0582 */ 0583 void Kiten::print() 0584 { 0585 // _ResultsView->toHTML(); 0586 } 0587 0588 /****************************************************************************** 0589 HISTORY HANDLING FUNCTIONS 0590 ******************************************************************************/ 0591 0592 /** 0593 * Given one Search Result, it adds it to the history list the logic in it 0594 * exists to maintain the history list of a certain size. Note that this method 0595 * does not display the EntryList it is given... so you can add something to the 0596 * history and display it separately. 0597 */ 0598 void Kiten::addHistory(EntryList *result) 0599 { 0600 _historyList.addItem(result); 0601 enableHistoryButtons(); 0602 } 0603 0604 /** 0605 * This goes back one item in the history and displays 0606 */ 0607 void Kiten::back() 0608 { 0609 _historyList.prev(); 0610 displayHistoryItem(); 0611 } 0612 0613 /** 0614 * This goes forward one item in the history and displays 0615 */ 0616 void Kiten::forward() 0617 { 0618 _historyList.next(); 0619 displayHistoryItem(); 0620 } 0621 0622 /** 0623 * This method just sets the current element in the list and triggers the display 0624 */ 0625 void Kiten::goInHistory(int index) 0626 { 0627 _historyList.setCurrent(index); 0628 displayHistoryItem(); 0629 } 0630 0631 void Kiten::displayHistoryItem() 0632 { 0633 if (_historyList.current() == nullptr) 0634 return; 0635 0636 _inputManager->setSearchQuery(_historyList.current()->getQuery()); 0637 enableHistoryButtons(); 0638 0639 displayResults(_historyList.current()); 0640 } 0641 0642 /** 0643 * This function determines whether the forward and back buttons should be enabled. 0644 * It is currently done independently of what action has just occurred. 0645 */ 0646 void Kiten::enableHistoryButtons() 0647 { 0648 _backAction->setEnabled(_historyList.index() > 0); 0649 _forwardAction->setEnabled(_historyList.index() + 1 < _historyList.count()); 0650 } 0651 0652 void Kiten::setCurrentScrollValue(int value) 0653 { 0654 if (_historyList.current() == nullptr) 0655 return; 0656 0657 _historyList.current()->setScrollValue(value); 0658 } 0659 0660 #include "moc_kiten.cpp"