You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeedu/kiten/kiten.cpp

902 lines
24 KiB

/**
This file is part of Kiten, a KDE Japanese Reference Tool...
Copyright (C) 2001 Jason Katz-Brown <jason@katzbrown.com>
(C) 2005 Paul Temple <paul.temple@gmx.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
**/
#include <kaction.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kconfigdialog.h>
#include <kdebug.h>
#include <kdeversion.h>
#include <kedittoolbar.h>
#include <kglobalaccel.h>
#include <kiconloader.h>
#include <kkeydialog.h>
#include <klocale.h>
#include <kmainwindow.h>
#include <kstandarddirs.h>
#include <kstatusbar.h>
#include <tqclipboard.h>
#include <tqregexp.h>
#include <tqtextcodec.h>
#include <tqtimer.h>
#include "kiten.h"
#include "learn.h"
#include "kitenconfig.h"
#include "optiondialog.h"
#include <cassert>
TopLevel::TopLevel(TQWidget *tqparent, const char *name) : KMainWindow(tqparent, name)
{
#if KDE_VERSION > 305
setStandardToolBarMenuEnabled(true);
#endif
config = Config::self();
config->readConfig();
Accel = new KGlobalAccel(TQT_TQOBJECT(this));
(void) Accel->insert("Lookup Kanji (Kanjidic)", i18n("Lookup Kanji (Kanjidic)"), i18n("Gives detailed information about Kanji currently on clipboard."), CTRL + ALT + Key_K, CTRL + ALT + Key_K, TQT_TQOBJECT(this), TQT_SLOT(kanjiSearchAccel()));
(void) Accel->insert("Lookup English/Japanese word", i18n("Lookup English/Japanese Word"), i18n("Looks up current text on clipboard in the same way as if you used Kiten's regular search."), CTRL + ALT + Key_S, CTRL + ALT + Key_S, TQT_TQOBJECT(this), TQT_SLOT(searchAccel()));
Accel->readSettings(KGlobal::config());
Accel->updateConnections();
_ResultView = new ResultView(true, this, "_ResultView");
setCentralWidget(_ResultView);
(void) KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection());
(void) KStdAction::print(TQT_TQOBJECT(this), TQT_SLOT(print()), actionCollection());
(void) KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(slotConfigure()), actionCollection());
KStdAction::keyBindings(guiFactory(), TQT_SLOT(configureShortcuts()), actionCollection());
(void) new KAction(i18n("&Learn"), "pencil", CTRL+Key_L, TQT_TQOBJECT(this), TQT_SLOT(createLearn()), actionCollection(), "file_learn");
(void) new KAction(i18n("&Dictionary Editor..."), "edit", 0, TQT_TQOBJECT(this), TQT_SLOT(createEEdit()), actionCollection(), "dict_editor");
(void) new KAction(i18n("Ra&dical Search..."), "gear", CTRL+Key_R, TQT_TQOBJECT(this), TQT_SLOT(radicalSearch()), actionCollection(), "search_radical");
Edit = new EditAction(i18n("Search Edit"), 0, TQT_TQOBJECT(this), TQT_SLOT(search()), actionCollection(), "search_edit");
(void) new KAction(i18n("&Clear Search Bar"), BarIcon("locationbar_erase", 16), CTRL+Key_N, Edit, TQT_SLOT(clear()), actionCollection(), "clear_search");
(void) new KAction(i18n("S&earch"), "key_enter", 0, TQT_TQOBJECT(this), TQT_SLOT(search()), actionCollection(), "search");
(void) new KAction(i18n("Search with &Beginning of Word"), 0, TQT_TQOBJECT(this), TQT_SLOT(searchBeginning()), actionCollection(), "search_beginning");
(void) new KAction(i18n("Search &Anywhere"), 0, TQT_TQOBJECT(this), TQT_SLOT(searchAnywhere()), actionCollection(), "search_anywhere");
(void) new KAction(i18n("Stro&kes"), "paintbrush", CTRL+Key_S, TQT_TQOBJECT(this), TQT_SLOT(strokeSearch()), actionCollection(), "search_stroke");
(void) new KAction(i18n("&Grade"), "leftjust", CTRL+Key_G, TQT_TQOBJECT(this), TQT_SLOT(gradeSearch()), actionCollection(), "search_grade");
kanjiCB = new KToggleAction(i18n("&Kanjidic"), "kanjidic", CTRL+Key_K, TQT_TQOBJECT(this), TQT_SLOT(kanjiDictChange()), actionCollection(), "kanji_toggle");
deinfCB = new KToggleAction(i18n("&Deinflect Verbs in Regular Search"), 0, TQT_TQOBJECT(this), TQT_SLOT(kanjiDictChange()), actionCollection(), "deinf_toggle");
comCB = new KToggleAction(i18n("&Filter Rare"), "filter", CTRL+Key_F, TQT_TQOBJECT(this), TQT_SLOT(toggleCom()), actionCollection(), "common");
autoSearchToggle = new KToggleAction(i18n("&Automatically Search Clipboard Selections"), "tqfind", 0, TQT_TQOBJECT(this), TQT_SLOT(kanjiDictChange()), actionCollection(), "autosearch_toggle");
irAction = new KAction(i18n("Search &in Results"), "tqfind", CTRL+Key_I, TQT_TQOBJECT(this), TQT_SLOT(resultSearch()), actionCollection(), "search_in_results");
(void) KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(configureToolBars()), actionCollection());
addAction = new KAction(i18n("Add &Kanji to Learning List"), 0, TQT_TQOBJECT(this), TQT_SLOT(addToList()), actionCollection(), "add");
addAction->setEnabled(false);
(void) new KAction(i18n("Configure &Global Shortcuts..."), "configure_shortcuts", 0, TQT_TQOBJECT(this), TQT_SLOT(configureGlobalKeys()), actionCollection(), "options_configure_keybinding");
historyAction = new KListAction(i18n("&History"), 0, 0, 0, actionCollection(), "history");
connect(historyAction, TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(goInHistory(int)));
backAction = KStdAction::back(TQT_TQOBJECT(this), TQT_SLOT(back()), actionCollection());
forwardAction = KStdAction::forward(TQT_TQOBJECT(this), TQT_SLOT(forward()), actionCollection());
backAction->setEnabled(false);
forwardAction->setEnabled(false);
currentResult = resultHistory.end();
currentResultIndex = 0;
createGUI();
StatusBar = statusBar();
optionDialog = 0;
comCB->setChecked(config->com());
kanjiCB->setChecked(config->kanji());
autoSearchToggle->setChecked(config->autosearch());
deinfCB->setChecked(config->deinf());
updateConfiguration();
if (config->startLearn())
createLearn();
resize(600, 400);
applyMainWindowSettings(KGlobal::config(), "TopLevelWindow");
connect(_ResultView, TQT_SIGNAL(linkClicked(const TQString &)), TQT_SLOT(ressearch(const TQString &)));
connect(kapp->clipboard(), TQT_SIGNAL(selectionChanged()), TQT_TQOBJECT(this), TQT_SLOT(autoSearch()));
TQTimer::singleShot(10, TQT_TQOBJECT(this), TQT_SLOT(finishInit()));
}
TopLevel::~TopLevel()
{
delete optionDialog;
optionDialog = 0;
}
void TopLevel::finishInit()
{
// if it's the application's first time starting,
// the app group won't exist and we show demo
if (!kapp->config()->hasGroup("app"))
{
if (kanjiCB->isChecked())
Edit->setText(TQString::fromUtf8(""));
else
Edit->setText(TQString::fromUtf8("辞書"));
search();
}
Edit->clear(); // make sure the edit is focused initially
StatusBar->message(i18n("Welcome to Kiten"));
setCaption(TQString());
}
bool TopLevel::queryClose()
{
for (TQPtrListIterator<Learn> i(learnList); *i;)
{
(*i)->show();
if (!(*i)->closeWindow())
return false; // cancel
Learn *old = *i;
++i;
learnList.remove(old);
}
config->setCom(comCB->isChecked());
config->setKanji(kanjiCB->isChecked());
config->setAutosearch(autoSearchToggle->isChecked());
config->setDeinf(deinfCB->isChecked());
config->writeConfig();
saveMainWindowSettings(KGlobal::config(), "TopLevelWindow");
return true;
}
void TopLevel::addToList()
{
if (learnList.isEmpty())
createLearn();
else
StatusBar->message(i18n("%1 added to learn list of all open learn windows").tqarg(toAddKanji.kanji()));
emit add(toAddKanji);
}
void TopLevel::doSearch(const TQString &text, TQRegExp regexp)
{
if (text.isEmpty())
{
StatusBar->message(i18n("Empty search items"));
return;
}
StatusBar->message(i18n("Searching..."));
Dict::SearchResult results;
if (kanjiCB->isChecked())
{
results = _Asyndeta.retrieveIndex()->searchKanji(regexp, text, comCB->isChecked());
}
else
{
results = _Asyndeta.retrieveIndex()->search(regexp, text, comCB->isChecked());
// do again... bad because sometimes reading is kanji
if ((readingSearch || beginningReadingSearch) && (results.count < 1))
{
//kdDebug() << "doing again\n";
if (beginningReadingSearch)
regexp = kanjiSearchItems(true);
else if (readingSearch)
regexp = kanjiSearchItems();
results = _Asyndeta.retrieveIndex()->search(regexp, text, comCB->isChecked());
}
}
addHistory(results);
handleSearchResult(results);
readingSearch = false;
}
void TopLevel::doSearchInResults(const TQString &text, TQRegExp regexp)
{
if (text.isEmpty())
{
StatusBar->message(i18n("Empty search items"));
return;
}
StatusBar->message(i18n("Searching..."));
Dict::SearchResult results = _Asyndeta.retrieveIndex()->searchPrevious(regexp, text, *currentResult, comCB->isChecked());
addHistory(results);
handleSearchResult(results);
readingSearch = false;
}
void TopLevel::handleSearchResult(Dict::SearchResult results)
{
Edit->setText(results.text);
setResults(results.count, results.outOf);
addAction->setEnabled(false);
_ResultView->clear();
Dict::Entry first = Dict::firstEntry(results);
if (results.count > 0)
kanjiCB->setChecked(first.extendedKanjiInfo());
else
{
_ResultView->flush();
return;
}
if (first.extendedKanjiInfo())
{
if (results.count == 1) // if its only one entry, give compounds too!
{
toAddKanji = first;
_ResultView->addKanjiResult(toAddKanji, results.common, _Rad.radByKanji(toAddKanji.kanji()));
addAction->setEnabled(true);
_ResultView->append(TQString("<p>%1</p>").tqarg(i18n("HTML Entity: %1").tqarg(TQString("&amp;#x%1;").tqarg(TQString::number(toAddKanji.kanji().tqat(0).tqunicode(), 16))))); // show html entity
// now show some compounds in which this kanji appears
TQString kanji = toAddKanji.kanji();
_ResultView->addHeader(i18n("%1 in compounds").tqarg(kanji));
Dict::SearchResult compounds = _Asyndeta.retrieveIndex()->search(TQRegExp(kanji), kanji, true);
bool common = true;
if (compounds.count <= 0)
{
compounds = _Asyndeta.retrieveIndex()->search(TQRegExp(kanji), kanji, false);
_ResultView->addHeader(i18n("(No common compounds)"), 4);
common = false;
}
for (TQValueListIterator<Dict::Entry> it = compounds.list.begin(); it != compounds.list.end(); ++it)
{
//kdDebug() << "adding " << (*it).kanji() << endl;
_ResultView->addResult(*it, common);
kapp->processEvents();
}
}
else
{
for (TQValueListIterator<Dict::Entry> it = results.list.begin(); it != results.list.end(); ++it)
{
kapp->processEvents();
_ResultView->addKanjiResult(*it, results.common);
}
}
}
else
{
for (TQValueListIterator<Dict::Entry> it = results.list.begin(); it != results.list.end(); ++it)
{
kapp->processEvents();
_ResultView->addResult(*it, comCB->isChecked());
}
}
_ResultView->flush();
}
void TopLevel::searchBeginning()
{
TQString text = Edit->text();
TQRegExp regexp;
switch (Dict::textType(text))
{
case Dict::Text_Latin:
regexp = TQRegExp(TQString("\\W").append(text));
break;
case Dict::Text_Kana:
if (kanjiCB->isChecked())
{
regexp = TQRegExp(TQString("\\W").append(text));
}
else
{
beginningReadingSearch = true;
regexp = TQRegExp(TQString("\\[").append(text));
}
break;
case Dict::Text_Kanji:
regexp = TQRegExp(TQString("^").append(text));
}
doSearch(text, regexp);
}
void TopLevel::searchAnywhere()
{
doSearch(Edit->text(), TQRegExp(Edit->text()));
}
void TopLevel::resultSearch()
{
search(true);
}
// called when a kanji is clicked on in result view
void TopLevel::ressearch(const TQString &text)
{
//kdDebug() << "ressearch(" << text << endl;
if (text.startsWith("__radical:"))
{
TQString radical = text.section(":", 1, 1).right(1);
//kdDebug() << "radical is " << radical << endl;
radicalSearch()->addRadical(radical);
return;
}
Edit->setText(text);
kanjiCB->setChecked(true);
search();
}
void TopLevel::search(bool inResults)
{
TQString text = Edit->text();
TQRegExp regexp;
switch (Dict::textType(text))
{
case Dict::Text_Latin:
regexp = searchItems();
break;
case Dict::Text_Kana:
regexp = readingSearchItems(kanjiCB->isChecked());
readingSearch = true;
break;
case Dict::Text_Kanji:
if (deinfCB->isChecked()) // deinflect
{
bool common = comCB->isChecked();
TQStringList names;
TQStringList res(_DeinfIndex.deinflect(text, names));
if (res.size() > 0)
{
Dict::SearchResult hist;
hist.count = 0;
hist.outOf = 0;
hist.common = common;
hist.text = text;
TQStringList done;
res.prepend(text);
names.prepend(i18n("No deinflection"));
TQStringList::Iterator nit = names.begin();
for (TQStringList::Iterator it = res.begin(); it != res.end(); ++it, ++nit)
{
if (done.tqcontains(*it) > 0)
continue;
//kdDebug() << "currently on deinflection " << *it << endl;
Dict::SearchResult results = _Asyndeta.retrieveIndex()->search(TQRegExp(TQString("^") + (*it) + "\\W"), *it, common);
if (results.count < 1) // stop if it isn't in the dictionary
continue;
hist.list.append(Dict::Entry(*nit, true));
hist.list += results.list;
hist.results += results.results;
hist.count += results.count;
hist.outOf += results.outOf;
done.append(*it);
}
handleSearchResult(hist);
addHistory(hist);
return;
}
}
regexp = kanjiSearchItems();
}
if (inResults)
doSearchInResults(text, regexp);
else
doSearch(text, regexp);
}
void TopLevel::strokeSearch()
{
TQString strokesString;
bool ok = false;
TQString text = Edit->text().stripWhiteSpace();
unsigned int strokes = text.toUInt(&ok);
if (!ok)
{
/*
if (text.tqfind("-") < 0)
{
StatusBar->message(i18n("For a range between 4 and 8 strokes, use '4-8'"));
return;
}
unsigned int first = text.section('-', 0, 0).toUInt(&ok);
if (!ok)
{
StatusBar->message(i18n("First number not parseable\n"));
return;
}
unsigned int second = text.section('-', 1, 1).toUInt(&ok);
if (!ok)
{
StatusBar->message(i18n("Second number not parseable\n"));
return;
}
bool already = false;
for (int i = first; i <= second; ++i)
{
if (already)
strokesString.append('|');
already = true;
strokesString.append(TQString::number(i));
}
strokesString.append(')');
strokesString.prepend("(?:");
//kdDebug() << "strokesString is " << strokesString << endl;
*/
StatusBar->message(i18n("Unparseable number"));
return;
}
else if (strokes <= 0 || strokes > 60)
{
StatusBar->message(i18n("Invalid stroke count"));
return;
}
else
{
strokesString = TQString::number(strokes);
}
TQRegExp regexp = TQRegExp(text);
// must be in kanjidic mode
kanjiCB->setChecked(true);
doSearch(TQString("S%1 ").tqarg(strokesString), regexp);
}
void TopLevel::gradeSearch()
{
TQString editText = Edit->text().stripWhiteSpace();
unsigned int grade;
if (editText.lower() == "jouyou")
grade = 8;
else if (editText.lower() == "jinmeiyou")
grade = 9;
else
grade = editText.toUInt();
if (grade <= 0 || grade > 9)
{
StatusBar->message(i18n("Invalid grade"));
return;
}
TQString text = TQString("G%1 ").tqarg(grade);
TQRegExp regexp = TQRegExp(text);
kanjiCB->setChecked(true);
doSearch(text, regexp);
}
TQString TopLevel::clipBoardText() // gets text from clipboard for globalaccels
{
kapp->tqclipboard()->setSelectionMode(true);
TQString text = kapp->tqclipboard()->text().stripWhiteSpace();
kapp->tqclipboard()->setSelectionMode(false);
return text;
}
TQString TopLevel::filteredClipboardText()
{
TQString newText = clipBoardText();
TQString currentText = Edit->text();
if (newText.length() < 80 && newText.tqfind(':') < 0 && newText.tqfind('#') < 0 && newText.tqfind("-") != 0 && newText.tqfind("+") < 0 && currentText.tqfind(newText) < 0)
return newText;
else
return TQString();
}
void TopLevel::autoSearch()
{
if (autoSearchToggle->isChecked())
searchAccel();
}
void TopLevel::searchAccel()
{
TQString newText = filteredClipboardText();
if (!newText.isNull())
{
kanjiCB->setChecked(false);
raise();
Edit->setText(newText);
search();
}
}
void TopLevel::kanjiSearchAccel()
{
TQString newText = filteredClipboardText();
if (!newText.isNull())
{
kanjiCB->setChecked(true);
raise();
Edit->setText(newText);
search();
}
}
void TopLevel::setResults(unsigned int results, unsigned int fullNum)
{
TQString str = i18n("%n result","%n results",results);
if (results < fullNum)
str += i18n(" out of %1").tqarg(fullNum);
StatusBar->message(str);
setCaption(str);
}
void TopLevel::slotConfigurationChanged()
{
updateConfiguration();
}
void TopLevel::updateConfiguration()
{
_Asyndeta.readKitenConfiguration();
_ResultView->updateFont();
}
void TopLevel::slotConfigure()
{
if (ConfigureDialog::showDialog("settings"))
return;
//ConfigureDialog didn't find an instance of this dialog, so lets create it :
optionDialog = new ConfigureDialog(this, "settings");
connect(optionDialog, TQT_SIGNAL(hidden()),this,TQT_SLOT(slotConfigureHide()));
connect(optionDialog, TQT_SIGNAL(settingsChanged()), TQT_TQOBJECT(this), TQT_SLOT(slotConfigurationChanged()));
connect(optionDialog, TQT_SIGNAL(valueChanged()), TQT_TQOBJECT(this), TQT_SIGNAL(quizConfChanged()));
optionDialog->show();
return;
}
void TopLevel::slotLearnConfigure()
{
slotConfigure();
optionDialog->showPage(2);
}
void TopLevel::slotConfigureHide()
{
TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotConfigureDestroy()));
}
void TopLevel::slotConfigureDestroy()
{
if (optionDialog != 0 && optionDialog->isVisible() == 0)
{
delete optionDialog;
optionDialog = 0;
}
}
void TopLevel::createLearn()
{
Learn *_Learn = new Learn(_Asyndeta.retrieveIndex(), 0);
connect(_Learn, TQT_SIGNAL(destroyed(Learn *)), TQT_TQOBJECT(this), TQT_SLOT(learnDestroyed(Learn *)));
connect(_Learn, TQT_SIGNAL(linkClicked(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(ressearch(const TQString &)));
connect(_Learn, TQT_SIGNAL(configureLearn()), TQT_TQOBJECT(this), TQT_SLOT(slotLearnConfigure()));
connect(this, TQT_SIGNAL(quizConfChanged()), _Learn, TQT_SLOT(updateQuizConfiguration()));
connect(this, TQT_SIGNAL(add(Dict::Entry)), _Learn, TQT_SLOT(add(Dict::Entry)));
learnList.append(_Learn);
_Learn->show();
}
void TopLevel::learnDestroyed(Learn *learn)
{
learnList.remove(learn);
}
void TopLevel::createEEdit()
{
eEdit *_eEdit = new eEdit(_Asyndeta.personalDictionaryLocation(), this);
_eEdit->show();
}
void TopLevel::kanjiDictChange()
{
// Do we even *need* something here?
}
TQRegExp TopLevel::readingSearchItems(bool kanji)
{
TQString text = Edit->text();
if (text.isEmpty()) // abandon search
return TQRegExp(); //empty
//CompletionObj->addItem(text);
TQString regexp;
if (kanji)
regexp = " %1 ";
else
regexp = "\\[%1\\]";
regexp = regexp.tqarg(text);
return TQRegExp(regexp, Config::caseSensitive());
}
TQRegExp TopLevel::kanjiSearchItems(bool beginning)
{
TQString text = Edit->text();
if (text.isEmpty())
return TQRegExp(); //empty
TQString regexp;
if (beginning)
regexp = "^%1";
else
regexp = "^%1\\W";
regexp = regexp.tqarg(text);
return TQRegExp(regexp, Config::caseSensitive());
}
TQRegExp TopLevel::searchItems()
{
TQString regexp;
TQString text = Edit->text();
if (text.isEmpty())
return TQRegExp(); //empty
unsigned int tqcontains = text.tqcontains(TQRegExp("[A-Za-z0-9_:]"));
if (Config::wholeWord() && tqcontains == text.length())
regexp = "\\W%1\\W";
else
regexp = "%1";
regexp = regexp.tqarg(text);
return TQRegExp(regexp, Config::caseSensitive());
}
void TopLevel::toggleCom()
{
}
void TopLevel::configureToolBars()
{
saveMainWindowSettings(KGlobal::config(), "TopLevelWindow");
KEditToolbar dlg(actionCollection(), "kitenui.rc");
connect(&dlg, TQT_SIGNAL(newToolbarConfig()), TQT_SLOT(newToolBarConfig()));
dlg.exec();
}
void TopLevel::newToolBarConfig()
{
createGUI("kitenui.rc");
applyMainWindowSettings(KGlobal::config(), "TopLevelWindow");
}
RadWidget *TopLevel::radicalSearch()
{
RadWidget *rw = new RadWidget(&_Rad, 0, "rw");
connect(rw, TQT_SIGNAL(set(const TQStringList &, unsigned int, unsigned int)), TQT_TQOBJECT(this), TQT_SLOT(radSearch(const TQStringList &, unsigned int, unsigned int)));
rw->show();
return rw;
}
void TopLevel::radSearch(const TQStringList &_list, unsigned int strokes, unsigned int errorMargin)
{
//kdDebug() << "TopLevel::radSearch\n";
TQStringList list(_Rad.kanjiByRad(_list));
TQStringList::iterator it;
Dict::SearchResult hist;
hist.count = 0;
hist.outOf = 0;
hist.common = comCB->isChecked();
TQString prettyRadicalString;
bool already = false;
for (TQStringList::ConstIterator it = _list.begin(); it != _list.end(); ++it)
{
if (already)
prettyRadicalString.append(", ");
prettyRadicalString.append(*it);
already = true;
}
hist.text = i18n("Radical(s): %1").tqarg(prettyRadicalString);
if (strokes)
hist.list.append(Dict::Entry(i18n("Kanji with radical(s) %1 and %2 strokes").tqarg(prettyRadicalString).tqarg(strokes), true));
else
hist.list.append(Dict::Entry(i18n("Kanji with radical(s) %1").tqarg(prettyRadicalString), true));
TQString strokesString;
if (strokes)
{
strokesString = TQString::number(strokes);
for (unsigned i = 1; i <= errorMargin; ++i)
{
strokesString.append('|');
strokesString.prepend('|');
strokesString.append(TQString::number(strokes + i));
strokesString.prepend(TQString::number(strokes - i));
}
strokesString.append(')');
strokesString.prepend("(?:");
//kdDebug() << "strokesString is " << strokesString << endl;
}
for (it = list.begin(); it != list.end(); ++it)
{
Dict::SearchResult results = _Asyndeta.retrieveIndex()->searchKanji(TQRegExp(strokes? (TQString("S%1 ").tqarg(strokesString)) : (TQString("^") + (*it)) ), (*it), comCB->isChecked());
hist.outOf += results.outOf;
if (results.count < 1)
continue;
hist.list.append(Dict::firstEntry(results));
hist.results.append(Dict::firstEntryText(results));
hist.count += results.count;
}
addHistory(hist);
handleSearchResult(hist);
}
void TopLevel::back(void)
{
assert(currentResult != resultHistory.begin());
--currentResult;
--currentResultIndex;
enableHistoryButtons();
handleSearchResult(*currentResult);
historySpotChanged();
}
void TopLevel::forward(void)
{
assert(currentResult != resultHistory.end());
++currentResult;
++currentResultIndex;
enableHistoryButtons();
handleSearchResult(*currentResult);
historySpotChanged();
}
void TopLevel::goInHistory(int index)
{
currentResult = resultHistory.at(resultHistory.count() - historyAction->items().count() + index);
currentResultIndex = index;
enableHistoryButtons();
handleSearchResult(*currentResult);
historySpotChanged();
}
void TopLevel::historySpotChanged()
{
historyAction->setCurrentItem(currentResultIndex);
}
void TopLevel::addHistory(Dict::SearchResult result)
{
TQStringList newHistoryList = historyAction->items();
// remove from back till we hit currentResult
while (resultHistory.fromLast() != currentResult)
{
resultHistory.pop_back();
newHistoryList.pop_back();
}
resultHistory.append(result);
newHistoryList.append(result.text);
// make history menu a reasonable length
while (newHistoryList.count() > 20)
newHistoryList.pop_front();
historyAction->setItems(newHistoryList);
currentResult = resultHistory.end();
--currentResult;
currentResultIndex = resultHistory.count() - 1;
historySpotChanged();
enableHistoryButtons();
if (resultHistory.size() > 50)
resultHistory.pop_front();
}
void TopLevel::enableHistoryButtons()
{
backAction->setEnabled(currentResult != resultHistory.begin());
forwardAction->setEnabled(++currentResult != resultHistory.end());
--currentResult;
}
void TopLevel::print()
{
_ResultView->print((*currentResult).text);
}
void TopLevel::configureGlobalKeys()
{
KKeyDialog::configure(Accel, this);
}
#include "kiten.moc"