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 <inspector/DFBrowserPane_AttributePaneAPI.hxx>
24 #include <inspector/DFBrowser_AttributePaneStack.hxx>
25 #include <inspector/DFBrowser_AttributePaneType.hxx>
26 #include <inspector/DFBrowser_DumpView.hxx>
27 #include <inspector/DFBrowser_Item.hxx>
28 #include <inspector/DFBrowser_ItemApplication.hxx>
29 #include <inspector/DFBrowser_Module.hxx>
30 #include <inspector/DFBrowser_OpenApplication.hxx>
31 #include <inspector/DFBrowser_PropertyPanel.hxx>
32 #include <inspector/DFBrowser_SearchLine.hxx>
33 #include <inspector/DFBrowser_SearchView.hxx>
34 #include <inspector/DFBrowser_Thread.hxx>
35 #include <inspector/DFBrowser_ThreadItemSearch.hxx>
36 #include <inspector/DFBrowser_Tools.hxx>
37 #include <inspector/DFBrowser_TreeLevelLine.hxx>
38 #include <inspector/DFBrowser_TreeLevelView.hxx>
39 #include <inspector/DFBrowser_TreeModel.hxx>
41 #include <inspector/DFBrowserPane_AttributePaneSelector.hxx>
42 #include <inspector/DFBrowserPane_SelectionKind.hxx>
43 #include <inspector/DFBrowserPane_Tools.hxx>
45 #include <inspector/TreeModel_ContextMenu.hxx>
46 #include <inspector/TreeModel_Tools.hxx>
48 #include <inspector/ViewControl_PropertyView.hxx>
49 #include <inspector/ViewControl_TreeView.hxx>
51 #include <OSD_Directory.hxx>
52 #include <OSD_Environment.hxx>
53 #include <OSD_Protection.hxx>
55 #include <inspector/View_Displayer.hxx>
56 #include <inspector/View_ToolBar.hxx>
57 #include <inspector/View_Viewer.hxx>
58 #include <inspector/View_Window.hxx>
60 #include <TDF_Tool.hxx>
61 #include <inspector/ViewControl_MessageDialog.hxx>
62 #include <inspector/ViewControl_Tools.hxx>
64 #include <Standard_WarningsDisable.hxx>
66 #include <QApplication>
69 #include <QDockWidget>
70 #include <QGridLayout>
72 #include <QMainWindow>
73 #include <QItemSelectionModel>
74 #include <QPushButton>
79 #include <QMessageBox>
82 #if QT_VERSION < 0x050000
83 #include <QWindowsStyle>
85 #include <QStyleFactory>
87 #include <Standard_WarningsRestore.hxx>
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 static Standard_Boolean MyIsUseDumpJson = Standard_False;
96 // =======================================================================
97 // function : Constructor
99 // =======================================================================
100 DFBrowser_Window::DFBrowser_Window()
101 : myModule (0), myParent (0), myPropertyPanel (0), myExportToShapeViewDialog (0)
103 myMainWindow = new QMainWindow (0);
106 myTreeView = new ViewControl_TreeView (myMainWindow);
107 myTreeView->setContextMenuPolicy (Qt::CustomContextMenu);
108 connect (myTreeView, SIGNAL (customContextMenuRequested (const QPoint&)),
109 this, SLOT (onTreeViewContextMenuRequested (const QPoint&)));
110 new TreeModel_ContextMenu (myTreeView);
111 ((ViewControl_TreeView*)myTreeView)->SetPredefinedSize (QSize (DFBROWSER_DEFAULT_TREE_VIEW_WIDTH,
112 DFBROWSER_DEFAULT_TREE_VIEW_HEIGHT));
113 myTreeView->setHeaderHidden (true);
114 myTreeView->setSortingEnabled (Standard_False);
115 myMainWindow->setCentralWidget (myTreeView);
117 #if QT_VERSION < 0x050000
118 myTreeView->setStyle (new QWindowsStyle);
120 myTreeView->setStyle (QStyleFactory::create("Windows"));
123 myTreeLevelLine = new DFBrowser_TreeLevelLine (myMainWindow);
124 connect (myTreeLevelLine->GetSearchLine(), SIGNAL (searchActivated()), this, SLOT (onSearchActivated()));
125 connect (myTreeLevelLine, SIGNAL (indexSelected (const QModelIndex&)),
126 this, SLOT (onTreeLevelLineSelected (const QModelIndex&)));
127 connect (myTreeLevelLine, SIGNAL (updateClicked()), this, SLOT (onUpdateClicked()));
129 QDockWidget* aTreeLineDockWidget = new QDockWidget (tr ("Tree Level Line"), myMainWindow);
130 aTreeLineDockWidget->setObjectName (aTreeLineDockWidget->windowTitle());
131 aTreeLineDockWidget->setTitleBarWidget (new QWidget(myMainWindow));
132 aTreeLineDockWidget->setWidget (myTreeLevelLine->GetControl());
133 myMainWindow->addDockWidget (Qt::TopDockWidgetArea, aTreeLineDockWidget);
136 myPropertyPanel = new DFBrowser_PropertyPanel (myMainWindow);
137 DFBrowser_AttributePaneStack* anAttributePaneStack = myPropertyPanel->GetAttributesStack();
138 anAttributePaneStack->GetSearchView()->SetSearchLine (myTreeLevelLine->GetSearchLine());
140 connect (anAttributePaneStack->GetPaneSelector(),
141 SIGNAL (tableSelectionChanged (const QItemSelection&, const QItemSelection&, QItemSelectionModel*)),
142 this, SLOT (onPaneSelectionChanged (const QItemSelection&, const QItemSelection&, QItemSelectionModel*)));
144 DFBrowser_SearchView* aSearchView = anAttributePaneStack->GetSearchView();
145 connect (aSearchView, SIGNAL (pathSelected (const QStringList&, const QString&)),
146 this, SLOT (onSearchPathSelected (const QStringList&, const QString&)));
147 connect (aSearchView, SIGNAL (pathDoubleClicked (const QStringList&, const QString&)),
148 this, SLOT (onSearchPathDoubleClicked (const QStringList&, const QString&)));
150 DFBrowser_TreeLevelView* aLevelView = anAttributePaneStack->GetTreeLevelView();
151 connect (aLevelView, SIGNAL (indexSelected (const QModelIndex&)), this, SLOT (onLevelSelected (const QModelIndex&)));
152 connect (aLevelView, SIGNAL (indexDoubleClicked (const QModelIndex&)),
153 this, SLOT (onLevelDoubleClicked (const QModelIndex&)));
155 // property custom panel with specific parameters of attributes
156 QDockWidget* aPropertyPanelWidget = new QDockWidget (tr ("PropertyPanel (custom)"), myMainWindow);
157 aPropertyPanelWidget->setObjectName (aPropertyPanelWidget->windowTitle());
158 aPropertyPanelWidget->setTitleBarWidget (new QWidget(myMainWindow));
159 aPropertyPanelWidget->setWidget (myPropertyPanel->GetControl());
160 myMainWindow->addDockWidget (Qt::RightDockWidgetArea, aPropertyPanelWidget);
163 myUseDumpJson = new QWidget(myMainWindow);
164 QVBoxLayout* aLay = new QVBoxLayout(myUseDumpJson);
165 QPushButton* aUseDumpJson = new QPushButton ("Use DumpJson", myMainWindow);
166 aLay->addWidget (aUseDumpJson);
168 connect(aUseDumpJson, SIGNAL (clicked (bool)), this, SLOT (onUseDumpJson()));
169 myUseDumpJson->setVisible (false);
171 myPropertyPanelWidget = new QDockWidget (tr ("PropertyPanel"), myMainWindow);
172 myPropertyView = new ViewControl_PropertyView (myMainWindow,
173 QSize(DFBROWSER_DEFAULT_VIEW_WIDTH, DFBROWSER_DEFAULT_VIEW_HEIGHT));
174 myPropertyPanelWidget->setObjectName (myPropertyPanelWidget->windowTitle());
175 myPropertyPanelWidget->setTitleBarWidget (new QWidget(myMainWindow));
176 myPropertyPanelWidget->setWidget (myPropertyView->GetControl());
177 updatePropertyPanelWidget();
178 myMainWindow->addDockWidget (Qt::RightDockWidgetArea, myPropertyPanelWidget);
181 QWidget* aDumpWidget = new QWidget(myMainWindow);
182 QVBoxLayout* aDumpLay = new QVBoxLayout(aDumpWidget);
183 aDumpLay->setMargin(0);
184 myDumpView = new DFBrowser_DumpView(aDumpWidget);
185 aDumpLay->addWidget(myDumpView->GetControl());
186 QDockWidget* aDumpDockWidget = new QDockWidget(tr("Dump"), myMainWindow);
187 aDumpDockWidget->setObjectName(aDumpDockWidget->windowTitle());
189 aDumpDockWidget->setWidget(aDumpWidget);
190 myMainWindow->addDockWidget(Qt::RightDockWidgetArea, aDumpDockWidget);
193 myViewWindow = new View_Window (myMainWindow);
194 myViewWindow->SetPredefinedSize (DFBROWSER_DEFAULT_VIEW_WIDTH, DFBROWSER_DEFAULT_VIEW_HEIGHT);
196 QDockWidget* aViewDockWidget = new QDockWidget (tr ("View"), myMainWindow);
197 aViewDockWidget->setObjectName (aViewDockWidget->windowTitle());
198 aViewDockWidget->setTitleBarWidget (myViewWindow->ViewToolBar()->GetControl());
199 aViewDockWidget->setWidget (myViewWindow);
200 myMainWindow->addDockWidget (Qt::RightDockWidgetArea, aViewDockWidget);
202 QColor aHColor (229, 243, 255);
203 myViewWindow->Displayer()->SetAttributeColor (Quantity_Color(aHColor.red() / 255., aHColor.green() / 255.,
204 aHColor.blue() / 255., Quantity_TOC_sRGB), View_PresentationType_Additional);
206 myMainWindow->splitDockWidget (myPropertyPanelWidget, aViewDockWidget, Qt::Vertical);
207 myMainWindow->tabifyDockWidget (myPropertyPanelWidget, aPropertyPanelWidget);
209 myMainWindow->tabifyDockWidget (aDumpDockWidget, aViewDockWidget);
211 myTreeView->resize (DFBROWSER_DEFAULT_TREE_VIEW_WIDTH, DFBROWSER_DEFAULT_TREE_VIEW_HEIGHT);
213 myThread = new DFBrowser_Thread (this);
216 // =======================================================================
217 // function : Destructor
219 // =======================================================================
220 DFBrowser_Window::~DFBrowser_Window()
225 // =======================================================================
226 // function : SetParent
228 // =======================================================================
229 void DFBrowser_Window::SetParent (void* theParent)
231 myParent = (QWidget*)theParent;
234 QLayout* aLayout = myParent->layout();
236 aLayout->addWidget (GetMainWindow());
238 if (!myOpenedFileName.isEmpty())
239 myParent->setObjectName(myOpenedFileName);
243 // =======================================================================
244 // function : FillActionsMenu
246 // =======================================================================
247 void DFBrowser_Window::FillActionsMenu (void* theMenu)
249 QMenu* aMenu = (QMenu*)theMenu;
250 QList<QDockWidget*> aDockwidgets = myMainWindow->findChildren<QDockWidget*>();
251 for (QList<QDockWidget*>::iterator it = aDockwidgets.begin(); it != aDockwidgets.end(); ++it)
253 QDockWidget* aDockWidget = *it;
254 if (aDockWidget->parentWidget() == myMainWindow)
255 aMenu->addAction (aDockWidget->toggleViewAction());
259 // =======================================================================
260 // function : GetPreferences
262 // =======================================================================
263 void DFBrowser_Window::GetPreferences (TInspectorAPI_PreferencesDataMap& theItem)
265 theItem.Bind ("geometry", TreeModel_Tools::ToString (myMainWindow->saveState()).toStdString().c_str());
267 QMap<QString, QString> anItems;
268 TreeModel_Tools::SaveState (myTreeView, anItems);
269 View_Window::SaveState(myViewWindow, anItems);
271 for (QMap<QString, QString>::const_iterator anItemsIt = anItems.begin(); anItemsIt != anItems.end(); anItemsIt++)
272 theItem.Bind (anItemsIt.key().toStdString().c_str(), anItemsIt.value().toStdString().c_str());
275 // =======================================================================
276 // function : SetPreferences
278 // =======================================================================
279 void DFBrowser_Window::SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem)
281 if (theItem.IsEmpty())
283 TreeModel_Tools::SetDefaultHeaderSections (myTreeView);
287 for (TInspectorAPI_IteratorOfPreferencesDataMap anItemIt (theItem); anItemIt.More(); anItemIt.Next())
289 if (anItemIt.Key().IsEqual ("geometry"))
290 myMainWindow->restoreState (TreeModel_Tools::ToByteArray (anItemIt.Value().ToCString()));
291 else if (TreeModel_Tools::RestoreState (myTreeView, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
293 else if (View_Window::RestoreState(myViewWindow, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
298 // =======================================================================
299 // function : UpdateContent
301 // =======================================================================
302 void DFBrowser_Window::UpdateContent()
304 TCollection_AsciiString aName = "TKDFBrowser";
306 if (myParameters->FindParameters (aName))
307 Init(myParameters->Parameters (aName));
309 Init(NCollection_List<Handle(Standard_Transient)>());
311 if (myParameters->FindFileNames(aName))
313 NCollection_List<TCollection_AsciiString> aFileNames = myParameters->FileNames (aName);
314 if (aFileNames.Extent() > 0) // only one document file might be opened
315 OpenFile (aFileNames.First());
316 myParameters->SetFileNames(aName, NCollection_List<TCollection_AsciiString>());
320 // make parameter items selected if defined
321 if (myParameters->FindSelectedNames(aName))
323 const NCollection_List<TCollection_AsciiString>& aSelected = myParameters->GetSelectedNames (aName);
325 DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
326 Handle(TDocStd_Application) anApplication = aTreeModel->GetTDocStdApplication();
328 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
329 aSelectionModel->clear();
331 NCollection_List<TCollection_AsciiString>::Iterator aSelectedIt (aSelected);
332 if (aSelectedIt.More())
334 TCollection_AsciiString aLabelEntry = aSelectedIt.Value();
337 for (Standard_Integer aDocId = 1, aNbDoc = anApplication->NbDocuments(); aDocId <= aNbDoc; aDocId++)
339 Handle(TDocStd_Document) aDocument;
340 anApplication->GetDocument (aDocId, aDocument);
342 TDF_Tool::Label(aDocument->GetData(), aLabelEntry.ToCString(), aLabel, Standard_False);
343 if (!aLabel.IsNull())
346 if (!aLabel.IsNull())
348 QModelIndex anIndexToBeSelected = aTreeModel->FindIndex (aLabel);
350 TCollection_AsciiString anAttributeType;
352 // find attribute by attribute type on the given label
353 if (aSelectedIt.More())
355 anAttributeType = aSelectedIt.Value();
357 TreeModel_ItemBasePtr aLabelItem = TreeModel_ModelBase::GetItemByIndex (anIndexToBeSelected);
358 //DFBrowser_ItemPtr anItem = itemDynamicCast<DFBrowser_Item> (anItemBase);
359 for (int aChildId = 0, aNbChildren = aLabelItem->rowCount(); aChildId < aNbChildren; aChildId++)
361 QModelIndex anIndex = aTreeModel->index (aChildId, 0, anIndexToBeSelected);
362 TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
363 DFBrowser_ItemPtr anItem = itemDynamicCast<DFBrowser_Item> (anItemBase);
364 if (anItem->HasAttribute())
366 // processing attribute in theValue
367 DFBrowser_ItemApplicationPtr aRootAppItem = itemDynamicCast<DFBrowser_ItemApplication>(aTreeModel->RootItem (0));
368 QString anAttributeInfo = DFBrowser_Module::GetAttributeInfo (anItem->GetAttribute(), aRootAppItem->GetModule(),
369 Qt::DisplayRole, 0).toString();
370 if (anAttributeInfo == anAttributeType.ToCString())
372 anIndexToBeSelected = anIndex;
378 aSelectionModel->select (anIndexToBeSelected, QItemSelectionModel::Select);
379 myTreeView->scrollTo (anIndexToBeSelected);
383 myParameters->SetSelectedNames(aName, NCollection_List<TCollection_AsciiString>());
387 // =======================================================================
390 // =======================================================================
391 void DFBrowser_Window::Init (const NCollection_List<Handle(Standard_Transient)>& theParameters)
393 Handle(TDocStd_Application) anApplication;
396 DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
398 anApplication = anOCAFViewModel->GetTDocStdApplication();
400 Handle(AIS_InteractiveContext) aContext;
402 aContext = myModule->GetExternalContext();
404 bool aSameApplication = !anApplication.IsNull(), aSameContext = !aContext.IsNull();
405 for (NCollection_List<Handle(Standard_Transient)>::Iterator aParametersIt (theParameters);
406 aParametersIt.More(); aParametersIt.Next())
408 Handle(Standard_Transient) anObject = aParametersIt.Value();
409 // check if the object is an application
410 Handle(TDocStd_Application) anIApplication = Handle(TDocStd_Application)::DownCast (anObject);
411 if (!anIApplication.IsNull())
413 aSameApplication = anApplication == anIApplication;
414 if (!aSameApplication)
415 anApplication = anIApplication;
417 // check if the object is an interactive context
418 Handle(AIS_InteractiveContext) anIContext = Handle(AIS_InteractiveContext)::DownCast (anObject);
419 if (!anIContext.IsNull())
421 aSameContext = aContext == anIContext;
423 aContext = anIContext;
426 if (aSameApplication)
428 if (!aSameContext && !aContext.IsNull())
430 myModule->SetExternalContext (aContext);
431 myViewWindow->SetContext (View_ContextType_External, aContext);
436 myModule = new DFBrowser_Module();
437 myModule->CreateViewModel (myMainWindow);
439 myPropertyPanel->GetAttributesStack()->SetModule (myModule);
441 // model should be set after the attribute pane stack is initialized by module
442 QAbstractItemModel* aModel = myModule->GetOCAFViewModel();
443 setOCAFModel (aModel);
444 myModule->SetOCAFViewSelectionModel (myTreeView->selectionModel());
445 myTreeLevelLine->GetSearchLine()->SetModule (myModule);
446 myPropertyPanel->GetAttributesStack()->GetSearchView()->InitModels();
448 connect (myModule, SIGNAL (beforeUpdateTreeModel()), this, SLOT (onBeforeUpdateTreeModel()));
450 if (!aContext.IsNull())
452 myModule->SetExternalContext (aContext);
453 myViewWindow->SetContext (View_ContextType_External, aContext);
456 myModule->SetApplication (anApplication);
457 //! expand first three levels: CUSTOM
458 QModelIndex aParentIndex = aModel->index (0, 0);
459 setExpandedLevels (myTreeView, aParentIndex, 3/*levels*/);
461 myThread->ProcessApplication();
462 myModule->SetInitialTreeViewSelection();
465 // =======================================================================
466 // function : OpenFile
468 // =======================================================================
469 void DFBrowser_Window::OpenFile (const TCollection_AsciiString& theFileName)
471 QApplication::setOverrideCursor (Qt::WaitCursor);
472 myThread->TerminateThread();
474 myTreeLevelLine->ClearHistory();
475 QItemSelectionModel* aSelectionModel = myModule->GetOCAFViewSelectionModel();
478 aSelectionModel->clearSelection();
480 aSelectionModel->select (anIndex, QItemSelectionModel::ClearAndSelect);
484 myTreeLevelLine->ClearHistory();
486 DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
487 anOCAFViewModel->Reset();
489 //! close previous documents to open new document
490 Handle(TDocStd_Application) anApplication = myModule->GetTDocStdApplication();
491 if (!anApplication.IsNull())
493 for (int aDocId = 1, aNbDocuments = anApplication->NbDocuments(); aDocId <= aNbDocuments; aDocId++)
495 Handle(TDocStd_Document) aDocument;
496 anApplication->GetDocument (aDocId, aDocument);
497 if (!aDocument.IsNull())
498 anApplication->Close (aDocument);
502 //! open new document
503 bool isSTEPFileName = false;
504 anApplication = DFBrowser_OpenApplication::OpenApplication (theFileName, isSTEPFileName);
507 myParent->setObjectName (isSTEPFileName ? QString (TCollection_AsciiString (theFileName).ToCString()) : getWindowTitle());
509 myOpenedFileName = isSTEPFileName ? QString(TCollection_AsciiString(theFileName).ToCString()) : getWindowTitle();
511 if (anApplication.IsNull())
513 QApplication::restoreOverrideCursor();
514 QMessageBox::information (0, "Error", QString ("File %1 can't be opened by OCAF application")
515 .arg(TCollection_AsciiString (theFileName).ToCString()));
518 myModule->SetApplication (anApplication);
519 //! expand first three levels: CUSTOM
520 QModelIndex aParentIndex = anOCAFViewModel->index (0, 0);
521 setExpandedLevels (myTreeView, aParentIndex, 3/*levels*/);
523 myThread->ProcessApplication();
524 myModule->SetInitialTreeViewSelection();
525 QApplication::restoreOverrideCursor();
529 // =======================================================================
530 // function : getWindowTitle
532 // =======================================================================
533 QString DFBrowser_Window::getWindowTitle() const
535 DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
536 if (!anOCAFViewModel)
539 Handle(TDocStd_Application) anApplication = anOCAFViewModel->GetTDocStdApplication();
540 if (anApplication.IsNull() || anApplication->NbDocuments() == 0)
543 Handle(TDocStd_Document) aDocument;
544 anApplication->GetDocument (1, aDocument);
545 if (aDocument.IsNull() || !aDocument->IsSaved())
548 return DFBrowserPane_Tools::ToString (aDocument->GetPath());
551 // =======================================================================
552 // function : setExpandedLevels
554 // =======================================================================
555 void DFBrowser_Window::setExpandedLevels (QTreeView* theTreeView, const QModelIndex& theParentIndex, const int theLevels)
560 QAbstractItemModel* aModel = theTreeView->model();
564 theTreeView->setExpanded (theParentIndex, true);
565 for (int aRowId = 0, aRows = aModel->rowCount (theParentIndex); aRowId < aRows; aRowId++)
566 setExpandedLevels (theTreeView, aModel->index (aRowId, 0, theParentIndex), theLevels - 1);
569 // =======================================================================
570 // function : setOCAFModel
572 // =======================================================================
573 void DFBrowser_Window::setOCAFModel (QAbstractItemModel* theModel)
575 myTreeView->setModel (theModel);
577 QItemSelectionModel* aSelectionModel = new QItemSelectionModel (theModel);
578 myTreeView->setSelectionModel (aSelectionModel);
580 connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
581 myTreeLevelLine, SLOT (OnTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
582 connect(aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
583 myDumpView, SLOT (OnTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
584 connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
585 this, SLOT (onTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
588 // =======================================================================
589 // function : onBeforeUpdateTreeModel
591 // =======================================================================
592 void DFBrowser_Window::onBeforeUpdateTreeModel()
594 myTreeLevelLine->ClearHistory();
596 myThread->ProcessApplication();
599 // =======================================================================
600 // function : ClearThreadCache
602 // =======================================================================
603 void DFBrowser_Window::ClearThreadCache()
605 DFBrowser_ThreadItemSearch::ClearValues (GetTreeLevelLine()->GetSearchLine());
608 // =======================================================================
609 // function : TmpDirectory
611 // =======================================================================
612 TCollection_AsciiString DFBrowser_Window::TmpDirectory()
614 TCollection_AsciiString aTmpDir;
616 OSD_Environment anEnvironment ("TEMP");
617 aTmpDir = anEnvironment.Value();
618 if (aTmpDir.IsEmpty() )
620 anEnvironment.SetName("TMP");
621 aTmpDir = anEnvironment.Value();
622 if (aTmpDir.IsEmpty())
625 OSD_Path aTmpPath (aTmpDir);
626 OSD_Directory aTmpDirectory (aTmpPath);
627 if (!aTmpDirectory.Exists())
628 aTmpDirectory.Build(OSD_Protection());
630 OSD_Directory aTmpDirectory = OSD_Directory::BuildTemporary();
632 aTmpDirectory.Path (aTmpPath);
633 aTmpPath.SystemName(aTmpDir);
639 // =======================================================================
640 // function : SetUseDumpJson
642 // =======================================================================
643 void DFBrowser_Window::SetUseDumpJson (const Standard_Boolean theValue)
645 MyIsUseDumpJson = theValue;
648 // =======================================================================
649 // function : IsUseDumpJson
651 // =======================================================================
652 Standard_Boolean DFBrowser_Window::IsUseDumpJson()
654 return MyIsUseDumpJson;
657 // =======================================================================
658 // function : onTreeViewContextMenuRequested
660 // =======================================================================
661 void DFBrowser_Window::onTreeViewContextMenuRequested (const QPoint& thePosition)
663 QMenu* aMenu = new QMenu(GetMainWindow());
664 aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Expand"), SLOT (onExpand()), GetMainWindow(), this));
665 aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Expand All"), SLOT (onExpandAll()), GetMainWindow(), this));
666 aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Collapse All"), SLOT (onCollapseAll()), GetMainWindow(), this));
668 aMenu->addSeparator();
669 QAction* aUseDumpJsonAction = ViewControl_Tools::CreateAction (tr ("Use DumpJson"), SLOT (onUseDumpJson()), GetMainWindow(), this);
670 aUseDumpJsonAction->setCheckable(true);
671 aUseDumpJsonAction->setChecked (IsUseDumpJson());
672 aMenu->addAction (aUseDumpJsonAction);
674 QPoint aPoint = myTreeView->mapToGlobal (thePosition);
675 aMenu->exec (aPoint);
678 // =======================================================================
679 // function : onExpand
681 // =======================================================================
682 void DFBrowser_Window::onExpand()
684 QApplication::setOverrideCursor (Qt::WaitCursor);
686 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
687 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
688 for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++)
691 TreeModel_Tools::SetExpanded (myTreeView, aSelectedIndices[aSelectedId], true, aLevels);
693 QApplication::restoreOverrideCursor();
696 // =======================================================================
697 // function : onExpandAll
699 // =======================================================================
700 void DFBrowser_Window::onExpandAll()
702 QApplication::setOverrideCursor (Qt::WaitCursor);
704 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
705 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
706 for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++)
709 TreeModel_Tools::SetExpanded (myTreeView, aSelectedIndices[aSelectedId], true, aLevels);
711 QApplication::restoreOverrideCursor();
714 // =======================================================================
715 // function : onCollapseAll
717 // =======================================================================
718 void DFBrowser_Window::onCollapseAll()
720 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
721 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
722 for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++) {
724 TreeModel_Tools::SetExpanded (myTreeView, aSelectedIndices[aSelectedId], false, aLevels);
728 // =======================================================================
729 // function : onUseDumpJson
731 // =======================================================================
732 void DFBrowser_Window::onUseDumpJson()
734 SetUseDumpJson(!IsUseDumpJson());
735 updatePropertyPanelWidget();
737 QApplication::setOverrideCursor (Qt::WaitCursor);
738 myModule->UpdateTreeModel();
739 QApplication::restoreOverrideCursor();
742 // =======================================================================
743 // function : onTreeViewSelectionChanged
745 // =======================================================================
746 void DFBrowser_Window::onTreeViewSelectionChanged (const QItemSelection& theSelected,
747 const QItemSelection& theDeselected)
752 if (IsUseDumpJson() && myPropertyPanelWidget->toggleViewAction()->isChecked())
754 myPropertyView->Init (ViewControl_Tools::CreateTableModelValues (myTreeView->selectionModel()));
757 // previuos selection should be cleared in the panel selectors
758 DFBrowser_AttributePaneStack* anAttributePaneStack = myPropertyPanel->GetAttributesStack();
759 anAttributePaneStack->GetPaneSelector()->ClearSelected();
761 myPropertyPanel->UpdateBySelectionChanged (theSelected, theDeselected);
762 anAttributePaneStack->GetTreeLevelView()->UpdateByTreeSelectionChanged (theSelected, theDeselected);
764 QModelIndexList aSelectedIndices = theSelected.indexes();
765 QModelIndex aSelectedIndex = TreeModel_ModelBase::SingleSelected (aSelectedIndices, 0);
767 myTreeView->scrollTo (aSelectedIndex);
768 View_Displayer* aDisplayer = myViewWindow->Displayer();
770 aDisplayer->ErasePresentations (View_PresentationType_Additional, false);
771 aDisplayer->DisplayPresentation (findPresentation (aSelectedIndex), View_PresentationType_Main);
774 // =======================================================================
775 // function : onSearchActivated
777 // =======================================================================
778 void DFBrowser_Window::onSearchActivated()
780 myPropertyPanel->GetAttributesStack()->SetPaneMode ((myTreeLevelLine->GetSearchLine()->Text().isEmpty()
781 ? DFBrowser_AttributePaneType_ItemView : DFBrowser_AttributePaneType_SearchView));
784 // =======================================================================
785 // function : onPaneSelectionChanged
787 // =======================================================================
788 void DFBrowser_Window::onPaneSelectionChanged (const QItemSelection&,
789 const QItemSelection&,
790 QItemSelectionModel* theModel)
792 DFBrowserPane_AttributePaneAPI* anAttributePane = myPropertyPanel->GetAttributesStack()->GetCurrentPane();
793 switch (anAttributePane->GetSelectionKind (theModel))
795 case DFBrowserPane_SelectionKind_ExportToShapeViewer:
797 QItemSelectionModel* aSelectionModel = theModel;
798 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
799 if (aSelectedIndices.size() != 1)
802 TCollection_AsciiString aPluginName ("TKShapeView");
803 NCollection_List<Handle(Standard_Transient)> aParameters;
804 if (myParameters->FindParameters (aPluginName))
805 aParameters = myParameters->Parameters (aPluginName);
807 NCollection_List<TCollection_AsciiString> anItemNames;
808 if (myParameters->FindSelectedNames (aPluginName))
809 anItemNames = myParameters->GetSelectedNames (aPluginName);
811 int aParametersCount = aParameters.Extent();
812 anAttributePane->GetSelectionParameters (aSelectionModel, aParameters, anItemNames);
813 if (aParametersCount != aParameters.Extent()) // some TShapes are added
815 TCollection_AsciiString aPluginShortName = aPluginName.SubString (3, aPluginName.Length());
816 QString aMessage = QString ("TShape %1 is sent to %2.")
817 .arg (Standard_Dump::GetPointerInfo (aParameters.Last()).ToCString())
818 .arg (aPluginShortName.ToCString());
819 QString aQuestion = QString ("Would you like to activate %1 immediately?\n")
820 .arg (aPluginShortName.ToCString()).toStdString().c_str();
821 if (!myExportToShapeViewDialog)
822 myExportToShapeViewDialog = new ViewControl_MessageDialog (myParent, aMessage, aQuestion);
824 myExportToShapeViewDialog->SetInformation (aMessage);
825 myExportToShapeViewDialog->Start();
827 myParameters->SetSelectedNames (aPluginName, anItemNames);
828 myParameters->SetParameters (aPluginName, aParameters, myExportToShapeViewDialog->IsAccepted());
832 case DFBrowserPane_SelectionKind_ExportToBREP:
833 case DFBrowserPane_SelectionKind_LabelReferences:
834 case DFBrowserPane_SelectionKind_AttributeReferences:
838 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
839 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
840 if (aSelectedIndices.size() != 1)
843 // make the shape visualized
844 QModelIndex aSelectedIndex = aSelectedIndices.first();
845 View_Displayer* aDisplayer = myViewWindow->Displayer();
846 aDisplayer->DisplayPresentation (findPresentation (aSelectedIndex), View_PresentationType_Main);
848 // highlight and scroll to the referenced item if it exists
849 Handle(TDF_Attribute) anAttribute = myModule->FindAttribute (aSelectedIndex);
850 NCollection_List<TDF_Label> aReferences;
851 Handle(Standard_Transient) aPresentation;
852 anAttributePane->GetReferences (anAttribute, aReferences, aPresentation);
853 QModelIndexList anIndices;
854 DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
855 if (!aReferences.IsEmpty())
856 aTreeModel->ConvertToIndices (aReferences, anIndices);
858 NCollection_List<Handle(TDF_Attribute)> anAttributeReferences;
859 anAttributePane->GetAttributeReferences (anAttribute, anAttributeReferences, aPresentation);
860 aTreeModel->ConvertToIndices (anAttributeReferences, anIndices);
862 highlightIndices (anIndices);
863 // display either the reference presentation of the panel or find a presentation if the reference
865 if (!aPresentation.IsNull())
866 aDisplayer->DisplayPresentation (aPresentation, View_PresentationType_Additional);
868 aDisplayer->ErasePresentations (View_PresentationType_Additional, false);
869 AIS_ListOfInteractive aDisplayed;
870 findPresentations (anIndices, aDisplayed);
871 for (AIS_ListIteratorOfListOfInteractive aDisplayedIt (aDisplayed); aDisplayedIt.More(); aDisplayedIt.Next())
872 aDisplayer->DisplayPresentation (aDisplayedIt.Value(), View_PresentationType_Additional, false);
874 aDisplayer->UpdateViewer();
878 // =======================================================================
879 // function : onTreeLevelLineSelected
881 // =======================================================================
882 void DFBrowser_Window::onTreeLevelLineSelected (const QModelIndex& theIndex)
884 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
885 if (theIndex.isValid())
886 aSelectionModel->select (theIndex, QItemSelectionModel::ClearAndSelect);
888 aSelectionModel->clearSelection();
891 // =======================================================================
892 // function : onUpdateClicked
894 // =======================================================================
895 void DFBrowser_Window::onUpdateClicked()
898 myModule->UpdateTreeModel();
901 // =======================================================================
902 // function : onSearchPathSelected
904 // =======================================================================
905 void DFBrowser_Window::onSearchPathSelected (const QStringList& thePath, const QString& theValue)
907 DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
908 const QModelIndex& anIndex = aDFBrowserModel->FindIndexByPath (thePath, theValue);
910 if (anIndex.isValid())
912 QModelIndexList anIndices;
913 anIndices.append (anIndex);
914 highlightIndices (anIndices);
918 // =======================================================================
919 // function : onSearchPathDoubleClicked
921 // =======================================================================
922 void DFBrowser_Window::onSearchPathDoubleClicked (const QStringList& thePath, const QString& theValue)
924 DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
925 const QModelIndex& anIndex = aDFBrowserModel->FindIndexByPath (thePath, theValue);
927 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
928 if (anIndex.isValid())
929 aSelectionModel->select (anIndex, QItemSelectionModel::ClearAndSelect);
931 aSelectionModel->clearSelection();
934 // =======================================================================
935 // function : onLevelSelected
937 // =======================================================================
938 void DFBrowser_Window::onLevelSelected (const QModelIndex& theIndex)
940 if (!theIndex.isValid())
943 QModelIndexList anIndices;
944 anIndices.append (theIndex);
945 highlightIndices (anIndices);
946 View_Displayer* aDisplayer = myViewWindow->Displayer();
947 aDisplayer->ErasePresentations (View_PresentationType_Additional, false);
948 aDisplayer->DisplayPresentation (findPresentation (theIndex), View_PresentationType_Main);
951 // =======================================================================
952 // function : onLevelDoubleClicked
954 // =======================================================================
955 void DFBrowser_Window::onLevelDoubleClicked (const QModelIndex& theIndex)
957 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
958 if (theIndex.isValid())
959 aSelectionModel->select (theIndex, QItemSelectionModel::ClearAndSelect);
961 aSelectionModel->clearSelection();
964 // =======================================================================
965 // function : highlightIndices
967 // =======================================================================
968 void DFBrowser_Window::highlightIndices (const QModelIndexList& theIndices)
970 QAbstractItemModel* aModel = myTreeView->model();
974 DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (aModel);
978 aTreeModel->SetHighlighted (theIndices);
980 QModelIndex anIndexToScroll;
981 if (!theIndices.isEmpty())
982 anIndexToScroll = theIndices.last(); // scroll to last selected index
985 // scroll to tree selected item
986 QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
987 QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
988 if (aSelectedIndices.size() == 1)
989 anIndexToScroll = aSelectedIndices.first();
991 if (anIndexToScroll.isValid())
992 myTreeView->scrollTo (anIndexToScroll);
994 if (theIndices.isEmpty())
995 myTreeView->setFocus(); // to see the selected item in active palette color
997 aTreeModel->EmitLayoutChanged();
1000 // =======================================================================
1001 // function : findPresentation
1003 // =======================================================================
1004 Handle(AIS_InteractiveObject) DFBrowser_Window::findPresentation (const QModelIndex& theIndex)
1006 Handle(AIS_InteractiveObject) aPresentation;
1008 QModelIndexList anIndices;
1009 anIndices.append (theIndex);
1010 AIS_ListOfInteractive aDisplayed;
1011 findPresentations (anIndices, aDisplayed);
1012 if (!aDisplayed.IsEmpty())
1013 aPresentation = aDisplayed.First();
1015 return aPresentation;
1018 // =======================================================================
1019 // function : findPresentations
1021 // =======================================================================
1022 void DFBrowser_Window::findPresentations (const QModelIndexList& theIndices, AIS_ListOfInteractive& thePresentations)
1024 for (int anIndexId = 0, aCount = theIndices.size(); anIndexId < aCount; anIndexId++)
1026 Handle(AIS_InteractiveObject) aPresentation;
1027 Handle(TDF_Attribute) anAttribute = myModule->FindAttribute (theIndices[anIndexId]);
1028 if (anAttribute.IsNull())
1030 DFBrowserPane_AttributePaneAPI* anAttributePane = myModule->GetAttributePane (anAttribute);
1031 if (!anAttributePane)
1033 aPresentation = Handle(AIS_InteractiveObject)::DownCast (anAttributePane->GetPresentation (anAttribute));
1034 if (aPresentation.IsNull())
1037 thePresentations.Append (aPresentation);
1041 // =======================================================================
1042 // function : updatePropertyPanelWidget
1044 // =======================================================================
1045 void DFBrowser_Window::updatePropertyPanelWidget()
1047 bool aUseDumpJson = IsUseDumpJson();
1049 myUseDumpJson->setVisible (!aUseDumpJson);
1050 myPropertyPanelWidget->setWidget (aUseDumpJson ? myPropertyView->GetControl() : myUseDumpJson);