diff --git a/urdf_editor/include/urdf_editor/link_collision_property.h b/urdf_editor/include/urdf_editor/link_collision_property.h index 7ec2586..5701d43 100644 --- a/urdf_editor/include/urdf_editor/link_collision_property.h +++ b/urdf_editor/include/urdf_editor/link_collision_property.h @@ -31,6 +31,7 @@ namespace urdf_editor QtProperty *getTopItem() { return top_item_; } + void removeSubProperties(); private slots: void onValueChanged(QtProperty *property, const QVariant &val); diff --git a/urdf_editor/include/urdf_editor/link_inertial_property.h b/urdf_editor/include/urdf_editor/link_inertial_property.h index 255181d..95e5276 100644 --- a/urdf_editor/include/urdf_editor/link_inertial_property.h +++ b/urdf_editor/include/urdf_editor/link_inertial_property.h @@ -27,6 +27,8 @@ namespace urdf_editor QtProperty *getTopItem() { return top_item_; } + void removeSubProperties(); + private slots: void onValueChanged(QtProperty *property, const QVariant &val); void onChildValueChanged(QtProperty *property, const QVariant &val); diff --git a/urdf_editor/include/urdf_editor/link_property.h b/urdf_editor/include/urdf_editor/link_property.h index 38f0d44..683344d 100644 --- a/urdf_editor/include/urdf_editor/link_property.h +++ b/urdf_editor/include/urdf_editor/link_property.h @@ -22,10 +22,12 @@ namespace urdf_editor void loadData(); + void setLinkName(QString new_name); + void removeSubProperties(); + bool hasInertialProperty(); void createInertialProperty(); LinkInertialPropertySharedPtr getInertialProperty(); - /*! Check if has visual property */ bool hasVisualProperty(); diff --git a/urdf_editor/include/urdf_editor/link_visual_property.h b/urdf_editor/include/urdf_editor/link_visual_property.h index 4187ea4..a06c629 100644 --- a/urdf_editor/include/urdf_editor/link_visual_property.h +++ b/urdf_editor/include/urdf_editor/link_visual_property.h @@ -33,6 +33,9 @@ namespace urdf_editor QtProperty *getTopItem() { return top_item_; } + void removeSubProperties(); + + private slots: void onValueChanged(QtProperty *property, const QVariant &val); void onChildValueChanged(QtProperty *property, const QVariant &val); diff --git a/urdf_editor/include/urdf_editor/urdf_property.h b/urdf_editor/include/urdf_editor/urdf_property.h index 1b13313..f3489f9 100644 --- a/urdf_editor/include/urdf_editor/urdf_property.h +++ b/urdf_editor/include/urdf_editor/urdf_property.h @@ -39,6 +39,7 @@ namespace urdf_editor private slots: void on_treeWidget_itemClicked(QTreeWidgetItem *item, int column); + void on_treeWidget_customContextMenuRequested(const QPoint &pos); void on_propertyWidget_customContextMenuRequested(const QPoint &pos); void on_propertyWidget_jointNameChanged(JointProperty *property, QString current_name, QString new_name); diff --git a/urdf_editor/src/link_collision_property.cpp b/urdf_editor/src/link_collision_property.cpp index 1900743..6fe2313 100644 --- a/urdf_editor/src/link_collision_property.cpp +++ b/urdf_editor/src/link_collision_property.cpp @@ -132,6 +132,13 @@ namespace urdf_editor loading_ = false; } + void LinkCollisionProperty::removeSubProperties() + { + QList sub_items = top_item_->subProperties(); + for (int i = 0; i < sub_items.length(); ++i) + top_item_->removeSubProperty(sub_items[i]); + } + void LinkCollisionProperty::loadFactoryForManager(QtTreePropertyBrowserSharedPtr& property_editor) { property_editor->setFactoryForManager(manager_, factory_); diff --git a/urdf_editor/src/link_inertial_property.cpp b/urdf_editor/src/link_inertial_property.cpp index c54b885..e2d02d9 100644 --- a/urdf_editor/src/link_inertial_property.cpp +++ b/urdf_editor/src/link_inertial_property.cpp @@ -121,6 +121,13 @@ namespace urdf_editor } } + void LinkInertialProperty::removeSubProperties() + { + QList sub_items = top_item_->subProperties(); + for (int i = 0; i < sub_items.length(); ++i) + top_item_->removeSubProperty(sub_items[i]); + } + void LinkInertialProperty::loadFactoryForManager(QtTreePropertyBrowserSharedPtr& property_editor) { property_editor->setFactoryForManager(manager_, factory_); diff --git a/urdf_editor/src/link_property.cpp b/urdf_editor/src/link_property.cpp index debf165..e350377 100644 --- a/urdf_editor/src/link_property.cpp +++ b/urdf_editor/src/link_property.cpp @@ -101,6 +101,19 @@ namespace urdf_editor } } + void LinkProperty::setLinkName(QString new_name) + { + name_item_->setValue(new_name); + } + + void LinkProperty::removeSubProperties() + { + QList sub_items = top_item_->subProperties(); + for (int i = 0; i < sub_items.length(); ++i) + if (sub_items[i]->propertyName() != "Type") + top_item_->removeSubProperty(sub_items[i]); + } + bool LinkProperty::hasInertialProperty() { return (inertial_property_ != NULL); diff --git a/urdf_editor/src/link_visual_property.cpp b/urdf_editor/src/link_visual_property.cpp index dce6a0f..f22daee 100644 --- a/urdf_editor/src/link_visual_property.cpp +++ b/urdf_editor/src/link_visual_property.cpp @@ -164,6 +164,13 @@ namespace urdf_editor loading_ = false; } + void LinkVisualProperty::removeSubProperties() + { + QList sub_items = top_item_->subProperties(); + for (int i = 0; i < sub_items.length(); ++i) + top_item_->removeSubProperty(sub_items[i]); + } + void LinkVisualProperty::loadFactoryForManager(QtTreePropertyBrowserSharedPtr& property_editor) { property_editor->setFactoryForManager(manager_, factory_); diff --git a/urdf_editor/src/urdf_property.cpp b/urdf_editor/src/urdf_property.cpp index 8c28702..26858b0 100644 --- a/urdf_editor/src/urdf_property.cpp +++ b/urdf_editor/src/urdf_property.cpp @@ -195,6 +195,119 @@ namespace urdf_editor return rviz_widget_->loadRobot(tree_widget_->getRobotModel()); } + void URDFProperty::on_treeWidget_customContextMenuRequested(const QPoint &pos) + { + QTreeWidgetItem *sel = tree_widget_->selectedItems()[0]; + QMenu *menu = new QMenu(tree_widget_); + menu->addAction("Add"); + menu->addAction("Remove"); + + // Add menu for converting the link to base/tool0 if there are no base/tool0 before + if (sel->parent() == link_root_) + { + bool base_exist = link_names_.contains("base", Qt::CaseSensitive); + bool tool0_exist = link_names_.contains("tool0", Qt::CaseSensitive); + if (!base_exist || !tool0_exist) + { + menu->addSeparator(); + QMenu *convertMenu = menu->addMenu("Convert to"); + if (!base_exist) + { + convertMenu->addAction("base"); + } + if (!tool0_exist) + { + convertMenu->addAction("tool0"); + } + } + } + + QAction *selected_item = menu->exec(tree_widget_->mapToGlobal(pos)); + if (selected_item) + { + if (selected_item->text() == "Add") + { + // we can only add to the link root item or to other links + if (sel == link_root_ || isLink(sel)) + { + addModelLink(sel); + } + // or to the joint root item or to other links + else if (sel == joint_root_ || isJoint(sel)) + { + addModelJoint(sel); + } + } + else if (selected_item->text() == "tool0") + { + // Change the name of current link + QString new_name = "tool0"; + LinkPropertySharedPtr activeLink = ltree_to_link_property_[sel]; + activeLink->setLinkName(new_name); + + // if this link already has an 'inertial' element, delete it + if (activeLink->hasInertialProperty()) + { + LinkInertialPropertySharedPtr inertial_property = activeLink->getInertialProperty(); + inertial_property->removeSubProperties(); + } + // if this link already has a 'visual element, delete it + if (activeLink->hasVisualProperty()) + { + LinkVisualPropertySharedPtr visual_property = activeLink->getVisualProperty(); + visual_property->removeSubProperties(); + } + // if this link already has a 'collision element, delete it + if (activeLink->hasCollisionProperty()) + { + LinkCollisionPropertySharedPtr collision_property = activeLink->getCollisionProperty(); + collision_property->removeSubProperties(); + } + } + else if (selected_item->text() == "base") + { + // Change the name of current link + QString new_name = "base"; + LinkPropertySharedPtr activeLink = ltree_to_link_property_[sel]; + activeLink->setLinkName(new_name); + + // if this link already has an 'inertial' element, delete it + if (activeLink->hasInertialProperty()) + { + LinkInertialPropertySharedPtr inertial_property = activeLink->getInertialProperty(); + inertial_property->removeSubProperties(); + } + // if this link already has a 'visual element, delete it + if (activeLink->hasVisualProperty()) + { + LinkVisualPropertySharedPtr visual_property = activeLink->getVisualProperty(); + visual_property->removeSubProperties(); + } + // if this link already has a 'collision element, delete it + if (activeLink->hasCollisionProperty()) + { + LinkCollisionPropertySharedPtr collision_property = activeLink->getCollisionProperty(); + collision_property->removeSubProperties(); + } + } + else + { + if (isLink(sel)) + { + link_names_.removeOne(sel->text(0)); + link_root_->removeChild(sel); + } + else if (isJoint(sel)) + { + joint_names_.removeOne(sel->text(0)); + sel->parent()->removeChild(sel); + } + } + } + + delete menu; + } + void URDFProperty::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column) { if (tree_widget_->isLink(item))