1 // Created on: 2017-06-16
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2017 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <inspector/DFBrowser_Window.hxx>
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_InteractiveObject.hxx>
20 #include <AIS_ListOfInteractive.hxx>
22 #include <CDF_Session.hxx>
24 #include <inspector/DFBrowserPane_AttributePaneAPI.hxx>
26 #include <inspector/DFBrowser_AttributePaneStack.hxx>
27 #include <inspector/DFBrowser_AttributePaneType.hxx>
28 #include <inspector/DFBrowser_DumpView.hxx>
29 #include <inspector/DFBrowser_Item.hxx>
30 #include <inspector/DFBrowser_ItemApplication.hxx>
31 #include <inspector/DFBrowser_Module.hxx>
32 #include <inspector/DFBrowser_OpenApplication.hxx>
33 #include <inspector/DFBrowser_PropertyPanel.hxx>
34 #include <inspector/DFBrowser_SearchLine.hxx>
35 #include <inspector/DFBrowser_SearchView.hxx>
36 #include <inspector/DFBrowser_Shortcut.hxx>
37 #include <inspector/DFBrowser_Thread.hxx>
38 #include <inspector/DFBrowser_ThreadItemSearch.hxx>
39 #include <inspector/DFBrowser_ThreadItemUsedShapesMap.hxx>
40 #include <inspector/DFBrowser_Tools.hxx>
41 #include <inspector/DFBrowser_TreeLevelLine.hxx>
42 #include <inspector/DFBrowser_TreeLevelView.hxx>
43 #include <inspector/DFBrowser_TreeModel.hxx>
44 #include <inspector/DFBrowser_TreeView.hxx>
46 #include <inspector/DFBrowserPane_AttributePaneSelector.hxx>
47 #include <inspector/DFBrowserPane_SelectionKind.hxx>
48 #include <inspector/DFBrowserPane_Tools.hxx>
50 #include <OSD_Directory.hxx>
51 #include <OSD_Environment.hxx>
52 #include <OSD_Protection.hxx>
54 #include <inspector/View_Displayer.hxx>
55 #include <inspector/View_ToolBar.hxx>
56 #include <inspector/View_Viewer.hxx>
57 #include <inspector/View_Widget.hxx>
58 #include <inspector/View_Window.hxx>
60 #include <TDF_Tool.hxx>
61 #include <inspector/TreeModel_MessageDialog.hxx>
63 #include <Standard_WarningsDisable.hxx>
65 #include <QApplication>
68 #include <QDockWidget>
69 #include <QGridLayout>
71 #include <QMainWindow>
72 #include <QItemSelectionModel>
77 #include <QMessageBox>
80 #if QT_VERSION < 0x050000
81 #include <QWindowsStyle>
83 #include <QStyleFactory>
85 #include <Standard_WarningsRestore.hxx>
87 const int DFBROWSER_DEFAULT_WIDTH = 650;
88 const int DFBROWSER_DEFAULT_HEIGHT = 350;
89 const int DFBROWSER_DEFAULT_TREE_VIEW_WIDTH = 325;
90 const int DFBROWSER_DEFAULT_TREE_VIEW_HEIGHT = 500;
91 const int DFBROWSER_DEFAULT_VIEW_WIDTH = 400;
92 const int DFBROWSER_DEFAULT_VIEW_HEIGHT = 300;
94 const int DFBROWSER_DEFAULT_POSITION_X = 200;
95 const int DFBROWSER_DEFAULT_POSITION_Y = 60;
97 const int OCAF_BROWSER_COLUMN_WIDTH_0 = 300;
98 const int DEFAULT_PROPERTY_PANEL_HEIGHT = 200;
99 const int DEFAULT_BROWSER_HEIGHT = 800;
101 // =======================================================================
102 // function : Constructor
104 // =======================================================================
105 DFBrowser_Window::DFBrowser_Window()
106 : myModule (0), myParent (0), myPropertyPanel (0), myExportToShapeViewDialog (0)
108 myMainWindow = new QMainWindow (0);
111 myTreeView = new DFBrowser_TreeView (myMainWindow);
112 myTreeView->setContextMenuPolicy (Qt::CustomContextMenu);
113 connect (myTreeView, SIGNAL (customContextMenuRequested (const QPoint&)),
114 this, SLOT (onTreeViewContextMenuRequested (const QPoint&)));
115 ((DFBrowser_TreeView*)myTreeView)->SetPredefinedSize (DFBROWSER_DEFAULT_TREE_VIEW_WIDTH,
116 DFBROWSER_DEFAULT_TREE_VIEW_HEIGHT);
117 myTreeView->setHeaderHidden (true);
118 myTreeView->setSortingEnabled (Standard_False);
120 QDockWidget* aTreeViewWidget = new QDockWidget (tr ("TreeView"), myMainWindow);
121 aTreeViewWidget->setTitleBarWidget (new QWidget(myMainWindow));
122 aTreeViewWidget->setFeatures (QDockWidget::NoDockWidgetFeatures);
123 aTreeViewWidget->setWidget (myTreeView);
124 myMainWindow->addDockWidget (Qt::LeftDockWidgetArea, aTreeViewWidget);
125 myMainWindow->setCorner (Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
127 #if QT_VERSION < 0x050000
128 myTreeView->setStyle (new QWindowsStyle);
130 myTreeView->setStyle (QStyleFactory::create("Windows"));
133 myTreeLevelLine = new DFBrowser_TreeLevelLine (myMainWindow);
134 connect (myTreeLevelLine->GetSearchLine(), SIGNAL (searchActivated()), this, SLOT (onSearchActivated()));
135 connect (myTreeLevelLine, SIGNAL (indexSelected (const QModelIndex&)),
136 this, SLOT (onTreeLevelLineSelected (const QModelIndex&)));
137 connect (myTreeLevelLine, SIGNAL (updateClicked()), this, SLOT (onUpdateClicked()));
139 QDockWidget* aTreeLineDockWidget = new QDockWidget (tr ("Tree Level Line"), myMainWindow);
140 aTreeLineDockWidget->setTitleBarWidget (new QWidget(myMainWindow));
141 aTreeLineDockWidget->setFeatures (QDockWidget::NoDockWidgetFeatures);
142 aTreeLineDockWidget->setWidget (myTreeLevelLine->GetControl());
143 myMainWindow->addDockWidget (Qt::TopDockWidgetArea, aTreeLineDockWidget);
146 QWidget* aDumpWidget = new QWidget (myMainWindow);
147 QVBoxLayout* aDumpLay = new QVBoxLayout (aDumpWidget);
148 aDumpLay->setMargin (0);
149 myDumpView = new DFBrowser_DumpView (aDumpWidget);
150 aDumpLay->addWidget (myDumpView->GetControl());
151 QDockWidget* aDumpDockWidget = new QDockWidget (tr ("Dump"), myMainWindow);
153 aDumpDockWidget->setWidget (aDumpWidget);
154 myMainWindow->addDockWidget (Qt::BottomDockWidgetArea, aDumpDockWidget);
157 myPropertyPanel = new DFBrowser_PropertyPanel (myMainWindow);
158 DFBrowser_AttributePaneStack* anAttributePaneStack = myPropertyPanel->GetAttributesStack();
159 anAttributePaneStack->GetSearchView()->SetSearchLine (myTreeLevelLine->GetSearchLine());
161 connect (anAttributePaneStack->GetPaneSelector(),
162 SIGNAL (tableSelectionChanged (const QItemSelection&, const QItemSelection&, QItemSelectionModel*)),
163 this, SLOT (onPaneSelectionChanged (const QItemSelection&, const QItemSelection&, QItemSelectionModel*)));
165 DFBrowser_SearchView* aSearchView = anAttributePaneStack->GetSearchView();
166 connect (aSearchView, SIGNAL (pathSelected (const QStringList&, const QString&)),
167 this, SLOT (onSearchPathSelected (const QStringList&, const QString&)));
168 connect (aSearchView, SIGNAL (pathDoubleClicked (const QStringList&, const QString&)),
169 this, SLOT (onSearchPathDoubleClicked (const QStringList&, const QString&)));
171 DFBrowser_TreeLevelView* aLevelView = anAttributePaneStack->GetTreeLevelView();
172 connect (aLevelView, SIGNAL (indexSelected (const QModelIndex&)), this, SLOT (onLevelSelected (const QModelIndex&)));
173 connect (aLevelView, SIGNAL (indexDoubleClicked (const QModelIndex&)),
174 this, SLOT (onLevelDoubleClicked (const QModelIndex&)));
176 myMainWindow->setCentralWidget (myPropertyPanel->GetControl());
179 myViewWindow = new View_Window (myMainWindow);
180 myViewWindow->GetView()->SetPredefinedSize (DFBROWSER_DEFAULT_VIEW_WIDTH, DFBROWSER_DEFAULT_VIEW_HEIGHT);
182 QDockWidget* aViewDockWidget = new QDockWidget (tr ("View"), myMainWindow);
183 aViewDockWidget->setTitleBarWidget (myViewWindow->GetViewToolBar()->GetControl());
184 aViewDockWidget->setWidget (myViewWindow);
185 myMainWindow->addDockWidget (Qt::BottomDockWidgetArea, aViewDockWidget);
187 QColor aHColor (229, 243, 255);
188 myViewWindow->GetDisplayer()->SetAttributeColor (Quantity_Color(aHColor.red() / 255., aHColor.green() / 255.,
189 aHColor.blue() / 255., Quantity_TOC_RGB), View_PresentationType_Additional);
190 myMainWindow->tabifyDockWidget (aDumpDockWidget, aViewDockWidget);
192 aTreeViewWidget->resize (DFBROWSER_DEFAULT_TREE_VIEW_WIDTH, DFBROWSER_DEFAULT_TREE_VIEW_HEIGHT);
194 myThread = new DFBrowser_Thread (this);
196 myShortcut = new DFBrowser_Shortcut (myMainWindow);
199 // =======================================================================
200 // function : Destructor
202 // =======================================================================
203 DFBrowser_Window::~DFBrowser_Window()
208 // =======================================================================
209 // function : SetParent
211 // =======================================================================
212 void DFBrowser_Window::SetParent (void* theParent)
214 myParent = (QWidget*)theParent;
217 QLayout* aLayout = myParent->layout();
219 aLayout->addWidget (GetMainWindow());
223 // =======================================================================
224 // function : UpdateContent
226 // =======================================================================
227 void DFBrowser_Window::UpdateContent()
229 TCollection_AsciiString aName = "TKDFBrowser";
231 if (myParameters->FindParameters (aName))
232 Init(myParameters->Parameters (aName));
234 Init(NCollection_List<Handle(Standard_Transient)>());
236 if (myParameters->FindFileNames(aName))
238 NCollection_List<TCollection_AsciiString> aFileNames = myParameters->FileNames (aName);
239 if (aFileNames.Extent() > 0) // only one document file might be opened
240 OpenFile (aFileNames.First());
241 myParameters->SetFileNames(aName, NCollection_List<TCollection_AsciiString>());
245 // make parameter items selected if defined
246 if (myParameters->FindSelectedNames(aName))
248 const NCollection_List<TCollection_AsciiString>& aSelected = myParameters->GetSelectedNames (aName);
250 DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
251 Handle(TDocStd_Application) anApplication = aTreeModel->GetTDocStdApplication();
253 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
254 aSelectionModel->clear();
256 NCollection_List<TCollection_AsciiString>::Iterator aSelectedIt (aSelected);
257 if (aSelectedIt.More())
259 TCollection_AsciiString aLabelEntry = aSelectedIt.Value();
262 for (Standard_Integer aDocId = 1, aNbDoc = anApplication->NbDocuments(); aDocId <= aNbDoc; aDocId++)
264 Handle(TDocStd_Document) aDocument;
265 anApplication->GetDocument (aDocId, aDocument);
267 TDF_Tool::Label(aDocument->GetData(), aLabelEntry.ToCString(), aLabel, Standard_False);
268 if (!aLabel.IsNull())
271 if (!aLabel.IsNull())
273 QModelIndex anIndexToBeSelected = aTreeModel->FindIndex (aLabel);
275 TCollection_AsciiString anAttributeType;
277 // find attribute by attribute type on the given label
278 if (aSelectedIt.More())
280 anAttributeType = aSelectedIt.Value();
282 TreeModel_ItemBasePtr aLabelItem = TreeModel_ModelBase::GetItemByIndex (anIndexToBeSelected);
283 //DFBrowser_ItemPtr anItem = itemDynamicCast<DFBrowser_Item> (anItemBase);
284 for (int aChildId = 0, aNbChildren = aLabelItem->rowCount(); aChildId < aNbChildren; aChildId++)
286 QModelIndex anIndex = aTreeModel->index (aChildId, 0, anIndexToBeSelected);
287 TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
288 DFBrowser_ItemPtr anItem = itemDynamicCast<DFBrowser_Item> (anItemBase);
289 if (anItem->HasAttribute())
291 // processing attribute in theValue
292 DFBrowser_ItemApplicationPtr aRootAppItem = itemDynamicCast<DFBrowser_ItemApplication>(aTreeModel->RootItem (0));
293 QString anAttributeInfo = DFBrowser_Module::GetAttributeInfo (anItem->GetAttribute(), aRootAppItem->GetModule(),
294 Qt::DisplayRole, 0).toString();
295 if (anAttributeInfo == anAttributeType.ToCString())
297 anIndexToBeSelected = anIndex;
303 aSelectionModel->select (anIndexToBeSelected, QItemSelectionModel::Select);
304 myTreeView->scrollTo (anIndexToBeSelected);
308 myParameters->SetSelectedNames(aName, NCollection_List<TCollection_AsciiString>());
312 // =======================================================================
315 // =======================================================================
316 void DFBrowser_Window::Init (const NCollection_List<Handle(Standard_Transient)>& theParameters)
318 Handle(TDocStd_Application) anApplication;
321 DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
323 anApplication = anOCAFViewModel->GetTDocStdApplication();
325 Handle(AIS_InteractiveContext) aContext;
327 aContext = myModule->GetExternalContext();
329 bool aSameApplication = !anApplication.IsNull(), aSameContext = !aContext.IsNull();
330 for (NCollection_List<Handle(Standard_Transient)>::Iterator aParametersIt (theParameters);
331 aParametersIt.More(); aParametersIt.Next())
333 Handle(Standard_Transient) anObject = aParametersIt.Value();
334 // check if the object is an application
335 Handle(TDocStd_Application) anIApplication = Handle(TDocStd_Application)::DownCast (anObject);
336 if (!anIApplication.IsNull())
338 aSameApplication = anApplication == anIApplication;
339 if (!aSameApplication)
340 anApplication = anIApplication;
342 // check if the object is an interactive context
343 Handle(AIS_InteractiveContext) anIContext = Handle(AIS_InteractiveContext)::DownCast (anObject);
344 if (!anIContext.IsNull())
346 aSameContext = aContext == anIContext;
348 aContext = anIContext;
351 if (aSameApplication)
353 if (!aSameContext && !aContext.IsNull())
355 myModule->SetExternalContext (aContext);
356 myViewWindow->SetContext (View_ContextType_External, aContext);
361 myModule = new DFBrowser_Module();
362 myModule->CreateViewModel (myMainWindow);
364 myPropertyPanel->GetAttributesStack()->SetModule (myModule);
366 // model should be set after the attribute pane stack is initialized by module
367 QAbstractItemModel* aModel = myModule->GetOCAFViewModel();
368 setOCAFModel (aModel);
369 myModule->SetOCAFViewSelectionModel (myTreeView->selectionModel());
370 myTreeLevelLine->GetSearchLine()->SetModule (myModule);
371 myPropertyPanel->GetAttributesStack()->GetSearchView()->InitModels();
373 myShortcut->SetModule (myModule);
374 myThread->SetModule (myModule);
376 connect (myModule, SIGNAL (beforeUpdateTreeModel()), this, SLOT (onBeforeUpdateTreeModel()));
378 if (!aContext.IsNull())
380 myModule->SetExternalContext (aContext);
381 myViewWindow->SetContext (View_ContextType_External, aContext);
384 myModule->SetApplication (anApplication);
385 //! expand first three levels: CUSTOM
386 QModelIndex aParentIndex = aModel->index (0, 0);
387 setExpandedLevels (myTreeView, aParentIndex, 3/*levels*/);
389 myThread->ProcessApplication();
390 myModule->SetInitialTreeViewSelection();
393 // =======================================================================
394 // function : OpenFile
396 // =======================================================================
397 void DFBrowser_Window::OpenFile (const TCollection_AsciiString& theFileName)
399 QApplication::setOverrideCursor (Qt::WaitCursor);
400 myThread->TerminateThread();
402 myTreeLevelLine->ClearHistory();
403 QItemSelectionModel* aSelectionModel = myModule->GetOCAFViewSelectionModel();
406 aSelectionModel->clearSelection();
408 aSelectionModel->select (anIndex, QItemSelectionModel::ClearAndSelect);
412 myTreeLevelLine->ClearHistory();
414 DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
415 anOCAFViewModel->Reset();
417 //! close previous documents to open new document
418 Handle(TDocStd_Application) anApplication;
419 if (CDF_Session::Exists())
421 Handle(CDF_Session) aSession = CDF_Session::CurrentSession();
422 if (!aSession.IsNull())
424 anApplication = Handle(TDocStd_Application)::DownCast (CDF_Session::CurrentSession()->CurrentApplication());
425 if (!anApplication.IsNull())
427 for (int aDocId = 1, aNbDocuments = anApplication->NbDocuments(); aDocId <= aNbDocuments; aDocId++)
429 Handle(TDocStd_Document) aDocument;
430 anApplication->GetDocument (aDocId, aDocument);
431 if (!aDocument.IsNull())
432 anApplication->Close (aDocument);
437 //! open new document
438 bool isSTEPFileName = false;
439 anApplication = DFBrowser_OpenApplication::OpenApplication (theFileName, isSTEPFileName);
442 myParent->setObjectName (isSTEPFileName ? QString (TCollection_AsciiString (theFileName).ToCString()) : getWindowTitle());
444 if (anApplication.IsNull())
446 QApplication::restoreOverrideCursor();
447 QMessageBox::information (0, "Error", QString ("File %1 can't be opened by OCAF application")
448 .arg(TCollection_AsciiString (theFileName).ToCString()));
451 myModule->SetApplication (anApplication);
452 //! expand first three levels: CUSTOM
453 QModelIndex aParentIndex = anOCAFViewModel->index (0, 0);
454 setExpandedLevels (myTreeView, aParentIndex, 3/*levels*/);
456 myThread->ProcessApplication();
457 myModule->SetInitialTreeViewSelection();
458 QApplication::restoreOverrideCursor();
462 // =======================================================================
463 // function : getWindowTitle
465 // =======================================================================
466 QString DFBrowser_Window::getWindowTitle() const
468 DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
469 if (!anOCAFViewModel)
472 Handle(TDocStd_Application) anApplication = anOCAFViewModel->GetTDocStdApplication();
473 if (anApplication.IsNull() || anApplication->NbDocuments() == 0)
476 Handle(TDocStd_Document) aDocument;
477 anApplication->GetDocument (1, aDocument);
478 if (aDocument.IsNull() || !aDocument->IsSaved())
481 return DFBrowserPane_Tools::ToString (aDocument->GetPath());
484 // =======================================================================
485 // function : setExpandedLevels
487 // =======================================================================
488 void DFBrowser_Window::setExpandedLevels (QTreeView* theTreeView, const QModelIndex& theParentIndex, const int theLevels)
493 QAbstractItemModel* aModel = theTreeView->model();
497 theTreeView->setExpanded (theParentIndex, true);
498 for (int aRowId = 0, aRows = aModel->rowCount (theParentIndex); aRowId < aRows; aRowId++)
499 setExpandedLevels (theTreeView, aModel->index (aRowId, 0, theParentIndex), theLevels - 1);
502 // =======================================================================
503 // function : setOCAFModel
505 // =======================================================================
506 void DFBrowser_Window::setOCAFModel (QAbstractItemModel* theModel)
508 myTreeView->setModel (theModel);
509 myTreeView->setColumnWidth (0, OCAF_BROWSER_COLUMN_WIDTH_0);
511 QItemSelectionModel* aSelectionModel = new QItemSelectionModel (theModel);
512 myTreeView->setSelectionModel (aSelectionModel);
514 connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
515 myTreeLevelLine, SLOT (OnTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
516 connect(aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
517 myDumpView, SLOT (OnTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
518 connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
519 this, SLOT (onTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
522 // =======================================================================
523 // function : onBeforeUpdateTreeModel
525 // =======================================================================
526 void DFBrowser_Window::onBeforeUpdateTreeModel()
528 myTreeLevelLine->ClearHistory();
530 myThread->ProcessApplication();
533 // =======================================================================
534 // function : ClearThreadCache
536 // =======================================================================
537 void DFBrowser_Window::ClearThreadCache()
539 DFBrowser_ThreadItemUsedShapesMap::ClearSortedReferences (myModule);
540 DFBrowser_ThreadItemSearch::ClearValues (GetTreeLevelLine()->GetSearchLine());
543 // =======================================================================
544 // function : SetWhiteBackground
546 // =======================================================================
547 void DFBrowser_Window::SetWhiteBackground (QWidget* theControl)
549 QPalette aPalette = theControl->palette();
550 aPalette.setColor (QPalette::All, QPalette::Foreground, Qt::white);
551 theControl->setPalette (aPalette);
554 // =======================================================================
555 // function : TmpDirectory
557 // =======================================================================
558 TCollection_AsciiString DFBrowser_Window::TmpDirectory()
560 TCollection_AsciiString aTmpDir;
562 OSD_Environment anEnvironment ("TEMP");
563 aTmpDir = anEnvironment.Value();
564 if (aTmpDir.IsEmpty() )
566 anEnvironment.SetName("TMP");
567 aTmpDir = anEnvironment.Value();
568 if (aTmpDir.IsEmpty())
571 OSD_Path aTmpPath (aTmpDir);
572 OSD_Directory aTmpDirectory (aTmpPath);
573 if (!aTmpDirectory.Exists())
574 aTmpDirectory.Build(OSD_Protection());
576 OSD_Directory aTmpDirectory = OSD_Directory::BuildTemporary();
578 aTmpDirectory.Path (aTmpPath);
579 aTmpPath.SystemName(aTmpDir);
585 // =======================================================================
586 // function : SingleSelected
588 // =======================================================================
589 QModelIndex DFBrowser_Window::SingleSelected (const QModelIndexList& theIndices, const int theCellId,
590 const Qt::Orientation theOrientation)
592 QModelIndexList aFirstColumnSelectedIndices;
593 for (QModelIndexList::const_iterator anIndicesIt = theIndices.begin(), aLast = theIndices.end();
594 anIndicesIt != aLast; anIndicesIt++)
596 QModelIndex anIndex = *anIndicesIt;
597 if ((theOrientation == Qt::Horizontal && anIndex.column() == theCellId) ||
598 (theOrientation == Qt::Vertical && anIndex.row() == theCellId))
599 aFirstColumnSelectedIndices.append (anIndex);
601 return aFirstColumnSelectedIndices.size() == 1 ? aFirstColumnSelectedIndices.first() : QModelIndex();
604 // =======================================================================
605 // function : onTreeViewContextMenuRequested
607 // =======================================================================
608 void DFBrowser_Window::onTreeViewContextMenuRequested (const QPoint& thePosition)
610 QMenu* aMenu = new QMenu(GetMainWindow());
611 aMenu->addAction (createAction (tr ("Expand"), SLOT (onExpand())));
612 aMenu->addAction (createAction (tr ("Expand All"), SLOT (onExpandAll())));
613 aMenu->addAction (createAction (tr ("Collapse All"), SLOT (onCollapseAll())));
615 QPoint aPoint = myTreeView->mapToGlobal (thePosition);
616 aMenu->exec (aPoint);
619 // =======================================================================
620 // function : createAction
622 // =======================================================================
623 QAction* DFBrowser_Window::createAction (const QString& theText, const char* theSlot)
625 QAction* anAction = new QAction (theText, GetMainWindow());
626 connect (anAction, SIGNAL (triggered(bool)), this, theSlot);
630 // =======================================================================
631 // function : onExpand
633 // =======================================================================
634 void DFBrowser_Window::onExpand()
636 QApplication::setOverrideCursor (Qt::WaitCursor);
638 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
639 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
640 for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++)
643 setExpanded (myTreeView, aSelectedIndices[aSelectedId], true, aLevels);
645 QApplication::restoreOverrideCursor();
648 // =======================================================================
649 // function : onExpandAll
651 // =======================================================================
652 void DFBrowser_Window::onExpandAll()
654 QApplication::setOverrideCursor (Qt::WaitCursor);
656 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
657 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
658 for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++)
661 setExpanded (myTreeView, aSelectedIndices[aSelectedId], true, aLevels);
663 QApplication::restoreOverrideCursor();
666 // =======================================================================
667 // function : onCollapseAll
669 // =======================================================================
670 void DFBrowser_Window::onCollapseAll()
672 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
673 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
674 for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++) {
676 setExpanded (myTreeView, aSelectedIndices[aSelectedId], false, aLevels);
680 // =======================================================================
681 // function : onTreeViewSelectionChanged
683 // =======================================================================
684 void DFBrowser_Window::onTreeViewSelectionChanged (const QItemSelection& theSelected,
685 const QItemSelection& theDeselected)
689 // previuos selection should be cleared in the panel selectors
690 DFBrowser_AttributePaneStack* anAttributePaneStack = myPropertyPanel->GetAttributesStack();
691 anAttributePaneStack->GetPaneSelector()->ClearSelected();
693 myPropertyPanel->UpdateBySelectionChanged (theSelected, theDeselected);
694 anAttributePaneStack->GetTreeLevelView()->UpdateByTreeSelectionChanged (theSelected, theDeselected);
696 QModelIndexList aSelectedIndices = theSelected.indexes();
697 QModelIndex aSelectedIndex = DFBrowser_Window::SingleSelected (aSelectedIndices, 0);
699 myTreeView->scrollTo (aSelectedIndex);
700 View_Displayer* aDisplayer = myViewWindow->GetDisplayer();
702 aDisplayer->ErasePresentations (View_PresentationType_Additional, false);
703 aDisplayer->DisplayPresentation (findPresentation (aSelectedIndex), View_PresentationType_Main);
706 // =======================================================================
707 // function : onSearchActivated
709 // =======================================================================
710 void DFBrowser_Window::onSearchActivated()
712 myPropertyPanel->GetAttributesStack()->SetPaneMode ((myTreeLevelLine->GetSearchLine()->Text().isEmpty()
713 ? DFBrowser_AttributePaneType_ItemView : DFBrowser_AttributePaneType_SearchView));
716 // =======================================================================
717 // function : onPaneSelectionChanged
719 // =======================================================================
720 void DFBrowser_Window::onPaneSelectionChanged (const QItemSelection&,
721 const QItemSelection&,
722 QItemSelectionModel* theModel)
724 DFBrowserPane_AttributePaneAPI* anAttributePane = myPropertyPanel->GetAttributesStack()->GetCurrentPane();
725 switch (anAttributePane->GetSelectionKind (theModel))
727 case DFBrowserPane_SelectionKind_ExportToShapeViewer:
729 QItemSelectionModel* aSelectionModel = theModel;
730 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
731 if (aSelectedIndices.size() != 1)
734 TCollection_AsciiString aPluginName ("TKShapeView");
735 NCollection_List<Handle(Standard_Transient)> aParameters;
736 if (myParameters->FindParameters (aPluginName))
737 aParameters = myParameters->Parameters (aPluginName);
739 int aParametersCount = aParameters.Extent();
740 anAttributePane->GetSelectionParameters (aSelectionModel, aParameters);
741 if (aParametersCount != aParameters.Extent()) // some TShapes are added
743 TCollection_AsciiString aPluginShortName = aPluginName.SubString (3, aPluginName.Length());
744 QString aMessage = QString ("TShape %1 is sent to %2.")
745 .arg (DFBrowserPane_Tools::GetPointerInfo (aParameters.Last()).ToCString())
746 .arg (aPluginShortName.ToCString());
747 QString aQuestion = QString ("Would you like to activate %1 immediately?\n")
748 .arg (aPluginShortName.ToCString()).toStdString().c_str();
749 if (!myExportToShapeViewDialog)
750 myExportToShapeViewDialog = new TreeModel_MessageDialog (myParent, aMessage, aQuestion);
752 myExportToShapeViewDialog->SetInformation (aMessage);
753 myExportToShapeViewDialog->Start();
755 myParameters->SetParameters (aPluginName, aParameters, myExportToShapeViewDialog->IsAccepted());
759 case DFBrowserPane_SelectionKind_ExportToBREP:
760 case DFBrowserPane_SelectionKind_LabelReferences:
761 case DFBrowserPane_SelectionKind_AttributeReferences:
765 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
766 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
767 if (aSelectedIndices.size() != 1)
770 // make the shape visualized
771 QModelIndex aSelectedIndex = aSelectedIndices.first();
772 View_Displayer* aDisplayer = myViewWindow->GetDisplayer();
773 aDisplayer->DisplayPresentation (findPresentation (aSelectedIndex), View_PresentationType_Main);
775 // highlight and scroll to the referenced item if it exists
776 Handle(TDF_Attribute) anAttribute = myModule->FindAttribute (aSelectedIndex);
777 NCollection_List<TDF_Label> aReferences;
778 Handle(Standard_Transient) aPresentation;
779 anAttributePane->GetReferences (anAttribute, aReferences, aPresentation);
780 QModelIndexList anIndices;
781 DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
782 if (!aReferences.IsEmpty())
783 aTreeModel->ConvertToIndices (aReferences, anIndices);
785 NCollection_List<Handle(TDF_Attribute)> anAttributeReferences;
786 anAttributePane->GetAttributeReferences (anAttribute, anAttributeReferences, aPresentation);
787 aTreeModel->ConvertToIndices (anAttributeReferences, anIndices);
789 highlightIndices (anIndices);
790 // display either the reference presentation of the panel or find a presentation if the reference
792 if (!aPresentation.IsNull())
793 aDisplayer->DisplayPresentation (aPresentation, View_PresentationType_Additional);
795 aDisplayer->ErasePresentations (View_PresentationType_Additional, false);
796 AIS_ListOfInteractive aDisplayed;
797 findPresentations (anIndices, aDisplayed);
798 for (AIS_ListIteratorOfListOfInteractive aDisplayedIt (aDisplayed); aDisplayedIt.More(); aDisplayedIt.Next())
799 aDisplayer->DisplayPresentation (aDisplayedIt.Value(), View_PresentationType_Additional, false);
801 aDisplayer->UpdateViewer();
805 // =======================================================================
806 // function : onTreeLevelLineSelected
808 // =======================================================================
809 void DFBrowser_Window::onTreeLevelLineSelected (const QModelIndex& theIndex)
811 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
812 if (theIndex.isValid())
813 aSelectionModel->select (theIndex, QItemSelectionModel::ClearAndSelect);
815 aSelectionModel->clearSelection();
818 // =======================================================================
819 // function : onUpdateClicked
821 // =======================================================================
822 void DFBrowser_Window::onUpdateClicked()
825 myModule->UpdateTreeModel();
828 // =======================================================================
829 // function : onSearchPathSelected
831 // =======================================================================
832 void DFBrowser_Window::onSearchPathSelected (const QStringList& thePath, const QString& theValue)
834 DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
835 const QModelIndex& anIndex = aDFBrowserModel->FindIndexByPath (thePath, theValue);
837 if (anIndex.isValid())
839 QModelIndexList anIndices;
840 anIndices.append (anIndex);
841 highlightIndices (anIndices);
845 // =======================================================================
846 // function : onSearchPathDoubleClicked
848 // =======================================================================
849 void DFBrowser_Window::onSearchPathDoubleClicked (const QStringList& thePath, const QString& theValue)
851 DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
852 const QModelIndex& anIndex = aDFBrowserModel->FindIndexByPath (thePath, theValue);
854 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
855 if (anIndex.isValid())
856 aSelectionModel->select (anIndex, QItemSelectionModel::ClearAndSelect);
858 aSelectionModel->clearSelection();
861 // =======================================================================
862 // function : onLevelSelected
864 // =======================================================================
865 void DFBrowser_Window::onLevelSelected (const QModelIndex& theIndex)
867 if (!theIndex.isValid())
870 QModelIndexList anIndices;
871 anIndices.append (theIndex);
872 highlightIndices (anIndices);
873 View_Displayer* aDisplayer = myViewWindow->GetDisplayer();
874 aDisplayer->ErasePresentations (View_PresentationType_Additional, false);
875 aDisplayer->DisplayPresentation (findPresentation (theIndex), View_PresentationType_Main);
878 // =======================================================================
879 // function : onLevelDoubleClicked
881 // =======================================================================
882 void DFBrowser_Window::onLevelDoubleClicked (const QModelIndex& theIndex)
884 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
885 if (theIndex.isValid())
886 aSelectionModel->select (theIndex, QItemSelectionModel::ClearAndSelect);
888 aSelectionModel->clearSelection();
891 // =======================================================================
892 // function : highlightIndices
894 // =======================================================================
895 void DFBrowser_Window::highlightIndices (const QModelIndexList& theIndices)
897 QAbstractItemModel* aModel = myTreeView->model();
901 DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (aModel);
905 aTreeModel->SetHighlighted (theIndices);
907 QModelIndex anIndexToScroll;
908 if (!theIndices.isEmpty())
909 anIndexToScroll = theIndices.last(); // scroll to last selected index
912 // scroll to tree selected item
913 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
914 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
915 if (aSelectedIndices.size() == 1)
916 anIndexToScroll = aSelectedIndices.first();
918 if (anIndexToScroll.isValid())
919 myTreeView->scrollTo (anIndexToScroll);
921 if (theIndices.isEmpty())
922 myTreeView->setFocus(); // to see the selected item in active palette color
924 aTreeModel->EmitLayoutChanged();
927 // =======================================================================
928 // function : findPresentation
930 // =======================================================================
931 Handle(AIS_InteractiveObject) DFBrowser_Window::findPresentation (const QModelIndex& theIndex)
933 Handle(AIS_InteractiveObject) aPresentation;
935 QModelIndexList anIndices;
936 anIndices.append (theIndex);
937 AIS_ListOfInteractive aDisplayed;
938 findPresentations (anIndices, aDisplayed);
939 if (!aDisplayed.IsEmpty())
940 aPresentation = aDisplayed.First();
942 return aPresentation;
945 // =======================================================================
946 // function : findPresentations
948 // =======================================================================
949 void DFBrowser_Window::findPresentations (const QModelIndexList& theIndices, AIS_ListOfInteractive& thePresentations)
951 for (int anIndexId = 0, aCount = theIndices.size(); anIndexId < aCount; anIndexId++)
953 Handle(AIS_InteractiveObject) aPresentation;
954 Handle(TDF_Attribute) anAttribute = myModule->FindAttribute (theIndices[anIndexId]);
955 if (anAttribute.IsNull())
957 DFBrowserPane_AttributePaneAPI* anAttributePane = myModule->GetAttributePane (anAttribute);
958 if (!anAttributePane)
960 aPresentation = Handle(AIS_InteractiveObject)::DownCast (anAttributePane->GetPresentation (anAttribute));
961 if (aPresentation.IsNull())
964 thePresentations.Append (aPresentation);
968 // =======================================================================
969 // function : setExpanded
971 // =======================================================================
972 void DFBrowser_Window::setExpanded (QTreeView* theTreeView, const QModelIndex& theIndex, const bool isExpanded,
975 bool isToExpand = theLevels == -1 || theLevels > 0;
979 theTreeView->setExpanded (theIndex, isExpanded);
983 QAbstractItemModel* aModel = theTreeView->model();
984 for (int aRowId = 0, aRows = aModel->rowCount (theIndex); aRowId < aRows; aRowId++)
986 int aLevels = theLevels;
987 setExpanded (theTreeView, aModel->index (aRowId, 0, theIndex), isExpanded, aLevels);