0031036: Foundation Classes, Message_PrinterOStream - add option printing colored...
authorkgv <kgv@opencascade.com>
Sat, 5 Oct 2019 19:01:09 +0000 (22:01 +0300)
committerapn <apn@opencascade.com>
Tue, 22 Oct 2019 12:15:53 +0000 (15:15 +0300)
New property Message_PrinterOStream::ToColorize() can be set to colorize text output into console.
The new option is disabled by default.

src/Message/FILES
src/Message/Message_ConsoleColor.hxx [new file with mode: 0644]
src/Message/Message_PrinterOStream.cxx
src/Message/Message_PrinterOStream.hxx

index e502c69..2747813 100755 (executable)
@@ -3,6 +3,7 @@ Message.hxx
 Message_Algorithm.cxx
 Message_Algorithm.hxx
 Message_Algorithm.lxx
+Message_ConsoleColor.hxx
 Message_ExecStatus.hxx
 Message_Gravity.hxx
 Message_HArrayOfMsg.hxx
diff --git a/src/Message/Message_ConsoleColor.hxx b/src/Message/Message_ConsoleColor.hxx
new file mode 100644 (file)
index 0000000..fb68e10
--- /dev/null
@@ -0,0 +1,31 @@
+// 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_ConsoleColor_HeaderFile
+#define _Message_ConsoleColor_HeaderFile
+
+//! Color definition for console/terminal output (limited palette).
+enum Message_ConsoleColor
+{
+  Message_ConsoleColor_Default, //!< default (white) color
+  Message_ConsoleColor_Black,   //!< black   color
+  Message_ConsoleColor_White,   //!< white   color
+  Message_ConsoleColor_Red,     //!< red     color
+  Message_ConsoleColor_Blue,    //!< blue    color
+  Message_ConsoleColor_Green,   //!< green   color
+  Message_ConsoleColor_Yellow,  //!< yellow  color
+  Message_ConsoleColor_Cyan,    //!< cyan    color
+  Message_ConsoleColor_Magenta, //!< magenta color
+};
+
+#endif // _Message_ConsoleColor_HeaderFile
index d2ed843..5028d67 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#ifdef _WIN32
+  #include <windows.h>
+#endif
+
 #include <Message_PrinterOStream.hxx>
 
 #include <OSD_OpenFile.hxx>
@@ -32,7 +36,8 @@ IMPLEMENT_STANDARD_RTTIEXT(Message_PrinterOStream,Message_Printer)
 Message_PrinterOStream::Message_PrinterOStream (const Message_Gravity theTraceLevel)
 : myStream  (&std::cout),
   myIsFile  (Standard_False),
-  myUseUtf8 (Standard_False)
+  myUseUtf8 (Standard_False),
+  myToColorize (Standard_False)
 {
   myTraceLevel = theTraceLevel;
 }
@@ -46,7 +51,9 @@ Message_PrinterOStream::Message_PrinterOStream (const Standard_CString theFileNa
                                                 const Standard_Boolean theToAppend,
                                                 const Message_Gravity  theTraceLevel)
 : myStream (&std::cout),
-  myIsFile (Standard_False)
+  myIsFile (Standard_False),
+  myUseUtf8 (Standard_False),
+  myToColorize (Standard_False)
 {
   myTraceLevel = theTraceLevel;
   if (strcasecmp(theFileName, "cerr") == 0)
@@ -112,10 +119,55 @@ void Message_PrinterOStream::Send (const Standard_CString theString,
                                   const Message_Gravity theGravity,
                                   const Standard_Boolean putEndl) const
 {
-  if ( theGravity < myTraceLevel || ! myStream ) return;
-  Standard_OStream* ostr = (Standard_OStream*)myStream;
-  (*ostr) << theString;
-  if ( putEndl ) (*ostr) << std::endl;
+  if (theGravity < myTraceLevel
+   || myStream == NULL)
+  {
+    return;
+  }
+
+  Message_ConsoleColor aColor = Message_ConsoleColor_Default;
+  bool toIntense = false;
+  if (myToColorize && !myIsFile)
+  {
+    switch(theGravity)
+    {
+      case Message_Trace:
+        aColor = Message_ConsoleColor_Yellow;
+        break;
+      case Message_Info:
+        aColor = Message_ConsoleColor_Green;
+        toIntense = true;
+        break;
+      case Message_Warning:
+        aColor = Message_ConsoleColor_Yellow;
+        toIntense = true;
+        break;
+      case Message_Alarm:
+        aColor = Message_ConsoleColor_Red;
+        toIntense = true;
+        break;
+      case Message_Fail:
+        aColor = Message_ConsoleColor_Red;
+        toIntense = true;
+        break;
+    }
+  }
+
+  Standard_OStream* aStream = (Standard_OStream*)myStream;
+  if (toIntense || aColor != Message_ConsoleColor_Default)
+  {
+    SetConsoleTextColor (aStream, aColor, toIntense);
+    *aStream << theString;
+    SetConsoleTextColor (aStream, Message_ConsoleColor_Default, false);
+  }
+  else
+  {
+    *aStream << theString;
+  }
+  if (putEndl)
+  {
+    (*aStream) << std::endl;
+  }
 }
 
 //=======================================================================
@@ -142,3 +194,91 @@ void Message_PrinterOStream::Send (const TCollection_ExtendedString &theString,
   TCollection_AsciiString aStr (theString, myUseUtf8 ? Standard_Character(0) : '?');
   Send (aStr.ToCString(), theGravity, putEndl);
 }
+
+//=======================================================================
+//function : SetConsoleTextColor
+//purpose  :
+//=======================================================================
+void Message_PrinterOStream::SetConsoleTextColor (Standard_OStream* theOStream,
+                                                  Message_ConsoleColor theTextColor,
+                                                  bool theIsIntenseText)
+{
+#ifdef _WIN32
+  // there is no difference between STD_OUTPUT_HANDLE/STD_ERROR_HANDLE for std::cout/std::cerr
+  (void )theOStream;
+  if (HANDLE anStdOut = GetStdHandle (STD_OUTPUT_HANDLE))
+  {
+    WORD aFlags = 0;
+    if (theIsIntenseText)
+    {
+      aFlags |= FOREGROUND_INTENSITY;
+    }
+    switch (theTextColor)
+    {
+      case Message_ConsoleColor_Default:
+      case Message_ConsoleColor_White:
+        aFlags |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+        break;
+      case Message_ConsoleColor_Black:
+        break;
+      case Message_ConsoleColor_Red:
+        aFlags |= FOREGROUND_RED;
+        break;
+      case Message_ConsoleColor_Green:
+        aFlags |= FOREGROUND_GREEN;
+        break;
+      case Message_ConsoleColor_Blue:
+        aFlags |= FOREGROUND_BLUE;
+        break;
+      case Message_ConsoleColor_Yellow:
+        aFlags |= FOREGROUND_RED | FOREGROUND_GREEN;
+        break;
+      case Message_ConsoleColor_Cyan:
+        aFlags |= FOREGROUND_GREEN | FOREGROUND_BLUE;
+        break;
+      case Message_ConsoleColor_Magenta:
+        aFlags |= FOREGROUND_RED | FOREGROUND_BLUE;
+        break;
+    }
+    SetConsoleTextAttribute (anStdOut, aFlags);
+  }
+#else
+  if (theOStream == NULL)
+  {
+    return;
+  }
+
+  const char* aCode = "\e[0m";
+  switch (theTextColor)
+  {
+    case Message_ConsoleColor_Default:
+      aCode = theIsIntenseText ? "\e[0;1m" : "\e[0m";
+      break;
+    case Message_ConsoleColor_Black:
+      aCode = theIsIntenseText ? "\e[30;1m" : "\e[30m";
+      break;
+    case Message_ConsoleColor_Red:
+      aCode = theIsIntenseText ? "\e[31;1m" : "\e[31m";
+      break;
+    case Message_ConsoleColor_Green:
+      aCode = theIsIntenseText ? "\e[32;1m" : "\e[32m";
+      break;
+    case Message_ConsoleColor_Yellow:
+      aCode = theIsIntenseText ? "\e[33;1m" : "\e[33m";
+      break;
+    case Message_ConsoleColor_Blue:
+      aCode = theIsIntenseText ? "\e[34;1m" : "\e[34m";
+      break;
+    case Message_ConsoleColor_Magenta:
+      aCode = theIsIntenseText ? "\e[35;1m" : "\e[35m";
+      break;
+    case Message_ConsoleColor_Cyan:
+      aCode = theIsIntenseText ? "\e[36;1m" : "\e[36m";
+      break;
+    case Message_ConsoleColor_White:
+      aCode = theIsIntenseText ? "\e[37;1m" : "\e[37m";
+      break;
+  }
+  *theOStream << aCode;
+#endif
+}
index 3c505c5..ca10fdd 100644 (file)
@@ -16,6 +16,7 @@
 #ifndef _Message_PrinterOStream_HeaderFile
 #define _Message_PrinterOStream_HeaderFile
 
+#include <Message_ConsoleColor.hxx>
 #include <Message_Printer.hxx>
 #include <Standard_Address.hxx>
 #include <Standard_OStream.hxx>
@@ -30,6 +31,21 @@ class Message_PrinterOStream : public Message_Printer
 {
   DEFINE_STANDARD_RTTIEXT(Message_PrinterOStream, Message_Printer)
 public:
+
+  //! Setup console text color.
+  //!
+  //! On Windows, this would affect active terminal color output.
+  //! On other systems, this would put special terminal codes;
+  //! the terminal should support these codes or them will appear in text otherwise.
+  //! The same will happen when stream is redirected into text file.
+  //!
+  //! Beware that within multi-threaded environment inducing console colors
+  //! might lead to colored text mixture due to concurrency.
+  Standard_EXPORT static void SetConsoleTextColor (Standard_OStream* theOStream,
+                                                   Message_ConsoleColor theTextColor,
+                                                   bool theIsIntenseText = false);
+
+public:
   
   //! Empty constructor, defaulting to cout
   Standard_EXPORT Message_PrinterOStream(const Message_Gravity theTraceLevel = Message_Info);
@@ -57,7 +73,13 @@ public:
 
   //! Returns reference to the output stream
   Standard_OStream& GetStream() const { return *(Standard_OStream*)myStream; }
-  
+
+  //! Returns TRUE if text output into console should be colorized depending on message gravity.
+  Standard_Boolean ToColorize() const { return myToColorize; }
+
+  //! Set if text output into console should be colorized depending on message gravity.
+  void SetToColorize (Standard_Boolean theToColorize) { myToColorize = theToColorize; }
+
   //! Puts a message to the current stream
   //! if its gravity is equal or greater
   //! to the trace level set by SetTraceLevel()
@@ -80,6 +102,7 @@ private:
   Standard_Address myStream;
   Standard_Boolean myIsFile;
   Standard_Boolean myUseUtf8;
+  Standard_Boolean myToColorize;
 
 };