diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp index 1c05f4ca..2a93e0fd 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.cpp +++ b/src/adaptors/UBSvgSubsetAdaptor.cpp @@ -498,6 +498,18 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() { mGroupLightBackgroundColor.setNamedColor(ubFillOnLightBackground.toString()); } + + QStringRef ubUuid = mXmlReader.attributes().value(mNamespaceUri, "uuid"); + + if (!ubUuid.isNull()) + strokesGroup->setUuid(ubUuid.toString()); + else + strokesGroup->setUuid(QUuid::createUuid()); + + QString uuid_stripped = strokesGroup->uuid().toString().replace("}","").replace("{",""); + + if (!mStrokesList.contains(uuid_stripped)) + mStrokesList.insert(uuid_stripped, strokesGroup); } else if (mXmlReader.name() == "polygon" || mXmlReader.name() == "line") { @@ -524,13 +536,15 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() if(!mStrokesList.contains(parentId)){ group = new UBGraphicsStrokesGroup(); mStrokesList.insert(parentId,group); - currentStroke = new UBGraphicsStroke(); group->setTransform(polygonItem->transform()); UBGraphicsItem::assignZValue(group, polygonItem->zValue()); } else group = mStrokesList.value(parentId); + if (!currentStroke) + currentStroke = new UBGraphicsStroke(); + if(polygonItem->transform().isIdentity()) polygonItem->setTransform(group->transform()); @@ -546,23 +560,33 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() { QList polygonItems = polygonItemsFromPolylineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black); - QString parentId = QUuid::createUuid().toString(); + QString parentId = mXmlReader.attributes().value(mNamespaceUri, "parent").toString(); + qDebug() << "parentID = " << parentId; + + if(parentId.isEmpty() && strokesGroup) + parentId = strokesGroup->uuid().toString(); + + if(parentId.isEmpty()) + parentId = QUuid::createUuid().toString(); foreach(UBGraphicsPolygonItem* polygonItem, polygonItems) { polygonItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic)); UBGraphicsStrokesGroup* group; + if(!mStrokesList.contains(parentId)){ group = new UBGraphicsStrokesGroup(); mStrokesList.insert(parentId,group); - currentStroke = new UBGraphicsStroke(); group->setTransform(polygonItem->transform()); UBGraphicsItem::assignZValue(group, polygonItem->zValue()); } else group = mStrokesList.value(parentId); + if (!currentStroke) + currentStroke = new UBGraphicsStroke(); + if(polygonItem->transform().isIdentity()) polygonItem->setTransform(group->transform()); @@ -861,6 +885,8 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() mGroupHasInfo = false; mGroupDarkBackgroundColor = QColor(); mGroupLightBackgroundColor = QColor(); + strokesGroup = NULL; + currentStroke = NULL; } } } @@ -1127,6 +1153,9 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(int pageIndex) , "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())); + qDebug() << "Attributes written"; groupHoldsInfo = true; @@ -1442,6 +1471,11 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::strokeToSvgPolyline(UBGraphicsStroke , "fill-on-light-background", firstPolygonItem->colorOnLightBackground().name()); } + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(firstPolygonItem->uuid())); + if (firstPolygonItem->parentItem()) { + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "parent", UBStringUtils::toCanonicalUuid(UBGraphicsItem::getOwnUuid(firstPolygonItem->strokesGroup()))); + } + mXmlWriter.writeEndElement(); } } diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 8e63c31e..7c5cf039 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -561,7 +561,7 @@ Here we determines cases when items should to get mouse press event at pressing break; case UBGraphicsItemType::StrokeItemType: - if (currentTool == UBStylusTool::Play) + if (currentTool == UBStylusTool::Play || currentTool == UBStylusTool::Selector) return true; break; // Groups shouldn't reacts on any presses and moves for Play tool. @@ -664,7 +664,7 @@ bool UBBoardView::itemShouldBeMoved(QGraphicsItem *item) return false; case UBGraphicsMediaItem::Type: case UBGraphicsStrokesGroup::Type: - return true; + return false; case UBGraphicsTextItem::Type: return !item->isSelected(); } @@ -1254,6 +1254,7 @@ void UBBoardView::mouseReleaseEvent (QMouseEvent *event) if (isUBItem(movingItem) && DelegateButton::Type != movingItem->type() && UBGraphicsDelegateFrame::Type != movingItem->type() && + UBGraphicsStrokesGroup::Type != movingItem->type() && UBGraphicsCache::Type != movingItem->type() && QGraphicsWebView::Type != movingItem->type() && // for W3C widgets as Tools. !(!isMultipleSelectionEnabled() && movingItem->parentItem() && UBGraphicsWidgetItem::Type == movingItem->type() && UBGraphicsGroupContainerItem::Type == movingItem->parentItem()->type())) diff --git a/src/domain/UBGraphicsStrokesGroup.cpp b/src/domain/UBGraphicsStrokesGroup.cpp index e5aa0884..a6dbc2a8 100644 --- a/src/domain/UBGraphicsStrokesGroup.cpp +++ b/src/domain/UBGraphicsStrokesGroup.cpp @@ -111,30 +111,44 @@ QColor UBGraphicsStrokesGroup::color(colorType pColorType) const void UBGraphicsStrokesGroup::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (Delegate()->mousePressEvent(event)) - { - //NOOP - } - else - { -// QGraphicsItemGroup::mousePressEvent(event); - } + Delegate()->startUndoStep(); + + mStartingPoint = event->scenePos(); + + initializeTransform(); + + mTranslateX = 0; + mTranslateY = 0; + mAngleOffset = 0; + + mInitialTransform = buildTransform(); + + event->accept(); } void UBGraphicsStrokesGroup::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (Delegate()->mouseMoveEvent(event)) - { - // NOOP; - } - else - { - QGraphicsItemGroup::mouseMoveEvent(event); - } + QLineF move = QLineF(mStartingPoint, event->scenePos()); + + mTranslateX = move.dx(); + mTranslateY = move.dy(); + //Delegate()->frame()->moveLinkedItems(move); + + setTransform(buildTransform()); + + event->accept(); + } void UBGraphicsStrokesGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + Delegate()->commitUndoStep(); + + mTotalTranslateX += mTranslateX; + mTotalTranslateY += mTranslateY; + + event->accept(); + Delegate()->mouseReleaseEvent(event); QGraphicsItemGroup::mouseReleaseEvent(event); } @@ -226,3 +240,80 @@ QPainterPath UBGraphicsStrokesGroup::shape() const return path; } + +void UBGraphicsStrokesGroup::initializeTransform() +{ + + QTransform itemTransform = sceneTransform(); + QRectF itemRect = boundingRect(); + QPointF topLeft = itemTransform.map(itemRect.topLeft()); + QPointF topRight = itemTransform.map(itemRect.topRight()); + QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft()); + + qreal horizontalFlip = (topLeft.x() > topRight.x()) ? -1 : 1; + mMirrorX = horizontalFlip < 0 ; + if(horizontalFlip < 0){ + // why this is because of the way of calculating the translations that checks which side is the most is the + // nearest instead of checking which one is the left side. + QPointF tmp = topLeft; + topLeft = topRight; + topRight = tmp; + + // because of the calculation of the height is done by lenght and not deltaY + bottomLeft = itemTransform.map(itemRect.bottomRight()); + } + + qreal verticalFlip = (bottomLeft.y() < topLeft.y()) ? -1 : 1; + // not sure that is usefull + mMirrorY = verticalFlip < 0; + if(verticalFlip < 0 && !mMirrorX){ + topLeft = itemTransform.map(itemRect.bottomLeft()); + topRight = itemTransform.map(itemRect.bottomRight()); + bottomLeft = itemTransform.map(itemRect.topLeft()); + } + + QLineF topLine(topLeft, topRight); + QLineF leftLine(topLeft, bottomLeft); + qreal width = topLine.length(); + qreal height = leftLine.length(); + + mAngle = topLine.angle(); + + // the fact the the length is used we loose the horizontalFlip information + // a better way to do this is using DeltaX that preserve the direction information. + mTotalScaleX = (width / itemRect.width()) * horizontalFlip; + mTotalScaleY = height / itemRect.height() * verticalFlip; + + + + QTransform tr; + QPointF center = boundingRect().center(); + tr.translate(center.x() * mTotalScaleX, center.y() * mTotalScaleY); + tr.rotate(-mAngle); + tr.translate(-center.x() * mTotalScaleX, -center.y() * mTotalScaleY); + tr.scale(mTotalScaleX, mTotalScaleY); + + mTotalTranslateX = transform().dx() - tr.dx(); + mTotalTranslateY = transform().dy() - tr.dy(); + + +} + +QTransform UBGraphicsStrokesGroup::buildTransform() +{ + QTransform tr; + QPointF center = boundingRect().center(); + + // Translate + tr.translate(mTotalTranslateX + mTranslateX, mTotalTranslateY + mTranslateY); + + // Set angle + tr.translate(center.x() * mTotalScaleX, center.y() * mTotalScaleY); + tr.rotate(-mAngle); + tr.translate(-center.x() * mTotalScaleX, -center.y() * mTotalScaleY); + + // Scale + tr.scale(mTotalScaleX, mTotalScaleY ); + + return tr; +} diff --git a/src/domain/UBGraphicsStrokesGroup.h b/src/domain/UBGraphicsStrokesGroup.h index 5ddf789e..545c8c9d 100644 --- a/src/domain/UBGraphicsStrokesGroup.h +++ b/src/domain/UBGraphicsStrokesGroup.h @@ -66,6 +66,34 @@ protected: virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + + private: + qreal mTranslateX; + qreal mTranslateY; + qreal mTotalTranslateX; + qreal mTotalTranslateY; + + qreal mAngle; + qreal mAngleOffset; + + qreal mTotalScaleX; + qreal mTotalScaleY; + qreal mScaleX; + qreal mScaleY; + + bool mFlippedX; + bool mFlippedY; + bool mMirrorX; + bool mMirrorY; + bool mResizing; + bool mMirroredXAtStart; + bool mMirroredYAtStart; + + QPointF mStartingPoint; + QTransform mInitialTransform; + + QTransform buildTransform (); + void initializeTransform (); }; #endif // UBGRAPHICSSTROKESGROUP_H