]> OCCT Git - occt-copy.git/commitdiff
0031362: Inspectors - MessageView plugin for message alerts
authornds <nds@opencascade.com>
Tue, 27 Oct 2020 16:24:59 +0000 (19:24 +0300)
committernds <nds@opencascade.com>
Mon, 29 Mar 2021 10:11:14 +0000 (13:11 +0300)
- OSD_Timer in message alert,
- DumpJson correction,
- Selection owner should be dumped in selector. Sensitive entities might be used in the same owner, that leads to lots of the same dump in the result stream.
- Inspector tools improvements
0031959: Inspectors - Statistics by name

(cherry picked from commit 60c65819c9b6668595e65215ea8de1111e9b0f97)

83 files changed:
adm/TOOLS
tools/DFBrowser/DFBrowser_TreeModel.cxx
tools/DFBrowser/DFBrowser_Window.cxx
tools/DFBrowserPane/DFBrowserPane_TDataStdTreeNodeModel.cxx
tools/MessageModel/FILES [new file with mode: 0644]
tools/MessageModel/MessageModel.qrc [new file with mode: 0644]
tools/MessageModel/MessageModel_ActionType.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Actions.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Actions.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemAlert.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemAlert.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemBase.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemBase.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemReport.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemReport.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemRoot.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemRoot.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Tools.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Tools.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_TreeModel.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_TreeModel.hxx [new file with mode: 0644]
tools/MessageModel/icons/item_shape.png [new file with mode: 0644]
tools/MessageModel/icons/item_shape.svg [new file with mode: 0644]
tools/MessageModel/icons/item_streamValues.png [new file with mode: 0644]
tools/MessageModel/icons/item_streamValues.svg [new file with mode: 0644]
tools/MessageView/FILES [new file with mode: 0644]
tools/MessageView/MessageView_ActionsTest.cxx [new file with mode: 0644]
tools/MessageView/MessageView_ActionsTest.hxx [new file with mode: 0644]
tools/MessageView/MessageView_Communicator.cxx [new file with mode: 0644]
tools/MessageView/MessageView_Communicator.hxx [new file with mode: 0644]
tools/MessageView/MessageView_UnitByNameModel.cxx [new file with mode: 0644]
tools/MessageView/MessageView_UnitByNameModel.hxx [new file with mode: 0644]
tools/MessageView/MessageView_VisibilityState.cxx [new file with mode: 0644]
tools/MessageView/MessageView_VisibilityState.hxx [new file with mode: 0644]
tools/MessageView/MessageView_Window.cxx [new file with mode: 0644]
tools/MessageView/MessageView_Window.hxx [new file with mode: 0644]
tools/ShapeView/ShapeView_Window.cxx
tools/ShapeView/ShapeView_Window.hxx
tools/TInspectorEXE/TInspectorEXE.cxx
tools/TKMessageModel/CMakeLists.txt [new file with mode: 0644]
tools/TKMessageModel/EXTERNLIB [new file with mode: 0644]
tools/TKMessageModel/FILES [new file with mode: 0644]
tools/TKMessageModel/PACKAGES [new file with mode: 0644]
tools/TKMessageView/CMakeLists.txt [new file with mode: 0644]
tools/TKMessageView/EXTERNLIB [new file with mode: 0644]
tools/TKMessageView/FILES [new file with mode: 0644]
tools/TKMessageView/PACKAGES [new file with mode: 0644]
tools/ToolsDraw/ToolsDraw.cxx
tools/TreeModel/TreeModel_ColumnType.hxx
tools/TreeModel/TreeModel_ContextMenu.cxx
tools/TreeModel/TreeModel_ItemBase.cxx
tools/TreeModel/TreeModel_ItemBase.hxx
tools/TreeModel/TreeModel_ItemProperties.cxx
tools/TreeModel/TreeModel_ItemProperties.hxx
tools/TreeModel/TreeModel_ModelBase.cxx
tools/TreeModel/TreeModel_ModelBase.hxx
tools/TreeModel/TreeModel_Tools.cxx
tools/VInspector/VInspector_ItemBase.cxx
tools/VInspector/VInspector_ItemBase.hxx
tools/VInspector/VInspector_ItemPresentableObject.hxx
tools/VInspector/VInspector_ViewModel.cxx
tools/VInspector/VInspector_ViewModelHistory.cxx
tools/VInspector/VInspector_Window.cxx
tools/View/View.qrc
tools/View/View_Displayer.cxx
tools/View/View_Displayer.hxx
tools/View/View_ToolActionType.hxx
tools/View/View_ToolBar.cxx
tools/View/View_ViewActionType.hxx
tools/View/View_Widget.cxx
tools/View/View_Widget.hxx
tools/View/View_Window.cxx
tools/View/View_Window.hxx
tools/View/icons/cursor_rotate.png [new file with mode: 0644]
tools/View/icons/cursor_zoom.png [new file with mode: 0644]
tools/View/icons/view_cube.png [deleted file]
tools/View/icons/view_fitarea.png [new file with mode: 0644]
tools/View/icons/view_pan.png [new file with mode: 0644]
tools/View/icons/view_rotate.png [new file with mode: 0644]
tools/View/icons/view_zoom.png [new file with mode: 0644]
tools/ViewControl/FILES
tools/ViewControl/ViewControl_PropertiesDialog.cxx [new file with mode: 0644]
tools/ViewControl/ViewControl_PropertiesDialog.hxx [new file with mode: 0644]

index b106a7c10bca46ca90821160ae370e4e3d4d8a06..57ddcfcc647d3402a54f4626ffc7134b7bd1e7f1 100644 (file)
--- a/adm/TOOLS
+++ b/adm/TOOLS
@@ -1,4 +1,4 @@
-TModelingData TKShapeView
+TModelingData TKShapeView TKMessageModel TKMessageView
 TVisualization TKView TKVInspector
 TApplicationFramework TKTreeModel TKTInspectorAPI TKDFBrowser
 TTool TKTInspector TKToolsDraw TInspectorEXE
\ No newline at end of file
index 23ab2c2aa837e07d1034ab245d8a4ae4f73aa5f5..70857bc046c8f010b358c1de83628e2ba8014c22 100644 (file)
@@ -49,7 +49,7 @@ DFBrowser_TreeModel::DFBrowser_TreeModel (QObject* theParent)
 // =======================================================================
 void DFBrowser_TreeModel::InitColumns()
 {
-  SetHeaderItem (0, TreeModel_HeaderSection ("Name"));
+  setHeaderItem (0, TreeModel_HeaderSection ("Name"));
 }
 
 // =======================================================================
index b7e94c7ffbe1ea4a40e01e5ac42e940e40500891..7b67da368e5b4eb5b73e3744a6727c97f032c616 100644 (file)
 #include <OSD_Directory.hxx>
 #include <OSD_Environment.hxx>
 #include <OSD_Protection.hxx>
-#include <OSD_Thread.hxx>
+
 #include <inspector/View_Displayer.hxx>
 #include <inspector/View_ToolBar.hxx>
 #include <inspector/View_Viewer.hxx>
+#include <inspector/View_Widget.hxx>
 #include <inspector/View_Window.hxx>
 
 #include <TDF_Tool.hxx>
@@ -62,7 +63,6 @@
 #include <inspector/ViewControl_Tools.hxx>
 
 #include <Standard_WarningsDisable.hxx>
-#include <Standard_ThreadId.hxx>
 #include <QAction>
 #include <QApplication>
 #include <QComboBox>
@@ -192,7 +192,7 @@ DFBrowser_Window::DFBrowser_Window()
 
   // view
   myViewWindow = new View_Window (myMainWindow);
-  myViewWindow->SetPredefinedSize (DFBROWSER_DEFAULT_VIEW_WIDTH, DFBROWSER_DEFAULT_VIEW_HEIGHT);
+  myViewWindow->ViewWidget()->SetPredefinedSize (DFBROWSER_DEFAULT_VIEW_WIDTH, DFBROWSER_DEFAULT_VIEW_HEIGHT);
 
   QDockWidget* aViewDockWidget = new QDockWidget (tr ("View"), myMainWindow);
   aViewDockWidget->setObjectName (aViewDockWidget->windowTitle());
index 4f8a4847f0dabca1173e63ebad4041ef783c60a6..0d6b98f12fa9cb65aa094ea319b1c1256f3c7c47 100644 (file)
@@ -37,7 +37,7 @@ DFBrowserPane_TDataStdTreeNodeModel::DFBrowserPane_TDataStdTreeNodeModel (QObjec
 // =======================================================================
 void DFBrowserPane_TDataStdTreeNodeModel::InitColumns()
 {
-  SetHeaderItem (0, TreeModel_HeaderSection ("Name"));
+  setHeaderItem (0, TreeModel_HeaderSection ("Name"));
 }
 
 // =======================================================================
diff --git a/tools/MessageModel/FILES b/tools/MessageModel/FILES
new file mode 100644 (file)
index 0000000..5fbdcbc
--- /dev/null
@@ -0,0 +1,16 @@
+MessageModel.qrc
+MessageModel_Actions.cxx
+MessageModel_Actions.hxx
+MessageModel_ActionType.hxx
+MessageModel_ItemAlert.cxx
+MessageModel_ItemAlert.hxx
+MessageModel_ItemBase.cxx
+MessageModel_ItemBase.hxx
+MessageModel_ItemReport.cxx
+MessageModel_ItemReport.hxx
+MessageModel_ItemRoot.cxx
+MessageModel_ItemRoot.hxx
+MessageModel_Tools.cxx
+MessageModel_Tools.hxx
+MessageModel_TreeModel.cxx
+MessageModel_TreeModel.hxx
diff --git a/tools/MessageModel/MessageModel.qrc b/tools/MessageModel/MessageModel.qrc
new file mode 100644 (file)
index 0000000..8b794a8
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+    <qresource>
+        <file>icons/item_shape.png</file>
+        <file>icons/item_streamValues.png</file>
+    </qresource>
+</RCC>
diff --git a/tools/MessageModel/MessageModel_ActionType.hxx b/tools/MessageModel/MessageModel_ActionType.hxx
new file mode 100644 (file)
index 0000000..3415c9d
--- /dev/null
@@ -0,0 +1,33 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ActionType_H
+#define MessageModel_ActionType_H
+
+//! Kind of action type for tree view context menu item
+enum MessageModel_ActionType
+{
+  MessageModel_ActionType_Activate, //!< set Message_Report active
+  MessageModel_ActionType_Deactivate, //!< set Message_Report not active
+  MessageModel_ActionType_Clear, //!< clear Message_Report alerts
+  MessageModel_ActionType_ExportToShapeView, //!< export TopoDS_Shape of selected item into TKShapeView plugin
+  MessageModel_ActionType_TestMetric, //!< test alerts
+  MessageModel_ActionType_TestProperties, //!< test alerts
+  MessageModel_ActionType_TestMessenger, //!< test message view on messenger printer to report
+  MessageModel_ActionType_TestReportTree, //!< test message view on hierarchical report
+  MessageModel_ActionType_TestReportTree2 //!< test message view on hierarchical report
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_Actions.cxx b/tools/MessageModel/MessageModel_Actions.cxx
new file mode 100644 (file)
index 0000000..ddc083b
--- /dev/null
@@ -0,0 +1,269 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+                                                          
+#include <inspector/MessageModel_Actions.hxx>
+
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_TreeModel.hxx>
+#include <inspector/TInspectorAPI_PluginParameters.hxx>
+#include <inspector/ViewControl_Tools.hxx>
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_Messenger.hxx>
+#include <Message_PrinterToReport.hxx>
+
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <OSD_Chronometer.hxx>
+#include <Quantity_Color.hxx>
+#include <Quantity_ColorRGBA.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TopoDS_AlertAttribute.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QAction>
+#include <QFileDialog>
+#include <QItemSelectionModel>
+#include <QMenu>
+#include <QMessageBox>
+#include <QWidget>
+#include <Standard_WarningsRestore.hxx>
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+MessageModel_Actions::MessageModel_Actions (QWidget* theParent,
+  MessageModel_TreeModel* theTreeModel, QItemSelectionModel* theModel)
+: QObject (theParent), myTreeModel (theTreeModel), mySelectionModel (theModel)
+{
+  myActions.insert (MessageModel_ActionType_Activate,
+                    ViewControl_Tools::CreateAction ("Activate", SLOT (OnActivateReport()), parent(), this));
+  myActions.insert (MessageModel_ActionType_Deactivate,
+                    ViewControl_Tools::CreateAction ("Deactivate", SLOT (OnDeactivateReport()), parent(), this));
+  myActions.insert (MessageModel_ActionType_Clear,
+                    ViewControl_Tools::CreateAction ("Clear", SLOT (OnClearReport()), parent(), this));
+  myActions.insert (MessageModel_ActionType_ExportToShapeView,
+                    ViewControl_Tools::CreateAction (tr ("Export to ShapeView"), SLOT (OnExportToShapeView()), parent(), this));
+}
+
+// =======================================================================
+// function : GetAction
+// purpose :
+// =======================================================================
+QAction* MessageModel_Actions::GetAction (const MessageModel_ActionType& theType)
+{
+  if (myActions.contains (theType))
+    return myActions[theType];
+
+  return 0;
+}
+
+// =======================================================================
+// function : AddMenuActions
+// purpose :
+// =======================================================================
+void MessageModel_Actions::AddMenuActions (const QModelIndexList& theSelectedIndices, QMenu* theMenu)
+{
+  MessageModel_ItemRootPtr aRootItem;
+  MessageModel_ItemReportPtr aReportItem;
+  MessageModel_ItemAlertPtr anAlertItem;
+  for (QModelIndexList::const_iterator aSelIt = theSelectedIndices.begin(); aSelIt != theSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItemBase);
+    if (aRootItem)
+      break;
+
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    if (aReportItem)
+      break;
+
+    anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (anItemBase);
+    if (anAlertItem)
+      break;
+  }
+
+  if (aReportItem && !aReportItem->GetReport().IsNull())
+  {
+    theMenu->addAction (myActions[MessageModel_ActionType_Deactivate]);
+    theMenu->addAction (myActions[MessageModel_ActionType_Activate]);
+    theMenu->addAction (myActions[MessageModel_ActionType_Clear]);
+  }
+  else if (anAlertItem)
+  {
+    theMenu->addAction (myActions[MessageModel_ActionType_ExportToShapeView]);
+  }
+
+  theMenu->addSeparator();
+}
+
+// =======================================================================
+// function : getSelectedReport
+// purpose :
+// =======================================================================
+Handle(Message_Report) MessageModel_Actions::getSelectedReport (QModelIndex& theReportIndex) const
+{
+  MessageModel_ItemReportPtr aReportItem;
+  QModelIndexList aSelectedIndices = mySelectionModel->selectedIndexes();
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    theReportIndex = anIndex;
+    if (aReportItem)
+      break;
+  }
+  if (!aReportItem)
+    return NULL;
+
+  return aReportItem->GetReport();
+}
+
+// =======================================================================
+// function : OnActivateReport
+// purpose :
+// =======================================================================
+static Handle(Message_PrinterToReport) MyPrinterToReport;
+static Message_SequenceOfPrinters MyDeactivatedPrinters;
+
+void MessageModel_Actions::OnActivateReport()
+{
+  if (MyPrinterToReport.IsNull())
+    MyPrinterToReport = new Message_PrinterToReport();
+
+  if (MyPrinterToReport->Report()->IsActiveInMessenger())
+    return;
+
+  MyDeactivatedPrinters = Message::DefaultMessenger()->Printers();
+  Message::DefaultMessenger()->ChangePrinters().Clear();
+
+  Message::DefaultMessenger()->AddPrinter (MyPrinterToReport);
+  //Message::DefaultMessenger()->SetTraceLevel (1);
+  Message::DefaultReport()->UpdateActiveInMessenger();
+
+  myTreeModel->UpdateTreeModel();
+}
+
+// =======================================================================
+// function : OnDeactivateReport
+// purpose :
+// =======================================================================
+void MessageModel_Actions::OnDeactivateReport()
+{
+  if (MyPrinterToReport.IsNull() || !MyPrinterToReport->Report()->IsActiveInMessenger())
+    return;
+
+  Message::DefaultMessenger()->RemovePrinter (MyPrinterToReport);
+  Message::DefaultMessenger()->ChangePrinters().Assign (MyDeactivatedPrinters);
+
+  myTreeModel->UpdateTreeModel();
+}
+
+// =======================================================================
+// function : OnClearReport
+// purpose :
+// =======================================================================
+void MessageModel_Actions::OnClearReport()
+{
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  aReport->Clear();
+  myTreeModel->UpdateTreeModel();
+}
+
+// =======================================================================
+// function : OnExportToShapeView
+// purpose :
+// =======================================================================
+void MessageModel_Actions::OnExportToShapeView()
+{
+  TCollection_AsciiString aPluginName ("TKShapeView");
+
+  NCollection_List<Handle(Standard_Transient)> aPluginParameters;
+  if (myParameters->FindParameters (aPluginName))
+    aPluginParameters = myParameters->Parameters (aPluginName);
+  NCollection_List<TCollection_AsciiString> anItemNames;
+  if (myParameters->FindSelectedNames (aPluginName))
+    anItemNames = myParameters->GetSelectedNames (aPluginName);
+
+  QModelIndexList aSelectedIndices = mySelectionModel->selectedIndexes();
+  QStringList anExportedPointers;
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (anItemBase);
+    if (!anAlertItem)
+      continue;
+
+    Handle(Message_Alert) anAlert = anAlertItem->GetAlert();
+    if (anAlert.IsNull())
+      continue;
+
+    Handle(Message_AlertExtended) anExtAlert = Handle(Message_AlertExtended)::DownCast (anAlert);
+    if (anExtAlert.IsNull())
+      continue;
+
+    Handle(Message_Attribute) anAttribute = anExtAlert->Attribute();
+    if (anAttribute.IsNull())
+      continue;
+
+    if (!anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+      continue;
+
+    const TopoDS_Shape aShape = Handle(TopoDS_AlertAttribute)::DownCast (anAttribute)->GetShape();
+    if (aShape.IsNull())
+      continue;
+    aPluginParameters.Append (aShape.TShape());
+    anItemNames.Append (TInspectorAPI_PluginParameters::ParametersToString (aShape));
+
+    anExportedPointers.append (MessageModel_Tools::GetPointerInfo (aShape.TShape(), true).ToCString());
+  }
+
+  if (anExportedPointers.empty())
+      return;
+  myParameters->SetSelectedNames (aPluginName, anItemNames);
+  myParameters->SetParameters (aPluginName, aPluginParameters);
+  QMessageBox::information (0, "Information", QString ("TShapes '%1' are sent to %2 tool.")
+    .arg (anExportedPointers.join (", ")).arg (QString (aPluginName.ToCString())));
+}
diff --git a/tools/MessageModel/MessageModel_Actions.hxx b/tools/MessageModel/MessageModel_Actions.hxx
new file mode 100644 (file)
index 0000000..39eab42
--- /dev/null
@@ -0,0 +1,98 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_Actions_H
+#define MessageModel_Actions_H
+
+#include <Standard.hxx>
+#include <Standard_Transient.hxx>
+
+#include <inspector/MessageModel_ActionType.hxx>
+#include <inspector/TInspectorAPI_PluginParameters.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QObject>
+#include <QMap>
+#include <QModelIndexList>
+#include <QPoint>
+#include <QString>
+#include <Standard_WarningsRestore.hxx>
+
+class Message_Report;
+class MessageModel_TreeModel;
+
+class QAction;
+class QItemSelectionModel;
+class QMenu;
+class QWidget;
+
+//! \class MessageModel_Actions
+//! \brief This is a listener of popup context menu items and selection change in message model
+class MessageModel_Actions : public QObject
+{
+  Q_OBJECT
+
+public:
+
+  //! Constructor
+  Standard_EXPORT MessageModel_Actions (QWidget* theParent,
+                                        MessageModel_TreeModel* theTreeModel,
+                                        QItemSelectionModel* theModel);
+
+  //! Destructor
+  virtual ~MessageModel_Actions() Standard_OVERRIDE {}
+
+  //! Returns action by the type
+  //! \param theType an action type
+  //! \return an action instance if it exists
+  Standard_EXPORT QAction* GetAction (const MessageModel_ActionType& theType);
+
+  //! Fills popup menu with actions depending on the current selection
+  //! \param theSelectedIndices tree model selected indices
+  //! \param theMenu menu to be filled
+  Standard_EXPORT void AddMenuActions (const QModelIndexList& theSelectedIndices, QMenu* theMenu);
+
+  //! Sets parameters container, it should be used when the plugin is initialized or in update content
+  //! \param theParameters a parameters container
+  void SetParameters (const Handle(TInspectorAPI_PluginParameters)& theParameters)
+  { myParameters = theParameters; }
+
+public slots:
+  //! Set selected report active
+  void OnActivateReport();
+
+  //! Set selected report not active
+  void OnDeactivateReport();
+
+  //! Clears container of alerts of selected report
+  void OnClearReport();
+
+  //! Exports the first selected shape into ShapeViewer plugin.
+  void OnExportToShapeView();
+
+protected:
+  //! Returns report of selected tree view item if a report item is selected
+  //! \param theReportIndex tree model index of the found report
+  //! \return report instance or NULL
+  Handle(Message_Report) getSelectedReport (QModelIndex& theReportIndex) const;
+
+protected:
+  MessageModel_TreeModel* myTreeModel; //< tree model
+  QItemSelectionModel* mySelectionModel; //< selection model
+  Handle(TInspectorAPI_PluginParameters) myParameters; //!< plugins parameters container
+  QMap<MessageModel_ActionType, QAction*> myActions; //!< container of all actions
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_ItemAlert.cxx b/tools/MessageModel/MessageModel_ItemAlert.cxx
new file mode 100644 (file)
index 0000000..1e2fbbd
--- /dev/null
@@ -0,0 +1,352 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_TreeModel.hxx>
+
+#include <inspector/ViewControl_Tools.hxx>
+#include <inspector/Convert_TransientShape.hxx>
+#include <inspector/TreeModel_ItemProperties.hxx>
+#include <inspector/TreeModel_Tools.hxx>
+
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeObject.hxx>
+#include <Message_AttributeMeter.hxx>
+#include <Message_AttributeStream.hxx>
+#include <Message_CompositeAlerts.hxx>
+
+#include <Bnd_Box.hxx>
+#include <Precision.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TopoDS_AlertAttribute.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QColor>
+#include <QIcon>
+#include <Standard_WarningsRestore.hxx>
+
+
+// =======================================================================
+// function : initValue
+// purpose :
+// =======================================================================
+QVariant MessageModel_ItemAlert::initValue (const int theRole) const
+{
+  QVariant aParentValue = MessageModel_ItemBase::initValue (theRole);
+  if (aParentValue.isValid())
+    return aParentValue;
+
+  MessageModel_ItemReportPtr aReportItem = MessageModel_ItemReport::FindReportItem (Parent());
+  if (!aReportItem)
+    return QVariant();
+
+  Handle(Message_Report) aReport = aReportItem->GetReport();
+  if (aReport.IsNull())
+    return QVariant();
+
+  if (theRole == Qt::ForegroundRole)
+  {
+    if (!aReport->IsActiveInMessenger())
+      return QColor(Qt::darkGray);
+
+    return QVariant();
+  }
+
+  Handle(Message_Alert) anAlert = getAlert();
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(anAlert);
+
+  // if the alert is composite, process the real alert
+  if (theRole == Qt::DecorationRole && Column() == 0)
+  {
+    if (anExtendedAlert.IsNull())
+      return QVariant();
+
+    Handle(Message_Attribute) anAttribute = anExtendedAlert->Attribute();
+    if (anAttribute.IsNull())
+      return QVariant();
+
+    if (anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+      return QIcon (":/icons/item_shape.png");
+    else if (!Handle(Message_AttributeStream)::DownCast (anAttribute).IsNull())
+      return QIcon (":/icons/item_streamValues.png");
+    else
+      return QVariant();
+  }
+
+  if (theRole != Qt::DisplayRole && theRole != Qt::ToolTipRole)
+    return QVariant();
+
+  if (anAlert.IsNull())
+    return QVariant();
+
+  if (Column() == 0)
+  {
+    if (theRole == Qt::DisplayRole)
+    {
+      TCollection_AsciiString aMessageKey = anAlert->GetMessageKey();
+      if (aMessageKey.IsEmpty() && !Properties().IsNull())
+        aMessageKey = Properties()->Key();
+      return aMessageKey.ToCString();
+    }
+    else
+      return anAlert->DynamicType()->Name();
+  }
+
+  Message_MetricType aMetricType;
+  int aPosition;
+  if (MessageModel_TreeModel::IsMetricColumn (Column(), aMetricType, aPosition))
+  {
+    if (anExtendedAlert.IsNull())
+      return QVariant();
+
+    Handle(Message_AttributeMeter) anAttribute = Handle(Message_AttributeMeter)::DownCast (anExtendedAlert->Attribute());
+    if (anAttribute.IsNull() || !anAttribute->HasMetric (aMetricType))
+      return QVariant();
+
+    if (!anAttribute->IsMetricValid (aMetricType))
+      return QVariant ("in process");
+
+    if (aMetricType == Message_MetricType_ProcessCPUUserTime ||
+        aMetricType == Message_MetricType_ProcessCPUSystemTime ||
+        aMetricType == Message_MetricType_WallClock)
+    {
+      Standard_Real aCumulativeMetric = anAttribute->StopValue (aMetricType) - anAttribute->StartValue (aMetricType);
+      if (fabs (aCumulativeMetric) < Precision::Confusion())
+        return QVariant();
+
+      if (aPosition == 0) return aCumulativeMetric;
+      else if (aPosition == 1)
+      {
+        Standard_Real aReportCumulativeMetric = MessageModel_ItemReport::CumulativeMetric (aReport, aMetricType);
+        if (fabs (aReportCumulativeMetric) > Precision::Confusion())
+          return 100. * aCumulativeMetric / aReportCumulativeMetric;
+        else
+          return QVariant();
+      }
+    }
+    else
+    {
+      if (aPosition == 0) return anAttribute->StopValue (aMetricType);
+      else if (aPosition == 1)
+      {
+        Standard_Real aCumulativeMetric = anAttribute->StopValue (aMetricType) - anAttribute->StartValue (aMetricType);
+        if (fabs (aCumulativeMetric) < Precision::Confusion())
+          return QVariant();
+        else
+          return aCumulativeMetric;
+      }
+
+    }
+  }
+  return QVariant();
+}
+
+// =======================================================================
+// function : initRowCount
+// purpose :
+// =======================================================================
+int MessageModel_ItemAlert::initRowCount() const
+{
+  const Handle(Message_Alert)& anAlert = getAlert();
+  if (anAlert.IsNull())
+    return 0;
+
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(anAlert);
+  if (anExtendedAlert.IsNull())
+    return 0;
+
+  Handle(Message_CompositeAlerts) aCompositeAlert = anExtendedAlert->CompositeAlerts();
+  if (aCompositeAlert.IsNull())
+    return 0;
+
+  MessageModel_ItemAlert* aCurrentItem = (MessageModel_ItemAlert*)this;
+  for (int aGravityId = Message_Trace; aGravityId <= Message_Fail; aGravityId++)
+  {
+    const Message_ListOfAlert& anAlerts  = aCompositeAlert->Alerts ((Message_Gravity)aGravityId);
+    {
+      for (Message_ListOfAlert::Iterator anIt(anAlerts); anIt.More(); anIt.Next())
+      {
+        Message_ListOfAlert aCurAlerts;
+        aCurAlerts.Append (anIt.Value());
+        aCurrentItem->myChildAlerts.Bind(myChildAlerts.Size(), aCurAlerts);
+      }
+    }
+  }
+
+  return aCurrentItem->myChildAlerts.Size();
+}
+
+// =======================================================================
+// function : initStream
+// purpose :
+// =======================================================================
+void MessageModel_ItemAlert::initStream (Standard_OStream& OS) const
+{
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (getAlert());
+  if (anExtendedAlert.IsNull() || anExtendedAlert->Attribute().IsNull())
+    return;
+
+  Handle(Message_Attribute) anAttribute = anExtendedAlert->Attribute();
+  if (anAttribute.IsNull())
+    return;
+
+  if (Handle(Message_AttributeStream)::DownCast(anAttribute).IsNull())
+    return;
+
+  Handle(Message_AttributeStream) anAttributeStream = Handle(Message_AttributeStream)::DownCast (anExtendedAlert->Attribute());
+  OS << anAttributeStream->Stream().str();
+}
+
+// =======================================================================
+// function : SetStream
+// purpose :
+// =======================================================================
+bool MessageModel_ItemAlert::SetStream (const Standard_SStream& theSStream, Standard_Integer& theStartPos,
+                                        Standard_Integer& theLastPos) const
+{
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (getAlert());
+  if (anExtendedAlert.IsNull() || anExtendedAlert->Attribute().IsNull())
+    return false;
+
+  Handle(Message_Attribute) anAttribute = anExtendedAlert->Attribute();
+  if (anAttribute.IsNull())
+    return false;
+
+  if (Handle(Message_AttributeStream)::DownCast(anAttribute).IsNull())
+    return false;
+
+  Handle(Message_AttributeStream) anAttributeStream = Handle(Message_AttributeStream)::DownCast (anExtendedAlert->Attribute());
+  TCollection_AsciiString aStreamValue = Standard_Dump::Text (anAttributeStream->Stream());
+
+  TCollection_AsciiString aNewValue = Standard_Dump::Text (theSStream);
+
+  Standard_SStream aStream;
+  aStream << aStreamValue.SubString (1, theStartPos - 1);
+  aStream << aNewValue;
+  if (theLastPos + 1 <= aStreamValue.Length())
+    aStream << aStreamValue.SubString (theLastPos + 1, aStreamValue.Length());
+
+  //TCollection_AsciiString aStreamValue_debug = Standard_Dump::Text (aStream);
+
+  anAttributeStream->SetStream (aStream);
+
+  return true;
+}
+
+// =======================================================================
+// function : createChild
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemAlert::createChild (int theRow, int theColumn)
+{
+  return MessageModel_ItemAlert::CreateItem (currentItem(), theRow, theColumn);
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void MessageModel_ItemAlert::Init()
+{
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport> (Parent());
+  MessageModel_ItemAlertPtr anAlertItem;
+  Handle(Message_Alert) anAlert;
+  if (aReportItem)
+  {
+    Message_ListOfAlert anAlerts;
+    if (aReportItem->GetChildAlerts (Row(), anAlerts))
+    {
+      myAlert = anAlerts.First();
+    }
+  }
+  else
+  {
+    anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (Parent());
+    if (anAlertItem)
+    {
+      Message_ListOfAlert anAlerts;
+      if (anAlertItem->GetChildAlerts (Row(), anAlerts))
+      {
+        myAlert = anAlerts.First();
+      }
+    }
+  }
+
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(myAlert);
+  if (!anExtendedAlert.IsNull() && !anExtendedAlert->Attribute().IsNull())
+  {
+    Handle(Message_Attribute) anAttribute = anExtendedAlert->Attribute();
+    if (!anAttribute.IsNull())
+    {
+      //if (!Handle(Message_AttributeStream)::DownCast(anAttribute).IsNull())
+      //{
+      //  if (GetProperties().IsNull())
+      //  {
+      //    TreeModel_ItemBasePtr anItem = Parent()->Child (Row(), Column(), false);
+      //    SetProperties (new MessageModel_ItemPropertiesAttributeStream (anItem));
+      //  }
+      //  Handle(Message_AttributeStream) anAttributeStream = Handle(Message_AttributeStream)::DownCast (anExtendedAlert->Attribute());
+      //  Handle(MessageModel_ItemPropertiesAttributeStream) aProperties = Handle(MessageModel_ItemPropertiesAttributeStream)::DownCast (GetProperties());
+      //  aProperties->Init (anAttributeStream->GetStream());
+      //}
+      ////if (anAttribute->IsKind (STANDARD_TYPE (Message_AttributeObject)))
+      ////  myPresentation = Handle(Message_AttributeObject)::DownCast (anAttribute)->GetObject();
+      if (anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+        myPresentation = new Convert_TransientShape (Handle(TopoDS_AlertAttribute)::DownCast (anAttribute)->GetShape());
+    }
+    //TCollection_AsciiString aDescription = anExtendedAlert->Attribute()->GetDescription();
+    //Bnd_Box aBox;
+    //if (aBox.Init (Standard_SStream (aDescription.ToCString())))
+    //  myPresentation =new Convert_TransientShape (Convert_Tools::CreateShape (aBox));
+  }
+  MessageModel_ItemBase::Init();
+}
+
+// =======================================================================
+// function : Reset
+// purpose :
+// =======================================================================
+void MessageModel_ItemAlert::Reset()
+{
+  MessageModel_ItemBase::Reset();
+  myAlert = Handle(Message_Alert)();
+  myChildAlerts.Clear();
+  myPresentation = NULL;
+}
+
+// =======================================================================
+// function : initItem
+// purpose :
+// =======================================================================
+void MessageModel_ItemAlert::initItem() const
+{
+  if (IsInitialized())
+    return;
+  const_cast<MessageModel_ItemAlert*>(this)->Init();
+}
+
+// =======================================================================
+// function : getAlert
+// purpose :
+// =======================================================================
+const Handle(Message_Alert)& MessageModel_ItemAlert::getAlert() const
+{
+  initItem();
+  return myAlert;
+}
diff --git a/tools/MessageModel/MessageModel_ItemAlert.hxx b/tools/MessageModel/MessageModel_ItemAlert.hxx
new file mode 100644 (file)
index 0000000..c9b5d0b
--- /dev/null
@@ -0,0 +1,137 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemAlert_H
+#define MessageModel_ItemAlert_H
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <Message_Alert.hxx>
+#include <Message_ListOfAlert.hxx>
+#include <Message_Report.hxx>
+#include <NCollection_DataMap.hxx>
+#include <Standard.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QMap>
+#include <QVariant>
+#include <Standard_WarningsRestore.hxx>
+
+#include <NCollection_List.hxx>
+#include <NCollection_Vector.hxx>
+
+class QAbstractTableModel;
+
+class MessageModel_ItemAlert;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemAlert> MessageModel_ItemAlertPtr;
+
+//! \class MessageModel_ItemAlert
+//! This item is connected to Message_Alert.
+//! Parent is either MessageModel_ItemRoot or MessageModel_ItemAlert, children are MessageModel_ItemAlert or no children
+class MessageModel_ItemAlert : public MessageModel_ItemBase
+{
+public:
+
+  //! Creates an item wrapped by a shared pointer
+  //! \param theRow the item row positition in the parent item
+  //! \param theColumn the item column positition in the parent item
+  //! \return the pointer to the created item
+  static MessageModel_ItemAlertPtr CreateItem (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  { return MessageModel_ItemAlertPtr (new MessageModel_ItemAlert (theParent, theRow, theColumn)); }
+
+  //! Destructor
+  virtual ~MessageModel_ItemAlert() Standard_OVERRIDE {};
+
+  //! Returns the current shape
+  const Handle(Message_Alert)& GetAlert() const { return myAlert; }
+
+  //! Returns alert of the report for the parameter row
+  Standard_Boolean GetChildAlerts (const int theRow, Message_ListOfAlert& theAlerts) const { return myChildAlerts.Find(theRow, theAlerts); }
+
+  //! Inits the item, fills internal containers
+  Standard_EXPORT virtual void Init() Standard_OVERRIDE;
+
+  //! Resets cached values
+  Standard_EXPORT virtual void Reset() Standard_OVERRIDE;
+
+  //! Return data value for the role.
+  //! \param theRole a value role
+  //! \return the value
+  Standard_EXPORT virtual QVariant initValue (const int theRole) const Standard_OVERRIDE;
+
+  //! \return number of children.
+  Standard_EXPORT virtual int initRowCount() const Standard_OVERRIDE;
+
+  //! Returns stream value of the item to fulfill property panel.
+  //! \return stream value or dummy
+  Standard_EXPORT virtual bool SetStream (const Standard_SStream& theSStream, Standard_Integer& theStartPos,
+                                          Standard_Integer& theLastPos) const Standard_OVERRIDE;
+
+  //! Sets some shape to present the item
+  //! \param theShape shape instance
+  void SetCustomShape (const TopoDS_Shape& theShape) { myCustomShape = theShape; }
+
+  //! Returns custom shape to present the item
+  //! \return instance of the shape
+  const TopoDS_Shape& GetCustomShape() const { return myCustomShape; }
+
+  //! Returns presentation of the attribute to be visualized in the view
+  //! \param theRow a model index row
+  //! \param theColumn a model index column
+  //! \thePresentations [out] container of presentation handles to be visualized
+  virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations) Standard_OVERRIDE
+  { TreeModel_ItemBase::Presentations (thePresentations); thePresentations.Append (myPresentation); }
+
+
+  ////! Returns summ of children alert elapsed times. The method is recusive.
+  ////! \param theAlert a message alert
+  ////! \return double value
+  //Standard_EXPORT static double CumulativeMetric (const Handle(Message_Alert)& theAlert);
+
+protected:
+
+  //! Initialize the current item. It is empty because Reset() is also empty.
+  virtual void initItem() const Standard_OVERRIDE;
+
+  //! Returns stream value of the item to fulfill property panel.
+  //! \return stream value or dummy
+  Standard_EXPORT virtual void initStream (Standard_OStream& OS) const Standard_OVERRIDE;
+
+  //! Creates a child item in the given position.
+  //! \param theRow the child row position
+  //! \param theColumn the child column position
+  //! \return the created item
+  virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) Standard_OVERRIDE;
+
+  //! Returns current alert, initialized item if it has not been initialized yet
+  //! \return alert value
+  const Handle(Message_Alert)& getAlert() const;
+
+private:
+
+  //! Constructor
+  MessageModel_ItemAlert (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : MessageModel_ItemBase (theParent, theRow, theColumn) {}
+
+private:
+  Handle(Message_Alert) myAlert;
+
+  NCollection_DataMap<Standard_Integer, Message_ListOfAlert> myChildAlerts; //!< container of child alerts
+
+  TopoDS_Shape myCustomShape;
+  Handle(Standard_Transient) myPresentation;
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_ItemBase.cxx b/tools/MessageModel/MessageModel_ItemBase.cxx
new file mode 100644 (file)
index 0000000..de74f85
--- /dev/null
@@ -0,0 +1,47 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+
+// =======================================================================
+// function : isReversed
+// purpose :
+// =======================================================================
+Standard_Boolean MessageModel_ItemBase::isReversed() const
+{
+  TreeModel_ItemBasePtr aParentItem = GetRootItem();
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (aParentItem);
+  return aRootItem ? aRootItem->IsReversed() : Standard_False;
+}
+
+// =======================================================================
+// function : GetRootItem
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemBase::GetRootItem() const
+{
+  TreeModel_ItemBasePtr anItem = Parent();
+  while (anItem)
+  {
+    if (MessageModel_ItemRootPtr aThisRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItem))
+    {
+      return aThisRootItem;
+    }
+    anItem = anItem->Parent();
+  }
+  return TreeModel_ItemBasePtr();
+}
diff --git a/tools/MessageModel/MessageModel_ItemBase.hxx b/tools/MessageModel/MessageModel_ItemBase.hxx
new file mode 100644 (file)
index 0000000..dfd9e7f
--- /dev/null
@@ -0,0 +1,56 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemBase_H
+#define MessageModel_ItemBase_H
+
+#include <Standard.hxx>
+#include <TopoDS_Shape.hxx>
+#include <inspector/TreeModel_ItemBase.hxx>
+
+class MessageModel_ItemBase;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemBase> MessageModel_ItemBasePtr;
+
+//! \class MessageModel_ItemBase
+// \brief Declaration of the tree model base item.
+class MessageModel_ItemBase : public TreeModel_ItemBase
+{
+public:
+
+  //! Resets cached values
+  virtual void Reset() Standard_OVERRIDE { TreeModel_ItemBase::Reset(); }
+
+protected:
+
+  //! Initialize the current item. It creates a backup of the specific item information
+  virtual void initItem() const {};
+
+  //! Constructor
+  //! param theParent a parent item
+  //! \param theRow the item row positition in the parent item
+  //! \param theColumn the item column positition in the parent item
+  MessageModel_ItemBase (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : TreeModel_ItemBase (theParent, theRow, theColumn) {}
+
+  //! Return whether the view is reversed or not
+  //! \return boolean value
+  Standard_Boolean isReversed() const;
+
+  //! Return root item
+  //! \return an item instance
+  TreeModel_ItemBasePtr GetRootItem() const;
+};
+
+#endif
\ No newline at end of file
diff --git a/tools/MessageModel/MessageModel_ItemReport.cxx b/tools/MessageModel/MessageModel_ItemReport.cxx
new file mode 100644 (file)
index 0000000..9efaf20
--- /dev/null
@@ -0,0 +1,233 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_ItemReport.hxx>
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_TreeModel.hxx>
+
+#include <Message.hxx>
+#include <Message_Alert.hxx>
+#include <Message_AttributeMeter.hxx>
+#include <Message_Messenger.hxx>
+#include <Message_PrinterToReport.hxx>
+#include <OSD_Path.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QColor>
+#include <Standard_WarningsRestore.hxx>
+
+// =======================================================================
+// function : initValue
+// purpose :
+// =======================================================================
+QVariant MessageModel_ItemReport::initValue (const int theRole) const
+{
+  QVariant aParentValue = MessageModel_ItemBase::initValue (theRole);
+  if (aParentValue.isValid())
+    return aParentValue;
+
+  const Handle(Message_Report)& aReport = getReport();
+  if (aReport.IsNull())
+    return QVariant();
+
+  if (theRole == Qt::ForegroundRole)
+  {
+    if (!aReport->IsActiveInMessenger())
+      return QColor(Qt::darkGray);
+
+    return QVariant();
+  }
+  if (theRole == Qt::ToolTipRole && !myDescription.IsEmpty() && Column() == 0) // display the exported file name in tool tip
+  {
+    OSD_Path aPath(myDescription);
+    return QString ("%1%2").arg (aPath.Name().ToCString()).arg (aPath.Extension().ToCString());
+  }
+
+  if (theRole != Qt::DisplayRole)
+    return QVariant();
+
+  if (Column() == 0)
+    return aReport->DynamicType()->Name();
+
+  Message_MetricType aMetricType;
+  int aPosition;
+  if (MessageModel_TreeModel::IsMetricColumn (Column(), aMetricType, aPosition) &&
+      (aMetricType == Message_MetricType_ProcessCPUUserTime || aMetricType == Message_MetricType_ProcessCPUSystemTime ||
+       aMetricType == Message_MetricType_WallClock))
+  {
+    if (aPosition == 0) return CumulativeMetric (aReport, aMetricType);
+    else if (aPosition == 1) return "100";
+  }
+  return QVariant();
+}
+
+// =======================================================================
+// function : initRowCount
+// purpose :
+// =======================================================================
+int MessageModel_ItemReport::initRowCount() const
+{
+  const Handle(Message_Report)& aReport = getReport();
+  if (aReport.IsNull())
+    return 0;
+
+  MessageModel_ItemReport* aCurrentItem = (MessageModel_ItemReport*)this;
+  for (int aGravityId = Message_Trace; aGravityId <= Message_Fail; aGravityId++)
+  {
+    const Message_ListOfAlert& anAlerts = aReport->GetAlerts ((Message_Gravity)aGravityId);
+    for (Message_ListOfAlert::Iterator anIt(anAlerts); anIt.More(); anIt.Next())
+    {
+      Message_ListOfAlert aCurAlerts;
+      aCurAlerts.Append (anIt.Value());
+      aCurrentItem->myChildAlerts.Bind(myChildAlerts.Size(), aCurAlerts);
+    }
+  }
+  return aCurrentItem->myChildAlerts.Size();
+}
+
+// =======================================================================
+// function : createChild
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemReport::createChild (int theRow, int theColumn)
+{
+  return MessageModel_ItemAlert::CreateItem (currentItem(), theRow, theColumn);
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void MessageModel_ItemReport::Init()
+{
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (Parent());
+  myReport = aRootItem ? aRootItem->GetReport (Row(), myDescription) : Handle(Message_Report)();
+
+  MessageModel_ItemBase::Init();
+}
+
+// =======================================================================
+// function : getReport
+// purpose :
+// =======================================================================
+const Handle(Message_Report)& MessageModel_ItemReport::getReport() const
+{
+  initItem();
+  return myReport;
+}
+
+// =======================================================================
+// function : Reset
+// purpose :
+// =======================================================================
+void MessageModel_ItemReport::Reset()
+{
+  MessageModel_ItemBase::Reset();
+  myReport = Handle(Message_Report)();
+  myChildAlerts.Clear();
+}
+
+// =======================================================================
+// function : initItem
+// purpose :
+// =======================================================================
+void MessageModel_ItemReport::initItem() const
+{
+  if (IsInitialized())
+    return;
+  const_cast<MessageModel_ItemReport*>(this)->Init();
+}
+
+// =======================================================================
+// function : FindReportItem
+// purpose :
+// =======================================================================
+MessageModel_ItemReportPtr MessageModel_ItemReport::FindReportItem (const TreeModel_ItemBasePtr& theItem)
+{
+  TreeModel_ItemBasePtr anItem = theItem;
+  while (anItem)
+  {
+    if (MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItem))
+      return aReportItem;
+
+    anItem = anItem->Parent();
+  }
+  return MessageModel_ItemReportPtr();
+}
+
+// =======================================================================
+// function : FindReport
+// purpose :
+// =======================================================================
+Handle(Message_Report) MessageModel_ItemReport::FindReport (const MessageModel_ItemBasePtr& theItem)
+{
+  Handle(Message_Report) aReport;
+
+  MessageModel_ItemBasePtr anItem = theItem;
+  while (anItem)
+  {
+    MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItem);
+
+    if (aReportItem)
+      return aReportItem->GetReport();
+
+    anItem = itemDynamicCast<MessageModel_ItemBase>(anItem->Parent());
+  }
+  return NULL;
+}
+
+// =======================================================================
+// function : CumulativeMetric
+// purpose :
+// =======================================================================
+Standard_Real MessageModel_ItemReport::CumulativeMetric (const Handle(Message_Report)& theReport, const Message_MetricType theMetricType)
+{
+  if (!theReport->ActiveMetrics().Contains (theMetricType))
+    return 0;
+
+  Standard_Real aMetric = 0;
+  for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+  {
+    const Message_ListOfAlert& anAlerts = theReport->GetAlerts ((Message_Gravity)iGravity);
+    Handle(Message_AttributeMeter) aFirstAttribute/*, aLastAttribute*/;
+    for (Message_ListOfAlert::Iterator anAlertsIterator (anAlerts); anAlertsIterator.More(); anAlertsIterator.Next())
+    {
+      Handle(Message_AlertExtended) anAlert = Handle(Message_AlertExtended)::DownCast (anAlertsIterator.Value());
+      if (anAlert.IsNull())
+        continue;
+      Handle(Message_AttributeMeter) anAttribute = Handle(Message_AttributeMeter)::DownCast (anAlert->Attribute());
+      if (anAttribute.IsNull() || !anAttribute->HasMetric (theMetricType) || !anAttribute->IsMetricValid (theMetricType))
+        continue;
+
+      //if (aFirstAttribute.IsNull())
+      //  aFirstAttribute = anAttribute;
+      //else
+      //{
+        //aLastAttribute = anAttribute;
+      //}
+      aMetric += anAttribute->StopValue (theMetricType) - anAttribute->StartValue (theMetricType);
+    }
+    //if (aFirstAttribute.IsNull())
+    //  continue;
+    //if (aLastAttribute.IsNull())
+    //  aLastAttribute = aFirstAttribute;
+
+    //aMetric += aLastAttribute->StopValue (theMetricType) - aFirstAttribute->StartValue (theMetricType);
+  }
+  return aMetric;
+}
diff --git a/tools/MessageModel/MessageModel_ItemReport.hxx b/tools/MessageModel/MessageModel_ItemReport.hxx
new file mode 100644 (file)
index 0000000..f03d98e
--- /dev/null
@@ -0,0 +1,117 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemReport_H
+#define MessageModel_ItemReport_H
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <Message_Alert.hxx>
+#include <Message_Report.hxx>
+#include <NCollection_DataMap.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QMap>
+#include <QVariant>
+#include <Standard_WarningsRestore.hxx>
+
+class MessageModel_ItemReport;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemReport> MessageModel_ItemReportPtr;
+
+//! \class MessageModel_ItemReport
+//! This item is connected to Message_Alert.
+//! Parent is MessageModel_ItemRoot, children are MessageModel_ItemAlert or no children
+class MessageModel_ItemReport : public MessageModel_ItemBase
+{
+public:
+
+  //! Creates an item wrapped by a shared pointer
+  //! \param theRow the item row positition in the parent item
+  //! \param theColumn the item column positition in the parent item
+  //! \return the pointer to the created item
+  static MessageModel_ItemReportPtr CreateItem (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  { return MessageModel_ItemReportPtr (new MessageModel_ItemReport (theParent, theRow, theColumn)); }
+
+  //! Destructor
+  virtual ~MessageModel_ItemReport() Standard_OVERRIDE {};
+
+  //! Returns the current shape
+  const Handle(Message_Report)& GetReport() const { return myReport; }
+
+  //! Returns alert of the report for the parameter row
+  Standard_Boolean GetChildAlerts (const int theRow, Message_ListOfAlert& theAlerts) const { return myChildAlerts.Find(theRow, theAlerts); }
+
+  //! Returns the report description or NULL
+  const TCollection_AsciiString& GetDescription() const { return myDescription; }
+
+  //! Inits the item, fills internal containers
+  Standard_EXPORT virtual void Init() Standard_OVERRIDE;
+
+  //! Resets cached values
+  Standard_EXPORT virtual void Reset() Standard_OVERRIDE;
+
+  //! Return data value for the role.
+  //! \param theRole a value role
+  //! \return the value
+  Standard_EXPORT virtual QVariant initValue (const int theRole) const Standard_OVERRIDE;
+
+  //! \return number of children.
+  Standard_EXPORT virtual int initRowCount() const Standard_OVERRIDE;
+
+  //! Returns report of the tree model item. Iterates up by parents intil the report item is found.
+  //! \return an item or NULL
+  Standard_EXPORT static MessageModel_ItemReportPtr FindReportItem (const TreeModel_ItemBasePtr& theItem);
+
+  //! Returns report of the item
+  static Handle(Message_Report) FindReport (const MessageModel_ItemBasePtr& thetItem);
+
+  //! Returns report cumulative metric as stop time of the last alert minus start time of the first alert
+  Standard_EXPORT static Standard_Real CumulativeMetric (const Handle(Message_Report)& theReport, const Message_MetricType theMetricType);
+
+protected:
+
+  //! Initialize the current item. It is empty because Reset() is also empty.
+  virtual void initItem() const Standard_OVERRIDE;
+
+  //! Creates a child item in the given position.
+  //! \param theRow the child row position
+  //! \param theColumn the child column position
+  //! \return the created item
+  virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) Standard_OVERRIDE;
+
+  //! Returns number of child shapes. Init item if it is not initialized
+  //! \return integer value
+  int getRowCount() const;
+
+  //! Returns current shape, initialized item if it has not been initialized yet
+  //! \return shape value
+  const Handle(Message_Report)& getReport() const;
+
+private:
+
+  //! Constructor
+  MessageModel_ItemReport (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : MessageModel_ItemBase (theParent, theRow, theColumn) {}
+
+private:
+
+  NCollection_DataMap<Standard_Integer, Message_ListOfAlert> myChildAlerts; //!< container of child alerts
+
+  Handle(Message_Report) myReport; //!< current report
+  TCollection_AsciiString myDescription; //!< description
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_ItemRoot.cxx b/tools/MessageModel/MessageModel_ItemRoot.cxx
new file mode 100644 (file)
index 0000000..b42dcc8
--- /dev/null
@@ -0,0 +1,96 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+
+// =======================================================================
+// function : SetReport
+// purpose :
+// =======================================================================
+void MessageModel_ItemRoot::SetReport (const int theRowId, const Handle(Message_Report)& theReport,
+                                       const TCollection_AsciiString& theReportDescription)
+{
+  NCollection_List<MessageModel_ReportInformation>::Iterator aReportsIt (myReports);
+  for (int aRowId = 0; aReportsIt.More(); aReportsIt.Next(), aRowId++)
+  {
+    if (aRowId == theRowId)
+      break;
+  }
+  aReportsIt.Value().myReport = theReport;
+  aReportsIt.Value().myDescription = theReportDescription;
+}
+
+// =======================================================================
+// function : GetReport
+// purpose :
+// =======================================================================
+const Handle(Message_Report)& MessageModel_ItemRoot::GetReport (const int theRowId,
+  TCollection_AsciiString& theReportDescription)
+{
+  NCollection_List<MessageModel_ReportInformation>::Iterator aReportsIt (myReports);
+  for (int aRowId = 0; aReportsIt.More(); aReportsIt.Next(), aRowId++)
+  {
+    if (aRowId == theRowId)
+      break;
+  }
+  theReportDescription = aReportsIt.Value().myDescription;
+  return aReportsIt.Value().myReport;
+}
+
+// =======================================================================
+// function : HasReport
+// purpose :
+// =======================================================================
+Standard_Boolean MessageModel_ItemRoot::HasReport (const Handle(Message_Report)& theReport)
+{
+  NCollection_List<MessageModel_ReportInformation>::Iterator aReportsIt (myReports);
+  for (int aRowId = 0; aReportsIt.More(); aReportsIt.Next(), aRowId++)
+  {
+    if (aReportsIt.Value().myReport == theReport)
+      return Standard_True;
+  }
+  return Standard_False;
+}
+
+// =======================================================================
+// function : initValue
+// purpose :
+// =======================================================================
+QVariant MessageModel_ItemRoot::initValue (const int theRole) const
+{
+  QVariant aParentValue = MessageModel_ItemBase::initValue (theRole);
+  if (aParentValue.isValid())
+    return aParentValue;
+
+  if (Column() != 0)
+    return QVariant();
+
+  if (theRole == Qt::DisplayRole)
+    return myName.IsEmpty() ? "Message_Reports" : myName.ToCString();
+
+  return QVariant();
+}
+
+// =======================================================================
+// function : createChild
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemRoot::createChild (int theRow, int theColumn)
+{
+  return MessageModel_ItemReport::CreateItem (currentItem(), theRow, theColumn);
+}
+
diff --git a/tools/MessageModel/MessageModel_ItemRoot.hxx b/tools/MessageModel/MessageModel_ItemRoot.hxx
new file mode 100644 (file)
index 0000000..197bd1e
--- /dev/null
@@ -0,0 +1,126 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemRoot_H
+#define MessageModel_ItemRoot_H
+
+#include <Message_Alert.hxx>
+#include <Message_Report.hxx>
+#include <NCollection_List.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <inspector/MessageModel_ItemBase.hxx>
+
+class MessageModel_ItemRoot;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemRoot> MessageModel_ItemRootPtr;
+
+//! \struct to extend report by description
+struct MessageModel_ReportInformation
+{
+  //! Constructor
+  MessageModel_ReportInformation (Handle(Message_Report) theReport, const TCollection_AsciiString& theDescription)
+    : myReport (theReport), myDescription (theDescription) {}
+
+  Handle(Message_Report) myReport; //! report
+  TCollection_AsciiString myDescription; //! report description
+};
+
+//! \class MessageModel_ItemRoot
+//! Collects message reports that should be visualized in tree view. Reports are cached and if reports are not needed,
+//! cache should be cleared using RemoveAllReports
+//! Parent is NULL, children are MessageModel_ItemReport items.
+class MessageModel_ItemRoot : public MessageModel_ItemBase
+{
+public:
+
+  //! Creates an item wrapped by a shared pointer
+  static MessageModel_ItemRootPtr CreateItem (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+    { return MessageModel_ItemRootPtr (new MessageModel_ItemRoot (theParent, theRow, theColumn)); }
+
+  //! Destructor
+  virtual ~MessageModel_ItemRoot() Standard_OVERRIDE {};
+
+  //! Appends new report
+  //! \param theReport a report instance
+  //! \param theReportDescription an additional report information
+  void AddReport (const Handle(Message_Report)& theReport, const TCollection_AsciiString& theReportDescription)
+  { myReports.Append (MessageModel_ReportInformation (theReport, theReportDescription)); }
+
+  //! Set report, se it into the given row index
+  //! \param theRowId a report child row
+  //! \param theReport a report instance
+  //! \param theReportDescription an additional report information
+  Standard_EXPORT void SetReport (const int theRowId, const Handle(Message_Report)& theReport,
+    const TCollection_AsciiString& theReportDescription = "");
+
+  //! Returns true if report exists is in the list of the current reports
+  //! \param theReport a report instance
+  //! \return boolen value
+  Standard_EXPORT Standard_Boolean HasReport (const Handle(Message_Report)& theReport);
+
+  //!< Returns processed reports
+  const NCollection_List<MessageModel_ReportInformation>& Reports() const { return myReports; }
+
+  //! Clears internal container of added reports
+  void RemoveAllReports() { myReports.Clear(); }
+
+  //! Returns report by the number
+  //! \param theRowId an index of the report in the internal container.
+  Standard_EXPORT const Handle(Message_Report)& GetReport (const int theRowId, TCollection_AsciiString& theReportDescription);
+
+  //! Set the view reversed. If reversed, the last report alert is upper item in the tree view
+  //! \param theReversed boolean flag
+  void SetReversed (const Standard_Boolean& theReversed) { myIsReversed = theReversed; }
+
+  //! Return whether the view is reversed or not
+  //! \return boolean value
+  Standard_Boolean IsReversed() const { return myIsReversed; };
+
+  //! Set the view reversed. If reversed, the last report alert is upper item in the tree view
+  //! \param theReversed boolean flag
+  void SetName (const TCollection_AsciiString& theName) { myName = theName; }
+
+protected:
+
+  //! Return data value for the role.
+  //! \param theRole a value role
+  //! \return the value
+  virtual QVariant initValue (const int theRole) const Standard_OVERRIDE;
+
+  //! \return number of children.
+  virtual int initRowCount() const Standard_OVERRIDE { return myReports.Size(); }
+
+  //! Creates a child item in the given position.
+  //! \param theRow the child row position
+  //! \param theColumn the child column position
+  //! \return the created item
+  virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) Standard_OVERRIDE;
+
+private:
+
+  //! Constructor
+  //! param theParent a parent item
+  MessageModel_ItemRoot (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : MessageModel_ItemBase (theParent, theRow, theColumn), myIsReversed (Standard_False) {}
+
+private:
+
+  NCollection_List<MessageModel_ReportInformation> myReports; //!< reports sent by algorithms
+  Standard_Boolean myIsReversed; //!< state if the model is reversed
+  TCollection_AsciiString myName; //!< DisplayRole data, if defined
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_Tools.cxx b/tools/MessageModel/MessageModel_Tools.cxx
new file mode 100644 (file)
index 0000000..5348d47
--- /dev/null
@@ -0,0 +1,59 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <inspector/ViewControl_Table.hxx>
+#include <inspector/ViewControl_TableModelValues.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepTools.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeObject.hxx>
+#include <Message_AttributeStream.hxx>
+
+#include <Precision.hxx>
+#include <TopoDS_AlertAttribute.hxx>
+#include <TopoDS_Edge.hxx>
+
+// =======================================================================
+// function : GetPointerInfo
+// purpose :
+// =======================================================================
+TCollection_AsciiString MessageModel_Tools::GetPointerInfo (const Handle(Standard_Transient)& thePointer, const bool isShortInfo)
+{
+  if (thePointer.IsNull())
+    return TCollection_AsciiString();
+
+  std::ostringstream aPtrStr;
+  aPtrStr << thePointer.operator->();
+  if (!isShortInfo)
+    return aPtrStr.str().c_str();
+
+  TCollection_AsciiString anInfoPtr (aPtrStr.str().c_str());
+  for (int aSymbolId = 1; aSymbolId < anInfoPtr.Length(); aSymbolId++)
+  {
+    if (anInfoPtr.Value(aSymbolId) != '0')
+    {
+      anInfoPtr = anInfoPtr.SubString (aSymbolId, anInfoPtr.Length());
+      anInfoPtr.Prepend("0x");
+      return anInfoPtr;
+    }
+  }
+  return aPtrStr.str().c_str();
+}
diff --git a/tools/MessageModel/MessageModel_Tools.hxx b/tools/MessageModel/MessageModel_Tools.hxx
new file mode 100644 (file)
index 0000000..c83922a
--- /dev/null
@@ -0,0 +1,53 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_Tools_H
+#define MessageModel_Tools_H
+
+#include <Standard.hxx>
+
+#include <TCollection_AsciiString.hxx>
+#include <Message_ListOfAlert.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Vector.hxx>
+#include <Standard_Transient.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <inspector/TreeModel_ItemBase.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QList>
+#include <Standard_WarningsRestore.hxx>
+
+class Message_Alert;
+class ViewControl_TableModelValues;
+
+class ViewControl_Table;
+
+//! \class MessageModel_Tools
+//! It gives auxiliary methods for Message classes manipulation
+class MessageModel_Tools
+{
+public:
+
+  //! Convert pointer to string value
+  //! \param thePointer a pointer
+  //! \param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
+  //! \return the string value 
+  Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const Handle(Standard_Transient)& thePointer,
+                                                                 const bool isShortInfo = true);
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_TreeModel.cxx b/tools/MessageModel/MessageModel_TreeModel.cxx
new file mode 100644 (file)
index 0000000..b5950bd
--- /dev/null
@@ -0,0 +1,213 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_TreeModel.hxx>
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/TreeModel_ColumnType.hxx>
+
+#include <Message.hxx>
+
+const int COLUMN_NAME_WIDTH = 230;
+const int COLUMN_SIZE_WIDTH = 30;
+
+const int COLUMN_REAL_VALUE_WIDTH = 115;
+const int COLUMN_PERCENT_VALUE_WIDTH = 50;
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+MessageModel_TreeModel::MessageModel_TreeModel (QObject* theParent)
+: TreeModel_ModelBase (theParent), myIsReversed (Standard_False)
+{
+}
+
+// =======================================================================
+// function : InitColumns
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::InitColumns()
+{
+  // 0 - Name, 1 - visibility, 2 - Row
+  setHeaderItem (TreeModel_ColumnType_Name,       TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
+  setHeaderItem (TreeModel_ColumnType_Visibility, TreeModel_HeaderSection ("Visibility", TreeModel_ModelBase::ColumnVisibilityWidth()));
+  setHeaderItem (TreeModel_ColumnType_Row,        TreeModel_HeaderSection ("Row", COLUMN_SIZE_WIDTH, Standard_True /*hidden*/));
+
+  int aNextIndex = 3;
+  for (int aMetricId = (int)Message_MetricType_None + 1; aMetricId <= (int)Message_MetricType_MemHeapUsage; aMetricId++)
+  {
+    Message_MetricType aMetricType = (Message_MetricType)aMetricId;
+    OSD_MemInfo::Counter aMemInfo;
+    bool isMemInfo = Message::ToOSDMetric (aMetricType, aMemInfo);
+
+    setHeaderItem (aNextIndex++,
+      TreeModel_HeaderSection (QString("%1 [%2]").arg (Message::MetricToString (aMetricType)).arg(isMemInfo ? "Mb" : "s"),
+      COLUMN_REAL_VALUE_WIDTH));
+    setHeaderItem (aNextIndex++, TreeModel_HeaderSection (isMemInfo ? "Delta" : "%", COLUMN_PERCENT_VALUE_WIDTH));
+  }
+}
+
+// =======================================================================
+// function : GetMetricColumns
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::GetMetricColumns (const Message_MetricType theMetricType, QList<int>& theMetricColumns)
+{
+  theMetricColumns.clear();
+  int aNextIndex = 3; // after default parent columns, see InitColumns
+  for (int aMetricId = (int)Message_MetricType_None + 1; aMetricId <= (int)Message_MetricType_MemHeapUsage; aMetricId++)
+  {
+    if (theMetricType != (Message_MetricType)aMetricId)
+    {
+      aNextIndex += 2;
+      continue;
+    }
+    theMetricColumns.append (aNextIndex++);
+    theMetricColumns.append (aNextIndex++);
+  }
+}
+
+// =======================================================================
+// function : IsMetricColumn
+// purpose :
+// =======================================================================
+bool MessageModel_TreeModel::IsMetricColumn (const int theColumnId, Message_MetricType& theMetricType, int& thePosition)
+{
+  int aNextIndex = 3; // after default parent columns, see InitColumns
+  for (int aMetricId = (int)Message_MetricType_None + 1; aMetricId <= (int)Message_MetricType_MemHeapUsage; aMetricId++)
+  {
+    if (theColumnId == aNextIndex || theColumnId == aNextIndex + 1)
+    {
+      theMetricType = (Message_MetricType)aMetricId;
+      thePosition = theColumnId - aNextIndex;
+      return true;
+    }
+    aNextIndex += 2;
+  }
+  return false;
+}
+
+// =======================================================================
+// function : createRootItem
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_TreeModel::createRootItem (const int theColumnId)
+{
+  return MessageModel_ItemRoot::CreateItem (TreeModel_ItemBasePtr(), 0, theColumnId);
+}
+
+// =======================================================================
+// function : HasShape
+// purpose :
+// =======================================================================
+Standard_Boolean MessageModel_TreeModel::HasReport (const Handle(Message_Report)& theReport)
+{
+  if (columnCount() == 0)
+    return Standard_False;
+
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (0));
+  return aRootItem && aRootItem->HasReport (theReport);
+}
+
+// =======================================================================
+// function : AddShape
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::AddReport (const Handle(Message_Report)& theReport,
+                                        const TCollection_AsciiString& theReportDescription)
+{
+  for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
+  {
+    MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (aColId));
+    if (!aRootItem)
+      continue;
+    aRootItem->AddReport (theReport, theReportDescription);
+    aRootItem->SetReversed (myIsReversed);
+  }
+
+  Reset();
+  EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : SetReport
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::SetReport (const int theRowId, const Handle(Message_Report)& theReport,
+                                        const TCollection_AsciiString& theReportDescription)
+{
+  for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
+  {
+    MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (aColId));
+    if (!aRootItem)
+      continue;
+    aRootItem->SetReport (theRowId, theReport, theReportDescription);
+  }
+  Reset();
+  EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : Reports
+// purpose :
+// =======================================================================
+const NCollection_List<MessageModel_ReportInformation>& MessageModel_TreeModel::Reports() const
+{
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (0));
+  return aRootItem->Reports();
+}
+
+// =======================================================================
+// function : SetReversed
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::SetReversed (const Standard_Boolean& theReversed)
+{
+  myIsReversed = theReversed;
+
+  for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
+  {
+    MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (aColId));
+    if (aRootItem)
+      aRootItem->SetReversed (myIsReversed);
+  }
+
+  Reset();
+  EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : UpdateTreeModel
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::SetRootItemName (const TCollection_AsciiString& theName)
+{
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (0));
+  if (aRootItem)
+    aRootItem->SetName (theName);
+}
+
+// =======================================================================
+// function : UpdateTreeModel
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::UpdateTreeModel()
+{
+  Reset();
+  EmitLayoutChanged();
+}
diff --git a/tools/MessageModel/MessageModel_TreeModel.hxx b/tools/MessageModel/MessageModel_TreeModel.hxx
new file mode 100644 (file)
index 0000000..01eeba4
--- /dev/null
@@ -0,0 +1,105 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_TreeModel_H
+#define MessageModel_TreeModel_H
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <Message_Report.hxx>
+#include <inspector/TreeModel_ModelBase.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QMap>
+#include <QObject>
+#include <Standard_WarningsRestore.hxx>
+
+class MessageModel_TreeModel;
+
+//! \class MessageModel_TreeModel
+//! View model to visualize MessageReport/s content
+class MessageModel_TreeModel : public TreeModel_ModelBase
+{
+public:
+
+  //! Constructor
+  Standard_EXPORT MessageModel_TreeModel (QObject* theParent);
+
+  //! Destructor
+  virtual ~MessageModel_TreeModel() Standard_OVERRIDE {};
+
+  //! Creates model columns and root items.
+  Standard_EXPORT virtual void InitColumns() Standard_OVERRIDE;
+
+  //!< Returns columns of the model for the metric
+  //!< \param theMetricType metric
+  //!< \param theMetricColumns [out] container of metric columns
+  static Standard_EXPORT void GetMetricColumns (const Message_MetricType theMetricType, QList<int>& theMetricColumns);
+
+  //!< Returns metric type for the column
+  //!< \param theColumnId [in] index of the tree column
+  //!< \param theMetricType [out] metric type if found
+  //!< \param thePosition [out] index of the metric column, 0 - is metric, 1 - is delta
+  //!< \return true if the column has metric parameters
+  static Standard_EXPORT bool IsMetricColumn (const int theColumnId, Message_MetricType& theMetricType, int& thePosition);
+
+  //! Returns true if parameter report was added into the model
+  //! \param theReport a report instance
+  //! \return boolen value
+  Standard_EXPORT Standard_Boolean HasReport (const Handle(Message_Report)& theReport);
+
+  //! Add shape, append it to the model root item
+  //! \param theReport a report instance
+  //! \param theReportDescription an additional report information
+  Standard_EXPORT void AddReport (const Handle(Message_Report)& theReport,
+    const TCollection_AsciiString& theReportDescription = "");
+
+  //! Set report, se it into the given row index
+  //! \param theRowId a report child row
+  //! \param theReport a report instance
+  //! \param theReportDescription an additional report information
+  Standard_EXPORT void SetReport (const int theRowId, const Handle(Message_Report)& theReport,
+    const TCollection_AsciiString& theReportDescription = "");
+
+  //!< Returns processed reports
+  Standard_EXPORT const NCollection_List<MessageModel_ReportInformation>& Reports() const;
+
+  //! Set the view reversed. If reversed, the last report alert is upper item in the tree view
+  //! \param theReversed boolean flag
+  Standard_EXPORT void SetReversed (const Standard_Boolean& theReversed);
+  
+  //! Return whether the view is reversed or not
+  //! \return boolean value
+  Standard_Boolean IsReversed() const { return myIsReversed; };
+
+  //! Sets the text value of the Root item, only "Name" column accepts the parameter value
+  //! \theName visulized text of root item
+  Standard_EXPORT void SetRootItemName (const TCollection_AsciiString& theName);
+
+  //! Updates tree model
+  Standard_EXPORT void UpdateTreeModel();
+
+protected:
+  //! Creates root item
+  //! \param theColumnId index of a column
+  virtual TreeModel_ItemBasePtr createRootItem (const int theColumnId) Standard_OVERRIDE;
+
+private:
+  Standard_Boolean myIsReversed; //!< state if the model is reversed
+};
+
+#endif
diff --git a/tools/MessageModel/icons/item_shape.png b/tools/MessageModel/icons/item_shape.png
new file mode 100644 (file)
index 0000000..a808bc5
Binary files /dev/null and b/tools/MessageModel/icons/item_shape.png differ
diff --git a/tools/MessageModel/icons/item_shape.svg b/tools/MessageModel/icons/item_shape.svg
new file mode 100644 (file)
index 0000000..14313ed
--- /dev/null
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="20"
+   viewBox="0 0 5.2916664 5.2916666"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="item_shape.svg"
+   inkscape:export-filename="D:\OCCT\master_CR29451_1\tools\MessageModel\icons\item_shape.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <defs
+     id="defs2">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="-2.6544163 : -0.28690906 : 1"
+       inkscape:vp_y="0 : 1028.295 : 0"
+       inkscape:vp_z="9.504499 : -1.1228559 : 1"
+       inkscape:persp3d-origin="2.7661607 : -1.3768436 : 1"
+       id="perspective3711" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.839192"
+     inkscape:cx="4.9829441"
+     inkscape:cy="7.75434"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1446"
+     inkscape:window-height="676"
+     inkscape:window-x="1766"
+     inkscape:window-y="124"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(71.966667,-93.642022)">
+    <g
+       sodipodi:type="inkscape:box3d"
+       id="g3741"
+       inkscape:perspectiveID="#perspective3711"
+       inkscape:corner0="0.78884625 : 0.0054590483 : 0 : 1"
+       inkscape:corner7="-0.14713316 : 0.0022509206 : 0.25 : 1">
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3743"
+         style="fill:#353564;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="6"
+         d="m -71.590875,96.691829 v 1.844151 l 1.119347,0.186449 v -1.618024 z"
+         points="-71.590875,98.53598 -70.471528,98.722429 -70.471528,97.104405 -71.590875,96.691829 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3753"
+         style="fill:#e9e9ff;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="11"
+         d="m -70.471528,97.104405 3.521639,-1.795967 v 2.991206 l -3.521639,0.422785 z"
+         points="-66.949889,95.308438 -66.949889,98.299644 -70.471528,98.722429 -70.471528,97.104405 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3745"
+         style="fill:#4d4d9f;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="5"
+         d="m -71.590875,96.691829 3.325505,-2.775198 1.315481,1.391807 -3.521639,1.795967 z"
+         points="-68.26537,93.916631 -66.949889,95.308438 -70.471528,97.104405 -71.590875,96.691829 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3751"
+         style="fill:#afafde;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="13"
+         d="m -71.590875,98.53598 3.325505,-0.751334 1.315481,0.514998 -3.521639,0.422785 z"
+         points="-68.26537,97.784646 -66.949889,98.299644 -70.471528,98.722429 -71.590875,98.53598 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3749"
+         style="fill:#d7d7ff;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="14"
+         d="m -68.26537,93.916631 v 3.868015 l 1.315481,0.514998 v -2.991206 z"
+         points="-68.26537,97.784646 -66.949889,98.299644 -66.949889,95.308438 -68.26537,93.916631 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3747"
+         style="fill:#8686bf;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="3"
+         d="m -71.590875,96.691829 3.325505,-2.775198 v 3.868015 l -3.325505,0.751334 z"
+         points="-68.26537,93.916631 -68.26537,97.784646 -71.590875,98.53598 -71.590875,96.691829 " />
+    </g>
+  </g>
+</svg>
diff --git a/tools/MessageModel/icons/item_streamValues.png b/tools/MessageModel/icons/item_streamValues.png
new file mode 100644 (file)
index 0000000..7181f94
Binary files /dev/null and b/tools/MessageModel/icons/item_streamValues.png differ
diff --git a/tools/MessageModel/icons/item_streamValues.svg b/tools/MessageModel/icons/item_streamValues.svg
new file mode 100644 (file)
index 0000000..38b1032
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="20"
+   viewBox="0 0 5.2916664 5.2916666"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="item_vectorOfReal.svg"
+   inkscape:export-filename="D:\OCCT\master_CR29451_1\tools\MessageModel\icons\item_vectorOfRealVec3.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <defs
+     id="defs2">
+    <linearGradient
+       id="linearGradient4578"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4576" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="-2.6544163 : -0.28690906 : 1"
+       inkscape:vp_y="0 : 1028.295 : 0"
+       inkscape:vp_z="9.504499 : -1.1228559 : 1"
+       inkscape:persp3d-origin="2.7661607 : -1.3768436 : 1"
+       id="perspective3711" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.839192"
+     inkscape:cx="-10.548151"
+     inkscape:cy="10.279721"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1446"
+     inkscape:window-height="838"
+     inkscape:window-x="1733"
+     inkscape:window-y="67"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(71.966667,-93.642022)">
+    <rect
+       id="rect3769"
+       width="4.660512"
+       height="4.443356"
+       x="-71.632576"
+       y="94.056023"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.26458332;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-3"
+       width="4.7041783"
+       height="2.2966287"
+       x="-71.676239"
+       y="96.202751"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.19110738;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-9"
+       width="2.3560426"
+       height="4.4502382"
+       x="-71.617508"
+       y="94.071091"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.18826659;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/tools/MessageView/FILES b/tools/MessageView/FILES
new file mode 100644 (file)
index 0000000..86a3a72
--- /dev/null
@@ -0,0 +1,10 @@
+MessageView_ActionsTest.cxx
+MessageView_ActionsTest.hxx
+MessageView_Communicator.cxx
+MessageView_Communicator.hxx
+MessageView_UnitByNameModel.cxx
+MessageView_UnitByNameModel.hxx
+MessageView_VisibilityState.cxx
+MessageView_VisibilityState.hxx
+MessageView_Window.cxx
+MessageView_Window.hxx
diff --git a/tools/MessageView/MessageView_ActionsTest.cxx b/tools/MessageView/MessageView_ActionsTest.cxx
new file mode 100644 (file)
index 0000000..f26ca86
--- /dev/null
@@ -0,0 +1,499 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageView_ActionsTest.hxx>
+
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_TreeModel.hxx>
+#include <inspector/TInspectorAPI_PluginParameters.hxx>
+#include <inspector/ViewControl_Tools.hxx>
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_Messenger.hxx>
+#include <Message_PrinterToReport.hxx>
+
+#include <gp_Ax1.hxx>
+#include <gp_Ax2.hxx>
+#include <gp_Ax3.hxx>
+#include <Bnd_Box.hxx>
+#include <Bnd_OBB.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <OSD_Chronometer.hxx>
+#include <Quantity_Color.hxx>
+#include <Quantity_ColorRGBA.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TopoDS_AlertAttribute.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QAction>
+#include <QFileDialog>
+#include <QItemSelectionModel>
+#include <QMenu>
+#include <QMessageBox>
+#include <QWidget>
+#include <Standard_WarningsRestore.hxx>
+
+//#define DEBUG_ALERTS
+
+#ifdef DEBUG_ALERTS
+#include <Message_Level.hxx>
+#endif
+
+#include <ctime>
+
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+MessageView_ActionsTest::MessageView_ActionsTest (QWidget* theParent,
+  MessageModel_TreeModel* theTreeModel, QItemSelectionModel* theModel)
+: QObject (theParent), myTreeModel (theTreeModel), mySelectionModel (theModel)
+{
+  myActions.insert (MessageModel_ActionType_TestMetric,
+                    ViewControl_Tools::CreateAction ("Test <metric>", SLOT (OnTestMetric()), parent(), this));
+  myActions.insert (MessageModel_ActionType_TestProperties,
+                    ViewControl_Tools::CreateAction ("Test <PropertyPanel>", SLOT (OnTestPropertyPanel()), parent(), this));
+  myActions.insert (MessageModel_ActionType_TestMessenger,
+                    ViewControl_Tools::CreateAction ("Test <Message_Messenger>", SLOT (OnTestMessenger()), parent(), this));
+  myActions.insert (MessageModel_ActionType_TestReportTree,
+                    ViewControl_Tools::CreateAction ("Test <Tree of messages>", SLOT (OnTestReportTree()), parent(), this));
+  myActions.insert (MessageModel_ActionType_TestReportTree2,
+                    ViewControl_Tools::CreateAction ("Test <Tree of messages> 2", SLOT (OnTestReportTree2()), parent(), this));
+}
+
+// =======================================================================
+// function : AddMenuActions
+// purpose :
+// =======================================================================
+void MessageView_ActionsTest::AddMenuActions (const QModelIndexList& theSelectedIndices, QMenu* theMenu)
+{
+  MessageModel_ItemRootPtr aRootItem;
+  MessageModel_ItemReportPtr aReportItem;
+  MessageModel_ItemAlertPtr anAlertItem;
+  for (QModelIndexList::const_iterator aSelIt = theSelectedIndices.begin(); aSelIt != theSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItemBase);
+    if (aRootItem)
+      break;
+
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    if (aReportItem)
+      break;
+
+    anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (anItemBase);
+    if (anAlertItem)
+      break;
+  }
+
+  if (aReportItem && !aReportItem->GetReport().IsNull())
+  {
+    theMenu->addAction (myActions[MessageModel_ActionType_TestMetric]);
+    theMenu->addAction (myActions[MessageModel_ActionType_TestProperties]);
+    theMenu->addAction (myActions[MessageModel_ActionType_TestMessenger]);
+    theMenu->addAction (myActions[MessageModel_ActionType_TestReportTree]);
+    theMenu->addAction (myActions[MessageModel_ActionType_TestReportTree2]);
+
+    bool isReportEnabled = aReportItem->GetReport()->IsActiveInMessenger();
+
+    myActions[MessageModel_ActionType_TestMetric]->setEnabled (isReportEnabled);
+    myActions[MessageModel_ActionType_TestProperties]->setEnabled (isReportEnabled);
+    myActions[MessageModel_ActionType_TestMessenger]->setEnabled (isReportEnabled);
+    myActions[MessageModel_ActionType_TestReportTree]->setEnabled (isReportEnabled);
+    myActions[MessageModel_ActionType_TestReportTree2]->setEnabled (isReportEnabled);
+  }
+  theMenu->addSeparator();
+}
+
+// =======================================================================
+// function : getSelectedReport
+// purpose :
+// =======================================================================
+Handle(Message_Report) MessageView_ActionsTest::getSelectedReport (QModelIndex& theReportIndex) const
+{
+  MessageModel_ItemReportPtr aReportItem;
+  QModelIndexList aSelectedIndices = mySelectionModel->selectedIndexes();
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    theReportIndex = anIndex;
+    if (aReportItem)
+      break;
+  }
+  if (!aReportItem)
+    return NULL;
+
+  return aReportItem->GetReport();
+}
+
+// =======================================================================
+// function : OnTestMetric
+// purpose :
+// =======================================================================
+void MessageView_ActionsTest::OnTestMetric()
+{
+#ifdef DEBUG_ALERTS
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY ("MessageModel_Actions::OnTestMetric()");
+  unsigned int start_time =  clock();
+  //Standard_Real aSystemSeconds, aCurrentSeconds;
+  //OSD_Chronometer::GetThreadCPU (aCurrentSeconds, aSystemSeconds);
+
+  Standard_Integer aCounter = 1500;//0;
+  Standard_Real aValue = 0., aValue2 = 0.1;
+
+  double* aMemValue;
+  for (int aTopIt = 0; aTopIt < 4; aTopIt++)
+  {
+    Message::SendInfo() << "Calculate";
+    for (int j = 0; j < aCounter; j++)
+    {
+      for (int i = 0; i < aCounter; i++)
+      {
+        aValue = (aValue * 2. + 3.) * 0.5 - 0.3 * 0.5;
+
+        Standard_Real aValue3 = aValue + aValue2 * 0.2;
+        (void)aValue3;
+
+        aMemValue = new double;
+      }
+    }
+  }
+
+  //((MessageModel_TreeModel*)mySelectionModel->model())->EmitLayoutChanged();
+
+  myTreeModel->UpdateTreeModel();
+
+  //Standard_Real aSystemSeconds1, aCurrentSeconds1;
+  //OSD_Chronometer::GetThreadCPU (aCurrentSeconds1, aSystemSeconds1);
+
+  //std::cout << aValue << std::endl;
+  //std::cout << "user time = " << aCurrentSeconds1 - aCurrentSeconds
+  //          << ",  system time = " << aSystemSeconds1 - aSystemSeconds << std::endl;
+
+  unsigned int end_time = clock();
+  std::cout << "clock() = " << end_time - start_time << std::endl;
+#endif
+}
+
+// =======================================================================
+// function : OnTestPropertyPanel
+// purpose :
+// =======================================================================
+void MessageView_ActionsTest::OnTestPropertyPanel()
+{
+#ifdef DEBUG_ALERTS
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY ("MessageModel_Actions::OnTestPropertyPanel()");
+
+  OCCT_SEND_MESSAGE ("Values")
+  OCCT_SEND_MESSAGE ("Values2")
+  // gp_XYZ
+  {
+    gp_XYZ aCoords (1.3, 2.3, 3.4);
+    OCCT_SEND_DUMPJSON (&aCoords, "gp_XYZ")
+  }
+  // gp_Dir
+  {
+    gp_Dir aDir (0.3, 0.3, 0.4);
+    OCCT_SEND_DUMPJSON (&aDir, "gp_Dir")
+  }
+  // gp_Ax1
+  {
+    gp_Ax1 aCoords (gp_Pnt (1.3, 2.3, 3.4), gp_Dir (0.3, 0.3, 0.4));
+    OCCT_SEND_DUMPJSON (&aCoords, "gp_Ax1")
+  }
+  // gp_Ax2
+  {
+    gp_Ax2 aCoords (gp_Pnt (10.3, 20.3, 30.4), gp_Dir (0.3, 0.3, 0.4));
+    OCCT_SEND_DUMPJSON (&aCoords, "gp_Ax2")
+  }
+  // gp_Ax3
+  {
+    gp_Ax3 aPln (gp_Pnt (10., 20., 15.), gp_Dir (0., 0., 1.), gp_Dir (1., 0., 0.));
+    OCCT_SEND_DUMPJSON (&aPln, "gp_Ax3")
+  }
+  // gp_Trsf
+  {
+    gp_Trsf aTrsf;
+    aTrsf.SetRotation (gp::OZ(), 0.3);
+    aTrsf.SetTranslationPart (gp_Vec (15., 15., 15.));
+    aTrsf.SetScaleFactor (3.);
+
+    OCCT_SEND_DUMPJSON (&aTrsf, "gp_Trsf")
+  }
+  // Bnd_Box
+  {
+    Bnd_Box aBox (gp_Pnt (20., 15., 10.), gp_Pnt (25., 20., 15.));
+    OCCT_SEND_DUMPJSON (&aBox, "Bnd_Box")
+  }
+  // Bnd_OBB
+  {
+    Bnd_OBB anOBB (gp_Pnt (-10., -15., -10.), gp_Dir (1., 0., 0.), gp_Dir (0., 1., 0.), gp_Dir (0., 0., 1.),
+                  5., 10., 5.);
+    OCCT_SEND_DUMPJSON (&anOBB, "Bnd_OBB");
+  }
+  // Quantity_ColorRGBA
+  {
+    Quantity_ColorRGBA aColor (0.2f, 0.8f, 0.8f, 0.2f);
+    OCCT_SEND_DUMPJSON (&aColor, "Quantity_ColorRGBA");
+  }
+  // Quantity_Color
+  {
+    Quantity_Color aColor (0.8, 0.8, 0.8, Quantity_TOC_RGB);
+    OCCT_SEND_DUMPJSON (&aColor, "Quantity_Color");
+  }
+
+  // stream of some table values
+  {
+    Standard_SStream aStream;
+    OCCT_DUMP_FIELD_VALUES_NUMERICAL (aStream, "value_1", 1, 100);
+    OCCT_DUMP_FIELD_VALUES_STRING (aStream, "value_2", 2, "value_1", "value_2");
+    OCCT_SEND_STREAM (aStream, "Table: Name to value");
+  }
+
+  // SHAPE messages
+  {
+    BRepBuilderAPI_MakeEdge aBuilder (gp_Pnt (0., 0., 0.), gp_Pnt (20., 10., 20.));
+    TopoDS_Shape aShape = aBuilder.Shape();
+
+    MESSAGE_INFO_SHAPE (aShape, "Shape message edge");
+  }
+
+  myTreeModel->UpdateTreeModel();
+#endif
+}
+
+// =======================================================================
+// function : createShapeOnLevel
+// purpose :
+// =======================================================================
+void createShapeOnLevel()
+{
+#ifdef DEBUG_ALERTS
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY ("createShapeOnLevel")
+
+  Message_Messenger::StreamBuffer sout = Message::SendInfo();
+
+  BRepBuilderAPI_MakeEdge aBuilder (gp_Pnt (0., 0., 0.), gp_Pnt (20., 10., 20.));
+  TopoDS_Shape aShape = aBuilder.Shape();
+
+  MESSAGE_INFO_SHAPE (aShape, "Shape message edge ON LEVEL");
+  //sout << "Shape message edge" << aShape;
+#endif
+}
+
+// =======================================================================
+// function : createShape
+// purpose :
+// =======================================================================
+void createShape()
+{
+#ifdef DEBUG_ALERTS
+  Message_Messenger::StreamBuffer sout = Message::SendInfo();
+
+  BRepBuilderAPI_MakeEdge aBuilder (gp_Pnt (0., 0., 0.), gp_Pnt (20., 10., 20.));
+  TopoDS_Shape aShape = aBuilder.Shape();
+
+  MESSAGE_INFO_SHAPE (aShape, "Shape message edge");
+  //sout << "Shape message edge" << aShape;
+
+  createShapeOnLevel();
+#endif
+}
+
+// =======================================================================
+// function : OnTestMessenger
+// purpose :
+// =======================================================================
+void MessageView_ActionsTest::OnTestMessenger()
+{
+#ifdef DEBUG_ALERTS
+  // string messages
+  Message_Messenger::StreamBuffer sout = Message::SendInfo();
+  Standard_Integer aTraceLevel_prev = Message::DefaultMessenger()->TraceLevel();
+  Message::DefaultMessenger()->SetTraceLevel (1);
+
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY ("MessageModel_Actions::OnTestMessenger()")
+
+  sout << "IGESBasic_Hierarchy" << std::endl;
+  sout << "Number of property valueaMessenger : " << 15 << std::endl;
+  sout << "Line Font    : " << 1 << std::endl << "View Number  : " << 3 << std::endl;
+  sout << "Entity level : " << 1 << std::endl;
+  sout << "Blank statuaMessenger : " << 0 << std::endl;
+  sout << "Line weight  : " << 14 << std::endl;
+  sout << "Color number : " << 5 << std::endl;
+
+  // stream messages
+  // gp_XYZ
+  {
+    gp_XYZ aCoords (1.3, 2.3, 3.4);
+    Standard_SStream aStream;
+    //aCoords.DumpJson (aStream);
+    //sout << "gp_XYZ" << aStream << std::endl;
+    aCoords.DumpJson (sout);
+  }
+  // Bnd_Box
+  {
+    Bnd_Box aBox (gp_Pnt (20., 15., 10.), gp_Pnt (25., 20., 15.));
+    Standard_SStream aStream;
+    //aBox.DumpJson (aStream);
+    //sout << "Bnd_Box" << aStream;
+    aBox.DumpJson (sout);
+  }
+
+  // object messages
+  Handle(Standard_Transient) anObject = new Message_AlertExtended();
+  //sout << "Message_AlertExtended" << anObject;
+
+  // shape messages
+  {
+    BRepBuilderAPI_MakeEdge aBuilder (gp_Pnt (0., 0., 0.), gp_Pnt (20., 10., 20.));
+    TopoDS_Shape aShape = aBuilder.Shape();
+
+    MESSAGE_INFO_SHAPE (aShape, "Shape message edge");
+    //sout << "Shape message edge" << aShape;
+
+    createShape();
+  }
+  myTreeModel->UpdateTreeModel();
+  Message::DefaultMessenger()->SetTraceLevel (aTraceLevel_prev);
+#endif
+}
+
+// =======================================================================
+// function : levelAlerts
+// purpose :
+// =======================================================================
+void levelAlerts (const int theCurrentLevel, const int theTopLevel)
+{
+#ifdef DEBUG_ALERTS
+  if (theTopLevel - theCurrentLevel <= 0)
+    return;
+
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY (TCollection_AsciiString ("Level: " ) + theCurrentLevel)
+
+  Message_Messenger::StreamBuffer sout = Message::SendInfo();
+  sout << "Alert(" << theCurrentLevel << "): " << 1 << ", " << 2 << std::endl;
+  sout << "Alert(" << theCurrentLevel << "): " << 3 << ", " << 4 << std::endl;
+
+  //for (int i = 0; i < 2; i++)
+    levelAlerts (theCurrentLevel + 1, theTopLevel);
+
+  sout << "Alert(" << theCurrentLevel << "): " << 4 << ", " << 5 << std::endl;
+#endif
+}
+
+// =======================================================================
+// function : levelAlert
+// purpose :
+// =======================================================================
+void levelAlert (const int theCurrentLevel, const int theTopLevel)
+{
+#ifdef DEBUG_ALERTS
+  if (theTopLevel - theCurrentLevel <= 0)
+    return;
+
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY ("levelAlert")
+
+  Message_Messenger::StreamBuffer sout = Message::SendInfo();
+  sout << "Level: " << theCurrentLevel << "(Single, no alerts on the level)" << std::endl;
+
+  //for (int i = 0; i < 2; i++)
+    levelAlerts (theCurrentLevel + 1, theTopLevel);
+#endif
+}
+
+// =======================================================================
+// function : OnTestReportTree
+// purpose :
+// =======================================================================
+void MessageView_ActionsTest::OnTestReportTree()
+{
+#ifdef DEBUG_ALERTS
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY ("MessageModel_Actions::OnTestReportTree()")
+  Message_Messenger::StreamBuffer sout = Message::SendInfo();
+
+  // string messages
+  //sout << "Alert: " << 1 << std::endl;
+  //sout << "Alert: " << 2 << std::endl;
+
+  int aTopLevel = 3;
+  levelAlerts (1, aTopLevel);
+
+  //sout << "Alert: " << 3 << std::endl;
+  //levelAlerts (1, aTopLevel);
+
+  sout << "Alert: " << 4 << std::endl;
+  levelAlert (1, aTopLevel);
+
+  myTreeModel->UpdateTreeModel();
+#endif
+}
+
+// =======================================================================
+// function : OnTestReportTree2
+// purpose :
+// =======================================================================
+void MessageView_ActionsTest::OnTestReportTree2()
+{
+#ifdef DEBUG_ALERTS
+  OCCT_ADD_MESSAGE_LEVEL_SENTRY ("MessageModel_Actions::OnTestReportTree()")
+  Message_Messenger::StreamBuffer sout = Message::SendInfo();
+
+  // string messages
+  //sout << "Alert: " << 1 << std::endl;
+  //sout << "Alert: " << 2 << std::endl;
+
+  int aTopLevel = 3;
+  levelAlerts (1, aTopLevel);
+
+  //sout << "Alert: " << 3 << std::endl;
+  //levelAlerts (1, aTopLevel);
+
+  //sout << "Alert: " << 4 << std::endl;
+  //levelAlert (1, aTopLevel);
+
+  myTreeModel->UpdateTreeModel();
+#endif
+}
diff --git a/tools/MessageView/MessageView_ActionsTest.hxx b/tools/MessageView/MessageView_ActionsTest.hxx
new file mode 100644 (file)
index 0000000..bf58b17
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageView_ActionsTest_H
+#define MessageView_ActionsTest_H
+
+#include <Standard.hxx>
+#include <Standard_Handle.hxx>
+#include <Standard_Transient.hxx>
+
+#include <inspector/MessageModel_ActionType.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QObject>
+#include <QMap>
+#include <QModelIndexList>
+#include <QPoint>
+#include <QString>
+#include <Standard_WarningsRestore.hxx>
+
+class Message_Report;
+class MessageModel_TreeModel;
+class QItemSelectionModel;
+
+class QAction;
+class QWidget;
+class QMenu;
+
+//! \class MessageView_ActionsTest
+//! Window that unites all MessageView controls.
+class MessageView_ActionsTest : public QObject
+{
+  Q_OBJECT
+public:
+
+  //! Constructor
+  MessageView_ActionsTest (QWidget* theParent, MessageModel_TreeModel* theTreeModel, QItemSelectionModel* theModel);
+
+  //! Destructor
+  virtual ~MessageView_ActionsTest() {}
+
+  //! Fills popup menu with actions depending on the current selection
+  //! \param theSelectedIndices tree model selected indices
+  //! \param theMenu menu to be filled
+  Standard_EXPORT void AddMenuActions (const QModelIndexList& theSelectedIndices, QMenu* theMenu);
+
+public slots:
+  //! Sending several alerts to check metric of message-alert-tool mechanizm
+  void OnTestMetric();
+
+  //! Sending several alerts to check property panel/presentations of message-alert-tool mechanizm
+  void OnTestPropertyPanel();
+
+  //! Sending several alerts to check property panel/presentations of messenger-alert-tool mechanizm
+  void OnTestMessenger();
+
+  //! Check tree of alerts
+  void OnTestReportTree();
+
+  //! Check tree of alerts
+  void OnTestReportTree2();
+
+protected:
+  //! Returns report of selected tree view item if a report item is selected
+  //! \param theReportIndex tree model index of the found report
+  //! \return report instance or NULL
+  Handle(Message_Report) getSelectedReport (QModelIndex& theReportIndex) const;
+
+protected:
+  MessageModel_TreeModel* myTreeModel; //< tree model
+  QItemSelectionModel* mySelectionModel; //< selection model
+  QMap<MessageModel_ActionType, QAction*> myActions; //!< container of all actions
+};
+
+#endif
diff --git a/tools/MessageView/MessageView_Communicator.cxx b/tools/MessageView/MessageView_Communicator.cxx
new file mode 100644 (file)
index 0000000..10b9548
--- /dev/null
@@ -0,0 +1,26 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageView_Communicator.hxx>
+
+
+// =======================================================================
+// function :  CreateCommunicator
+// purpose : Creates a communicator by the library loading
+// =======================================================================
+Standard_EXPORTEXTERNC TInspectorAPI_Communicator* CreateCommunicator()
+{
+  return new MessageView_Communicator();
+}
diff --git a/tools/MessageView/MessageView_Communicator.hxx b/tools/MessageView/MessageView_Communicator.hxx
new file mode 100644 (file)
index 0000000..7d93c21
--- /dev/null
@@ -0,0 +1,66 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageView_Communicator_H
+#define MessageView_Communicator_H
+
+#include <inspector/MessageView_Window.hxx>
+#include <inspector/TInspectorAPI_Communicator.hxx>
+
+//! \class MessageView_Communicator.
+//! \brief This is a connector from TInspector application to MessageView window
+class MessageView_Communicator : public TInspectorAPI_Communicator
+{
+public:
+
+  //! Constructor
+  MessageView_Communicator() : TInspectorAPI_Communicator(), myWindow (new MessageView_Window (0)) {}
+
+  //! Destructor
+  virtual ~MessageView_Communicator() Standard_OVERRIDE {}
+
+  //! Provides the container with a parent where this container should be inserted.
+  //! If Qt implementation, it should be QWidget with QLayout set inside
+  //! \param theParent a parent class
+  virtual void SetParent (void* theParent) Standard_OVERRIDE { myWindow->SetParent (theParent); }
+
+  //! Sets parameters container, it should be used when the plugin is initialized or in update content
+  //! \param theParameters a parameters container
+  virtual void SetParameters (const Handle(TInspectorAPI_PluginParameters)& theParameters) Standard_OVERRIDE
+  { myWindow->SetParameters (theParameters); }
+
+  //! Provide container for actions available in inspector on general level
+  //! \param theMenu if Qt implementation, it is QMenu object
+  virtual void FillActionsMenu(void* theMenu) Standard_OVERRIDE { myWindow->FillActionsMenu (theMenu); }
+
+  //! Returns plugin preferences, empty implementation by default
+  //! \param theItem container of preference elements
+  virtual void GetPreferences (TInspectorAPI_PreferencesDataMap& theItem) Standard_OVERRIDE
+  { myWindow->GetPreferences (theItem); }
+
+  //! Stores plugin preferences, empty implementation by default
+  //! \param theItem container of preference elements
+  virtual void SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem) Standard_OVERRIDE
+  { myWindow->SetPreferences (theItem); }
+
+  //! Calls update of the plugin's content
+  virtual void UpdateContent() Standard_OVERRIDE { myWindow->UpdateContent(); }
+
+private:
+
+  MessageView_Window* myWindow; //!< current window
+};
+
+#endif
diff --git a/tools/MessageView/MessageView_UnitByNameModel.cxx b/tools/MessageView/MessageView_UnitByNameModel.cxx
new file mode 100644 (file)
index 0000000..efef73e
--- /dev/null
@@ -0,0 +1,181 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+// OCCT includes
+#include <inspector/MessageView_UnitByNameModel.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+
+#include <Message_AlertExtended.hxx>
+#include <Message_Attribute.hxx>
+#include <Message_AttributeMeter.hxx>
+#include <Message_CompositeAlerts.hxx>
+#include <Message_Report.hxx>
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void MessageView_UnitByNameModel::Init (const TreeModel_ItemBasePtr theItemBase)
+{
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport> (theItemBase);
+  if (aReportItem)
+  {
+    Handle(Message_Report) aReport = aReportItem->GetReport();
+    const Message_ListOfAlert& anAlerts = aReport->GetAlerts (Message_Info);
+    for (Message_ListOfAlert::Iterator anIt(anAlerts); anIt.More(); anIt.Next())
+    {
+      initByAlert (anIt.Value());
+    }
+  }
+  else
+  {
+    MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (theItemBase);
+    if (anAlertItem)
+    {
+      initByAlert (anAlertItem->GetAlert());
+    }
+  }
+  std::map<double, std::list<QString>> aTmpMap;
+  std::list<double> aTimes;
+  for (QMap<QString, QPair<int, double> >::Iterator anIterValue = myValues.begin();
+       anIterValue != myValues.end(); ++anIterValue)
+  {
+    std::map<double, std::list<QString>>::iterator anIter = aTmpMap.find (anIterValue.value().second);
+    if (anIter != aTmpMap.end())
+    {
+      aTmpMap.at (anIterValue.value().second).push_back (anIterValue.key());
+    }
+    else
+    {
+      std::list<QString> list;
+      list.push_back (anIterValue.key());
+      aTmpMap.insert (std::pair<double, std::list<QString> > (anIterValue.value().second, list));
+      aTimes.push_back (anIterValue.value().second);
+    }
+  }
+
+  aTimes.sort();
+  aTimes.reverse();
+
+  for (std::list<double>::iterator anIter = aTimes.begin(); anIter != aTimes.end(); anIter++)
+  {
+    double aTime = *anIter;
+    std::list<QString> names = aTmpMap.at (aTime);
+    for (std::list<QString>::iterator name = names.begin(); name != names.end(); name++)
+    {
+      int nb = myValues.find (*name).value().first;
+      RowValues value = {*name, nb, aTime};
+      setValueByIndex (-1, value);
+    }
+  }
+}
+
+// =======================================================================
+// function : initByAlert
+// purpose :
+// =======================================================================
+void MessageView_UnitByNameModel::initByAlert(const Handle(Message_Alert)& theAlert)
+{
+  Handle(Message_AlertExtended) anExtAlert = Handle(Message_AlertExtended)::DownCast (theAlert);
+  if (anExtAlert.IsNull())
+  {
+    return;
+  }
+  Handle(Message_Attribute) anAttr = anExtAlert->Attribute();
+  Handle(Message_AttributeMeter) anAttrMeter = Handle(Message_AttributeMeter)::DownCast (anAttr);
+  if(anAttrMeter.IsNull())
+  {
+    return;
+  }
+
+  if (myValues.contains (anAttr->GetName().ToCString()))
+  {
+    int aCount = myValues.value (anAttr->GetName().ToCString()).first;
+    aCount++;
+    double aTime = myValues.value (anAttr->GetName().ToCString()).second;
+    aTime += anAttrMeter->StopValue (Message_MetricType_WallClock) - anAttrMeter->StartValue (Message_MetricType_WallClock);
+    myValues[anAttr->GetName().ToCString()] = qMakePair (aCount, aTime);
+  }
+  else
+  {
+    int aCount = 1;
+    double aTime = anAttrMeter->StopValue (Message_MetricType_WallClock) - anAttrMeter->StartValue (Message_MetricType_WallClock);
+    myValues.insert (anAttr->GetName().ToCString(), qMakePair (aCount, aTime));
+  }
+
+  if (!anExtAlert->CompositeAlerts().IsNull())
+  {
+    const Message_ListOfAlert& anAlerts = anExtAlert->CompositeAlerts()->Alerts (Message_Info);
+    for (Message_ListOfAlert::Iterator anIt (anAlerts); anIt.More(); anIt.Next())
+    {
+      initByAlert (anIt.Value());
+    }
+  }
+}
+
+// =======================================================================
+// function : data
+// purpose :
+// =======================================================================
+QVariant MessageView_UnitByNameModel::data (const QModelIndex& theIndex, int theRole) const
+{
+  switch (theRole)
+  {
+    case Qt::DisplayRole:
+    {
+      switch (theIndex.column())
+      {
+        case 0: return mySortValues[theIndex.row()].myName;
+        case 1: return mySortValues[theIndex.row()].myCounter;
+        case 2: return mySortValues[theIndex.row()].myTime;
+      }
+      break;
+    }
+    default: break;
+  }
+  return QVariant();
+}
+
+// =======================================================================
+// function : getValueIndex
+// purpose :
+// =======================================================================
+int MessageView_UnitByNameModel::getValueIndex (const QString theName)
+{
+  for (QMap<int, RowValues>::iterator anIter = mySortValues.begin(); anIter != mySortValues.end(); anIter++)
+  {
+    if (anIter.value().myName == theName)
+    {
+      return anIter.key();
+    }
+  }
+}
+
+// =======================================================================
+// function : setValueByIndex
+// purpose :
+// =======================================================================
+void MessageView_UnitByNameModel::setValueByIndex (const int theIndex, const RowValues theValue)
+{
+  if (theIndex == -1)
+  {
+    mySortValues.insert (mySortValues.size(), theValue);
+  }
+  else
+  {
+    mySortValues.insert (theIndex, theValue);
+  }
+}
diff --git a/tools/MessageView/MessageView_UnitByNameModel.hxx b/tools/MessageView/MessageView_UnitByNameModel.hxx
new file mode 100644 (file)
index 0000000..fe438a5
--- /dev/null
@@ -0,0 +1,96 @@
+// Created on: 2020-12-01
+// Created by: Svetlana SHUTINA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#pragma once
+
+#include <inspector/TreeModel_ItemBase.hxx>
+
+#include <Message_Alert.hxx>
+
+#include <QAbstractTableModel>
+
+//! @class MessageView_UnitByNameModel
+//! Table model that sums the number of calls and
+//! the time spent on the functionality inside the value.
+//! It visualizes container of string values,
+//! count of the values and time, sorted by descending time.
+class MessageView_UnitByNameModel : public QAbstractTableModel
+{
+public:
+
+  // Consists the table fields.
+  struct RowValues
+  {
+    QString myName; //!< string values.
+    int myCounter;  //!< count of the values.
+    double myTime;  //!< total time.
+  };
+
+  //! Constructor
+  MessageView_UnitByNameModel (QObject* theParent = 0) : QAbstractTableModel (theParent)
+  {}
+
+  //! Destructor
+  virtual ~MessageView_UnitByNameModel()
+  {}
+
+  //! Fills map of the fields values.
+  //! @param theItemBase a parent item.
+  void Init (const TreeModel_ItemBasePtr theItemBase);
+
+  //! Returns content of the model index for the given role,
+  //! it is obtained from internal container of values.
+  //! It returns value only for DisplayRole.
+  //! @param theIndex a model index.
+  //! @param theRole a view role.
+  //! @return value intepreted depending on the given role.
+  virtual QVariant data (const QModelIndex& theIndex, int theRole = Qt::DisplayRole) const Standard_OVERRIDE;
+
+  //! Returns number of rows.
+  //! @param theParent an index of the parent item.
+  //! @return an integer value.
+  virtual int rowCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
+  { 
+    (void)theParent;
+    return myValues.size();
+  }
+
+  //! Returns number of columns.
+  //! @param theParent an index of the parent item.
+  //! @return an integer value.
+  virtual int columnCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
+  { (void)theParent; return 3; }
+
+private:
+
+  //! Sortes values and fills map of the fields values depends on unique text identifier.
+  //! @param theAlert unique text identifier.
+  void initByAlert (const Handle(Message_Alert)& theAlert);
+
+  //! @param theName the unique text identifier.
+  //! @return serial number in the map for the unique text identifier.
+  int getValueIndex (const QString theName);
+
+  //! Adds theValues in the map to position theIndex.
+  //! If theIndex is -1, the element will be added in the end of the map.
+  //! @param theIndex the serial number in the map.
+  //! @param theValues the field values.
+  void setValueByIndex (const int theIndex, const RowValues theValues);
+
+private:
+
+  QMap<QString, QPair<int, double> > myValues; //!< map of fields values.
+  QMap<int, RowValues> mySortValues;              //!< sorted map of fields values.
+};
diff --git a/tools/MessageView/MessageView_VisibilityState.cxx b/tools/MessageView/MessageView_VisibilityState.cxx
new file mode 100644 (file)
index 0000000..9b79935
--- /dev/null
@@ -0,0 +1,150 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageView_VisibilityState.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeStream.hxx>
+
+#include <TopoDS_AlertAttribute.hxx>
+
+// =======================================================================
+// function : CanBeVisible
+// purpose :
+// =======================================================================
+bool MessageView_VisibilityState::CanBeVisible (const QModelIndex& theIndex) const
+{
+  MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex);
+  if (anAlertItem)
+  {
+    NCollection_List<Handle(Standard_Transient)> aPresentations;
+    anAlertItem->Presentations (aPresentations);
+    if (!aPresentations.IsEmpty())
+      return true;
+  }
+
+  return !Shape (theIndex).IsNull();// || hasTableValues (theIndex);
+}
+
+// =======================================================================
+// function : SetVisible
+// purpose :
+// =======================================================================
+bool MessageView_VisibilityState::SetVisible (const QModelIndex& theIndex, const bool theState, const bool toEmitDataChanged)
+{
+  TopoDS_Shape aShape = Shape (theIndex);
+  if (aShape.IsNull())
+    return false;
+
+  myDisplayer->SetVisible (aShape, theState, myPresentationType);
+
+  if (!theState) {
+    MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex);
+    if (anAlertItem && !anAlertItem->GetCustomShape().IsNull())
+      anAlertItem->SetCustomShape (TopoDS_Shape());
+  }
+
+  if (toEmitDataChanged)
+  {
+    QModelIndex anIndex = theIndex;
+    if (theIndex.column() != TreeModel_ColumnType_Visibility)
+      anIndex = theIndex.model()->index(theIndex.row(), TreeModel_ColumnType_Visibility, theIndex.parent());
+
+    getModel()->EmitDataChanged (anIndex, anIndex);
+  }
+  return true;
+}
+
+// =======================================================================
+// function : IsVisible
+// purpose :
+// =======================================================================
+bool MessageView_VisibilityState::IsVisible (const QModelIndex& theIndex) const
+{
+  return myDisplayer->IsVisible (Shape (theIndex), myPresentationType);
+}
+
+// =======================================================================
+// function : OnClicked
+// purpose :
+// =======================================================================
+void MessageView_VisibilityState::OnClicked (const QModelIndex& theIndex)
+{
+  processClicked (theIndex);
+  emit itemClicked (theIndex);
+}
+
+// =======================================================================
+// function : getAlertItem
+// purpose :
+// =======================================================================
+MessageModel_ItemAlertPtr MessageView_VisibilityState::getAlertItem (const QModelIndex& theIndex) const
+{
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (theIndex);
+  if (!anItemBase)
+    return MessageModel_ItemAlertPtr();
+
+  MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert>(anItemBase);
+  return anAlertItem;
+}
+
+// =======================================================================
+// function : Shape
+// purpose :
+// =======================================================================
+TopoDS_Shape MessageView_VisibilityState::Shape (const QModelIndex& theIndex) const
+{
+  MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex);
+  if (!anAlertItem)
+    return TopoDS_Shape();
+
+  /*if (!anAlertItem->GetCustomShape().IsNull())
+    return anAlertItem->GetCustomShape();
+
+  Handle(Message_Alert) anAlert = anAlertItem->GetAlert();
+  if (anAlert.IsNull())
+    return TopoDS_Shape();
+
+  Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast(anAlert);
+  if (anAlertExtended.IsNull())
+    return TopoDS_Shape();
+
+  Handle(TopoDS_AlertAttribute) aShapeAttribute = Handle(TopoDS_AlertAttribute)::DownCast (anAlertExtended->Attribute());
+  if (!aShapeAttribute.IsNull())
+    return aShapeAttribute->GetShape();
+  */
+  return TopoDS_Shape();
+}
+
+// =======================================================================
+// function : hasTableValues
+// purpose :
+// =======================================================================
+bool MessageView_VisibilityState::hasTableValues (const QModelIndex& theIndex) const
+{
+  MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex);
+  if (!anAlertItem)
+    return false;
+
+  Handle(Message_Alert) anAlert = anAlertItem->GetAlert();
+  if (anAlert.IsNull())
+    return false;
+
+  if (anAlert->IsKind (STANDARD_TYPE (Message_AttributeStream)))
+    return true;
+
+  return false;
+}
\ No newline at end of file
diff --git a/tools/MessageView/MessageView_VisibilityState.hxx b/tools/MessageView/MessageView_VisibilityState.hxx
new file mode 100644 (file)
index 0000000..b26e73f
--- /dev/null
@@ -0,0 +1,99 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageView_VisibilityState_H
+#define MessageView_VisibilityState_H
+
+#include <inspector/TreeModel_VisibilityState.hxx>
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <inspector/View_Displayer.hxx>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <TopoDS_Shape.hxx>
+
+class TreeModel_ModelBase;
+
+//! \class MessageView_VisibilityState
+//! \brief Class provides connection between model and visualization control
+class MessageView_VisibilityState : public QObject, public TreeModel_VisibilityState
+{
+  Q_OBJECT
+public:
+  //! Constructor
+  MessageView_VisibilityState (TreeModel_ModelBase* theModel)
+  : TreeModel_VisibilityState (theModel), myPresentationType (View_PresentationType_Main) {}
+
+  //! Destructor
+  ~MessageView_VisibilityState() {}
+
+  //! Sets current displayer
+  //! \theDisplayer class that provides connection to visualized objects
+  void SetDisplayer (View_Displayer* theDisplayer) { myDisplayer = theDisplayer; }
+
+  //! Sets presentation type for displayer
+  //! \param theType type value
+  void SetPresentationType (const View_PresentationType theType) { myPresentationType = theType; }
+
+  //! Returns true if visibility of the item can be changed
+  //! \param theIndex tree model index
+  //! \return boolean value
+  Standard_EXPORT virtual bool CanBeVisible (const QModelIndex& theIndex) const Standard_OVERRIDE;
+
+  //! Sets visibility state
+  //! \theIndex tree model index
+  //! \param theState visibility state
+  //! \param toEmitDataChanged boolean flag whether emit of the model should be done immediatelly
+  //! \return true if state is changed
+  Standard_EXPORT virtual bool SetVisible (const QModelIndex& theIndex, const bool theState, const bool toEmitDataChanged) Standard_OVERRIDE;
+
+  //! Returns visibility state value
+  Standard_EXPORT virtual bool IsVisible (const QModelIndex& theIndex) const Standard_OVERRIDE;
+
+public slots:
+  //! Processes the mouse clicked on the index.
+  //! It changes the item visibility if model allows to change it.
+  //! \theIndex tree model index
+  void OnClicked (const QModelIndex& theIndex);
+
+signals:
+  //! Signal after OnClicked is performed
+  //! \theIndex tree model index
+  void itemClicked (const QModelIndex& theIndex);
+
+protected:
+  //! Gets the alert item
+  //! \theIndex tree model index
+  //! \return item or NULL
+  MessageModel_ItemAlertPtr getAlertItem (const QModelIndex& theIndex) const;
+
+  //! Gets shape of the view model by the parameter index if it has a shape
+  //! \param theIndex tree model index
+  //! \return shape instance
+  TopoDS_Shape Shape (const QModelIndex& theIndex) const;
+
+  //! Returns true if alert of the item has table values
+  //! \param theIndex tree model index
+  //! \return boolean result
+  bool hasTableValues (const QModelIndex& theIndex) const;
+
+private:
+  View_Displayer* myDisplayer; //! view displayer
+  View_PresentationType myPresentationType; //! presentation type
+};
+
+#endif
diff --git a/tools/MessageView/MessageView_Window.cxx b/tools/MessageView/MessageView_Window.cxx
new file mode 100644 (file)
index 0000000..4134913
--- /dev/null
@@ -0,0 +1,983 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageView_Window.hxx>
+#include <inspector/MessageView_VisibilityState.hxx>
+#include <inspector/MessageView_ActionsTest.hxx>
+
+#include <inspector/MessageModel_Actions.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_TreeModel.hxx>
+#include <inspector/MessageView_UnitByNameModel.hxx>
+
+#include <inspector/TreeModel_ContextMenu.hxx>
+#include <inspector/TreeModel_Tools.hxx>
+
+#include <inspector/ViewControl_PropertyView.hxx>
+#include <inspector/ViewControl_TableModelValues.hxx>
+#include <inspector/ViewControl_TreeView.hxx>
+#include <inspector/Convert_Tools.hxx>
+
+#include <inspector/View_Viewer.hxx>
+#include <inspector/View_Widget.hxx>
+
+#include <AIS_Shape.hxx>
+#include <Graphic3d_Camera.hxx>
+#include <OSD_Environment.hxx>
+#include <OSD_Directory.hxx>
+#include <OSD_Protection.hxx>
+#include <Message.hxx>
+#include <TCollection_AsciiString.hxx>
+
+//#define DEBUG_ALERTS
+
+//#include <XmlDrivers_MessageReportStorage.hxx>
+
+#include <inspector/ViewControl_Tools.hxx>
+#include <inspector/View_Displayer.hxx>
+#include <inspector/View_ToolBar.hxx>
+#include <inspector/View_Widget.hxx>
+#include <inspector/View_Window.hxx>
+#include <inspector/View_Viewer.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepTools.hxx>
+#include <OSD_File.hxx>
+#include <OSD_Path.hxx>
+
+#include <QApplication>
+#include <QAction>
+#include <QComboBox>
+#include <QDockWidget>
+#include <QDir>
+#include <QFile>
+#include <QFileDialog>
+#include <QHeaderView>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMessageBox>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QTextEdit>
+#include <QTextStream>
+#include <QToolBar>
+#include <QToolButton>
+#include <QTreeView>
+#include <QWidget>
+#include <QVBoxLayout>
+
+const int DEFAULT_TEXT_VIEW_WIDTH = 800;// 800;
+const int DEFAULT_TEXT_VIEW_HEIGHT = 700;
+const int DEFAULT_TEXT_VIEW_POSITION_X = 430;
+const int DEFAULT_TEXT_VIEW_POSITION_Y = 30;
+const int DEFAULT_TEXT_VIEW_DELTA = 100;
+
+const int DEFAULT_SHAPE_VIEW_WIDTH = 400;// 900;
+const int DEFAULT_SHAPE_VIEW_HEIGHT = 450;
+const int DEFAULT_SHAPE_VIEW_POSITION_X = 60;
+const int DEFAULT_SHAPE_VIEW_POSITION_Y = 60;
+
+const int DEFAULT_DETACH_POSITION_X = 5;
+const int DEFAULT_DETACH_POSITION_Y = 450;
+
+const int MESSAGEVIEW_DEFAULT_TREE_VIEW_WIDTH = 950; //600
+const int MESSAGEVIEW_DEFAULT_TREE_VIEW_HEIGHT = 500;
+
+const int MESSAGEVIEW_DEFAULT_VIEW_WIDTH = 200;// 400;
+const int MESSAGEVIEW_DEFAULT_VIEW_HEIGHT = 300;// 1000;
+
+#include <Prs3d_PointAspect.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+Handle(Prs3d_Drawer) GetPreviewAttributes (const Handle(AIS_InteractiveContext)& theContext)
+{
+  Handle(Prs3d_Drawer) myDrawer = new Prs3d_Drawer();
+  myDrawer->Link (theContext->DefaultDrawer());
+
+  Quantity_Color aColor(Quantity_NOC_TOMATO);//Quantity_NOC_GREENYELLOW));//Quantity_NOC_BLUE1));
+  Standard_ShortReal aTransparency = 0.8;
+
+  // point parameters
+  myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_O_PLUS, aColor, 3.0));
+
+  // shading parameters
+  Graphic3d_MaterialAspect aShadingMaterial;
+  aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
+  aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
+
+  myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+  myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  myDrawer->ShadingAspect()->SetColor (aColor);
+  myDrawer->ShadingAspect()->SetMaterial (aShadingMaterial);
+
+  myDrawer->ShadingAspect()->Aspect()->ChangeFrontMaterial().SetTransparency (aTransparency);
+  myDrawer->ShadingAspect()->Aspect()->ChangeBackMaterial() .SetTransparency (aTransparency);
+  myDrawer->SetTransparency (aTransparency);
+
+  // common parameters
+  myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
+
+  return myDrawer;
+}
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+MessageView_Window::MessageView_Window (QWidget* theParent)
+: QObject (theParent)
+{
+  myMainWindow = new QMainWindow (theParent);
+
+  myTreeView = new ViewControl_TreeView (myMainWindow);
+  ((ViewControl_TreeView*)myTreeView)->SetPredefinedSize (QSize (MESSAGEVIEW_DEFAULT_TREE_VIEW_WIDTH,
+                                                                 MESSAGEVIEW_DEFAULT_TREE_VIEW_HEIGHT));
+  MessageModel_TreeModel* aModel = new MessageModel_TreeModel (myTreeView);
+  aModel->InitColumns();
+  //aModel->SetReversed (Standard_True);
+
+  connect (myTreeView->header(), SIGNAL (sectionResized (int, int, int)),
+           this, SLOT(onHeaderResized (int, int, int)));
+
+  myTreeView->setModel (aModel);
+  MessageView_VisibilityState* aVisibilityState = new MessageView_VisibilityState (aModel);
+  aModel->SetVisibilityState (aVisibilityState);
+  connect (aVisibilityState, SIGNAL (itemClicked (const QModelIndex&)), this, SLOT(onTreeViewVisibilityClicked(const QModelIndex&)));
+
+  TreeModel_Tools::UseVisibilityColumn (myTreeView);
+  TreeModel_Tools::SetDefaultHeaderSections (myTreeView);
+
+  QItemSelectionModel* aSelectionModel = new QItemSelectionModel (aModel);
+  myTreeView->setSelectionMode (QAbstractItemView::ExtendedSelection);
+  myTreeView->setSelectionModel (aSelectionModel);
+  connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
+           this, SLOT (onTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
+
+  myTreeViewActions = new MessageModel_Actions (myMainWindow, aModel, aSelectionModel);
+  myTestViewActions = new MessageView_ActionsTest (myMainWindow, aModel, aSelectionModel);
+
+  myTreeView->setContextMenuPolicy (Qt::CustomContextMenu);
+  connect (myTreeView, SIGNAL (customContextMenuRequested (const QPoint&)),
+          this, SLOT (onTreeViewContextMenuRequested (const QPoint&)));
+  //new TreeModel_ContextMenu (myTreeView);
+
+  connect (myTreeView->header(), SIGNAL (sectionResized (int, int, int)),
+           this, SLOT(onHeaderResized (int, int, int)));
+
+  QModelIndex aParentIndex = myTreeView->model()->index (0, 0);
+  myTreeView->setExpanded (aParentIndex, true);
+
+  myMainWindow->setCentralWidget (myTreeView);
+
+  // property view
+  myPropertyView = new ViewControl_PropertyView (myMainWindow);
+  myPropertyPanelWidget = new QDockWidget (tr ("PropertyPanel"), myMainWindow);
+  myPropertyPanelWidget->setObjectName (myPropertyPanelWidget->windowTitle());
+  myPropertyPanelWidget->setTitleBarWidget (new QWidget(myMainWindow));
+  myPropertyPanelWidget->setWidget (myPropertyView->GetControl());
+  myMainWindow->addDockWidget (Qt::RightDockWidgetArea, myPropertyPanelWidget);
+  connect (myPropertyPanelWidget->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT (onPropertyPanelShown (bool)));
+  connect (myPropertyView, SIGNAL (propertyViewDataChanged()), this, SLOT (onPropertyViewDataChanged()));
+
+  myCustomView = new QTableView (myMainWindow);
+  myCustomPanelWidget = new QDockWidget (tr ("Unit By Name"), myMainWindow);
+  myCustomPanelWidget->setObjectName (myCustomPanelWidget->windowTitle());
+  myCustomPanelWidget->setTitleBarWidget (new QWidget(myMainWindow));
+  myCustomPanelWidget->setWidget (myCustomView);
+  myMainWindow->addDockWidget (Qt::RightDockWidgetArea, myCustomPanelWidget);
+
+  // view
+  myViewWindow = new View_Window (myMainWindow, false);
+  connect (myViewWindow, SIGNAL(eraseAllPerformed()), this, SLOT(onEraseAllPerformed()));
+  aVisibilityState->SetDisplayer (myViewWindow->Displayer());
+  aVisibilityState->SetPresentationType (View_PresentationType_Main);
+  myViewWindow->ViewWidget()->SetPredefinedSize (MESSAGEVIEW_DEFAULT_VIEW_WIDTH, MESSAGEVIEW_DEFAULT_VIEW_HEIGHT);
+
+  myViewDockWidget = new QDockWidget (tr ("View"), myMainWindow);
+  myViewDockWidget->setObjectName (myViewDockWidget->windowTitle());
+  myViewDockWidget->setWidget (myViewWindow);
+  myMainWindow->addDockWidget (Qt::RightDockWidgetArea, myViewDockWidget);
+
+  myMainWindow->tabifyDockWidget (myPropertyPanelWidget, myCustomPanelWidget);
+
+  myMainWindow->resize (DEFAULT_SHAPE_VIEW_WIDTH, DEFAULT_SHAPE_VIEW_HEIGHT);
+  myMainWindow->move (DEFAULT_SHAPE_VIEW_POSITION_X, DEFAULT_SHAPE_VIEW_POSITION_Y);
+
+  updateVisibleColumns();
+}
+
+// =======================================================================
+// function : SetParent
+// purpose :
+// =======================================================================
+void MessageView_Window::SetParent (void* theParent)
+{
+  QWidget* aParent = (QWidget*)theParent;
+  if (aParent)
+  {
+    QLayout* aLayout = aParent->layout();
+    if (aLayout)
+      aLayout->addWidget (GetMainWindow());
+  }
+  else
+  {
+    GetMainWindow()->setParent (0);
+    GetMainWindow()->setVisible (true);
+  }
+}
+
+// =======================================================================
+// function : FillActionsMenu
+// purpose :
+// =======================================================================
+void MessageView_Window::FillActionsMenu (void* theMenu)
+{
+  QMenu* aMenu = (QMenu*)theMenu;
+  QList<QDockWidget*> aDockwidgets = myMainWindow->findChildren<QDockWidget*>();
+  for (QList<QDockWidget*>::iterator it = aDockwidgets.begin(); it != aDockwidgets.end(); ++it)
+  {
+    QDockWidget* aDockWidget = *it;
+    if (aDockWidget->parentWidget() == myMainWindow)
+      aMenu->addAction (aDockWidget->toggleViewAction());
+  }
+}
+
+// =======================================================================
+// function : GetPreferences
+// purpose :
+// =======================================================================
+void MessageView_Window::GetPreferences (TInspectorAPI_PreferencesDataMap& theItem)
+{
+  theItem.Clear();
+  theItem.Bind ("geometry",  TreeModel_Tools::ToString (myMainWindow->saveState()).toStdString().c_str());
+
+  QMap<QString, QString> anItems;
+  TreeModel_Tools::SaveState (myTreeView, anItems);
+  for (QMap<QString, QString>::const_iterator anItemsIt = anItems.begin(); anItemsIt != anItems.end(); anItemsIt++)
+  {
+    theItem.Bind (anItemsIt.key().toStdString().c_str(), anItemsIt.value().toStdString().c_str());
+  }
+
+  anItems.clear();
+  View_Window::SaveState(myViewWindow, anItems);
+  for (QMap<QString, QString>::const_iterator anItemsIt = anItems.begin(); anItemsIt != anItems.end(); anItemsIt++)
+  {
+    theItem.Bind (anItemsIt.key().toStdString().c_str(), anItemsIt.value().toStdString().c_str());
+  }
+}
+
+// =======================================================================
+// function : SetPreferences
+// purpose :
+// =======================================================================
+void MessageView_Window::SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem)
+{
+  for (TInspectorAPI_IteratorOfPreferencesDataMap anItemIt (theItem); anItemIt.More(); anItemIt.Next())
+  {
+    if (anItemIt.Key().IsEqual ("geometry"))
+      myMainWindow->restoreState (TreeModel_Tools::ToByteArray (anItemIt.Value().ToCString()));
+    else if (TreeModel_Tools::RestoreState (myTreeView, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
+      continue;
+    else if (myViewWindow && View_Window::RestoreState(myViewWindow, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
+      continue;
+  }
+}
+
+// =======================================================================
+// function : UpdateContent
+// purpose :
+// =======================================================================
+void MessageView_Window::UpdateContent()
+{
+  bool isUpdated = false;
+  TCollection_AsciiString aName = "TKMessageView";
+  if (myParameters->FindParameters (aName))
+  {
+    NCollection_List<Handle(Standard_Transient)> aParameters = myParameters->Parameters (aName);
+    // Init will remove from parameters those, that are processed only one time (TShape)
+    Init (aParameters);
+    myParameters->SetParameters (aName, aParameters);
+    isUpdated = true;
+  }
+  if (myParameters->FindFileNames (aName))
+  {
+    for (NCollection_List<TCollection_AsciiString>::Iterator aFilesIt (myParameters->FileNames (aName));
+         aFilesIt.More(); aFilesIt.Next())
+      openFile (aFilesIt.Value());
+
+    NCollection_List<TCollection_AsciiString> aNames;
+    myParameters->SetFileNames (aName, aNames);
+    isUpdated = true;
+  }
+  Handle(Message_Report) aDefaultReport = Message::DefaultReport();
+  MessageModel_TreeModel* aViewModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  if (!aDefaultReport.IsNull() && !aViewModel->HasReport (aDefaultReport))
+  {
+    addReport (aDefaultReport);
+  }
+  // reload report of selected item
+  //onReloadReport();
+
+  updateTreeModel();
+  updateVisibleColumns();
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void MessageView_Window::Init (NCollection_List<Handle(Standard_Transient)>& theParameters)
+{
+  Handle(AIS_InteractiveContext) aContext;
+  NCollection_List<Handle(Standard_Transient)> aParameters;
+
+  Handle(Graphic3d_Camera) aViewCamera;
+
+  for (NCollection_List<Handle(Standard_Transient)>::Iterator aParamsIt (theParameters);
+       aParamsIt.More(); aParamsIt.Next())
+  {
+    Handle(Standard_Transient) anObject = aParamsIt.Value();
+    Handle(Message_Report) aMessageReport = Handle(Message_Report)::DownCast (anObject);
+    if (!aMessageReport.IsNull())
+    {
+      addReport (aMessageReport);
+    }
+    else if (!Handle(AIS_InteractiveContext)::DownCast (anObject).IsNull())
+    {
+      aParameters.Append (anObject);
+      if (aContext.IsNull())
+        aContext = Handle(AIS_InteractiveContext)::DownCast (anObject);
+    }
+    else if (!Handle(Graphic3d_Camera)::DownCast (anObject).IsNull())
+    {
+      aViewCamera = Handle(Graphic3d_Camera)::DownCast (anObject);
+    }
+  }
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  if (!aTreeModel)
+    return;
+
+  aTreeModel->EmitLayoutChanged();
+
+  if (!aContext.IsNull())
+  {
+    myViewWindow->SetContext (View_ContextType_External, aContext);
+    //myViewWindow->GetViewToolBar()->SetCurrentContextType (View_ContextType_External);
+  }
+
+  //if (!aViewCamera.IsNull())
+  //  myViewWindow->View()->Viewer()->View()->Camera()->Copy (aViewCamera);
+
+  theParameters = aParameters;
+}
+
+// =======================================================================
+// function : openFile
+// purpose :
+// =======================================================================
+void MessageView_Window::openFile(const TCollection_AsciiString& theFileName)
+{
+#ifdef DEBUG_ALERTS
+  if (theFileName.IsEmpty())
+    return;
+
+  const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_True);
+
+  //Handle(Message_Report) aReport = new Message_Report();
+  if (aReport->MessageWriter().IsNull())
+    aReport->SetMessageWriter (new XmlDrivers_MessageReportStorage());
+
+  aReport->MessageWriter()->SetFileName (TCollection_AsciiString (theFileName));
+  aReport->MessageWriter()->ImportReport (aReport);
+
+  addReport (aReport, theFileName);
+#endif
+}
+
+// =======================================================================
+// function : updateTreeModel
+// purpose :
+// =======================================================================
+void MessageView_Window::updateTreeModel()
+{
+  MessageModel_TreeModel* aViewModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  if (!aViewModel)
+    return;
+
+  aViewModel->UpdateTreeModel();
+}
+
+// =======================================================================
+// function : addReport
+// purpose :
+// =======================================================================
+void MessageView_Window::addReport (const Handle(Message_Report)& theReport,
+                                    const TCollection_AsciiString& theReportDescription)
+{
+  MessageModel_TreeModel* aModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  aModel->AddReport (theReport, theReportDescription);
+
+  //updateVisibleColumns();
+}
+
+// =======================================================================
+// function : onTreeViewVisibilityClicked
+// purpose :
+// =======================================================================
+void MessageView_Window::onTreeViewVisibilityClicked(const QModelIndex& theIndex)
+{
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  TreeModel_VisibilityState* aVisibilityState = aTreeModel->GetVisibilityState();
+  if (!aVisibilityState->IsVisible (theIndex))
+    myPropertyView->ClearActiveTablesSelection();
+}
+
+// =======================================================================
+// function : onTreeViewSelectionChanged
+// purpose :
+// =======================================================================
+void MessageView_Window::onTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)
+{
+  if (!myPropertyPanelWidget->toggleViewAction()->isChecked())
+    return;
+
+  updatePropertyPanelBySelection();
+  updatePreviewPresentation();
+}
+
+// =======================================================================
+// function : onTreeViewContextMenuRequested
+// purpose :
+// =======================================================================
+void MessageView_Window::onTreeViewContextMenuRequested (const QPoint& thePosition)
+{
+  QMenu* aMenu = new QMenu (GetMainWindow());
+
+  MessageModel_ItemRootPtr aRootItem;
+  MessageModel_ItemReportPtr aReportItem;
+  QModelIndexList aSelectedIndices = myTreeView->selectionModel()->selectedIndexes();
+
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItemBase);
+    if (aRootItem)
+      break;
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    if (aReportItem)
+      break;
+  }
+  if (aRootItem)
+  {
+    aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Create Default Report"),
+                      SLOT (onCreateDefaultReport()), myMainWindow, this));
+    // unite
+    //MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+    //aMenu->addAction (ViewControl_Tools::CreateAction (aTreeModel->IsUniteAlerts() ? tr ("SetUniteAlerts - OFF") : tr ("SetUniteAlerts - ON"),
+    //                  SLOT (onUniteAlerts()), myMainWindow, this));
+    // reversed
+    //aMenu->addAction (ViewControl_Tools::CreateAction (aTreeModel->IsReversed() ? tr ("SetReversed - OFF") : tr ("SetReversed - ON"),
+    //                  SLOT (onSetReversedAlerts()), myMainWindow, this));
+  }
+  else if (aReportItem)
+  {
+    aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Export Report"), SLOT (onExportReport()), myMainWindow, this));
+    const TCollection_AsciiString& aDescription = aReportItem->GetDescription();
+    if (!aDescription.IsEmpty())
+    {
+      OSD_Path aPath(aDescription);
+      OSD_File aDescriptionFile (aPath);
+      if (aDescriptionFile.IsReadable())
+        aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Reload"), SLOT (onReloadReport()), myMainWindow, this));
+    }
+    Handle(Message_Report) aReport = aReportItem->GetReport();
+    /*QAction* anAction = ViewControl_Tools::CreateAction (tr ("Export by alert"), SLOT (onAutoExportActivate()), myMainWindow, this);
+    anAction->setCheckable (true);
+    anAction->setChecked (aReport->WriteFileOnEachAlert());
+    aMenu->addAction (anAction);
+
+    anAction = ViewControl_Tools::CreateAction (tr ("Export trace only"), SLOT (onExportTraceOnly()), myMainWindow, this);
+    anAction->setCheckable (true);
+    bool isTraceOnly = aReport->MessageWriter().IsNull() ? false : aReport->MessageWriter()->Gravity() == Message_Trace;
+    anAction->setChecked (isTraceOnly);
+    aMenu->addAction (anAction);*/
+
+    QAction* anAction = anAction = ViewControl_Tools::CreateAction (tr ("Unit by name"), SLOT (onUnitByName()), myMainWindow, this);
+    anAction->setCheckable (true);
+    aMenu->addAction (anAction);
+  }
+  aMenu->addSeparator();
+
+  aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Preview children presentations"), SLOT (onPreviewChildren()), myMainWindow, this));
+  aMenu->addSeparator();
+
+  myTreeViewActions->AddMenuActions (aSelectedIndices, aMenu);
+  addActivateMetricActions (aMenu);
+
+#ifdef DEBUG_ALERTS
+  aMenu->addSeparator();
+  myTestViewActions->AddMenuActions (aSelectedIndices, aMenu);
+#endif
+
+  QPoint aPoint = myTreeView->mapToGlobal (thePosition);
+  aMenu->exec (aPoint);
+}
+
+// =======================================================================
+// function : onPropertyPanelShown
+// purpose :
+// =======================================================================
+void MessageView_Window::onPropertyPanelShown (bool isToggled)
+{
+  if (!isToggled)
+    return;
+
+  updatePropertyPanelBySelection();
+}
+
+// =======================================================================
+// function : onPropertyViewDataChanged
+// purpose :
+// =======================================================================
+void MessageView_Window::onPropertyViewDataChanged()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+
+  updatePropertyPanelBySelection();
+  updatePreviewPresentation();
+}
+
+// =======================================================================
+// function : onHeaderResized
+// purpose :
+// =======================================================================
+void MessageView_Window::onHeaderResized (int theSectionId, int, int)
+{
+  TreeModel_ModelBase* aViewModel = dynamic_cast<TreeModel_ModelBase*> (myTreeView->model());
+
+  TreeModel_HeaderSection* aSection = aViewModel->ChangeHeaderItem (theSectionId);
+  aSection->SetWidth (myTreeView->columnWidth (theSectionId));
+}
+
+// =======================================================================
+// function : onEraseAllPerformed
+// purpose :
+// =======================================================================
+void MessageView_Window::onEraseAllPerformed()
+{
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+
+  // TODO: provide update for only visibility state for better performance  TopoDS_Shape myCustomShape;
+
+  aTreeModel->Reset();
+  aTreeModel->EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : onExportReport
+// purpose :
+// =======================================================================
+void MessageView_Window::onExportReport()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItemBase);
+  if (!aReportItem)
+    return;
+
+  QString aFilter (tr ("Document file (*.json *)"));
+  QString aSelectedFilter;
+  QString aFileName = QFileDialog::getSaveFileName (0, tr ("Export report to file"), QString(), aFilter, &aSelectedFilter);
+
+  Handle(Message_Report) aReport = aReportItem->GetReport();
+  Standard_SStream aStream;
+  aReport->DumpJson(aStream);
+
+  QFile aLogFile(aFileName);
+  if (!aLogFile.open(QFile::WriteOnly | QFile::Text))
+  {
+    return;
+  }
+  QTextStream anOut( &aLogFile );
+  anOut << Standard_Dump::FormatJson (aStream).ToCString();//aStream.str().c_str();
+  aLogFile.close();
+}
+
+// =======================================================================
+// function : onCreateDefaultReport
+// purpose :
+// =======================================================================
+void MessageView_Window::onCreateDefaultReport()
+{
+  if (!Message::DefaultReport().IsNull())
+  {
+    return;
+  }
+
+  addReport (Message::DefaultReport (Standard_True));
+}
+
+// =======================================================================
+// function : onImportReport
+// purpose :
+// =======================================================================
+//void MessageView_Window::onUniteAlerts()
+//{
+  //MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  //Standard_Boolean isUniteAlerts = aTreeModel->IsUniteAlerts();
+
+  //aTreeModel->SetUniteAlerts (!isUniteAlerts);
+//}
+
+// =======================================================================
+// function : onSetReversedAlerts
+// purpose :
+// =======================================================================
+void MessageView_Window::onSetReversedAlerts()
+{
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  Standard_Boolean isReversed = aTreeModel->IsReversed();
+
+  aTreeModel->SetReversed (!isReversed);
+}
+
+// =======================================================================
+// function : onReloadReport
+// purpose :
+// =======================================================================
+void MessageView_Window::onReloadReport()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItemBase);
+  if (!aReportItem)
+    aReportItem = MessageModel_ItemReport::FindReportItem (anItemBase);
+
+  if (!aReportItem)
+    return;
+
+  const TCollection_AsciiString aDescription = aReportItem->GetDescription();
+  if (aDescription.IsEmpty())
+    return;
+
+  Handle(Message_Report) aReport = aReportItem->GetReport();
+  /*aReport->Clear();
+  if (aReport->MessageWriter().IsNull())
+    aReport->SetMessageWriter (new XmlDrivers_MessageReportStorage());
+
+  aReport->MessageWriter()->SetFileName (TCollection_AsciiString (aDescription));
+  if (!aReport->MessageWriter()->ImportReport (aReport))
+    return;*/
+
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  aModel->clearSelection();
+  aTreeModel->SetReport (aReportItem->Row(), aReport, aDescription);
+}
+
+// =======================================================================
+// function : onAutoExportActivate
+// purpose :
+// =======================================================================
+void MessageView_Window::onAutoExportActivate()
+{
+  /*QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItemBase);
+  if (!aReportItem)
+    aReportItem = MessageModel_ItemReport::FindReportItem (anItemBase);
+
+  if (!aReportItem)
+    return;
+
+  Handle(Message_Report) aReport = aReportItem->GetReport();
+  QAction* anAction = (QAction*)(sender());
+  aReport->SetWriteFileOnEachAlert (anAction->isChecked());*/
+}
+
+// =======================================================================
+// function : onExportTraceOnly
+// purpose :
+// =======================================================================
+void MessageView_Window::onExportTraceOnly()
+{
+  /*QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItemBase);
+  if (!aReportItem)
+    aReportItem = MessageModel_ItemReport::FindReportItem (anItemBase);
+
+  if (!aReportItem)
+    return;
+
+  Handle(Message_Report) aReport = aReportItem->GetReport();
+  if (aReport->MessageWriter().IsNull())
+    return;
+
+  QAction* anAction = (QAction*)(sender());
+  aReport->MessageWriter()->SetGravity (anAction->isChecked() ? Message_Trace : Message_Info);*/
+}
+
+// =======================================================================
+// function : onPreviewChildren
+// purpose :
+// =======================================================================
+void MessageView_Window::onPreviewChildren()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+
+  QModelIndexList aSelectedIndices = myTreeView->selectionModel()->selectedIndexes();
+  NCollection_List<Handle(Standard_Transient)> aPresentations;
+  TreeModel_ModelBase::SubItemsPresentations (aSelectedIndices, aPresentations);
+
+  displayer()->UpdatePreview (View_DisplayActionType_DisplayId, aPresentations);
+}
+
+// =======================================================================
+// function : onUnitByName
+// purpose :
+// =======================================================================
+void MessageView_Window::onUnitByName()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+  {
+    return;
+  }
+
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+  {
+    return;
+  }
+
+  MessageView_UnitByNameModel* aUnitByNameModel = new MessageView_UnitByNameModel(myCustomView);
+  if (aUnitByNameModel)
+  {
+    aUnitByNameModel->Init (anItemBase);
+  }
+
+  myCustomView->setModel (aUnitByNameModel);
+}
+
+// =======================================================================
+// function : addActivateMetricActions
+// purpose :
+// =======================================================================
+void MessageView_Window::addActivateMetricActions (QMenu* theMenu)
+{
+  Handle(Message_Report) aReport = Message::DefaultReport();
+  if (aReport.IsNull())
+  {
+    return;
+  }
+
+  QMenu* aSubMenu = new QMenu ("Activate metric");
+  for (int aMetricId = (int)Message_MetricType_None + 1; aMetricId <= (int)Message_MetricType_MemHeapUsage; aMetricId++)
+  {
+    Message_MetricType aMetricType = (Message_MetricType)aMetricId;
+    QAction* anAction = ViewControl_Tools::CreateAction (Message::MetricToString (aMetricType),
+      SLOT (OnActivateMetric()), parent(), this);
+    anAction->setCheckable (true);
+    anAction->setChecked (aReport->ActiveMetrics().Contains (aMetricType));
+    aSubMenu->addAction (anAction);
+  }
+  aSubMenu->addSeparator();
+  aSubMenu->addAction (ViewControl_Tools::CreateAction ("Deactivate all", SLOT (OnDeactivateAllMetrics()), parent(), this));
+
+  theMenu->addMenu (aSubMenu);
+}
+
+// =======================================================================
+// function : OnActivateMetric
+// purpose :
+// =======================================================================
+void MessageView_Window::OnActivateMetric()
+{
+  QAction* anAction = (QAction*)(sender());
+
+  Message_MetricType aMetricType;
+  if (!Message::MetricFromString (anAction->text().toStdString().c_str(), aMetricType))
+    return;
+
+  Handle(Message_Report) aReport = Message::DefaultReport();
+  const NCollection_IndexedMap<Message_MetricType>& anActiveMetrics = aReport->ActiveMetrics();
+  aReport->SetActiveMetric (aMetricType, !anActiveMetrics.Contains (aMetricType));
+
+  updateVisibleColumns();
+}
+
+// =======================================================================
+// function : OnDeactivateAllMetrics
+// purpose :
+// =======================================================================
+void MessageView_Window::OnDeactivateAllMetrics()
+{
+  Handle(Message_Report) aReport = Message::DefaultReport();
+  if (aReport.IsNull())
+    return;
+  aReport->ClearMetrics();
+
+  updateVisibleColumns();
+}
+
+// =======================================================================
+// function : displayer
+// purpose :
+// =======================================================================
+View_Displayer* MessageView_Window::displayer()
+{
+  return myViewWindow->Displayer();
+}
+
+// =======================================================================
+// function : updatePropertyPanelBySelection
+// purpose :
+// =======================================================================
+void MessageView_Window::updatePropertyPanelBySelection()
+{
+  /*QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+
+  QList<ViewControl_TableModelValues*> aTableValues;
+  MessageModel_Tools::GetPropertyTableValues (anItemBase, aTableValues);
+
+  myPropertyView->Init (aTableValues);*/
+  ViewControl_TableModelValues* aTableValues = 0;
+
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (anItemBase)
+  {
+    Handle(TreeModel_ItemProperties) anItemProperties = anItemBase->Properties ();
+    if (!anItemProperties.IsNull())
+    {
+      aTableValues = new ViewControl_TableModelValues();
+      aTableValues->SetProperties (anItemProperties);
+    }
+  }
+  myPropertyView->Init (aTableValues);
+}
+
+// =======================================================================
+// function : updatePreviewPresentation
+// purpose :
+// =======================================================================
+void MessageView_Window::updatePreviewPresentation()
+{
+  Handle(AIS_InteractiveContext) aContext = myViewWindow->ViewToolBar()->CurrentContext();
+  if (aContext.IsNull())
+    return;
+
+  NCollection_List<Handle(Standard_Transient)> aPresentations;
+  QModelIndexList aSelectedIndices = myTreeView->selectionModel()->selectedIndexes();
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    anItemBase->Presentations (aPresentations);
+  }
+
+  displayer()->UpdatePreview (View_DisplayActionType_DisplayId, aPresentations);
+}
+
+// =======================================================================
+// function : updateVisibleColumns
+// purpose :
+// =======================================================================
+void MessageView_Window::updateVisibleColumns()
+{
+  MessageModel_TreeModel* aViewModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+
+  NCollection_IndexedMap<Message_MetricType> anActiveMetrics;
+  for (NCollection_List<MessageModel_ReportInformation>::Iterator anIterator (aViewModel->Reports()); anIterator.More(); anIterator.Next())
+  {
+    Handle(Message_Report) aReport = anIterator.Value().myReport;
+    for (NCollection_IndexedMap<Message_MetricType>::Iterator aMetricsIterator (aReport->ActiveMetrics()); aMetricsIterator.More(); aMetricsIterator.Next())
+    {
+      if (anActiveMetrics.Contains (aMetricsIterator.Value()))
+        continue;
+      anActiveMetrics.Add (aMetricsIterator.Value());
+    }
+  }
+
+  for (int aMetricId = (int)Message_MetricType_None + 1; aMetricId <= (int)Message_MetricType_MemHeapUsage; aMetricId++)
+  {
+    Message_MetricType aMetricType = (Message_MetricType)aMetricId;
+    QList<int> aMetricColumns;
+    aViewModel->GetMetricColumns (aMetricType, aMetricColumns);
+    bool isColumnHidden = !anActiveMetrics.Contains (aMetricType);
+    for (int i = 0; i < aMetricColumns.size(); i++)
+    {
+      int aColumnId = aMetricColumns[i];
+      myTreeView->setColumnHidden (aColumnId, isColumnHidden);
+      TreeModel_HeaderSection* aSection = aViewModel->ChangeHeaderItem (aColumnId);
+      aSection->SetIsHidden (isColumnHidden);
+    }
+  }
+}
diff --git a/tools/MessageView/MessageView_Window.hxx b/tools/MessageView/MessageView_Window.hxx
new file mode 100644 (file)
index 0000000..c8eee15
--- /dev/null
@@ -0,0 +1,217 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageView_Window_H
+#define MessageView_Window_H
+
+#include <Message_Report.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <inspector/MessageModel_Actions.hxx>
+#include <inspector/TInspectorAPI_PluginParameters.hxx>
+
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_InteractiveObject.hxx>
+#include <TopoDS_Shape.hxx>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4127) // conditional expression is constant
+#endif
+#include <QItemSelection>
+#include <QList>
+#include <QModelIndexList>
+#include <QObject>
+#include <QPoint>
+#include <QString>
+#include <QTableView>
+#include <QTreeView>
+
+class View_Displayer;
+class View_Window;
+
+class ViewControl_PropertyView;
+
+class MessageView_ActionsTest;
+
+class QDockWidget;
+class QMainWindow;
+class QMenu;
+class QWidget;
+
+//! \class MessageView_Window
+//! Window that unites all MessageView controls.
+class MessageView_Window : public QObject
+{
+  Q_OBJECT
+public:
+
+  //! Constructor
+  Standard_EXPORT MessageView_Window (QWidget* theParent);
+
+  //! Destructor
+  virtual ~MessageView_Window() {}
+
+  //! Provides the container with a parent where this container should be inserted.
+  //! If Qt implementation, it should be QWidget with QLayout set inside
+  //! \param theParent a parent class
+  Standard_EXPORT void SetParent (void* theParent);
+
+  //! Sets parameters container, it should be used when the plugin is initialized or in update content
+  //! \param theParameters a parameters container
+  void SetParameters (const Handle(TInspectorAPI_PluginParameters)& theParameters)
+  { myParameters = theParameters; myTreeViewActions->SetParameters (theParameters); }
+
+  //! Provide container for actions available in inspector on general level
+  //! \param theMenu if Qt implementation, it is QMenu object
+  Standard_EXPORT virtual void FillActionsMenu (void* theMenu);
+
+  //! Returns plugin preferences: dock widgets state, tree view columns.
+  //! \param theItem container of preference elements
+  Standard_EXPORT void GetPreferences (TInspectorAPI_PreferencesDataMap& theItem);
+
+  //! Applies plugin preferences
+  //! \param theItem container of preference elements
+  Standard_EXPORT void SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem);
+
+  //! Applyes parameters to Init controls, opens files if there are in parameters, updates OCAF tree view model
+  Standard_EXPORT void UpdateContent();
+
+  //! Returns main control
+  QMainWindow* GetMainWindow() const { return myMainWindow; }
+
+  //! Returns current tree view
+  QTreeView* GetTreeView() const { return myTreeView; }
+
+protected:
+  //! Appends shape into tree view model
+  //! \param theShape a shape instance
+  //! \param theReportDescription an additional report information
+  void addReport (const Handle(Message_Report)& theReport,
+                  const TCollection_AsciiString& theReportDescription = "");
+
+private:
+
+  //! Fills controls of the plugin by parameters:
+  //! - Fine AIS_InteractiveObject and fills View if it if it differs from the current context
+  //! \param theParameters a parameters container
+  void Init (NCollection_List<Handle(Standard_Transient)>& theParameters);
+
+  //! Read Shape from the file name, add Shape into tree view
+  //! \param theFileName BREP file name
+  void openFile (const TCollection_AsciiString& theFileName);
+
+  //! Updates tree model
+  void updateTreeModel();
+
+protected slots:
+  //! Updates property view selection in table if the item is hidden
+  //! \param theIndex tree view model index
+  void onTreeViewVisibilityClicked(const QModelIndex& theIndex);
+
+  //! Udpates all controls by changed selection in OCAF tree view
+  //! \param theSelected list of selected tree view items
+  //! \param theDeselected list of deselected tree view items
+  void onTreeViewSelectionChanged (const QItemSelection& theSelected, const QItemSelection& theDeselected);
+
+  //! Shows context menu for tree view selected item. It contains expand/collapse actions.
+  //! \param thePosition a clicked point
+  void onTreeViewContextMenuRequested (const QPoint& thePosition);
+
+  //! Display content of selected tree view item if isToggled is true
+  //! \param isToggled true if the property dock widget is shown
+  void onPropertyPanelShown (bool isToggled);
+
+  //! Update tree view item, preview presentation by item value change
+  void onPropertyViewDataChanged();
+
+  //! Update tree view header item width
+  void onHeaderResized (int theSectionId, int, int);
+
+  //! Updates visibility states by erase all in context
+  void onEraseAllPerformed();
+
+  //! Export report into document
+  void onExportReport();
+
+  //! Create default report into document
+  void onCreateDefaultReport();
+
+  //! Unite alerts in view model
+  //void onUniteAlerts();
+
+  //! Sets report reversed 
+  void onSetReversedAlerts();
+
+  //! Reads if possible report of a selected item and updates this report in tree view
+  void onReloadReport();
+
+  //! Sets report state to write it by each message alert
+  void onAutoExportActivate();
+
+  //! Sets report writer state to write only trace information of alerts
+  void onExportTraceOnly();
+
+  //! Iterates by children items of selected items and display its presentations if found
+  void onPreviewChildren();
+
+  //! Creates the table that sums the number of calls and
+  //! the time spent on the functionality inside the value.
+  void onUnitByName();
+
+  //! Switch active state in report for clicked type of metric
+  void OnActivateMetric();
+
+  //! Deactivate all types of metrics for the current report
+  void OnDeactivateAllMetrics();
+
+protected:
+  //! Appends items to activate report metrics
+  void addActivateMetricActions (QMenu* theMenu);
+
+  //! Returns displayer where the presentations/preview should be shown/erased
+  //! If default view is created, it returns displayer of this view
+  Standard_EXPORT View_Displayer* displayer();
+
+  //! Updates property panel content by item selected in tree view.
+  void updatePropertyPanelBySelection();
+
+  //!< Updates presentation of preview for parameter shapes. Creates a compound of the shapes
+  void updatePreviewPresentation();
+
+  //!< Sets reports metric columns visible if used
+  void updateVisibleColumns();
+
+private:
+  QMainWindow* myMainWindow; //!< main control, parent for all MessageView controls
+  QDockWidget* myViewDockWidget; //!< view dock widget to hide/show
+
+  QDockWidget* myPropertyPanelWidget; //!< property pane dockable widget
+  ViewControl_PropertyView* myPropertyView; //!< property control to display model item values if exist
+
+  View_Window* myViewWindow; //!< OCC 3d view to visualize presentations
+  QTreeView* myTreeView; //!< tree view visualized shapes
+  MessageModel_Actions* myTreeViewActions; //!< processing history view actions
+  MessageView_ActionsTest* myTestViewActions; //!< check view actions
+
+  QTableView* myCustomView;         //!< table that units messages by name.
+  QDockWidget* myCustomPanelWidget; //!< panel for table that units messages by name.
+
+  Handle(TInspectorAPI_PluginParameters) myParameters; //!< plugins parameters container
+
+  Handle(AIS_InteractiveObject) myPreviewPresentation; //!< presentation of preview for a selected object
+};
+
+#endif
index d6f54d75cc4cd24f428c2f91b08d2dfc7b1c5ea6..7ae4fb55c472c6bdb3277c5ea489e7c02a7b20a3 100644 (file)
@@ -18,6 +18,7 @@
 #include <inspector/ShapeView_ItemShape.hxx>
 #include <inspector/ShapeView_TreeModel.hxx>
 #include <inspector/ShapeView_VisibilityState.hxx>
+#include <inspector/ViewControl_PropertiesDialog.hxx>
 
 #include <inspector/Convert_Tools.hxx>
 
@@ -31,6 +32,7 @@
 #include <inspector/View_Displayer.hxx>
 #include <inspector/View_PresentationType.hxx>
 #include <inspector/View_ToolBar.hxx>
+#include <inspector/View_Widget.hxx>
 #include <inspector/View_Window.hxx>
 #include <inspector/View_Viewer.hxx>
 
 #include <inspector/ShapeView_OpenFileDialog.hxx>
 #include <inspector/ShapeView_Tools.hxx>
 
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
 #include <BRep_Builder.hxx>
 #include <BRepTools.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <Message_Report.hxx>
+#include <StdPrs_ShadedShape.hxx>
+#include <TopoDS.hxx>
 
 #include <Standard_WarningsDisable.hxx>
 #include <QApplication>
@@ -106,6 +115,7 @@ ShapeView_Window::ShapeView_Window (QWidget* theParent)
                     aVisibilityState, SLOT (OnClicked(const QModelIndex&)));
 
   QItemSelectionModel* aSelModel = new QItemSelectionModel (myTreeView->model(), myTreeView);
+  myTreeView->setSelectionMode (QAbstractItemView::ExtendedSelection);
   myTreeView->setSelectionModel (aSelModel);
   connect (aSelModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
            this, SLOT (onTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
@@ -128,7 +138,7 @@ ShapeView_Window::ShapeView_Window (QWidget* theParent)
   connect (myViewWindow, SIGNAL(eraseAllPerformed()), this, SLOT(onEraseAllPerformed()));
   aVisibilityState->SetDisplayer (myViewWindow->Displayer());
   aVisibilityState->SetPresentationType (View_PresentationType_Main);
-  myViewWindow->SetPredefinedSize (SHAPEVIEW_DEFAULT_VIEW_WIDTH, SHAPEVIEW_DEFAULT_VIEW_HEIGHT);
+  myViewWindow->ViewWidget()->SetPredefinedSize (SHAPEVIEW_DEFAULT_VIEW_WIDTH, SHAPEVIEW_DEFAULT_VIEW_HEIGHT);
 
   QDockWidget* aViewDockWidget = new QDockWidget (tr ("View"), myMainWindow);
   aViewDockWidget->setObjectName (aViewDockWidget->windowTitle());
@@ -359,42 +369,47 @@ void ShapeView_Window::onTreeViewContextMenuRequested (const QPoint& thePosition
 
   QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
   TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
-  if (!anItemBase)
-    return;
-
   QMenu* aMenu = new QMenu(myMainWindow);
+
   ShapeView_ItemRootPtr aRootItem = itemDynamicCast<ShapeView_ItemRoot> (anItemBase);
   if (aRootItem) {
     aMenu->addAction (ViewControl_Tools::CreateAction ("Load BREP file", SLOT (onLoadFile()), myMainWindow, this));
     aMenu->addAction (ViewControl_Tools::CreateAction ("Remove all shape items", SLOT (onClearView()), myMainWindow, this));
   }
-  else {
+  else if (anItemBase) { // single selection
     aMenu->addAction (ViewControl_Tools::CreateAction ("Export to BREP", SLOT (onExportToBREP()), myMainWindow, this));
+
     ShapeView_ItemShapePtr aShapeItem = itemDynamicCast<ShapeView_ItemShape>(anItemBase);
-    const TopoDS_Shape& aShape = aShapeItem->GetItemShape();
-    TopAbs_ShapeEnum anExplodeType = aShapeItem->ExplodeType();
-    NCollection_List<TopAbs_ShapeEnum> anExplodeTypes;
-    ShapeView_Tools::IsPossibleToExplode (aShape, anExplodeTypes);
-    if (anExplodeTypes.Size() > 0)
+    if (aShapeItem)
     {
-      QMenu* anExplodeMenu = aMenu->addMenu ("Explode");
-      for (NCollection_List<TopAbs_ShapeEnum>::Iterator anExpIterator (anExplodeTypes); anExpIterator.More();
-        anExpIterator.Next())
+      const TopoDS_Shape& aShape = aShapeItem->GetItemShape();
+      TopAbs_ShapeEnum anExplodeType = aShapeItem->ExplodeType();
+      NCollection_List<TopAbs_ShapeEnum> anExplodeTypes;
+      ShapeView_Tools::IsPossibleToExplode (aShape, anExplodeTypes);
+      if (anExplodeTypes.Size() > 0)
       {
-        TopAbs_ShapeEnum aType = anExpIterator.Value();
-        QAction* anAction = ViewControl_Tools::CreateAction (TopAbs::ShapeTypeToString (aType), SLOT (onExplode()), myMainWindow, this);
-        anExplodeMenu->addAction (anAction);
-        if (anExplodeType == aType)
+        QMenu* anExplodeMenu = aMenu->addMenu ("Explode");
+        for (NCollection_List<TopAbs_ShapeEnum>::Iterator anExpIterator (anExplodeTypes); anExpIterator.More();
+          anExpIterator.Next())
         {
-          anAction->setCheckable (true);
-          anAction->setChecked (true);
+          TopAbs_ShapeEnum aType = anExpIterator.Value();
+          QAction* anAction = ViewControl_Tools::CreateAction (TopAbs::ShapeTypeToString (aType), SLOT (onExplode()), myMainWindow, this);
+          anExplodeMenu->addAction (anAction);
+          if (anExplodeType == aType)
+          {
+            anAction->setCheckable (true);
+            anAction->setChecked (true);
+          }
         }
+        QAction* anAction = ViewControl_Tools::CreateAction ("NONE", SLOT (onExplode()), myMainWindow, this);
+        anExplodeMenu->addSeparator();
+        anExplodeMenu->addAction (anAction);
       }
-      QAction* anAction = ViewControl_Tools::CreateAction ("NONE", SLOT (onExplode()), myMainWindow, this);
-      anExplodeMenu->addSeparator();
-      anExplodeMenu->addAction (anAction);
     }
   }
+  aMenu->addAction (ViewControl_Tools::CreateAction ("Create Face", SLOT (onCreateFace()), myMainWindow, this));
+  aMenu->addAction (ViewControl_Tools::CreateAction ("Create Compound", SLOT (onCreateCompound()), myMainWindow, this));
+  aMenu->addAction (ViewControl_Tools::CreateAction ("Algo: Incremental Mesh", SLOT (onIncrementalMesh()), myMainWindow, this));
 
   QPoint aPoint = myTreeView->mapToGlobal (thePosition);
   aMenu->exec (aPoint);
@@ -520,3 +535,84 @@ void ShapeView_Window::onExportToBREP()
   anItem->SetFileName (aFileNameIndiced.ToCString());
   aFileName = aFileNameIndiced.ToCString();
 }
+
+// =======================================================================
+// function : onCreateFace
+// purpose :
+// =======================================================================
+void ShapeView_Window::onCreateFace()
+{
+  /*QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QList<TreeModel_ItemBasePtr> anItems = TreeModel_ModelBase::SelectedItems (aModel->selectedIndexes());
+
+  QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
+  NCollection_List<Handle(Standard_Transient)> anItemPresentations;
+
+  BRepBuilderAPI_MakeWire aWireBuilder;
+  for (QList<TreeModel_ItemBasePtr>::const_iterator anItemIt = anItems.begin(); anItemIt != anItems.end(); ++anItemIt)
+  {
+    ShapeView_ItemShapePtr anItem = itemDynamicCast<ShapeView_ItemShape>(*anItemIt);
+    if (!anItem)
+      continue;
+
+    const TopoDS_Shape& aShape = anItem->GetItemShape();
+    if (aShape.ShapeType() != TopAbs_EDGE)
+      continue;
+
+    const TopoDS_Edge& aSourceEdge = TopoDS::Edge (aShape);
+    const TopoDS_Edge& anEdgeCopied = TopoDS::Edge (aSourceEdge.EmptyCopied());
+
+    aWireBuilder.Add (anEdgeCopied);//aSourceEdge);
+  }
+  if (!aWireBuilder.IsDone())
+    return;
+
+  BRepBuilderAPI_MakeFace aFaceBuilder;
+
+  const TopoDS_Wire& aWire = aWireBuilder.Wire();
+  const TopoDS_Wire& aWireCopied = TopoDS::Wire (aWire.EmptyCopied());
+
+  aFaceBuilder.Add (aWireCopied);
+
+  addShape (aFaceBuilder.Face());
+  */
+}
+
+// =======================================================================
+// function : onCreateCompound
+// purpose :
+// =======================================================================
+void ShapeView_Window::onCreateCompound()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QList<TreeModel_ItemBasePtr> anItems = TreeModel_ModelBase::SelectedItems (aModel->selectedIndexes());
+
+  QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
+  NCollection_List<Handle(Standard_Transient)> anItemPresentations;
+
+  BRep_Builder aBB;
+  TopoDS_Compound aC;
+  aBB.MakeCompound(aC);
+
+  for (QList<TreeModel_ItemBasePtr>::const_iterator anItemIt = anItems.begin(); anItemIt != anItems.end(); ++anItemIt)
+  {
+    ShapeView_ItemShapePtr anItem = itemDynamicCast<ShapeView_ItemShape>(*anItemIt);
+    if (!anItem)
+      return;
+
+    aBB.Add(aC, anItem->GetItemShape());
+  }
+  addShape (aC);
+}
+
+// =======================================================================
+// function : onIncrementalMesh
+// purpose :
+// =======================================================================
+void ShapeView_Window::onIncrementalMesh()
+{
+}
index 950119326efde75b397ae5c11b469e751b086ec3..5119fd903986c8429aabcb9de64cc41e611ae914 100644 (file)
@@ -129,6 +129,15 @@ protected slots:
   //! Views BREP files of selected items if exist
   void onExportToBREP();
 
+  //! Create a wire of selected edges
+  void onCreateFace();
+
+  //! Create a compound of selected shapes
+  void onCreateCompound();
+
+  //! Perform BRepMesh_IncrementalMesh on the selected shape
+  void onIncrementalMesh();
+
   //! Convers file name to Ascii String and perform opeging file
   //! \param theFileName a file name to be opened
   void onOpenFile(const QString& theFileName) { OpenFile (TCollection_AsciiString (theFileName.toUtf8().data())); }
index b22e57eb815911f0f4120dced5d1074aa2114bc7..f3b29732f20a7c707fa72bc5d003a03228bc85f7 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <inspector/TInspector_Communicator.hxx>
 
+#include <Message.hxx>
+#include <Message_Report.hxx>
 #include <OSD_Environment.hxx>
 
 #include <Standard_WarningsDisable.hxx>
@@ -104,6 +106,9 @@ int main (int argc, char** argv)
 
     if (!strcmp (argv[anArgId], "vinspector"))
       aPlugins.insert ("TKVInspector");
+
+    if (!strcmp (argv[anArgId], "messageview"))
+      aPlugins.insert ("TKMessageView");
   }
   NCollection_List<Handle(Standard_Transient)> aParameters;
 
@@ -123,7 +128,14 @@ int main (int argc, char** argv)
     aPlugins.insert("TKShapeView");
     aPlugins.insert("TKVInspector");
 
-    anActivatedPluginName = "TKDFBrowser";
+    //Handle(Message_Report) aReport = Message::DefaultReport (Standard_True);
+    //aReport->SetLimit (100);//30);
+    aPlugins.insert("TKMessageView");
+
+    //anActivatedPluginName = "TKVInspector";
+    //anActivatedPluginName = "TKMessageView";
+    //anActivatedPluginName = "TKDFBrowser";
+    anActivatedPluginName = "TKShapeView";
   }
   else
     anActivatedPluginName = *aPlugins.rbegin();
diff --git a/tools/TKMessageModel/CMakeLists.txt b/tools/TKMessageModel/CMakeLists.txt
new file mode 100644 (file)
index 0000000..911ffb1
--- /dev/null
@@ -0,0 +1,5 @@
+project(TKMessageModel)
+
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
diff --git a/tools/TKMessageModel/EXTERNLIB b/tools/TKMessageModel/EXTERNLIB
new file mode 100644 (file)
index 0000000..54b0274
--- /dev/null
@@ -0,0 +1,10 @@
+TKMath
+TKBin
+TKBRep
+TKGeomBase
+TKG3d
+TKTInspectorAPI
+TKService
+TKTopAlgo
+TKTreeModel
+CSF_QT
diff --git a/tools/TKMessageModel/FILES b/tools/TKMessageModel/FILES
new file mode 100644 (file)
index 0000000..ca4f0e5
--- /dev/null
@@ -0,0 +1,2 @@
+EXTERNLIB
+PACKAGES
diff --git a/tools/TKMessageModel/PACKAGES b/tools/TKMessageModel/PACKAGES
new file mode 100644 (file)
index 0000000..9021fbf
--- /dev/null
@@ -0,0 +1 @@
+MessageModel
diff --git a/tools/TKMessageView/CMakeLists.txt b/tools/TKMessageView/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9b3c1aa
--- /dev/null
@@ -0,0 +1,5 @@
+project(TKMessageView)
+
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
diff --git a/tools/TKMessageView/EXTERNLIB b/tools/TKMessageView/EXTERNLIB
new file mode 100644 (file)
index 0000000..84e5b5d
--- /dev/null
@@ -0,0 +1,13 @@
+TKTInspectorAPI
+TKMath
+TKMessageModel
+TKBin
+TKBRep
+TKGeomBase
+TKG3d
+TKService
+TKTopAlgo
+TKTreeModel
+TKView
+TKXml
+CSF_QT
diff --git a/tools/TKMessageView/FILES b/tools/TKMessageView/FILES
new file mode 100644 (file)
index 0000000..ca4f0e5
--- /dev/null
@@ -0,0 +1,2 @@
+EXTERNLIB
+PACKAGES
diff --git a/tools/TKMessageView/PACKAGES b/tools/TKMessageView/PACKAGES
new file mode 100644 (file)
index 0000000..46a67b2
--- /dev/null
@@ -0,0 +1 @@
+MessageView
index c0abd7766ab10208f5166ca90932698d952e19c5..104bda3336a7497f596150296e8c88c1b70915e8 100644 (file)
@@ -62,6 +62,7 @@ Standard_Boolean convertToPluginName (const TCollection_AsciiString& theArgument
   if (anArgument == "dfbrowser")       { thePluginName = "TKDFBrowser"; return Standard_True; }
   else if (anArgument == "shapeview")  { thePluginName = "TKShapeView"; return Standard_True; }
   else if (anArgument == "vinspector") { thePluginName = "TKVInspector"; return Standard_True; }
+  else if (anArgument == "messageview") { thePluginName = "TKMessageView"; return Standard_True; }
 
   return Standard_False;
 }
@@ -305,6 +306,7 @@ static int tinspector (Draw_Interpretor& di, Standard_Integer theArgsNb, const c
       aPlugins.Append ("TKDFBrowser");
       aPlugins.Append ("TKShapeView");
       aPlugins.Append ("TKVInspector");
+      aPlugins.Append ("TKMessageView");
     }
     aPluginNameToActivate = !aPluginNameToActivate.IsEmpty() ? aPluginNameToActivate : aPlugins.First();
   }
@@ -391,10 +393,10 @@ void ToolsDraw::Commands(Draw_Interpretor& theCommands)
     "\n\t\t: Starts tool of inspection."
     "\n\t\t: Options:"
     "\n\t\t:  -plugins enters plugins that should be added in the inspector."
-    "\n\t\t:           Available names are: dfbrowser, vinspector and shapeview."
+    "\n\t\t:           Available names are: dfbrowser, vinspector, shapeview and messageview."
     "\n\t\t:           Plugins order will be the same as defined in arguments."
     "\n\t\t:           'all' adds all available plugins in the order:"
-    "\n\t\t:                 DFBrowser, VInspector and ShapeView."
+    "\n\t\t:                 DFBrowser, VInspector, ShapeView and MessageView."
     "\n\t\t:           If at the first call this option is not used, 'all' option is applied;"
     "\n\t\t:  -activate activates the plugin in the tool view."
     "\n\t\t:           If at the first call this option is not used, the first plugin is activated;"
index 80cb3f97daa9f6b5d8fbed1743efbfd028d488c5..520cec6fdfd415f15590622da423b9dea3fb1650 100644 (file)
@@ -24,7 +24,8 @@
 enum TreeModel_ColumnType
 {
   TreeModel_ColumnType_Name = 0, //! name column
-  TreeModel_ColumnType_Visibility //! visibility state column
+  TreeModel_ColumnType_Visibility, //! visibility state column
+  TreeModel_ColumnType_Row //! row of the item column
 };
 
 #endif
index 9a60792c6098179c2a22a107cb7a7a67559563a7..9cd0d07ab6f9ee4db73fd73848b89a01dc43870d 100644 (file)
@@ -55,7 +55,7 @@ void TreeModel_ContextMenu::onTreeViewHeaderContextMenuRequested (const QPoint&
   int aNbSections = aModel->columnCount();
   for (int aColumnId = 0; aColumnId < aNbSections; aColumnId++)
   {
-    QAction* anAction = ViewControl_Tools::CreateAction (aModel->GetHeaderItem (aColumnId).GetName(),
+    QAction* anAction = ViewControl_Tools::CreateAction (aModel->ChangeHeaderItem (aColumnId)->GetName(),
                                                        SLOT (onColumnVisibilityChanged()), myTreeView, this);
     anAction->setCheckable (true);
     anAction->setChecked (!myTreeView->isColumnHidden (aColumnId));
index 1b23b909cbc3a923cd57195c77f98898d48bc6a7..359ed3901874e44db7e93d3ae6e1007d6e1c108b 100644 (file)
@@ -14,6 +14,8 @@
 // commercial license or contractual agreement. 
 
 #include <inspector/TreeModel_ItemBase.hxx>
+
+#include <inspector/TreeModel_ColumnType.hxx>
 #include <inspector/TreeModel_ItemProperties.hxx>
 #include <inspector/TreeModel_ItemRole.hxx>
 #include <inspector/TreeModel_ItemStream.hxx>
@@ -195,7 +197,7 @@ QVariant TreeModel_ItemBase::initValue (const int theItemRole) const
 
   switch (Column())
   {
-    case 1: { return Row(); }
+    case TreeModel_ColumnType_Row: { return Row(); }
   }
 
   return QVariant();
index 4c121f8213b2044c4fd5be22422efc71f7426732..8654b068762038a3c562f98fa87bfe421afaca36 100644 (file)
 #ifndef TreeModel_ItemBase_H
 #define TreeModel_ItemBase_H
 
-#include <NCollection_List.hxx>
 #include <Standard.hxx>
 #include <Standard_Macro.hxx>
 #include <Standard_Handle.hxx>
 #include <Standard_OStream.hxx>
 #include <Standard_SStream.hxx>
+#include <NCollection_List.hxx>
 
 #include <inspector/TreeModel_ItemRole.hxx>
 
@@ -150,7 +150,10 @@ public:
   //! Returns the item properties
   const Handle(TreeModel_ItemProperties)& Properties() const { return myProperties; }
 
+  //! Returns presentation of the attribute to be visualized in the view
+  //! \thePresentations [out] container of presentation handles to be visualized
   Standard_EXPORT virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations);
+
 protected:
 
   //! \param theParent the parent item
index 631d2f2c1822e2a62377a9103c5ddfb0759a5fe8..8aa7a0d81d3cfdca9cb95f3c1754bd389e726486 100644 (file)
@@ -39,6 +39,15 @@ void TreeModel_ItemProperties::Init ()
 
   const Standard_SStream& aStream = Item()->Stream();
 
+  InitByStream (aStream);
+}
+
+// =======================================================================
+// function : InitByStream
+// purpose :
+// =======================================================================
+void TreeModel_ItemProperties::InitByStream (const Standard_SStream& aStream)
+{
   NCollection_IndexedDataMap<TCollection_AsciiString, Standard_DumpValue> aValues;
   TCollection_AsciiString aStreamText = Standard_Dump::Text (aStream);
   Standard_Dump::SplitJson (aStreamText, aValues);
@@ -48,8 +57,15 @@ void TreeModel_ItemProperties::Init ()
   Standard_DumpValue aKeyValue;
   if (!aStreamParent)
   {
-    const Handle(Standard_Transient)& anItemObject = Item()->Object();
-    aKey = anItemObject.IsNull() ? "Dump" : anItemObject->DynamicType()->Name();
+    if (!Item() || Item()->Object().IsNull())
+    {
+      aKey = "Dump";
+    }
+    else
+    {
+      const Handle(Standard_Transient)& anItemObject = Item()->Object();
+      aKey = anItemObject.IsNull() ? "Dump" : anItemObject->DynamicType()->Name();
+    }
     aKeyValue = Standard_DumpValue (aStreamText, 1);
 
     myKey = aKey;
@@ -95,6 +111,11 @@ void TreeModel_ItemProperties::Init ()
         (int)(aGreen * aDelta), (int)(aBlue * aDelta)));
     }
   }
+  // in case if the stream alert has empty key avalue, use as the key the first row value
+  if ((myKey.IsEmpty() || myKey.IsEqual ("Dump")) && myRowValues.Size() > 0)
+  {
+    myKey = myRowValues.FindFromIndex (1).Value.toString().toStdString().c_str();
+  }
 }
 
 // =======================================================================
@@ -172,10 +193,16 @@ ViewControl_EditType TreeModel_ItemProperties::EditType (const int, const int th
 // function : SetData
 // purpose :
 // =======================================================================
-bool TreeModel_ItemProperties::SetData (const int /*theRow*/, const int theColumn, const QVariant& /*theValue*/, int)
+bool TreeModel_ItemProperties::SetData (const int theRow, const int theColumn, const QVariant& theValue, int theRole)
 {
   if (theColumn == 0)
     return false;
+
+  if (theRole == Qt::DisplayRole || theRole == Qt::EditRole)
+  {
+    myRowValues.ChangeFromIndex (theRow + 1).Value = theValue;
+  }
+
   return false;
 }
 
@@ -185,6 +212,8 @@ bool TreeModel_ItemProperties::SetData (const int /*theRow*/, const int theColum
 // =======================================================================
 void TreeModel_ItemProperties::Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations)
 {
+  if (!Item())
+    return;
   const Standard_SStream& aStream = Item()->Stream();
   Convert_Tools::ConvertStreamToPresentations (aStream, 1, -1, thePresentations);
 }
index 7f498d70e44d8bbbafa4cb9d55479a8057ca42a9..a86ef9baec4d2146d1868c1680439603cb4a7c8a 100644 (file)
@@ -73,6 +73,9 @@ public:
   //! Sets the current item
   void SetItem (const TreeModel_ItemBasePtr& theItem) { myItem = theItem; }
 
+  //! Fills properties with the stream value
+  Standard_EXPORT void InitByStream (const Standard_SStream& theStream);
+
   //! Returns the current item
   TreeModel_ItemBasePtr Item() const { return myItem; }
 
@@ -80,7 +83,7 @@ public:
   Standard_EXPORT void Init();
 
   //! If the item has internal values, there should be reseted here.
-  Standard_EXPORT virtual void Reset();
+  Standard_EXPORT void Reset();
 
   //! Returns number of table rows
   //! \return an integer value
@@ -108,18 +111,18 @@ public:
   //! \param theColumn a model index column
   //! \param theRole a view role
   //! \return true if the value is changed
-  Standard_EXPORT virtual bool SetData (const int theRow, const int theColumn, const QVariant& theValue,
-                                        int theRole = Qt::DisplayRole);
+  Standard_EXPORT bool SetData (const int theRow, const int theColumn, const QVariant& theValue,
+                                int theRole = Qt::DisplayRole);
 
   //! Returns presentation of the attribute to be visualized in the view
   //! \thePresentations [out] container of presentation handles to be visualized
-  Standard_EXPORT virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations);
+  Standard_EXPORT void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations);
 
   //! Returns flags for the item: ItemIsEnabled | Qt::ItemIsSelectable.
   //! Additional flag for the column 1 is Qt::ItemIsEditable.
   //! \param theIndex a model index
   //! \return flags
-  Standard_EXPORT virtual Qt::ItemFlags TableFlags (const int theRow, const int theColumn) const;
+  Standard_EXPORT Qt::ItemFlags TableFlags (const int theRow, const int theColumn) const;
 
   //! Returns stream value of the item to fulfill property panel.
   //! \return stream value or dummy
index a87cbe662ee767d024f82a581eae42c29b0bf807..5dd4055b7e027ed4f5dae409bc25710dc6509f04 100644 (file)
@@ -16,6 +16,7 @@
 #include <inspector/TreeModel_ModelBase.hxx>
 
 #include <inspector/TreeModel_ItemBase.hxx>
+#include <inspector/TreeModel_ItemProperties.hxx>
 #include <inspector/TreeModel_Tools.hxx>
 #include <inspector/TreeModel_VisibilityState.hxx>
 
@@ -46,9 +47,9 @@ TreeModel_ModelBase::TreeModel_ModelBase (QObject* theParent)
 // =======================================================================
 void TreeModel_ModelBase::InitColumns()
 {
-  SetHeaderItem (0, TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
-  SetHeaderItem (1, TreeModel_HeaderSection ("Visibility", TreeModel_ModelBase::ColumnVisibilityWidth()));
-  SetHeaderItem (2, TreeModel_HeaderSection ("Row", COLUMN_SIZE_WIDTH));
+  setHeaderItem (TreeModel_ColumnType_Name,       TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
+  setHeaderItem (TreeModel_ColumnType_Visibility, TreeModel_HeaderSection ("Visibility", TreeModel_ModelBase::ColumnVisibilityWidth()));
+  setHeaderItem (TreeModel_ColumnType_Row,        TreeModel_HeaderSection ("Row", COLUMN_SIZE_WIDTH));
 }
 
 // =======================================================================
@@ -177,7 +178,7 @@ QVariant TreeModel_ModelBase::headerData (int theSection, Qt::Orientation theOri
   if (IsUseVisibilityColumn() && theSection == TreeModel_ColumnType_Visibility)
     return QVariant();
 
-  return GetHeaderItem (theSection).GetName();
+  return myHeaderValues[theSection].GetName();
 }
 
 // =======================================================================
@@ -231,23 +232,6 @@ void TreeModel_ModelBase::EmitDataChanged (const QModelIndex& theTopLeft, const
 #endif
 }
 
-// =======================================================================
-// function : SetHeaderItem
-// purpose :
-// =======================================================================
-void TreeModel_ModelBase::SetHeaderItem (const int theColumnId, const TreeModel_HeaderSection& theSection)
-{
-  if (theSection.IsEmpty())
-  {
-    // remove section
-    myHeaderValues.remove (theColumnId);
-    myRootItems.remove (theColumnId);
-  }
-
-  myHeaderValues[theColumnId] = theSection;
-  createRoot (theColumnId);
-}
-
 // =======================================================================
 // function : Selected
 // purpose :
@@ -295,6 +279,40 @@ QList<TreeModel_ItemBasePtr> TreeModel_ModelBase::SelectedItems (const QModelInd
   return anItems;
 }
 
+// =======================================================================
+// function : SubItemsPresentations
+// purpose :
+// =======================================================================
+void TreeModel_ModelBase::SubItemsPresentations (const QModelIndexList& theIndices,
+                                                 NCollection_List<Handle(Standard_Transient)>& thePresentations)
+{
+  QList<TreeModel_ItemBasePtr> anItems;
+
+  for (QModelIndexList::const_iterator anIndicesIt = theIndices.begin(); anIndicesIt != theIndices.end(); anIndicesIt++)
+  {
+    TreeModel_ItemBasePtr anItem = TreeModel_ModelBase::GetItemByIndex (*anIndicesIt);
+    if (!anItem || anItems.contains (anItem))
+      continue;
+    subItemsPresentations (anItem, thePresentations);
+  }
+}
+
+// =======================================================================
+// function : subItemPresentations
+// purpose :
+// =======================================================================
+void TreeModel_ModelBase::subItemsPresentations (const TreeModel_ItemBasePtr& theItem,
+                                                 NCollection_List<Handle(Standard_Transient)>& thePresentations)
+{
+  theItem->Presentations (thePresentations);
+
+  QList<TreeModel_ItemBasePtr> anItems;
+  for (int aRowId = 0; aRowId < theItem->rowCount(); aRowId++)
+  {
+    subItemsPresentations (theItem->Child (aRowId, theItem->Column()), thePresentations);
+  }
+}
+
 // =======================================================================
 // function : createRoot
 // purpose :
@@ -304,6 +322,23 @@ void TreeModel_ModelBase::createRoot (const int theColumnId)
   myRootItems.insert (theColumnId, createRootItem (theColumnId));
 }
 
+// =======================================================================
+// function : setHeaderItem
+// purpose :
+// =======================================================================
+void TreeModel_ModelBase::setHeaderItem (const int theColumnId, const TreeModel_HeaderSection& theSection)
+{
+  if (theSection.IsEmpty())
+  {
+    // remove section
+    myHeaderValues.remove (theColumnId);
+    myRootItems.remove (theColumnId);
+  }
+
+  myHeaderValues[theColumnId] = theSection;
+  createRoot (theColumnId);
+}
+
 // =======================================================================
 // function :  getIndexValue
 // purpose :
index b8a31e903ec77565087ca2b67baf225354856d4d..f616846496b73805883e6973db6aaec092aec256 100644 (file)
@@ -141,12 +141,7 @@ public:
   //! Returns whether the column is hidden by default
   //! \param theColumnId a column index
   //! \return header section values container
-  TreeModel_HeaderSection GetHeaderItem (const int theColumnId) const { return myHeaderValues[theColumnId]; }
-
-  //! Sets header properties item.
-  //! \param theColumnId a column index
-  //! \param theSection a section value
-  Standard_EXPORT void SetHeaderItem (const int theColumnId, const TreeModel_HeaderSection& theSection);
+  TreeModel_HeaderSection* ChangeHeaderItem (const int theColumnId) { return &myHeaderValues[theColumnId]; }
 
   //! Returns count of columns in the model
   //! \param theParent an index of the parent item
@@ -180,16 +175,33 @@ public:
   //! \return model items from the list
   Standard_EXPORT static QList<TreeModel_ItemBasePtr> SelectedItems (const QModelIndexList& theIndices);
 
+  //! Returns presentations of sub items
+  //! \param theIndices a container of selected indices
+  //! \thePresentations [out] container of presentation handles to be visualized
+  Standard_EXPORT static void SubItemsPresentations (const QModelIndexList& theIndices,
+                                                     NCollection_List<Handle(Standard_Transient)>& thePresentations);
+
 protected:
   //! Creates root item
   //! \param theColumnId index of a column
   virtual TreeModel_ItemBasePtr createRootItem (const int theColumnId) = 0;
 
+  //! Sets header properties item.
+  //! \param theColumnId a column index
+  //! \param theSection a section value
+  Standard_EXPORT void setHeaderItem (const int theColumnId, const TreeModel_HeaderSection& theSection);
+
   //! Converts the item shared pointer to void* type
   //! \param theItem
   //!  \return an item pointer
   Standard_EXPORT static void* getIndexValue (const TreeModel_ItemBasePtr& theItem);
 
+  //! Returns presentations of sub items
+  //! \param theIndices a container of selected indices
+  //! \thePresentations [out] container of presentation handles to be visualized
+  static void subItemsPresentations (const TreeModel_ItemBasePtr& theItem,
+                                    NCollection_List<Handle(Standard_Transient)>& thePresentations);
+
 private:
   //! Creates root item
   //! \param theColumnId index of a column
index e3d8b2afa54f7d917b1ec5861f55a0e0751314c1..00bc92f59fb3c17048e82883da6d2a777361aa21 100644 (file)
@@ -89,6 +89,7 @@ void TreeModel_Tools::SaveState (QTreeView* theTreeView, QMap<QString, QString>&
   QStringList aColumnWidths, aHiddenColumns;
   for (int aColumnId = 0; aColumnId < theTreeView->model()->columnCount(); aColumnId++)
   {
+    int aWidth = theTreeView->columnWidth (aColumnId);
     if (theTreeView->isColumnHidden (aColumnId))
     {
       aHiddenColumns.append (QString::number (aColumnId));
@@ -121,18 +122,18 @@ bool TreeModel_Tools::RestoreState (QTreeView* theTreeView, const QString& theKe
   }
   else if (theKey == thePrefix + "columns_hidden")
   {
-    int aColumnSize = theTreeView->model()->columnCount();
-    QStringList aValues = theValue.split (",", QString::SkipEmptyParts);
-    QList<int> aColumnIds;
-    for (int aValueId = 0; aValueId < aValues.size(); aValueId++)
-    {
-      if (aValueId < aColumnSize)
-        aColumnIds.append (aValues.at (aValueId).toInt());
-    }
-    for (int aColumnId = 0; aColumnId < aColumnSize; aColumnId++)
-    {
-      theTreeView->setColumnHidden (aColumnId, aColumnIds.contains(aColumnId) == true);
-    }
+    //int aColumnSize = theTreeView->model()->columnCount();
+    //QStringList aValues = theValue.split (",", QString::SkipEmptyParts);
+    //QList<int> aColumnIds;
+    //for (int aValueId = 0; aValueId < aValues.size(); aValueId++)
+    //{
+    //  if (aValueId < aColumnSize)
+    //    aColumnIds.append (aValues.at (aValueId).toInt());
+    //}
+    //for (int aColumnId = 0; aColumnId < aColumnSize; aColumnId++)
+    //{
+    //  theTreeView->setColumnHidden (aColumnId, aColumnIds.contains(aColumnId) == true);
+    //}
   }
   else
     return false;
@@ -149,9 +150,9 @@ void TreeModel_Tools::SetDefaultHeaderSections(QTreeView* theTreeView)
 
   for (int aColumnId = 0, aNbColumns = aTreeModel->columnCount(); aColumnId < aNbColumns; aColumnId++)
   {
-    TreeModel_HeaderSection aSection = aTreeModel->GetHeaderItem (aColumnId);
-    theTreeView->setColumnWidth (aColumnId, aSection.GetWidth());
-    theTreeView->setColumnHidden (aColumnId, aSection.IsHidden());
+    TreeModel_HeaderSection* aSection = aTreeModel->ChangeHeaderItem (aColumnId);
+    theTreeView->setColumnWidth (aColumnId, aSection->GetWidth());
+    theTreeView->setColumnHidden (aColumnId, aSection->IsHidden());
   }
 }
 
@@ -170,8 +171,10 @@ void TreeModel_Tools::UseVisibilityColumn (QTreeView* theTreeView, const bool th
   aHeader->moveSection (TreeModel_ColumnType_Name, TreeModel_ColumnType_Visibility);
 
   TreeModel_ModelBase* aModel = dynamic_cast<TreeModel_ModelBase*> (theTreeView->model());
-  aModel->SetHeaderItem (TreeModel_ColumnType_Visibility,
-    TreeModel_HeaderSection ("Visibility", TreeModel_ModelBase::ColumnVisibilityWidth()));
+  TreeModel_HeaderSection* anItem = aModel->ChangeHeaderItem ((int)TreeModel_ColumnType_Visibility);
+  anItem->SetIsHidden (theActive);
+  anItem->SetWidth (TreeModel_ModelBase::ColumnVisibilityWidth());
+
   aModel->SetUseVisibilityColumn (theActive);
 }
 
index 591ecb0661d4de1871ac655b98f15b45dc46a59d..3ac0a4e0223681da98223304c15c7874dd23e072 100644 (file)
@@ -43,7 +43,7 @@ QVariant VInspector_ItemBase::initValue (const int theItemRole) const
     case 3: return Standard_Dump::GetPointerInfo (Object(), true).ToCString();
   }
 
-  return QVariant();
+  return TreeModel_ItemBase::initValue (theItemRole);
 }
 
 // =======================================================================
index 4e35513625cb3fb928ee5909ac37b868c5d6da25..cfe70758d8451b2a048ea9e0a5ed2f337d296c2d 100644 (file)
@@ -51,11 +51,6 @@ public:
   //! \return the value
   Standard_EXPORT virtual QVariant initValue (const int theItemRole) const Standard_OVERRIDE;
 
-  //! Returns presentation of the attribute to be visualized in the view
-  //! \thePresentations [out] container of presentation handles to be visualized
-  virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations)
-  { (void)thePresentations; }
-
   //! Returns transform persistent of the item or NULL
   Handle(Graphic3d_TransformPers) TransformPersistence() const { return myTransformPersistence; }
 
index 28ea2399535ddb60096c370342f5add140e1d726..31df492fc618596430fef21264ac72251f1c74bd 100644 (file)
@@ -61,7 +61,7 @@ public:
 
   //! Returns presentation of the attribute to be visualized in the view
   //! \thePresentations [out] container of presentation handles to be visualized
-  Standard_EXPORT virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations);
+  Standard_EXPORT virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations) Standard_OVERRIDE;
 
 protected:
 
index 2ca792b334b158835662706cc562885cd7648344..894d0a3ba3087fa9c53402afa0fef4596cc05096 100644 (file)
@@ -43,8 +43,8 @@ void VInspector_ViewModel::InitColumns()
 {
   TreeModel_ModelBase::InitColumns();
 
-  SetHeaderItem (3, TreeModel_HeaderSection ("Pointer", COLUMN_POINTER_WIDTH));
-  SetHeaderItem (4, TreeModel_HeaderSection ("SelectedOwners", -1));
+  setHeaderItem (3, TreeModel_HeaderSection ("Pointer", COLUMN_POINTER_WIDTH));
+  setHeaderItem (4, TreeModel_HeaderSection ("SelectedOwners", -1));
 }
 
 // =======================================================================
index 980dc1e865890ff6dbfa76424b1c9dcce94b68a1..0b50eca7d8834aadcee893bf1824a82dd31900e8 100644 (file)
@@ -54,13 +54,13 @@ void VInspector_ViewModelHistory::InitColumns()
 {
   TreeModel_ModelBase::InitColumns();
 
-  SetHeaderItem (0, TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
-  SetHeaderItem (1, TreeModel_HeaderSection ("Visibility", COLUMN_SIZE_WIDTH)); // visualization item
-  SetHeaderItem (2, TreeModel_HeaderSection ("Size", COLUMN_SIZE_WIDTH));
-  SetHeaderItem (3, TreeModel_HeaderSection ("Pointer", COLUMN_POINTER_WIDTH));
-  SetHeaderItem (4, TreeModel_HeaderSection ("Shape type", COLUMN_SHAPE_TYPE_WIDTH));
-  SetHeaderItem (5, TreeModel_HeaderSection ("AIS Name", COLUMN_AIS_NAME_WIDTH));
-  SetHeaderItem (6, TreeModel_HeaderSection ("Selected/Highlighted", -1));
+  setHeaderItem (0, TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
+  setHeaderItem (1, TreeModel_HeaderSection ("Visibility", COLUMN_SIZE_WIDTH)); // visualization item
+  setHeaderItem (2, TreeModel_HeaderSection ("Size", COLUMN_SIZE_WIDTH));
+  setHeaderItem (3, TreeModel_HeaderSection ("Pointer", COLUMN_POINTER_WIDTH));
+  setHeaderItem (4, TreeModel_HeaderSection ("Shape type", COLUMN_SHAPE_TYPE_WIDTH));
+  setHeaderItem (5, TreeModel_HeaderSection ("AIS Name", COLUMN_AIS_NAME_WIDTH));
+  setHeaderItem (6, TreeModel_HeaderSection ("Selected/Highlighted", -1));
 
   for (int aColumnId = 0, aNbColumns = columnCount(); aColumnId < aNbColumns; aColumnId++)
   {
index 17fc850e6dd16e3e6ed5b49d4daa4256e5e1c732..163df690dd1c1d596f250aee31427b917fc17110 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <AIS_Shape.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
-#include <V3d_Viewer.hxx>
 
 #include <inspector/Convert_Tools.hxx>
 
@@ -49,7 +48,6 @@
 #include <inspector/View_PreviewParameters.hxx>
 #include <inspector/View_Widget.hxx>
 #include <inspector/View_Window.hxx>
-#include <inspector/View_Viewer.hxx>
 
 #include <Standard_WarningsDisable.hxx>
 #include <QApplication>
@@ -114,9 +112,8 @@ VInspector_Window::VInspector_Window()
   aTreeModel->InitColumns();
   myTreeView->setModel (aTreeModel);
   // hide Visibility column
-  TreeModel_HeaderSection anItem = aTreeModel->GetHeaderItem ((int)TreeModel_ColumnType_Visibility);
-  anItem.SetIsHidden (true);
-  aTreeModel->SetHeaderItem ((int)TreeModel_ColumnType_Visibility, anItem);
+  TreeModel_HeaderSection* anItem = aTreeModel->ChangeHeaderItem ((int)TreeModel_ColumnType_Visibility);
+  anItem->SetIsHidden (true);
 
   connect (myTreeView, SIGNAL(customContextMenuRequested(const QPoint&)),
            this, SLOT (onTreeViewContextMenuRequested(const QPoint&)));
@@ -159,12 +156,11 @@ VInspector_Window::VInspector_Window()
   connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
     this, SLOT (onHistoryViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
 
-  anItem = aHistoryModel->GetHeaderItem (0);
+  anItem = aHistoryModel->ChangeHeaderItem (0);
   // hide Visibility column
   TreeModel_Tools::UseVisibilityColumn (myHistoryView, false);
-  anItem = aHistoryModel->GetHeaderItem ((int)TreeModel_ColumnType_Visibility);
-  anItem.SetIsHidden (true);
-  aHistoryModel->SetHeaderItem ((int)TreeModel_ColumnType_Visibility, anItem);
+  anItem = aHistoryModel->ChangeHeaderItem ((int)TreeModel_ColumnType_Visibility);
+  anItem->SetIsHidden (true);
 
   QModelIndex aParentIndex = myHistoryView->model()->index (0, 0);
   myHistoryView->setExpanded (aParentIndex, true);
@@ -636,12 +632,12 @@ void VInspector_Window::onExportToShapeView()
 
   TCollection_AsciiString aPluginName ("TKShapeView");
   NCollection_List<Handle(Standard_Transient)> aParameters;
-  if (myParameters->FindParameters (aPluginName))
-    aParameters = myParameters->Parameters (aPluginName);
+  //if (myParameters->FindParameters (aPluginName))
+  //  aParameters = myParameters->Parameters (aPluginName);
 
   NCollection_List<TCollection_AsciiString> anItemNames;
-  if (myParameters->FindSelectedNames (aPluginName))
-    anItemNames = myParameters->GetSelectedNames (aPluginName);
+  //if (myParameters->FindSelectedNames (aPluginName))
+  //  anItemNames = myParameters->GetSelectedNames (aPluginName);
 
   QStringList anExportedPointers;
   if (aSelectedShapes.Extent() > 0)
@@ -661,23 +657,23 @@ void VInspector_Window::onExportToShapeView()
     }
   }
 
-  // search for objects to be exported
-  QList<TreeModel_ItemBasePtr> anItems = TreeModel_ModelBase::SelectedItems (myTreeView->selectionModel()->selectedIndexes());
-  for (QList<TreeModel_ItemBasePtr>::const_iterator anItemIt = anItems.begin(); anItemIt != anItems.end(); ++anItemIt)
-  {
-    TreeModel_ItemBasePtr anItem = *anItemIt;
-    VInspector_ItemBasePtr aVItem = itemDynamicCast<VInspector_ItemBase>(anItem);
-    if (!aVItem)
-    continue;
+  //// search for objects to be exported
+  //QList<TreeModel_ItemBasePtr> anItems = TreeModel_ModelBase::SelectedItems (myTreeView->selectionModel()->selectedIndexes());
+  //for (QList<TreeModel_ItemBasePtr>::const_iterator anItemIt = anItems.begin(); anItemIt != anItems.end(); ++anItemIt)
+  //{
+  //  TreeModel_ItemBasePtr anItem = *anItemIt;
+  //  VInspector_ItemBasePtr aVItem = itemDynamicCast<VInspector_ItemBase>(anItem);
+  //  if (!aVItem)
+  //  continue;
 
-    const Handle(Standard_Transient)& anObject = aVItem->Object();
-    if (anObject.IsNull())
-      continue;
+  //  const Handle(Standard_Transient)& anObject = aVItem->Object();
+  //  if (anObject.IsNull())
+  //    continue;
 
-    aParameters.Append (anObject);
-    anItemNames.Append (anObject->DynamicType()->Name());
-    anExportedPointers.append (Standard_Dump::GetPointerInfo (anObject, true).ToCString());
-  }
+  //  aParameters.Append (anObject);
+  //  anItemNames.Append (anObject->DynamicType()->Name());
+  //  anExportedPointers.append (Standard_Dump::GetPointerInfo (anObject, true).ToCString());
+  //}
 
   if (anExportedPointers.isEmpty())
     return;
@@ -894,7 +890,7 @@ Handle(AIS_InteractiveContext) VInspector_Window::createView()
   Handle(AIS_InteractiveContext) aContext = View_Viewer::CreateStandardViewer();
 
   myViewWindow = new View_Window (0, aContext, false /*for opening several BREP files*/, true);
-  myViewWindow->SetPredefinedSize (VINSPECTOR_DEFAULT_VIEW_WIDTH, VINSPECTOR_DEFAULT_VIEW_HEIGHT);
+  myViewWindow->ViewWidget()->SetPredefinedSize (VINSPECTOR_DEFAULT_VIEW_WIDTH, VINSPECTOR_DEFAULT_VIEW_HEIGHT);
   myViewWindow->move (VINSPECTOR_DEFAULT_VIEW_POSITION_X, VINSPECTOR_DEFAULT_VIEW_POSITION_Y);
   myViewWindow->show();
 
index d403f34bb9e6f7c4c1a1aa32502f89e0f2770b0e..89d2f9a795803b44bd4484f98cadf6a87865598f 100644 (file)
@@ -1,13 +1,18 @@
 <!DOCTYPE RCC><RCC version="1.0">
     <qresource>
+        <file>icons/cursor_rotate.png</file>
+        <file>icons/cursor_zoom.png</file>
         <file>icons/keep_view_off.png</file>
         <file>icons/keep_view_on.png</file>
         <file>icons/trihedron.png</file>
         <file>icons/view_clear.png</file>
-        <file>icons/view_cube.png</file>
         <file>icons/view_dm_shading.png</file>
         <file>icons/view_dm_wireframe.png</file>
         <file>icons/view_fitall.png</file>
+        <file>icons/view_fitarea.png</file>
+        <file>icons/view_pan.png</file>
+        <file>icons/view_rotate.png</file>
+        <file>icons/view_zoom.png</file>
     </qresource>
 </RCC>
 
index 82592275d70709aeb867e80ee3efa373c6e2061a..72c1c28ec738a30821a818d0bddb5a6d597d00e4 100644 (file)
@@ -20,7 +20,6 @@
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
 #include <AIS_Shape.hxx>
 #include <AIS_Trihedron.hxx>
-#include <AIS_ViewCube.hxx>
 #include <Geom_Axis2Placement.hxx>
 #include <Prs3d_PointAspect.hxx>
 #include <V3d_View.hxx>
@@ -231,28 +230,6 @@ void View_Displayer::DisplayDefaultTrihedron (const Standard_Boolean toDisplay,
     GetContext()->Erase (aTrihedron, theToUpdateViewer);
 }
 
-// =======================================================================
-// function : DisplayViewCube
-// purpose :
-// =======================================================================
-void View_Displayer::DisplayViewCube (const Standard_Boolean toDisplay, const bool theToUpdateViewer)
-{
-  if (myViewCube.IsNull() && toDisplay)
-  {
-    myViewCube = new AIS_ViewCube();
-    myViewCube->SetSize (35.0);
-    myViewCube->SetBoxColor (Quantity_NOC_GRAY50);
-  }
-
-  if (myViewCube.IsNull())
-    return;
-
-  if (toDisplay)
-    GetContext()->Display (myViewCube, theToUpdateViewer);
-  else
-    GetContext()->Erase (myViewCube, theToUpdateViewer);
-}
-
 // =======================================================================
 // function : SetVisible
 // purpose :
index 3ba29968d8a3e87b60bc260b1b4e1775209d0e0e..da1f029a46c11372f0b7b9c86aaa6204379de606 100644 (file)
@@ -28,7 +28,6 @@
 #include <inspector/View_DisplayActionType.hxx>
 
 class AIS_Trihedron;
-class AIS_ViewCube;
 class V3d_View;
 class View_DisplayPreview;
 
@@ -122,11 +121,6 @@ public:
   //! \param isToUpdateView boolean state if viewer should be updated
   Standard_EXPORT void DisplayDefaultTrihedron (const Standard_Boolean toDisplay, const bool theToUpdateViewer);
 
-  //! Displays presentation of view cube, create it by the first call
-  //! \param toDisplay flag to display presentation if true, or erase it
-  //! \param isToUpdateView boolean state if viewer should be updated
-  Standard_EXPORT void DisplayViewCube (const Standard_Boolean toDisplay, const bool theToUpdateViewer);
-
   //! Sets shape visible/invisible
   //! \theShape shape instance
   //! \theState visibility state
@@ -192,8 +186,7 @@ private:
   View_DisplayPreview* myDisplayPreview; //!< class for preview display
 
   Handle(AIS_InteractiveContext) myContext; //!< context, where the displayer works
-  Handle(AIS_Trihedron) myDefaultTrihedron; //!< trihedron presentation for the current context
-  Handle(AIS_ViewCube) myViewCube; //!< view cube presentation for current context
+  Handle(AIS_Trihedron) myDefaultTrihedron; //!< NULL presentation until the first display
 
   NCollection_DataMap<View_PresentationType, NCollection_Shared<AIS_ListOfInteractive>> myDisplayed; //!< visualized presentations
   NCollection_DataMap<View_PresentationType, Quantity_Color> myColorAttributes; //!< color properties of presentations
index b2b0d0d4cb89182aeb9cfb280342843cabe05db7..a518d2ba541e47e786fadb82a381d8b3eb5332f3 100644 (file)
@@ -22,8 +22,7 @@ enum View_ToolActionType
   View_ToolActionType_KeepViewId,    //!< Do not clear previously shown presentations
   View_ToolActionType_KeepViewOffId, //!< Do show only for new displayed presentation
   View_ToolActionType_ClearViewId,   //!< Erase all displayed presentations
-  View_ToolActionType_Trihedron,     //!< Display/Erase trihedron presentation
-  View_ToolActionType_ViewCube       //!< Display/Erase view cube presentation
+  View_ToolActionType_Trihedron      //!< Display/Erase trihedron presentation
 };
 
 #endif
index e23b402ee3ca2f4cb034e90c405dd1e3c39e522f..7887ebbed6f999214e98d8775322760af5d5d526 100644 (file)
@@ -69,13 +69,6 @@ View_ToolBar::View_ToolBar (QWidget* theParent, const bool isUseKeepView)
   myActionsMap[View_ToolActionType_Trihedron]->setCheckable (true);
   myActionsMap[View_ToolActionType_Trihedron]->setChecked (false);
 
-  myActionsMap[View_ToolActionType_ViewCube] = new QToolButton (theParent);
-  myActionsMap[View_ToolActionType_ViewCube]->setIcon (QIcon (":/icons/view_cube.png"));
-  myActionsMap[View_ToolActionType_ViewCube]->setToolTip (tr ("View Cube display"));
-  myActionsMap[View_ToolActionType_ViewCube]->setCheckable (true);
-  myActionsMap[View_ToolActionType_ViewCube]->setChecked (false);
-
-
   if (isUseKeepView)
   {
     myActionsMap[View_ToolActionType_KeepViewId] = new QToolButton (theParent);
index d970c3554dba7fc590fb185d919a75614725e61e..1f3288fa5f4caf953096cbf016b0be121f3991cc 100644 (file)
 //! Actions of view widget
 enum View_ViewActionType
 {
-  View_ViewActionType_FitAllId,     //!< fits the view to wrap the bounding box of displayed objects
+  View_ViewActionType_FitAllId,  //!< fits the view to wrap the bounding box of displayed objects
+  View_ViewActionType_FitAreaId, //!< zoom the view to the given area
+  View_ViewActionType_ZoomId,    //!< zoom in/out the view by some delta
+  View_ViewActionType_PanId,     //!< move position of the view camera
+  View_ViewActionType_RotationId, //!< rotate the view
   View_ViewActionType_DisplayModeId //!< change display mode of visualized presentations (to wireframe or shading)
 };
 
index e0c88e05a726856bda4f15ae5a26d91b21b313af..878b19f708739cf5dfbb29d119772a6615cb7d7a 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <inspector/View_Widget.hxx>
 
-#include <AIS_ViewController.hxx>
 #include <Geom_Axis2Placement.hxx>
 #include <Graphic3d_GraphicDriver.hxx>
 
 #include <Xw_Window.hxx>
 #endif
 
+// the key for multi selection :
+#define MULTISELECTIONKEY Qt::ShiftModifier
+// the key for shortcut (use to activate dynamic onRotate, panning)
+#define CASCADESHORTCUTKEY Qt::ControlModifier
+// for elastic bean selection
+#define ValZWMin 1
+
 // =======================================================================
 // function :  Constructor
 // purpose :
 View_Widget::View_Widget (QWidget* theParent,
                           const Handle(AIS_InteractiveContext)& theContext,
                           const bool isFitAllActive)
-: QWidget (theParent), myFirst (true), myDefaultWidth (-1),
-  myDefaultHeight (-1), myViewIsEnabled (true),
+: QWidget (theParent), myCurrentMode (View_CurrentAction3d_Nothing), myFirst (true), myDefaultWidth (-1),
+  myDefaultHeight (-1), myViewIsEnabled (true), myXmin (0), myYmin (0), myXmax (0), myYmax (0), myDragButtonDownX (0),
+  myDragButtonDownY (0), myDragMultiButtonDownX (0), myDragMultiButtonDownY (0), myIsRectVisible (false), myRectBand (0),
   myHasInitProj (Standard_False), myInitVx (0), myInitVy (0), myInitVz (0)
 {
   myViewer = new View_Viewer (View_Viewer::DefaultColor());
   if (!theContext.IsNull())
-  {
     myViewer->InitViewer (theContext);
-  }
   else
   {
     myViewer->InitViewer (myViewer->CreateStandardViewer());
   }
-  myController = new AIS_ViewController();
 
   setAttribute (Qt::WA_PaintOnScreen);
   setAttribute (Qt::WA_NoSystemBackground);
@@ -83,6 +87,7 @@ View_Widget::View_Widget (QWidget* theParent,
 
   initViewActions();
   ((View_ToolButton*)myFitAllAction)->SetButtonChecked (isFitAllActive);
+  initCursors();
 }
 
 // =======================================================================
@@ -199,7 +204,8 @@ void View_Widget::SetEnabledView (const bool theIsEnabled)
   if (myViewer->GetView())
     myViewer->GetView()->SetBackgroundColor (theIsEnabled ? View_Viewer::DefaultColor()
                                                           : View_Viewer::DisabledColor());
-  ViewAction (View_ViewActionType_DisplayModeId)->setEnabled (theIsEnabled);
+  for (int anActionId = View_ViewActionType_FitAreaId; anActionId <= View_ViewActionType_DisplayModeId; anActionId++)
+    ViewAction ((View_ViewActionType)anActionId)->setEnabled (theIsEnabled);
 }
 
 // =======================================================================
@@ -248,6 +254,53 @@ void View_Widget::onCheckedStateChanged (bool isOn)
     emit checkedStateChanged(View_ViewActionType_FitAllId, isOn);
 }
 
+// =======================================================================
+// function : OnUpdateToggled
+// purpose :
+// =======================================================================
+void View_Widget::OnUpdateToggled (bool isOn)
+{
+  QAction* aSentByAction = (QAction*)sender();
+
+  if (aSentByAction == myViewActions[View_ViewActionType_DisplayModeId])
+  {
+    aSentByAction->setIcon (isOn ? QIcon (":/icons/view_dm_wireframe.png")
+                          : QIcon (":/icons/view_dm_shading.png"));
+    return;
+  }
+
+  if (!isOn)
+    return;
+
+  for (int anActionId = View_ViewActionType_FitAreaId; anActionId <= View_ViewActionType_RotationId; anActionId++)
+  {
+    QAction* anAction = myViewActions[(View_ViewActionType)anActionId];
+    if ((anAction == myViewActions[View_ViewActionType_FitAreaId]) ||
+        (anAction == myViewActions[View_ViewActionType_ZoomId]) ||
+        (anAction == myViewActions[View_ViewActionType_PanId]) ||
+        (anAction == myViewActions[View_ViewActionType_RotationId]))
+    {
+      if (anAction && (anAction != aSentByAction))
+      {
+        anAction->setChecked (false);
+      }
+      else
+      {
+        if (aSentByAction == myViewActions[View_ViewActionType_FitAreaId])
+          setActiveCursor (View_CursorMode_HandCursor);
+        else if (aSentByAction == myViewActions[View_ViewActionType_ZoomId])
+          setActiveCursor (View_CursorMode_ZoomCursor);
+        else if (aSentByAction == myViewActions[View_ViewActionType_PanId])
+          setActiveCursor (View_CursorMode_PanCursor);
+        else if (aSentByAction == myViewActions[View_ViewActionType_RotationId])
+          setActiveCursor (View_CursorMode_RotationCursor);
+        else
+          setActiveCursor (View_CursorMode_DefaultCursor);
+      }
+    }
+  }
+}
+
 // =======================================================================
 // function : initViewActions
 // purpose :
@@ -262,8 +315,31 @@ void View_Widget::initViewActions()
   createAction (View_ViewActionType_FitAllId, ":/icons/view_fitall.png", tr ("Fit All"), SLOT (OnFitAll()));
   myFitAllAction->setDefaultAction (ViewAction (View_ViewActionType_FitAllId));
 
+  createAction (View_ViewActionType_FitAreaId, ":/icons/view_fitarea.png", tr ("Fit Area"), SLOT (OnFitArea()), true);
+  createAction (View_ViewActionType_ZoomId, ":/icons/view_zoom.png", tr ("Zoom"), SLOT (OnZoom()), true);
+  createAction (View_ViewActionType_PanId, ":/icons/view_pan.png", tr ("Pan"), SLOT (OnPan()), true);
+  createAction (View_ViewActionType_RotationId, ":/icons/view_rotate.png", tr ("Rotation"), SLOT (OnRotate()), true);
   createAction (View_ViewActionType_DisplayModeId, ":/icons/view_dm_shading.png", tr ("Display Mode"),
                 SIGNAL (displayModeClicked()), true);
+
+  for (int anActionId = View_ViewActionType_FitAreaId; anActionId <= View_ViewActionType_RotationId; anActionId++)
+    connect (myViewActions[(View_ViewActionType)anActionId], SIGNAL (toggled(bool)), this, SLOT (OnUpdateToggled(bool)));
+}
+
+// =======================================================================
+// function : initCursors
+// purpose :
+// =======================================================================
+void View_Widget::initCursors()
+{
+  if (!myCursors.empty())
+    return;
+
+  myCursors[View_CursorMode_DefaultCursor] = QCursor (Qt::ArrowCursor);
+  myCursors[View_CursorMode_HandCursor] = QCursor (Qt::PointingHandCursor);
+  myCursors[View_CursorMode_PanCursor] = QCursor (Qt::SizeAllCursor);
+  myCursors[View_CursorMode_ZoomCursor] = QCursor(QIcon (":/icons/cursor_zoom.png").pixmap (20, 20));
+  myCursors[View_CursorMode_RotationCursor] = QCursor(QIcon (":/icons/cursor_rotate.png").pixmap (20, 20));
 }
 
 // =======================================================================
@@ -272,13 +348,12 @@ void View_Widget::initViewActions()
 // =======================================================================
 void View_Widget::mousePressEvent (QMouseEvent* theEvent)
 {
-  if (myController->PressMouseButton (Graphic3d_Vec2i (theEvent->x(), theEvent->y()),
-                                      keyMouse (theEvent->button()),
-                                      keyFlag (theEvent->modifiers()),
-                                      Standard_False))
-  {
-    myController->FlushViewEvents (myViewer->GetContext(), myViewer->GetView(), Standard_True);
-  }
+  if (theEvent->button() == Qt::LeftButton)
+    processLeftButtonDown (theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
+  else if (theEvent->button() == Qt::MidButton)
+    processMiddleButtonDown (theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
+  else if (theEvent->button() == Qt::RightButton)
+    processRightButtonDown (theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
 }
 
 // =======================================================================
@@ -287,13 +362,12 @@ void View_Widget::mousePressEvent (QMouseEvent* theEvent)
 // =======================================================================
 void View_Widget::mouseReleaseEvent (QMouseEvent* theEvent)
 {
-  if (myController->ReleaseMouseButton (Graphic3d_Vec2i (theEvent->x(), theEvent->y()),
-                                        keyMouse (theEvent->button()),
-                                        keyFlag (theEvent->modifiers()),
-                                        Standard_False))
-  {
-    myController->FlushViewEvents (myViewer->GetContext(), myViewer->GetView(), Standard_True);
-  }
+  if (theEvent->button() == Qt::LeftButton)
+    processLeftButtonUp (theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
+  else if (theEvent->button() == Qt::MidButton)
+    processMiddleButtonUp (theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
+  else if (theEvent->button() == Qt::RightButton)
+    processRightButtonUp (theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
 }
 
 // =======================================================================
@@ -302,11 +376,411 @@ void View_Widget::mouseReleaseEvent (QMouseEvent* theEvent)
 // =======================================================================
 void View_Widget::mouseMoveEvent (QMouseEvent* theEvent)
 {
-  myController->UpdateMousePosition (Graphic3d_Vec2i (theEvent->x(), theEvent->y()),
-                                     keyMouse (theEvent->button()),
-                                     keyFlag (theEvent->modifiers()), Standard_False);
+  processMouseMove (theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
+}
+
+// =======================================================================
+// function : activateCursor
+// purpose :
+// =======================================================================
+void View_Widget::activateCursor (const View_CurrentAction3d theMode)
+{
+  switch (theMode)
+  {
+    case View_CurrentAction3d_DynamicPanning:
+    {
+      setActiveCursor (View_CursorMode_PanCursor);
+      break;
+    }
+    case View_CurrentAction3d_DynamicZooming:
+    {
+      setActiveCursor (View_CursorMode_ZoomCursor);
+      break;
+    }
+    case View_CurrentAction3d_DynamicRotation:
+    {
+      setActiveCursor (View_CursorMode_RotationCursor);
+      break;
+    }
+    case View_CurrentAction3d_WindowZooming:
+    {
+      setActiveCursor (View_CursorMode_HandCursor);
+      break;
+    }
+    case View_CurrentAction3d_Nothing:
+    default:
+    {
+      setActiveCursor (View_CursorMode_DefaultCursor);
+      break;
+    }
+  }
+}
+
+// =======================================================================
+// function : processLeftButtonDown
+// purpose :
+// =======================================================================
+void View_Widget::processLeftButtonDown (const int theFlags, const QPoint thePoint)
+{
+  //  save the current mouse coordinate in min
+  myXmin = thePoint.x();
+  myYmin = thePoint.y();
+  myXmax = thePoint.x();
+  myYmax = thePoint.y();
+
+  if (theFlags & CASCADESHORTCUTKEY)
+  {
+    myCurrentMode = View_CurrentAction3d_DynamicZooming;
+    OnUpdateToggled(true);
+  }
+  else
+  {
+    switch (myCurrentMode)
+    {
+      case View_CurrentAction3d_Nothing:
+      {
+        if (theFlags & MULTISELECTIONKEY)
+          processDragMultiEvent (myXmax, myYmax, View_DragMode_ButtonDown);
+        else
+          processDragEvent (myXmax, myYmax, View_DragMode_ButtonDown);
+        break;
+      }
+      case View_CurrentAction3d_DynamicZooming:
+      case View_CurrentAction3d_WindowZooming:
+      case View_CurrentAction3d_DynamicPanning:
+        break;
+      case View_CurrentAction3d_DynamicRotation:
+      {
+        myViewer->GetView()->StartRotation (thePoint.x(), thePoint.y());
+        break;
+      }
+      default:
+      {
+        throw Standard_ProgramError ("View_Widget::processLeftButtonDown : Incompatible Current Mode");
+        break;
+      }
+    }
+  }
+  activateCursor (myCurrentMode);
+  emit leftButtonDown(thePoint.x(), thePoint.y());
+}
+
+// =======================================================================
+// function : processMiddleButtonDown
+// purpose :
+// =======================================================================
+void View_Widget::processMiddleButtonDown (const int theFlags, const QPoint /*thePoint*/)
+{
+  if (theFlags & CASCADESHORTCUTKEY) {
+    myCurrentMode = View_CurrentAction3d_DynamicPanning;
+    OnUpdateToggled(true);
+  }
+  activateCursor (myCurrentMode);
+}
+
+// =======================================================================
+// function : processRightButtonDown
+// purpose :
+// =======================================================================
+void View_Widget::processRightButtonDown (const int theFlags, const QPoint thePoint)
+{
+  if (theFlags & CASCADESHORTCUTKEY)
+  {
+    myCurrentMode = View_CurrentAction3d_DynamicRotation;
+    myViewer->GetView()->StartRotation (thePoint.x(), thePoint.y());
+    OnUpdateToggled(true);
+  }
+  else
+  {
+    popup (thePoint.x(), thePoint.y());
+  }
+  activateCursor (myCurrentMode);
+}
+
+// =======================================================================
+// function : processLeftButtonUp
+// purpose :
+// =======================================================================
+void View_Widget::processLeftButtonUp (const int theFlags, const QPoint thePoint)
+{
+  switch (myCurrentMode)
+  {
+    case View_CurrentAction3d_Nothing:
+    {
+      if (thePoint.x() == myXmin && thePoint.y() == myYmin)
+      {
+        // no offset between down and up --> selectEvent
+        myXmax = thePoint.x();
+        myYmax = thePoint.y();
+        if (theFlags & MULTISELECTIONKEY)
+          processInputMultiEvent (thePoint.x(), thePoint.y());
+        else
+          processInputEvent (thePoint.x(), thePoint.y());
+      }
+      else
+      {
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, Standard_False);
+        myXmax = thePoint.x();
+        myYmax = thePoint.y();
+        if (theFlags & MULTISELECTIONKEY)
+          processDragMultiEvent (thePoint.x(), thePoint.y(), View_DragMode_ButtonUp);
+        else
+          processDragEvent (thePoint.x(), thePoint.y(), View_DragMode_ButtonUp);
+      }
+      break;
+    }
+    case View_CurrentAction3d_DynamicZooming:
+    break;
+    case View_CurrentAction3d_WindowZooming:
+    {
+      drawRectangle (myXmin, myYmin, myXmax, myYmax, Standard_False);
+      myXmax = thePoint.x();
+      myYmax = thePoint.y();
+      if ((abs(myXmin - myXmax) > ValZWMin) ||
+          (abs(myYmin - myYmax) > ValZWMin))
+        myViewer->GetView()->WindowFitAll (myXmin, myYmin, myXmax, myYmax);
+      break;
+    }
+    case View_CurrentAction3d_DynamicPanning:
+    break;
+    case View_CurrentAction3d_DynamicRotation:
+    break;
+    default:
+    {
+      throw Standard_ProgramError("View_Widget::processLeftButtonUp : Incompatible Current Mode");
+      break;
+    }
+  }
+  myDragButtonDownX = 0;
+  myDragButtonDownY = 0;
+  myDragMultiButtonDownX = 0;
+  myDragMultiButtonDownY = 0;
+
+  emit selectionChanged();
+  emit leftButtonUp(thePoint.x(), thePoint.y());
+}
+
+// =======================================================================
+// function : processMiddleButtonUp
+// purpose :
+// =======================================================================
+void View_Widget::processMiddleButtonUp (const int /*theFlags*/, const QPoint /*thePoint*/)
+{
+  myCurrentMode = View_CurrentAction3d_Nothing;
+  activateCursor (myCurrentMode);
+}
+
+// =======================================================================
+// function : processRightButtonUp
+// purpose :
+// =======================================================================
+void View_Widget::processRightButtonUp (const int /*theFlags*/, const QPoint thePoint)
+{
+  if (myCurrentMode == View_CurrentAction3d_Nothing)
+  {
+    popup (thePoint.x(), thePoint.y());
+  }
+  else
+    myCurrentMode = View_CurrentAction3d_Nothing;
+  activateCursor (myCurrentMode);
+}
+
+// =======================================================================
+// function : processMouseMove
+// purpose :
+// =======================================================================
+void View_Widget::processMouseMove (const int theFlags, const QPoint thePoint)
+{
+  if (theFlags & Qt::LeftButton || theFlags & Qt::RightButton || theFlags & Qt::MidButton)
+  {
+    switch (myCurrentMode)
+    {
+      case View_CurrentAction3d_Nothing:
+      {
+        myXmax = thePoint.x();
+        myYmax = thePoint.y();
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, Standard_False);
+        if (theFlags & MULTISELECTIONKEY)
+          processDragMultiEvent (myXmax, myYmax, View_DragMode_ButtonMove);
+        else
+          processDragEvent (myXmax, myYmax, View_DragMode_ButtonMove);
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, Standard_True);
+        break;
+      }
+      case View_CurrentAction3d_DynamicZooming:
+      {
+        myViewer->GetView()->Zoom (myXmax, myYmax, thePoint.x(), thePoint.y());
+        myXmax = thePoint.x();
+        myYmax = thePoint.y();
+        break;
+      }
+      case View_CurrentAction3d_WindowZooming:
+      {
+        myXmax = thePoint.x();
+        myYmax = thePoint.y();
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, Standard_False);
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, Standard_True);
+        break;
+      }
+      case View_CurrentAction3d_DynamicPanning:
+      {
+        myViewer->GetView()->Pan (thePoint.x() - myXmax, myYmax - thePoint.y());
+        myXmax = thePoint.x();
+        myYmax = thePoint.y();
+        break;
+      }
+      case View_CurrentAction3d_DynamicRotation:
+      {
+        myViewer->GetView()->Rotation (thePoint.x(), thePoint.y());
+        myViewer->GetView()->Redraw();
+        break;
+      }
+      default:
+      {
+        throw Standard_ProgramError("View_Widget::processMouseMove : Incompatible Current Mode");
+        break;
+      }
+    }
+  }
+  else
+  {
+    myXmax = thePoint.x();
+    myYmax = thePoint.y();
+    if (theFlags & MULTISELECTIONKEY)
+      processMoveMultiEvent (thePoint.x(), thePoint.y());
+     else
+      processMoveEvent (thePoint.x(), thePoint.y());
+  }
+  emit moveTo (thePoint.x(), thePoint.y());
+}
+
+// =======================================================================
+// function : processDragEvent
+// purpose :
+// =======================================================================
+void View_Widget::processDragEvent (const Standard_Integer theX, const Standard_Integer theY, const View_DragMode& theState)
+{
+  //myDragButtonDownX = 0;
+  //myDragButtonDownY = 0;
 
-  myController->FlushViewEvents (myViewer->GetContext(), myViewer->GetView(), Standard_True);
+  switch (theState)
+  {
+    case View_DragMode_ButtonDown:
+    {
+      myDragButtonDownX = theX;
+      myDragButtonDownY = theY;
+      break;
+    }
+    case View_DragMode_ButtonMove:
+    break;
+    case View_DragMode_ButtonUp:
+    {
+      myViewer->GetContext()->Select (myDragButtonDownX, myDragButtonDownY, theX, theY, myViewer->GetView(), Standard_True);
+      emit selectionChanged();
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+// =======================================================================
+// function : processInputEvent
+// purpose :
+// =======================================================================
+void View_Widget::processInputEvent (const Standard_Integer/* theX*/, const Standard_Integer/* theY*/)
+{
+  myViewer->GetContext()->Select (Standard_True);
+  emit selectionChanged();
+}
+
+// =======================================================================
+// function : processMoveEvent
+// purpose :
+// =======================================================================
+void View_Widget::processMoveEvent (const Standard_Integer theX, const Standard_Integer theY)
+{
+  if (myViewer->GetView())
+    myViewer->GetContext()->MoveTo (theX, theY, myViewer->GetView(), Standard_True);
+}
+
+// =======================================================================
+// function : processDragMultiEvent
+// purpose :
+// =======================================================================
+void View_Widget::processDragMultiEvent (const Standard_Integer theX, const Standard_Integer theY,
+                                         const View_DragMode& theState)
+{
+  switch (theState)
+  {
+    case View_DragMode_ButtonDown:
+    {
+      myDragMultiButtonDownX = theX;
+      myDragMultiButtonDownY = theY;
+      break;
+    }
+    case View_DragMode_ButtonMove:
+    {
+      myViewer->GetContext()->ShiftSelect (myDragMultiButtonDownX, myDragMultiButtonDownY, theX, theY,
+                                           myViewer->GetView(), Standard_True);
+      emit selectionChanged();
+      break;
+    }
+    case View_DragMode_ButtonUp:
+    default:
+      break;
+  }
+}
+
+// =======================================================================
+// function : processInputMultiEvent
+// purpose :
+// =======================================================================
+void View_Widget::processInputMultiEvent (const Standard_Integer /*theX*/, const Standard_Integer /*theY*/)
+{
+  myViewer->GetContext()->ShiftSelect (Standard_True);
+  emit selectionChanged();
+}
+
+// =======================================================================
+// function : drawRectangle
+// purpose :
+// =======================================================================
+void View_Widget::drawRectangle (const Standard_Integer theMinX, const Standard_Integer MinY,
+                                 const Standard_Integer MaxX, const Standard_Integer MaxY,
+                                 const Standard_Boolean theToDraw)
+{
+  Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
+
+  StoredMinX = (theMinX < MaxX) ? theMinX : MaxX;
+  StoredMinY = (MinY < MaxY) ? MinY : MaxY;
+  StoredMaxX = (theMinX > MaxX) ? theMinX : MaxX;
+  StoredMaxY = (MinY > MaxY) ? MinY : MaxY;
+
+  QRect aRect;
+  aRect.setRect(StoredMinX, StoredMinY, abs (StoredMaxX-StoredMinX), abs (StoredMaxY-StoredMinY));
+
+  if (!myRectBand) 
+  {
+    myRectBand = new QRubberBand (QRubberBand::Rectangle, this);
+    myRectBand->setStyle (QStyleFactory::create ("windows"));
+    myRectBand->setGeometry (aRect);
+    myRectBand->show();
+  }
+
+  if (myIsRectVisible && !theToDraw) // move or up  : erase at the old position
+  {
+    myRectBand->hide();
+    delete myRectBand;
+    myRectBand = 0;
+    myIsRectVisible = false;
+  }
+
+  if (theToDraw) // move : draw
+  {
+    myIsRectVisible = true;
+    myRectBand->setGeometry (aRect);
+  }
 }
 
 // =======================================================================
@@ -327,34 +801,11 @@ void View_Widget::createAction (const View_ViewActionType theActionId, const QSt
 }
 
 // =======================================================================
-// function : keyFlag
+// function : setActiveCursor
 // purpose :
 // =======================================================================
-Aspect_VKeyFlags View_Widget::keyFlag (const int theModifierId)
+void View_Widget::setActiveCursor (const View_CursorMode& theMode)
 {
-  switch (theModifierId)
-  {
-    case Qt::NoModifier:      return Aspect_VKeyFlags_NONE;
-    case Qt::ShiftModifier:   return Aspect_VKeyFlags_SHIFT;
-    case Qt::ControlModifier: return Aspect_VKeyFlags_CTRL;
-    default: break;
-  }
-  return Aspect_VKeyFlags_NONE;
-}
-
-// =======================================================================
-// function : keyMouse
-// purpose :
-// =======================================================================
-Aspect_VKeyMouse View_Widget::keyMouse (const int theButtonId)
-{
-  switch (theButtonId)
-  {
-    case Qt::NoButton:    return Aspect_VKeyMouse_NONE;
-    case Qt::LeftButton:  return Aspect_VKeyMouse_LeftButton;
-    case Qt::RightButton: return Aspect_VKeyMouse_RightButton;
-    case Qt::MidButton:   return Aspect_VKeyMouse_MiddleButton;
-    default: break;
-  }
-  return Aspect_VKeyMouse_NONE;
+  QCursor aCursor = myCursors[theMode];
+  setCursor (myCursors[theMode]);
 }
index b882f32619070f273ff6cd59d4bca929735c8081..3fd7fdb069cfe32dd1505de6fcfc7811e0e9e06c 100644 (file)
@@ -17,8 +17,6 @@
 #define View_View_H
 
 #include <AIS_InteractiveContext.hxx>
-#include <AIS_ViewController.hxx>
-#include <Aspect_VKeyFlags.hxx>
 #include <V3d_View.hxx>
 #include <inspector/View_ViewActionType.hxx>
 #include <inspector/View_Viewer.hxx>
@@ -33,6 +31,8 @@
 
 class View_Viewer;
 
+class QRubberBand;
+
 //! \class View_Widget
 //! \brief It is a Qt control that visualizes content of OCCT 3D view
 //! It creates control and actions of manipulating of this view,
@@ -41,8 +41,38 @@ class View_Viewer;
 class View_Widget : public QWidget
 {
   Q_OBJECT
+protected:
+
+  //! Enumeration defines manipulating actions of the widget
+  enum View_CurrentAction3d
+  {
+    View_CurrentAction3d_Nothing, //!< Empty action
+    View_CurrentAction3d_DynamicZooming, //!< Zoom action
+    View_CurrentAction3d_WindowZooming, //!< Zoom action using rectangle
+    View_CurrentAction3d_DynamicPanning, //!< Panning action
+    View_CurrentAction3d_DynamicRotation //!< Rotation action
+  };
+
+  //! Enumeration defines cursor kind
+  enum View_CursorMode
+  {
+    View_CursorMode_DefaultCursor, //!< default Qt cursor
+    View_CursorMode_HandCursor, //!< hand cursor
+    View_CursorMode_PanCursor, //!< panning cursor
+    View_CursorMode_ZoomCursor, //!< zoom cursor
+    View_CursorMode_RotationCursor //!< onRotate cursor
+  };
+
+  //! Enumeration defines drag mode
+  enum View_DragMode
+  {
+    View_DragMode_ButtonDown, //!< theState == -1  button down
+    View_DragMode_ButtonMove, //!< theState ==  0  move
+    View_DragMode_ButtonUp //< theState ==  1  button up
+  };
 
 public:
+
   //! Constructor
   Standard_EXPORT View_Widget (QWidget* theParent,
                                const Handle(AIS_InteractiveContext)& theContext,
@@ -124,6 +154,21 @@ signals:
   //! Sends a signal about selection change if the left mouse button is pressed and current action does not process it
   void selectionChanged();
 
+  //! Sends a signal about moving to the point in the view
+  //! \param theX X mouse position in pixels
+  //! \param theY Y mouse position in pixels
+  void  moveTo (const int theX, const int theY);
+
+  //! Sends a signal about up the left mouse button down
+  //! \param theX X mouse position in pixels
+  //! \param theY Y mouse position in pixels
+  void leftButtonDown (const int theX, const int theY);
+
+  //! Sends a signal about up the left mouse button up
+  //! \param theX X mouse position in pixels
+  //! \param theY Y mouse position in pixels
+  void leftButtonUp (const int theX, const int theY);
+
   //! Sends a signal about display mode change
   void displayModeClicked();
 
@@ -137,11 +182,29 @@ public slots:
   //! Fits all the V3d view and redraw view
   void OnFitAll() { myViewer->GetView()->FitAll(); }
 
+  //! Stores state about fitting all to use it by the mouse move
+  void OnFitArea() { myCurrentMode = View_CurrentAction3d_WindowZooming; }
+
+  //! Stores state about zoom to use it by the mouse move
+  void OnZoom() { myCurrentMode = View_CurrentAction3d_DynamicZooming; }
+
+  //! Stores state about pan to use it by the mouse move
+  void OnPan() { myCurrentMode = View_CurrentAction3d_DynamicPanning; }
+
+  //! Stores state about onRotate to use it by the mouse move
+  void OnRotate() { myCurrentMode = View_CurrentAction3d_DynamicRotation; }
+
   //! Updates states of widget actions
   //! 
   //! - if the state is checked, uncheck all other actions
   Standard_EXPORT void onCheckedStateChanged (bool isOn);
 
+  //! Updates states of tool actions:
+  //! - if the action is display mode, it changes an icon for action(wireframe or shading)
+  //! - if the state is checked, uncheck all other actions
+  //! \param isOn boolean value about check
+  Standard_EXPORT void OnUpdateToggled (bool isOn);
+
 protected:
 
   //! Avoids Qt standard execution of this method, redraw V3d view
@@ -169,11 +232,99 @@ protected:
   //! Creates view actions and fills an internal map
   void initViewActions();
 
+  //! Creates cursors and fills an internal map
+  void initCursors();
+
+  //! Sets widget cursor by the action type
+  //! \param theMode an active action mode
+  void activateCursor (const View_CurrentAction3d theMode);
+
+  //! Activates cursor of the active operation, perform drag, onRotate depending on mode,
+  //! stores the point position in xmin/xmax and ymin/ymax
+  //! \param theFlags an event buttons and modifiers
+  //! \param thePoint a clicked point
+  void processLeftButtonDown (const int theFlags, const QPoint thePoint);
+
+  //! Activates cursor of the active operation and performs dynamic pan if it is active
+  //! \param theFlags an event buttons and modifiers
+  //! \param thePoint a clicked point
+  void processMiddleButtonDown (const int theFlags, const QPoint thePoint);
+
+  //! Activates cursor of the active operation, build popup menu
+  //! \param theFlags an event buttons and modifiers
+  //! \param thePoint a clicked point
+  void processRightButtonDown (const int theFlags, const QPoint thePoint);
+
+  //! Performs the active operation or performs Input/Drag event processing, emits selection changed signal
+  //! \param theFlags an event buttons and modifiers
+  //! \param thePoint a clicked point
+  void processLeftButtonUp (const int  theFlags, const QPoint thePoint);
+
+  //! Changes the active operation to None
+  //! \param theFlags an event buttons and modifiers
+  //! \param thePoint a clicked point
+  void processMiddleButtonUp (const int  theFlags, const QPoint thePoint);
+
+  //! Calls popup menu build and changes the active operation to None
+  //! \param theFlags an event buttons and modifiers
+  //! \param thePoint a clicked point
+  void processRightButtonUp (const int  theFlags, const QPoint thePoint);
+
+  //! Performs active operation or draws rectangle of zoom
+  //! \param theFlags an event buttons and modifiers
+  //! \param thePoint a clicked point
+  void processMouseMove (const int  theFlags, const QPoint thePoint);
+
+  //! Performs selection: store clicked point by botton down, call Select by button up
+  //! Emits signal about selection changed
+  //! \param theX a horizontal position of mouse event
+  //! \param theX a vertical position of mouse event
+  //! \param theState a mouse button state: down, move or up
+  void processDragEvent (const Standard_Integer theX, const Standard_Integer theY, const View_DragMode& theState);
+
+  //! Performs selection in context without parameter, it means the selection of picked object
+  //! \param theX a horizontal position of mouse event
+  //! \param theX a vertical position of mouse event
+  void processInputEvent (const Standard_Integer theX, const Standard_Integer theY);
+
+  //! Calls MoveTo of the context for the parameter coordinates
+  //! \param theX a horizontal position of mouse event
+  //! \param theX a vertical position of mouse event
+  void processMoveEvent (const Standard_Integer theX, const Standard_Integer theY);
+
+  //! Empty: template to process mouse move with multi selection key pressed
+  //! \param theX a horizontal position of mouse event
+  //! \param theX a vertical position of mouse event
+  void processMoveMultiEvent (const Standard_Integer theX, const Standard_Integer theY)
+  { (void)theX; (void)theY; }
+
+  //! Performs selection: store clicked point by botton down, call ShiftSelect by button move
+  //! Emits signal about selection changed
+  //! \param theX a horizontal position of mouse event
+  //! \param theX a vertical position of mouse event
+  //! \param theState a mouse button state: down, move or up
+  void processDragMultiEvent (const Standard_Integer theX, const Standard_Integer theY, const View_DragMode& theState);
+
+  //! Performs shift selection in context without parameter, it means the selection of picked object
+  //! \param theX a horizontal position of mouse event
+  //! \param theX a vertical position of mouse event
+  void processInputMultiEvent (const Standard_Integer theX, const Standard_Integer theY);
+
   //! Empty: template to create popup menu
   //! \param theX a horizontal position of mouse event
   //! \param theX a vertical position of mouse event
   void popup (const Standard_Integer theX, const Standard_Integer theY) { (void)theX; (void)theY; }
 
+  //! Draws Qt rectangle for the given area (e.g. for panning operation)
+  //! \param theMinX a minimal X coordinate
+  //! \param theMinY a minimal Y coordinate
+  //! \param theMinZ a minimal Z coordinate
+  //! \param theMaxX a maximum X coordinate
+  //! \param theMaxY a maximum Y coordinate
+  //! \param theMaxZ a maximum Z coordinate
+  //! \param theToDraw state whether the rectangle should be visualized or hidden
+  void drawRectangle (const Standard_Integer theMinX, const Standard_Integer theMinY, const Standard_Integer theMaxX,
+                      const Standard_Integer theMaxY, const Standard_Boolean theToDraw);
 private:
   //! Creates action and stores it in a map of actions
   //! \param theActionId an identifier of action in internal map
@@ -185,32 +336,38 @@ private:
                      const char* theSlot, const bool isCheckable = false,
                      const QString& theToolBar = QString(), const QString& theStatusBar = QString());
 
-private:
-  //! Converts Qt modifier key to Aspect key flag
-  //! \param theModifierId the event modifier
-  static Aspect_VKeyFlags keyFlag (const int theModifierId);
-
-  //! Converts Qt button key to Aspect key mouse
-  //! \param theButtonId the event button
-  static Aspect_VKeyMouse keyMouse (const int theButtonId);
+  //! Sets active action cursor for application
+  //! \param theMode a cursor mode
+  void setActiveCursor (const View_CursorMode& theMode);
 
 private:
 
   View_Viewer* myViewer; //!< connector to context, V3d viewer and V3d View
-  AIS_ViewController* myController; //!< controller to process view actions
-
   QToolButton* myFitAllAction; //!< widget for fit all, processed double click to perform action automatically
   QMap<View_ViewActionType, QAction*> myViewActions; //!< tool bar view actions
+  QMap<View_CursorMode, QCursor> myCursors; //!< possible cursors for view actions
 
+  View_CurrentAction3d myCurrentMode; //!< an active action mode for viewer
   Standard_Boolean myFirst; //!< flag to Init view by the first resize/paint call
   Standard_Integer myDefaultWidth; //!< default width for the first sizeHint
   Standard_Integer myDefaultHeight; //!< default height for the first sizeHint
   Standard_Boolean myViewIsEnabled; //!< flag if the view and tool bar view actions are enabled/disabled
+  Standard_Integer myXmin; //!< cached X minimal position by mouse press event
+  Standard_Integer myYmin; //!< cached Y minimal position by mouse press event
+  Standard_Integer myXmax; //!< cached X maximum position by mouse press event
+  Standard_Integer myYmax; //!< cached Y maximum position by mouse press event
+  Standard_Integer myDragButtonDownX; //!< cached X button down by drag event
+  Standard_Integer myDragButtonDownY; //!< cached Y button down by drag event
+  Standard_Integer myDragMultiButtonDownX; //!< cached X button down by multi drag event
+  Standard_Integer myDragMultiButtonDownY; //!< cached Y button down by multi drag event
+  Standard_Boolean myIsRectVisible; //!< true if rectangle is visible now
+  QRubberBand* myRectBand; //!< selection rectangle rubber band
 
   Standard_Boolean myHasInitProj; //!< is initial camera position defined
   Standard_Real myInitVx; //!< initial camera position on X
   Standard_Real myInitVy; //!< initial camera position on Y
   Standard_Real myInitVz; //!< initial camera position on Z
+
 };
 
 #endif
index beb4cda431b7019627d0a2933bb5456413e55951..f47cbeb9c2d9722cb183f2ebd27043af18f274b9 100644 (file)
@@ -69,7 +69,8 @@ View_Window::View_Window (QWidget* theParent,
   myActionsToolBar->setOrientation (Qt::Vertical);
 
   myActionsToolBar->addWidget (myView-> GetWidget (View_ViewActionType_FitAllId));
-  myActionsToolBar->addAction (myView->ViewAction (View_ViewActionType_DisplayModeId));
+  for (int anActionId = View_ViewActionType_FitAreaId; anActionId <= View_ViewActionType_DisplayModeId; anActionId++)
+    myActionsToolBar->addAction (myView->ViewAction ((View_ViewActionType)anActionId));
 
   aViewLayout->addWidget (myActionsToolBar, 1, 0);
   aViewLayout->addWidget (myView, 1, 1);
@@ -95,33 +96,6 @@ void View_Window::SetContext (View_ContextType /*theType*/, const Handle(AIS_Int
   ViewToolBar()->SetContext (View_ContextType_External, theContext);
 }
 
-// =======================================================================
-// function : SetPredefinedSize
-// purpose :
-// =======================================================================
-void View_Window::SetPredefinedSize (int theDefaultWidth, int theDefaultHeight)
-{
-  myView->SetPredefinedSize (theDefaultWidth, theDefaultHeight);
-}
-
-// =======================================================================
-// function : SetInitProj
-// purpose :
-// =======================================================================
-void View_Window::SetInitProj (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
-{
-  myView->SetInitProj (theVx, theVy, theVz);
-}
-
-// =======================================================================
-// function : View
-// purpose :
-// =======================================================================
-Handle(V3d_View) View_Window::View() const
-{
-  return myView->GetViewer()->GetView();
-}
-
 // =======================================================================
 // function : SaveState
 // purpose :
@@ -131,7 +105,7 @@ void View_Window::SaveState (View_Window* theView, QMap<QString, QString>& theIt
 {
   QStringList aCameraDirection;
   Standard_Real aVX, aVY, aVZ;
-  Handle(V3d_View) aView = theView->View();
+  Handle(V3d_View) aView = theView->ViewWidget()->GetViewer()->GetView();
   if (aView.IsNull())
     return;
 
@@ -161,7 +135,7 @@ bool View_Window::RestoreState (View_Window* theView, const QString& theKey, con
       Standard_Real aVY = aValues.at (1).toDouble();
       Standard_Real aVZ = aValues.at (2).toDouble();
 
-      theView->SetInitProj (aVX, aVY, aVZ);
+      theView->ViewWidget()->SetInitProj (aVX, aVY, aVZ);
     }
     return true;
   }
@@ -222,12 +196,6 @@ void View_Window::onToolBarActionClicked (const int theActionId)
       myDisplayer->DisplayDefaultTrihedron (myViewToolBar->IsActionChecked (theActionId), Standard_True);
       break;
     }
-    case View_ToolActionType_ViewCube:
-    {
-      myDisplayer->DisplayViewCube (myViewToolBar->IsActionChecked (theActionId), Standard_True);
-      break;
-    }
-
     case View_ToolActionType_KeepViewId:
     {
       myDisplayer->KeepPresentations (myViewToolBar->IsActionChecked (theActionId));
index 8d85646fbc9f0ebabe4a75aacbb7d5d72d84514c..b270f816d339ac0c92567dc45b689867d050f1b7 100644 (file)
@@ -64,18 +64,6 @@ public:
   //! \param theContext an AIS context
   Standard_EXPORT void SetContext (View_ContextType theType, const Handle(AIS_InteractiveContext)& theContext);
 
-  //! Sets default size that is used in sizeHint when the widget is firstly show
-  Standard_EXPORT void SetPredefinedSize (int theDefaultWidth, int theDefaultHeight);
-
-  //! Sets initial camera position
-  //! \param theVx direction on Ox
-  //! \param theVy direction on Oy
-  //! \param theVz direction on Oz
-  Standard_EXPORT void SetInitProj (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz);
-
-  //! Returns an active view
-  Standard_EXPORT Handle(V3d_View) View() const;
-
   //! Saves state of view window in a container in form: key, value. It saves:
   //! - visibility of columns,
   //! - columns width
diff --git a/tools/View/icons/cursor_rotate.png b/tools/View/icons/cursor_rotate.png
new file mode 100644 (file)
index 0000000..a3cb0c1
Binary files /dev/null and b/tools/View/icons/cursor_rotate.png differ
diff --git a/tools/View/icons/cursor_zoom.png b/tools/View/icons/cursor_zoom.png
new file mode 100644 (file)
index 0000000..0020fea
Binary files /dev/null and b/tools/View/icons/cursor_zoom.png differ
diff --git a/tools/View/icons/view_cube.png b/tools/View/icons/view_cube.png
deleted file mode 100644 (file)
index d373c4b..0000000
Binary files a/tools/View/icons/view_cube.png and /dev/null differ
diff --git a/tools/View/icons/view_fitarea.png b/tools/View/icons/view_fitarea.png
new file mode 100644 (file)
index 0000000..f20f5c0
Binary files /dev/null and b/tools/View/icons/view_fitarea.png differ
diff --git a/tools/View/icons/view_pan.png b/tools/View/icons/view_pan.png
new file mode 100644 (file)
index 0000000..68343b8
Binary files /dev/null and b/tools/View/icons/view_pan.png differ
diff --git a/tools/View/icons/view_rotate.png b/tools/View/icons/view_rotate.png
new file mode 100644 (file)
index 0000000..7e5d013
Binary files /dev/null and b/tools/View/icons/view_rotate.png differ
diff --git a/tools/View/icons/view_zoom.png b/tools/View/icons/view_zoom.png
new file mode 100644 (file)
index 0000000..1b50a37
Binary files /dev/null and b/tools/View/icons/view_zoom.png differ
index 9fda7a71be65a026c13b8b0e5f8964df7ed89b31..3560ed577993da4e7daf2c54078739b7d20e2625 100644 (file)
@@ -3,6 +3,8 @@ ViewControl_MessageDialog.cxx
 ViewControl_MessageDialog.hxx
 ViewControl_PropertyView.cxx
 ViewControl_PropertyView.hxx
+ViewControl_PropertiesDialog.cxx
+ViewControl_PropertiesDialog.hxx
 ViewControl_Table.cxx
 ViewControl_Table.hxx
 ViewControl_TableModel.cxx
diff --git a/tools/ViewControl/ViewControl_PropertiesDialog.cxx b/tools/ViewControl/ViewControl_PropertiesDialog.cxx
new file mode 100644 (file)
index 0000000..c72627a
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/ViewControl_PropertiesDialog.hxx>
+
+#include <inspector/ViewControl_TableModel.hxx>
+#include <inspector/TreeModel_ItemProperties.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QGridLayout>
+#include <QPushButton>
+#include <QWidget>
+#include <Standard_WarningsRestore.hxx>
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+ViewControl_PropertiesDialog::ViewControl_PropertiesDialog (QWidget* theParent)
+: QDialog (theParent)
+{
+  setWindowTitle ("Properties");
+
+  QGridLayout* aLayout = new QGridLayout (this);
+  myTable = new ViewControl_Table (this);
+  ViewControl_TableModel* aModel = new ViewControl_TableModel (myTable->TableView());
+  myTable->SetModel (aModel);
+
+  aLayout->addWidget(myTable->TableView(), 0, 0, 1, 3);
+
+  myOkButton = new QPushButton ("Ok", this);
+  myCancelButton = new QPushButton ("Cancel", this);
+  connect (myOkButton, SIGNAL (clicked()), this, SLOT (accept()));
+  connect (myCancelButton, SIGNAL (clicked()), this, SLOT (reject()));
+  aLayout->addWidget (myOkButton, 1, 1);
+  aLayout->addWidget (myCancelButton, 1, 2);
+
+  aLayout->setColumnStretch (0, 1);
+
+  myCancelButton->setDefault (true);
+
+  setMinimumSize (200, 600);
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void ViewControl_PropertiesDialog::Init (const Handle(TreeModel_ItemProperties)& theProperties)
+{
+  ViewControl_TableModelValues* aTableValues = new ViewControl_TableModelValues();
+  aTableValues->SetProperties (theProperties);
+
+  myTable->Init (aTableValues);
+}
diff --git a/tools/ViewControl/ViewControl_PropertiesDialog.hxx b/tools/ViewControl/ViewControl_PropertiesDialog.hxx
new file mode 100644 (file)
index 0000000..609bcb9
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef ViewControl_PropertiesDialog_H
+#define ViewControl_PropertiesDialog_H
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+
+#include <inspector/ViewControl_Table.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QDialog>
+#include <Standard_WarningsRestore.hxx>
+
+class TreeModel_ItemProperties;
+
+class QWidget;
+class QPushButton;
+
+//! \class ViewControl_PropertiesDialog
+//! Dialog providing table of stream values
+class ViewControl_PropertiesDialog : public QDialog
+{
+  Q_OBJECT
+public:
+
+  //! Constructor
+  Standard_EXPORT ViewControl_PropertiesDialog (QWidget* theParent);
+
+  //! Destructor
+  virtual ~ViewControl_PropertiesDialog() {}
+
+  Standard_EXPORT void Init (const Handle(TreeModel_ItemProperties)& theProperties);
+
+private:
+  ViewControl_Table* myTable; //!< table view
+
+  QPushButton* myOkButton; //!< accept button
+  QPushButton* myCancelButton; //!< reject button
+};
+
+
+#endif