]> OCCT Git - occt-copy.git/commitdiff
0029451: Information Message Alert to debug an algorithm or object functionality
authornds <nds@opencascade.com>
Fri, 4 Oct 2019 15:30:10 +0000 (18:30 +0300)
committernds <nds@opencascade.com>
Sun, 8 Dec 2019 18:29:36 +0000 (21:29 +0300)
(cherry picked from commit 1f64bcf7813ab6bad61310ae6f19539d133f1ac4)

#compilation correction is ammended
(cherry picked from commit 98d49da76f9c9403d2fa06916ff27bac71297180)

78 files changed:
adm/TOOLS
src/Graphic3d/Graphic3d_ClipPlane.cxx
src/Message/FILES
src/Message/Message.cxx
src/Message/Message.hxx
src/Message/Message_AlertExtended.cxx [new file with mode: 0644]
src/Message/Message_AlertExtended.hxx [new file with mode: 0644]
src/Message/Message_Alerts.hxx [new file with mode: 0644]
src/Message/Message_Attribute.cxx [new file with mode: 0644]
src/Message/Message_Attribute.hxx [new file with mode: 0644]
src/Message/Message_AttributeObject.cxx [new file with mode: 0644]
src/Message/Message_AttributeObject.hxx [new file with mode: 0644]
src/Message/Message_AttributeStream.cxx [new file with mode: 0644]
src/Message/Message_AttributeStream.hxx [new file with mode: 0644]
src/Message/Message_CompositeAlerts.cxx [new file with mode: 0644]
src/Message/Message_CompositeAlerts.hxx [new file with mode: 0644]
src/Message/Message_PerfMeter.cxx [new file with mode: 0644]
src/Message/Message_PerfMeter.hxx [new file with mode: 0644]
src/Message/Message_PerfMeterMode.hxx [new file with mode: 0644]
src/Message/Message_Report.cxx
src/Message/Message_Report.hxx
src/Message/Message_ReportCallBack.cxx [new file with mode: 0644]
src/Message/Message_ReportCallBack.hxx [new file with mode: 0644]
src/NCollection/NCollection_Mat4.hxx
src/OSD/OSD_MemInfo.cxx
src/OSD/OSD_MemInfo.hxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_MatrixState.hxx
src/TopoDS/FILES
src/TopoDS/TopoDS_AlertAttribute.cxx [new file with mode: 0644]
src/TopoDS/TopoDS_AlertAttribute.hxx [new file with mode: 0644]
src/XmlDrivers/FILES
src/XmlDrivers/XmlDrivers_MessageReportStorage.cxx [new file with mode: 0644]
src/XmlDrivers/XmlDrivers_MessageReportStorage.hxx [new file with mode: 0644]
tools/MessageModel/FILES [new file with mode: 0644]
tools/MessageModel/MessageModel.qrc [new file with mode: 0644]
tools/MessageModel/MessageModel_ActionType.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Actions.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Actions.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemAlert.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemAlert.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemBase.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemBase.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemReport.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemReport.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemRoot.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ItemRoot.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ReportCallBack.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_ReportCallBack.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Tools.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_Tools.hxx [new file with mode: 0644]
tools/MessageModel/MessageModel_TreeModel.cxx [new file with mode: 0644]
tools/MessageModel/MessageModel_TreeModel.hxx [new file with mode: 0644]
tools/MessageModel/icons/item_shape.png [new file with mode: 0644]
tools/MessageModel/icons/item_shape.svg [new file with mode: 0644]
tools/MessageModel/icons/item_vectorOfReal.png [new file with mode: 0644]
tools/MessageModel/icons/item_vectorOfReal.svg [new file with mode: 0644]
tools/MessageModel/icons/item_vectorOfRealVec3.png [new file with mode: 0644]
tools/MessageModel/icons/item_vectorOfRealVec3.svg [new file with mode: 0644]
tools/MessageModel/icons/item_vectorOfValues.png [new file with mode: 0644]
tools/MessageModel/icons/item_vectorOfValues.svg [new file with mode: 0644]
tools/MessageView/FILES [new file with mode: 0644]
tools/MessageView/MessageView_Communicator.cxx [new file with mode: 0644]
tools/MessageView/MessageView_Communicator.hxx [new file with mode: 0644]
tools/MessageView/MessageView_VisibilityState.cxx [new file with mode: 0644]
tools/MessageView/MessageView_VisibilityState.hxx [new file with mode: 0644]
tools/MessageView/MessageView_Window.cxx [new file with mode: 0644]
tools/MessageView/MessageView_Window.hxx [new file with mode: 0644]
tools/TKMessageModel/CMakeLists.txt [new file with mode: 0644]
tools/TKMessageModel/EXTERNLIB [new file with mode: 0644]
tools/TKMessageModel/FILES [new file with mode: 0644]
tools/TKMessageModel/PACKAGES [new file with mode: 0644]
tools/TKMessageView/CMakeLists.txt [new file with mode: 0644]
tools/TKMessageView/EXTERNLIB [new file with mode: 0644]
tools/TKMessageView/FILES [new file with mode: 0644]
tools/TKMessageView/PACKAGES [new file with mode: 0644]
tools/ToolsDraw/ToolsDraw.cxx
tools/TreeModel/TreeModel_ItemStream.cxx

index b106a7c10bca46ca90821160ae370e4e3d4d8a06..57ddcfcc647d3402a54f4626ffc7134b7bd1e7f1 100644 (file)
--- a/adm/TOOLS
+++ b/adm/TOOLS
@@ -1,4 +1,4 @@
-TModelingData TKShapeView
+TModelingData TKShapeView TKMessageModel TKMessageView
 TVisualization TKView TKVInspector
 TApplicationFramework TKTreeModel TKTInspectorAPI TKDFBrowser
 TTool TKTInspector TKToolsDraw TInspectorEXE
\ No newline at end of file
index 6ac691217a5ad71f21ab2df65d1837327ee77db4..9edaf4d8de6fb7e30e1ccad6bc722736057492e6 100755 (executable)
@@ -268,9 +268,9 @@ void Graphic3d_ClipPlane::SetChainNextPlane (const Handle(Graphic3d_ClipPlane)&
 // =======================================================================
 void Graphic3d_ClipPlane::DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth) const
 {
-  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myAspect.get());
+  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, mySectionStyle.get());
 
-  OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myId);
+  OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myEntityUID);
 
   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPlane);
 
index e502c6903c12729687f96d1fc5ac2c5cff4cd31f..9a4bf4a9826cad3ca423c82d4aef91dd34d2a155 100755 (executable)
@@ -1,8 +1,21 @@
 Message.cxx
 Message.hxx
+Message_Alert.cxx
+Message_Alert.hxx
+Message_AlertExtended.cxx
+Message_AlertExtended.hxx
+Message_Alerts.hxx
 Message_Algorithm.cxx
 Message_Algorithm.hxx
 Message_Algorithm.lxx
+Message_Attribute.cxx
+Message_Attribute.hxx
+Message_AttributeObject.cxx
+Message_AttributeObject.hxx
+Message_AttributeStream.cxx
+Message_AttributeStream.hxx
+Message_CompositeAlerts.cxx
+Message_CompositeAlerts.hxx
 Message_ExecStatus.hxx
 Message_Gravity.hxx
 Message_HArrayOfMsg.hxx
@@ -15,6 +28,9 @@ Message_Msg.hxx
 Message_Msg.lxx
 Message_MsgFile.cxx
 Message_MsgFile.hxx
+Message_PerfMeter.cxx
+Message_PerfMeter.hxx
+Message_PerfMeterMode.hxx
 Message_Printer.cxx
 Message_Printer.hxx
 Message_PrinterOStream.cxx
@@ -32,8 +48,8 @@ Message_SequenceOfPrinters.hxx
 Message_SequenceOfProgressScale.hxx
 Message_Status.hxx
 Message_StatusType.hxx
-Message_Alert.cxx
-Message_Alert.hxx
 Message_ListOfAlert.hxx
 Message_Report.cxx
 Message_Report.hxx
+Message_ReportCallBack.cxx
+Message_ReportCallBack.hxx
index b540ae5fb291a83a530de83e54e994db0e7cd51b..3aea6317a4a52ccda50642af82b1de6e5727f611 100644 (file)
@@ -49,3 +49,342 @@ TCollection_AsciiString Message::FillTime (const Standard_Integer hour,
     Sprintf (t, "%.2fs", second);
   return TCollection_AsciiString (t);
 }
+
+namespace
+{
+  static Standard_CString Message_Table_PrintGravityEnum[5] =
+  {
+    "TRACE", "INFO", "WARNING", "ALARM", "FAIL"
+  };
+
+  static Standard_CString Message_Table_PrintPerfMeterModeEnum[10] =
+  {
+    "NONE", "USER_TIME_CPU", "SYSTEM_TIME_CPU", "MEM_PRIVATE", "MEM_VIRTUAL",
+    "MEM_WORKING_SET", "MEM_WORKING_SET_PEAK", "MEM_SWAP_USAGE", "MEM_SWAP_USAGE_PEAK", "MEM_HEAP_USAGE"
+  };
+}
+
+//=======================================================================
+//function : GravityToString
+//purpose  :
+//=======================================================================
+
+Standard_CString Message::GravityToString (const Message_Gravity theGravity)
+{
+  return Message_Table_PrintGravityEnum[theGravity];
+}
+
+//=======================================================================
+//function : GravityFromString
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message::GravityFromString (const Standard_CString theGravityString,
+                                             Message_Gravity& theGravity)
+{
+  TCollection_AsciiString aName (theGravityString);
+  aName.UpperCase();
+  for (Standard_Integer aGravityIter = 0; aGravityIter <= Message_Fail; ++aGravityIter)
+  {
+    Standard_CString aGravityName = Message_Table_PrintGravityEnum[aGravityIter];
+    if (aName == aGravityName)
+    {
+      theGravity = Message_Gravity (aGravityIter);
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : PerfMeterModeToString
+//purpose  :
+//=======================================================================
+
+Standard_CString Message::PerfMeterModeToString (const Message_PerfMeterMode theValue)
+{
+  return Message_Table_PrintPerfMeterModeEnum[theValue];
+}
+
+//=======================================================================
+//function : PerfMeterModeFromString
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message::PerfMeterModeFromString (const Standard_CString theString,
+                                                   Message_PerfMeterMode& theValue)
+{
+  TCollection_AsciiString aName (theString);
+  aName.UpperCase();
+  for (Standard_Integer aModeIter = 0; aModeIter <= Message_PerfMeterMode_MemHeapUsage; ++aModeIter)
+  {
+    Standard_CString aModeName = Message_Table_PrintPerfMeterModeEnum[aModeIter];
+    if (aName == aModeName)
+    {
+      theValue = Message_PerfMeterMode (aModeIter);
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+// =======================================================================
+// function : GetPointerInfo
+// purpose :
+// =======================================================================
+TCollection_AsciiString Message::TransientToString (const Handle(Standard_Transient)& thePointer, const bool isShortInfo)
+{
+  if (thePointer.IsNull())
+    return TCollection_AsciiString();
+
+  return PointerToString(thePointer.operator->(), isShortInfo);
+}
+
+// =======================================================================
+// function : GetPointerInfo
+// purpose :
+// =======================================================================
+TCollection_AsciiString Message::PointerToString (const void* thePointer, const bool isShortInfo)
+{
+  std::ostringstream aPtrStr;
+  aPtrStr << thePointer;
+  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();
+}
+
+// =======================================================================
+// function : StrVectorToString
+// purpose :
+// =======================================================================
+TCollection_AsciiString Message::StrVectorToString
+    (const NCollection_Vector<TCollection_AsciiString>& theValues)
+{
+  TCollection_AsciiString aValue;
+  for (NCollection_Vector<TCollection_AsciiString>::Iterator aValuesIt (theValues); aValuesIt.More(); aValuesIt.Next())
+  {
+    aValue += aValuesIt.Value();
+    if (aValuesIt.More())
+      aValue += VectorSeparator();
+  }
+  return aValue;
+}
+
+// =======================================================================
+// function : StrVectorFromString
+// purpose :
+// =======================================================================
+Standard_Boolean Message::StrVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<TCollection_AsciiString>& theValues)
+{
+  TCollection_AsciiString aCurrentString = theValue, aValueString;
+
+  while (!aCurrentString.IsEmpty())
+  {
+    Standard_Integer aPosition = aCurrentString.Search (", ");
+    aValueString = aCurrentString;
+    if (aPosition > 0)
+      aCurrentString = aValueString.Split (aPosition - 1);
+    theValues.Append (aValueString.RealValue());
+    if (aPosition > 0)
+      aCurrentString = aCurrentString.Split (2);
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : RealVectorToString
+// purpose :
+// =======================================================================
+TCollection_AsciiString Message::RealVectorToString
+    (const NCollection_Vector<Standard_Real>& theValues)
+{
+  TCollection_AsciiString aValue = ("(");
+
+  for (NCollection_Vector<Standard_Real>::Iterator aValuesIt (theValues); aValuesIt.More(); aValuesIt.Next())
+  {
+    aValue += aValuesIt.Value();
+    if (aValuesIt.More())
+      aValue += VectorSeparator();
+  }
+  aValue += ")";
+
+  return aValue;
+}
+
+// =======================================================================
+// function : RealVectorFromString
+// purpose :
+// =======================================================================
+Standard_Boolean Message::RealVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<Standard_Real>& theValues)
+{
+  TCollection_AsciiString aCurrentString = theValue, aValueString;
+
+  Standard_Integer aPosition = aCurrentString.Search ("(");
+  if (aPosition != 1)
+    return Standard_False;
+  aCurrentString = aCurrentString.Split (aPosition);
+
+  aPosition = aCurrentString.Search (")");
+  if (aPosition != 1)
+    return Standard_False;
+  aValueString = aCurrentString.Split (aPosition);
+
+
+  while (!aCurrentString.IsEmpty())
+  {
+    // x value
+    aPosition = aCurrentString.Search (", ");
+    aValueString = aCurrentString;
+    if (aPosition > 0)
+      aCurrentString = aValueString.Split (aPosition - 1);
+    theValues.Append (aValueString.RealValue());
+    if (aPosition > 0)
+      aCurrentString = aCurrentString.Split (2);
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : CoordVectorToString
+// purpose :
+// =======================================================================
+TCollection_AsciiString Message::CoordVectorToString
+    (const NCollection_Vector<Standard_Real>& theValues)
+{
+  TCollection_AsciiString aValue = ("(");
+  aValue += RealVectorToString (theValues);
+  aValue += ")";
+
+  return aValue;
+}
+
+// =======================================================================
+// function : CoordVectorFromString
+// purpose :
+// =======================================================================
+Standard_Boolean Message::CoordVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<Standard_Real>& theValues)
+{
+  TCollection_AsciiString aCurrentString = theValue, aValueString;
+
+  Standard_Integer aPosition = aCurrentString.Search ("(");
+  if (aPosition != 1)
+    return Standard_False;
+  aCurrentString = aCurrentString.Split (aPosition);
+
+  aPosition = aCurrentString.Search (")");
+  if (aPosition != 1)
+    return Standard_False;
+  aValueString = aCurrentString.Split (aPosition);
+
+  return RealVectorFromString (aCurrentString, theValues); 
+}
+
+// =======================================================================
+// function : ColorVectorToString
+// purpose :
+// =======================================================================
+TCollection_AsciiString Message::ColorVectorToString
+    (const NCollection_Vector<Standard_Real>& theValues)
+{
+  TCollection_AsciiString aValue = ("[");
+  aValue += RealVectorToString (theValues);
+  aValue += "]";
+
+  return aValue;
+}
+
+// =======================================================================
+// function : ColorVectorFromString
+// purpose :
+// =======================================================================
+Standard_Boolean Message::ColorVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<Standard_Real>& theValues)
+{
+  TCollection_AsciiString aCurrentString = theValue, aValueString;
+
+  Standard_Integer aPosition = aCurrentString.Search ("[");
+  if (aPosition != 1)
+    return Standard_False;
+  aCurrentString = aCurrentString.Split (aPosition);
+
+  aPosition = aCurrentString.Search ("]");
+  if (aPosition != 1)
+    return Standard_False;
+  aValueString = aCurrentString.Split (aPosition);
+
+  return RealVectorFromString (aCurrentString, theValues); 
+}
+
+// =======================================================================
+// function : ConvertStream
+// purpose :
+// =======================================================================
+void Message::ConvertStream (const Standard_SStream& theStream,
+  Standard_Integer& theColumnCount,
+  NCollection_Vector<TCollection_AsciiString>& theValues)
+{
+  TCollection_AsciiString aStream (theStream.str().c_str());
+  Standard_Character aSeparator = Message::DumpSeparator();
+  Standard_Integer aColumnCount = 0;
+
+  TCollection_AsciiString aCurrentString = aStream;
+  Standard_Integer aPosition = aCurrentString.Search (aSeparator);
+  if (aPosition >= 1)
+  {
+    TCollection_AsciiString aTailString = aCurrentString.Split (aPosition);
+    Standard_Boolean aClassNameFound = Standard_False;
+    while (!aCurrentString.IsEmpty())
+    {
+      TCollection_AsciiString aValueString = aCurrentString;
+      aPosition = aValueString.Search (aSeparator);
+      if (aPosition < 0 )
+        break;
+      aCurrentString = aValueString.Split (aPosition - 1);
+
+      if (!aColumnCount)
+      {
+        if (!aClassNameFound)
+          aClassNameFound = Standard_True;
+        else
+        {
+          if (!aValueString.IsIntegerValue())
+            break; // not correct Dump, in correct the first value is number of property columns
+          aColumnCount = aValueString.IntegerValue();
+        }
+      }
+      else
+        theValues.Append (aValueString);
+
+      if (aTailString.IsEmpty())
+        break;
+      aCurrentString = aTailString;
+      aPosition = aCurrentString.Search (aSeparator);
+      if (aPosition < 0 )
+      {
+        aCurrentString = aTailString;
+        aTailString = TCollection_AsciiString();
+      }
+      else
+        aTailString = aCurrentString.Split (aPosition);
+    }
+  }
+  theColumnCount = aColumnCount;
+}
index 4be71135b3580949da7dbc6d0188305865d0634f..6c440bad812e517d388bfd8ac87358179c799066 100644 (file)
 #ifndef _Message_HeaderFile
 #define _Message_HeaderFile
 
+#include <Message_Gravity.hxx>
+#include <Message_PerfMeterMode.hxx>
+#include <NCollection_Vector.hxx>
+
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
 #include <Standard_Integer.hxx>
 #include <Standard_Real.hxx>
+#include <TCollection_AsciiString.hxx>
+
 class Message_Messenger;
-class TCollection_AsciiString;
 class Message_Msg;
 class Message_MsgFile;
 class Message_Messenger;
@@ -59,8 +64,129 @@ public:
   //! 3. (0,  0,  4.5   ) returns "4.50s"
   Standard_EXPORT static TCollection_AsciiString FillTime (const Standard_Integer Hour, const Standard_Integer Minute, const Standard_Real Second);
 
-
-
+  //! Returns the string name for a given gravity.
+  //! @param Gravity gravity type
+  //! @return string identifier from the list Message_Trace, Message_Info, Message_Warning, Message_Alarm and Message_Fail
+  Standard_EXPORT static Standard_CString GravityToString (const Message_Gravity theGravity);
+
+  //! Returns the gravity type from the given string identifier (using case-insensitive comparison).
+  //! @param theGravityString string identifier
+  //! @return gravity or Message_Trace if string identifier is invalid
+  static Message_Gravity GravityFromString (const Standard_CString theGravityString)
+  {
+    Message_Gravity aGravity = Message_Trace;
+    GravityFromString (theGravityString, aGravity);
+    return aGravity;
+  }
+
+  //! Determines the gravity from the given string identifier (using case-insensitive comparison).
+  //! @param theGravityString string identifier
+  //! @param theGravity detected shape type
+  //! @return TRUE if string identifier is known
+  Standard_EXPORT static Standard_Boolean GravityFromString (const Standard_CString theGravityString,
+                                                             Message_Gravity& theGravity);
+
+  //! Returns the string name for a perf meter mode.
+  //! @param theValue mode
+  //! @return string identifier
+  Standard_EXPORT static Standard_CString PerfMeterModeToString (const Message_PerfMeterMode theValue);
+
+  //! Returns the enum value from the given string identifier (using case-insensitive comparison).
+  //! @param theString string identifier
+  //! @return enum or Message_PerfMeterMode_None if string identifier is invalid
+  static Message_PerfMeterMode PerfMeterModeFromString (const Standard_CString theString)
+  {
+    Message_PerfMeterMode aValue = Message_PerfMeterMode_None;
+    PerfMeterModeFromString (theString, aValue);
+    return aValue;
+  }
+
+  //! Returns the enum value from the given string identifier (using case-insensitive comparison).
+  //! @param theString string identifier
+  //! @return enum or Message_PerfMeterMode_None if string identifier is invalid
+  //! @return TRUE if string identifier is known
+  Standard_EXPORT static Standard_Boolean PerfMeterModeFromString (const Standard_CString theString,
+                                                                   Message_PerfMeterMode& theValue);
+
+
+  //! Returns separator symbol of Dump information
+  static Standard_Character DumpSeparator() { return '\\'; }
+
+  //! Returns separator symbol of values vector union
+  static TCollection_AsciiString VectorSeparator() { return " ,"; }
+
+  //! Convert handle 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 TransientToString (const Handle(Standard_Transient)& thePointer,
+                                                                    const bool isShortInfo = true);
+
+  //! 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 PointerToString (const void* thePointer,
+                                                                  const bool isShortInfo = true);
+  //! Convert vector of real values to string, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static TCollection_AsciiString StrVectorToString
+    (const NCollection_Vector<TCollection_AsciiString>& theValues);
+
+  //! Convert string to vector of real values, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static Standard_Boolean StrVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<TCollection_AsciiString>& theValues);
+
+  //! Convert vector of real values to string, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static TCollection_AsciiString RealVectorToString
+    (const NCollection_Vector<Standard_Real>& theValues);
+
+  //! Convert string to vector of real values, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static Standard_Boolean RealVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<Standard_Real>& theValues);
+
+  //! Convert vector of real values to string, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static TCollection_AsciiString CoordVectorToString
+    (const NCollection_Vector<Standard_Real>& theValues);
+
+  //! Convert string to vector of real values, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static Standard_Boolean CoordVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<Standard_Real>& theValues);
+
+  //! Convert vector of real values to string, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static TCollection_AsciiString ColorVectorToString
+    (const NCollection_Vector<Standard_Real>& theValues);
+
+  //! Convert string to vector of real values, separator is vector separator
+  //! \param thePointer a container of real values
+  //! \return the string value
+  Standard_EXPORT static Standard_Boolean ColorVectorFromString
+    (const TCollection_AsciiString& theValue,
+     NCollection_Vector<Standard_Real>& theValues);
+
+  //! Converts stream to vector of values and column count
+  //! \param theStream stream value
+  //! \param theColumnCount [out] number of columns
+  //! \param theValues [out] container of split values
+  static Standard_EXPORT void ConvertStream (const Standard_SStream& theStream,
+    Standard_Integer& theColumnCount,
+    NCollection_Vector<TCollection_AsciiString>& theValues);
 
 protected:
 
diff --git a/src/Message/Message_AlertExtended.cxx b/src/Message/Message_AlertExtended.cxx
new file mode 100644 (file)
index 0000000..44555fc
--- /dev/null
@@ -0,0 +1,81 @@
+// 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 <Message_AlertExtended.hxx>
+#include <Message_Attribute.hxx>
+#include <Message_CompositeAlerts.hxx>
+#include <Message_Report.hxx>
+
+#include <Precision.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_AlertExtended,Message_Alert)
+
+//=======================================================================
+//function : GetMessageKey
+//purpose  :
+//=======================================================================
+
+Standard_CString Message_AlertExtended::GetMessageKey () const
+{
+  if (myAttribute.IsNull())
+    return Message_Alert::GetMessageKey();
+
+  return myAttribute->GetMessageKey();
+}
+
+//=======================================================================
+//function : GetCompositeAlerts
+//purpose  : 
+//=======================================================================
+
+Handle (Message_CompositeAlerts) Message_AlertExtended::GetCompositeAlerts (const Standard_Boolean isCreate)
+{
+  if (myCompositAlerts.IsNull() && isCreate)
+    myCompositAlerts = new Message_CompositeAlerts();
+
+  return myCompositAlerts;
+}
+
+//=======================================================================
+//function : IsMetricValid
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean Message_AlertExtended::IsMetricValid() const
+{
+  return fabs (myMetricStart - GetUndefinedMetric()) > Precision::Confusion() &&
+         fabs (myMetricStop  - GetUndefinedMetric()) > Precision::Confusion();
+}
+
+//=======================================================================
+//function : AddAlert
+//purpose  : 
+//=======================================================================
+
+Handle(Message_Alert) Message_AlertExtended::AddAlert (const Handle(Message_Report)& theReport,
+                                                       const Handle(Message_Attribute)& theAttribute,
+                                                       Message_PerfMeter* thePerfMeter,
+                                                       const Handle(Message_Alert)& theParentAlert)
+{
+  if (!theReport->IsActive (Message_Info))
+    return Handle(Message_Alert)();
+
+  Handle(Message_AlertExtended) anAlert = new Message_AlertExtended();
+  anAlert->SetAttribute (theAttribute);
+  theReport->AddAlert (Message_Info, anAlert, thePerfMeter, theParentAlert);
+
+  return anAlert;
+}
diff --git a/src/Message/Message_AlertExtended.hxx b/src/Message/Message_AlertExtended.hxx
new file mode 100644 (file)
index 0000000..bac7047
--- /dev/null
@@ -0,0 +1,133 @@
+// 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 _Message_AlertExtended_HeaderFile
+#define _Message_AlertExtended_HeaderFile
+
+#include <Message_Alert.hxx>
+#include <TCollection_AsciiString.hxx>
+
+class Message_Attribute;
+class Message_PerfMeter;
+class Message_Report;
+
+DEFINE_STANDARD_HANDLE(Message_AlertExtended, Message_Alert)
+
+class Message_CompositeAlerts;
+
+//! Inherited class of Message_Alert with some additional information.
+//!
+//! It has Message_Attributes to provide the alert name, description and
+//! other custom information
+//!
+//! It is possible to set performance meter into alert to store time/memory metric information
+//! spent between the next alert adding. Also time of child alerts are collected
+//!
+//! It has a container of composite alerts, if the alert might provide
+//! sub-alerts collecting.
+//!
+
+class Message_AlertExtended : public Message_Alert
+{
+public:
+  //! Empty constructor
+  Standard_EXPORT Message_AlertExtended()
+    : Message_Alert(), myMetricStart (GetUndefinedMetric()), myMetricStop (GetUndefinedMetric()) {}
+
+  //! Return a C string to be used as a key for generating text user 
+  //! messages describing this alert.
+  //! The messages are generated with help of Message_Msg class, in
+  //! Message_Report::Dump().
+  //! Base implementation returns dynamic type name of the instance.
+  virtual Standard_EXPORT Standard_CString GetMessageKey () const;
+
+  //! Sets container of the alert attributes
+  //! \param theAttributes an attribute values
+  void SetAttribute (const Handle(Message_Attribute)& theAttribute) { myAttribute = theAttribute; }
+
+  //! Returns container of the alert attributes
+  //! \param theAttributes an attribute values
+  const Handle(Message_Attribute)& Attribute () const { return myAttribute; }
+
+  //! Returns class provided hierarchy of alerts if created or create if the parameter is true
+  //! \param isCreate if composite alert has not been created for this alert, it should be created
+  //! \return instance or NULL
+  Standard_EXPORT Handle (Message_CompositeAlerts) GetCompositeAlerts (const Standard_Boolean isCreate = Standard_False);
+
+  //! Returns performance meter
+  //! \return instance or NULL
+  Message_PerfMeter* GetPerfMeter() { return myPerfMeter; }
+
+  //! Returns true if metric is computed
+  //! @return value
+  Standard_EXPORT Standard_Boolean IsMetricValid() const;
+
+  //! Returns the alert cumulative metric. It includes time/mem of sub alerts
+  //! @return value
+  Standard_Real MetricStart() const { return myMetricStart; }
+
+  //! Returns the alert cumulative metric. It includes time/mem of sub alerts
+  //! @return value
+  Standard_Real MetricStop() const { return myMetricStop; }
+
+  //! Sets cumulative time/mem of alert
+  //! \param theCumulativeMetric time/mem of the alert
+  void SetMetricValues (const Standard_Real theStartValue, const Standard_Real theStopValue)
+    { myMetricStart = theStartValue; myMetricStop = theStopValue; }
+
+  //! Return true if this type of alert can be merged with other
+  //! of the same type to avoid duplication.
+  //! Basis implementation returns true.
+  virtual Standard_EXPORT Standard_Boolean SupportsMerge () const { return Standard_False; }
+
+  //! Returns default value of the time/mem when it is not defined
+  //! \return integer value
+  static Standard_Real GetUndefinedMetric() { return -1.0; }
+
+  //! Creates new instance of the alert and put it into report with Message_Info gravity.
+  //! It does nothing if such kind of gravity is not active in the report
+  //! @param theReport the message report where new alert is placed
+  //! @param theAttribute container of additional values of the alert
+  //! @param thePerfMeter performance meter calculates the alert spent time and participate in searching the last alert if needed
+  //! @param theParentAlert parent for the new alert, or alert is placed under the report
+  //! @return created alert or NULL if Message_Info is not active in report
+  static Standard_EXPORT Handle(Message_Alert) AddAlert (const Handle(Message_Report)& theReport,
+                                                         const Handle(Message_Attribute)& theAttribute,
+                                                         Message_PerfMeter* thePerfMeter,
+                                                         const Handle(Message_Alert)& theParentAlert = Handle(Message_Alert)());
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_AlertExtended, Message_Alert)
+
+protected:
+  //! Sets performance meter
+  //! \param theMeter instance pointer or NULL
+  void SetPerfMeter (Message_PerfMeter* theMeter) { myPerfMeter = theMeter; }
+
+protected:
+
+  Handle(Message_CompositeAlerts) myCompositAlerts; //!< class provided hierarchical structure of alerts
+  //!< It should be created by an attempt of a child alert creation
+
+  Handle(Message_Attribute) myAttribute; //!< container of the alert attributes
+
+  Message_PerfMeter* myPerfMeter; //!< performance meter
+  Standard_Real myMetricStart; //!< value on start metric computation
+  Standard_Real myMetricStop; //!< value on stop metric computation
+
+  friend Message_PerfMeter;
+};
+
+#endif // _Message_Alert_HeaderFile
diff --git a/src/Message/Message_Alerts.hxx b/src/Message/Message_Alerts.hxx
new file mode 100644 (file)
index 0000000..9f73a1f
--- /dev/null
@@ -0,0 +1,102 @@
+// 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 _Message_Alerts_HeaderFile
+#define _Message_Alerts_HeaderFile
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeObject.hxx>
+#include <Message_AttributeStream.hxx>
+#include <Message_Gravity.hxx>
+#include <Message_Report.hxx>
+
+#include <NCollection_Vector.hxx>
+#include <TCollection_AsciiString.hxx>
+
+static Handle(Message_Alert) OCCT_Message_Alert;
+
+#define MESSAGE_INFO(Name, Description, PerfMeter, ParentAlert) \
+  { \
+    if (!Message_Report::CurrentReport().IsNull() && \
+         Message_Report::CurrentReport()->IsActive (Message_Info)) \
+    { \
+      OCCT_Message_Alert = Message_AlertExtended::AddAlert (Message_Report::CurrentReport(), \
+        new Message_Attribute (Name, Description), PerfMeter, ParentAlert); \
+    } \
+  }
+
+#define MESSAGE_INFO_OBJECT(Object, StreamValues, Name, Description, PerfMeter, ParentAlert) \
+  { \
+    if (!Message_Report::CurrentReport().IsNull() && \
+         Message_Report::CurrentReport()->IsActive (Message_Info)) \
+    { \
+      OCCT_Message_Alert = Message_AlertExtended::AddAlert (Message_Report::CurrentReport(), \
+        new Message_AttributeObject (Object, StreamValues, Name, Description), PerfMeter, ParentAlert ); \
+    } \
+  }
+
+#define MESSAGE_INFO_STREAM(StreamValues, Name, Description, PerfMeter, ParentAlert) \
+  { \
+    if (!Message_Report::CurrentReport().IsNull() && \
+         Message_Report::CurrentReport()->IsActive (Message_Info)) \
+    { \
+      OCCT_Message_Alert = Message_AlertExtended::AddAlert (Message_Report::CurrentReport(), \
+        new Message_AttributeStream (StreamValues, Name, Description), PerfMeter, ParentAlert ); \
+    } \
+  }
+
+//#define DUMP_VALUE(OS, Value) \
+//  { \
+//    OS << Value << Message::DumpSeparator(); \
+//  }
+//
+//#define DUMP_VALUES_COLUMNS(OS, ObjectName, ColumnCount) \
+//  { \
+//    OS << ObjectName << Message::DumpSeparator() << ColumnCount << Message::DumpSeparator(); \
+//  }
+//
+//#define DUMP_VALUES(OS, Value1, Value2) \
+//  { \
+//    OS << Value1 << Message::DumpSeparator() << Value2 << Message::DumpSeparator(); \
+//  }
+//
+//#define DUMP_VEC_COLOR(Values, Value) \
+//  { \
+//    Value = Message::ColorVectorToString (aValues); \
+//  }
+//
+//#define DUMP_VEC_COLOR_SPLIT(Value, Values) \
+//  { \
+//    Message::ColorVectorFromString (Value, Values); \
+//  }
+//
+//#define DUMP_VEC_COORD(Values, Value) \
+//  { \
+//    Value = Message::CoordVectorToString (aValues); \
+//  }
+//
+//#define DUMP_VEC_COORD_SPLIT(Value, Values) \
+//  { \
+//    Message::CoordVectorFromString (Value, Values); \
+//  }
+//
+//
+//#define DUMP_VALUES_SPLIT(OS, ColumnCount, Values) \
+//  { \
+//    Message::ConvertStream (OS, aColumnCount, aValues); \
+//  }
+
+#endif // _Message_Alerts_HeaderFile
diff --git a/src/Message/Message_Attribute.cxx b/src/Message/Message_Attribute.cxx
new file mode 100644 (file)
index 0000000..b76c1cb
--- /dev/null
@@ -0,0 +1,30 @@
+// 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 <Message_Attribute.hxx>
+
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_Attribute, Standard_Transient)
+
+//=======================================================================
+//function : GetMessageKey
+//purpose  :
+//=======================================================================
+
+Standard_CString Message_Attribute::GetMessageKey () const
+{
+  return !myName.IsEmpty() ? myName.ToCString() : "";
+}
diff --git a/src/Message/Message_Attribute.hxx b/src/Message/Message_Attribute.hxx
new file mode 100644 (file)
index 0000000..f27b332
--- /dev/null
@@ -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 _Message_Attribute_HeaderFile
+#define _Message_Attribute_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <TCollection_AsciiString.hxx>
+
+DEFINE_STANDARD_HANDLE(Message_Attribute, Standard_Transient)
+
+//! Additional information of extended alert attribute
+//! To provide other custom attribute container, it might be redefined.
+class Message_Attribute : public Standard_Transient
+{
+public:
+  //! Empty constructor
+  Standard_EXPORT Message_Attribute (const TCollection_AsciiString& theName = TCollection_AsciiString(),
+                                     const TCollection_AsciiString& theDescription = TCollection_AsciiString())
+    : myName (theName), myDescription (theDescription) {}
+
+  //! Return a C string to be used as a key for generating text user 
+  //! messages describing this alert.
+  //! The messages are generated with help of Message_Msg class, in
+  //! Message_Report::Dump().
+  //! Base implementation returns dynamic type name of the instance.
+  virtual Standard_EXPORT Standard_CString GetMessageKey () const;
+
+  //! Returns custom name of alert if it is set
+  //! @return alert name
+  const TCollection_AsciiString& GetName() const { return myName; }
+
+  //! Sets the custom name of alert
+  //! @param theName a name for the alert
+  void SetName (const TCollection_AsciiString& theName) { myName = theName; }
+
+  //! Sets desription of alert
+  //! @param theName a name for the alert
+  void SetDescription (const TCollection_AsciiString& theDescription) { myDescription = theDescription; }
+
+  //! Returns description of alert if it is set
+  //! @return alert description
+  virtual const TCollection_AsciiString& GetDescription() const { return myDescription; }
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_Attribute, Standard_Transient)
+
+private:
+
+  TCollection_AsciiString myName; //!< alert name, if defined is used in GetMessageKey
+  TCollection_AsciiString myDescription; //!< alert description if defined
+
+};
+
+#endif // _Message_Attribute_HeaderFile
diff --git a/src/Message/Message_AttributeObject.cxx b/src/Message/Message_AttributeObject.cxx
new file mode 100644 (file)
index 0000000..b31ad97
--- /dev/null
@@ -0,0 +1,32 @@
+// 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 <Message_AttributeObject.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_AttributeObject, Message_AttributeStream)
+
+//=======================================================================
+//function : Message_AttributeObject
+//purpose  : 
+//=======================================================================
+
+Message_AttributeObject::Message_AttributeObject (const Handle(Standard_Transient)& theObject,
+                                                  const Standard_SStream& theStream,
+                                                  const TCollection_AsciiString& theName,
+                                                  const TCollection_AsciiString& theDescription)
+: Message_AttributeStream (theStream, theName, theDescription)
+{
+  myObject = theObject;
+}
diff --git a/src/Message/Message_AttributeObject.hxx b/src/Message/Message_AttributeObject.hxx
new file mode 100644 (file)
index 0000000..29e45e9
--- /dev/null
@@ -0,0 +1,46 @@
+// 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 _Message_AttributeObject_HeaderFile
+#define _Message_AttributeObject_HeaderFile
+
+#include <Message_AttributeStream.hxx>
+#include <TCollection_AsciiString.hxx>
+
+//! Alert object storing Transient object in its field
+class Message_AttributeObject : public Message_AttributeStream
+{
+public:
+  //! Constructor with string argument
+  Standard_EXPORT Message_AttributeObject (const Handle(Standard_Transient)& theObject,
+    const Standard_SStream& theStream,
+    const TCollection_AsciiString& theName = TCollection_AsciiString(),
+    const TCollection_AsciiString& theDescription = TCollection_AsciiString());
+
+  //! Sets the object
+  //! @param theObject an instance
+  void SetObject (const Handle(Standard_Transient)& theObject) { myObject = theObject; }
+
+  //! Returns object
+  Handle(Standard_Transient) GetObject() const { return myObject; }
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_AttributeObject, Message_AttributeStream)
+
+private:
+  Handle(Standard_Transient) myObject;
+};
+
+#endif // _Message_AttributeObject_HeaderFile
diff --git a/src/Message/Message_AttributeStream.cxx b/src/Message/Message_AttributeStream.cxx
new file mode 100644 (file)
index 0000000..0e4ed5f
--- /dev/null
@@ -0,0 +1,47 @@
+// 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 <Message_AttributeStream.hxx>
+
+#include <Message.hxx>
+#include <Message_Msg.hxx>
+#include <Message_PerfMeter.hxx>
+#include <Message_Report.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_AttributeStream, Message_Attribute)
+
+//=======================================================================
+//function : SetValues
+//purpose  : 
+//=======================================================================
+Message_AttributeStream::Message_AttributeStream (const Standard_SStream& theStream,
+                                                  const TCollection_AsciiString& theName,
+                                                  const TCollection_AsciiString& theDescription)
+: Message_Attribute(theName, theDescription)
+{
+  SetStream (theStream);
+}
+
+//=======================================================================
+//function : SetStream
+//purpose  : 
+//=======================================================================
+
+void Message_AttributeStream::SetStream (const Standard_SStream& theStream)
+{
+  TCollection_AsciiString aStreamStr (theStream.str().c_str());
+  myStream << aStreamStr;
+}
+
diff --git a/src/Message/Message_AttributeStream.hxx b/src/Message/Message_AttributeStream.hxx
new file mode 100644 (file)
index 0000000..c0a3218
--- /dev/null
@@ -0,0 +1,50 @@
+// 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 _Message_AttributeStream_HeaderFile
+#define _Message_AttributeStream_HeaderFile
+
+#include <Message_Attribute.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <NCollection_Vector.hxx>
+
+class Message_PerfMeter;
+class Message_Report;
+
+//! Alert object storing container of Standard_Real values in its field
+class Message_AttributeStream : public Message_Attribute
+{
+public:
+
+  //! Constructor with string argument
+  Standard_EXPORT Message_AttributeStream (const Standard_SStream& theStream,
+                                           const TCollection_AsciiString& theName = TCollection_AsciiString(),
+                                           const TCollection_AsciiString& theDescription = TCollection_AsciiString());
+
+  //! Sets stream value
+  Standard_EXPORT void SetStream (const Standard_SStream& theStream);
+
+  //! Returns stream value
+  const Standard_SStream& GetStream() const { return myStream; }
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_AttributeStream, Message_Attribute)
+
+private:
+  Standard_SStream myStream; //!< container of values
+};
+
+#endif // _Message_AttributeStream_HeaderFile
diff --git a/src/Message/Message_CompositeAlerts.cxx b/src/Message/Message_CompositeAlerts.cxx
new file mode 100644 (file)
index 0000000..bf390d4
--- /dev/null
@@ -0,0 +1,69 @@
+// 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 <Message_CompositeAlerts.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_CompositeAlerts, Standard_Transient)
+
+//=======================================================================
+//function : Merge
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean Message_CompositeAlerts::Merge (const Handle(Message_Alert)& theTarget)
+{
+  Handle(Message_AlertExtended) anExtAlert = Handle(Message_AlertExtended)::DownCast (theTarget);
+  if (!anExtAlert.IsNull() && !anExtAlert->GetCompositeAlerts().IsNull())
+  {
+    Handle(Message_CompositeAlerts) anExtCompositeAlert = anExtAlert->GetCompositeAlerts();
+    // hierarchical alerts can not be merged
+    for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+    {
+      if (!GetAlerts ((Message_Gravity)iGravity).IsEmpty() ||
+          !anExtCompositeAlert->GetAlerts ((Message_Gravity)iGravity).IsEmpty())
+        return Standard_False;
+    }
+  }
+  // by default, merge trivially
+  return Standard_True;
+}
+
+//=======================================================================
+//function : GetAlerts
+//purpose  :
+//=======================================================================
+
+Message_ListOfAlert& Message_CompositeAlerts::GetAlerts (const Message_Gravity theGravity)
+{
+  return myChildAlerts[theGravity];
+}
+
+//=======================================================================
+//function : HasAlerts
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message_CompositeAlerts::HasAlert (const Handle(Message_Alert)& theAlert)
+{
+  for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+  {
+    Message_ListOfAlert& anAlerts = GetAlerts ((Message_Gravity)iGravity);
+    if (anAlerts.Contains (theAlert))
+      return Standard_True;
+  }
+  return Standard_False;
+}
diff --git a/src/Message/Message_CompositeAlerts.hxx b/src/Message/Message_CompositeAlerts.hxx
new file mode 100644 (file)
index 0000000..f069d45
--- /dev/null
@@ -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 _Message_CompositeAlerts_HeaderFile
+#define _Message_CompositeAlerts_HeaderFile
+
+#include <Message_Alert.hxx>
+#include <Message_Gravity.hxx>
+#include <Message_ListOfAlert.hxx>
+#include <Standard_Transient.hxx>
+
+class Message_CompositeAlerts;
+DEFINE_STANDARD_HANDLE(Message_CompositeAlerts, Standard_Transient)
+
+//! Base class of the hierarchy of classes describing various situations
+//! occurring during execution of some algorithm or procedure.
+//!
+//! Alert should provide unique text identifier that can be used to distinguish 
+//! particular type of alerts, e.g. to get text message string describing it. 
+//! See method GetMessageKey(); by default, dynamic type name is used.
+//!
+//! Alert can contain some data. To avoid duplication of data, new alert
+//! can be merged with another one of the same type. Method SupportsMerge() 
+//! should return true if merge is supported; method Merge() should do the
+//! merge if possible and return true in that case and false otherwise.
+//! 
+class Message_CompositeAlerts : public Standard_Transient
+{
+public:
+  //! Empty constructor
+  Standard_EXPORT Message_CompositeAlerts () {}
+
+  //! If possible, merge data contained in this alert to theTarget.
+  //! @return True if merged.
+  //! Base implementation always returns true.
+  virtual Standard_EXPORT Standard_Boolean Merge (const Handle(Message_Alert)& theTarget);
+  
+  //! Returns list of collected alerts with specified gravity
+  Standard_EXPORT Message_ListOfAlert& GetAlerts (const Message_Gravity theGravity);
+
+  //! Returns true if the alert belong the list of the child alerts.
+  //! \param theAlert an alert to be checked as a child alert
+  //! \return true if the alert is found in a container of children
+  Standard_EXPORT Standard_Boolean HasAlert (const Handle(Message_Alert)& theAlert);
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_CompositeAlerts,Standard_Transient)
+
+protected:
+  // store messages in a lists sorted by gravity;
+  // here we rely on knowledge that Message_Fail is the last element of the enum
+  Message_ListOfAlert myChildAlerts[Message_Fail + 1];
+};
+
+#endif // _Message_CompositeAlerts_HeaderFile
diff --git a/src/Message/Message_PerfMeter.cxx b/src/Message/Message_PerfMeter.cxx
new file mode 100644 (file)
index 0000000..d602574
--- /dev/null
@@ -0,0 +1,192 @@
+// 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 <Message_PerfMeter.hxx>
+
+#include <Message_AlertExtended.hxx>
+#include <Message_CompositeAlerts.hxx>
+
+#include <OSD_Chronometer.hxx>
+#include <OSD_MemInfo.hxx>
+
+//=======================================================================
+//function : Destructor
+//purpose  :
+//=======================================================================
+
+Message_PerfMeter::~Message_PerfMeter()
+{
+  releaseAlert (0);
+}
+
+//=======================================================================
+//function : GetAlert
+//purpose  :
+//=======================================================================
+
+Handle(Message_AlertExtended) Message_PerfMeter::GetAlert (const Standard_Integer theLevelId) const
+{
+  if (!myActiveAlerts.IsBound (theLevelId))
+    return Handle(Message_AlertExtended)();
+
+  return myActiveAlerts.Find (theLevelId).myAlert;
+}
+
+//=======================================================================
+//function : AddAlert
+//purpose  :
+//=======================================================================
+
+void Message_PerfMeter::AddAlert (const Handle(Message_Alert)& theAlert,
+                                  const Message_PerfMeterMode theMode)
+{
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (theAlert);
+  if (anExtendedAlert.IsNull())
+    return;
+
+  if (myActiveAlerts.IsEmpty())
+  {
+    setAlert (0, theAlert, theMode);
+    return;
+  }
+
+  Standard_Integer aSize = myActiveAlerts.Size();
+  // looking for the parent of the parameter alert to release the previous alert
+  for (Standard_Integer aLevelId = 0; aLevelId < aSize; aLevelId++)
+  {
+    Handle(Message_AlertExtended) anAlert = GetAlert (aLevelId);
+    Handle(Message_CompositeAlerts) aCompositeAlert = anAlert->GetCompositeAlerts();
+    Standard_ASSERT_RETURN (! aCompositeAlert.IsNull(), "Any alert of the performance meter has composite and children",);
+    if (!aCompositeAlert->HasAlert (theAlert))
+      continue;
+    // parent alert is found
+    if (myActiveAlerts.IsBound (aLevelId + 1))
+      releaseAlert (aLevelId + 1);
+
+    setAlert (aLevelId + 1, theAlert, theMode);
+    return;
+  }
+  Standard_Boolean isDone = Standard_True;
+  Standard_ASSERT_RETURN (!isDone, "Alert should be processed above",);
+}
+
+//=======================================================================
+//function : setAlert
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message_PerfMeter::setAlert (const Standard_Integer theLevelId,
+                                              const Handle(Message_Alert)& theAlert,
+                                              const Message_PerfMeterMode theMode)
+{
+  if (!GetAlert (theLevelId).IsNull())
+    return Standard_False;
+
+  Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast (theAlert);
+  if (anAlertExtended.IsNull())
+    return Standard_False;
+
+  myActiveAlerts.Bind (theLevelId, AlertInfo (anAlertExtended, getCurrentInfo (theMode)));
+  anAlertExtended->SetPerfMeter (this);
+  myMode = theMode;
+  return Standard_True;
+}
+
+//=======================================================================
+//function : releaseAlert
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message_PerfMeter::releaseAlert (const Standard_Integer theLevelId)
+{
+  // release alerts from the tail till the given alert
+  for (Standard_Integer aLevelId = myActiveAlerts.Extent() - 1; aLevelId >= theLevelId; aLevelId--)
+  {
+    if (!myActiveAlerts.IsBound (aLevelId))
+      continue;
+    stopAlert (aLevelId);
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : stopAlert
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message_PerfMeter::stopAlert (const Standard_Integer theLevelId)
+{
+  if (!myActiveAlerts.IsBound (theLevelId))
+    return Standard_False;
+
+  AlertInfo anAlertInfo = myActiveAlerts.Find (theLevelId);
+  Handle(Message_AlertExtended) anExtendedAlert = anAlertInfo.myAlert;
+
+  anExtendedAlert->SetMetricValues (anAlertInfo.myStartValue, getCurrentInfo(myMode));
+  anExtendedAlert->SetPerfMeter (0);
+  myActiveAlerts.UnBind (theLevelId);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : getLevel
+//purpose  :
+//=======================================================================
+
+Standard_Integer Message_PerfMeter::getLevel (const Handle(Message_Alert)& theAlert)
+{
+  for (NCollection_DataMap<Standard_Integer, AlertInfo>::Iterator anIterator (myActiveAlerts);
+    anIterator.More(); anIterator.Next())
+  {
+    if (anIterator.Value().myAlert == theAlert)
+      return anIterator.Key();
+  }
+  return -1;
+}
+
+//=======================================================================
+//function : getCurrentInfo
+//purpose  :
+//=======================================================================
+
+Standard_Real Message_PerfMeter::getCurrentInfo (const Message_PerfMeterMode theMode)
+{
+  if (theMode == Message_PerfMeterMode_UserTimeCPU ||
+      theMode == Message_PerfMeterMode_SystemTimeInfo)
+  {
+    Standard_Real aUserSeconds, aSystemSeconds;
+    OSD_Chronometer::GetThreadCPU (aUserSeconds, aSystemSeconds);
+    return theMode == Message_PerfMeterMode_UserTimeCPU ? aUserSeconds : aSystemSeconds;
+  }
+
+  OSD_MemInfo::Counter aType;
+  switch (theMode)
+  {
+    case Message_PerfMeterMode_MemPrivate:        aType = OSD_MemInfo::MemPrivate; break;
+    case Message_PerfMeterMode_MemVirtual:        aType = OSD_MemInfo::MemVirtual; break;
+    case Message_PerfMeterMode_MemWorkingSet:     aType = OSD_MemInfo::MemWorkingSet; break;
+    case Message_PerfMeterMode_MemWorkingSetPeak: aType = OSD_MemInfo::MemWorkingSetPeak; break;
+    case Message_PerfMeterMode_MemSwapUsage:      aType = OSD_MemInfo::MemSwapUsage; break;
+    case Message_PerfMeterMode_MemSwapUsagePeak:  aType = OSD_MemInfo::MemSwapUsagePeak; break;
+    case Message_PerfMeterMode_MemHeapUsage:      aType = OSD_MemInfo::MemHeapUsage; break;
+    default: return Message_AlertExtended::GetUndefinedMetric(); break;
+  }
+
+  OSD_MemInfo aMemInfo (Standard_False);
+  aMemInfo.Update (aType);
+  return (Standard_Real)aMemInfo.ValuePreciseMiB (aType);
+}
diff --git a/src/Message/Message_PerfMeter.hxx b/src/Message/Message_PerfMeter.hxx
new file mode 100644 (file)
index 0000000..d9f85bd
--- /dev/null
@@ -0,0 +1,97 @@
+// 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 _Message_PerfMeter_HeaderFile
+#define _Message_PerfMeter_HeaderFile
+
+#include <Message_AlertExtended.hxx>
+#include <Message_Gravity.hxx>
+#include <Message_PerfMeterMode.hxx>
+
+#include <NCollection_DataMap.hxx>
+#include <Standard.hxx>
+
+//! This class is performance meter for message alerts. The usage is create the simple instance of it (not a pointer)
+//! in a method. Finalizing of the method will call destructor of the meter and store time into alert.
+class Message_PerfMeter
+{
+
+public:
+  //! Constructs and starts (if autoStart is true) the named meter
+  //! One string key is used for all alert meters. The perf meter is not started automatically, it will be done in
+  //! AddAlert method
+  Message_PerfMeter() : myGravity (Message_Info), myMode (Message_PerfMeterMode_None) {}
+
+  //! Assures stopping upon destruction
+  Standard_EXPORT ~Message_PerfMeter();
+
+  //! Returns message alert on the level, by default the upper alert is returned
+  //! \param theLevelId a level of child position inside the upper alert of performance meter
+  //! \return alert instance or NULL
+  Handle(Message_AlertExtended) GetAlert (const Standard_Integer theLevelId = 0) const;
+
+  //! Processes the parameter alert. There are some variants:
+  //! - current alert is NULL, the alert becomes the current one and perf meter is started
+  //! - last alert of the current alert is stopped (perf meter becomes NULL, time is calculated),
+  //! the parameter alert is started (perf meter becomes the current one)
+  Standard_EXPORT void AddAlert (const Handle(Message_Alert)& theAlert,
+                                 const Message_PerfMeterMode theMode);
+
+protected:
+
+  //! Sets message alert on the level
+  //! \param theLevelId a level of child position inside the upper alert of performance meter
+  //! \param theAlert an alert to be stored
+  //! \return true if succeeded, false if there is stored alert on the given level
+  Standard_Boolean setAlert (const Standard_Integer theLevelId,
+                             const Handle(Message_Alert)& theAlert,
+                             const Message_PerfMeterMode theMode);
+
+  //! Stop alert, store time into the alert and last child alert
+  //! \param theLevelId a level of child position inside the upper alert of performance meter
+  Standard_Boolean releaseAlert (const Standard_Integer theLevelId);
+
+  //! Sets NULL perf meter and parameter time into the alert
+  //! \param theLevelId a level of child position inside the upper alert of performance meter
+  Standard_Boolean stopAlert (const Standard_Integer theLevelId);
+
+  //! Returns level of given alert if it participates in the performance meter
+  //! \param theAlert modified alert
+  //! \return level value or -1
+  Standard_Integer getLevel (const Handle(Message_Alert)& theAlert);
+
+  //! Returns cumulative info of the performance meter
+  //! \param theMeterId a performance meter index
+  //! \return time value
+  static Standard_Real getCurrentInfo (const Message_PerfMeterMode theMode);
+
+protected:
+  //! Struct to store start time for the alert
+  struct AlertInfo
+  {
+    AlertInfo (const Handle(Message_AlertExtended)& theAlert, Standard_Real theStartValue)
+      : myAlert (theAlert), myStartValue (theStartValue) {}
+
+    Handle(Message_AlertExtended) myAlert; //!< an alert
+    Standard_Real myStartValue; //!< start alert information
+  };
+
+  NCollection_DataMap<Standard_Integer, AlertInfo> myActiveAlerts; //!< container of current alerts
+  Message_Gravity myGravity; //!< perf meter alert gravity
+  Message_PerfMeterMode myMode; //!< mode to define which information to collect
+};
+
+
+#endif // _Message_PerfMeter_HeaderFile
diff --git a/src/Message/Message_PerfMeterMode.hxx b/src/Message/Message_PerfMeterMode.hxx
new file mode 100644 (file)
index 0000000..d03d5d4
--- /dev/null
@@ -0,0 +1,34 @@
+// Created on: 2019-08-13
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2019 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 _Message_PerfMeterMode_HeaderFile
+#define _Message_PerfMeterMode_HeaderFile
+
+//! Specifies kind of report information to collect
+enum Message_PerfMeterMode
+{
+  Message_PerfMeterMode_None,           //!< no computation
+  Message_PerfMeterMode_UserTimeCPU,    //!< the current CPU user time in seconds
+  Message_PerfMeterMode_SystemTimeInfo, //!< the current CPU system time in seconds
+  Message_PerfMeterMode_MemPrivate,     //!< OSD_MemInfo::MemPrivate
+  Message_PerfMeterMode_MemVirtual,     //!< OSD_MemInfo::MemVirtual
+  Message_PerfMeterMode_MemWorkingSet,   //!< OSD_MemInfo::MemWorkingSet
+  Message_PerfMeterMode_MemWorkingSetPeak, //!< OSD_MemInfo::MemWorkingSetPeak
+  Message_PerfMeterMode_MemSwapUsage,     //!< OSD_MemInfo::MemSwapUsage
+  Message_PerfMeterMode_MemSwapUsagePeak, //!< OSD_MemInfo::MemSwapUsagePeak
+  Message_PerfMeterMode_MemHeapUsage      //!< OSD_MemInfo::MemHeapUsage
+};
+
+#endif // _Message_PerfMeterKind_HeaderFile
index 07324599d2fc5bbed00fe24b37848cd2221143b9..344c7fbf04ac8dbb8eba08bc7813498666b053eb 100644 (file)
 // commercial license or contractual agreement.
 
 #include <Message_Report.hxx>
+
+#include <Message_AlertExtended.hxx>
+#include <Message_CompositeAlerts.hxx>
 #include <Message_Msg.hxx>
 #include <Message_Messenger.hxx>
+#include <Message_PerfMeter.hxx>
+#include <Message_ReportCallBack.hxx>
+
 #include <NCollection_Map.hxx>
+#include <Precision.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
 
+static Handle(Message_Report) MyReport;
+
 //=======================================================================
 //function : Message_Report
 //purpose  :
 //=======================================================================
 
 Message_Report::Message_Report ()
+: myPerfMeterMode (Message_PerfMeterMode_None), myLimit (-1)
+{
+  SetActive (Standard_True);
+}
+
+//=======================================================================
+//function : CurrentReport
+//purpose  :
+//=======================================================================
+Handle(Message_Report) Message_Report::CurrentReport(const Standard_Boolean theToCreate)
 {
+  if (MyReport.IsNull() && theToCreate)
+    MyReport = new Message_Report();
+
+  return MyReport;
 }
 
 //=======================================================================
@@ -36,6 +59,9 @@ Message_Report::Message_Report ()
 
 void Message_Report::AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert)
 {
+  if (!IsActive (theGravity))
+    return;
+
   Standard_ASSERT_RETURN (! theAlert.IsNull(), "Attempt to add null alert",);
   Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
                           "Adding alert with gravity not in valid range",);
@@ -58,6 +84,63 @@ void Message_Report::AddAlert (Message_Gravity theGravity, const Handle(Message_
 
   // if not merged, just add to the list
   aList.Append (theAlert);
+
+  if (!myCallBack.IsNull())
+    myCallBack->Update (theAlert);
+}
+
+//=======================================================================
+//function : AddAlert
+//purpose  :
+//=======================================================================
+
+void Message_Report::AddAlert (const Message_Gravity theGravity, const Handle(Message_Alert)& theAlert,
+                               Message_PerfMeter* thePerfMeter, const Handle(Message_Alert)& theParentAlert)
+{
+  if (!IsActive (theGravity))
+    return;
+
+  Standard_ASSERT_RETURN (!theAlert.IsNull(), "Attempt to add null alert",);
+  Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
+                          "Adding alert with gravity not in valid range",);
+
+  Standard_Mutex::Sentry aSentry (myMutex);
+
+  // iterate by already recorded alerts and try to merge new one with one of those
+  Handle(Message_Alert) aParentAlert = theParentAlert;
+  if (aParentAlert.IsNull() && thePerfMeter)
+    aParentAlert = thePerfMeter->GetAlert();
+  if (aParentAlert.IsNull())
+    aParentAlert = getLastAlertInPerfMeter(theGravity);
+
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(aParentAlert);
+  Handle(Message_CompositeAlerts) aCompositeAlert = !anExtendedAlert.IsNull() ? anExtendedAlert->GetCompositeAlerts (Standard_True)
+    : Handle(Message_CompositeAlerts)();
+  Message_ListOfAlert& aList = !aCompositeAlert.IsNull() ? aCompositeAlert->GetAlerts (theGravity) : myAlerts[theGravity];
+
+  if (theAlert->SupportsMerge() && !aList.IsEmpty())
+  {
+    // merge is performed only for alerts of exactly same type and same name
+    const Handle(Standard_Type)& aType = theAlert->DynamicType();
+    for (Message_ListOfAlert::Iterator anIt(aList); anIt.More(); anIt.Next())
+    {
+      // if merged successfully, just return
+      if (aType == anIt.Value()->DynamicType() && theAlert->Merge (anIt.Value()))
+        return;
+    }
+  }
+
+  // if not merged, just add to the list
+  aList.Append (theAlert);
+  // remove alerts under the report only
+  if (theParentAlert.IsNull() && aParentAlert.IsNull() && myLimit > 0 && aList.Extent() > myLimit)
+    aList.RemoveFirst();
+
+  if (thePerfMeter)
+    thePerfMeter->AddAlert (theAlert, PerfMeterMode());
+
+  if (!myCallBack.IsNull())
+    myCallBack->Update(theAlert);
 }
 
 //=======================================================================
@@ -73,6 +156,156 @@ const Message_ListOfAlert& Message_Report::GetAlerts (Message_Gravity theGravity
   return myAlerts[theGravity];
 }
 
+//=======================================================================
+//function : CumulativeMetric
+//purpose  :
+//=======================================================================
+
+Standard_Real Message_Report::CumulativeMetric (const Message_Gravity theGravity) const
+{
+  switch (myPerfMeterMode)
+  {
+    case Message_PerfMeterMode_None: return 0.0;
+    case Message_PerfMeterMode_UserTimeCPU:
+    case Message_PerfMeterMode_SystemTimeInfo:
+    {
+      Standard_Real aStartTime = Message_AlertExtended::GetUndefinedMetric();
+      Standard_Boolean isFound = Standard_False;
+      for (Message_ListOfAlert::Iterator anAlertsIt (GetAlerts (theGravity)); anAlertsIt.More(); anAlertsIt.Next())
+      {
+        Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(anAlertsIt.Value());
+        if (anExtendedAlert.IsNull() && anExtendedAlert->IsMetricValid())
+        {
+          aStartTime = anExtendedAlert->MetricStart();
+          isFound = Standard_True;
+          break;
+        }
+      }
+      if (!isFound)
+        return 0.0;
+
+      Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(getLastAlert (theGravity));
+      if (anExtendedAlert.IsNull() || !anExtendedAlert->IsMetricValid())
+        return 0.0;
+
+      return anExtendedAlert->MetricStop() - aStartTime;
+    }
+    case Message_PerfMeterMode_MemPrivate:
+    case Message_PerfMeterMode_MemVirtual:
+    case Message_PerfMeterMode_MemWorkingSet:
+    {
+      Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(getLastAlert (theGravity));
+      if (!anExtendedAlert.IsNull())
+        return anExtendedAlert->MetricStop();
+    }
+  }
+  return 0.0;
+}
+
+//=======================================================================
+//function : getLastAlert
+//purpose  :
+//=======================================================================
+
+Handle(Message_Alert) Message_Report::getLastAlert (const Message_Gravity theGravity) const
+{
+  if (!IsActive (theGravity))
+    return Handle(Message_Alert)();
+
+  const Message_ListOfAlert& anAlerts = GetAlerts (theGravity);
+  if (anAlerts.IsEmpty())
+    return Handle(Message_Alert)();
+
+  Handle(Message_Alert) aLastAlert = anAlerts.Last();
+
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (aLastAlert);
+  if (anExtendedAlert.IsNull())
+    return aLastAlert;
+  Handle(Message_CompositeAlerts) aCompositeAlert = anExtendedAlert->GetCompositeAlerts (Standard_True);
+  if (aCompositeAlert.IsNull())
+    return aLastAlert;
+
+  while (!aCompositeAlert.IsNull() && !aCompositeAlert->GetAlerts (theGravity).IsEmpty())
+  {
+    Handle(Message_Alert) anAlert = aCompositeAlert->GetAlerts (theGravity).Last();
+
+    Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (anAlert);
+    if (anExtendedAlert.IsNull())
+    {
+      aLastAlert = anAlert;
+      break;
+    }
+
+    aLastAlert = anExtendedAlert;
+    aCompositeAlert = anExtendedAlert->GetCompositeAlerts();
+  }
+
+  // if alert has perf meter, use as the last alert, an alert of the perf meter
+  anExtendedAlert = Handle(Message_AlertExtended)::DownCast (aLastAlert);
+  if (anExtendedAlert.IsNull())
+    return aLastAlert;
+
+  return aLastAlert;
+}
+
+//=======================================================================
+//function : getLastAlertInPerfMeter
+//purpose  :
+//=======================================================================
+
+Handle(Message_Alert) Message_Report::getLastAlertInPerfMeter (const Message_Gravity theGravity) const
+{
+  if (!IsActive (theGravity))
+    return Handle(Message_Alert)();
+
+  const Message_ListOfAlert& anAlerts = GetAlerts (theGravity);
+  if (anAlerts.IsEmpty())
+    return Handle(Message_Alert)();
+
+  Handle(Message_Alert) aLastAlert = anAlerts.Last();
+
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (aLastAlert);
+  if (anExtendedAlert.IsNull())
+    return aLastAlert;
+  Handle(Message_CompositeAlerts) aCompositeAlert = anExtendedAlert->GetCompositeAlerts (Standard_True);
+  if (aCompositeAlert.IsNull())
+    return aLastAlert;
+
+  Standard_Boolean aHasPerfMeter = anExtendedAlert->GetPerfMeter() != NULL;
+  if (!aHasPerfMeter) // the alert has finished and is not the last alert anymore
+    return Handle(Message_Alert)();
+
+  while (!aCompositeAlert.IsNull() && !aCompositeAlert->GetAlerts (theGravity).IsEmpty())
+  {
+    Handle(Message_Alert) anAlert = aCompositeAlert->GetAlerts (theGravity).Last();
+
+    Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (anAlert);
+    if (anExtendedAlert.IsNull())
+    {
+      if (!aHasPerfMeter) // if there is a perf meter, use alert of it
+        aLastAlert = anAlert;
+      break;
+    }
+
+    if (!aHasPerfMeter)
+      aHasPerfMeter = anExtendedAlert->GetPerfMeter() != NULL;
+    else if (!anExtendedAlert->GetPerfMeter())
+      break; // last alert is the previous alert where perf meter is not NULL
+
+    aLastAlert = anExtendedAlert;
+    aCompositeAlert = anExtendedAlert->GetCompositeAlerts();
+  }
+
+  // if alert has perf meter, use as the last alert, an alert of the perf meter
+  anExtendedAlert = Handle(Message_AlertExtended)::DownCast (aLastAlert);
+  if (anExtendedAlert.IsNull())
+    return aLastAlert;
+  //if (anExtendedAlert->GetPerfMeter())
+  //  aLastAlert = anExtendedAlert->GetPerfMeter()->GetAlert();
+
+  return aLastAlert;
+}
+
 //=======================================================================
 //function : HasAlert
 //purpose  :
@@ -248,3 +481,22 @@ void Message_Report::Merge (const Handle(Message_Report)& theOther, Message_Grav
     AddAlert (theGravity, anIt.Value());
   }
 }
+
+//=======================================================================
+//function : SetActive
+//purpose  :
+//=======================================================================
+
+void Message_Report::SetActive (const Standard_Boolean theActive, const Standard_Integer theGravity)
+{
+  if (theGravity < 0)
+  {
+    for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+      SetActive (theActive, iGravity);
+    return;
+  }
+
+  Standard_ASSERT_RETURN (theGravity >= 0 && size_t (theGravity) < sizeof (myAlerts) / sizeof (myAlerts[0]), 
+                          "Set active report with gravity not in valid range", );
+  myIsActive[theGravity] = theActive;
+}
index 8440ba81498a823a8d8039a0b0caa345f16cd4be..b8c1df512b4e9434c17605b679e716dcd4e253d7 100644 (file)
 
 #include <Message_Gravity.hxx>
 #include <Message_ListOfAlert.hxx>
+#include <Message_PerfMeterMode.hxx>
 #include <Standard_Mutex.hxx>
 
 class Message_Messenger;
-
+class Message_PerfMeter;
 class Message_Report;
-DEFINE_STANDARD_HANDLE(Message_Report, MMgt_TShared)
+class Message_ReportCallBack;
+
+DEFINE_STANDARD_HANDLE(Message_Report, Standard_Transient)
 
 //! Container for alert messages, sorted according to their gravity.
 //! 
@@ -54,10 +57,24 @@ public:
   //! Empty constructor
   Standard_EXPORT Message_Report ();
   
+  //! returns the only one instance of Report
+  //! When theToCreate is true - automatically creates message report when not exist.
+  //! that has been created.
+  Standard_EXPORT static Handle(Message_Report) CurrentReport (const Standard_Boolean theToCreate = Standard_False);
+
   //! Add alert with specified gravity.
   //! This method is thread-safe, i.e. alerts can be added from parallel threads safely.
   Standard_EXPORT void AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert);
 
+  //! Add alert with specified gravity. The alert is a sub-alert of report or another alert
+  //! The parent alert is the parameter alert or the last alert if found else report.
+  //! \param theGravity a message gravity
+  //! \param theAlert a new alert to be added
+  //! \param thePerfMeter performance meter calculates the alert spent time and participate in searching the last alert if needed
+  //! \param theParentAlert if not NULL specifies parent alert where the alert should be placed, if the parent is an extednded alert
+  Standard_EXPORT void AddAlert (const Message_Gravity theGravity, const Handle(Message_Alert)& theAlert,
+                                 Message_PerfMeter* thePerfMeter, const Handle(Message_Alert)& theParentAlert = Handle(Message_Alert)());
+
   //! Returns list of collected alerts with specified gravity
   Standard_EXPORT const Message_ListOfAlert& GetAlerts (Message_Gravity theGravity) const;
 
@@ -94,15 +111,70 @@ public:
   //! Merges alerts with specified gravity from theOther report into this
   Standard_EXPORT void Merge (const Handle(Message_Report)& theOther, Message_Gravity theGravity);
 
+  //! Returns a state whether the report is active
+  //! \return the state
+  Standard_Boolean IsActive (const Message_Gravity theGravity) const { return myIsActive[theGravity]; }
+
+  //! Starts a timer to compute time between messages. If a timer has already been started, it will be stopped
+  //! \param theActive new state of report active
+  //! \param theGravity gravity type, if '-1', apply value for all gravity kinds
+  Standard_EXPORT void SetActive (const Standard_Boolean theActive, const Standard_Integer theGravity = -1);
+
+  //! Sets a perf meter mode
+  //! \param theMode new mode
+  Standard_EXPORT void SetPerfMeterMode (const Message_PerfMeterMode theMode)
+  { myPerfMeterMode = theMode; }
+
+  //! Returns mode of perf meter
+  //! \return the state
+  Standard_EXPORT Message_PerfMeterMode PerfMeterMode() const
+  { return myPerfMeterMode; }
+
+  //! Returns maximum number of collecting alerts. If the limit is achieved,
+  //! adding of a new alert after removing the first cached alert.
+  //! \return the limit value
+  Standard_EXPORT Standard_Integer GetLimit() const { return myLimit; }
+
+  //! Sets maximum number of collecting alerts.
+  //! \return theLimit limit value
+  Standard_EXPORT void SetLimit(const Standard_Integer theLimit) { myLimit = theLimit; }
+
+  //! Returns the report cumulative metric. It includes time/mem of sub alerts depending on PerfMeter mode
+  //! @return value
+  Standard_EXPORT Standard_Real CumulativeMetric (const Message_Gravity theGravity) const;
+
+  //! Sets a listener for the report events
+  void SetCallBack(const Handle(Message_ReportCallBack)& theCallBack) { myCallBack = theCallBack; }
+
+  //! Returns listener of the reports events
+  const Handle(Message_ReportCallBack)& GetCallBack() const { return myCallBack; }
+
   // OCCT RTTI
   DEFINE_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
 
+protected:
+  //! Returns last alert in list of report alerts or last alert in hierarchical tree of alerts provided by
+  //! the last alert
+  //! \parm theGravity a message gravity
+  Standard_EXPORT Handle(Message_Alert) getLastAlert (const Message_Gravity theGravity) const;
+
+  //! Returns last alert in list of report alerts or last alert in hierarchical tree of alerts provided by
+  //! the last alert
+  //! \parm theGravity a message gravity
+  Standard_EXPORT Handle(Message_Alert) getLastAlertInPerfMeter (const Message_Gravity theGravity) const;
+
 protected:
   Standard_Mutex myMutex;
 
   // store messages in a lists sorted by gravity;
   // here we rely on knowledge that Message_Fail is the last element of the enum
   Message_ListOfAlert myAlerts[Message_Fail + 1];
+
+  Standard_Boolean myIsActive[Message_Fail + 1];
+  Message_PerfMeterMode myPerfMeterMode; //! If true, each alert will store the mode information
+  Standard_Integer myLimit; //! Maximum number of collected alerts
+
+  Handle(Message_ReportCallBack) myCallBack; //! signal about performed modifications
 };
 
 #endif // _Message_Report_HeaderFile
diff --git a/src/Message/Message_ReportCallBack.cxx b/src/Message/Message_ReportCallBack.cxx
new file mode 100644 (file)
index 0000000..5f0ce64
--- /dev/null
@@ -0,0 +1,22 @@
+// Created on: 2017-12-01
+// 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 "Message_ReportCallBack.hxx"
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_ReportCallBack, Standard_Transient)
+
+Message_ReportCallBack::Message_ReportCallBack ()
+{
+}
diff --git a/src/Message/Message_ReportCallBack.hxx b/src/Message/Message_ReportCallBack.hxx
new file mode 100644 (file)
index 0000000..884b64d
--- /dev/null
@@ -0,0 +1,44 @@
+// Created on: 2017-12-01
+// 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 _Message_ReportCallBack_HeaderFile
+#define _Message_ReportCallBack_HeaderFile
+
+#include <Standard_Handle.hxx>
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+
+class Message_Alert;
+class Message_ReportCallBack;
+DEFINE_STANDARD_HANDLE(Message_ReportCallBack, Standard_Transient)
+
+//! Interface to have possibility of processing message report events.
+class Message_ReportCallBack : public Standard_Transient
+{
+public:
+
+  //! Empty constructor
+  Standard_EXPORT Message_ReportCallBack ();
+  ~Message_ReportCallBack () {}
+
+  //! Interface to be implemented in the child to process the message report event
+  //! \param theAlert created or modified message alert
+  virtual void Update(const Handle(Message_Alert)& theAlert) = 0;
+
+  //! OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_ReportCallBack, Standard_Transient)
+};
+
+#endif // _Message_ReportCallBack_HeaderFile
index d44e73be3a8c9449bcb163c783a563cf9c218fe3..c887ad58e06ddb3b7033bd82b8cf8d5c80f7ecc3 100755 (executable)
@@ -17,6 +17,8 @@
 #define _NCollection_Mat4_HeaderFile
 
 #include <NCollection_Vec4.hxx>
+#include <Standard_Dump.hxx>
+#include <Standard_OStream.hxx>
 
 //! Generic matrix of 4 x 4 elements.
 //! To be used in conjunction with NCollection_Vec4 entities.
@@ -461,6 +463,7 @@ public:
     return *reinterpret_cast<const NCollection_Mat4<Element_t>*> (theData);
   }
 
+  //! Dumps the content of me into the stream
   void DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth = -1) const
   {
     OCCT_DUMP_FIELD_VALUES_NUMERICAL (theOStream, "NCollection_Mat4", 16,
index 277804e2037b6a1a5a1ea189a199b25851402fae..6651c8f2b1c8e5c66e6c839bc03f02a944fee68d 100644 (file)
@@ -186,6 +186,145 @@ void OSD_MemInfo::Update()
 #endif
 }
 
+// =======================================================================
+// function : Update
+// purpose  :
+// =======================================================================
+void OSD_MemInfo::Update (const OSD_MemInfo::Counter theCounter)
+{
+#ifndef OCCT_UWP
+#if defined(_WIN32)
+
+  if (theCounter == MemVirtual)
+  {
+  #if (_WIN32_WINNT >= 0x0500)
+    MEMORYSTATUSEX aStatEx;
+    aStatEx.dwLength = sizeof(aStatEx);
+    GlobalMemoryStatusEx (&aStatEx);
+    myCounters[MemVirtual] = Standard_Size(aStatEx.ullTotalVirtual - aStatEx.ullAvailVirtual);
+  #else
+    MEMORYSTATUS aStat;
+    aStat.dwLength = sizeof(aStat);
+    GlobalMemoryStatus (&aStat);
+    myCounters[MemVirtual] = Standard_Size(aStat.dwTotalVirtual - aStat.dwAvailVirtual);
+  #endif
+
+    return;
+  }
+
+  if (theCounter == MemPrivate ||
+      theCounter == MemWorkingSet ||
+      theCounter == MemWorkingSetPeak ||
+      theCounter == MemSwapUsage ||
+      theCounter == MemSwapUsagePeak)
+  {
+    // use Psapi library
+    HANDLE aProcess = GetCurrentProcess();
+  #if (_WIN32_WINNT >= 0x0501)
+    PROCESS_MEMORY_COUNTERS_EX aProcMemCnts;
+  #else
+    PROCESS_MEMORY_COUNTERS    aProcMemCnts;
+  #endif
+    if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts)))
+    {
+    #if (_WIN32_WINNT >= 0x0501)
+      myCounters[MemPrivate]        = aProcMemCnts.PrivateUsage;
+    #endif
+      myCounters[MemWorkingSet]     = aProcMemCnts.WorkingSetSize;
+      myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize;
+      myCounters[MemSwapUsage]      = aProcMemCnts.PagefileUsage;
+      myCounters[MemSwapUsagePeak]  = aProcMemCnts.PeakPagefileUsage;
+    }
+    return;
+  }
+
+  if (theCounter == MemHeapUsage)
+  {
+    _HEAPINFO hinfo;
+    int heapstatus;
+    hinfo._pentry = NULL;
+
+    myCounters[MemHeapUsage] = 0;
+    while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK)
+    {
+      if(hinfo._useflag == _USEDENTRY)
+        myCounters[MemHeapUsage] += hinfo._size;
+    }
+   return;
+  }
+
+#elif (defined(__linux__) || defined(__linux))
+/*
+  // use procfs on Linux
+  char aBuff[4096];
+  snprintf (aBuff, sizeof(aBuff), "/proc/%d/status", getpid());
+  std::ifstream aFile;
+  aFile.open (aBuff);
+  if (!aFile.is_open())
+  {
+    return;
+  }
+
+  while (!aFile.eof())
+  {
+    memset (aBuff, 0, sizeof(aBuff));
+    aFile.getline (aBuff, 4096);
+    if (aBuff[0] == '\0')
+    {
+      continue;
+    }
+
+    if (strncmp (aBuff, "VmSize:", strlen ("VmSize:")) == 0)
+    {
+      myCounters[MemVirtual] = atol (aBuff + strlen ("VmSize:")) * 1024;
+    }
+    //else if (strncmp (aBuff, "VmPeak:", strlen ("VmPeak:")) == 0)
+    //  myVirtualPeak = atol (aBuff + strlen ("VmPeak:")) * 1024;
+    else if (strncmp (aBuff, "VmRSS:", strlen ("VmRSS:")) == 0)
+    {
+      myCounters[MemWorkingSet] = atol (aBuff + strlen ("VmRSS:")) * 1024; // RSS - resident set size
+    }
+    else if (strncmp (aBuff, "VmHWM:", strlen ("VmHWM:")) == 0)
+    {
+      myCounters[MemWorkingSetPeak] = atol (aBuff + strlen ("VmHWM:")) * 1024; // HWM - high water mark
+    }
+    else if (strncmp (aBuff, "VmData:", strlen ("VmData:")) == 0)
+    {
+      if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate];
+      myCounters[MemPrivate] += atol (aBuff + strlen ("VmData:")) * 1024;
+    }
+    else if (strncmp (aBuff, "VmStk:", strlen ("VmStk:")) == 0)
+    {
+      if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate];
+      myCounters[MemPrivate] += atol (aBuff + strlen ("VmStk:")) * 1024;
+    }
+  }
+  aFile.close();
+
+  struct mallinfo aMI = mallinfo();
+  myCounters[MemHeapUsage] = aMI.uordblks;
+
+#elif (defined(__APPLE__))
+  struct task_basic_info aTaskInfo;
+  mach_msg_type_number_t aTaskInfoCount = TASK_BASIC_INFO_COUNT;
+  if (task_info (mach_task_self(), TASK_BASIC_INFO,
+                 (task_info_t )&aTaskInfo, &aTaskInfoCount) == KERN_SUCCESS)
+  {
+    // On Mac OS X, these values in bytes, not pages!
+    myCounters[MemVirtual]    = aTaskInfo.virtual_size;
+    myCounters[MemWorkingSet] = aTaskInfo.resident_size;
+
+    //Getting malloc statistics
+    malloc_statistics_t aStats;
+    malloc_zone_statistics (NULL, &aStats);
+
+    myCounters[MemHeapUsage] = aStats.size_in_use;
+  }
+*/
+#endif
+#endif
+}
+
 // =======================================================================
 // function : ToString
 // purpose  :
index f06d5d05a1209e7a48d1908eee98dff0364acb49..71c0c9a1eacf174704f27da04dbd7cf301c7081a 100644 (file)
@@ -74,6 +74,9 @@ public:
   //! Update counters
   Standard_EXPORT void Update();
 
+  //! Update counter of specified counter
+  Standard_EXPORT void Update (const OSD_MemInfo::Counter theCounter);
+
   //! Return the string representation for all available counter.
   Standard_EXPORT TCollection_AsciiString ToString() const;
 
index 434b96b0972154523b67e0c9388bf9c38c39a71e..a837d639794935c90581090fc3fba36b7d7f42da 100644 (file)
@@ -862,6 +862,9 @@ public: //! @name methods to alter or retrieve current state
   //! Return Graphics Driver's vendor.
   const TCollection_AsciiString& Vendor() const { return myVendor; }
 
+  //! Dumps the content of me into the stream
+  Standard_EXPORT void DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth = -1) const;
+
 private:
 
   //! Wrapper to system function to retrieve GL function pointer by name.
index 82ae98b84758f20a448cc861962e57d4cc9ebd3c..1a96f61f32a96e3c03757eba81f08b1fa81d127f 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <OpenGl_Vec.hxx>
 #include <NCollection_Vector.hxx>
+#include <Standard_Dump.hxx>
 
 //! Software implementation for OpenGL matrix stack.
 template<class T>
@@ -85,8 +86,9 @@ public:
   }
 
   //! Dumps the content of me into the stream
-  Standard_EXPORT void DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth = -1) const
+  void DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth = -1) const
   {
+    (void)theDepth;
     OCCT_DUMP_FIELD_VALUES_NUMERICAL (theOStream, "myCurrent", 16,
       myCurrent.GetValue (0, 0),  myCurrent.GetValue (0, 1), myCurrent.GetValue (0, 2),  myCurrent.GetValue (0, 3),
       myCurrent.GetValue (1, 0),  myCurrent.GetValue (1, 1), myCurrent.GetValue (1, 2),  myCurrent.GetValue (1, 3),
index 8e17f304b65771f2acf1f64edf3c142647d89c20..27345a189fc39878a902c236d20ed90e5448ba2e 100644 (file)
@@ -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 (file)
index 0000000..aac6e48
--- /dev/null
@@ -0,0 +1,37 @@
+// 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 <TopoDS_AlertAttribute.hxx>
+
+#include <Message_Msg.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(TopoDS_AlertAttribute, Message_Attribute)
+
+//=======================================================================
+//function : TopoDS_AlertAttribute
+//purpose  : 
+//=======================================================================
+
+
+TopoDS_AlertAttribute::TopoDS_AlertAttribute (const TopoDS_Shape& theShape,
+  const TCollection_AsciiString& theName,
+  const TCollection_AsciiString& theDescription)
+: Message_AttributeStream (Standard_SStream(), theName, theDescription), myShape (theShape)
+{
+  Standard_SStream aStream;
+  theShape.DumpJson (aStream);
+
+  SetStream (aStream);
+}
diff --git a/src/TopoDS/TopoDS_AlertAttribute.hxx b/src/TopoDS/TopoDS_AlertAttribute.hxx
new file mode 100644 (file)
index 0000000..ea34794
--- /dev/null
@@ -0,0 +1,51 @@
+// 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 <Message_AttributeStream.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! 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(),
+    const TCollection_AsciiString& theDescription = TCollection_AsciiString());
+
+  //! Returns contained shape
+  const TopoDS_Shape& GetShape() const { return myShape; }
+  
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(TopoDS_AlertAttribute, Message_AttributeStream)
+
+private:
+  TopoDS_Shape myShape;
+};
+
+#define MESSAGE_INFO_SHAPE(Shape, Name, Description, PerfMeter, ParentAlert) \
+  { \
+    if (!Message_Report::CurrentReport().IsNull() && \
+         Message_Report::CurrentReport()->IsActive (Message_Info)) \
+    { \
+      OCCT_Message_Alert = Message_AlertExtended::AddAlert (Message_Report::CurrentReport(), \
+        new TopoDS_AlertAttribute (Shape, Name, Description), PerfMeter, ParentAlert); \
+    } \
+  }
+
+#endif // _TopoDS_AlertAttribute_HeaderFile
index 058b8acc20f0d2644227e9ada3c180631c144b43..d4a93d94ff64b87d880556880189189475da7ac9 100644 (file)
@@ -4,3 +4,5 @@ XmlDrivers_DocumentRetrievalDriver.cxx
 XmlDrivers_DocumentRetrievalDriver.hxx
 XmlDrivers_DocumentStorageDriver.cxx
 XmlDrivers_DocumentStorageDriver.hxx
+XmlDrivers_MessageReportStorage.cxx
+XmlDrivers_MessageReportStorage.hxx
diff --git a/src/XmlDrivers/XmlDrivers_MessageReportStorage.cxx b/src/XmlDrivers/XmlDrivers_MessageReportStorage.cxx
new file mode 100644 (file)
index 0000000..b6a5696
--- /dev/null
@@ -0,0 +1,347 @@
+// Created on: 2018-06-10
+// Created by: Natalia Ermolaeva
+// Copyright (c) 2001-2014 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 <XmlDrivers_MessageReportStorage.hxx>
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeStream.hxx>
+#include <Message_CompositeAlerts.hxx>
+#include <Message_Report.hxx>
+
+#include <TCollection.hxx>
+#include <TDataStd_AsciiString.hxx>
+#include <TDataStd_Comment.hxx>
+#include <TDataStd_Real.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDataStd_ExtStringArray.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDocStd_Application.hxx>
+#include <TDocStd_Document.hxx>
+#include <XmlDrivers.hxx>
+
+// =======================================================================
+// function : GetApplication
+// purpose :
+// =======================================================================
+
+const Handle(TDocStd_Application)& GetApplication()
+{
+  static Handle(TDocStd_Application) anApp;
+  if (anApp.IsNull())
+  {
+    anApp = new TDocStd_Application;
+    XmlDrivers::DefineFormat (anApp);
+  }
+  return anApp;
+}
+
+// =======================================================================
+// function : ExportReport
+// purpose :
+// =======================================================================
+
+void XmlDrivers_MessageReportStorage::ExportReport (const Handle(Message_Report)& theReport,
+                                                    const TCollection_AsciiString& theFileName)
+{
+  if (theReport.IsNull())
+    return;
+
+  Handle(TDocStd_Document) aDocument;
+  GetApplication()->NewDocument (TCollection_ExtendedString ("XmlOcaf"), aDocument);
+
+  TDF_Label aMainLabel = aDocument->Main();
+
+  for (int aGravityId = Message_Trace; aGravityId <= Message_Fail; aGravityId++)
+  {
+    Message_Gravity aGravity = (Message_Gravity)aGravityId;
+
+    if (theReport->GetAlerts (aGravity).Size() == 0)
+      continue;
+    // Gravity Label
+    TDF_Label aGravityLabel = aMainLabel.NewChild();
+    // set gravity kind string
+    TCollection_ExtendedString aName (Message::GravityToString ((Message_Gravity)aGravity));
+    if (!aName.IsEmpty())
+      TDataStd_Name::Set (aGravityLabel, aName);
+
+    /// reserved label to store gravity information
+    //TDF_Label aFirstAlertLabel = aGravityLabel.NewChild();
+
+    // Alert Labels: labels are started from the second index
+    const Message_ListOfAlert& anAlerts = theReport->GetAlerts (aGravity);
+    for (Message_ListOfAlert::Iterator anAlertsIt (anAlerts); anAlertsIt.More(); anAlertsIt.Next())
+    {
+      exportAlert (anAlertsIt.Value(), aGravityLabel);
+    }
+  }
+  GetApplication()->SaveAs (aDocument, theFileName);
+}
+
+// =======================================================================
+// function : ImportReport
+// purpose :
+// =======================================================================
+
+Handle(Message_Report) XmlDrivers_MessageReportStorage::ImportReport (const TCollection_AsciiString& theFileName)
+{
+  Handle(TDocStd_Application) anApplication = GetApplication();
+  Standard_Integer aDocumentId = anApplication->IsInSession (theFileName);
+  if (aDocumentId > 0)
+  {
+    Handle(TDocStd_Document) aDocument;
+    anApplication->GetDocument (aDocumentId, aDocument);
+    anApplication->Close (aDocument);
+  }
+
+  Handle(TDocStd_Document) aDocument;
+  GetApplication()->Open (theFileName, aDocument);
+  if (aDocument.IsNull())
+    return Handle(Message_Report)();
+
+  TDF_Label aMainLabel = aDocument->Main();
+  if (aMainLabel.IsNull())
+    return Handle(Message_Report)();
+
+  TDF_Label aLabel;
+  Handle(Message_Report) aReport = new Message_Report();
+  for (TDF_ChildIterator aLabelsIt(aMainLabel); aLabelsIt.More(); aLabelsIt.Next())
+  {
+    TDF_Label aGravityLabel = aLabelsIt.Value();
+    if (aGravityLabel.IsNull())
+      continue;
+    Handle(TDF_Attribute) anAttribute;
+    if (!aGravityLabel.FindAttribute (TDataStd_Name::GetID(), anAttribute))
+      continue;
+    Handle(TDataStd_Name) aNameAttribute = Handle(TDataStd_Name)::DownCast (anAttribute);
+    if (aNameAttribute.IsNull())
+      continue;
+
+    // get gravity type
+    const TCollection_ExtendedString& aGravityName = aNameAttribute->Get();
+    Message_Gravity aGravity = Message::GravityFromString (TCollection_AsciiString (aGravityName).ToCString());
+
+    /// reserved label to store gravity information
+    //TDF_Label aFirstAlertLabel = aGravityLabel.FindChild (1, Standard_False);
+
+    // find alerts information, add corresponded alerts to the report
+    for (TDF_ChildIterator anAlertLabelsIt (aGravityLabel); anAlertLabelsIt.More(); anAlertLabelsIt.Next())
+    {
+      TDF_Label anAlertLabel = anAlertLabelsIt.Value();
+      if (anAlertLabel.IsNull())
+        continue;
+
+      importAlert (anAlertLabel, aGravity, aReport, Handle(Message_Alert)());
+    }
+  }
+  return aReport;
+}
+
+// =======================================================================
+// function : exportAlert
+// purpose :
+// =======================================================================
+void XmlDrivers_MessageReportStorage::exportAlert (const Handle(Message_Alert)& theAlert, const TDF_Label& theParentLabel)
+{
+   TDF_Label anAlertLabel = theParentLabel.NewChild();
+  TDataStd_Name::Set (anAlertLabel, theAlert->DynamicType()->Name());
+
+  /// reserved label to store parameters of the current label
+  TDF_Label anAlertParmetersLabel = anAlertLabel.NewChild();
+  exportAlertParameters (theAlert, anAlertParmetersLabel);
+
+  for (int aGravityId = Message_Trace; aGravityId <= Message_Fail; aGravityId++)
+  {
+    // Gravity Label
+    TDF_Label aGravityLabel = anAlertLabel.NewChild();
+    // set gravity kind string
+    TDataStd_Name::Set (aGravityLabel, Message::GravityToString ((Message_Gravity)aGravityId));
+
+    Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast (theAlert);
+    if (anAlertExtended.IsNull())
+      continue;
+    Handle(Message_CompositeAlerts) aComposite = anAlertExtended->GetCompositeAlerts();
+    if (aComposite.IsNull())
+      continue;
+
+    const Message_ListOfAlert& anAlerts = aComposite->GetAlerts ((Message_Gravity)aGravityId);
+    for (Message_ListOfAlert::Iterator anAlertsIt (anAlerts); anAlertsIt.More(); anAlertsIt.Next())
+      exportAlert (anAlertsIt.Value(), aGravityLabel);
+  }
+}
+
+// =======================================================================
+// function : importAlert
+// purpose :
+// =======================================================================
+
+void XmlDrivers_MessageReportStorage::importAlert (const TDF_Label& theAlertLabel,
+                                                   const Message_Gravity theGravity,
+                                                   Handle(Message_Report)& theReport,
+                                                   const Handle(Message_Alert)& theParentAlert)
+{
+  TDF_Label aParametersLabel = theAlertLabel.FindChild (1, Standard_False);
+  Handle(Message_Alert) anAlert = importAlertParameters (aParametersLabel);
+  if (anAlert.IsNull())
+    return;
+
+  TDF_Label aLabel;
+  TDF_ChildIterator aSubAlertsLabelsIt (theAlertLabel);
+  aSubAlertsLabelsIt.Next(); // do not processing the first (parameters) label
+  for (; aSubAlertsLabelsIt.More(); aSubAlertsLabelsIt.Next())
+  {
+    TDF_Label aGravityLabel = aSubAlertsLabelsIt.Value();
+    if (aGravityLabel.IsNull())
+      continue;
+    Handle(TDF_Attribute) anAttribute;
+    if (!aGravityLabel.FindAttribute (TDataStd_Name::GetID(), anAttribute))
+      continue;
+    Handle(TDataStd_Name) aNameAttribute = Handle(TDataStd_Name)::DownCast (anAttribute);
+    if (aNameAttribute.IsNull())
+      continue;
+
+    // get gravity type
+    Message_Gravity aGravity = Message::GravityFromString (TCollection_AsciiString (aNameAttribute->Get()).ToCString());
+    // find alerts information, add corresponded alerts to the report
+    for (TDF_ChildIterator anAlertLabelsIt (aGravityLabel); anAlertLabelsIt.More(); anAlertLabelsIt.Next())
+    {
+      TDF_Label anAlertLabel = anAlertLabelsIt.Value();
+      if (anAlertLabel.IsNull())
+        continue;
+
+      importAlert (anAlertLabel, aGravity, theReport, anAlert);
+    }
+  }
+  theReport->AddAlert (theGravity, anAlert, 0, theParentAlert);
+}
+
+// =======================================================================
+// function : exportAlertParameters
+// purpose :
+// =======================================================================
+void XmlDrivers_MessageReportStorage::exportAlertParameters (const Handle(Message_Alert)& theAlert, const TDF_Label& theAlertLabel)
+{
+  //Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast (theAlert);
+  //if (anAlertExtended.IsNull()) // name attribute is empty
+  //  return;
+
+  //// store attribute time
+  //Handle(Message_Attribute) anAttribute = anAlertExtended->Attribute();
+
+  //TDataStd_Name::Set (theAlertLabel, anAttribute->DynamicType()->Name());
+  ////TDataStd_Real::Set (theAlertLabel, anAlertExtended->CumulativeMetric());
+
+  //TDataStd_AsciiString::Set (theAlertLabel, anAttribute->GetName());
+  //TCollection_AsciiString aDescription = anAttribute->GetDescription();
+  //if (!aDescription.IsEmpty())
+  //  TDataStd_Comment::Set (theAlertLabel, anAttribute->GetDescription());
+
+  //Standard_CString aDynamicTypeName = anAttribute->DynamicType()->Name();
+  //if (aDynamicTypeName == STANDARD_TYPE (Message_AttributeStream)->Name())
+  //{
+  //  Handle(Message_AttributeStream) aValuesArrayAlert = Handle(Message_AttributeStream)::DownCast (anAttribute);
+  //  // store values
+  //  NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString> aValues;
+  //  TCollection_AsciiString aKey;
+  //  TCollection::Split (aValuesArrayAlert->GetStream(), aValues, aKey);
+  //  if (aValues.IsEmpty())
+  //    return;
+  //  int anArraySize = 2 * aValues.Size();
+  //  Handle(TDataStd_ExtStringArray) aListAttribute = TDataStd_ExtStringArray::Set (theAlertLabel, 0, anArraySize - 1);
+  //  for (int aValueId = 0; aValueId < anArraySize; aValueId++)
+  //  {
+  //    TCollection_AsciiString aKey = aValues.FindKey (aValueId);
+  //    aListAttribute->SetValue (aValueId * 2, aKey);
+  //    aListAttribute->SetValue (aValueId * 2 + 1, aValues.FindFromKey (aKey));
+  //  }
+  //}
+}
+
+// =======================================================================
+// function : importAlertParameters
+// purpose :
+// =======================================================================
+Handle(Message_Alert) XmlDrivers_MessageReportStorage::importAlertParameters (const TDF_Label& aParametersLabel)
+{
+  //Handle(TDF_Attribute) anAttribute;
+  //if (!aParametersLabel.FindAttribute (TDataStd_Name::GetID(), anAttribute))
+  //  return Handle(Message_Alert)();
+
+  //Handle(TDataStd_Name) aDynamicTypeAttribute = Handle(TDataStd_Name)::DownCast (anAttribute);
+  //if (aDynamicTypeAttribute.IsNull())
+  //  return Handle(Message_Alert)();
+  //const TCollection_ExtendedString& aDynamicTypeName = aDynamicTypeAttribute->Get();
+
+  //TCollection_ExtendedString aDescription;
+  //if (aParametersLabel.FindAttribute (TDataStd_Comment::GetID(), anAttribute))
+  //{
+  //  Handle(TDataStd_Comment) aDescriptionAttribute = Handle(TDataStd_Comment)::DownCast (anAttribute);
+  //  if (!aDescriptionAttribute.IsNull())
+  //    aDescription = aDescriptionAttribute->Get();
+  //}
+
+  //Handle(Message_AlertExtended) anAlert = new Message_AlertExtended();
+  //Handle(Message_Attribute) aMessageAttribute;
+  //if (aDynamicTypeName == STANDARD_TYPE (Message_Attribute)->Name())
+  //  aMessageAttribute = new Message_Attribute();
+  //else if (aDynamicTypeName == STANDARD_TYPE (Message_AttributeStream)->Name())
+  //{
+  //  // values
+  //  NCollection_Vector<TCollection_AsciiString> anArrayValues;
+  //  if (!aParametersLabel.FindAttribute (TDataStd_ExtStringArray::GetID(), anAttribute))
+  //    return Handle(Message_Alert)();
+
+  //  Handle(TDataStd_ExtStringArray) aValuesAttribute = Handle(TDataStd_ExtStringArray)::DownCast (anAttribute);
+  //  if (aValuesAttribute.IsNull())
+  //    return Handle(Message_Alert)();
+
+  //  Standard_SStream aStream;
+  //  for (int aValueId = aValuesAttribute->Lower(); aValueId <= aValuesAttribute->Upper(); aValueId++)
+  //  {
+  //    TCollection_AsciiString aKey = aValuesAttribute->Value (aValueId++);
+  //    if (aValueId > aValuesAttribute->Upper())
+  //      break;
+  //    DUMP_VALUES (aStream, aKey, aValuesAttribute->Value (aValueId));
+  //  }
+  //  Handle(Message_AttributeStream) anAlert = new Message_AttributeStream (aStream);
+  //  aMessageAttribute = anAlert;
+  //}
+
+  //if (!aMessageAttribute.IsNull())
+  //{
+  //  // name
+  //  if (!aParametersLabel.FindAttribute (TDataStd_AsciiString::GetID(), anAttribute))
+  //    return Handle(Message_Alert)();
+  //  Handle(TDataStd_AsciiString) aNameAttribute = Handle(TDataStd_AsciiString)::DownCast (anAttribute);
+  //  if (aNameAttribute.IsNull())
+  //    return Handle(Message_Alert)();
+
+  //  aMessageAttribute->SetName (aNameAttribute->Get());
+  //  aMessageAttribute->SetDescription (aDescription);
+
+  //  anAlert->SetAttribute (aMessageAttribute);
+  //}
+
+  //// time
+  //Standard_Real aTime = -1;
+  //Handle(TDataStd_Real) aTimeAttribute;
+  //if (aParametersLabel.FindAttribute (TDataStd_Real::GetID(), aTimeAttribute))
+  //  aTime = aTimeAttribute->Get();
+
+  ////anAlert->SetCumulativeMetric (aTime);
+  //return anAlert;
+  return NULL;
+}
diff --git a/src/XmlDrivers/XmlDrivers_MessageReportStorage.hxx b/src/XmlDrivers/XmlDrivers_MessageReportStorage.hxx
new file mode 100644 (file)
index 0000000..cd97441
--- /dev/null
@@ -0,0 +1,68 @@
+// Created on: 2018-06-10
+// Created by: Natalia Ermolaeva
+// Copyright (c) 2001-2014 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 _XmlDrivers_MessageReportStorage
+#define _XmlDrivers_MessageReportStorage
+
+#include <Standard_Handle.hxx>
+
+#include <Message_Report.hxx>
+#include <Message_Alert.hxx>
+#include <TDF_Label.hxx>
+
+//! Base class to store/restore Message_Report content in XML document
+class XmlDrivers_MessageReportStorage
+{
+public:
+  //! Create document for the report
+  //! \param theReport the source report
+  //! \param theFileName a file name
+  Standard_EXPORT static void ExportReport (const Handle(Message_Report)& theReport, const TCollection_AsciiString& theFileName);
+
+  //! Restores document file content into report instance
+  //! \param theFileName a file name
+  //! \return new report or NULL
+  Standard_EXPORT static Handle(Message_Report) ImportReport (const TCollection_AsciiString& theFileName);
+
+private:
+  //! Create labels/attributes for the alert and place it under the parent label.
+  //! It is recursive as alerts may contains other alerts
+  //! \param theAlert a source alert
+  //! \parm theParentLabel a label where alert label is placed
+  static void exportAlert (const Handle(Message_Alert)& theAlert, const TDF_Label& theParentLabel);
+
+  //! Creates a new alert by the label parameters
+  //! \param theAlertLabel a source document label
+  //! \param theGravity an alert gravity
+  //! \param theReport a container of alerts
+  //! \param theParentAlert a parent alert, if null, the parent is report
+  static void importAlert (const TDF_Label& theAlertLabel,
+                           const Message_Gravity theGravity,
+                           Handle(Message_Report)& theReport,
+                           const Handle(Message_Alert)& theParentAlert);
+
+  //! Convert alert to a custom type and store parameters in child labels and attributes
+  //! \param theAlert a source alert
+  //! \parm theAlertLabel an alert label
+  static void exportAlertParameters (const Handle(Message_Alert)& theAlert,
+                                     const TDF_Label& theAlertLabel);
+
+  //! Creates alert by label type filled by the label content
+  //! \param theParametersLabel a label
+  //! \return new alert or NULL
+  static Handle(Message_Alert) importAlertParameters (const TDF_Label& aParametersLabel);
+};
+
+#endif // _XmlDrivers_MessageReportStorage
diff --git a/tools/MessageModel/FILES b/tools/MessageModel/FILES
new file mode 100644 (file)
index 0000000..953018c
--- /dev/null
@@ -0,0 +1,18 @@
+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_ReportCallBack.cxx
+MessageModel_ReportCallBack.hxx
+MessageModel_Tools.cxx
+MessageModel_Tools.hxx
+MessageModel_TreeModel.cxx
+MessageModel_TreeModel.hxx
diff --git a/tools/MessageModel/MessageModel.qrc b/tools/MessageModel/MessageModel.qrc
new file mode 100644 (file)
index 0000000..6862caf
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+    <qresource>
+        <file>icons/item_shape.png</file>
+        <file>icons/item_vectorOfValues.png</file>
+    </qresource>
+</RCC>
diff --git a/tools/MessageModel/MessageModel_ActionType.hxx b/tools/MessageModel/MessageModel_ActionType.hxx
new file mode 100644 (file)
index 0000000..8cd073c
--- /dev/null
@@ -0,0 +1,30 @@
+// 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
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_Actions.cxx b/tools/MessageModel/MessageModel_Actions.cxx
new file mode 100644 (file)
index 0000000..03115c1
--- /dev/null
@@ -0,0 +1,367 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+                                                          
+#include <inspector/MessageModel_Actions.hxx>
+
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_TreeModel.hxx>
+#include <inspector/TInspectorAPI_PluginParameters.hxx>
+#include <inspector/ViewControl_Tools.hxx>
+
+#include <Message_AlertExtended.hxx>
+
+#include <TCollection_AsciiString.hxx>
+#include <TopoDS_AlertAttribute.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QAction>
+#include <QFileDialog>
+#include <QItemSelectionModel>
+#include <QMenu>
+#include <QMessageBox>
+#include <QWidget>
+#include <Standard_WarningsRestore.hxx>
+
+#define DEBUG_ALERTS
+
+#ifdef DEBUG_ALERTS
+#include <Message_Alerts.hxx>
+#include <Message_PerfMeter.hxx>
+#endif
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+MessageModel_Actions::MessageModel_Actions (QWidget* theParent,
+  MessageModel_TreeModel* theTreeModel, QItemSelectionModel* theModel)
+: QObject (theParent), myTreeModel (theTreeModel), mySelectionModel (theModel)
+{
+  myActions.insert (MessageModel_ActionType_Deactivate,
+                    ViewControl_Tools::CreateAction ("Deactivate", SLOT (OnDeactivateReport()), parent(), this));
+  myActions.insert (MessageModel_ActionType_Activate,
+                    ViewControl_Tools::CreateAction ("Activate", SLOT (OnActivateReport()), 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));
+#ifdef DEBUG_ALERTS
+  myActions.insert (MessageModel_ActionType_TestMetric,
+                    ViewControl_Tools::CreateAction ("Test <metric>", SLOT (OnTestMetric()), parent(), this));
+  myActions.insert (MessageModel_ActionType_TestProperties,
+                    ViewControl_Tools::CreateAction ("Test <PropertyPanel>", SLOT (OnTestPropertyPanel()), parent(), this));
+#endif
+}
+
+// =======================================================================
+// function : GetAction
+// purpose :
+// =======================================================================
+QAction* MessageModel_Actions::GetAction (const MessageModel_ActionType& theType)
+{
+  if (myActions.contains (theType))
+    return myActions[theType];
+
+  return 0;
+}
+
+// =======================================================================
+// function : AddMenuActions
+// purpose :
+// =======================================================================
+void MessageModel_Actions::AddMenuActions (const QModelIndexList& theSelectedIndices, QMenu* theMenu)
+{
+  MessageModel_ItemRootPtr aRootItem;
+  MessageModel_ItemReportPtr aReportItem;
+  MessageModel_ItemAlertPtr anAlertItem;
+  for (QModelIndexList::const_iterator aSelIt = theSelectedIndices.begin(); aSelIt != theSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItemBase);
+    if (aRootItem)
+      break;
+
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    if (aReportItem)
+      break;
+
+    anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (anItemBase);
+    if (anAlertItem)
+      break;
+  }
+
+  if (aReportItem && !aReportItem->GetReport().IsNull())
+  {
+    theMenu->addAction (myActions[MessageModel_ActionType_Deactivate]);
+    theMenu->addAction (myActions[MessageModel_ActionType_Activate]);
+    theMenu->addAction (myActions[MessageModel_ActionType_Clear]);
+#ifdef DEBUG_ALERTS
+    theMenu->addAction (myActions[MessageModel_ActionType_TestMetric]);
+    theMenu->addAction (myActions[MessageModel_ActionType_TestProperties]);
+#endif
+  }
+  else if (anAlertItem)
+  {
+    theMenu->addAction (myActions[MessageModel_ActionType_ExportToShapeView]);
+  }
+
+  theMenu->addSeparator();
+}
+
+// =======================================================================
+// function : onImportReport
+// purpose :
+// =======================================================================
+Handle(Message_Report) MessageModel_Actions::getSelectedReport (QModelIndex& theReportIndex) const
+{
+  MessageModel_ItemReportPtr aReportItem;
+  QModelIndexList aSelectedIndices = mySelectionModel->selectedIndexes();
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    theReportIndex = anIndex;
+    if (aReportItem)
+      break;
+  }
+  if (!aReportItem)
+    return NULL;
+
+  return aReportItem->GetReport();
+}
+
+// =======================================================================
+// function : OnDeactivateReport
+// purpose :
+// =======================================================================
+void MessageModel_Actions::OnDeactivateReport()
+{
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  aReport->SetActive (Standard_False);
+  ((MessageModel_TreeModel*)mySelectionModel->model())->EmitDataChanged (aReportIndex, aReportIndex);
+}
+
+// =======================================================================
+// function : OnActivateReport
+// purpose :
+// =======================================================================
+void MessageModel_Actions::OnActivateReport()
+{
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  aReport->SetActive (Standard_True);
+  ((MessageModel_TreeModel*)mySelectionModel->model())->EmitDataChanged (aReportIndex, aReportIndex);
+}
+
+// =======================================================================
+// function : OnClearReport
+// purpose :
+// =======================================================================
+void MessageModel_Actions::OnClearReport()
+{
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  aReport->Clear();
+  ((MessageModel_TreeModel*)mySelectionModel->model())->EmitDataChanged (aReportIndex, aReportIndex);
+}
+
+// =======================================================================
+// function : OnExportToShapeView
+// purpose :
+// =======================================================================
+void MessageModel_Actions::OnExportToShapeView()
+{
+  TCollection_AsciiString aPluginName ("TKShapeView");
+
+  NCollection_List<Handle(Standard_Transient)> aPluginParameters;
+  if (myParameters->FindParameters (aPluginName))
+    aPluginParameters = myParameters->Parameters (aPluginName);
+  NCollection_List<TCollection_AsciiString> anItemNames;
+  if (myParameters->FindSelectedNames (aPluginName))
+    anItemNames = myParameters->GetSelectedNames (aPluginName);
+
+  QModelIndexList aSelectedIndices = mySelectionModel->selectedIndexes();
+  QStringList anExportedPointers;
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (anItemBase);
+    if (!anAlertItem)
+      continue;
+
+    Handle(Message_Alert) anAlert = anAlertItem->GetAlert();
+    if (anAlert.IsNull())
+      continue;
+
+    Handle(Message_AlertExtended) anExtAlert = Handle(Message_AlertExtended)::DownCast (anAlert);
+    if (anExtAlert.IsNull())
+      continue;
+
+    Handle(Message_Attribute) anAttribute = anExtAlert->Attribute();
+    if (anAttribute.IsNull())
+      continue;
+
+    if (!anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+      continue;
+
+    const TopoDS_Shape aShape = Handle(TopoDS_AlertAttribute)::DownCast (anAttribute)->GetShape();
+    if (aShape.IsNull())
+      continue;
+    aPluginParameters.Append (aShape.TShape());
+    anItemNames.Append (TInspectorAPI_PluginParameters::ParametersToString (aShape));
+
+    anExportedPointers.append (MessageModel_Tools::GetPointerInfo (aShape.TShape(), true).ToCString());
+  }
+
+  if (anExportedPointers.empty())
+      return;
+  myParameters->SetSelectedNames (aPluginName, anItemNames);
+  myParameters->SetParameters (aPluginName, aPluginParameters);
+  QMessageBox::information (0, "Information", QString ("TShapes '%1' are sent to %2 tool.")
+    .arg (anExportedPointers.join (", ")).arg (QString (aPluginName.ToCString())));
+}
+
+// =======================================================================
+// function : OnTestMetric
+// purpose :
+// =======================================================================
+#include <OSD_Chronometer.hxx>
+#include <ctime>
+void MessageModel_Actions::OnTestMetric()
+{
+#ifdef DEBUG_ALERTS
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  Message_PerfMeter aPerfMeter;
+  MESSAGE_INFO ("MessageModel_Actions::OnTestAlerts()", "", &aPerfMeter, NULL);
+  unsigned int start_time =  clock();
+  //Standard_Real aSystemSeconds, aCurrentSeconds;
+  //OSD_Chronometer::GetThreadCPU (aCurrentSeconds, aSystemSeconds);
+
+  Standard_Integer aCounter = 5000;//0;
+  Standard_Real aValue = 0., aValue2 = 0.1;
+
+  double* aMemValue;
+  for (int aTopIt = 0; aTopIt < 4; aTopIt++)
+  {
+    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;
+      }
+    }
+    MESSAGE_INFO ("Calculate", "", &aPerfMeter, NULL);
+  }
+
+  //((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 MessageModel_Actions::OnTestPropertyPanel()
+{
+#ifdef DEBUG_ALERTS
+  QModelIndex aReportIndex;
+  Handle(Message_Report) aReport = getSelectedReport (aReportIndex);
+  if (aReport.IsNull())
+    return;
+
+  Message_PerfMeter aPerfMeter;
+  MESSAGE_INFO ("MessageModel_Actions::OnTestAlerts()", "", &aPerfMeter, NULL);
+
+  // gp_XYZ
+  {
+    gp_XYZ aCoords (1.3, 2.3, 3.4);
+    Standard_SStream aStream;
+    aCoords.DumpJson (aStream);
+    MESSAGE_INFO_STREAM(aStream, "gp_XYZ", "", &aPerfMeter, NULL);
+  }
+  // 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", "", &aPerfMeter, NULL);
+  }
+  // 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", "", &aPerfMeter, NULL);
+  }
+  myTreeModel->UpdateTreeModel();
+#endif
+}
diff --git a/tools/MessageModel/MessageModel_Actions.hxx b/tools/MessageModel/MessageModel_Actions.hxx
new file mode 100644 (file)
index 0000000..c030c97
--- /dev/null
@@ -0,0 +1,104 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_Actions_H
+#define MessageModel_Actions_H
+
+#include <Standard.hxx>
+#include <Standard_Transient.hxx>
+
+#include <inspector/MessageModel_ActionType.hxx>
+#include <inspector/TInspectorAPI_PluginParameters.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QObject>
+#include <QMap>
+#include <QModelIndexList>
+#include <QPoint>
+#include <QString>
+#include <Standard_WarningsRestore.hxx>
+
+class Message_Report;
+class MessageModel_TreeModel;
+
+class QAction;
+class QItemSelectionModel;
+class QMenu;
+class QWidget;
+
+//! \class MessageModel_Actions
+//! \brief This is a listener of popup context menu items and selection change in message model
+class MessageModel_Actions : public QObject
+{
+  Q_OBJECT
+
+public:
+
+  //! Constructor
+  Standard_EXPORT MessageModel_Actions (QWidget* theParent,
+                                        MessageModel_TreeModel* theTreeModel,
+                                        QItemSelectionModel* theModel);
+
+  //! Destructor
+  virtual ~MessageModel_Actions() Standard_OVERRIDE {}
+
+  //! Returns action by the type
+  //! \param theType an action type
+  //! \return an action instance if it exists
+  Standard_EXPORT QAction* GetAction (const MessageModel_ActionType& theType);
+
+  //! Fills popup menu with actions depending on the current selection
+  //! \param theSelectedIndices tree model selected indices
+  //! \param theMenu menu to be filled
+  Standard_EXPORT void AddMenuActions (const QModelIndexList& theSelectedIndices, QMenu* theMenu);
+
+  //! Sets parameters container, it should be used when the plugin is initialized or in update content
+  //! \param theParameters a parameters container
+  void SetParameters (const Handle(TInspectorAPI_PluginParameters)& theParameters)
+  { myParameters = theParameters; }
+
+public slots:
+  //! Set selected report not active
+  void OnDeactivateReport();
+
+  //! Set selected report active
+  void OnActivateReport();
+
+  //! Clears container of alerts of selected report
+  void OnClearReport();
+
+  //! Exports the first selected shape into ShapeViewer plugin.
+  void OnExportToShapeView();
+
+  //! 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();
+
+protected:
+  //! Returns report of selected tree view item if a report item is selected
+  //! \param theReportIndex tree model index of the found report
+  //! \return report instance or NULL
+  Handle(Message_Report) getSelectedReport (QModelIndex& theReportIndex) const;
+
+protected:
+  MessageModel_TreeModel* myTreeModel; //< tree model
+  QItemSelectionModel* mySelectionModel; //< selection model
+  Handle(TInspectorAPI_PluginParameters) myParameters; //!< plugins parameters container
+  QMap<MessageModel_ActionType, QAction*> myActions; //!< container of all actions
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_ItemAlert.cxx b/tools/MessageModel/MessageModel_ItemAlert.cxx
new file mode 100644 (file)
index 0000000..c4882a9
--- /dev/null
@@ -0,0 +1,332 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/ViewControl_Tools.hxx>
+#include <inspector/Convert_TransientShape.hxx>
+#include <inspector/TreeModel_Tools.hxx>
+
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeObject.hxx>
+#include <Message_AttributeStream.hxx>
+#include <Message_CompositeAlerts.hxx>
+
+#include <Bnd_Box.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TopoDS_AlertAttribute.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QColor>
+#include <QIcon>
+#include <Standard_WarningsRestore.hxx>
+
+
+// =======================================================================
+// function : initValue
+// purpose :
+// =======================================================================
+QVariant MessageModel_ItemAlert::initValue (const int theRole) const
+{
+  QVariant aParentValue = MessageModel_ItemBase::initValue (theRole);
+  if (aParentValue.isValid())
+    return aParentValue;
+
+  MessageModel_ItemReportPtr aReportItem = MessageModel_ItemReport::FindReportItem (Parent());
+  if (!aReportItem)
+    return QVariant();
+
+  Handle(Message_Report) aReport = aReportItem->GetReport();
+  if (aReport.IsNull())
+    return QVariant();
+
+  Standard_Boolean isTimeReport = aReport->PerfMeterMode() == Message_PerfMeterMode_UserTimeCPU ||
+                                  aReport->PerfMeterMode() == Message_PerfMeterMode_SystemTimeInfo;
+
+  if (aReport->PerfMeterMode() == Message_PerfMeterMode_UserTimeCPU ||
+      aReport->PerfMeterMode() == Message_PerfMeterMode_SystemTimeInfo)
+
+  if (theRole == Qt::ForegroundRole)
+  {
+    if (!aReport->GetAlerts (Message_Fail).IsEmpty())
+      return QColor(Qt::darkRed);
+
+    for (int aGravityId = (int)Message_Trace; aGravityId <= (int)Message_Fail; aGravityId++)
+    {
+      if (!aReport->IsActive ((Message_Gravity)aGravityId))
+        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->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+      return QIcon (":/icons/item_shape.png");
+    else if (!Handle(Message_AttributeStream)::DownCast (anAttribute).IsNull())
+      return QIcon (":/icons/item_vectorOfValues.png");
+    else
+      return QVariant();
+  }
+
+  if (theRole != Qt::DisplayRole && theRole != Qt::ToolTipRole)
+    return QVariant();
+
+  if (anAlert.IsNull())
+    return QVariant();
+
+  switch (Column())
+  {
+    case 0:
+      return theRole == Qt::DisplayRole ? anAlert->GetMessageKey() : anAlert->DynamicType()->Name();
+    //case 1: return QVariant(); // visibility state
+    //case 2: return rowCount() > 0 ? QVariant (rowCount()) : QVariant();
+    //case 3: return anAlert->ElapsedTime() < 0 ? QVariant() : anAlert->ElapsedTime();
+    case 4:
+    {
+      if (!anExtendedAlert->IsMetricValid())
+        return QVariant();
+
+      if (isTimeReport)
+        return anExtendedAlert->MetricStop() - anExtendedAlert->MetricStart();
+      else
+        return anExtendedAlert->MetricStart();
+    }
+    case 5:
+    {
+      if (!anExtendedAlert->IsMetricValid())
+        return QVariant();
+
+      if (isTimeReport)
+      {
+        TreeModel_ItemBasePtr aParentItem = Parent();
+        MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport> (aParentItem);
+        while (!aReportItem)
+        {
+          aParentItem = aParentItem->Parent();
+          aReportItem = itemDynamicCast<MessageModel_ItemReport> (aParentItem);
+        }
+        double aDivideTo = aReport->CumulativeMetric (Message_Info);
+        double anAlertTime = anExtendedAlert->MetricStop() - anExtendedAlert->MetricStart();
+
+        return aDivideTo == 0 ? QVariant() : 100. * anAlertTime / aDivideTo;
+      }
+      else
+      {
+        TreeModel_ItemBasePtr aParentItem = Parent();
+        //MessageModel_ItemAlertPtr aParentAlertItem = itemDynamicCast<MessageModel_ItemAlert> (aParentItem);
+        //if (aParentAlertItem)
+        //{
+          //double aDeltaToParent = CumulativeMetric (anAlert) - CumulativeMetric (aParentAlertItem->GetAlert());
+
+          //return fabs (aDeltaToParent) > Precision::Confusion() ? QVariant (aDeltaToParent) : QVariant();
+        //}
+        double anAlertMem = anExtendedAlert->MetricStop() - anExtendedAlert->MetricStart();
+        return anAlertMem;
+      }
+    }
+    case 6: return MessageModel_Tools::GetPointerAlertInfo (anAlert).ToCString();
+    case 7: return MessageModel_Tools::GetShapeTypeAlertInfo (anAlert).ToCString();
+    case 8: return MessageModel_Tools::GetStandardTypeAlertInfo (anAlert).ToCString();
+    case 9:
+    {
+      if (!anExtendedAlert.IsNull() && !anExtendedAlert->Attribute().IsNull())
+      {
+        TCollection_AsciiString aDescription = anExtendedAlert->Attribute()->GetDescription();
+        return theRole == Qt::DisplayRole ? TreeModel_Tools::CutString (aDescription.ToCString())
+                                          : aDescription.ToCString();
+      }
+    }
+    default: break;
+  }
+  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->GetCompositeAlerts();
+  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->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 : GetStream
+// purpose :
+// =======================================================================
+void MessageModel_ItemAlert::GetStream (Standard_OStream& OS) const
+{
+  //return;
+  Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (getAlert());
+  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());
+        OS << anAttributeStream->GetStream().str();
+      }
+    }
+  }
+}
+
+// =======================================================================
+// function : createChild
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemAlert::createChild (int theRow, int theColumn)
+{
+  return MessageModel_ItemAlert::CreateItem (currentItem(), theRow, theColumn);
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void MessageModel_ItemAlert::Init()
+{
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport> (Parent());
+  MessageModel_ItemAlertPtr anAlertItem;
+  Handle(Message_Alert) anAlert;
+  if (aReportItem)
+  {
+    Message_ListOfAlert anAlerts;
+    if (aReportItem->GetChildAlerts (Row(), anAlerts))
+    {
+      myAlert = anAlerts.First();
+    }
+  }
+  else
+  {
+    anAlertItem = itemDynamicCast<MessageModel_ItemAlert> (Parent());
+    if (anAlertItem)
+    {
+      Message_ListOfAlert anAlerts;
+      if (anAlertItem->GetChildAlerts (Row(), anAlerts))
+      {
+        myAlert = anAlerts.First();
+      }
+    }
+  }
+
+  /*Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(myAlert);
+  if (!anExtendedAlert.IsNull() && !anExtendedAlert->Attribute().IsNull())
+  {
+    Handle(Message_Attribute) anAttribute = anExtendedAlert->Attribute();
+    if (!anAttribute.IsNull())
+    {
+      if (!Handle(Message_AttributeStream)::DownCast(anAttribute).IsNull())
+      {
+        if (GetProperties().IsNull())
+        {
+          TreeModel_ItemBasePtr anItem = Parent()->Child (Row(), Column(), false);
+          SetProperties (new MessageModel_ItemPropertiesAttributeStream (anItem));
+        }
+        Handle(Message_AttributeStream) anAttributeStream = Handle(Message_AttributeStream)::DownCast (anExtendedAlert->Attribute());
+        Handle(MessageModel_ItemPropertiesAttributeStream) aProperties = Handle(MessageModel_ItemPropertiesAttributeStream)::DownCast (GetProperties());
+        aProperties->Init (anAttributeStream->GetStream());
+      }
+      //if (anAttribute->IsKind (STANDARD_TYPE (Message_AttributeObject)))
+      //  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<MessageModel_ItemAlert*>(this)->Init();
+}
+
+// =======================================================================
+// function : getAlert
+// purpose :
+// =======================================================================
+const Handle(Message_Alert)& MessageModel_ItemAlert::getAlert() const
+{
+  initItem();
+  return myAlert;
+}
diff --git a/tools/MessageModel/MessageModel_ItemAlert.hxx b/tools/MessageModel/MessageModel_ItemAlert.hxx
new file mode 100644 (file)
index 0000000..41950e8
--- /dev/null
@@ -0,0 +1,132 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemAlert_H
+#define MessageModel_ItemAlert_H
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <Message_Alert.hxx>
+#include <Message_ListOfAlert.hxx>
+#include <Message_Report.hxx>
+#include <NCollection_DataMap.hxx>
+#include <Standard.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QMap>
+#include <QVariant>
+#include <Standard_WarningsRestore.hxx>
+
+#include <NCollection_List.hxx>
+#include <NCollection_Vector.hxx>
+
+class QAbstractTableModel;
+
+class MessageModel_ItemAlert;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemAlert> MessageModel_ItemAlertPtr;
+
+//! \class MessageModel_ItemAlert
+//! This item is connected to Message_Alert.
+//! Parent is either MessageModel_ItemRoot or MessageModel_ItemAlert, children are MessageModel_ItemAlert or no children
+class MessageModel_ItemAlert : public MessageModel_ItemBase
+{
+public:
+
+  //! Creates an item wrapped by a shared pointer
+  //! \param theRow the item row positition in the parent item
+  //! \param theColumn the item column positition in the parent item
+  //! \return the pointer to the created item
+  static MessageModel_ItemAlertPtr CreateItem (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  { return MessageModel_ItemAlertPtr (new MessageModel_ItemAlert (theParent, theRow, theColumn)); }
+
+  //! Destructor
+  virtual ~MessageModel_ItemAlert() Standard_OVERRIDE {};
+
+  //! Returns the current shape
+  const Handle(Message_Alert)& GetAlert() const { return myAlert; }
+
+  //! Returns alert of the report for the parameter row
+  Standard_Boolean GetChildAlerts (const int theRow, Message_ListOfAlert& theAlerts) const { return myChildAlerts.Find(theRow, theAlerts); }
+
+  //! Inits the item, fills internal containers
+  Standard_EXPORT virtual void Init() Standard_OVERRIDE;
+
+  //! Resets cached values
+  Standard_EXPORT virtual void Reset() Standard_OVERRIDE;
+
+  //! Return data value for the role.
+  //! \param theRole a value role
+  //! \return the value
+  Standard_EXPORT virtual QVariant initValue (const int theRole) const Standard_OVERRIDE;
+
+  //! \return number of children.
+  Standard_EXPORT virtual int initRowCount() const Standard_OVERRIDE;
+
+  //! Returns stream value of the item to fulfill property panel.
+  //! \return stream value or dummy
+  Standard_EXPORT virtual void GetStream (Standard_OStream& OS) 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<Handle(Standard_Transient)>& 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;
+
+  //! Creates a child item in the given position.
+  //! \param theRow the child row position
+  //! \param theColumn the child column position
+  //! \return the created item
+  virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) Standard_OVERRIDE;
+
+  //! Returns current alert, initialized item if it has not been initialized yet
+  //! \return alert value
+  const Handle(Message_Alert)& getAlert() const;
+
+private:
+
+  //! Constructor
+  MessageModel_ItemAlert (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : MessageModel_ItemBase (theParent, theRow, theColumn) {}
+
+private:
+  Handle(Message_Alert) myAlert;
+
+  NCollection_DataMap<Standard_Integer, Message_ListOfAlert> myChildAlerts; //!< container of child alerts
+
+  TopoDS_Shape myCustomShape;
+  NCollection_List<Handle(Standard_Transient)> myPresentations;
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_ItemBase.cxx b/tools/MessageModel/MessageModel_ItemBase.cxx
new file mode 100644 (file)
index 0000000..de74f85
--- /dev/null
@@ -0,0 +1,47 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+
+// =======================================================================
+// function : isReversed
+// purpose :
+// =======================================================================
+Standard_Boolean MessageModel_ItemBase::isReversed() const
+{
+  TreeModel_ItemBasePtr aParentItem = GetRootItem();
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (aParentItem);
+  return aRootItem ? aRootItem->IsReversed() : Standard_False;
+}
+
+// =======================================================================
+// function : GetRootItem
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemBase::GetRootItem() const
+{
+  TreeModel_ItemBasePtr anItem = Parent();
+  while (anItem)
+  {
+    if (MessageModel_ItemRootPtr aThisRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItem))
+    {
+      return aThisRootItem;
+    }
+    anItem = anItem->Parent();
+  }
+  return TreeModel_ItemBasePtr();
+}
diff --git a/tools/MessageModel/MessageModel_ItemBase.hxx b/tools/MessageModel/MessageModel_ItemBase.hxx
new file mode 100644 (file)
index 0000000..dfd9e7f
--- /dev/null
@@ -0,0 +1,56 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemBase_H
+#define MessageModel_ItemBase_H
+
+#include <Standard.hxx>
+#include <TopoDS_Shape.hxx>
+#include <inspector/TreeModel_ItemBase.hxx>
+
+class MessageModel_ItemBase;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemBase> MessageModel_ItemBasePtr;
+
+//! \class MessageModel_ItemBase
+// \brief Declaration of the tree model base item.
+class MessageModel_ItemBase : public TreeModel_ItemBase
+{
+public:
+
+  //! Resets cached values
+  virtual void Reset() Standard_OVERRIDE { TreeModel_ItemBase::Reset(); }
+
+protected:
+
+  //! Initialize the current item. It creates a backup of the specific item information
+  virtual void initItem() const {};
+
+  //! Constructor
+  //! param theParent a parent item
+  //! \param theRow the item row positition in the parent item
+  //! \param theColumn the item column positition in the parent item
+  MessageModel_ItemBase (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : TreeModel_ItemBase (theParent, theRow, theColumn) {}
+
+  //! Return whether the view is reversed or not
+  //! \return boolean value
+  Standard_Boolean isReversed() const;
+
+  //! Return root item
+  //! \return an item instance
+  TreeModel_ItemBasePtr GetRootItem() const;
+};
+
+#endif
\ No newline at end of file
diff --git a/tools/MessageModel/MessageModel_ItemReport.cxx b/tools/MessageModel/MessageModel_ItemReport.cxx
new file mode 100644 (file)
index 0000000..9730033
--- /dev/null
@@ -0,0 +1,200 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_ItemReport.hxx>
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+
+#include <OSD_Path.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QColor>
+#include <Standard_WarningsRestore.hxx>
+
+// =======================================================================
+// function : initValue
+// purpose :
+// =======================================================================
+QVariant MessageModel_ItemReport::initValue (const int theRole) const
+{
+  QVariant aParentValue = MessageModel_ItemBase::initValue (theRole);
+  if (aParentValue.isValid())
+    return aParentValue;
+
+  const Handle(Message_Report)& aReport = getReport();
+  if (aReport.IsNull())
+    return QVariant();
+
+  if (theRole == Qt::ForegroundRole)
+  {
+    if (!aReport->GetAlerts (Message_Fail).IsEmpty())
+      return QColor(Qt::darkRed);
+
+    for (int aGravityId = (int)Message_Trace; aGravityId <= (int)Message_Fail; aGravityId++)
+    {
+      if (!aReport->IsActive ((Message_Gravity)aGravityId))
+        return QColor(Qt::darkGray);
+    }
+    return QVariant();
+  }
+  if (theRole == Qt::ToolTipRole && !myDescription.IsEmpty() && Column() == 8)
+    return myDescription.ToCString();
+
+  if (theRole != Qt::DisplayRole)
+    return QVariant();
+
+  switch (Column())
+  {
+    case 0: return aReport->DynamicType()->Name();
+    //case 1: return QVariant(); // visibility state
+    //case 2: return rowCount() > 0 ? QVariant (rowCount()) : QVariant();
+    case 4: return aReport->CumulativeMetric (Message_Info);
+    case 5:
+    {
+      if (aReport->PerfMeterMode() == Message_PerfMeterMode_UserTimeCPU ||
+          aReport->PerfMeterMode() == Message_PerfMeterMode_SystemTimeInfo)
+        return "100";
+      else
+        return QVariant();
+    }
+    case 9:
+    {
+      if (myDescription.IsEmpty())
+        return QVariant();
+
+      OSD_Path aPath(myDescription);
+      return QString ("%1%2").arg (aPath.Name().ToCString()).arg (aPath.Extension().ToCString());
+    }
+    default: break;
+  }
+  return QVariant();
+}
+
+// =======================================================================
+// function : initRowCount
+// purpose :
+// =======================================================================
+int MessageModel_ItemReport::initRowCount() const
+{
+  const Handle(Message_Report)& aReport = getReport();
+  if (aReport.IsNull())
+    return 0;
+
+  MessageModel_ItemReport* aCurrentItem = (MessageModel_ItemReport*)this;
+  for (int aGravityId = Message_Trace; aGravityId <= Message_Fail; aGravityId++)
+  {
+    const Message_ListOfAlert& anAlerts = aReport->GetAlerts ((Message_Gravity)aGravityId);
+    for (Message_ListOfAlert::Iterator anIt(anAlerts); anIt.More(); anIt.Next())
+    {
+      Message_ListOfAlert aCurAlerts;
+      aCurAlerts.Append (anIt.Value());
+      aCurrentItem->myChildAlerts.Bind(myChildAlerts.Size(), aCurAlerts);
+    }
+  }
+  return aCurrentItem->myChildAlerts.Size();
+}
+
+// =======================================================================
+// function : createChild
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemReport::createChild (int theRow, int theColumn)
+{
+  return MessageModel_ItemAlert::CreateItem (currentItem(), theRow, theColumn);
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void MessageModel_ItemReport::Init()
+{
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (Parent());
+  myReport = aRootItem ? aRootItem->GetReport (Row(), myDescription) : Handle(Message_Report)();
+
+  MessageModel_ItemBase::Init();
+}
+
+// =======================================================================
+// function : getReport
+// purpose :
+// =======================================================================
+const Handle(Message_Report)& MessageModel_ItemReport::getReport() const
+{
+  initItem();
+  return myReport;
+}
+
+// =======================================================================
+// function : Reset
+// purpose :
+// =======================================================================
+void MessageModel_ItemReport::Reset()
+{
+  MessageModel_ItemBase::Reset();
+  myReport = Handle(Message_Report)();
+  myChildAlerts.Clear();
+}
+
+// =======================================================================
+// function : initItem
+// purpose :
+// =======================================================================
+void MessageModel_ItemReport::initItem() const
+{
+  if (IsInitialized())
+    return;
+  const_cast<MessageModel_ItemReport*>(this)->Init();
+}
+
+// =======================================================================
+// function : FindReportItem
+// purpose :
+// =======================================================================
+MessageModel_ItemReportPtr MessageModel_ItemReport::FindReportItem (const TreeModel_ItemBasePtr& theItem)
+{
+  TreeModel_ItemBasePtr anItem = theItem;
+  while (anItem)
+  {
+    if (MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItem))
+      return aReportItem;
+
+    anItem = anItem->Parent();
+  }
+  return MessageModel_ItemReportPtr();
+}
+
+// =======================================================================
+// function : FindReport
+// purpose :
+// =======================================================================
+Handle(Message_Report) MessageModel_ItemReport::FindReport (const MessageModel_ItemBasePtr& theItem)
+{
+  Handle(Message_Report) aReport;
+
+  MessageModel_ItemBasePtr anItem = theItem;
+  while (anItem)
+  {
+    MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItem);
+
+    if (aReportItem)
+      return aReportItem->GetReport();
+
+    anItem = itemDynamicCast<MessageModel_ItemBase>(anItem->Parent());
+  }
+  return NULL;
+}
diff --git a/tools/MessageModel/MessageModel_ItemReport.hxx b/tools/MessageModel/MessageModel_ItemReport.hxx
new file mode 100644 (file)
index 0000000..258a58a
--- /dev/null
@@ -0,0 +1,114 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemReport_H
+#define MessageModel_ItemReport_H
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <Message_Alert.hxx>
+#include <Message_Report.hxx>
+#include <NCollection_DataMap.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QMap>
+#include <QVariant>
+#include <Standard_WarningsRestore.hxx>
+
+class MessageModel_ItemReport;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemReport> MessageModel_ItemReportPtr;
+
+//! \class MessageModel_ItemReport
+//! This item is connected to Message_Alert.
+//! Parent is MessageModel_ItemRoot, children are MessageModel_ItemAlert or no children
+class MessageModel_ItemReport : public MessageModel_ItemBase
+{
+public:
+
+  //! Creates an item wrapped by a shared pointer
+  //! \param theRow the item row positition in the parent item
+  //! \param theColumn the item column positition in the parent item
+  //! \return the pointer to the created item
+  static MessageModel_ItemReportPtr CreateItem (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  { return MessageModel_ItemReportPtr (new MessageModel_ItemReport (theParent, theRow, theColumn)); }
+
+  //! Destructor
+  virtual ~MessageModel_ItemReport() Standard_OVERRIDE {};
+
+  //! Returns the current shape
+  const Handle(Message_Report)& GetReport() const { return myReport; }
+
+  //! Returns alert of the report for the parameter row
+  Standard_Boolean GetChildAlerts (const int theRow, Message_ListOfAlert& theAlerts) const { return myChildAlerts.Find(theRow, theAlerts); }
+
+  //! Returns the report description or NULL
+  const TCollection_AsciiString& GetDescription() const { return myDescription; }
+
+  //! Inits the item, fills internal containers
+  Standard_EXPORT virtual void Init() Standard_OVERRIDE;
+
+  //! Resets cached values
+  Standard_EXPORT virtual void Reset() Standard_OVERRIDE;
+
+  //! Return data value for the role.
+  //! \param theRole a value role
+  //! \return the value
+  Standard_EXPORT virtual QVariant initValue (const int theRole) const Standard_OVERRIDE;
+
+  //! \return number of children.
+  Standard_EXPORT virtual int initRowCount() const Standard_OVERRIDE;
+
+  //! Returns report of the tree model item. Iterates up by parents intil the report item is found.
+  //! \return an item or NULL
+  Standard_EXPORT static MessageModel_ItemReportPtr FindReportItem (const TreeModel_ItemBasePtr& theItem);
+
+  //! Returns report of the item
+  static Handle(Message_Report) FindReport (const MessageModel_ItemBasePtr& thetItem);
+
+protected:
+
+  //! Initialize the current item. It is empty because Reset() is also empty.
+  virtual void initItem() const Standard_OVERRIDE;
+
+  //! Creates a child item in the given position.
+  //! \param theRow the child row position
+  //! \param theColumn the child column position
+  //! \return the created item
+  virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) Standard_OVERRIDE;
+
+  //! Returns number of child shapes. Init item if it is not initialized
+  //! \return integer value
+  int getRowCount() const;
+
+  //! Returns current shape, initialized item if it has not been initialized yet
+  //! \return shape value
+  const Handle(Message_Report)& getReport() const;
+
+private:
+
+  //! Constructor
+  MessageModel_ItemReport (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : MessageModel_ItemBase (theParent, theRow, theColumn) {}
+
+private:
+
+  NCollection_DataMap<Standard_Integer, Message_ListOfAlert> myChildAlerts; //!< container of child alerts
+
+  Handle(Message_Report) myReport; //!< current report
+  TCollection_AsciiString myDescription; //!< description
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_ItemRoot.cxx b/tools/MessageModel/MessageModel_ItemRoot.cxx
new file mode 100644 (file)
index 0000000..b42dcc8
--- /dev/null
@@ -0,0 +1,96 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+
+// =======================================================================
+// function : SetReport
+// purpose :
+// =======================================================================
+void MessageModel_ItemRoot::SetReport (const int theRowId, const Handle(Message_Report)& theReport,
+                                       const TCollection_AsciiString& theReportDescription)
+{
+  NCollection_List<MessageModel_ReportInformation>::Iterator aReportsIt (myReports);
+  for (int aRowId = 0; aReportsIt.More(); aReportsIt.Next(), aRowId++)
+  {
+    if (aRowId == theRowId)
+      break;
+  }
+  aReportsIt.Value().myReport = theReport;
+  aReportsIt.Value().myDescription = theReportDescription;
+}
+
+// =======================================================================
+// function : GetReport
+// purpose :
+// =======================================================================
+const Handle(Message_Report)& MessageModel_ItemRoot::GetReport (const int theRowId,
+  TCollection_AsciiString& theReportDescription)
+{
+  NCollection_List<MessageModel_ReportInformation>::Iterator aReportsIt (myReports);
+  for (int aRowId = 0; aReportsIt.More(); aReportsIt.Next(), aRowId++)
+  {
+    if (aRowId == theRowId)
+      break;
+  }
+  theReportDescription = aReportsIt.Value().myDescription;
+  return aReportsIt.Value().myReport;
+}
+
+// =======================================================================
+// function : HasReport
+// purpose :
+// =======================================================================
+Standard_Boolean MessageModel_ItemRoot::HasReport (const Handle(Message_Report)& theReport)
+{
+  NCollection_List<MessageModel_ReportInformation>::Iterator aReportsIt (myReports);
+  for (int aRowId = 0; aReportsIt.More(); aReportsIt.Next(), aRowId++)
+  {
+    if (aReportsIt.Value().myReport == theReport)
+      return Standard_True;
+  }
+  return Standard_False;
+}
+
+// =======================================================================
+// function : initValue
+// purpose :
+// =======================================================================
+QVariant MessageModel_ItemRoot::initValue (const int theRole) const
+{
+  QVariant aParentValue = MessageModel_ItemBase::initValue (theRole);
+  if (aParentValue.isValid())
+    return aParentValue;
+
+  if (Column() != 0)
+    return QVariant();
+
+  if (theRole == Qt::DisplayRole)
+    return myName.IsEmpty() ? "Message_Reports" : myName.ToCString();
+
+  return QVariant();
+}
+
+// =======================================================================
+// function : createChild
+// purpose :
+// =======================================================================
+TreeModel_ItemBasePtr MessageModel_ItemRoot::createChild (int theRow, int theColumn)
+{
+  return MessageModel_ItemReport::CreateItem (currentItem(), theRow, theColumn);
+}
+
diff --git a/tools/MessageModel/MessageModel_ItemRoot.hxx b/tools/MessageModel/MessageModel_ItemRoot.hxx
new file mode 100644 (file)
index 0000000..b746567
--- /dev/null
@@ -0,0 +1,123 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_ItemRoot_H
+#define MessageModel_ItemRoot_H
+
+#include <Message_Alert.hxx>
+#include <Message_Report.hxx>
+#include <NCollection_List.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <inspector/MessageModel_ItemBase.hxx>
+
+class MessageModel_ItemRoot;
+typedef QExplicitlySharedDataPointer<MessageModel_ItemRoot> MessageModel_ItemRootPtr;
+
+//! \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
+{
+private:
+  //! \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
+  };
+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);
+
+  //! Clears internal container of added reports
+  void RemoveAllReports() { myReports.Clear(); }
+
+  //! Returns report by the number
+  //! \param theRowId an index of the report in the internal container.
+  Standard_EXPORT const Handle(Message_Report)& GetReport (const int theRowId, TCollection_AsciiString& theReportDescription);
+
+  //! Set the view reversed. If reversed, the last report alert is upper item in the tree view
+  //! \param theReversed boolean flag
+  void SetReversed (const Standard_Boolean& theReversed) { myIsReversed = theReversed; }
+
+  //! Return whether the view is reversed or not
+  //! \return boolean value
+  Standard_Boolean IsReversed() const { return myIsReversed; };
+
+  //! Set the view reversed. If reversed, the last report alert is upper item in the tree view
+  //! \param theReversed boolean flag
+  void SetName (const TCollection_AsciiString& theName) { myName = theName; }
+
+protected:
+
+  //! Return data value for the role.
+  //! \param theRole a value role
+  //! \return the value
+  virtual QVariant initValue (const int theRole) const Standard_OVERRIDE;
+
+  //! \return number of children.
+  virtual int initRowCount() const Standard_OVERRIDE { return myReports.Size(); }
+
+  //! Creates a child item in the given position.
+  //! \param theRow the child row position
+  //! \param theColumn the child column position
+  //! \return the created item
+  virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) Standard_OVERRIDE;
+
+private:
+
+  //! Constructor
+  //! param theParent a parent item
+  MessageModel_ItemRoot (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  : MessageModel_ItemBase (theParent, theRow, theColumn), myIsReversed (Standard_False) {}
+
+private:
+
+  NCollection_List<MessageModel_ReportInformation> myReports; //!< reports sent by algorithms
+  Standard_Boolean myIsReversed; //!< state if the model is reversed
+  TCollection_AsciiString myName; //!< DisplayRole data, if defined
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_ReportCallBack.cxx b/tools/MessageModel/MessageModel_ReportCallBack.cxx
new file mode 100644 (file)
index 0000000..695722f
--- /dev/null
@@ -0,0 +1,18 @@
+// Created on: 2018-06-20
+// 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 "MessageModel_ReportCallBack.hxx"
+
+IMPLEMENT_STANDARD_RTTIEXT(MessageModel_ReportCallBack, Message_ReportCallBack)
diff --git a/tools/MessageModel/MessageModel_ReportCallBack.hxx b/tools/MessageModel/MessageModel_ReportCallBack.hxx
new file mode 100644 (file)
index 0000000..be5d7c9
--- /dev/null
@@ -0,0 +1,48 @@
+// Created on: 2018-06-20
+// 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_ReportCallBack_HeaderFile
+#define _MessageModel_ReportCallBack_HeaderFile
+
+#include <Message_ReportCallBack.hxx>
+
+#include "inspector/TInspectorAPI_Communicator.hxx"
+
+class TInspectorAPI_Communicator;
+DEFINE_STANDARD_HANDLE(MessageModel_ReportCallBack, Message_ReportCallBack)
+
+//! Class to update tree view model by message report events.
+class MessageModel_ReportCallBack : public Message_ReportCallBack
+{
+public:
+
+  //! Constructor
+  MessageModel_ReportCallBack (TInspectorAPI_Communicator* theWindow) : Message_ReportCallBack(), myCommunicator (theWindow) {}
+
+  //! Destructor
+  ~MessageModel_ReportCallBack() {}
+
+  // Interface to be implemented in the child to process the message report event
+  // \theAlert updated alert
+  virtual void Update(const Handle(Message_Alert)& theAlert) { (void)theAlert; /*myCommunicator->UpdateContent();*/ }
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(MessageModel_ReportCallBack, Message_ReportCallBack)
+
+private:
+  TInspectorAPI_Communicator* myCommunicator; //< communicator
+};
+
+#endif // _MessageModel_ReportCallBack_HeaderFile
diff --git a/tools/MessageModel/MessageModel_Tools.cxx b/tools/MessageModel/MessageModel_Tools.cxx
new file mode 100644 (file)
index 0000000..189ecb5
--- /dev/null
@@ -0,0 +1,195 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <inspector/ViewControl_Table.hxx>
+#include <inspector/ViewControl_TableModelValues.hxx>
+#include <inspector/ViewControl_TableModelValuesDefault.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepTools.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeObject.hxx>
+#include <Message_AttributeStream.hxx>
+
+#include <Precision.hxx>
+#include <TopoDS_AlertAttribute.hxx>
+#include <TopoDS_Edge.hxx>
+
+// =======================================================================
+// function : GetPointerInfo
+// purpose :
+// =======================================================================
+TCollection_AsciiString MessageModel_Tools::GetPointerInfo (const Handle(Standard_Transient)& thePointer, const bool isShortInfo)
+{
+  if (thePointer.IsNull())
+    return TCollection_AsciiString();
+
+  std::ostringstream aPtrStr;
+  aPtrStr << thePointer.operator->();
+  if (!isShortInfo)
+    return aPtrStr.str().c_str();
+
+  TCollection_AsciiString anInfoPtr (aPtrStr.str().c_str());
+  for (int aSymbolId = 1; aSymbolId < anInfoPtr.Length(); aSymbolId++)
+  {
+    if (anInfoPtr.Value(aSymbolId) != '0')
+    {
+      anInfoPtr = anInfoPtr.SubString (aSymbolId, anInfoPtr.Length());
+      anInfoPtr.Prepend("0x");
+      return anInfoPtr;
+    }
+  }
+  return aPtrStr.str().c_str();
+}
+
+// =======================================================================
+// function : GetPointerAlertInfo
+// purpose :
+// =======================================================================
+TCollection_AsciiString MessageModel_Tools::GetPointerAlertInfo (const Handle(Message_Alert)& theAlert)
+{
+  Handle(Message_AlertExtended) anExtAlert = Handle(Message_AlertExtended)::DownCast (theAlert);
+  if (anExtAlert.IsNull())
+    return TCollection_AsciiString();
+
+  Handle(Message_Attribute) anAttribute = anExtAlert->Attribute();
+  if (anAttribute.IsNull())
+    return TCollection_AsciiString();
+
+  if (anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+    return GetPointerInfo (Handle(TopoDS_AlertAttribute)::DownCast (anAttribute)->GetShape().TShape());
+  else if (anAttribute->IsKind (STANDARD_TYPE (Message_AttributeObject)))
+    return GetPointerInfo (Handle(Message_AttributeObject)::DownCast (anAttribute)->GetObject());
+  return TCollection_AsciiString();
+}
+
+// =======================================================================
+// function : GetShapeTypeAlertInfo
+// purpose :
+// =======================================================================
+TCollection_AsciiString MessageModel_Tools::GetShapeTypeAlertInfo (const Handle(Message_Alert)& theAlert)
+{
+  Handle(Message_AlertExtended) anExtAlert = Handle(Message_AlertExtended)::DownCast (theAlert);
+  if (anExtAlert.IsNull())
+    return TCollection_AsciiString();
+
+  Handle(Message_Attribute) anAttribute = anExtAlert->Attribute();
+  if (anAttribute.IsNull())
+    return TCollection_AsciiString();
+
+  TopoDS_Shape aShape;
+  if (anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+    aShape = Handle(TopoDS_AlertAttribute)::DownCast (anAttribute)->GetShape();
+
+  if (aShape.IsNull())
+    return TCollection_AsciiString();
+
+  TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+  Standard_SStream aSStream;
+  TopAbs::Print ((TopAbs_ShapeEnum)aShapeType, aSStream);
+  return aSStream.str().c_str();
+}
+
+// =======================================================================
+// function : GetStandardTypeAlertInfo
+// purpose :
+// =======================================================================
+TCollection_AsciiString MessageModel_Tools::GetStandardTypeAlertInfo (const Handle(Message_Alert)& theAlert)
+{
+  Handle(Message_AlertExtended) anExtAlert = Handle(Message_AlertExtended)::DownCast (theAlert);
+  if (anExtAlert.IsNull())
+    return TCollection_AsciiString();
+
+  Handle(Message_Attribute) anAttribute = anExtAlert->Attribute();
+  if (anAttribute.IsNull())
+    return TCollection_AsciiString();
+
+  Handle(Standard_Transient) aPointer;
+  if (anAttribute->IsKind (STANDARD_TYPE (TopoDS_AlertAttribute)))
+    aPointer = Handle(TopoDS_AlertAttribute)::DownCast (anAttribute)->GetShape().TShape();
+  else if (anAttribute->IsKind (STANDARD_TYPE (Message_AttributeObject)))
+    aPointer = Handle(Message_AttributeObject)::DownCast (anAttribute)->GetObject();
+
+  if (aPointer.IsNull())
+    return TCollection_AsciiString();
+
+  return aPointer->DynamicType()->Name();
+}
+
+// =======================================================================
+// function : GetPropertyTableValues
+// purpose :
+// =======================================================================
+void MessageModel_Tools::GetPropertyTableValues (const TreeModel_ItemBasePtr& theItem,
+                                                 QList<ViewControl_TableModelValues*>& theTableValues)
+{
+  //Handle(TreeModel_ItemProperties) anItemProperties = theItem->GetProperties();
+  //if (!anItemProperties.IsNull())
+  //{
+  //  ViewControl_TableModelValues* aTableValues = new ViewControl_TableModelValues();
+  //  aTableValues->SetProperties (anItemProperties);
+  //  theTableValues.append (aTableValues);
+  //  return;
+  //}
+
+  //MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert>(theItem);
+  //if (!anAlertItem)
+  //  return;
+
+  //const Handle(Message_Alert)& anAlert = anAlertItem->GetAlert();
+  //Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast(anAlert);
+  //if (anExtendedAlert.IsNull())
+  //  return;
+
+  //Handle(Message_Attribute) anAttribute = anExtendedAlert->Attribute();
+  //if (anAttribute.IsNull())
+  //  return;
+
+  ////if (anAttribute->IsKind (STANDARD_TYPE (Message_AttributeStream)))
+  ////{
+  //  //int aSectionSize = 200;
+  //  //ViewControl_TableModelValues* aTableValues = new MessageModel_TableModelValues (anAttribute, aSectionSize);
+  //  //theTableValues.append (aTableValues);
+  ////}
+  ////else
+  ////{
+  //if (!anAttribute->GetDescription().IsEmpty())
+  //{
+  //  ViewControl_TableModelValuesDefault* aTableValues = new ViewControl_TableModelValuesDefault();
+  //  QList<TreeModel_HeaderSection> aHeaderValues;
+  //  QVector<QVariant> aValues;
+  //  aHeaderValues << TreeModel_HeaderSection ("Description", -2);
+  //  aValues << anAttribute->GetDescription().ToCString();
+  //  aTableValues->SetHeaderValues (aHeaderValues, Qt::Horizontal);
+
+  //  QString aValueStr = anAttribute->GetDescription().ToCString();
+  //  QStringList aValueStrList = aValueStr.split ("\n");
+  //  int aNbRows = aValueStrList.size();
+
+  //  QFontMetrics aFontMetrics (qApp->font());
+  //  int aHeight = aFontMetrics.boundingRect(aValueStr).height();
+  //  aHeight = (aHeight + TreeModel_Tools::HeaderSectionMargin()) * aNbRows;
+  //  aTableValues->SetValues (aValues);
+  //  aTableValues->SetDefaultSectionSize(Qt::Vertical, aHeight);
+
+  //  theTableValues.append (aTableValues);
+  //}
+  ////}
+}
diff --git a/tools/MessageModel/MessageModel_Tools.hxx b/tools/MessageModel/MessageModel_Tools.hxx
new file mode 100644 (file)
index 0000000..15ff578
--- /dev/null
@@ -0,0 +1,74 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_Tools_H
+#define MessageModel_Tools_H
+
+#include <Standard.hxx>
+
+#include <TCollection_AsciiString.hxx>
+#include <Message_ListOfAlert.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Vector.hxx>
+#include <Standard_Transient.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <inspector/TreeModel_ItemBase.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QList>
+#include <Standard_WarningsRestore.hxx>
+
+class Message_Alert;
+class ViewControl_TableModelValues;
+
+class ViewControl_Table;
+
+//! \class MessageModel_Tools
+//! It gives auxiliary methods for Message classes manipulation
+class MessageModel_Tools
+{
+public:
+
+  //! Convert pointer to string value
+  //! \param thePointer a pointer
+  //! \param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
+  //! \return the string value 
+  Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const Handle(Standard_Transient)& thePointer,
+                                                                 const bool isShortInfo = true);
+
+  //! Returns pointer alert information depening on type of alert (Transient_Object or TopoDS_TShape)
+  //! \param theAlert a message alert
+  //! \return text presentation
+  Standard_EXPORT static TCollection_AsciiString GetPointerAlertInfo (const Handle(Message_Alert)& theAlert);
+
+  //! Returns TopoDS_Shape type alert information or empty string
+  //! \param theAlert a message alert
+  //! \return text presentation
+  Standard_EXPORT static TCollection_AsciiString GetShapeTypeAlertInfo (const Handle(Message_Alert)& theAlert);
+
+  //! Returns dynamic type of an alert object/shape
+  //! \param theAlert a message alert
+  //! \return text presentation
+  Standard_EXPORT static TCollection_AsciiString GetStandardTypeAlertInfo (const Handle(Message_Alert)& theAlert);
+
+  //! Fills container of table values
+  //! \param theAlert a message alert
+  //! \param theTableValue container of values
+  Standard_EXPORT static void GetPropertyTableValues (const TreeModel_ItemBasePtr& theItem,
+                                                      QList<ViewControl_TableModelValues*>& theTableValues);
+};
+
+#endif
diff --git a/tools/MessageModel/MessageModel_TreeModel.cxx b/tools/MessageModel/MessageModel_TreeModel.cxx
new file mode 100644 (file)
index 0000000..a994a4e
--- /dev/null
@@ -0,0 +1,153 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageModel_TreeModel.hxx>
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+
+const int COLUMN_NAME_WIDTH = 310;
+const int COLUMN_SIZE_WIDTH = 30;
+const int COLUMN_POINTER_WIDTH = 70;
+const int COLUMN_SHAPE_TYPE_WIDTH = 75;
+const int COLUMN_STANDARD_TYPE_WIDTH = 120;
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+MessageModel_TreeModel::MessageModel_TreeModel (QObject* theParent)
+: TreeModel_ModelBase (theParent), myIsReversed (Standard_False)
+{
+  SetHeaderItem (0, TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
+  SetHeaderItem (1, TreeModel_HeaderSection ("Size", COLUMN_SIZE_WIDTH));
+  SetHeaderItem (2, TreeModel_HeaderSection ("Pointer", COLUMN_POINTER_WIDTH));
+  SetHeaderItem (3, TreeModel_HeaderSection ("Row", COLUMN_SIZE_WIDTH));
+
+  //SetHeaderItem (0, TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
+  // column 1 is reserved for visiblity state
+  //SetHeaderItem (2, TreeModel_HeaderSection ("Size", COLUMN_SIZE_WIDTH));
+
+  SetHeaderItem (4, TreeModel_HeaderSection ("Metric", -1));
+  SetHeaderItem (5, TreeModel_HeaderSection ("Difference", -1));
+
+  SetHeaderItem (6, TreeModel_HeaderSection ("Pointer", COLUMN_POINTER_WIDTH));
+  SetHeaderItem (7, TreeModel_HeaderSection ("Shape Type", COLUMN_SHAPE_TYPE_WIDTH));
+  SetHeaderItem (8, TreeModel_HeaderSection ("Standard Type", COLUMN_STANDARD_TYPE_WIDTH));
+  SetHeaderItem (9, TreeModel_HeaderSection ("Description", -1));
+}
+
+// =======================================================================
+// function : createRootItem
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::createRootItem (const int theColumnId)
+{
+  myRootItems.insert (theColumnId, MessageModel_ItemRoot::CreateItem (TreeModel_ItemBasePtr(), 0, theColumnId));
+  if (theColumnId == 0)
+      m_pRootItem = myRootItems[0];
+}
+
+// =======================================================================
+// function : HasShape
+// purpose :
+// =======================================================================
+Standard_Boolean MessageModel_TreeModel::HasReport (const Handle(Message_Report)& theReport)
+{
+  if (columnCount() == 0)
+    return Standard_False;
+
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (0));
+  return aRootItem && aRootItem->HasReport (theReport);
+}
+
+// =======================================================================
+// function : AddShape
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::AddReport (const Handle(Message_Report)& theReport,
+                                        const TCollection_AsciiString& theReportDescription)
+{
+  for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
+  {
+    MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (aColId));
+    if (!aRootItem)
+      continue;
+    aRootItem->AddReport (theReport, theReportDescription);
+    aRootItem->SetReversed (myIsReversed);
+  }
+
+  Reset();
+  EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : SetReport
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::SetReport (const int theRowId, const Handle(Message_Report)& theReport,
+                                        const TCollection_AsciiString& theReportDescription)
+{
+  for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
+  {
+    MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (aColId));
+    if (!aRootItem)
+      continue;
+    aRootItem->SetReport (theRowId, theReport, theReportDescription);
+  }
+  Reset();
+  EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : SetReversed
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::SetReversed (const Standard_Boolean& theReversed)
+{
+  myIsReversed = theReversed;
+
+  for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
+  {
+    MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (aColId));
+    if (aRootItem)
+      aRootItem->SetReversed (myIsReversed);
+  }
+
+  Reset();
+  EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : UpdateTreeModel
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::SetRootItemName (const TCollection_AsciiString& theName)
+{
+  MessageModel_ItemRootPtr aRootItem = itemDynamicCast<MessageModel_ItemRoot> (RootItem (0));
+  if (aRootItem)
+    aRootItem->SetName (theName);
+}
+
+// =======================================================================
+// function : UpdateTreeModel
+// purpose :
+// =======================================================================
+void MessageModel_TreeModel::UpdateTreeModel()
+{
+  Reset();
+  EmitLayoutChanged();
+}
diff --git a/tools/MessageModel/MessageModel_TreeModel.hxx b/tools/MessageModel/MessageModel_TreeModel.hxx
new file mode 100644 (file)
index 0000000..c4403a0
--- /dev/null
@@ -0,0 +1,93 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageModel_TreeModel_H
+#define MessageModel_TreeModel_H
+
+#include <inspector/MessageModel_ItemBase.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <Message_Report.hxx>
+#include <inspector/TreeModel_ModelBase.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QMap>
+#include <QObject>
+#include <Standard_WarningsRestore.hxx>
+
+class MessageModel_TreeModel;
+
+//! \class MessageModel_TreeModel
+//! View model to visualize MessageReport/s content
+class MessageModel_TreeModel : public TreeModel_ModelBase
+{
+public:
+
+  //! Constructor
+  Standard_EXPORT MessageModel_TreeModel (QObject* theParent);
+
+  //! Destructor
+  virtual ~MessageModel_TreeModel() Standard_OVERRIDE {};
+
+  //! 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 = "");
+
+  //! 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);
+
+  //! Returns root item by column
+  //! \param theColumn an index of the column
+  //! \return root item instance
+  virtual TreeModel_ItemBasePtr RootItem (const int theColumn) const Standard_OVERRIDE
+  { return myRootItems.contains (theColumn) ? myRootItems[theColumn] : TreeModel_ItemBasePtr(); }
+
+  //! Updates tree model
+  Standard_EXPORT void UpdateTreeModel();
+
+protected:
+  //! Creates root item
+  //! \param theColumnId index of a column
+  virtual void createRootItem (const int theColumnId) Standard_OVERRIDE;
+
+private:
+  QMap<int, TreeModel_ItemBasePtr> myRootItems; //!< container of root items, for each column own root item
+  Standard_Boolean myIsReversed; //!< state if the model is reversed
+};
+
+#endif
diff --git a/tools/MessageModel/icons/item_shape.png b/tools/MessageModel/icons/item_shape.png
new file mode 100644 (file)
index 0000000..a808bc5
Binary files /dev/null and b/tools/MessageModel/icons/item_shape.png differ
diff --git a/tools/MessageModel/icons/item_shape.svg b/tools/MessageModel/icons/item_shape.svg
new file mode 100644 (file)
index 0000000..14313ed
--- /dev/null
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="20"
+   viewBox="0 0 5.2916664 5.2916666"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="item_shape.svg"
+   inkscape:export-filename="D:\OCCT\master_CR29451_1\tools\MessageModel\icons\item_shape.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <defs
+     id="defs2">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="-2.6544163 : -0.28690906 : 1"
+       inkscape:vp_y="0 : 1028.295 : 0"
+       inkscape:vp_z="9.504499 : -1.1228559 : 1"
+       inkscape:persp3d-origin="2.7661607 : -1.3768436 : 1"
+       id="perspective3711" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.839192"
+     inkscape:cx="4.9829441"
+     inkscape:cy="7.75434"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1446"
+     inkscape:window-height="676"
+     inkscape:window-x="1766"
+     inkscape:window-y="124"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(71.966667,-93.642022)">
+    <g
+       sodipodi:type="inkscape:box3d"
+       id="g3741"
+       inkscape:perspectiveID="#perspective3711"
+       inkscape:corner0="0.78884625 : 0.0054590483 : 0 : 1"
+       inkscape:corner7="-0.14713316 : 0.0022509206 : 0.25 : 1">
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3743"
+         style="fill:#353564;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="6"
+         d="m -71.590875,96.691829 v 1.844151 l 1.119347,0.186449 v -1.618024 z"
+         points="-71.590875,98.53598 -70.471528,98.722429 -70.471528,97.104405 -71.590875,96.691829 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3753"
+         style="fill:#e9e9ff;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="11"
+         d="m -70.471528,97.104405 3.521639,-1.795967 v 2.991206 l -3.521639,0.422785 z"
+         points="-66.949889,95.308438 -66.949889,98.299644 -70.471528,98.722429 -70.471528,97.104405 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3745"
+         style="fill:#4d4d9f;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="5"
+         d="m -71.590875,96.691829 3.325505,-2.775198 1.315481,1.391807 -3.521639,1.795967 z"
+         points="-68.26537,93.916631 -66.949889,95.308438 -70.471528,97.104405 -71.590875,96.691829 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3751"
+         style="fill:#afafde;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="13"
+         d="m -71.590875,98.53598 3.325505,-0.751334 1.315481,0.514998 -3.521639,0.422785 z"
+         points="-68.26537,97.784646 -66.949889,98.299644 -70.471528,98.722429 -71.590875,98.53598 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3749"
+         style="fill:#d7d7ff;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="14"
+         d="m -68.26537,93.916631 v 3.868015 l 1.315481,0.514998 v -2.991206 z"
+         points="-68.26537,97.784646 -66.949889,98.299644 -66.949889,95.308438 -68.26537,93.916631 " />
+      <path
+         sodipodi:type="inkscape:box3dside"
+         id="path3747"
+         style="fill:#8686bf;fill-rule:evenodd;stroke:none;stroke-width:1.45609081;stroke-linejoin:round"
+         inkscape:box3dsidetype="3"
+         d="m -71.590875,96.691829 3.325505,-2.775198 v 3.868015 l -3.325505,0.751334 z"
+         points="-68.26537,93.916631 -68.26537,97.784646 -71.590875,98.53598 -71.590875,96.691829 " />
+    </g>
+  </g>
+</svg>
diff --git a/tools/MessageModel/icons/item_vectorOfReal.png b/tools/MessageModel/icons/item_vectorOfReal.png
new file mode 100644 (file)
index 0000000..7181f94
Binary files /dev/null and b/tools/MessageModel/icons/item_vectorOfReal.png differ
diff --git a/tools/MessageModel/icons/item_vectorOfReal.svg b/tools/MessageModel/icons/item_vectorOfReal.svg
new file mode 100644 (file)
index 0000000..38b1032
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="20"
+   viewBox="0 0 5.2916664 5.2916666"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="item_vectorOfReal.svg"
+   inkscape:export-filename="D:\OCCT\master_CR29451_1\tools\MessageModel\icons\item_vectorOfRealVec3.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <defs
+     id="defs2">
+    <linearGradient
+       id="linearGradient4578"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4576" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="-2.6544163 : -0.28690906 : 1"
+       inkscape:vp_y="0 : 1028.295 : 0"
+       inkscape:vp_z="9.504499 : -1.1228559 : 1"
+       inkscape:persp3d-origin="2.7661607 : -1.3768436 : 1"
+       id="perspective3711" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.839192"
+     inkscape:cx="-10.548151"
+     inkscape:cy="10.279721"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1446"
+     inkscape:window-height="838"
+     inkscape:window-x="1733"
+     inkscape:window-y="67"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(71.966667,-93.642022)">
+    <rect
+       id="rect3769"
+       width="4.660512"
+       height="4.443356"
+       x="-71.632576"
+       y="94.056023"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.26458332;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-3"
+       width="4.7041783"
+       height="2.2966287"
+       x="-71.676239"
+       y="96.202751"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.19110738;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-9"
+       width="2.3560426"
+       height="4.4502382"
+       x="-71.617508"
+       y="94.071091"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.18826659;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/tools/MessageModel/icons/item_vectorOfRealVec3.png b/tools/MessageModel/icons/item_vectorOfRealVec3.png
new file mode 100644 (file)
index 0000000..4d0ebf9
Binary files /dev/null and b/tools/MessageModel/icons/item_vectorOfRealVec3.png differ
diff --git a/tools/MessageModel/icons/item_vectorOfRealVec3.svg b/tools/MessageModel/icons/item_vectorOfRealVec3.svg
new file mode 100644 (file)
index 0000000..4d2d42b
--- /dev/null
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="20"
+   viewBox="0 0 5.2916664 5.2916666"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="item_vectorOfRealVec3.svg"
+   inkscape:export-filename="D:\OCCT\master_CR29451_1\tools\MessageModel\icons\item_vectorOfRealVec3.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <defs
+     id="defs2">
+    <linearGradient
+       id="linearGradient4578"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4576" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="-2.6544163 : -0.28690906 : 1"
+       inkscape:vp_y="0 : 1028.295 : 0"
+       inkscape:vp_z="9.504499 : -1.1228559 : 1"
+       inkscape:persp3d-origin="2.7661607 : -1.3768436 : 1"
+       id="perspective3711" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.839192"
+     inkscape:cx="-10.548151"
+     inkscape:cy="10.279721"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1446"
+     inkscape:window-height="838"
+     inkscape:window-x="1733"
+     inkscape:window-y="67"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(71.966667,-93.642022)">
+    <rect
+       id="rect3769"
+       width="4.660512"
+       height="4.443356"
+       x="-71.632576"
+       y="94.056023"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.26458332;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-3"
+       width="4.7041783"
+       height="2.2966287"
+       x="-71.676239"
+       y="96.202751"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.19110738;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-9"
+       width="2.3560426"
+       height="4.4502382"
+       x="-71.617508"
+       y="94.071091"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.18826659;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-9-6"
+       width="0.78304976"
+       height="2.0045512"
+       x="-71.618477"
+       y="94.141006"
+       style="opacity:1;fill:#dc8c8c;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.07284392;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-9-6-0"
+       width="0.78304976"
+       height="2.0045512"
+       x="-70.835426"
+       y="94.141006"
+       style="opacity:1;fill:#8cdc8c;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.07284392;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-9-6-5"
+       width="0.78304976"
+       height="2.0045512"
+       x="-70.052376"
+       y="94.141006"
+       style="opacity:1;fill:#8c8cdc;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.07284392;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/tools/MessageModel/icons/item_vectorOfValues.png b/tools/MessageModel/icons/item_vectorOfValues.png
new file mode 100644 (file)
index 0000000..7181f94
Binary files /dev/null and b/tools/MessageModel/icons/item_vectorOfValues.png differ
diff --git a/tools/MessageModel/icons/item_vectorOfValues.svg b/tools/MessageModel/icons/item_vectorOfValues.svg
new file mode 100644 (file)
index 0000000..38b1032
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="20"
+   viewBox="0 0 5.2916664 5.2916666"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="item_vectorOfReal.svg"
+   inkscape:export-filename="D:\OCCT\master_CR29451_1\tools\MessageModel\icons\item_vectorOfRealVec3.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <defs
+     id="defs2">
+    <linearGradient
+       id="linearGradient4578"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4576" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="-2.6544163 : -0.28690906 : 1"
+       inkscape:vp_y="0 : 1028.295 : 0"
+       inkscape:vp_z="9.504499 : -1.1228559 : 1"
+       inkscape:persp3d-origin="2.7661607 : -1.3768436 : 1"
+       id="perspective3711" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.839192"
+     inkscape:cx="-10.548151"
+     inkscape:cy="10.279721"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1446"
+     inkscape:window-height="838"
+     inkscape:window-x="1733"
+     inkscape:window-y="67"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(71.966667,-93.642022)">
+    <rect
+       id="rect3769"
+       width="4.660512"
+       height="4.443356"
+       x="-71.632576"
+       y="94.056023"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.26458332;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-3"
+       width="4.7041783"
+       height="2.2966287"
+       x="-71.676239"
+       y="96.202751"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.19110738;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <rect
+       id="rect3769-9"
+       width="2.3560426"
+       height="4.4502382"
+       x="-71.617508"
+       y="94.071091"
+       style="opacity:1;fill:none;fill-opacity:1;stroke:#8c8c8c;stroke-width:0.18826659;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/tools/MessageView/FILES b/tools/MessageView/FILES
new file mode 100644 (file)
index 0000000..529ec64
--- /dev/null
@@ -0,0 +1,6 @@
+MessageView_Communicator.cxx
+MessageView_Communicator.hxx
+MessageView_VisibilityState.cxx
+MessageView_VisibilityState.hxx
+MessageView_Window.cxx
+MessageView_Window.hxx
diff --git a/tools/MessageView/MessageView_Communicator.cxx b/tools/MessageView/MessageView_Communicator.cxx
new file mode 100644 (file)
index 0000000..10b9548
--- /dev/null
@@ -0,0 +1,26 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageView_Communicator.hxx>
+
+
+// =======================================================================
+// function :  CreateCommunicator
+// purpose : Creates a communicator by the library loading
+// =======================================================================
+Standard_EXPORTEXTERNC TInspectorAPI_Communicator* CreateCommunicator()
+{
+  return new MessageView_Communicator();
+}
diff --git a/tools/MessageView/MessageView_Communicator.hxx b/tools/MessageView/MessageView_Communicator.hxx
new file mode 100644 (file)
index 0000000..2164e22
--- /dev/null
@@ -0,0 +1,68 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageView_Communicator_H
+#define MessageView_Communicator_H
+
+#include <inspector/MessageModel_ReportCallBack.hxx>
+#include <inspector/MessageView_Window.hxx>
+#include <inspector/TInspectorAPI_Communicator.hxx>
+
+//! \class MessageView_Communicator.
+//! \brief This is a connector from TInspector application to MessageView window
+class MessageView_Communicator : public TInspectorAPI_Communicator
+{
+public:
+
+  //! Constructor
+  MessageView_Communicator() : TInspectorAPI_Communicator(), myWindow (new MessageView_Window (0))
+  { myWindow->SetCallBack (new MessageModel_ReportCallBack (this)); }
+
+  //! 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 (file)
index 0000000..5b7e5d4
--- /dev/null
@@ -0,0 +1,140 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageView_VisibilityState.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeStream.hxx>
+
+#include <TopoDS_AlertAttribute.hxx>
+
+// =======================================================================
+// function : CanBeVisible
+// purpose :
+// =======================================================================
+bool MessageView_VisibilityState::CanBeVisible (const QModelIndex& theIndex) const
+{
+  MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex);
+  if (anAlertItem)
+  {
+    NCollection_List<Handle(Standard_Transient)> aPresentations;
+    anAlertItem->GetPresentations (aPresentations);
+    if (!aPresentations.IsEmpty())
+      return true;
+  }
+
+  return !getShape (theIndex).IsNull();// || hasTableValues (theIndex);
+}
+
+// =======================================================================
+// function : SetVisible
+// purpose :
+// =======================================================================
+bool MessageView_VisibilityState::SetVisible (const QModelIndex& theIndex, const bool theState, const bool toEmitDataChanged)
+{
+  TopoDS_Shape aShape = getShape (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 (getShape (theIndex), myPresentationType);
+}
+
+// =======================================================================
+// function : getAlertItem
+// purpose :
+// =======================================================================
+MessageModel_ItemAlertPtr MessageView_VisibilityState::getAlertItem (const QModelIndex& theIndex) const
+{
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (theIndex);
+  if (!anItemBase)
+    return MessageModel_ItemAlertPtr();
+
+  MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert>(anItemBase);
+  return anAlertItem;
+}
+
+// =======================================================================
+// function : getShape
+// purpose :
+// =======================================================================
+TopoDS_Shape MessageView_VisibilityState::getShape (const QModelIndex& theIndex) const
+{
+  MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex);
+  if (!anAlertItem)
+    return TopoDS_Shape();
+
+  if (!anAlertItem->GetCustomShape().IsNull())
+    return anAlertItem->GetCustomShape();
+
+  Handle(Message_Alert) anAlert = anAlertItem->GetAlert();
+  if (anAlert.IsNull())
+    return TopoDS_Shape();
+
+  Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast(anAlert);
+  if (anAlertExtended.IsNull())
+    return TopoDS_Shape();
+
+  Handle(TopoDS_AlertAttribute) aShapeAttribute = Handle(TopoDS_AlertAttribute)::DownCast (anAlertExtended->Attribute());
+  if (!aShapeAttribute.IsNull())
+    return aShapeAttribute->GetShape();
+
+  return TopoDS_Shape();
+}
+
+// =======================================================================
+// function : hasTableValues
+// purpose :
+// =======================================================================
+bool MessageView_VisibilityState::hasTableValues (const QModelIndex& theIndex) const
+{
+  MessageModel_ItemAlertPtr anAlertItem = getAlertItem (theIndex);
+  if (!anAlertItem)
+    return false;
+
+  Handle(Message_Alert) anAlert = anAlertItem->GetAlert();
+  if (anAlert.IsNull())
+    return false;
+
+  if (anAlert->IsKind (STANDARD_TYPE (Message_AttributeStream)))
+    return true;
+
+  return false;
+}
\ No newline at end of file
diff --git a/tools/MessageView/MessageView_VisibilityState.hxx b/tools/MessageView/MessageView_VisibilityState.hxx
new file mode 100644 (file)
index 0000000..787558a
--- /dev/null
@@ -0,0 +1,87 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageView_VisibilityState_H
+#define MessageView_VisibilityState_H
+
+#include <inspector/TreeModel_VisibilityState.hxx>
+
+#include <inspector/MessageModel_ItemAlert.hxx>
+
+#include <inspector/View_Displayer.hxx>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <TopoDS_Shape.hxx>
+
+class TreeModel_ModelBase;
+
+//! \class MessageView_VisibilityState
+//! \brief Class provides connection between model and visualization control
+class MessageView_VisibilityState : public TreeModel_VisibilityState
+{
+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;
+
+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 getShape (const QModelIndex& theIndex) const;
+
+  //! Returns true if alert of the item has table values
+  //! \param theIndex tree model index
+  //! \return boolean result
+  bool hasTableValues (const QModelIndex& theIndex) const;
+
+private:
+  View_Displayer* myDisplayer; //! view displayer
+  View_PresentationType myPresentationType; //! presentation type
+};
+
+#endif
diff --git a/tools/MessageView/MessageView_Window.cxx b/tools/MessageView/MessageView_Window.cxx
new file mode 100644 (file)
index 0000000..69fda29
--- /dev/null
@@ -0,0 +1,818 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/MessageView_Window.hxx>
+#include <inspector/MessageView_VisibilityState.hxx>
+
+#include <inspector/MessageModel_Actions.hxx>
+#include <inspector/MessageModel_ItemAlert.hxx>
+#include <inspector/MessageModel_ItemReport.hxx>
+#include <inspector/MessageModel_ItemRoot.hxx>
+#include <inspector/MessageModel_ReportCallBack.hxx>
+#include <inspector/MessageModel_Tools.hxx>
+#include <inspector/MessageModel_TreeModel.hxx>
+
+#include <inspector/TreeModel_ContextMenu.hxx>
+#include <inspector/TreeModel_ItemStream.hxx>
+#include <inspector/TreeModel_Tools.hxx>
+
+#include <inspector/ViewControl_PropertyView.hxx>
+#include <inspector/ViewControl_TableModelValues.hxx>
+#include <inspector/ViewControl_TreeView.hxx>
+#include <inspector/Convert_TransientShape.hxx>
+
+#include <inspector/View_Tools.hxx>
+#include <inspector/View_Viewer.hxx>
+#include <inspector/View_Widget.hxx>
+
+#include <AIS_Shape.hxx>
+#include <Graphic3d_Camera.hxx>
+#include <OSD_Environment.hxx>
+
+#include <OSD_Directory.hxx>
+#include <OSD_Protection.hxx>
+
+#include <TCollection_AsciiString.hxx>
+//#include <TopoDS_AlertWithShape.hxx>
+
+#include <XmlDrivers_MessageReportStorage.hxx>
+
+#include <inspector/ViewControl_Tools.hxx>
+#include <inspector/View_Displayer.hxx>
+#include <inspector/View_ToolBar.hxx>
+#include <inspector/View_Widget.hxx>
+#include <inspector/View_Window.hxx>
+#include <inspector/View_Viewer.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepTools.hxx>
+#include <OSD_File.hxx>
+#include <OSD_Path.hxx>
+
+#include <QApplication>
+#include <QAction>
+#include <QComboBox>
+#include <QDockWidget>
+#include <QDir>
+#include <QFile>
+#include <QFileDialog>
+#include <QHeaderView>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMessageBox>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QTextEdit>
+#include <QTextStream>
+#include <QToolBar>
+#include <QToolButton>
+#include <QTreeView>
+#include <QWidget>
+#include <QVBoxLayout>
+
+const int DEFAULT_TEXT_VIEW_WIDTH = 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 <Prs3d_PointAspect.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+Handle(Prs3d_Drawer) GetPreviewAttributes (const Handle(AIS_InteractiveContext)& theContext)
+{
+  Handle(Prs3d_Drawer) myDrawer = new Prs3d_Drawer();
+  myDrawer->Link (theContext->DefaultDrawer());
+
+  Quantity_Color aColor(Quantity_NOC_TOMATO);//Quantity_NOC_GREENYELLOW));//Quantity_NOC_BLUE1));
+  Standard_ShortReal aTransparency = 0.8;
+
+  // point parameters
+  myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_O_PLUS, aColor, 3.0));
+
+  // shading parameters
+  Graphic3d_MaterialAspect aShadingMaterial;
+  aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
+  aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
+
+  myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+  myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  myDrawer->ShadingAspect()->SetColor (aColor);
+  myDrawer->ShadingAspect()->SetMaterial (aShadingMaterial);
+
+  myDrawer->ShadingAspect()->Aspect()->ChangeFrontMaterial().SetTransparency (aTransparency);
+  myDrawer->ShadingAspect()->Aspect()->ChangeBackMaterial() .SetTransparency (aTransparency);
+  myDrawer->SetTransparency (aTransparency);
+
+  // common parameters
+  myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
+
+  return myDrawer;
+}
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+MessageView_Window::MessageView_Window (QWidget* theParent)
+: QObject (theParent)
+{
+  myMainWindow = new QMainWindow (theParent);
+
+  myTreeView = new ViewControl_TreeView (myMainWindow);
+  ((ViewControl_TreeView*)myTreeView)->SetPredefinedSize (QSize (MESSAGEVIEW_DEFAULT_TREE_VIEW_WIDTH,
+                                                                 MESSAGEVIEW_DEFAULT_TREE_VIEW_HEIGHT));
+  MessageModel_TreeModel* aModel = new MessageModel_TreeModel (myTreeView);
+  //aModel->SetReversed (Standard_True);
+  for (int i = 6; i <= 8; i++) // hide shape parameters columns
+  {
+    TreeModel_HeaderSection anItem = aModel->GetHeaderItem (i);
+    anItem.SetIsHidden (true);
+    aModel->SetHeaderItem (i, anItem);
+  }
+
+  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);
+  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 (propertyViewSelectionChanged()), this, SLOT (onPropertyViewSelectionChanged ()));
+
+  // view
+  myViewWindow = new View_Window (myMainWindow, false);
+  connect (myViewWindow, SIGNAL(eraseAllPerformed()), this, SLOT(onEraseAllPerformed()));
+  aVisibilityState->SetDisplayer (myViewWindow->GetDisplayer());
+  aVisibilityState->SetPresentationType (View_PresentationType_Main);
+  myViewWindow->GetView()->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);
+}
+
+// =======================================================================
+// function : SetParent
+// purpose :
+// =======================================================================
+void MessageView_Window::SetParent (void* theParent)
+{
+  QWidget* aParent = (QWidget*)theParent;
+  if (aParent)
+  {
+    QLayout* aLayout = aParent->layout();
+    if (aLayout)
+      aLayout->addWidget (GetMainWindow());
+  }
+  else
+  {
+    GetMainWindow()->setParent (0);
+    GetMainWindow()->setVisible (true);
+  }
+}
+
+// =======================================================================
+// function : FillActionsMenu
+// purpose :
+// =======================================================================
+void MessageView_Window::FillActionsMenu (void* theMenu)
+{
+  QMenu* aMenu = (QMenu*)theMenu;
+  QList<QDockWidget*> aDockwidgets = myMainWindow->findChildren<QDockWidget*>();
+  for (QList<QDockWidget*>::iterator it = aDockwidgets.begin(); it != aDockwidgets.end(); ++it)
+  {
+    QDockWidget* aDockWidget = *it;
+    if (aDockWidget->parentWidget() == myMainWindow)
+      aMenu->addAction (aDockWidget->toggleViewAction());
+  }
+}
+
+// =======================================================================
+// function : GetPreferences
+// purpose :
+// =======================================================================
+void MessageView_Window::GetPreferences (TInspectorAPI_PreferencesDataMap& theItem)
+{
+  theItem.Clear();
+  theItem.Bind ("geometry",  TreeModel_Tools::ToString (myMainWindow->saveState()).toStdString().c_str());
+
+  QMap<QString, QString> anItems;
+  TreeModel_Tools::SaveState (myTreeView, anItems);
+  View_Tools::SaveState (myViewWindow, anItems);
+
+  for (QMap<QString, QString>::const_iterator anItemsIt = anItems.begin(); anItemsIt != anItems.end(); anItemsIt++)
+    theItem.Bind (anItemsIt.key().toStdString().c_str(), anItemsIt.value().toStdString().c_str());
+}
+
+// =======================================================================
+// function : SetPreferences
+// purpose :
+// =======================================================================
+void MessageView_Window::SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem)
+{
+  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 (View_Tools::RestoreState (myViewWindow, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
+      continue;
+  }
+}
+
+// =======================================================================
+// function : UpdateContent
+// purpose :
+// =======================================================================
+void MessageView_Window::UpdateContent()
+{
+  bool isUpdated = false;
+  TCollection_AsciiString aName = "TKMessageView";
+  if (myParameters->FindParameters (aName))
+  {
+    NCollection_List<Handle(Standard_Transient)> aParameters = myParameters->Parameters (aName);
+    // Init will remove from parameters those, that are processed only one time (TShape)
+    Init (aParameters);
+    myParameters->SetParameters (aName, aParameters);
+    isUpdated = true;
+  }
+  if (myParameters->FindFileNames (aName))
+  {
+    for (NCollection_List<TCollection_AsciiString>::Iterator aFilesIt (myParameters->FileNames (aName));
+         aFilesIt.More(); aFilesIt.Next())
+      openFile (aFilesIt.Value());
+
+    NCollection_List<TCollection_AsciiString> aNames;
+    myParameters->SetFileNames (aName, aNames);
+    isUpdated = true;
+  }
+  Handle(Message_Report) aDefaultReport = Message_Report::CurrentReport( Standard_False);
+  MessageModel_TreeModel* aViewModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  if (!aDefaultReport.IsNull() && !aViewModel->HasReport (aDefaultReport))
+  {
+    aDefaultReport->SetCallBack (myCallBack);
+    addReport (aDefaultReport);
+  }
+  // reload report of selected item
+  onReloadReport();
+
+  updateTreeModel();
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void MessageView_Window::Init (NCollection_List<Handle(Standard_Transient)>& theParameters)
+{
+  Handle(AIS_InteractiveContext) aContext;
+  NCollection_List<Handle(Standard_Transient)> aParameters;
+
+  Handle(Message_ReportCallBack) aReportCallBack;
+  Handle(Graphic3d_Camera) aViewCamera;
+
+  for (NCollection_List<Handle(Standard_Transient)>::Iterator aParamsIt (theParameters);
+       aParamsIt.More(); aParamsIt.Next())
+  {
+    Handle(Standard_Transient) anObject = aParamsIt.Value();
+    Handle(Message_Report) aMessageReport = Handle(Message_Report)::DownCast (anObject);
+    if (!aMessageReport.IsNull())
+    {
+      aMessageReport->SetCallBack (myCallBack);
+      addReport (aMessageReport);
+    }
+    else if (!Handle(AIS_InteractiveContext)::DownCast (anObject).IsNull())
+    {
+      aParameters.Append (anObject);
+      if (aContext.IsNull())
+        aContext = Handle(AIS_InteractiveContext)::DownCast (anObject);
+    }
+    else if (!Handle(Graphic3d_Camera)::DownCast (anObject).IsNull())
+    {
+      aViewCamera = Handle(Graphic3d_Camera)::DownCast (anObject);
+    }
+  }
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  if (!aTreeModel)
+    return;
+
+  aTreeModel->EmitLayoutChanged();
+
+  if (!aContext.IsNull())
+  {
+    myViewWindow->SetContext (View_ContextType_External, aContext);
+  }
+
+  if (!aViewCamera.IsNull())
+    myViewWindow->GetView()->GetViewer()->GetView()->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<MessageModel_TreeModel*> (myTreeView->model());
+  if (!aViewModel)
+    return;
+
+  aViewModel->UpdateTreeModel();
+}
+
+// =======================================================================
+// function : addReport
+// purpose :
+// =======================================================================
+void MessageView_Window::addReport (const Handle(Message_Report)& theReport,
+                                    const TCollection_AsciiString& theReportDescription)
+{
+  MessageModel_TreeModel* aModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  aModel->AddReport (theReport, theReportDescription);
+}
+
+// =======================================================================
+// function : onTreeViewSelectionChanged
+// purpose :
+// =======================================================================
+void MessageView_Window::onTreeViewVisibilityClicked(const QModelIndex& theIndex)
+{
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  TreeModel_VisibilityState* aVisibilityState = aTreeModel->GetVisibilityState();
+  if (!aVisibilityState->IsVisible (theIndex))
+    myPropertyView->ClearActiveTablesSelection();
+}
+
+// =======================================================================
+// function : onTreeViewSelectionChanged
+// purpose :
+// =======================================================================
+void MessageView_Window::onTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)
+{
+  if (!myPropertyPanelWidget->toggleViewAction()->isChecked())
+    return;
+
+  updatePropertyPanelBySelection();
+
+  NCollection_List<Handle(Standard_Transient)> aPresentations;
+  MessageModel_ItemRootPtr aRootItem;
+  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->GetProperties();
+    //if (anItemProperties)
+    //  anItemProperties->GetPresentations (-1, -1, aPresentations);
+    TreeModel_ItemStreamPtr aStreamParent = itemDynamicCast<TreeModel_ItemStream> (anItemBase);
+    if (!aStreamParent)
+      return;
+
+    Handle(TreeModel_ItemProperties) anItemProperties = aStreamParent->Properties ();
+    if (anItemProperties)
+      anItemProperties->GetPresentations (-1, -1, aPresentations);
+
+    MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert>(anItemBase);
+    if (!anAlertItem)
+      continue;
+    anAlertItem->GetPresentations (aPresentations);
+  }
+  updatePreviewPresentation (aPresentations);
+}
+
+// =======================================================================
+// function : onTreeViewContextMenuRequested
+// purpose :
+// =======================================================================
+void MessageView_Window::onTreeViewContextMenuRequested (const QPoint& thePosition)
+{
+  QMenu* aMenu = new QMenu (GetMainWindow());
+
+  MessageModel_ItemRootPtr aRootItem;
+  MessageModel_ItemReportPtr aReportItem;
+  QModelIndexList aSelectedIndices = myTreeView->selectionModel()->selectedIndexes();
+
+  for (QModelIndexList::const_iterator aSelIt = aSelectedIndices.begin(); aSelIt != aSelectedIndices.end(); aSelIt++)
+  {
+    QModelIndex anIndex = *aSelIt;
+    if (anIndex.column() != 0)
+      continue;
+
+    TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+    if (!anItemBase)
+      continue;
+
+    aRootItem = itemDynamicCast<MessageModel_ItemRoot> (anItemBase);
+    if (aRootItem)
+      break;
+    aReportItem = itemDynamicCast<MessageModel_ItemReport> (anItemBase);
+    if (aReportItem)
+      break;
+  }
+  if (aRootItem)
+  {
+    aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Import Report"), SLOT (onImportReport()), myMainWindow, this));
+    // unite
+    //MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+    //aMenu->addAction (ViewControl_Tools::CreateAction (aTreeModel->IsUniteAlerts() ? tr ("SetUniteAlerts - OFF") : tr ("SetUniteAlerts - ON"),
+    //                  SLOT (onUniteAlerts()), myMainWindow, this));
+    // reversed
+    //aMenu->addAction (ViewControl_Tools::CreateAction (aTreeModel->IsReversed() ? tr ("SetReversed - OFF") : tr ("SetReversed - ON"),
+    //                  SLOT (onSetReversedAlerts()), myMainWindow, this));
+  }
+  else if (aReportItem)
+  {
+    aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Export Report"), SLOT (onExportReport()), myMainWindow, this));
+    const TCollection_AsciiString& aDescription = aReportItem->GetDescription();
+     if (!aDescription.IsEmpty())
+     {
+       OSD_Path aPath(aDescription);
+       OSD_File aDescriptionFile (aPath);
+       if (aDescriptionFile.IsReadable())
+         aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Reload"), SLOT (onReloadReport()), myMainWindow, this));
+     }
+  }
+  aMenu->addSeparator();
+  myTreeViewActions->AddMenuActions (aSelectedIndices, aMenu);
+
+  QPoint aPoint = myTreeView->mapToGlobal (thePosition);
+  aMenu->exec (aPoint);
+}
+
+// =======================================================================
+// function : onPropertyPanelShown
+// purpose :
+// =======================================================================
+void MessageView_Window::onPropertyPanelShown (bool isToggled)
+{
+  if (!isToggled)
+    return;
+
+  updatePropertyPanelBySelection();
+}
+
+// =======================================================================
+// function : onPropertyViewSelectionChanged
+// purpose :
+// =======================================================================
+void MessageView_Window::onPropertyViewSelectionChanged()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex aSelectedIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  QModelIndex anIndex = myTreeView->model()->index (aSelectedIndex.row(), TreeModel_ColumnType_Visibility, aSelectedIndex.parent());
+
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+  MessageModel_ItemAlertPtr anAlertItem = itemDynamicCast<MessageModel_ItemAlert>(anItemBase);
+  if (!anAlertItem)
+    return;
+
+  QList<ViewControl_Table*> aPropertyTables;
+  myPropertyView->GetActiveTables (aPropertyTables);
+  if (aPropertyTables.isEmpty())
+    return;
+
+  ViewControl_Table* aFirstTable = aPropertyTables[0]; // TODO: implement for several tables
+
+  QMap<int, QList<int>> aSelectedIndices;
+  aFirstTable->GetSelectedIndices (aSelectedIndices);
+
+  // clear presentation if selection is empty
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  TreeModel_VisibilityState* aVisibilityState = aTreeModel->GetVisibilityState();
+  if (aSelectedIndices.isEmpty() && aVisibilityState->IsVisible (anIndex))
+  {
+    aVisibilityState->SetVisible (anIndex, false, true);
+    anAlertItem->SetCustomShape (TopoDS_Shape());
+    return;
+  }
+
+  /*TopoDS_Shape aShapeOfSelection = MessageModel_Tools::BuildShape (anAlertItem->GetAlert(), aSelectedIndices[0], aFirstTable);
+  if (aShapeOfSelection.IsNull())
+    return;
+
+  if (aVisibilityState->IsVisible (anIndex))
+  {
+    View_Displayer* aDisplayer = myViewWindow->GetDisplayer();
+
+    Handle(AIS_InteractiveObject) aPresentation = myViewWindow->GetDisplayer()->FindPresentation (anAlertItem->GetCustomShape());
+
+    Handle(AIS_Shape) aShapePresentation = Handle(AIS_Shape)::DownCast (aPresentation);
+    aShapePresentation->Set (aShapeOfSelection);
+
+    aDisplayer->RedisplayPresentation (aPresentation);
+    anAlertItem->SetCustomShape (aShapeOfSelection);
+  }
+  else
+  {
+    anAlertItem->SetCustomShape (aShapeOfSelection);
+    aVisibilityState->SetVisible (anIndex, true);
+  }*/
+}
+
+// =======================================================================
+// function : onEraseAllPerformed
+// purpose :
+// =======================================================================
+void MessageView_Window::onEraseAllPerformed()
+{
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+
+  // TODO: provide update for only visibility state for better performance  TopoDS_Shape myCustomShape;
+
+  aTreeModel->Reset();
+  aTreeModel->EmitLayoutChanged();
+}
+
+// =======================================================================
+// function : onExportReport
+// purpose :
+// =======================================================================
+void MessageView_Window::onExportReport()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItemBase);
+  if (!aReportItem)
+    return;
+
+  QString aFilter (tr ("Document file (*.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;
+
+  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<MessageModel_TreeModel*> (myTreeView->model());
+  //Standard_Boolean isUniteAlerts = aTreeModel->IsUniteAlerts();
+
+  //aTreeModel->SetUniteAlerts (!isUniteAlerts);
+//}
+
+// =======================================================================
+// function : onSetReversedAlerts
+// purpose :
+// =======================================================================
+void MessageView_Window::onSetReversedAlerts()
+{
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  Standard_Boolean isReversed = aTreeModel->IsReversed();
+
+  aTreeModel->SetReversed (!isReversed);
+}
+
+
+// =======================================================================
+// function : onReloadReport
+// purpose :
+// =======================================================================
+void MessageView_Window::onReloadReport()
+{
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+  MessageModel_ItemReportPtr aReportItem = itemDynamicCast<MessageModel_ItemReport>(anItemBase);
+  if (!aReportItem)
+    aReportItem = MessageModel_ItemReport::FindReportItem (anItemBase);
+
+  if (!aReportItem)
+    return;
+
+  const TCollection_AsciiString aDescription = aReportItem->GetDescription();
+  Handle(Message_Report) aReport = XmlDrivers_MessageReportStorage::ImportReport (aDescription);
+  if (aReport.IsNull())
+    return;
+
+  MessageModel_TreeModel* aTreeModel = dynamic_cast<MessageModel_TreeModel*> (myTreeView->model());
+  aModel->clearSelection();
+  aTreeModel->SetReport (aReportItem->Row(), aReport, aDescription);
+}
+
+// =======================================================================
+// function : updatePropertyPanelBySelection
+// purpose :
+// =======================================================================
+void MessageView_Window::updatePropertyPanelBySelection()
+{
+  /*QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
+  if (!anItemBase)
+    return;
+
+  QList<ViewControl_TableModelValues*> aTableValues;
+  MessageModel_Tools::GetPropertyTableValues (anItemBase, aTableValues);
+
+  myPropertyView->Init (aTableValues);*/
+  QList<ViewControl_TableModelValues*> aTableValuesList;
+
+  QItemSelectionModel* aModel = myTreeView->selectionModel();
+  if (!aModel)
+    return;
+
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
+  TreeModel_ItemStreamPtr aStreamItem = itemDynamicCast<TreeModel_ItemStream> (TreeModel_ModelBase::GetItemByIndex (anIndex));
+  if (aStreamItem)
+  {
+    Handle(TreeModel_ItemProperties) anItemProperties = aStreamItem->Properties ();
+    if (!anItemProperties.IsNull())
+    {
+      ViewControl_TableModelValues* aTableValues = new ViewControl_TableModelValues();
+      aTableValues->SetProperties (anItemProperties);
+      aTableValuesList.append (aTableValues);
+    }
+  }
+  myPropertyView->Init (aTableValuesList);
+}
+
+// =======================================================================
+// function : updatePreviewPresentation
+// purpose :
+// =======================================================================
+void MessageView_Window::updatePreviewPresentation (const NCollection_List<Handle(Standard_Transient)>& thePresentations)
+{
+  Handle(AIS_InteractiveContext) aContext = myViewWindow->GetViewToolBar()->GetCurrentContext();
+  if (aContext.IsNull())
+    return;
+
+  if (!myPreviewPresentations.IsEmpty())
+  {
+    for (NCollection_List<Handle(Standard_Transient)>::Iterator aDisplayedIt (myPreviewPresentations); aDisplayedIt.More(); aDisplayedIt.Next())
+    {
+      Handle(AIS_InteractiveObject) aPrs = Handle(AIS_InteractiveObject)::DownCast (aDisplayedIt.Value());
+      if (!aPrs.IsNull() && aPrs->GetContext() == aContext)
+        aContext->Remove (aPrs, Standard_True);
+    }
+  }
+  myPreviewPresentations.Clear();
+
+  myPreviewPresentations = thePresentations;
+  if (myPreviewPresentations.IsEmpty())
+    return;
+
+  BRep_Builder aBuilder;
+  TopoDS_Compound aCompound;
+  aBuilder.MakeCompound (aCompound);
+  for (NCollection_List<Handle(Standard_Transient)>::Iterator aDisplayedIt (myPreviewPresentations); aDisplayedIt.More(); aDisplayedIt.Next())
+  {
+    Handle(AIS_InteractiveObject) aPrs = Handle(AIS_InteractiveObject)::DownCast (aDisplayedIt.Value());
+    if (!aPrs.IsNull())
+    {
+      if (!aPrs->GetContext().IsNull())
+        continue; // not possible to display one object in several contexts
+      aContext->Display (aPrs, AIS_Shaded, -1/*do not participate in selection*/, Standard_True);
+    }
+    else if (!Handle(Convert_TransientShape)::DownCast (aDisplayedIt.Value()).IsNull())
+    {
+      Handle(Convert_TransientShape) aShapeObject = Handle(Convert_TransientShape)::DownCast (aDisplayedIt.Value());
+      aBuilder.Add (aCompound, aShapeObject->GetShape());
+    }
+  }
+
+  if (aCompound.IsNull())
+  {
+    if (!aContext.IsNull() && myPreviewPresentation->GetContext() == aContext)
+      aContext->Remove (myPreviewPresentation, Standard_True);
+    myPreviewPresentation = NULL;
+    return;
+
+  }
+  else
+  {
+    if (myPreviewPresentation.IsNull())
+    {
+      myPreviewPresentation = new AIS_Shape (aCompound);
+      myPreviewPresentation->SetAttributes (GetPreviewAttributes(aContext));
+      //myPreviewPresentation->SetAttributes (myPreviewParameters->GetDrawer());
+
+      //myPreviewPresentation->SetTransformPersistence(thePersistent);
+      if (!aContext.IsNull())
+        aContext->Display (myPreviewPresentation, AIS_Shaded, -1/*do not participate in selection*/, Standard_True);
+    }
+    else
+    {
+      Handle(AIS_Shape)::DownCast (myPreviewPresentation)->Set (aCompound);
+      //myPreviewPresentation->SetTransformPersistence(thePersistent);
+      if (!aContext.IsNull() && myPreviewPresentation->GetContext() == aContext)
+        aContext->Redisplay (myPreviewPresentation, Standard_True);
+    }
+  }
+}
diff --git a/tools/MessageView/MessageView_Window.hxx b/tools/MessageView/MessageView_Window.hxx
new file mode 100644 (file)
index 0000000..6ff19ed
--- /dev/null
@@ -0,0 +1,186 @@
+// Created on: 2017-06-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef MessageView_Window_H
+#define MessageView_Window_H
+
+#include <Message_Report.hxx>
+#include <Standard.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <inspector/MessageModel_Actions.hxx>
+#include <inspector/TInspectorAPI_PluginParameters.hxx>
+
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_InteractiveObject.hxx>
+#include <TopoDS_Shape.hxx>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4127) // conditional expression is constant
+#endif
+#include <QItemSelection>
+#include <QList>
+#include <QModelIndexList>
+#include <QObject>
+#include <QPoint>
+#include <QString>
+#include <QTreeView>
+
+class View_Window;
+
+class ViewControl_PropertyView;
+class MessageModel_ReportCallBack;
+
+class QDockWidget;
+class QMainWindow;
+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); }
+
+  //! Sets message callback to update the current content of the view
+  //! \param theCallBack
+  void SetCallBack (const Handle(Message_ReportCallBack)& theCallBack) { myCallBack = theCallBack; }
+
+  //! Provide container for actions available in inspector on general level
+  //! \param theMenu if Qt implementation, it is QMenu object
+  Standard_EXPORT virtual void FillActionsMenu (void* theMenu);
+
+  //! Returns plugin preferences: dock widgets state, tree view columns.
+  //! \param theItem container of preference elements
+  Standard_EXPORT void GetPreferences (TInspectorAPI_PreferencesDataMap& theItem);
+
+  //! Applies plugin preferences
+  //! \param theItem container of preference elements
+  Standard_EXPORT void SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem);
+
+  //! Applyes parameters to Init controls, opens files if there are in parameters, updates OCAF tree view model
+  Standard_EXPORT void UpdateContent();
+
+  //! Returns main control
+  QMainWindow* GetMainWindow() const { return myMainWindow; }
+
+  //! Returns current tree view
+  QTreeView* GetTreeView() const { return myTreeView; }
+
+protected:
+  //! Appends shape into tree view model
+  //! \param theShape a shape instance
+  //! \param theReportDescription an additional report information
+  void addReport (const Handle(Message_Report)& theReport,
+                  const TCollection_AsciiString& theReportDescription = "");
+
+private:
+
+  //! Fills controls of the plugin by parameters:
+  //! - Fine AIS_InteractiveObject and fills View if it if it differs from the current context
+  //! \param theParameters a parameters container
+  void Init (NCollection_List<Handle(Standard_Transient)>& theParameters);
+
+  //! Read Shape from the file name, add Shape into tree view
+  //! \param theFileName BREP file name
+  void openFile (const TCollection_AsciiString& theFileName);
+
+  //! Updates tree model
+  void updateTreeModel();
+
+protected slots:
+  //! Updates property view selection in table if the item is hidden
+  //! \param theIndex tree view model index
+  void onTreeViewVisibilityClicked(const QModelIndex& theIndex);
+
+  //! Udpates all controls by changed selection in OCAF tree view
+  //! \param theSelected list of selected tree view items
+  //! \param theDeselected list of deselected tree view items
+  void onTreeViewSelectionChanged (const QItemSelection& theSelected, const QItemSelection& theDeselected);
+
+  //! Shows context menu for tree view selected item. It contains expand/collapse actions.
+  //! \param thePosition a clicked point
+  void onTreeViewContextMenuRequested (const QPoint& thePosition);
+
+  //! Display content of selected tree view item if isToggled is true
+  //! \param isToggled true if the property dock widget is shown
+  void onPropertyPanelShown (bool isToggled);
+
+  //! Update presentation of the selected tree view item using information about selection in property view
+  //! \param theSelected container of selected table cells
+  //! \param theDeselected container of selected table cells
+  void onPropertyViewSelectionChanged();
+
+  //! 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();
+
+protected:
+  //! 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
+  //!< \param theShape container of shapes
+  void updatePreviewPresentation (const NCollection_List<Handle(Standard_Transient)>& thePresentations);
+
+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
+
+  Handle(TInspectorAPI_PluginParameters) myParameters; //!< plugins parameters container
+  Handle(Message_ReportCallBack) myCallBack; //! < message call back to update content of the view
+
+  Handle(AIS_InteractiveObject) myPreviewPresentation; //!< presentation of preview for a selected object
+  NCollection_List<Handle(Standard_Transient)> myPreviewPresentations;
+};
+
+#endif
diff --git a/tools/TKMessageModel/CMakeLists.txt b/tools/TKMessageModel/CMakeLists.txt
new file mode 100644 (file)
index 0000000..911ffb1
--- /dev/null
@@ -0,0 +1,5 @@
+project(TKMessageModel)
+
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
diff --git a/tools/TKMessageModel/EXTERNLIB b/tools/TKMessageModel/EXTERNLIB
new file mode 100644 (file)
index 0000000..54b0274
--- /dev/null
@@ -0,0 +1,10 @@
+TKMath
+TKBin
+TKBRep
+TKGeomBase
+TKG3d
+TKTInspectorAPI
+TKService
+TKTopAlgo
+TKTreeModel
+CSF_QT
diff --git a/tools/TKMessageModel/FILES b/tools/TKMessageModel/FILES
new file mode 100644 (file)
index 0000000..ca4f0e5
--- /dev/null
@@ -0,0 +1,2 @@
+EXTERNLIB
+PACKAGES
diff --git a/tools/TKMessageModel/PACKAGES b/tools/TKMessageModel/PACKAGES
new file mode 100644 (file)
index 0000000..9021fbf
--- /dev/null
@@ -0,0 +1 @@
+MessageModel
diff --git a/tools/TKMessageView/CMakeLists.txt b/tools/TKMessageView/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9b3c1aa
--- /dev/null
@@ -0,0 +1,5 @@
+project(TKMessageView)
+
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit_prepare_tool)
diff --git a/tools/TKMessageView/EXTERNLIB b/tools/TKMessageView/EXTERNLIB
new file mode 100644 (file)
index 0000000..84e5b5d
--- /dev/null
@@ -0,0 +1,13 @@
+TKTInspectorAPI
+TKMath
+TKMessageModel
+TKBin
+TKBRep
+TKGeomBase
+TKG3d
+TKService
+TKTopAlgo
+TKTreeModel
+TKView
+TKXml
+CSF_QT
diff --git a/tools/TKMessageView/FILES b/tools/TKMessageView/FILES
new file mode 100644 (file)
index 0000000..ca4f0e5
--- /dev/null
@@ -0,0 +1,2 @@
+EXTERNLIB
+PACKAGES
diff --git a/tools/TKMessageView/PACKAGES b/tools/TKMessageView/PACKAGES
new file mode 100644 (file)
index 0000000..46a67b2
--- /dev/null
@@ -0,0 +1 @@
+MessageView
index 618620f544481ac9e9e6982a7382fbf0ba2a3e16..c8adc9a66315240918f71d38b2fc22d236a61bd6 100644 (file)
@@ -62,6 +62,7 @@ Standard_Boolean convertToPluginName (const TCollection_AsciiString& theArgument
   if (anArgument == "dfbrowser")       { thePluginName = "TKDFBrowser"; return Standard_True; }
   else if (anArgument == "shapeview")  { thePluginName = "TKShapeView"; return Standard_True; }
   else if (anArgument == "vinspector") { thePluginName = "TKVInspector"; return Standard_True; }
+  else if (anArgument == "messageview") { thePluginName = "TKMessageView"; return Standard_True; }
 
   return Standard_False;
 }
@@ -305,6 +306,7 @@ static int tinspector (Draw_Interpretor& di, Standard_Integer theArgsNb, const c
       aPlugins.Append ("TKDFBrowser");
       aPlugins.Append ("TKShapeView");
       aPlugins.Append ("TKVInspector");
+      aPlugins.Append ("TKMessageView");
     }
     aPluginNameToActivate = !aPluginNameToActivate.IsEmpty() ? aPluginNameToActivate : aPlugins.First();
   }
@@ -391,7 +393,7 @@ 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."
index 94c67d031db28b17c3e4b09a5625f103d2b4c90b..17cda16e6035e05fbfe226fc5b2647e0eac36b42 100644 (file)
@@ -38,7 +38,7 @@ void TreeModel_ItemStream::Init()
   if (!myProperties->Item())
     myProperties->SetItem (currentItem());
 
-  TCollection_AsciiString aKey, aKeyValue;
+  TCollection_AsciiString aKey, aKeyValue, aPropertiesValue;
   TreeModel_ItemStreamPtr aStreamParent = itemDynamicCast<TreeModel_ItemStream>(Parent());
   if (!aStreamParent)
   {
@@ -50,6 +50,13 @@ void TreeModel_ItemStream::Init()
 
     aKey = aValues.FindKey (Row() + 1);
     aKeyValue = aValues.FindFromIndex (Row() + 1);
+
+    // one row value, like gp_XYZ, without additional { for type
+    aValues.Clear();
+    if (!Standard_Dump::SplitJson (aKeyValue, aValues))
+      aPropertiesValue = Standard_Dump::Text (aStream);
+    else
+      aPropertiesValue = aKeyValue;
   }
   else
   {
@@ -57,10 +64,11 @@ void TreeModel_ItemStream::Init()
 
     TCollection_AsciiString aValue;
     aStreamParent->GetChildStream (Row(), aKey, aKeyValue);
+    aPropertiesValue = aKeyValue;
   }
 
   myKey = aKey;
-  myProperties->Init (aKeyValue);
+  myProperties->Init (aPropertiesValue);
   myStreamValue = aKeyValue;
 
   NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString> aValues;