/** This file is part of Kiten, a KDE Japanese Reference Tool... Copyright (C) 2001 Jason Katz-Brown (C) 2005 Paul Temple 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kitenconfig.h" #include "dict.h" #include "kromajiedit.h" #include "widgets.h" ResultView::ResultView(bool showLinks, TQWidget *parent, const char *name) : KTextBrowser(parent, name) { setReadOnly(true); setLinkUnderline(false); basicMode = false; links = showLinks; // don't let ktextbrowser internally handle link clicks setNotifyClick(true); } void ResultView::addResult(Dict::Entry result, bool common) { if (result.dictName() != "__NOTSET") { addHeader((common? i18n("Common results from %1") : i18n("Results from %1")).arg(result.dictName()), 5); return; } if (result.header() != "__NOTSET") { addHeader(result.header()); return; } TQString html; if (result.kanaOnly()) html = TQString("

%1 ").arg(result.firstReading()); else html = TQString("

%1: %2 ").arg(putchars(result.kanji())).arg(result.firstReading()); TQStringList::Iterator it; TQStringList Meanings = result.meanings(); for (it = Meanings.begin(); it != Meanings.end(); ++it) { if ((*it).find("(P)") >= 0) { if (common) continue; else { html += TQString("") + i18n("Common") + TQString(" "); } } else { html += (*it); html += "; "; } } html += "

"; append(html); } void ResultView::addKanjiResult(Dict::Entry result, bool common, Radical rad) { if (result.dictName() != "__NOTSET") { addHeader((common? i18n("Common results from %1") : i18n("Results from %1")).arg(result.dictName()), 5); return; } if (result.header() != "__NOTSET") { addHeader(result.header()); return; } TQString html; html = TQString("

%1: %2 ").arg(putchars(result.kanji())); unsigned int freq = result.freq(); if (freq == 0) // does it have a frequency? html = html.arg(i18n("Rare")); else // this isn't a number of times, it's simply an index of // probability html = html.arg(i18n("Probability rank #%1").arg(freq)); html += "
"; TQStringList::Iterator it; TQStringList Readings = result.readings(); for (it = Readings.begin(); it != Readings.end(); ++it) { if ((*it) == "T1") { if (basicMode) break; html.truncate(html.length() - 2); // get rid of last , html += i18n("
In names: "); } else { if ((*it) == "T2") { if (basicMode) break; html.truncate(html.length() - 2); html += i18n("
As radical: "); } else { html += (*it); html += ", "; } } } html.truncate(html.length() - 2); html += "
"; TQStringList Meanings = result.meanings(); for (it = Meanings.begin(); it != Meanings.end(); ++it) { html += (*it); html += "; "; } html.truncate(html.length() - 2); html += "
"; html += i18n("Grade Level: %1. Strokes: %2."); switch (result.grade()) { case 0: html = html.arg(i18n("None")); break; case 8: html = html.arg(i18n("In Jouyou")); break; case 9: html = html.arg(i18n("In Jinmeiyou")); break; default: html = html.arg(result.grade()); } html = html.arg(result.strokes()); if (result.miscount() != 0) html.append(i18n(" Common Miscount: %1.").arg(result.miscount())); if (!!rad.radical()) html.append(i18n(" Largest radical: %1, with %2 strokes.").arg(TQString("%2").arg(rad.radical()).arg(rad.radical())).arg(rad.strokes())); html += "

"; append(html); } void ResultView::addHeader(const TQString &header, unsigned int degree) { append(TQString("%2").arg(degree).arg(header).arg(degree)); } TQString ResultView::putchars(const TQString &text) { if (!links) return text; unsigned int len = text.length(); TQString ret; for (unsigned i = 0; i < len; i++) { if (Dict::textType(TQString(text.at(i))) == Dict::Text_Kanji) ret.append(TQString("%1").arg(text.at(i)).arg(text.at(i))); else ret.append(text.at(i)); } return ret; } void ResultView::append(const TQString &text) { printText.append(text); } void ResultView::clear() { printText = ""; } void ResultView::flush() { setText(printText); setCursorPosition(0, 0); ensureCursorVisible(); } void ResultView::print(TQString title) { KPrinter printer; printer.setFullPage(true); if (printer.setup(this, i18n("Print Japanese Reference"))) { TQPainter p(&printer); TQPaintDeviceMetrics metrics(p.device()); int dpix = metrics.logicalDpiX(); int dpiy = metrics.logicalDpiY(); const int margin = 72; // pt TQRect body(dpix, dpiy, metrics.width() - margin * dpix / margin * 2, metrics.height() - margin * dpiy / margin * 2); TQSimpleRichText richText(title.isNull()? printText : i18n("

Search for \"%1\"

").arg(title) + printText, font(), context(), styleSheet(), mimeSourceFactory(), body.height(), TQt::black, false); richText.setWidth(&p, body.width()); TQRect view(body); int page = 1; TQColorGroup goodColorGroup = TQColorGroup(colorGroup()); goodColorGroup.setColor(TQColorGroup::Link, TQt::black); do { richText.draw(&p, body.left(), body.top(), view, goodColorGroup); view.moveBy(0, body.height()); p.translate(0, -body.height()); TQFont myFont(font()); myFont.setPointSize(9); p.setFont(myFont); TQString footer(TQString("%1 - Kiten").arg(TQString::number(page))); p.drawText(view.right() - p.fontMetrics().width(footer), view.bottom() + p.fontMetrics().ascent() + 5, footer); if (view.top() >= richText.height()) break; printer.newPage(); page++; kapp->processEvents(); } while (true); } } void ResultView::updateFont() { setFont(Config::self()->font()); } ///////////////////////////////////////////////////// // nice EDICT dictionary editor eEdit::eEdit(const TQString &_filename, TQWidget *parent, const char *name) : TDEMainWindow(parent, name) , filename(_filename) { List = new TDEListView(this); setCentralWidget(List); List->addColumn(i18n("Kanji")); List->addColumn(i18n("Reading")); List->addColumn(i18n("Meanings")); List->addColumn(i18n("Common")); List->setItemsRenameable(true); List->setRenameable(0); List->setRenameable(1); List->setRenameable(2); List->setRenameable(3); List->setAllColumnsShowFocus(true); List->setColumnWidthMode(0, TQListView::Maximum); List->setColumnWidthMode(1, TQListView::Maximum); List->setColumnWidthMode(2, TQListView::Maximum); List->setColumnWidthMode(3, TQListView::Maximum); List->setMultiSelection(true); List->setDragEnabled(true); saveAct = KStdAction::save(this, TQ_SLOT(save()), actionCollection()); removeAct = new TDEAction(i18n("&Delete"), "edit_remove", CTRL + Key_X, this, TQ_SLOT(del()), actionCollection(), "del"); (void) new TDEAction(i18n("&Disable Dictionary"), 0, this, TQ_SLOT(disable()), actionCollection(), "disable"); addAct = new TDEAction(i18n("&Add"), "edit_add", CTRL + Key_A, this, TQ_SLOT(add()), actionCollection(), "add"); (void) KStdAction::close(this, TQ_SLOT(close()), actionCollection()); createGUI("eeditui.rc"); //closeAction->plug(toolBar()); openFile(filename); isMod = false; } eEdit::~eEdit() { } void eEdit::add() { if (List) new TDEListViewItem(List); } void eEdit::openFile(const TQString &file) { TQFile f(file); if (!f.open(IO_ReadOnly)) return; TQTextStream t(&f); TQString s; while (!t.eof()) { s = t.readLine(); if (s.left(1) == "#" || s.isEmpty()) continue; Dict::Entry entry = Dict::parse(s); TQString meanings = Dict::prettyMeaning(entry.meanings()); bool common = meanings.find(TQString("(P)")) >= 0; meanings.replace(TQRegExp("; "), "/"); meanings.replace(TQRegExp("/\\(P\\)"), ""); new TQListViewItem(List, entry.kanji(), Dict::prettyKanjiReading(entry.readings()), meanings, common? i18n("yes") : i18n("no")); } } void eEdit::save() { TQFile f(filename); if (!f.open(IO_WriteOnly)) return; TQTextStream t(&f); t << "# Generated by Kiten's EDICT editor" << endl << "# http://katzbrown.com/kiten" << endl << endl; TQListViewItemIterator it(List); for (; it.current(); ++it) { TQString kanji = it.current()->text(0); TQString reading = it.current()->text(1); TQString text = kanji.isEmpty()? reading : kanji; TQString meanings = it.current()->text(2); if (meanings.right(1) != "/") meanings.append("/"); if (meanings.left(1) != "/") meanings.prepend("/"); TQString commonString = it.current()->text(3).lower(); bool common = (commonString == "true" || commonString == "yes" || commonString == "1" || commonString == "common"); text.append(" "); if (!kanji.isEmpty()) text.append(TQString("[%1] ").arg(reading)); text.append(meanings); if (common) text.append("(P)/"); t << text << endl; } f.flush(); // find the index generator executable TDEProcess proc; proc << TDEStandardDirs::findExe("kitengen") << filename << TDEGlobal::dirs()->saveLocation("data", "kiten/xjdx/", true) + TQFileInfo(filename).baseName() + ".xjdx"; // TODO: put up a status dialog and event loop instead of blocking proc.start(TDEProcess::Block, TDEProcess::NoCommunication); statusBar()->message(i18n("Saved")); isMod = false; } void eEdit::disable() { int result = KMessageBox::warningYesNo(this, i18n("Disabling your personal dictionary will delete its contents.\n\n(You can however always create your dictionary again.)"), TQString(), i18n("Disable"), KStdGuiItem::cancel(), "DisableAsk", true); if (result == KMessageBox::No) return; TQFile::remove(filename); delete this; } void eEdit::del() { TQPtrList selected = List->selectedItems(); assert(selected.count()); for(TQPtrListIterator i(selected); *i; ++i) delete *i; isMod = true; } ///////////////////////////////////////////////////// // sorta taken from konqy EditAction::EditAction(const TQString& text, int accel, const TQObject *receiver, const char *member, TQObject* parent, const char* name) : TDEAction(text, accel, parent, name) { m_receiver = receiver; m_member = member; } EditAction::~EditAction() { } int EditAction::plug( TQWidget *w, int index ) { // if ( !w->inherits( "TDEToolBar" ) ) // return -1; TDEToolBar *toolBar = (TDEToolBar *)w; int id = TDEAction::getToolButtonID(); KRomajiEdit *comboBox = new KRomajiEdit(toolBar, "search edit"); toolBar->insertWidget( id, 70, comboBox, index ); connect( comboBox, TQ_SIGNAL( returnPressed()), m_receiver, m_member ); addContainer(toolBar, id); connect( toolBar, TQ_SIGNAL( destroyed() ), this, TQ_SLOT( slotDestroyed() ) ); toolBar->setItemAutoSized( id, true ); m_combo = comboBox; emit plugged(); //TQWhatsThis::add( comboBox, whatsThis() ); return containerCount() - 1; } void EditAction::unplug( TQWidget *w ) { // if ( !w->inherits( "TDEToolBar" ) ) // return; TDEToolBar *toolBar = (TDEToolBar *)w; int idx = findContainer( w ); toolBar->removeItem( itemId( idx ) ); removeContainer( idx ); m_combo = 0L; } void EditAction::clear() { m_combo->clear(); m_combo->setFocus(); } void EditAction::insert(const TQString &text) { m_combo->insert(text); } void EditAction::setText(const TQString &text) { m_combo->setText(text); } TQGuardedPtr EditAction::editor() { return m_combo; } #include "widgets.moc"