diff --git a/doc/ChangeLog b/doc/ChangeLog index 792da9f9c..c1bcfd581 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,11 @@ 2011-07-08 vadim + * ObjectManipulator_slots.cpp (makeSubinterface): see #2561 "Add + context menu to move an interface to be a child of another + interface". New context menu (submenu) allows user to move an + interface in the tree to make it a subinterface of another + interface. + * parsers/pf.g: see #2556 "PF import: impor of rules referring to undefined macros". Importer now records all parser errors in the comments of rules where they occurred and marks these rules diff --git a/src/libgui/ObjectManipulator.cpp b/src/libgui/ObjectManipulator.cpp index e9c626301..545585bd1 100644 --- a/src/libgui/ObjectManipulator.cpp +++ b/src/libgui/ObjectManipulator.cpp @@ -825,6 +825,15 @@ void ObjectManipulator::contextMenuRequested(const QPoint &pos) popup_menu->addAction( tr("Inspect"), this, SLOT( inspect())); } + if (Interface::cast(currentObj)!=NULL) + { + popup_menu->addSeparator(); + FWObject *h = Host::getParentHost(currentObj); + list top_level_interfaces = h->getByType(Interface::TYPENAME); + top_level_interfaces.sort(FWObjectNameCmpPredicate()); + addSubinterfaceSubmenu(popup_menu, top_level_interfaces); + } + popup_menu->addSeparator(); QAction* lckID = popup_menu->addAction(tr("Lock"), this, SLOT(lockObject())); QAction* unlckID = popup_menu->addAction(tr("Unlock"), this, SLOT(unlockObject())); @@ -878,6 +887,53 @@ void ObjectManipulator::contextMenuRequested(const QPoint &pos) popup_menu->exec(QCursor::pos()); } +/* + * Add menu item "Make subinterface of ..." and submenu with list of + * top level interfaces. + */ +void ObjectManipulator::addSubinterfaceSubmenu( + QMenu *menu, + const list &top_level_interfaces) +{ + QMenu *submenu = menu->addMenu( tr("Make subinterface of...")); + list::const_iterator it; + for (it=top_level_interfaces.begin(); it!=top_level_interfaces.end(); ++it) + { + Interface *intf = Interface::cast(*it); + + bool skip_selected_interface = false; + foreach(FWObject *obj, getCurrentObjectTree()->getSelectedObjects()) + { + if (obj == intf) + { + skip_selected_interface = true; + break; + } + } + if (skip_selected_interface) continue; + if (intf->isLoopback()) continue; + + // can not add interfaces to a read-only parent interface + if (intf->isReadOnly()) continue; + + QString itf_name = QString::fromUtf8(intf->getName().c_str()); + FWObject *parent_fw = Host::getParentHost(intf); + + std::auto_ptr int_prop( + interfacePropertiesObjectFactory::getInterfacePropertiesObject( + parent_fw)); + if (int_prop->looksLikeVlanInterface(itf_name)) continue; + + QAction *a = submenu->addAction( + QIcon(":/Icons/Interface/icon-tree"), itf_name); + + a->setData(intf->getId()); + + connect( submenu, SIGNAL(triggered(QAction*)), + this, SLOT(makeSubinterface(QAction*))); + } +} + bool ObjectManipulator::getDeleteMenuState(FWObject *obj) { if (obj->isReadOnly()) return false; diff --git a/src/libgui/ObjectManipulator.h b/src/libgui/ObjectManipulator.h index ce4531dad..6fb28b4fd 100644 --- a/src/libgui/ObjectManipulator.h +++ b/src/libgui/ObjectManipulator.h @@ -278,6 +278,8 @@ public slots: void addNewKeywordSlot(); void processKeywordSlot(); + void makeSubinterface(QAction*); + public: Ui::ObjectManipulator_q *m_objectManipulator; @@ -466,6 +468,10 @@ public: const QString &text=QString(), int add_to_group_id=-1); + void addSubinterfaceSubmenu( + QMenu *menu, + const std::list &top_level_interfaces); + bool isObjectAllowed(const QString &type_name); bool isObjectAllowed(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); diff --git a/src/libgui/ObjectManipulator_slots.cpp b/src/libgui/ObjectManipulator_slots.cpp index a45a4f0d6..3d8209176 100644 --- a/src/libgui/ObjectManipulator_slots.cpp +++ b/src/libgui/ObjectManipulator_slots.cpp @@ -493,3 +493,36 @@ void ObjectManipulator::findWhereUsedSlot() } +void ObjectManipulator::makeSubinterface(QAction *act) +{ + int intf_id = act->data().toInt(); + FWObject *new_parent_interface = m_project->db()->findInIndex(intf_id); + assert(new_parent_interface!=NULL); + + if (getCurrentObjectTree()->getNumSelected()==0) return; + + ObjectTreeView* ot = getCurrentObjectTree(); + ot->freezeSelection(true); + FWObject *obj; + + vector so = getCurrentObjectTree()->getSimplifiedSelection(); + for (vector::iterator i=so.begin(); i!=so.end(); ++i) + { + obj = *i; + + if (fwbdebug) + qDebug() << "ObjectManipulator::makeSubinterface" + << "obj=" << obj + << obj->getName().c_str() + << "new parent:" << new_parent_interface->getName().c_str(); + + new_parent_interface->reparent(obj); + } + + FWObject *h = Host::getParentHost(new_parent_interface); + QCoreApplication::postEvent( + mw, new reloadObjectTreeEvent(m_project->getFileName())); + + ot->freezeSelection(false); +} +