Commit 9f97092c authored by Jeremy Whiting's avatar Jeremy Whiting
Browse files

Use QXmlStreamReader instead of deprecated QXmlInputSource, etc.

Use same levels as old code.
If starting a book don't icrease level if top is empty.
parent c47ef275
......@@ -64,7 +64,7 @@ include_directories(./wordcompletion/ )
add_executable(kmouth)
target_sources(kmouth PRIVATE
./phrasebook/phrasebookparser.cpp
./phrasebook/phrasebookreader.cpp
./phrasebook/phrasebookdialog.cpp
./phrasebook/initialphrasebookwidget.cpp
./phrasebook/phrasebook.cpp
......
......@@ -19,7 +19,7 @@
***************************************************************************/
#include "phrasebook.h"
#include "phrasebookparser.h"
#include "phrasebookreader.h"
#include <QBuffer>
#include <QFile>
......@@ -36,6 +36,7 @@
#include <KLocalizedString>
#include <KMessageBox>
#include <QtDebug>
Phrase::Phrase()
{
......@@ -141,26 +142,18 @@ void PhraseBook::print(QPrinter *pPrinter)
printpainter.end();
}
bool PhraseBook::decode(const QString &xml)
bool PhraseBook::decode(QIODevice *source)
{
QXmlInputSource source;
source.setData(xml);
return decode(source);
}
bool PhraseBook::decode(QXmlInputSource &source)
{
PhraseBookParser parser;
QXmlSimpleReader reader;
reader.setFeature(QStringLiteral("http://qt-project.org/xml/features/report-start-end-entity"), true);
reader.setContentHandler(&parser);
PhraseBookReader reader;
if (reader.parse(source)) {
if (reader.read(source)) {
PhraseBookEntryList::clear();
*(PhraseBookEntryList *)this += parser.getPhraseList();
*(PhraseBookEntryList *)this += reader.getPhraseList();
return true;
} else
} else {
qDebug() << "Unable to read xml file: " << reader.errorString();
return false;
}
}
QByteArray encodeString(const QString &str)
......@@ -348,8 +341,9 @@ bool PhraseBook::open(const QUrl &url)
QBuffer fileBuffer;
fileBuffer.setData(downloadJob->data());
QXmlInputSource source(&fileBuffer);
bool error = !decode(source);
fileBuffer.open(QIODevice::ReadOnly);
bool error = !decode(&fileBuffer);
// Second: if the file does not contain a phrase book, load it as
// a plain text file
......
......@@ -22,10 +22,10 @@
#define PHRASEBOOK_H
#include <QObject>
#include <QIODevice>
#include <QMenu>
#include <QPrinter>
#include <QTextStream>
#include <QXmlInputSource>
#include <QAction>
#include <KActionCollection>
......@@ -47,7 +47,6 @@ typedef QList<StandardBook> StandardBookList;
*/
class Phrase
{
friend class PhraseBookParser;
public:
Phrase();
Phrase(const QString &phrase);
......@@ -113,10 +112,7 @@ public:
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);
bool decode(QIODevice *source);
/** Writes the phrases to a file. Returns true if successful. */
bool save(const QUrl &url);
......
/***************************************************************************
* Copyright (C) 2002 by Gunnar Schmi Dt <kmouth@schmi-dt.de *
* (C) 2015 by Jeremy Whiting <jpwhiting@kde.org> *
* (C) 2015,2022 by Jeremy Whiting <jpwhiting@kde.org> *
* *
* 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 *
......@@ -18,107 +18,100 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "phrasebookparser.h"
#include "phrasebookreader.h"
PhraseBookParser::PhraseBookParser()
{
}
PhraseBookParser::~PhraseBookParser()
{
}
bool PhraseBookParser::warning(const QXmlParseException &)
{
return false;
}
#include <QtDebug>
bool PhraseBookParser::error(const QXmlParseException &)
PhraseBookReader::PhraseBookReader()
{
return false;
}
bool PhraseBookParser::fatalError(const QXmlParseException &)
PhraseBookReader::~PhraseBookReader()
{
return false;
}
QString PhraseBookParser::errorString() const
bool PhraseBookReader::read(QIODevice *device)
{
return QLatin1String("");
}
xml.setDevice(device);
bool PhraseBookParser::startDocument()
{
list.clear();
isInPhrase = false;
level = 0;
offset = 0;
starting = true;
return true;
}
bool PhraseBookParser::startElement(const QString &, const QString &,
const QString &name,
const QXmlAttributes &attributes)
{
if (name == QLatin1String("phrase")) {
if (isInPhrase)
return false;
phrase.phrase.clear();
phrase.shortcut = attributes.value(QLatin1String("shortcut"));
isInPhrase = true;
} else if (name == QLatin1String("phrasebook")) {
if (isInPhrase)
return false;
phrase.phrase = attributes.value(QLatin1String("name"));
phrase.shortcut.clear();
if ((phrase.phrase.isNull() || phrase.phrase.isEmpty()) && starting)
offset = -1;
else {
list += PhraseBookEntry(phrase, level, false);
level++;
qDebug() << "Beginning to read xml document";
if (xml.readNextStartElement()) {
qDebug() << "First node name " << xml.name();
if (xml.name() == QLatin1String("phrasebook")) {
readbook();
} else if (xml.name() == QLatin1String("phrase")) {
readphrase();
} else {
xml.raiseError(QLatin1String("The file is not a valid phrasebook xml file"));
}
starting = false;
} else {
xml.raiseError(QLatin1String("Unable to get first xml element"));
}
return true;
}
bool PhraseBookParser::characters(const QString &ch)
{
phrase.phrase += ch;
return true;
return !xml.error();
}
bool PhraseBookParser::ignorableWhitespace(const QString &ch)
void PhraseBookReader::readbook()
{
phrase.phrase += ch;
return true;
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("phrasebook"));
// Get the book's name attribute if any
QString name = xml.attributes().value(QLatin1String("name")).toString();
qDebug() << "Reading book with name " << name << " level is " << level;
Phrase phrase;
phrase.setPhrase(name);
if ((phrase.getPhrase().isNull() || phrase.getPhrase().isEmpty()) && starting) {
// Phrase book name is empty, and starting, so don't increase level or add empty entry
} else {
list += PhraseBookEntry(phrase, level, false);
level++;
}
starting = false;
while (xml.readNextStartElement()) {
if (xml.name() == QLatin1String("phrase")) {
readphrase();
} else if (xml.name() == QLatin1String("phrasebook")) {
readbook();
}
else
xml.skipCurrentElement();
}
level--;
}
bool PhraseBookParser::endElement(const QString &, const QString &,
const QString &name)
void PhraseBookReader::readphrase()
{
if (name == QLatin1String("phrase")) {
list += PhraseBookEntry(phrase, level, true);
isInPhrase = false;
} else if (name == QLatin1String("phrasebook")) {
if (level == offset)
return false;
level--;
}
return true;
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("phrase"));
QString shortcut = xml.attributes().value(QLatin1String("shortcut")).toString();
Phrase phrase;
phrase.setShortcut(shortcut);
phrase.setPhrase(xml.readElementText());
qDebug() << "Reading phrase with text " << phrase.getPhrase();
list += PhraseBookEntry(phrase, level, true);
}
bool PhraseBookParser::endDocument()
QString PhraseBookReader::errorString() const
{
return (level == offset);
return QLatin1String("%1\nLine %2, column %3")
.arg(xml.errorString())
.arg(xml.lineNumber())
.arg(xml.columnNumber());
}
PhraseBookEntryList PhraseBookParser::getPhraseList()
PhraseBookEntryList PhraseBookReader::getPhraseList()
{
return list;
}
/***************************************************************************
* Copyright (C) 2002 by Gunnar Schmi Dt <kmouth@schmi-dt.de *
* (C) 2015 by Jeremy Whiting <jpwhiting@kde.org> *
* (C) 2015,2022 by Jeremy Whiting <jpwhiting@kde.org> *
* *
* 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 *
......@@ -18,61 +18,43 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef PHRASEBOOKPARSER_H
#define PHRASEBOOKPARSER_H
#ifndef PHRASEBOOKREADER_H
#define PHRASEBOOKREADER_H
#include <QXmlAttributes>
#include <QXmlParseException>
#include <QXmlStreamReader>
#include "phrasebook.h"
/**
* This class implements a parser for both the phrase list and for phrase
* books. It is intended to be used together with the Qt SAX2 framework.
* @author Gunnar Schmi Dt
* This class implements a reader for both the phrase list and for phrase
* books. Pass a QIODevice to read check the return value and get the list.
*/
class PhraseBookParser : public QXmlDefaultHandler
class PhraseBookReader
{
public:
PhraseBookParser();
~PhraseBookParser() override;
PhraseBookReader();
~PhraseBookReader();
bool warning(const QXmlParseException &exception) override;
bool error(const QXmlParseException &exception) override;
bool fatalError(const QXmlParseException &exception) override;
QString errorString() const override;
bool read(QIODevice *device);
/** 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;
QString errorString() const;
/** returns a list of phrase book entries */
PhraseBookEntryList getPhraseList();
private:
bool isInPhrase;
bool starting;
int offset;
Phrase phrase;
// Read an entire book
void readbook();
// Read a phrase
void readphrase();
PhraseBookEntryList list;
QXmlStreamReader xml;
int level;
bool starting;
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment