|
|
|
@ -40,6 +40,7 @@ |
|
|
|
|
#include "domain/UBGraphicsPixmapItem.h" |
|
|
|
|
#include "domain/UBGraphicsProxyWidget.h" |
|
|
|
|
#include "domain/UBGraphicsPolygonItem.h" |
|
|
|
|
#include "domain/UBGraphicsLineItem.h" |
|
|
|
|
#include "domain/UBGraphicsMediaItem.h" |
|
|
|
|
#include "domain/UBGraphicsWidgetItem.h" |
|
|
|
|
#include "domain/UBGraphicsPDFItem.h" |
|
|
|
@ -618,6 +619,47 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx |
|
|
|
|
group->addToGroup(polygonItem); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (mXmlReader.name() == "lineL") |
|
|
|
|
{ |
|
|
|
|
UBGraphicsLineItem* lineItem = 0; |
|
|
|
|
|
|
|
|
|
QString parentId = mXmlReader.attributes().value(mNamespaceUri, "parent").toString(); |
|
|
|
|
|
|
|
|
|
lineItem = lineItemFromLineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black); |
|
|
|
|
|
|
|
|
|
if(parentId.isEmpty() && strokesGroup) |
|
|
|
|
parentId = strokesGroup->uuid().toString(); |
|
|
|
|
|
|
|
|
|
if(parentId.isEmpty()) |
|
|
|
|
parentId = QUuid::createUuid().toString(); |
|
|
|
|
|
|
|
|
|
if (lineItem) |
|
|
|
|
{ |
|
|
|
|
lineItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic)); |
|
|
|
|
|
|
|
|
|
UBGraphicsStrokesGroup* group; |
|
|
|
|
if(!mStrokesList.contains(parentId)){ |
|
|
|
|
group = new UBGraphicsStrokesGroup(); |
|
|
|
|
mStrokesList.insert(parentId,group); |
|
|
|
|
group->setTransform(lineItem->transform()); |
|
|
|
|
UBGraphicsItem::assignZValue(group, lineItem->zValue()); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
group = mStrokesList.value(parentId); |
|
|
|
|
|
|
|
|
|
if (!currentStroke) |
|
|
|
|
currentStroke = new UBGraphicsStroke(); |
|
|
|
|
|
|
|
|
|
if(lineItem->transform().isIdentity()) |
|
|
|
|
lineItem->setTransform(group->transform()); |
|
|
|
|
|
|
|
|
|
group->addToGroup(lineItem); |
|
|
|
|
lineItem->setStrokesGroup(group); |
|
|
|
|
|
|
|
|
|
lineItem->show(); |
|
|
|
|
group->addToGroup(lineItem); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (mXmlReader.name() == "polyline") |
|
|
|
|
{ |
|
|
|
|
QList<UBGraphicsPolygonItem*> polygonItems = polygonItemsFromPolylineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black); |
|
|
|
@ -1300,6 +1342,56 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(UBDocumentProxy* proxy, |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Is the item a line?
|
|
|
|
|
UBGraphicsLineItem *lineItem = qgraphicsitem_cast<UBGraphicsLineItem*> (item); |
|
|
|
|
if (lineItem && lineItem->isVisible()) |
|
|
|
|
{ |
|
|
|
|
UBGraphicsLineStroke* currentStroke = lineItem->stroke(); |
|
|
|
|
|
|
|
|
|
bool firstLineInStroke = currentStroke && !openStroke; |
|
|
|
|
|
|
|
|
|
if (firstLineInStroke) |
|
|
|
|
{ |
|
|
|
|
mXmlWriter.writeStartElement("g"); |
|
|
|
|
|
|
|
|
|
QColor colorOnDarkBackground = lineItem->colorOnDarkBackground(); |
|
|
|
|
QColor colorOnLightBackground = lineItem->colorOnLightBackground(); |
|
|
|
|
UBGraphicsStrokesGroup * sg = lineItem->strokesGroup(); |
|
|
|
|
|
|
|
|
|
if (colorOnDarkBackground.isValid() && colorOnLightBackground.isValid() && sg) |
|
|
|
|
{ |
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value" |
|
|
|
|
, QString("%1").arg(lineItem->strokesGroup()->zValue())); |
|
|
|
|
|
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri |
|
|
|
|
, "fill-on-dark-background", colorOnDarkBackground.name()); |
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri |
|
|
|
|
, "fill-on-light-background", colorOnLightBackground.name()); |
|
|
|
|
|
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(sg->uuid())); |
|
|
|
|
|
|
|
|
|
QVariant locked = sg->data(UBGraphicsItemData::ItemLocked); |
|
|
|
|
if (!locked.isNull() && locked.toBool()) |
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "locked", xmlTrue); |
|
|
|
|
|
|
|
|
|
QVariant layer = sg->data(UBGraphicsItemData::ItemLayerType); |
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "layer", QString("%1").arg(layer.toInt())); |
|
|
|
|
|
|
|
|
|
QMatrix matrix = sg->sceneMatrix(); |
|
|
|
|
if (!matrix.isIdentity()) |
|
|
|
|
mXmlWriter.writeAttribute("transform", toSvgTransform(matrix)); |
|
|
|
|
|
|
|
|
|
qDebug() << "Attributes written"; |
|
|
|
|
|
|
|
|
|
groupHoldsInfo = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lineItemToSvgLine(lineItem, groupHoldsInfo); |
|
|
|
|
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (openStroke) |
|
|
|
|
{ |
|
|
|
|
mXmlWriter.writeEndElement(); //g
|
|
|
|
@ -1555,6 +1647,53 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::polygonItemToSvgLine(UBGraphicsPolyg |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UBSvgSubsetAdaptor::UBSvgSubsetWriter::lineItemToSvgLine(UBGraphicsLineItem* lineItem, bool groupHoldsInfo) |
|
|
|
|
{ |
|
|
|
|
mXmlWriter.writeStartElement("lineL"); |
|
|
|
|
|
|
|
|
|
QLineF line = lineItem->originalLine(); |
|
|
|
|
|
|
|
|
|
mXmlWriter.writeAttribute("x1", QString::number(line.p1().x(), 'f', 2)); |
|
|
|
|
mXmlWriter.writeAttribute("y1", QString::number(line.p1().y(), 'f', 2)); |
|
|
|
|
|
|
|
|
|
// SVG renderers (Chrome) do not like line where (x1, y1) == (x2, y2)
|
|
|
|
|
qreal x2 = line.p2().x(); |
|
|
|
|
if (line.p1() == line.p2()) |
|
|
|
|
x2 += 0.01; |
|
|
|
|
|
|
|
|
|
mXmlWriter.writeAttribute("x2", QString::number(x2, 'f', 2)); |
|
|
|
|
mXmlWriter.writeAttribute("y2", QString::number(line.p2().y(), 'f', 2)); |
|
|
|
|
|
|
|
|
|
mXmlWriter.writeAttribute("stroke-width", QString::number(lineItem->originalWidth(), 'f', -1)); |
|
|
|
|
mXmlWriter.writeAttribute("stroke", lineItem->pen().color().name()); |
|
|
|
|
|
|
|
|
|
qreal alpha = lineItem->pen().color().alphaF(); |
|
|
|
|
if (alpha < 1.0) |
|
|
|
|
mXmlWriter.writeAttribute("stroke-opacity", QString::number(alpha, 'f', 2)); |
|
|
|
|
mXmlWriter.writeAttribute("stroke-linecap", "round"); |
|
|
|
|
|
|
|
|
|
switch (lineItem->style()) |
|
|
|
|
{ |
|
|
|
|
case Qt::PenStyle::DotLine: |
|
|
|
|
mXmlWriter.writeAttribute("line-style", "2"); |
|
|
|
|
break; |
|
|
|
|
case Qt::PenStyle::DashLine: |
|
|
|
|
mXmlWriter.writeAttribute("line-style", "1"); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
mXmlWriter.writeAttribute("line-style", "0"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!groupHoldsInfo) |
|
|
|
|
{ |
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value", QString("%1").arg(lineItem->zValue())); |
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "fill-on-dark-background", lineItem->colorOnDarkBackground().name()); |
|
|
|
|
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "fill-on-light-background", lineItem->colorOnLightBackground().name()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mXmlWriter.writeEndElement(); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UBSvgSubsetAdaptor::UBSvgSubsetWriter::strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo) |
|
|
|
|
{ |
|
|
|
@ -1901,6 +2040,114 @@ UBGraphicsPolygonItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItemFromLin |
|
|
|
|
return polygonItem; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
UBGraphicsLineItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::lineItemFromLineSvg(const QColor& pDefaultColor) |
|
|
|
|
{ |
|
|
|
|
QStringRef svgX1 = mXmlReader.attributes().value("x1"); |
|
|
|
|
QStringRef svgY1 = mXmlReader.attributes().value("y1"); |
|
|
|
|
QStringRef svgX2 = mXmlReader.attributes().value("x2"); |
|
|
|
|
QStringRef svgY2 = mXmlReader.attributes().value("y2"); |
|
|
|
|
|
|
|
|
|
qreal style = mXmlReader.attributes().value("line-style").toDouble(); |
|
|
|
|
|
|
|
|
|
QLineF line; |
|
|
|
|
|
|
|
|
|
if (!svgX1.isNull() && !svgY1.isNull() && !svgX2.isNull() && !svgY2.isNull()) |
|
|
|
|
{ |
|
|
|
|
qreal x1 = svgX1.toString().toFloat(); |
|
|
|
|
qreal y1 = svgY1.toString().toFloat(); |
|
|
|
|
qreal x2 = svgX2.toString().toFloat(); |
|
|
|
|
qreal y2 = svgY2.toString().toFloat(); |
|
|
|
|
|
|
|
|
|
line.setLine(x1, y1, x2, y2); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qWarning() << "cannot make sense of 'line' value"; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QStringRef strokeWidth = mXmlReader.attributes().value("stroke-width"); |
|
|
|
|
|
|
|
|
|
qreal lineWidth = 1.; |
|
|
|
|
|
|
|
|
|
if (!strokeWidth.isNull()) |
|
|
|
|
{ |
|
|
|
|
lineWidth = strokeWidth.toString().toFloat(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
UBGraphicsLineItem* lineItem = new UBGraphicsLineItem(line, lineWidth); |
|
|
|
|
graphicsItemFromSvg(lineItem); |
|
|
|
|
|
|
|
|
|
QStringRef svgStroke = mXmlReader.attributes().value("stroke"); |
|
|
|
|
|
|
|
|
|
QColor penColor = pDefaultColor; |
|
|
|
|
|
|
|
|
|
if (!svgStroke.isNull()) |
|
|
|
|
{ |
|
|
|
|
penColor.setNamedColor(svgStroke.toString()); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QStringRef svgStrokeOpacity = mXmlReader.attributes().value("stroke-opacity"); |
|
|
|
|
qreal opacity = 1.0; |
|
|
|
|
|
|
|
|
|
if (!svgStrokeOpacity.isNull()) |
|
|
|
|
{ |
|
|
|
|
opacity = svgStrokeOpacity.toString().toFloat(); |
|
|
|
|
penColor.setAlphaF(opacity); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lineItem->setColor(penColor); |
|
|
|
|
if (style == 2) |
|
|
|
|
{ |
|
|
|
|
lineItem->setStyle(Qt::PenStyle::DotLine); |
|
|
|
|
} else if (style == 1) |
|
|
|
|
{ |
|
|
|
|
lineItem->setStyle(Qt::PenStyle::DashLine); |
|
|
|
|
} else |
|
|
|
|
{ |
|
|
|
|
lineItem->setStyle(Qt::PenStyle::SolidLine); |
|
|
|
|
} |
|
|
|
|
QStringRef ubFillOnDarkBackground = mXmlReader.attributes().value(mNamespaceUri, "fill-on-dark-background"); |
|
|
|
|
|
|
|
|
|
if (!ubFillOnDarkBackground.isNull()) |
|
|
|
|
{ |
|
|
|
|
QColor color; |
|
|
|
|
color.setNamedColor(ubFillOnDarkBackground.toString()); |
|
|
|
|
if (!color.isValid()) |
|
|
|
|
color = Qt::white; |
|
|
|
|
|
|
|
|
|
color.setAlphaF(opacity); |
|
|
|
|
lineItem->setColorOnDarkBackground(color); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
QColor color = mGroupDarkBackgroundColor; |
|
|
|
|
color.setAlphaF(opacity); |
|
|
|
|
lineItem->setColorOnDarkBackground(color); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QStringRef ubFillOnLightBackground = mXmlReader.attributes().value(mNamespaceUri, "fill-on-light-background"); |
|
|
|
|
|
|
|
|
|
if (!ubFillOnLightBackground.isNull()) |
|
|
|
|
{ |
|
|
|
|
QColor color; |
|
|
|
|
color.setNamedColor(ubFillOnLightBackground.toString()); |
|
|
|
|
if (!color.isValid()) |
|
|
|
|
color = Qt::black; |
|
|
|
|
color.setAlphaF(opacity); |
|
|
|
|
lineItem->setColorOnLightBackground(color); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
QColor color = mGroupLightBackgroundColor; |
|
|
|
|
color.setAlphaF(opacity); |
|
|
|
|
lineItem->setColorOnLightBackground(color); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return lineItem; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QList<UBGraphicsPolygonItem*> UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItemsFromPolylineSvg(const QColor& pDefaultColor) |
|
|
|
|
{ |
|
|
|
|
QStringRef strokeWidth = mXmlReader.attributes().value("stroke-width"); |
|
|
|
|