1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
|
/******************************************************************************
*
* package: log4qt
* file: colorconsoleappender.cpp
* created: March 2010
* author: Filonenko Michael
*
*
* Copyright 2010 Filonenko Michael
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
* Dependencies
******************************************************************************/
#include "colorconsoleappender.h"
#include <QtCore/QTextStream>
#include "loggingevent.h"
#include "layout.h"
#define NIX_BACK_BLACK 40
#define NIX_BACK_RED 41
#define NIX_BACK_GREEN 42
#define NIX_BACK_YELLOW 43
#define NIX_BACK_BLUE 44
#define NIX_BACK_MAGNETTA 45
#define NIX_BACK_CYAN 46
#define NIX_BACK_GRAY 47
#define NIX_FORE_BLACK 30
#define NIX_FORE_RED 31
#define NIX_FORE_GREEN 32
#define NIX_FORE_YELLOW 33
#define NIX_FORE_BLUE 34
#define NIX_FORE_MAGNETTA 35
#define NIX_FORE_CYAN 36
#define NIX_FORE_GRAY 37
#define NIX_FORE_BOLD 1
#define NIX_DEFAULT 0
#if defined(__WIN32__) || defined(WIN) || defined(WIN32) || defined(Q_OS_WIN32)
//#include <windows.h>
#define WIN_BACK_BLACK 0
#define WIN_BACK_RED BACKGROUND_RED
#define WIN_BACK_LIGHT_RED BACKGROUND_RED | BACKGROUND_INTENSITY
#define WIN_BACK_GREEN BACKGROUND_GREEN
#define WIN_BACK_LIGHT_GREEN BACKGROUND_GREEN | BACKGROUND_INTENSITY
#define WIN_BACK_YELLOW BACKGROUND_GREEN | BACKGROUND_RED
#define WIN_BACK_LIGHT_YELLOW BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY
#define WIN_BACK_BLUE BACKGROUND_BLUE
#define WIN_BACK_LIGHT_BLUE BACKGROUND_BLUE | BACKGROUND_INTENSITY
#define WIN_BACK_MAGNETTA BACKGROUND_RED | BACKGROUND_BLUE
#define WIN_BACK_LIGHT_MAGNETTA BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY
#define WIN_BACK_CYAN BACKGROUND_BLUE | BACKGROUND_GREEN
#define WIN_BACK_LIGHT_CYAN BACKGROUND_BLUE | BACKGROUND_GREEN
#define WIN_BACK_GRAY BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED
#define WIN_BACK_WHITE BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY
#define WIN_FORE_BLACK 0
#define WIN_FORE_RED FOREGROUND_RED
#define WIN_FORE_LIGHT_RED FOREGROUND_RED | FOREGROUND_INTENSITY
#define WIN_FORE_GREEN FOREGROUND_GREEN
#define WIN_FORE_LIGHT_GREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define WIN_FORE_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
#define WIN_FORE_LIGHT_YELLOW FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
#define WIN_FORE_BLUE FOREGROUND_BLUE
#define WIN_FORE_LIGHT_BLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY
#define WIN_FORE_MAGNETTA FOREGROUND_RED | FOREGROUND_BLUE
#define WIN_FORE_LIGHT_MAGNETTA FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY
#define WIN_FORE_CYAN FOREGROUND_BLUE | FOREGROUND_GREEN
#define WIN_FORE_LIGHT_CYAN FOREGROUND_BLUE | FOREGROUND_GREEN
#define WIN_FORE_GRAY FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
#define WIN_FORE_WHITE FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
#define WIN_FORE_BOLD FOREGROUND_INTENSITY
#define WIN_DEFAULT FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
static void colorOutputString(HANDLE hConsole, const QString& output)
{
QString message = output;
// save colors
CONSOLE_SCREEN_BUFFER_INFO cbi;
GetConsoleScreenBufferInfo(hConsole,&cbi);
wchar_t *wideMessage;
QStringList colorizedMessage = message.split('\033');
int actualSize;
DWORD out;
WORD color = 0;
WORD newColor = 0;
QString parsedWordString;
QStringList escParams;
int indexOfM;
// display first part of message
if (!colorizedMessage.at(0).isEmpty()) {
wideMessage = new wchar_t [colorizedMessage.at(0).size()];
actualSize = colorizedMessage.at(0).toWCharArray(wideMessage);
WriteConsoleW(hConsole, wideMessage, actualSize, &out, 0);
delete [] wideMessage;
colorizedMessage.removeAt(0);
}
foreach (QString it, colorizedMessage) {
// color setted
if (it.startsWith("[")) {
indexOfM = it.indexOf('m');
// not esc-sequence
if (indexOfM != -1) {
parsedWordString = it.mid(1, indexOfM - 1);
escParams = parsedWordString.split(';');
foreach(QString param, escParams) {
color = param.toUInt();
switch(color) {
case NIX_DEFAULT:
newColor = WIN_DEFAULT;
break;
case NIX_FORE_BOLD:
newColor |= WIN_FORE_BOLD;
break;
case NIX_BACK_BLACK :
newColor = (newColor & 0x0f) | WIN_BACK_BLACK;
break;
case NIX_BACK_RED :
newColor = (newColor & 0x0f) | WIN_BACK_RED;
break;
case NIX_BACK_GREEN :
newColor = (newColor & 0x0f) | WIN_BACK_GREEN;
break;
case NIX_BACK_YELLOW :
newColor = (newColor & 0x0f) | WIN_BACK_YELLOW;
break;
case NIX_BACK_BLUE :
newColor = (newColor & 0x0f) | WIN_BACK_BLUE;
break;
case NIX_BACK_MAGNETTA :
newColor = (newColor & 0x0f) | WIN_BACK_MAGNETTA;
break;
case NIX_BACK_CYAN :
newColor = (newColor & 0x0f) | WIN_BACK_CYAN;
break;
case NIX_BACK_GRAY :
newColor = (newColor & 0x0f) | WIN_BACK_GRAY;
break;
case NIX_FORE_BLACK :
newColor = (newColor & 0xF8)| WIN_FORE_BLACK;
break;
case NIX_FORE_RED :
newColor = (newColor & 0xF8) | WIN_FORE_RED;
break;
case NIX_FORE_GREEN :
newColor = (newColor & 0xF8) | WIN_FORE_GREEN;
break;
case NIX_FORE_YELLOW :
newColor = (newColor & 0xF8) | WIN_FORE_YELLOW;
break;
case NIX_FORE_BLUE :
newColor = (newColor & 0xF8) | WIN_FORE_BLUE;
break;
case NIX_FORE_MAGNETTA :
newColor = (newColor & 0xF8) | WIN_FORE_MAGNETTA;
break;
case NIX_FORE_CYAN :
newColor = (newColor & 0xF8) | WIN_FORE_CYAN;
break;
case NIX_FORE_GRAY :
newColor = (newColor & 0xF8) | WIN_FORE_GRAY;
break;
default:break;
}
}
it = it.mid(indexOfM + 1);
SetConsoleTextAttribute(hConsole, newColor);
}
}
wideMessage = new wchar_t [it.size()];
actualSize = it.toWCharArray(wideMessage);
WriteConsoleW(hConsole, wideMessage, actualSize, &out, 0);
delete [] wideMessage;
}
// load old colors
SetConsoleTextAttribute(hConsole, cbi.wAttributes);
//qDebug() << colorizedMessage;
}
#endif
namespace Log4Qt {
/**************************************************************************
* Declarations
**************************************************************************/
/**************************************************************************
* C helper functions
**************************************************************************/
/**************************************************************************
* Class implementation: ColorConsoleAppender
**************************************************************************/
ColorConsoleAppender::ColorConsoleAppender(QObject *pParent) :
ConsoleAppender(pParent)
{
}
ColorConsoleAppender::ColorConsoleAppender(Layout *pLayout, QObject *pParent) :
ConsoleAppender(pLayout, pParent)
{
}
ColorConsoleAppender::ColorConsoleAppender(Layout *pLayout,
const QString &rTarget, QObject *pParent) :
ConsoleAppender(pLayout, rTarget, pParent)
{
}
ColorConsoleAppender::ColorConsoleAppender(Layout *pLayout, Target target,
QObject *pParent) :
ConsoleAppender(pLayout, target, pParent)
{
}
#if defined(__WIN32__) || defined(WIN) || defined(WIN32) || defined(Q_OS_WIN32)
void ColorConsoleAppender::append(const LoggingEvent &rEvent)
{
QString message = layout()->format(rEvent);
colorOutputString(hConsole, message);
// обрабатываем ошибки, по умолчанию метод не реализован
if (handleIoErrors())
return;
if (immediateFlush())
{
writer()->flush();
if (handleIoErrors())
return;
}
}
void ColorConsoleAppender::activateOptions()
{
ConsoleAppender::activateOptions();
if (target() == "STDOUT_TARGET")
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
else
hConsole = GetStdHandle(STD_ERROR_HANDLE);
}
void ColorConsoleAppender::close()
{
ConsoleAppender::close();
CloseHandle(hConsole);
}
#endif
/******************************************************************************
* Implementation: Operators, Helper
******************************************************************************/
} // namespace Log4Qt
|