File indexing completed on 2023-10-03 03:04:58
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 auto 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 auto 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->empty()) // 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->empty()) { 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 for (const QString &it : _config->dictionary_list()) { 0590 loadDictConfig(it); 0591 } 0592 0593 // Load settings for each dictionary type 0594 for (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 for (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 for (const auto &it : dictionariesToLoad) { 0631 // Remove from the loadedDictionaries list all the dicts that we are supposed to load 0632 // This will leave only those that need to be unloaded at the end 0633 if (loadedDictionaries.removeAll(it.first) == 0) { 0634 _dictionaryManager.addDictionary(it.second, it.first, dictType.toLower()); 0635 } 0636 } 0637 0638 for (const QString &it : loadedDictionaries) { 0639 _dictionaryManager.removeDictionary(it); 0640 } 0641 0642 /* 0643 #define PERSONALDictionaryLocation( __X ) KGlobal::dirs()->saveLocation(__X, \ 0644 "kiten/dictionaries/",true).append("personal") 0645 if(!isKanji) { //Don't load personal dicts as kanji dicts 0646 QString personalDict(PERSONALDictionaryLocation("data")); 0647 if (QFile::exists(personalDict) && 0648 loadedDicts.find(personalDict) == loadedDicts.end()) 0649 { 0650 dictionaryManager.addDictionary(personalDict,"Personal",dictType.lower()); 0651 } 0652 } 0653 */ 0654 } 0655 0656 /** 0657 * This function allows one to print out the currently displayed result 0658 */ 0659 void Kiten::print() 0660 { 0661 // _ResultsView->toHTML(); 0662 } 0663 0664 /****************************************************************************** 0665 HISTORY HANDLING FUNCTIONS 0666 ******************************************************************************/ 0667 0668 /** 0669 * Given one Search Result, it adds it to the history list the logic in it 0670 * exists to maintain the history list of a certain size. Note that this method 0671 * does not display the EntryList it is given... so you can add something to the 0672 * history and display it separately. 0673 */ 0674 void Kiten::addHistory(EntryList *result) 0675 { 0676 _historyList.addItem(result); 0677 enableHistoryButtons(); 0678 } 0679 0680 /** 0681 * This goes back one item in the history and displays 0682 */ 0683 void Kiten::back() 0684 { 0685 _historyList.prev(); 0686 displayHistoryItem(); 0687 } 0688 0689 /** 0690 * This goes forward one item in the history and displays 0691 */ 0692 void Kiten::forward() 0693 { 0694 _historyList.next(); 0695 displayHistoryItem(); 0696 } 0697 0698 /** 0699 * This method just sets the current element in the list and triggers the display 0700 */ 0701 void Kiten::goInHistory(int index) 0702 { 0703 _historyList.setCurrent(index); 0704 displayHistoryItem(); 0705 } 0706 0707 void Kiten::displayHistoryItem() 0708 { 0709 if (_historyList.current() == nullptr) 0710 return; 0711 0712 _inputManager->setSearchQuery(_historyList.current()->getQuery()); 0713 enableHistoryButtons(); 0714 0715 displayResults(_historyList.current()); 0716 } 0717 0718 /** 0719 * This function determines whether the forward and back buttons should be enabled. 0720 * It is currently done independently of what action has just occurred. 0721 */ 0722 void Kiten::enableHistoryButtons() 0723 { 0724 _backAction->setEnabled(_historyList.index() > 0); 0725 _forwardAction->setEnabled(_historyList.index() + 1 < _historyList.count()); 0726 } 0727 0728 void Kiten::setCurrentScrollValue(int value) 0729 { 0730 if (_historyList.current() == nullptr) 0731 return; 0732 0733 _historyList.current()->setScrollValue(value); 0734 } 0735 0736 #include "moc_kiten.cpp"