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>
35 #include <TColStd_ListIteratorOfListOfInteger.hxx>
37 #include <TopExp_Explorer.hxx>
38 #include <TopoDS_Iterator.hxx>
39 #include <TopTools_IndexedMapOfShape.hxx>
40 #include <TopTools_MapOfShape.hxx>
43 #include <QGridLayout>
45 #include <QHBoxLayout>
48 #include <QListWidget>
49 #include <QPushButton>
50 #include <QRadioButton>
51 #include <QTreeWidget>
52 #include <QVBoxLayout>
55 #if QT_VERSION >= 0x050300
56 #include <QSignalBlocker>
59 * This class is named as QT class as it is introduced since Qt 5.3.
60 * It should not be compiled when Salome is ported on Qt 5.3.
65 QSignalBlocker(QObject *object)
67 myIsBlocked (object && object->signalsBlocked()) {
69 myObject->blockSignals(true);
75 myObject->blockSignals(myIsBlocked);
80 QObject *myObject; ///< Blocked object.
81 bool myIsBlocked; ///< Initial blocked state.
86 #define ID_ROLE Qt::DisplayRole
87 #define TYPE_ROLE Qt::UserRole
89 static const char* const TMP_STR = "TEMP";
91 static const char* const SINGLE_SHAPE_TYPE_TR_CODES [] = {
102 static const char* const PLURAL_SHAPE_TYPE_TR_CODES [] = {
103 "GEOM_COMPOUND", // Not used
115 * This static function creates a new list widget item with given ID and
118 * \param theID the item ID.
119 * \param theListWidget the list widget.
120 * \return the created list widget item.
122 static QListWidgetItem *addNewItem(const int theID,
123 QListWidget *theListWidget)
125 QListWidgetItem *aResult = new QListWidgetItem;
127 aResult->setData(ID_ROLE, theID);
128 theListWidget->addItem(aResult);
134 * This static function creates a new tree widget item as a child of the input
135 * one with given ID and returns it.
137 * \param theID the item ID.
138 * \param theParentItem the parent item.
139 * \return the created tree widget item.
141 static QTreeWidgetItem *addChildItem(const int theID,
142 QTreeWidgetItem *theParentItem)
144 QTreeWidgetItem *aResult = new QTreeWidgetItem;
146 aResult->setData(0, ID_ROLE, theID);
147 theParentItem->addChild(aResult);
153 * This static function returns the maximal shape type of sub-shapes stored in
154 * the input compound. If it is not a compound, it returns TopAbs_SHAPE.
156 * \param theCompound the compound.
157 * \return the maximal shape type of sub-shapes stored in the input compound.
159 static TopAbs_ShapeEnum GetMaxShapeTypeInComp(const TopoDS_Shape &theCompound)
161 TopAbs_ShapeEnum aResult = TopAbs_SHAPE;
163 if (theCompound.IsNull() || theCompound.ShapeType() != TopAbs_COMPOUND) {
167 TopoDS_Iterator anIt(theCompound, Standard_False, Standard_False);
169 for (; anIt.More(); anIt.Next()) {
170 const TopoDS_Shape &aSubShape = anIt.Value();
172 if (aSubShape.IsNull()) {
176 // Get the sub-shape type.
177 TopAbs_ShapeEnum aSubType = aSubShape.ShapeType();
179 if (aSubType == TopAbs_COMPOUND) {
180 aSubType = GetMaxShapeTypeInComp(aSubShape);
183 if (aSubType == TopAbs_SHAPE) {
187 if (aResult == TopAbs_SHAPE) {
188 // This is an initialization.
190 } else if (aResult > aSubType) {
198 //=================================================================================
199 // class : OperationGUI_ExtractionDlg()
201 //=================================================================================
202 OperationGUI_ExtractionDlg::OperationGUI_ExtractionDlg
203 (GeometryGUI* GUI, QWidget* parent)
204 : GEOMBase_Skeleton (GUI, parent, false),
207 mySubShTypeCompo (0),
214 myIsHiddenMain (false)
216 QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap(
217 "GEOM", tr("ICON_DLG_EXTRACTION")));
218 QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap(
219 "GEOM", tr("ICON_SELECT")));
221 setWindowTitle(tr("GEOM_EXTRACT_TITLE"));
223 /***************************************************************/
225 mainFrame()->GroupConstructors->setTitle(tr("GEOM_EXTRACT_TYPE"));
226 mainFrame()->RadioButton1->setIcon( image0 );
227 mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose);
228 mainFrame()->RadioButton2->close();
229 mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
230 mainFrame()->RadioButton3->close();
232 // Create an input group.
233 QGroupBox *anInputGrp = new QGroupBox(tr("GEOM_EXTRACT_INPUT_PARAMS"), centralWidget());
234 QGridLayout *anInputLayout = new QGridLayout(anInputGrp);
235 QHBoxLayout *aShapeLayout = new QHBoxLayout(anInputGrp);
236 QVBoxLayout *aViewBtnsLayout = new QVBoxLayout(anInputGrp);
237 QVBoxLayout *aMoveBtnsLayout = new QVBoxLayout(anInputGrp);
238 QLabel *aMainObjLbl = new QLabel(tr("GEOM_MAIN_OBJECT"), anInputGrp);
239 QLabel *aSubShTypeLbl = new QLabel(tr("GEOM_EXTRACT_SUB_SHAPE_TYPE"), anInputGrp);
240 QLabel *aFilteredLbl = new QLabel(tr("GEOM_EXTRACT_FILTERED_SHAPES"), anInputGrp);
241 QLabel *anExtractedLbl = new QLabel(tr("GEOM_EXTRACT_SHAPES_TO_EXTRACT"), anInputGrp);
242 QPushButton *aShowOnlySelBtn = new QPushButton(tr("SHOW_ONLY_SELECTED"), anInputGrp);
243 QPushButton *aHideSelBtn = new QPushButton(tr("HIDE_SELECTED"), anInputGrp);
244 QPushButton *aShowAllBtn = new QPushButton(tr("SHOW_ALL_SUB_SHAPES"), anInputGrp);
245 QPushButton *anAddBtn = new QPushButton(">>", anInputGrp);
246 QPushButton *aRemoveBtn = new QPushButton("<<", anInputGrp);
248 myRebuildBtn = new QPushButton(tr("GEOM_EXTRACT_REBUILD"), anInputGrp);
249 mySelBtn = new QPushButton(anInputGrp);
250 myMainShapeEdit = new QLineEdit(anInputGrp);
251 mySubShTypeCompo = new QComboBox(anInputGrp);
252 myFilteredList = new QListWidget(anInputGrp);
253 myExtractedTree = new QTreeWidget(anInputGrp);
254 mySelBtn->setIcon(image1);
255 myMainShapeEdit->setReadOnly(true);
257 aShapeLayout->addWidget(mySelBtn);
258 aShapeLayout->addWidget(myMainShapeEdit);
260 aViewBtnsLayout->addStretch();
261 aViewBtnsLayout->addWidget(aShowOnlySelBtn);
262 aViewBtnsLayout->addWidget(aHideSelBtn);
263 aViewBtnsLayout->addWidget(aShowAllBtn);
264 aViewBtnsLayout->addStretch();
266 aMoveBtnsLayout->addStretch();
267 aMoveBtnsLayout->addWidget(anAddBtn);
268 aMoveBtnsLayout->addWidget(aRemoveBtn);
269 aMoveBtnsLayout->addStretch();
271 anInputLayout->setSpacing(6);
272 anInputLayout->setContentsMargins(9, 9, 9, 9);
273 anInputLayout->addWidget(aMainObjLbl, 0, 0);
274 anInputLayout->addLayout(aShapeLayout, 0, 1, 1, 3);
275 anInputLayout->addWidget(aSubShTypeLbl, 1, 0);
276 anInputLayout->addWidget(mySubShTypeCompo, 1, 1, 1, 3);
277 anInputLayout->addWidget(aFilteredLbl, 2, 1);
278 anInputLayout->addWidget(anExtractedLbl, 2, 3);
279 anInputLayout->addLayout(aViewBtnsLayout, 3, 0);
280 anInputLayout->addWidget(myFilteredList, 3, 1);
281 anInputLayout->addLayout(aMoveBtnsLayout, 3, 2);
282 anInputLayout->addWidget(myExtractedTree, 3, 3);
283 anInputLayout->addWidget(myRebuildBtn, 4, 0, 1, 4);
285 // Create a statistics group.
286 QGroupBox *aStatGrp = new QGroupBox(tr("GEOM_EXTRACT_STATISTICS"), centralWidget());
287 QGridLayout *aStatLayout = new QGridLayout(aStatGrp);
288 QLabel *aRemovedLbl = new QLabel(tr("GEOM_EXTRACT_REMOVED"), aStatGrp);
289 QLabel *aModifiedLbl = new QLabel(tr("GEOM_EXTRACT_MODIFIED"), aStatGrp);
290 QLabel *anAddedLbl = new QLabel(tr("GEOM_EXTRACT_ADDED"), aStatGrp);
292 myRemovedList = new QListWidget(aStatGrp);
293 myModifiedList = new QListWidget(aStatGrp);
294 myAddedList = new QListWidget(aStatGrp);
296 aStatLayout->setSpacing(6);
297 aStatLayout->setContentsMargins(9, 9, 9, 9);
298 aStatLayout->addWidget(aRemovedLbl, 0, 0);
299 aStatLayout->addWidget(aModifiedLbl, 0, 1);
300 aStatLayout->addWidget(anAddedLbl, 0, 2);
301 aStatLayout->addWidget(myRemovedList, 1, 0);
302 aStatLayout->addWidget(myModifiedList, 1, 1);
303 aStatLayout->addWidget(myAddedList, 1, 2);
305 // Create a main layout.
306 QVBoxLayout* aLayout = new QVBoxLayout(centralWidget());
308 aLayout->setMargin(0);
309 aLayout->setSpacing(6);
310 aLayout->addWidget(anInputGrp);
311 aLayout->addWidget(aStatGrp);
313 // signals and slots connections
314 connect(anAddBtn, SIGNAL(clicked()), this, SLOT(onAddExtracted()));
315 connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemoveExtracted()));
316 connect(aShowOnlySelBtn, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
317 connect(aHideSelBtn, SIGNAL(clicked()), this, SLOT(hideSelected()));
318 connect(aShowAllBtn, SIGNAL(clicked()), this, SLOT(showAllSelected()));
320 /***************************************************************/
321 myHelpFileName = "extract_and_rebuild_page.html";
329 //=================================================================================
330 // function : ~OperationGUI_ExtractionDlg()
331 // purpose : Destroys the object and frees any allocated resources
332 //=================================================================================
333 OperationGUI_ExtractionDlg::~OperationGUI_ExtractionDlg()
338 //=================================================================================
341 //=================================================================================
342 void OperationGUI_ExtractionDlg::Init()
344 mySelBtn->setCheckable(true);
345 mySelBtn->setChecked(true);
346 myFilteredList->setSelectionMode(QAbstractItemView::ExtendedSelection);
347 myFilteredList->setSortingEnabled(true);
348 myExtractedTree->setHeaderHidden(true);
349 myExtractedTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
350 myExtractedTree->setColumnCount(1);
351 myRebuildBtn->setEnabled(false);
352 myRemovedList->setSelectionMode(QAbstractItemView::NoSelection);
353 myModifiedList->setSelectionMode(QAbstractItemView::NoSelection);
354 myAddedList->setSelectionMode(QAbstractItemView::NoSelection);
356 // Fill in the extracted tree with initial elements.
357 myTopItems[0] = 0; // No need to create a item for compound.
361 for (i = 1; i < 8; i++) {
362 myTopItems[i] = new QTreeWidgetItem;
363 myTopItems[i]->setText(0, tr(PLURAL_SHAPE_TYPE_TR_CODES[i]));
364 myTopItems[i]->setData(0, TYPE_ROLE, i);
366 myExtractedTree->addTopLevelItem(myTopItems[i]);
367 myTopItems[i]->setHidden(true);
370 // signals and slots connections
371 connect(mySelBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
372 connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
373 connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
374 connect(mySubShTypeCompo, SIGNAL(currentIndexChanged(int)),
375 this, SLOT(onShapeTypeChanged()));
376 connect(myRebuildBtn, SIGNAL(clicked()), this, SLOT(onRebuild()));
377 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
378 this, SLOT(SelectionIntoArgument()));
379 connect(myFilteredList, SIGNAL(itemSelectionChanged()),
380 this, SLOT(onListSelectionChanged()));
381 connect(myExtractedTree, SIGNAL(itemSelectionChanged()),
382 this, SLOT(onListSelectionChanged()));
384 initName(tr("GEOM_EXTRACT_NAME"));
387 SelectionIntoArgument();
390 //=================================================================================
391 // function : updateSubShTypeCompo()
393 //=================================================================================
394 bool OperationGUI_ExtractionDlg::updateSubShTypeCompo()
397 int anIStart = TopAbs_COMPOUND;
398 const int anIEnd = TopAbs_VERTEX;
401 if (GEOMBase::GetShape(myObj, aShape)) {
402 const TopAbs_ShapeEnum aType = aShape.ShapeType();
404 if (aType == TopAbs_COMPOUND) {
405 anIStart = GetMaxShapeTypeInComp(aShape);
406 isValid = anIStart != TopAbs_SHAPE;
408 anIStart = aType + 1;
412 QSignalBlocker aBlocker(mySubShTypeCompo);
413 mySubShTypeCompo->clear();
418 for (i = anIStart; i <= anIEnd; i++) {
419 mySubShTypeCompo->addItem(tr(SINGLE_SHAPE_TYPE_TR_CODES[i]), i);
422 updateFilteredList();
428 //=================================================================================
429 // function : updateFilteredList()
431 //=================================================================================
432 void OperationGUI_ExtractionDlg::updateFilteredList()
435 QSignalBlocker aBlocker(myFilteredList);
437 myFilteredList->clear();
439 if (GEOMBase::GetShape(myObj, aShape)) {
440 const TopAbs_ShapeEnum aType = (TopAbs_ShapeEnum)
441 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
442 TopExp_Explorer anExp(aShape, aType);
445 TopTools_MapOfShape aMapFence;
447 for (; anExp.More(); anExp.Next()) {
448 const TopoDS_Shape &aSubShape = anExp.Current();
450 if (!aSubShape.IsNull() && aMapFence.Add(aSubShape)) {
451 int anIndex = myIndices.FindIndex(aSubShape);
453 if (!myMapExtractedIDs.Contains(anIndex)) {
454 addNewItem(anIndex, myFilteredList);
462 //=================================================================================
463 // function : resetBuildData()
465 //=================================================================================
466 void OperationGUI_ExtractionDlg::resetBuildData(const bool isEnableBuild)
468 // Clear result data.
469 myRemovedList->clear();
470 myModifiedList->clear();
471 myAddedList->clear();
472 myRebuildBtn->setEnabled(isEnableBuild);
475 //=================================================================================
476 // function : isEmptyExtracted()
478 //=================================================================================
479 bool OperationGUI_ExtractionDlg::isEmptyExtracted()
484 // Check if there are sub-shapes to be extracted.
485 for (i = 1; i < 8; i++) {
486 if (!myTopItems[i]->isHidden()) {
496 //=================================================================================
497 // function : selectMainShape
499 //=================================================================================
500 void OperationGUI_ExtractionDlg::selectMainShape()
502 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
503 SALOME_ListIO aSelList;
505 aSelMgr->selectedObjects(aSelList);
507 if (aSelList.Extent() == 1) {
508 GEOM::GEOM_Object_var aSelObject =
509 GEOMBase::ConvertIOinGEOMObject(aSelList.First());
510 TopoDS_Shape aSelShape;
512 if (GEOMBase::GetShape(aSelObject, aSelShape)) {
513 const TopAbs_ShapeEnum aType = aSelShape.ShapeType();
516 if (aType != TopAbs_VERTEX) {
519 // Initialize map of indices. Note that myIndices should be empty.
520 TopExp::MapShapes(aSelShape, myIndices);
525 if (!updateSubShTypeCompo()) {
526 // Invalid selected object.
527 myObj = GEOM::GEOM_Object::_nil();
530 if (!CORBA::is_nil(myObj)) {
531 mySelBtn->setChecked(false);
532 myMainShapeEdit->setEnabled(false);
533 myMainShapeEdit->setText(GEOMBase::GetName(myObj));
535 // Hide the main object from the viewer.
536 SALOME_View* aView = GEOM_Displayer::GetActiveView();
539 CORBA::String_var aMainEntry = myObj->GetStudyEntry();
540 Handle(SALOME_InteractiveObject) anIO = createIO(aMainEntry.in());
542 if (aView->isVisible(anIO)) {
543 GEOM_Displayer *aDisplayer = getDisplayer();
545 aDisplayer->Erase(myObj, false, true);
546 myIsHiddenMain = true;
552 //=================================================================================
553 // function : selectSubShapes
555 //=================================================================================
556 void OperationGUI_ExtractionDlg::selectSubShapes()
558 QSignalBlocker aBlocker(myFilteredList);
560 // Clear current selection.
561 myFilteredList->clearSelection();
563 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
564 SALOME_ListIO aSelList;
566 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
568 aSelMgr->selectedObjects(aSelList);
570 // try to find out and process the global selection
571 // (of not published objects and of published sub-shapes)
572 SALOME_ListIteratorOfListIO anIter(aSelList);
574 for (; anIter.More(); anIter.Next()) {
575 Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
576 QString anEntry = anIObj->getEntry();
577 QStringList aParts = anEntry.split("_");
578 int aSubShapeId = -1;
580 if (!aParts.isEmpty()) {
581 if (aParts.first() == TMP_STR) {
583 const int anIndex = aParts.last().toInt(&isOk);
585 if (isOk && anIndex > 0) {
586 // This is a sub-shape.
587 aSubShapeId = anIndex;
592 if (aSubShapeId < 0) {
593 // This is a published shape.
594 GEOM::GEOM_Object_var aSelObject =
595 GEOMBase::ConvertIOinGEOMObject(anIObj);
596 TopoDS_Shape aSelShape;
598 if (GEOMBase::GetShape(aSelObject, aSelShape)) {
600 if (aSelShape.ShapeType() == aCurType) {
601 const int anIndex = myIndices.FindIndex(aSelShape);
604 // This is a sub-shape. Select it in the filtered list.
605 aSubShapeId = anIndex;
611 // Select a list widget item by Id.
612 if (aSubShapeId > 0) {
613 QString anIdText = QString("%1").arg(aSubShapeId);
614 QList<QListWidgetItem *> aFound =
615 myFilteredList->findItems(anIdText, Qt::MatchExactly);
617 foreach (QListWidgetItem *anItem, aFound) {
618 anItem->setSelected(true);
624 //=================================================================================
625 // function : ClickOnOk()
627 //=================================================================================
628 void OperationGUI_ExtractionDlg::ClickOnOk()
630 if (ClickOnApply()) {
635 //=================================================================================
636 // function : ClickOnApply()
638 //=================================================================================
639 bool OperationGUI_ExtractionDlg::ClickOnApply()
650 //=================================================================================
651 // function : onShapeTypeChanged
653 //=================================================================================
654 void OperationGUI_ExtractionDlg::onShapeTypeChanged()
656 updateFilteredList();
660 //=================================================================================
661 // function : onAddExtracted
663 //=================================================================================
664 void OperationGUI_ExtractionDlg::onAddExtracted()
666 QList<QListWidgetItem *> aListSelected = myFilteredList->selectedItems();
668 if (aListSelected.empty()) {
672 const int aShapeType =
673 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
674 bool isTreeUpdated = false;
676 foreach (QListWidgetItem *anItem, aListSelected) {
677 const int anIndex = anItem->data(ID_ROLE).toInt();
679 if (myMapExtractedIDs.Add(anIndex)) {
680 addChildItem(anIndex, myTopItems[aShapeType]);
681 isTreeUpdated = true;
684 // Remove anItem from the list.
685 myFilteredList->removeItemWidget(anItem);
690 myTopItems[aShapeType]->sortChildren(0, Qt::AscendingOrder);
693 resetBuildData(true);
696 myFilteredList->clearSelection();
697 myTopItems[aShapeType]->setHidden(false);
700 //=================================================================================
701 // function : onRemoveExtracted
703 //=================================================================================
704 void OperationGUI_ExtractionDlg::onRemoveExtracted()
706 QList<QTreeWidgetItem *> aListSelected = myExtractedTree->selectedItems();
708 if (aListSelected.empty()) {
712 const int aShapeType =
713 mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt();
714 QSet<QTreeWidgetItem *> aSetFence;
715 bool isTreeUpdated = false;
717 foreach (QTreeWidgetItem *anItem, aListSelected) {
718 if (!aSetFence.contains(anItem)) {
719 aSetFence.insert(anItem);
721 QTreeWidgetItem *aParent = anItem->parent();
724 const int anIndex = anItem->data(0, ID_ROLE).toInt();
725 // This is a ID item. Remove the ID from myMapExtractedIDs.
726 if (myMapExtractedIDs.Remove(anIndex)) {
727 // The item is not removed yet. Get parent index.
728 const int aParentIndex = aParent->data(0, TYPE_ROLE).toInt();
730 if (aShapeType == aParentIndex) {
731 // Create an item in the filtered list.
732 addNewItem(anIndex, myFilteredList);
735 aParent->removeChild(anItem);
737 isTreeUpdated = true;
739 // Hilde an empty parent item.
740 if (aParent->childCount() == 0) {
741 aParent->setHidden(true);
745 // This is a top level item. Remove all its children.
746 QList<QTreeWidgetItem *> aChildItems = anItem->takeChildren();
747 const int anIndex = anItem->data(0, TYPE_ROLE).toInt();
749 // Remove IDs from myMapExtractedIDs.
750 foreach (QTreeWidgetItem *aChild, aChildItems) {
751 if (!aSetFence.contains(aChild)) {
752 aSetFence.insert(aChild);
754 const int aChildIndex = aChild->data(0, ID_ROLE).toInt();
756 if (myMapExtractedIDs.Remove(aChildIndex)) {
757 if (aShapeType == anIndex) {
758 // Create items in the filtered list.
759 addNewItem(aChildIndex, myFilteredList);
763 isTreeUpdated = true;
768 // Hilde an empty item.
769 anItem->setHidden(true);
774 myExtractedTree->clearSelection();
778 const bool isEnableRebuild = !isEmptyExtracted();
780 resetBuildData(isEnableRebuild);
784 //=================================================================================
785 // function : onListSelectionChanged
787 //=================================================================================
788 void OperationGUI_ExtractionDlg::onListSelectionChanged()
790 SALOME_ListIO anIOList;
791 QList<QListWidgetItem *> aListSel = myFilteredList->selectedItems();
792 QList<QTreeWidgetItem *> aTreeSel = myExtractedTree->selectedItems();
794 // Collect selected items from myFilteredList
795 foreach (QListWidgetItem *anItem, aListSel) {
796 const int anIndex = anItem->data(ID_ROLE).toInt();
798 if (myMapDisplayedIDs.Contains(anIndex)) {
799 // Collect only displayed sub-shapes for selection in the viewer.
800 QString anEntry = getSubShapeEntry(anIndex);
801 Handle(SALOME_InteractiveObject) anIO =
802 createIO(anEntry.toLatin1().data());
804 anIOList.Append(anIO);
808 // Collect selected items from myExtractedTree
809 foreach (QTreeWidgetItem *anItem, aTreeSel) {
810 if (anItem->parent()) {
811 // This is a ID item.
812 const int anIndex = anItem->data(0, ID_ROLE).toInt();
814 if (myMapDisplayedIDs.Contains(anIndex)) {
815 // Collect only displayed sub-shapes for selection in the viewer.
816 QString anEntry = getSubShapeEntry(anIndex);
817 Handle(SALOME_InteractiveObject) anIO =
818 createIO(anEntry.toLatin1().data());
820 anIOList.Append(anIO);
825 // Select object in viewer.
826 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
828 aSelMgr->setSelectedObjects(anIOList);
831 //=================================================================================
832 // function : showOnlySelected
834 //=================================================================================
835 void OperationGUI_ExtractionDlg::showOnlySelected()
837 TColStd_MapOfInteger aMapIDsSelected;
838 TColStd_MapOfInteger aMapIDsToDisplay;
839 const int aNbItems = myFilteredList->count();
841 QSet<QString> aSelEntry;
843 // Get sub-shape IDs to be displayed.
844 for (i = 0; i < aNbItems; ++i) {
845 QListWidgetItem *anItem = myFilteredList->item(i);
846 const int anIndex = anItem->data(ID_ROLE).toInt();
848 if (anItem->isSelected()) {
849 aMapIDsSelected.Add(anIndex);
850 aSelEntry.insert(getSubShapeEntry(anIndex));
852 if (!myMapDisplayedIDs.Contains(anIndex)) {
853 aMapIDsToDisplay.Add(anIndex);
858 // Get sub-shape IDs to be erased.
859 TColStd_MapOfInteger aMapIDsToHide;
860 TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs);
862 for (; anIter.More(); anIter.Next()) {
863 const int anIndex = anIter.Key();
865 if (!aMapIDsSelected.Contains(anIndex)) {
866 aMapIDsToHide.Add(anIndex);
870 // Display sub-shapes.
871 for (anIter.Initialize(aMapIDsToDisplay); anIter.More(); anIter.Next()) {
872 displaySubShape(anIter.Key());
876 for (anIter.Initialize(aMapIDsToHide); anIter.More(); anIter.Next()) {
877 eraseSubShape(anIter.Key());
880 // Hide all objects except already displayed sub-shapes.
881 SALOME_ListIO aDisplayed;
882 SALOME_View *aView = GEOM_Displayer::GetActiveView();
885 aView->GetVisible(aDisplayed);
888 SALOME_ListIteratorOfListIO aDispIt(aDisplayed);
889 GEOM_Displayer *aDisplayer = getDisplayer();
891 for (; aDispIt.More(); aDispIt.Next()) {
892 Handle(SALOME_InteractiveObject) anIO = aDispIt.Value();
894 if (!aSelEntry.contains(anIO->getEntry())) {
895 aDisplayer->Erase(anIO, false, false);
899 onListSelectionChanged();
900 aDisplayer->UpdateViewer();
903 //=================================================================================
904 // function : hideSelected
906 //=================================================================================
907 void OperationGUI_ExtractionDlg::hideSelected()
909 QList<QListWidgetItem *> aListSelected = myFilteredList->selectedItems();
911 foreach (QListWidgetItem *anItem, aListSelected) {
912 const int anIndex = anItem->data(ID_ROLE).toInt();
914 eraseSubShape(anIndex);
917 getDisplayer()->UpdateViewer();
920 //=================================================================================
921 // function : showAllSelected
923 //=================================================================================
924 void OperationGUI_ExtractionDlg::showAllSelected()
926 const int aNbItems = myFilteredList->count();
929 for (i = 0; i < aNbItems; ++i) {
930 QListWidgetItem *anItem = myFilteredList->item(i);
931 const int anIndex = anItem->data(ID_ROLE).toInt();
933 displaySubShape(anIndex);
936 onListSelectionChanged();
937 getDisplayer()->UpdateViewer();
940 //=================================================================================
941 // function : onRebuild
943 //=================================================================================
944 void OperationGUI_ExtractionDlg::onRebuild()
946 GEOM::GEOM_Object_var aResShape;
947 GEOM::GEOM_IShapesOperations::ExtractionStats aStats;
949 if (!getResult(aResShape.out(), aStats)) {
950 resetBuildData(false);
954 TopoDS_Shape anOldShape;
955 TopoDS_Shape aNewShape;
956 TopTools_IndexedMapOfShape aNewIndices;
958 if (!GEOMBase::GetShape(aResShape, aNewShape)) {
959 resetBuildData(false);
963 TopExp::MapShapes(aNewShape, aNewIndices);
965 const int aNbStat = aStats.length();
968 for (i = 0; i < aNbStat; ++i) {
969 // Compute number of sub-shapes of each type.
970 const int aNbSubShapes = aStats[i].indices.length();
971 int aNbShapes [] = { 0, 0, 0, 0, 0, 0, 0, 0 };
974 TopTools_IndexedMapOfShape *aMapShapes =
975 (aStats[i].type == GEOM::GEOM_IShapesOperations::EST_Added) ?
976 &aNewIndices : &myIndices;
978 for (j = 0; j < aNbSubShapes; ++j) {
979 const int anIndex = aStats[i].indices[j];
981 if (anIndex < 1 || anIndex > aMapShapes->Extent()) {
982 resetBuildData(false);
986 const TopoDS_Shape &aSubShape = aMapShapes->FindKey(anIndex);
988 aNbShapes[aSubShape.ShapeType()]++;
991 // Fill the statistics.
992 QListWidget *aListWidget = 0;
994 switch (aStats[i].type) {
995 case GEOM::GEOM_IShapesOperations::EST_Removed:
996 aListWidget = myRemovedList;
998 case GEOM::GEOM_IShapesOperations::EST_Modified:
999 aListWidget = myModifiedList;
1001 case GEOM::GEOM_IShapesOperations::EST_Added:
1002 aListWidget = myAddedList;
1005 resetBuildData(false);
1009 QStringList aStrList;
1011 for (j = 0; j < 8; ++j) {
1012 if (aNbShapes[j] >= 1) {
1013 const char *aShapeType = aNbShapes[j] == 1 ?
1014 SINGLE_SHAPE_TYPE_TR_CODES[j] : PLURAL_SHAPE_TYPE_TR_CODES[j];
1016 aStrList.append(QString("%1 %2").arg(aNbShapes[j]).arg(tr(aShapeType)));
1020 aListWidget->addItems(aStrList);
1023 myRebuildBtn->setEnabled(false);
1026 //=================================================================================
1027 // function : SelectionIntoArgument
1029 //=================================================================================
1030 void OperationGUI_ExtractionDlg::SelectionIntoArgument()
1032 if (myMainShapeEdit->isEnabled()) {
1033 // Selection of main object
1036 // Selection of filtered shapes
1041 //=================================================================================
1042 // function : SetEditCurrentArgument
1044 //=================================================================================
1045 void OperationGUI_ExtractionDlg::SetEditCurrentArgument()
1047 QSignalBlocker aBlockerList(myFilteredList);
1048 QSignalBlocker aBlockerTree(myExtractedTree);
1051 myObj = GEOM::GEOM_Object::_nil();
1052 myMainShapeEdit->setEnabled(true);
1053 myMainShapeEdit->setText("");
1054 myMainShapeEdit->setFocus();
1056 updateSubShTypeCompo();
1058 myFilteredList->clear();
1059 myRemovedList->clear();
1060 myModifiedList->clear();
1061 myAddedList->clear();
1064 // Clear myExtractedTree.
1067 for (i = 1; i < 8; i++) {
1068 QList<QTreeWidgetItem *> aListItems = myTopItems[i]->takeChildren();
1070 foreach (QTreeWidgetItem *anItem, aListItems) {
1074 myTopItems[i]->setHidden(true);
1077 myExtractedTree->clearSelection();
1079 myMapExtractedIDs.Clear();
1085 //=================================================================================
1086 // function : ActivateThisDialog()
1088 //=================================================================================
1089 void OperationGUI_ExtractionDlg::ActivateThisDialog()
1091 GEOMBase_Skeleton::ActivateThisDialog();
1093 LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr();
1096 connect(aSel, SIGNAL(currentSelectionChanged()),
1097 this, SLOT(SelectionIntoArgument()));
1100 activateSelection();
1103 //=================================================================================
1104 // function : activateSelection
1105 // purpose : activate selection of all shapes
1106 //=================================================================================
1107 void OperationGUI_ExtractionDlg::activateSelection()
1109 globalSelection(GEOM_ALLSHAPES);
1112 //=================================================================================
1113 // function : enterEvent()
1115 //=================================================================================
1116 void OperationGUI_ExtractionDlg::enterEvent(QEvent *)
1118 if (!mainFrame()->GroupConstructors->isEnabled()) {
1119 ActivateThisDialog();
1123 //=================================================================================
1124 // function : getResult
1126 //=================================================================================
1127 bool OperationGUI_ExtractionDlg::getResult
1128 (GEOM::GEOM_Object_ptr &theResult,
1129 GEOM::GEOM_IShapesOperations::ExtractionStats &theStats)
1131 if (myObj->_is_nil()) {
1135 // Get IDs of extracted shapes.
1139 for (i = 1; i < 8; i++) {
1140 aNbShapes += myTopItems[i]->childCount();
1143 if (aNbShapes == 0) {
1147 GEOM::ListOfLong_var aSubShapeIDs = new GEOM::ListOfLong;
1151 aSubShapeIDs->length(aNbShapes);
1153 for (jCur = 0, i = 1; i < 8; ++i) {
1154 aNbShapes = myTopItems[i]->childCount();
1156 for (j = 0; j < aNbShapes; ++j, ++jCur) {
1157 aSubShapeIDs[jCur] = myTopItems[i]->child(j)->data(0, ID_ROLE).toInt();
1161 GEOM::GEOM_IShapesOperations_var anOper =
1162 GEOM::GEOM_IShapesOperations::_narrow(getOperation());
1165 GEOM::GEOM_Object_var anObj;
1166 GEOM::GEOM_IShapesOperations::ExtractionStats_var aStats;
1168 anObj = anOper->MakeExtraction(myObj, aSubShapeIDs, aStats);
1170 if (anOper->IsDone() && aStats->length() > 0) {
1174 if (!CORBA::is_nil(anObj)) {
1175 theResult = anObj._retn();
1178 catch (const SALOME::SALOME_Exception& e) {
1179 SalomeApp_Tools::QtCatchCorbaException(e);
1183 return anOper->IsDone();
1186 //=================================================================================
1187 // function : isValid
1189 //=================================================================================
1190 bool OperationGUI_ExtractionDlg::isValid(QString &)
1192 bool isOk = !myObj->_is_nil() && !isEmptyExtracted();
1197 //=================================================================================
1198 // function : createOperation
1200 //=================================================================================
1201 GEOM::GEOM_IOperations_ptr OperationGUI_ExtractionDlg::createOperation()
1203 return getGeomEngine()->GetIShapesOperations(getStudyId());
1206 //=================================================================================
1207 // function : execute
1209 //=================================================================================
1210 bool OperationGUI_ExtractionDlg::execute(ObjectList &objects)
1212 GEOM::GEOM_Object_var aResShape;
1213 GEOM::GEOM_IShapesOperations::ExtractionStats aStats;
1215 if (!getResult(aResShape.out(), aStats)) {
1219 if (!aResShape->_is_nil()) {
1220 objects.push_back(aResShape._retn());
1226 //=================================================================================
1227 // function : getSubShapeEntry
1229 //=================================================================================
1230 QString OperationGUI_ExtractionDlg::getSubShapeEntry(const int theId)
1232 CORBA::String_var aMainEntry = myObj->GetStudyEntry();
1233 QString anEntry = QString("%1_").arg(TMP_STR) +
1234 aMainEntry.in() + QString("_%1").arg(theId);
1239 //=================================================================================
1240 // function : createIO
1242 //=================================================================================
1243 Handle_SALOME_InteractiveObject OperationGUI_ExtractionDlg::createIO
1244 (const char *theEntry)
1246 Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
1247 (theEntry, "GEOM", "TEMP_IO");
1252 //=================================================================================
1253 // function : displaySubShape
1255 //=================================================================================
1256 void OperationGUI_ExtractionDlg::displaySubShape(const int theId)
1258 if (theId < 1 || theId > myIndices.Extent()) {
1262 // Create a presentation
1263 const TopoDS_Shape &aSubShape = myIndices.FindKey(theId);
1264 QString anEntry = getSubShapeEntry(theId);
1265 SALOME_View *aView = GEOM_Displayer::GetActiveView();
1266 GEOM_Displayer *aDisplayer = getDisplayer();
1267 SALOME_Prs *aPrs = aDisplayer->buildSubshapePresentation
1268 (aSubShape, anEntry, aView);
1272 aView->Display(aDisplayer, aPrs);
1277 myMapDisplayedIDs.Add(theId);
1281 //=================================================================================
1282 // function : eraseSubShape
1284 //=================================================================================
1285 void OperationGUI_ExtractionDlg::eraseSubShape(const int theId)
1287 QString anEntry = getSubShapeEntry(theId);
1288 Handle(SALOME_InteractiveObject) anIO =
1289 createIO(anEntry.toLatin1().data());
1291 getDisplayer()->Erase(anIO, false, false);
1292 myMapDisplayedIDs.Remove(theId);
1295 //=================================================================================
1296 // function : eraseAll
1298 //=================================================================================
1299 void OperationGUI_ExtractionDlg::eraseAll()
1301 TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs);
1302 TColStd_ListOfInteger aDisplayedIDs;
1304 for (; anIter.More(); anIter.Next()) {
1305 aDisplayedIDs.Append(anIter.Key());
1308 TColStd_ListIteratorOfListOfInteger aListIter(aDisplayedIDs);
1310 for (; aListIter.More(); aListIter.Next()) {
1311 eraseSubShape(aListIter.Value());
1314 getDisplayer()->UpdateViewer();
1317 //=================================================================================
1318 // function : restoreViewer
1320 //=================================================================================
1321 void OperationGUI_ExtractionDlg::restoreViewer()
1323 if (!CORBA::is_nil(myObj)) {
1324 if (myIsHiddenMain) {
1325 getDisplayer()->Display(myObj, false);
1326 myIsHiddenMain = false;