Gui: refactor TreeWidget::dropEvent

This commit is contained in:
wmayer
2023-01-12 19:40:59 +01:00
parent 5b1c781b8d
commit ac81fad372
2 changed files with 67 additions and 39 deletions

View File

@@ -1616,6 +1616,7 @@ struct ItemInfo {
std::vector<std::string> 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<std::pair<DocumentObjectItem*, std::vector<std::string> > > filterItems(const QList<QTreeWidgetItem*>& sels, QTreeWidgetItem* targetItem)
{
std::vector<std::pair<DocumentObjectItem*, std::vector<std::string> > > 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<DocumentObjectItem*>(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<App::PropertyPlacement>(
obj->getPropertyByName("Placement"));
}
}
}
}
else {
propPlacement = Base::freecad_dynamic_cast<App::PropertyPlacement>(
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<std::pair<DocumentObjectItem*, std::vector<std::string> > > 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<DocumentObjectItem*>(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<App::PropertyPlacement>(
obj->getPropertyByName("Placement"));
}
}
}
}
else {
propPlacement = Base::freecad_dynamic_cast<App::PropertyPlacement>(
obj->getPropertyByName("Placement"));
if (propPlacement)
mat = propPlacement->getValue().toMatrix();
}
propPlacement = DropHandler::getPlacement(info, obj, mat);
}
auto dropParent = targetParent;

View File

@@ -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<std::string>& getSubNames() const {
return mySubs;
}
void setHighlight(bool set, HighlightMode mode = HighlightMode::LightBlue);