From: nds Date: Sat, 22 Feb 2020 04:49:37 +0000 (+0300) Subject: 0029451: Information Message Alert to debug an algorithm or object functionality X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=fa0db38649fe181d0b55a96f72cc9db66a0c58ca;p=occt-copy.git 0029451: Information Message Alert to debug an algorithm or object functionality MessageView --- diff --git a/adm/TOOLS b/adm/TOOLS index b106a7c10b..57ddcfcc64 100644 --- 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 diff --git a/adm/TOOLS.bak b/adm/TOOLS.bak new file mode 100644 index 0000000000..b106a7c10b --- /dev/null +++ b/adm/TOOLS.bak @@ -0,0 +1,4 @@ +TModelingData TKShapeView +TVisualization TKView TKVInspector +TApplicationFramework TKTreeModel TKTInspectorAPI TKDFBrowser +TTool TKTInspector TKToolsDraw TInspectorEXE \ No newline at end of file diff --git a/adm/cmake/qt.cmake b/adm/cmake/qt.cmake index 6958bab562..535e6a2038 100644 --- a/adm/cmake/qt.cmake +++ b/adm/cmake/qt.cmake @@ -7,7 +7,8 @@ if (NOT DEFINED ${3RDPARTY_QT_DIR} AND ${3RDPARTY_QT_DIR} STREQUAL "") FIND_PRODUCT_DIR ("${3RDPARTY_DIR}" Qt 3RDPARTY_QT_DIR_NAME) if (NOT DEFINED ${3RDPARTY_QT_DIR_NAME} AND ${3RDPARTY_QT_DIR_NAME} STREQUAL "") - message (FATAL_ERROR "... Qt root directory was not found") + set (3RDPARTY_QT_DIR "" CACHE PATH "The directory containing qt") + message (FATAL_ERROR "Could not find used third-party product: 3RDPARTY_QT_DIR") endif() # Combine directory name with absolute path and show in GUI @@ -31,4 +32,10 @@ if (NOT ${Qt5_FOUND}) #message (STATUS "Qt4 cmake configuration") else() #message (STATUS "Qt5 cmake configuration") -endif() \ No newline at end of file +endif() + +if (3RDPARTY_QT_DIR OR EXISTS "${3RDPARTY_QT_DIR}") + list (APPEND 3RDPARTY_DLL_DIRS "${3RDPARTY_QT_DIR}/bin") +else() + list (APPEND 3RDPARTY_NO_DLLS 3RDPARTY_QT_DLL_DIR) +endif() diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx index ea157d7a38..4f2d04c6ab 100644 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx @@ -21,6 +21,8 @@ #include #include #include +#include +#include namespace { @@ -97,6 +99,9 @@ void BRepMesh_IncrementalMesh::Perform() //======================================================================= void BRepMesh_IncrementalMesh::Perform(const Handle(IMeshTools_Context)& theContext) { + Handle(Message_Messenger) sout = Message::DefaultMessenger(); + sout << "BRepMesh_IncrementalMesh::Perform" << Message_EndLine; + initParameters(); theContext->SetShape(Shape()); diff --git a/src/IMeshTools/FILES b/src/IMeshTools/FILES index 66b4f92699..579ebd6d0b 100644 --- a/src/IMeshTools/FILES +++ b/src/IMeshTools/FILES @@ -8,6 +8,7 @@ IMeshTools_MeshBuilder.cxx IMeshTools_ModelAlgo.hxx IMeshTools_ModelBuilder.hxx IMeshTools_Parameters.hxx +IMeshTools_Parameters.cxx IMeshTools_ShapeExplorer.hxx IMeshTools_ShapeExplorer.cxx IMeshTools_ShapeVisitor.hxx diff --git a/src/IMeshTools/IMeshTools_Parameters.cxx b/src/IMeshTools/IMeshTools_Parameters.cxx new file mode 100644 index 0000000000..5681bcc074 --- /dev/null +++ b/src/IMeshTools/IMeshTools_Parameters.cxx @@ -0,0 +1,38 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// 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 +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +void IMeshTools_Parameters::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const +{ + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Angle) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Deflection) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, AngleInterior) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, DeflectionInterior) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, MinSize) + + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, InParallel) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Relative) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, InternalVerticesMode) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, ControlSurfaceDeflection) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, CleanModel) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, AdjustMinSize) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, ForceFaceDeflection) +} diff --git a/src/IMeshTools/IMeshTools_Parameters.hxx b/src/IMeshTools/IMeshTools_Parameters.hxx index c0526becdb..2132446d2a 100644 --- a/src/IMeshTools/IMeshTools_Parameters.hxx +++ b/src/IMeshTools/IMeshTools_Parameters.hxx @@ -46,6 +46,9 @@ struct IMeshTools_Parameters { return 0.1; } + //! Dumps the content of me into the stream + Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; + //! Angular deflection used to tessellate the boundary edges Standard_Real Angle; diff --git a/src/MeshTest/MeshTest.cxx b/src/MeshTest/MeshTest.cxx index 9882f52266..acf90073a3 100644 --- a/src/MeshTest/MeshTest.cxx +++ b/src/MeshTest/MeshTest.cxx @@ -133,6 +133,10 @@ options:\n\ { aMeshParams.Angle = aVal * M_PI / 180.; } + if (aOpt == "-ae") + { + aMeshParams.Angle = aVal; + } else if (aOpt == "-ai") { aMeshParams.AngleInterior = aVal * M_PI / 180.; diff --git a/src/TopoDS/FILES b/src/TopoDS/FILES index 8e17f304b6..27345a189f 100644 --- a/src/TopoDS/FILES +++ b/src/TopoDS/FILES @@ -1,5 +1,7 @@ TopoDS.hxx TopoDS.lxx +TopoDS_AlertAttribute.hxx +TopoDS_AlertAttribute.cxx TopoDS_Builder.cxx TopoDS_Builder.hxx TopoDS_Builder.lxx diff --git a/src/TopoDS/TopoDS_AlertAttribute.cxx b/src/TopoDS/TopoDS_AlertAttribute.cxx new file mode 100644 index 0000000000..a1b9c5b1ba --- /dev/null +++ b/src/TopoDS/TopoDS_AlertAttribute.cxx @@ -0,0 +1,56 @@ +// Created on: 2018-06-10 +// 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 + +#include + +IMPLEMENT_STANDARD_RTTIEXT(TopoDS_AlertAttribute, Message_Attribute) + +//======================================================================= +//function : TopoDS_AlertAttribute +//purpose : +//======================================================================= +TopoDS_AlertAttribute::TopoDS_AlertAttribute (const TopoDS_Shape& theShape, + const TCollection_AsciiString& theName) +: Message_AttributeStream (Standard_SStream(), theName), myShape (theShape) +{ + Standard_SStream aStream; + theShape.DumpJson (aStream); + + SetStream (aStream); +} + +//======================================================================= +//function : Send +//purpose : +//======================================================================= +void TopoDS_AlertAttribute::Send (const Handle(Message_Messenger)& theMessenger, + const TopoDS_Shape& theShape) +{ + for (Message_SequenceOfPrinters::Iterator aPrinterIter (theMessenger->Printers()); aPrinterIter.More(); aPrinterIter.Next()) + { + const Handle(Message_Printer)& aPrinter = aPrinterIter.Value(); + if (!aPrinter->IsKind (STANDARD_TYPE (Message_PrinterToReport))) + continue; + + Handle (Message_PrinterToReport) aPrinterToReport = Handle(Message_PrinterToReport)::DownCast (aPrinter); + const Handle(Message_Report)& aReport = aPrinterToReport->Report(); + + Message_AlertExtended::AddAlert (aReport, new TopoDS_AlertAttribute (theShape, aPrinterToReport->Value()), + theMessenger->OuputGravity()); + aPrinterToReport->Clear(); + } +} diff --git a/src/TopoDS/TopoDS_AlertAttribute.hxx b/src/TopoDS/TopoDS_AlertAttribute.hxx new file mode 100644 index 0000000000..09e7cb401d --- /dev/null +++ b/src/TopoDS/TopoDS_AlertAttribute.hxx @@ -0,0 +1,67 @@ +// Created on: 2018-06-10 +// 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 _TopoDS_AlertAttribute_HeaderFile +#define _TopoDS_AlertAttribute_HeaderFile + +#include +#include +#include +#include + +#include + +class Message_Messenger; + +//! Alert attributre object storing TopoDS shape in its field +class TopoDS_AlertAttribute : public Message_AttributeStream +{ +public: + //! Constructor with shape argument + Standard_EXPORT TopoDS_AlertAttribute (const TopoDS_Shape& theShape, + const TCollection_AsciiString& theName = TCollection_AsciiString()); + + //! Returns contained shape + const TopoDS_Shape& GetShape() const { return myShape; } + + //! Push shape information into messenger + Standard_EXPORT static void Send (const Handle(Message_Messenger)& theMessenger, + const TopoDS_Shape& theShape); + + // OCCT RTTI + DEFINE_STANDARD_RTTIEXT(TopoDS_AlertAttribute, Message_AttributeStream) + +private: + TopoDS_Shape myShape; +}; + +#define MESSAGE_INFO_SHAPE(Shape, Name) \ + { \ + if (!Message::DefaultReport().IsNull()) \ + { \ + Message_AlertExtended::AddAlert (Message::DefaultReport(), \ + new TopoDS_AlertAttribute (Shape, Name), Message_Info); \ + } \ + } + +// HAsciiString +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const TopoDS_Shape& theShape) +{ + TopoDS_AlertAttribute::Send (theMessenger, theShape); + return theMessenger; +} + +#endif // _TopoDS_AlertAttribute_HeaderFile diff --git a/tools/MessageModel/FILES b/tools/MessageModel/FILES new file mode 100644 index 0000000000..5fbdcbc86b --- /dev/null +++ b/tools/MessageModel/FILES @@ -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 index 0000000000..8b794a8599 --- /dev/null +++ b/tools/MessageModel/MessageModel.qrc @@ -0,0 +1,6 @@ + + + icons/item_shape.png + icons/item_streamValues.png + + diff --git a/tools/MessageModel/MessageModel_ActionType.hxx b/tools/MessageModel/MessageModel_ActionType.hxx new file mode 100644 index 0000000000..7df28caaba --- /dev/null +++ b/tools/MessageModel/MessageModel_ActionType.hxx @@ -0,0 +1,32 @@ +// 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 +}; + +#endif diff --git a/tools/MessageModel/MessageModel_Actions.cxx b/tools/MessageModel/MessageModel_Actions.cxx new file mode 100644 index 0000000000..b5e4785262 --- /dev/null +++ b/tools/MessageModel/MessageModel_Actions.cxx @@ -0,0 +1,266 @@ +// 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 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// ======================================================================= +// 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 (anItemBase); + if (aRootItem) + break; + + aReportItem = itemDynamicCast (anItemBase); + if (aReportItem) + break; + + anAlertItem = itemDynamicCast (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 (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); + 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 aPluginParameters; + if (myParameters->FindParameters (aPluginName)) + aPluginParameters = myParameters->Parameters (aPluginName); + NCollection_List 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 (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 index 0000000000..39eab429e2 --- /dev/null +++ b/tools/MessageModel/MessageModel_Actions.hxx @@ -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 +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +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 myActions; //!< container of all actions +}; + +#endif diff --git a/tools/MessageModel/MessageModel_ItemAlert.cxx b/tools/MessageModel/MessageModel_ItemAlert.cxx new file mode 100644 index 0000000000..f13c27f472 --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemAlert.cxx @@ -0,0 +1,320 @@ +// 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 + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +// ======================================================================= +// 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) + return theRole == Qt::DisplayRole ? anAlert->GetMessageKey() : 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()) + return QVariant(); + + 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(); + } + } + 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 (Parent()); + MessageModel_ItemAlertPtr anAlertItem; + Handle(Message_Alert) anAlert; + if (aReportItem) + { + Message_ListOfAlert anAlerts; + if (aReportItem->GetChildAlerts (Row(), anAlerts)) + { + myAlert = anAlerts.First(); + } + } + else + { + anAlertItem = itemDynamicCast (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))) + //// myPresentations.Append (Handle(Message_AttributeObject)::DownCast (anAttribute)->GetObject()); + if (anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute))) + myPresentations.Append (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()))) + // myPresentations.Append (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(); + myPresentations.Clear(); +} + +// ======================================================================= +// function : initItem +// purpose : +// ======================================================================= +void MessageModel_ItemAlert::initItem() const +{ + if (IsInitialized()) + return; + const_cast(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 index 0000000000..1c21ffa288 --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemAlert.hxx @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +class QAbstractTableModel; + +class MessageModel_ItemAlert; +typedef QExplicitlySharedDataPointer 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 + void GetPresentations (NCollection_List& thePresentations) + { thePresentations.Append (myPresentations); } + + + ////! 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 myChildAlerts; //!< container of child alerts + + TopoDS_Shape myCustomShape; + NCollection_List myPresentations; +}; + +#endif diff --git a/tools/MessageModel/MessageModel_ItemBase.cxx b/tools/MessageModel/MessageModel_ItemBase.cxx new file mode 100644 index 0000000000..de74f85a3c --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemBase.cxx @@ -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 +#include + +// ======================================================================= +// function : isReversed +// purpose : +// ======================================================================= +Standard_Boolean MessageModel_ItemBase::isReversed() const +{ + TreeModel_ItemBasePtr aParentItem = GetRootItem(); + MessageModel_ItemRootPtr aRootItem = itemDynamicCast (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 (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 index 0000000000..dfd9e7fb61 --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemBase.hxx @@ -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 +#include +#include + +class MessageModel_ItemBase; +typedef QExplicitlySharedDataPointer 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 index 0000000000..575de32fe4 --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemReport.cxx @@ -0,0 +1,227 @@ +// 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 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// ======================================================================= +// 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)) + { + 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 (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(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(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(anItem); + + if (aReportItem) + return aReportItem->GetReport(); + + anItem = itemDynamicCast(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()) + continue; + if (aFirstAttribute.IsNull()) + aFirstAttribute = anAttribute; + else + aLastAttribute = anAttribute; + } + 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 index 0000000000..f03d98e58d --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemReport.hxx @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +class MessageModel_ItemReport; +typedef QExplicitlySharedDataPointer 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 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 index 0000000000..b42dcc8864 --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemRoot.cxx @@ -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 +#include + +// ======================================================================= +// function : SetReport +// purpose : +// ======================================================================= +void MessageModel_ItemRoot::SetReport (const int theRowId, const Handle(Message_Report)& theReport, + const TCollection_AsciiString& theReportDescription) +{ + NCollection_List::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::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::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 index 0000000000..197bd1eb9a --- /dev/null +++ b/tools/MessageModel/MessageModel_ItemRoot.hxx @@ -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 +#include +#include +#include +#include + +#include + +class MessageModel_ItemRoot; +typedef QExplicitlySharedDataPointer 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& 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 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 index 0000000000..5348d47ca8 --- /dev/null +++ b/tools/MessageModel/MessageModel_Tools.cxx @@ -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 +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// ======================================================================= +// 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 index 0000000000..c83922aed6 --- /dev/null +++ b/tools/MessageModel/MessageModel_Tools.hxx @@ -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 + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +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 index 0000000000..85b539817b --- /dev/null +++ b/tools/MessageModel/MessageModel_TreeModel.cxx @@ -0,0 +1,207 @@ +// 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 + +#include +#include +#include + +#include + +const int COLUMN_REAL_VALUE_WIDTH = 115; +const int COLUMN_PERCENT_VALUE_WIDTH = 40; + +// ======================================================================= +// function : Constructor +// purpose : +// ======================================================================= +MessageModel_TreeModel::MessageModel_TreeModel (QObject* theParent) +: TreeModel_ModelBase (theParent), myIsReversed (Standard_False) +{ +} + +// ======================================================================= +// function : InitColumns +// purpose : +// ======================================================================= +void MessageModel_TreeModel::InitColumns() +{ + TreeModel_ModelBase::InitColumns(); + // 0 - Name, 1 - visibility, 2 - Row + + 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 ("%", COLUMN_PERCENT_VALUE_WIDTH)); + } +} + +// ======================================================================= +// function : GetMetricColumns +// purpose : +// ======================================================================= +void MessageModel_TreeModel::GetMetricColumns (const Message_MetricType theMetricType, QList& 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 (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 (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 (RootItem (aColId)); + if (!aRootItem) + continue; + aRootItem->SetReport (theRowId, theReport, theReportDescription); + } + Reset(); + EmitLayoutChanged(); +} + +// ======================================================================= +// function : Reports +// purpose : +// ======================================================================= +const NCollection_List& MessageModel_TreeModel::Reports() const +{ + MessageModel_ItemRootPtr aRootItem = itemDynamicCast (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 (RootItem (aColId)); + if (aRootItem) + aRootItem->SetReversed (myIsReversed); + } + + Reset(); + EmitLayoutChanged(); +} + +// ======================================================================= +// function : UpdateTreeModel +// purpose : +// ======================================================================= +void MessageModel_TreeModel::SetRootItemName (const TCollection_AsciiString& theName) +{ + MessageModel_ItemRootPtr aRootItem = itemDynamicCast (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 index 0000000000..01eeba4144 --- /dev/null +++ b/tools/MessageModel/MessageModel_TreeModel.hxx @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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& 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& 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 index 0000000000..a808bc55e5 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 index 0000000000..14313ed68a --- /dev/null +++ b/tools/MessageModel/icons/item_shape.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/MessageModel/icons/item_streamValues.png b/tools/MessageModel/icons/item_streamValues.png new file mode 100644 index 0000000000..7181f9460e 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 index 0000000000..38b1032701 --- /dev/null +++ b/tools/MessageModel/icons/item_streamValues.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/tools/MessageView/FILES b/tools/MessageView/FILES new file mode 100644 index 0000000000..5fe2f52661 --- /dev/null +++ b/tools/MessageView/FILES @@ -0,0 +1,8 @@ +MessageView_ActionsTest.cxx +MessageView_ActionsTest.hxx +MessageView_Communicator.cxx +MessageView_Communicator.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 index 0000000000..6aad3ea70b --- /dev/null +++ b/tools/MessageView/MessageView_ActionsTest.cxx @@ -0,0 +1,438 @@ +// 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 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DEBUG_ALERTS + +#ifdef DEBUG_ALERTS +#include +#include +#endif + +#include + + +// ======================================================================= +// 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 ", SLOT (OnTestMetric()), parent(), this)); + myActions.insert (MessageModel_ActionType_TestProperties, + ViewControl_Tools::CreateAction ("Test ", SLOT (OnTestPropertyPanel()), parent(), this)); + myActions.insert (MessageModel_ActionType_TestMessenger, + ViewControl_Tools::CreateAction ("Test ", SLOT (OnTestMessenger()), parent(), this)); + myActions.insert (MessageModel_ActionType_TestReportTree, + ViewControl_Tools::CreateAction ("Test ", SLOT (OnTestReportTree()), 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 (anItemBase); + if (aRootItem) + break; + + aReportItem = itemDynamicCast (anItemBase); + if (aReportItem) + break; + + anAlertItem = itemDynamicCast (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]); + + 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); + } + 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 (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; + + MESSAGE_ADD_LEVEL_SENTRY + MESSAGE_INFO ("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_INFO ("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; + + MESSAGE_ADD_LEVEL_SENTRY + MESSAGE_INFO ("MessageModel_Actions::OnTestPropertyPanel()"); + + // gp_XYZ + { + gp_XYZ aCoords (1.3, 2.3, 3.4); + Standard_SStream aStream; + aCoords.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "gp_XYZ"); + } + // gp_Dir + { + gp_Dir aDir (0.3, 0.3, 0.4); + Standard_SStream aStream; + aDir.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "gp_Dir"); + } + // gp_Ax1 + { + gp_Ax1 aCoords (gp_Pnt (1.3, 2.3, 3.4), gp_Dir (0.3, 0.3, 0.4)); + Standard_SStream aStream; + aCoords.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "gp_Ax1"); + } + // gp_Ax2 + { + gp_Ax2 aCoords (gp_Pnt (10.3, 20.3, 30.4), gp_Dir (0.3, 0.3, 0.4)); + Standard_SStream aStream; + aCoords.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "gp_Ax2"); + } + // gp_Ax3 + { + gp_Ax3 aPln (gp_Pnt (10., 20., 15.), gp_Dir (0., 0., 1.), gp_Dir (1., 0., 0.)); + Standard_SStream aStream; + aPln.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "gp_Ax3"); + } + // gp_Trsf + { + gp_Trsf aTrsf; + aTrsf.SetRotation (gp::OZ(), 0.3); + aTrsf.SetTranslationPart (gp_Vec (15., 15., 15.)); + aTrsf.SetScaleFactor (3.); + + Standard_SStream aStream; + aTrsf.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "gp_Trsf"); + } + // Bnd_Box + { + Bnd_Box aBox (gp_Pnt (20., 15., 10.), gp_Pnt (25., 20., 15.)); + Standard_SStream aStream; + aBox.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "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.); + Standard_SStream aStream; + anOBB.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "Bnd_OBB"); + } + // Quantity_ColorRGBA + { + Quantity_ColorRGBA aColor (0.2f, 0.8f, 0.8f, 0.2f); + Standard_SStream aStream; + aColor.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "Quantity_ColorRGBA"); + } + // Quantity_Color + { + Quantity_Color aColor (0.8, 0.8, 0.8, Quantity_TOC_RGB); + Standard_SStream aStream; + aColor.DumpJson (aStream); + MESSAGE_INFO_STREAM(aStream, "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"); + + MESSAGE_INFO_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 : OnTestMessenger +// purpose : +// ======================================================================= +void MessageView_ActionsTest::OnTestMessenger() +{ + // string messages + const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger(); + + MESSAGE_ADD_LEVEL_SENTRY + aMessenger << "MessageModel_Actions::OnTestMessenger()" << Message_EndLine; + + aMessenger << "IGESBasic_Hierarchy" << Message_EndLine; + aMessenger << "Number of property valueaMessenger : " << 15 << Message_EndLine; + aMessenger << "Line Font : " << 1 << Message_EndLine << "View Number : " << 3 << Message_EndLine; + aMessenger << "Entity level : " << 1 << Message_EndLine; + aMessenger << "Blank statuaMessenger : " << 0 << Message_EndLine; + aMessenger << "Line weight : " << 14 << Message_EndLine; + aMessenger << "Color number : " << 5 << Message_EndLine; + + // stream messages + // gp_XYZ + { + gp_XYZ aCoords (1.3, 2.3, 3.4); + Standard_SStream aStream; + aCoords.DumpJson (aStream); + aMessenger << "gp_XYZ" << aStream << Message_EndLine; + } + // Bnd_Box + { + Bnd_Box aBox (gp_Pnt (20., 15., 10.), gp_Pnt (25., 20., 15.)); + Standard_SStream aStream; + aBox.DumpJson (aStream); + aMessenger << "Bnd_Box" << aStream; + } + + // object messages + Handle(Standard_Transient) anObject = new Message_AlertExtended(); + aMessenger << "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"); + + aMessenger << "Shape message edge" << aShape; + } + myTreeModel->UpdateTreeModel(); +} + +// ======================================================================= +// function : levelAlerts +// purpose : +// ======================================================================= +void levelAlerts (const int theCurrentLevel, const int theTopLevel) +{ + if (theTopLevel - theCurrentLevel <= 0) + return; + + MESSAGE_ADD_LEVEL_SENTRY + + const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger(); + aMessenger << "Level: " << theCurrentLevel << Message_EndLine; + aMessenger << "Alert: " << 1 << ", " << 2 << Message_EndLine; + aMessenger << "Alert: " << 3 << ", " << 4 << Message_EndLine; + + for (int i = 0; i < 2; i++) + levelAlerts (theCurrentLevel + 1, theTopLevel); + + aMessenger << "Alert: " << 4 << ", " << 5 << Message_EndLine; +} + +// ======================================================================= +// function : levelAlert +// purpose : +// ======================================================================= +void levelAlert (const int theCurrentLevel, const int theTopLevel) +{ + if (theTopLevel - theCurrentLevel <= 0) + return; + + MESSAGE_ADD_LEVEL_SENTRY + + const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger(); + aMessenger << "Level: " << theCurrentLevel << "(Single, no alerts on the level)" << Message_EndLine; + + for (int i = 0; i < 2; i++) + levelAlerts (theCurrentLevel + 1, theTopLevel); +} + +// ======================================================================= +// function : OnTestMessenger +// purpose : +// ======================================================================= +void MessageView_ActionsTest::OnTestReportTree() +{ + MESSAGE_ADD_LEVEL_SENTRY + const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger(); + aMessenger << "MessageModel_Actions::OnTestReportTree()" << Message_EndLine; + + // string messages + //aMessenger << "Alert: " << 1 << Message_EndLine; + //aMessenger << "Alert: " << 2 << Message_EndLine; + + int aTopLevel = 3; + levelAlerts (1, aTopLevel); + + //aMessenger << "Alert: " << 3 << Message_EndLine; + //levelAlerts (1, aTopLevel); + + aMessenger << "Alert: " << 4 << Message_EndLine; + levelAlert (1, aTopLevel); + + myTreeModel->UpdateTreeModel(); +} + diff --git a/tools/MessageView/MessageView_ActionsTest.hxx b/tools/MessageView/MessageView_ActionsTest.hxx new file mode 100644 index 0000000000..54943819e6 --- /dev/null +++ b/tools/MessageView/MessageView_ActionsTest.hxx @@ -0,0 +1,82 @@ +// 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +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(); + +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 myActions; //!< container of all actions +}; + +#endif diff --git a/tools/MessageView/MessageView_Communicator.cxx b/tools/MessageView/MessageView_Communicator.cxx new file mode 100644 index 0000000000..10b95480f7 --- /dev/null +++ b/tools/MessageView/MessageView_Communicator.cxx @@ -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 + + +// ======================================================================= +// 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 index 0000000000..7d93c21b55 --- /dev/null +++ b/tools/MessageView/MessageView_Communicator.hxx @@ -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 +#include + +//! \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_VisibilityState.cxx b/tools/MessageView/MessageView_VisibilityState.cxx new file mode 100644 index 0000000000..1a1de536c3 --- /dev/null +++ b/tools/MessageView/MessageView_VisibilityState.cxx @@ -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 +#include + +#include +#include + +#include + +// ======================================================================= +// function : CanBeVisible +// purpose : +// ======================================================================= +bool MessageView_VisibilityState::CanBeVisible (const QModelIndex& theIndex) const +{ + MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex); + if (anAlertItem) + { + NCollection_List aPresentations; + anAlertItem->GetPresentations (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(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 index 0000000000..b26e73f4ef --- /dev/null +++ b/tools/MessageView/MessageView_VisibilityState.hxx @@ -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 + +#include + +#include + +#include +#include +#include + +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 index 0000000000..e609df7b14 --- /dev/null +++ b/tools/MessageView/MessageView_Window.cxx @@ -0,0 +1,825 @@ +// 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 +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_ALERTS + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const int DEFAULT_TEXT_VIEW_WIDTH = 400;// 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 +#include +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); + + 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); + + 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); + + 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())); + + + // 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->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 aDockwidgets = myMainWindow->findChildren(); + for (QList::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 anItems; + //TreeModel_Tools::SaveState (myTreeView, anItems); + + anItems.clear(); + View_Window::SaveState(myViewWindow, anItems); + for (QMap::const_iterator anItemsIt = anItems.begin(); anItemsIt != anItems.end(); anItemsIt++) + theItem.Bind (anItemsIt.key().toStdString().c_str(), anItemsIt.value().toStdString().c_str()); + + for (QMap::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) +{ + if (theItem.IsEmpty()) + { + TreeModel_Tools::SetDefaultHeaderSections (myTreeView); + return; + } + + 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 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::Iterator aFilesIt (myParameters->FileNames (aName)); + aFilesIt.More(); aFilesIt.Next()) + openFile (aFilesIt.Value()); + + NCollection_List aNames; + myParameters->SetFileNames (aName, aNames); + isUpdated = true; + } + Handle(Message_Report) aDefaultReport = Message::DefaultReport (Standard_False); + MessageModel_TreeModel* aViewModel = dynamic_cast (myTreeView->model()); + if (!aDefaultReport.IsNull() && !aViewModel->HasReport (aDefaultReport)) + { + addReport (aDefaultReport); + } + // reload report of selected item + onReloadReport(); + + updateTreeModel(); +} + +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +void MessageView_Window::Init (NCollection_List& theParameters) +{ + Handle(AIS_InteractiveContext) aContext; + NCollection_List aParameters; + + Handle(Graphic3d_Camera) aViewCamera; + + for (NCollection_List::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 (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) +{ + Handle(Message_Report) aReport = XmlDrivers_MessageReportStorage::ImportReport(theFileName); + if (aReport.IsNull()) + return; + + addReport (aReport, theFileName); +} + +// ======================================================================= +// function : updateTreeModel +// purpose : +// ======================================================================= +void MessageView_Window::updateTreeModel() +{ + MessageModel_TreeModel* aViewModel = dynamic_cast (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 (myTreeView->model()); + aModel->AddReport (theReport, theReportDescription); + + updateVisibleColumns(); +} + +// ======================================================================= +// function : onTreeViewVisibilityClicked +// purpose : +// ======================================================================= +void MessageView_Window::onTreeViewVisibilityClicked(const QModelIndex& theIndex) +{ + MessageModel_TreeModel* aTreeModel = dynamic_cast (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 (anItemBase); + if (aRootItem) + break; + aReportItem = itemDynamicCast (anItemBase); + if (aReportItem) + break; + } + if (aRootItem) + { + aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Import Report"), SLOT (onImportReport()), myMainWindow, this)); + // unite + //MessageModel_TreeModel* aTreeModel = dynamic_cast (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)); + } + } + 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 : onEraseAllPerformed +// purpose : +// ======================================================================= +void MessageView_Window::onEraseAllPerformed() +{ + MessageModel_TreeModel* aTreeModel = dynamic_cast (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(anItemBase); + if (!aReportItem) + return; + + QString aFilter (tr ("Document file (*.xml *)")); + QString aSelectedFilter; + QString aFileName = QFileDialog::getSaveFileName (0, tr ("Export report to file"), QString(), aFilter, &aSelectedFilter); + + XmlDrivers_MessageReportStorage::ExportReport (aReportItem->GetReport(), + TCollection_AsciiString (aFileName.toStdString().c_str())); +} + +// ======================================================================= +// function : onImportReport +// purpose : +// ======================================================================= +void MessageView_Window::onImportReport() +{ + QString aFilter (tr ("Document file (*.cbf *)")); + QString aSelectedFilter; + + QItemSelectionModel* aSelectionModel = myTreeView->selectionModel(); + aSelectionModel->clear(); + + QString aFileName = QFileDialog::getOpenFileName (0, tr("Import report"), QString(), aSelectedFilter); + openFile (TCollection_AsciiString (aFileName.toStdString().c_str())); +} + +// ======================================================================= +// function : onImportReport +// purpose : +// ======================================================================= +//void MessageView_Window::onUniteAlerts() +//{ + //MessageModel_TreeModel* aTreeModel = dynamic_cast (myTreeView->model()); + //Standard_Boolean isUniteAlerts = aTreeModel->IsUniteAlerts(); + + //aTreeModel->SetUniteAlerts (!isUniteAlerts); +//} + +// ======================================================================= +// function : onSetReversedAlerts +// purpose : +// ======================================================================= +void MessageView_Window::onSetReversedAlerts() +{ + MessageModel_TreeModel* aTreeModel = dynamic_cast (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(anItemBase); + if (!aReportItem) + aReportItem = MessageModel_ItemReport::FindReportItem (anItemBase); + + if (!aReportItem) + return; + + const TCollection_AsciiString aDescription = aReportItem->GetDescription(); + Handle(Message_Report) aReport = XmlDrivers_MessageReportStorage::ImportReport (aDescription); + if (aReport.IsNull()) + return; + + MessageModel_TreeModel* aTreeModel = dynamic_cast (myTreeView->model()); + aModel->clearSelection(); + aTreeModel->SetReport (aReportItem->Row(), aReport, aDescription); +} + +// ======================================================================= +// function : addActivateMetricActions +// purpose : +// ======================================================================= +void MessageView_Window::addActivateMetricActions (QMenu* theMenu) +{ + QMenu* aSubMenu = new QMenu ("Activate metric"); + + Handle(Message_Report) aReport = Message::DefaultReport (Standard_True); + + 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 (Standard_True); + const NCollection_Map& 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 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 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; + + Handle(TreeModel_ItemProperties) anItemProperties = anItemBase->Properties(); + if (anItemProperties) + { + anItemProperties->Presentations (aPresentations); + } + + MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast(anItemBase); + if (anAlertItem) + { + anAlertItem->GetPresentations (aPresentations); + } + } + + displayer()->DisplayPreview()->UpdatePreview (View_DisplayActionType_DisplayId, aPresentations, myViewWindow->ViewWidget()->DisplayMode()); +} + +// ======================================================================= +// function : updateVisibleColumns +// purpose : +// ======================================================================= +void MessageView_Window::updateVisibleColumns() +{ + MessageModel_TreeModel* aViewModel = dynamic_cast (myTreeView->model()); + const NCollection_List& aReports = aViewModel->Reports(); + + NCollection_Map anActiveMetrics; + for (NCollection_List::Iterator anIterator (aViewModel->Reports()); anIterator.More(); anIterator.Next()) + { + Handle(Message_Report) aReport = anIterator.Value().myReport; + for (NCollection_Map::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 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->GetHeaderItem (aColumnId); + aSection.SetIsHidden (isColumnHidden); + aViewModel->SetHeaderItem (aColumnId, aSection); + } + } +} diff --git a/tools/MessageView/MessageView_Window.hxx b/tools/MessageView/MessageView_Window.hxx new file mode 100644 index 0000000000..00547e44c4 --- /dev/null +++ b/tools/MessageView/MessageView_Window.hxx @@ -0,0 +1,197 @@ +// 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 +#include +#include + +#include +#include + +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(disable : 4127) // conditional expression is constant +#endif +#include +#include +#include +#include +#include +#include +#include + +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& 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(); + + //! Updates visibility states by erase all in context + void onEraseAllPerformed(); + + //! Export report into document + void onExportReport(); + + //! Import report into document + void onImportReport(); + + //! 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(); + + //! 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 + + Handle(TInspectorAPI_PluginParameters) myParameters; //!< plugins parameters container + + Handle(AIS_InteractiveObject) myPreviewPresentation; //!< presentation of preview for a selected object +}; + +#endif diff --git a/tools/ShapeView/ShapeView_Window.cxx b/tools/ShapeView/ShapeView_Window.cxx index bfe8d34eca..ce6526335d 100644 --- a/tools/ShapeView/ShapeView_Window.cxx +++ b/tools/ShapeView/ShapeView_Window.cxx @@ -107,6 +107,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&))); @@ -360,17 +361,16 @@ 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 (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(anItemBase); const TopoDS_Shape& aShape = aShapeItem->GetItemShape(); TopAbs_ShapeEnum anExplodeType = aShapeItem->ExplodeType(); @@ -396,6 +396,7 @@ void ShapeView_Window::onTreeViewContextMenuRequested (const QPoint& thePosition anExplodeMenu->addAction (anAction); } } + aMenu->addAction (ViewControl_Tools::CreateAction ("Create Compound", SLOT (onCreateCompound()), myMainWindow, this)); QPoint aPoint = myTreeView->mapToGlobal (thePosition); aMenu->exec (aPoint); @@ -521,3 +522,33 @@ void ShapeView_Window::onExportToBREP() anItem->SetFileName (aFileNameIndiced.ToCString()); aFileName = aFileNameIndiced.ToCString(); } + +// ======================================================================= +// function : onCreateCompound +// purpose : +// ======================================================================= +void ShapeView_Window::onCreateCompound() +{ + QItemSelectionModel* aModel = myTreeView->selectionModel(); + if (!aModel) + return; + QList anItems = TreeModel_ModelBase::SelectedItems (aModel->selectedIndexes()); + + QList aSelectedIds; // Remember of selected address in order to avoid duplicates + NCollection_List anItemPresentations; + + BRep_Builder aBB; + TopoDS_Compound aC; + aBB.MakeCompound(aC); + + for (QList::const_iterator anItemIt = anItems.begin(); anItemIt != anItems.end(); ++anItemIt) + { + ShapeView_ItemShapePtr anItem = itemDynamicCast(*anItemIt); + if (!anItem) + return; + + aBB.Add(aC, anItem->GetItemShape()); + } + + addShape (aC); +} diff --git a/tools/ShapeView/ShapeView_Window.hxx b/tools/ShapeView/ShapeView_Window.hxx index 950119326e..ea39a4c28c 100644 --- a/tools/ShapeView/ShapeView_Window.hxx +++ b/tools/ShapeView/ShapeView_Window.hxx @@ -129,6 +129,9 @@ protected slots: //! Views BREP files of selected items if exist void onExportToBREP(); + //! Create a compound of selected shapes + void onCreateCompound(); + //! 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())); } diff --git a/tools/TInspectorEXE/TInspectorEXE.cxx b/tools/TInspectorEXE/TInspectorEXE.cxx index 73ab696359..d0181b1560 100644 --- a/tools/TInspectorEXE/TInspectorEXE.cxx +++ b/tools/TInspectorEXE/TInspectorEXE.cxx @@ -19,6 +19,8 @@ #include +#include +#include #include #include @@ -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 aParameters; @@ -123,7 +128,13 @@ 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"; } else anActivatedPluginName = *aPlugins.rbegin(); diff --git a/tools/TKMessageModel/CMakeLists.txt b/tools/TKMessageModel/CMakeLists.txt new file mode 100644 index 0000000000..911ffb1fbe --- /dev/null +++ b/tools/TKMessageModel/CMakeLists.txt @@ -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 index 0000000000..54b02742af --- /dev/null +++ b/tools/TKMessageModel/EXTERNLIB @@ -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 index 0000000000..ca4f0e567b --- /dev/null +++ b/tools/TKMessageModel/FILES @@ -0,0 +1,2 @@ +EXTERNLIB +PACKAGES diff --git a/tools/TKMessageModel/PACKAGES b/tools/TKMessageModel/PACKAGES new file mode 100644 index 0000000000..9021fbf297 --- /dev/null +++ b/tools/TKMessageModel/PACKAGES @@ -0,0 +1 @@ +MessageModel diff --git a/tools/TKMessageView/CMakeLists.txt b/tools/TKMessageView/CMakeLists.txt new file mode 100644 index 0000000000..9b3c1aaec7 --- /dev/null +++ b/tools/TKMessageView/CMakeLists.txt @@ -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 index 0000000000..84e5b5d8b5 --- /dev/null +++ b/tools/TKMessageView/EXTERNLIB @@ -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 index 0000000000..ca4f0e567b --- /dev/null +++ b/tools/TKMessageView/FILES @@ -0,0 +1,2 @@ +EXTERNLIB +PACKAGES diff --git a/tools/TKMessageView/PACKAGES b/tools/TKMessageView/PACKAGES new file mode 100644 index 0000000000..46a67b229d --- /dev/null +++ b/tools/TKMessageView/PACKAGES @@ -0,0 +1 @@ +MessageView diff --git a/tools/ToolsDraw/ToolsDraw.cxx b/tools/ToolsDraw/ToolsDraw.cxx index c0abd7766a..104bda3336 100644 --- a/tools/ToolsDraw/ToolsDraw.cxx +++ b/tools/ToolsDraw/ToolsDraw.cxx @@ -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;" diff --git a/tools/VInspector/VInspector_Window.cxx b/tools/VInspector/VInspector_Window.cxx index 22ed9e50f6..d3ee3c9822 100644 --- a/tools/VInspector/VInspector_Window.cxx +++ b/tools/VInspector/VInspector_Window.cxx @@ -603,7 +603,7 @@ void VInspector_Window::onTreeViewSelectionChanged (const QItemSelection&, } SelectedShapes (aSelPresentations); - displayer()->DisplayPreview()->UpdatePreview (View_DisplayActionType_DisplayId, aSelPresentations, myViewWindow->ViewWidget()->DisplayMode()); + displayer()->DisplayPreview()->UpdatePreview (View_DisplayActionType_DisplayId, aSelPresentations, displayer()->DisplayMode()); } // ======================================================================= @@ -636,12 +636,12 @@ void VInspector_Window::onExportToShapeView() TCollection_AsciiString aPluginName ("TKShapeView"); NCollection_List aParameters; - if (myParameters->FindParameters (aPluginName)) - aParameters = myParameters->Parameters (aPluginName); + //if (myParameters->FindParameters (aPluginName)) + // aParameters = myParameters->Parameters (aPluginName); NCollection_List 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 +661,23 @@ void VInspector_Window::onExportToShapeView() } } - // search for objects to be exported - QList anItems = TreeModel_ModelBase::SelectedItems (myTreeView->selectionModel()->selectedIndexes()); - for (QList::const_iterator anItemIt = anItems.begin(); anItemIt != anItems.end(); ++anItemIt) - { - TreeModel_ItemBasePtr anItem = *anItemIt; - VInspector_ItemBasePtr aVItem = itemDynamicCast(anItem); - if (!aVItem) - 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()); - } + //// search for objects to be exported + //QList anItems = TreeModel_ModelBase::SelectedItems (myTreeView->selectionModel()->selectedIndexes()); + //for (QList::const_iterator anItemIt = anItems.begin(); anItemIt != anItems.end(); ++anItemIt) + //{ + // TreeModel_ItemBasePtr anItem = *anItemIt; + // VInspector_ItemBasePtr aVItem = itemDynamicCast(anItem); + // if (!aVItem) + // 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()); + //} if (anExportedPointers.isEmpty()) return;