From 6c58d8d7867ce39a4eb34d94bcc54b9f6969ba10 Mon Sep 17 00:00:00 2001
From: Julian Sikorski <belegdol+github@gmail.com>
Date: Fri, 8 Mar 2024 15:52:22 +0100
Subject: [PATCH 08/10] imp: Replaced custom XML parsing with QXmlStreamReader.
(#42)
* Refactored machinelist.{cpp,h} to use QXmlStreamReader.
* Refactored softwarelist.cpp to use QXmlStreamReader.
* Refactored deviceconfigurator.cpp to QXmlStreamReader.
* Refactored romalyzer.cpp to QXmlStreamReader.
* Refactored qmc2main.cpp to QXmlStreamReader.
---
src/deviceconfigurator.cpp | 88 +++--
src/machinelist.cpp | 639 ++++++++++++++++++-------------------
src/machinelist.h | 6 +-
src/qmc2main.cpp | 64 ++--
src/romalyzer.cpp | 99 +++---
src/softwarelist.cpp | 60 ++--
6 files changed, 466 insertions(+), 490 deletions(-)
diff --git a/src/deviceconfigurator.cpp b/src/deviceconfigurator.cpp
index 6b06ebc4e..9b7b104a7 100644
--- a/src/deviceconfigurator.cpp
+++ b/src/deviceconfigurator.cpp
@@ -2006,57 +2006,55 @@ QString DeviceTreeXmlHandler::getXmlData(const QString &machine)
QString DeviceTreeXmlHandler::lookupDescription(const QString &machine)
{
- QStringList xmlLines(qmc2MachineList->xmlDb()->xml(machine).split('\n'));
- if ( xmlLines.count() > 1 ) {
- int index = 0;
- while ( index < xmlLines.count() && !xmlLines.at(index).startsWith("<description>") )
- index++;
- QString description(xmlLines.at(index));
- description.remove("<description>").remove("</description>");
- QTextDocument doc;
- doc.setHtml(description);
- return doc.toPlainText();
- } else
- return QString();
+ QXmlStreamReader xmlMachineEntry(qmc2MachineList->xmlDb()->xml(machine));
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "description" ) {
+ QString description(xmlMachineEntry.readElementText());
+ QTextDocument doc;
+ doc.setHtml(description);
+ return doc.toPlainText();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ }
+ }
+ }
+ return QString();
}
QString DeviceTreeXmlHandler::lookupBiosOptions(const QString &machine, QStringList *bioses, QStringList *biosDescriptions)
{
- QStringList xmlLines(qmc2MachineList->xmlDb()->xml(machine).split('\n'));
- if ( xmlLines.count() > 1 ) {
- int index = 0;
- QString defaultOption;
- while ( index < xmlLines.count() ) {
- if ( xmlLines.at(index).startsWith("<biosset ") ) {
- QString name;
- QString description;
- int startIndex = xmlLines.at(index).indexOf("name=\"");
- if ( startIndex >= 0 ) {
- startIndex += 6;
- int endIndex = xmlLines.at(index).indexOf("\"", startIndex);
- name = xmlLines.at(index).mid(startIndex, endIndex - startIndex);
- }
- startIndex = xmlLines.at(index).indexOf("description=\"");
- if ( startIndex >= 0 ) {
- startIndex += 13;
- int endIndex = xmlLines.at(index).indexOf("\"", startIndex);
- description = xmlLines.at(index).mid(startIndex, endIndex - startIndex);
- QTextDocument doc;
- doc.setHtml(description);
- description = doc.toPlainText();
- }
- if ( !name.isEmpty() && !description.isEmpty() ) {
- bioses->append(name);
- biosDescriptions->append(description);
- if ( xmlLines.at(index).indexOf("default=\"yes\"") >= 0 )
- defaultOption = name;
- }
+ QXmlStreamReader xmlMachineEntry(qmc2MachineList->xmlDb()->xml(machine));
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ QString defaultOption;
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "biosset" ) {
+ QString name;
+ QString description;
+ if ( xmlMachineEntry.attributes().hasAttribute("name") )
+ name = xmlMachineEntry.attributes().value("name").toString();
+ if ( xmlMachineEntry.attributes().hasAttribute("description") ) {
+ description = xmlMachineEntry.attributes().value("description").toString();
+ QTextDocument doc;
+ doc.setHtml(description);
+ description = doc.toPlainText();
+ }
+ if ( !name.isEmpty() && !description.isEmpty() ) {
+ bioses->append(name);
+ biosDescriptions->append(description);
+ if ( xmlMachineEntry.attributes().hasAttribute("default") && xmlMachineEntry.attributes().value("default").toString() == "yes" )
+ defaultOption = name;
+ }
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
}
- index++;
+ return defaultOption;
}
- return defaultOption;
- } else
- return QString();
+ }
+ return QString();
}
bool FileChooserKeyEventFilter::eventFilter(QObject *obj, QEvent *event)
diff --git a/src/machinelist.cpp b/src/machinelist.cpp
index 4ccdc3c4b..7be2aa311 100644
--- a/src/machinelist.cpp
+++ b/src/machinelist.cpp
@@ -892,14 +892,10 @@ void MachineList::verify(bool currentOnly)
verifyProc->start(command, args, QIODevice::ReadOnly | QIODevice::Text);
}
-QString MachineList::value(QString element, QString attribute, bool translate)
+QString MachineList::value(QXmlStreamReader &element, QString attribute, bool translate)
{
- QString attributePattern(" " + attribute + "=\"");
- if ( element.contains(attributePattern) ) {
- QString valueString(element.remove(0, element.indexOf(attributePattern) + attributePattern.length()));
- valueString = valueString.remove(valueString.indexOf("\""), valueString.lastIndexOf(">")).replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"").replace("'", "'");
- if ( valueString == ">" )
- return QString();
+ if ( element.attributes().hasAttribute(attribute) ) {
+ QString valueString(element.attributes().value(attribute).toString());
if ( translate )
return tr(valueString.toUtf8().constData());
else
@@ -908,7 +904,7 @@ QString MachineList::value(QString element, QString attribute, bool translate)
return QString();
}
-void MachineList::insertAttributeItems(QTreeWidgetItem *parent, QString element, QStringList attributes, QStringList descriptions, bool translate)
+void MachineList::insertAttributeItems(QTreeWidgetItem *parent, QXmlStreamReader &element, QStringList attributes, QStringList descriptions, bool translate)
{
QList<QTreeWidgetItem *> itemList;
for (int i = 0; i < attributes.count(); i++) {
@@ -923,7 +919,7 @@ void MachineList::insertAttributeItems(QTreeWidgetItem *parent, QString element,
parent->addChildren(itemList);
}
-void MachineList::insertAttributeItems(QList<QTreeWidgetItem *> *itemList, QString element, QStringList attributes, QStringList descriptions, bool translate)
+void MachineList::insertAttributeItems(QList<QTreeWidgetItem *> *itemList, QXmlStreamReader &element, QStringList attributes, QStringList descriptions, bool translate)
{
for (int i = 0; i < attributes.count(); i++) {
QString valueString(value(element, attributes.at(i), translate));
@@ -939,12 +935,7 @@ void MachineList::insertAttributeItems(QList<QTreeWidgetItem *> *itemList, QStri
void MachineList::parseMachineDetail(QTreeWidgetItem *item)
{
QString machineName(item->text(QMC2_MACHINELIST_COLUMN_NAME));
- QStringList xmlLines(xmlDb()->xml(machineName).split("\n", QString::SkipEmptyParts));
- if ( xmlLines.count() < 2 ) {
- qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("WARNING: couldn't find machine information for '%1'").arg(machineName));
- return;
- }
- int gamePos = 1;
+ QXmlStreamReader xmlMachineEntry(xmlDb()->xml(machineName));
item->child(0)->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Updating"));
qmc2MainWindow->treeWidgetMachineList->viewport()->repaint();
qApp->processEvents();
@@ -955,259 +946,263 @@ void MachineList::parseMachineDetail(QTreeWidgetItem *item)
attributes << "name" << "sourcefile" << "isbios" << "isdevice" << "runnable" << "cloneof" << "romof" << "sampleof";
descriptions << tr("Name") << tr("Source file") << tr("Is BIOS?") << tr("Is device?") << tr("Runnable") << tr("Clone of") << tr("ROM of") << tr("Sample of");
- element = xmlLines.at(gamePos - 1).simplified();
- insertAttributeItems(&itemList, element, attributes, descriptions, true);
- QString endMark("</machine>");
-
- while ( !xmlLines.at(gamePos).contains(endMark) ) {
- childItem = 0;
- element = xmlLines.at(gamePos).simplified();
- if ( element.contains("<year>") ) {
- content = element.remove("<year>").remove("</year>");
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Year"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, content);
- }
- if ( element.contains("<manufacturer>") ) {
- content = element.remove("<manufacturer>").remove("</manufacturer>");
- content.replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"").replace("'", "'");
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Manufacturer"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, content);
- }
- if ( element.contains("<rom ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("ROM"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- attributes.clear();
- attributes << "bios" << "size" << "crc" << "sha1" << "merge" << "region" << "offset" << "status" << "optional";
- descriptions.clear();
- descriptions << tr("BIOS") << tr("Size") << tr("CRC") << tr("SHA-1") << tr("Merge") << tr("Region") << tr("Offset") << tr("Status") << tr("Optional");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<device_ref ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Device reference"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- }
- if ( element.contains("<chip ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Chip"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- attributes.clear();
- attributes << "tag" << "type" << "clock";
- descriptions.clear();
- descriptions << tr("Tag") << tr("Type") << tr("Clock");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<display ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Display"));
- attributes.clear();
- attributes << "type" << "rotate" << "flipx" << "width" << "height" << "refresh" << "pixclock" << "htotal" << "hbend" << "hbstart" << "vtotal" << "vbend" << "vbstart";
- descriptions.clear();
- descriptions << tr("Type") << tr("Rotate") << tr("Flip-X") << tr("Width") << tr("Height") << tr("Refresh") << tr("Pixel clock") << tr("H-Total") << tr("H-Bend") << tr("HB-Start") << tr("V-Total") << tr("V-Bend") << tr("VB-Start");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<sound ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Sound"));
- attributes.clear();
- attributes << "channels";
- descriptions.clear();
- descriptions << tr("Channels");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<input ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Input"));
- attributes.clear();
- attributes << "service" << "tilt" << "players" << "buttons" << "coins";
- descriptions.clear();
- descriptions << tr("Service") << tr("Tilt") << tr("Players") << tr("Buttons") << tr("Coins");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- gamePos++;
- while ( xmlLines.at(gamePos).contains("<control ") ) {
- QString subElement(xmlLines.at(gamePos).simplified());
- QTreeWidgetItem *nextChildItem = new QTreeWidgetItem(childItem);
- nextChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Control"));
- nextChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(subElement, "type", true));
- attributes.clear();
- attributes << "minimum" << "maximum" << "sensitivity" << "keydelta" << "reverse" << "player" << "buttons" << "ways";
- descriptions.clear();
- descriptions << tr("Minimum") << tr("Maximum") << tr("Sensitivity") << tr("Key Delta") << tr("Reverse") << tr("Player") << tr("Buttons") << tr("Ways");
- insertAttributeItems(nextChildItem, subElement, attributes, descriptions, true);
- gamePos++;
- }
- }
- if ( element.contains("<dipswitch ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("DIP switch"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name", true));
- gamePos++;
- while ( xmlLines.at(gamePos).contains("<dipvalue ") ) {
- QString subElement(xmlLines.at(gamePos).simplified());
- QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("DIP value"));
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(subElement, "name", true));
- attributes.clear();
- attributes << "default";
- descriptions.clear();
- descriptions << tr("Default");
- insertAttributeItems(secondChildItem, subElement, attributes, descriptions, true);
- gamePos++;
- }
- }
- if ( element.contains("<configuration ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Configuration"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name", true));
- attributes.clear();
- attributes << "tag" << "mask";
- descriptions.clear();
- descriptions << tr("Tag") << tr("Mask");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- gamePos++;
- while ( xmlLines.at(gamePos).contains("<confsetting ") ) {
- QString subElement(xmlLines.at(gamePos).simplified());
- QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Setting"));
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(subElement, "name", true));
- attributes.clear();
- attributes << "value" << "default";
- descriptions.clear();
- descriptions << tr("Value") << tr("Default");
- insertAttributeItems(secondChildItem, subElement, attributes, descriptions, true);
- gamePos++;
- }
- }
- if ( element.contains("<driver ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Driver"));
- attributes.clear();
- attributes << "status" << "emulation" << "color" << "sound" << "graphic" << "cocktail" << "protection" << "savestate" << "palettesize";
- descriptions.clear();
- descriptions << tr("Status") << tr("Emulation") << tr("Color") << tr("Sound") << tr("Graphic") << tr("Cocktail") << tr("Protection") << tr("Save state") << tr("Palette size");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<biosset ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("BIOS set"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- attributes.clear();
- attributes << "description" << "default";
- descriptions.clear();
- descriptions << tr("Description") << tr("Default");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<sample ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Sample"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- }
- if ( element.contains("<disk ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Disk"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- attributes.clear();
- attributes << "md5" << "sha1" << "merge" << "region" << "index" << "status" << "optional";
- descriptions.clear();
- descriptions << tr("MD5") << tr("SHA-1") << tr("Merge") << tr("Region") << tr("Index") << tr("Status") << tr("Optional");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<adjuster ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Adjuster"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- attributes.clear();
- attributes << "default";
- descriptions.clear();
- descriptions << tr("Default");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<softwarelist ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Software list"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name"));
- attributes.clear();
- attributes << "status";
- descriptions.clear();
- descriptions << tr("Status");
- insertAttributeItems(childItem, element, attributes, descriptions, true);
- }
- if ( element.contains("<category ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Category"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "name", true));
- gamePos++;
- while ( xmlLines.at(gamePos).contains("<item ") ) {
- QString subElement(xmlLines.at(gamePos).simplified());
- QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Item"));
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(subElement, "name", true));
- attributes.clear();
- attributes << "default";
- descriptions.clear();
- descriptions << tr("Default");
- insertAttributeItems(secondChildItem, subElement, attributes, descriptions, true);
- gamePos++;
- }
- }
- if ( element.contains("<device ") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Device"));
- childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(element, "type", true));
- attributes.clear();
- attributes << "tag" << "mandatory" << "interface";
- descriptions.clear();
- descriptions << tr("Tag") << tr("Mandatory") << tr("Interface");
- insertAttributeItems(childItem, element, attributes, descriptions, false);
- gamePos++;
- while ( xmlLines.at(gamePos).contains("<instance ") ) {
- QString subElement(xmlLines.at(gamePos).simplified());
- QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Instance"));
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(subElement, "name", false));
- attributes.clear();
- attributes << "briefname";
- descriptions.clear();
- descriptions << tr("Brief name");
- insertAttributeItems(secondChildItem, element, attributes, descriptions, false);
- gamePos++;
- }
- while ( xmlLines.at(gamePos).contains("<extension ") ) {
- QString subElement(xmlLines.at(gamePos).simplified());
- QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Extension"));
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(subElement, "name", false));
- gamePos++;
- }
- }
- if ( element.contains("<ramoption") ) {
- childItem = new QTreeWidgetItem();
- childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("RAM options"));
- while ( xmlLines.at(gamePos).contains("<ramoption") ) {
- QString subElement(xmlLines.at(gamePos).simplified());
- QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Option"));
- int fromIndex = subElement.indexOf('>') + 1;
- int toIndex = subElement.indexOf('<', fromIndex);
- QString ramOptionValue(subElement.mid(fromIndex, toIndex - fromIndex));
- secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, ramOptionValue);
- attributes.clear();
- attributes << "default";
- descriptions.clear();
- descriptions << tr("Default");
- insertAttributeItems(secondChildItem, subElement, attributes, descriptions, false);
- gamePos++;
+
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ insertAttributeItems(&itemList, xmlMachineEntry, attributes, descriptions, true);
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "year" ) {
+ content = xmlMachineEntry.readElementText();
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Year"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, content);
+ } else if ( xmlMachineEntry.name() =="manufacturer" ) {
+ content = xmlMachineEntry.readElementText();
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Manufacturer"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, content);
+ } else if ( xmlMachineEntry.name() == "rom" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("ROM"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ attributes.clear();
+ attributes << "bios" << "size" << "crc" << "sha1" << "merge" << "region" << "offset" << "status" << "optional";
+ descriptions.clear();
+ descriptions << tr("BIOS") << tr("Size") << tr("CRC") << tr("SHA-1") << tr("Merge") << tr("Region") << tr("Offset") << tr("Status") << tr("Optional");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "device_ref" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Device reference"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "chip") {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Chip"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ attributes.clear();
+ attributes << "tag" << "type" << "clock";
+ descriptions.clear();
+ descriptions << tr("Tag") << tr("Type") << tr("Clock");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "display" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Display"));
+ attributes.clear();
+ attributes << "type" << "rotate" << "flipx" << "width" << "height" << "refresh" << "pixclock" << "htotal" << "hbend" << "hbstart" << "vtotal" << "vbend" << "vbstart";
+ descriptions.clear();
+ descriptions << tr("Type") << tr("Rotate") << tr("Flip-X") << tr("Width") << tr("Height") << tr("Refresh") << tr("Pixel clock") << tr("H-Total") << tr("H-Bend") << tr("HB-Start") << tr("V-Total") << tr("V-Bend") << tr("VB-Start");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "sound" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Sound"));
+ attributes.clear();
+ attributes << "channels";
+ descriptions.clear();
+ descriptions << tr("Channels");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "input" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Input"));
+ attributes.clear();
+ attributes << "service" << "tilt" << "players" << "buttons" << "coins";
+ descriptions.clear();
+ descriptions << tr("Service") << tr("Tilt") << tr("Players") << tr("Buttons") << tr("Coins");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "control" ) {
+ QTreeWidgetItem *nextChildItem = new QTreeWidgetItem(childItem);
+ nextChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Control"));
+ nextChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "type", true));
+ attributes.clear();
+ attributes << "minimum" << "maximum" << "sensitivity" << "keydelta" << "reverse" << "player" << "buttons" << "ways";
+ descriptions.clear();
+ descriptions << tr("Minimum") << tr("Maximum") << tr("Sensitivity") << tr("Key Delta") << tr("Reverse") << tr("Player") << tr("Buttons") << tr("Ways");
+ insertAttributeItems(nextChildItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ }
+ } else if ( xmlMachineEntry.name() == "dipswitch") {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("DIP switch"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", true));
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "dipvalue") {
+ QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("DIP value"));
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", true));
+ attributes.clear();
+ attributes << "default";
+ descriptions.clear();
+ descriptions << tr("Default");
+ insertAttributeItems(secondChildItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ }
+ } else if ( xmlMachineEntry.name() == "configuration" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Configuration"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", true));
+ attributes.clear();
+ attributes << "tag" << "mask";
+ descriptions.clear();
+ descriptions << tr("Tag") << tr("Mask");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "confsetting" ) {
+ QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Setting"));
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", true));
+ attributes.clear();
+ attributes << "value" << "default";
+ descriptions.clear();
+ descriptions << tr("Value") << tr("Default");
+ insertAttributeItems(secondChildItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ }
+ } else if ( xmlMachineEntry.name() == "driver" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Driver"));
+ attributes.clear();
+ attributes << "status" << "emulation" << "color" << "sound" << "graphic" << "cocktail" << "protection" << "savestate" << "palettesize";
+ descriptions.clear();
+ descriptions << tr("Status") << tr("Emulation") << tr("Color") << tr("Sound") << tr("Graphic") << tr("Cocktail") << tr("Protection") << tr("Save state") << tr("Palette size");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "biosset" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("BIOS set"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ attributes.clear();
+ attributes << "description" << "default";
+ descriptions.clear();
+ descriptions << tr("Description") << tr("Default");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "sample" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Sample"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "disk" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Disk"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ attributes.clear();
+ attributes << "md5" << "sha1" << "merge" << "region" << "index" << "status" << "optional";
+ descriptions.clear();
+ descriptions << tr("MD5") << tr("SHA-1") << tr("Merge") << tr("Region") << tr("Index") << tr("Status") << tr("Optional");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "adjuster" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Adjuster"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ attributes.clear();
+ attributes << "default";
+ descriptions.clear();
+ descriptions << tr("Default");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "softwarelist" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Software list"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name"));
+ attributes.clear();
+ attributes << "status";
+ descriptions.clear();
+ descriptions << tr("Status");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "category" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Category"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", true));
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "item" ) {
+ QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Item"));
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", true));
+ attributes.clear();
+ attributes << "default";
+ descriptions.clear();
+ descriptions << tr("Default");
+ insertAttributeItems(secondChildItem, xmlMachineEntry, attributes, descriptions, true);
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ }
+ } else if ( xmlMachineEntry.name() == "device" ) {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Device"));
+ childItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "type", true));
+ attributes.clear();
+ attributes << "tag" << "mandatory" << "interface";
+ descriptions.clear();
+ descriptions << tr("Tag") << tr("Mandatory") << tr("Interface");
+ insertAttributeItems(childItem, xmlMachineEntry, attributes, descriptions, false);
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "instance" ) {
+ QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Instance"));
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", false));
+ attributes.clear();
+ attributes << "briefname";
+ descriptions.clear();
+ descriptions << tr("Brief name");
+ insertAttributeItems(secondChildItem, xmlMachineEntry, attributes, descriptions, false);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "extension" ) {
+ QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Extension"));
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, value(xmlMachineEntry, "name", false));
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ }
+ } else if ( xmlMachineEntry.name() == "ramoption") {
+ childItem = new QTreeWidgetItem();
+ childItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("RAM options"));
+ QTreeWidgetItem *secondChildItem = new QTreeWidgetItem(childItem);
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Option"));
+ attributes.clear();
+ attributes << "default";
+ descriptions.clear();
+ descriptions << tr("Default");
+ insertAttributeItems(secondChildItem, xmlMachineEntry, attributes, descriptions, false);
+ QString ramOptionValue = xmlMachineEntry.readElementText();
+ secondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, ramOptionValue);
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "ramoption" ) {
+ QTreeWidgetItem *anotherSecondChildItem = new QTreeWidgetItem(childItem);
+ anotherSecondChildItem->setText(QMC2_MACHINELIST_COLUMN_MACHINE, tr("Option"));
+ attributes.clear();
+ attributes << "default";
+ descriptions.clear();
+ descriptions << tr("Default");
+ insertAttributeItems(anotherSecondChildItem, xmlMachineEntry, attributes, descriptions, false);
+ QString ramOptionValue = xmlMachineEntry.readElementText();
+ anotherSecondChildItem->setText(QMC2_MACHINELIST_COLUMN_ICON, ramOptionValue);
+ }
+ }
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ if ( childItem )
+ itemList.append(childItem);
}
- if ( xmlLines.at(gamePos).contains(endMark) )
- gamePos--;
+ } else {
+ qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("WARNING: couldn't find machine information for '%1'").arg(machineName));
+ return;
}
- gamePos++;
- if ( childItem )
- itemList.append(childItem);
}
+
qmc2MainWindow->treeWidgetMachineList->setUpdatesEnabled(false);
delete item->takeChild(0);
item->addChildren(itemList);
@@ -1548,26 +1543,21 @@ void MachineList::parse()
machineListDb()->beginTransaction();
int pendingDbUpdates = 0;
for (qint64 rowCounter = 1; rowCounter <= xmlRowCount && !qmc2LoadingInterrupted; rowCounter++) {
- QStringList xmlLines(xmlDb()->xml(rowCounter).split(lineSplitChar, QString::SkipEmptyParts));
- for (int lineCounter = 0; lineCounter < xmlLines.count() && !qmc2LoadingInterrupted; lineCounter++) {
- while ( lineCounter < xmlLines.count() && !xmlLines.at(lineCounter).contains("<description>") )
- lineCounter++;
- if ( !qmc2LoadingInterrupted && lineCounter < xmlLines.count() ) {
- QString machineElement(xmlLines.at(lineCounter - 1).simplified());
- if ( !machineElement.contains(" name=\"") )
- continue;
- bool isBIOS = value(machineElement, "isbios").compare("yes") == 0;
- bool isDev = value(machineElement, "isdevice").compare("yes") == 0;
- QString machineName(value(machineElement, "name"));
+ QXmlStreamReader xmlMachineEntry(xmlDb()->xml(rowCounter));
+ if ( xmlMachineEntry.readNextStartElement() && !qmc2LoadingInterrupted ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ bool isBIOS = value(xmlMachineEntry, "isbios").compare("yes") == 0;
+ bool isDev = value(xmlMachineEntry, "isdevice").compare("yes") == 0;
+ QString machineName(value(xmlMachineEntry, "name"));
if ( machineName.isEmpty() ) {
- qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("WARNING: name attribute empty on XML line %1 (set will be ignored!) -- please inform MAME developers and include the offending output from -listxml").arg(lineCounter + 2));
+ qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("WARNING: name attribute empty on XML line %1 (set will be ignored!) -- please inform MAME developers and include the offending output from -listxml").arg(xmlMachineEntry.lineNumber()));
qApp->processEvents();
continue;
}
- QString machineSource(value(machineElement, "sourcefile"));
- QString machineCloneOf(value(machineElement, "cloneof"));
- QString descriptionElement(xmlLines.at(lineCounter).simplified());
- QString machineDescription(descriptionElement.remove("<description>").remove("</description>").replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"").replace("'", "'"));
+ QString machineSource(value(xmlMachineEntry, "sourcefile"));
+ QString machineCloneOf(value(xmlMachineEntry, "cloneof"));
+ QString descriptionElement;
+ QString machineDescription;
MachineListItem *machineItem = new MachineListItem();
qmc2MachineListItemHash.insert(machineName, machineItem);
machineItem->setFlags(MachineListItem::defaultItemFlags);
@@ -1576,37 +1566,39 @@ void MachineList::parse()
hiddenItemHash.insert(machineItem, true);
// find year & manufacturer and determine ROM/CHD requirements
bool endMachine = false;
- int i = lineCounter;
+
QString machineYear(trQuestionMark), machineManufacturer(trQuestionMark), machinePlayers(trQuestionMark), machineDrvStat(trQuestionMark);
bool yearFound = false, manufacturerFound = false, hasROMs = false, hasCHDs = false, playersFound = false, statusFound = false;
- QString endMark("</machine>");
- while ( !endMachine ) {
- QString xmlLine(xmlLines.at(i));
- if ( xmlLine.contains("<year>") ) {
- machineYear = xmlLine.simplified().remove("<year>").remove("</year>");
+ while ( xmlMachineEntry.readNextStartElement() && !endMachine ) {
+ if ( xmlMachineEntry.name() == "description" ) {
+ machineDescription = xmlMachineEntry.readElementText();
+ } else if ( xmlMachineEntry.name() == "year" ) {
+ machineYear = xmlMachineEntry.readElementText();
yearFound = true;
- } else if ( xmlLine.contains("<manufacturer>") ) {
- machineManufacturer = xmlLine.simplified().remove("<manufacturer>").remove("</manufacturer>").replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"").replace("'", "'");
+ } else if ( xmlMachineEntry.name() == "manufacturer" ) {
+ machineManufacturer = xmlMachineEntry.readElementText();
manufacturerFound = true;
- } else if ( xmlLine.contains("<rom name") ) {
+ } else if ( xmlMachineEntry.name() == "rom" ) {
hasROMs = true;
- } else if ( xmlLine.contains("<disk name") ) {
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "disk" ) {
hasCHDs = true;
- } else if ( xmlLine.contains("<input players") ) {
- int playersPos = xmlLine.indexOf("input players=\"") + 15;
- if ( playersPos >= 0 ) {
- machinePlayers = xmlLine.mid(playersPos, xmlLine.indexOf("\"", playersPos) - playersPos);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "input" ) {
+ if ( xmlMachineEntry.attributes().hasAttribute("players") ) {
+ machinePlayers = xmlMachineEntry.attributes().value("players").toString();
playersFound = true;
}
- } else if ( xmlLine.contains("<driver status") ) {
- int statusPos = xmlLine.indexOf("driver status=\"") + 15;
- if ( statusPos >= 0 ) {
- machineDrvStat = xmlLine.mid(statusPos, xmlLine.indexOf("\"", statusPos) - statusPos);
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "driver" ) {
+ if ( xmlMachineEntry.attributes().hasAttribute("status") ) {
+ machineDrvStat = xmlMachineEntry.attributes().value("status").toString();
statusFound = true;
}
- }
- endMachine = xmlLine.contains(endMark) || (yearFound && manufacturerFound && hasROMs && hasCHDs && playersFound && statusFound);
- i++;
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ endMachine = yearFound && manufacturerFound && hasROMs && hasCHDs && playersFound && statusFound;
}
if ( machineCloneOf.isEmpty() ) {
if ( !hierarchyHash.contains(machineName) )
@@ -2544,28 +2536,29 @@ void MachineList::verifyFinished(int exitCode, QProcess::ExitStatus exitStatus)
QTreeWidgetItem *versionItem = qmc2VersionItemHash.value(machineName);
// there are quite a number of sets in MAME that don't require any ROMs... many/most device-sets in particular
bool romRequired = true;
- int xmlCounter = 0;
- QStringList xmlLines(xmlDb()->xml(machineName).split("\n", QString::SkipEmptyParts));
- if ( xmlLines.count() > 0 ) {
- int romCounter = 0;
- int chdCounter = 0;
- bool endFound = false;
- QString endMark = "</machine>";
- while ( !endFound && xmlCounter < xmlLines.count() ) {
- if ( xmlLines.at(xmlCounter).contains("<rom name=\"") ) {
- romCounter++;
- endFound = true;
- } else if ( xmlLines.at(xmlCounter).contains("<disk name=\"") ) {
- chdCounter++;
- endFound = true;
- } else if ( xmlLines.at(xmlCounter).contains(endMark) )
- endFound = true;
- xmlCounter++;
+ QXmlStreamReader xmlMachineEntry(xmlDb()->xml(machineName));
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ int romCounter = 0;
+ int chdCounter = 0;
+ bool endFound = false;
+ while ( xmlMachineEntry.readNextStartElement() && !endFound ) {
+ if ( xmlMachineEntry.name() == "rom" ) {
+ romCounter++;
+ endFound = true;
+ xmlMachineEntry.skipCurrentElement();
+ } else if ( xmlMachineEntry.name() == "disk" ) {
+ chdCounter++;
+ endFound = true;
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
+ }
+ if ( romCounter == 0 && chdCounter > 0 )
+ romRequired = true;
+ else
+ romRequired = (romCounter > 0);
}
- if ( romCounter == 0 && chdCounter > 0 )
- romRequired = true;
- else
- romRequired = (romCounter > 0);
}
if ( romItem && hierarchyItem ) {
if ( romStateCache.isOpen() ) {
diff --git a/src/machinelist.h b/src/machinelist.h
index 8a4eee1e0..944ee88d0 100644
--- a/src/machinelist.h
+++ b/src/machinelist.h
@@ -132,11 +132,11 @@ class MachineList : public QObject
void verifyReadyReadStandardOutput();
// internal methods
- QString value(QString, QString, bool translate = false);
+ QString value(QXmlStreamReader &, QString, bool translate = false);
void parse();
void parseMachineDetail(QTreeWidgetItem *);
- void insertAttributeItems(QTreeWidgetItem *, QString, QStringList, QStringList, bool translate = false);
- void insertAttributeItems(QList<QTreeWidgetItem *> *itemList, QString element, QStringList attributes, QStringList descriptions, bool translate = false);
+ void insertAttributeItems(QTreeWidgetItem *, QXmlStreamReader &, QStringList, QStringList, bool translate = false);
+ void insertAttributeItems(QList<QTreeWidgetItem *> *itemList, QXmlStreamReader &element, QStringList attributes, QStringList descriptions, bool translate = false);
void enableWidgets(bool enable = true);
void disableWidgets() { enableWidgets(false); }
void filter(bool initial = false);
diff --git a/src/qmc2main.cpp b/src/qmc2main.cpp
index ec16009b2..e24fe89d6 100644
--- a/src/qmc2main.cpp
+++ b/src/qmc2main.cpp
@@ -4631,44 +4631,36 @@ QStringList &MainWindow::getXmlChoices(const QString &machineName, const QString
return xmlChoices;
if ( defaultChoice )
defaultChoice->clear();
- QStringList xmlLines(qmc2MachineList->xmlDb()->xml(machineName).split('\n', QString::SkipEmptyParts));
- QString defaultYes("default=\"yes\"");
- QString defaultOne("default=\"1\"");
- int i = 0;
- while ( i < xmlLines.count() ) {
- QString xmlLine(xmlLines.at(i++).simplified());
- int index = xmlLine.indexOf('<' + optionElement);
- if ( index >= 0 ) {
- if ( optionAttribute.isEmpty() ) {
- index = xmlLine.indexOf('>', index);
- if ( index >= 0 ) {
- xmlLine.remove(0, index + 1);
- bool isDefaultChoice = false;
- if ( defaultChoice && (xmlLine.indexOf(defaultYes) >= 0 || xmlLine.indexOf(defaultOne) >= 0 || defaultChoice->isEmpty()) )
- isDefaultChoice = true;
- xmlLine.replace("</" + optionElement + '>', "");
- QTextDocument doc;
- doc.setHtml(xmlLine);
- xmlLine = doc.toPlainText();
- xmlChoices << xmlLine;
- if ( isDefaultChoice )
- *defaultChoice = xmlLine;
- }
- } else {
- QString prefix(optionAttribute + "=\"");
- index = xmlLine.indexOf(prefix);
- if ( index >= 0 ) {
- xmlLine.remove(0, index + prefix.length());
- index = xmlLine.indexOf('\"');
- if ( index >= 0 ) {
+ QXmlStreamReader xmlMachineEntry(qmc2MachineList->xmlDb()->xml(machineName));
+ QString defaultYes("yes");
+ QString defaultOne("1");
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == optionElement ) {
+ if ( optionAttribute.isEmpty() ) {
+ bool isDefaultChoice = false;
+ if ( defaultChoice && (xmlMachineEntry.attributes().hasAttribute("default") && xmlMachineEntry.attributes().value("default").toString() == defaultYes || xmlMachineEntry.attributes().value("default").toString() == defaultOne || defaultChoice->isEmpty()) )
+ isDefaultChoice = true;
QTextDocument doc;
- doc.setHtml(xmlLine.left(index));
- QString choice = doc.toPlainText();
- xmlChoices << choice;
- if ( defaultChoice && (xmlLine.indexOf(defaultYes) >= 0 || xmlLine.indexOf(defaultOne) >= 0 || defaultChoice->isEmpty()) )
- *defaultChoice = choice;
+ doc.setHtml(xmlMachineEntry.readElementText());
+ QString xmlLine = doc.toPlainText();
+ xmlChoices << xmlLine;
+ if ( isDefaultChoice )
+ *defaultChoice = xmlLine;
+ } else {
+ if ( xmlMachineEntry.attributes().hasAttribute(optionAttribute) ) {
+ QTextDocument doc;
+ doc.setHtml(xmlMachineEntry.attributes().value(optionAttribute).toString());
+ QString choice = doc.toPlainText();
+ xmlChoices << choice;
+ if ( defaultChoice && (xmlMachineEntry.attributes().hasAttribute("default") && xmlMachineEntry.attributes().value("default").toString() == defaultYes || xmlMachineEntry.attributes().value("default").toString() == defaultOne || defaultChoice->isEmpty()) )
+ *defaultChoice = choice;
+ xmlMachineEntry.skipCurrentElement();
+ }
}
- }
+ } else
+ xmlMachineEntry.skipCurrentElement();
}
}
}
diff --git a/src/romalyzer.cpp b/src/romalyzer.cpp
index ddb5b0b38..902db6ed7 100644
--- a/src/romalyzer.cpp
+++ b/src/romalyzer.cpp
@@ -2753,18 +2753,15 @@ void ROMAlyzer::on_pushButtonChecksumWizardSearch_clicked()
lineEditSets->setEnabled(false);
labelStatus->setText(tr("Check-sum search"));
- QString hashStartString;
- int hashStartOffset;
+ QString hashAttribute;
switch ( comboBoxChecksumWizardHashType->currentIndex() ) {
case QMC2_ROMALYZER_CSF_HASHTYPE_CRC:
- hashStartString = "crc=\"";
- hashStartOffset = 5;
+ hashAttribute = "crc";
break;
default:
case QMC2_ROMALYZER_CSF_HASHTYPE_SHA1:
- hashStartString = "sha1=\"";
- hashStartOffset = 6;
+ hashAttribute = "sha1";
break;
}
@@ -2775,29 +2772,28 @@ void ROMAlyzer::on_pushButtonChecksumWizardSearch_clicked()
int progressCount = 0, updateCount = 0;
foreach (QString list, uniqueSoftwareLists) {
foreach (QString set, qmc2MainWindow->swlDb->uniqueSoftwareSets(list)) {
- QStringList xmlLines(qmc2MainWindow->swlDb->xml(list, set).split('\n', QString::SkipEmptyParts));
- for (int i = 0; i < xmlLines.count(); i++) {
- QString xmlLine(xmlLines.at(i));
- int hashIndex = xmlLine.indexOf(hashStartString);
- if ( hashIndex >= 0 ) {
- int hashPos = hashIndex + hashStartOffset;
- QString currentChecksum(xmlLine.mid(hashPos, xmlLine.indexOf('\"', hashPos) - hashPos).toLower());
- if ( currentChecksum.compare(searchedChecksum) == 0 ) {
- int fileNamePos;
- QString fileType;
- if ( xmlLine.startsWith("<disk name=\"") ) {
- fileType = tr("CHD");
- fileNamePos = xmlLine.indexOf("<disk name=\"") + 12;
- } else {
- fileType = tr("ROM");
- fileNamePos = xmlLine.indexOf("<rom name=\"") + 11;
- }
- QString fileName(xmlLine.mid(fileNamePos, xmlLine.indexOf('\"', fileNamePos) - fileNamePos));
- QTreeWidgetItem *item = new QTreeWidgetItem(treeWidgetChecksumWizardSearchResult);
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_ID, list + ":" + set);
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_FILENAME, fileName.replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"").replace("'", "'"));
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_TYPE, fileType);
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_STATUS, tr("unknown"));
+ QXmlStreamReader xmlMachineEntry(qmc2MainWindow->swlDb->xml(list, set));
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.attributes().hasAttribute(hashAttribute) ) {
+ QString currentChecksum(xmlMachineEntry.attributes().value(hashAttribute).toString().toLower());
+ if ( currentChecksum.compare(searchedChecksum) == 0 ) {
+ QString fileType;
+ if ( xmlMachineEntry.name() == "disk" )
+ fileType = tr("CHD");
+ else
+ fileType = tr("ROM");
+ QString fileName(xmlMachineEntry.attributes().value("name").toString());
+ QTreeWidgetItem *item = new QTreeWidgetItem(treeWidgetChecksumWizardSearchResult);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_ID, list + ":" + set);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_FILENAME, fileName);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_TYPE, fileType);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_STATUS, tr("unknown"));
+ }
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
}
}
}
@@ -2820,29 +2816,28 @@ void ROMAlyzer::on_pushButtonChecksumWizardSearch_clicked()
qApp->processEvents();
}
QString currentMachine(qmc2MainWindow->treeWidgetMachineList->topLevelItem(i)->text(QMC2_MACHINELIST_COLUMN_NAME));
- QStringList xmlLines(qmc2MachineList->xmlDb()->xml(currentMachine).split('\n', QString::SkipEmptyParts));
- for (int j = 0; j < xmlLines.count(); j++) {
- QString xmlLine(xmlLines.at(j));
- int hashIndex = xmlLine.indexOf(hashStartString);
- if ( hashIndex >= 0 ) {
- int hashPos = hashIndex + hashStartOffset;
- QString currentChecksum(xmlLine.mid(hashPos, xmlLine.indexOf('\"', hashPos) - hashPos).toLower());
- if ( currentChecksum.compare(searchedChecksum) == 0 ) {
- int fileNamePos;
- QString fileType;
- if ( xmlLine.startsWith("<disk name=\"") ) {
- fileType = tr("CHD");
- fileNamePos = xmlLine.indexOf("<disk name=\"") + 12;
- } else {
- fileType = tr("ROM");
- fileNamePos = xmlLine.indexOf("<rom name=\"") + 11;
- }
- QString fileName(xmlLine.mid(fileNamePos, xmlLine.indexOf('\"', fileNamePos) - fileNamePos));
- QTreeWidgetItem *item = new QTreeWidgetItem(treeWidgetChecksumWizardSearchResult);
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_ID, currentMachine);
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_FILENAME, fileName.replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"").replace("'", "'"));
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_TYPE, fileType);
- item->setText(QMC2_ROMALYZER_CSF_COLUMN_STATUS, tr("unknown"));
+ QXmlStreamReader xmlMachineEntry(qmc2MachineList->xmlDb()->xml(currentMachine));
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.attributes().hasAttribute(hashAttribute) ) {
+ QString currentChecksum(xmlMachineEntry.attributes().value(hashAttribute).toString().toLower());
+ if ( currentChecksum.compare(searchedChecksum) == 0 ) {
+ QString fileType;
+ if ( xmlMachineEntry.name() == "disk" )
+ fileType = tr("CHD");
+ else
+ fileType = tr("ROM");
+ QString fileName(xmlMachineEntry.attributes().value("name").toString());
+ QTreeWidgetItem *item = new QTreeWidgetItem(treeWidgetChecksumWizardSearchResult);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_ID, currentMachine);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_FILENAME, fileName);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_TYPE, fileType);
+ item->setText(QMC2_ROMALYZER_CSF_COLUMN_STATUS, tr("unknown"));
+ }
+ xmlMachineEntry.skipCurrentElement();
+ } else
+ xmlMachineEntry.skipCurrentElement();
}
}
}
diff --git a/src/softwarelist.cpp b/src/softwarelist.cpp
index 99f806da4..13c1f0f55 100644
--- a/src/softwarelist.cpp
+++ b/src/softwarelist.cpp
@@ -1012,6 +1012,7 @@ QString &SoftwareList::lookupMountDevice(QString device, QString deviceInterface
QStringList xmlLines(qmc2MachineList->xmlDb()->xml(systemName).split('\n', QString::SkipEmptyParts));
QStringList *xmlData = &xmlLines;
QStringList dynamicXmlData;
+ QXmlStreamReader xmlMachineEntry(qmc2MachineList->xmlDb()->xml(systemName));
if ( comboBoxDeviceConfiguration->currentIndex() > 0 ) {
qmc2Config->beginGroup(QMC2_EMULATOR_PREFIX + QString("Configuration/Devices/%1/%2").arg(systemName).arg(comboBoxDeviceConfiguration->currentText()));
QStringList instances(qmc2Config->value("Instances").toStringList());
@@ -1047,37 +1048,34 @@ QString &SoftwareList::lookupMountDevice(QString device, QString deviceInterface
#endif
}
- int i = 0;
- while ( i < xmlData->count() && !xmlData->at(i).contains("</machine>") ) {
- QString line(xmlData->at(i++).simplified());
- if ( line.startsWith("<device type=\"") ) {
- int startIndex = line.indexOf("interface=\"");
- int endIndex = -1;
- QString devName;
- if ( startIndex >= 0 ) {
- startIndex += 11;
- endIndex = line.indexOf("\"", startIndex);
- QStringList devInterfaces(line.mid(startIndex, endIndex - startIndex).split(',', QString::SkipEmptyParts));
- line = xmlData->at(i++).simplified();
- startIndex = line.indexOf("briefname=\"");
- if ( startIndex >= 0 ) {
- startIndex += 11;
- endIndex = line.indexOf("\"", startIndex);
- devName = line.mid(startIndex, endIndex - startIndex);
- }
- if ( !devName.isEmpty() )
- foreach (QString devIf, devInterfaces)
- deviceInstanceHash[devIf] << devName;
- } else {
- line = xmlData->at(i++).simplified();
- startIndex = line.indexOf("briefname=\"");
- if ( startIndex >= 0 ) {
- startIndex += 11;
- endIndex = line.indexOf("\"", startIndex);
- devName = line.mid(startIndex, endIndex - startIndex);
- }
- if ( !devName.isEmpty() )
- deviceInstanceHash[devName] << devName;
+ if ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "machine" ) {
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "device" && xmlMachineEntry.attributes().hasAttribute("type") ) {
+ QString devName;
+ if ( xmlMachineEntry.attributes().hasAttribute("interface") ) {
+ QStringList devInterfaces(xmlMachineEntry.attributes().value("interface").toString().split(',', QString::SkipEmptyParts));
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "instance" && xmlMachineEntry.attributes().hasAttribute("briefname") ) {
+ devName = xmlMachineEntry.attributes().value("briefname").toString();
+ if ( !devName.isEmpty() )
+ foreach (QString devIf, devInterfaces)
+ deviceInstanceHash[devIf] << devName;
+ }
+ xmlMachineEntry.skipCurrentElement();
+ }
+ } else {
+ while ( xmlMachineEntry.readNextStartElement() ) {
+ if ( xmlMachineEntry.name() == "instance" && xmlMachineEntry.attributes().hasAttribute("briefname") ) {
+ devName = xmlMachineEntry.attributes().value("briefname").toString();
+ if ( !devName.isEmpty() )
+ deviceInstanceHash[devName] << devName;
+ }
+ xmlMachineEntry.skipCurrentElement();
+ }
+ }
+ } else
+ xmlMachineEntry.skipCurrentElement();
}
}
}
--
2.44.0