From ac81fad37257fd0b4617af2e16e0bdd7999cd382 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 12 Jan 2023 19:40:59 +0100 Subject: [PATCH] Gui: refactor TreeWidget::dropEvent --- src/Gui/Tree.cpp | 103 +++++++++++++++++++++++++++++------------------ src/Gui/Tree.h | 3 ++ 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index 326c5402aa..16c9eff9ce 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -1616,6 +1616,7 @@ struct ItemInfo { std::vector subs; bool dragging = false; }; + struct ItemInfo2 { std::string doc; std::string obj; @@ -1626,6 +1627,60 @@ struct ItemInfo2 { std::string topSubname; }; +namespace { +class DropHandler +{ +public: + static std::vector > > filterItems(const QList& sels, QTreeWidgetItem* targetItem) + { + std::vector > > items; + items.reserve(sels.size()); + for (auto ti : sels) { + if (ti->type() != TreeWidget::ObjectType) + continue; + // ignore child elements if the parent is selected + if (sels.contains(ti->parent())) + continue; + if (ti == targetItem) + continue; + auto item = static_cast(ti); + items.emplace_back(); + auto& info = items.back(); + info.first = item; + const auto& subnames = item->getSubNames(); + info.second.insert(info.second.end(), subnames.begin(), subnames.end()); + } + + return items; + } + static App::PropertyPlacement* getPlacement(const ItemInfo& info, const App::DocumentObject* obj, Base::Matrix4D& mat) + { + App::PropertyPlacement* propPlacement = nullptr; + if (!info.topObj.empty()) { + auto doc = App::GetApplication().getDocument(info.topDoc.c_str()); + if (doc) { + auto topObj = doc->getObject(info.topObj.c_str()); + if (topObj) { + auto sobj = topObj->getSubObject(info.topSubname.c_str(), nullptr, &mat); + if (sobj == obj) { + propPlacement = Base::freecad_dynamic_cast( + obj->getPropertyByName("Placement")); + } + } + } + } + else { + propPlacement = Base::freecad_dynamic_cast( + obj->getPropertyByName("Placement")); + if (propPlacement) + mat = propPlacement->getValue().toMatrix(); + } + + return propPlacement; + } +}; +} + void TreeWidget::dropEvent(QDropEvent* event) { //FIXME: This should actually be done inside dropMimeData @@ -1649,35 +1704,23 @@ void TreeWidget::dropEvent(QDropEvent* event) // filter out the selected items we cannot handle std::vector > > items; - auto sels = selectedItems(); - items.reserve(sels.size()); - for (auto ti : sels) { - if (ti->type() != TreeWidget::ObjectType) - continue; - // ignore child elements if the parent is selected - if (sels.contains(ti->parent())) - continue; - if (ti == targetItem) - continue; - auto item = static_cast(ti); - items.emplace_back(); - auto& info = items.back(); - info.first = item; - info.second.insert(info.second.end(), item->mySubs.begin(), item->mySubs.end()); - } - + items = DropHandler::filterItems(selectedItems(), targetItem); if (items.empty()) return; // nothing needs to be done std::string errMsg; - if (QApplication::keyboardModifiers() == Qt::ControlModifier) + if (QApplication::keyboardModifiers() == Qt::ControlModifier) { event->setDropAction(Qt::CopyAction); + } else if (QApplication::keyboardModifiers() == Qt::AltModifier - && (items.size() == 1 || targetItem->type() == TreeWidget::DocumentType)) + && (items.size() == 1 || targetItem->type() == TreeWidget::DocumentType)) { event->setDropAction(Qt::LinkAction); - else + } + else { event->setDropAction(Qt::MoveAction); + } + auto da = event->dropAction(); bool dropOnly = da == Qt::CopyAction || da == Qt::LinkAction; @@ -1850,25 +1893,7 @@ void TreeWidget::dropEvent(QDropEvent* event) Base::Matrix4D mat; App::PropertyPlacement* propPlacement = nullptr; if (syncPlacement) { - if (!info.topObj.empty()) { - auto doc = App::GetApplication().getDocument(info.topDoc.c_str()); - if (doc) { - auto topObj = doc->getObject(info.topObj.c_str()); - if (topObj) { - auto sobj = topObj->getSubObject(info.topSubname.c_str(), nullptr, &mat); - if (sobj == obj) { - propPlacement = Base::freecad_dynamic_cast( - obj->getPropertyByName("Placement")); - } - } - } - } - else { - propPlacement = Base::freecad_dynamic_cast( - obj->getPropertyByName("Placement")); - if (propPlacement) - mat = propPlacement->getValue().toMatrix(); - } + propPlacement = DropHandler::getPlacement(info, obj, mat); } auto dropParent = targetParent; diff --git a/src/Gui/Tree.h b/src/Gui/Tree.h index f801c1e964..6e041bfacf 100644 --- a/src/Gui/Tree.h +++ b/src/Gui/Tree.h @@ -412,6 +412,9 @@ public: // cannot handle selection with sub name. So only a linked group can have // subname in selection int getSubName(std::ostringstream &str, App::DocumentObject *&topParent) const; + const std::vector& getSubNames() const { + return mySubs; + } void setHighlight(bool set, HighlightMode mode = HighlightMode::LightBlue);