/* * 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, see . */ #include "UBGraphicsItemUndoCommand.h" #include #include "UBGraphicsScene.h" #include "core/UBApplication.h" #include "board/UBBoardController.h" #include "core/memcheck.h" #include "domain/UBGraphicsGroupContainerItem.h" UBGraphicsItemUndoCommand::UBGraphicsItemUndoCommand(UBGraphicsScene* pScene, const QSet& pRemovedItems, const QSet& pAddedItems, const QMultiMap &groupsMap) : mScene(pScene) , mRemovedItems(pRemovedItems - pAddedItems) , mAddedItems(pAddedItems - pRemovedItems) , mExcludedFromGroup(groupsMap) { mFirstRedo = true; QSetIterator itAdded(mAddedItems); while (itAdded.hasNext()) { UBApplication::boardController->freezeW3CWidget(itAdded.next(), true); } QSetIterator itRemoved(mRemovedItems); while (itRemoved.hasNext()) { UBApplication::boardController->freezeW3CWidget(itRemoved.next(), false); } } UBGraphicsItemUndoCommand::UBGraphicsItemUndoCommand(UBGraphicsScene* pScene, QGraphicsItem* pRemovedItem, QGraphicsItem* pAddedItem) : mScene(pScene) { if (pRemovedItem) { mRemovedItems.insert(pRemovedItem); } if (pAddedItem) { mAddedItems.insert(pAddedItem); } mFirstRedo = true; } UBGraphicsItemUndoCommand::~UBGraphicsItemUndoCommand() { //NOOP } void UBGraphicsItemUndoCommand::undo() { if (!mScene){ return; } QSetIterator itAdded(mAddedItems); while (itAdded.hasNext()) { QGraphicsItem* item = itAdded.next(); //if removing group if (item->type() == UBGraphicsGroupContainerItem::Type) { UBGraphicsGroupContainerItem *curGroup = qgraphicsitem_cast(item); if (curGroup) { curGroup->destroy(); } } UBApplication::boardController->freezeW3CWidget(item, true); item->setSelected(false); mScene->removeItem(item); } QSetIterator itRemoved(mRemovedItems); while (itRemoved.hasNext()) { QGraphicsItem* item = itRemoved.next(); if (item) { if (UBItemLayerType::FixedBackground == item->data(UBGraphicsItemData::ItemLayerType)) mScene->setAsBackgroundObject(item); else mScene->addItem(item); UBApplication::boardController->freezeW3CWidget(item, false); } } QMapIterator curMapElement(mExcludedFromGroup); UBGraphicsGroupContainerItem *nextGroup = 0; UBGraphicsGroupContainerItem *previousGroupItem; bool groupChanged = false; while (curMapElement.hasNext()) { curMapElement.next(); groupChanged = previousGroupItem != curMapElement.key(); //trying to find the group on the scene; if (!nextGroup || groupChanged) { UBGraphicsGroupContainerItem *groupCandidate = curMapElement.key(); if (groupCandidate) { nextGroup = groupCandidate; if(!mScene->items().contains(nextGroup)) { mScene->addItem(nextGroup); } nextGroup->setVisible(true); } } QGraphicsItem *groupedItem = mScene->itemForUuid(curMapElement.value()); if (groupedItem) { nextGroup->addToGroup(groupedItem); } previousGroupItem = curMapElement.key(); UBGraphicsItem::Delegate(nextGroup)->update(); } // force refresh, QT is a bit lazy and take a lot of time (nb item ^2 ?) to trigger repaint mScene->update(mScene->sceneRect()); } void UBGraphicsItemUndoCommand::redo() { // the Undo framework calls a redo while appending the undo command. // as we have already plotted the elements, we do not want to do it twice if (!mFirstRedo) { if (!mScene){ return; } QMapIterator curMapElement(mExcludedFromGroup); UBGraphicsGroupContainerItem *nextGroup = 0; UBGraphicsGroupContainerItem *previousGroupItem; bool groupChanged = false; while (curMapElement.hasNext()) { curMapElement.next(); groupChanged = previousGroupItem != curMapElement.key(); //trying to find the group on the scene; if (!nextGroup || groupChanged) { UBGraphicsGroupContainerItem *groupCandidate = curMapElement.key(); if (groupCandidate) { nextGroup = groupCandidate; } } QGraphicsItem *groupedItem = mScene->itemForUuid(curMapElement.value()); if (groupedItem) { if (nextGroup->childItems().count() == 1) { nextGroup->destroy(false); break; } nextGroup->removeFromGroup(groupedItem); } previousGroupItem = curMapElement.key(); UBGraphicsItem::Delegate(nextGroup)->update(); } QSetIterator itRemoved(mRemovedItems); while (itRemoved.hasNext()) { QGraphicsItem* item = itRemoved.next(); item->setSelected(false); mScene->removeItem(item); UBApplication::boardController->freezeW3CWidget(item, true); } QSetIterator itAdded(mAddedItems); while (itAdded.hasNext()) { QGraphicsItem* item = itAdded.next(); if (item) { UBApplication::boardController->freezeW3CWidget(item, false); if (UBItemLayerType::FixedBackground == item->data(UBGraphicsItemData::ItemLayerType)) mScene->setAsBackgroundObject(item); else mScene->addItem(item); } } // force refresh, QT is a bit lazy and take a lot of time (nb item ^2) to trigger repaint mScene->update(mScene->sceneRect()); } else { mFirstRedo = false; } }