::pointer;
+ return std::less()(l.get(), nullptr);
+}
+
+template
+inline bool operator<(std::nullptr_t, const impl_ptr &p)
+{
+ using P = typename impl_ptr::pointer;
+ return std::less()(nullptr, p.get());
+}
+
+template
+inline bool operator>(const impl_ptr &p, std::nullptr_t)
+{
+ return nullptr < p;
+}
+
+template
+inline bool operator>(std::nullptr_t, const impl_ptr &p)
+{
+ return p < nullptr;
+}
+
+template
+inline bool operator<=(const impl_ptr &p, std::nullptr_t)
+{
+ return !(nullptr < p);
+}
+
+template
+inline bool operator<=(std::nullptr_t, const impl_ptr &p)
+{
+ return !(p < nullptr);
+}
+
+template
+inline bool operator>=(const impl_ptr &p, std::nullptr_t)
+{
+ return !(p < nullptr);
+}
+
+template
+inline bool operator>=(std::nullptr_t, const impl_ptr &p)
+{
+ return !(nullptr < p);
+}
+
+
+template
+inline impl_ptr make_impl(Args &&... args)
+{
+ return impl_ptr(new T(std::forward(args)...), &details::default_delete,
+ &details::default_copy);
+}
+
+
+// Helpers to manage unique impl, stored in std::unique_ptr
+
+template
+using unique_impl_ptr = std::unique_ptr;
+
+template
+inline unique_impl_ptr make_unique_impl(Args &&... args)
+{
+ static_assert(!std::is_array::value, "unique_impl_ptr does not support arrays");
+ return unique_impl_ptr(new T(std::forward(args)...), &details::default_delete);
+}
+}
+
+namespace std {
+template
+struct hash > {
+ using argument_type = spimpl::impl_ptr;
+ using result_type = size_t;
+
+ result_type operator()(const argument_type &p) const SPIMPL_NOEXCEPT
+ {
+ return hash()(p.get());
+ }
+};
+}
+
+#endif // SPIMPL_H_
diff --git a/core/include/DataSource/DataSourceController.h b/core/include/DataSource/DataSourceController.h
new file mode 100644
index 0000000..94e9d7f
--- /dev/null
+++ b/core/include/DataSource/DataSourceController.h
@@ -0,0 +1,39 @@
+#ifndef SCIQLOP_DATASOURCECONTROLLER_H
+#define SCIQLOP_DATASOURCECONTROLLER_H
+
+#include "DataSourceController.h"
+
+#include
+#include
+
+#include
+
+Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
+
+/**
+ * @brief The DataSourceController class aims to make the link between SciQlop
+ * and its plugins. This is the intermediate class that SciQlop have to use
+ * in the way to connect a data source. Please first use load method to intialize
+ * a plugin specified by its metadata name (JSON plugin source) then others specifics
+ * method will ba able to access it.
+ * You can load a data source driver plugin then create a data source.
+ */
+class DataSourceController : public QObject {
+ Q_OBJECT
+public:
+ explicit DataSourceController(QObject *parent = 0);
+ virtual ~DataSourceController();
+
+public slots:
+ /// Manage init/end of the controller
+ void initialize();
+ void finalize();
+
+private:
+ void waitForFinish();
+
+ class DataSourceControllerPrivate;
+ spimpl::unique_impl_ptr impl;
+};
+
+#endif // SCIQLOP_DATASOURCECONTROLLER_H
diff --git a/core/resources/Version.cpp.in b/core/resources/Version.cpp.in
new file mode 100644
index 0000000..2a27649
--- /dev/null
+++ b/core/resources/Version.cpp.in
@@ -0,0 +1,78 @@
+#include "Version.h"
+
+/***************************************************
+ * @SCIQLOP_CMAKE_GENERATION_WARNING@ *
+ ***************************************************/
+
+#include
+#include
+
+namespace sciqlop {
+
+const char *Version::VERSION_SUFFIX = "@SCIQLOP_VERSION_SUFFIX@";
+
+/**
+ * From the C99 standard:
+ * __DATE__: The date of translation of the preprocessing translation unit:
+ * a character string literal of the form "Mmm dd yyyy", where the names of
+ * the months are the same as those generated by the asctime function, and
+ * the first character of dd is a space character if the value is less than
+ * 10. If the date of translation is not available, an
+ * implementation-defined valid date shall be supplied.
+ */
+const char *Version::BUILD_DATE = __DATE__;
+/**
+ * From the C99 standard:
+ * __TIME__: The time of translation of the preprocessing translation unit:
+ * a character string literal of the form "hh:mm:ss" as in the time
+ * generated by the asctime function. If the time of translation is not
+ * available, an implementation-defined valid time shall be supplied.
+ */
+const char *Version::BUILD_TIME = __TIME__;
+
+QDateTime Version::buildDateTime()
+{
+ static QDateTime buildDateTime;
+ if (!buildDateTime.isValid()) {
+ // Convert BUILD_DATE to a QDate
+ // The __DATE__ macro return the month name with the asctime() function,
+ // which doesn't support localization, the month names returned are
+ // always the same. On the contrary, the "MMM" format on
+ // QDate::fromString() is localized, so this method can't be used to
+ // retrieve the month and we must manually do it instead.
+ QString buildDateStr = QString(BUILD_DATE);
+ QString buildMonthStr = buildDateStr.left(3);
+ QString buildDayAndYearStr = buildDateStr.mid(4).trimmed();
+
+ QDate buildDate = QDate::fromString(buildDayAndYearStr, "d yyyy");
+ QStringList monthList = QStringList() << "Jan"
+ << "Feb"
+ << "Mar"
+ << "Apr"
+ << "May"
+ << "Jun"
+ << "Jul"
+ << "Aug"
+ << "Sep"
+ << "Oct"
+ << "Nov"
+ << "Dec";
+ for (int i = 0; i < monthList.size(); ++i) {
+ if (buildMonthStr == monthList.at(i)) {
+ buildDate.setDate(buildDate.year(), i + 1, buildDate.day());
+ break;
+ }
+ }
+
+ // Convert BUILD_TIME to a QTime
+ QTime buildTime = QTime::fromString(BUILD_TIME, "hh:mm:ss");
+
+ // Set the buildDateTime
+ buildDateTime.setDate(buildDate);
+ buildDateTime.setTime(buildTime);
+ }
+
+ return buildDateTime;
+}
+
+} // namespace sciqlop
diff --git a/core/resources/Version.h.in b/core/resources/Version.h.in
new file mode 100644
index 0000000..cf7a260
--- /dev/null
+++ b/core/resources/Version.h.in
@@ -0,0 +1,98 @@
+// TODO copyright
+/**
+ * @file Version.h
+ */
+#ifndef SCIQLOP_VERSION_H
+#define SCIQLOP_VERSION_H
+
+/***************************************************
+ * @SCIQLOP_CMAKE_GENERATION_WARNING@ *
+ ***************************************************/
+
+//#include "SciqlopExport.h"
+#include
+
+class QDateTime;
+
+namespace sciqlop {
+
+/**
+ * Holds the version of Sciqlop.
+ *
+ * @attention Don't update this class directly, it is generated from the
+ * `resources/Version.h.in` and `resources/Version.cpp.in` files, along with
+ * the cmake variables defined in the `cmake/sciqlop_version.cmake` file.
+ *
+ * To change the Sciqlop version number, update the `cmake/sciqlop_version.cmake`
+ * file, and to change this class other than to change the version number,
+ * update the `resources/Version.h.in` and `resources/Version.cpp.in` files.
+ * @ingroup Utils
+ */
+class /*SCIQLOP_API*/ Version {
+public:
+ /**
+ * Retrieve the version of Sciqlop.
+ *
+ * The version is of the form MAJOR.MINOR.PATCH. If a suffix has been
+ * provided to the version, it is appended after the PATCH.
+ *
+ * The version can be modified by updating the cmake/sciqlop_version.cmake
+ * file.
+ *
+ * @return The version of Sciqlop as a QString.
+ */
+ static QString version()
+ {
+ static const QString v("@SCIQLOP_VERSION@");
+ return v;
+ }
+
+ /**
+ * @return The datetime of the build.
+ */
+ static QDateTime buildDateTime();
+
+ /**
+ * Major version.
+ */
+ static const int VERSION_MAJOR = @SCIQLOP_VERSION_MAJOR@;
+ /**
+ * Minor version.
+ */
+ static const int VERSION_MINOR = @SCIQLOP_VERSION_MINOR@;
+ /**
+ * Patch version.
+ */
+ static const int VERSION_PATCH = @SCIQLOP_VERSION_PATCH@;
+ /**
+ * Suffix version.
+ */
+ static const char *VERSION_SUFFIX;
+
+ /**
+ * Compile date computed with the __DATE__ macro.
+ *
+ * From the C99 standard:
+ * __DATE__: The date of translation of the preprocessing translation unit:
+ * a character string literal of the form "Mmm dd yyyy", where the names of
+ * the months are the same as those generated by the asctime function, and
+ * the first character of dd is a space character if the value is less than
+ * 10. If the date of translation is not available, an
+ * implementation-defined valid date shall be supplied.
+ */
+ static const char *BUILD_DATE;
+ /**
+ * Compile time computed with the __TIME__ macro.
+ *
+ * From the C99 standard:
+ * __TIME__: The time of translation of the preprocessing translation unit:
+ * a character string literal of the form "hh:mm:ss" as in the time
+ * generated by the asctime function. If the time of translation is not
+ * available, an implementation-defined valid time shall be supplied.
+ */
+ static const char *BUILD_TIME;
+};
+
+} // namespace sciqlop
+
+#endif // SCIQLOP_VERSION_H
diff --git a/core/src/DataSource/DataSourceController.cpp b/core/src/DataSource/DataSourceController.cpp
new file mode 100644
index 0000000..2a330b8
--- /dev/null
+++ b/core/src/DataSource/DataSourceController.cpp
@@ -0,0 +1,47 @@
+#include "DataSource/DataSourceController.h"
+
+#include
+#include
+
+Q_LOGGING_CATEGORY(LOG_DataSourceController, "dataSourceController")
+
+class DataSourceController::DataSourceControllerPrivate {
+public:
+ DataSourceControllerPrivate() {}
+
+
+ QMutex m_WorkingMutex;
+};
+
+DataSourceController::DataSourceController(QObject *parent)
+ : impl{spimpl::make_unique_impl()}
+{
+ qCInfo(LOG_DataSourceController()) << tr("Construction du DataSourceController");
+}
+
+DataSourceController::~DataSourceController()
+{
+ // delete impl;
+ this->waitForFinish();
+}
+
+void DataSourceController::initialize()
+{
+ qCInfo(LOG_DataSourceController()) << tr("initialize du DataSourceController");
+ impl->m_WorkingMutex.lock();
+ qCInfo(LOG_DataSourceController()) << tr("initialize du DataSourceController END");
+}
+
+void DataSourceController::finalize()
+{
+ qCInfo(LOG_DataSourceController()) << tr("finalize du DataSourceController");
+ impl->m_WorkingMutex.unlock();
+ qCInfo(LOG_DataSourceController()) << tr("finalize du DataSourceController END");
+}
+
+void DataSourceController::waitForFinish()
+{
+ qCInfo(LOG_DataSourceController()) << tr("waitForFinish du DataSourceController");
+ QMutexLocker locker(&impl->m_WorkingMutex);
+ qCInfo(LOG_DataSourceController()) << tr("waitForFinish du DataSourceController END");
+}
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt
new file mode 100644
index 0000000..117e771
--- /dev/null
+++ b/gui/CMakeLists.txt
@@ -0,0 +1,159 @@
+
+## gui - CMakeLists.txt
+STRING(TOLOWER ${CMAKE_PROJECT_NAME} LIBRARY_PREFFIX)
+SET(SQPGUI_LIBRARY_NAME "${LIBRARY_PREFFIX}_gui${DEBUG_SUFFIX}")
+SET(SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
+SET(INCLUDES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
+SET(UI_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/ui")
+SET(RES_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/resources")
+
+# Include gui directory
+include_directories("${INCLUDES_DIR}")
+include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+
+# Set a variable to display a warning in the version files.
+SET(SCIQLOP_CMAKE_GENERATION_WARNING "DON'T CHANGE THIS FILE. AUTOGENERATED BY CMAKE.")
+
+#
+# Find Qt modules
+#
+SCIQLOP_FIND_QT(Core Widgets)
+
+#
+# Find dependent libraries
+# ========================
+find_package(sciqlop-core)
+
+message("Librairies inclues dans APP: ${SCIQLOP-CORE_LIBRARIES}")
+SET(LIBRARIES ${SCIQLOP-CORE_LIBRARIES})
+
+INCLUDE_DIRECTORIES(${SCIQLOP-CORE_INCLUDE_DIR})
+
+# Add sqpcore to the list of libraries to use
+list(APPEND LIBRARIES ${SQPCORE_LIBRARY_NAME})
+
+# Add dependent shared libraries
+list(APPEND SHARED_LIBRARIES ${SQPCORE_SHARED_LIBRARIES})
+
+
+# Ui files
+FILE (GLOB_RECURSE PROJECT_FORMS ${UI_FOLDER}/*.ui)
+
+# Resources files
+FILE (GLOB_RECURSE PROJECT_RESOURCES ${RES_FOLDER}/*.qrc)
+
+#
+# Compile the library library
+#
+FILE (GLOB_RECURSE MODULE_SOURCES
+ ${INCLUDES_DIR}/*.h
+ ${SOURCES_DIR}/*.c
+ ${SOURCES_DIR}/*.cpp
+ ${SOURCES_DIR}/*.h
+ ${PROJECT_FORMS})
+
+QT5_ADD_RESOURCES(RCC_HDRS
+ ${PROJECT_RESOURCES}
+)
+
+QT5_WRAP_UI(UIS_HDRS
+ ${PROJECT_FORMS}
+)
+
+
+ADD_LIBRARY(${SQPGUI_LIBRARY_NAME} ${MODULE_SOURCES} ${UIS_HDRS} ${RCC_HDRS})
+set_property(TARGET ${SQPGUI_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
+set_property(TARGET ${SQPGUI_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
+
+TARGET_LINK_LIBRARIES(${SQPGUI_LIBRARY_NAME} ${LIBRARIES})
+qt5_use_modules(${SQPGUI_LIBRARY_NAME} Core Widgets)
+
+# From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
+# Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
+# The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
+IF(BUILD_SHARED_LIBS)
+ SET_TARGET_PROPERTIES(${SQPGUI_LIBRARY_NAME} PROPERTIES COMPILE_DEFINITIONS "SCIQLOP_EXPORT")
+ELSE()
+ TARGET_COMPILE_DEFINITIONS(${SQPGUI_LIBRARY_NAME} PUBLIC "SCIQLOP_STATIC_LIBRARIES")
+ENDIF()
+
+# Set the variable to parent scope so that the other projects can copy the
+# dependent shared libraries
+SCIQLOP_SET_TO_PARENT_SCOPE(SQPGUI_LIBRARY_NAME)
+
+# Copy extern shared libraries to the lib folder
+SCIQLOP_COPY_TO_TARGET(LIBRARY ${SQPGUI_LIBRARY_NAME})
+
+# Add the files to the list of files to be analyzed
+LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
+SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_INPUT_FILES)
+# Vera++ exclusion files
+#LIST(APPEND CHECKSTYLE_EXCLUSION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/path/to/exclusionFiles.tcl)
+SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_EXCLUSION_FILES)
+
+#
+# Compile the tests
+#
+IF(BUILD_TESTS)
+ INCLUDE_DIRECTORIES(${SOURCES_DIR})
+ FILE (GLOB_RECURSE TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Test*.cpp)
+ FILE (GLOB_RECURSE TESTS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Test*.h)
+ SET( TEST_LIBRARIES ${SQPGUI_LIBRARY_NAME})
+
+ FOREACH( testFile ${TESTS_SOURCES} )
+ GET_FILENAME_COMPONENT( testDirectory ${testFile} DIRECTORY )
+ GET_FILENAME_COMPONENT( testName ${testFile} NAME_WE )
+
+ # Add to the list of sources files all the sources in the same
+ # directory that aren't another test
+ FILE (GLOB currentTestSources
+ ${testDirectory}/*.c
+ ${testDirectory}/*.cpp
+ ${testDirectory}/*.h)
+ LIST (REMOVE_ITEM currentTestSources ${TESTS_SOURCES})
+ LIST (REMOVE_ITEM currentTestSources ${TESTS_HEADERS})
+
+ ADD_EXECUTABLE(${testName} ${testFile} ${currentTestSources})
+ TARGET_LINK_LIBRARIES( ${testName} ${TEST_LIBRARIES} )
+ qt5_use_modules(${testName} Test)
+
+ ADD_TEST( NAME ${testName} COMMAND ${testName} )
+
+ SCIQLOP_COPY_TO_TARGET(RUNTIME ${testName} ${EXTERN_SHARED_LIBRARIES})
+ ENDFOREACH( testFile )
+
+ LIST(APPEND testFilesToFormat ${TESTS_SOURCES})
+ LIST(APPEND testFilesToFormat ${TESTS_HEADERS})
+ LIST(APPEND FORMATTING_INPUT_FILES ${testFilesToFormat})
+ SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
+ENDIF(BUILD_TESTS)
+
+#
+# Set the files that must be formatted by clang-format.
+#
+LIST (APPEND FORMATTING_INPUT_FILES ${MODULE_SOURCES})
+SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
+
+#
+# Set the directories that doxygen must browse to generate the
+# documentation.
+#
+# Source directories:
+LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/docs")
+LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
+SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_INPUT_DIRS)
+# Source directories to exclude from the documentation generation
+#LIST (APPEND DOXYGEN_EXCLUDE_PATTERNS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir/*")
+SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_EXCLUDE_PATTERNS)
+
+#
+# Set the directories with the sources to analyze and propagate the
+# modification to the parent scope
+#
+# Source directories to analyze:
+LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
+LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/tests")
+SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_INPUT_DIRS)
+# Source directories to exclude from the analysis
+#LIST (APPEND ANALYSIS_EXCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir")
+SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_EXCLUDE_DIRS)
diff --git a/gui/cmake/Findsciqlop-gui.cmake b/gui/cmake/Findsciqlop-gui.cmake
new file mode 100755
index 0000000..890f96f
--- /dev/null
+++ b/gui/cmake/Findsciqlop-gui.cmake
@@ -0,0 +1,21 @@
+# - Try to find sciqlop-gui
+# Once done this will define
+# SCIQLOP-GUI_FOUND - System has sciqlop-gui
+# SCIQLOP-GUI_INCLUDE_DIR - The sciqlop-gui include directories
+# SCIQLOP-GUI_LIBRARIES - The libraries needed to use sciqlop-gui
+
+if(SCIQLOP-GUI_FOUND)
+ return()
+endif(SCIQLOP-GUI_FOUND)
+
+set(SCIQLOP-GUI_INCLUDE_DIR ${sciqlop-gui_DIR}/../include)
+
+set (OS_LIB_EXTENSION "so")
+
+if(WIN32)
+ set (OS_LIB_EXTENSION "dll")
+endif(WIN32)
+# TODO: Add Mac Support
+set(SCIQLOP-GUI_LIBRARIES ${LIBRARY_OUTPUT_PATH}/libsciqlop_gui${DEBUG_SUFFIX}.${OS_LIB_EXTENSION})
+
+set(SCIQLOP-GUI_FOUND TRUE)
diff --git a/gui/include/SqpApplication.h b/gui/include/SqpApplication.h
new file mode 100644
index 0000000..7114ca5
--- /dev/null
+++ b/gui/include/SqpApplication.h
@@ -0,0 +1,33 @@
+#ifndef SCIQLOP_SQPAPPLICATION_H
+#define SCIQLOP_SQPAPPLICATION_H
+
+#include "SqpApplication.h"
+
+#include
+#include
+
+#include
+
+Q_DECLARE_LOGGING_CATEGORY(LOG_SqpApplication)
+
+/**
+ * @brief The SqpApplication class aims to make the link between SciQlop
+ * and its plugins. This is the intermediate class that SciQlop have to use
+ * in the way to connect a data source. Please first use load method to intialize
+ * a plugin specified by its metadata name (JSON plugin source) then others specifics
+ * method will ba able to access it.
+ * You can load a data source driver plugin then create a data source.
+ */
+class SqpApplication : public QApplication {
+ Q_OBJECT
+public:
+ explicit SqpApplication(int &argc, char **argv);
+ virtual ~SqpApplication();
+ void initialize();
+
+private:
+ class SqpApplicationPrivate;
+ spimpl::unique_impl_ptr impl;
+};
+
+#endif // SCIQLOP_SQPAPPLICATION_H
diff --git a/gui/src/SqpApplication.cpp b/gui/src/SqpApplication.cpp
new file mode 100644
index 0000000..3bfa138
--- /dev/null
+++ b/gui/src/SqpApplication.cpp
@@ -0,0 +1,40 @@
+#include "SqpApplication.h"
+
+#include
+#include
+
+Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
+
+class SqpApplication::SqpApplicationPrivate {
+public:
+ SqpApplicationPrivate() {}
+
+ std::unique_ptr m_DataSourceController;
+ QThread m_DataSourceControllerThread;
+};
+
+
+SqpApplication::SqpApplication(int &argc, char **argv)
+ : QApplication(argc, argv), impl{spimpl::make_unique_impl()}
+{
+ qCInfo(LOG_SqpApplication()) << tr("Construction du SqpApplication");
+
+ impl->m_DataSourceController = std::make_unique();
+ impl->m_DataSourceController->moveToThread(&impl->m_DataSourceControllerThread);
+
+ connect(&impl->m_DataSourceControllerThread, &QThread::started,
+ impl->m_DataSourceController.get(), &DataSourceController::initialize);
+ connect(&impl->m_DataSourceControllerThread, &QThread::finished,
+ impl->m_DataSourceController.get(), &DataSourceController::finalize);
+
+ impl->m_DataSourceControllerThread.start();
+}
+
+SqpApplication::~SqpApplication()
+{
+ impl->m_DataSourceControllerThread.quit();
+}
+
+void SqpApplication::initialize()
+{
+}