/* * Copyright (c) 2010 Mark Liversedge (liversedge@gmail.com) * * 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. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "LTMChartParser.h" #include "LTMSettings.h" #include "LTMTool.h" #include #include #include // local helper functions to convert Qwt enums to ints and back static int curveToInt(QwtPlotCurve::CurveStyle x) { switch (x) { case QwtPlotCurve::NoCurve : return 0; case QwtPlotCurve::Lines : return 1; case QwtPlotCurve::Sticks : return 2; case QwtPlotCurve::Steps : return 3; case QwtPlotCurve::Dots : return 4; default : return 100; } } static QwtPlotCurve::CurveStyle intToCurve(int x) { switch (x) { default: case 0 : return QwtPlotCurve::NoCurve; case 1 : return QwtPlotCurve::Lines; case 2 : return QwtPlotCurve::Sticks; case 3 : return QwtPlotCurve::Steps; case 4 : return QwtPlotCurve::Dots; case 100: return QwtPlotCurve::UserCurve; } } static int symbolToInt(QwtSymbol::Style x) { switch (x) { default: case QwtSymbol::NoSymbol: return -1; case QwtSymbol::Ellipse: return 0; case QwtSymbol::Rect: return 1; case QwtSymbol::Diamond: return 2; case QwtSymbol::Triangle: return 3; case QwtSymbol::DTriangle: return 4; case QwtSymbol::UTriangle: return 5; case QwtSymbol::LTriangle: return 6; case QwtSymbol::RTriangle: return 7; case QwtSymbol::Cross: return 8; case QwtSymbol::XCross: return 9; case QwtSymbol::HLine: return 10; case QwtSymbol::VLine: return 11; case QwtSymbol::Star1: return 12; case QwtSymbol::Star2: return 13; case QwtSymbol::Hexagon: return 14; case QwtSymbol::StyleCnt: return 15; } } static QwtSymbol::Style intToSymbol(int x) { switch (x) { default: case -1: return QwtSymbol::NoSymbol; case 0 : return QwtSymbol::Ellipse; case 1 : return QwtSymbol::Rect; case 2 : return QwtSymbol::Diamond; case 3 : return QwtSymbol::Triangle; case 4 : return QwtSymbol::DTriangle; case 5 : return QwtSymbol::UTriangle; case 6 : return QwtSymbol::LTriangle; case 7 : return QwtSymbol::RTriangle; case 8 : return QwtSymbol::Cross; case 9 : return QwtSymbol::XCross; case 10 : return QwtSymbol::HLine; case 11 : return QwtSymbol::VLine; case 12 : return QwtSymbol::Star1; case 13 : return QwtSymbol::Star2; case 14 : return QwtSymbol::Hexagon; case 15 : return QwtSymbol::StyleCnt; } } bool LTMChartParser::startDocument() { buffer.clear(); return TRUE; } static QString unprotect(QString buffer) { // get local TM character code QTextEdit trademark("™"); // process html encoding of(TM) QString tm = trademark.toPlainText(); // remove quotes QString t = buffer.trimmed(); QString s = t.mid(1,t.length()-2); // replace html (TM) with local TM character s.replace( "™", tm ); // html special chars are automatically handled // XXX other special characters will not work // cross-platform but will work locally, so not a biggie // i.e. if thedefault charts.xml has a special character // in it it should be added here return s; } // to see the format of the charts.xml file, look at the serialize() // function at the bottom of this source file. bool LTMChartParser::endElement( const QString&, const QString&, const QString &qName ) { // // Single Attribute elements // if(qName == "chartname") setting.name = unprotect(buffer); else if(qName == "metricname") metric.symbol = buffer.trimmed(); else if(qName == "metricdesc") metric.name = unprotect(buffer); else if(qName == "metricuname") metric.uname = unprotect(buffer); else if(qName == "metricuunits") metric.uunits = unprotect(buffer); else if(qName == "metricbaseline") metric.baseline = buffer.trimmed().toDouble(); else if(qName == "metricsmooth") metric.smooth = buffer.trimmed().toInt(); else if(qName == "metrictrend") metric.trend = buffer.trimmed().toInt(); else if(qName == "metrictopn") metric.topN = buffer.trimmed().toInt(); else if(qName == "metriccurve") metric.curveStyle = intToCurve(buffer.trimmed().toInt()); else if(qName == "metricsymbol") metric.symbolStyle = intToSymbol(buffer.trimmed().toInt()); else if(qName == "metricpencolor") { // the r,g,b values are in red="xx",green="xx" and blue="xx" attributes // of this element and captured in startelement below metric.penColor = QColor(red,green,blue); } else if(qName == "metricpenalpha") metric.penAlpha = buffer.trimmed().toInt(); else if(qName == "metricpenwidth") metric.penWidth = buffer.trimmed().toInt(); else if(qName == "metricpenstyle") metric.penStyle = buffer.trimmed().toInt(); else if(qName == "metricbrushcolor") { // the r,g,b values are in red="xx",green="xx" and blue="xx" attributes // of this element and captured in startelement below metric.brushColor = QColor(red,green,blue); } else if(qName == "metricbrushalpha") metric.penAlpha = buffer.trimmed().toInt(); // // Complex Elements // else if(qName == "metric") // block setting.metrics.append(metric); else if (qName == "LTM-chart") // block settings.append(setting); else if (qName == "charts") { // block top-level } // do nothing for now return TRUE; } bool LTMChartParser::startElement( const QString&, const QString&, const QString &name, const QXmlAttributes &attrs ) { buffer.clear(); if(name == "charts") ; // do nothing for now else if (name == "LTM-chart") setting = LTMSettings(); else if (name == "metric") metric = MetricDetail(); else if (name == "metricpencolor" || name == "metricbrushcolor") { // red="x" green="x" blue="x" attributes for pen/brush color for(int i=0; i LTMChartParser::getSettings() { return settings; } bool LTMChartParser::endDocument() { return TRUE; } // static helper to protect special xml characters // ideally we would use XMLwriter to do this but // the file format is trivial and this implementation // is easier to follow and modify... for now. static QString xmlprotect(QString string) { QTextEdit trademark("™"); // process html encoding of(TM) QString tm = trademark.toPlainText(); QString s = string; s.replace( tm, "™" ); s.replace( "&", "&" ); s.replace( ">", ">" ); s.replace( "<", "<" ); s.replace( "\"", """ ); s.replace( "\'", "'" ); return s; } // // Write out the charts.xml file // void LTMChartParser::serialize(QString filename, QList charts) { // open file - truncate contents QFile file(filename); file.open(QFile::WriteOnly); file.resize(0); QTextStream out(&file); // begin document out << "\n"; // write out to file foreach (LTMSettings chart, charts) { // chart name out<\n\t\t\"%1\"\n").arg(xmlprotect(chart.name)); // all the metrics foreach (MetricDetail metric, chart.metrics) { out<\n"); out<\"%1\"\n").arg(xmlprotect(metric.name)); out<%1\n").arg(metric.symbol); out<\"%1\"\n").arg(xmlprotect(metric.uname)); out<\"%1\"\n").arg(xmlprotect(metric.uunits)); // SMOOTH, TREND, TOPN out<%1\n").arg(metric.smooth); out<%1\n").arg(metric.trend); out<%1\n").arg(metric.topN); out<%1\n").arg(metric.baseline); // CURVE, SYMBOL out<%1\n").arg(curveToInt(metric.curveStyle)); out<%1\n").arg(symbolToInt(metric.symbolStyle)); // PEN out<\n") .arg(metric.penColor.red()) .arg(metric.penColor.green()) .arg(metric.penColor.blue()); out<%1\n").arg(metric.penAlpha); out<%1\n").arg(metric.penWidth); out<%1\n").arg(metric.penStyle); // BRUSH out<\n") .arg(metric.brushColor.red()) .arg(metric.brushColor.green()) .arg(metric.brushColor.blue()); out<%1\n").arg(metric.brushAlpha); out<\n"); } out<\n"); } // end document out << "\n"; // close file file.close(); }