Salome HOME
Update viewer on delete an item
[modules/shaper.git] / src / XGUI / XGUI_FacesPanel.cpp
index 6c1e40370672d9f413acc44158bc470b25fd28d1..d92ae5669053b9799e40617da2307bf3e1d137fb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2019  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
 //
 // 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
+// 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>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "XGUI_FacesPanel.h"
+#include "XGUI_ObjectsBrowser.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_Tools.h"
+#include "XGUI_Workshop.h"
+
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_ISelection.h>
+#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_IViewer.h>
+#include <ModuleBase_ListView.h>
+#include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_Tools.h>
+#include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_SelectionFilterType.h>
 
 #include <Config_PropManager.h>
 #include <Events_Loop.h>
 
 #include <ModelAPI_Events.h>
 
-#include <ModuleBase_IModule.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_SelectionMgr.h"
-#include "XGUI_SelectionFilterType.h"
-#include "XGUI_Tools.h"
-#include "XGUI_Workshop.h"
-
 #include <QAction>
 #include <QCheckBox>
 #include <QFocusEvent>
@@ -85,17 +85,23 @@ void XGUI_FacesPanel::reset(const bool isToFlushRedisplay)
   myItems.clear();
 
   // restore previous view of presentations
-  bool isModified = redisplayObjects(myItemObjects, false);
+  bool isModified = redisplayObjects(myItemObjects);
   std::set<std::shared_ptr<ModelAPI_Object> > aHiddenObjects = myHiddenObjects;
-  isModified = displayHiddenObjects(aHiddenObjects, myHiddenObjects, false) || isModified;
+  isModified = displayHiddenObjects(aHiddenObjects, myHiddenObjects) || isModified;
   if (isModified)// && isToFlushRedisplay) // flush signal immediatelly until container is filled
-    Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+    flushRedisplay();
 
   updateProcessedObjects(myItems, myItemObjects);
   myHiddenObjects.clear();
   myLastItemIndex = 0; // it should be after redisplay as flag used in customize
 }
 
+//********************************************************************
+bool XGUI_FacesPanel::isEmpty() const
+{
+  return myItems.size() == 0;
+}
+
 //********************************************************************
 void XGUI_FacesPanel::selectionModes(QIntList& theModes)
 {
@@ -136,9 +142,11 @@ void XGUI_FacesPanel::setActivePanel(const bool theIsActive)
   myIsActive = theIsActive;
 
   if (myIsActive) {
+    emit activated();
+    // selection should be cleared after emit of signal to do not process selection change
+    // event by the previous selector
     // the selection is cleared by activating selection control
     XGUI_Tools::workshop(myWorkshop)->selector()->clearSelection();
-    emit activated();
   }
   else
     emit deactivated();
@@ -208,6 +216,9 @@ void XGUI_FacesPanel::processSelection()
                                                        ModuleBase_ISelection::Viewer);
   bool isModified = false;
   static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+
+  std::map<ObjectPtr, NCollection_List<TopoDS_Shape> > anObjectToShapes;
+  std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
   for (int i = 0; i < aSelected.size(); i++) {
     ModuleBase_ViewerPrsPtr aPrs = aSelected[i];
     ObjectPtr anObject = aPrs->object();
@@ -220,26 +231,43 @@ void XGUI_FacesPanel::processSelection()
       aPrs->interactive());
     if (aResultPrs.IsNull())
       continue;
+    QString aItemName = XGUI_Tools::generateName(aPrs);
+    if (myListView->hasItem(aItemName))
+      return;
 
     myItems.insert(myLastItemIndex, aPrs);
-    myListView->addItem(generateName(aPrs), myLastItemIndex);
+    myListView->addItem(aItemName, myLastItemIndex);
     myLastItemIndex++;
     isModified = true;
 
-    if (aResultPrs->hasSubShapeVisible(ModuleBase_Tools::getSelectedShape(aPrs)) ||
-        useTransparency()) // redisplay
-      ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
-    else { // erase object because it is entirely hidden
+    if (anObjectToShapes.find(anObject) != anObjectToShapes.end())
+      anObjectToShapes.at(anObject).Append(ModuleBase_Tools::getSelectedShape(aPrs));
+    else {
+      NCollection_List<TopoDS_Shape> aListOfShapes;
+      aListOfShapes.Append(ModuleBase_Tools::getSelectedShape(aPrs));
+      anObjectToShapes[anObject] = aListOfShapes;
+      anObjectToPrs[anObject] = aResultPrs;
+    }
+  }
+  for (std::map<ObjectPtr, NCollection_List<TopoDS_Shape> >::const_iterator
+    anIt = anObjectToShapes.begin(); anIt != anObjectToShapes.end(); anIt++) {
+    ObjectPtr anObject = anIt->first;
+    if (!anObject.get() || anObjectToPrs.find(anObject) == anObjectToPrs.end())
+      continue;
+    Handle(ModuleBase_ResultPrs) aResultPrs = anObjectToPrs.at(anObject);
+
+    if (!aResultPrs->hasSubShapeVisible(anIt->second)) { // redisplay
+      // erase object because it is entirely hidden
       anObject->setDisplayed(false);
       myHiddenObjects.insert(anObject);
-      ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
     }
+    ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
   }
-  if (isModified)
-  {
+  if (isModified) {
     updateProcessedObjects(myItems, myItemObjects);
-    Events_Loop::loop()->flush(aDispEvent);
+    flushRedisplay();
   }
+  onTransparencyChanged();
 }
 
 //********************************************************************
@@ -264,13 +292,16 @@ bool XGUI_FacesPanel::processDelete()
     isModified = true;
   }
   if (isModified) {
-    bool isRedisplayed = redisplayObjects(aRestoredObjects, false);
-    isRedisplayed = displayHiddenObjects(aRestoredObjects, myHiddenObjects, false)
+    bool isRedisplayed = redisplayObjects(aRestoredObjects);
+    isRedisplayed = displayHiddenObjects(aRestoredObjects, myHiddenObjects)
                     || isRedisplayed;
-    if (isRedisplayed)
-      Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+    if (isRedisplayed) {
+      flushRedisplay();
+      myWorkshop->viewer()->update();
+    }
     // should be after flush of redisplay to have items object to be updated
     updateProcessedObjects(myItems, myItemObjects);
+
   }
 
   myListView->removeSelectedItems();
@@ -282,8 +313,7 @@ bool XGUI_FacesPanel::processDelete()
 
 //********************************************************************
 bool XGUI_FacesPanel::redisplayObjects(
-  const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects,
-  const bool isToFlushRedisplay)
+  const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects)
 {
   if (theObjects.empty())
     return false;
@@ -299,16 +329,13 @@ bool XGUI_FacesPanel::redisplayObjects(
     ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
     isModified = true;
   }
-  if (isModified && isToFlushRedisplay)
-    Events_Loop::loop()->flush(aDispEvent);
   return isModified;
 }
 
 //********************************************************************
 bool XGUI_FacesPanel::displayHiddenObjects(
   const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects,
-  std::set<std::shared_ptr<ModelAPI_Object> >& theHiddenObjects,
-  const bool isToFlushRedisplay)
+  std::set<std::shared_ptr<ModelAPI_Object> >& theHiddenObjects)
 {
   if (theObjects.empty())
     return false;
@@ -328,9 +355,6 @@ bool XGUI_FacesPanel::displayHiddenObjects(
     ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
     isModified = true;
   }
-
-  if (isModified && isToFlushRedisplay)
-    Events_Loop::loop()->flush(aDispEvent);
   return isModified;
 }
 
@@ -339,6 +363,9 @@ bool XGUI_FacesPanel::hideEmptyObjects()
 {
   bool isModified = false;
   static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  std::map<ObjectPtr, NCollection_List<TopoDS_Shape> > anObjectToShapes;
+  std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
+
   for (QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator anIt = myItems.begin();
        anIt != myItems.end(); anIt++) {
     ModuleBase_ViewerPrsPtr aPrs = anIt.value();
@@ -351,7 +378,23 @@ bool XGUI_FacesPanel::hideEmptyObjects()
     if (aResultPrs.IsNull())
       continue;
 
-    if (!aResultPrs->hasSubShapeVisible(ModuleBase_Tools::getSelectedShape(aPrs))) {
+    if (anObjectToShapes.find(anObject) != anObjectToShapes.end())
+      anObjectToShapes.at(anObject).Append(ModuleBase_Tools::getSelectedShape(aPrs));
+    else {
+      NCollection_List<TopoDS_Shape> aListOfShapes;
+      aListOfShapes.Append(ModuleBase_Tools::getSelectedShape(aPrs));
+      anObjectToShapes[anObject] = aListOfShapes;
+      anObjectToPrs[anObject] = aResultPrs;
+    }
+  }
+  for (std::map<ObjectPtr, NCollection_List<TopoDS_Shape> >::const_iterator
+    anIt = anObjectToShapes.begin(); anIt != anObjectToShapes.end(); anIt++) {
+    ObjectPtr anObject = anIt->first;
+    if (!anObject.get() || anObjectToPrs.find(anObject) == anObjectToPrs.end())
+      continue;
+    Handle(ModuleBase_ResultPrs) aResultPrs = anObjectToPrs.at(anObject);
+
+    if (!aResultPrs->hasSubShapeVisible(anIt->second)) {
       // erase object because it is entirely hidden
       anObject->setDisplayed(false);
       myHiddenObjects.insert(anObject);
@@ -384,31 +427,6 @@ void XGUI_FacesPanel::closeEvent(QCloseEvent* theEvent)
   emit closed();
 }
 
-//********************************************************************
-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 AISObjectPtr& thePresentation)
@@ -461,15 +479,14 @@ void XGUI_FacesPanel::onTransparencyChanged()
   bool isModified = false;
   if (useTransparency()) {
     std::set<std::shared_ptr<ModelAPI_Object> > aHiddenObjects = myHiddenObjects;
-    isModified = displayHiddenObjects(aHiddenObjects, myHiddenObjects, false);
+    isModified = displayHiddenObjects(aHiddenObjects, myHiddenObjects);
   }
   else
     isModified = hideEmptyObjects();
 
-  isModified = redisplayObjects(myItemObjects, false) || isModified;
+  isModified = redisplayObjects(myItemObjects) || isModified;
   if (isModified)
-    Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
-
+    flushRedisplay();
 }
 
 //********************************************************************
@@ -478,3 +495,13 @@ void XGUI_FacesPanel::onClosed()
   setActivePanel(false);
   reset(true);
 }
+
+//********************************************************************
+void XGUI_FacesPanel::flushRedisplay() const
+{
+  Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  // Necessary for update visibility icons in ObjectBrowser
+  XGUI_ObjectsBrowser* anObjectBrowser = XGUI_Tools::workshop(myWorkshop)->objectBrowser();
+  if (anObjectBrowser)
+    anObjectBrowser->updateAllIndexes();
+}