Salome HOME
Copyright update 2022
[modules/shaper.git] / src / XGUI / XGUI_ObjectsBrowser.cpp
index 76a63127ad85eb93f23419198fe1f3e773943b2e..34c113f2cdc01ef0a3b68fe714316684678d9a95 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2022  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_ObjectsBrowser.h"
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Tools.h>
+#include <ModelAPI_ResultField.h>
 
 #include <ModuleBase_Tools.h>
+#include <ModuleBase_ITreeNode.h>
 
 #include <XGUI_Workshop.h>
+#include <XGUI_Displayer.h>
 
 #include <QLayout>
 #include <QLineEdit>
@@ -39,6 +41,7 @@
 #include <QAction>
 #include <QStyledItemDelegate>
 #include <QMessageBox>
+#include <QApplication>
 
 #ifdef DEBUG_INDXES
 #include <QToolTip>
@@ -48,7 +51,6 @@
 #define FIRST_COL_WIDTH 20
 #define SECOND_COL_WIDTH 30
 
-
 /**
 * \ingroup GUI
 * Tree item delegate for definition of data in column items editor
@@ -71,7 +73,7 @@ public:
       XGUI_DataModel* aModel = myTreedView->dataModel();
       ObjectPtr aObj = aModel->object(index);
       if (aObj.get() != NULL) {
-        aEditor->setText(aObj->data()->name().c_str());
+        aEditor->setText(QString::fromStdWString(aObj->data()->name()));
         return;
       }
     }
@@ -129,7 +131,7 @@ void XGUI_DataTree::commitData(QWidget* theEditor)
       if (XGUI_Tools::canRename(aObj, aName)) {
         SessionPtr aMgr = ModelAPI_Session::get();
         aMgr->startOperation("Rename");
-        aObj->data()->setName(qPrintable(aName));
+        aObj->data()->setName(aName.toStdWString());
         aMgr->finishOperation();
       }
     }
@@ -211,7 +213,7 @@ void XGUI_DataTree::processHistoryChange(const QModelIndex& theIndex)
     if ((theIndex.internalId() == 0) && (aDoc != aMgr->moduleDocument()))
       // Clicked folder under root but active document is another
       return;
-    if ((theIndex.internalId() != 0) && (aDoc.get() != theIndex.internalPointer()))
+    if ((theIndex.internalId() != 0) && (aDoc != aModel->document(theIndex)))
       // Cliced not on active document folder
       return;
 
@@ -219,7 +221,6 @@ void XGUI_DataTree::processHistoryChange(const QModelIndex& theIndex)
     aDoc->setCurrentFeature(FeaturePtr(), true);
     aMgr->finishOperation();
   }
-  QModelIndex aNewIndex = aModel->lastHistoryIndex();
   QModelIndex aParent = theIndex.parent();
   int aSize = aModel->rowCount(aParent);
   for (int i = 0; i < aSize; i++) {
@@ -227,27 +228,34 @@ void XGUI_DataTree::processHistoryChange(const QModelIndex& theIndex)
     update(aModel->index(i, 1, aParent));
     update(aModel->index(i, 2, aParent));
   }
+  XGUI_ObjectsBrowser* aObjBrowser = qobject_cast<XGUI_ObjectsBrowser*>(parent());
+  aObjBrowser->workshop()->displayer()->updateViewer();
 }
 
 void XGUI_DataTree::processEyeClick(const QModelIndex& theIndex)
 {
+  XGUI_ObjectsBrowser* aObjBrowser = qobject_cast<XGUI_ObjectsBrowser*>(parent());
   XGUI_DataModel* aModel = dataModel();
   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);
+    std::set<ObjectPtr> anObjects;
+    anObjects.insert(aObj);
+
+    bool hasHiddenState = aModel->hasHiddenState(theIndex);
+    if (aObjBrowser && hasHiddenState && !aObjBrowser->workshop()->prepareForDisplay(anObjects))
+      return;
+    if (hasHiddenState) { // #issue 2335(hide all faces then show solid problem)
+      if (aObj->isDisplayed())
+        aObj->setDisplayed(false);
+      aObj->setDisplayed(true);
     }
+    else
+      aObj->setDisplayed(!aObj->isDisplayed());
+
     // Update list of selected objects because this event happens after
     // selection event in object browser
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+    update(theIndex);
     if (aObjBrowser) {
       aObjBrowser->onSelectionChanged();
     }
@@ -409,7 +417,7 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent, XGUI_Workshop* theW
   aLabelWgt->setPalette(aPalet);
 
   myDocModel = new XGUI_DataModel(this);
-  connect(myDocModel, SIGNAL(modelAboutToBeReset()), SLOT(onBeforeReset()));
+  connect(myDocModel, SIGNAL(beforeTreeRebuild()), SLOT(onBeforeReset()));
   connect(myDocModel, SIGNAL(treeRebuilt()), SLOT(onAfterModelReset()));
 
   connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
@@ -421,9 +429,10 @@ XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
 {
 }
 
-void XGUI_ObjectsBrowser::setXMLReader(Config_DataModelReader* theReader)
+void XGUI_ObjectsBrowser::initialize(ModuleBase_ITreeNode* theRoot)
 {
-  myDocModel->setXMLReader(theReader);
+  //myDocModel->setXMLReader(theReader);
+  myDocModel->setRoot(theRoot);
   myTreeView->setModel(myDocModel);
 
   // It has to be done after setting of model
@@ -483,10 +492,12 @@ void XGUI_ObjectsBrowser::onEditItem()
       // Find index which corresponds the feature
       QModelIndex aIndex;
       foreach(QModelIndex aIdx, selectedIndexes()) {
-        ObjectPtr aFea = dataModel()->object(aIdx);
-        if (dataModel()->object(aIdx)->isSame(anObject)) {
-          aIndex = aIdx;
-          break;
+        if (aIdx.column() == 1) {
+          ObjectPtr aFea = dataModel()->object(aIdx);
+          if (dataModel()->object(aIdx)->isSame(anObject)) {
+            aIndex = aIdx;
+            break;
+          }
         }
       }
       if (aIndex.isValid()) {
@@ -499,16 +510,17 @@ void XGUI_ObjectsBrowser::onEditItem()
 }
 
 //***************************************************
-QModelIndexList XGUI_ObjectsBrowser::expandedItems(const QModelIndex& theParent) const
+QList<ModuleBase_ITreeNode*> XGUI_ObjectsBrowser::expandedItems(const QModelIndex& theParent) const
 {
-  QModelIndexList aIndexes;
+  QList<ModuleBase_ITreeNode*> aIndexes;
   QModelIndex aIndex;
-  for (int i = 0; i < myDocModel->rowCount(theParent); i++) {
+  int aCount = myDocModel->rowCount(theParent);
+  for (int i = 0; i < aCount; i++) {
     aIndex = myDocModel->index(i, 0, theParent);
     if (myDocModel->hasChildren(aIndex)) {
       if (myTreeView->isExpanded(aIndex)) {
-        aIndexes.append(aIndex);
-        QModelIndexList aSubIndexes = expandedItems(aIndex);
+        aIndexes.append((ModuleBase_ITreeNode*)aIndex.internalPointer());
+        QList<ModuleBase_ITreeNode*> aSubIndexes = expandedItems(aIndex);
         if (!aSubIndexes.isEmpty())
           aIndexes.append(aSubIndexes);
       }
@@ -520,6 +532,7 @@ QModelIndexList XGUI_ObjectsBrowser::expandedItems(const QModelIndex& theParent)
 //***************************************************
 void XGUI_ObjectsBrowser::rebuildDataTree()
 {
+  myDocModel->root()->update();
   myDocModel->rebuildDataTree();
   update();
 }
@@ -527,16 +540,74 @@ void XGUI_ObjectsBrowser::rebuildDataTree()
 //***************************************************
 void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects)
 {
-  QList<QModelIndex> theIndexes;
   QItemSelectionModel* aSelectModel = myTreeView->selectionModel();
-  aSelectModel->clear();
+  QModelIndexList aIndexes = aSelectModel->selectedIndexes();
+  if (theObjects.size() == 0) {
+    bool aIsBlock = aSelectModel->blockSignals(true);
+    aSelectModel->clear();
+    aSelectModel->blockSignals(aIsBlock);
+    foreach(QModelIndex aIdx, aIndexes) {
+      myTreeView->update(aIdx);
+    }
+    return;
+  }
 
-  foreach(ObjectPtr aFeature, theObjects)
-  {
-    QModelIndex aIndex = myDocModel->objectIndex(aFeature);
-    if (aIndex.isValid()) {
-      aSelectModel->select(aIndex, QItemSelectionModel::Select);
+  ObjectPtr aObject;
+  QModelIndexList aUnselect;
+  QObjectPtrList aToSelect = theObjects;
+  QHash<qint64, ObjectPtr> aNotChanged;
+  foreach(QModelIndex aIdx, aIndexes) {
+    aObject = myDocModel->object(aIdx);
+    if (aObject.get()) {
+      if (aToSelect.contains(aObject)) {
+        aNotChanged.insert((qint64)aObject.get(), aObject);
+      } else {
+        aUnselect.append(aIdx);
+      }
+    }
+    else {
+      aUnselect.append(aIdx);
+    }
+  }
+
+  foreach(ObjectPtr aObj, aNotChanged)
+    aToSelect.removeAll(aObj);
+
+  bool aIsBlock = aSelectModel->blockSignals(true);
+  foreach(QModelIndex aIdx, aUnselect) {
+    aSelectModel->select(aIdx, QItemSelectionModel::Deselect);
+    myTreeView->update(aIdx);
+  }
+
+  QModelIndex aIndex0, aIndex1, aIndex2, aCurrent;
+  foreach(ObjectPtr aFeature, aToSelect) {
+    aIndex1 = myDocModel->objectIndex(aFeature, 1);
+    if (aIndex1.isValid()) {
+      if (!aCurrent.isValid())
+        aCurrent = aIndex1;
+      aIndex0 = myDocModel->objectIndex(aFeature, 0);
+      aIndex2 = myDocModel->objectIndex(aFeature, 2);
+      aSelectModel->select(aIndex1, QItemSelectionModel::Select | QItemSelectionModel::Rows);
+      myTreeView->update(aIndex0);
+      myTreeView->update(aIndex1);
+      myTreeView->update(aIndex2);
+    }
+  }
+  aSelectModel->setCurrentIndex(aCurrent, QItemSelectionModel::NoUpdate);
+  aSelectModel->blockSignals(aIsBlock);
+}
+
+//***************************************************
+void XGUI_ObjectsBrowser::ensureVisible(const ObjectPtr theObject)
+{
+  QModelIndex aIndex = myDocModel->objectIndex(theObject);
+  if (aIndex.isValid())  {
+    QModelIndex aParent = aIndex.parent();
+    while (aParent.isValid()) {
+      myTreeView->expand(aParent);
+      aParent = aParent.parent();
     }
+    myTreeView->scrollTo(aIndex);
   }
 }
 
@@ -547,8 +618,8 @@ void XGUI_ObjectsBrowser::clearContent()
 }
 
 //***************************************************
-void XGUI_ObjectsBrowser::onSelectionChanged(const QItemSelection& theSelected,
-                                       const QItemSelection& theDeselected)
+void XGUI_ObjectsBrowser::onSelectionChanged(const QItemSelection& /*theSelected*/,
+                                             const QItemSelection& /*theDeselected*/)
 {
   onSelectionChanged();
 }
@@ -565,14 +636,14 @@ QObjectPtrList XGUI_ObjectsBrowser::selectedObjects(QModelIndexList* theIndexes)
   QObjectPtrList aList;
   QModelIndexList aIndexes = selectedIndexes();
   XGUI_DataModel* aModel = dataModel();
-  QModelIndexList::const_iterator aIt;
-  for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
-    if ((*aIt).column() == 1) {
-      ObjectPtr aObject = aModel->object(*aIt);
+
+  foreach(QModelIndex aIdx, aIndexes) {
+    if (aIdx.column() == 1) {
+      ObjectPtr aObject = aModel->object(aIdx);
       if (aObject) {
         aList.append(aObject);
         if (theIndexes)
-          theIndexes->append(*aIt);
+          theIndexes->append(aIdx);
       }
     }
   }
@@ -586,9 +657,16 @@ void XGUI_ObjectsBrowser::onBeforeReset()
 
 void XGUI_ObjectsBrowser::onAfterModelReset()
 {
-  foreach(QModelIndex aIndex, myExpandedItems) {
-    myTreeView->setExpanded(aIndex, true);
+  XGUI_DataModel* aModel = myTreeView->dataModel();
+  QModelIndex aIndex;
+  foreach(ModuleBase_ITreeNode* aNode, myExpandedItems) {
+    if (aModel->hasNode(aNode)) {
+      aIndex = aModel->getIndex(aNode, 0);
+      if (aIndex.isValid() && (myTreeView->dataModel()->hasIndex(aIndex)))
+        myTreeView->setExpanded(aIndex, true);
+    }
   }
+  myExpandedItems.clear();
 }
 
 std::list<bool> XGUI_ObjectsBrowser::getStateForDoc(DocumentPtr theDoc) const
@@ -598,7 +676,7 @@ std::list<bool> XGUI_ObjectsBrowser::getStateForDoc(DocumentPtr theDoc) const
   QModelIndex aRootIdx = aModel->documentRootIndex(theDoc);
   int aNbChild = aModel->rowCount(aRootIdx);
   for (int i = 0; i < aNbChild; i++) {
-    QModelIndex aIdx = aModel->index(i, 1, aRootIdx);
+    QModelIndex aIdx = aModel->index(i, 0, aRootIdx);
     aStates.push_back(myTreeView->isExpanded(aIdx));
   }
   return aStates;
@@ -624,11 +702,43 @@ void XGUI_ObjectsBrowser::setStateForDoc(DocumentPtr theDoc, const std::list<boo
 
 void XGUI_ObjectsBrowser::updateAllIndexes(int theColumn, const QModelIndex& theParent)
 {
-  const QAbstractItemModel* aModel = theParent.model();
-  int aNb = aModel->rowCount();
+  int aNb = myDocModel->rowCount(theParent);
   for (int i = 0; i < aNb; i++) {
-    QModelIndex aIdx = theParent.child(i, theColumn);
-    myTreeView->update(aIdx);
-    updateAllIndexes(theColumn, aIdx);
+    QModelIndex aIdx = myDocModel->index(i, theColumn, theParent);
+    if (aIdx.isValid() && myDocModel->hasIndex(aIdx)) {
+      myTreeView->update(aIdx);
+      if (myTreeView->isExpanded(aIdx))
+        updateAllIndexes(theColumn, aIdx);
+    }
+  }
+}
+
+QMap<ObjectPtr, bool> XGUI_ObjectsBrowser::getFoldersState(DocumentPtr theDoc) const
+{
+  QMap<ObjectPtr, bool> aMap;
+
+  int aNb = theDoc->size(ModelAPI_Folder::group());
+  ObjectPtr aObj;
+  for (int i = 0; i < aNb; i++) {
+    aObj = theDoc->object(ModelAPI_Folder::group(), i);
+    QModelIndex aIdx = myDocModel->objectIndex(aObj, 0);
+    aMap[aObj] = myTreeView->isExpanded(aIdx);
   }
+  return aMap;
+}
+
+void XGUI_ObjectsBrowser::setFoldersState(const QMap<ObjectPtr, bool>& theStates)
+{
+  QMap<ObjectPtr, bool>::const_iterator aIt;
+  for (aIt = theStates.constBegin(); aIt != theStates.constEnd(); aIt++) {
+    QModelIndex aIdx = myDocModel->objectIndex(aIt.key(), 0);
+    myTreeView->setExpanded(aIdx, aIt.value());
+  }
+}
+
+
+void XGUI_ObjectsBrowser::resizeEvent(QResizeEvent* theEvent)
+{
+  QWidget::resizeEvent(theEvent);
+  emit sizeChanged();
 }