// **************************************************************************
/** @class WindowLog
@brief A C++ ostream to an ncurses window supporting attributes and colors
@section References
- GNU Ncurses
@todo
improve docu
**/
// **************************************************************************
#include "WindowLog.h"
#include
#include
#include
#include
#include "tools.h"
using namespace std;
// --------------------------------------------------------------------------
//
//! Delete the contents of the backlog
//
void WindowLog::EmptyBacklog()
{
fMuxBacklog.lock();
fBacklog.clear();
fMuxBacklog.unlock();
}
// --------------------------------------------------------------------------
//
//! Display the backlog. If fWindow is NULL then it is flushed to cout
//! otherwise to the window (including the colors and attributes)
//!
//! Access to cout, the backlog and the window is encapsulated in mutices.
//
void WindowLog::Display(bool empty)
{
if (!fWindow)
{
fMuxBacklog.lock();
fMuxCout.lock();
cout.write(fBacklog.data(), fBacklog.size());
cout.flush();
if (empty)
fBacklog.clear();
fMuxCout.unlock();
fMuxBacklog.unlock();
return;
}
const int w = getmaxx(fWindow);
fMuxBacklog.lock();
fMuxWindow.lock();
//vector::iterator p0 = fBacklog.begin();
int lines = 0;
int x = 0;
for (unsigned int i=0; i999)
{
s/=1000;
u = 'M';
}
ostringstream str;
str << s << u;
return str.str();
}
// --------------------------------------------------------------------------
//
//! @returns
//! the ANSI code corresponding to the attributes
//
string WindowLog::GetAnsiAttr(int m)
{
if (m==kReset || m==kDefault)
return "\033[0m";
string rc;
if ((m&COLOR_PAIR(kRed) )==COLOR_PAIR(kRed) ) rc += "\033[31m";
if ((m&COLOR_PAIR(kGreen) )==COLOR_PAIR(kGreen) ) rc += "\033[32m";
if ((m&COLOR_PAIR(kYellow) )==COLOR_PAIR(kYellow) ) rc += "\033[33m";
if ((m&COLOR_PAIR(kBlue) )==COLOR_PAIR(kBlue) ) rc += "\033[34m";
if ((m&COLOR_PAIR(kMagenta))==COLOR_PAIR(kMagenta)) rc += "\033[35m";
if ((m&COLOR_PAIR(kCyan) )==COLOR_PAIR(kCyan) ) rc += "\033[36m";
if ((m&COLOR_PAIR(kWhite) )==COLOR_PAIR(kWhite) ) rc += "\033[0m\033[1m";
if ((m&kBold )==kBold ) rc += "\033[1m";
if ((m&kDim )==kDim ) rc += "\033[2m";
if ((m&kUnderline)==kUnderline) rc += "\033[4m";
if ((m&kBlink )==kBlink ) rc += "\033[5m";
return rc;
}
// --------------------------------------------------------------------------
//
//! Add color to the stream according to the attribute. If fWindow is not
//! set this is an ANSI color code, otherwise the window's output
//! attributes are set.
//! It is also added to the backlog. Access to the backlog is encapsulated
//! into its mutex.
//
void WindowLog::AddColor(int m)
{
const int col = COLOR_PAIR(m);
if (!fWindow)
// We don't have to flush here, because the attributes are simply
// part of the stream
*this << GetAnsiAttr(col);
else
{
// Before we change the attributes we have to flush the screen
// otherwise we would have to buffer them until we flush the
// contents
flush();
wattron(fWindow, col);
}
fMuxBacklog.lock();
fAttributes[fBacklog.size()] |= col;
fMuxBacklog.unlock();
}
// --------------------------------------------------------------------------
//
//! Add attributes to the stream according to the attribute. If fWindow is
//! not set this is an ANSI code, otherwise the window's output
//! attributes are set.
//! It is also added to the backlog. Access to the backlog is encapsulated
//! into its mutex.
//
void WindowLog::AddAttr(int m)
{
if (!fWindow)
// We don't have to flush here, because the attributes are simply
// part of the stream
*this << GetAnsiAttr(m);
else
{
// Before we change the attributes we have to flush the screen
// otherwise we would have to buffer them until we flush the
// contents
flush();
m==kReset ? wattrset(fWindow, 0) : wattron(fWindow, m);
}
fMuxBacklog.lock();
m==kReset ?
fAttributes[fBacklog.size()] = -1 :
fAttributes[fBacklog.size()] |= m;
fMuxBacklog.unlock();
}
// --------------------------------------------------------------------------
//
//!
//
std::ostream &operator<<(std::ostream &lout, WindowLogColor m)
{
WindowLog *log=dynamic_cast(lout.rdbuf());
if (log)
log->AddColor(m);
return lout;
}
// --------------------------------------------------------------------------
//
//!
//
std::ostream &operator<<(std::ostream &lout, WindowLogAttrs m)
{
WindowLog *log=dynamic_cast(lout.rdbuf());
if (log)
log->AddAttr(m);
return lout;
}