0032429: Coding - Warnings during compilation on macosx arm64 with option BUILD_Inspe...
[occt.git] / tools / DFBrowser / DFBrowser_Window.cxx
1 // Created on: 2017-06-16
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2017 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement. 
15
16 #include <inspector/DFBrowser_Window.hxx>
17
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_InteractiveObject.hxx>
20 #include <AIS_ListOfInteractive.hxx>
21
22 #include <inspector/DFBrowserPane_AttributePaneAPI.hxx>
23
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>
40
41 #include <inspector/DFBrowserPane_AttributePaneSelector.hxx>
42 #include <inspector/DFBrowserPane_SelectionKind.hxx>
43 #include <inspector/DFBrowserPane_Tools.hxx>
44
45 #include <inspector/TreeModel_ContextMenu.hxx>
46 #include <inspector/TreeModel_Tools.hxx>
47
48 #include <inspector/ViewControl_PropertyView.hxx>
49 #include <inspector/ViewControl_TreeView.hxx>
50
51 #include <OSD_Directory.hxx>
52 #include <OSD_Environment.hxx>
53 #include <OSD_Protection.hxx>
54
55 #include <inspector/View_Displayer.hxx>
56 #include <inspector/View_ToolBar.hxx>
57 #include <inspector/View_Viewer.hxx>
58 #include <inspector/View_Window.hxx>
59
60 #include <TDF_Tool.hxx>
61 #include <inspector/ViewControl_MessageDialog.hxx>
62 #include <inspector/ViewControl_Tools.hxx>
63
64 #include <Standard_WarningsDisable.hxx>
65 #include <QAction>
66 #include <QApplication>
67 #include <QComboBox>
68 #include <QDir>
69 #include <QDockWidget>
70 #include <QGridLayout>
71 #include <QList>
72 #include <QMainWindow>
73 #include <QItemSelectionModel>
74 #include <QPushButton>
75 #include <QTabWidget>
76 #include <QToolBar>
77 #include <QTreeView>
78 #include <QMenu>
79 #include <QMessageBox>
80 #include <QStatusBar>
81 #include <QWidget>
82 #if QT_VERSION < 0x050000
83 #include <QWindowsStyle>
84 #else
85 #include <QStyleFactory>
86 #endif
87 #include <Standard_WarningsRestore.hxx>
88
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;
93
94 static Standard_Boolean MyIsUseDumpJson = Standard_False;
95
96 // =======================================================================
97 // function : Constructor
98 // purpose :
99 // =======================================================================
100 DFBrowser_Window::DFBrowser_Window()
101 : myModule (0), myParent (0), myPropertyPanel (0), myExportToShapeViewDialog (0)
102 {
103   myMainWindow = new QMainWindow (0);
104
105   // tree view
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);
116
117 #if QT_VERSION < 0x050000
118   myTreeView->setStyle (new QWindowsStyle);
119 #else
120   myTreeView->setStyle (QStyleFactory::create("Windows"));
121 #endif
122
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()));
128
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);
134
135   // property panel
136   myPropertyPanel = new DFBrowser_PropertyPanel (myMainWindow);
137   DFBrowser_AttributePaneStack* anAttributePaneStack = myPropertyPanel->GetAttributesStack();
138   anAttributePaneStack->GetSearchView()->SetSearchLine (myTreeLevelLine->GetSearchLine());
139
140   connect (anAttributePaneStack->GetPaneSelector(),
141            SIGNAL (tableSelectionChanged (const QItemSelection&, const QItemSelection&, QItemSelectionModel*)),
142            this, SLOT (onPaneSelectionChanged (const QItemSelection&, const QItemSelection&, QItemSelectionModel*)));
143
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&)));
149
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&)));
154
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);
161
162   // property panel
163   myUseDumpJson = new QWidget(myMainWindow);
164   QVBoxLayout* aLay = new QVBoxLayout(myUseDumpJson);
165   QPushButton* aUseDumpJson = new QPushButton ("Use DumpJson", myMainWindow);
166   aLay->addWidget (aUseDumpJson);
167   aLay->addStretch(1);
168   connect(aUseDumpJson, SIGNAL (clicked (bool)), this, SLOT (onUseDumpJson()));
169   myUseDumpJson->setVisible (false);
170
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);
179
180   // dump view window
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());
188
189   aDumpDockWidget->setWidget(aDumpWidget);
190   myMainWindow->addDockWidget(Qt::RightDockWidgetArea, aDumpDockWidget);
191
192   // view
193   myViewWindow = new View_Window (myMainWindow);
194   myViewWindow->SetPredefinedSize (DFBROWSER_DEFAULT_VIEW_WIDTH, DFBROWSER_DEFAULT_VIEW_HEIGHT);
195
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);
201
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);
205
206   myMainWindow->splitDockWidget (myPropertyPanelWidget, aViewDockWidget, Qt::Vertical);
207   myMainWindow->tabifyDockWidget (myPropertyPanelWidget, aPropertyPanelWidget);
208
209   myMainWindow->tabifyDockWidget (aDumpDockWidget, aViewDockWidget);
210
211   myTreeView->resize (DFBROWSER_DEFAULT_TREE_VIEW_WIDTH, DFBROWSER_DEFAULT_TREE_VIEW_HEIGHT);
212
213   myThread = new DFBrowser_Thread (this);
214 }
215
216 // =======================================================================
217 // function : Destructor
218 // purpose :
219 // =======================================================================
220 DFBrowser_Window::~DFBrowser_Window()
221 {
222   delete myModule;
223 }
224
225 // =======================================================================
226 // function : SetParent
227 // purpose :
228 // =======================================================================
229 void DFBrowser_Window::SetParent (void* theParent)
230 {
231   myParent = (QWidget*)theParent;
232   if (myParent)
233   {
234     QLayout* aLayout = myParent->layout();
235     if (aLayout)
236       aLayout->addWidget (GetMainWindow());
237
238     if (!myOpenedFileName.isEmpty())
239       myParent->setObjectName(myOpenedFileName);
240   }
241 }
242
243 // =======================================================================
244 // function : FillActionsMenu
245 // purpose :
246 // =======================================================================
247 void DFBrowser_Window::FillActionsMenu (void* theMenu)
248 {
249   QMenu* aMenu = (QMenu*)theMenu;
250   QList<QDockWidget*> aDockwidgets = myMainWindow->findChildren<QDockWidget*>();
251   for (QList<QDockWidget*>::iterator it = aDockwidgets.begin(); it != aDockwidgets.end(); ++it)
252   {
253     QDockWidget* aDockWidget = *it;
254     if (aDockWidget->parentWidget() == myMainWindow)
255       aMenu->addAction (aDockWidget->toggleViewAction());
256   }
257 }
258
259 // =======================================================================
260 // function : GetPreferences
261 // purpose :
262 // =======================================================================
263 void DFBrowser_Window::GetPreferences (TInspectorAPI_PreferencesDataMap& theItem)
264 {
265   theItem.Bind ("geometry",  TreeModel_Tools::ToString (myMainWindow->saveState()).toStdString().c_str());
266
267   QMap<QString, QString> anItems;
268   TreeModel_Tools::SaveState (myTreeView, anItems);
269   View_Window::SaveState(myViewWindow, anItems);
270
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());
273 }
274
275 // =======================================================================
276 // function : SetPreferences
277 // purpose :
278 // =======================================================================
279 void DFBrowser_Window::SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem)
280 {
281   if (theItem.IsEmpty())
282   {
283     TreeModel_Tools::SetDefaultHeaderSections (myTreeView);
284     return;
285   }
286
287   for (TInspectorAPI_IteratorOfPreferencesDataMap anItemIt (theItem); anItemIt.More(); anItemIt.Next())
288   {
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()))
292       continue;
293     else if (View_Window::RestoreState(myViewWindow, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
294       continue;
295   }
296 }
297
298 // =======================================================================
299 // function : UpdateContent
300 // purpose :
301 // =======================================================================
302 void DFBrowser_Window::UpdateContent()
303 {
304   TCollection_AsciiString aName = "TKDFBrowser";
305
306   if (myParameters->FindParameters (aName))
307     Init(myParameters->Parameters (aName));
308   else
309     Init(NCollection_List<Handle(Standard_Transient)>());
310
311   if (myParameters->FindFileNames(aName))
312   {
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>());
317   }
318   onUpdateClicked();
319
320   // make parameter items selected if defined
321   if (myParameters->FindSelectedNames(aName))
322   {
323     const NCollection_List<TCollection_AsciiString>& aSelected = myParameters->GetSelectedNames (aName);
324
325     DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
326     Handle(TDocStd_Application) anApplication = aTreeModel->GetTDocStdApplication();
327
328     QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
329     aSelectionModel->clear();
330
331     NCollection_List<TCollection_AsciiString>::Iterator aSelectedIt (aSelected);
332     if (aSelectedIt.More())
333     {
334       TCollection_AsciiString aLabelEntry = aSelectedIt.Value();
335
336       TDF_Label aLabel;
337       for (Standard_Integer aDocId = 1, aNbDoc = anApplication->NbDocuments(); aDocId <= aNbDoc; aDocId++)
338       {
339         Handle(TDocStd_Document) aDocument;
340         anApplication->GetDocument (aDocId, aDocument);
341
342         TDF_Tool::Label(aDocument->GetData(), aLabelEntry.ToCString(), aLabel, Standard_False);
343         if (!aLabel.IsNull())
344           break;
345       }
346       if (!aLabel.IsNull())
347       {
348         QModelIndex anIndexToBeSelected = aTreeModel->FindIndex (aLabel);
349
350         TCollection_AsciiString anAttributeType;
351         aSelectedIt.Next();
352         // find attribute by attribute type on the given label
353         if  (aSelectedIt.More())
354         {
355           anAttributeType = aSelectedIt.Value();
356
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++)
360           {
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())
365             {
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())
371               {
372                 anIndexToBeSelected = anIndex;
373                 break;
374               }
375             }
376           }
377         }
378         aSelectionModel->select (anIndexToBeSelected, QItemSelectionModel::Select);
379         myTreeView->scrollTo (anIndexToBeSelected);
380       }
381     }
382
383     myParameters->SetSelectedNames(aName, NCollection_List<TCollection_AsciiString>());
384   }
385 }
386
387 // =======================================================================
388 // function : Init
389 // purpose :
390 // =======================================================================
391 void DFBrowser_Window::Init (const NCollection_List<Handle(Standard_Transient)>& theParameters)
392 {
393   Handle(TDocStd_Application) anApplication;
394   if (myModule)
395   {
396     DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
397     if (anOCAFViewModel)
398       anApplication = anOCAFViewModel->GetTDocStdApplication();
399   }
400   Handle(AIS_InteractiveContext) aContext;
401   if (myModule)
402     aContext = myModule->GetExternalContext();
403
404   bool aSameApplication = !anApplication.IsNull(), aSameContext = !aContext.IsNull();
405   for (NCollection_List<Handle(Standard_Transient)>::Iterator aParametersIt (theParameters);
406        aParametersIt.More(); aParametersIt.Next())
407   {
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())
412     {
413       aSameApplication = anApplication == anIApplication;
414       if (!aSameApplication)
415         anApplication = anIApplication;
416     }
417     // check if the object is an interactive context
418     Handle(AIS_InteractiveContext) anIContext = Handle(AIS_InteractiveContext)::DownCast (anObject);
419     if (!anIContext.IsNull())
420     {
421       aSameContext = aContext == anIContext;
422       if (!aSameContext)
423         aContext = anIContext;
424     }
425   }
426   if (aSameApplication)
427   {
428     if (!aSameContext && !aContext.IsNull())
429     {
430       myModule->SetExternalContext (aContext);
431       myViewWindow->SetContext (View_ContextType_External, aContext);
432     }
433     return;
434   }
435
436   myModule = new DFBrowser_Module();
437   myModule->CreateViewModel (myMainWindow);
438
439   myPropertyPanel->GetAttributesStack()->SetModule (myModule);
440
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();
447
448   connect (myModule, SIGNAL (beforeUpdateTreeModel()), this, SLOT (onBeforeUpdateTreeModel()));
449
450   if (!aContext.IsNull())
451   {
452     myModule->SetExternalContext (aContext);
453     myViewWindow->SetContext (View_ContextType_External, aContext);
454   }
455
456   myModule->SetApplication (anApplication);
457   //! expand first three levels: CUSTOM
458   QModelIndex aParentIndex = aModel->index (0, 0);
459   setExpandedLevels (myTreeView, aParentIndex, 3/*levels*/);
460
461   myThread->ProcessApplication();
462   myModule->SetInitialTreeViewSelection();
463 }
464
465 // =======================================================================
466 // function : OpenFile
467 // purpose :
468 // =======================================================================
469 void DFBrowser_Window::OpenFile (const TCollection_AsciiString& theFileName)
470 {
471   QApplication::setOverrideCursor (Qt::WaitCursor);
472   myThread->TerminateThread();
473
474   myTreeLevelLine->ClearHistory();
475   QItemSelectionModel* aSelectionModel = myModule->GetOCAFViewSelectionModel();
476   if (aSelectionModel)
477   {
478     aSelectionModel->clearSelection();
479     QModelIndex anIndex;
480     aSelectionModel->select (anIndex, QItemSelectionModel::ClearAndSelect);
481   }
482   ClearThreadCache();
483
484   myTreeLevelLine->ClearHistory();
485
486   DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
487   anOCAFViewModel->Reset();
488
489   //! close previous documents to open new document
490   Handle(TDocStd_Application) anApplication = myModule->GetTDocStdApplication();
491   if (!anApplication.IsNull())
492   {
493     for (int aDocId = 1, aNbDocuments = anApplication->NbDocuments(); aDocId <= aNbDocuments; aDocId++)
494     {
495       Handle(TDocStd_Document) aDocument;
496       anApplication->GetDocument (aDocId, aDocument);
497       if (!aDocument.IsNull())
498         anApplication->Close (aDocument);
499     }
500   }
501
502   //! open new document
503   bool isSTEPFileName = false;
504   anApplication = DFBrowser_OpenApplication::OpenApplication (theFileName, isSTEPFileName);
505   
506   if (myParent)
507     myParent->setObjectName (isSTEPFileName ? QString (TCollection_AsciiString (theFileName).ToCString()) : getWindowTitle());
508   else
509     myOpenedFileName = isSTEPFileName ? QString(TCollection_AsciiString(theFileName).ToCString()) : getWindowTitle();
510
511   if (anApplication.IsNull())
512   {
513     QApplication::restoreOverrideCursor();
514     QMessageBox::information (0, "Error", QString ("File %1 can't be opened by OCAF application")
515                                                    .arg(TCollection_AsciiString (theFileName).ToCString()));
516   }
517   else {
518     myModule->SetApplication (anApplication);
519     //! expand first three levels: CUSTOM
520     QModelIndex aParentIndex = anOCAFViewModel->index (0, 0);
521     setExpandedLevels (myTreeView, aParentIndex, 3/*levels*/);
522
523     myThread->ProcessApplication();
524     myModule->SetInitialTreeViewSelection();
525     QApplication::restoreOverrideCursor();
526   }
527 }
528
529 // =======================================================================
530 // function : getWindowTitle
531 // purpose :
532 // =======================================================================
533 QString DFBrowser_Window::getWindowTitle() const
534 {
535   DFBrowser_TreeModel* anOCAFViewModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
536   if (!anOCAFViewModel)
537     return "";
538
539   Handle(TDocStd_Application) anApplication = anOCAFViewModel->GetTDocStdApplication();
540   if (anApplication.IsNull() || anApplication->NbDocuments() == 0)
541     return "";
542
543   Handle(TDocStd_Document) aDocument;
544   anApplication->GetDocument (1, aDocument);
545   if (aDocument.IsNull() || !aDocument->IsSaved())
546     return "";
547
548   return DFBrowserPane_Tools::ToString (aDocument->GetPath());
549 }
550
551 // =======================================================================
552 // function : setExpandedLevels
553 // purpose :
554 // =======================================================================
555 void DFBrowser_Window::setExpandedLevels (QTreeView* theTreeView, const QModelIndex& theParentIndex, const int theLevels)
556 {
557   if (theLevels <= 0)
558     return;
559
560   QAbstractItemModel* aModel = theTreeView->model();
561   if (!aModel)
562     return;
563
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);
567 }
568
569 // =======================================================================
570 // function : setOCAFModel
571 // purpose :
572 // =======================================================================
573 void DFBrowser_Window::setOCAFModel (QAbstractItemModel* theModel)
574 {
575   myTreeView->setModel (theModel);
576
577   QItemSelectionModel* aSelectionModel = new QItemSelectionModel (theModel);
578   myTreeView->setSelectionModel (aSelectionModel);
579
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&)));
586 }
587
588 // =======================================================================
589 // function : onBeforeUpdateTreeModel
590 // purpose :
591 // =======================================================================
592 void DFBrowser_Window::onBeforeUpdateTreeModel()
593 {
594   myTreeLevelLine->ClearHistory();
595   ClearThreadCache();
596   myThread->ProcessApplication();
597 }
598
599 // =======================================================================
600 // function : ClearThreadCache
601 // purpose :
602 // =======================================================================
603 void DFBrowser_Window::ClearThreadCache()
604 {
605   DFBrowser_ThreadItemSearch::ClearValues (GetTreeLevelLine()->GetSearchLine());
606 }
607
608 // =======================================================================
609 // function : TmpDirectory
610 // purpose :
611 // =======================================================================
612 TCollection_AsciiString DFBrowser_Window::TmpDirectory()
613 {
614   TCollection_AsciiString aTmpDir;
615 #ifdef _WIN32
616   OSD_Environment anEnvironment ("TEMP");
617   aTmpDir = anEnvironment.Value();
618   if (aTmpDir.IsEmpty() )
619   {
620     anEnvironment.SetName("TMP");
621     aTmpDir = anEnvironment.Value();
622     if (aTmpDir.IsEmpty())
623       aTmpDir = "C:\\";
624   }
625   OSD_Path aTmpPath (aTmpDir);
626   OSD_Directory aTmpDirectory (aTmpPath);
627   if (!aTmpDirectory.Exists())
628     aTmpDirectory.Build(OSD_Protection());
629 #else
630   OSD_Directory aTmpDirectory = OSD_Directory::BuildTemporary();
631   OSD_Path aTmpPath;
632   aTmpDirectory.Path (aTmpPath);
633   aTmpPath.SystemName(aTmpDir);
634 #endif
635
636   return aTmpDir;
637 }
638
639 // =======================================================================
640 // function : SetUseDumpJson
641 // purpose :
642 // =======================================================================
643 void DFBrowser_Window::SetUseDumpJson (const Standard_Boolean theValue)
644 {
645   MyIsUseDumpJson = theValue;
646 }
647
648 // =======================================================================
649 // function : IsUseDumpJson
650 // purpose :
651 // =======================================================================
652 Standard_Boolean DFBrowser_Window::IsUseDumpJson()
653 {
654   return MyIsUseDumpJson;
655 }
656
657 // =======================================================================
658 // function : onTreeViewContextMenuRequested
659 // purpose :
660 // =======================================================================
661 void DFBrowser_Window::onTreeViewContextMenuRequested (const QPoint& thePosition)
662 {
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));
667
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);
673
674   QPoint aPoint = myTreeView->mapToGlobal (thePosition);
675   aMenu->exec (aPoint);
676 }
677
678 // =======================================================================
679 // function : onExpand
680 // purpose :
681 // =======================================================================
682 void DFBrowser_Window::onExpand()
683 {
684   QApplication::setOverrideCursor (Qt::WaitCursor);
685
686   QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
687   QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
688   for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++)
689   {
690     int aLevels = 2;
691     TreeModel_Tools::SetExpanded (myTreeView, aSelectedIndices[aSelectedId], true, aLevels);
692   }
693   QApplication::restoreOverrideCursor();
694 }
695
696 // =======================================================================
697 // function : onExpandAll
698 // purpose :
699 // =======================================================================
700 void DFBrowser_Window::onExpandAll()
701 {
702   QApplication::setOverrideCursor (Qt::WaitCursor);
703
704   QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
705   QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
706   for (int  aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++)
707   {
708     int aLevels = -1;
709     TreeModel_Tools::SetExpanded (myTreeView, aSelectedIndices[aSelectedId], true, aLevels);
710   }
711   QApplication::restoreOverrideCursor();
712 }
713
714 // =======================================================================
715 // function : onCollapseAll
716 // purpose :
717 // =======================================================================
718 void DFBrowser_Window::onCollapseAll()
719 {
720   QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
721   QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
722   for (int aSelectedId = 0, aSize = aSelectedIndices.size(); aSelectedId < aSize; aSelectedId++) {
723     int aLevels = -1;
724     TreeModel_Tools::SetExpanded (myTreeView, aSelectedIndices[aSelectedId], false, aLevels);
725   }
726 }
727
728 // =======================================================================
729 // function : onUseDumpJson
730 // purpose :
731 // =======================================================================
732 void DFBrowser_Window::onUseDumpJson()
733 {
734   SetUseDumpJson(!IsUseDumpJson());
735   updatePropertyPanelWidget();
736
737   QApplication::setOverrideCursor (Qt::WaitCursor);
738   myModule->UpdateTreeModel();
739   QApplication::restoreOverrideCursor();
740 }
741
742 // =======================================================================
743 // function : onTreeViewSelectionChanged
744 // purpose :
745 // =======================================================================
746 void DFBrowser_Window::onTreeViewSelectionChanged (const QItemSelection& theSelected,
747                                                    const QItemSelection& theDeselected)
748 {
749   if (!myModule)
750     return;
751
752   if (IsUseDumpJson() && myPropertyPanelWidget->toggleViewAction()->isChecked())
753   {
754       myPropertyView->Init (ViewControl_Tools::CreateTableModelValues (myTreeView->selectionModel()));
755   }
756
757   // previuos selection should be cleared in the panel selectors
758   DFBrowser_AttributePaneStack* anAttributePaneStack = myPropertyPanel->GetAttributesStack();
759   anAttributePaneStack->GetPaneSelector()->ClearSelected();
760
761   myPropertyPanel->UpdateBySelectionChanged (theSelected, theDeselected);
762   anAttributePaneStack->GetTreeLevelView()->UpdateByTreeSelectionChanged (theSelected, theDeselected);
763
764   QModelIndexList aSelectedIndices = theSelected.indexes();
765   QModelIndex aSelectedIndex = TreeModel_ModelBase::SingleSelected (aSelectedIndices, 0);
766
767   myTreeView->scrollTo (aSelectedIndex);
768   View_Displayer* aDisplayer = myViewWindow->Displayer();
769   
770   aDisplayer->ErasePresentations (View_PresentationType_Additional, false);
771   aDisplayer->DisplayPresentation (findPresentation (aSelectedIndex), View_PresentationType_Main);
772 }
773
774 // =======================================================================
775 // function : onSearchActivated
776 // purpose :
777 // =======================================================================
778 void DFBrowser_Window::onSearchActivated()
779 {
780   myPropertyPanel->GetAttributesStack()->SetPaneMode ((myTreeLevelLine->GetSearchLine()->Text().isEmpty()
781                         ? DFBrowser_AttributePaneType_ItemView : DFBrowser_AttributePaneType_SearchView));
782 }
783
784 // =======================================================================
785 // function : onPaneSelectionChanged
786 // purpose :
787 // =======================================================================
788 void DFBrowser_Window::onPaneSelectionChanged (const QItemSelection&,
789                                                const QItemSelection&,
790                                                QItemSelectionModel* theModel)
791 {
792   DFBrowserPane_AttributePaneAPI* anAttributePane = myPropertyPanel->GetAttributesStack()->GetCurrentPane();
793   switch (anAttributePane->GetSelectionKind (theModel))
794   {
795     case DFBrowserPane_SelectionKind_ExportToShapeViewer:
796     {
797       QItemSelectionModel* aSelectionModel = theModel;
798       QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
799       if (aSelectedIndices.size() != 1)
800         return;
801
802       TCollection_AsciiString aPluginName ("TKShapeView");
803       NCollection_List<Handle(Standard_Transient)> aParameters;
804       if (myParameters->FindParameters (aPluginName))
805         aParameters = myParameters->Parameters (aPluginName);
806
807       NCollection_List<TCollection_AsciiString> anItemNames;
808       if (myParameters->FindSelectedNames (aPluginName))
809         anItemNames = myParameters->GetSelectedNames (aPluginName);
810
811       int aParametersCount = aParameters.Extent();
812       anAttributePane->GetSelectionParameters (aSelectionModel, aParameters, anItemNames);
813       if (aParametersCount != aParameters.Extent()) // some TShapes are added
814       {
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);
823         else
824           myExportToShapeViewDialog->SetInformation (aMessage);
825         myExportToShapeViewDialog->Start();
826
827         myParameters->SetSelectedNames (aPluginName, anItemNames);
828         myParameters->SetParameters (aPluginName, aParameters, myExportToShapeViewDialog->IsAccepted());
829       }
830       return;
831     }
832     case DFBrowserPane_SelectionKind_ExportToBREP:
833     case DFBrowserPane_SelectionKind_LabelReferences:
834     case DFBrowserPane_SelectionKind_AttributeReferences:
835     default: break;
836   }
837
838   QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
839   QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
840   if (aSelectedIndices.size() != 1)
841     return;
842
843   // make the shape visualized
844   QModelIndex aSelectedIndex = aSelectedIndices.first();
845   View_Displayer* aDisplayer = myViewWindow->Displayer();
846   aDisplayer->DisplayPresentation (findPresentation (aSelectedIndex), View_PresentationType_Main);
847
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);
857   else {
858     NCollection_List<Handle(TDF_Attribute)> anAttributeReferences;
859     anAttributePane->GetAttributeReferences (anAttribute, anAttributeReferences, aPresentation);
860     aTreeModel->ConvertToIndices (anAttributeReferences, anIndices);
861   }
862   highlightIndices (anIndices);
863   // display either the reference presentation of the panel or find a presentation if the reference
864   // is an attribute
865   if (!aPresentation.IsNull())
866     aDisplayer->DisplayPresentation (aPresentation, View_PresentationType_Additional);
867   else {
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);
873
874     aDisplayer->UpdateViewer();
875   }
876 }
877
878 // =======================================================================
879 // function : onTreeLevelLineSelected
880 // purpose :
881 // =======================================================================
882 void DFBrowser_Window::onTreeLevelLineSelected (const QModelIndex& theIndex)
883 {
884   QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
885   if (theIndex.isValid())
886     aSelectionModel->select (theIndex, QItemSelectionModel::ClearAndSelect);
887   else
888     aSelectionModel->clearSelection();
889 }
890
891 // =======================================================================
892 // function : onUpdateClicked
893 // purpose :
894 // =======================================================================
895 void DFBrowser_Window::onUpdateClicked()
896 {
897   if (myModule)
898     myModule->UpdateTreeModel();
899 }
900
901 // =======================================================================
902 // function : onSearchPathSelected
903 // purpose :
904 // =======================================================================
905 void DFBrowser_Window::onSearchPathSelected (const QStringList& thePath, const QString& theValue)
906 {
907   DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
908   const QModelIndex& anIndex = aDFBrowserModel->FindIndexByPath (thePath, theValue);
909
910   if (anIndex.isValid())
911   {
912     QModelIndexList anIndices;
913     anIndices.append (anIndex);
914     highlightIndices (anIndices);
915   }
916 }
917
918 // =======================================================================
919 // function : onSearchPathDoubleClicked
920 // purpose :
921 // =======================================================================
922 void DFBrowser_Window::onSearchPathDoubleClicked (const QStringList& thePath, const QString& theValue)
923 {
924   DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myTreeView->model());
925   const QModelIndex& anIndex = aDFBrowserModel->FindIndexByPath (thePath, theValue);
926
927   QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
928   if (anIndex.isValid())
929     aSelectionModel->select (anIndex, QItemSelectionModel::ClearAndSelect);
930   else
931     aSelectionModel->clearSelection();
932 }
933
934 // =======================================================================
935 // function : onLevelSelected
936 // purpose :
937 // =======================================================================
938 void DFBrowser_Window::onLevelSelected (const QModelIndex& theIndex)
939 {
940   if (!theIndex.isValid())
941     return;
942
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);
949 }
950
951 // =======================================================================
952 // function : onLevelDoubleClicked
953 // purpose :
954 // =======================================================================
955 void DFBrowser_Window::onLevelDoubleClicked (const QModelIndex& theIndex)
956 {
957   QItemSelectionModel* aSelectionModel = myTreeView->selectionModel();
958   if (theIndex.isValid())
959     aSelectionModel->select (theIndex, QItemSelectionModel::ClearAndSelect);
960   else
961     aSelectionModel->clearSelection();
962 }
963
964 // =======================================================================
965 // function : highlightIndices
966 // purpose :
967 // =======================================================================
968 void DFBrowser_Window::highlightIndices (const QModelIndexList& theIndices)
969 {
970   QAbstractItemModel* aModel = myTreeView->model();
971   if (!aModel)
972     return;
973
974   DFBrowser_TreeModel* aTreeModel = dynamic_cast<DFBrowser_TreeModel*> (aModel);
975   if (!aTreeModel)
976     return;
977
978   aTreeModel->SetHighlighted (theIndices);
979
980   QModelIndex anIndexToScroll;
981   if (!theIndices.isEmpty())
982     anIndexToScroll = theIndices.last(); // scroll to last selected index
983   else
984   {
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();
990   }
991   if (anIndexToScroll.isValid())
992     myTreeView->scrollTo (anIndexToScroll);
993
994   if (theIndices.isEmpty())
995     myTreeView->setFocus(); // to see the selected item in active palette color
996
997   aTreeModel->EmitLayoutChanged();
998 }
999
1000 // =======================================================================
1001 // function : findPresentation
1002 // purpose :
1003 // =======================================================================
1004 Handle(AIS_InteractiveObject) DFBrowser_Window::findPresentation (const QModelIndex& theIndex)
1005 {
1006   Handle(AIS_InteractiveObject) aPresentation;
1007
1008   QModelIndexList anIndices;
1009   anIndices.append (theIndex);
1010   AIS_ListOfInteractive aDisplayed;
1011   findPresentations (anIndices, aDisplayed);
1012   if (!aDisplayed.IsEmpty())
1013     aPresentation = aDisplayed.First();
1014
1015   return aPresentation;
1016 }
1017
1018 // =======================================================================
1019 // function : findPresentations
1020 // purpose :
1021 // =======================================================================
1022 void DFBrowser_Window::findPresentations (const QModelIndexList& theIndices, AIS_ListOfInteractive& thePresentations)
1023 {
1024   for (int anIndexId = 0, aCount = theIndices.size(); anIndexId < aCount; anIndexId++)
1025   {
1026     Handle(AIS_InteractiveObject) aPresentation;
1027     Handle(TDF_Attribute) anAttribute = myModule->FindAttribute (theIndices[anIndexId]);
1028     if (anAttribute.IsNull())
1029       continue;
1030     DFBrowserPane_AttributePaneAPI* anAttributePane = myModule->GetAttributePane (anAttribute);
1031     if (!anAttributePane)
1032       continue;
1033     aPresentation = Handle(AIS_InteractiveObject)::DownCast (anAttributePane->GetPresentation (anAttribute));
1034     if (aPresentation.IsNull())
1035       continue;
1036
1037     thePresentations.Append (aPresentation);
1038   }
1039 }
1040
1041 // =======================================================================
1042 // function : updatePropertyPanelWidget
1043 // purpose :
1044 // =======================================================================
1045 void DFBrowser_Window::updatePropertyPanelWidget()
1046 {
1047   bool aUseDumpJson = IsUseDumpJson();
1048
1049   myUseDumpJson->setVisible (!aUseDumpJson);
1050   myPropertyPanelWidget->setWidget (aUseDumpJson ? myPropertyView->GetControl() : myUseDumpJson);
1051 }