From 005011cf4bb41865253788dc4e1b7ab9b76778e5 Mon Sep 17 00:00:00 2001 From: sshutina Date: Wed, 2 Dec 2020 00:26:51 +0300 Subject: [PATCH] 0031959: Inspectors - Statistics by name --- tools/MessageView/FILES | 2 + .../MessageView_UnitByNameModel.cxx | 181 ++++++++++++++++++ .../MessageView_UnitByNameModel.hxx | 96 ++++++++++ tools/MessageView/MessageView_Window.cxx | 41 ++++ tools/MessageView/MessageView_Window.hxx | 8 + 5 files changed, 328 insertions(+) create mode 100644 tools/MessageView/MessageView_UnitByNameModel.cxx create mode 100644 tools/MessageView/MessageView_UnitByNameModel.hxx diff --git a/tools/MessageView/FILES b/tools/MessageView/FILES index 5fe2f52661..86a3a722dc 100644 --- a/tools/MessageView/FILES +++ b/tools/MessageView/FILES @@ -2,6 +2,8 @@ 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 diff --git a/tools/MessageView/MessageView_UnitByNameModel.cxx b/tools/MessageView/MessageView_UnitByNameModel.cxx new file mode 100644 index 0000000000..efef73e130 --- /dev/null +++ b/tools/MessageView/MessageView_UnitByNameModel.cxx @@ -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 +#include +#include + +#include +#include +#include +#include +#include + +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +void MessageView_UnitByNameModel::Init (const TreeModel_ItemBasePtr theItemBase) +{ + MessageModel_ItemReportPtr aReportItem = itemDynamicCast (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 (theItemBase); + if (anAlertItem) + { + initByAlert (anAlertItem->GetAlert()); + } + } + std::map> aTmpMap; + std::list aTimes; + for (QMap >::Iterator anIterValue = myValues.begin(); + anIterValue != myValues.end(); ++anIterValue) + { + std::map>::iterator anIter = aTmpMap.find (anIterValue.value().second); + if (anIter != aTmpMap.end()) + { + aTmpMap.at (anIterValue.value().second).push_back (anIterValue.key()); + } + else + { + std::list list; + list.push_back (anIterValue.key()); + aTmpMap.insert (std::pair > (anIterValue.value().second, list)); + aTimes.push_back (anIterValue.value().second); + } + } + + aTimes.sort(); + aTimes.reverse(); + + for (std::list::iterator anIter = aTimes.begin(); anIter != aTimes.end(); anIter++) + { + double aTime = *anIter; + std::list names = aTmpMap.at (aTime); + for (std::list::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::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 index 0000000000..fe438a5785 --- /dev/null +++ b/tools/MessageView/MessageView_UnitByNameModel.hxx @@ -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 + +#include + +#include + +//! @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 > myValues; //!< map of fields values. + QMap mySortValues; //!< sorted map of fields values. +}; diff --git a/tools/MessageView/MessageView_Window.cxx b/tools/MessageView/MessageView_Window.cxx index b619b898c6..f3abcebfaa 100644 --- a/tools/MessageView/MessageView_Window.cxx +++ b/tools/MessageView/MessageView_Window.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -192,6 +193,12 @@ MessageView_Window::MessageView_Window (QWidget* theParent) 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); @@ -205,6 +212,8 @@ MessageView_Window::MessageView_Window (QWidget* theParent) 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); @@ -513,6 +522,10 @@ void MessageView_Window::onTreeViewContextMenuRequested (const QPoint& thePositi bool isTraceOnly = aReport->MessageWriter().IsNull() ? false : aReport->MessageWriter()->Gravity() == Message_Trace; anAction->setChecked (isTraceOnly); aMenu->addAction (anAction);*/ + + QAction* anAction = ViewControl_Tools::CreateAction (tr ("Unit by name"), SLOT (onUnitByName()), myMainWindow, this); + anAction->setCheckable (true); + aMenu->addAction (anAction); } aMenu->addSeparator(); @@ -768,6 +781,34 @@ void MessageView_Window::onPreviewChildren() 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 : diff --git a/tools/MessageView/MessageView_Window.hxx b/tools/MessageView/MessageView_Window.hxx index bae2ad6fa8..c8eee151e6 100644 --- a/tools/MessageView/MessageView_Window.hxx +++ b/tools/MessageView/MessageView_Window.hxx @@ -36,6 +36,7 @@ #include #include #include +#include #include class View_Displayer; @@ -166,6 +167,10 @@ protected slots: //! 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(); @@ -201,6 +206,9 @@ private: 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 -- 2.39.5