* @brief iLogger interface implementation
  * @author Enar Vaikene
  *
- * Copyright (c) 2011 Enar Vaikene
+ * Copyright (c) 2011-2012 Enar Vaikene
  *
  * This file is part of the eVaf C++ cross-platform application development framework.
  *
 #include "logger.h"
 #include "iregistry.h"
 #include "iapp.h"
+#include "iconfig.h"
+#include "globals.h"
+#include "inifile.h"
 #include "version.h"
 
 #include <QtCore>
 
 LoggerSource::LoggerSource(LoggerSource const & o)
     : QSharedData()
+    , name(o.name)
     , severity(o.severity)
+    , fileName(o.fileName)
     , maxSize(o.maxSize)
     , maxCount(o.maxCount)
 {}
 
-void LoggerSource::init(QString const & source, QString const & logDir, QString const & etcDir)
+void LoggerSource::init(QString const & source)
 {
-    Q_UNUSED(etcDir);
-
-    fileName = logDir + source + ".log";
+    name = source;
+    fileName = iApp::instance()->logDir() + source + ".log";
+
+    // Set default settings
+    severity = iLogger::Fatal;
+    maxSize = 100 * 1024;
+    maxCount = 3;
+
+    // Read settings from the 'logger.ini' file
+    QString confFileName = iApp::instance()->etcDir() + "logger.ini";
+    if (QFile::exists(confFileName)) {
+        IniFile ini(confFileName, QIODevice::ReadOnly);
+
+        // Default values for all sources
+        maxSize = 1024 * ini.getValue(".default/log_size", maxSize / 1024).toInt();
+        maxCount = ini.getValue(".default/log_count", maxCount).toInt();
+
+        // Default values for this source
+        maxSize = 1024 * ini.getValue(source.toLatin1() + "/log_size", maxSize / 1024).toInt();
+        maxCount = ini.getValue(source.toLatin1() + "/log_count", maxCount).toInt();
+    }
 }
 
 
 
 void LoggerWorker::writeToLogFile(LoggerSource const & src, QString const & msg)
 {
+    //::printf("writeToLogFile(\'%s\', \'%s\') fileName = \'%s\'\n", qPrintable(src.name), qPrintable(msg), qPrintable(src.fileName));
+    if (src.fileName.isEmpty())
+        return;
     QFile f(src.fileName);
     QFile::OpenMode mode;
 #ifdef Q_OS_LINUX
 
 Logger::Logger()
     : iLogger()
+    , mReady(false)
     , mFatalMsgHandler(defFatalMsgHandler)
     , mConsoleSeverity(iLogger::Fatal)
-    , mDefaultSource("evaf")
     , mThread(0)
     , mWorker(0)
 {
 
     qRegisterMetaType<LoggerSource>("LoggerSource");
 
+    // Create the default source
+    mDefaultSource = new LoggerSource;
+    mDefaultSource->name = "common";
+
     write(Info, QString("%1 created").arg(objectName()), 0, printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
 }
 
     // Clear existing sources in case the application was restarted
     mSources.clear();
 
+    // Set the default source name to the name of the application
+    setDefaultSource(iApp::instance()->name());
+
+    // Read configuration parameters from the application's INI file
+    QVariant v = iConfig::instance()->getValue(QString("%1/general/log_level").arg(iApp::instance()->name()), severity());
+    if (v.isValid())
+        setSeverity(iLogger::Severity(qBound(int(iLogger::None), v.toInt(), int(iLogger::Debug))));
+    v = iConfig::instance()->getValue(QString("%1/general/log_size").arg(iApp::instance()->name()), maxSize());
+    if (v.isValid())
+        setMaxSize(v.toUInt());
+    v = iConfig::instance()->getValue(QString("%1/general/log_cnt").arg(iApp::instance()->name()), maxCount());
+    if (v.isValid())
+        setMaxCount(v.toUInt());
+
     // Destroy the previous worker thread
     if (mWorker) {
         delete mWorker;
     mThread->start(QThread::IdlePriority);
     connect(this, SIGNAL(writeToLogFile(LoggerSource,QString)), mWorker, SLOT(writeToLogFile(LoggerSource,QString)), Qt::QueuedConnection);
 
+    mReady = true;
+
     write(Info, QString("%1 initialized").arg(objectName()), 0, printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
 
     return true;
 }
 
+QString Logger::defaultSource() const
+{
+    return mDefaultSource->name;
+}
+
 void Logger::setDefaultSource(QString const & source)
 {
-    mDefaultSource = source;
+    LoggerSource * src = getSource();
+    if (src && src->name != source)
+        getSource(QString())->init(source);
 }
 
 iLogger::Severity Logger::severity(QString const & source)
 
 void Logger::setMaxSize(uint maxSize, QString const & source)
 {
-    getSource(source)->maxSize = maxSize;
+    getSource(source)->maxSize = maxSize * 1024;
 }
 
 uint Logger::maxCount(QString const & source)
         return;
 
     // Write to the log file
-    LoggerSource * src = getSource(source);
-    if (severity <= src->severity && src->severity != iLogger::None) {
-        QString buf;
-        QTextStream io(&buf);
+    if (mReady) {
+        LoggerSource * src = getSource(source);
+        if (severity <= src->severity && src->severity != iLogger::None) {
+            QString buf;
+            QTextStream io(&buf);
 
-        // Date/time stamp
-        io << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
+            // Date/time stamp
+            io << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
 
-        // Severity
-        io << " " << severityText[severity];
+            // Severity
+            io << " " << severityText[severity];
 
-        // Message
-        io << msg;
+            // Message
+            io << msg;
 
-        // Location in the source file
-        if (!where.isEmpty())
-            io << " (occurred in " << where << ")";
+            // Location in the source file
+            if (!where.isEmpty())
+                io << " (occurred in " << where << ")";
 
-        io << endl;
-        io.flush();
+            io << endl;
+            io.flush();
 
-        // If the worker is initialized, use the worker thread to do the job
-        if (mWorker) {
             emit writeToLogFile(*src, buf);
         }
-        // Otherwise we have to do it ourselves
-        else {
-            QFile f(src->fileName);
-            QFile::OpenMode mode;
-#ifdef Q_OS_LINUX
-            mode = QFile::Append | QFile::Text | QFile::Unbuffered;
-#else
-            mode = QFile::Append | QFile::Text;
-#endif
-
-            if (f.open(mode)) {
-                f.write(buf.toLocal8Bit());
-                f.close();
-            }
-        }
     }
 
     // Output to the console
 
 LoggerSource * Logger::getSource(QString const & source)
 {
+    if (source.isEmpty() || source == mDefaultSource->name)
+        return mDefaultSource.data();
+
     QHash<QString, QExplicitlySharedDataPointer<LoggerSource> >::const_iterator it = mSources.constFind(source);
     if (it != mSources.constEnd())
         return it->data();
         mSources.insert(source, src);
 
         // Initialize the new source
-        src->init(source.isEmpty() ? mDefaultSource : source, iApp::instance()->logDir(), iApp::instance()->etcDir());
+        src->init(source);
 
         return src.data();
     }
 
  * @brief iLogger interface implementation
  * @author Enar Vaikene
  *
- * Copyright (c) 2011 Enar Vaikene
+ * Copyright (c) 2011-2012 Enar Vaikene
  *
  * This file is part of the eVaf C++ cross-platform application development framework.
  *
     /**
      * Initializes the source
      * @param source Name of the source
-     * @param logDir Full path to the log directory
-     * @param etcDir Full path to the configuration files directory
      *
      * This function initializes the newly created logger source and sets initial
      * parameters for the source.
      * Example logger.ini file:
      * @code
      * [.default]
-     * severity = Fatal
-     * maxSize = 100
-     * maxCount = 3
+     * log_level = Fatal
+     * log_size = 100
+     * log_count = 3
      *
      * [my-source]
-     * severity = Warning
-     * maxSize = 1000
-     * maxCount = 10
+     * log_level = Warning
+     * log_size = 1000
+     * log_count = 10
      * @endcode
      */
-    void init(QString const & source, QString const & logDir, QString const & etcDir);
+    void init(QString const & source);
 
 
 public: // Members (we don't bother adding getter/setter functions)
 
+    /// Name of the source
+    QString name;
+
     /// Current severity level
     iLogger::Severity severity;
 
-    /// Current log file name
+    /// File name
     QString fileName;
 
     /// Current maximum size of log files
     virtual ~Logger();
 
     /**
-     * Initializes the interface implementation
+     * Initializes the iLogger interface implementation
      * @return True if ok; false if initialization failed
      */
     bool init();
         iLogger interface
     */
 
-    virtual QString defaultSource() const { return mDefaultSource; }
+    virtual QString defaultSource() const;
 
     virtual void setDefaultSource(QString const & source);
 
 
 private: // Members
 
+    /// Flag indicating that logger is fully initialized
+    bool mReady;
+
     /// Current fatal error message handler
     FatalMsgHandler mFatalMsgHandler;
 
     /// Console output severity level
     iLogger::Severity mConsoleSeverity;
 
-    /// Current default source (defaults to "evaf")
-    QString mDefaultSource;
+    /// Default logger source
+    QExplicitlySharedDataPointer<LoggerSource> mDefaultSource;
 
-    /// Logger sources
+    /// Other logger sources
     QHash<QString, QExplicitlySharedDataPointer<LoggerSource> > mSources;
 
     /// Worker thread
 private: // Methods
 
     /// Returns the source by the name. The source is created if it does not exist yet.
-    LoggerSource * getSource(QString const & name);
+    LoggerSource * getSource(QString const & name = QString());
 
 #ifdef Q_OS_WIN32
     /// Changes text colors on the Windows console