UniversalIndentGUI 1.2.0
TSLogger.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006-2012 by Thomas Schweitzer                          *
00003  *   thomas-schweitzer(at)arcor.de                                         *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License version 2.0 as   *
00007  *   published by the Free Software Foundation.                            *
00008  *                                                                         *
00009  *   This program is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU General Public License for more details.                          *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU General Public License     *
00015  *   along with this program in the file LICENSE.GPL; if not, write to the *
00016  *   Free Software Foundation, Inc.,                                       *
00017  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00018  ***************************************************************************/
00019 
00020 #include "TSLogger.h"
00021 #include "ui_TSLoggerDialog.h"
00022 
00023 #include "SettingsPaths.h"
00024 
00025 #include <QDateTime>
00026 #include <QFile>
00027 #include <QFileInfo>
00028 #include <QUrl>
00029 #include <QTextStream>
00030 #include <QDesktopServices>
00031 #include <QMessageBox>
00032 
00033 #include <ctime>
00034 
00035 using namespace tschweitzer;
00036 using namespace tschweitzer::debugging;
00037 
00038 TSLogger* TSLogger::_instance = NULL;
00039 
00055 TSLogger* TSLogger::getInstance(int verboseLevel) {
00056     if ( _instance == NULL )
00057         _instance = new TSLogger(verboseLevel);
00058 
00059     return _instance;
00060 }
00061 
00062 
00066 TSLogger* TSLogger::getInstance() {
00067 #ifdef _DEBUG
00068     return TSLogger::getInstance(QtDebugMsg);
00069 #else
00070     return TSLogger::getInstance(QtWarningMsg);
00071 #endif
00072 }
00073 
00074 
00079 TSLogger::TSLogger(int verboseLevel) : QDialog() {
00080     _TSLoggerDialogForm = new Ui::TSLoggerDialog();
00081     _TSLoggerDialogForm->setupUi(this);
00082 #ifdef _DEBUG
00083     _verboseLevel = QtDebugMsg;
00084 #else
00085     _verboseLevel = QtMsgType(verboseLevel);
00086 #endif
00087 
00088     _logFileInitState = NOTINITIALZED;
00089 
00090     connect( _TSLoggerDialogForm->openLogFileFolderToolButton, SIGNAL(clicked()), this, SLOT(openLogFileFolder()) );
00091 
00092     // Make the main application not to wait for the logging window to close.
00093     setAttribute(Qt::WA_QuitOnClose, false);
00094 }
00095 
00096 
00102 void TSLogger::messageHandler(QtMsgType type, const char *msg) {
00103     if ( _instance == NULL )
00104         _instance = TSLogger::getInstance();
00105 
00106 /*
00107     QMessageBox messageBox;
00108     QString messageBoxText = QString::fromUtf8( msg );
00109     messageBox.setText( messageBoxText );
00110     messageBox.setWindowModality( Qt::ApplicationModal );
00111     messageBox.exec();
00112 */
00113 
00114     // Only log messages that have a higher or equal priority than set with the verbose level.
00115     if ( type < _instance->_verboseLevel )
00116         return;
00117 
00118     // Init log message with prepended date and time.
00119     QString message = QDateTime::currentDateTime().toString();
00120 
00121     // Depending on the QtMsgType prepend a different colored Debug, Warning, Critical or Fatal.
00122     switch (type) {
00123         case QtDebugMsg :
00124             message += " <span style=\"font-weight:bold; color:black;\">Debug:</span> ";
00125             break;
00126         case QtWarningMsg :
00127             message += " <span style=\"font-weight:bold; color:gold;\">Warning:</span> ";
00128             break;
00129         case QtCriticalMsg :
00130             message += "<span style=\"font-weight:bold; color:red;\">Critical:</span> ";
00131             break;
00132         case QtFatalMsg :
00133             message += " <span style=\"font-weight:bold; color:#D60000;\">Fatal:</span> ";
00134         // This one is no Qt message type, but can be used to send info messages to the log
00135         // by calling TSLogger::messageHandler() directly.
00136         case TSLoggerInfoMsg :
00137             message += " <span style=\"font-weight:bold; color:darkgray;\">Info:</span> ";
00138             break;
00139     }
00140 
00141     // Append the to UTF-8 back converted message parameter.
00142     message += QString::fromUtf8( msg ) + "<br/>\n";
00143 
00144     // Write the message to the log windows text edit.
00145     _instance->_TSLoggerDialogForm->logTextEdit->append( message );
00146 
00147     // Write/append the log message to the log file.
00148     _instance->writeToLogFile( message );
00149 
00150     // In case of a fatal error abort the application.
00151     if ( type == QtFatalMsg )
00152         abort();
00153 }
00154 
00155 
00160 void TSLogger::setVerboseLevel(int level) {
00161     if ( level < 0 )
00162         _verboseLevel = QtDebugMsg;
00163     if ( level > 3 )
00164         _verboseLevel = QtFatalMsg;
00165     else
00166         _verboseLevel = QtMsgType(level);
00167 }
00168 
00169 
00173 void TSLogger::deleteInstance() {
00174     if ( _instance != NULL ) {
00175         delete _instance;
00176         _instance = NULL;
00177     }
00178 }
00179 
00180 
00184 void TSLogger::openLogFileFolder() {
00185     QDesktopServices::openUrl( QFileInfo( _logFile ).absolutePath() );
00186 }
00187 
00188 
00192 void TSLogger::writeToLogFile(const QString &message) {
00193     // If the file where all logging messages should go to isn't initilized yet, do that now.
00194     if ( _logFileInitState == NOTINITIALZED ) {
00195         _logFileInitState = INITIALIZING;
00196 
00197         // On different systems it may be that "QDir::tempPath()" ends with a "/" or not. So check this.
00198         // Remove any trailing slashes.
00199         QString tempPath = QFileInfo( SettingsPaths::getTempPath() ).absolutePath();
00200         while ( tempPath.right(1) == "/" ) {
00201             tempPath.chop(1);
00202         }
00203 
00204         // To make the temporary log file invulnerable against file symbolic link hacks
00205         // append the current date and time up to milliseconds to its name and a random character.
00206         QString logFileName = "UiGUI_log_" + QDateTime::currentDateTime().toString("yyyyMMdd");
00207         logFileName += "-" + QDateTime::currentDateTime().toString("hhmmsszzz");
00208         // By random decide whether to append a number or an upper or lower case character.
00209         qsrand( time(NULL) );
00210         unsigned char randomChar;
00211         switch ( qrand() % 3 ) {
00212             // Append a number from 0 to 9.
00213             case 0 :
00214                 randomChar = qrand() % 10 + '0';
00215                 break;
00216             // Append a upper case characer between A and Z.
00217             case 1 :
00218                 randomChar = qrand() % 26 + 'A';
00219                 break;
00220             // Append a lower case characer between a and z.
00221             default :
00222                 randomChar = qrand() % 26 + 'a';
00223                 break;
00224         }
00225         logFileName += "_" + QString(randomChar) + ".html";
00226 
00227         _logFile.setFileName( tempPath + "/" + logFileName );
00228 
00229         // Set the tooltip of the open log file folder button to show the unique name of the log file.
00230         _TSLoggerDialogForm->openLogFileFolderToolButton->setToolTip( _TSLoggerDialogForm->openLogFileFolderToolButton->toolTip() + " (" + logFileName + ")" );
00231 
00232         _logFileInitState = INITIALZED;
00233     }
00234 
00235     // Add the message to the message queue.
00236     _messageQueue << message;
00237 
00238     // If the logging file is initialzed, write all messages contained in the message queue into the file.
00239     if ( _logFileInitState == INITIALZED ) {
00240         // Write/append the log message to the log file.
00241         if ( _logFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append) ) {
00242             QTextStream out(&_logFile);
00243 
00244             while ( !_messageQueue.isEmpty() ) {
00245                 out << _messageQueue.takeFirst() << "\n";
00246             }
00247 
00248             _logFile.close();
00249         }
00250     }
00251 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines