From bdbf5140f9b8584144cb3a3b0fa1c2b4107f119a Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Mon, 25 Aug 2014 13:39:38 +0200 Subject: [PATCH] Sketcher new feature: Selects the elements associated with the selected constraint(s) Ex 1: User selects constraints from the list => right click => select "select elements" from the contextual menu => The elements (edges,vertex) involved in the constraint(s) are selected. Ex 2: User selects (a) constraint(s) => Clicks button in toolbar (if included by the user) => The elements (edges,vertex) involved in the constraint(s) are selected. Intended as visual aid to see which elements are being affected by a constraint. Requested by Jim on thread: http://forum.freecadweb.org/viewtopic.php?f=19&t=6875&start=10 Solving another Mantis ticket I can not find now. --- src/Mod/Sketcher/Gui/CommandSketcherTools.cpp | 126 ++++++++++++++++++ .../Sketcher/Gui/TaskSketcherConstrains.cpp | 24 ++++ src/Mod/Sketcher/Gui/TaskSketcherConstrains.h | 1 + src/Mod/Sketcher/Gui/Workbench.cpp | 6 +- 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp index 52dbe42cb..87ef06789 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp @@ -448,6 +448,131 @@ bool CmdSketcherSelectHorizontalAxis::isActive(void) return isSketcherAcceleratorActive( getActiveGuiDocument(), false ); } +DEF_STD_CMD_A(CmdSketcherSelectElementsAssociatedWithConstraints); + +CmdSketcherSelectElementsAssociatedWithConstraints::CmdSketcherSelectElementsAssociatedWithConstraints() + :Command("Sketcher_SelectElementsAssociatedWithConstraints") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Select Elements associated with constraints"); + sToolTipText = QT_TR_NOOP("Select Elements associated with constraints"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_SelectElementsAssociatedWithConstraints"; + sAccel = "CTRL+SHIFT+E"; + eType = ForEdit; +} + +void CmdSketcherSelectElementsAssociatedWithConstraints::activated(int iMsg) +{ + std::vector selection = Gui::Selection().getSelectionEx(); + + + + Gui::Document * doc= getActiveGuiDocument(); + + SketcherGui::ViewProviderSketch* vp = dynamic_cast(doc->getInEdit()); + + Sketcher::SketchObject* Obj= vp->getSketchObject(); + + const std::vector &SubNames = selection[0].getSubNames(); + const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); + + getSelection().clearSelection(); + + std::string doc_name = Obj->getDocument()->getName(); + std::string obj_name = Obj->getNameInDocument(); + std::stringstream ss; + + int selected=0; + + // go through the selected subelements + for (std::vector::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { + // only handle constraints + if (it->size() > 10 && it->substr(0,10) == "Constraint") { + int ConstrId = std::atoi(it->substr(10,4000).c_str()) - 1; + + if(ConstrIdFirst!=Constraint::GeoUndef){ + ss.str(std::string()); + + switch(vals[ConstrId]->FirstPos) + { + case Sketcher::none: + ss << "Edge" << vals[ConstrId]->First + 1; + break; + case Sketcher::start: + case Sketcher::end: + case Sketcher::mid: + int vertex = Obj->getVertexIndexGeoPos(vals[ConstrId]->First,vals[ConstrId]->FirstPos); + if(vertex>-1) + ss << "Vertex" << vertex + 1; + break; + } + + Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str()); + selected++; + } + + if(vals[ConstrId]->Second!=Constraint::GeoUndef){ + ss.str(std::string()); + + switch(vals[ConstrId]->SecondPos) + { + case Sketcher::none: + ss << "Edge" << vals[ConstrId]->Second + 1; + vals[ConstrId]->Second; + break; + case Sketcher::start: + case Sketcher::end: + case Sketcher::mid: + int vertex = Obj->getVertexIndexGeoPos(vals[ConstrId]->Second,vals[ConstrId]->SecondPos); + if(vertex>-1) + ss << "Vertex" << vertex + 1; + break; + } + + Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str()); + selected++; + } + + if(vals[ConstrId]->Third!=Constraint::GeoUndef){ + ss.str(std::string()); + + switch(vals[ConstrId]->ThirdPos) + { + case Sketcher::none: + ss << "Edge" << vals[ConstrId]->Third + 1; + vals[ConstrId]->Third; + break; + case Sketcher::start: + case Sketcher::end: + case Sketcher::mid: + int vertex = Obj->getVertexIndexGeoPos(vals[ConstrId]->Third,vals[ConstrId]->ThirdPos); + if(vertex>-1) + ss << "Vertex" << vertex + 1; + break; + } + + Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str()); + selected++; + } + } + } + } + + if ( selected == 0 ) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No constraint selected"), + QObject::tr("At least one constraint must be selected")); + } +} + +bool CmdSketcherSelectElementsAssociatedWithConstraints::isActive(void) +{ + return isSketcherAcceleratorActive( getActiveGuiDocument(), true ); +} + // Add Accelerator Commands void CreateSketcherCommandsConstraintAccel(void) { @@ -459,4 +584,5 @@ void CreateSketcherCommandsConstraintAccel(void) rcCmdMgr.addCommand(new CmdSketcherSelectOrigin()); rcCmdMgr.addCommand(new CmdSketcherSelectVerticalAxis()); rcCmdMgr.addCommand(new CmdSketcherSelectHorizontalAxis()); + rcCmdMgr.addCommand(new CmdSketcherSelectElementsAssociatedWithConstraints()); } diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp index c69c925f2..47fba3661 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp @@ -45,10 +45,28 @@ #include #include #include +#include using namespace SketcherGui; using namespace Gui::TaskView; +/// Inserts a QAction into an existing menu +/// ICONSTR is the string of the icon in the resource file +/// NAMESTR is the text appearing in the contextual menuAction +/// CMDSTR is the string registered in the commandManager +/// FUNC is the name of the member function to be executed on selection of the menu item +/// ACTSONSELECTION is a true/false value to activate the command only if a selection is made +#define CONTEXT_ITEM(ICONSTR,NAMESTR,CMDSTR,FUNC,ACTSONSELECTION) \ +QIcon icon_ ## FUNC( Gui::BitmapFactory().pixmap(ICONSTR) ); \ + QAction* constr_ ## FUNC = menu.addAction(icon_ ## FUNC,tr(NAMESTR), this, SLOT(FUNC()), \ + QKeySequence(QString::fromUtf8(Gui::Application::Instance->commandManager().getCommandByName(CMDSTR)->getAccel()))); \ + if(ACTSONSELECTION) constr_ ## FUNC->setEnabled(!items.isEmpty()); else constr_ ## FUNC->setEnabled(true); + +/// Defines the member function corresponding to the CONTEXT_ITEM macro +#define CONTEXT_MEMBER_DEF(CMDSTR,FUNC) \ +void ConstraintView::FUNC(){ \ + Gui::Application::Instance->commandManager().runCommandByName(CMDSTR);} + // helper class to store additional information about the listWidget entry. class ConstraintItem : public QListWidgetItem { @@ -106,6 +124,10 @@ void ConstraintView::contextMenuEvent (QContextMenuEvent* event) QMenu menu; QListWidgetItem* item = currentItem(); QList items = selectedItems(); + + CONTEXT_ITEM("Constraint_SelectElements","Select Elements","Sketcher_SelectElementsAssociatedWithConstraints",doSelectConstraints,true) + + QAction* sep = menu.addSeparator(); QAction* change = menu.addAction(tr("Change value"), this, SLOT(modifyCurrentItem())); QVariant v = item ? item->data(Qt::UserRole) : QVariant(); @@ -124,6 +146,8 @@ void ConstraintView::contextMenuEvent (QContextMenuEvent* event) menu.exec(event->globalPos()); } +CONTEXT_MEMBER_DEF("Sketcher_SelectElementsAssociatedWithConstraints",doSelectConstraints) + void ConstraintView::modifyCurrentItem() { /*emit*/itemActivated(currentItem()); diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.h b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.h index 870caf4b1..7d7806000 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.h +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.h @@ -52,6 +52,7 @@ protected Q_SLOTS: void modifyCurrentItem(); void renameCurrentItem(); void deleteSelectedItems(); + void doSelectConstraints(); }; class TaskSketcherConstrains : public Gui::TaskView::TaskBox, public Gui::SelectionObserver diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp index 04b77b90b..5aca75008 100644 --- a/src/Mod/Sketcher/Gui/Workbench.cpp +++ b/src/Mod/Sketcher/Gui/Workbench.cpp @@ -209,13 +209,15 @@ inline void SketcherAddWorkbenchTools(Gui::MenuItem& consaccel){ << "Sketcher_SelectConstraints" << "Sketcher_SelectOrigin" << "Sketcher_SelectVerticalAxis" - << "Sketcher_SelectHorizontalAxis"; + << "Sketcher_SelectHorizontalAxis" + << "Sketcher_SelectElementsAssociatedWithConstraints"; } template <> inline void SketcherAddWorkbenchTools(Gui::ToolBarItem& consaccel){ consaccel << "Sketcher_CloseShape" << "Sketcher_ConnectLines" - << "Sketcher_SelectConstraints"; + << "Sketcher_SelectConstraints" + << "Sketcher_SelectElementsAssociatedWithConstraints"; } template