00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "logger.h"
00021 #include <QFile>
00022 #include <QTextStream>
00023 #include <QTextEdit>
00024 #include <QDateTime>
00025 #include <iostream>
00026 #include <QObject>
00027 #include <QEvent>
00028 #include <QApplication>
00029 #include <QMutex>
00030 #include <QMutexLocker>
00031 #include <QMessageBox>
00032
00033 namespace farsa {
00034
00035 namespace {
00036
00037 class TextToAppend : public QEvent {
00038 public:
00039 TextToAppend( QString text, QString level, QString pureMessage ) :
00040 QEvent((Type)type),
00041 text(text),
00042 level(level),
00043 pureMessage(pureMessage) { };
00044 QString getText() {
00045 return text;
00046 };
00047 QString getLevel() {
00048 return level;
00049 };
00050 QString getPureMessage() {
00051 return pureMessage;
00052 };
00053 private:
00054 static int type;
00055 QString text;
00056 QString level;
00057 QString pureMessage;
00058 };
00059 int TextToAppend::type = QEvent::registerEventType();
00060
00061 class TextEditUpdater : public QObject {
00062 public:
00063 TextEditUpdater() :
00064 QObject(),
00065 textEdit(NULL)
00066 {
00067 }
00068
00069 void setTextEditToUpdate(QTextEdit* e)
00070 {
00071 textEdit = e;
00072 }
00073
00074 bool hasTextEdit() const
00075 {
00076 return (textEdit != NULL);
00077 }
00078
00079 protected:
00080 virtual void customEvent( QEvent* event ) {
00081
00082 TextToAppend* tevent = dynamic_cast<TextToAppend*>( event );
00083 if ( tevent ) {
00084 textEdit->append( tevent->getText() );
00085 textEdit->moveCursor( QTextCursor::End );
00086 textEdit->moveCursor( QTextCursor::StartOfLine );
00087 if ( tevent->getLevel() == "ERROR" ) {
00088 QMessageBox::critical( 0, "Error from Component", tevent->getPureMessage() );
00089 }
00090 tevent->accept();
00091 } else {
00092 QObject::customEvent( event );
00093 }
00094 };
00095
00096 QTextEdit* textEdit;
00097 };
00098
00099
00100
00101
00102 class LoggerImplementation
00103 {
00104 public:
00105
00106 static LoggerImplementation& getInstance();
00107
00108 void info(QString msg);
00109
00110 void warning(QString msg);
00111
00112 void error(QString msg);
00113
00114 void setQTextEdit(QTextEdit* textedit);
00115
00116 void enableStdOut(bool enabled);
00117
00118 void setLogLevel(Logger::LogLevel level);
00119
00120 void setLogFilename(QString logfile);
00121
00122 private:
00123
00124 LoggerImplementation();
00125
00126
00127 ~LoggerImplementation();
00128
00129
00130 void logIt(QString level, QString msg);
00131
00132 bool stdOut;
00133 QFile* file;
00134 QTextStream* fileStream;
00135 QTextStream* outStream;
00136 TextEditUpdater* textEditUpdater;
00137 Logger::LogLevel logLevel;
00138
00139 QMutex outStreamMutex;
00140 QMutex fileStreamMutex;
00141
00142 private:
00143
00144 LoggerImplementation(LoggerImplementation&);
00145
00146
00147 LoggerImplementation& operator=(LoggerImplementation&);
00148 };
00149
00150 LoggerImplementation& LoggerImplementation::getInstance()
00151 {
00152
00153 static LoggerImplementation loggerImplementation;
00154
00155 return loggerImplementation;
00156 }
00157
00158 void LoggerImplementation::info(QString msg)
00159 {
00160 if (logLevel <= Logger::Default) {
00161 logIt("INFO", msg);
00162 }
00163 }
00164
00165 void LoggerImplementation::warning(QString msg)
00166 {
00167 if (logLevel <= Logger::Warning) {
00168 logIt("WARNING", msg);
00169 }
00170 }
00171
00172 void LoggerImplementation::error(QString msg)
00173 {
00174 if (logLevel <= Logger::Quiet) {
00175 logIt("ERROR", msg);
00176 }
00177 }
00178
00179 void LoggerImplementation::setQTextEdit(QTextEdit* textedit)
00180 {
00181 textEditUpdater->setTextEditToUpdate(textedit);
00182 }
00183
00184 void LoggerImplementation::enableStdOut(bool enabled)
00185 {
00186 stdOut = enabled;
00187 }
00188
00189 void LoggerImplementation::setLogLevel(Logger::LogLevel level)
00190 {
00191 logLevel = level;
00192 }
00193
00194 void LoggerImplementation::setLogFilename(QString logfile)
00195 {
00196 QFile* oldfile = file;
00197 file = new QFile(logfile);
00198 fileStream->setDevice(file);
00199
00200 delete oldfile;
00201 }
00202
00203 LoggerImplementation::LoggerImplementation() :
00204 stdOut(true),
00205 file(NULL),
00206 fileStream(new QTextStream()),
00207 outStream(new QTextStream(stdout)),
00208 textEditUpdater(new TextEditUpdater()),
00209 logLevel(Logger::Default),
00210 outStreamMutex(),
00211 fileStreamMutex()
00212 {
00213 }
00214
00215 LoggerImplementation::~LoggerImplementation()
00216 {
00217 delete textEditUpdater;
00218 delete outStream;
00219 delete fileStream;
00220 delete file;
00221
00222
00223
00224 textEditUpdater = NULL;
00225 outStream = NULL;
00226 fileStream = NULL;
00227 file = NULL;
00228 }
00229
00230
00231 void LoggerImplementation::logIt(QString level, QString msg)
00232 {
00233 QString logtmpl("[%1] %2: %3");
00234 QString timestamp = QDateTime::currentDateTime().toString( "dd-MM-yyyy hh:mm:ss.zzz" );
00235 QString logmsg = logtmpl.arg( timestamp ).arg( level, -10 ).arg( msg );
00236 if ( stdOut ) {
00237 QMutexLocker locker(&outStreamMutex);
00238
00239 (*outStream) << logmsg << "\n";
00240 outStream->flush();
00241 }
00242 if ( textEditUpdater->hasTextEdit() ) {
00243
00244 QString color = "#ffffff";
00245 if ( level == "INFO" ) {
00246 color = "#afeeee";
00247 } else if ( level == "WARNING" ) {
00248 color = "#f0e68c";
00249 } else if ( level == "ERROR" ) {
00250 color = "#ff4500";
00251 }
00252
00253
00254
00255 qApp->postEvent( textEditUpdater, new TextToAppend( QString("<pre style=\"margin-top: 0px; margin-bottom: 0px; color: ")+color+";\">"+logmsg+QString("</pre>"), level, msg ) );
00256
00257
00258
00259 }
00260 if ( fileStream && fileStream->device() ) {
00261 QMutexLocker locker(&fileStreamMutex);
00262
00263 (*fileStream) << logmsg << "\n";
00264 fileStream->flush();
00265 }
00266 }
00267 }
00268
00269 void Logger::info(QString msg)
00270 {
00271 LoggerImplementation::getInstance().info(msg);
00272 }
00273
00274 void Logger::warning(QString msg)
00275 {
00276 LoggerImplementation::getInstance().warning(msg);
00277 }
00278
00279 void Logger::error(QString msg)
00280 {
00281 LoggerImplementation::getInstance().error(msg);
00282 }
00283
00284 void Logger::setLogFilename(QString logfile)
00285 {
00286 LoggerImplementation::getInstance().setLogFilename(logfile);
00287 }
00288
00289 void Logger::setQTextEdit(QTextEdit* textedit)
00290 {
00291 LoggerImplementation::getInstance().setQTextEdit(textedit);
00292 }
00293
00294 void Logger::enableStdOut(bool enabled)
00295 {
00296 LoggerImplementation::getInstance().enableStdOut(enabled);
00297 }
00298
00299 void Logger::setLogLevel(LogLevel level) {
00300 LoggerImplementation::getInstance().setLogLevel(level);
00301 }
00302
00303 QString Logger::logLevelToString(Logger::LogLevel level)
00304 {
00305 QString str = "unknown";
00306
00307 switch(level)
00308 {
00309 case Default:
00310 str = "Default";
00311 break;
00312 case Warning:
00313 str = "Warning";
00314 break;
00315 case Quiet:
00316 str = "Quiet";
00317 break;
00318 case Superquiet:
00319 str = "Superquiet";
00320 break;
00321 }
00322
00323 return str;
00324 }
00325
00326 Logger::LogLevel Logger::stringToLogLevel(QString level)
00327 {
00328 LogLevel l = Default;
00329
00330 if (level.toUpper() == "DEFAULT") {
00331 l = Default;
00332 } else if (level.toUpper() == "WARNING") {
00333 l = Warning;
00334 } else if (level.toUpper() == "QUIET") {
00335 l = Quiet;
00336 } else if (level.toUpper() == "SUPERQUIET") {
00337 l = Superquiet;
00338 }
00339
00340 return l;
00341 }
00342
00343 }