diff --git a/src/core/UB.h b/src/core/UB.h index ab42fb7f..87065310 100644 --- a/src/core/UB.h +++ b/src/core/UB.h @@ -200,7 +200,7 @@ struct UBUndoType { enum Enum { - undotype_UNKNOWN = 0, undotype_DOCUMENT, undotype_GRAPHICITEMTRANSFORM, undotype_GRAPHICITEM, undotype_GRAPHICTEXTITEM, undotype_PAGESIZE, undotype_GRAPHICSGROUPITEM + undotype_UNKNOWN = 0, undotype_DOCUMENT, undotype_GRAPHICITEMTRANSFORM, undotype_GRAPHICITEM, undotype_GRAPHICTEXTITEM, undotype_PAGESIZE, undotype_GRAPHICSGROUPITEM, undotype_GRAPHICITEMZVALUE }; }; diff --git a/src/domain/UBGraphicsItemDelegate.cpp b/src/domain/UBGraphicsItemDelegate.cpp index ab73d0ad..07cdfeec 100644 --- a/src/domain/UBGraphicsItemDelegate.cpp +++ b/src/domain/UBGraphicsItemDelegate.cpp @@ -524,28 +524,28 @@ void UBGraphicsItemDelegate::increaseZLevelUp() { UBGraphicsScene *curScene = castUBGraphicsScene(); if (curScene) { - curScene->changeZLevelTo(delegated(), UBZLayerController::up); + curScene->changeZLevelTo(delegated(), UBZLayerController::up, true); } } void UBGraphicsItemDelegate::increaseZlevelTop() { UBGraphicsScene *curScene = castUBGraphicsScene(); if (curScene) { - curScene->changeZLevelTo(delegated(), UBZLayerController::top); + curScene->changeZLevelTo(delegated(), UBZLayerController::top, true); } } void UBGraphicsItemDelegate::increaseZLevelDown() { UBGraphicsScene *curScene = castUBGraphicsScene(); if (curScene) { - curScene->changeZLevelTo(delegated(), UBZLayerController::down); + curScene->changeZLevelTo(delegated(), UBZLayerController::down, true); } } void UBGraphicsItemDelegate::increaseZlevelBottom() { UBGraphicsScene *curScene = castUBGraphicsScene(); if (curScene) { - curScene->changeZLevelTo(delegated(), UBZLayerController::bottom); + curScene->changeZLevelTo(delegated(), UBZLayerController::bottom, true); } } diff --git a/src/domain/UBGraphicsItemZLevelUndoCommand.cpp b/src/domain/UBGraphicsItemZLevelUndoCommand.cpp new file mode 100644 index 00000000..d1683929 --- /dev/null +++ b/src/domain/UBGraphicsItemZLevelUndoCommand.cpp @@ -0,0 +1,59 @@ +#include "UBGraphicsItemZLevelUndoCommand.h" + +UBGraphicsItemZLevelUndoCommand::UBGraphicsItemZLevelUndoCommand(UBGraphicsScene *_scene, const QList& _items, qreal _previousZLevel, UBZLayerController::moveDestination dest):UBUndoCommand(){ + Q_ASSERT(_scene != NULL); + mpScene = _scene; + mItems = _items; + mPreviousZLevel = _previousZLevel; + mDest = dest; + mHack = false; +} + +UBGraphicsItemZLevelUndoCommand::UBGraphicsItemZLevelUndoCommand(UBGraphicsScene *_scene, QGraphicsItem* _item, qreal _previousZLevel, UBZLayerController::moveDestination dest):UBUndoCommand(){ + Q_ASSERT(_scene != NULL); + mpScene = _scene; + if(NULL != _item) + mItems.append(_item); + + mPreviousZLevel = _previousZLevel; + mDest = dest; + mHack = false; +} + +UBGraphicsItemZLevelUndoCommand::~UBGraphicsItemZLevelUndoCommand(){ + +} + +void UBGraphicsItemZLevelUndoCommand::undo(){ + if(!mpScene) + return; + + foreach(QGraphicsItem* item, mItems){ + if(mDest == UBZLayerController::down){ + mpScene->changeZLevelTo(item, UBZLayerController::up); + }else if(mDest == UBZLayerController::up){ + mpScene->changeZLevelTo(item, UBZLayerController::down); + } + updateLazyScene(); + } +} + +void UBGraphicsItemZLevelUndoCommand::redo(){ + if(!mHack){ + // Ugly! But pushing a new command to QUndoStack calls redo by itself. + mHack = true; + }else{ + if(!mpScene) + return; + + foreach(QGraphicsItem* item, mItems){ + mpScene->changeZLevelTo(item, mDest); + updateLazyScene(); + } + } +} + +void UBGraphicsItemZLevelUndoCommand::updateLazyScene(){ + mpScene->update(mpScene->sceneRect()); + mpScene->updateSelectionFrame(); +} diff --git a/src/domain/UBGraphicsItemZLevelUndoCommand.h b/src/domain/UBGraphicsItemZLevelUndoCommand.h new file mode 100644 index 00000000..0ec3a710 --- /dev/null +++ b/src/domain/UBGraphicsItemZLevelUndoCommand.h @@ -0,0 +1,32 @@ +#ifndef UBGRAPHICSITEMZLEVELUNDOCOMMAND_H +#define UBGRAPHICSITEMZLEVELUNDOCOMMAND_H + +#include + +#include "UBUndoCommand.h" +#include "UBGraphicsScene.h" + +class UBGraphicsItemZLevelUndoCommand : public UBUndoCommand{ +public: + UBGraphicsItemZLevelUndoCommand(UBGraphicsScene* _scene, const QList& _items, qreal _previousZLevel, UBZLayerController::moveDestination dest); + UBGraphicsItemZLevelUndoCommand(UBGraphicsScene* _scene, QGraphicsItem* _item, qreal _previousZLevel, UBZLayerController::moveDestination dest); + ~UBGraphicsItemZLevelUndoCommand(); + + virtual int getType() const { return UBUndoType::undotype_GRAPHICITEMZVALUE; } + +protected: + virtual void undo(); + virtual void redo(); + +private: + void updateLazyScene(); + + qreal mPreviousZLevel; + QList mItems; + UBGraphicsScene* mpScene; + UBZLayerController::moveDestination mDest; + bool mHack; +}; + + +#endif // UBGRAPHICSITEMZLEVELUNDOCOMMAND_H diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index fca39c3a..a87532a4 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -68,6 +68,7 @@ #include "UBGraphicsTextItem.h" #include "UBGraphicsStrokesGroup.h" #include "UBSelectionFrame.h" +#include "UBGraphicsItemZLevelUndoCommand.h" #include "domain/UBGraphicsGroupContainerItem.h" @@ -164,6 +165,7 @@ qreal UBZLayerController::changeZLevelTo(QGraphicsItem *item, moveDestination de QMapIteratoriCurElement(sortedItems); if (dest == up) { + qDebug() << "item data zvalue= " << item->data(UBGraphicsItemData::ItemOwnZValue).toReal(); if (iCurElement.findNext(item)) { if (iCurElement.hasNext()) { qreal nextZ = iCurElement.peekNext().value()->data(UBGraphicsItemData::ItemOwnZValue).toReal(); @@ -1068,8 +1070,6 @@ void UBGraphicsScene::notifyZChanged(QGraphicsItem *item, qreal zValue) void UBGraphicsScene::updateSelectionFrame() { - qDebug() << "selected item count" << selectedItems().count(); - if (!mSelectionFrame) { mSelectionFrame = new UBSelectionFrame(); addItem(mSelectionFrame); @@ -2170,9 +2170,17 @@ QUuid UBGraphicsScene::getPersonalUuid(QGraphicsItem *item) return idCandidate == QUuid().toString() ? QUuid() : QUuid(idCandidate); } -qreal UBGraphicsScene::changeZLevelTo(QGraphicsItem *item, UBZLayerController::moveDestination dest) +qreal UBGraphicsScene::changeZLevelTo(QGraphicsItem *item, UBZLayerController::moveDestination dest, bool addUndo) { - return mZLayerController->changeZLevelTo(item, dest); + qreal previousZVal = item->data(UBGraphicsItemData::ItemOwnZValue).toReal(); + qreal res = mZLayerController->changeZLevelTo(item, dest); + + if(addUndo){ + UBGraphicsItemZLevelUndoCommand* uc = new UBGraphicsItemZLevelUndoCommand(this, item, previousZVal, dest); + UBApplication::undoStack->push(uc); + } + + return res; } QGraphicsItem* UBGraphicsScene::rootItem(QGraphicsItem* item) const diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 19db8218..edd302f9 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -275,7 +275,7 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem void setNominalSize(int pWidth, int pHeight); - qreal changeZLevelTo(QGraphicsItem *item, UBZLayerController::moveDestination dest); + qreal changeZLevelTo(QGraphicsItem *item, UBZLayerController::moveDestination dest, bool addUndo=false); enum RenderingContext { @@ -314,7 +314,6 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem UBBoardView *controlView(); void notifyZChanged(QGraphicsItem *item, qreal zValue); - public slots: void updateSelectionFrame(); void updateSelectionFrameWrapper(int); diff --git a/src/domain/UBSelectionFrame.cpp b/src/domain/UBSelectionFrame.cpp index c253b197..e0b91b48 100644 --- a/src/domain/UBSelectionFrame.cpp +++ b/src/domain/UBSelectionFrame.cpp @@ -3,12 +3,12 @@ #include #include "domain/UBItem.h" +#include "domain/UBGraphicsItemZLevelUndoCommand.h" #include "board/UBBoardController.h" #include "core/UBSettings.h" #include "core/UBApplication.h" #include "gui/UBResources.h" #include "core/UBApplication.h" -#include "domain/UBGraphicsScene.h" #include "board/UBBoardView.h" UBSelectionFrame::UBSelectionFrame() @@ -245,37 +245,58 @@ void UBSelectionFrame::duplicate() void UBSelectionFrame::increaseZlevelUp() { - foreach (QGraphicsItem *item, sortedByZ(scene()->selectedItems())) { + QList selItems = sortedByZ(scene()->selectedItems()); + + QList::iterator itemIt = selItems.end(); + while(itemIt != selItems.begin()){ + itemIt--; + QGraphicsItem* item = *itemIt; ubscene()->changeZLevelTo(item, UBZLayerController::up); } + + addSelectionUndo(selItems, UBZLayerController::up); } void UBSelectionFrame::increaseZlevelTop() { - foreach (QGraphicsItem *item, sortedByZ(scene()->selectedItems())) { + QList selItems = sortedByZ(scene()->selectedItems()); + foreach (QGraphicsItem *item, selItems) { ubscene()->changeZLevelTo(item, UBZLayerController::top); } + addSelectionUndo(selItems, UBZLayerController::top); } void UBSelectionFrame::increaseZlevelDown() { - foreach (QGraphicsItem *item, sortedByZ(scene()->selectedItems())) { + QList selItems = sortedByZ(scene()->selectedItems()); + foreach (QGraphicsItem *item, selItems) { ubscene()->changeZLevelTo(item, UBZLayerController::down); } + addSelectionUndo(selItems, UBZLayerController::down); } void UBSelectionFrame::increaseZlevelBottom() { - QListIterator iter(sortedByZ(scene()->selectedItems())); + QList selItems = sortedByZ(scene()->selectedItems()); + QListIterator iter(selItems); iter.toBack(); while (iter.hasPrevious()) { ubscene()->changeZLevelTo(iter.previous(), UBZLayerController::bottom); } + addSelectionUndo(selItems, UBZLayerController::bottom); // foreach (QGraphicsItem *item, sortedByZ(scene()->selectedItems())) { // ubscene()->changeZLevelTo(item, UBZLayerController::bottom); // } } +void UBSelectionFrame::addSelectionUndo(QList items, UBZLayerController::moveDestination dest){ + if(!items.empty()){ + qreal topItemLevel = items.at(0)->data(UBGraphicsItemData::ItemOwnZValue).toReal(); + UBGraphicsItemZLevelUndoCommand* cmd = new UBGraphicsItemZLevelUndoCommand(ubscene(), items, topItemLevel, dest); + UBApplication::undoStack->push(cmd); + } +} + void UBSelectionFrame::translateItem(QGraphicsItem */*item*/, const QPointF &/*translatePoint*/) { } @@ -388,6 +409,7 @@ void UBSelectionFrame::setCursorFromAngle(QString angle) QList UBSelectionFrame::sortedByZ(const QList &pItems) { //select only items wiht the same z-level as item's one and push it to sortedItems QMultiMap + // It means: keep only the selected items and remove the selection frame from the list QMultiMap sortedItems; foreach (QGraphicsItem *tmpItem, pItems) { if (tmpItem->type() == Type) { diff --git a/src/domain/UBSelectionFrame.h b/src/domain/UBSelectionFrame.h index b9069ebe..184750d5 100644 --- a/src/domain/UBSelectionFrame.h +++ b/src/domain/UBSelectionFrame.h @@ -5,9 +5,10 @@ #include #include +#include "domain/UBGraphicsScene.h" + class DelegateButton; class UBGraphicsItemDelegate; -class UBGraphicsScene; class UBSelectionFrame : public QObject, public QGraphicsRectItem { @@ -48,6 +49,7 @@ private slots: void increaseZlevelBottom(); private: + void addSelectionUndo(QList items, UBZLayerController::moveDestination dest); void translateItem(QGraphicsItem *item, const QPointF &translatePoint); void placeButtons(); void placeExceptionButton(DelegateButton *pButton, QTransform pTransform); diff --git a/src/domain/domain.pri b/src/domain/domain.pri index b525dfd6..bfe9c11e 100644 --- a/src/domain/domain.pri +++ b/src/domain/domain.pri @@ -24,7 +24,8 @@ HEADERS += src/domain/UBGraphicsScene.h \ src/domain/UBGraphicsWidgetItemDelegate.h \ src/domain/UBGraphicsMediaItemDelegate.h \ src/domain/UBSelectionFrame.h \ - src/domain/UBUndoCommand.h + src/domain/UBUndoCommand.h \ + src/domain/UBGraphicsItemZLevelUndoCommand.h SOURCES += src/domain/UBGraphicsScene.cpp \ src/domain/UBGraphicsItemUndoCommand.cpp \ @@ -52,4 +53,5 @@ SOURCES += src/domain/UBGraphicsScene.cpp \ src/domain/UBGraphicsDelegateFrame.cpp \ src/domain/UBGraphicsWidgetItemDelegate.cpp \ src/domain/UBSelectionFrame.cpp \ - src/domain/UBUndoCommand.cpp + src/domain/UBUndoCommand.cpp \ + src/domain/UBGraphicsItemZLevelUndoCommand.cpp