From d9be19bbe8cde4775e0f61c5702e751267a4af32 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Thu, 30 Nov 2017 20:18:42 +0100 Subject: [PATCH] re-enable drag-n-drop to edit task pipeline --- .../src/task_list_model.cpp | 22 +++++++--------- .../src/task_list_model.h | 1 - .../motion_planning_tasks/src/task_panel.cpp | 6 ++++- .../test/test_merge_models.cpp | 3 ++- .../utils/flat_merge_proxy_model.cpp | 11 ++++++++ .../utils/flat_merge_proxy_model.h | 2 ++ .../utils/tree_merge_proxy_model.cpp | 26 +++++++++++++------ .../utils/tree_merge_proxy_model.h | 2 ++ 8 files changed, 49 insertions(+), 24 deletions(-) diff --git a/visualization/motion_planning_tasks/src/task_list_model.cpp b/visualization/motion_planning_tasks/src/task_list_model.cpp index c5e9e762..375d0c72 100644 --- a/visualization/motion_planning_tasks/src/task_list_model.cpp +++ b/visualization/motion_planning_tasks/src/task_list_model.cpp @@ -141,6 +141,7 @@ TaskListModel::TaskListModel(QObject *parent) : FlatMergeProxyModel(parent) { ROS_DEBUG_NAMED(LOGNAME, "created TaskListModel: %p", this); + setStageFactory(getStageFactory()); } TaskListModel::~TaskListModel() { @@ -171,28 +172,21 @@ void TaskListModel::setSolutionClient(ros::ServiceClient *client) void TaskListModel::setStageFactory(const StageFactoryPtr &factory) { stage_factory_ = factory; + if (stage_factory_) + setMimeTypes({ stage_factory_->mimeType() }); } // re-implemented from base class to allow dropping Qt::ItemFlags TaskListModel::flags(const QModelIndex &index) const { + auto f = FlatMergeProxyModel::flags(index); + if (!index.isValid()) { - Qt::ItemFlags f = QAbstractItemModel::flags(index); // dropping at root will create a new local task if (stage_factory_) f |= Qt::ItemIsDropEnabled; - return f; } - - return FlatMergeProxyModel::flags(index); -} - -QStringList TaskListModel::mimeTypes() const -{ - QStringList result; - if (stage_factory_) - result << stage_factory_->mimeType(); - return result; + return f; } QVariant TaskListModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -290,7 +284,9 @@ bool TaskListModel::dropMimeData(const QMimeData *mime, Qt::DropAction action, i } // create a new local task using the given container as root - insertModel(new LocalTaskModel(std::move(container), this), row); + auto *m = new LocalTaskModel(std::move(container), this); + m->setStageFactory(stage_factory_); + insertModel(m, row); return true; } diff --git a/visualization/motion_planning_tasks/src/task_list_model.h b/visualization/motion_planning_tasks/src/task_list_model.h index 32165b8b..c801fe8a 100644 --- a/visualization/motion_planning_tasks/src/task_list_model.h +++ b/visualization/motion_planning_tasks/src/task_list_model.h @@ -141,7 +141,6 @@ public: /// providing a StageFactory makes the model accepting drops void setStageFactory(const StageFactoryPtr &factory); - QStringList mimeTypes() const override; bool dropMimeData(const QMimeData *mime, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; Qt::DropActions supportedDropActions() const override; Qt::ItemFlags flags(const QModelIndex &index) const; diff --git a/visualization/motion_planning_tasks/src/task_panel.cpp b/visualization/motion_planning_tasks/src/task_panel.cpp index 2cffd95f..78d018f2 100644 --- a/visualization/motion_planning_tasks/src/task_panel.cpp +++ b/visualization/motion_planning_tasks/src/task_panel.cpp @@ -98,7 +98,11 @@ TaskPanelPrivate::TaskPanelPrivate(TaskPanel *q_ptr) { setupUi(q_ptr); // init tasks view - tasks_view->setModel(&MetaTaskListModel::instance()); + MetaTaskListModel *meta_model = &MetaTaskListModel::instance(); + StageFactoryPtr factory = getStageFactory(); + if (factory) meta_model->setMimeTypes( { factory->mimeType() } ); + else button_show_stage_dock_widget->setEnabled(false); + tasks_view->setModel(meta_model); tasks_view->setSelectionMode(QAbstractItemView::ExtendedSelection); tasks_view->setAcceptDrops(true); diff --git a/visualization/motion_planning_tasks/test/test_merge_models.cpp b/visualization/motion_planning_tasks/test/test_merge_models.cpp index 424ffb6a..abdf5d52 100644 --- a/visualization/motion_planning_tasks/test/test_merge_models.cpp +++ b/visualization/motion_planning_tasks/test/test_merge_models.cpp @@ -97,7 +97,8 @@ TEST(TreeMergeModel, basics) { EXPECT_EQ(tree.rowCount(), 1); EXPECT_EQ(tree.columnCount(), 3); - EXPECT_TRUE(tree.index(0, 1).flags() & Qt::ItemIsSelectable); + EXPECT_TRUE(tree.index(0, 0).flags() & Qt::ItemIsSelectable); + EXPECT_FALSE(tree.index(0, 1).flags() & Qt::ItemIsSelectable); EXPECT_FALSE(tree.index(1, 0).isValid()); QModelIndex idx = tree.index(0, 0); diff --git a/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.cpp b/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.cpp index 3661b9cf..a1ae58af 100644 --- a/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.cpp +++ b/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.cpp @@ -45,6 +45,7 @@ class FlatMergeProxyModelPrivate { public: Q_DECLARE_PUBLIC(FlatMergeProxyModel) FlatMergeProxyModel* q_ptr; + QStringList mime_types_; struct ModelData { ModelData(QAbstractItemModel* m) : model_(m) {} @@ -297,6 +298,16 @@ bool FlatMergeProxyModel::setData(const QModelIndex &index, const QVariant &valu return data->model_->setData(src_index, value, role); } +void FlatMergeProxyModel::setMimeTypes(const QStringList &mime_types) +{ + d_ptr->mime_types_ = mime_types; +} + +QStringList FlatMergeProxyModel::mimeTypes() const +{ + return d_ptr->mime_types_; +} + bool FlatMergeProxyModel::dropMimeData(const QMimeData *mime, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (!parent.isValid()) diff --git a/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.h b/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.h index a937f6b6..4ffb89d7 100644 --- a/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.h +++ b/visualization/motion_planning_tasks/utils/flat_merge_proxy_model.h @@ -78,6 +78,8 @@ public: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + void setMimeTypes(const QStringList& mime_types); + QStringList mimeTypes() const override; bool dropMimeData(const QMimeData *mime, Qt::DropAction action, int row, int column, const QModelIndex &parent); bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; diff --git a/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.cpp b/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.cpp index 27bd1c23..b6629c59 100644 --- a/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.cpp +++ b/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.cpp @@ -44,6 +44,7 @@ class TreeMergeProxyModelPrivate { public: Q_DECLARE_PUBLIC(TreeMergeProxyModel) TreeMergeProxyModel* q_ptr; + QStringList mime_types_; struct ModelData { ModelData(const QString& name, QAbstractItemModel* m) @@ -248,16 +249,15 @@ Qt::ItemFlags TreeMergeProxyModel::flags(const QModelIndex &index) const if (!index.isValid()) return QAbstractItemModel::flags(index); - if (isGroupItem(index)) { // top-level item - auto f = QAbstractItemModel::flags(index); - if (index.column() == 0) - f |= Qt::ItemIsEditable | Qt::ItemIsSelectable; - return f; - } - TreeMergeProxyModelPrivate::ModelData *data = nullptr; QModelIndex src_index = d_ptr->mapToSource(index, data); - return data->model_ ->flags(src_index); + auto f = data->model_ ->flags(src_index); + + if (isGroupItem(index)) { // top-level item + if (index.column() == 0) + f |= Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable; + } + return f; } QVariant TreeMergeProxyModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -302,6 +302,16 @@ bool TreeMergeProxyModel::setData(const QModelIndex &index, const QVariant &valu return data->model_->setData(src_index, value, role); } +void TreeMergeProxyModel::setMimeTypes(const QStringList &mime_types) +{ + d_ptr->mime_types_ = mime_types; +} + +QStringList TreeMergeProxyModel::mimeTypes() const +{ + return d_ptr->mime_types_; +} + bool TreeMergeProxyModel::dropMimeData(const QMimeData *mime, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (!parent.isValid()) diff --git a/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.h b/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.h index 50de93c0..55d97219 100644 --- a/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.h +++ b/visualization/motion_planning_tasks/utils/tree_merge_proxy_model.h @@ -79,6 +79,8 @@ public: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + void setMimeTypes(const QStringList& mime_types); + QStringList mimeTypes() const override; bool dropMimeData(const QMimeData *mime, Qt::DropAction action, int row, int column, const QModelIndex &parent); bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;