diff --git a/gui/main.ui b/gui/main.ui index 3e0a708c3..3317d4452 100644 --- a/gui/main.ui +++ b/gui/main.ui @@ -73,6 +73,7 @@ &File + @@ -347,6 +348,11 @@ Error categories + + + &Open XML... + + diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 15d4b08de..81acef2b7 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -56,6 +56,7 @@ MainWindow::MainWindow() : connect(mUI.mActionCheckDirectory, SIGNAL(triggered()), this, SLOT(CheckDirectory())); connect(mUI.mActionSettings, SIGNAL(triggered()), this, SLOT(ProgramSettings())); connect(mUI.mActionClearResults, SIGNAL(triggered()), this, SLOT(ClearResults())); + connect(mUI.mActionOpenXML, SIGNAL(triggered()), this, SLOT(OpenXML())); connect(mUI.mActionShowStyle, SIGNAL(toggled(bool)), this, SLOT(ShowStyle(bool))); connect(mUI.mActionShowErrors, SIGNAL(toggled(bool)), this, SLOT(ShowErrors(bool))); @@ -431,6 +432,22 @@ void MainWindow::ClearResults() mUI.mActionSave->setEnabled(false); } +void MainWindow::OpenXML() +{ + QString selectedFilter; + QString filter(tr("XML files (*.xml)")); + QString selectedFile = QFileDialog::getOpenFileName(this, + tr("Open the report file"), + QString(), + filter, + &selectedFilter); + + if (!selectedFile.isEmpty()) + { + mUI.mResults->ReadErrorsXml(selectedFile); + } +} + void MainWindow::EnableCheckButtons(bool enable) { mUI.mActionStop->setEnabled(!enable); diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 0fa17db2d..3142dccaa 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -67,6 +67,12 @@ public slots: */ void ClearResults(); + /** + * @brief Slot to open XML report file + * + */ + void OpenXML(); + /** * @brief Show errors with type "style" * @param checked Should errors be shown (true) or hidden (false) diff --git a/gui/report.cpp b/gui/report.cpp index 0fbfc4e54..cd2c911bd 100644 --- a/gui/report.cpp +++ b/gui/report.cpp @@ -41,6 +41,17 @@ bool Report::Create() return succeed; } +bool Report::Open() +{ + bool succeed = false; + if (!mFile.isOpen()) + { + mFile.setFileName(mFilename); + succeed = mFile.open(QIODevice::ReadOnly | QIODevice::Text); + } + return succeed; +} + void Report::Close() { if (mFile.isOpen()) diff --git a/gui/report.h b/gui/report.h index 5459e31ee..9e8972951 100644 --- a/gui/report.h +++ b/gui/report.h @@ -50,6 +50,12 @@ public: */ virtual bool Create(); + /** + * @brief Open the existing report (file). + * @return true if succeeded, false if file could not be created. + */ + virtual bool Open(); + /** * @brief Close the report (file). */ diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index f0f3e37f2..9c3b14a77 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -217,3 +217,29 @@ void ResultsView::DisableProgressbar() { mUI.mProgress->setEnabled(false); } + +void ResultsView::ReadErrorsXml(const QString &filename) +{ + XmlReport *report = new XmlReport(filename, this); + if (report) + { + if (report->Open()) + report->Read(); + else + { + QMessageBox msgBox; + msgBox.setText(tr("Failed to read the report.")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.exec(); + } + delete report; + report = NULL; + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("Failed to read the report.")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.exec(); + } +} diff --git a/gui/resultsview.h b/gui/resultsview.h index cb3f4abb1..6b9161581 100644 --- a/gui/resultsview.h +++ b/gui/resultsview.h @@ -129,6 +129,14 @@ public: void Translate(); void DisableProgressbar(); + + /** + * @brief Read errors from report XML file. + * @param filename Report file to read. + * + */ + void ReadErrorsXml(const QString &filename); + signals: /** diff --git a/gui/xmlreport.cpp b/gui/xmlreport.cpp index 41dbfe5f3..30d0e2d6b 100644 --- a/gui/xmlreport.cpp +++ b/gui/xmlreport.cpp @@ -18,16 +18,27 @@ #include #include +#include #include "xmlreport.h" +static const char ResultElementName[] = "results"; +static const char ErrorElementName[] = "error"; +static const char FilenameAttribute[] = "file"; +static const char LineAttribute[] = "line"; +static const char IdAttribute[] = "id"; +static const char SeverityAttribute[] = "severity"; +static const char MsgAttribute[] = "msg"; + XmlReport::XmlReport(const QString &filename, QObject * parent) : Report(filename, parent), + mXmlReader(NULL), mXmlWriter(NULL) { } XmlReport::~XmlReport() { + delete mXmlReader; delete mXmlWriter; Close(); } @@ -43,11 +54,22 @@ bool XmlReport::Create() return success; } +bool XmlReport::Open() +{ + bool success = false; + if (Report::Open()) + { + mXmlReader = new QXmlStreamReader(Report::GetFile()); + success = true; + } + return success; +} + void XmlReport::WriteHeader() { mXmlWriter->setAutoFormatting(true); mXmlWriter->writeStartDocument(); - mXmlWriter->writeStartElement("results"); + mXmlWriter->writeStartElement(ResultElementName); } void XmlReport::WriteFooter() @@ -65,11 +87,66 @@ void XmlReport::WriteError(const QStringList &files, const QStringList &lines, The callstack seems to be ignored here aswell, instead last item of the stack is used */ - mXmlWriter->writeStartElement("error"); - mXmlWriter->writeAttribute("file", files[files.size() - 1]); - mXmlWriter->writeAttribute("line", lines[lines.size() - 1]); - mXmlWriter->writeAttribute("id", id); - mXmlWriter->writeAttribute("severity", severity); - mXmlWriter->writeAttribute("msg", msg); + mXmlWriter->writeStartElement(ErrorElementName); + mXmlWriter->writeAttribute(FilenameAttribute, files[files.size() - 1]); + mXmlWriter->writeAttribute(LineAttribute, lines[lines.size() - 1]); + mXmlWriter->writeAttribute(IdAttribute, id); + mXmlWriter->writeAttribute(SeverityAttribute, severity); + mXmlWriter->writeAttribute(MsgAttribute, msg); mXmlWriter->writeEndElement(); } + +void XmlReport::Read() +{ + bool insideResults = false; + if (!mXmlReader) + { + qDebug() << "You must Open() the file before reading it!"; + return; + } + while (!mXmlReader->atEnd()) + { + switch (mXmlReader->readNext()) + { + case QXmlStreamReader::StartElement: + if (mXmlReader->name() == ResultElementName) + insideResults = true; + + // Read error element from inside result element + if (insideResults && mXmlReader->name() == ErrorElementName) + ReadError(mXmlReader); + break; + + case QXmlStreamReader::EndElement: + if (mXmlReader->name() == ResultElementName) + insideResults = false; + break; + + // Not handled + case QXmlStreamReader::NoToken: + case QXmlStreamReader::Invalid: + case QXmlStreamReader::StartDocument: + case QXmlStreamReader::EndDocument: + case QXmlStreamReader::Characters: + case QXmlStreamReader::Comment: + case QXmlStreamReader::DTD: + case QXmlStreamReader::EntityReference: + case QXmlStreamReader::ProcessingInstruction: + break; + } + } +} + +void XmlReport::ReadError(QXmlStreamReader *reader) +{ + if (reader->name().toString() == ErrorElementName) + { + QXmlStreamAttributes attribs = reader->attributes(); + QString filename = attribs.value("", FilenameAttribute).toString(); + QString line = attribs.value("", LineAttribute).toString(); + QString id = attribs.value("", IdAttribute).toString(); + QString severity = attribs.value("", SeverityAttribute).toString(); + QString msg = attribs.value("", MsgAttribute).toString(); + qDebug() << "Error: " << filename << " " << line << " " << id << " " << severity << " " << msg; + } +} diff --git a/gui/xmlreport.h b/gui/xmlreport.h index cacdd4dec..06c0fbf35 100644 --- a/gui/xmlreport.h +++ b/gui/xmlreport.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "report.h" @@ -47,6 +48,11 @@ public: */ virtual bool Create(); + /** + * @brief Open existing report file. + */ + bool Open(); + /** * @brief Write report header. */ @@ -63,7 +69,23 @@ public: virtual void WriteError(const QStringList &files, const QStringList &lines, const QString &id, const QString &severity, const QString &msg); + /** + * @brief Read contents of the report file. + */ + void Read(); + +protected: + /** + * @brief Read and parse error item from XML stream. + * @param reader XML stream reader to use. + */ + void ReadError(QXmlStreamReader *reader); + private: + /** + * @brief XML stream reader for reading the report in XML format. + */ + QXmlStreamReader *mXmlReader; /** * @brief XML stream writer for writing the report in XML format.