Files
GoldenCheetah/src/Train/VideoLayoutParser.cpp
Peter Kanatselis 2d1e36549c Live map with route (#3534)
* Updated LiveMap widget with route
* OSM URL configurable in video-layout.xml file
* Enhanced HTML and JS code
2020-12-03 21:02:44 -03:00

325 lines
11 KiB
C++

/*
* Copyright (c) 2015 Vianney Boyer (vlcvboyer@gmail.com) copied from
* GPXParser.cpp
* Copyright (c) 2010 Greg Lonnon (greg.lonnon@gmail.com)
* Copyright (c) 2008 Sean C. Rhea (srhea@srhea.net),
* J.T Conklin (jtc@acorntoolworks.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 <QString>
#include <QDebug>
#include "VideoLayoutParser.h"
#include "MeterWidget.h"
VideoLayoutParser::VideoLayoutParser (QList<MeterWidget*>* metersWidget, QList<QString>* layoutNames, QWidget* VideoContainer)
: metersWidget(metersWidget), layoutNames(layoutNames), VideoContainer(VideoContainer)
{
nonameindex = 0;
skipLayout = false;
layoutPosition = 0;
meterWidget = NULL;
}
void VideoLayoutParser::SetDefaultValues()
{
meterWidget->m_RelativeWidth = 20.0;
meterWidget->m_RelativeHeight = 20.0;
meterWidget->m_RelativePosX = 50.0;
meterWidget->m_RelativePosY = 80.0;
meterWidget->m_RangeMin = 0.0;
meterWidget->m_RangeMax = 80.0;
meterWidget->m_MainColor = QColor(255,0,0,200);
meterWidget->m_ScaleColor = QColor(255,255,255,200);
meterWidget->m_OutlineColor = QColor(100,100,100,200);
meterWidget->m_BackgroundColor = QColor(100,100,100,0);
meterWidget->m_BoundingRectColor = QColor(150,150,150,100);
meterWidget->m_MainFont = QFont(meterWidget->font().family(), 64);
meterWidget->m_AltFont = QFont(meterWidget->font().family(), 48);
meterWidget->m_VideoContainer = VideoContainer;
meterWidget->Text = "";
meterWidget->AltText = "";
meterWidget->AltTextSuffix = "";
}
QColor GetColorFromFields(const QXmlAttributes& qAttributes)
{
int i;
int R,G,B,A;
// reset all
R=G=B=A=0;
if((i = qAttributes.index("R"))>= 0)
R = qAttributes.value(i).toInt();
if((i = qAttributes.index("G"))>= 0)
G = qAttributes.value(i).toInt();
if((i = qAttributes.index("B"))>= 0)
B = qAttributes.value(i).toInt();
if((i = qAttributes.index("A"))>= 0)
A = qAttributes.value(i).toInt();
return QColor(R,G,B,A);
}
bool VideoLayoutParser::startElement( const QString&, const QString&,
const QString& qName,
const QXmlAttributes& qAttributes)
{
QString source;
QString meterName;
QString meterType;
QString container; // will be "Video" when not defined otherwise another meter name (allows positioning of one meter inside another one)
int textWidth;
Qt::Alignment alignment;
bool boundingRectVisibility;
bool backgroundVisibility;
if(skipLayout) return true;
buffer.clear();
if(qName == "layout")
{
int i = qAttributes.index("name");
layoutNames->append(i >= 0 ? qAttributes.value(i) : QString("noname_") + QString::number(layoutPosition));
if(layoutPositionSelected != layoutPosition) skipLayout = true;
}
else if(qName == "meter")
{
int i = qAttributes.index("name"); // To be used to enclose another sub meter (typ. text within NeedleMeter)
if(i >= 0)
meterName = qAttributes.value(i);
else
meterName = QString("noname_") + QString::number(nonameindex++);
i = qAttributes.index("container"); // Video, ... or other meter name
if(i >= 0)
container = qAttributes.value(i);
else
container = QString("Video");
i = qAttributes.index("source"); // Watt, Speed...
if(i >= 0)
source = qAttributes.value(i);
else
source = QString("None");
i = qAttributes.index("type"); // Text, NeedleMeter, CircularMeter...
if(i >= 0)
meterType = qAttributes.value(i);
else
meterType = QString("Text");
i = qAttributes.index("alignment");
if(i >= 0)
if(qAttributes.value(i) == QString("AlignLeft")) alignment = Qt::AlignLeft;
else if(qAttributes.value(i) == QString("AlignRight")) alignment = Qt::AlignRight;
else alignment = Qt::AlignHCenter;
else
alignment = Qt::AlignHCenter;
i = qAttributes.index("textWidth");
if(i >= 0)
textWidth = qAttributes.value(i).toInt();
else
textWidth = 0;
i = qAttributes.index("BoundingRect");
if(i >= 0 && qAttributes.value(i) == QString("true"))
boundingRectVisibility = true;
else
boundingRectVisibility = false;
i = qAttributes.index("Background");
if(i >= 0 && qAttributes.value(i) == QString("true"))
backgroundVisibility = true;
else
backgroundVisibility = false;
//TODO: allow creation of meter when container will be created later
QWidget* containerWidget = NULL;
if (container == QString("Video"))
{
containerWidget = VideoContainer;
}
else
{
foreach(MeterWidget* p_meterWidget , *metersWidget)
{
if (p_meterWidget->m_Name == container)
containerWidget = p_meterWidget;
}
}
//create meter object
if (meterType == QString("Text"))
{
meterWidget = new TextMeterWidget(meterName, containerWidget, source);
}
else if (meterType == QString("NeedleMeter"))
{
meterWidget = new NeedleMeterWidget(meterName, containerWidget, source);
}
else if (meterType == QString("CircularMeter"))
{
meterWidget = new CircularIndicatorMeterWidget(meterName, containerWidget, source);
}
else if (meterType == QString("CircularBargraph"))
{
meterWidget = new CircularBargraphMeterWidget(meterName, containerWidget, source);
}
else if (meterType == QString("Elevation"))
{
meterWidget = new ElevationMeterWidget(meterName, containerWidget, source);
}
else if (meterType == QString("LiveMap"))
{
meterWidget = new LiveMapWidget(meterName, containerWidget, source);
}
else
{
qDebug() << QObject::tr("Error creating meter");
}
if (meterWidget)
{
SetDefaultValues();
meterWidget->textWidth = textWidth;
meterWidget->alignment = alignment;
meterWidget->boundingRectVisibility = boundingRectVisibility;
meterWidget->backgroundVisibility = backgroundVisibility;
}
}
else if ((qName == "MainColor") && meterWidget)
meterWidget->m_MainColor = GetColorFromFields(qAttributes);
else if ((qName == "OutlineColor") && meterWidget)
meterWidget->m_OutlineColor = GetColorFromFields(qAttributes);
else if ((qName == "ScaleColor") && meterWidget)
meterWidget->m_ScaleColor = GetColorFromFields(qAttributes);
else if ((qName == "BackgroundColor") && meterWidget)
meterWidget->m_BackgroundColor = GetColorFromFields(qAttributes);
else if ((qName == "BoundingRectColor") && meterWidget)
meterWidget->m_BoundingRectColor = GetColorFromFields(qAttributes);
else if ((qName == "RelativeSize") && meterWidget)
{
int i;
if ((i = qAttributes.index("Width")) >= 0)
meterWidget->m_RelativeWidth = qAttributes.value(i).toFloat()/100.0;
if ((i = qAttributes.index("Height")) >= 0)
meterWidget->m_RelativeHeight = qAttributes.value(i).toFloat()/100.0;
}
else if ((qName == "RelativePosition") && meterWidget)
{
int i;
if ((i = qAttributes.index("X")) >= 0)
meterWidget->m_RelativePosX = qAttributes.value(i).toFloat()/100.0;
if ((i = qAttributes.index("Y")) >= 0)
meterWidget->m_RelativePosY = qAttributes.value(i).toFloat()/100.0;
}
else if ((qName == "Range") && meterWidget)
{
int i;
if ((i = qAttributes.index("Min")) >= 0)
meterWidget->m_RangeMin = qAttributes.value(i).toFloat();
if ((i = qAttributes.index("Max")) >= 0)
meterWidget->m_RangeMax = qAttributes.value(i).toFloat();
}
else if ((qName == "MainFont") && meterWidget)
{
int i;
int FontSize = 64;
QString FontName = "Arial";
if ((i = qAttributes.index("Name")) >= 0)
FontName = qAttributes.value(i);
if ((i = qAttributes.index("Size")) >= 0)
FontSize = qAttributes.value(i).toInt();
meterWidget->m_MainFont = QFont(FontName, FontSize);
// Set fixed width, otherwise the meter digits keep moving sideways from a thin "1" to a fat "5"
meterWidget->m_MainFont.setFixedPitch(true);
}
else if ((qName == "AltFont") && meterWidget)
{
int i;
int FontSize = 48;
QString FontName = "Arial";
if ((i = qAttributes.index("Name")) >= 0)
FontName = qAttributes.value(i);
if ((i = qAttributes.index("Size")) >= 0)
FontSize = qAttributes.value(i).toInt();
meterWidget->m_AltFont = QFont(FontName, FontSize);
meterWidget->m_AltFont.setFixedPitch(true);
}
else if(qName != "layouts" && qName != "Text" && qName != "AltText" && qName != "Angle" && qName != "SubRange" && qName != "Zoom")
{
qDebug() << QObject::tr("Unknown start element ") << qName;
}
return true;
}
bool VideoLayoutParser::endElement( const QString&, const QString&, const QString& qName)
{
if(qName == "layout")
{
layoutPosition++;
skipLayout = false;
return true;
}
if(skipLayout) return true;
if (meterWidget)
{
if (qName == "Angle")
meterWidget->m_Angle = buffer.toFloat();
else if (qName == "SubRange")
meterWidget->m_SubRange = buffer.toInt();
else if (qName == "Text")
meterWidget->Text = QString(buffer);
else if (qName == "AltText")
meterWidget->AltTextSuffix = QString(buffer);
else if (qName == "meter")
{
if (metersWidget)
metersWidget->append(meterWidget);
meterWidget = NULL;
}
LiveMapWidget* liveMapWidget = dynamic_cast<LiveMapWidget*>(meterWidget);
if (liveMapWidget != NULL)
{
if (qName == "Zoom")
liveMapWidget->m_Zoom = buffer.toInt();
else if (qName == "osmURL")
liveMapWidget->m_osmURL = QString(buffer);
}
return true;
}
else
return false;
}
bool VideoLayoutParser::characters( const QString& str )
{
if(skipLayout) return true;
buffer += str;
return true;
}