moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kiten / widgets.cpp
blob591d38c53e0f65edcf373041e34b2ab7b4a7a412
1 /**
2 This file is part of Kiten, a KDE Japanese Reference Tool...
3 Copyright (C) 2001 Jason Katz-Brown <jason@katzbrown.com>
4 (C) 2005 Paul Temple <paul.temple@gmx.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA
20 **/
22 #include <kaction.h>
23 #include <kapplication.h>
24 #include <kconfig.h>
25 #include <klistview.h>
26 #include <klocale.h>
27 #include <kmessagebox.h>
28 #include <kprinter.h>
29 #include <kprocess.h>
30 #include <kstandarddirs.h>
31 #include <kstatusbar.h>
32 #include <qfileinfo.h>
33 #include <qpaintdevicemetrics.h>
34 #include <qpainter.h>
35 #include <qregexp.h>
36 #include <qsimplerichtext.h>
37 #include <qtextcodec.h>
39 #include <cassert>
41 #include "kitenconfig.h"
42 #include "dict.h"
43 #include "kromajiedit.h"
44 #include "widgets.h"
46 ResultView::ResultView(bool showLinks, QWidget *parent, const char *name)
47 : KTextBrowser(parent, name)
49 setReadOnly(true);
50 setLinkUnderline(false);
51 basicMode = false;
52 links = showLinks;
54 // don't let ktextbrowser internally handle link clicks
55 setNotifyClick(true);
58 void ResultView::addResult(Dict::Entry result, bool common)
60 if (result.dictName() != "__NOTSET")
62 addHeader((common? i18n("Common results from %1") : i18n("Results from %1")).arg(result.dictName()), 5);
63 return;
65 if (result.header() != "__NOTSET")
67 addHeader(result.header());
68 return;
71 QString html;
72 if (result.kanaOnly())
73 html = QString("<p><font size=\"+2\">%1</font> ").arg(result.firstReading());
74 else
75 html = QString("<p><font size=\"+2\">%1</font>: %2 ").arg(putchars(result.kanji())).arg(result.firstReading());
77 QStringList::Iterator it;
78 QStringList Meanings = result.meanings();
79 for (it = Meanings.begin(); it != Meanings.end(); ++it)
81 if ((*it).find("(P)") >= 0)
83 if (common)
84 continue;
85 else
87 html += QString("<strong>") + i18n("Common") + QString("</strong> ");
90 else
92 html += (*it);
93 html += "; ";
97 html += "</p>";
99 append(html);
102 void ResultView::addKanjiResult(Dict::Entry result, bool common, Radical rad)
104 if (result.dictName() != "__NOTSET")
106 addHeader((common? i18n("Common results from %1") : i18n("Results from %1")).arg(result.dictName()), 5);
107 return;
109 if (result.header() != "__NOTSET")
111 addHeader(result.header());
112 return;
115 QString html;
116 html = QString("<p><font size=\"+3\">%1</font>: %2 ").arg(putchars(result.kanji()));
118 unsigned int freq = result.freq();
119 if (freq == 0) // does it have a frequency?
120 html = html.arg(i18n("Rare"));
121 else
122 // this isn't a number of times, it's simply an index of
123 // probability
124 html = html.arg(i18n("Probability rank #%1").arg(freq));
126 html += "<br />";
128 QStringList::Iterator it;
129 QStringList Readings = result.readings();
130 for (it = Readings.begin(); it != Readings.end(); ++it)
132 if ((*it) == "T1")
134 if (basicMode)
135 break;
137 html.truncate(html.length() - 2); // get rid of last ,
138 html += i18n("<br />In names: ");
140 else
142 if ((*it) == "T2")
144 if (basicMode)
145 break;
147 html.truncate(html.length() - 2);
148 html += i18n("<br />As radical: ");
150 else
152 html += (*it);
153 html += ", ";
157 html.truncate(html.length() - 2);
159 html += "<br />";
161 QStringList Meanings = result.meanings();
162 for (it = Meanings.begin(); it != Meanings.end(); ++it)
164 html += (*it);
165 html += "; ";
167 html.truncate(html.length() - 2);
168 html += "<br />";
169 html += i18n("Grade Level: %1. Strokes: %2.");
171 switch (result.grade())
173 case 0:
174 html = html.arg(i18n("None"));
175 break;
176 case 8:
177 html = html.arg(i18n("In Jouyou"));
178 break;
179 case 9:
180 html = html.arg(i18n("In Jinmeiyou"));
181 break;
182 default:
183 html = html.arg(result.grade());
186 html = html.arg(result.strokes());
188 if (result.miscount() != 0)
189 html.append(i18n(" Common Miscount: %1.").arg(result.miscount()));
191 if (!!rad.radical())
192 html.append(i18n(" Largest radical: %1, with %2 strokes.").arg(QString("<a href=\"__radical:%1\">%2</a>").arg(rad.radical()).arg(rad.radical())).arg(rad.strokes()));
194 html += "</p>";
196 append(html);
199 void ResultView::addHeader(const QString &header, unsigned int degree)
201 append(QString("<h%1>%2</h%3>").arg(degree).arg(header).arg(degree));
204 QString ResultView::putchars(const QString &text)
206 if (!links)
207 return text;
209 unsigned int len = text.length();
210 QString ret;
212 for (unsigned i = 0; i < len; i++)
214 if (Dict::textType(QString(text.at(i))) == Dict::Text_Kanji)
215 ret.append(QString("<a href=\"%1\">%1</a>").arg(text.at(i)).arg(text.at(i)));
216 else
217 ret.append(text.at(i));
220 return ret;
223 void ResultView::append(const QString &text)
225 printText.append(text);
228 void ResultView::clear()
230 printText = "";
233 void ResultView::flush()
235 setText(printText);
236 setCursorPosition(0, 0);
237 ensureCursorVisible();
240 void ResultView::print(QString title)
242 KPrinter printer;
243 printer.setFullPage(true);
244 if (printer.setup(this, i18n("Print Japanese Reference")))
246 QPainter p(&printer);
247 QPaintDeviceMetrics metrics(p.device());
248 int dpix = metrics.logicalDpiX();
249 int dpiy = metrics.logicalDpiY();
250 const int margin = 72; // pt
252 QRect body(dpix, dpiy, metrics.width() - margin * dpix / margin * 2, metrics.height() - margin * dpiy / margin * 2);
254 QSimpleRichText richText(title.isNull()? printText : i18n("<h1>Search for \"%1\"</h1>").arg(title) + printText, font(), context(), styleSheet(), mimeSourceFactory(), body.height(), Qt::black, false);
255 richText.setWidth(&p, body.width());
256 QRect view(body);
257 int page = 1;
259 QColorGroup goodColorGroup = QColorGroup(colorGroup());
260 goodColorGroup.setColor(QColorGroup::Link, Qt::black);
264 richText.draw(&p, body.left(), body.top(), view, goodColorGroup);
265 view.moveBy(0, body.height());
266 p.translate(0, -body.height());
268 QFont myFont(font());
269 myFont.setPointSize(9);
270 p.setFont(myFont);
271 QString footer(QString("%1 - Kiten").arg(QString::number(page)));
272 p.drawText(view.right() - p.fontMetrics().width(footer), view.bottom() + p.fontMetrics().ascent() + 5, footer);
275 if (view.top() >= richText.height())
276 break;
278 printer.newPage();
279 page++;
281 kapp->processEvents();
283 while (true);
287 void ResultView::updateFont()
289 setFont(Config::self()->font());
292 /////////////////////////////////////////////////////
293 // nice EDICT dictionary editor
295 eEdit::eEdit(const QString &_filename, QWidget *parent, const char *name)
296 : KMainWindow(parent, name)
297 , filename(_filename)
299 List = new KListView(this);
300 setCentralWidget(List);
302 List->addColumn(i18n("Kanji"));
303 List->addColumn(i18n("Reading"));
304 List->addColumn(i18n("Meanings"));
305 List->addColumn(i18n("Common"));
306 List->setItemsRenameable(true);
307 List->setRenameable(0);
308 List->setRenameable(1);
309 List->setRenameable(2);
310 List->setRenameable(3);
312 List->setAllColumnsShowFocus(true);
313 List->setColumnWidthMode(0, QListView::Maximum);
314 List->setColumnWidthMode(1, QListView::Maximum);
315 List->setColumnWidthMode(2, QListView::Maximum);
316 List->setColumnWidthMode(3, QListView::Maximum);
317 List->setMultiSelection(true);
318 List->setDragEnabled(true);
320 saveAct = KStdAction::save(this, SLOT(save()), actionCollection());
321 removeAct = new KAction(i18n("&Delete"), "edit_remove", CTRL + Key_X, this, SLOT(del()), actionCollection(), "del");
322 (void) new KAction(i18n("&Disable Dictionary"), 0, this, SLOT(disable()), actionCollection(), "disable");
323 addAct = new KAction(i18n("&Add"), "edit_add", CTRL + Key_A, this, SLOT(add()), actionCollection(), "add");
324 (void) KStdAction::close(this, SLOT(close()), actionCollection());
326 createGUI("eeditui.rc");
327 //closeAction->plug(toolBar());
329 openFile(filename);
331 isMod = false;
334 eEdit::~eEdit()
338 void eEdit::add()
340 if (List)
341 new KListViewItem(List);
344 void eEdit::openFile(const QString &file)
346 QFile f(file);
347 if (!f.open(IO_ReadOnly))
348 return;
350 QTextStream t(&f);
351 QString s;
353 while (!t.eof())
355 s = t.readLine();
356 if (s.left(1) == "#" || s.isEmpty())
357 continue;
358 Dict::Entry entry = Dict::parse(s);
359 QString meanings = Dict::prettyMeaning(entry.meanings());
360 bool common = meanings.find(QString("(P)")) >= 0;
361 meanings.replace(QRegExp("; "), "/");
362 meanings.replace(QRegExp("/\\(P\\)"), "");
363 new QListViewItem(List, entry.kanji(), Dict::prettyKanjiReading(entry.readings()), meanings, common? i18n("yes") : i18n("no"));
367 void eEdit::save()
369 QFile f(filename);
370 if (!f.open(IO_WriteOnly))
371 return;
372 QTextStream t(&f);
374 t << "# Generated by Kiten's EDICT editor" << endl << "# http://katzbrown.com/kiten" << endl << endl;
376 QListViewItemIterator it(List);
377 for (; it.current(); ++it)
379 QString kanji = it.current()->text(0);
380 QString reading = it.current()->text(1);
381 QString text = kanji.isEmpty()? reading : kanji;
383 QString meanings = it.current()->text(2);
384 if (meanings.right(1) != "/")
385 meanings.append("/");
386 if (meanings.left(1) != "/")
387 meanings.prepend("/");
389 QString commonString = it.current()->text(3).lower();
390 bool common = (commonString == "true" || commonString == "yes" || commonString == "1" || commonString == "common");
392 text.append(" ");
393 if (!kanji.isEmpty())
394 text.append(QString("[%1] ").arg(reading));
395 text.append(meanings);
397 if (common)
398 text.append("(P)/");
400 t << text << endl;
403 f.flush();
405 // find the index generator executable
406 KProcess proc;
407 proc << KStandardDirs::findExe("kitengen") << filename << KGlobal::dirs()->saveLocation("data", "kiten/xjdx/", true) + QFileInfo(filename).baseName() + ".xjdx";
408 // TODO: put up a status dialog and event loop instead of blocking
409 proc.start(KProcess::Block, KProcess::NoCommunication);
411 statusBar()->message(i18n("Saved"));
412 isMod = false;
415 void eEdit::disable()
417 int result = KMessageBox::warningYesNo(this, i18n("Disabling your personal dictionary will delete its contents.\n\n(You can however always create your dictionary again.)"), QString::null, i18n("Disable"), KStdGuiItem::cancel(), "DisableAsk", true);
418 if (result == KMessageBox::No)
419 return;
421 QFile::remove(filename);
422 delete this;
425 void eEdit::del()
427 QPtrList<QListViewItem> selected = List->selectedItems();
428 assert(selected.count());
430 for(QPtrListIterator<QListViewItem> i(selected); *i; ++i)
431 delete *i;
433 isMod = true;
436 /////////////////////////////////////////////////////
437 // sorta taken from konqy
439 EditAction::EditAction(const QString& text, int accel, const QObject *receiver, const char *member, QObject* parent, const char* name)
440 : KAction(text, accel, parent, name)
442 m_receiver = receiver;
443 m_member = member;
446 EditAction::~EditAction()
450 int EditAction::plug( QWidget *w, int index )
452 // if ( !w->inherits( "KToolBar" ) )
453 // return -1;
455 KToolBar *toolBar = (KToolBar *)w;
457 int id = KAction::getToolButtonID();
459 KRomajiEdit *comboBox = new KRomajiEdit(toolBar, "search edit");
460 toolBar->insertWidget( id, 70, comboBox, index );
461 connect( comboBox, SIGNAL( returnPressed()), m_receiver, m_member );
463 addContainer(toolBar, id);
465 connect( toolBar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
467 toolBar->setItemAutoSized( id, true );
469 m_combo = comboBox;
471 emit plugged();
473 //QWhatsThis::add( comboBox, whatsThis() );
475 return containerCount() - 1;
478 void EditAction::unplug( QWidget *w )
480 // if ( !w->inherits( "KToolBar" ) )
481 // return;
483 KToolBar *toolBar = (KToolBar *)w;
485 int idx = findContainer( w );
487 toolBar->removeItem( itemId( idx ) );
489 removeContainer( idx );
490 m_combo = 0L;
493 void EditAction::clear()
495 m_combo->clear();
496 m_combo->setFocus();
499 void EditAction::insert(const QString &text)
501 m_combo->insert(text);
504 void EditAction::setText(const QString &text)
506 m_combo->setText(text);
509 QGuardedPtr<KLineEdit> EditAction::editor()
511 return m_combo;
514 #include "widgets.moc"