summaryrefslogtreecommitdiffstats
path: root/kmouth/phrasebook/phrasebook.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmouth/phrasebook/phrasebook.cpp')
-rw-r--r--kmouth/phrasebook/phrasebook.cpp512
1 files changed, 512 insertions, 0 deletions
diff --git a/kmouth/phrasebook/phrasebook.cpp b/kmouth/phrasebook/phrasebook.cpp
new file mode 100644
index 0000000..0ec8da3
--- /dev/null
+++ b/kmouth/phrasebook/phrasebook.cpp
@@ -0,0 +1,512 @@
+/***************************************************************************
+ phrasebook.cpp - description
+ -------------------
+ begin : Don Sep 19 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include <qprinter.h>
+#include <qpainter.h>
+#include <qfile.h>
+#include <qxml.h>
+#include <qregexp.h>
+#include <qptrstack.h>
+
+#include <klocale.h>
+#include <kaction.h>
+#include <kpopupmenu.h>
+#include <ktoolbar.h>
+#include <ktempfile.h>
+#include <kio/netaccess.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kglobalsettings.h>
+
+#include "phrasebookparser.h"
+#include "phrasebook.h"
+
+Phrase::Phrase() {
+ this->phrase = "";
+ this->shortcut = "";
+}
+
+Phrase::Phrase (const QString &phrase) {
+ this->phrase = phrase;
+ this->shortcut = "";
+}
+
+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) {
+ 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(KPrinter *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 (KGlobalSettings::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::WordBreak,
+ (*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::WordBreak,
+ (*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 ("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;
+}
+
+QCString encodeString (const QString str) {
+ QCString res = "";
+ for (int i = 0; i < (int)str.length(); i++) {
+ QChar ch = str.at(i);
+ ushort uc = ch.unicode();
+ QCString number; number.setNum(uc);
+ if ((uc>127) || (uc<32) || (ch=='<') || (ch=='>') || (ch=='&') || (ch==';'))
+ res = res + "&#" + number + ";";
+ else
+ res = res + (char)uc;
+ }
+ return res;
+}
+
+QString PhraseBook::encode () {
+ QString result;
+ result = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ result += "<!DOCTYPE phrasebook>\n";
+ result += "<phrasebook>\n";
+
+ PhraseBookEntryList::iterator it;
+ int level = 0;
+ for (it = begin(); it != end(); ++it) {
+ int newLevel = (*it).getLevel();
+ while (level < newLevel) {
+ result += "<phrasebook>\n";
+ level++;
+ }
+ while (level > newLevel) {
+ result += "</phrasebook>\n";
+ level--;
+ }
+
+ if ((*it).isPhrase()) {
+ Phrase phrase = (*it).getPhrase();
+ result += "<phrase shortcut=\"" + encodeString(phrase.getShortcut());
+ result += "\">" + encodeString(phrase.getPhrase()) + "</phrase>\n";
+ }
+ else {
+ Phrase phrase = (*it).getPhrase();
+ result += "<phrasebook name=\"" + encodeString(phrase.getPhrase()) + "\">\n";
+ level++;
+ }
+ }
+ while (level > 0) {
+ result += "</phrasebook>\n";
+ level--;
+ }
+ result += "</phrasebook>";
+ 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 KURL &url) {
+ QRegExp pattern("*.phrasebook",true,true);
+ return save (url, pattern.exactMatch(url.filename()));
+}
+
+
+void PhraseBook::save (QTextStream &stream, bool asPhrasebook) {
+ if (asPhrasebook)
+ stream << encode();
+ else
+ stream << toStringList().join("\n");
+}
+
+bool PhraseBook::save (const KURL &url, bool asPhrasebook) {
+ if (url.isLocalFile()) {
+ QFile file(url.path());
+ if(!file.open(IO_WriteOnly))
+ return false;
+
+ QTextStream stream(&file);
+ save (stream, asPhrasebook);
+ file.close();
+
+ if (file.status() != IO_Ok)
+ return false;
+ else
+ return true;
+ }
+ else {
+ KTempFile tempFile;
+ tempFile.setAutoDelete(true);
+
+ save (*tempFile.textStream(), asPhrasebook);
+ tempFile.close();
+
+ return KIO::NetAccess::upload(tempFile.name(), url);
+ }
+}
+
+int PhraseBook::save (QWidget *parent, const QString &title, KURL &url, bool phrasebookFirst) {
+ // KFileDialog::getSaveURL(...) is not useful here as we need
+ // to know the requested file type.
+
+ QString filters;
+ if (phrasebookFirst)
+ filters = i18n("*.phrasebook|Phrase Books (*.phrasebook)\n*.txt|Plain Text Files (*.txt)\n*|All Files");
+ else
+ filters = i18n("*.txt|Plain Text Files (*.txt)\n*.phrasebook|Phrase Books (*.phrasebook)\n*|All Files");
+
+ KFileDialog fdlg(QString::null,filters, parent, "filedialog", true);
+ fdlg.setCaption(title);
+ fdlg.setOperationMode( KFileDialog::Saving );
+
+ if (fdlg.exec() != QDialog::Accepted) {
+ return 0;
+ }
+
+ url = fdlg.selectedURL();
+
+ if (url.isEmpty() || !url.isValid()) {
+ return -1;
+ }
+
+ if (KIO::NetAccess::exists(url)) {
+ if (KMessageBox::warningContinueCancel(0,QString("<qt>%1</qt>").arg(i18n("The file %1 already exists. "
+ "Do you want to overwrite it?").arg(url.url())),i18n("File Exists"),i18n("&Overwrite"))==KMessageBox::Cancel) {
+ return 0;
+ }
+ }
+
+ bool result;
+ if (fdlg.currentFilter() == "*.phrasebook") {
+ if (url.fileName (false).contains('.') == 0) {
+ url.setFileName (url.fileName(false) + ".phrasebook");
+ }
+ else if (url.fileName (false).right (11).contains (".phrasebook", false) == 0) {
+ int filetype = KMessageBox::questionYesNoCancel (0,QString("<qt>%1</qt>").arg(i18n("Your chosen filename <i>%1</i> has a different extension than <i>.phrasebook</i>. "
+ "Do you wish to add <i>.phrasebook</i> to the filename?").arg(url.filename())),i18n("File Extension"),i18n("Add"),i18n("Do Not Add"));
+ if (filetype == KMessageBox::Cancel) {
+ return 0;
+ }
+ if (filetype == KMessageBox::Yes) {
+ url.setFileName (url.fileName(false) + ".phrasebook");
+ }
+ }
+ result = save (url, true);
+ }
+ else if (fdlg.currentFilter() == "*.txt") {
+ if (url.fileName (false).right (11).contains (".phrasebook", false) == 0) {
+ result = save (url, false);
+ }
+ else {
+ int filetype = KMessageBox::questionYesNoCancel (0,QString("<qt>%1</qt>").arg(i18n("Your chosen filename <i>%1</i> has the extension <i>.phrasebook</i>. "
+ "Do you wish to save in phrasebook format?").arg(url.filename())),i18n("File Extension"),i18n("As Phrasebook"),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 KURL &url) {
+ QString tempFile;
+ KURL fileUrl = url;
+
+ QString protocol = fileUrl.protocol();
+ if (protocol.isEmpty() || protocol.isNull()) {
+ fileUrl.setProtocol ("file");
+ fileUrl.setPath (url.url());
+ }
+
+ if (KIO::NetAccess::download (fileUrl, tempFile)) {
+ QStringList list = QStringList();
+
+ // First: try to load it as a normal phrase book
+ QFile file(tempFile);
+ QXmlInputSource source (&file);
+ 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
+
+ QFile file(tempFile);
+ if (file.open(IO_ReadOnly)) {
+ QTextStream stream(&file);
+
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ if (!(s.isNull() || s.isEmpty()))
+ *this += PhraseBookEntry(Phrase(s, ""), 0, true);
+ }
+ file.close();
+ error = false;
+ }
+ else
+ error = true;
+ }
+ KIO::NetAccess::removeTempFile (tempFile);
+
+ return !error;
+ }
+ else
+ return false;
+}
+
+void PhraseBook::addToGUI (QPopupMenu *popup, KToolBar *toolbar, KActionCollection *phrases,
+ QObject *receiver, const char *slot) const {
+ if ((popup != 0) || (toolbar != 0)) {
+ QPtrStack<QWidget> stack;
+ QWidget *parent = popup;
+ int level = 0;
+
+ QValueListConstIterator<PhraseBookEntry> it;
+ for (it = begin(); it != end(); ++it) {
+ int newLevel = (*it).getLevel();
+ while (newLevel > level) {
+ KActionMenu *menu = new KActionMenu("", "phrasebook");
+ menu->setDelayed(false);
+ phrases->insert(menu);
+ menu->plug (parent);
+ if (parent == popup)
+ menu->plug (toolbar);
+ if (parent != 0)
+ stack.push (parent);
+ parent = menu->popupMenu();
+ level++;
+ }
+ while (newLevel < level && (parent != popup)) {
+ parent = stack.pop();
+ level--;
+ }
+ if ((*it).isPhrase()) {
+ Phrase phrase = (*it).getPhrase();
+ KAction *action = new PhraseAction (phrase.getPhrase(),
+ phrase.getShortcut(), receiver, slot, phrases);
+ if (parent == popup)
+ action->plug (toolbar);
+ if (parent != 0)
+ action->plug(parent);
+ }
+ else {
+ Phrase phrase = (*it).getPhrase();
+ KActionMenu *menu = new KActionMenu(phrase.getPhrase(), "phrasebook");
+ menu->setDelayed(false);
+ phrases->insert(menu);
+ if (parent == popup)
+ menu->plug (toolbar);
+ if (parent != 0)
+ menu->plug (parent);
+ stack.push (parent);
+ parent = menu->popupMenu();
+ level++;
+ }
+ }
+ }
+}
+
+void PhraseBook::insert (const QString &name, const PhraseBook &book) {
+ *this += PhraseBookEntry(Phrase(name), 0, false);
+
+ QValueListConstIterator<PhraseBookEntry> it;
+ for (it = book.begin(); it != book.end(); ++it) {
+ *this += PhraseBookEntry ((*it).getPhrase(), (*it).getLevel()+1, (*it).isPhrase());
+ }
+}
+
+// ***************************************************************************
+
+PhraseBookDrag::PhraseBookDrag (PhraseBook *book, QWidget *dragSource, const char *name)
+ : QDragObject (dragSource, name)
+{
+ setBook (book);
+}
+
+PhraseBookDrag::PhraseBookDrag (QWidget *dragSource, const char *name)
+ : QDragObject (dragSource, name)
+{
+ setBook (0);
+}
+
+PhraseBookDrag::~PhraseBookDrag () {
+}
+
+void PhraseBookDrag::setBook (PhraseBook *book) {
+ if (book == 0) {
+ isEmpty = true;
+ xmlphrasebook.setText(QString::null);
+ xml.setText(QString::null);
+ plain.setText(QString::null);
+ }
+ else {
+ isEmpty = false;
+ xmlphrasebook.setText(book->encode());
+ xml.setText(book->encode());
+ plain.setText(book->toStringList().join("\n"));
+ }
+ xmlphrasebook.setSubtype("x-xml-phrasebook");
+ xml.setSubtype("xml");
+ plain.setSubtype("plain");
+}
+
+const char *PhraseBookDrag::format (int i) const {
+ if (isEmpty)
+ return plain.format(i);
+ else if (i%3 == 0)
+ return plain.format(i/3);
+ else if (i%3 == 1)
+ return xml.format(i/3);
+ else
+ return xmlphrasebook.format(i/3);
+}
+
+QByteArray PhraseBookDrag::encodedData (const char* mime) const {
+ QCString m(mime);
+ m = m.lower();
+ if (m.contains("xml-phrasebook"))
+ return xmlphrasebook.encodedData(mime);
+ else if (m.contains("xml"))
+ return xml.encodedData(mime);
+ else
+ return plain.encodedData(mime);
+}
+
+bool PhraseBookDrag::canDecode (const QMimeSource* e) {
+ return QTextDrag::canDecode(e);
+}
+
+bool PhraseBookDrag::decode (const QMimeSource *e, PhraseBook *book) {
+ QString string;
+ QCString subtype1 = "x-xml-phrasebook";
+ QCString subtype2 = "xml";
+
+ if (!QTextDrag::decode(e, string, subtype1))
+ if (!QTextDrag::decode(e, string, subtype2)) {
+ if (QTextDrag::decode(e, string)) {
+ *book += PhraseBookEntry(Phrase(string, ""), 0, true);
+ return true;
+ }
+ else return false;
+ }
+
+ return book->decode(string);
+}
+
+#include "phrasebook.moc"