1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0031362: Inspectors - MessageView plugin for message alerts

- append new MessageView plugin to display content of Message_Report;

- correct DumpJson of TDataStd array attributes to print Lower/Upper values;
- correct remove level of Message_Report to store stop time during removing all levels;
- append DumpJson for TFunction, TPrsStd attributes;
- correct DumpJson of XCAFDoc tools due to simplify performance of it;
- move AttributeInfo functionality from XDEDRAW into a static public method of XCAFDoc to call it outside;
- remove obsolete pane classes in DFBrowser plugin, now we may use DumpJSon panel to visualize this content of attributes;
- add new property panel in DFBrowser (synchronized with the same in other plugins);
- add button to switch ON DumpJson in DFBrowser(OFF by default, for better performance), also there is a context menu item in tree view;
- rename in DFBrowser "Property Panel" into "Property Panel (custom)";
- implement ViewControl_ColorSeletor and setting color in TreeModel_ItemProperties. Use only for light in VInspector now;
- implement setting false for all created AIS_Shape presentation to don't modify source TopoDS_Shape;
- remove not use VInspector_CallBack. It's possible using Message_Report/MessageView to track commands way;
- remove History panel in VInspector as not used, MessageView will be better solution for this;
- implement item and actions in VInspector for setting Lights in the view.
This commit is contained in:
nds
2021-04-26 18:01:38 +03:00
committed by bugmaster
parent 9a5bfc1c07
commit d16ecfe28e
239 changed files with 6001 additions and 8009 deletions

10
tools/MessageView/FILES Normal file
View File

@@ -0,0 +1,10 @@
MessageView_ActionsTest.cxx
MessageView_ActionsTest.hxx
MessageView_Communicator.cxx
MessageView_Communicator.hxx
MessageView_MetricStatisticModel.cxx
MessageView_MetricStatisticModel.hxx
MessageView_VisibilityState.cxx
MessageView_VisibilityState.hxx
MessageView_Window.cxx
MessageView_Window.hxx

View File

@@ -0,0 +1,347 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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_TreeModel.hxx>
#include <inspector/ViewControl_Tools.hxx>
#include <Message.hxx>
#include <Message_AlertExtended.hxx>
#include <Message_Level.hxx>
#include <Message_Messenger.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>
#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_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));
}
// =======================================================================
// function : AddMenuActions
// purpose :
// =======================================================================
void MessageView_ActionsTest::AddMenuActions (const QModelIndexList& theSelectedIndices, QMenu* theMenu)
{
MessageModel_ItemReportPtr aReportItem;
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;
MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItemBase);
if (aRootItem)
continue;
aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
if (aReportItem)
break;
MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (anItemBase);
if (anAlertItem)
continue;
}
if (aReportItem && !aReportItem->GetReport().IsNull())
{
theMenu->addAction (myActions[MessageModel_ActionType_TestMetric]);
theMenu->addAction (myActions[MessageModel_ActionType_TestMessenger]);
theMenu->addAction (myActions[MessageModel_ActionType_TestReportTree]);
bool isReportEnabled = aReportItem->GetReport()->IsActiveInMessenger();
myActions[MessageModel_ActionType_TestMetric]->setEnabled (isReportEnabled);
myActions[MessageModel_ActionType_TestMessenger]->setEnabled (isReportEnabled);
myActions[MessageModel_ActionType_TestReportTree]->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()
{
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_Integer aCounter = 1500;
Standard_Real aValue = 0., aValue2 = 0.1;
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;
}
}
}
myTreeModel->UpdateTreeModel();
unsigned int end_time = clock();
std::cout << "clock() = " << end_time - start_time << std::endl;
}
// =======================================================================
// function : createShapeOnLevel
// purpose :
// =======================================================================
void createShapeOnLevel()
{
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::DefaultMessenger() << aShape;
}
// =======================================================================
// function : createShape
// purpose :
// =======================================================================
void createShape()
{
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::DefaultMessenger() << aShape;
createShapeOnLevel();
}
// =======================================================================
// function : OnTestMessenger
// purpose :
// =======================================================================
void MessageView_ActionsTest::OnTestMessenger()
{
// string messages
OCCT_ADD_MESSAGE_LEVEL_SENTRY ("MessageModel_Actions::OnTestMessenger()")
Message::DefaultMessenger()->Send ("Values");
Message::DefaultMessenger()->Send ("Values second");
Message_Messenger::StreamBuffer sout = Message::SendInfo();
// gp_XYZ
{
gp_XYZ aCoords (1.3, 2.3, 3.4);
aCoords.DumpJson (sout);
sout.Flush(Standard_True);
}
// gp_Dir
{
gp_Dir aDir (0.3, 0.3, 0.4);
aDir.DumpJson (sout);
sout.Flush(Standard_True);
}
// gp_Ax1
{
gp_Ax1 aCoords (gp_Pnt (1.3, 2.3, 3.4), gp_Dir (0.3, 0.3, 0.4));
aCoords.DumpJson (sout);
sout.Flush(Standard_True);
}
// gp_Ax2
{
gp_Ax2 aCoords (gp_Pnt (10.3, 20.3, 30.4), gp_Dir (0.3, 0.3, 0.4));
aCoords.DumpJson (sout);
sout.Flush(Standard_True);
}
// gp_Ax3
{
gp_Ax3 aPln (gp_Pnt (10., 20., 15.), gp_Dir (0., 0., 1.), gp_Dir (1., 0., 0.));
aPln.DumpJson (sout);
sout.Flush(Standard_True);
}
// gp_Trsf
{
gp_Trsf aTrsf;
aTrsf.SetRotation (gp::OZ(), 0.3);
aTrsf.SetTranslationPart (gp_Vec (15., 15., 15.));
aTrsf.SetScaleFactor (3.);
aTrsf.DumpJson (sout);
sout.Flush(Standard_True);
}
// Bnd_Box
{
Bnd_Box aBox (gp_Pnt (20., 15., 10.), gp_Pnt (25., 20., 15.));
aBox.DumpJson (sout);
sout.Flush (Standard_True);
}
// 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.);
anOBB.DumpJson (sout);
sout.Flush (Standard_True);
}
// Quantity_ColorRGBA
{
Quantity_ColorRGBA aColor (0.2f, 0.8f, 0.8f, 0.2f);
aColor.DumpJson (sout);
sout.Flush (Standard_True);
}
// Quantity_Color
{
Quantity_Color aColor (0.8, 0.8, 0.8, Quantity_TOC_RGB);
aColor.DumpJson (sout);
sout.Flush (Standard_True);
}
//shape messages
{
createShape();
}
myTreeModel->UpdateTreeModel();
}
// =======================================================================
// function : levelAlerts
// purpose :
// =======================================================================
void levelAlerts (const int theCurrentLevel, const int theTopLevel)
{
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;
levelAlerts (theCurrentLevel + 1, theTopLevel);
sout << "Alert(" << theCurrentLevel << "): " << 4 << ", " << 5 << std::endl;
}
// =======================================================================
// function : levelAlert
// purpose :
// =======================================================================
void levelAlert (const int theCurrentLevel, const int theTopLevel)
{
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;
levelAlerts (theCurrentLevel + 1, theTopLevel);
}
// =======================================================================
// function : OnTestReportTree
// purpose :
// =======================================================================
void MessageView_ActionsTest::OnTestReportTree()
{
OCCT_ADD_MESSAGE_LEVEL_SENTRY ("MessageModel_Actions::OnTestReportTree()")
Message_Messenger::StreamBuffer sout = Message::SendInfo();
int aTopLevel = 3;
levelAlerts (1, aTopLevel);
sout << "Alert: " << 4 << std::endl;
levelAlert (1, aTopLevel);
myTreeModel->UpdateTreeModel();
}

View File

@@ -0,0 +1,81 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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 QAction;
class QItemSelectionModel;
class QMenu;
class QWidget;
//! \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 messenger-alert-tool mechanizm
void OnTestMessenger();
//! Check tree of alerts
void OnTestReportTree();
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

View File

@@ -0,0 +1,25 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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();
}

View File

@@ -0,0 +1,66 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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

View File

@@ -0,0 +1,157 @@
// Created on: 2021-04-27
// Created by: Svetlana SHUTINA
// Copyright (c) 2021 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_MetricStatisticModel.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_MetricStatisticModel::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())
{
appendAlert (anIt.Value());
}
}
else
{
MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (theItemBase);
if (anAlertItem)
{
appendAlert (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 : appendAlert
// purpose :
// =======================================================================
void MessageView_MetricStatisticModel::appendAlert(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;
}
int aCount = 1;
double aTime = 0;
if (myValues.contains (anAttr->GetName().ToCString()))
{
aCount = myValues.value (anAttr->GetName().ToCString()).first + 1;
aTime = myValues.value (anAttr->GetName().ToCString()).second
+ anAttrMeter->StopValue (myMetricType) - anAttrMeter->StartValue (myMetricType);
}
else
{
aCount = 1;
aTime = anAttrMeter->StopValue (myMetricType) - anAttrMeter->StartValue (myMetricType);
}
myValues[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())
{
appendAlert (anIt.Value());
}
}
}
// =======================================================================
// function : data
// purpose :
// =======================================================================
QVariant MessageView_MetricStatisticModel::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 : setValueByIndex
// purpose :
// =======================================================================
void MessageView_MetricStatisticModel::setValueByIndex (const int theIndex, const RowValues theValue)
{
mySortValues.insert (theIndex == -1 ? mySortValues.size() : theIndex, theValue);
}

View File

@@ -0,0 +1,93 @@
// Created on: 2021-04-27
// Created by: Svetlana SHUTINA
// Copyright (c) 2021 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 <Message_MetricType.hxx>
#include <Standard_WarningsDisable.hxx>
#include <QAbstractTableModel>
#include <Standard_WarningsRestore.hxx>
//! @class MessageView_MetricStatisticModel
//! Table model that sums for parameter alert the number of calls and
//! metric time spent on the alert and its children.
//! It visualizes a table with statistic information:
//! the 1st column is alert name, the 2nd column is a counter of the name appearance,
//! the 3rd column is the cummulative time.
//! Tables rows are sorted by descending time.
class MessageView_MetricStatisticModel : public QAbstractTableModel
{
private:
// Struct to describe a row of the table
struct RowValues
{
QString myName; //!< string values
int myCounter; //!< count of the values
double myTime; //!< total time
};
public:
//! Constructor
MessageView_MetricStatisticModel (const Message_MetricType& theType, QObject* theParent = 0)
: QAbstractTableModel (theParent), myMetricType (theType) {}
//! Destructor
virtual ~MessageView_MetricStatisticModel() {}
//! Fills map of the fields values
//! \param theItemBase a parent item.
Standard_EXPORT 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
Standard_EXPORT 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
Standard_EXPORT 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
Standard_EXPORT virtual int columnCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
{ (void)theParent; return 3; }
private:
//! Sorts values and fills map of the fields values depends on unique text identifier. It's recursive.
//! \param theAlert unique text identifier. The alert should have attribute of the metric type
void appendAlert (const Handle(Message_Alert)& theAlert);
//! 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:
Message_MetricType myMetricType; //!< current metric type
QMap<QString, QPair<int, double> > myValues; //!< map of fields values
QMap<int, RowValues> mySortValues; //!< sorted map of fields values
};

View File

@@ -0,0 +1,81 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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 false;
}
// =======================================================================
// function : SetVisible
// purpose :
// =======================================================================
bool MessageView_VisibilityState::SetVisible (const QModelIndex&, const bool, const bool)
{
return false;
}
// =======================================================================
// function : IsVisible
// purpose :
// =======================================================================
bool MessageView_VisibilityState::IsVisible (const QModelIndex&) const
{
return false;
}
// =======================================================================
// 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;
}

View File

@@ -0,0 +1,87 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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;
private:
View_Displayer* myDisplayer; //! view displayer
View_PresentationType myPresentationType; //! presentation type
};
#endif

View File

@@ -0,0 +1,719 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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_TreeModel.hxx>
#include <inspector/MessageView_MetricStatisticModel.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 <Message.hxx>
#include <TCollection_AsciiString.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 <Standard_WarningsDisable.hxx>
#include <QApplication>
#include <QAction>
#include <QDockWidget>
#include <QFile>
#include <QFileDialog>
#include <QHeaderView>
#include <QLayout>
#include <QMainWindow>
#include <QMenu>
#include <QMessageBox>
#include <QPushButton>
#include <QTextStream>
#include <QToolBar>
#include <QToolButton>
#include <QTreeView>
#include <QWidget>
#include <Standard_WarningsRestore.hxx>
const int DEFAULT_SHAPE_VIEW_WIDTH = 400;
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 MESSAGEVIEW_DEFAULT_TREE_VIEW_WIDTH = 950;
const int MESSAGEVIEW_DEFAULT_TREE_VIEW_HEIGHT = 500;
const int MESSAGEVIEW_DEFAULT_VIEW_WIDTH = 200;
const int MESSAGEVIEW_DEFAULT_VIEW_HEIGHT = 300;
// =======================================================================
// 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();
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&)));
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 ("PropertyPanel (custom)"), myMainWindow);
myCustomPanelWidget->setObjectName (myCustomPanelWidget->windowTitle());
myCustomPanelWidget->setTitleBarWidget (new QWidget(myMainWindow));
myCustomPanelWidget->setWidget (myCustomView);
myMainWindow->addDockWidget (Qt::RightDockWidgetArea, myCustomPanelWidget);
// view
myViewWindow = new View_Window (myMainWindow, NULL, 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 (myCustomPanelWidget, myViewDockWidget);
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()
{
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);
}
Handle(Message_Report) aDefaultReport = Message::DefaultReport();
MessageModel_TreeModel* aViewModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
if (!aDefaultReport.IsNull() && !aViewModel->HasReport (aDefaultReport))
{
addReport (aDefaultReport);
}
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);
}
theParameters = aParameters;
}
// =======================================================================
// 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);
}
// =======================================================================
// 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));
}
else if (aReportItem)
{
aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Export Report"), SLOT (onExportReport()), myMainWindow, this));
QAction* anAction = ViewControl_Tools::CreateAction (tr ("WallClock Metric statistic"),
SLOT (onMetricStatistic()), 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);
aMenu->addSeparator();
myTestViewActions->AddMenuActions (aSelectedIndices, aMenu);
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());
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();
aLogFile.close();
}
// =======================================================================
// function : onCreateDefaultReport
// purpose :
// =======================================================================
void MessageView_Window::onCreateDefaultReport()
{
if (!Message::DefaultReport().IsNull())
{
return;
}
addReport (Message::DefaultReport (Standard_True));
}
// =======================================================================
// 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 : onMetricStatistic
// purpose :
// =======================================================================
void MessageView_Window::onMetricStatistic()
{
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_MetricStatisticModel* aUnitByNameModel = new MessageView_MetricStatisticModel (Message_MetricType_WallClock, myCustomView);
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()
{
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);
}
}
}

View File

@@ -0,0 +1,197 @@
// Created on: 2021-04-27
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2021 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>
#include <Standard_WarningsDisable.hxx>
#include <QItemSelection>
#include <QList>
#include <QModelIndexList>
#include <QObject>
#include <QPoint>
#include <QString>
#include <QTableView>
#include <QTreeView>
#include <Standard_WarningsRestore.hxx>
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);
//! 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();
//! 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 onMetricStatistic();
//! 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