From e1d039d56d6d01cc72513f898c3b30a9c165f1d3 Mon Sep 17 00:00:00 2001 From: kgv Date: Sat, 5 Oct 2019 22:01:09 +0300 Subject: [PATCH 1/1] 0031036: Foundation Classes, Message_PrinterOStream - add option printing colored text into console New property Message_PrinterOStream::ToColorize() can be set to colorize text output into console. The new option is disabled by default. --- src/Message/FILES | 1 + src/Message/Message_ConsoleColor.hxx | 31 +++++ src/Message/Message_PrinterOStream.cxx | 152 ++++++++++++++++++++++++- src/Message/Message_PrinterOStream.hxx | 25 +++- 4 files changed, 202 insertions(+), 7 deletions(-) create mode 100644 src/Message/Message_ConsoleColor.hxx diff --git a/src/Message/FILES b/src/Message/FILES index e502c6903c..2747813201 100755 --- a/src/Message/FILES +++ b/src/Message/FILES @@ -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 index 0000000000..fb68e10cd8 --- /dev/null +++ b/src/Message/Message_ConsoleColor.hxx @@ -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 diff --git a/src/Message/Message_PrinterOStream.cxx b/src/Message/Message_PrinterOStream.cxx index d2ed843d0d..5028d67bf2 100644 --- a/src/Message/Message_PrinterOStream.cxx +++ b/src/Message/Message_PrinterOStream.cxx @@ -13,6 +13,10 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#ifdef _WIN32 + #include +#endif + #include #include @@ -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 +} diff --git a/src/Message/Message_PrinterOStream.hxx b/src/Message/Message_PrinterOStream.hxx index 3c505c5f4b..ca10fdde26 100644 --- a/src/Message/Message_PrinterOStream.hxx +++ b/src/Message/Message_PrinterOStream.hxx @@ -16,6 +16,7 @@ #ifndef _Message_PrinterOStream_HeaderFile #define _Message_PrinterOStream_HeaderFile +#include #include #include #include @@ -29,6 +30,21 @@ DEFINE_STANDARD_HANDLE(Message_PrinterOStream, Message_Printer) 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 @@ -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; }; -- 2.20.1