diff --git a/phrasebook/phrasebook.cpp b/phrasebook/phrasebook.cpp index ffe343f..4979548 100644 --- a/phrasebook/phrasebook.cpp +++ b/phrasebook/phrasebook.cpp @@ -1,512 +1,512 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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 "phrasebook.h" #include "phrasebookparser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Phrase::Phrase() { this->phrase.clear(); this->shortcut.clear(); } Phrase::Phrase(const QString &phrase) { this->phrase = phrase; this->shortcut.clear(); } Phrase::Phrase(const QString &phrase, const QString &shortcut) { this->phrase = phrase; this->shortcut = shortcut; } QString Phrase::getPhrase() const { return phrase; } QString Phrase::getShortcut() const { return shortcut; } void Phrase::setPhrase(const QString &phrase) { this->phrase = phrase; } void Phrase::setShortcut(const QString &shortcut) { this->shortcut = shortcut; } // *************************************************************************** PhraseBookEntry::PhraseBookEntry() { phrase = Phrase(); level = 1; isPhraseValue = false; } -PhraseBookEntry::PhraseBookEntry(Phrase phrase, int level, bool isPhrase) +PhraseBookEntry::PhraseBookEntry(const Phrase &phrase, int level, bool isPhrase) { this->phrase = phrase; this->level = level; isPhraseValue = isPhrase; } bool PhraseBookEntry::isPhrase() const { return isPhraseValue; } Phrase PhraseBookEntry::getPhrase() const { return phrase; } int PhraseBookEntry::getLevel() const { return level; } // *************************************************************************** void PhraseBook::print(QPrinter *pPrinter) { QPainter printpainter; printpainter.begin(pPrinter); QRect size = printpainter.viewport(); int x = size.x(); int y = size.y(); int w = size.width(); printpainter.setFont(QFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family(), 12)); QFontMetrics metrics = printpainter.fontMetrics(); PhraseBookEntryList::iterator it; for (it = begin(); it != end(); ++it) { QRect rect = metrics.boundingRect(x + 16 * (*it).getLevel(), y, w - 16 * (*it).getLevel(), 0, Qt::AlignJustify | Qt::TextWordWrap, (*it).getPhrase().getPhrase()); if (y + rect.height() > size.height()) { pPrinter->newPage(); y = 0; } printpainter.drawText(x + 16 * (*it).getLevel(), y, w - 16 * (*it).getLevel(), rect.height(), Qt::AlignJustify | Qt::TextWordWrap, (*it).getPhrase().getPhrase()); y += rect.height(); } printpainter.end(); } bool PhraseBook::decode(const QString &xml) { QXmlInputSource source; source.setData(xml); return decode(source); } bool PhraseBook::decode(QXmlInputSource &source) { PhraseBookParser parser; QXmlSimpleReader reader; reader.setFeature(QStringLiteral("http://trolltech.com/xml/features/report-start-end-entity"), true); reader.setContentHandler(&parser); if (reader.parse(source)) { PhraseBookEntryList::clear(); *(PhraseBookEntryList *)this += parser.getPhraseList(); return true; } else return false; } -QByteArray encodeString(const QString str) +QByteArray encodeString(const QString &str) { QByteArray res = ""; for (int i = 0; i < (int)str.length(); i++) { QChar ch = str.at(i); ushort uc = ch.unicode(); QByteArray number; number.setNum(uc); if ((uc > 127) || (uc < 32) || (ch == QLatin1Char('<')) || (ch == QLatin1Char('>')) || (ch == QLatin1Char('&')) || (ch == QLatin1Char(';'))) res = res + "&#" + number + ';'; else res = res + (char)uc; } return res; } QString PhraseBook::encode() { QString result; result = QStringLiteral("\n"); result += QLatin1String("\n"); result += QLatin1String("\n"); PhraseBookEntryList::iterator it; int level = 0; for (it = begin(); it != end(); ++it) { int newLevel = (*it).getLevel(); while (level < newLevel) { result += QLatin1String("\n"); level++; } while (level > newLevel) { result += QLatin1String("\n"); level--; } if ((*it).isPhrase()) { Phrase phrase = (*it).getPhrase(); result += QStringLiteral("") + QLatin1String(encodeString(phrase.getPhrase())) + QStringLiteral("\n"); } else { Phrase phrase = (*it).getPhrase(); result += QStringLiteral("\n"); level++; } } while (level > 0) { result += QLatin1String("\n"); level--; } result += QLatin1String(""); return result; } QStringList PhraseBook::toStringList() { QStringList result; PhraseBook::iterator it; for (it = begin(); it != end(); ++it) { if ((*it).isPhrase()) result += (*it).getPhrase().getPhrase(); } return result; } bool PhraseBook::save(const QUrl &url) { QRegExp pattern(QStringLiteral("*.phrasebook"), Qt::CaseSensitive, QRegExp::Wildcard); return save(url, pattern.exactMatch(url.fileName())); } void PhraseBook::save(QTextStream &stream, bool asPhrasebook) { if (asPhrasebook) stream << encode(); else stream << toStringList().join(QStringLiteral("\n")); } bool PhraseBook::save(const QUrl &url, bool asPhrasebook) { if (url.isLocalFile()) { QFile file(url.path()); if (!file.open(QIODevice::WriteOnly)) return false; QTextStream stream(&file); save(stream, asPhrasebook); file.close(); if (file.error() != QFile::NoError) return false; else return true; } else { QByteArray data; QTextStream ts(&data); save(ts, asPhrasebook); ts.flush(); KIO::StoredTransferJob *uploadJob = KIO::storedPut(data, url, -1); return uploadJob->exec(); } } int PhraseBook::save(QWidget *parent, const QString &title, QUrl &url, bool phrasebookFirst) { // KFileDialog::getSaveUrl(...) is not useful here as we need // to know the requested file type. QString filters; if (phrasebookFirst) filters = i18n("Phrase Books (*.phrasebook);;Plain Text Files (*.txt);;All Files (*)"); else filters = i18n("Plain Text Files (*.txt);;Phrase Books (*.phrasebook);;All Files (*)"); QFileDialog fdlg(parent, title, QString(), filters); fdlg.setAcceptMode(QFileDialog::AcceptSave); if (fdlg.exec() != QDialog::Accepted || fdlg.selectedUrls().size() < 1) { return 0; } url = fdlg.selectedUrls().at(0); if (url.isEmpty() || !url.isValid()) { return -1; } if (QFile::exists(url.toLocalFile())) { if (KMessageBox::warningContinueCancel(nullptr, QStringLiteral("%1").arg(i18n("The file %1 already exists. " "Do you want to overwrite it?", url.url())), i18n("File Exists"), KGuiItem(i18n("&Overwrite"))) == KMessageBox::Cancel) { return 0; } } bool result; if (fdlg.selectedNameFilter() == QLatin1String("*.phrasebook")) { if (url.fileName(nullptr).contains(QLatin1Char('.')) == 0) { url = url.adjusted(QUrl::RemoveFilename); url.setPath(url.path() + url.fileName(nullptr) + QStringLiteral(".phrasebook")); } else if (url.fileName(nullptr).rightRef(11).contains(QLatin1String(".phrasebook"), Qt::CaseInsensitive) == 0) { int filetype = KMessageBox::questionYesNoCancel(nullptr, QStringLiteral("%1").arg(i18n("Your chosen filename %1 has a different extension than .phrasebook. " "Do you wish to add .phrasebook to the filename?", url.fileName())), i18n("File Extension"), KGuiItem(i18n("Add")), KGuiItem(i18n("Do Not Add"))); if (filetype == KMessageBox::Cancel) { return 0; } if (filetype == KMessageBox::Yes) { url = url.adjusted(QUrl::RemoveFilename); url.setPath(url.path() + url.fileName(nullptr) + QStringLiteral(".phrasebook")); } } result = save(url, true); } else if (fdlg.selectedNameFilter() == QLatin1String("*.txt")) { if (url.fileName(nullptr).rightRef(11).contains(QLatin1String(".phrasebook"), Qt::CaseInsensitive) == 0) { result = save(url, false); } else { int filetype = KMessageBox::questionYesNoCancel(nullptr, QStringLiteral("%1").arg(i18n("Your chosen filename %1 has the extension .phrasebook. " "Do you wish to save in phrasebook format?", url.fileName())), i18n("File Extension"), KGuiItem(i18n("As Phrasebook")), KGuiItem(i18n("As Plain Text"))); if (filetype == KMessageBox::Cancel) { return 0; } if (filetype == KMessageBox::Yes) { result = save(url, true); } else { result = save(url, false); } } } else // file format "All files" requested, so decide by extension result = save(url); if (result) return 1; else return -1; } bool PhraseBook::open(const QUrl &url) { KIO::StoredTransferJob *downloadJob = KIO::storedGet(url); if (downloadJob->exec()) { // First: try to load it as a normal phrase book QBuffer fileBuffer; fileBuffer.setData(downloadJob->data()); QXmlInputSource source(&fileBuffer); bool error = !decode(source); // Second: if the file does not contain a phrase book, load it as // a plain text file if (error) { // Load each line of the plain text file as a new phrase QTextStream stream(&fileBuffer); while (!stream.atEnd()) { QString s = stream.readLine(); if (!(s.isNull() || s.isEmpty())) *this += PhraseBookEntry(Phrase(s, QLatin1String("")), 0, true); } error = false; } return !error; } return false; } StandardBookList PhraseBook::standardPhraseBooks() { // Get all the standard phrasebook filenames in bookPaths. QStringList bookPaths; const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("books"), QStandardPaths::LocateDirectory); Q_FOREACH (const QString &dir, dirs) { const QStringList locales = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); Q_FOREACH (const QString &locale, locales) { const QStringList fileNames = QDir(dir + QLatin1Char('/') + locale).entryList(QStringList() << QStringLiteral("*.phrasebook")); Q_FOREACH (const QString &file, fileNames) { bookPaths.append(dir + QLatin1Char('/') + locale + QLatin1Char('/') + file); } } } QStringList bookNames; QMap bookMap; QStringList::iterator it; // Iterate over all books creating a phrasebook for each, creating a StandardBook of each. for (it = bookPaths.begin(); it != bookPaths.end(); ++it) { PhraseBook pbook; // Open the phrasebook. if (pbook.open(QUrl::fromLocalFile(*it))) { StandardBook book; book.name = (*pbook.begin()).getPhrase().getPhrase(); book.path = displayPath(*it); book.filename = *it; bookNames += book.path + QLatin1Char('/') + book.name; bookMap [book.path + QLatin1Char('/') + book.name] = book; } } bookNames.sort(); StandardBookList result; for (it = bookNames.begin(); it != bookNames.end(); ++it) result += bookMap [*it]; return result; } -QString PhraseBook::displayPath(QString filename) +QString PhraseBook::displayPath(const QString &filename) { QFileInfo file(filename); QString path = file.path(); QString dispPath; int position = path.indexOf(QLatin1String("/kmouth/books/")) + QStringLiteral("/kmouth/books/").length(); while (path.length() > position) { file.setFile(path); KDesktopFile *dirDesc = new KDesktopFile(QStandardPaths::GenericDataLocation, path + QStringLiteral("/.directory")); QString name = dirDesc->readName(); delete dirDesc; if (name.isNull() || name.isEmpty()) dispPath += QLatin1Char('/') + file.fileName(); else dispPath += QLatin1Char('/') + name; path = file.path(); } return dispPath; } void PhraseBook::addToGUI(QMenu *popup, KToolBar *toolbar, KActionCollection *phrases, QObject *receiver, const char *slot) const { if ((popup != nullptr) || (toolbar != nullptr)) { QStack stack; QWidget *parent = popup; int level = 0; QList::ConstIterator it; for (it = begin(); it != end(); ++it) { int newLevel = (*it).getLevel(); while (newLevel > level) { KActionMenu *menu = phrases->add(QStringLiteral("phrasebook")); menu->setDelayed(false); if (parent == popup) toolbar->addAction(menu); if (parent != nullptr) { parent->addAction(menu); stack.push(parent); } parent = menu->menu(); level++; } while (newLevel < level && (parent != popup)) { parent = stack.pop(); level--; } if ((*it).isPhrase()) { Phrase phrase = (*it).getPhrase(); QAction *action = new PhraseAction(phrase.getPhrase(), phrase.getShortcut(), receiver, slot, phrases); if (parent == popup) toolbar->addAction(action); if (parent != nullptr) parent->addAction(action); } else { Phrase phrase = (*it).getPhrase(); KActionMenu *menu = phrases->add(QStringLiteral("phrasebook")); menu->setText(phrase.getPhrase()); menu->setDelayed(false); if (parent == popup) toolbar->addAction(menu); parent->addAction(menu); stack.push(parent); parent = menu->menu(); level++; } } } } void PhraseBook::insert(const QString &name, const PhraseBook &book) { *this += PhraseBookEntry(Phrase(name), 0, false); QList::ConstIterator it; for (it = book.begin(); it != book.end(); ++it) { *this += PhraseBookEntry((*it).getPhrase(), (*it).getLevel() + 1, (*it).isPhrase()); } } diff --git a/phrasebook/phrasebook.h b/phrasebook/phrasebook.h index aa56991..3b64242 100644 --- a/phrasebook/phrasebook.h +++ b/phrasebook/phrasebook.h @@ -1,198 +1,198 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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. * ***************************************************************************/ #ifndef PHRASEBOOK_H #define PHRASEBOOK_H #include #include #include #include #include #include #include #include #include class QUrl; struct StandardBook { QString name; QString path; QString filename; }; typedef QList StandardBookList; /** * The class Phrase represents one phrase in a phrase book. * @author Gunnar Schmi Dt */ class Phrase { friend class PhraseBookParser; public: Phrase(); Phrase(const QString &phrase); Phrase(const QString &phrase, const QString &shortcut); QString getPhrase() const; QString getShortcut() const; void setPhrase(const QString &phrase); void setShortcut(const QString &shortcut); private: QString phrase; QString shortcut; }; /** * The class PhraseBookEntry implements a phrase book entry. That can be either * a phrase or a start tag a sub phrase book. * @author Gunnar Schmi Dt */ class PhraseBookEntry { public: PhraseBookEntry(); - explicit PhraseBookEntry(Phrase phrase, int level = 1, bool isPhrase = true); + explicit PhraseBookEntry(const Phrase &phrase, int level = 1, bool isPhrase = true); ~PhraseBookEntry() {} void setPhrase(Phrase phrase, int level = 1, bool isPhrase = true); bool isPhrase() const; Phrase getPhrase() const; int getLevel() const; private: bool isPhraseValue; Phrase phrase; int level; }; typedef QList PhraseBookEntryList; /** * The class PhraseBook implements a phrase book. It mainly stores a * token list where each token is a phrase book entry (either a phrase * or a sub phrase book). The entries are placed into a tree structure * as follows: * * The level of each entry tells the level in the tree (level=0 is the top * level), each sub book in level i directly or indirectly contains all * following entries until an entry of level at most i or the end of the * token list. * * @author Gunnar Schmi Dt */ class PhraseBook : public PhraseBookEntryList { public: PhraseBook() : PhraseBookEntryList() {} ~PhraseBook() {} /** opens a file containing a phrase book. Returns true if successful. */ bool open(const QUrl &url); /** decodes a phrase book. Returns true if successful. */ bool decode(const QString &xml); /** decodes a phrase book. Returns true if successful. */ bool decode(QXmlInputSource &source); /** Writes the phrases to a file. Returns true if successful. */ bool save(const QUrl &url); /** Writes the phrases to a file. Returns true if successful. */ bool save(const QUrl &url, bool asPhrasebook); /** Writes the phrases to a QTextStream. */ void save(QTextStream &stream, bool asPhrasebook); /** Prints the phrases. */ void print(QPrinter *pPrinter); /** Shows a file selector and writes the phrases to a file. * @return 1, if the file got successfully written, * 0, if the user canceled the operation, * -1, if there was an error when saving the file. */ int save(QWidget *parent, const QString &title, QUrl &url, bool phrasebookFirst = true); /** encodes the phrase book. Returns the encoded xml code. */ QString encode(); /** Stores all entries in a QStringList. All hierarchy information and all * shortcuts are ignored during this operation. */ QStringList toStringList(); /** Adds the entries of the book to both the given popup menu and the given * toolbar. The corresponding actions will be inserted into phrases. */ void addToGUI(QMenu *popup, KToolBar *toolbar, KActionCollection *phrases, QObject *receiver, const char *slot) const; /** Inserts book into a new sub phrase book. * @param name the name of the new sub phrase book. * @param book the phrase book to insert. */ void insert(const QString &name, const PhraseBook &book); static StandardBookList standardPhraseBooks(); private: - static QString displayPath(QString path); + static QString displayPath(const QString &path); }; class PhraseAction : public QAction { Q_OBJECT public: PhraseAction(const QString& phrase, const QString& cut, const QObject* receiver, const char* slot, KActionCollection* parent) : QAction(QIcon::fromTheme(QStringLiteral("phrase")), phrase, parent) { this->setShortcut(cut); this->phrase = phrase; connect(this, &QAction::triggered, this, &PhraseAction::slotTriggered); connect(this, SIGNAL(slotActivated(const QString &)), receiver, slot); parent->addAction(phrase, this); } ~PhraseAction() { } public Q_SLOTS: void slotTriggered() { // trigger(); emit slotActivated(phrase); } Q_SIGNALS: void slotActivated(const QString &phrase); private: QString phrase; }; #endif diff --git a/phrasebook/phrasebookdialog.cpp b/phrasebook/phrasebookdialog.cpp index a2b7eef..3b5177e 100644 --- a/phrasebook/phrasebookdialog.cpp +++ b/phrasebook/phrasebookdialog.cpp @@ -1,704 +1,704 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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 "phrasebookdialog.h" // include files for Qt #include #include #include #include #include // include files for KDE #include #include #include #include #include "phrasebook.h" #include #include const int kTextColumn = 0; const int kShortcutColumn = 1; const QString kName = QStringLiteral("name"); const QString kShortcut = QStringLiteral("shortcut"); const QString kPhraseBook = QStringLiteral("phrasebook"); const QString kPhrase = QStringLiteral("phrase"); const QString kPhraseBookXML = QStringLiteral("\n%2\n"); const QString kPhraseXML = QStringLiteral("%1\n"); const QString kWholeBookXML = QStringLiteral("\n" "\n" "\n%1" ""); const QIcon kPhraseBookIcon = QIcon::fromTheme(kPhraseBook); const QIcon kPhraseIcon = QIcon::fromTheme(kPhrase); StandardPhraseBookInsertAction::StandardPhraseBookInsertAction(const QUrl &url, const QString& name, const QObject* receiver, const char* slot, KActionCollection* parent) : QAction(QIcon::fromTheme(QStringLiteral("phrasebook")), name, parent) { this->url = url; connect(this, SIGNAL(triggered(bool)), this, SLOT(slotActivated())); connect(this, SIGNAL(slotActivated(const QUrl &)), receiver, slot); parent->addAction(name, this); } StandardPhraseBookInsertAction::~StandardPhraseBookInsertAction() { } void StandardPhraseBookInsertAction::slotActivated() { emit slotActivated(url); } namespace PhraseBookPrivate { PhraseBookDialog *instance = nullptr; } PhraseBookDialog::PhraseBookDialog() : KXmlGuiWindow(nullptr) { // Create model with 2 columns and no rows m_bookModel = new QStandardItemModel(0, 2, this); m_rootItem = m_bookModel->invisibleRootItem(); m_bookModel->setHeaderData(kTextColumn, Qt::Horizontal, i18n("Phrase")); m_bookModel->setHeaderData(kShortcutColumn, Qt::Horizontal, i18n("Shortcut")); setObjectName(QStringLiteral("phraseEditDialog")); setWindowTitle(i18n("Phrase Book")); initGUI(); initActions(); initStandardPhraseBooks(); QString standardBook = QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("standard.phrasebook")); if (!standardBook.isNull() && !standardBook.isEmpty()) { QFile file(standardBook); file.open(QIODevice::ReadOnly); QDomDocument document; document.setContent(&file); const QDomNodeList nodes = document.documentElement().childNodes(); for (int i = 0; i < nodes.count(); ++i) { deserializeBook(nodes.at(i), m_rootItem); } selectionChanged(); phrasebookChanged = false; fileSave->setEnabled(false); } // Watch any changes in the model. connect(m_bookModel, &QAbstractItemModel::dataChanged, this, &PhraseBookDialog::slotModelChanged); connect(m_bookModel, &QAbstractItemModel::rowsInserted, this, &PhraseBookDialog::slotModelChanged); connect(m_bookModel, &QAbstractItemModel::rowsMoved, this, &PhraseBookDialog::slotModelChanged); connect(m_bookModel, &QAbstractItemModel::rowsRemoved, this, &PhraseBookDialog::slotModelChanged); //printer = 0; // i18n("Edit Phrase Book") } PhraseBookDialog *PhraseBookDialog::get() { if (PhraseBookPrivate::instance == nullptr) PhraseBookPrivate::instance = new PhraseBookDialog(); return PhraseBookPrivate::instance; } PhraseBookDialog::~PhraseBookDialog() { PhraseBookPrivate::instance = nullptr; //delete printer; } QStandardItem* PhraseBookDialog::deserializeBook(const QDomNode &node, QStandardItem *parent) { QString text; QString shortcut; bool isBook = (node.nodeName() == kPhraseBook); text = isBook ? node.attributes().namedItem(kName).nodeValue() : node.lastChild().nodeValue(); shortcut = isBook ? QString() : node.attributes().namedItem(kShortcut).nodeValue(); QStandardItem *item = isBook ? new QStandardItem(kPhraseBookIcon, text) : new QStandardItem(kPhraseIcon, text); QStandardItem *shortcutItem = new QStandardItem(shortcut); if (!isBook) { item->setDropEnabled(false); shortcutItem->setDropEnabled(false); } QList items; items << item << shortcutItem; if (parent) parent->appendRow(items); else m_bookModel->appendRow(items); if (isBook) { // Iterate over the document creating QStandardItems as needed const QDomNodeList childNodes = node.childNodes(); for (int i = 0; i < childNodes.count(); ++i) { const QDomNode child = childNodes.at(i); deserializeBook(child, item); } } return item; } QString PhraseBookDialog::serializeBook(const QModelIndex &index) { QString value; if (index.isValid()) { QStandardItem *item = m_bookModel->itemFromIndex(index); QStandardItem *shortcutItem = m_bookModel->itemFromIndex(index.sibling(index.row(), kShortcutColumn)); bool isBook = item->isDropEnabled(); // We know it's a book if it's drop enabled if (isBook) { QString childrenText; for (int i = 0; i < item->rowCount(); ++i) { childrenText += serializeBook(index.child(i, 0)); } value = kPhraseBookXML.arg(item->text()).arg(childrenText); } else { value = kPhraseXML.arg(item->text()).arg(shortcutItem->text()); } } else { // Do the whole model, inside a tag. int rows = m_bookModel->rowCount(QModelIndex()); QString childrenText; for (int i = 0; i < rows; ++i) { childrenText += serializeBook(m_bookModel->index(i, 0)); } value = kWholeBookXML.arg(childrenText); } return value; } void PhraseBookDialog::initGUI() { QWidget *page = new QWidget(this); m_ui = new Ui::PhraseBookDialog(); m_ui->setupUi(page); setCentralWidget(page); m_ui->treeView->setModel(m_bookModel); connect(m_ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PhraseBookDialog::selectionChanged); connect(m_ui->treeView, &QWidget::customContextMenuRequested, this, &PhraseBookDialog::contextMenuRequested); connectEditor(); } void PhraseBookDialog::slotModelChanged() { phrasebookChanged = true; fileSave->setEnabled(true); } void PhraseBookDialog::initActions() { // The file menu fileNewPhrase = actionCollection()->addAction(QStringLiteral("file_new_phrase")); fileNewPhrase->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); fileNewPhrase->setText(i18n("&New Phrase")); connect(fileNewPhrase, &QAction::triggered, this, &PhraseBookDialog::slotAddPhrase); fileNewPhrase->setToolTip(i18n("Adds a new phrase")); fileNewPhrase->setWhatsThis(i18n("Adds a new phrase")); fileNewBook = actionCollection()->addAction(QStringLiteral("file_new_book")); fileNewBook->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); fileNewBook->setText(i18n("New Phrase &Book")); connect(fileNewBook, &QAction::triggered, this, &PhraseBookDialog::slotAddPhrasebook); fileNewBook->setToolTip(i18n("Adds a new phrase book into which other books and phrases can be placed")); fileNewBook->setWhatsThis(i18n("Adds a new phrase book into which other books and phrases can be placed")); fileSave = KStandardAction::save(this, SLOT(slotSave()), actionCollection()); fileSave->setToolTip(i18n("Saves the phrase book onto the hard disk")); fileSave->setWhatsThis(i18n("Saves the phrase book onto the hard disk")); fileImport = actionCollection()->addAction(QStringLiteral("file_import")); fileImport->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); fileImport->setText(i18n("&Import...")); connect(fileImport, SIGNAL(triggered(bool)), this, SLOT(slotImportPhrasebook())); fileImport->setToolTip(i18n("Imports a file and adds its contents to the phrase book")); fileImport->setWhatsThis(i18n("Imports a file and adds its contents to the phrase book")); toolbarImport = new KToolBarPopupAction(QIcon::fromTheme(QStringLiteral("document-open")), i18n("&Import..."), this); actionCollection()->addAction(QStringLiteral("toolbar_import"), toolbarImport); connect(toolbarImport, SIGNAL(triggered(bool)), this, SLOT(slotImportPhrasebook())); toolbarImport->setToolTip(i18n("Imports a file and adds its contents to the phrase book")); toolbarImport->setWhatsThis(i18n("Imports a file and adds its contents to the phrase book")); fileImportStandardBook = actionCollection()->add(QStringLiteral("file_import_standard_book")); fileImportStandardBook->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); fileImportStandardBook->setText(i18n("I&mport Standard Phrase Book")); fileImportStandardBook->setToolTip(i18n("Imports a standard phrase book and adds its contents to the phrase book")); fileImportStandardBook->setWhatsThis(i18n("Imports a standard phrase book and adds its contents to the phrase book")); fileExport = actionCollection()->addAction(QStringLiteral("file_export")); fileExport->setIcon(QIcon::fromTheme(QStringLiteral("document-save"))); fileExport->setText(i18n("&Export...")); connect(fileExport, &QAction::triggered, this, &PhraseBookDialog::slotExportPhrasebook); fileExport->setToolTip(i18n("Exports the currently selected phrase(s) or phrase book(s) into a file")); fileExport->setWhatsThis(i18n("Exports the currently selected phrase(s) or phrase book(s) into a file")); //filePrint = KStandardAction::print(this, SLOT(slotPrint()), actionCollection()); //filePrint->setToolTip(i18n("Prints the currently selected phrase(s) or phrase book(s)")); //filePrint->setWhatsThis (i18n("Prints the currently selected phrase(s) or phrase book(s)")); fileClose = KStandardAction::close(this, SLOT(close()), actionCollection()); fileClose->setToolTip(i18n("Closes the window")); fileClose->setWhatsThis(i18n("Closes the window")); // The edit menu editCut = KStandardAction::cut(this, SLOT(slotCut()), actionCollection()); editCut->setToolTip(i18n("Cuts the currently selected entries from the phrase book and puts it to the clipboard")); editCut->setWhatsThis(i18n("Cuts the currently selected entries from the phrase book and puts it to the clipboard")); editCopy = KStandardAction::copy(this, SLOT(slotCopy()), actionCollection()); editCopy->setToolTip(i18n("Copies the currently selected entry from the phrase book to the clipboard")); editCopy->setWhatsThis(i18n("Copies the currently selected entry from the phrase book to the clipboard")); editPaste = KStandardAction::paste(this, SLOT(slotPaste()), actionCollection()); editPaste->setToolTip(i18n("Pastes the clipboard contents to current position")); editPaste->setWhatsThis(i18n("Pastes the clipboard contents at the current cursor position into the edit field.")); editDelete = actionCollection()->addAction(QStringLiteral("edit_delete")); editDelete->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); editDelete->setText(i18n("&Delete")); connect(editDelete, &QAction::triggered, this, &PhraseBookDialog::slotRemove); editDelete->setToolTip(i18n("Deletes the selected entries from the phrase book")); editDelete->setWhatsThis(i18n("Deletes the selected entries from the phrase book")); // use the absolute path to your kmouthui.rc file for testing purpose in createGUI(); createGUI(QStringLiteral("phrasebookdialogui.rc")); } void PhraseBookDialog::initStandardPhraseBooks() { StandardBookList bookPaths = PhraseBook::standardPhraseBooks(); KActionMenu *parent = fileImportStandardBook; QStringList currentNamePath; currentNamePath << QStringLiteral("x"); QStack stack; StandardBookList::iterator it; for (it = bookPaths.begin(); it != bookPaths.end(); ++it) { QUrl url = QUrl::fromLocalFile((*it).filename); QString namePath = QStringLiteral("x") + (*it).path; QStringList dirs = namePath.split(QLatin1Char('/')); QStringList::iterator it1 = currentNamePath.begin(); QStringList::iterator it2 = dirs.begin(); for (; (it1 != currentNamePath.end()) && (it2 != dirs.end()) && (*it1 == *it2); ++it1, ++it2); for (; it1 != currentNamePath.end(); ++it1) parent = stack.pop(); for (; it2 != dirs.end(); ++it2) { stack.push(parent); KActionMenu *newParent = actionCollection()->add(*it2); newParent->setText(*it2); parent->addAction(newParent); if (parent == fileImportStandardBook) toolbarImport->menu()->addAction(newParent); parent = newParent; } currentNamePath = dirs; QAction *book = new StandardPhraseBookInsertAction( url, (*it).name, this, SLOT(slotImportPhrasebook(QUrl)), actionCollection()); parent->addAction(book); if (parent == fileImportStandardBook) toolbarImport->menu()->addAction(book); } } void PhraseBookDialog::connectEditor() { connect(m_ui->lineEdit, &QLineEdit::textChanged, this, &PhraseBookDialog::slotTextChanged); connect(m_ui->noKey, &QAbstractButton::clicked, this, &PhraseBookDialog::slotNoKey); connect(m_ui->customKey, &QAbstractButton::clicked, this, &PhraseBookDialog::slotCustomKey); connect(m_ui->keyButton, &KKeySequenceWidget::keySequenceChanged, this, &PhraseBookDialog::slotKeySequenceChanged); } void PhraseBookDialog::disconnectEditor() { disconnect(m_ui->lineEdit, &QLineEdit::textChanged, this, &PhraseBookDialog::slotTextChanged); disconnect(m_ui->noKey, &QAbstractButton::clicked, this, &PhraseBookDialog::slotNoKey); disconnect(m_ui->customKey, &QAbstractButton::clicked, this, &PhraseBookDialog::slotCustomKey); disconnect(m_ui->keyButton, &KKeySequenceWidget::keySequenceChanged, this, &PhraseBookDialog::slotKeySequenceChanged); } void PhraseBookDialog::selectionChanged() { disconnectEditor(); bool modified = phrasebookChanged; QModelIndex selected = m_ui->treeView->selectionModel()->currentIndex(); QModelIndex shortcutIndex = selected.sibling(selected.row(), 1); QStandardItem *item = m_bookModel->itemFromIndex(selected); if (!m_ui->treeView->selectionModel()->hasSelection()) { m_ui->textLabel->setText(i18n("Text of the &phrase:")); m_ui->textLabel->setEnabled(false); m_ui->phrasebox->setEnabled(false); m_ui->lineEdit->setText(QLatin1String("")); m_ui->lineEdit->setEnabled(false); m_ui->shortcutLabel->setEnabled(false); m_ui->keyButton->clearKeySequence(); m_ui->keyButton->setEnabled(false); m_ui->noKey->setChecked(false); m_ui->noKey->setEnabled(false); m_ui->customKey->setChecked(false); m_ui->customKey->setEnabled(false); } else if (!item->isDropEnabled()) { // It's a phrase, since drop isn't enabled m_ui->textLabel->setText(i18n("Text of the &phrase:")); m_ui->textLabel->setEnabled(true); m_ui->phrasebox->setEnabled(true); m_ui->lineEdit->setText(m_bookModel->data(selected, Qt::DisplayRole).toString()); m_ui->lineEdit->setEnabled(true); m_ui->shortcutLabel->setEnabled(true); QString shortcut = m_bookModel->data(shortcutIndex, Qt::DisplayRole).toString(); m_ui->keyButton->setKeySequence(QKeySequence(shortcut)); if (shortcut.isEmpty() || shortcut.isNull()) { m_ui->noKey->setChecked(true); } else { m_ui->customKey->setChecked(true); } m_ui->keyButton->setEnabled(true); m_ui->noKey->setEnabled(true); m_ui->customKey->setEnabled(true); } else { // It's a book since drop is enabled m_ui->textLabel->setText(i18n("Name of the &phrase book:")); m_ui->textLabel->setEnabled(true); m_ui->phrasebox->setEnabled(true); m_ui->lineEdit->setText(m_bookModel->data(selected, Qt::DisplayRole).toString()); m_ui->lineEdit->setEnabled(true); m_ui->shortcutLabel->setEnabled(false); m_ui->keyButton->clearKeySequence(); // Can't have a shortcut for a book m_ui->keyButton->setEnabled(false); m_ui->noKey->setChecked(false); m_ui->noKey->setEnabled(false); m_ui->customKey->setChecked(false); m_ui->customKey->setEnabled(false); } connectEditor(); phrasebookChanged = modified; } bool PhraseBookDialog::queryClose() { if (phrasebookChanged) { int answer = KMessageBox::questionYesNoCancel(this, i18n("There are unsaved changes.
Do you want to apply the changes before closing the \"phrase book\" window or discard the changes?
"), i18n("Closing \"Phrase Book\" Window"), KStandardGuiItem::apply(), KStandardGuiItem::discard(), KStandardGuiItem::cancel(), QStringLiteral("AutomaticSave")); if (answer == KMessageBox::Yes) { slotSave(); return true; } return (answer == KMessageBox::No); } return true; } void PhraseBookDialog::slotTextChanged(const QString &s) { QModelIndex selected = m_ui->treeView->selectionModel()->currentIndex(); QModelIndex textIndex = selected.sibling(selected.row(), kTextColumn); if (textIndex.isValid()) { m_bookModel->setData(textIndex, s); } } void PhraseBookDialog::slotNoKey() { m_ui->noKey->setChecked(true); m_ui->customKey->setChecked(false); // This shouldn't be needed because of the groupbox... FIXME QModelIndex selected = m_ui->treeView->selectionModel()->currentIndex(); QModelIndex shortcutIndex = selected.sibling(selected.row(), kShortcutColumn); if (shortcutIndex.isValid()) m_bookModel->setData(shortcutIndex, QString()); m_ui->keyButton->clearKeySequence(); } void PhraseBookDialog::slotCustomKey() { m_ui->keyButton->captureKeySequence(); } void PhraseBookDialog::slotKeySequenceChanged(const QKeySequence& sequence) { if (sequence.isEmpty()) { slotNoKey(); } else setShortcut(sequence); } void PhraseBookDialog::setShortcut(const QKeySequence& sequence) { // Check whether the shortcut is valid // const QList cutList = cut.toList(); // for (int i = 0; i < cutList.count(); i++) { // const QKeySequence& seq = cutList[i]; // //const KKey& key = seq.key(0); //#ifdef __GNUC__ //#warning "kde 4 port it"; //#endif //#if 0 // if (key.modFlags() == 0 && key.sym() < 0x3000 // && QChar(key.sym()).isLetterOrNumber()) // { // QString s = i18n("In order to use the '%1' key as a shortcut, " // "it must be combined with the " // "Win, Alt, Ctrl, and/or Shift keys.", QChar(key.sym())); // KMessageBox::sorry( this, s, i18n("Invalid Shortcut Key") ); // return; // } //#endif // } QModelIndex selected = m_ui->treeView->selectionModel()->currentIndex(); QModelIndex shortcutIndex = selected.sibling(selected.row(), kShortcutColumn); if (shortcutIndex.isValid()) m_bookModel->setData(shortcutIndex, sequence.toString()); //// If key isn't already in use, // // Update display m_ui->noKey->setChecked(false); m_ui->customKey->setChecked(true); m_ui->keyButton->setKeySequence(sequence); } void PhraseBookDialog::contextMenuRequested(const QPoint &pos) { QString name; if (m_ui->treeView->selectionModel()->hasSelection()) name = QStringLiteral("phrasebook_popup_sel"); else name = QStringLiteral("phrasebook_popup_nosel"); QMenu *popup = (QMenu *)factory()->container(name, this); if (popup != nullptr) { popup->popup(m_ui->treeView->mapToGlobal(pos), nullptr); } } void PhraseBookDialog::slotRemove() { if (m_ui->treeView->selectionModel()->hasSelection()) { QList selected = m_ui->treeView->selectionModel()->selectedRows(); qSort(selected.begin(), selected.end()); // Iterate over the rows backwards so we don't modify the .row of any indexes in selected. for (int i = selected.size() - 1; i >= 0; --i) { QModelIndex index = selected.at(i); m_bookModel->removeRows(index.row(), 1, index.parent()); } } } void PhraseBookDialog::slotCut() { slotCopy(); slotRemove(); } void PhraseBookDialog::slotCopy() { QList selected = m_ui->treeView->selectionModel()->selectedRows(); QString xml; foreach (const QModelIndex index, selected) { xml += serializeBook(index); } QMimeData *data = new QMimeData(); data->setText(xml); QApplication::clipboard()->setMimeData(data); } void PhraseBookDialog::slotPaste() { const QMimeData *data = QApplication::clipboard()->mimeData(); QModelIndex index = m_ui->treeView->selectionModel()->currentIndex(); QStandardItem *item = m_bookModel->itemFromIndex(index); while (item != nullptr && !item->isDropEnabled()) item = item->parent(); QDomDocument document; document.setContent(data->text()); QDomNode node = document.documentElement(); deserializeBook(node, item); } QModelIndex PhraseBookDialog::getCurrentParent() { QModelIndex currentIndex = m_ui->treeView->currentIndex(); QStandardItem *item = m_bookModel->itemFromIndex(currentIndex); if (item != nullptr && !item->isDropEnabled()) // If it's not a book currentIndex = currentIndex.parent(); return currentIndex; } -void PhraseBookDialog::focusNewItem(QModelIndex parent, QStandardItem *item) +void PhraseBookDialog::focusNewItem(const QModelIndex &parent, QStandardItem *item) { m_ui->treeView->expand(parent); QModelIndex newIndex = m_bookModel->indexFromItem(item); m_ui->treeView->setCurrentIndex(newIndex); m_ui->lineEdit->selectAll(); m_ui->lineEdit->setFocus(); } void PhraseBookDialog::slotAddPhrasebook() { QModelIndex parentIndex = getCurrentParent(); QStandardItem *parent = m_bookModel->itemFromIndex(parentIndex); QStandardItem *item = new QStandardItem(kPhraseBookIcon, i18n("(New Phrase Book)")); QStandardItem *shortcutItem = new QStandardItem(); QList items; items << item << shortcutItem; if (parent) parent->appendRow(items); else m_bookModel->appendRow(items); focusNewItem(parentIndex, item); } void PhraseBookDialog::slotAddPhrase() { QModelIndex parentIndex = getCurrentParent(); QStandardItem *parent = m_bookModel->itemFromIndex(parentIndex); QStandardItem *item = new QStandardItem(kPhraseIcon, i18n("(New Phrase)")); QStandardItem *shortcutItem = new QStandardItem(); item->setDropEnabled(false); shortcutItem->setDropEnabled(false); QList items; items << item << shortcutItem; if (parent) parent->appendRow(items); else m_bookModel->appendRow(items); focusNewItem(parentIndex, item); } void PhraseBookDialog::slotSave() { QString standardBook = QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("standard.phrasebook")); if (!standardBook.isNull() && !standardBook.isEmpty()) { QFile file(standardBook); file.open(QIODevice::WriteOnly); file.write(serializeBook(QModelIndex()).toUtf8()); file.close(); emit phrasebookConfirmed(); phrasebookChanged = false; fileSave->setEnabled(false); } } void PhraseBookDialog::slotImportPhrasebook() { QUrl url = QFileDialog::getOpenFileUrl(this, i18n("Import Phrasebook"), QUrl(), i18n("Phrase Books (*.phrasebook);Plain Text Files (*.txt);All Files (*)")); slotImportPhrasebook(url); } void PhraseBookDialog::slotImportPhrasebook(const QUrl &url) { if (!url.isEmpty()) { QModelIndex parentIndex = getCurrentParent(); QStandardItem *parentItem = m_bookModel->itemFromIndex(parentIndex); QFile file(url.toLocalFile()); if (file.open(QIODevice::ReadOnly)) { QDomDocument document; document.setContent(&file); QDomNode node = document.documentElement(); QStandardItem *item = nullptr; if (node.hasAttributes()) { // It has attributes, so add it directly item = deserializeBook(node, parentItem); } else { // It has no attributes, so add all it's children QDomNodeList nodes = node.childNodes(); for (int i = 0; i < nodes.count(); ++i) { QDomNode child = nodes.at(i); item = deserializeBook(child, parentItem); } } focusNewItem(parentIndex, item); } else { qDebug() << "Unable to open file " << url.toLocalFile(); KMessageBox::sorry(this, i18n("There was an error loading file\n%1", url.toLocalFile())); } } } void PhraseBookDialog::slotExportPhrasebook() { // Get the current book or if a phrase is selected get it's parent book to export. QModelIndex parentIndex = getCurrentParent(); QString content = kWholeBookXML.arg(serializeBook(parentIndex)); QUrl url = QFileDialog::getSaveFileUrl(this, i18n("Export Phrase Book"), QUrl(), i18n("Phrase Books (*.phrasebook)")); QFile file(url.toLocalFile()); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&file); out << content; file.close(); } else { KMessageBox::sorry(this, i18n("There was an error saving file\n%1", url.toLocalFile())); } } //void PhraseBookDialog::slotPrint() //{ // if (printer == 0) { // printer = new QPrinter(); // } // QPrintDialog *printDialog = KdePrint::createPrintDialog(printer, this); // if (printDialog->exec()) { // PhraseBook book; // //treeView->fillBook (&book, treeView->hasSelectedItems()); // book.print(printer); // } // delete printDialog; //} diff --git a/phrasebook/phrasebookdialog.h b/phrasebook/phrasebookdialog.h index ef6fcc9..9e8e898 100644 --- a/phrasebook/phrasebookdialog.h +++ b/phrasebook/phrasebookdialog.h @@ -1,164 +1,164 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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. * ***************************************************************************/ #ifndef PHRASEBOOKDIALOG_H #define PHRASEBOOKDIALOG_H #include #include #include #include #include #include //#include "phrasebook.h" #include "ui_phrasebookdialog.h" class KActionMenu; class KToolBarPopupAction; /** * The class StandardPhraseBookInsertAction implements an Action for * inserting a standard phrase book. * @author Gunnar Schmi Dt */ class StandardPhraseBookInsertAction : public QAction { Q_OBJECT public: StandardPhraseBookInsertAction(const QUrl &url, const QString& name, const QObject* receiver, const char* slot, KActionCollection* parent); ~StandardPhraseBookInsertAction(); public Q_SLOTS: void slotActivated(); Q_SIGNALS: void slotActivated(const QUrl &url); private: QUrl url; }; /** * The class PhraseBookDialog implements a dialog for editing phrase books. * @author Gunnar Schmi Dt */ class PhraseBookDialog : public KXmlGuiWindow { friend class InitialPhraseBookWidget; Q_OBJECT private: /** Constructor. It is private because this class implements the singleton * pattern. For creating the instance of the dialog, use the get() method. */ PhraseBookDialog(); public: /** Returns a pointer to the instance of this dialog. As a part off the * singleton pattern it will make sure that there is at most one instance * of the dialog at a given time. */ static PhraseBookDialog *get(); /** Destructor. */ ~PhraseBookDialog(); bool queryClose() override; public Q_SLOTS: void slotTextChanged(const QString &s); void slotNoKey(); void slotCustomKey(); void slotKeySequenceChanged(const QKeySequence& sequence); void selectionChanged(); void contextMenuRequested(const QPoint &pos); void slotRemove(); void slotCut(); void slotCopy(); void slotPaste(); void slotAddPhrasebook(); void slotAddPhrase(); void slotSave(); void slotImportPhrasebook(); void slotImportPhrasebook(const QUrl &url); void slotExportPhrasebook(); //void slotPrint (); void slotModelChanged(); Q_SIGNALS: void phrasebookConfirmed(); private: void initGUI(); /** initializes the KActions of the window */ void initActions(); /** initializes the list of standard phrase books */ void initStandardPhraseBooks(); void connectEditor(); void disconnectEditor(); // Deserialize the book from the given QDomNode and under the given parent // Return the new QStandardItem so it can get focused. QStandardItem* deserializeBook(const QDomNode &node, QStandardItem *parent); // Return a serialized string of the book or phrase at the given index. QString serializeBook(const QModelIndex &index); // Get the current parent, if the current index is not a book, get it's parent. QModelIndex getCurrentParent(); // Expand to, select and focus a new item from the given parameters - void focusNewItem(QModelIndex parent, QStandardItem *item); + void focusNewItem(const QModelIndex &parent, QStandardItem *item); void setShortcut(const QKeySequence &sequence); bool phrasebookChanged; QAction* fileNewPhrase; QAction* fileNewBook; QAction* fileSave; QAction* fileImport; KToolBarPopupAction* toolbarImport; KActionMenu* fileImportStandardBook; QAction* fileExport; //QAction* filePrint; QAction* fileClose; QAction* editCut; QAction* editCopy; QAction* editPaste; QAction* editDelete; QStandardItemModel* m_bookModel; QStandardItem *m_rootItem; // Keep QPrinter so settings persist //QPrinter *printer; Ui::PhraseBookDialog *m_ui; }; #endif diff --git a/speech.cpp b/speech.cpp index 18fa029..a16bdc0 100644 --- a/speech.cpp +++ b/speech.cpp @@ -1,234 +1,234 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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 "speech.h" #include #include #include #include #include #define macroExpander #include Speech::Speech() { } Speech::~Speech() { } -QString Speech::prepareCommand(QString command, const QString &text, +QString Speech::prepareCommand(const QString &command, const QString &text, const QString &filename, const QString &language) { #ifdef macroExpander QHash map; map[QLatin1Char('t')] = text; map[QLatin1Char('f')] = filename; map[QLatin1Char('l')] = language; return KMacroExpander::expandMacrosShellQuote(command, map); #else QStack stack; // saved isdoublequote values during parsing of braces bool issinglequote = false; // inside '...' ? bool isdoublequote = false; // inside "..." ? int noreplace = 0; // nested braces when within ${...} QString escText = K3ShellProcess::quote(text); // character sequences that change the state or need to be otherwise processed QRegExp re_singlequote("('|%%|%t|%f|%l)"); QRegExp re_doublequote("(\"|\\\\|`|\\$\\(|\\$\\{|%%|%t|%f|%l)"); QRegExp re_noquote("('|\"|\\\\|`|\\$\\(|\\$\\{|\\(|\\{|\\)|\\}|%%|%t|%f|%l)"); // parse the command: for (int i = re_noquote.search(command); i != -1; i = (issinglequote ? re_singlequote.search(command, i) : isdoublequote ? re_doublequote.search(command, i) : re_noquote.search(command, i)) ) // while there are character sequences that need to be processed { if ((command[i] == '(') || (command[i] == '{')) { // (...) or {...} // assert(isdoublequote == false) stack.push(isdoublequote); if (noreplace > 0) // count nested braces when within ${...} noreplace++; i++; } else if (command[i] == '$') { // $(...) or ${...} stack.push(isdoublequote); isdoublequote = false; if ((noreplace > 0) || (command[i + 1] == '{')) // count nested braces when within ${...} noreplace++; i += 2; } else if ((command[i] == ')') || (command[i] == '}')) { // $(...) or (...) or ${...} or {...} if (!stack.isEmpty()) isdoublequote = stack.pop(); else qWarning("Parse error."); if (noreplace > 0) // count nested braces when within ${...} noreplace--; i++; } else if (command[i] == '\'') { issinglequote = !issinglequote; i++; } else if (command[i] == '"') { isdoublequote = !isdoublequote; i++; } else if (command[i] == '\\') i += 2; else if (command[i] == '`') { // Replace all `...` with safer $(...) command.replace(i, 1, "$("); QRegExp re_backticks("(`|\\\\`|\\\\\\\\|\\\\\\$)"); for (int i2 = re_backticks.search(command, i + 2); i2 != -1; i2 = re_backticks.search(command, i2) ) { if (command[i2] == '`') { command.replace(i2, 1, ")"); i2 = command.length(); // leave loop } else { // remove backslash and ignore following character command.remove(i2, 1); i2++; } } // Leave i unchanged! We need to process "$(" } else if (noreplace > 0) { // do not replace macros within ${...} if (issinglequote) i += re_singlequote.matchedLength(); else if (isdoublequote) i += re_doublequote.matchedLength(); else i += re_noquote.matchedLength(); } else { // replace macro QString match, v; // get match if (issinglequote) match = re_singlequote.cap(); else if (isdoublequote) match = re_doublequote.cap(); else match = re_noquote.cap(); // substitute %variables if (match == "%t") v = escText; else if (match == "%f") v = filename; else if (match == "%%") v = "%"; else if (match == "%l") v = language; // %variable inside of a quote? if (isdoublequote) v = '"' + v + '"'; else if (issinglequote) v = '\'' + v + '\''; command.replace(i, match.length(), v); i += v.length(); } } return command; #endif } void Speech::speak(QString command, bool stdIn, const QString &text, const QString &language, int encoding, QTextCodec *codec) { if (text.length() > 0) { // 1. prepare the text: // 1.a) encode the text QTextStream ts(&encText, QIODevice::WriteOnly); if (encoding == Local) ts.setCodec(QTextCodec::codecForLocale()); else if (encoding == Latin1) ts.setCodec("ISO-8859-1"); else if (encoding == Unicode) ts.setCodec("UTF-16"); else ts.setCodec(codec); ts << text; ts.flush(); // 1.b) create a temporary file for the text tempFile.open(); QTextStream fs(&tempFile); if (encoding == Local) fs.setCodec(QTextCodec::codecForLocale()); else if (encoding == Latin1) fs.setCodec("ISO-8859-1"); else if (encoding == Unicode) fs.setCodec("UTF-16"); else fs.setCodec(codec); fs << text; fs << endl; QString filename = tempFile.fileName(); tempFile.flush(); // 2. prepare the command: command = prepareCommand(command, QLatin1String(encText), filename, language); // 3. create a new process connect(&m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processExited(int, QProcess::ExitStatus))); //connect(&process, SIGNAL(wroteStdin(K3Process*)), this, SLOT(wroteStdin(K3Process*))); //connect(&process, SIGNAL(receivedStdout(K3Process*, char*, int)), this, SLOT(receivedStdout(K3Process*, char*, int))); //connect(&process, SIGNAL(receivedStderr(K3Process*, char*, int)), this, SLOT(receivedStderr(K3Process*, char*, int))); // 4. start the process if (stdIn) { m_process.start(command); if (encText.size() > 0) m_process.write(encText.constData(), encText.size()); else m_process.close(); } else m_process.start(command); } } //void Speech::receivedStdout(K3Process *, char *buffer, int buflen) //{ // kDebug() << QString::fromLatin1(buffer, buflen) + QLatin1Char('\n'); //} //void Speech::receivedStderr(K3Process *, char *buffer, int buflen) //{ // kDebug() << QString::fromLatin1(buffer, buflen) + QLatin1Char('\n'); //} //void Speech::wroteStdin(K3Process *) //{ // process.closeStdin(); //} void Speech::processExited(int exitCode, QProcess::ExitStatus exitStatus) { delete this; } diff --git a/speech.h b/speech.h index e5ee68f..6203fd8 100644 --- a/speech.h +++ b/speech.h @@ -1,75 +1,75 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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. * ***************************************************************************/ #ifndef SPEECH_H #define SPEECH_H #include #include #include /**This class is used internally by TextToSpeechSystem in order to do the actual speaking. *@author Gunnar Schmi Dt */ class Speech : public QObject { Q_OBJECT public: enum CharacterCodec { Local = 0, Latin1 = 1, Unicode = 2, UseCodec = 3 }; Speech(); ~Speech(); /** * Speaks the given text. * @param command the program that shall be executed for speaking * @param stdin true if the program shall receive its data via standard input * @param text The text that shall be spoken */ void speak(QString command, bool use_stdin, const QString &text, const QString &language, int encoding, QTextCodec *codec); /** * Prepares a command for being executed. During the preparation the * command is parsed and occurrences of "%t" are replaced by text. * @param command the command that shall be executed for speaking * @param text the quoted text that can be inserted into the command */ - QString prepareCommand(QString command, const QString &text, + QString prepareCommand(const QString &command, const QString &text, const QString &filename, const QString &language); public Q_SLOTS: //void wroteStdin(K3Process *p); void processExited(int exitCode, QProcess::ExitStatus exitStatus); //void receivedStdout(K3Process *proc, char *buffer, int buflen); //void receivedStderr(K3Process *proc, char *buffer, int buflen); private: QProcess m_process; QByteArray encText; QTemporaryFile tempFile; }; #endif diff --git a/wordcompletion/wordlist.cpp b/wordcompletion/wordlist.cpp index 498df04..510c1d4 100644 --- a/wordcompletion/wordlist.cpp +++ b/wordcompletion/wordlist.cpp @@ -1,571 +1,571 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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 "wordlist.h" #include #include #include #include #include #include #include #include #include #include #include #include #include namespace WordList { -void addWords(WordMap &map, QString line); +void addWords(WordMap &map, const QString &line); XMLParser::XMLParser() { } XMLParser::~XMLParser() { } bool XMLParser::warning(const QXmlParseException &) { return false; } bool XMLParser::error(const QXmlParseException &) { return false; } bool XMLParser::fatalError(const QXmlParseException &) { return false; } QString XMLParser::errorString() const { return QLatin1String(""); } bool XMLParser::startDocument() { text.clear(); return true; } bool XMLParser::startElement(const QString &, const QString &, const QString &, const QXmlAttributes &) { if (!text.isNull() && !text.isEmpty()) { addWords(list, text); text.clear(); } return true; } bool XMLParser::characters(const QString &ch) { text += ch; return true; } bool XMLParser::ignorableWhitespace(const QString &) { if (!text.isNull() && !text.isEmpty()) { addWords(list, text); text.clear(); } return true; } bool XMLParser::endElement(const QString &, const QString &, const QString &) { if (!text.isNull() && !text.isEmpty()) { addWords(list, text); text.clear(); } return true; } bool XMLParser::endDocument() { if (!text.isNull() && !text.isEmpty()) { addWords(list, text); text.clear(); } return true; } WordMap XMLParser::getList() { return list; } /***************************************************************************/ QProgressDialog *progressDialog() { QProgressDialog *pdlg = new QProgressDialog(i18n("Creating Word List"), i18n("Parsing the KDE documentation..."), 0, 100); pdlg->setCancelButton(nullptr); pdlg->setAutoReset(false); pdlg->setAutoClose(false); return pdlg; } -bool saveWordList(WordMap map, QString filename) +bool saveWordList(const WordMap &map, const QString &filename) { QFile file(filename); if (!file.open(QIODevice::WriteOnly)) return false; QTextStream stream(&file); stream.setCodec("UTF-8"); stream << "WPDictFile\n"; WordMap::ConstIterator it; for (it = map.constBegin(); it != map.constEnd(); ++it) stream << it.key() << "\t" << it.value() << "\t2\n"; file.close(); return true; } /***************************************************************************/ -void addWords(WordMap &map, QString line) +void addWords(WordMap &map, const QString &line) { const QStringList words = line.split(QRegExp(QStringLiteral("\\W"))); QStringList::ConstIterator it; for (it = words.constBegin(); it != words.constEnd(); ++it) { if (!(*it).contains(QRegExp(QStringLiteral("\\d|_")))) { QString key = (*it).toLower(); if (map.contains(key)) map[key] += 1; else map[key] = 1; } } } -void addWords(WordMap &map, WordMap add) +void addWords(WordMap &map, const WordMap &add) { WordList::WordMap::ConstIterator it; for (it = add.constBegin(); it != add.constEnd(); ++it) if (map.contains(it.key())) map[it.key()] += it.value(); else map[it.key()] = it.value(); } -void addWordsFromFile(WordMap &map, QString filename, QTextCodec *codec) +void addWordsFromFile(WordMap &map, const QString &filename, QTextCodec *codec) { QFile xmlfile(filename); QXmlInputSource source(&xmlfile); XMLParser parser; QXmlSimpleReader reader; reader.setFeature(QStringLiteral("http://trolltech.com/xml/features/report-start-end-entity"), true); reader.setContentHandler(&parser); WordMap words; if (reader.parse(source)) // try to load the file as an xml-file addWords(map, parser.getList()); else { QFile wpdfile(filename); if (wpdfile.open(QIODevice::ReadOnly)) { QTextStream stream(&wpdfile); stream.setCodec("UTF-8"); if (!stream.atEnd()) { QString s = stream.readLine(); if (s == QLatin1String("WPDictFile")) { // Contains the file a weighted word list? // We can assume that weighted word lists are always UTF8 coded. while (!stream.atEnd()) { QString s = stream.readLine(); if (!(s.isNull() || s.isEmpty())) { QStringList list = s.split(QLatin1Char('\t')); bool ok; int weight = list[1].toInt(&ok); if (ok && (weight > 0)) { if (map.contains(list[0])) map[list[0]] += weight; else map[list[0]] = weight; } } } } else { // Count the words in an ordinary text file QFile file(filename); if (file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); Q_ASSERT(codec != nullptr); stream.setCodec(codec); while (!stream.atEnd()) addWords(map, stream.readLine()); } } } } } } -WordMap parseFiles(QStringList files, QTextCodec *codec, QProgressDialog *pdlg) +WordMap parseFiles(const QStringList &files, QTextCodec *codec, QProgressDialog *pdlg) { int progress = 0; int steps = files.count(); int percent = 0; WordMap map; QStringList::ConstIterator it; for (progress = 1, it = files.constBegin(); it != files.constEnd(); ++progress, ++it) { addWordsFromFile(map, *it, codec); if (steps != 0 && progress * 100 / steps > percent) { percent = progress * 100 / steps; pdlg->setValue(percent); qApp->processEvents(QEventLoop::AllEvents, 20); } } return map; } -WordMap mergeFiles(QMap files, QProgressDialog *pdlg) +WordMap mergeFiles(const QMap &files, QProgressDialog *pdlg) { pdlg->setLabelText(i18n("Merging dictionaries...")); pdlg->show(); qApp->processEvents(QEventLoop::AllEvents, 20); int progress = 0; int steps = files.count(); int percent = 0; float totalWeight = 0; long long maxWeight = 0; QMap map; QMap::ConstIterator it; for (progress = 1, it = files.constBegin(); it != files.constEnd(); ++progress, ++it) { WordMap fileMap; addWordsFromFile(fileMap, it.key(), QTextCodec::codecForName("UTF-8")); long long weight = 0; WordMap::ConstIterator iter; for (iter = fileMap.constBegin(); iter != fileMap.constEnd(); ++iter) weight += iter.value(); float factor = 1.0 * it.value() / weight; totalWeight += it.value(); if (weight > maxWeight) maxWeight = weight; for (iter = fileMap.constBegin(); iter != fileMap.constEnd(); ++iter) if (map.contains(iter.key())) map[iter.key()] += iter.value() * factor; else map[iter.key()] = iter.value() * factor; if (steps != 0 && progress * 100 / steps > percent) { percent = progress * 100 / steps; pdlg->setValue(percent); qApp->processEvents(QEventLoop::AllEvents, 20); } } float factor; if (1.0 * maxWeight * totalWeight > 1000000000) factor = 1000000000 / totalWeight; else factor = 1.0 * maxWeight; WordMap resultMap; QMap::ConstIterator iter; for (iter = map.constBegin(); iter != map.constEnd(); ++iter) resultMap[iter.key()] = (int)(factor * iter.value() + 0.5); return resultMap; } WordMap parseKDEDoc(QString language, QProgressDialog *pdlg) { pdlg->setLabelText(i18n("Parsing the KDE documentation...")); pdlg->show(); qApp->processEvents(QEventLoop::AllEvents, 20); QStringList files = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("html/") + language + QStringLiteral("/*.docbook")); if ((files.count() == 0) && (language.length() == 5)) { language = language.left(2); files = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("html/") + language + QStringLiteral("/*.docbook")); } return parseFiles(files, QTextCodec::codecForName("UTF-8"), pdlg); } -WordMap parseFile(QString filename, QTextCodec *codec, QProgressDialog *pdlg) +WordMap parseFile(const QString &filename, QTextCodec *codec, QProgressDialog *pdlg) { pdlg->setLabelText(i18n("Parsing file...")); pdlg->show(); qApp->processEvents(QEventLoop::AllEvents, 20); QStringList files; files.append(filename); return parseFiles(files, codec, pdlg); } -WordMap parseDir(QString directory, QTextCodec *codec, QProgressDialog *pdlg) +WordMap parseDir(const QString &directory, QTextCodec *codec, QProgressDialog *pdlg) { pdlg->setLabelText(i18n("Parsing directory...")); pdlg->show(); qApp->processEvents(QEventLoop::AllEvents, 20); QStringList directories; directories += directory; QStringList files; int dirNdx = 0; while (dirNdx < directories.count()) { QDir dir(directories.at(dirNdx)); const QFileInfoList entries = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoSymLinks | QDir::Readable); for (int i = 0; i < entries.size(); ++i) { QFileInfo fileInfo = entries.at(i); QString name = fileInfo.fileName(); if (name != QLatin1String(".") && name != QLatin1String("..")) { if (fileInfo.isDir()) directories += fileInfo.filePath(); else files += fileInfo.filePath(); } } directories.removeAt(dirNdx); } return parseFiles(files, codec, pdlg); } /***************************************************************************/ /* Structures used for storing *.aff files (part of OpenOffice.org dictionaries) */ struct AffEntry { bool cross; int charsToRemove; QString add; QStringList condition; }; typedef QList AffList; typedef QMap AffMap; /** Loads an *.aff file (part of OpenOffice.org dictionaries) */ void loadAffFile(const QString &filename, AffMap &prefixes, AffMap &suffixes) { bool cross = false; QFile afile(filename); if (afile.open(QIODevice::ReadOnly)) { QTextStream stream(&afile); while (!stream.atEnd()) { QString s = stream.readLine(); QStringList fields = s.split(QRegExp(QStringLiteral("\\s"))); if (fields.count() == 4) { cross = (fields[2] == QLatin1String("Y")); } else { if (fields.count() >= 5) { AffEntry e; e.cross = cross; if (fields[2] == QLatin1String("0")) e.charsToRemove = 0; else e.charsToRemove = fields[2].length(); e.add = fields[3]; if (fields[4] != QLatin1String(".")) { QString condition = fields[4]; for (int idx = 0; idx < condition.length(); ++idx) { if (condition[idx] == QLatin1Char('[')) { QString code; for (++idx; (idx < condition.length()) && condition[idx] != QLatin1Char(']'); ++idx) code += condition[idx]; e.condition << code; } else e.condition << QString(condition[idx]); } } if (s.startsWith(QLatin1String("PFX"))) { AffList list; if (prefixes.contains(fields[1][0])) list = prefixes[fields[1][0]]; list << e; prefixes[fields[1][0]] = list; } else if (s.startsWith(QLatin1String("SFX"))) { AffList list; if (suffixes.contains(fields[1][0])) list = suffixes[fields[1][0]]; list << e; suffixes[fields[1][0]] = list; } } } } } } /** Checks if the given word matches the given condition. Each entry of the * QStringList "condition" describes one character of the word. (If the word * has more characters than condition entries only the last characters are * compared). * Each entry contains either all valid characters (if it does _not_ start * with "^") or all invalid characters (if it starts with "^"). */ inline bool checkCondition(const QString &word, const QStringList &condition) { if (condition.count() == 0) return true; if (word.length() < condition.count()) return false; QStringList::ConstIterator it; int idx; for (it = condition.constBegin(), idx = word.length() - condition.count(); it != condition.constEnd(); ++it, ++idx) { if ((*it).contains(word[idx]) == ((*it)[0] == QLatin1Char('^'))) return false; } return true; } /** Constructs words by adding suffixes to the given word, and copies the * resulting words from map to checkedMap. * @param modifiers discribes which suffixes are valid * @param cross true if the word has a prefix */ inline void checkWord(const QString &word, const QString &modifiers, bool cross, const WordMap &map, WordMap &checkedMap, const AffMap &suffixes) { for (int i = 0; i < modifiers.length(); i++) { if (suffixes.contains(modifiers[i])) { AffList sList = suffixes[modifiers[i]]; AffList::ConstIterator sIt; for (sIt = sList.constBegin(); sIt != sList.constEnd(); ++sIt) { if (((*sIt).cross || !cross) && (checkCondition(word, (*sIt).condition))) { QString sWord = word.left(word.length() - (*sIt).charsToRemove) + (*sIt).add; if (map.contains(sWord)) checkedMap[sWord] = map[sWord]; } } } } } /** Constructs words by adding pre- and suffixes to the given word, and * copies the resulting words from map to checkedMap. * @param modifiers discribes which pre- and suffixes are valid */ void checkWord(const QString &word, const QString &modifiers, const WordMap &map, WordMap &checkedMap, const AffMap &prefixes, const AffMap &suffixes) { if (map.contains(word)) checkedMap[word] = map[word]; checkWord(word, modifiers, true, map, checkedMap, suffixes); for (int i = 0; i < modifiers.length(); i++) { if (prefixes.contains(modifiers[i])) { AffList pList = prefixes[modifiers[i]]; AffList::ConstIterator pIt; for (pIt = pList.constBegin(); pIt != pList.constEnd(); ++pIt) { QString pWord = (*pIt).add + word; if (map.contains(pWord)) checkedMap[pWord] = map[pWord]; checkWord(pWord, modifiers, false, map, checkedMap, suffixes); } } } } -WordMap spellCheck(WordMap map, QString dictionary, QProgressDialog *pdlg) +WordMap spellCheck(WordMap map, const QString &dictionary, QProgressDialog *pdlg) { if (dictionary.endsWith(QLatin1String(".dic"))) { AffMap prefixes; AffMap suffixes; WordMap checkedMap; loadAffFile(dictionary.left(dictionary.length() - 4) + QStringLiteral(".aff"), prefixes, suffixes); pdlg->reset(); //pdlg->setAllowCancel (false); //pdlg->showCancelButton (false); pdlg->setAutoReset(false); pdlg->setAutoClose(false); pdlg->setLabelText(i18n("Performing spell check...")); pdlg->setMaximum(100); pdlg->setValue(0); qApp->processEvents(QEventLoop::AllEvents, 20); int progress = 0; int steps = 0; int percent = 0; QFile dfile(dictionary); if (dfile.open(QIODevice::ReadOnly)) { QTextStream stream(&dfile); if (!stream.atEnd()) { QString s = stream.readLine(); // Number of words steps = s.toInt(); } while (!stream.atEnd()) { QString s = stream.readLine(); if (s.contains(QLatin1Char('/'))) { QString word = s.left(s.indexOf(QLatin1Char('/'))).toLower(); QString modifiers = s.right(s.length() - s.indexOf(QLatin1Char('/'))); checkWord(word, modifiers, map, checkedMap, prefixes, suffixes); } else { if (!s.isEmpty() && !s.isNull() && map.contains(s.toLower())) checkedMap[s.toLower()] = map[s.toLower()]; } progress++; if (steps != 0 && progress * 100 / steps > percent) { percent = progress * 100 / steps; pdlg->setValue(percent); qApp->processEvents(QEventLoop::AllEvents, 20); } } } return checkedMap; } else return map; } } diff --git a/wordcompletion/wordlist.h b/wordcompletion/wordlist.h index 9709c8b..8e18c25 100644 --- a/wordcompletion/wordlist.h +++ b/wordcompletion/wordlist.h @@ -1,94 +1,94 @@ /*************************************************************************** * Copyright (C) 2002 by Gunnar Schmi Dt * * * * 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. * ***************************************************************************/ #ifndef WORDLIST_H #define WORDLIST_H #include #include #include #include class QTextCodec; class QProgressDialog; namespace WordList { typedef QMap WordMap; QProgressDialog *progressDialog(); WordMap parseKDEDoc(QString language, QProgressDialog *pdlg); -WordMap parseFile(QString filename, QTextCodec *codec, QProgressDialog *pdlg); -WordMap parseDir(QString directory, QTextCodec *codec, QProgressDialog *pdlg); -WordMap mergeFiles(QMap files, QProgressDialog *pdlg); +WordMap parseFile(const QString &filename, QTextCodec *codec, QProgressDialog *pdlg); +WordMap parseDir(const QString &directory, QTextCodec *codec, QProgressDialog *pdlg); +WordMap mergeFiles(const QMap &files, QProgressDialog *pdlg); -WordMap spellCheck(WordMap wordlist, QString dictionary, QProgressDialog *pdlg); +WordMap spellCheck(WordMap wordlist, const QString &dictionary, QProgressDialog *pdlg); -bool saveWordList(WordMap map, QString filename); +bool saveWordList(const WordMap &map, const QString &filename); /** * This class implements a parser for reading docbooks and generating word * lists. It is intended to be used together with the Qt SAX2 framework. * @author Gunnar Schmi Dt */ class XMLParser : public QXmlDefaultHandler { public: XMLParser(); ~XMLParser(); bool warning(const QXmlParseException &exception) override; bool error(const QXmlParseException &exception) override; bool fatalError(const QXmlParseException &exception) override; QString errorString() const override; /** Processes the start of the document. */ bool startDocument() override; /** Processes the start tag of an element. */ bool startElement(const QString &, const QString &, const QString &name, const QXmlAttributes &attributes) override; /** Processes a chunk of normal character data. */ bool characters(const QString &ch) override; /** Processes whitespace. */ bool ignorableWhitespace(const QString &ch) override; /** Processes the end tag of an element. */ bool endElement(const QString &, const QString &, const QString &name) override; /** Processes the end of the document. */ bool endDocument() override; /** returns a list of words */ WordMap getList(); private: WordMap list; QString text; }; } #endif