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