From 613e672654df0f1e6838fb55b384842ce534809a Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 5 Dec 2017 16:25:04 +0300 Subject: [PATCH] #2309 Possibility to hide faces --- src/ModuleBase/CMakeLists.txt | 5 + src/ModuleBase/ModuleBase_ActionType.h | 1 + src/ModuleBase/ModuleBase_BRepOwner.cpp | 23 + src/ModuleBase/ModuleBase_BRepOwner.h | 63 +++ src/ModuleBase/ModuleBase_IModule.h | 3 + src/ModuleBase/ModuleBase_ListView.cpp | 177 ++++++++ src/ModuleBase/ModuleBase_ListView.h | 95 +++++ src/ModuleBase/ModuleBase_ModelWidget.h | 3 + src/ModuleBase/ModuleBase_ResultPrs.cpp | 80 +++- src/ModuleBase/ModuleBase_ResultPrs.h | 54 +-- src/ModuleBase/ModuleBase_Tools.cpp | 14 + src/ModuleBase/ModuleBase_Tools.h | 9 +- src/ModuleBase/ModuleBase_ViewerPrs.cpp | 1 + .../ModuleBase_WidgetFeatureSelector.cpp | 15 +- .../ModuleBase_WidgetFeatureSelector.h | 5 +- .../ModuleBase_WidgetMultiSelector.cpp | 146 ++----- .../ModuleBase_WidgetMultiSelector.h | 27 +- src/PartSet/PartSet_Module.cpp | 33 +- src/PartSet/PartSet_Module.h | 2 + src/PartSet/PartSet_PreviewSketchPlane.cpp | 2 +- src/PartSet/PartSet_SketcherMgr.cpp | 42 +- src/PartSet/PartSet_SketcherMgr.h | 6 + src/PartSet/PartSet_WidgetSketchLabel.cpp | 20 +- src/PartSet/PartSet_WidgetSketchLabel.h | 9 +- src/XGUI/CMakeLists.txt | 14 + src/XGUI/XGUI_ActiveControlMgr.cpp | 109 +++++ src/XGUI/XGUI_ActiveControlMgr.h | 78 ++++ src/XGUI/XGUI_ActiveControlSelector.h | 78 ++++ src/XGUI/XGUI_Displayer.cpp | 26 +- src/XGUI/XGUI_Displayer.h | 3 +- src/XGUI/XGUI_FacesPanel.cpp | 396 ++++++++++++++++++ src/XGUI/XGUI_FacesPanel.h | 175 ++++++++ src/XGUI/XGUI_FacesPanelSelector.cpp | 49 +++ src/XGUI/XGUI_FacesPanelSelector.h | 64 +++ src/XGUI/XGUI_ObjectsBrowser.cpp | 9 +- src/XGUI/XGUI_OperationMgr.cpp | 19 + src/XGUI/XGUI_PropertyPanel.cpp | 12 +- src/XGUI/XGUI_PropertyPanelSelector.cpp | 67 +++ src/XGUI/XGUI_PropertyPanelSelector.h | 71 ++++ src/XGUI/XGUI_Selection.cpp | 3 +- src/XGUI/XGUI_Workshop.cpp | 227 +++++++--- src/XGUI/XGUI_Workshop.h | 33 +- src/XGUI/XGUI_WorkshopListener.cpp | 52 ++- 43 files changed, 1996 insertions(+), 324 deletions(-) create mode 100644 src/ModuleBase/ModuleBase_BRepOwner.cpp create mode 100644 src/ModuleBase/ModuleBase_BRepOwner.h create mode 100644 src/ModuleBase/ModuleBase_ListView.cpp create mode 100644 src/ModuleBase/ModuleBase_ListView.h create mode 100644 src/XGUI/XGUI_ActiveControlMgr.cpp create mode 100644 src/XGUI/XGUI_ActiveControlMgr.h create mode 100644 src/XGUI/XGUI_ActiveControlSelector.h create mode 100644 src/XGUI/XGUI_FacesPanel.cpp create mode 100644 src/XGUI/XGUI_FacesPanel.h create mode 100644 src/XGUI/XGUI_FacesPanelSelector.cpp create mode 100644 src/XGUI/XGUI_FacesPanelSelector.h create mode 100644 src/XGUI/XGUI_PropertyPanelSelector.cpp create mode 100644 src/XGUI/XGUI_PropertyPanelSelector.h diff --git a/src/ModuleBase/CMakeLists.txt b/src/ModuleBase/CMakeLists.txt index cb40f7222..b1b612da8 100644 --- a/src/ModuleBase/CMakeLists.txt +++ b/src/ModuleBase/CMakeLists.txt @@ -33,6 +33,7 @@ SET(PROJECT_HEADERS ModuleBase.h ModuleBase_ActionInfo.h ModuleBase_ActionType.h + ModuleBase_BRepOwner.h ModuleBase_Definitions.h ModuleBase_DoubleSpinBox.h ModuleBase_Events.h @@ -49,6 +50,7 @@ SET(PROJECT_HEADERS ModuleBase_IWidgetCreator.h ModuleBase_IWorkshop.h ModuleBase_LabelValue.h + ModuleBase_ListView.h ModuleBase_ModelWidget.h ModuleBase_Operation.h ModuleBase_OperationAction.h @@ -106,6 +108,7 @@ SET(PROJECT_MOC_HEADERS ModuleBase_IViewer.h ModuleBase_IWorkshop.h ModuleBase_LabelValue.h + ModuleBase_ListView.h ModuleBase_ModelDialogWidget.h ModuleBase_ModelWidget.h ModuleBase_Operation.h @@ -142,6 +145,7 @@ SET(PROJECT_MOC_HEADERS SET(PROJECT_SOURCES ModuleBase_ActionInfo.cpp + ModuleBase_BRepOwner.cpp ModuleBase_DoubleSpinBox.cpp ModuleBase_Filter.cpp ModuleBase_FilterValidated.cpp @@ -156,6 +160,7 @@ SET(PROJECT_SOURCES ModuleBase_IWidgetCreator.cpp ModuleBase_IWorkshop.cpp ModuleBase_LabelValue.cpp + ModuleBase_ListView.cpp ModuleBase_ModelWidget.cpp ModuleBase_Operation.cpp ModuleBase_OperationAction.cpp diff --git a/src/ModuleBase/ModuleBase_ActionType.h b/src/ModuleBase/ModuleBase_ActionType.h index 864c5e64a..7228e98ea 100644 --- a/src/ModuleBase/ModuleBase_ActionType.h +++ b/src/ModuleBase/ModuleBase_ActionType.h @@ -31,6 +31,7 @@ enum MODULEBASE_EXPORT ModuleBase_ActionType ActionEnter, ActionEscape, ActionDelete, + ActionSelection, ActionUndo, ActionRedo }; diff --git a/src/ModuleBase/ModuleBase_BRepOwner.cpp b/src/ModuleBase/ModuleBase_BRepOwner.cpp new file mode 100644 index 000000000..1c13dcfa6 --- /dev/null +++ b/src/ModuleBase/ModuleBase_BRepOwner.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include "ModuleBase_BRepOwner.h" + +IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner); diff --git a/src/ModuleBase/ModuleBase_BRepOwner.h b/src/ModuleBase/ModuleBase_BRepOwner.h new file mode 100644 index 000000000..b0dade4b1 --- /dev/null +++ b/src/ModuleBase/ModuleBase_BRepOwner.h @@ -0,0 +1,63 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef ModuleBase_BRepOwner_H +#define ModuleBase_BRepOwner_H + +#include "ModuleBase.h" + +#include +#include + +#include + +DEFINE_STANDARD_HANDLE(ModuleBase_BRepOwner, StdSelect_BRepOwner) + +/** +* \ingroup GUI +* A redefinition of standard BRep Owner in order to provide specific selection +* of CompSolid objects. This owner is created only for selection mode TopAbs_COMPSOLID +*/ +class ModuleBase_BRepOwner: public StdSelect_BRepOwner +{ +public: + /// Constructor + /// \param aShape an owner shape + /// \param aPriority drawig priority + /// \param ComesFromDecomposition decomposition flag + ModuleBase_BRepOwner(const TopoDS_Shape& aShape, + const Standard_Integer aPriority = 0, + const Standard_Boolean ComesFromDecomposition = Standard_False) + : StdSelect_BRepOwner(aShape, aPriority, ComesFromDecomposition) {} + + /// Highlight the presentation with the given color + /// \param aPM a presentations manager + /// \param theStyle a style of presentation + /// \param theMode a drawing mode + virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& aPM, + const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer theMode = 0) + { + Selectable()->HilightOwnerWithColor(aPM, theStyle, this); + } + + DEFINE_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner) +}; + +#endif \ No newline at end of file diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index 927cfdc26..4290fc3cd 100755 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -83,6 +83,9 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject /// Remove default selection filters of the module from the current viewer virtual void deactivateSelectionFilters() {} + /// Update selection filters depending on the module active controls + virtual void updateActiveSelectionFilters() {} + /// Stores the current selection virtual void storeSelection() {} diff --git a/src/ModuleBase/ModuleBase_ListView.cpp b/src/ModuleBase/ModuleBase_ListView.cpp new file mode 100644 index 000000000..4bf680a72 --- /dev/null +++ b/src/ModuleBase/ModuleBase_ListView.cpp @@ -0,0 +1,177 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include "ModuleBase_ListView.h" +#include "ModuleBase_Tools.h" + +#include +#include +#include +#include +#include + +const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1; + +/** +* Customization of a List Widget to make it to be placed on full width of container +*/ +class CustomListWidget : public QListWidget +{ +public: + /// Constructor + /// \param theParent a parent widget + CustomListWidget(QWidget* theParent) + : QListWidget(theParent) + { + } + + /// Redefinition of virtual method + virtual QSize sizeHint() const + { + int aHeight = 2*QFontMetrics(font()).height(); + QSize aSize = QListWidget::sizeHint(); + return QSize(aSize.width(), aHeight); + } + + /// Redefinition of virtual method + virtual QSize minimumSizeHint() const + { + int aHeight = 4/*2*/*QFontMetrics(font()).height(); + QSize aSize = QListWidget::minimumSizeHint(); + return QSize(aSize.width(), aHeight); + } + +#ifndef WIN32 +// The code is necessary only for Linux because +//it can not update viewport on widget resize +protected: + void resizeEvent(QResizeEvent* theEvent) + { + QListWidget::resizeEvent(theEvent); + QTimer::singleShot(5, viewport(), SLOT(repaint())); + } +#endif +}; + +//******************************************************************** +ModuleBase_ListView::ModuleBase_ListView(QWidget* theParent, const QString& theObjectName, + const QString& theToolTip) +{ + myListControl = new CustomListWidget(theParent); + + myListControl->setObjectName(theObjectName); + myListControl->setToolTip(theToolTip); + myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection); + + myCopyAction = ModuleBase_Tools::createAction(QIcon(":pictures/copy.png"), tr("Copy"), + theParent, this, SLOT(onCopyItem())); + myCopyAction->setShortcut(QKeySequence::Copy); + myCopyAction->setEnabled(false); + myListControl->addAction(myCopyAction); + + myDeleteAction = ModuleBase_Tools::createAction(QIcon(":pictures/delete.png"), tr("Delete"), + theParent, this, SIGNAL(deleteActionClicked())); + myDeleteAction->setEnabled(false); + myListControl->addAction(myDeleteAction); + + myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); + connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); +} + +//******************************************************************** +void ModuleBase_ListView::addItem(const QString& theTextValue, const int theIndex) +{ + QListWidgetItem* anItem = new QListWidgetItem(theTextValue, myListControl); + anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, theIndex); + myListControl->addItem(anItem); +} + +//******************************************************************** +void ModuleBase_ListView::getSelectedIndices(std::set& theIndices) +{ + QList aItems = myListControl->selectedItems(); + foreach(QListWidgetItem* anItem, aItems) { + int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt(); + if (theIndices.find(anIndex) == theIndices.end()) + theIndices.insert(anIndex); + } +} + +//******************************************************************** +void ModuleBase_ListView::removeSelectedItems() +{ + QList aItems = myListControl->selectedItems(); + foreach(QListWidgetItem* anItem, aItems) + myListControl->takeItem(myListControl->row(anItem)); +} + +//******************************************************************** +void ModuleBase_ListView::removeItems(std::set& theIndices) +{ + QList aItems; + for (int i = 0; i < myListControl->count(); i++) { + QListWidgetItem* anItem = myListControl->item(i); + int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt(); + if (theIndices.find(anIndex) != theIndices.end()) + aItems.append(anItem); + } + foreach(QListWidgetItem* anItem, aItems) + myListControl->takeItem(myListControl->row(anItem)); +} + +//******************************************************************** +void ModuleBase_ListView::restoreSelection(const QModelIndexList& theIndices) +{ + int aRows = myListControl->model()->rowCount(); + if (aRows > 0) { + foreach(QModelIndex aIndex, theIndices) { + if (aIndex.row() < aRows) + myListControl->selectionModel()->select(aIndex, QItemSelectionModel::Select); + else { + QModelIndex aIdx = myListControl->model()->index(aRows - 1, 0); + myListControl->selectionModel()->select(aIdx, QItemSelectionModel::Select); + } + } + } +} + +//******************************************************************** +void ModuleBase_ListView::onCopyItem() +{ + QList aItems = myListControl->selectedItems(); + QString aRes; + foreach(QListWidgetItem* aItem, aItems) { + if (!aRes.isEmpty()) + aRes += "\n"; + aRes += aItem->text(); + } + if (!aRes.isEmpty()) { + QClipboard* aClipboard = QApplication::clipboard(); + aClipboard->setText(aRes); + } +} + +//******************************************************************** +void ModuleBase_ListView::onListSelection() +{ + QList aItems = myListControl->selectedItems(); + myCopyAction->setEnabled(!aItems.isEmpty()); + myDeleteAction->setEnabled(!aItems.isEmpty()); +} \ No newline at end of file diff --git a/src/ModuleBase/ModuleBase_ListView.h b/src/ModuleBase/ModuleBase_ListView.h new file mode 100644 index 000000000..27c22622d --- /dev/null +++ b/src/ModuleBase/ModuleBase_ListView.h @@ -0,0 +1,95 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef ModuleBase_ListView_H_ +#define ModuleBase_ListView_H_ + +#include "ModuleBase.h" + +#include +#include + +#include + +class QAction; +class QListWidget; +class QWidget; + +/** +* \ingroup GUI +* An extension of QListWidget to provide Undo/Redo functionality +*/ +class MODULEBASE_EXPORT ModuleBase_ListView : public QObject +{ +Q_OBJECT + +public: + /// Constructor + ModuleBase_ListView(QWidget* theParent = 0, const QString& theObjectName = QString(), + const QString& theToolTip = QString()); + /// Destructor + virtual ~ModuleBase_ListView() {} + + /// Returns current control + /// \return list view instance + QListWidget* getControl() const { return myListControl; } + + /// Adds a new list widget item to the end of the list and connect it to the given index + /// \param theTextValue value visualized in the view + /// \param theIndex an item internal index + void addItem(const QString& theTextValue, const int theIndex); + + /// Returns list of internal list view item indices + /// \param theIndices an output container for indices + void getSelectedIndices(std::set& theIndices); + + /// Removes selected items from the list widget + void removeSelectedItems(); + + /// Remove items contain parameter indices + /// \param theIndices an indices + void removeItems(std::set& theIndices); + + /// Set selected items if possible + /// \param theIndices container of indices to be selected + void restoreSelection(const QModelIndexList& theIndices); + + /// Update enable/disable state of context menu actions + void updateActionsStatus(); + +protected slots: + /// Slot for copy command in a list pop-up menu + void onCopyItem(); + + /// Slot is called on selection of list of selected items + void onListSelection(); + +signals: + /// Signal about delete action click + void deleteActionClicked(); + +protected: + QListWidget* myListControl; ///< List control + + QAction* myCopyAction; ///< A copy action for pop-up menu in a list control + QAction* myDeleteAction; ///< A delete action for pop-up menu in a list control +}; + +#endif diff --git a/src/ModuleBase/ModuleBase_ModelWidget.h b/src/ModuleBase/ModuleBase_ModelWidget.h index 4882e2903..c63e684cb 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.h +++ b/src/ModuleBase/ModuleBase_ModelWidget.h @@ -184,6 +184,9 @@ Q_OBJECT /// The method called when widget is deactivated virtual void deactivate(); + /// The method called if widget should be activated always + virtual bool needToBeActiated() { return false; } + /// Returns list of widget controls /// \return a control list virtual QList getControls() const = 0; diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp index 907fd6a60..41724e977 100755 --- a/src/ModuleBase/ModuleBase_ResultPrs.cpp +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -19,13 +19,16 @@ // #include "ModuleBase_ResultPrs.h" -#include "ModuleBase_Tools.h" + +#include #include #include #include #include -#include + +#include "ModuleBase_Tools.h" +#include "ModuleBase_BRepOwner.h" #include #include @@ -48,8 +51,6 @@ #include #include -IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner); - //******************************************************************************************* IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape); @@ -80,6 +81,56 @@ void ModuleBase_ResultPrs::setAdditionalSelectionPriority(const int thePriority) myAdditionalSelectionPriority = thePriority; } +bool ModuleBase_ResultPrs::setSubShapeHidden(const NCollection_List& theShapes) +{ + bool isModified = false; + + // restore hidden shapes if there are not the shapes in parameter container + NCollection_List aVisibleSubShapes; + for (NCollection_List::Iterator aHiddenIt(myHiddenSubShapes); aHiddenIt.More(); + aHiddenIt.Next()) { + if (!theShapes.Contains(aHiddenIt.Value())) + aVisibleSubShapes.Append(aHiddenIt.Value()); + } + isModified = !aVisibleSubShapes.IsEmpty(); + for (NCollection_List::Iterator aVisibleIt(aVisibleSubShapes); aVisibleIt.More(); + aVisibleIt.Next()) + myHiddenSubShapes.Remove(aVisibleIt.Value()); + + // append hidden shapes into internal container if there are not these shapes + for (NCollection_List::Iterator aShapeIt(theShapes); aShapeIt.More(); + aShapeIt.Next()) + { + if (aShapeIt.Value().ShapeType() != TopAbs_FACE) // only face shape can be hidden + continue; + + if (!myHiddenSubShapes.Contains(aShapeIt.Value())) { + myHiddenSubShapes.Append(aShapeIt.Value()); + isModified = true; + } + } + return isModified; +} + +bool ModuleBase_ResultPrs::hasSubShapeVisible(const TopoDS_Shape& theShape) +{ + int aNbOfHiddenSubShapes = myHiddenSubShapes.Size(); + + if (!myHiddenSubShapes.Contains(theShape)) + aNbOfHiddenSubShapes++; // the shape to be hidden later + + TopExp_Explorer anExp(myOriginalShape, TopAbs_FACE); + bool aHasVisibleShape = false; + for(TopExp_Explorer anExp(myOriginalShape, TopAbs_FACE); anExp.More() && !aHasVisibleShape; + anExp.Next()) + { + aNbOfHiddenSubShapes--; + if (aNbOfHiddenSubShapes < 0) + aHasVisibleShape = true; + } + return aHasVisibleShape; +} + void ModuleBase_ResultPrs::Compute( const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, const Handle(Prs3d_Presentation)& thePresentation, @@ -89,8 +140,25 @@ void ModuleBase_ResultPrs::Compute( bool aReadyToDisplay = aShapePtr.get(); if (aReadyToDisplay) { myOriginalShape = aShapePtr->impl(); - if (!myOriginalShape.IsNull()) - Set(myOriginalShape); + if (myHiddenSubShapes.IsEmpty() || myOriginalShape.ShapeType() > TopAbs_FACE ) { + if (!myOriginalShape.IsNull()) + Set(myOriginalShape); + } + else { // convert shape into SHELL + TopoDS_Shell aShell; + BRep_Builder aShellBuilder; + aShellBuilder.MakeShell(aShell); + bool isEmptyShape = true; + for(TopExp_Explorer anExp(myOriginalShape, TopAbs_FACE); anExp.More(); anExp.Next()) { + if (myHiddenSubShapes.Contains(anExp.Current())) + continue; + aShellBuilder.Add(aShell, anExp.Current()); + isEmptyShape = false; + } + Set(aShell); + if (isEmptyShape) + aReadyToDisplay = false; + } } // change deviation coefficient to provide more precise circle //ModuleBase_Tools::setDefaultDeviationCoefficient(myResult, Attributes()); diff --git a/src/ModuleBase/ModuleBase_ResultPrs.h b/src/ModuleBase/ModuleBase_ResultPrs.h index d9a0da37c..e95018a79 100644 --- a/src/ModuleBase/ModuleBase_ResultPrs.h +++ b/src/ModuleBase/ModuleBase_ResultPrs.h @@ -25,46 +25,12 @@ #include +#include #include #include -#include #include -DEFINE_STANDARD_HANDLE(ModuleBase_BRepOwner, StdSelect_BRepOwner) - -/** -* \ingroup GUI -* A redefinition of standard BRep Owner in order to provide specific selection -* of CompSolid objects. This owner is created only for selection mode TopAbs_COMPSOLID -*/ -class ModuleBase_BRepOwner: public StdSelect_BRepOwner -{ -public: - /// Constructor - /// \param aShape an owner shape - /// \param aPriority drawig priority - /// \param ComesFromDecomposition decomposition flag - ModuleBase_BRepOwner(const TopoDS_Shape& aShape, - const Standard_Integer aPriority = 0, - const Standard_Boolean ComesFromDecomposition = Standard_False) - : StdSelect_BRepOwner(aShape, aPriority, ComesFromDecomposition) {} - - /// Highlight the presentation with the given color - /// \param aPM a presentations manager - /// \param theStyle a style of presentation - /// \param theMode a drawing mode - virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& aPM, - const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer theMode = 0) - { - Selectable()->HilightOwnerWithColor(aPM, theStyle, this); - } - - DEFINE_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner) -}; - - - DEFINE_STANDARD_HANDLE(ModuleBase_ResultPrs, ViewerData_AISShape) /** @@ -110,7 +76,22 @@ public: /// \param thePriority a new priority value Standard_EXPORT void setAdditionalSelectionPriority(const int thePriority); + /// Change presentation to have given shape hidden. + /// It suports FACE type of the shape to be hidden. + /// If presentation type is greater than FACE, the SHELL with be shown with the FACE hidden + /// It is possible to hide more than one FACE by calling the method with given FACES + /// Visual state of the face is controlled by the second parameter + /// \param theShapes a container of shape objects + /// \returns true if the presentation is changed, or false (if for example it was hidden) + Standard_EXPORT bool setSubShapeHidden(const NCollection_List& theShapes); + + /// Returns true if there are no hidden sub shapes or original shape has at least one not hidden + /// \param theShapeToSkip the shape should be interpreted as additional hidden in the presentation + /// \return boolean value + Standard_EXPORT bool hasSubShapeVisible(const TopoDS_Shape& theShapeToSkip); + DEFINE_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape) + protected: /// Redefinition of virtual function Standard_EXPORT virtual void Compute( @@ -137,6 +118,9 @@ private: /// Original shape of the result object TopoDS_Shape myOriginalShape; + /// Container of original Shape sub shape to be hidden and not selectable + NCollection_List myHiddenSubShapes; + /// selection priority that will be added to the standard /// selection priority of the selection entity int myAdditionalSelectionPriority; diff --git a/src/ModuleBase/ModuleBase_Tools.cpp b/src/ModuleBase/ModuleBase_Tools.cpp index 32d61570b..bd3c855cc 100755 --- a/src/ModuleBase/ModuleBase_Tools.cpp +++ b/src/ModuleBase/ModuleBase_Tools.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -50,6 +51,7 @@ #include +#include #include #include @@ -516,6 +518,18 @@ TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape) return aShapeType; } +TopoDS_Shape getSelectedShape(const std::shared_ptr& thePrs) +{ + if (thePrs->shape().get()) + return thePrs->shape()->impl(); + + Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner()); + if (!anOwner.IsNull()) + return anOwner->Shape(); + + return TopoDS_Shape(); +} + void getParameters(QStringList& theParameters) { theParameters.clear(); diff --git a/src/ModuleBase/ModuleBase_Tools.h b/src/ModuleBase/ModuleBase_Tools.h index 8a179c25a..0cd2ed2dc 100755 --- a/src/ModuleBase/ModuleBase_Tools.h +++ b/src/ModuleBase/ModuleBase_Tools.h @@ -45,9 +45,10 @@ class QWidget; class QLayout; class QDoubleSpinBox; class QAction; +class ModuleBase_IWorkshop; class ModuleBase_ParamIntSpinBox; class ModuleBase_ParamSpinBox; -class ModuleBase_IWorkshop; +class ModuleBase_ViewerPrs; class GeomAPI_Shape; @@ -212,6 +213,12 @@ MODULEBASE_EXPORT ObjectPtr getObject(const AttributePtr& theAttribute); /// \param theObj an object MODULEBASE_EXPORT TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape); +/// Returns either presentation shape or shape of BREP owner if it is casted to it +/// \param thePrs selection presentation +/// \return shape +MODULEBASE_EXPORT TopoDS_Shape getSelectedShape( + const std::shared_ptr& thePrs); + /// Returns list of parameters accessible in the active part and partset /// \theParameters a list of parameter names MODULEBASE_EXPORT void getParameters(QStringList& theParameters); diff --git a/src/ModuleBase/ModuleBase_ViewerPrs.cpp b/src/ModuleBase/ModuleBase_ViewerPrs.cpp index 3eaa15c2c..3d4d446e6 100644 --- a/src/ModuleBase/ModuleBase_ViewerPrs.cpp +++ b/src/ModuleBase/ModuleBase_ViewerPrs.cpp @@ -21,6 +21,7 @@ #include "ModuleBase_ViewerPrs.h" #include +#include ModuleBase_ViewerPrs::ModuleBase_ViewerPrs(ObjectPtr theResult, const GeomShapePtr& theShape, diff --git a/src/ModuleBase/ModuleBase_WidgetFeatureSelector.cpp b/src/ModuleBase/ModuleBase_WidgetFeatureSelector.cpp index 285fbe765..a378b0a04 100644 --- a/src/ModuleBase/ModuleBase_WidgetFeatureSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFeatureSelector.cpp @@ -113,17 +113,24 @@ bool ModuleBase_WidgetFeatureSelector::setSelectionCustom(const ModuleBase_Viewe void ModuleBase_WidgetFeatureSelector::deactivate() { ModuleBase_ModelWidget::deactivate(); - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); activateFilters(false); myWorkshop->deactivateSubShapesSelection(); } //******************************************************************** -void ModuleBase_WidgetFeatureSelector::activateCustom() +bool ModuleBase_WidgetFeatureSelector::processAction(ModuleBase_ActionType theActionType) { - connect(myWorkshop, SIGNAL(selectionChanged()), this, - SLOT(onSelectionChanged()), Qt::UniqueConnection); + if (theActionType == ActionSelection) + onSelectionChanged(); + else + return ModuleBase_WidgetValidated::processAction(theActionType); + + return true; +} +//******************************************************************** +void ModuleBase_WidgetFeatureSelector::activateCustom() +{ activateFilters(true); QIntList aShapeTypes; diff --git a/src/ModuleBase/ModuleBase_WidgetFeatureSelector.h b/src/ModuleBase/ModuleBase_WidgetFeatureSelector.h index 606fc1dad..dc47862a9 100644 --- a/src/ModuleBase/ModuleBase_WidgetFeatureSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetFeatureSelector.h @@ -79,6 +79,9 @@ Q_OBJECT /// The method called when widget is deactivated virtual void deactivate(); + /// Processes Selection action. + virtual bool processAction(ModuleBase_ActionType theActionType); + protected: /// The method called when widget is activated virtual void activateCustom(); @@ -104,7 +107,7 @@ protected: /// \param theDone a state whether the selection is set virtual void updateOnSelectionChanged(const bool theDone); -protected slots: +protected: /// Called on selection changed event virtual void onSelectionChanged(); diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index 973b9b6ec..15be27427 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -19,16 +19,18 @@ // #include -#include + +#include +#include +#include +#include #include -#include #include +#include +#include #include -#include -#include #include -#include -#include +#include #include #include @@ -47,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -56,51 +57,8 @@ #include #include -const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1; - //#define DEBUG_UNDO_REDO -/** -* Customization of a List Widget to make it to be placed on full width of container -*/ -class CustomListWidget : public QListWidget -{ -public: - /// Constructor - /// \param theParent a parent widget - CustomListWidget( QWidget* theParent ) - : QListWidget( theParent ) - { - } - - /// Redefinition of virtual method - virtual QSize sizeHint() const - { - int aHeight = 2*QFontMetrics( font() ).height(); - QSize aSize = QListWidget::sizeHint(); - return QSize( aSize.width(), aHeight ); - } - - /// Redefinition of virtual method - virtual QSize minimumSizeHint() const - { - int aHeight = 4/*2*/*QFontMetrics( font() ).height(); - QSize aSize = QListWidget::minimumSizeHint(); - return QSize( aSize.width(), aHeight ); - } - -#ifndef WIN32 -// The code is necessary only for Linux because -//it can not update viewport on widget resize -protected: - void resizeEvent(QResizeEvent* theEvent) - { - QListWidget::resizeEvent(theEvent); - QTimer::singleShot(5, viewport(), SLOT(repaint())); - } -#endif -}; - #ifdef DEBUG_UNDO_REDO void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex, QList > > theSelectedHistoryValues) @@ -163,33 +121,18 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen } QString aToolTip = QString::fromStdString(theData->widgetTooltip()); - myListControl = new CustomListWidget(this); QString anObjName = QString::fromStdString(attributeID()); - myListControl->setObjectName(anObjName); - myListControl->setToolTip(aToolTip); - myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection); + myListView = new ModuleBase_ListView(this, anObjName, aToolTip); + connect(myListView->getControl(), SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); + connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem())); - aMainLay->addWidget(myListControl, 2, 0, 1, -1); + aMainLay->addWidget(myListView->getControl(), 2, 0, 1, -1); aMainLay->setRowStretch(2, 1); //aMainLay->addWidget(new QLabel(this)); //FIXME(sbh)??? //aMainLay->setRowMinimumHeight(3, 20); //this->setLayout(aMainLay); connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged())); - myCopyAction = ModuleBase_Tools::createAction(QIcon(":pictures/copy.png"), tr("Copy"), - myWorkshop->desktop(), this, SLOT(onCopyItem())); - myCopyAction->setShortcut(QKeySequence::Copy); - myCopyAction->setEnabled(false); - myListControl->addAction(myCopyAction); - - myDeleteAction = ModuleBase_Tools::createAction(QIcon(":pictures/delete.png"), tr("Delete"), - myWorkshop->desktop(), this, SLOT(onDeleteItem())); - myDeleteAction->setEnabled(false); - myListControl->addAction(myDeleteAction); - - myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); - connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); - myIsNeutralPointClear = theData->getBooleanAttribute("clear_in_neutral_point", true); } @@ -425,7 +368,7 @@ bool ModuleBase_WidgetMultiSelector::processDelete() std::set anAttributeIds; getSelectedAttributeIndices(anAttributeIds); - QModelIndexList aIndexes = myListControl->selectionModel()->selectedIndexes(); + QModelIndexList anIndices = myListView->getControl()->selectionModel()->selectedIndexes(); // refill attribute by the items which indices are not in the list of ids bool aDone = false; @@ -462,17 +405,8 @@ bool ModuleBase_WidgetMultiSelector::processDelete() } // Restore selection - int aRows = myListControl->model()->rowCount(); - if (aRows > 0) { - foreach(QModelIndex aIndex, aIndexes) { - if (aIndex.row() < aRows) - myListControl->selectionModel()->select(aIndex, QItemSelectionModel::Select); - else { - QModelIndex aIdx = myListControl->model()->index(aRows - 1, 0); - myListControl->selectionModel()->select(aIdx, QItemSelectionModel::Select); - } - } - } + myListView->restoreSelection(anIndices); + appendSelectionInHistory(); return aDone; } @@ -482,7 +416,7 @@ QList ModuleBase_WidgetMultiSelector::getControls() const { QList result; //result << myTypeCombo; - result << myListControl; + result << myListView->getControl(); return result; } @@ -593,7 +527,7 @@ void ModuleBase_WidgetMultiSelector::updateFocus() { // Set focus to List control in order to make possible // to use Tab key for transfer the focus to next widgets - ModuleBase_Tools::setFocus(myListControl, + ModuleBase_Tools::setFocus(myListView->getControl(), "ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()"); } @@ -670,7 +604,7 @@ QList ModuleBase_WidgetMultiSelector::getAttributeSelec //******************************************************************** void ModuleBase_WidgetMultiSelector::updateSelectionList() { - myListControl->clear(); + myListView->getControl()->clear(); DataPtr aData = myFeature->data(); AttributePtr anAttribute = aData->attribute(attributeID()); @@ -679,9 +613,7 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID()); for (int i = 0; i < aSelectionListAttr->size(); i++) { AttributeSelectionPtr aAttr = aSelectionListAttr->value(i); - QListWidgetItem* anItem = new QListWidgetItem(aAttr->namingName().c_str(), myListControl); - anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); - myListControl->addItem(anItem); + myListView->addItem(aAttr->namingName().c_str(), i); } } else if (aType == ModelAPI_AttributeRefList::typeId()) { @@ -689,10 +621,7 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() for (int i = 0; i < aRefListAttr->size(); i++) { ObjectPtr anObject = aRefListAttr->object(i); if (anObject.get()) { - QListWidgetItem* anItem = new QListWidgetItem(anObject->data()->name().c_str(), - myListControl); - anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); - myListControl->addItem(anItem); + myListView->addItem(anObject->data()->name().c_str(), i); } } } @@ -711,14 +640,12 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() aName = anObject->data()->name().c_str(); } } - QListWidgetItem* anItem = new QListWidgetItem(aName, myListControl); - anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); - myListControl->addItem(anItem); + myListView->addItem(aName, i); } } // We have to call repaint because sometimes the List control is not updated - myListControl->repaint(); + myListView->getControl()->repaint(); } //******************************************************************** @@ -746,29 +673,13 @@ void ModuleBase_WidgetMultiSelector::clearSelection() QList anEmptyList; // This method will call Selection changed event which will call onSelectionChanged - // To clear mySelection, myListControl and storeValue() + // To clear mySelection, myListView and storeValue() // So, we don't need to call it myWorkshop->setSelected(anEmptyList); myIsNeutralPointClear = isClearInNeutralPoint; } -//******************************************************************** -void ModuleBase_WidgetMultiSelector::onCopyItem() -{ - QList aItems = myListControl->selectedItems(); - QString aRes; - foreach(QListWidgetItem* aItem, aItems) { - if (!aRes.isEmpty()) - aRes += "\n"; - aRes += aItem->text(); - } - if (!aRes.isEmpty()) { - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(aRes); - } -} - //******************************************************************** void ModuleBase_WidgetMultiSelector::onDeleteItem() { @@ -778,10 +689,6 @@ void ModuleBase_WidgetMultiSelector::onDeleteItem() //******************************************************************** void ModuleBase_WidgetMultiSelector::onListSelection() { - QList aItems = myListControl->selectedItems(); - myCopyAction->setEnabled(!aItems.isEmpty()); - myDeleteAction->setEnabled(!aItems.isEmpty()); - myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects, true); } @@ -789,12 +696,7 @@ void ModuleBase_WidgetMultiSelector::onListSelection() //******************************************************************** void ModuleBase_WidgetMultiSelector::getSelectedAttributeIndices(std::set& theAttributeIds) { - QList aItems = myListControl->selectedItems(); - foreach(QListWidgetItem* anItem, aItems) { - int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt(); - if (theAttributeIds.find(anIndex) == theAttributeIds.end()) - theAttributeIds.insert(anIndex); - } + myListView->getSelectedIndices(theAttributeIds); } void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::set theAttributeIds, diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h index 74b0ff510..6b35b9380 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h @@ -37,11 +37,9 @@ #include class QWidget; -class QListWidget; class QComboBox; +class ModuleBase_ListView; class ModuleBase_IWorkshop; -class QAction; - /** * \ingroup GUI @@ -114,9 +112,6 @@ public slots: virtual void onSelectionChanged(); protected slots: - /// Slot for copy command in a list pop-up menu - void onCopyItem(); - /// Slot for delete command in a list pop-up menu void onDeleteItem(); @@ -215,23 +210,9 @@ protected: ModuleBase_IWorkshop* theWorkshop); protected: - /// List control - QListWidget* myListControl; - - /// Combobox of types - QComboBox* myTypeCombo; - - /// Provides correspondance between Result object and its shape - typedef QPair GeomSelection; - - /// A copy action for pop-up menu in a list control - QAction* myCopyAction; - - /// A delete action for pop-up menu in a list control - QAction* myDeleteAction; - - /// A flag to store use_choice parameter state - bool myIsUseChoice; + ModuleBase_ListView* myListView; ///< List control + QComboBox* myTypeCombo; ///< Combobox of types + bool myIsUseChoice; /// A flag to store use_choice parameter state /// A flag to clear selection by click in empty place in the viewer bool myIsNeutralPointClear; diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index f6131c3fe..8b2d83405 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -75,20 +75,22 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include #include -#include -#include -#include +#include #include +#include #include -#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include #include @@ -223,6 +225,17 @@ void PartSet_Module::deactivateSelectionFilters() } } +void PartSet_Module::updateActiveSelectionFilters() +{ + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(workshop()); + XGUI_ActiveControlSelector* anActiveSelector = aWorkshop->activeControlMgr()->activeSelector(); + + if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type()) + sketchMgr()->deactivateSelectionFilters(); + else + sketchMgr()->activateSelectionFilters(); +} + void PartSet_Module::storeSelection() { // cash is used only to restore selection, so it should be filled in storeSelection and diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index 4a70c942f..a54c16660 100755 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -88,6 +88,8 @@ public: virtual void activateSelectionFilters(); // Remove default selection filters of the module from the current viewer virtual void deactivateSelectionFilters(); + /// Update selection filters depending on the module active controls + virtual void updateActiveSelectionFilters(); // Stores the current selection virtual void storeSelection(); diff --git a/src/PartSet/PartSet_PreviewSketchPlane.cpp b/src/PartSet/PartSet_PreviewSketchPlane.cpp index f0f614bb0..243b23268 100644 --- a/src/PartSet/PartSet_PreviewSketchPlane.cpp +++ b/src/PartSet/PartSet_PreviewSketchPlane.cpp @@ -97,7 +97,7 @@ void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& th } XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer(); - aDisp->displayAIS(myPlane, true, 1/*shaded*/, false); + aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false); myPreviewIsDisplayed = true; } diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index abaadd311..86d0c5921 100755 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -183,12 +183,15 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule) myIsConstraintsShown[PartSet_Tools::Expressions] = false; mySketchPlane = new PartSet_PreviewSketchPlane(); + + myCirclePointFilter = new PartSet_CirclePointFilter(anIWorkshop); + myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); } PartSet_SketcherMgr::~PartSet_SketcherMgr() { - if (!myPlaneFilter.IsNull()) - myPlaneFilter.Nullify(); + myPlaneFilter.Nullify(); + myCirclePointFilter.Nullify(); } void PartSet_SketcherMgr::onEnterViewPort() @@ -1005,21 +1008,13 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) qDebug(QString("startSketch: %1, %2").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str()); #endif - if(myCirclePointFilter.IsNull()) { - myCirclePointFilter = new PartSet_CirclePointFilter(myModule->workshop()); - } - - myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter); - - if (myPlaneFilter.IsNull()) - myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); - - myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter); bool aHasPlane = false; std::shared_ptr aPln; aPln = PartSet_Tools::sketchPlane(myCurrentSketch); myPlaneFilter->setPlane(aPln); + activateSelectionFilters(); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); // all displayed objects should be activated in current selection modes according to switched // plane filter @@ -1049,9 +1044,6 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) // The sketch was aborted myCurrentSketch = CompositeFeaturePtr(); mySketchPlane->eraseSketchPlane(myModule->workshop()); - // TODO: move this outside of if-else - myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter); - myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); // Erase all sketcher objects QObjectPtrList aObjects = aDisplayer->displayedObjects(); @@ -1094,11 +1086,10 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) myCurrentSketch = CompositeFeaturePtr(); mySketchPlane->eraseSketchPlane(myModule->workshop()); - myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter); - myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); - Events_Loop::loop()->flush(aDispEvent); } + deactivateSelectionFilters(); + // restore the module selection modes, which were changed on startSketch aConnector->activateModuleSelectionModes(); } @@ -1160,6 +1151,18 @@ void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation) } } +void PartSet_SketcherMgr::activateSelectionFilters() +{ + myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter); + myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter); +} + +void PartSet_SketcherMgr::deactivateSelectionFilters() +{ + myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter); + myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); +} + void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate) { if (toActivate) @@ -1470,9 +1473,6 @@ bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr& thePln) { - if (myPlaneFilter.IsNull()) - myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); - myPlaneFilter->setPlane(thePln); } diff --git a/src/PartSet/PartSet_SketcherMgr.h b/src/PartSet/PartSet_SketcherMgr.h index 62e67fac2..119764273 100644 --- a/src/PartSet/PartSet_SketcherMgr.h +++ b/src/PartSet/PartSet_SketcherMgr.h @@ -194,6 +194,12 @@ public: /// \param theOperation a committed operation void commitNestedSketch(ModuleBase_Operation* theOperation); + /// Append the sketch selection filters in 3D viewer (plane and circle pointer) + void activateSelectionFilters(); + + // Remove sketch selection filter from the current viewer + virtual void deactivateSelectionFilters(); + /// Append the sketch plane filter into the current viewer /// \param toActivate state whether the filter should be activated/deactivated void activatePlaneFilter(const bool& toActivate); diff --git a/src/PartSet/PartSet_WidgetSketchLabel.cpp b/src/PartSet/PartSet_WidgetSketchLabel.cpp index 63cd3927e..bbf6e2b66 100644 --- a/src/PartSet/PartSet_WidgetSketchLabel.cpp +++ b/src/PartSet/PartSet_WidgetSketchLabel.cpp @@ -195,6 +195,10 @@ QList PartSet_WidgetSketchLabel::getControls() const void PartSet_WidgetSketchLabel::onSelectionChanged() { + std::shared_ptr aPlane = plane(); + if (aPlane.get()) + return; + QList aSelected = getFilteredSelected(); if (aSelected.empty()) @@ -356,8 +360,6 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs //myLabel->setText(""); //myLabel->setToolTip(""); XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop); - disconnect(aWorkshop->selector(), SIGNAL(selectionChanged()), - this, SLOT(onSelectionChanged())); // 4. deactivate face selection filter activateFilters(false); @@ -449,6 +451,17 @@ bool PartSet_WidgetSketchLabel::canFillSketch(const ModuleBase_ViewerPrsPtr& the return aCanFillSketch; } +//******************************************************************** +bool PartSet_WidgetSketchLabel::processAction(ModuleBase_ActionType theActionType) +{ + if (theActionType == ActionSelection) + onSelectionChanged(); + else + return ModuleBase_WidgetValidated::processAction(theActionType); + + return true; +} + bool PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(const ModuleBase_ViewerPrsPtr& thePrs) { bool isOwnerSet = false; @@ -513,9 +526,6 @@ void PartSet_WidgetSketchLabel::activateCustom() mySizeOfViewWidget->setVisible(false); activateSelection(true); - - connect(XGUI_Tools::workshop(myWorkshop)->selector(), SIGNAL(selectionChanged()), - this, SLOT(onSelectionChanged())); activateFilters(true); } diff --git a/src/PartSet/PartSet_WidgetSketchLabel.h b/src/PartSet/PartSet_WidgetSketchLabel.h index 5cc4a10cf..eb5327061 100644 --- a/src/PartSet/PartSet_WidgetSketchLabel.h +++ b/src/PartSet/PartSet_WidgetSketchLabel.h @@ -80,6 +80,9 @@ public: /// The methiod called when widget is deactivated virtual void deactivate(); + /// The method called if widget should be activated always + virtual bool needToBeActiated() { return true; } + /// Returns sketcher plane std::shared_ptr plane() const; @@ -92,6 +95,9 @@ public: /// \param thePrs a presentation static bool canFillSketch(const std::shared_ptr& thePrs); + /// Processes Selection action. + virtual bool processAction(ModuleBase_ActionType theActionType); + signals: /// Signal on plane selection void planeSelected(const std::shared_ptr& thePln); @@ -172,10 +178,11 @@ protected: /// Activate or deactivate selection void activateSelection(bool toActivate); - private slots: + private: /// Slot on change selection void onSelectionChanged(); +private slots: /// A slot called on set sketch plane view void onSetPlaneView(); diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index 7f0fe59ff..9380b2688 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -29,6 +29,8 @@ ADD_DEFINITIONS(${QT_DEFINITIONS}) SET(PROJECT_HEADERS XGUI.h XGUI_ActionsMgr.h + XGUI_ActiveControlMgr.h + XGUI_ActiveControlSelector.h XGUI_ColorDialog.h XGUI_ContextMenuMgr.h XGUI_CustomPrs.h @@ -37,6 +39,8 @@ SET(PROJECT_HEADERS XGUI_Displayer.h XGUI_ErrorDialog.h XGUI_ErrorMgr.h + XGUI_FacesPanel.h + XGUI_FacesPanelSelector.h XGUI_HistoryMenu.h XGUI_MenuGroup.h XGUI_MenuMgr.h @@ -46,6 +50,7 @@ SET(PROJECT_HEADERS XGUI_OperationMgr.h XGUI_PropertyDialog.h XGUI_PropertyPanel.h + XGUI_PropertyPanelSelector.h XGUI_QtEvents.h XGUI_SalomeConnector.h XGUI_Selection.h @@ -59,6 +64,8 @@ SET(PROJECT_HEADERS SET(PROJECT_MOC_HEADERS XGUI_ActionsMgr.h + XGUI_ActiveControlMgr.h + XGUI_ActiveControlSelector.h XGUI_ColorDialog.h XGUI_ContextMenuMgr.h XGUI_DataModel.h @@ -66,12 +73,15 @@ SET(PROJECT_MOC_HEADERS XGUI_Displayer.h XGUI_ErrorDialog.h XGUI_ErrorMgr.h + XGUI_FacesPanel.h + XGUI_FacesPanelSelector.h XGUI_HistoryMenu.h XGUI_ModuleConnector.h XGUI_ObjectsBrowser.h XGUI_OperationMgr.h XGUI_PropertyDialog.h XGUI_PropertyPanel.h + XGUI_PropertyPanelSelector.h XGUI_SelectionMgr.h XGUI_TransparencyWidget.h XGUI_ViewerProxy.h @@ -84,6 +94,7 @@ QT_WRAP_MOC(PROJECT_AUTOMOC ${PROJECT_MOC_HEADERS}) SET(PROJECT_SOURCES XGUI_ActionsMgr.cpp + XGUI_ActiveControlMgr.cpp XGUI_ColorDialog.cpp XGUI_ContextMenuMgr.cpp XGUI_CustomPrs.cpp @@ -92,6 +103,8 @@ SET(PROJECT_SOURCES XGUI_Displayer.cpp XGUI_ErrorDialog.cpp XGUI_ErrorMgr.cpp + XGUI_FacesPanel.cpp + XGUI_FacesPanelSelector.cpp XGUI_HistoryMenu.cpp XGUI_MenuGroup.cpp XGUI_MenuMgr.cpp @@ -101,6 +114,7 @@ SET(PROJECT_SOURCES XGUI_OperationMgr.cpp XGUI_PropertyDialog.cpp XGUI_PropertyPanel.cpp + XGUI_PropertyPanelSelector.cpp XGUI_QtEvents.cpp XGUI_SalomeConnector.cpp XGUI_Selection.cpp diff --git a/src/XGUI/XGUI_ActiveControlMgr.cpp b/src/XGUI/XGUI_ActiveControlMgr.cpp new file mode 100644 index 000000000..7c2fc833b --- /dev/null +++ b/src/XGUI/XGUI_ActiveControlMgr.cpp @@ -0,0 +1,109 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include +#include + +#include +#include + +//******************************************************************** +XGUI_ActiveControlMgr::XGUI_ActiveControlMgr(ModuleBase_IWorkshop* theWorkshop) +: myWorkshop(theWorkshop), myActiveSelector(0) +{ + connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); +} + +//******************************************************************** +void XGUI_ActiveControlMgr::addSelector(XGUI_ActiveControlSelector* theSelector) +{ + mySelectors.append(theSelector); + connect(theSelector, SIGNAL(activated()), this, SLOT(onSelectorActivated())); + connect(theSelector, SIGNAL(deactivated()), this, SLOT(onSelectorDeactivated())); +} + +//******************************************************************** +XGUI_ActiveControlSelector* XGUI_ActiveControlMgr::getSelector(const QString& theType) +{ + XGUI_ActiveControlSelector* aSelector; + for (int i = 0, aCount = mySelectors.count(); i < aCount; i++) + { + if (mySelectors[i]->getType() != theType) + continue; + aSelector = mySelectors[i]; + break; + } + return aSelector; +} + +//******************************************************************** +void XGUI_ActiveControlMgr::onSelectorActivated() +{ + XGUI_ActiveControlSelector* aSelector = qobject_cast(sender()); + if (!aSelector || aSelector == myActiveSelector) + return; + + if (myActiveSelector) + myActiveSelector->setActive(false); + + activateSelector(aSelector); +} + +//******************************************************************** +void XGUI_ActiveControlMgr::onSelectorDeactivated() +{ + XGUI_ActiveControlSelector* aSelector = qobject_cast(sender()); + if (!aSelector) + return; + + myActiveSelector = NULL; + + aSelector->setActive(false); + myWorkshop->module()->updateActiveSelectionFilters(); + + XGUI_ActiveControlSelector* aSelectorToBeActivated = 0; + for (int i = 0, aCount = mySelectors.count(); i < aCount; i++) + { + if (!mySelectors[i]->needToBeActiated()) + continue; + aSelectorToBeActivated = mySelectors[i]; + break; + } + if (aSelectorToBeActivated) + activateSelector(aSelectorToBeActivated); +} + +//******************************************************************** +void XGUI_ActiveControlMgr::onSelectionChanged() +{ + if (!myActiveSelector) + return; + + myActiveSelector->processSelection(); +} + +//******************************************************************** +void XGUI_ActiveControlMgr::activateSelector(XGUI_ActiveControlSelector* theSelector) +{ + myActiveSelector = theSelector; + theSelector->setActive(true); + + myWorkshop->module()->updateActiveSelectionFilters(); +} diff --git a/src/XGUI/XGUI_ActiveControlMgr.h b/src/XGUI/XGUI_ActiveControlMgr.h new file mode 100644 index 000000000..40355b697 --- /dev/null +++ b/src/XGUI/XGUI_ActiveControlMgr.h @@ -0,0 +1,78 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef XGUI_ActiveControlMgr_H +#define XGUI_ActiveControlMgr_H + +#include "XGUI.h" + +#include +#include + + +class XGUI_ActiveControlSelector; +class ModuleBase_IWorkshop; + +/** +* Interface of providing only one active control for workshop. +* It has container of selectors, where only one might be active at the moment. +* Selection in 3D view is processed by the active selector. +*/ +class XGUI_ActiveControlMgr : public QObject +{ + Q_OBJECT +public: + /// Constructor + /// \param theWorkshop the current workshop instance + XGUI_EXPORT XGUI_ActiveControlMgr(ModuleBase_IWorkshop* theWorkshop); + + XGUI_EXPORT virtual ~XGUI_ActiveControlMgr() {}; + + /// Register selector to process activation of control + void addSelector(XGUI_ActiveControlSelector* theSelector); + + /// Returns selector by type name + /// \param theType a selector type + /// \return selector instance + XGUI_EXPORT XGUI_ActiveControlSelector* getSelector(const QString& theType); + + /// Returns the active selector + /// \return selector instance + XGUI_ActiveControlSelector* activeSelector() const { return myActiveSelector; } + +protected slots: + /// Deactivates active selector and set the sender selector as active + void onSelectorActivated(); + /// Deactivate the active selector + void onSelectorDeactivated(); + /// Listens workshop selection and pass it to the active selector + void onSelectionChanged(); + +protected: + void activateSelector(XGUI_ActiveControlSelector* theSelector); + +protected: + ModuleBase_IWorkshop* myWorkshop; ///< the current workshop + + QList mySelectors; ///< workshop selectors + XGUI_ActiveControlSelector* myActiveSelector; ///< active selector +}; + +#endif diff --git a/src/XGUI/XGUI_ActiveControlSelector.h b/src/XGUI/XGUI_ActiveControlSelector.h new file mode 100644 index 000000000..c0a3e1511 --- /dev/null +++ b/src/XGUI/XGUI_ActiveControlSelector.h @@ -0,0 +1,78 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef XGUI_ActiveControlSelector_H +#define XGUI_ActiveControlSelector_H + +#include "XGUI.h" + +#include + +/** +* Interface to have an active control and process selection by the control. +* Activation of control may set selection modes and selection filters of the control. +*/ +class XGUI_ActiveControlSelector : public QObject +{ + Q_OBJECT + +public: + /// Constructor + /// \param theWorkshop the current workshop instance + XGUI_EXPORT XGUI_ActiveControlSelector() {}; + /// Destructor + XGUI_EXPORT virtual ~XGUI_ActiveControlSelector() {}; + + /// Returns name of the selector + XGUI_EXPORT virtual QString getType() = 0; + + /// Clear need to be activated widget if it exists + XGUI_EXPORT virtual void reset() {} + + /// Sets enable/disable state of the selector. If disable, it will not react to selection + /// \param theEnabled if true, selector is enabled + XGUI_EXPORT void setEnable(const bool& theEnabled) { myIsEnabled = theEnabled; } + + /// Returns whether the selector is enabled or not + /// \return boolean result + XGUI_EXPORT bool isEnabled() const { return myIsEnabled; } + + /// Sets control active. It should activates/deactivates selection and selection filters. + /// \param isActive if true, the control becomes active + XGUI_EXPORT virtual void setActive(const bool& isActive) = 0; + + /// Returns whether the selector should be activated as soon as possible (by deactivatate other) + /// \return boolean result + XGUI_EXPORT virtual bool needToBeActiated() const { return false; } + + /// Processes current selection of workshop. Reaction to selection change in workshop. + XGUI_EXPORT virtual void processSelection() = 0; + +signals: + /// control is activated + void activated(); + /// control is deactivated + void deactivated(); + +protected: + bool myIsEnabled; ///< enable state of the selector +}; + +#endif diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 961245200..4b7e02f5a 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -18,12 +18,13 @@ // email : webmaster.salome@opencascade.com // +#include "XGUI_CustomPrs.h" #include "XGUI_Displayer.h" -#include "XGUI_Workshop.h" -#include "XGUI_ViewerProxy.h" -#include "XGUI_SelectionMgr.h" +#include "XGUI_FacesPanel.h" #include "XGUI_Selection.h" -#include "XGUI_CustomPrs.h" +#include "XGUI_SelectionMgr.h" +#include "XGUI_ViewerProxy.h" +#include "XGUI_Workshop.h" #ifndef HAVE_SALOME #include @@ -36,11 +37,12 @@ #include #include +#include +#include +#include #include #include -#include #include -#include #include #include @@ -266,7 +268,7 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, if (!anAISIO.IsNull()) { appendResultObject(theObject, theAIS); - bool isCustomized = customizeObject(theObject); + bool isCustomized = customizeObject(theObject, true); int aDispMode = isShading? Shading : Wireframe; if (isShading) @@ -369,7 +371,7 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer) } } // Customization of presentation - bool isCustomized = customizeObject(theObject); + bool isCustomized = customizeObject(theObject, false); #ifdef DEBUG_FEATURE_REDISPLAY qDebug(QString("Redisplay: %1, isEqualShapes=%2, isCustomized=%3"). arg(!isEqualShapes || isCustomized).arg(isEqualShapes) @@ -1365,7 +1367,7 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, return isActivationChanged; } -bool XGUI_Displayer::customizeObject(ObjectPtr theObject) +bool XGUI_Displayer::customizeObject(ObjectPtr theObject, const bool isDisplayed) { AISObjectPtr anAISObj = getAISObject(theObject); // correct the result's color it it has the attribute @@ -1389,6 +1391,12 @@ bool XGUI_Displayer::customizeObject(ObjectPtr theObject) aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs); isCustomized = myWorkshop->module()->afterCustomisePresentation(aResult, anAISObj, myCustomPrs) || isCustomized; + + // update presentation state if faces panel is active + if (anAISObj.get() && myWorkshop->facesPanel()) + isCustomized = myWorkshop->facesPanel()->customizeObject(theObject, isDisplayed) || + isCustomized; + return isCustomized; } diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index 9b606dab3..4414598d0 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -337,8 +337,9 @@ private: /// If the object is result with the color attribute value set, it is used, /// otherwise the customize is applyed to the object's feature if it is a custom prs /// \param theObject an object instance + /// \param isDisplayed boolean state whether the object is displayed/redisplayed /// \return the true state if there is changes and the presentation is customized - bool customizeObject(ObjectPtr theObject); + bool customizeObject(ObjectPtr theObject, const bool isDisplayed); /// Append the objects in the internal map. Checks whether the map already contains the object /// \param theObject an object to display diff --git a/src/XGUI/XGUI_FacesPanel.cpp b/src/XGUI/XGUI_FacesPanel.cpp new file mode 100644 index 000000000..79f299077 --- /dev/null +++ b/src/XGUI/XGUI_FacesPanel.cpp @@ -0,0 +1,396 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include "XGUI_FacesPanel.h" + +#include +#include "GeomAlgoAPI_CompoundBuilder.h" + +#include + +#include +#include "ModuleBase_IWorkshop.h" +#include "ModuleBase_ListView.h" +#include "ModuleBase_ResultPrs.h" +#include "ModuleBase_Tools.h" +#include "ModuleBase_ViewerPrs.h" + +#include "XGUI_Displayer.h" +#include "XGUI_Tools.h" +#include "XGUI_Workshop.h" + +#include +#include +#include +#include +#include +#include + +static const int LayoutMargin = 3; + +//******************************************************************** +XGUI_FacesPanel::XGUI_FacesPanel(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop) + : QDockWidget(theParent), myIsActive(false), myWorkshop(theWorkshop) +{ + setWindowTitle(tr("Hide Faces")); + QAction* aViewAct = toggleViewAction(); + setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }"); + + QWidget* aContent = new QWidget(this); + QGridLayout* aMainLayout = new QGridLayout(aContent); + aMainLayout->setContentsMargins(LayoutMargin, LayoutMargin, LayoutMargin, LayoutMargin); + setWidget(aContent); + + myHiddenOrTransparent = new QCheckBox(tr("Transparent"), aContent); + myListView = new ModuleBase_ListView(aContent, "", "Hidden/transparent faces in 3D view"); + connect(myListView->getControl(), SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); + connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem())); + + aMainLayout->addWidget(myHiddenOrTransparent, 0, 0); + aMainLayout->addWidget(myListView->getControl(), 1, 0); + + myListView->getControl()->setFocusPolicy(Qt::StrongFocus); + myListView->getControl()->viewport()->installEventFilter(this); +} + +//******************************************************************** +void XGUI_FacesPanel::reset(const bool isToFlushRedisplay) +{ + // restore presentation state + bool isModified = false; + std::set aRestoredObjects; + for (QMap::const_iterator anIt = myItems.begin(); + anIt != myItems.end(); anIt++) { + if (aRestoredObjects.find(anIt.value()->object()) == aRestoredObjects.end()) + aRestoredObjects.insert(anIt.value()->object()); + } + // clear internal containers + myListView->getControl()->clear(); + myLastItemIndex = 0; + myItems.clear(); + + isModified = redisplayObjects(aRestoredObjects, isToFlushRedisplay); + + if (isToFlushRedisplay && isModified) + XGUI_Tools::workshop(myWorkshop)->displayer()->updateViewer(); +} + +//******************************************************************** +bool XGUI_FacesPanel::eventFilter(QObject* theObject, QEvent *theEvent) +{ + QWidget* aWidget = qobject_cast(theObject); + if (theEvent->type() == QEvent::MouseButtonRelease) + { + if (myListView->getControl()->viewport() == aWidget) + setActivePanel(true); + } + // pass the event on to the parent class + return QObject::eventFilter(theObject, theEvent); +} + +//******************************************************************** +void XGUI_FacesPanel::setActivePanel(const bool theIsActive) +{ + if (myIsActive == theIsActive) + return; + + ModuleBase_Tools::setShadowEffect(myListView->getControl(), theIsActive); + myIsActive = theIsActive; + + if (myIsActive) + { + emit activated(); + // selection should be activated after emit signal, that deactivates current widget(selection) + activateSelection(theIsActive); + } + else + { + // selection should be activated after emit signal, that deactivates current widget(selection) + activateSelection(theIsActive); + emit deactivated(); + } +} + +//******************************************************************** +void XGUI_FacesPanel::restoreObjects(const std::set& theHiddenObjects) +{ + std::set anIndicesToBeRemoved; + for (QMap::const_iterator anItemsIt = myItems.begin(); + anItemsIt != myItems.end(); anItemsIt++) + { + ModuleBase_ViewerPrsPtr aPrs = anItemsIt.value(); + ObjectPtr anObject = aPrs->object(); + if (theHiddenObjects.find(anObject) == theHiddenObjects.end()) // not found + continue; + anIndicesToBeRemoved.insert(anItemsIt.key()); + } + + // remove from myItes container + for (std::set::const_iterator aToBeRemovedIt = anIndicesToBeRemoved.begin(); + aToBeRemovedIt != anIndicesToBeRemoved.end(); aToBeRemovedIt++) + myItems.remove(*aToBeRemovedIt); + + myListView->removeItems(anIndicesToBeRemoved); + + // remove from container of hidden objects + for (std::set::const_iterator aHiddenIt = theHiddenObjects.begin(); + aHiddenIt != theHiddenObjects.end(); aHiddenIt++) + { + if (myHiddenObjects.find(*aHiddenIt) != myHiddenObjects.end()) ///< found objects + myHiddenObjects.erase(*aHiddenIt); + } +} + +//******************************************************************** +bool XGUI_FacesPanel::processAction(ModuleBase_ActionType theActionType) +{ + switch (theActionType) { + //case ActionEnter: + // return processEnter(); + case ActionEscape: + setActivePanel(false); + return true; + case ActionDelete: + return processDelete(); + //case ActionUndo: + //case ActionRedo: + default: + return false; + } +} + +//******************************************************************** +void XGUI_FacesPanel::processSelection() +{ + QList aSelected = myWorkshop->selection()->getSelected( + ModuleBase_ISelection::Viewer); + bool isModified = false; + for (int i = 0; i < aSelected.size(); i++) { + ModuleBase_ViewerPrsPtr aPrs = aSelected[i]; + ObjectPtr anObject = aPrs->object(); + if (!anObject.get()) + continue; + + if (ModuleBase_Tools::getSelectedShape(aPrs).ShapeType() != TopAbs_FACE) + continue; + + myItems.insert(myLastItemIndex, aPrs); + myListView->addItem(generateName(aPrs), myLastItemIndex); + isModified = hideFace(myLastItemIndex) || isModified; + + myLastItemIndex++; + } + + if (isModified) + XGUI_Tools::workshop(myWorkshop)->displayer()->updateViewer(); +} + +//******************************************************************** +bool XGUI_FacesPanel::processDelete() +{ + //appendFirstSelectionInHistory(); + QModelIndexList anIndices = myListView->getControl()->selectionModel()->selectedIndexes(); + + std::set aSelectedIds; + myListView->getSelectedIndices(aSelectedIds); + if (aSelectedIds.empty()) + return false; + + bool isModified = false; + std::set aRestoredObjects; + XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); + for (std::set::const_iterator anIt = aSelectedIds.begin(); anIt != aSelectedIds.end(); + anIt++) { + ModuleBase_ViewerPrsPtr aPrs = myItems[*anIt]; + if (aRestoredObjects.find(aPrs->object()) == aRestoredObjects.end()) + aRestoredObjects.insert(aPrs->object()); + myItems.remove(*anIt); + } + myListView->removeSelectedItems(); + + isModified = redisplayObjects(aRestoredObjects, true) || isModified; + if (isModified) + XGUI_Tools::workshop(myWorkshop)->displayer()->updateViewer(); + + // Restore selection + myListView->restoreSelection(anIndices); + //appendSelectionInHistory(); + return true; +} + +//******************************************************************** +bool XGUI_FacesPanel::redisplayObjects( + const std::set >& theObjects, + const bool isToFlushRedisplay) +{ + bool isModified = false; + XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); + static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + + for (std::set::const_iterator anIt = theObjects.begin(); anIt != theObjects.end(); + anIt++) + { + ObjectPtr anObject = *anIt; + if (!anObject->isDisplayed()) { + // if the object was hidden by this panel + if (myHiddenObjects.find(anObject) != myHiddenObjects.end()) + myHiddenObjects.erase(anObject); + anObject->setDisplayed(true); // it means that the object is hidden by hide all faces + ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); + isModified = true; + //isModified = aDisplayer->display(anObject, false) || isModified; + } + else { + ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); + isModified = true; + } + } + if (isToFlushRedisplay) + Events_Loop::loop()->flush(aDispEvent); + return isModified; +} + +//******************************************************************** +bool XGUI_FacesPanel::hideFace(const int theIndex) +{ + XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); + + if (!myItems.contains(theIndex)) + return false; + + ModuleBase_ViewerPrsPtr aPrs = myItems[theIndex]; + + AISObjectPtr aAISObj = aDisplayer->getAISObject(aPrs->object()); + if (aAISObj.get() == NULL) + return false; + Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast( + aAISObj->impl()); + if (aResultPrs.IsNull()) + return false; + // set shape hidden to check whether the presentation should be erased from the viewer + bool isModified = false; + if (aResultPrs->hasSubShapeVisible(ModuleBase_Tools::getSelectedShape(aPrs))) + isModified = aDisplayer->redisplay(aPrs->object(), false) || isModified; + else + { + ObjectPtr anObject = aPrs->object(); + myHiddenObjects.insert(anObject); + static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + anObject->setDisplayed(false); + isModified = aDisplayer->erase(anObject, false) || isModified; + ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); + Events_Loop::loop()->flush(aDispEvent); + } + return isModified; +} + +//******************************************************************** +void XGUI_FacesPanel::closeEvent(QCloseEvent* theEvent) +{ + QDockWidget::closeEvent(theEvent); + emit closed(); +} + +//******************************************************************** +void XGUI_FacesPanel::activateSelection(bool toActivate) +{ + QIntList aShapeTypes; + aShapeTypes.append(TopAbs_FACE); + + if (toActivate) { + myWorkshop->activateSubShapesSelection(aShapeTypes); + } else { + myWorkshop->deactivateSubShapesSelection(); + } + if (toActivate) + activateSelectionFilters(); + else + deactivateSelectionFilters(); +} + +//******************************************************************** +QString XGUI_FacesPanel::generateName(const ModuleBase_ViewerPrsPtr& thePrs) +{ + if (!thePrs.get() || !thePrs->object().get()) + return "Undefined"; + + GeomShapePtr aContext; + ObjectPtr anObject = thePrs->object(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get()) + aContext = aResult->shape(); + else { + // TODO if there is this case + } + + QString aName = anObject->data()->name().c_str(); + if (aContext.get()) { + GeomShapePtr aSubShape(new GeomAPI_Shape()); + aSubShape->setImpl(new TopoDS_Shape(ModuleBase_Tools::getSelectedShape(thePrs))); + if (!aSubShape->isEqual(aContext)) + aName += QString("_%1").arg(GeomAlgoAPI_CompoundBuilder::id(aContext, aSubShape)); + } + return aName; +} + +//******************************************************************** +bool XGUI_FacesPanel::customizeObject(const ObjectPtr& theObject, const bool isDisplayed) +{ + if (isDisplayed && myItems.isEmpty()) + return false; + + XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); + + AISObjectPtr aAISObj = aDisplayer->getAISObject(theObject); + if (aAISObj.get() == NULL) + return false; + Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast( + aAISObj->impl()); + if (aResultPrs.IsNull()) + return false; + + // if the object is displayed, the hidden faces are collected and set to the presentation + bool isModified = false; + NCollection_List aHiddenSubShapes; + for (QMap::const_iterator anIt = myItems.begin(); + anIt != myItems.end(); anIt++) { + ModuleBase_ViewerPrsPtr aPrs = anIt.value(); + if (aPrs.get() && aPrs->object() != theObject) + continue; + TopoDS_Shape aShape = ModuleBase_Tools::getSelectedShape(aPrs); + if (!aHiddenSubShapes.Contains(aShape)) + aHiddenSubShapes.Append(aShape); + } + isModified = aResultPrs->setSubShapeHidden(aHiddenSubShapes); + + return isModified; +} + +//******************************************************************** +void XGUI_FacesPanel::onDeleteItem() +{ + processDelete(); +} + +//******************************************************************** +void XGUI_FacesPanel::onClosed() +{ + reset(true); +} diff --git a/src/XGUI/XGUI_FacesPanel.h b/src/XGUI/XGUI_FacesPanel.h new file mode 100644 index 000000000..dd99a65dc --- /dev/null +++ b/src/XGUI/XGUI_FacesPanel.h @@ -0,0 +1,175 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef XGUI_FacesPanel_H_ +#define XGUI_FacesPanel_H_ + +#include "XGUI.h" + +#include + +#include +#include +#include + +#include + +class AIS_InteractiveObject; + +class ModelAPI_Object; +class ModuleBase_IWorkshop; +class ModuleBase_ListView; +class ModuleBase_ViewerPrs; + +class QAction; +class QCheckBox; +class QEvent; + +/** +* \ingroup GUI +* A Hide Faces panel for making it possible to hide faces in the 3D view. +* The panel has multi-selector filled by faces elements. When the control is active +* it is possible to select faces in the viewer. The selected faces are hidden/transparent +* after selection and the corresponding item is appeared in the multi selector. +* +* In order to redisplay a face, it is enough to click delete on the name of this face +* in the multiselector. +* When the panel is opened, the multiselector is empty. +* When the panel is closed, the multiselector is emptied and the faces are displayed again. +* The default position by of this dockable window is to the right of the view (in SALOME mode). +* If no feature is processed (in neutral point), this panel can be activated too. +* On feature edition start or finish, movement of the history line, undo/redo and other +* modification of the model, the multiselector is emptied. +*/ +class XGUI_EXPORT XGUI_FacesPanel : public QDockWidget +{ + Q_OBJECT +public: + /// Constructor + /// \param theParent is a parent of the property panel + XGUI_FacesPanel(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop); + ~XGUI_FacesPanel() {} + + /// Clear content of list widget + /// \param isToFlushRedisplay flag if redisplay should be flushed immediatelly + virtual void reset(const bool isToFlushRedisplay); + + /// Returns whether the panel is active or not + bool isActivePanel() const { return myIsActive; } + + /// Stores the state if panel is active and highlight the panel in an active color + /// \param theIsActive state whether the panel should be activated or deactivated + void setActivePanel(const bool theIsActive); + + /// Returns true if the object is in internal container of hidden objects by this panel + /// \param theObject a checked object + /// \return boolean value + bool isObjectHiddenByPanel(const std::shared_ptr& theObject) const + { return myHiddenObjects.find(theObject) != myHiddenObjects.end(); } + + /// Removed faces of the objects from the panel + /// \param container of objects + void restoreObjects(const std::set >& theHiddenObjects); + + /// Returns true if the event is processed. The default implementation is empty, returns false. + virtual bool processAction(ModuleBase_ActionType theActionType); + + /// Append selected item in the list and customize presentations to hide faces + void processSelection(); + + /// Deletes item in a list of elements + /// \return whether the delete action is processed + bool processDelete(); + + /// Processing focus in/out for the faces control + /// \param theObject source object of event + /// \param theEvent an event + virtual bool eventFilter(QObject* theObject, QEvent *theEvent); + + /// Hide/show faces of the object if: + /// - face selector is active + /// - object is mentioned in the list of selected elements + /// If the object is displayed, all panel faces selected on it will be moved into presentation + /// or, if redisplayed, fuction return if the object should be redisplayed or not + /// \param theObject a customized object + /// \param isDisplayed state if the object is displayed or redisplayed + /// \return true if the presentation is customized + bool customizeObject(const std::shared_ptr& theObject, const bool isDisplayed); + +protected: + /// Add panel selection filters to the current viewer + virtual void activateSelectionFilters() {} + + /// Remove panel selection filters from the current viewer + virtual void deactivateSelectionFilters() {} + +protected: + /// Reimplementation to emit a signal about the panel close + virtual void closeEvent(QCloseEvent* theEvent); + +signals: + /// Signal about activating pane + void activated(); + /// Signal about deactivating pane + void deactivated(); + /// Signal is emitted by the top widget cross button click + void closed(); + +private: + /// Activate or deactivate selection and selection filters + void activateSelection(bool toActivate); + + /// Redisplay or display objects. The viewer is not updated after redisplay. + /// \param theObjects container of objects + /// \param isToFlushRedisplay flag if redisplay should be flushed immediatelly + /// \return true if some of objects was redisplayed to update viewer + bool redisplayObjects(const std::set >& theObjects, + const bool isToFlushRedisplay); + + /// Change the presentation to have the selected presentation hidden + /// \param theIndex an index of selected item that should be hidden + /// \return true if presentation is changed + bool hideFace(const int theIndex); + + /// Generates a presentation name in form: /_ + /// \param thePrs a presentation + /// \return string value + static QString generateName(const std::shared_ptr& thePrs); + +protected slots: + /// Deletes element in list of items + void onDeleteItem(); + + /// Closes faces panel restore all hidden faces by calling reset() + void onClosed(); + +protected: + QCheckBox* myHiddenOrTransparent; ///< if checked - transparent, else hidden + ModuleBase_ListView* myListView; ///< list control of processed faces + ModuleBase_IWorkshop* myWorkshop; ///< workshop + + bool myIsActive; ///< current state about the panel is active + int myLastItemIndex; ///< last index to be used in the map of items for the next added item + + QMap > myItems; ///< selected face items + std::set > myHiddenObjects; ///< hidden objects +}; + +#endif \ No newline at end of file diff --git a/src/XGUI/XGUI_FacesPanelSelector.cpp b/src/XGUI/XGUI_FacesPanelSelector.cpp new file mode 100644 index 000000000..7d496992b --- /dev/null +++ b/src/XGUI/XGUI_FacesPanelSelector.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include + +#include + +//******************************************************************** +XGUI_FacesPanelSelector::XGUI_FacesPanelSelector(XGUI_FacesPanel* thePanel) +: myPanel(thePanel) +{ + connect(myPanel, SIGNAL(activated()), this, SIGNAL(activated())); + connect(myPanel, SIGNAL(deactivated()), this, SIGNAL(deactivated())); +} + +//******************************************************************** +void XGUI_FacesPanelSelector::reset() +{ + myPanel->reset(true); +} + +//******************************************************************** +void XGUI_FacesPanelSelector::setActive(const bool& isActive) +{ + myPanel->setActivePanel(isActive); +} + +//******************************************************************** +void XGUI_FacesPanelSelector::processSelection() +{ + myPanel->processSelection(); +} diff --git a/src/XGUI/XGUI_FacesPanelSelector.h b/src/XGUI/XGUI_FacesPanelSelector.h new file mode 100644 index 000000000..fc16b36c3 --- /dev/null +++ b/src/XGUI/XGUI_FacesPanelSelector.h @@ -0,0 +1,64 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef XGUI_FacesPanelSelector_H +#define XGUI_FacesPanelSelector_H + +#include "XGUI.h" + +#include + +class XGUI_FacesPanel; + +/** +* Processing selection by the faces panel. +*/ +class XGUI_FacesPanelSelector : public XGUI_ActiveControlSelector +{ + Q_OBJECT + +public: + /// Constructor + /// \param thePanel the workshop faces panel + XGUI_EXPORT XGUI_FacesPanelSelector(XGUI_FacesPanel* thePanel); + /// Destructor + XGUI_EXPORT virtual ~XGUI_FacesPanelSelector() {}; + + /// Returns name of the selector + XGUI_EXPORT static QString Type() { return "XGUI_FacesPanelSelector"; } + + /// Returns name of the selector + XGUI_EXPORT virtual QString getType() { return Type(); } + + /// Set empty widget that need to be activated widget if it is not empty + XGUI_EXPORT virtual void reset(); + + /// Sets control active. It should activates/deactivates selection and selection filters. + /// \param isActive if true, the control becomes active + XGUI_EXPORT virtual void setActive(const bool& isActive); + + /// Processes current selection of workshop. Reaction to selection change in workshop. + XGUI_EXPORT virtual void processSelection(); + +protected: + XGUI_FacesPanel* myPanel; ///< processed panel +}; + +#endif diff --git a/src/XGUI/XGUI_ObjectsBrowser.cpp b/src/XGUI/XGUI_ObjectsBrowser.cpp index eda25f837..3b09d6ab7 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.cpp +++ b/src/XGUI/XGUI_ObjectsBrowser.cpp @@ -29,6 +29,8 @@ #include +#include + #include #include #include @@ -233,14 +235,19 @@ void XGUI_DataTree::processEyeClick(const QModelIndex& theIndex) ObjectPtr aObj = aModel->object(theIndex); if (aObj.get()) { ResultPtr aResObj = std::dynamic_pointer_cast(aObj); + XGUI_ObjectsBrowser* aObjBrowser = qobject_cast(parent()); if (aResObj.get()) { + std::set anObjects; + anObjects.insert(aResObj); + if (aObjBrowser && !aResObj->isDisplayed() && + !aObjBrowser->workshop()->prepareForDisplay(anObjects)) + return; aResObj->setDisplayed(!aResObj->isDisplayed()); Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); update(theIndex); } // Update list of selected objects because this event happens after // selection event in object browser - XGUI_ObjectsBrowser* aObjBrowser = qobject_cast(parent()); if (aObjBrowser) { aObjBrowser->onSelectionChanged(); } diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 50f690425..d8a7041d2 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -19,9 +19,14 @@ // #include "XGUI_OperationMgr.h" + +#include "XGUI_ActiveControlMgr.h" +#include "XGUI_ActiveControlSelector.h" +#include "XGUI_FacesPanelSelector.h" #include "XGUI_ModuleConnector.h" #include "XGUI_Workshop.h" #include "XGUI_ErrorMgr.h" +#include "XGUI_FacesPanel.h" #include "XGUI_Tools.h" #include "XGUI_ObjectsBrowser.h" #include "XGUI_ContextMenuMgr.h" @@ -711,6 +716,13 @@ bool XGUI_OperationMgr::onKeyPressed(QObject *theObject, QKeyEvent* theEvent) if (anActiveWgt) isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEscape); } + if (!isAccepted) + { + XGUI_ActiveControlSelector* anActiveSelector = + XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector(); + if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type()) + isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionEscape); + } // default Escape button functionality if (!isAccepted && aOperation) { onAbortOperation(); @@ -801,6 +813,13 @@ bool XGUI_OperationMgr::onProcessDelete(QObject* theObject) } } } + if (!isAccepted) + { + XGUI_ActiveControlSelector* anActiveSelector = + XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector(); + if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type()) + isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionDelete); + } if (!isAccepted) { // after widget, object browser and viewer should process delete /// other widgets such as line edit controls should not lead to diff --git a/src/XGUI/XGUI_PropertyPanel.cpp b/src/XGUI/XGUI_PropertyPanel.cpp index bdc479259..cb031c166 100755 --- a/src/XGUI/XGUI_PropertyPanel.cpp +++ b/src/XGUI/XGUI_PropertyPanel.cpp @@ -18,9 +18,15 @@ // email : webmaster.salome@opencascade.com // -#include #include +#include +#include +#include +#include #include +#include +#include + //#include #include #include @@ -123,6 +129,10 @@ void XGUI_PropertyPanel::cleanContent() if (myActiveWidget) myActiveWidget->deactivate(); + XGUI_ActiveControlSelector* aPPSelector = XGUI_Tools::workshop(myOperationMgr->workshop())-> + activeControlMgr()->getSelector(XGUI_PropertyPanelSelector::Type()); + aPPSelector->reset(); // it removes need to be updated widget link + /// as the widgets are deleted later, it is important that the signals /// of these widgets are not processed. An example of the error is issue 986. /// In the given case, the property panel is firstly filled by new widgets diff --git a/src/XGUI/XGUI_PropertyPanelSelector.cpp b/src/XGUI/XGUI_PropertyPanelSelector.cpp new file mode 100644 index 000000000..f33e77c91 --- /dev/null +++ b/src/XGUI/XGUI_PropertyPanelSelector.cpp @@ -0,0 +1,67 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include +#include + +//******************************************************************** +XGUI_PropertyPanelSelector::XGUI_PropertyPanelSelector(XGUI_PropertyPanel* thePanel) +: myPanel(thePanel), myWidgetToBeActivated (NULL) +{ + connect(myPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), this, SIGNAL(activated())); +} + +//******************************************************************** +void XGUI_PropertyPanelSelector::reset() +{ + myWidgetToBeActivated = NULL; +} + +//******************************************************************** +void XGUI_PropertyPanelSelector::setActive(const bool& isActive) +{ + if (isActive) { + if (myWidgetToBeActivated) + myPanel->activateWidget(myWidgetToBeActivated, true); + return; + } + ModuleBase_ModelWidget* aWidget = myPanel->activeWidget(); + if (aWidget && aWidget->needToBeActiated()) + { + myWidgetToBeActivated = aWidget; + } + myPanel->activateWidget(NULL, false); +} + +//******************************************************************** +bool XGUI_PropertyPanelSelector::needToBeActiated() const +{ + return myWidgetToBeActivated != NULL; +} + +//******************************************************************** +void XGUI_PropertyPanelSelector::processSelection() +{ + ModuleBase_ModelWidget* aWidget = myPanel->activeWidget(); + if (!aWidget) + return; + + aWidget->processAction(ActionSelection); +} diff --git a/src/XGUI/XGUI_PropertyPanelSelector.h b/src/XGUI/XGUI_PropertyPanelSelector.h new file mode 100644 index 000000000..37b5e2706 --- /dev/null +++ b/src/XGUI/XGUI_PropertyPanelSelector.h @@ -0,0 +1,71 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef XGUI_PropertyPanelSelector_H +#define XGUI_PropertyPanelSelector_H + +#include "XGUI.h" + +#include + +class ModuleBase_ModelWidget; +class XGUI_PropertyPanel; + +/** +* Processing selection by the property panel. +*/ +class XGUI_PropertyPanelSelector : public XGUI_ActiveControlSelector +{ + Q_OBJECT + +public: + /// Constructor + /// \param thePanel the workshop property panel + XGUI_EXPORT XGUI_PropertyPanelSelector(XGUI_PropertyPanel* thePanel); + /// Destructor + XGUI_EXPORT virtual ~XGUI_PropertyPanelSelector() {}; + + /// Returns name of the selector + XGUI_EXPORT static QString Type() { return "XGUI_PropertyPanelSelector"; } + + /// Returns name of the selector + XGUI_EXPORT virtual QString getType() { return Type(); } + + /// Clear need to be activated widget if it exists + XGUI_EXPORT virtual void reset(); + + /// Sets control active. It should activates/deactivates selection and selection filters. + /// \param isActive if true, the control becomes active + XGUI_EXPORT virtual void setActive(const bool& isActive); + + /// Returns whether the selector should be activated as soon as possible (by deactivatate other) + /// \return boolean result + XGUI_EXPORT virtual bool needToBeActiated() const; + + /// Processes current selection of workshop. Reaction to selection change in workshop. + XGUI_EXPORT virtual void processSelection(); + +protected: + XGUI_PropertyPanel* myPanel; ///< processed panel + ModuleBase_ModelWidget* myWidgetToBeActivated; ///< used as need to be activated back + +}; + +#endif diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index a6edd15f9..a8972a47d 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -24,8 +24,9 @@ #include "XGUI_ViewerProxy.h" #include "XGUI_ObjectsBrowser.h" +#include "ModuleBase_BRepOwner.h" #include "ModuleBase_ResultPrs.h" -#include +#include "ModuleBase_ViewerPrs.h" #include #include diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 5112ff24c..2c02212bb 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -21,6 +21,8 @@ #include "XGUI_Workshop.h" #include "XGUI_ActionsMgr.h" +#include "XGUI_ActiveControlMgr.h" +#include "XGUI_ActiveControlSelector.h" #include "XGUI_MenuMgr.h" #include "XGUI_ColorDialog.h" #include "XGUI_DeflectionDialog.h" @@ -29,10 +31,13 @@ #include "XGUI_Displayer.h" #include "XGUI_ErrorDialog.h" #include "XGUI_ErrorMgr.h" +#include "XGUI_FacesPanel.h" +#include "XGUI_FacesPanelSelector.h" #include "XGUI_ModuleConnector.h" #include "XGUI_ObjectsBrowser.h" #include "XGUI_OperationMgr.h" #include "XGUI_PropertyPanel.h" +#include "XGUI_PropertyPanelSelector.h" #include "XGUI_PropertyDialog.h" #include "XGUI_SalomeConnector.h" #include "XGUI_Selection.h" @@ -65,13 +70,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include //#include @@ -152,18 +157,23 @@ static Handle(VInspector_CallBack) MyVCallBack; #include #endif +//#define DEBUG_FACES_PANEL +//#define DEBUG_WITH_MESSAGE_REPORT + QString XGUI_Workshop::MOVE_TO_END_COMMAND = QObject::tr("Move to the end"); //#define DEBUG_DELETE //#define DEBUG_FEATURE_NAME //#define DEBUG_CLEAN_HISTORY +//****************************************************** XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) : QObject(), myCurrentDir(QString()), myModule(NULL), mySalomeConnector(theConnector), myPropertyPanel(0), + myFacesPanel(0), myObjectBrowser(0), myDisplayer(0) //myViewerSelMode(TopAbs_FACE) @@ -213,6 +223,7 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) connect(mySelector, SIGNAL(selectionChanged()), this, SLOT(updateCommandStatus())); myActionsMgr = new XGUI_ActionsMgr(this); + myActiveControlMgr = new XGUI_ActiveControlMgr(myModuleConnector); myMenuMgr = new XGUI_MenuMgr(this); myErrorDlg = new XGUI_ErrorDialog(QApplication::desktop()); myContextMenuMgr = new XGUI_ContextMenuMgr(this); @@ -333,6 +344,7 @@ void XGUI_Workshop::startApplication() #endif } +//****************************************************** void XGUI_Workshop::activateModule() { myModule->activateSelectionFilters(); @@ -351,6 +363,7 @@ void XGUI_Workshop::activateModule() myOperationMgr->activate(); } +//****************************************************** void XGUI_Workshop::deactivateModule() { myModule->deactivateSelectionFilters(); @@ -415,14 +428,6 @@ void XGUI_Workshop::initMenu() addHistoryMenu(aAction, SIGNAL(updateRedoHistory(const QList&)), SLOT(onRedo(int))); salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT"); - //aAction = salomeConnector()->addDesktopCommand("REBUILD_CMD", tr("Rebuild"), - // tr("Rebuild data objects"), - // QIcon(":pictures/rebuild.png"), QKeySequence(), - // false, "MEN_DESK_EDIT"); - //salomeConnector()->addActionInToolbar( aAction, aToolBarTitle ); - - //connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRebuild())); - //salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT"); aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export native..."), tr("Export the current document into a native file"), @@ -470,12 +475,6 @@ void XGUI_Workshop::initMenu() SIGNAL(updateRedoHistory(const QList&)), SLOT(onRedo(int))); - //aCommand = aGroup->addFeature("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"), - // QIcon(":pictures/rebuild.png"), QKeySequence()); - //aCommand->connectTo(this, SLOT(onRebuild())); - - //aCommand->disable(); - aCommand = aGroup->addFeature("OPEN_CMD", tr("Open..."), tr("Open a new document"), QIcon(":pictures/open.png"), QKeySequence::Open); aCommand->connectTo(this, SLOT(onOpen())); @@ -491,6 +490,7 @@ void XGUI_Workshop::initMenu() } #ifndef HAVE_SALOME +//****************************************************** AppElements_Workbench* XGUI_Workshop::addWorkbench(const QString& theName) { AppElements_MainMenu* aMenuBar = myMainWindow->menuObject(); @@ -576,6 +576,7 @@ bool XGUI_Workshop::isFeatureOfNested(const FeaturePtr& theFeature) return aHasNested; } +//****************************************************** void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation) { ModuleBase_OperationFeature* aFOperation = @@ -583,7 +584,7 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation) if (!aFOperation) return; - showPropertyPanel(); + showPanel(myPropertyPanel); myPropertyPanel->cleanContent(); QList aWidgets; @@ -667,6 +668,7 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation) myErrorMgr->setPropertyPanel(myPropertyPanel); } +//****************************************************** void XGUI_Workshop::connectToPropertyPanel(const bool isToConnect) { XGUI_PropertyPanel* aPropertyPanel = propertyPanel(); @@ -716,7 +718,7 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation) ModuleBase_ISelection* aSel = mySelector->selection(); QObjectPtrList aObj = aSel->selectedPresentations(); //!< No need for property panel - hidePropertyPanel(); + hidePanel(myPropertyPanel); myPropertyPanel->cleanContent(); connectToPropertyPanel(false); @@ -742,17 +744,19 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation) activateObjectsSelection(anObjects); } - +//****************************************************** void XGUI_Workshop::onOperationCommitted(ModuleBase_Operation* theOperation) { myModule->operationCommitted(theOperation); } +//****************************************************** void XGUI_Workshop::onOperationAborted(ModuleBase_Operation* theOperation) { myModule->operationAborted(theOperation); } +//****************************************************** void XGUI_Workshop::setGrantedFeatures(ModuleBase_Operation* theOperation) { ModuleBase_OperationFeature* aFOperation = @@ -1078,23 +1082,6 @@ void XGUI_Workshop::onRedo(int theTimes) myDisplayer->updateViewer(); } -//****************************************************** -//void XGUI_Workshop::onRebuild() -//{ -// SessionPtr aMgr = ModelAPI_Session::get(); -// bool aWasOperation = aMgr->isOperation(); // keep this value -// if (!aWasOperation) { -// aMgr->startOperation("Rebuild"); -// } -// static const Events_ID aRebuildEvent = Events_Loop::loop()->eventByName("Rebuild"); -// Events_Loop::loop()->send(std::shared_ptr( -// new Events_Message(aRebuildEvent, this))); -// if (!aWasOperation) { -// aMgr->finishOperation(); -// } -// updateCommandStatus(); -//} - //****************************************************** void XGUI_Workshop::onWidgetStateChanged(int thePreviousState) { @@ -1133,11 +1120,13 @@ void XGUI_Workshop::onValuesChanged() } } +//****************************************************** void XGUI_Workshop::onWidgetObjectUpdated() { operationMgr()->onValidateOperation(); } +//****************************************************** ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule) { QString libName = QString::fromStdString(library(theModule.toStdString())); @@ -1271,6 +1260,7 @@ void XGUI_Workshop::updateCommandStatus() emit commandStatusUpdated(); } +//****************************************************** void XGUI_Workshop::updateHistory() { std::list aUndoList = ModelAPI_Session::get()->undoList(); @@ -1312,13 +1302,45 @@ void XGUI_Workshop::createDockWidgets() QDockWidget* aObjDock = createObjectBrowser(aDesktop); aDesktop->addDockWidget(Qt::LeftDockWidgetArea, aObjDock); myPropertyPanel = new XGUI_PropertyPanel(aDesktop, myOperationMgr); + myActiveControlMgr->addSelector(new XGUI_PropertyPanelSelector(myPropertyPanel)); + myPropertyPanel->setupActions(myActionsMgr); myPropertyPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); aDesktop->addDockWidget(Qt::LeftDockWidgetArea, myPropertyPanel); - hidePropertyPanel(); ///addSelector(new XGUI_FacesPanelSelector(myFacesPanel)); + myFacesPanel->setAllowedAreas(Qt::LeftDockWidgetArea | + Qt::RightDockWidgetArea | + Qt::BottomDockWidgetArea); + connect(myFacesPanel, SIGNAL(closed()), myFacesPanel, SLOT(onClosed())); + + aDesktop->addDockWidget( +#ifdef HAVE_SALOME + Qt::RightDockWidgetArea, +#else + Qt::LeftDockWidgetArea, +#endif + myFacesPanel); + hidePanel(myFacesPanel); ///addDockWidget(Qt::RightDockWidgetArea, myFacesPanel); + showPanel(myFacesPanel); +#endif + hideObjectBrowser(); + +#ifdef DEBUG_FACES_PANEL +#else +#ifndef HAVE_SALOME + aDesktop->tabifyDockWidget(myFacesPanel, aObjDock); +#endif +#endif + aDesktop->tabifyDockWidget(aObjDock, myPropertyPanel); myPropertyPanel->installEventFilter(myOperationMgr); @@ -1338,28 +1360,32 @@ void XGUI_Workshop::createDockWidgets() } //****************************************************** -void XGUI_Workshop::showPropertyPanel() +void XGUI_Workshop::showPanel(QDockWidget* theDockWidget) { - QAction* aViewAct = myPropertyPanel->toggleViewAction(); - ///setEnabled(true); - myPropertyPanel->show(); - myPropertyPanel->raise(); + if (theDockWidget == myPropertyPanel) { + QAction* aViewAct = myPropertyPanel->toggleViewAction(); + ///setEnabled(true); + } + theDockWidget->show(); + theDockWidget->raise(); // The next code is necessary to made the property panel the active window // in order to operation manager could process key events of the panel. // otherwise they are ignored. It happens only if the same(activateWindow) is // not happened by property panel activation(e.g. resume operation of Sketch) - ModuleBase_Tools::setFocus(myPropertyPanel, "XGUI_Workshop::showPropertyPanel()"); + ModuleBase_Tools::setFocus(theDockWidget, "XGUI_Workshop::showPanel()"); } //****************************************************** -void XGUI_Workshop::hidePropertyPanel() +void XGUI_Workshop::hidePanel(QDockWidget* theDockWidget) { - QAction* aViewAct = myPropertyPanel->toggleViewAction(); - ///setEnabled(false); - myPropertyPanel->hide(); + if (theDockWidget && theDockWidget == myPropertyPanel) { + QAction* aViewAct = theDockWidget->toggleViewAction(); + ///setEnabled(false); + } + theDockWidget->hide(); // the property panel is active window of the desktop, when it is // hidden, it is undefined which window becomes active. By this reason @@ -1369,7 +1395,7 @@ void XGUI_Workshop::hidePropertyPanel() // are processed by this console. For example Undo actions. // It is possible that this code is to be moved to SHAPER package QMainWindow* aDesktop = desktop(); - ModuleBase_Tools::setFocus(aDesktop, "XGUI_Workshop::showPropertyPanel()"); + ModuleBase_Tools::setFocus(aDesktop, "XGUI_Workshop::hidePanel()"); } //****************************************************** @@ -1487,6 +1513,13 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) if (!aContext.IsNull()) aParameters.Append(aContext); +#ifdef DEBUG_WITH_MESSAGE_REPORT + Handle(Message_Report) aContextReport = aContext->GetReport(); + aContextReport->SetActive (Standard_True); + aContextReport->SetLimit (1000); + if (!aContextReport.IsNull()) + aParameters.Append(aContextReport); +#endif MyVCallBack = new VInspector_CallBack(); myDisplayer->setCallBack(MyVCallBack); #ifndef HAVE_SALOME @@ -1499,13 +1532,23 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) MyTCommunicator->RegisterPlugin("TKDFBrowser"); MyTCommunicator->RegisterPlugin("TKShapeView"); MyTCommunicator->RegisterPlugin("TKVInspector"); +#ifdef DEBUG_WITH_MESSAGE_REPORT + MyTCommunicator->RegisterPlugin("TKMessageView"); +#endif MyTCommunicator->RegisterPlugin("SMBrowser"); // custom plugin to view ModelAPI //MyTCommunicator->RegisterPlugin("TKSMBrowser"); // custom plugin to view ModelAPI MyTCommunicator->Init(aParameters); MyTCommunicator->Activate("TKSMBrowser"); // to have button in TInspector +#ifndef DEBUG_WITH_MESSAGE_REPORT MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model +#endif MyTCommunicator->Activate("TKDFBrowser"); + +#ifdef DEBUG_WITH_MESSAGE_REPORT + MyTCommunicator->Activate("TKMessageView"); // temporary + MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model +#endif } MyTCommunicator->SetVisible(true); } @@ -1516,6 +1559,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) //************************************************************** void XGUI_Workshop::setViewerSelectionMode(int theMode) { + XGUI_ActiveControlSelector* anActiveSelector = activeControlMgr()->activeSelector(); + if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type()) + facesPanel()->setActivePanel(false); + if (theMode == -1) myViewerSelMode.clear(); else { @@ -1537,6 +1584,56 @@ void XGUI_Workshop::activateObjectsSelection(const QObjectPtrList& theList) myDisplayer->activateObjects(aModes, theList); } +//************************************************************** +bool XGUI_Workshop::prepareForDisplay(const std::set& theObjects) const +{ + // generate container of objects taking into account sub elments of compsolid + std::set anAllProcessedObjects; + for (std::set::const_iterator anObjectsIt = theObjects.begin(); + anObjectsIt != theObjects.end(); anObjectsIt++) { + ObjectPtr anObject = *anObjectsIt; + ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast(anObject); + if (aCompRes.get()) { + if (aCompRes->numberOfSubs(true) == 0) + anAllProcessedObjects.insert(anObject); + else { + for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { + ResultPtr aSubRes = aCompRes->subResult(i, true); + anAllProcessedObjects.insert(aCompRes->subResult(i, true)); + } + } + } + else + anAllProcessedObjects.insert(anObject); + } + + // find hidden objects in faces panel + std::set aHiddenObjects; + QStringList aHiddenObjectNames; + for (std::set::const_iterator anObjectsIt = theObjects.begin(); + anObjectsIt != theObjects.end(); anObjectsIt++) { + if (!facesPanel()->isObjectHiddenByPanel(*anObjectsIt)) + continue; + aHiddenObjects.insert(*anObjectsIt); + aHiddenObjectNames.append((*anObjectsIt)->data()->name().c_str()); + } + if (aHiddenObjects.empty()) + return true; + + int anAnswer = QMessageBox::question( + desktop(), tr("Show object"), + tr("The following objects are hidden by the '%1' panel:\n %2.\ + \nRemove objects from the panel to be displayed?") + .arg(facesPanel()->windowTitle()).arg(aHiddenObjectNames.join(','), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No)); + + bool aToBeDisplayed = anAnswer == QMessageBox::Yes; + if (aToBeDisplayed) + facesPanel()->restoreObjects(aHiddenObjects); + + return aToBeDisplayed; +} + //************************************************************** void XGUI_Workshop::deleteObjects() { @@ -1800,6 +1897,7 @@ bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theObjects) return ModelAPI_Tools::removeFeaturesAndReferences(aFeatures); } +//****************************************************** bool hasResults(QObjectPtrList theObjects, const std::set& theTypes) { bool isFoundResultType = false; @@ -1873,6 +1971,7 @@ std::list toCurrentFeatures(const ObjectPtr& theObject) return std::list(aObjectIt, aCurrentIt); } +//****************************************************** bool XGUI_Workshop::canMoveFeature() { QString anActionId = "MOVE_CMD"; @@ -1960,6 +2059,7 @@ bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const return false; } +//****************************************************** void setColor(ResultPtr theResult, const std::vector& theColor) { if (!theResult.get()) @@ -2234,8 +2334,19 @@ void XGUI_Workshop::onPreviewStateChanged() for (int i = 0; i < aDoc->size(aGroupName); i++) { \ aDoc->object(aGroupName, i)->setDisplayed(aDisplay); \ } + +//****************************************************** void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible) { + if (isVisible) { + std::set anObjects; + foreach (ObjectPtr aObj, theList) { + anObjects.insert(aObj); + } + if (!prepareForDisplay(anObjects)) + return; + } + foreach (ObjectPtr aObj, theList) { aObj->setDisplayed(isVisible); } @@ -2269,6 +2380,14 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList) viewer()->eraseAll(); #endif + std::set anObjects; + foreach (ObjectPtr aObj, theList) { + anObjects.insert(aObj); + } + + if (!prepareForDisplay(anObjects)) + return; + // Show only objects from the list foreach (ObjectPtr aObj, theList) { aObj->setDisplayed(true); @@ -2285,7 +2404,6 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList) #endif } - //************************************************************** void XGUI_Workshop::registerValidators() const { @@ -2356,6 +2474,7 @@ void XGUI_Workshop::closeDocument() //objectBrowser()->dataModel()->blockEventsProcessing(isBlocked); } +//****************************************************** void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot) { XGUI_HistoryMenu* aMenu = NULL; @@ -2372,6 +2491,7 @@ void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, co connect(aMenu, SIGNAL(actionSelected(int)), this, theSlot); } +//****************************************************** QList XGUI_Workshop::processHistoryList(const std::list& theList) const { QList aResult; @@ -2397,6 +2517,7 @@ QList XGUI_Workshop::processHistoryList(const std::list return aResult; } +//****************************************************** void XGUI_Workshop::setStatusBarMessage(const QString& theMessage) { #ifdef HAVE_SALOME @@ -2406,6 +2527,7 @@ void XGUI_Workshop::setStatusBarMessage(const QString& theMessage) #endif } +//****************************************************** void XGUI_Workshop::synchronizeViewer() { SessionPtr aMgr = ModelAPI_Session::get(); @@ -2421,6 +2543,7 @@ void XGUI_Workshop::synchronizeViewer() } } +//****************************************************** void XGUI_Workshop::synchronizeGroupInViewer(const DocumentPtr& theDoc, const std::string& theGroup, bool theUpdateViewer) @@ -2442,6 +2565,7 @@ void XGUI_Workshop::synchronizeGroupInViewer(const DocumentPtr& theDoc, myDisplayer->updateViewer(); } +//****************************************************** void XGUI_Workshop::highlightResults(const QObjectPtrList& theObjects) { FeaturePtr aFeature; @@ -2470,6 +2594,7 @@ void XGUI_Workshop::highlightResults(const QObjectPtrList& theObjects) tr("Results not found"), QMessageBox::Ok); } +//****************************************************** void XGUI_Workshop::highlightFeature(const QObjectPtrList& theObjects) { ResultPtr aResult; @@ -2541,4 +2666,4 @@ void XGUI_Workshop::moveOutFolder(bool isBefore) aMgr->startOperation(); aDoc->removeFromFolder(aFeatures, isBefore); aMgr->finishOperation(); -} \ No newline at end of file +} diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 8a96cfa80..d3dadf04a 100755 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -41,10 +41,12 @@ class AppElements_Workbench; #endif class XGUI_ActionsMgr; +class XGUI_ActiveControlMgr; class XGUI_ContextMenuMgr; class XGUI_Displayer; class XGUI_ErrorDialog; class XGUI_ErrorMgr; +class XGUI_FacesPanel; class XGUI_MenuMgr; class XGUI_ModuleConnector; class XGUI_ObjectsBrowser; @@ -131,6 +133,12 @@ Q_OBJECT return myActionsMgr; } + //! ! Returns an active control manager + XGUI_ActiveControlMgr* activeControlMgr() const + { + return myActiveControlMgr; + } + //! ! Returns an actions manager XGUI_MenuMgr* menuMgr() const { @@ -143,6 +151,12 @@ Q_OBJECT return myPropertyPanel; } + //! Returns panel for hide object faces + XGUI_FacesPanel* facesPanel() const + { + return myFacesPanel; + } + //! Returns context menu manager object XGUI_ContextMenuMgr* contextMenuMgr() const { @@ -190,6 +204,12 @@ Q_OBJECT /// \return a desktop instance QMainWindow* desktop() const; + /// If faces panel made the object hidden, show message box whether the object should be + /// restored (removed from the panel) and displayed, if answer is No, returns false + /// \param theObject a model object + /// \return boolean state if the object should not be displayed + virtual bool prepareForDisplay(const std::set& theObjects) const; + //! Delete features void deleteObjects(); @@ -379,9 +399,6 @@ signals: /// Redo previous command void onRedo(int times = 1); - // Rebuild data tree - //void onRebuild(); - /// Validates the operation to change the "Apply" button state. /// \param thePreviousState the previous state of the widget void onWidgetStateChanged(int thePreviousState); @@ -393,11 +410,11 @@ signals: /// Listens the corresponded signal of model widget and updates Apply button state by feature void onWidgetObjectUpdated(); - /// Show property panel - void showPropertyPanel(); + /// Show dock widget panel + void showPanel(QDockWidget* theDockWidget); - /// Hide property panel - void hidePropertyPanel(); + /// Hide dock widget panel + void hidePanel(QDockWidget* theDockWidget); /// Show object Browser void showObjectBrowser(); @@ -541,10 +558,12 @@ private: XGUI_ErrorMgr* myErrorMgr; XGUI_ObjectsBrowser* myObjectBrowser; XGUI_PropertyPanel* myPropertyPanel; + XGUI_FacesPanel* myFacesPanel; //< panel for hide object faces XGUI_SelectionMgr* mySelector; XGUI_Displayer* myDisplayer; XGUI_OperationMgr* myOperationMgr; ///< manager to manipulate through the operations XGUI_ActionsMgr* myActionsMgr; + XGUI_ActiveControlMgr* myActiveControlMgr; ///< manager to have none or one active control XGUI_MenuMgr* myMenuMgr; ///< manager to build menu/tool bar using order defined in XML XGUI_SalomeConnector* mySalomeConnector; XGUI_ErrorDialog* myErrorDlg; diff --git a/src/XGUI/XGUI_WorkshopListener.cpp b/src/XGUI/XGUI_WorkshopListener.cpp index d1b34d181..218058a69 100755 --- a/src/XGUI/XGUI_WorkshopListener.cpp +++ b/src/XGUI/XGUI_WorkshopListener.cpp @@ -19,23 +19,18 @@ // #include "XGUI_WorkshopListener.h" -#include "XGUI_Workshop.h" -#include "XGUI_Displayer.h" -#include "XGUI_ErrorMgr.h" -#include "XGUI_OperationMgr.h" -#include "XGUI_SalomeConnector.h" -#include "XGUI_ActionsMgr.h" -#include "XGUI_PropertyPanel.h" -#include "XGUI_ModuleConnector.h" -#include "XGUI_QtEvents.h" -#include "XGUI_SelectionMgr.h" #ifndef HAVE_SALOME #include #endif -#include -#include +#include +#include +#include + +#include +#include +#include #include #include @@ -46,27 +41,33 @@ #include #include -#include -#include - +#include +#include +#include #include - #include #include #include #include -#include #include -#include -#include -#include -#include +#include "XGUI_ActionsMgr.h" +#include "XGUI_Displayer.h" +#include "XGUI_ErrorMgr.h" +#include "XGUI_FacesPanel.h" +#include "XGUI_OperationMgr.h" +#include "XGUI_ModuleConnector.h" +#include "XGUI_PropertyPanel.h" +#include "XGUI_QtEvents.h" +#include "XGUI_SalomeConnector.h" +#include "XGUI_SelectionMgr.h" +#include "XGUI_Workshop.h" + +#include #include #include #include -#include #ifdef _DEBUG #include @@ -110,6 +111,9 @@ void XGUI_WorkshopListener::initializeEventListening() aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION)); + + aLoop->registerListener(this, Events_Loop::eventByName("FinishOperation")); + aLoop->registerListener(this, Events_Loop::eventByName("AbortOperation")); } //****************************************************** @@ -157,7 +161,9 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr& if (aWidgetSelector) workshop()->selector()->setSelected(aWidgetSelector->getAttributeSelection()); } - } + } else if (theMessage->eventID() == Events_Loop::eventByName("FinishOperation") || + theMessage->eventID() == Events_Loop::eventByName("AbortOperation")) + workshop()->facesPanel()->reset(false); // do not flush redisplay, it is flushed after event //Update property panel on corresponding message. If there is no current operation (no //property panel), or received message has different feature to the current - do nothing. -- 2.39.2