1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "OperationGUI_ExtractionDlg.h"
26 #include <GeometryGUI.h>
28 #include <LightApp_SelectionMgr.h>
29 #include <SalomeApp_Application.h>
30 #include <SalomeApp_Tools.h>
31 #include <SUIT_ResourceMgr.h>
32 #include <SUIT_Session.h>
34 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopoDS_Iterator.hxx>
38 #include <TopTools_IndexedMapOfShape.hxx>
39 #include <TopTools_MapOfShape.hxx>
42 #include <QGridLayout>
44 #include <QHBoxLayout>
47 #include <QListWidget>
48 #include <QPushButton>
49 #include <QRadioButton>
50 #include <QTreeWidget>
51 #include <QVBoxLayout>
54 #if QT_VERSION >= 0x050300
55 #include <QSignalBlocker>
58 * This class is named as QT class as it is introduced since Qt 5.3.
59 * It should not be compiled when Salome is ported on Qt 5.3.
64 QSignalBlocker(QObject *object)
66 myIsBlocked (object && object->signalsBlocked()) {
68 myObject->blockSignals(true);
74 myObject->blockSignals(myIsBlocked);
79 QObject *myObject; ///< Blocked object.
80 bool myIsBlocked; ///< Initial blocked state.
85 #define ID_ROLE Qt::DisplayRole
86 #define TYPE_ROLE Qt::UserRole
88 static const char* const TMP_STR = "TEMP";
90 static const char* const SINGLE_SHAPE_TYPE_TR_CODES [] = {
101 static const char* const PLURAL_SHAPE_TYPE_TR_CODES [] = {
102 "GEOM_COMPOUND", // Not used
114 * This static function creates a new list widget item with given ID and
117 * \param theID the item ID.
118 * \param theListWidget the list widget.
119 * \return the created list widget item.
121 static QListWidgetItem *addNewItem(const int theID,
122 QListWidget *theListWidget)
124 QListWidgetItem *aResult = new QListWidgetItem;
126 aResult->setData(ID_ROLE, theID);
127 theListWidget->addItem(aResult);
133 * This static function creates a new tree widget item as a child of the input
134 * one with given ID and returns it.
136 * \param theID the item ID.
137 * \param theParentItem the parent item.
138 * \return the created tree widget item.
140 static QTreeWidgetItem *addChildItem(const int theID,
141 QTreeWidgetItem *theParentItem)
143 QTreeWidgetItem *aResult = new QTreeWidgetItem;
145 aResult->setData(0, ID_ROLE, theID);
146 theParentItem->addChild(aResult);
152 * This static function returns the maximal shape type of sub-shapes stored in
153 * the input compound. If it is not a compound, it returns TopAbs_SHAPE.
155 * \param theCompound the compound.
156 * \return the maximal shape type of sub-shapes stored in the input compound.
158 static TopAbs_ShapeEnum GetMaxShapeTypeInComp(const TopoDS_Shape &theCompound)
160 TopAbs_ShapeEnum aResult = TopAbs_SHAPE;
162 if (theCompound.IsNull() || theCompound.ShapeType() != TopAbs_COMPOUND) {
166 TopoDS_Iterator anIt(theCompound, Standard_False, Standard_False);
168 for (; anIt.More(); anIt.Next()) {
169 const TopoDS_Shape &aSubShape = anIt.Value();
171 if (aSubShape.IsNull()) {
175 // Get the sub-shape type.
176 TopAbs_ShapeEnum aSubType = aSubShape.ShapeType();
178 if (aSubType == TopAbs_COMPOUND) {
179 aSubType = GetMaxShapeTypeInComp(aSubShape);
182 if (aSubType == TopAbs_SHAPE) {
186 if (aResult == TopAbs_SHAPE) {
187 // This is an initialization.
189 } else if (aResult > aSubType) {
197 //=================================================================================
198 // class : OperationGUI_ExtractionDlg()
200 //=================================================================================
201 OperationGUI_ExtractionDlg::OperationGUI_ExtractionDlg
202 (GeometryGUI* GUI, QWidget* parent)
203 : GEOMBase_Skeleton (GUI, parent, false),
206 mySubShTypeCompo (0),
213 myIsHiddenMain (false)
215 QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap(
216 "GEOM", tr("ICON_DLG_EXTRACTION")));
217 QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap(
218 "GEOM", tr("ICON_SELECT")));
220 setWindowTitle(tr("GEOM_EXTRACT_TITLE"));
222 /***************************************************************/
224 mainFrame()->GroupConstructors->setTitle(tr("GEOM_EXTRACT_TYPE"));
225 mainFrame()->RadioButton1->setIcon( image0 );
226 mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose);
227 mainFrame()->RadioButton2->close();
228 mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
229 mainFrame()->RadioButton3->close();
231 // Create an input group.
232 QGroupBox *anInputGrp = new QGroupBox(tr("GEOM_EXTRACT_INPUT_PARAMS"), centralWidget());
233 QGridLayout *anInputLayout = new QGridLayout(anInputGrp);
234 QHBoxLayout *aShapeLayout = new QHBoxLayout(anInputGrp);
235 QVBoxLayout *aViewBtnsLayout = new QVBoxLayout(anInputGrp);
236 QVBoxLayout *aMoveBtnsLayout = new QVBoxLayout(anInputGrp);
237 QLabel *aMainObjLbl = new QLabel(tr("GEOM_MAIN_OBJECT"), anInputGrp);
238 QLabel *aSubShTypeLbl = new QLabel(tr("GEOM_EXTRACT_SUB_SHAPE_TYPE"), anInputGrp);
239 QLabel *aFilteredLbl = new QLabel(tr("GEOM_EXTRACT_FILTERED_SHAPES"), anInputGrp);
240 QLabel *anExtractedLbl = new QLabel(tr("GEOM_EXTRACT_SHAPES_TO_EXTRACT"), anInputGrp);
241 QPushButton *aShowOnlySelBtn = new QPushButton(tr("SHOW_ONLY_SELECTED"), anInputGrp);
242 QPushButton *aHideSelBtn = new QPushButton(tr("HIDE_SELECTED"), anInputGrp);
243 QPushButton *aShowAllBtn = new QPushButton(tr("SHOW_ALL_SUB_SHAPES"), anInputGrp);
244 QPushButton *anAddBtn = new QPushButton(">>", anInputGrp);
245 QPushButton *aRemoveBtn = new QPushButton("<<", anInputGrp);
247 myRebuildBtn = new QPushButton(tr("GEOM_EXTRACT_REBUILD"), anInputGrp);
248 mySelBtn = new QPushButton(anInputGrp);
249 myMainShapeEdit = new QLineEdit(anInputGrp);
250 mySubShTypeCompo = new QComboBox(anInputGrp);
251 myFilteredList = new QListWidget(anInputGrp);
252 myExtractedTree = new QTreeWidget(anInputGrp);
253 mySelBtn->setIcon(image1);
254 myMainShapeEdit->setReadOnly(true);
256 aShapeLayout->addWidget(mySelBtn);
257 aShapeLayout->addWidget(myMainShapeEdit);
259 aViewBtnsLayout->addStretch();
260 aViewBtnsLayout->addWidget(aShowOnlySelBtn);
261 aViewBtnsLayout->addWidget(aHideSelBtn);
262 aViewBtnsLayout->addWidget(aShowAllBtn);
263 aViewBtnsLayout->addStretch();
265 aMoveBtnsLayout->addStretch();
266 aMoveBtnsLayout->addWidget(anAddBtn);
267 aMoveBtnsLayout->addWidget(aRemoveBtn);
268 aMoveBtnsLayout->addStretch();
270 anInputLayout->setSpacing(6);
271 anInputLayout->setContentsMargins(9, 9, 9, 9);
272 anInputLayout->addWidget(aMainObjLbl, 0, 0);
273 anInputLayout->addLayout(aShapeLayout, 0, 1, 1, 3);
274 anInputLayout->addWidget(aSubShTypeLbl, 1, 0);
275 anInputLayout->addWidget(mySubShTypeCompo, 1, 1, 1, 3);
276 anInputLayout->addWidget(aFilteredLbl, 2, 1);
277 anInputLayout->addWidget(anExtractedLbl, 2, 3);
278 anInputLayout->addLayout(aViewBtnsLayout, 3, 0);
279 anInputLayout->addWidget(myFilteredList, 3, 1);
280 anInputLayout->addLayout(aMoveBtnsLayout, 3, 2);
281 anInputLayout->addWidget(myExtractedTree, 3, 3);
282 anInputLayout->addWidget(myRebuildBtn, 4, 0, 1, 4);
284 // Create a statistics group.
285 QGroupBox *aStatGrp = new QGroupBox(tr("GEOM_EXTRACT_STATISTICS"), centralWidget());
286 QGridLayout *aStatLayout = new QGridLayout(aStatGrp);
287 QLabel *aRemovedLbl = new QLabel(tr("GEOM_EXTRACT_REMOVED"), aStatGrp);
288 QLabel *aModifiedLbl = new QLabel(tr("GEOM_EXTRACT_MODIFIED"), aStatGrp);
289 QLabel *anAddedLbl = new QLabel(tr("GEOM_EXTRACT_ADDED"), aStatGrp);
291 myRemovedList = new QListWidget(aStatGrp);
292 myModifiedList = new QListWidget(aStatGrp);
293 myAddedList = new QListWidget(aStatGrp);
295 aStatLayout->setSpacing(6);
296 aStatLayout->setContentsMargins(9, 9, 9, 9);
297 aStatLayout->addWidget(aRemovedLbl, 0, 0);
298 aStatLayout->addWidget(aModifiedLbl, 0, 1);
299 aStatLayout->addWidget(anAddedLbl, 0, 2);
300 aStatLayout->addWidget(myRemovedList, 1, 0);
301 aStatLayout->addWidget(myModifiedList, 1, 1);
302 aStatLayout->addWidget(myAddedList, 1, 2);
304 // Create a main layout.
305 QVBoxLayout* aLayout = new QVBoxLayout(centralWidget());
307 aLayout->setMargin(0);
308 aLayout->setSpacing(6);
309 aLayout->addWidget(anInputGrp);
310 aLayout->addWidget(aStatGrp);
312 // signals and slots connections
313 connect(anAddBtn, SIGNAL(clicked()), this, SLOT(onAddExtracted()));
314 connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemoveExtracted()));
315 connect(aShowOnlySelBtn, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
316 connect(aHideSelBtn, SIGNAL(clicked()), this, SLOT(hideSelected()));
317 connect(aShowAllBtn, SIGNAL(clicked()), this, SLOT(showAllSelected()));
319 /***************************************************************/
320 myHelpFileName = "extract_and_rebuild_page.html";
328 //=================================================================================
329 // function : ~OperationGUI_ExtractionDlg()
330 // purpose : Destroys the object and frees any allocated resources
331 //=================================================================================
332 OperationGUI_ExtractionDlg::~OperationGUI_ExtractionDlg()
337 //=================================================================================
340 //=================================================================================
341 void OperationGUI_ExtractionDlg::Init()
343 mySelBtn->setCheckable(true);
344 mySelBtn->setChecked(true);
345 myFilteredList->setSelectionMode(QAbstractItemView::ExtendedSelection);
346 myFilteredList->setSortingEnabled(true);
347 myExtractedTree->setHeaderHidden(true);
348 myExtractedTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
349 myExtractedTree->setColumnCount(1);
350 myRebuildBtn->setEnabled(false);
351 myRemovedList->setSelectionMode(QAbstractItemView::NoSelection);
352 myModifiedList->setSelectionMode(QAbstractItemView::NoSelection);
353 myAddedList->setSelectionMode(QAbstractItemView::NoSelection);
355 // Fill in the extracted tree with initial elements.
356 myTopItems[0] = 0; // No need to create a item for compound.
360 for (i = 1; i < 8; i++) {
361 myTopItems[i] = new QTreeWidgetItem;
362 myTopItems[i]->setText(0, tr(PLURAL_SHAPE_TYPE_TR_CODES[i]));
363 myTopItems[i]->setData(0, TYPE_ROLE, i);
365 myExtractedTree->addTopLevelItem(myTopItems[i]);
366 myTopItems[i]->setHidden(true);
369 // signals and slots connections
370 connect(mySelBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
371 connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
372 connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
373 connect(mySubShTypeCompo, SIGNAL(currentIndexChanged(int)),
374 this, SLOT(onShapeTypeChanged()));
375 connect(myRebuildBtn, SIGNAL(clicked()), this, SLOT(onRebuild()));
376 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
377 this, SLOT(SelectionIntoArgument()));
378 connect(myFilteredList, SIGNAL(itemSelectionChanged()),
379 this, SLOT(onListSelectionChanged()));
380 connect(myExtractedTree, SIGNAL(itemSelectionChanged()),
381 this, SLOT(onListSelectionChanged()));
383 initName(tr("GEOM_EXTRACT_NAME"));
386 SelectionIntoArgument();
389 //=================================================================================
390 // function : updateSubShTypeCompo()
392 //=================================================================================
393 bool OperationGUI_ExtractionDlg::updateSubShTypeCompo()
396 int anIStart = TopAbs_COMPOUND;
397 const int anIEnd = TopAbs_VERTEX;
400 if (GEOMBase::GetShape(myObj, aShape)) {
401 const TopAbs_ShapeEnum aType = aShape.ShapeType();
403 if (aType == TopAbs_COMPOUND) {
404 anIStart = GetMaxShapeTypeInComp(aShape);
405 isValid = anIStart != TopAbs_SHAPE;
407 anIStart = aType + 1;
411 QSignalBlocker aBlocker(mySubShTypeCompo);
412 mySubShTypeCompo->clear();
417 for (i = anIStart; i <= anIEnd; i++) {
418 mySubShTypeCompo->addItem(tr(SINGLE_SHAPE_TYPE_TR_CODES[i]), i);
421 updateFilteredList();
427 //=================================================================================
428 // function : updateFilteredList()
430 //=================================================================================
431 void OperationGUI_ExtractionDlg::updateFilteredList()
434 QSignalBlocker aBlocker(myFilteredList);
436 myFilteredList->clear();
438 if (GEOMBase::GetShape(myObj, aShape)) {
439 const TopAbs_ShapeEnum aType = (TopAbs_ShapeEnum)
440 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
441 TopExp_Explorer anExp(aShape, aType);
444 TopTools_MapOfShape aMapFence;
446 for (; anExp.More(); anExp.Next()) {
447 const TopoDS_Shape &aSubShape = anExp.Current();
449 if (!aSubShape.IsNull() && aMapFence.Add(aSubShape)) {
450 int anIndex = myIndices.FindIndex(aSubShape);
452 if (!myMapExtractedIDs.Contains(anIndex)) {
453 addNewItem(anIndex, myFilteredList);
461 //=================================================================================
462 // function : resetBuildData()
464 //=================================================================================
465 void OperationGUI_ExtractionDlg::resetBuildData(const bool isEnableBuild)
467 // Clear result data.
468 myRemovedList->clear();
469 myModifiedList->clear();
470 myAddedList->clear();
471 myRebuildBtn->setEnabled(isEnableBuild);
474 //=================================================================================
475 // function : isEmptyExtracted()
477 //=================================================================================
478 bool OperationGUI_ExtractionDlg::isEmptyExtracted()
483 // Check if there are sub-shapes to be extracted.
484 for (i = 1; i < 8; i++) {
485 if (!myTopItems[i]->isHidden()) {
495 //=================================================================================
496 // function : selectMainShape
498 //=================================================================================
499 void OperationGUI_ExtractionDlg::selectMainShape()
501 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
502 SALOME_ListIO aSelList;
504 aSelMgr->selectedObjects(aSelList);
506 if (aSelList.Extent() == 1) {
507 GEOM::GEOM_Object_var aSelObject =
508 GEOMBase::ConvertIOinGEOMObject(aSelList.First());
509 TopoDS_Shape aSelShape;
511 if (GEOMBase::GetShape(aSelObject, aSelShape)) {
512 const TopAbs_ShapeEnum aType = aSelShape.ShapeType();
515 if (aType != TopAbs_VERTEX) {
518 // Initialize map of indices. Note that myIndices should be empty.
519 TopExp::MapShapes(aSelShape, myIndices);
524 if (!updateSubShTypeCompo()) {
525 // Invalid selected object.
526 myObj = GEOM::GEOM_Object::_nil();
529 if (!CORBA::is_nil(myObj)) {
530 mySelBtn->setChecked(false);
531 myMainShapeEdit->setEnabled(false);
532 myMainShapeEdit->setText(GEOMBase::GetName(myObj));
534 // Hide the main object from the viewer.
535 SALOME_View* aView = GEOM_Displayer::GetActiveView();
538 CORBA::String_var aMainEntry = myObj->GetStudyEntry();
539 Handle(SALOME_InteractiveObject) anIO = createIO(aMainEntry.in());
541 if (aView->isVisible(anIO)) {
542 GEOM_Displayer *aDisplayer = getDisplayer();
544 aDisplayer->Erase(myObj, false, true);
545 myIsHiddenMain = true;
551 //=================================================================================
552 // function : selectSubShapes
554 //=================================================================================
555 void OperationGUI_ExtractionDlg::selectSubShapes()
557 QSignalBlocker aBlocker(myFilteredList);
559 // Clear current selection.
560 myFilteredList->clearSelection();
562 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
563 SALOME_ListIO aSelList;
565 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
567 aSelMgr->selectedObjects(aSelList);
569 // try to find out and process the global selection
570 // (of not published objects and of published sub-shapes)
571 SALOME_ListIteratorOfListIO anIter(aSelList);
573 for (; anIter.More(); anIter.Next()) {
574 Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
575 QString anEntry = anIObj->getEntry();
576 QStringList aParts = anEntry.split("_");
577 int aSubShapeId = -1;
579 if (!aParts.isEmpty()) {
580 if (aParts.first() == TMP_STR) {
582 const int anIndex = aParts.last().toInt(&isOk);
584 if (isOk && anIndex > 0) {
585 // This is a sub-shape.
586 aSubShapeId = anIndex;
591 if (aSubShapeId < 0) {
592 // This is a published shape.
593 GEOM::GEOM_Object_var aSelObject =
594 GEOMBase::ConvertIOinGEOMObject(anIObj);
595 TopoDS_Shape aSelShape;
597 if (GEOMBase::GetShape(aSelObject, aSelShape)) {
599 if (aSelShape.ShapeType() == aCurType) {
600 const int anIndex = myIndices.FindIndex(aSelShape);
603 // This is a sub-shape. Select it in the filtered list.
604 aSubShapeId = anIndex;
610 // Select a list widget item by Id.
611 if (aSubShapeId > 0) {
612 QString anIdText = QString("%1").arg(aSubShapeId);
613 QList<QListWidgetItem *> aFound =
614 myFilteredList->findItems(anIdText, Qt::MatchExactly);
616 foreach (QListWidgetItem *anItem, aFound) {
617 anItem->setSelected(true);
623 //=================================================================================
624 // function : ClickOnOk()
626 //=================================================================================
627 void OperationGUI_ExtractionDlg::ClickOnOk()
629 if (ClickOnApply()) {
634 //=================================================================================
635 // function : ClickOnApply()
637 //=================================================================================
638 bool OperationGUI_ExtractionDlg::ClickOnApply()
649 //=================================================================================
650 // function : onShapeTypeChanged
652 //=================================================================================
653 void OperationGUI_ExtractionDlg::onShapeTypeChanged()
655 updateFilteredList();
659 //=================================================================================
660 // function : onAddExtracted
662 //=================================================================================
663 void OperationGUI_ExtractionDlg::onAddExtracted()
665 QList<QListWidgetItem *> aListSelected = myFilteredList->selectedItems();
667 if (aListSelected.empty()) {
671 const int aShapeType =
672 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
673 bool isTreeUpdated = false;
675 foreach (QListWidgetItem *anItem, aListSelected) {
676 const int anIndex = anItem->data(ID_ROLE).toInt();
678 if (myMapExtractedIDs.Add(anIndex)) {
679 addChildItem(anIndex, myTopItems[aShapeType]);
680 isTreeUpdated = true;
683 // Remove anItem from the list.
684 myFilteredList->removeItemWidget(anItem);
689 myTopItems[aShapeType]->sortChildren(0, Qt::AscendingOrder);
692 resetBuildData(true);
695 myFilteredList->clearSelection();
696 myTopItems[aShapeType]->setHidden(false);
699 //=================================================================================
700 // function : onRemoveExtracted
702 //=================================================================================
703 void OperationGUI_ExtractionDlg::onRemoveExtracted()
705 QList<QTreeWidgetItem *> aListSelected = myExtractedTree->selectedItems();
707 if (aListSelected.empty()) {
711 const int aShapeType =
712 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
713 QSet<QTreeWidgetItem *> aSetFence;
714 bool isTreeUpdated = false;
716 foreach (QTreeWidgetItem *anItem, aListSelected) {
717 if (!aSetFence.contains(anItem)) {
718 aSetFence.insert(anItem);
720 QTreeWidgetItem *aParent = anItem->parent();
723 const int anIndex = anItem->data(0, ID_ROLE).toInt();
724 // This is a ID item. Remove the ID from myMapExtractedIDs.
725 if (myMapExtractedIDs.Remove(anIndex)) {
726 // The item is not removed yet. Get parent index.
727 const int aParentIndex = aParent->data(0, TYPE_ROLE).toInt();
729 if (aShapeType == aParentIndex) {
730 // Create an item in the filtered list.
731 addNewItem(anIndex, myFilteredList);
734 aParent->removeChild(anItem);
736 isTreeUpdated = true;
738 // Hilde an empty parent item.
739 if (aParent->childCount() == 0) {
740 aParent->setHidden(true);
744 // This is a top level item. Remove all its children.
745 QList<QTreeWidgetItem *> aChildItems = anItem->takeChildren();
746 const int anIndex = anItem->data(0, TYPE_ROLE).toInt();
748 // Remove IDs from myMapExtractedIDs.
749 foreach (QTreeWidgetItem *aChild, aChildItems) {
750 if (!aSetFence.contains(aChild)) {
751 aSetFence.insert(aChild);
753 const int aChildIndex = aChild->data(0, ID_ROLE).toInt();
755 if (myMapExtractedIDs.Remove(aChildIndex)) {
756 if (aShapeType == anIndex) {
757 // Create items in the filtered list.
758 addNewItem(aChildIndex, myFilteredList);
762 isTreeUpdated = true;
767 // Hilde an empty item.
768 anItem->setHidden(true);
773 myExtractedTree->clearSelection();
777 const bool isEnableRebuild = !isEmptyExtracted();
779 resetBuildData(isEnableRebuild);
783 //=================================================================================
784 // function : onListSelectionChanged
786 //=================================================================================
787 void OperationGUI_ExtractionDlg::onListSelectionChanged()
789 SALOME_ListIO anIOList;
790 QList<QListWidgetItem *> aListSel = myFilteredList->selectedItems();
791 QList<QTreeWidgetItem *> aTreeSel = myExtractedTree->selectedItems();
793 // Collect selected items from myFilteredList
794 foreach (QListWidgetItem *anItem, aListSel) {
795 const int anIndex = anItem->data(ID_ROLE).toInt();
797 if (myMapDisplayedIDs.Contains(anIndex)) {
798 // Collect only displayed sub-shapes for selection in the viewer.
799 QString anEntry = getSubShapeEntry(anIndex);
800 Handle(SALOME_InteractiveObject) anIO =
801 createIO(anEntry.toLatin1().data());
803 anIOList.Append(anIO);
807 // Collect selected items from myExtractedTree
808 foreach (QTreeWidgetItem *anItem, aTreeSel) {
809 if (anItem->parent()) {
810 // This is a ID item.
811 const int anIndex = anItem->data(0, ID_ROLE).toInt();
813 if (myMapDisplayedIDs.Contains(anIndex)) {
814 // Collect only displayed sub-shapes for selection in the viewer.
815 QString anEntry = getSubShapeEntry(anIndex);
816 Handle(SALOME_InteractiveObject) anIO =
817 createIO(anEntry.toLatin1().data());
819 anIOList.Append(anIO);
824 // Select object in viewer.
825 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
827 aSelMgr->setSelectedObjects(anIOList);
830 //=================================================================================
831 // function : showOnlySelected
833 //=================================================================================
834 void OperationGUI_ExtractionDlg::showOnlySelected()
836 TColStd_MapOfInteger aMapIDsSelected;
837 TColStd_MapOfInteger aMapIDsToDisplay;
838 const int aNbItems = myFilteredList->count();
840 QSet<QString> aSelEntry;
842 // Get sub-shape IDs to be displayed.
843 for (i = 0; i < aNbItems; ++i) {
844 QListWidgetItem *anItem = myFilteredList->item(i);
845 const int anIndex = anItem->data(ID_ROLE).toInt();
847 if (anItem->isSelected()) {
848 aMapIDsSelected.Add(anIndex);
849 aSelEntry.insert(getSubShapeEntry(anIndex));
851 if (!myMapDisplayedIDs.Contains(anIndex)) {
852 aMapIDsToDisplay.Add(anIndex);
857 // Get sub-shape IDs to be erased.
858 TColStd_MapOfInteger aMapIDsToHide;
859 TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs);
861 for (; anIter.More(); anIter.Next()) {
862 const int anIndex = anIter.Key();
864 if (!aMapIDsSelected.Contains(anIndex)) {
865 aMapIDsToHide.Add(anIndex);
869 // Display sub-shapes.
870 for (anIter.Initialize(aMapIDsToDisplay); anIter.More(); anIter.Next()) {
871 displaySubShape(anIter.Key());
875 for (anIter.Initialize(aMapIDsToHide); anIter.More(); anIter.Next()) {
876 eraseSubShape(anIter.Key());
879 // Hide all objects except already displayed sub-shapes.
880 SALOME_ListIO aDisplayed;
881 SALOME_View *aView = GEOM_Displayer::GetActiveView();
884 aView->GetVisible(aDisplayed);
887 SALOME_ListIteratorOfListIO aDispIt(aDisplayed);
888 GEOM_Displayer *aDisplayer = getDisplayer();
890 for (; aDispIt.More(); aDispIt.Next()) {
891 Handle(SALOME_InteractiveObject) anIO = aDispIt.Value();
893 if (!aSelEntry.contains(anIO->getEntry())) {
894 aDisplayer->Erase(anIO, false, false);
898 onListSelectionChanged();
899 aDisplayer->UpdateViewer();
902 //=================================================================================
903 // function : hideSelected
905 //=================================================================================
906 void OperationGUI_ExtractionDlg::hideSelected()
908 QList<QListWidgetItem *> aListSelected = myFilteredList->selectedItems();
910 foreach (QListWidgetItem *anItem, aListSelected) {
911 const int anIndex = anItem->data(ID_ROLE).toInt();
913 eraseSubShape(anIndex);
916 getDisplayer()->UpdateViewer();
919 //=================================================================================
920 // function : showAllSelected
922 //=================================================================================
923 void OperationGUI_ExtractionDlg::showAllSelected()
925 const int aNbItems = myFilteredList->count();
928 for (i = 0; i < aNbItems; ++i) {
929 QListWidgetItem *anItem = myFilteredList->item(i);
930 const int anIndex = anItem->data(ID_ROLE).toInt();
932 displaySubShape(anIndex);
935 onListSelectionChanged();
936 getDisplayer()->UpdateViewer();
939 //=================================================================================
940 // function : onRebuild
942 //=================================================================================
943 void OperationGUI_ExtractionDlg::onRebuild()
945 GEOM::GEOM_Object_var aResShape;
946 GEOM::GEOM_IShapesOperations::ExtractionStats aStats;
948 if (!getResult(aResShape.out(), aStats)) {
949 resetBuildData(false);
953 TopoDS_Shape anOldShape;
954 TopoDS_Shape aNewShape;
955 TopTools_IndexedMapOfShape aNewIndices;
957 if (!GEOMBase::GetShape(aResShape, aNewShape)) {
958 resetBuildData(false);
962 TopExp::MapShapes(aNewShape, aNewIndices);
964 const int aNbStat = aStats.length();
967 for (i = 0; i < aNbStat; ++i) {
968 // Compute number of sub-shapes of each type.
969 const int aNbSubShapes = aStats[i].indices.length();
970 int aNbShapes [] = { 0, 0, 0, 0, 0, 0, 0, 0 };
973 TopTools_IndexedMapOfShape *aMapShapes =
974 (aStats[i].type == GEOM::GEOM_IShapesOperations::EST_Added) ?
975 &aNewIndices : &myIndices;
977 for (j = 0; j < aNbSubShapes; ++j) {
978 const int anIndex = aStats[i].indices[j];
980 if (anIndex < 1 || anIndex > aMapShapes->Extent()) {
981 resetBuildData(false);
985 const TopoDS_Shape &aSubShape = aMapShapes->FindKey(anIndex);
987 aNbShapes[aSubShape.ShapeType()]++;
990 // Fill the statistics.
991 QListWidget *aListWidget = 0;
993 switch (aStats[i].type) {
994 case GEOM::GEOM_IShapesOperations::EST_Removed:
995 aListWidget = myRemovedList;
997 case GEOM::GEOM_IShapesOperations::EST_Modified:
998 aListWidget = myModifiedList;
1000 case GEOM::GEOM_IShapesOperations::EST_Added:
1001 aListWidget = myAddedList;
1004 resetBuildData(false);
1008 QStringList aStrList;
1010 for (j = 0; j < 8; ++j) {
1011 if (aNbShapes[j] >= 1) {
1012 const char *aShapeType = aNbShapes[j] == 1 ?
1013 SINGLE_SHAPE_TYPE_TR_CODES[j] : PLURAL_SHAPE_TYPE_TR_CODES[j];
1015 aStrList.append(QString("%1 %2").arg(aNbShapes[j]).arg(tr(aShapeType)));
1019 aListWidget->addItems(aStrList);
1022 myRebuildBtn->setEnabled(false);
1025 //=================================================================================
1026 // function : SelectionIntoArgument
1028 //=================================================================================
1029 void OperationGUI_ExtractionDlg::SelectionIntoArgument()
1031 if (myMainShapeEdit->isEnabled()) {
1032 // Selection of main object
1035 // Selection of filtered shapes
1040 //=================================================================================
1041 // function : SetEditCurrentArgument
1043 //=================================================================================
1044 void OperationGUI_ExtractionDlg::SetEditCurrentArgument()
1046 QSignalBlocker aBlockerList(myFilteredList);
1047 QSignalBlocker aBlockerTree(myExtractedTree);
1050 myObj = GEOM::GEOM_Object::_nil();
1051 myMainShapeEdit->setEnabled(true);
1052 myMainShapeEdit->setText("");
1053 myMainShapeEdit->setFocus();
1055 updateSubShTypeCompo();
1057 myFilteredList->clear();
1058 myRemovedList->clear();
1059 myModifiedList->clear();
1060 myAddedList->clear();
1063 // Clear myExtractedTree.
1066 for (i = 1; i < 8; i++) {
1067 QList<QTreeWidgetItem *> aListItems = myTopItems[i]->takeChildren();
1069 foreach (QTreeWidgetItem *anItem, aListItems) {
1073 myTopItems[i]->setHidden(true);
1076 myExtractedTree->clearSelection();
1078 myMapExtractedIDs.Clear();
1084 //=================================================================================
1085 // function : ActivateThisDialog()
1087 //=================================================================================
1088 void OperationGUI_ExtractionDlg::ActivateThisDialog()
1090 GEOMBase_Skeleton::ActivateThisDialog();
1092 LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr();
1095 connect(aSel, SIGNAL(currentSelectionChanged()),
1096 this, SLOT(SelectionIntoArgument()));
1099 activateSelection();
1102 //=================================================================================
1103 // function : activateSelection
1104 // purpose : activate selection of all shapes
1105 //=================================================================================
1106 void OperationGUI_ExtractionDlg::activateSelection()
1108 globalSelection(GEOM_ALLSHAPES);
1111 //=================================================================================
1112 // function : enterEvent()
1114 //=================================================================================
1115 void OperationGUI_ExtractionDlg::enterEvent(QEvent *)
1117 if (!mainFrame()->GroupConstructors->isEnabled()) {
1118 ActivateThisDialog();
1122 //=================================================================================
1123 // function : getResult
1125 //=================================================================================
1126 bool OperationGUI_ExtractionDlg::getResult
1127 (GEOM::GEOM_Object_ptr &theResult,
1128 GEOM::GEOM_IShapesOperations::ExtractionStats &theStats)
1130 if (myObj->_is_nil()) {
1134 // Get IDs of extracted shapes.
1138 for (i = 1; i < 8; i++) {
1139 aNbShapes += myTopItems[i]->childCount();
1142 if (aNbShapes == 0) {
1146 GEOM::ListOfLong_var aSubShapeIDs = new GEOM::ListOfLong;
1150 aSubShapeIDs->length(aNbShapes);
1152 for (jCur = 0, i = 1; i < 8; ++i) {
1153 aNbShapes = myTopItems[i]->childCount();
1155 for (j = 0; j < aNbShapes; ++j, ++jCur) {
1156 aSubShapeIDs[jCur] = myTopItems[i]->child(j)->data(0, ID_ROLE).toInt();
1160 GEOM::GEOM_IShapesOperations_var anOper =
1161 GEOM::GEOM_IShapesOperations::_narrow(getOperation());
1164 GEOM::GEOM_Object_var anObj;
1165 GEOM::GEOM_IShapesOperations::ExtractionStats_var aStats;
1167 anObj = anOper->MakeExtraction(myObj, aSubShapeIDs, aStats);
1169 if (anOper->IsDone() && aStats->length() > 0) {
1173 if (!CORBA::is_nil(anObj)) {
1174 theResult = anObj._retn();
1177 catch (const SALOME::SALOME_Exception& e) {
1178 SalomeApp_Tools::QtCatchCorbaException(e);
1182 return anOper->IsDone();
1185 //=================================================================================
1186 // function : isValid
1188 //=================================================================================
1189 bool OperationGUI_ExtractionDlg::isValid(QString &)
1191 bool isOk = !myObj->_is_nil() && !isEmptyExtracted();
1196 //=================================================================================
1197 // function : createOperation
1199 //=================================================================================
1200 GEOM::GEOM_IOperations_ptr OperationGUI_ExtractionDlg::createOperation()
1202 return getGeomEngine()->GetIShapesOperations(getStudyId());
1205 //=================================================================================
1206 // function : execute
1208 //=================================================================================
1209 bool OperationGUI_ExtractionDlg::execute(ObjectList &objects)
1211 GEOM::GEOM_Object_var aResShape;
1212 GEOM::GEOM_IShapesOperations::ExtractionStats aStats;
1214 if (!getResult(aResShape.out(), aStats)) {
1218 if (!aResShape->_is_nil()) {
1219 objects.push_back(aResShape._retn());
1225 //=================================================================================
1226 // function : getSubShapeEntry
1228 //=================================================================================
1229 QString OperationGUI_ExtractionDlg::getSubShapeEntry(const int theId)
1231 CORBA::String_var aMainEntry = myObj->GetStudyEntry();
1232 QString anEntry = QString("%1_").arg(TMP_STR) +
1233 aMainEntry.in() + QString("_%1").arg(theId);
1238 //=================================================================================
1239 // function : createIO
1241 //=================================================================================
1242 Handle_SALOME_InteractiveObject OperationGUI_ExtractionDlg::createIO
1243 (const char *theEntry)
1245 Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
1246 (theEntry, "GEOM", "TEMP_IO");
1251 //=================================================================================
1252 // function : displaySubShape
1254 //=================================================================================
1255 void OperationGUI_ExtractionDlg::displaySubShape(const int theId)
1257 if (theId < 1 || theId > myIndices.Extent()) {
1261 // Create a presentation
1262 const TopoDS_Shape &aSubShape = myIndices.FindKey(theId);
1263 QString anEntry = getSubShapeEntry(theId);
1264 SALOME_View *aView = GEOM_Displayer::GetActiveView();
1265 GEOM_Displayer *aDisplayer = getDisplayer();
1266 SALOME_Prs *aPrs = aDisplayer->buildSubshapePresentation
1267 (aSubShape, anEntry, aView);
1271 aView->Display(aDisplayer, aPrs);
1276 myMapDisplayedIDs.Add(theId);
1280 //=================================================================================
1281 // function : eraseSubShape
1283 //=================================================================================
1284 void OperationGUI_ExtractionDlg::eraseSubShape(const int theId)
1286 QString anEntry = getSubShapeEntry(theId);
1287 Handle(SALOME_InteractiveObject) anIO =
1288 createIO(anEntry.toLatin1().data());
1290 getDisplayer()->Erase(anIO, false, false);
1291 myMapDisplayedIDs.Remove(theId);
1294 //=================================================================================
1295 // function : eraseAll
1297 //=================================================================================
1298 void OperationGUI_ExtractionDlg::eraseAll()
1300 TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs);
1301 TColStd_ListOfInteger aDisplayedIDs;
1303 for (; anIter.More(); anIter.Next()) {
1304 aDisplayedIDs.Append(anIter.Key());
1307 TColStd_ListIteratorOfListOfInteger aListIter(aDisplayedIDs);
1309 for (; aListIter.More(); aListIter.Next()) {
1310 eraseSubShape(aListIter.Value());
1313 getDisplayer()->UpdateViewer();
1316 //=================================================================================
1317 // function : restoreViewer
1319 //=================================================================================
1320 void OperationGUI_ExtractionDlg::restoreViewer()
1322 if (!CORBA::is_nil(myObj)) {
1323 if (myIsHiddenMain) {
1324 getDisplayer()->Display(myObj, false);
1325 myIsHiddenMain = false;