From 36be73c9b78b77e544f9522c220a9b929715ce90 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Sat, 30 Apr 2022 10:51:57 +0800 Subject: [PATCH] Sketcher: add 3D view context menu when editing sketch Closes realthunder/FreeCAD_Assembly3#723 @wohltat --- src/Mod/Sketcher/Gui/CommandCreateGeo.cpp | 9 +-- .../Sketcher/Gui/TaskSketcherConstraints.cpp | 44 +++++++++----- .../Sketcher/Gui/TaskSketcherConstraints.h | 5 ++ src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 58 +++++++++++++++++++ 4 files changed, 99 insertions(+), 17 deletions(-) diff --git a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp index 0b3a8824b327..cdf0ddbbda8a 100644 --- a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp +++ b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp @@ -6747,7 +6747,7 @@ CmdSketcherExternal::CmdSketcherExternal() { sAppModule = "Sketcher"; sGroup = "Sketcher"; - sMenuText = QT_TR_NOOP("External geometry"); + sMenuText = QT_TR_NOOP("Add external geometry"); sToolTipText = QT_TR_NOOP("Create an edge linked to an external geometry"); sWhatsThis = "Sketcher_External"; sStatusTip = sToolTipText; @@ -6774,8 +6774,9 @@ CmdSketcherDefining::CmdSketcherDefining() { sAppModule = "Sketcher"; sGroup = QT_TR_NOOP("Sketcher"); - sMenuText = QT_TR_NOOP("Defining geometry"); - sToolTipText = QT_TR_NOOP("Create an defining edge linked to an external geometry"); + sMenuText = QT_TR_NOOP("Add/toggle defining geometry"); + sToolTipText = QT_TR_NOOP("Import an external geometry as defining geometry that can be use for extrusion.\n" + "Or toggle the defining status of an already imported external geometry."); sWhatsThis = "Sketcher_Defining"; sStatusTip = sToolTipText; sPixmap = "Sketcher_Defining"; @@ -7009,7 +7010,7 @@ void CmdSketcherFixExternal::activated(int iMsg) bool CmdSketcherFixExternal::isActive(void) { - return true; + return getExternalSelection(0)!=0; } diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp index e337a12776e7..1d78e3e87c70 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp @@ -432,20 +432,35 @@ class ExpressionDelegate : public QStyledItemDelegate QListWidget * view; }; +static ConstraintView *_ConstraintViewInstance; + ConstraintView::ConstraintView(QWidget *parent) : QListWidget(parent) { ExpressionDelegate * delegate = new ExpressionDelegate(this); setItemDelegate(delegate); + _ConstraintViewInstance = this; } ConstraintView::~ConstraintView() { + _ConstraintViewInstance = nullptr; +} + +ConstraintView *ConstraintView::getInstance() +{ + return _ConstraintViewInstance; } void ConstraintView::contextMenuEvent (QContextMenuEvent* event) { QMenu menu; + populateMenu(menu); + menu.exec(event->globalPos()); +} + +void ConstraintView::populateMenu(QMenu &menu) +{ QListWidgetItem* item = currentItem(); QList items = selectedItems(); @@ -456,18 +471,23 @@ void ConstraintView::contextMenuEvent (QContextMenuEvent* event) // Sync the FreeCAD selection with the selection in the ConstraintView widget if (didRelease) { Gui::Selection().clearSelection(); - std::string doc_name = static_cast(item)->sketchView->getSketchObject()->getDocument()->getName(); - std::string obj_name = static_cast(item)->sketchView->getSketchObject()->getNameInDocument(); - - std::vector constraintSubNames; - for (auto&& it : items) { - auto ci = static_cast(it); - std::string constraint_name = Sketcher::PropertyConstraintList::getConstraintName(ci->ConstraintNbr); - constraintSubNames.push_back(constraint_name.c_str()); - } - if(!constraintSubNames.empty()) - Gui::Selection().addSelections(doc_name.c_str(), obj_name.c_str(), constraintSubNames); + if (auto parent = qobject_cast(parentWidget())) { + if (auto sketchView = parent->getViewProvider()) { + std::string doc_name = sketchView->getSketchObject()->getDocument()->getName(); + std::string obj_name = sketchView->getSketchObject()->getNameInDocument(); + + std::vector constraintSubNames; + for (auto&& it : items) { + auto ci = static_cast(it); + std::string constraint_name = Sketcher::PropertyConstraintList::getConstraintName(ci->ConstraintNbr); + constraintSubNames.push_back(constraint_name.c_str()); + } + + if(!constraintSubNames.empty()) + Gui::Selection().addSelections(doc_name.c_str(), obj_name.c_str(), constraintSubNames); + } + } } bool isQuantity = false; @@ -524,8 +544,6 @@ void ConstraintView::contextMenuEvent (QContextMenuEvent* event) QAction* swap = menu.addAction(tr("Swap constraint names"), this, SLOT(swapNamedOfSelectedItems())); swap->setEnabled(items.size() == 2); - - menu.exec(event->globalPos()); } CONTEXT_MEMBER_DEF("Sketcher_SelectElementsAssociatedWithConstraints",doSelectConstraints) diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h index bfd5d19e08a7..e2f965820594 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h @@ -50,6 +50,9 @@ class ConstraintView : public QListWidget explicit ConstraintView(QWidget *parent = 0); ~ConstraintView(); + static ConstraintView *getInstance(); + void populateMenu(QMenu &menu); + protected: void contextMenuEvent (QContextMenuEvent* event); @@ -89,6 +92,8 @@ class TaskSketcherConstraints : public Gui::TaskView::TaskBox, public Gui::Selec /// Observer message from the Selection void onSelectionChanged(const Gui::SelectionChanges& msg); + ViewProviderSketch *getViewProvider() {return sketchView;} + private: void slotConstraintsChanged(void); bool isConstraintFiltered(QListWidgetItem * item); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 162b0286141a..315011fe8e23 100755 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -110,6 +110,7 @@ #include #include #include +#include #include #include @@ -125,6 +126,8 @@ #include "DrawSketchHandler.h" #include "TaskDlgEditSketch.h" #include "TaskSketcherValidation.h" +#include "TaskSketcherConstraints.h" +#include "Workbench.h" #include "CommandConstraints.h" #include "ViewProviderSketchGeometryExtension.h" #include @@ -814,6 +817,61 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe return false; } + if (_Mode == STATUS_NONE && !pressed && Button == 2) { + QMenu menu; + if (Gui::Selection().hasPreselection()) { + auto sel = Gui::Selection().getPreselection(); + if (!Gui::Selection().isSelected(sel.pDocName, sel.pObjectName, sel.pSubName, 0)) { + if (!(QApplication::queryKeyboardModifiers() & Qt::ShiftModifier)) + Gui::Selection().clearSelection(); + Gui::SelectionNoTopParentCheck guard; + Gui::Selection().addSelection(sel.pDocName, sel.pObjectName, sel.pSubName); + } + } + if (!edit->SelConstraintSet.empty()) { + if (auto inst = ConstraintView::getInstance()) + inst->populateMenu(menu); + } + else if (!Gui::Selection().hasSelection()) { + Gui::MenuItem mitems; + addSketcherWorkbenchGeometries(mitems); + Gui::MenuManager::getInstance()->setupContextMenu(&mitems, menu); + } else { + Gui::MenuItem mitems; + Gui::MenuItem *cstrItems = new Gui::MenuItem; + cstrItems->setCommand(QT_TRANSLATE_NOOP("Sketcher", "Add constraint")); + addSketcherWorkbenchConstraints(*cstrItems); + Gui::MenuItem *toolsItems = new Gui::MenuItem; + toolsItems->setCommand(QT_TRANSLATE_NOOP("Sketcher", "Tools")); + *toolsItems << "Sketcher_Trimming" + << "Sketcher_Extend" + << "Sketcher_Split" + << "Sketcher_CarbonCopy" + << "Sketcher_ExportGeometry" + << "Sketcher_ExportCompound" + << "Sketcher_SwapGeometryID"; + Gui::MenuItem *bsplineItems = new Gui::MenuItem; + bsplineItems->setCommand(QT_TRANSLATE_NOOP("Sketcher", "BSpline tools")); + addSketcherWorkbenchBSplines(*bsplineItems); + mitems << cstrItems + << "Separator"; + if (auto cmd = dynamic_cast( + Gui::Application::Instance->commandManager().getCommandByName("Sketcher_ExternalCmds"))) { + for(auto c : cmd->getCommands()) + mitems << c->getName(); + } + mitems << "Separator" + << "Sketcher_ToggleConstruction" + << toolsItems + << bsplineItems + << "Separator"; + addSketcherWorkbenchVirtualSpace(mitems); + Gui::MenuManager::getInstance()->setupContextMenu(&mitems, menu); + } + menu.exec(QCursor::pos()); + return true; + } + // Both Mouse button is down, cancel current mode to avoid conflict with // some navigation method. auto btns = QApplication::mouseButtons();