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
23 #include <kapplication.h>
25 #include <klistview.h>
27 #include <kmessagebox.h>
30 #include <kstandarddirs.h>
31 #include <kstatusbar.h>
32 #include <qfileinfo.h>
33 #include <qpaintdevicemetrics.h>
36 #include <qsimplerichtext.h>
37 #include <qtextcodec.h>
41 #include "kitenconfig.h"
43 #include "kromajiedit.h"
46 ResultView::ResultView(bool showLinks
, QWidget
*parent
, const char *name
)
47 : KTextBrowser(parent
, name
)
50 setLinkUnderline(false);
54 // don't let ktextbrowser internally handle link clicks
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);
65 if (result
.header() != "__NOTSET")
67 addHeader(result
.header());
72 if (result
.kanaOnly())
73 html
= QString("<p><font size=\"+2\">%1</font> ").arg(result
.firstReading());
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)
87 html
+= QString("<strong>") + i18n("Common") + QString("</strong> ");
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);
109 if (result
.header() != "__NOTSET")
111 addHeader(result
.header());
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"));
122 // this isn't a number of times, it's simply an index of
124 html
= html
.arg(i18n("Probability rank #%1").arg(freq
));
128 QStringList::Iterator it
;
129 QStringList Readings
= result
.readings();
130 for (it
= Readings
.begin(); it
!= Readings
.end(); ++it
)
137 html
.truncate(html
.length() - 2); // get rid of last ,
138 html
+= i18n("<br />In names: ");
147 html
.truncate(html
.length() - 2);
148 html
+= i18n("<br />As radical: ");
157 html
.truncate(html
.length() - 2);
161 QStringList Meanings
= result
.meanings();
162 for (it
= Meanings
.begin(); it
!= Meanings
.end(); ++it
)
167 html
.truncate(html
.length() - 2);
169 html
+= i18n("Grade Level: %1. Strokes: %2.");
171 switch (result
.grade())
174 html
= html
.arg(i18n("None"));
177 html
= html
.arg(i18n("In Jouyou"));
180 html
= html
.arg(i18n("In Jinmeiyou"));
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()));
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()));
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
)
209 unsigned int len
= text
.length();
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
)));
217 ret
.append(text
.at(i
));
223 void ResultView::append(const QString
&text
)
225 printText
.append(text
);
228 void ResultView::clear()
233 void ResultView::flush()
236 setCursorPosition(0, 0);
237 ensureCursorVisible();
240 void ResultView::print(QString title
)
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());
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);
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())
281 kapp
->processEvents();
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());
341 new KListViewItem(List
);
344 void eEdit::openFile(const QString
&file
)
347 if (!f
.open(IO_ReadOnly
))
356 if (s
.left(1) == "#" || s
.isEmpty())
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"));
370 if (!f
.open(IO_WriteOnly
))
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");
393 if (!kanji
.isEmpty())
394 text
.append(QString("[%1] ").arg(reading
));
395 text
.append(meanings
);
405 // find the index generator executable
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"));
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
)
421 QFile::remove(filename
);
427 QPtrList
<QListViewItem
> selected
= List
->selectedItems();
428 assert(selected
.count());
430 for(QPtrListIterator
<QListViewItem
> i(selected
); *i
; ++i
)
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
;
446 EditAction::~EditAction()
450 int EditAction::plug( QWidget
*w
, int index
)
452 // if ( !w->inherits( "KToolBar" ) )
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 );
473 //QWhatsThis::add( comboBox, whatsThis() );
475 return containerCount() - 1;
478 void EditAction::unplug( QWidget
*w
)
480 // if ( !w->inherits( "KToolBar" ) )
483 KToolBar
*toolBar
= (KToolBar
*)w
;
485 int idx
= findContainer( w
);
487 toolBar
->removeItem( itemId( idx
) );
489 removeContainer( idx
);
493 void EditAction::clear()
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()
514 #include "widgets.moc"