Replace deprecated QXmlSimpleReader with homegrown picoxml rather than switching to non-sax QXmlStreamReader

This commit is contained in:
Jean-Francois Dockes
2020-07-13 16:01:00 +02:00
parent 8f0d3cbac5
commit 97e2b26da0
2 changed files with 508 additions and 101 deletions
+69 -101
View File
@@ -37,42 +37,75 @@
#include "log.h"
#include "readfile.h"
#include "copyfile.h"
#include "picoxml.h"
using namespace std;
class FragButsParser : public QXmlDefaultHandler {
class FragButsParser : public PicoXMLParser {
public:
FragButsParser(FragButs *_parent, vector<FragButs::ButFrag>& _buttons)
: parent(_parent), vlw(new QVBoxLayout(parent)),
vl(new QVBoxLayout()), buttons(_buttons),
hl(0), bg(0), radio(false) {
}
FragButsParser(
const std::string& in, FragButs *_p, vector<FragButs::ButFrag>& _bts)
: PicoXMLParser(in), parent(_p), vlw(new QVBoxLayout(parent)),
vl(new QVBoxLayout()), buttons(_bts) {}
bool startElement(const QString & /* namespaceURI */,
const QString & /* localName */,
const QString &qName,
const QXmlAttributes &attributes);
bool endElement(const QString & /* namespaceURI */,
const QString & /* localName */,
const QString &qName);
bool characters(const QString &str) {
currentText += str;
return true;
void startElement(const std::string &nm,
const std::map<std::string, std::string>&) override {
std::cerr << "startElement [" << nm << "]\n";
currentText.clear();
if (nm == "buttons") {
radio = false;
hl = new QHBoxLayout();
} else if (nm == "radiobuttons") {
radio = true;
bg = new QButtonGroup(parent);
hl = new QHBoxLayout();
} else if (nm == "label" || nm == "frag" || nm == "fragbuts" ||
nm == "fragbut") {
} else {
QMessageBox::warning(
0, "Recoll", QString("Bad element name: [%1]").arg(nm.c_str()));
}
}
void endElement(const std::string& nm) override {
std::cerr << "endElement [" << nm << "]\n";
bool error(const QXmlParseException& exception) {
fatalError(exception);
return false;
if (nm == "label") {
label = u8s2qs(currentText);
} else if (nm == "frag") {
frag = currentText;
} else if (nm == "fragbut") {
string slab = qs2utf8s(label);
trimstring(slab, " \t\n\t");
label = u8s2qs(slab.c_str());
QAbstractButton *abut;
if (radio) {
QRadioButton *but = new QRadioButton(label, parent);
bg->addButton(but);
if (bg->buttons().length() == 1)
but->setChecked(true);
abut = but;
} else {
QCheckBox *but = new QCheckBox(label, parent);
abut = but;
}
abut->setToolTip(u8s2qs(currentText));
buttons.push_back(FragButs::ButFrag(abut, frag));
hl->addWidget(abut);
} else if (nm == "buttons" || nm == "radiobuttons") {
vl->addLayout(hl);
hl = 0;
} else if (nm == "fragbuts") {
vlw->addLayout(vl);
} else {
QMessageBox::warning(
0, "Recoll", QString("Bad element name: [%1]").arg(nm.c_str()));
}
}
bool fatalError(const QXmlParseException& x) {
errorMessage = QString("%2 at line %3 column %4")
.arg(x.message())
.arg(x.lineNumber())
.arg(x.columnNumber());
return false;
void characterData(const std::string &str) override {
std::cerr << "characterData [" << str << "]\n";
currentText += str;
}
QString errorMessage;
private:
QWidget *parent;
QVBoxLayout *vlw;
@@ -80,75 +113,14 @@ private:
vector<FragButs::ButFrag>& buttons;
// Temporary data while parsing.
QHBoxLayout *hl;
QButtonGroup *bg;
QString currentText;
QHBoxLayout *hl{nullptr};
QButtonGroup *bg{nullptr};
QString label;
string frag;
bool radio;
std::string currentText;
std::string frag;
bool radio{false};
};
bool FragButsParser::startElement(const QString & /* namespaceURI */,
const QString & /* localName */,
const QString &qName,
const QXmlAttributes &/*attributes*/)
{
currentText = "";
if (qName == "buttons") {
radio = false;
hl = new QHBoxLayout();
} else if (qName == "radiobuttons") {
radio = true;
bg = new QButtonGroup(parent);
hl = new QHBoxLayout();
} else if (qName == "label" || qName == "frag" || qName == "fragbuts" ||
qName == "fragbut") {
} else {
QMessageBox::warning(0, "Recoll",
QString("Bad element name: [%1]").arg(qName));
return false;
}
return true;
}
bool FragButsParser::endElement(const QString & /* namespaceURI */,
const QString & /* localName */,
const QString &qName)
{
if (qName == "label") {
label = currentText;
} else if (qName == "frag") {
frag = qs2utf8s(currentText);
} else if (qName == "fragbut") {
string slab = qs2utf8s(label);
trimstring(slab, " \t\n\t");
label = QString::fromUtf8(slab.c_str());
QAbstractButton *abut;
if (radio) {
QRadioButton *but = new QRadioButton(label, parent);
bg->addButton(but);
if (bg->buttons().length() == 1)
but->setChecked(true);
abut = but;
} else {
QCheckBox *but = new QCheckBox(label, parent);
abut = but;
}
abut->setToolTip(currentText);
buttons.push_back(FragButs::ButFrag(abut, frag));
hl->addWidget(abut);
} else if (qName == "buttons" || qName == "radiobuttons") {
vl->addLayout(hl);
hl = 0;
} else if (qName == "fragbuts") {
vlw->addLayout(vl);
} else {
QMessageBox::warning(0, "Recoll",
QString("Bad element name: [%1]").arg(qName));
return false;
}
return true;
}
FragButs::FragButs(QWidget* parent)
: QWidget(parent), m_reftime(0), m_ok(false)
@@ -168,15 +140,11 @@ FragButs::FragButs(QWidget* parent)
LOGERR("Fragbuts:: can't read [" << m_fn << "]\n");
return;
}
FragButsParser parser(this, m_buttons);
QXmlSimpleReader reader;
reader.setContentHandler(&parser);
reader.setErrorHandler(&parser);
QXmlInputSource xmlInputSource;
xmlInputSource.setData(QString::fromUtf8(data.c_str()));
if (!reader.parse(xmlInputSource)) {
QMessageBox::warning(0, "Recoll", tr("%1:\n %2")
.arg(path2qs(m_fn)).arg(parser.errorMessage));
FragButsParser parser(data, this, m_buttons);
if (!parser.Parse()) {
QMessageBox::warning(
0, "Recoll", tr("%1:\n %2").arg(path2qs(m_fn))
.arg(u8s2qs(parser.getReason())));
return;
}
for (vector<ButFrag>::iterator it = m_buttons.begin();