File indexing completed on 2024-04-21 03:41:59

0001 /*
0002     This file is part of Kiten, a KDE Japanese Reference Tool
0003     SPDX-FileCopyrightText: 2011 Daniel E. Moctezuma <democtezuma@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kanjibrowser.h"
0009 
0010 #include "ui_preferences.h"
0011 
0012 #include "DictKanjidic/dictfilekanjidic.h"
0013 #include "kanjibrowserconfig.h"
0014 #include "kanjibrowserview.h"
0015 #include "kitenmacros.h"
0016 
0017 #include <QStatusBar>
0018 
0019 #include <KActionCollection>
0020 #include <KConfigDialog>
0021 #include <KLocalizedString>
0022 #include <KStandardAction>
0023 
0024 using namespace Qt::StringLiterals;
0025 
0026 KanjiBrowser::KanjiBrowser()
0027     : KXmlGuiWindow()
0028     , _dictFileKanjidic(nullptr)
0029 {
0030     // Read the configuration file.
0031     _config = KanjiBrowserConfigSkeleton::self();
0032     _config->load();
0033 
0034     statusBar()->show();
0035 
0036     // Add some actions.
0037     KStandardAction::quit(this, SLOT(close()), actionCollection());
0038     KStandardAction::preferences(this, SLOT(showPreferences()), actionCollection());
0039 
0040     _view = new KanjiBrowserView(this->parentWidget());
0041     connect(_view, &KanjiBrowserView::statusBarChanged, this, &KanjiBrowser::changeStatusBar);
0042     // Load the necessary information and setup the view.
0043     loadKanji();
0044 
0045     setCentralWidget(_view);
0046     setObjectName(QStringLiteral("kanjibrowser"));
0047 
0048     setupGUI(Default, QStringLiteral("kanjibrowserui.rc"));
0049 }
0050 
0051 KanjiBrowser::~KanjiBrowser()
0052 {
0053     if (_dictFileKanjidic) {
0054         delete _dictFileKanjidic;
0055     }
0056 }
0057 
0058 void KanjiBrowser::changeStatusBar(const QString &text)
0059 {
0060     statusBar()->showMessage(text);
0061 }
0062 
0063 void KanjiBrowser::loadKanji()
0064 {
0065     if (_dictFileKanjidic) {
0066         return;
0067     }
0068 
0069     qDebug() << "Loading kanji...";
0070 
0071     QString dictionary = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kiten/kanjidic"));
0072     _dictFileKanjidic = new DictFileKanjidic();
0073     _dictFileKanjidic->loadSettings();
0074     _dictFileKanjidic->loadDictionary(dictionary, KANJIDIC);
0075 
0076     // Parse the contents of KANJIDIC that we need to create the view.
0077     // We need:
0078     //  - Kanji
0079     //  - Grade
0080     //  - Number of strokes
0081     QRegularExpression gradeMatch(QStringLiteral("^G\\d+"));
0082     QRegularExpression strokeMatch(QStringLiteral("^S\\d+"));
0083     QList<int> gradeList;
0084     QList<int> strokeList;
0085     QHash<QString, QPair<int, int>> kanjiList;
0086     for (const QString &line : _dictFileKanjidic->dumpDictionary()) {
0087         // All the kanji without grade will have Grade 0, making easy to
0088         // manage that information in KanjiBrowserView.
0089         int grade = 0;
0090         int strokes = 0;
0091         QStringList gradeSection = line.split(' '_L1, Qt::SkipEmptyParts).filter(gradeMatch);
0092         QStringList strokesSection = line.split(' '_L1, Qt::SkipEmptyParts).filter(strokeMatch);
0093 
0094         // There are some kanji without grade (example: those not in Jouyou list).
0095         if (!gradeSection.isEmpty()) {
0096             // In KANJIDIC the grade/stroke section is: G# (for grade)
0097             //                                          S# (for strokes)
0098             // where # can be one or more digits.
0099             // We remove the first character and convert the remaining ones to int.
0100             grade = gradeSection.first().remove(0, 1).toInt();
0101             gradeList << grade;
0102         }
0103 
0104         strokes = strokesSection.first().remove(0, 1).toInt();
0105         strokeList << strokes;
0106 
0107         // Insert the extracted information into our QHash.
0108         kanjiList.insert(line[0], qMakePair(grade, strokes));
0109     }
0110 
0111     // This conversion from QList to QSet to QList, is to remove duplicated items.
0112     std::sort(gradeList.begin(), gradeList.end());
0113     gradeList.erase(std::unique(gradeList.begin(), gradeList.end()), gradeList.end());
0114 
0115     std::sort(strokeList.begin(), strokeList.end());
0116     strokeList.erase(std::unique(strokeList.begin(), strokeList.end()), strokeList.end());
0117     qDebug() << "Max. grade:" << gradeList.last();
0118     qDebug() << "Max. stroke count:" << strokeList.last();
0119 
0120     // Finally setup the view.
0121     _view->setupView(this, kanjiList, gradeList, strokeList);
0122 }
0123 
0124 void KanjiBrowser::showPreferences()
0125 {
0126     if (KConfigDialog::showDialog(QStringLiteral("settings"))) {
0127         return;
0128     }
0129 
0130     auto preferences = new QWidget();
0131     Ui::preferences layout;
0132     layout.setupUi(preferences);
0133 
0134     KConfigDialog *dialog = new KConfigDialog(this, QStringLiteral("settings"), KanjiBrowserConfigSkeleton::self());
0135     dialog->setFaceType(KPageDialog::FaceType::Plain);
0136     dialog->addPage(preferences, QString(), QStringLiteral("help-contents"));
0137     connect(dialog, &KConfigDialog::settingsChanged, _view, &KanjiBrowserView::loadSettings);
0138     dialog->show();
0139 }
0140 
0141 #include "moc_kanjibrowser.cpp"