diff --git a/plugins/cffadaptor/src/UBCFFAdaptor.cpp b/plugins/cffadaptor/src/UBCFFAdaptor.cpp index 5630c01d..f5c84068 100644 --- a/plugins/cffadaptor/src/UBCFFAdaptor.cpp +++ b/plugins/cffadaptor/src/UBCFFAdaptor.cpp @@ -550,8 +550,8 @@ QDomElement UBCFFAdaptor::UBToCFFConverter::parsePage(const QString &pageFileNam pageFile.close(); return QDomElement(); } - } else if (tagname == tUBZGroup) { - group = parseGroupPageSection(nextTopElement); + } else if (tagname == tUBZGroups) { + group = parseGroupsPageSection(nextTopElement); if (group.isNull()) { qDebug() << "Page doesn't contains any groups."; pageFile.close(); @@ -634,6 +634,7 @@ QDomElement UBCFFAdaptor::UBToCFFConverter::parseSvgPageSection(const QDomElemen else if (tagName == tUBZLine) parseUBZLine(nextElement, svgElements); else if (tagName == tUBZPolygon) parseUBZPolygon(nextElement, svgElements); else if (tagName == tUBZPolyline) parseUBZPolyline(nextElement, svgElements); + else if (tagName == tUBZGroups) parseGroupsPageSection(nextElement); nextElement = nextElement.nextSiblingElement(); } @@ -694,12 +695,34 @@ bool UBCFFAdaptor::UBToCFFConverter::writeExtendedIwbSection() // extended element options // editable, background, locked are supported for now -QDomElement UBCFFAdaptor::UBToCFFConverter::parseGroupPageSection(const QDomElement &element) +QDomElement UBCFFAdaptor::UBToCFFConverter::parseGroupsPageSection(const QDomElement &groupRoot) { // First sankore side implementation needed. TODO in Sankore 1.5 - Q_UNUSED(element) + if (!groupRoot.hasChildNodes()) { + qDebug() << "Group root is empty"; + return QDomElement(); + } + + QDomElement groupElement = groupRoot.firstChildElement(); + + while (!groupElement.isNull()) { + QDomElement extendedElement = mDataModel->createElementNS(iwbNS, groupElement.tagName()); + QDomElement groupChildElement = groupElement.firstChildElement(); + while (!groupChildElement.isNull()) { + QDomElement extSubElement = mDataModel->createElementNS(iwbNS, groupChildElement.tagName()); + extSubElement.setAttribute(aRef, groupChildElement.attribute(aID, QUuid().toString())); + extendedElement.appendChild(extSubElement); + + groupChildElement = groupChildElement.nextSiblingElement(); + } + + mExtendedElements.append(extendedElement); + + groupElement = groupElement.nextSiblingElement(); + } + qDebug() << "parsing ubz group section"; - return QDomElement(); + return groupRoot; } QString UBCFFAdaptor::UBToCFFConverter::getDstContentFolderName(const QString &elementType) @@ -1250,6 +1273,19 @@ bool UBCFFAdaptor::UBToCFFConverter::setCFFAttribute(const QString &attributeNam { setGeometryFromUBZ(ubzElement, svgElement); } + else + if (attributeName.contains(aUBZUuid)) + { + + QString parentId = ubzElement.attribute(aUBZParent); + QString id; + if (!parentId.isEmpty()) + id = "{" + parentId + "}" + "{" + ubzElement.attribute(aUBZUuid)+"}"; + else + id = "{" + ubzElement.attribute(aUBZUuid)+"}"; + + svgElement.setAttribute(aID, id); + } else if (attributeName.contains(aUBZHref)||attributeName.contains(aSrc)) { @@ -1799,7 +1835,10 @@ bool UBCFFAdaptor::UBToCFFConverter::parseUBZPolygon(const QDomElement &element, if (0 < iwbElementPart.attributes().count()) { - QString id = QUuid::createUuid().toString(); + QString id = svgElementPart.attribute(aUBZUuid); + if (id.isEmpty()) + id = QUuid::createUuid().toString(); + svgElementPart.setAttribute(aID, id); iwbElementPart.setAttribute(aRef, id); diff --git a/plugins/cffadaptor/src/UBCFFAdaptor.h b/plugins/cffadaptor/src/UBCFFAdaptor.h index d9891460..f38d51e0 100644 --- a/plugins/cffadaptor/src/UBCFFAdaptor.h +++ b/plugins/cffadaptor/src/UBCFFAdaptor.h @@ -63,7 +63,7 @@ private: QDomElement parseSvgPageSection(const QDomElement &element); void writeQDomElementToXML(const QDomNode &node); bool writeExtendedIwbSection(); - QDomElement parseGroupPageSection(const QDomElement &element); + QDomElement parseGroupsPageSection(const QDomElement &groupRoot); bool createBackground(const QDomElement &element, QMultiMap &dstSvgList); QString createBackgroundImage(const QDomElement &element, QSize size); diff --git a/plugins/cffadaptor/src/UBCFFConstants.h b/plugins/cffadaptor/src/UBCFFConstants.h index adeeb507..69de92dd 100644 --- a/plugins/cffadaptor/src/UBCFFConstants.h +++ b/plugins/cffadaptor/src/UBCFFConstants.h @@ -28,6 +28,7 @@ const QString tIWBPageSet = "pageset"; const QString tId = "id"; const QString tElement = "element"; const QString tUBZGroup = "group"; +const QString tUBZGroups = "groups"; const QString tUBZG = "g"; const QString tUBZPolygon = "polygon"; const QString tUBZPolyline = "polyline"; @@ -67,6 +68,7 @@ const QString aBackground = "background"; const QString aCrossedBackground = "crossed-background"; const QString aUBZType = "type"; const QString aUBZUuid = "uuid"; +const QString aUBZParent = "parent"; const QString aFill = "fill"; // IWB attribute contans color to fill const QString aID = "id"; // ID of any svg element can be placed in to iwb section @@ -334,8 +336,10 @@ stroke-lineshape-end \ const QString ubzElementAttributesToConvert(" \ xlink:href, \ src, \ -transform \ -"); +transform, \ +uuid \ +" +); // additional attributes. Have references in SVG section. const QString svgElementAttributes(" \ @@ -376,4 +380,4 @@ struct UBItemLayerType }; }; -#endif // UBCFFCONSTANTS_H \ No newline at end of file +#endif // UBCFFCONSTANTS_H diff --git a/src/adaptors/UBCFFSubsetAdaptor.cpp b/src/adaptors/UBCFFSubsetAdaptor.cpp index f156e4c5..d06c95a7 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.cpp +++ b/src/adaptors/UBCFFSubsetAdaptor.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "core/UBPersistenceManager.h" @@ -248,6 +249,11 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgRect(const QDomElement &elem painter.end(); UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + QTransform transform; QString textTransform = element.attribute(aTransform); @@ -298,6 +304,11 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgEllipse(const QDomElement &e painter.end(); UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + QTransform transform; QString textTransform = element.attribute(aTransform); @@ -373,37 +384,65 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolygon(const QDomElement &e brush.setColor(fillColor); brush.setStyle(Qt::SolidPattern); - QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); - QPainter painter; + + QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length())); + QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1)); + if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ + { + UBGraphicsPolygonItem *graphicsPolygon = mCurrentScene->polygonToPolygonItem(polygon); - painter.begin(generator); //drawing to svg tmp file + graphicsPolygon->setBrush(brush); - painter.translate(pen.widthF() / 2 - x1, pen.widthF() / 2 - y1); - painter.setBrush(brush); - painter.setPen(pen); - painter.drawPolygon(polygon); + QTransform transform; + QString textTransform = element.attribute(aTransform); - painter.end(); + graphicsPolygon->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, graphicsPolygon); + } + mCurrentScene->addItem(graphicsPolygon); - //add resulting svg file to scene - UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); - QTransform transform; - QString textTransform = element.attribute(aTransform); + graphicsPolygon->setUuid(itemUuid); + mRefToUuidMap.insert(element.attribute(aId), itemUuid); - svgItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, svgItem); } - repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); - hashSceneItem(element, svgItem); - - if (mGSectionContainer) + else // single CFF { - addItemToGSection(svgItem); - } + QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); + QPainter painter; - delete generator; + painter.begin(generator); //drawing to svg tmp file + + painter.translate(pen.widthF() / 2 - x1, pen.widthF() / 2 - y1); + painter.setBrush(brush); + painter.setPen(pen); + painter.drawPolygon(polygon); + + painter.end(); + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + QTransform transform; + QString textTransform = element.attribute(aTransform); + + QUuid uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(uuid); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); + hashSceneItem(element, svgItem); + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; + } return true; } bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolyline(const QDomElement &element) @@ -441,6 +480,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolyline(const QDomElement & //bounding rect lef top corner coordinates qreal x1 = polygon.boundingRect().topLeft().x(); qreal y1 = polygon.boundingRect().topLeft().y(); + //bounding rect dimensions qreal width = polygon.boundingRect().width(); qreal height = polygon.boundingRect().height(); @@ -458,35 +498,72 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolyline(const QDomElement & pen.setColor(strokeColor); pen.setWidth(strokeWidth); - QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); - QPainter painter; + QBrush brush; + brush.setColor(strokeColor); + brush.setStyle(Qt::SolidPattern); - painter.begin(generator); //drawing to svg tmp file + QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length())); + QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1)); + if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ + { + UBGraphicsPolygonItem *graphicsPolygon = new UBGraphicsPolygonItem(polygon); - painter.translate(pen.widthF()/2 - x1, pen.widthF()/2- y1); - painter.setPen(pen); - painter.drawPolyline(polygon); + UBGraphicsStroke *stroke = new UBGraphicsStroke(); + graphicsPolygon->setStroke(stroke); - painter.end(); + graphicsPolygon->setBrush(brush); + QTransform transform; + QString textTransform = element.attribute(aTransform); - //add resulting svg file to scene - UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); - QTransform transform; - QString textTransform = element.attribute(aTransform); + graphicsPolygon->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, graphicsPolygon); + } + mCurrentScene->addItem(graphicsPolygon); - svgItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, svgItem); - } - repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 + transform.m31() - strokeWidth/2, y1 + transform.m32() + strokeWidth/2, transform); - hashSceneItem(element, svgItem); + graphicsPolygon->setUuid(itemUuid); + mRefToUuidMap.insert(element.attribute(aId), itemUuid); - if (mGSectionContainer) + } + else // simple CFF { - addItemToGSection(svgItem); + QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); + QPainter painter; + + painter.begin(generator); //drawing to svg tmp file + + painter.translate(pen.widthF() / 2 - x1, pen.widthF() / 2 - y1); + painter.setBrush(brush); + painter.setPen(pen); + painter.drawPolygon(polygon); + + painter.end(); + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; } - delete generator; return true; } @@ -621,6 +698,10 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgText(const QDomElement &elem //add resulting svg file to scene UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + svgItem->resetTransform(); repositionSvgItem(svgItem, width, height, x + transform.m31(), y + transform.m32(), transform); hashSceneItem(element, svgItem); @@ -734,6 +815,10 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgTextarea(const QDomElement & UBGraphicsTextItem *svgItem = mCurrentScene->addTextHtml(doc.toHtml()); svgItem->resize(width, height); + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + QTransform transform; QString textTransform = element.attribute(aTransform); @@ -783,6 +868,11 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgImage(const QDomElement &ele } UBGraphicsPixmapItem *pixItem = mCurrentScene->addPixmap(pix, NULL); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + pixItem->setUuid(QUuid(uuid)); + QTransform transform; QString textTransform = element.attribute(aTransform); @@ -830,6 +920,10 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgFlash(const QDomElement &ele UBGraphicsWidgetItem *flashItem = mCurrentScene->addW3CWidget(QUrl::fromLocalFile(flashUrl)); flashItem->setSourceUrl(urlPath); + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + flashItem->setUuid(QUuid(uuid)); + QTransform transform; QString textTransform = element.attribute(aTransform); @@ -867,14 +961,15 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgAudio(const QDomElement &ele concreteUrl = QUrl::fromLocalFile(audioPath); } - QUuid uuid = QUuid::createUuid(); + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); QString destFile; bool b = UBPersistenceManager::persistenceManager()->addFileToDocument( mCurrentScene->document(), concreteUrl.toLocalFile(), UBPersistenceManager::audioDirectory, - uuid, + QUuid(uuid), destFile); if (!b) { @@ -883,6 +978,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgAudio(const QDomElement &ele concreteUrl = QUrl::fromLocalFile(destFile); UBGraphicsMediaItem *audioItem = mCurrentScene->addAudio(concreteUrl, false); + QTransform transform; QString textTransform = parentOfAudio.attribute(aTransform); @@ -920,15 +1016,15 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgVideo(const QDomElement &ele concreteUrl = QUrl::fromLocalFile(videoPath); } - QUuid uuid = QUuid::createUuid(); - + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); QString destFile; bool b = UBPersistenceManager::persistenceManager()->addFileToDocument( mCurrentScene->document(), concreteUrl.toLocalFile(), UBPersistenceManager::videoDirectory, - uuid, + QUuid(uuid), destFile); if (!b) { @@ -937,6 +1033,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgVideo(const QDomElement &ele concreteUrl = QUrl::fromLocalFile(destFile); UBGraphicsMediaItem *videoItem = mCurrentScene->addVideo(concreteUrl, false); + QTransform transform; QString textTransform = element.attribute(aTransform); @@ -980,8 +1077,8 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgElement(const QDomElement &p { QString tagName = parent.tagName(); if (parent.namespaceURI() != svgNS) { - qDebug() << "Incorrect namespace, error at content file, line number" << parent.lineNumber(); - return false; + qWarning() << "Incorrect namespace, error at content file, line number" << parent.lineNumber(); + //return false; } if (tagName == tG && !parseGSection(parent)) return false; @@ -1027,8 +1124,8 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPageset(const QDomElement &p bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbMeta(const QDomElement &element) { if (element.namespaceURI() != iwbNS) { - qDebug() << "incorrect meta namespace, incorrect document"; - return false; + qWarning() << "incorrect meta namespace, incorrect document"; + //return false; } return true; @@ -1036,8 +1133,8 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbMeta(const QDomElement &elem bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvg(const QDomElement &svgSection) { if (svgSection.namespaceURI() != svgNS) { - qDebug() << "incorrect svg namespace, incorrect document"; - return false; + qWarning() << "incorrect svg namespace, incorrect document"; + // return false; } parseSvgSectionAttr(svgSection); @@ -1052,15 +1149,92 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvg(const QDomElement &svgSecti return true; } -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbGroup(QDomElement &parent) +UBGraphicsGroupContainerItem *UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbGroup(QDomElement &parent) { //TODO. Create groups from elements parsed by parseIwbElement() function if (parent.namespaceURI() != iwbNS) { - qDebug() << "incorrect iwb group namespace, incorrect document"; - return false; + qWarning() << "incorrect iwb group namespace, incorrect document"; + // return false; } - return true; + UBGraphicsGroupContainerItem *group = new UBGraphicsGroupContainerItem(); + QMultiMap strokesGroupsContainer; + QList groupContainer; + QString currentStrokeIdentifier; + + QDomElement currentStrokeElement = parent.firstChildElement(); + while (!currentStrokeElement.isNull()) + { + if (tGroup == currentStrokeElement.tagName()) + group->addToGroup(parseIwbGroup(currentStrokeElement)); + else + { + + QString ref = currentStrokeElement.attribute(aRef); + QString uuid = mRefToUuidMap[ref]; + if (!uuid.isEmpty()) + { + if (ref.size() > QUuid().toString().length()) // create stroke group + { + currentStrokeIdentifier = ref.left(QUuid().toString().length()-1); + UBGraphicsPolygonItem *strokeByUuid = qgraphicsitem_cast(mCurrentScene->itemForUuid(QUuid(ref.right(QUuid().toString().length())))); + + if (strokeByUuid) + strokesGroupsContainer.insert(currentStrokeIdentifier, strokeByUuid); + } + else // single elements in group + groupContainer.append(mCurrentScene->itemForUuid(QUuid(uuid))); + } + } + currentStrokeElement = currentStrokeElement.nextSiblingElement(); + } + + + + foreach (QString key, strokesGroupsContainer.keys().toSet()) + { + UBGraphicsStrokesGroup* pStrokesGroup = new UBGraphicsStrokesGroup(); + UBGraphicsStroke *currentStroke = new UBGraphicsStroke(); + foreach(UBGraphicsPolygonItem* poly, strokesGroupsContainer.values(key)) + { + if (poly) + { + mCurrentScene->removeItem(poly); + mCurrentScene->removeItemFromDeletion(poly); + poly->setStrokesGroup(pStrokesGroup); + poly->setStroke(currentStroke); + pStrokesGroup->addToGroup(poly); + } + } + if (currentStroke->polygons().empty()) + delete currentStroke; + + if (pStrokesGroup->childItems().count()) + mCurrentScene->addItem(pStrokesGroup); + else + delete pStrokesGroup; + + if (pStrokesGroup) + { + QGraphicsItem *strokeGroup = qgraphicsitem_cast(pStrokesGroup); + groupContainer.append(strokeGroup); + } + } + + foreach(QGraphicsItem* item, groupContainer) + group->addToGroup(item); + + if (group->childItems().count()) + { + mCurrentScene->addItem(group); + + if (1 == group->childItems().count()) + { + group->destroy(false); + } + } + + return group; } bool UBCFFSubsetAdaptor::UBCFFSubsetReader::strToBool(QString str) @@ -1071,8 +1245,8 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::strToBool(QString str) bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbElement(QDomElement &element) { if (element.namespaceURI() != iwbNS) { - qDebug() << "incorrect iwb element namespace, incorrect document"; - return false; + qWarning() << "incorrect iwb element namespace, incorrect document"; + // return false; } bool locked = false; diff --git a/src/adaptors/UBCFFSubsetAdaptor.h b/src/adaptors/UBCFFSubsetAdaptor.h index acebc151..3a6f89a6 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.h +++ b/src/adaptors/UBCFFSubsetAdaptor.h @@ -74,6 +74,7 @@ private: QDomDocument mDOMdoc; QDomNode mCurrentDOMElement; QHash persistedItems; + QMap mRefToUuidMap; QDir mTmpFlashDir; void addItemToGSection(QGraphicsItem *item); @@ -102,7 +103,7 @@ private: inline bool parseSvgFlash(const QDomElement &element); inline bool parseSvgAudio(const QDomElement &element); inline bool parseSvgVideo(const QDomElement &element); - inline bool parseIwbGroup(QDomElement &parent); + inline UBGraphicsGroupContainerItem *parseIwbGroup(QDomElement &parent); inline bool parseIwbElement(QDomElement &element); inline void parseTSpan(const QDomElement &parent, QPainter &painter , qreal &curX, qreal &curY, qreal &width, qreal &height, qreal &linespacing, QRectF &lastDrawnTextBoundingRect diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp index cabc74ad..17e25564 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.cpp +++ b/src/adaptors/UBSvgSubsetAdaptor.cpp @@ -48,6 +48,7 @@ #include "frameworks/UBFileSystemUtils.h" #include "frameworks/UBStringUtils.h" +#include "frameworks/UBFileSystemUtils.h" #include "core/UBSettings.h" #include "core/UBSetting.h" @@ -79,6 +80,7 @@ const QString UBSvgSubsetAdaptor::sFormerUniboardDocumentNamespaceUri = "http:// const QString tElement = "element"; const QString tGroup = "group"; +const QString tStrokeGroup = "strokeGroup"; const QString tGroups = "groups"; const QString aId = "id"; @@ -553,6 +555,10 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() if (polygonItem) { + mScene->addItem(polygonItem); + + polygonItem->setUuid(uuidFromSvg); + if (annotationGroup) { polygonItem->setStroke(annotationGroup); @@ -989,31 +995,45 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() UBGraphicsGroupContainerItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::readGroup() { - UBGraphicsGroupContainerItem *result = new UBGraphicsGroupContainerItem(); - + UBGraphicsGroupContainerItem *group = new UBGraphicsGroupContainerItem(); + QMultiMap strokesGroupsContainer; + QList groupContainer; + QString currentStrokeIdentifier; + QUuid groupUuid = QUuid(mXmlReader.attributes().value(aId).toString()); mXmlReader.readNext(); - while (!mXmlReader.atEnd()) { + while (!mXmlReader.atEnd()) + { if (mXmlReader.isEndElement()) { mXmlReader.readNext(); - result->setUuid(groupUuid); - if (!result->childItems().count()) { - delete result; - result = 0; - } break; - } else if (mXmlReader.isStartElement()) { - if (mXmlReader.name() == tGroup) { + } else if (mXmlReader.isStartElement()) + { + if (mXmlReader.name() == tGroup) + { qDebug() << "came across the group id is" << mXmlReader.attributes().value(aId); UBGraphicsGroupContainerItem *curGroup = readGroup(); - if (curGroup) { - result->addToGroup(curGroup); - } - } else if (mXmlReader.name() == tElement) { + if (curGroup) + groupContainer.append(curGroup); + } + else if (mXmlReader.name() == tElement) + { + QString id = mXmlReader.attributes().value(aId).toString(); + QString itemId = id.right(QUuid().toString().size()); + QString groupId = id.left(QUuid().toString().size()); + QGraphicsItem *curItem = readElementFromGroup(); - if (curItem) { - result->addToGroup(curItem); + + UBGraphicsPolygonItem *curPolygon = qgraphicsitem_cast(curItem); + + if (curPolygon && !groupId.isEmpty() && !itemId.isEmpty() && itemId != groupId) + { + strokesGroupsContainer.insert(groupId, curPolygon); + } + else // item + { + groupContainer.append(curItem); } }else { mXmlReader.skipCurrentElement(); @@ -1023,7 +1043,49 @@ UBGraphicsGroupContainerItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::readGroup() } } - return result; + foreach (QString key, strokesGroupsContainer.keys().toSet()) + { + UBGraphicsStrokesGroup* pStrokesGroup = new UBGraphicsStrokesGroup(); + UBGraphicsStroke *currentStroke = new UBGraphicsStroke(); + foreach(UBGraphicsPolygonItem* poly, strokesGroupsContainer.values(key)) + { + if (poly) + { + mScene->removeItem(poly); + mScene->removeItemFromDeletion(poly); + poly->setStrokesGroup(pStrokesGroup); + poly->setStroke(currentStroke); + pStrokesGroup->addToGroup(poly); + } + } + if (currentStroke->polygons().empty()) + delete currentStroke; + + if (pStrokesGroup->childItems().count()) + mScene->addItem(pStrokesGroup); + else + delete pStrokesGroup; + + if (pStrokesGroup) + { + QGraphicsItem *strokeGroup = qgraphicsitem_cast(pStrokesGroup); + groupContainer.append(strokeGroup); + } + } + + foreach(QGraphicsItem* item, groupContainer) + group->addToGroup(item); + + if (group->childItems().count()) + { + mScene->addItem(group); + + if (1 == group->childItems().count()) + { + group->destroy(false); + } + } + return group; } void UBSvgSubsetAdaptor::UBSvgSubsetReader::readGroupRoot() @@ -1051,8 +1113,9 @@ void UBSvgSubsetAdaptor::UBSvgSubsetReader::readGroupRoot() QGraphicsItem *UBSvgSubsetAdaptor::UBSvgSubsetReader::readElementFromGroup() { QGraphicsItem *result = 0; - - result = mScene->itemForUuid(QUuid(mXmlReader.attributes().value(aId).toString())); + QString id = mXmlReader.attributes().value(aId).toString(); + QString uuid = id.right(QUuid().toString().size()); + result = mScene->itemForUuid(QUuid(uuid)); mXmlReader.skipCurrentElement(); mXmlReader.readNext(); @@ -1152,25 +1215,42 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(int pageIndex) QGraphicsItem *item = items.takeFirst(); // Is the item a strokes group? + UBGraphicsStrokesGroup* strokesGroupItem = qgraphicsitem_cast(item); + if(strokesGroupItem && strokesGroupItem->isVisible()){ - mXmlWriter.writeStartElement("g"); - mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(strokesGroupItem->uuid())); + QDomElement newGroupElement; + if (!strokesGroupItem->parentItem() && strokesGroupItem->childItems().count()) { + newGroupElement = groupDomDocument.createElement(tGroup); + newGroupElement.setAttribute(aId, strokesGroupItem->uuid().toString()); + groupRoot.appendChild(newGroupElement); + } + + //disabling g section parsing as a group of elements. Use groups refs instead +// mXmlWriter.writeStartElement("g"); +// mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(strokesGroupItem->uuid())); QMatrix matrix = item->sceneMatrix(); if (!matrix.isIdentity()){ mXmlWriter.writeAttribute("transform", toSvgTransform(matrix)); } - // Add the polygons - foreach(QGraphicsItem* item, strokesGroupItem->childItems()){ - UBGraphicsPolygonItem* poly = qgraphicsitem_cast(item); - if(NULL != poly){ - polygonItemToSvgPolygon(poly, true); - items.removeOne(poly); - } - } + // Add the polygons + foreach(QGraphicsItem* item, strokesGroupItem->childItems()){ + + UBGraphicsPolygonItem* poly = qgraphicsitem_cast(item); + if(NULL != poly){ + polygonItemToSvgPolygon(poly, true); + if (!newGroupElement.isNull()) { + QDomElement curPolygonElement = groupDomDocument.createElement(tElement); + curPolygonElement.setAttribute(aId, strokesGroupItem->uuid().toString() + + poly->uuid().toString()); + newGroupElement.appendChild(curPolygonElement); + } + items.removeOne(poly); + } + } - mXmlWriter.writeEndElement(); //g +// mXmlWriter.writeEndElement(); //g } // Is the item a polygon? @@ -1401,12 +1481,12 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(int pageIndex) QDomElement curElement = groupRoot.firstChildElement(); while (!curElement.isNull()) { if (curElement.hasAttribute(aId)) { - mXmlWriter.writeStartElement(tGroup); + mXmlWriter.writeStartElement(curElement.tagName()); mXmlWriter.writeAttribute(aId, curElement.attribute(aId)); QDomElement curSubElement = curElement.firstChildElement(); while (!curSubElement.isNull()) { if (curSubElement.hasAttribute(aId)) { - mXmlWriter.writeStartElement(tElement); + mXmlWriter.writeStartElement(curSubElement.tagName()); mXmlWriter.writeAttribute(aId, curSubElement.attribute(aId)); mXmlWriter.writeEndElement(); curSubElement = curSubElement.nextSiblingElement(); @@ -1454,8 +1534,16 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistGroupToDom(QGraphicsItem *gro if (!tmpUuid.isNull()) { if (item->type() == UBGraphicsGroupContainerItem::Type && item->childItems().count()) { persistGroupToDom(item, curParent, groupDomDocument); + } else if (item->type() == UBGraphicsStrokesGroup::Type) { + foreach (QGraphicsItem *polygonItem, item->childItems()) { + QDomElement curPolygonElement = groupDomDocument->createElement(tElement); + curPolygonElement.setAttribute(aId, tmpUuid.toString() + + UBGraphicsItem::getOwnUuid(polygonItem).toString()); + curGroupElement.appendChild(curPolygonElement); + } } else { - QDomElement curSubElement = groupDomDocument->createElement(tGroup); + QDomElement curSubElement = groupDomDocument->createElement(tElement); + curSubElement.setAttribute(aId, tmpUuid); curGroupElement.appendChild(curSubElement); } @@ -1464,6 +1552,27 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistGroupToDom(QGraphicsItem *gro } } +void UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistStrokeToDom(QGraphicsItem *strokeItem, QDomElement *curParent, QDomDocument *curDomDocument) +{ + QUuid uuid = UBGraphicsScene::getPersonalUuid(strokeItem); + if (!uuid.isNull()) { + QDomElement curStrokesGroupElement = curDomDocument->createElement(tStrokeGroup); + curStrokesGroupElement.setAttribute(aId, uuid); + curParent->appendChild(curStrokesGroupElement); + + foreach (QGraphicsItem *item, strokeItem->childItems()) { + QUuid tmpUuid = UBGraphicsScene::getPersonalUuid(item); + if (!tmpUuid.isNull()) { + if (item->type() == UBGraphicsPolygonItem::Type && item->childItems().count()) { + QDomElement curSubElement = curDomDocument->createElement(tElement); + curSubElement.setAttribute(aId, tmpUuid); + curStrokesGroupElement.appendChild(curSubElement); + } + } + } + } +} + void UBSvgSubsetAdaptor::UBSvgSubsetWriter::polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo) { mXmlWriter.writeStartElement("line"); @@ -1615,6 +1724,11 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::polygonItemToSvgPolygon(UBGraphicsPo , "fill-on-light-background", polygonItem->colorOnLightBackground().name()); } + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(polygonItem->uuid())); + if (polygonItem->parentItem()) { + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "parent", UBStringUtils::toCanonicalUuid(UBGraphicsItem::getOwnUuid(polygonItem->parentItem()))); + } + mXmlWriter.writeEndElement(); } } diff --git a/src/adaptors/UBSvgSubsetAdaptor.h b/src/adaptors/UBSvgSubsetAdaptor.h index d02765c3..39a3ccd0 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.h +++ b/src/adaptors/UBSvgSubsetAdaptor.h @@ -179,6 +179,7 @@ class UBSvgSubsetAdaptor private: void persistGroupToDom(QGraphicsItem *groupItem, QDomElement *curParent, QDomDocument *curDomDocument); + void persistStrokeToDom(QGraphicsItem *strokeItem, QDomElement *curParent, QDomDocument *curDomDocument); void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo); diff --git a/src/domain/UBGraphicsPolygonItem.cpp b/src/domain/UBGraphicsPolygonItem.cpp index d6448e06..55c55dda 100644 --- a/src/domain/UBGraphicsPolygonItem.cpp +++ b/src/domain/UBGraphicsPolygonItem.cpp @@ -60,6 +60,13 @@ UBGraphicsPolygonItem::UBGraphicsPolygonItem (const QLineF& pLine, qreal pWidth) void UBGraphicsPolygonItem::initialize() { setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::DrawingItem)); //Necessary to set if we want z value to be assigned correctly + setUuid(QUuid::createUuid()); +} + +void UBGraphicsPolygonItem::setUuid(const QUuid &pUuid) +{ + UBItem::setUuid(pUuid); + setData(UBGraphicsItemData::ItemUuid, QVariant(pUuid)); //store item uuid inside the QGraphicsItem to fast operations with Items on the scene } void UBGraphicsPolygonItem::clearStroke() diff --git a/src/domain/UBGraphicsPolygonItem.h b/src/domain/UBGraphicsPolygonItem.h index 7b961e52..511e5da7 100644 --- a/src/domain/UBGraphicsPolygonItem.h +++ b/src/domain/UBGraphicsPolygonItem.h @@ -39,6 +39,8 @@ class UBGraphicsPolygonItem : public QGraphicsPolygonItem, public UBItem void initialize(); + void setUuid(const QUuid &pUuid); + void setStrokesGroup(UBGraphicsStrokesGroup* group); UBGraphicsStrokesGroup* strokesGroup() const{return mpGroup;} void setColor(const QColor& color); diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index 621dc9a4..99bfe301 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -1713,6 +1713,7 @@ QRectF UBGraphicsScene::normalizedSceneRect(qreal ratio) QGraphicsItem *UBGraphicsScene::itemForUuid(QUuid uuid) { QGraphicsItem *result = 0; + QString ui = uuid.toString(); //simple search before implementing container for fast access foreach (QGraphicsItem *item, items()) { diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 6d496369..1b0a54db 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -302,6 +302,8 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem static QUuid getPersonalUuid(QGraphicsItem *item); + UBGraphicsPolygonItem* polygonToPolygonItem(const QPolygonF pPolygon); + public slots: void initStroke(); void hideEraser(); @@ -338,7 +340,6 @@ public slots: UBGraphicsPolygonItem* lineToPolygonItem(const QLineF& pLine, const qreal& pWidth); UBGraphicsPolygonItem* arcToPolygonItem(const QLineF& pStartRadius, qreal pSpanAngle, qreal pWidth); - UBGraphicsPolygonItem* polygonToPolygonItem(const QPolygonF pPolygon); void initPolygonItem(UBGraphicsPolygonItem*);