changeset 0:147b08bc7d64

Initial commit of a basic Application framework.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 23 Mar 2015 12:41:52 +0100
parents
children 7a2637c3eb83
files CMakeLists.txt INSTALL cmake/HGVersion.cmake cmake/SvgToPng.cmake src/CMakeLists.txt src/constants.h src/fonts.qrc src/fonts/DejaVuSans.ttf src/l10n/l10n.qrc.in src/l10n/main_de_DE.ts src/main.cpp src/mainwindow.cpp src/mainwindow.h src/strhelp.c src/strhelp.h src/util.h src/util_linux.c src/util_win.c
diffstat 18 files changed, 1374 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CMakeLists.txt	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,64 @@
+# Copyright (C) 2014 by Intevation GmbH
+#
+# This file is Free Software under the GNU GPL (v>=2)
+# and comes with ABSOLUTELY NO WARRANTY!
+# See LICENSE.txt for details.
+
+cmake_minimum_required(VERSION 2.8.8)
+project(replay-it)
+
+
+### Generic Setup
+
+#Old qtmain linking behavior to be compatible with cmake versions < 2.8.11
+
+if(POLICY CMP0020)
+  cmake_policy(SET CMP0020 OLD)
+endif()
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
+
+include(HGVersion)
+
+if(HG_REVISION)
+   If(HG_REVISION_DIST STREQUAL "0")
+      add_definitions(-DIS_TAG_BUILD)
+   endif()
+   set(PROJECT_VERSION ${HG_REVISION})
+else()
+   set(PROJECT_VERSION unknown)
+endif()
+
+add_definitions(-DVERSION="${PROJECT_VERSION}")
+add_definitions(-DAPPNAME="${PROJECT_NAME}")
+
+find_package(Qt5Widgets)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+### Hardening flags
+
+set(HARDENING_FLAGS " -Wall -s -fstack-protector-all -fno-exceptions")
+set(HARDENING_FLAGS " ${HARDENING_FLAGS} -Wstack-protector")
+set(HARDENING_FLAGS " ${HARDENING_FLAGS} --param ssp-buffer-size=4")
+set(HARDENING_FLAGS " ${HARDENING_FLAGS} -D_FORTIFY_SOURCE=2 -O0")
+
+if(WIN32)
+   add_definitions(-D_WIN32_WINNT=0x0600) # Windows vista
+   add_definitions(-DWINVER=0x0600)
+   add_definitions(-DUNICODE -D_UNICODE)
+   add_definitions(-DMINGW_HAS_SECURE_API) # for _s functions
+endif(WIN32)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${HARDENING_FLAGS}")
+
+# Cmake does not correctly identify gcc windres when cross compiling
+# making this line neccessary to set the correct flags for it.
+# See: http://public.kitware.com/Bug/view.php?id=11773
+SET(CMAKE_RC_COMPILE_OBJECT
+      "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -Ocoff <SOURCE> <OBJECT>")
+
+#add_subdirectory(img)
+### Include the actual source directories
+add_subdirectory(src)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,68 @@
+/** @file INSTALL
+@brief Installation Instructions
+*******************************
+
+For Debian based GNU / Linux
+============================
+Tested development platform: Ubuntu 14.4 amd64.
+
+Build dependencies are:
+    build-essential cmake libqt5core5a qttools5-dev-tools qt5-default \
+    qtbase-dev qtbase5-dev-tools qttools5-dev inkscape
+
+
+This document expects the following setup for build and installation.
+It is recommended to set a custom installation prefix to avoid root
+privileges.
+
+    export CUSTOM_PREFIX=<Prefix of your choice (default /usr)>
+    mkdir -p $CUSTOM_PREFIX/bin
+    export PATH=$CUSTOM_PREFIX/bin:$PATH
+
+Building the Software:
+    cd <PATH_TO_REPO>
+    mkdir build-native
+    cd build-native
+    cmake .. -DCMAKE_PREFIX_PATH=$CUSTOM_PREFIX
+
+For Microsoft Windows
+=====================
+The Windows variant should be cross compiled from a Debian based GNU/Linux
+system. The minimum requirement is Debian stable.
+
+Tested development platform is Ubuntu 14.4
+
+Dependencies on the Host system:
+
+    apt-get install git autoconf automake bash bison bzip2 \
+    cmake flex gettext git g++ intltool \
+    libffi-dev libtool libltdl-dev libssl-dev \
+    libxml-parser-perl make openssl patch perl \
+    pkg-config scons sed unzip curl xz-utils autopoint \
+    gperf
+
+Build the windows binaries:
+
+    MXEPATH=$CUSTOM_PREFIX/win
+    git clone https://github.com/Intevation/mxe.git $MXEPATH
+    cd $MXEPATH
+    git checkout replay-it
+    echo "MXE_TARGETS := i686-w64-mingw32.static" > settings.mk
+    make qtbase
+
+Add CMAKE_STRIP to the toolchain file:
+
+    echo "set(CMAKE_STRIP $MXEPATH/usr/bin/i686-w64-mingw32.static-strip)" >> \
+        "$MXEPATH/usr/i686-w64-mingw32.static/share/cmake/mxe-conf.cmake"
+
+Compile the software:
+
+    cd repo
+    mkdir build-windows
+    cd build-windows
+    MXETARGET=$MXEPATH/usr/i686-w64-mingw32.static/
+    cmake .. \
+        -DCMAKE_PREFIX_PATH="$MXETARGET/qt5;$MXETARGET;" \
+        -DCMAKE_TOOLCHAIN_FILE="$MXETARGET/share/cmake/mxe-conf.cmake" \
+        -DCMAKE_VERBOSE_MAKEFILE=True
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/HGVersion.cmake	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,57 @@
+# Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+# Software engineering by Intevation GmbH
+#
+# This file is Free Software under the GNU GPL (v>=2)
+# and comes with ABSOLUTELY NO WARRANTY!
+# See LICENSE.txt for details.
+
+# This makes some variables available to generate a nice version number for
+# hg managed repositories.
+# It sets HG_REVISION_TAG to the value of the latest tag
+# HG_REVISION_DIST to the differences between the tag and the current tip
+# HG_REVISION_ID to the actual revision
+# based on code found in the lemon graph library https://lemon.cs.elte.hu
+# HG_REVISON to a nice combination of those.
+find_package(Hg)
+if (HG_FOUND)
+  EXECUTE_PROCESS(
+    COMMAND
+    hg log -r. --template "{latesttag}"
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_TAG
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  EXECUTE_PROCESS(
+    COMMAND
+    hg log -r. --template "{latesttagdistance}"
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_DIST
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  EXECUTE_PROCESS(
+    COMMAND
+    hg log -r. --template "{node|short}"
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_ID
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+
+  IF(HG_REVISION_TAG STREQUAL "")
+    SET(HG_REVISION_ID "hg-tip")
+  ELSE()
+    IF(HG_REVISION_TAG STREQUAL "null")
+      SET(HG_REVISION_TAG "trunk")
+    ELSEIF(HG_REVISION_TAG MATCHES "^r")
+      STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG)
+    ENDIF()
+    IF(HG_REVISION_DIST STREQUAL "0")
+      SET(HG_REVISION ${HG_REVISION_TAG})
+    ELSE()
+      SET(HG_REVISION
+        "${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}")
+    ENDIF()
+  ENDIF()
+ENDIF()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/SvgToPng.cmake	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,29 @@
+macro(svg_to_png
+      file_from
+      file_to
+      dpi
+      size
+      list_to_add)
+
+# remove ../'s
+get_filename_component(_file_from ${CMAKE_CURRENT_SOURCE_DIR}/${file_from} REALPATH)
+get_filename_component(_file_to   ${CMAKE_CURRENT_SOURCE_DIR}/${file_to}   REALPATH)
+
+list(APPEND ${list_to_add} ${_file_to})
+
+find_program(INKSCAPE_EXE inkscape)
+mark_as_advanced(INKSCAPE_EXE)
+
+if(INKSCAPE_EXE)
+   add_custom_command(
+      OUTPUT  ${_file_to}
+      COMMAND ${INKSCAPE_EXE} ${_file_from} --export-width=${size} --export-height=${size} --export-dpi=${dpi}  --without-gui --export-png=${_file_to}
+      DEPENDS ${_file_from} ${INKSCAPE_EXE}
+   )
+else()
+   message(WARNING "Inkscape not found, could not re-generate ${_file_to} from ${_file_from}!")
+endif()
+
+unset(_file_from)
+unset(_file_to)
+endmacro()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/CMakeLists.txt	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,92 @@
+# Copyright (C) 2014 by Intevation GmbH
+#
+# This file is Free Software under the GNU GPL (v>=2)
+# and comes with ABSOLUTELY NO WARRANTY!
+# See LICENSE.txt for details.
+
+include_directories(${Qt5Widgets_INCLUDE_DIRS})
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_definitions(${Qt5Widgets_DEFINITIONS})
+
+set(APPLICATION_SRC
+   main.cpp
+   mainwindow.cpp
+   strhelp.c
+   util_win.c
+   util_linux.c
+)
+
+find_package(Qt5LinguistTools)
+
+if(UNIX)
+   # See: https://bugreports.qt-project.org/browse/QTBUG-35918
+   # XCB_EXTRA_LIBS should be gotten automatically.
+   # The following list is taken from the .pri file
+   get_target_property(_loc Qt5::Widgets LOCATION)
+   get_filename_component(_qtpath ${_loc} PATH)
+
+   set(XCB_EXTRA_LIBS
+      -L${_qtpath}
+      -lQt5DBus -lQt5Gui -lQt5Core -lQt5PlatformSupport
+      -lX11 -lX11-xcb -lxcb
+      -lXrender -lSM -lICE -ldbus-1
+      -lm -ldl -lrt -lpthread )
+
+elseif(WIN32)
+   set (_add_executable_params WIN32)
+
+   get_target_property(_loc Qt5::Widgets LOCATION)
+   get_filename_component(_qtpath ${_loc} PATH)
+   set(WINDOWS_EXTRA_LIBS
+        -L${_qtpath}
+        -lwinspool -lshlwapi
+        -lQt5PlatformSupport -lQt5Gui -lcomdlg32 -loleaut32 -limm32 -lwinmm
+        -lglu32 -lopengl32 -lgdi32 -lQt5Core -lole32 -lmstask -luuid -lws2_32
+        -ladvapi32 -lshell32 -luser32 -lkernel32 -lpcre16 -lz)
+
+   set(EXTRA_STATIC_LIBS Qt5::QWindowsIntegrationPlugin ${WINDOWS_EXTRA_LIBS})
+endif()
+
+set(QT_RESOURCES
+   ${CMAKE_CURRENT_SOURCE_DIR}/fonts.qrc
+   #   ${CMAKE_SOURCE_DIR}/img/icons.qrc
+)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+qt5_add_resources(APPLICATION_SRC ${QT_RESOURCES})
+
+if(Qt5LinguistTools_FOUND)
+
+   set(FILES_TO_TRANSLATE
+      ${APPLICATION_SRC}
+   )
+
+   # Include translation as a resource
+   # This works in the source directory to enable the rcc dependencies to be found
+   # and it also updates the currently available localization.
+   configure_file(l10n/l10n.qrc.in l10n.qrc)
+   qt5_add_resources(APPLICATION_SRC ${CMAKE_CURRENT_BINARY_DIR}/l10n.qrc)
+   qt5_create_translation(TRANSLATION_SRC ${FILES_TO_TRANSLATE}
+      ${CMAKE_CURRENT_SOURCE_DIR}/l10n/main_de_DE.ts)
+endif()
+
+add_executable(${PROJECT_NAME}
+   ${_add_executable_params}
+   #   ${IMG_SRC}
+   ${APPLICATION_SRC}
+   ${TRANSLATION_SRC}
+   #   ${CMAKE_SOURCE_DIR}/img/icon.rc
+   )
+
+
+target_link_libraries(${PROJECT_NAME}
+   Qt5::Widgets
+   ${EXTRA_STATIC_LIBS})
+
+if (WIN32)
+   set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-municode")
+endif(WIN32)
+
+install(TARGETS ${PROJECT_NAME} DESTINATION bin)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/constants.h	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,56 @@
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+/* Copyright (C) 2014 by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+/** @file Common definitions for this project.
+ *
+ * This file can be included to pull in common
+ * definitions in the application. */
+
+/**@def The version of the software package. */
+#ifndef VERSION
+#define VERSION "0.0.1"
+#endif
+
+/**@def The user visible application name. */
+#ifndef APPNAME
+#define APPNAME "undefined"
+#endif
+
+/**@def The user visible organization behind this. */
+#ifndef ORGANIZATION
+#define ORGANIZATION "Intevation GmbH"
+#endif
+
+/**@def Short command line description. */
+#define DESCRIPTION "A tool to replay recorded user sessions."
+
+/**@def Short copyright notice to show users. */
+#define COPYRIGHT "Copyright (C) 2015 Intevation GmbH \n\n" \
+                  "This file is Free Software under the GNU GPL (v>=2)\n" \
+                  "and comes with ABSOLUTELY NO WARRANTY!\n"
+
+/**@def the config key for the last selected root folder. */
+#define ROOT_FOLDER_KEY "RootFolder"
+
+/**@def the config key for the root folder info pattern. */
+#define ROOT_FOLDER_PATTERN_KEY "RootFolderPattern"
+
+/**@def the default value for the root folder pattern */
+#define DEFAULT_ROOT_PATTERN "Datum_Fachnummr_Batch-Nr."
+
+/**@def the config key for the last selected subfolder. */
+#define SUB_FOLDER_KEY "SubFolder"
+
+/**@def the config key for the sub folder info pattern. */
+#define SUB_FOLDER_PATTERN_KEY "SubFolderPattern"
+
+/**@def the default value for the root folder pattern */
+#define SUB_FOLDER_PATTERN "IP-Addr_Nethz-Login"
+
+#endif // CONSTANTS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fonts.qrc	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/fonts">
+    <file alias="DejaVuSans.ttf">fonts/DejaVuSans.ttf</file>
+</qresource>
+</RCC>
Binary file src/fonts/DejaVuSans.ttf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/l10n/l10n.qrc.in	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/l10n">
+    <file alias="main_de_DE.qm">@CMAKE_CURRENT_BINARY_DIR@/main_de_DE.qm</file>
+</qresource>
+</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/l10n/main_de_DE.ts	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="de_DE">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <location filename="../mainwindow.cpp" line="50"/>
+        <source>Error!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="112"/>
+        <source>Failed to access directory: &apos;%1&apos;</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>main</name>
+    <message>
+        <location filename="../main.cpp" line="145"/>
+        <source>The folder containing the data to replay.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main.cpp" line="147"/>
+        <source>Print debug output.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.cpp	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,172 @@
+/* Copyright (C) 2014 by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+/** @file Main entry point for the application.
+ *
+ * This file is the wrapper around the qt application.
+ * Does command line parsing and preparation of the QApplication.
+ */
+#include "constants.h"
+
+#include "mainwindow.h"
+
+#include "strhelp.h"
+#include "util.h"
+
+#include <QApplication>
+#include <QCommandLineParser>
+#include <QtPlugin>
+#include <QDebug>
+#include <QTranslator>
+#include <QSettings>
+#include <QFontDatabase>
+#include <QSplashScreen>
+#include <QTimer>
+
+#ifdef Q_OS_WIN
+
+ #include <windows.h>
+ #include <shlobj.h>
+
+ Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
+#else
+/* this is only necessary if we build statically for GNU/Linux */
+// Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
+#endif
+
+#ifdef IS_TAG_BUILD
+bool g_debug = false;
+#else
+bool g_debug = true;
+#endif
+
+QtMessageHandler g_default_msg_handler = NULL;
+
+void filterDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+    if (!g_debug && type == QtDebugMsg) {
+        return;
+    }
+
+    if (g_default_msg_handler) {
+        (*g_default_msg_handler)(type, context, msg);
+    }
+}
+
+int realMain(int argc, char **argv);
+
+#if defined(WIN32) && defined(UNICODE)
+
+/** @brief Unicode entry point.
+ *
+ * Converts arguments to UTF-8 and executes the real
+ * entry point realMain.
+ */
+int wmain(int argc, wchar_t **argv, wchar_t **envp)
+{
+    char **utf8args = NULL;
+
+    utf8args = (char**) xmalloc0 ((argc + 1) * sizeof(char*));
+
+    for (int i = 0; i < argc; i++) {
+        utf8args[i] = wchar_to_utf8(argv[i], wcslen(argv[i]));
+        if (utf8args[i] == NULL) {
+            printf ("Fatal: could not convert arguments to UTF-8.\n");
+            exit(-1);
+        }
+    }
+    int ret = realMain(argc, utf8args);
+    strv_free(utf8args);
+
+    return ret;
+}
+#else
+int main(int argc, char **argv)
+{
+    return realMain(argc, argv);
+}
+#endif
+
+/** @brief The real entry point to the application.
+ *
+ * @param [in] argc the count of the arguments.
+ * @param [in] argv On GNU/Linux this function expects argv to be in the
+ * native system encoding. On Windows the arguments
+ * shall be UTF-8
+ *
+ * @returns 0 on success an error code otherwise. */
+int realMain(int argc, char **argv)
+{
+    /* QApplication setup */
+    QApplication app (argc, argv);
+    QApplication::setQuitOnLastWindowClosed(true);
+    QApplication::setOrganizationName(QString::fromLatin1(ORGANIZATION));
+    QApplication::setApplicationName(QString::fromLatin1(APPNAME));
+    QApplication::setApplicationVersion(QString::fromLatin1(VERSION));
+    QSettings::setDefaultFormat(QSettings::IniFormat);
+
+    /* Setup translations */
+    QTranslator translator;
+    if (QLocale::system().name() == "C") {
+        /* Useful for testing / development as the primary target is german */
+        translator.load(":/l10n/main_de_DE");
+    } else {
+        translator.load(":/l10n/main_" + QLocale::system().name());
+    }
+    app.installTranslator(&translator);
+
+    /* Install static fonts */
+
+    /* The putenv here works around a bug in qt (#29192). Qt thinks it is a fatal
+     * error if the font directory does not exist. Will be fixed in Qt 5.4 */
+    char * inst_dir = get_install_dir();
+    if (inst_dir) {
+        qputenv("QT_QPA_FONTDIR", inst_dir);
+        xfree(inst_dir);
+    }
+    int fontId = QFontDatabase::addApplicationFont(":/fonts/DejaVuSans.ttf");
+    if (fontId != -1)
+    {
+        QFont font("DejaVuSans");
+        font.setPointSize(9);
+        app.setFont(font);
+    }
+
+    /* Parse the command line */
+    QCommandLineParser parser;
+    parser.setApplicationDescription(QObject::tr(DESCRIPTION) + "\n" +
+                                     QObject::tr(COPYRIGHT));
+    parser.addHelpOption();
+
+    parser.addPositionalArgument("folder", QCoreApplication::translate("main", "The folder containing the data to replay."));
+    QCommandLineOption debugOpt(QStringList() << "debug",
+            QCoreApplication::translate("main", "Print debug output."));
+    parser.addOption(debugOpt);
+
+    parser.process(app);
+
+#ifdef IS_TAG_BUILD
+    g_debug = parser.isSet(debugOpt);
+#else
+    g_debug = true;
+#endif
+    g_default_msg_handler = qInstallMessageHandler(filterDebugOutput);
+
+
+    /* Initialize the main window */
+    MainWindow mainWin;
+
+    const QStringList args = parser.positionalArguments();
+    if (args.isEmpty() || args.size() > 1) {
+        parser.showHelp(1);
+    }
+    mainWin.setFolder(args.first());
+
+    mainWin.show();
+
+    return app.exec(); /* Go event loop */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mainwindow.cpp	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,117 @@
+/* Copyright (C) 2014 by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+/** @file See mainwindow.h */
+#include "mainwindow.h"
+
+#include "constants.h"
+
+#include <QDebug>
+#include <QDialog>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QPushButton>
+#include <QDir>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QApplication>
+#include <QDragEnterEvent>
+#include <QDragLeaveEvent>
+#include <QDropEvent>
+#include <QDragMoveEvent>
+#include <QMimeData>
+#include <QStandardPaths>
+#include <QStyle>
+#include <QStatusBar>
+
+MainWindow::MainWindow() :
+    mHasValidFolder(false)
+{
+    setStatusBar(new QStatusBar());
+
+    setupGUI();
+    readSettings();
+    setAcceptDrops(true);
+    //QIcon windowIcon = QIcon(":/icon-64.png");
+    //setWindowIcon(windowIcon);
+
+}
+
+void MainWindow::setupGUI()
+{
+}
+
+void MainWindow::showErrorMessage(const QString& errMsg) {
+    QMessageBox::warning(this, tr("Error!"), errMsg);
+    statusBar()->showMessage(errMsg);
+}
+
+void MainWindow::closeEvent(QCloseEvent *event) {
+    mSettings.setValue("geometry", saveGeometry());
+    mSettings.setValue("windowState", saveState());
+    QMainWindow::closeEvent(event);
+}
+
+void MainWindow::readSettings() {
+    restoreGeometry(mSettings.value("geometry").toByteArray());
+    restoreState(mSettings.value("windowState").toByteArray());
+}
+
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+    if (event->mimeData()->hasUrls()) {
+        foreach (const QUrl & url, event->mimeData()->urls()) {
+            if (url.isLocalFile()) {
+                event->acceptProposedAction();
+                return;
+            }
+        }
+    }
+}
+
+void MainWindow::dragMoveEvent(QDragMoveEvent *event)
+{
+    if (event->mimeData()->hasUrls()) {
+        foreach (const QUrl & url, event->mimeData()->urls()) {
+            if (url.isLocalFile()) {
+                event->acceptProposedAction();
+                return;
+            }
+        }
+    }
+}
+
+void MainWindow::dropEvent(QDropEvent *event)
+{
+    const QMimeData *mimeData = event->mimeData();
+
+    if (mimeData->hasUrls()) {
+        foreach (const QUrl & url, mimeData->urls()) {
+            if (!url.isLocalFile()) {
+                qDebug() << "Ignoring drop of " << url;
+                continue;
+            }
+        }
+    }
+}
+
+void MainWindow::dragLeaveEvent(QDragLeaveEvent *event)
+{
+    event->accept();
+}
+
+void MainWindow::setFolder(const QString& folder)
+{
+    QFileInfo fi(folder);
+    if (!fi.isDir() || !fi.isReadable()) {
+        showErrorMessage(tr("Failed to access directory: '%1'").arg(folder));
+    }
+    QDir dir = QDir(folder);
+
+    // TODO;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mainwindow.h	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,58 @@
+/* Copyright (C) 2014 by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+
+/** @file The Main UI class.
+ *
+ * Parent class of all dialogs and graphical user interaction.
+ */
+#include <QMainWindow>
+#include <QSettings>
+
+class QPushButton;
+class QDropEvent;
+class QDragLeaveEvent;
+class QDragMoveEvent;
+class QDragEnterEvent;
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    MainWindow();
+
+protected:
+    /** @brief UI setup */
+    void setupGUI();
+
+    /** @brief Cleanup and save the current state */
+    virtual void closeEvent(QCloseEvent *event);
+
+    /** @brief Restores the last window state */
+    void readSettings();
+
+    /* The drag drop actions */
+    void dragEnterEvent(QDragEnterEvent *event);
+    void dragMoveEvent(QDragMoveEvent *event);
+    void dragLeaveEvent(QDragLeaveEvent *event);
+    void dropEvent(QDropEvent *event);
+
+public slots:
+    /** @brief set an absolute folder to read a metadata.csv from. */
+    void setFolder(const QString &folder);
+
+protected slots:
+    /** @brief Show an error dialog to the user. */
+    void showErrorMessage(const QString& errMsg);
+
+private:
+    QSettings mSettings;
+
+    bool mHasValidFolder;
+    QString mCurFolder;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/strhelp.c	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,276 @@
+/* Copyright (C) 2014 by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+/* Needed to get asprintf */
+#define _GNU_SOURCE 1
+
+/** @file See strhelp.h for documentation. */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+static void
+out_of_core(void)
+{
+  fputs("\nfatal: out of memory\n", stderr);
+  exit(2);
+}
+
+void *
+xmalloc( size_t n )
+{
+  void *p = malloc( n );
+  if( !p )
+    out_of_core();
+  return p;
+}
+
+void *
+xmalloc0( size_t n )
+{
+  void *p = malloc( n );
+  if( !p )
+    out_of_core();
+  memset (p, 0, n);
+  return p;
+}
+
+void *
+xrealloc( void *a, size_t n )
+{
+  void *p = realloc( a, n );
+  if( !p )
+    out_of_core();
+  return p;
+}
+
+char *
+xstrndup( const char *string, const size_t len )
+{
+  char *p = xmalloc( len + 1 );
+  memcpy( p, string, len );
+  p[len] = '\0';
+  return p;
+}
+
+unsigned int
+strv_length (char **str_array)
+{
+  unsigned int i = 0;
+
+  if (!str_array)
+    return 0;
+
+  while (str_array[i])
+    ++i;
+
+  return i;
+}
+
+void strv_append (char ***pArray, const char *string, const size_t len)
+{
+  unsigned int old_len = 0;
+
+  if (!*pArray)
+    {
+      *pArray = xmalloc(2 * sizeof(char*));
+      (*pArray)[0] = xstrndup(string, len);
+      (*pArray)[1] = NULL;
+      return;
+    }
+  old_len = strv_length(*pArray);
+  *pArray = xrealloc(*pArray, sizeof(char**) * (old_len + 2));
+
+  (*pArray)[old_len] = xstrndup(string, len);
+  (*pArray)[old_len + 1] = NULL;
+}
+
+void
+str_append_str(char **pDst, size_t *dst_len, const char *appendage, const size_t len)
+{
+  if (!appendage)
+    return;
+
+  if (!(*pDst))
+    {
+      *pDst = xstrndup(appendage, len);
+      *dst_len = len;
+    }
+  else
+    {
+      size_t new_size = (*dst_len) + len + 1;
+      char *p_old = *pDst;
+      *pDst = xmalloc(new_size);
+      strncpy(*pDst, p_old, *dst_len);
+      strncpy(*pDst + *dst_len, appendage, len);
+      *dst_len = new_size - 1;
+      (*pDst)[*dst_len] = '\0';
+      free (p_old);
+    }
+}
+
+void
+strv_free (char **str_array)
+{
+  if (str_array)
+    {
+      int i;
+
+      for (i = 0; str_array[i] != NULL; i++)
+        free (str_array[i]);
+
+      free (str_array);
+    }
+}
+
+bool
+str_equal (char *s1, char *s2)
+{
+  size_t l1 = strlen(s1);
+  size_t l2 = strlen(s2);
+  if ((l1 == l2) &&
+      (strcmp(s1, s2) == 0))
+    return true;
+  else
+    return false;
+}
+
+bool
+str_starts_with (char *s1, char *s2)
+{
+  size_t l2 = strlen(s2);
+  if (strncmp(s1, s2, l2) == 0)
+    return true;
+  else
+    return false;
+}
+
+void
+str_trim (char **s)
+{
+  size_t i;
+  if (*s != NULL)
+    {
+      while (isspace(**s))
+        (*s)++;
+      i = strlen(*s);
+      while (isspace((*s)[--i]))
+        (*s)[i] = '\0';
+    }
+}
+
+void
+xfree (void *p)
+{
+  if (p)
+    free (p);
+}
+
+int
+xasprintf (char **strp, const char *fmt, ...)
+{
+  int ret;
+  va_list ap;
+  va_start(ap, fmt);
+  ret = vasprintf(strp, fmt, ap);
+  va_end(ap);
+
+  if (ret == -1)
+    out_of_core();
+
+  return ret;
+}
+
+#ifdef WIN32
+/* Adapted from GPGOL rev. e512053 */
+char *
+wchar_to_utf8 (const wchar_t *string, size_t len)
+{
+  int n, ilen;
+  char *result;
+
+  ilen = (int) len;
+  if (ilen < 0)
+    return NULL;
+
+  /* Note, that CP_UTF8 is not defined in Windows versions earlier
+     than NT.*/
+  n = WideCharToMultiByte (CP_UTF8, 0, string, ilen, NULL, 0, NULL, NULL);
+  if (n < 0)
+    return NULL;
+
+  result = xmalloc ((size_t)n+1);
+  n = WideCharToMultiByte (CP_UTF8, 0, string, ilen, result, n, NULL, NULL);
+  if (n < 0)
+    {
+      xfree (result);
+      return NULL;
+    }
+  result[n] = 0;
+  return result;
+}
+
+/* Adapted from GPGOL rev. e512053 */
+wchar_t *
+utf8_to_wchar (const char *string, size_t len)
+{
+  int n, ilen;
+  wchar_t *result;
+
+  ilen = (int) len;
+  if (ilen < 0)
+    return NULL;
+
+  n = MultiByteToWideChar (CP_UTF8, 0, string, ilen, NULL, 0);
+  if (n < 0 || n + 1 < 0)
+    return NULL;
+
+  result = xmalloc ((size_t)(n+1) * sizeof *result);
+  n = MultiByteToWideChar (CP_UTF8, 0, string, ilen, result, n);
+  if (n < 0)
+    {
+      xfree (result);
+      return NULL;
+    }
+  result[n] = 0;
+  return result;
+}
+
+wchar_t
+*acp_to_wchar (const char *string, size_t len)
+{
+  int n, ilen;
+  wchar_t *result;
+
+  ilen = (int) len;
+  if (ilen < 0)
+    return NULL;
+
+  n = MultiByteToWideChar (CP_ACP, 0, string, ilen, NULL, 0);
+  if (n < 0 || n + 1 < 0)
+    return NULL;
+
+  result = xmalloc ((size_t)(n+1) * sizeof *result);
+  n = MultiByteToWideChar (CP_ACP, 0, string, ilen, result, n);
+  if (n < 0)
+    {
+      xfree (result);
+      return NULL;
+    }
+  result[n] = 0;
+  return result;
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/strhelp.h	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,172 @@
+/* Copyright (C) 2014 by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+#ifndef STRHELP_H
+#define STRHELP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+
+/**
+ * @file  strhelp.h
+ * @brief Helper functions for c strings and memory management
+ * @details strhelp contains terminating memory allocation functions and
+ * some conveniance functions to work with c strings or arrays of c
+ * strings.
+ */
+
+/** @def To avoid that a compiler optimizes certain memset calls away */
+#define wipememory2(_ptr,_set,_len) do { \
+              volatile char *_vptr=(volatile char *)(_ptr); \
+              size_t _vlen=(_len); \
+              while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+                  } while(0)
+/** @def To avoid that a compiler optimizes certain memset calls away */
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+
+void *xmalloc( size_t n );
+/** @brief like malloc but initalizes the values with 0 */
+void *xmalloc0( size_t n );
+void *xrealloc( void *a, size_t n );
+void *xcalloc( size_t n, size_t m );
+char *xstrndup( const char *string, const size_t len );
+void xfree ( void *p );
+
+/**
+ * @brief Terminating variant of asprintf
+ *
+ * This function behaves exactly like asprintf(3) but will terminate
+ * when an error occures (usally that means that memoy allocation
+ * failed).
+ */
+int xasprintf (char **strp, const char *fmt, ...);
+
+/**
+ * @brief Returns the length of the given %NULL-terminated
+ * string array str_array.
+ * @param[in] str_array a %NULL-terminated array of strings
+ * @returns length of str_array.
+ */
+unsigned int strv_length (char **str_array);
+
+/**
+ * @brief append a string to a NULL terminated array of strings.
+ *
+ * @param[in,out] pArray pointer to the NULL terminated list of string pointers.
+ * @param[in] string pointer to the string to append to the list.
+ * @param[in] len length of the string to append to the list
+ */
+void strv_append (char ***pArray, const char *string, const size_t len);
+
+/**
+ * @brief append a string to another string.
+ *
+ * @param[in,out] pDst pointer to the string to be extended.
+ * @param[in,out] dst_len length of the dst string. Will be modified.
+ * @param[in] appendage pointer to the string to append.
+ * @param[in] len length of the string to append.
+ */
+void str_append_str (char **pDst, size_t *dst_len, const char *appendage,
+                    const size_t len);
+
+/**
+ * @brief Frees the given %NULL-terminated string array.
+ * @param[in,out] str_array a %NULL-terminated array of strings
+ */
+void strv_free (char **str_array);
+
+/**
+ * @brief Checks whether two strings exactly match
+ * @param[in] s1 the first string
+ * @param[in] s2 the second string
+ * @returns true if s1 and s2 are equal
+ */
+bool str_equal (char *s1, char *s2);
+
+/**
+ * @brief Checks whether s2 exactly matches the beginning of s1.
+ * @param[in] s1 the string who's beginning is searched
+ * @param[in] s2 the string which is searched for
+ * @returns true if s1 starts with s2, false otherwise
+ */
+bool str_starts_with (char *s1, char *s2);
+
+/**
+ * @brief Trims all white space from the start and end of string.
+ * @details the start of the string is trimmed by setting *s to the
+ * first non white space character.  The end is trimmed by setting the
+ * first character after the last non white space character to \0.
+ * @param[in,out] s ponter to the string to strip
+ */
+bool str_trim (char **s);
+
+/** @brief decode base64 encoded data
+ *
+ * The memory allocated for dest needs to be free'd by the
+ * caller.
+ *
+ * _Input warning:_
+ * If the input contains invalid base64 characters an error
+ * is returned.
+ *
+ * If the input is invalid base64 but consists of valid
+ * base64 characters _no error_ is returned and dst contains
+ * the valid input up to the error.
+ *
+ * @param [out] dst Pointer to the destination. Needs to be NULL
+ * @param [out] dst_size Size allocated for the destination.
+ * @param [in] src Pointer to the base64 encoded data.
+ * @param [in] src_size Size of the encoded data.
+ *
+ * @returns 0 on success a polarssl error or -1 otherwise
+ */
+int str_base64_decode(char **dst, size_t *dst_size, char *src,
+                      size_t src_size);
+
+#ifdef WIN32
+
+/** @brief convert a utf8 string to utf16 wchar
+ *
+ * @param[in] string utf8 string. Must be at least len characters long.
+ * @param[in] len number of characters to be converted.
+ *
+ * @returns pointer to a newly allocated wchar array. NULL on error.
+ *
+ **/
+wchar_t *utf8_to_wchar (const char *string, size_t len);
+
+/** @brief convert a local 8 bit (acp) string to utf16 wchar
+ *
+ * @param[in] string acp string. Must be at least len characters long.
+ * @param[in] len number of characters to be converted.
+ *
+ * @returns pointer to a newly allocated wchar array. NULL on error.
+ *
+ **/
+wchar_t *acp_to_wchar (const char *string, size_t len);
+
+/** @brief convert a utf16 string to utf8
+ *
+ * @param[in] string utf16 string. Must be at least len characters long.
+ * @param[in] len number of characters to be converted.
+ *
+ * @returns pointer to a newly allocated char array. NULL on error.
+ *
+ **/
+char *wchar_to_utf8 (const wchar_t *string, size_t len);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util.h	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,54 @@
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+#ifndef COMMON_UTIL_H
+#define COMMON_UTIL_H
+/* @file util.h
+ * @brief The usual useful stuff that fit nowhere else
+ */
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Get the directory in which the current process resides in
+ *
+ * Look up the directory in which the current process is placed.
+ * If the path is longer then MAX_PATH NULL is returned.
+ *
+ * Returns a utf-8 encoded string that has to be freed by the caller
+ * on linux the path is returned as is including the last /.
+ *
+ * @returns The directory of the current process
+ */
+char * get_install_dir();
+
+#ifndef WIN32
+/**@def Some value to use as equivalent as MAX_PATH on windows */
+#define MAX_PATH_LINUX 4000
+
+/**@brief Get the directory in which the process proc resides in
+ *
+ * Look up the directory in which the process proc is placed.
+ * If the path is longer then MAX_PATH NULL is returned.
+ *
+ * Returns a utf-8 encoded string that has to be freed by the caller
+ * on linux the path is returned as is including the last /.
+ *
+ * @param[in] A process id or special name from the proc file system.
+ *
+ * @returns The directory of the process
+ */
+char * get_proc_install_dir(const char *proc);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COMMON_UTIL_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util_linux.c	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,70 @@
+#ifndef WIN32
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+/**@file Linux implementation of functions declared in util.h */
+
+#include "util.h"
+#include "string.h"
+#include "strhelp.h"
+#include "unistd.h"
+#include <sys/types.h>
+#include <pwd.h>
+
+char *
+get_proc_install_dir(const char *proc)
+{
+  char *retval = NULL,
+       *procpath = NULL,
+       *p = NULL,
+        buf[MAX_PATH_LINUX];
+  ssize_t ret;
+  size_t path_len = 0;
+
+  if (!proc)
+    {
+      return NULL;
+    }
+
+  xasprintf(&procpath, "/proc/%s/exe", proc);
+
+  ret = readlink (procpath, buf, MAX_PATH_LINUX);
+  xfree(procpath);
+  procpath = NULL;
+
+  if (ret <= 0)
+    {
+      return NULL;
+    }
+
+  buf[ret] = '\0';
+
+  /* cut off the filename */
+  p = strrchr (buf, '/');
+  if (p == NULL)
+    {
+      return NULL;
+    }
+  *(p + 1) = '\0';
+
+  path_len = strlen (buf);
+  retval = xmalloc (path_len + 1);
+  strncpy (retval, buf, path_len);
+  retval[path_len] = '\0';
+
+  return retval;
+}
+
+char *
+get_install_dir()
+{
+  return get_proc_install_dir("self");
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util_win.c	Mon Mar 23 12:41:52 2015 +0100
@@ -0,0 +1,49 @@
+#ifdef WIN32
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+/**@file Linux implementation of functions declared in util.h */
+
+#include "util.h"
+#include "strhelp.h"
+
+#include <windows.h>
+
+char *
+get_install_dir()
+{
+  wchar_t wPath[MAX_PATH];
+  char *utf8path = NULL;
+  char *dirsep = NULL;
+
+  if (!GetModuleFileNameW (NULL, wPath, MAX_PATH - 1))
+    {
+      return NULL;
+    }
+
+  /* wPath might not be 0 terminated */
+  wPath[MAX_PATH - 1] = '\0';
+
+  utf8path = wchar_to_utf8 (wPath, wcsnlen(wPath, MAX_PATH));
+
+  if (utf8path == NULL)
+    {
+      return NULL;
+    }
+
+  /* Cut away the executable name */
+  dirsep = strrchr(utf8path, '\\');
+  if (dirsep == NULL)
+    {
+      return NULL;
+    }
+  *dirsep = '\0';
+  return utf8path;
+}
+#endif
+
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)