From b21dc4fe4caa9634df19c39c10ea952e098744af Mon Sep 17 00:00:00 2001
From: Teo Mrnjavac <teo@kde.org>
Date: Fri, 6 Jun 2014 16:00:42 +0200
Subject: [PATCH] Added Utils, Logger, Translations, QCommandLineParser, init
 boilerplate

---
 CMakeLists.txt                                |  11 +-
 lang/calamares_i18n.qrc                       |   6 +
 lang/translations.cmake                       |  48 +++++
 src/calamares/CMakeLists.txt                  |   6 +-
 src/calamares/CalamaresApplication.cpp        | 106 +++++++++++
 src/calamares/CalamaresApplication.h          |  48 +++++
 .../{MainWindow.cpp => CalamaresWindow.cpp}   |   0
 src/calamares/CalamaresWindow.h               |  29 +++
 src/calamares/MainWindow.h                    |   0
 src/calamares/main.cpp                        |  12 ++
 src/libcalamares/CMakeLists.txt               |   7 +-
 src/libcalamares/utils/CalamaresUtils.cpp     |  92 ++++++++++
 src/libcalamares/utils/CalamaresUtils.h       |  40 +++++
 src/libcalamares/utils/Logger.cpp             | 169 ++++++++++++++++++
 src/libcalamares/utils/Logger.h               |  61 +++++++
 15 files changed, 628 insertions(+), 7 deletions(-)
 create mode 100644 lang/calamares_i18n.qrc
 create mode 100644 lang/translations.cmake
 rename src/calamares/{MainWindow.cpp => CalamaresWindow.cpp} (100%)
 create mode 100644 src/calamares/CalamaresWindow.h
 delete mode 100644 src/calamares/MainWindow.h
 create mode 100644 src/libcalamares/utils/CalamaresUtils.cpp
 create mode 100644 src/libcalamares/utils/CalamaresUtils.h
 create mode 100644 src/libcalamares/utils/Logger.cpp
 create mode 100644 src/libcalamares/utils/Logger.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7fb397bb9..0aa4faa27f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,15 +4,16 @@ set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" )
 
 cmake_policy( SET CMP0023 OLD )
 
-find_package( Qt5 5.3.0 CONFIG REQUIRED Core Gui Widgets )
+find_package( Qt5 5.3.0 CONFIG REQUIRED Core Gui Widgets LinguistTools )
 
 ###
 ### Calamares application info
 ###
-SET( CALAMARES_ORGANIZATION_NAME "The Calamares Team" )
-SET( CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares" )
-SET( CALAMARES_APPLICATION_NAME  "Calamares" )
-SET( CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framework" )
+set( CALAMARES_ORGANIZATION_NAME "The Calamares Team" )
+set( CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares" )
+set( CALAMARES_APPLICATION_NAME  "Calamares" )
+set( CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framework" )
+set( CALAMARES_TRANSLATION_LANGUAGES de en )
 
 set( CALAMARES_VERSION_MAJOR 0 )
 set( CALAMARES_VERSION_MINOR 1 )
diff --git a/lang/calamares_i18n.qrc b/lang/calamares_i18n.qrc
new file mode 100644
index 0000000000..e8a27e1a97
--- /dev/null
+++ b/lang/calamares_i18n.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/lang">
+<file>calamares_de.qm</file>
+<file>calamares_en.qm</file>
+</qresource>
+</RCC>
diff --git a/lang/translations.cmake b/lang/translations.cmake
new file mode 100644
index 0000000000..d33178894d
--- /dev/null
+++ b/lang/translations.cmake
@@ -0,0 +1,48 @@
+macro(add_calamares_translations language)
+    list( APPEND CALAMARES_LANGUAGES ${ARGV} )
+
+    set( calamares_i18n_qrc_content "<!DOCTYPE RCC><RCC version=\"1.0\">\n" )
+
+    # calamares and qt language files
+    set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}<qresource prefix=\"/lang\">\n" )
+    foreach( lang ${CALAMARES_LANGUAGES} )
+        set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}<file>calamares_${lang}.qm</file>\n" )
+        if( NOT lang STREQUAL "en" AND EXISTS ${QT_TRANSLATIONS_DIR}/qt_${lang}.qm )
+            file( COPY ${QT_TRANSLATIONS_DIR}/qt_${lang}.qm DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )
+            set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}<file>qt_${lang}.qm</file>\n" )
+        endif()
+
+        # build explicitly enabled languages
+        list( APPEND TS_FILES "${CMAKE_SOURCE_DIR}/lang/calamares_${lang}.ts" )
+    endforeach()
+
+    set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}</qresource>\n" )
+    set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}</RCC>\n" )
+
+    file( WRITE ${CMAKE_BINARY_DIR}/lang/calamares_i18n.qrc "${calamares_i18n_qrc_content}" )
+
+    qt5_add_translation(QM_FILES ${TS_FILES})
+
+    ## HACK HACK HACK - around rcc limitations to allow out of source-tree building
+    set( trans_file calamares_i18n )
+    set( trans_srcfile ${CMAKE_BINARY_DIR}/lang/${trans_file}.qrc )
+    set( trans_infile ${CMAKE_CURRENT_BINARY_DIR}/${trans_file}.qrc )
+    set( trans_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${trans_file}.cxx )
+
+    # Copy the QRC file to the output directory
+    add_custom_command(
+        OUTPUT ${trans_infile}
+        COMMAND ${CMAKE_COMMAND} -E copy ${trans_srcfile} ${trans_infile}
+        MAIN_DEPENDENCY ${trans_srcfile}
+    )
+
+    # Run the resource compiler (rcc_options should already be set)
+    add_custom_command(
+        OUTPUT ${trans_outfile}
+        COMMAND ${QT_RCC_EXECUTABLE}
+        ARGS ${rcc_options} -name ${trans_file} -o ${trans_outfile} ${trans_infile}
+        MAIN_DEPENDENCY ${trans_infile}
+        DEPENDS ${QM_FILES}
+    )
+endmacro()
+
diff --git a/src/calamares/CMakeLists.txt b/src/calamares/CMakeLists.txt
index 8d658a24c3..beae830bf5 100644
--- a/src/calamares/CMakeLists.txt
+++ b/src/calamares/CMakeLists.txt
@@ -7,7 +7,7 @@ endif()
 set( calamaresSources
     main.cpp
     CalamaresApplication.cpp
-    MainWindow.cpp
+    CalamaresWindow.cpp
 )
 
 set( calamaresUi
@@ -28,6 +28,10 @@ qt5_wrap_ui( calamaresUi_H ${calamaresUi} )
 
 #qt_add_resources( calamaresRc "../../resources.qrc" )
 
+# Translations
+include( ${CMAKE_SOURCE_DIR}/lang/translations.cmake )
+add_calamares_translations( ${CALAMARES_TRANSLATION_LANGUAGES} )
+
 set( final_src ${calamaresUi_H} ${calamaresSources} ${calamaresRc} )
 
 add_executable( calamares_bin ${final_src} )
diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp
index e69de29bb2..ed5f9dd565 100644
--- a/src/calamares/CalamaresApplication.cpp
+++ b/src/calamares/CalamaresApplication.cpp
@@ -0,0 +1,106 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CalamaresApplication.h"
+
+#include "CalamaresWindow.h"
+#include "CalamaresVersion.h"
+
+#include "utils/CalamaresUtils.h"
+#include "utils/Logger.h"
+
+
+CalamaresApplication::CalamaresApplication( int& argc, char *argv[] )
+    : QApplication( argc, argv )
+    , m_mainwindow( 0 )
+{
+    setOrganizationName( QLatin1String( CALAMARES_ORGANIZATION_NAME ) );
+    setOrganizationDomain( QLatin1String( CALAMARES_ORGANIZATION_DOMAIN ) );
+    setApplicationName( QLatin1String( CALAMARES_APPLICATION_NAME ) );
+    setApplicationVersion( QLatin1String( CALAMARES_VERSION ) );
+
+    CalamaresUtils::installTranslator( this );
+}
+
+
+void
+CalamaresApplication::init()
+{
+    qDebug() << "CalamaresApplication thread:" << thread();
+
+    //TODO: Icon loader
+    Logger::setupLogfile();
+
+    setQuitOnLastWindowClosed( false );
+
+    initBranding();
+
+    setWindowIcon( QIcon( "from branding" ) );
+
+    initPlugins();
+
+    initJobQueue();
+
+    m_mainwindow = new CalamaresWindow();
+    m_mainwindow->show();
+}
+
+
+CalamaresApplication::~CalamaresApplication()
+{
+    tDebug( LOGVERBOSE ) << "Shutting down Calamares...";
+
+//    if ( JobQueue::instance() )
+//        JobQueue::instance()->stop();
+
+//    delete m_mainwindow;
+
+//    delete JobQueue::instance();
+
+    tDebug( LOGVERBOSE ) << "Finished shutdown.";
+}
+
+
+CalamaresApplication*
+CalamaresApplication::instance()
+{
+    return qobject_cast< CalamaresApplication* >( QApplication::instance() );
+}
+
+
+void
+CalamaresApplication::initBranding()
+{
+
+}
+
+
+void
+CalamaresApplication::initPlugins()
+{
+
+}
+
+
+void
+CalamaresApplication::initJobQueue()
+{
+
+}
+
+
diff --git a/src/calamares/CalamaresApplication.h b/src/calamares/CalamaresApplication.h
index e69de29bb2..72616d8d09 100644
--- a/src/calamares/CalamaresApplication.h
+++ b/src/calamares/CalamaresApplication.h
@@ -0,0 +1,48 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CALAMARESAPPLICATION_H
+#define CALAMARESAPPLICATION_H
+
+#include <QApplication>
+
+#define APP CalamaresApplication::instance()
+
+class CalamaresWindow;
+
+class CalamaresApplication : public QApplication
+{
+    Q_OBJECT
+public:
+    CalamaresApplication( int& argc, char *argv[] );
+    virtual ~CalamaresApplication();
+
+    void init();
+    static CalamaresApplication* instance();
+
+    void initBranding();
+    void initPlugins();
+    void initJobQueue();
+
+private:
+    CalamaresWindow* m_mainwindow;
+
+    //QPointer< Calamares::JobQueue > m_jobQueue;
+};
+
+#endif //CALAMARESAPPLICATION_H
diff --git a/src/calamares/MainWindow.cpp b/src/calamares/CalamaresWindow.cpp
similarity index 100%
rename from src/calamares/MainWindow.cpp
rename to src/calamares/CalamaresWindow.cpp
diff --git a/src/calamares/CalamaresWindow.h b/src/calamares/CalamaresWindow.h
new file mode 100644
index 0000000000..d7c2cc63d8
--- /dev/null
+++ b/src/calamares/CalamaresWindow.h
@@ -0,0 +1,29 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CALAMARESWINDOW_H
+#define CALAMARESWINDOW_H
+
+#include <QMainWindow>
+
+class CalamaresWindow : public QMainWindow
+{
+
+};
+
+#endif //CALAMARESWINDOW_H
diff --git a/src/calamares/MainWindow.h b/src/calamares/MainWindow.h
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/calamares/main.cpp b/src/calamares/main.cpp
index 401ee3404c..e561a85c8b 100644
--- a/src/calamares/main.cpp
+++ b/src/calamares/main.cpp
@@ -20,7 +20,9 @@
 #include "CalamaresApplication.h"
 
 #include "kdsingleapplicationguard/kdsingleapplicationguard.h"
+#include "utils/Logger.h"
 
+#include <QCommandLineParser>
 #include <QDebug>
 
 int
@@ -28,6 +30,16 @@ main( int argc, char *argv[] )
 {
     CalamaresApplication a( argc, argv );
 
+    QCommandLineParser parser;
+    parser.setApplicationDescription( "Distribution-independent installer framework" );
+    parser.addHelpOption();
+    parser.addVersionOption();
+    QCommandLineOption verboseOption( QStringList() << "v" << "verbose",
+                                      "Verbose output for debugging purposes." );
+    parser.addOption( verboseOption );
+
+    parser.process( a );
+
     KDSingleApplicationGuard guard( KDSingleApplicationGuard::AutoKillOtherInstances );
     QObject::connect( &guard, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ), &a, SLOT( instanceStarted( KDSingleApplicationGuard::Instance ) ) );
 
diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt
index 5736fa752a..af0b25c844 100644
--- a/src/libcalamares/CMakeLists.txt
+++ b/src/libcalamares/CMakeLists.txt
@@ -16,6 +16,9 @@ set( libSources
     kdsingleapplicationguard/kdsharedmemorylocker.cpp
     kdsingleapplicationguard/kdtoolsglobal.cpp
     kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp
+
+    utils/Logger.cpp
+    utils/CalamaresUtils.cpp
 )
 
 include_directories(
@@ -34,7 +37,7 @@ set_target_properties( calamareslib
         OUTPUT_NAME "calamares"
 )
 
-qt5_use_modules( calamareslib Widgets )
+qt5_use_modules( calamareslib Core )
 
 target_link_libraries( calamareslib
     #LINK_PRIVATE
@@ -55,7 +58,9 @@ install( TARGETS calamareslib
 # Install header files
 file( GLOB rootHeaders "*.h" )
 file( GLOB kdsingleapplicationguardHeaders "kdsingleapplicationguard/*.h" )
+file( GLOB utilsHeaders "utils/*.h" )
 
 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h DESTINATION include/libcalamares )
 install( FILES ${rootHeaders}                       DESTINATION include/libcalamares )
 install( FILES ${kdsingleapplicationguardHeaders}   DESTINATION include/libcalamares/kdsingleapplicationguard )
+install( FILES ${utilsHeaders}                      DESTINATION include/libcalamares/utils )
diff --git a/src/libcalamares/utils/CalamaresUtils.cpp b/src/libcalamares/utils/CalamaresUtils.cpp
new file mode 100644
index 0000000000..3cd7cdc3f0
--- /dev/null
+++ b/src/libcalamares/utils/CalamaresUtils.cpp
@@ -0,0 +1,92 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2013-2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Originally from Tomahawk, portions:
+ *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
+ *   Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
+ *   Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CalamaresUtils.h"
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QDir>
+#include <QLocale>
+#include <QTranslator>
+
+namespace CalamaresUtils
+{
+
+QDir
+appDataDir()
+{
+    QString path;
+    path = QDir::home().filePath( ".local/share" );
+
+    path += "/" + QCoreApplication::organizationName();
+    QDir d( path );
+    d.mkpath( path );
+
+    return d;
+}
+
+
+QDir
+appLogDir()
+{
+    return appDataDir();
+}
+
+
+void
+installTranslator( QObject* parent )
+{
+    QString locale = QLocale::system().uiLanguages().first().replace( "-", "_" );
+
+    if ( locale == "C" )
+        locale = "en";
+
+    // Calamares translations
+    QTranslator* translator = new QTranslator( parent );
+    if ( translator->load( QString( ":/lang/calamares_" ) + locale ) )
+    {
+        qDebug() << "Translation: Calamares: Using system locale:" << locale;
+    }
+    else
+    {
+        qDebug() << "Translation: Calamares: Using default locale, system locale one not found:" << locale;
+        translator->load( QString( ":/lang/calamares_en" ) );
+    }
+
+    QCoreApplication::installTranslator( translator );
+
+    // Qt translations
+    translator = new QTranslator( parent );
+    if ( translator->load( QString( ":/lang/qt_" ) + locale ) )
+    {
+        qDebug() << "Translation: Qt: Using system locale:" << locale;
+    }
+    else
+    {
+        qDebug() << "Translation: Qt: Using default locale, system locale one not found:" << locale;
+    }
+
+    QCoreApplication::installTranslator( translator );
+}
+
+}
diff --git a/src/libcalamares/utils/CalamaresUtils.h b/src/libcalamares/utils/CalamaresUtils.h
new file mode 100644
index 0000000000..e8041a1a17
--- /dev/null
+++ b/src/libcalamares/utils/CalamaresUtils.h
@@ -0,0 +1,40 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2013-2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Originally from Tomahawk, portions:
+ *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
+ *   Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
+ *   Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CALAMARESUTILS_H
+#define CALAMARESUTILS_H
+
+#include "DllMacro.h"
+
+class QDir;
+class QObject;
+
+namespace CalamaresUtils
+{
+    DLLEXPORT QDir appDataDir();
+    DLLEXPORT QDir appLogDir();
+    DLLEXPORT void installTranslator( QObject* parent );
+
+}
+
+#endif // CALAMARESUTILS_H
diff --git a/src/libcalamares/utils/Logger.cpp b/src/libcalamares/utils/Logger.cpp
new file mode 100644
index 0000000000..8ddc1f34fe
--- /dev/null
+++ b/src/libcalamares/utils/Logger.cpp
@@ -0,0 +1,169 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
+ *   Copyright 2014,      Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Logger.h"
+
+#include <iostream>
+#include <fstream>
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QFileInfo>
+#include <QMutex>
+#include <QTime>
+#include <QVariant>
+
+#include "utils/CalamaresUtils.h"
+
+#define LOGFILE_SIZE 1024 * 256
+
+#define RELEASE_LEVEL_THRESHOLD 0
+#define DEBUG_LEVEL_THRESHOLD LOGEXTRA
+
+using namespace std;
+
+ofstream logfile;
+static int s_threshold = -1;
+QMutex s_mutex;
+
+namespace Logger
+{
+
+static void
+log( const char *msg, unsigned int debugLevel, bool toDisk = true )
+{
+    if ( s_threshold < 0 )
+    {
+        if ( qApp->arguments().contains( "--verbose" ) ||
+             qApp->arguments().contains( "-v" ) )
+            s_threshold = LOGVERBOSE;
+        else
+            #ifdef QT_NO_DEBUG
+            s_threshold = RELEASE_LEVEL_THRESHOLD;
+            #else
+            s_threshold = DEBUG_LEVEL_THRESHOLD;
+            #endif
+    }
+
+    if ( toDisk || (int)debugLevel <= s_threshold )
+    {
+        QMutexLocker lock( &s_mutex );
+
+        logfile << QDate::currentDate().toString().toUtf8().data()
+                << " - "
+                << QTime::currentTime().toString().toUtf8().data()
+                << " [" << QString::number( debugLevel ).toUtf8().data() << "]: "
+                << msg << endl;
+
+        logfile.flush();
+    }
+
+    if ( debugLevel <= LOGEXTRA || (int)debugLevel <= s_threshold )
+    {
+        QMutexLocker lock( &s_mutex );
+
+        cout << QTime::currentTime().toString().toUtf8().data()
+             << " [" << QString::number( debugLevel ).toUtf8().data() << "]: "
+             << msg << endl;
+
+        cout.flush();
+    }
+}
+
+
+void
+CalamaresLogHandler( QtMsgType type, const QMessageLogContext& context, const QString& msg )
+{
+    static QMutex s_mutex;
+
+    QByteArray ba = msg.toUtf8();
+    const char* message = ba.constData();
+
+    QMutexLocker locker( &s_mutex );
+    switch( type )
+    {
+        case QtDebugMsg:
+            log( message, LOGVERBOSE );
+            break;
+
+        case QtCriticalMsg:
+            log( message, 0 );
+            break;
+
+        case QtWarningMsg:
+            log( message, 0 );
+            break;
+
+        case QtFatalMsg:
+            log( message, 0 );
+            break;
+    }
+}
+
+
+QString
+logFile()
+{
+    return CalamaresUtils::appLogDir().filePath( "Calamares.log" );
+}
+
+
+void
+setupLogfile()
+{
+    if ( QFileInfo( logFile().toLocal8Bit() ).size() > LOGFILE_SIZE )
+    {
+        QByteArray lc;
+        {
+            QFile f( logFile().toLocal8Bit() );
+            f.open( QIODevice::ReadOnly | QIODevice::Text );
+            lc = f.readAll();
+            f.close();
+        }
+
+        QFile::remove( logFile().toLocal8Bit() );
+
+        {
+            QFile f( logFile().toLocal8Bit() );
+            f.open( QIODevice::WriteOnly | QIODevice::Text );
+            f.write( lc.right( LOGFILE_SIZE - ( LOGFILE_SIZE / 4 ) ) );
+            f.close();
+        }
+    }
+
+    logfile.open( logFile().toLocal8Bit(), ios::app );
+    qInstallMessageHandler( CalamaresLogHandler );
+}
+
+}
+
+using namespace Logger;
+
+CLog::CLog( unsigned int debugLevel )
+    : QDebug( &m_msg )
+    , m_debugLevel( debugLevel )
+{
+}
+
+
+CLog::~CLog()
+{
+    log( m_msg.toUtf8().data(), m_debugLevel );
+}
+
diff --git a/src/libcalamares/utils/Logger.h b/src/libcalamares/utils/Logger.h
new file mode 100644
index 0000000000..2350089014
--- /dev/null
+++ b/src/libcalamares/utils/Logger.h
@@ -0,0 +1,61 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
+ *   Copyright 2014,      Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CALAMARES_LOGGER_H
+#define CALAMARES_LOGGER_H
+
+#include <QDebug>
+
+#include "DllMacro.h"
+
+#define LOGDEBUG 1
+#define LOGINFO 2
+#define LOGEXTRA 5
+#define LOGVERBOSE 8
+
+namespace Logger
+{
+    class DLLEXPORT CLog : public QDebug
+    {
+    public:
+        CLog( unsigned int debugLevel = 0 );
+        virtual ~CLog();
+
+    private:
+        QString m_msg;
+        unsigned int m_debugLevel;
+    };
+
+    class DLLEXPORT CDebug : public CLog
+    {
+    public:
+        CDebug( unsigned int debugLevel = LOGDEBUG ) : CLog( debugLevel )
+        {
+        }
+    };
+
+    DLLEXPORT void CalamaresLogHandler( QtMsgType type, const char* msg );
+    DLLEXPORT void setupLogfile();
+    DLLEXPORT QString logFile();
+}
+
+#define tLog Logger::CLog
+#define tDebug Logger::CDebug
+
+#endif // CALAMARES_LOGGER_H
-- 
GitLab