From 459e0945822c4ffd06cfc3bc3974ee1241ca93f7 Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 16 Jun 2016 15:03:46 +0300 Subject: [PATCH] Fix for the issue #1569 : the moved groups must be updated --- src/Model/Model_Document.cpp | 36 ++++++++++++++++++++++---------- src/Model/Model_Events.cpp | 11 +++++----- src/Model/Model_Events.h | 20 ++++++------------ src/Model/Model_Objects.cpp | 3 +-- src/Model/Model_Update.cpp | 7 +++++++ src/ModelAPI/ModelAPI_Events.cpp | 2 +- src/ModelAPI/ModelAPI_Events.h | 10 +++------ src/XGUI/XGUI_DataModel.cpp | 4 ++-- 8 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 8ce08d8ee..ebc4de9d8 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -831,12 +831,37 @@ void Model_Document::removeFeature(FeaturePtr theFeature) myObjs->removeFeature(theFeature); } +// recursive function to check if theSub is a child of theMain composite feature +// through all the hierarchy of parents +static bool isSub(const CompositeFeaturePtr theMain, const FeaturePtr theSub) { + CompositeFeaturePtr aParent = ModelAPI_Tools::compositeOwner(theSub); + if (!aParent.get()) + return false; + if (aParent == theMain) + return true; + return isSub(theMain, aParent); +} + + void Model_Document::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis) { bool aCurrentUp = theMoved == currentFeature(false); if (aCurrentUp) { setCurrentFeatureUp(); } + // if user adds after high-level feature with nested, add it after all nested (otherwise the nested will be disabled) + CompositeFeaturePtr aCompositeAfter = std::dynamic_pointer_cast(theAfterThis); + if (aCompositeAfter.get()) { + FeaturePtr aSub = aCompositeAfter; + do { + FeaturePtr aNext = myObjs->nextFeature(aSub); + if (!isSub(aCompositeAfter, aNext)) { + theAfterThis = aSub; + break; + } + aSub = aNext; + } while (aSub.get()); + } myObjs->moveFeature(theMoved, theAfterThis); if (aCurrentUp) { // make the moved feature enabled or disabled due to the real status @@ -921,17 +946,6 @@ std::shared_ptr Model_Document::currentFeature(const bool theV return std::shared_ptr(); // null feature means the higher than first } -// recursive function to check if theSub is a child of theMain composite feature -// through all the hierarchy of parents -static bool isSub(const CompositeFeaturePtr theMain, const FeaturePtr theSub) { - CompositeFeaturePtr aParent = ModelAPI_Tools::compositeOwner(theSub); - if (!aParent.get()) - return false; - if (aParent == theMain) - return true; - return isSub(theMain, aParent); -} - void Model_Document::setCurrentFeature( std::shared_ptr theCurrent, const bool theVisible) { diff --git a/src/Model/Model_Events.cpp b/src/Model/Model_Events.cpp index 7847f99b1..34d9522d8 100644 --- a/src/Model/Model_Events.cpp +++ b/src/Model/Model_Events.cpp @@ -27,11 +27,10 @@ void Model_EventCreator::sendDeleted(const std::shared_ptr& t Events_Loop::loop()->send(aMsg, true); } -void Model_EventCreator::sendReordered(const std::shared_ptr& theDoc, - const std::string& theGroup) const +void Model_EventCreator::sendReordered(const std::shared_ptr& theReordered) const { std::shared_ptr aMsg( - new Model_OrderUpdatedMessage(theDoc, theGroup)); + new Model_OrderUpdatedMessage(theReordered)); Events_Loop::loop()->send(aMsg, true); } @@ -105,9 +104,9 @@ void Model_ObjectDeletedMessage::Join(const std::shared_ptr /////////////////////// REORDERED MESSAGE ///////////////////////////// Model_OrderUpdatedMessage::Model_OrderUpdatedMessage( - const std::shared_ptr& theDoc, const std::string& theGroup) - : ModelAPI_OrderUpdatedMessage(messageId(), 0), - myDoc(theDoc), myGroup(theGroup) + FeaturePtr theReordered, const void* theSender) + : ModelAPI_OrderUpdatedMessage(messageId(), theSender), + myReordered(theReordered) { } diff --git a/src/Model/Model_Events.h b/src/Model/Model_Events.h index 97f4170a4..09518c791 100644 --- a/src/Model/Model_Events.h +++ b/src/Model/Model_Events.h @@ -24,8 +24,7 @@ class Model_EventCreator : public ModelAPI_EventCreator const std::string& theGroup) const; /// creates reordered message and sends to the loop - virtual void sendReordered(const std::shared_ptr& theDoc, - const std::string& theGroup) const; + virtual void sendReordered(const std::shared_ptr& theReordered) const; /// must be one per application, the constructor for internal usage only Model_EventCreator(); @@ -90,25 +89,18 @@ class Model_ObjectDeletedMessage : public ModelAPI_ObjectDeletedMessage /// Message that feature was deleted (used for Object Browser update) class Model_OrderUpdatedMessage : public ModelAPI_OrderUpdatedMessage { - std::shared_ptr myDoc; ///< document owner of the feature - std::string myGroup; ///< group identifier that contained the deleted feature + std::shared_ptr myReordered; ///< the feature that was moved /// Use ModelAPI for creation of this event. - Model_OrderUpdatedMessage(const std::shared_ptr& theDoc, - const std::string& theGroup); + Model_OrderUpdatedMessage(FeaturePtr theReordered, + const void* theSender = 0); friend class Model_EventCreator; public: /// Returns the document that has been updated - virtual std::shared_ptr document() const - { - return myDoc; - } - - /// Returns the group where the objects were reordered - virtual const std::string& group() const + virtual std::shared_ptr reordered() { - return myGroup; + return myReordered; } /// Returns the identifier of this message diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 0be76f106..2351c9835 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -314,10 +314,9 @@ void Model_Objects::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis) // update the feature and the history clearHistory(theMoved); // make sure all (selection) attributes of moved feature will be updated - theMoved->data()->setUpdateID(0); static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED); ModelAPI_EventCreator::get()->sendUpdated(theMoved, EVENT_UPD); - ModelAPI_EventCreator::get()->sendReordered(theMoved->document(), theMoved->groupName()); + ModelAPI_EventCreator::get()->sendReordered(theMoved); } void Model_Objects::clearHistory(ObjectPtr theObj) diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 98d68fe1d..52cf1d1ba 100755 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -56,6 +56,8 @@ Model_Update::Model_Update() aLoop->registerListener(this, kPreviewBlockedEvent); static const Events_ID kPreviewRequestedEvent = aLoop->eventByName(EVENT_PREVIEW_REQUESTED); aLoop->registerListener(this, kPreviewRequestedEvent); + static const Events_ID kReorderEvent = aLoop->eventByName(EVENT_ORDER_UPDATED); + aLoop->registerListener(this, kReorderEvent); // Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true"; myIsParamUpdated = false; @@ -182,6 +184,7 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag static const Events_ID kStabilityEvent = aLoop->eventByName(EVENT_STABILITY_CHANGED); static const Events_ID kPreviewBlockedEvent = aLoop->eventByName(EVENT_PREVIEW_BLOCKED); static const Events_ID kPreviewRequestedEvent = aLoop->eventByName(EVENT_PREVIEW_REQUESTED); + static const Events_ID kReorderEvent = aLoop->eventByName(EVENT_ORDER_UPDATED); #ifdef DEB_UPDATE std::cout<<"****** Event "<eventID().eventText()<& theMessag // in the end of transaction everything is updated, so clear the old objects myIsParamUpdated = false; myWaitForFinish.clear(); + } else if (theMessage->eventID() == kReorderEvent) { + std::shared_ptr aMsg = + std::dynamic_pointer_cast(theMessage); + addModified(aMsg->reordered(), aMsg->reordered()); // to update all attributes } } diff --git a/src/ModelAPI/ModelAPI_Events.cpp b/src/ModelAPI/ModelAPI_Events.cpp index 45f321509..0b64a091e 100644 --- a/src/ModelAPI/ModelAPI_Events.cpp +++ b/src/ModelAPI/ModelAPI_Events.cpp @@ -35,7 +35,7 @@ ModelAPI_ObjectDeletedMessage::~ModelAPI_ObjectDeletedMessage() } ModelAPI_OrderUpdatedMessage::ModelAPI_OrderUpdatedMessage(const Events_ID theID, - const void* theSender) + const void* theSender) : Events_Message(theID, theSender) { diff --git a/src/ModelAPI/ModelAPI_Events.h b/src/ModelAPI/ModelAPI_Events.h index 93a8870b0..f80dd6240 100644 --- a/src/ModelAPI/ModelAPI_Events.h +++ b/src/ModelAPI/ModelAPI_Events.h @@ -115,17 +115,14 @@ public: class MODELAPI_EXPORT ModelAPI_OrderUpdatedMessage : public Events_Message { protected: - /// Creates an empty message + /// Creates a message: ModelAPI_OrderUpdatedMessage(const Events_ID theID, const void* theSender = 0); /// The virtual destructor virtual ~ModelAPI_OrderUpdatedMessage(); public: /// Returns the document that has been updated - virtual std::shared_ptr document() const = 0; - - /// Returns the groups where the objects were reordered - virtual const std::string& group() const = 0; + virtual std::shared_ptr reordered() = 0; /// Returns the identifier of the kind of a message virtual const Events_ID messageId() = 0; @@ -142,8 +139,7 @@ public: virtual void sendDeleted(const std::shared_ptr& theDoc, const std::string& theGroup) const = 0; /// creates reordered message and sends to the loop - virtual void sendReordered(const std::shared_ptr& theDoc, - const std::string& theGroup) const = 0; + virtual void sendReordered(const std::shared_ptr& theReordered) const = 0; /// returns the creator instance static const ModelAPI_EventCreator* get(); diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 7b66c2bff..cc80025fb 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -255,8 +255,8 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) { std::shared_ptr aUpdMsg = std::dynamic_pointer_cast(theMessage); - DocumentPtr aDoc = aUpdMsg->document(); - std::string aGroup = aUpdMsg->group(); + DocumentPtr aDoc = aUpdMsg->reordered()->document(); + std::string aGroup = aUpdMsg->reordered()->group(); QModelIndex aParent; int aStartId = 0; -- 2.39.2