]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
#2309 Possibility to hide faces
authornds <nds@opencascade.com>
Tue, 5 Dec 2017 13:25:04 +0000 (16:25 +0300)
committernds <nds@opencascade.com>
Tue, 5 Dec 2017 13:25:04 +0000 (16:25 +0300)
43 files changed:
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_ActionType.h
src/ModuleBase/ModuleBase_BRepOwner.cpp [new file with mode: 0644]
src/ModuleBase/ModuleBase_BRepOwner.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_IModule.h
src/ModuleBase/ModuleBase_ListView.cpp [new file with mode: 0644]
src/ModuleBase/ModuleBase_ListView.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_ModelWidget.h
src/ModuleBase/ModuleBase_ResultPrs.cpp
src/ModuleBase/ModuleBase_ResultPrs.h
src/ModuleBase/ModuleBase_Tools.cpp
src/ModuleBase/ModuleBase_Tools.h
src/ModuleBase/ModuleBase_ViewerPrs.cpp
src/ModuleBase/ModuleBase_WidgetFeatureSelector.cpp
src/ModuleBase/ModuleBase_WidgetFeatureSelector.h
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_PreviewSketchPlane.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_WidgetSketchLabel.cpp
src/PartSet/PartSet_WidgetSketchLabel.h
src/XGUI/CMakeLists.txt
src/XGUI/XGUI_ActiveControlMgr.cpp [new file with mode: 0644]
src/XGUI/XGUI_ActiveControlMgr.h [new file with mode: 0644]
src/XGUI/XGUI_ActiveControlSelector.h [new file with mode: 0644]
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_Displayer.h
src/XGUI/XGUI_FacesPanel.cpp [new file with mode: 0644]
src/XGUI/XGUI_FacesPanel.h [new file with mode: 0644]
src/XGUI/XGUI_FacesPanelSelector.cpp [new file with mode: 0644]
src/XGUI/XGUI_FacesPanelSelector.h [new file with mode: 0644]
src/XGUI/XGUI_ObjectsBrowser.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_PropertyPanelSelector.cpp [new file with mode: 0644]
src/XGUI/XGUI_PropertyPanelSelector.h [new file with mode: 0644]
src/XGUI/XGUI_Selection.cpp
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h
src/XGUI/XGUI_WorkshopListener.cpp

index cb40f7222e31aa572d7f5efde477570c881dae8a..b1b612da8d35dddba374cfcaf523fd19e2e2ef71 100644 (file)
@@ -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
index 864c5e64acb38314756689195ca504aaddc7ec63..7228e98ea8f9e06297574117d6e484af86796405 100644 (file)
@@ -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 (file)
index 0000000..1c13dcf
--- /dev/null
@@ -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<mailto: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 (file)
index 0000000..b0dade4
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_BRepOwner_H
+#define ModuleBase_BRepOwner_H
+
+#include "ModuleBase.h"
+
+#include <Standard_DefineHandle.hxx>
+#include <StdSelect_BRepOwner.hxx>
+
+#include <QMap>
+
+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
index 927cfdc26906686bf0d2782e51384ba8639c06b8..4290fc3cdee0c93303e9aa60341f4faf16d48bf0 100755 (executable)
@@ -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 (file)
index 0000000..4bf680a
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModuleBase_ListView.h"
+#include "ModuleBase_Tools.h"
+
+#include <QAction>
+#include <QApplication>
+#include <QClipboard>
+#include <QListWidget>
+#include <QWidget>
+
+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<int>& theIndices)
+{
+  QList<QListWidgetItem*> 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<QListWidgetItem*> aItems = myListControl->selectedItems();
+  foreach(QListWidgetItem* anItem, aItems)
+    myListControl->takeItem(myListControl->row(anItem));
+}
+
+//********************************************************************
+void ModuleBase_ListView::removeItems(std::set<int>& theIndices)
+{
+  QList<QListWidgetItem*> 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<QListWidgetItem*> 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<QListWidgetItem*> 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 (file)
index 0000000..27c2262
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ListView_H_
+#define ModuleBase_ListView_H_
+
+#include "ModuleBase.h"
+
+#include <QModelIndex>
+#include <QObject>
+
+#include <set>
+
+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<int>& theIndices);
+
+  /// Removes selected items from the list widget
+  void removeSelectedItems();
+
+  /// Remove items contain parameter indices
+  /// \param theIndices an indices
+  void removeItems(std::set<int>& 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
index 4882e290317761c872cc6d83df7e62b6eccece0b..c63e684cbe7bf7539ce0d885f2af06d42091f76e 100644 (file)
@@ -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<QWidget*> getControls() const = 0;
index 907fd6a6098ffb50752defe12d7ff04ddbc2d987..41724e9772689aaefd96d62b973bbff41a19b607 100755 (executable)
 //
 
 #include "ModuleBase_ResultPrs.h"
-#include "ModuleBase_Tools.h"
+
+#include <GeomAPI_PlanarEdges.h>
 
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultCompSolid.h>
-#include <GeomAPI_PlanarEdges.h>
+
+#include "ModuleBase_Tools.h"
+#include "ModuleBase_BRepOwner.h"
 
 #include <Events_InfoMessage.h>
 #include <Events_Loop.h>
@@ -48,8 +51,6 @@
 #include <Graphic3d_AspectMarker3d.hxx>
 #include <TopExp_Explorer.hxx>
 
-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<TopoDS_Shape>& theShapes)
+{
+  bool isModified = false;
+
+  // restore hidden shapes if there are not the shapes in parameter container
+  NCollection_List<TopoDS_Shape> aVisibleSubShapes;
+  for (NCollection_List<TopoDS_Shape>::Iterator aHiddenIt(myHiddenSubShapes); aHiddenIt.More();
+       aHiddenIt.Next()) {
+    if (!theShapes.Contains(aHiddenIt.Value()))
+      aVisibleSubShapes.Append(aHiddenIt.Value());
+  }
+  isModified = !aVisibleSubShapes.IsEmpty();
+  for (NCollection_List<TopoDS_Shape>::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<TopoDS_Shape>::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<TopoDS_Shape>();
-    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());
index d9a0da37c2f1ad9d9916fb74eba139b389fcc8f8..e95018a7933bd2b4b002004943f0015c8801c8a8 100644 (file)
 
 #include <ModelAPI_Result.h>
 
+#include <NCollection_List.hxx>
 #include <ViewerData_AISShape.hxx>
 #include <Standard_DefineHandle.hxx>
-#include <StdSelect_BRepOwner.hxx>
 
 #include <QMap>
 
-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<TopoDS_Shape>& 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<TopoDS_Shape> myHiddenSubShapes;
+
   /// selection priority that will be added to the standard
   /// selection priority of the selection entity
   int myAdditionalSelectionPriority;
index 32d61570b082efd575f8e1afc995cec6c33cb87d..bd3c855cc0b8628317c957ba05a751613bc25d9b 100755 (executable)
@@ -27,6 +27,7 @@
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_IconFactory.h>
 #include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_ViewerPrs.h>
 
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_AttributeRefAttr.h>
@@ -50,6 +51,7 @@
 
 #include <ModelGeomAlgo_Point2D.h>
 
+#include <StdSelect_BRepOwner.hxx>
 #include <TopoDS_Iterator.hxx>
 
 #include <GeomDataAPI_Point2D.h>
@@ -516,6 +518,18 @@ TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
   return aShapeType;
 }
 
+TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
+{
+  if (thePrs->shape().get())
+    return thePrs->shape()->impl<TopoDS_Shape>();
+
+  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();
index 8a179c25adf1bc17ca09c83cd33f9a8590b34041..0cd2ed2dc815842b1185cb53b6e01cb8b30c24ac 100755 (executable)
@@ -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<ModuleBase_ViewerPrs>& thePrs);
+
 /// Returns list of parameters accessible in the active part and partset
 /// \theParameters a list of parameter names
 MODULEBASE_EXPORT void getParameters(QStringList& theParameters);
index 3eaa15c2c0086b93b1949fd52736d07bcfd0a229..3d4d446e616c5057711b2f7ec1a3583dd3f62816 100644 (file)
@@ -21,6 +21,7 @@
 #include "ModuleBase_ViewerPrs.h"
 
 #include <ModuleBase_ResultPrs.h>
+#include <StdSelect_BRepOwner.hxx>
 
 ModuleBase_ViewerPrs::ModuleBase_ViewerPrs(ObjectPtr theResult,
                                            const GeomShapePtr& theShape,
index 285fbe76563742ed741668300b553a85bb323903..a378b0a04f46cd1d31f05d77cca223745ae1aa5b 100644 (file)
@@ -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;
index 606fc1dad25d6b0be52f3e903404c5a819a39697..dc47862a9c410081f1d7dd8509d71d56dbb2c5d7 100644 (file)
@@ -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();
 
index 973b9b6ec5aeaa7d02d27de41f478b5d5fac19bc..15be27427a803b0a94c54e306b9a0c07220982c7 100755 (executable)
 //
 
 #include <ModuleBase_WidgetMultiSelector.h>
-#include <ModuleBase_WidgetShapeSelector.h>
+
+#include <ModuleBase_Definitions.h>
+#include <ModuleBase_Events.h>
+#include <ModuleBase_IconFactory.h>
+#include <ModuleBase_IModule.h>
 #include <ModuleBase_ISelection.h>
-#include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_IViewer.h>
+#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_ListView.h>
 #include <ModuleBase_Tools.h>
-#include <ModuleBase_Definitions.h>
-#include <ModuleBase_IModule.h>
 #include <ModuleBase_ViewerPrs.h>
-#include <ModuleBase_IconFactory.h>
-#include <ModuleBase_Events.h>
+#include <ModuleBase_WidgetShapeSelector.h>
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Object.h>
@@ -47,7 +49,6 @@
 #include <QString>
 #include <QComboBox>
 #include <QEvent>
-#include <QAction>
 #include <QApplication>
 #include <QClipboard>
 #include <QTimer>
 #include <memory>
 #include <string>
 
-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<QList<std::shared_ptr<ModuleBase_ViewerPrs> > > 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<int> 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<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 {
   QList<QWidget*> 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_ViewerPrsPtr> 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<ModuleBase_ViewerPrsPtr> 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<QListWidgetItem*> 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<QListWidgetItem*> 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<int>& theAttributeIds)
 {
-  QList<QListWidgetItem*> 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<int> theAttributeIds,
index 74b0ff510ea36567495b8204b91dbfb30d0653ae..6b35b93801dfb77e054fbf63938bb46709ac29a5 100755 (executable)
 #include <QMap>
 
 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<ResultPtr, GeomShapePtr> 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;
index f6131c3fe37b61a13c8aa19504a8b202efcfa33f..8b2d83405749f57bd4f0cafde6c51d18217c8589 100755 (executable)
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Dir.h>
 
-#include <XGUI_Displayer.h>
-#include <XGUI_Workshop.h>
-#include <XGUI_OperationMgr.h>
-#include <XGUI_PropertyPanel.h>
-#include <XGUI_ModuleConnector.h>
+#include <XGUI_ActiveControlMgr.h>
+#include <XGUI_ActiveControlSelector.h>
+#include <XGUI_ActionsMgr.h>
 #include <XGUI_ContextMenuMgr.h>
-#include <XGUI_Tools.h>
-#include <XGUI_ObjectsBrowser.h>
-#include <XGUI_SelectionMgr.h>
+#include <XGUI_CustomPrs.h>
 #include <XGUI_DataModel.h>
+#include <XGUI_Displayer.h>
 #include <XGUI_ErrorMgr.h>
-#include <XGUI_CustomPrs.h>
+#include <XGUI_FacesPanelSelector.h>
+#include <XGUI_ModuleConnector.h>
+#include <XGUI_ObjectsBrowser.h>
+#include <XGUI_OperationMgr.h>
+#include <XGUI_PropertyPanel.h>
 #include <XGUI_SelectionMgr.h>
-#include <XGUI_ActionsMgr.h>
+#include <XGUI_Tools.h>
+#include <XGUI_Workshop.h>
 
 #include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_ConstraintLength.h>
@@ -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
index 4a70c942f511760ce05a93907663a9707df3424b..a54c16660383a56d4311dfbd7656b9fa2351b100 100755 (executable)
@@ -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();
index f0f614bb0f4ec9d7dccc2037b878fa7b1f784433..243b232685f8c68d76625938bbb0bb9ea299b757 100644 (file)
@@ -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;
 }
 
index abaadd3119b5d3a25735baf406845eafc02354e0..86d0c5921691106015bb2f6481e0e5c973e86342 100755 (executable)
@@ -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<GeomAPI_Pln> 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<GeomAPI_Pln>& thePln)
 {
-  if (myPlaneFilter.IsNull())
-   myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
-
   myPlaneFilter->setPlane(thePln);
 }
 
index 62e67fac2bd3a3beaa07f25473996e149f0f0f1a..119764273f5168c1eb3a2b396c744aff27693eb6 100644 (file)
@@ -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);
index 63cd3927ee2a66112b1837dd45677cc43786346a..bbf6e2b667016b85655b00558cb0657218703ac0 100644 (file)
@@ -195,6 +195,10 @@ QList<QWidget*> PartSet_WidgetSketchLabel::getControls() const
 
 void PartSet_WidgetSketchLabel::onSelectionChanged()
 {
+  std::shared_ptr<GeomAPI_Pln> aPlane = plane();
+  if (aPlane.get())
+    return;
+
   QList<ModuleBase_ViewerPrsPtr> 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);
 }
 
index 5cc4a10cf76049ac3b633341362dcc22228c420c..eb532706152ea81d1ba498e787429bb6874e3efc 100644 (file)
@@ -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<GeomAPI_Pln> plane() const;
 
@@ -92,6 +95,9 @@ public:
   /// \param thePrs a presentation
   static bool canFillSketch(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
 
+  /// Processes Selection action.
+  virtual bool processAction(ModuleBase_ActionType theActionType);
+
 signals:
   /// Signal on plane selection
   void planeSelected(const std::shared_ptr<GeomAPI_Pln>& 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();
 
index 7f0fe59ff7d9dd72c9f9f147f36063391d4f495a..9380b2688f71640e1e1edffb1094a264036a10e6 100644 (file)
@@ -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 (file)
index 0000000..7c2fc83
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include <XGUI_ActiveControlMgr.h>
+#include <XGUI_ActiveControlSelector.h>
+
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_IWorkshop.h>
+
+//********************************************************************
+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<XGUI_ActiveControlSelector*>(sender());
+  if (!aSelector || aSelector == myActiveSelector)
+    return;
+
+  if (myActiveSelector)
+    myActiveSelector->setActive(false);
+
+  activateSelector(aSelector);
+}
+
+//********************************************************************
+void XGUI_ActiveControlMgr::onSelectorDeactivated()
+{
+  XGUI_ActiveControlSelector* aSelector = qobject_cast<XGUI_ActiveControlSelector*>(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 (file)
index 0000000..40355b6
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_ActiveControlMgr_H
+#define XGUI_ActiveControlMgr_H
+
+#include "XGUI.h"
+
+#include <QList>
+#include <QObject>
+
+
+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<XGUI_ActiveControlSelector*> 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 (file)
index 0000000..c0a3e15
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_ActiveControlSelector_H
+#define XGUI_ActiveControlSelector_H
+
+#include "XGUI.h"
+
+#include <QObject>
+
+/**
+* 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
index 9612452007b84038bfce8bec51f01a0824c51f4f..4b7e02f5abbc5fe8172a030c8750cb1b0ffaab2f 100644 (file)
 // email : webmaster.salome@opencascade.com<mailto: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 <AppElements_Viewer.h>
 #include <ModelAPI_AttributeIntArray.h>
 #include <ModelAPI_ResultCompSolid.h>
 
+#include <ModuleBase_BRepOwner.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_Preferences.h>
 #include <ModuleBase_ResultPrs.h>
 #include <ModuleBase_Tools.h>
-#include <ModuleBase_IModule.h>
 #include <ModuleBase_ViewerPrs.h>
-#include <ModuleBase_Preferences.h>
 
 #include <GeomAPI_Shape.h>
 #include <GeomAPI_IPresentable.h>
@@ -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;
 }
 
index 9b606dab3b55c0877694e1fe5033e150b8df9d77..4414598d033cec4ddc0361abd55295c4fd9254f4 100644 (file)
@@ -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 (file)
index 0000000..79f2990
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "XGUI_FacesPanel.h"
+
+#include <Events_Loop.h>
+#include "GeomAlgoAPI_CompoundBuilder.h"
+
+#include <ModelAPI_Events.h>
+
+#include <ModuleBase_ISelection.h>
+#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 <QAction>
+#include <QCheckBox>
+#include <QFocusEvent>
+#include <QGridLayout>
+#include <QListWidget>
+#include <QMainWindow>
+
+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<ObjectPtr> aRestoredObjects;
+  for (QMap<int, ModuleBase_ViewerPrsPtr>::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<QWidget*>(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<ObjectPtr>& theHiddenObjects)
+{
+  std::set<int> anIndicesToBeRemoved;
+  for (QMap<int, ModuleBase_ViewerPrsPtr>::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<int>::const_iterator aToBeRemovedIt = anIndicesToBeRemoved.begin();
+    aToBeRemovedIt != anIndicesToBeRemoved.end(); aToBeRemovedIt++)
+    myItems.remove(*aToBeRemovedIt);
+
+  myListView->removeItems(anIndicesToBeRemoved);
+
+  // remove from container of hidden objects
+  for (std::set<ObjectPtr>::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<ModuleBase_ViewerPrsPtr> 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<int> aSelectedIds;
+  myListView->getSelectedIndices(aSelectedIds);
+  if (aSelectedIds.empty())
+    return false;
+
+  bool isModified = false;
+  std::set<ObjectPtr> aRestoredObjects;
+  XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer();
+  for (std::set<int>::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<std::shared_ptr<ModelAPI_Object> >& 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<ObjectPtr>::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<Handle(AIS_InteractiveObject)>());
+  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<ModelAPI_Result>(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<Handle(AIS_InteractiveObject)>());
+  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<TopoDS_Shape> aHiddenSubShapes;
+  for (QMap<int, ModuleBase_ViewerPrsPtr>::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 (file)
index 0000000..dd99a65
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_FacesPanel_H_
+#define XGUI_FacesPanel_H_
+
+#include "XGUI.h"
+
+#include <ModuleBase_ActionType.h>
+
+#include <QDockWidget>
+#include <QObject>
+#include <QMap>
+
+#include <set>
+
+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<ModelAPI_Object>& 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<std::shared_ptr<ModelAPI_Object> >& 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<ModelAPI_Object>& 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<std::shared_ptr<ModelAPI_Object> >& 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: <object_name>/<face>_<face_index>
+  /// \param thePrs a presentation
+  /// \return string value
+  static QString generateName(const std::shared_ptr<ModuleBase_ViewerPrs>& 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<int, std::shared_ptr<ModuleBase_ViewerPrs> > myItems; ///< selected face items
+  std::set<std::shared_ptr<ModelAPI_Object> > 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 (file)
index 0000000..7d49699
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include <XGUI_FacesPanelSelector.h>
+
+#include <XGUI_FacesPanel.h>
+
+//********************************************************************
+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 (file)
index 0000000..fc16b36
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_FacesPanelSelector_H
+#define XGUI_FacesPanelSelector_H
+
+#include "XGUI.h"
+
+#include <XGUI_ActiveControlSelector.h>
+
+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
index eda25f837032b3830713a6fb4b4ef37f9c6a4657..3b09d6ab7cb75b5b1154bd8a760d71119c3eeda4 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <ModuleBase_Tools.h>
 
+#include <XGUI_Workshop.h>
+
 #include <QLayout>
 #include <QLineEdit>
 #include <QPixmap>
@@ -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<ModelAPI_Result>(aObj);
+    XGUI_ObjectsBrowser* aObjBrowser = qobject_cast<XGUI_ObjectsBrowser*>(parent());
     if (aResObj.get()) {
+      std::set<ObjectPtr> 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<XGUI_ObjectsBrowser*>(parent());
     if (aObjBrowser) {
       aObjBrowser->onSelectionChanged();
     }
index 50f690425b92de3e73a40b4e3ce721691c1bb6cb..d8a7041d2e641a936ddf28e55cfea129cfeca4ba 100644 (file)
 //
 
 #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
index bdc4792593ea8b0c9439af775711c4f4daa76d9b..cb031c166c80e27d5d86f3ba4f386db686b17d15 100755 (executable)
 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
 //
 
-#include <XGUI_PropertyPanel.h>
 #include <XGUI_ActionsMgr.h>
+#include <XGUI_ActiveControlMgr.h>
+#include <XGUI_ActiveControlSelector.h>
+#include <XGUI_PropertyPanel.h>
+#include <XGUI_PropertyPanelSelector.h>
 #include <XGUI_OperationMgr.h>
+#include <XGUI_Tools.h>
+#include <XGUI_Workshop.h>
+
 //#include <AppElements_Constants.h>
 #include <ModuleBase_WidgetMultiSelector.h>
 #include <ModuleBase_Tools.h>
@@ -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 (file)
index 0000000..f33e77c
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include <XGUI_PropertyPanelSelector.h>
+#include <XGUI_PropertyPanel.h>
+
+//********************************************************************
+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 (file)
index 0000000..37b5e27
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_PropertyPanelSelector_H
+#define XGUI_PropertyPanelSelector_H
+
+#include "XGUI.h"
+
+#include <XGUI_ActiveControlSelector.h>
+
+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
index a6edd15f9aed56966fc4f9362564e066477b817c..a8972a47dc429ca9258075d1a61998e2b9cba468 100644 (file)
@@ -24,8 +24,9 @@
 #include "XGUI_ViewerProxy.h"
 #include "XGUI_ObjectsBrowser.h"
 
+#include "ModuleBase_BRepOwner.h"
 #include "ModuleBase_ResultPrs.h"
-#include <ModuleBase_ViewerPrs.h>
+#include "ModuleBase_ViewerPrs.h"
 
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Tools.h>
index 5112ff24ccbbfe703fcaa1763a46c9c50d8d787f..2c02212bbe79cd808b3183f89b1880ce2c96e803 100755 (executable)
@@ -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"
 #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"
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Object.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultGroup.h>
 #include <ModelAPI_ResultParameter.h>
 #include <ModelAPI_ResultField.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
-#include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_Tools.h>
 
 //#include <PartSetPlugin_Part.h>
@@ -152,18 +157,23 @@ static Handle(VInspector_CallBack) MyVCallBack;
 #include <dlfcn.h>
 #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<ActionInfo>&)), 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<ActionInfo>&)),
                  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<ModuleBase_ModelWidget*> 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<Events_Message>(
-//    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<std::string> 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();  ///<! Invisible by default
+  hidePanel(myPropertyPanel);  ///<! Invisible by default
+
+  myFacesPanel = new XGUI_FacesPanel(aDesktop, myModuleConnector);
+  myActiveControlMgr->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);  ///<! Invisible by default
+
+#ifdef DEBUG_FACES_PANEL
+  aDesktop->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();
-  ///<! Restore ability to close panel from the window's menu
-  aViewAct->setEnabled(true);
-  myPropertyPanel->show();
-  myPropertyPanel->raise();
+  if (theDockWidget == myPropertyPanel) {
+    QAction* aViewAct = myPropertyPanel->toggleViewAction();
+    ///<! Restore ability to close panel from the window's menu
+    aViewAct->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();
-  ///<! Do not allow to show empty property panel
-  aViewAct->setEnabled(false);
-  myPropertyPanel->hide();
+  if (theDockWidget && theDockWidget == myPropertyPanel) {
+    QAction* aViewAct = theDockWidget->toggleViewAction();
+    ///<! Do not allow to show empty property panel
+    aViewAct->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<ObjectPtr>& theObjects) const
+{
+  // generate container of objects taking into account sub elments of compsolid
+  std::set<ObjectPtr> anAllProcessedObjects;
+  for (std::set<ObjectPtr>::const_iterator anObjectsIt = theObjects.begin();
+    anObjectsIt != theObjects.end(); anObjectsIt++) {
+    ObjectPtr anObject = *anObjectsIt;
+    ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(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<ObjectPtr> aHiddenObjects;
+  QStringList aHiddenObjectNames;
+  for (std::set<ObjectPtr>::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<std::string>& theTypes)
 {
   bool isFoundResultType = false;
@@ -1873,6 +1971,7 @@ std::list<FeaturePtr> toCurrentFeatures(const ObjectPtr& theObject)
   return std::list<FeaturePtr>(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<int>& 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<ObjectPtr> 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<ObjectPtr> 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<ActionInfo> XGUI_Workshop::processHistoryList(const std::list<std::string>& theList) const
 {
   QList<ActionInfo> aResult;
@@ -2397,6 +2517,7 @@ QList<ActionInfo> XGUI_Workshop::processHistoryList(const std::list<std::string>
   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
+}
index 8a96cfa803fd838891e70dad003e90cf6974a787..d3dadf04a667977e7e7876bb09d82f215c047232 100755 (executable)
@@ -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<ObjectPtr>& 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;
index d1b34d181e594d4a0f0742629db393e22c41b380..218058a696eed4368754a1358d626941e1ada375 100755 (executable)
 //
 
 #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 <AppElements_MainWindow.h>
 #endif
 
-#include <ModuleBase_IModule.h>
-#include <ModuleBase_Events.h>
+#include <Config_FeatureMessage.h>
+#include <Config_PointerMessage.h>
+#include <Config_Keywords.h>
+
+#include <Events_InfoMessage.h>
+#include <Events_Loop.h>
+#include <Events_LongOp.h>
 
 #include <ModelAPI_Object.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_Tools.h>
 
-#include <Events_Loop.h>
-#include <Events_LongOp.h>
-
+#include <ModuleBase_Events.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_IViewer.h>
 #include <ModuleBase_IWorkshop.h>
-
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_OperationDescription.h>
 #include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_Tools.h>
-#include <ModuleBase_IViewer.h>
 #include <ModuleBase_WidgetSelector.h>
 
-#include <Config_FeatureMessage.h>
-#include <Config_PointerMessage.h>
-#include <Config_Keywords.h>
-#include <Events_InfoMessage.h>
+#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 <QAction>
 #include <QApplication>
 #include <QMainWindow>
 #include <QThread>
-#include <QAction>
 
 #ifdef _DEBUG
 #include <QDebug>
@@ -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<Events_Message>&
       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.