##// END OF EJS Templates
Started PySide2 migration, builds with CMake and produces a working binary...
jeandet -
r1477:70de8bd3d575
parent child
Show More
@@ -0,0 +1,79
1 find_package(PythonLibs 3 REQUIRED)
2 find_package(PythonInterp 3 REQUIRED)
3 find_package(PySide2 REQUIRED)
4 find_package(Shiboken2 REQUIRED)
5 include(PythonInfo)
6 find_python_site_packages(PYTHON_SITE_PACKAGES)
7
8 set(BINDINGS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
9 set(BINDINGS_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
10
11 configure_file("${BINDINGS_SRC_DIR}/bindings.xml" "${BINDINGS_BUILD_DIR}/bindings.xml" COPYONLY)
12 configure_file("${BINDINGS_SRC_DIR}/main.py" "${BINDINGS_BUILD_DIR}/main.py" COPYONLY)
13
14 execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${BINDINGS_SRC_DIR}/src_list.py" cmake "${BINDINGS_BUILD_DIR}" OUTPUT_VARIABLE BINDINGS_SOURCE)
15
16 set_property(SOURCE ${BINDINGS_SOURCE} PROPERTY SKIP_AUTOGEN ON)
17
18 list(APPEND BINDINGS_INCLUDE_DIRS
19 ${PYTHON_INCLUDE_DIRS}
20 ${Qt5Core_INCLUDE_DIRS}
21 ${Qt5Widgets_INCLUDE_DIRS}
22 ${Qt5Gui_INCLUDE_DIRS}
23 ${CMAKE_CURRENT_SOURCE_DIR}/../../gui/include
24 ${CMAKE_CURRENT_SOURCE_DIR}/../../core/include
25 ${CMAKE_CURRENT_SOURCE_DIR}/../../core/external/TimeSeries/include
26 )
27 list(REMOVE_DUPLICATES BINDINGS_INCLUDE_DIRS)
28 foreach(DIR ${BINDINGS_INCLUDE_DIRS})
29 list(APPEND BINDINGS_INCLUDE_DIRS_ARGS "-I${DIR}")
30 endforeach()
31
32 set(SHIBOKEN_OPTIONS --generator-set=shiboken
33 --enable-parent-ctor-heuristic
34 --enable-return-value-heuristic
35 --use-isnull-as-nb_nonzero
36 --avoid-protected-hack
37 --enable-pyside-extensions
38 -std=c++17)
39 add_custom_command(
40 OUTPUT ${BINDINGS_SOURCE}
41 COMMAND Shiboken2::shiboken2 ${SHIBOKEN_OPTIONS}
42 ${BINDINGS_INCLUDE_DIRS_ARGS}
43 --typesystem-paths=${PYSIDE_TYPESYSTEMS}
44 --output-directory=${CMAKE_CURRENT_BINARY_DIR}
45 ${CMAKE_CURRENT_SOURCE_DIR}/bindings.h ${CMAKE_CURRENT_SOURCE_DIR}/bindings.xml
46
47 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/bindings.xml"
48 IMPLICIT_DEPENDS CXX "${CMAKE_CURRENT_SOURCE_DIR}/bindings.h"
49 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
50 COMMENT "Generating Python bindings with shiboken2")
51
52 include_directories(
53 ${PYSIDE_INCLUDE_DIR}/QtCore
54 ${PYSIDE_INCLUDE_DIR}/QtGui
55 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
56
57 include_directories(
58 ${PYTHON_SITE_PACKAGES}/numpy/core/include/
59 ${PYTHON_INCLUDE_DIRS}
60 ${SHIBOKEN_INCLUDE_DIR}
61 ${PYSIDE_INCLUDE_DIR}
62 ${PYSIDE_INCLUDE_DIR}/QtCore
63 ${PYSIDE_INCLUDE_DIR}/QtGui
64 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
65
66 add_library(SciQLopBindings MODULE ${BINDINGS_SOURCE} numpy_wrappers.h)
67 set_target_properties(
68 SciQLopBindings
69 PROPERTIES
70 PREFIX ""
71 OUTPUT_NAME "SciQLopBindings"
72 )
73 target_link_libraries(SciQLopBindings sciqlopapp)
74 target_link_libraries(SciQLopBindings Shiboken2::libshiboken)
75 target_link_libraries(SciQLopBindings PySide2::pyside2)
76
77 add_executable(debug_sciqlop_app main.cpp )
78 find_package (Python3 COMPONENTS Development)
79 target_link_libraries(debug_sciqlop_app PRIVATE Python3::Python)
@@ -0,0 +1,16
1 #pragma once
2 #include <Data/IDataProvider.h>
3
4 class PyDataProvider : public IDataProvider
5 {
6 public:
7 PyDataProvider() {}
8
9 virtual TimeSeries::ITimeSerie getData(const std::string& key, double start_time, double stop_time)
10 {}
11
12 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters)
13 {
14 return nullptr;
15 }
16 };
@@ -0,0 +1,12
1 #ifndef SCIQLOP_BINDINGS_H
2 #define SCIQLOP_BINDINGS_H
3 #define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a)))
4 #include "../include/MainWindow.h"
5 #include "PyDataProvider.h"
6 #include "numpy_wrappers.h"
7 #include <Data/IDataProvider.h>
8 #include <Data/ScalarTimeSerie.h>
9 #include <SqpApplication.h>
10
11
12 #endif // SCIQLOP_BINDINGS_H
@@ -0,0 +1,72
1 <?xml version="1.0"?>
2 <typesystem package="SciQLopBindings">
3 <load-typesystem name="typesystem_core.xml" generate="no" />
4 <load-typesystem name="typesystem_gui.xml" generate="no" />
5 <load-typesystem name="typesystem_widgets.xml" generate="no" />
6 <primitive-type name="std::string"/>
7 <primitive-type name="std::size_t"/>
8 <container-type name="std::vector" type="vector">
9 <include file-name="vector" location="global"/>
10 <conversion-rule>
11 <native-to-target>
12 %INTYPE::size_type vectorSize = %in.size();
13 PyObject* %out = PyList_New((int) vectorSize);
14 for (%INTYPE::size_type idx = 0; idx &lt; vectorSize; ++idx) {
15 %INTYPE_0 cppItem(%in[idx]);
16 PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
17 }
18 return %out;
19 </native-to-target>
20 <target-to-native>
21 <add-conversion type="PySequence">
22 Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
23 int vectorSize = PySequence_Fast_GET_SIZE(seq.object());
24 %out.reserve(vectorSize);
25 for (int idx = 0; idx &lt; vectorSize; ++idx ) {
26 PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), idx);
27 %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
28 %out.push_back(cppItem);
29 }
30 </add-conversion>
31 </target-to-native>
32 </conversion-rule>
33 </container-type>
34 <object-type name="MainWindow" />
35 <object-type name="SqpApplication">
36 <modify-function signature="SqpApplication(int&amp;,char**)" access="private"/>
37 </object-type>
38 <object-type name="PyDataProvider" />
39 <function signature="SqpApplication_ctor()"/>
40 <function signature="init_resources()"/>
41 <primitive-type name="NpArray" target-lang-api-name="PyObject">
42 <include file-name="numpy_wrappers.h" location="local"/>
43 <conversion-rule>
44 <native-to-target>
45 return %in.py_object();
46 </native-to-target>
47 <target-to-native>
48 <add-conversion type="PyObject" check="NpArray::isNpArray(%in)">
49 %out = %OUTTYPE(%in);
50 </add-conversion>
51 </target-to-native>
52 </conversion-rule>
53 </primitive-type>
54 <function signature="load_plugins(const SqpApplication&amp;)"/>
55 <object-type name="ScalarTimeSerie">
56 <add-function signature="ScalarTimeSerie(NpArray&amp;,NpArray&amp;)" return-type="ScalarTimeSerie">
57 <inject-code class="target">
58 %BEGIN_ALLOW_THREADS
59 %0 = new ScalarTimeSerieWrapper();
60 %0.set_data(%1.to_std_vect(),%2.to_std_vect());
61 %END_ALLOW_THREADS
62 </inject-code>
63 </add-function>
64 <add-function signature="size()" return-type="int" access="public" static="no">
65 <inject-code class="target">
66 %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
67 %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
68 </inject-code>
69 </add-function>
70 </object-type>
71 <function signature="test_np_array(NpArray&amp;)"/>
72 </typesystem>
@@ -0,0 +1,26
1 #include <fstream>
2 #include <iostream>
3 #define PY_SSIZE_T_CLEAN
4 #define Py_DEBUG
5 #include <Python.h>
6
7 int main(int argc, char** argv)
8 {
9 wchar_t* program = Py_DecodeLocale(argv[0], NULL);
10 if (program == NULL)
11 {
12 fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
13 exit(1);
14 }
15 Py_SetProgramName(program); /* optional but recommended */
16 Py_Initialize();
17 std::ifstream t(argv[1]);
18 std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
19 PyRun_SimpleString(str.data());
20 if (Py_FinalizeEx() < 0)
21 {
22 exit(120);
23 }
24 PyMem_RawFree(program);
25 return 0;
26 }
@@ -0,0 +1,102
1 # This Python file uses the following encoding: utf-8
2 import os
3 print(os.getcwd())
4 import sys
5 from PySide2.QtWidgets import QApplication, QMainWindow, QDockWidget
6 from PySide2.QtCore import QSize, Qt
7 from PySide2 import QtGui
8 import os
9 from SciQLopBindings import SqpApplication, MainWindow, init_resources, load_plugins, SqpApplication_ctor
10 from qtconsole.rich_ipython_widget import RichJupyterWidget
11 from qtconsole.inprocess import QtInProcessKernelManager
12
13
14 class IPythonWidget(RichJupyterWidget):
15 """Live IPython console widget.
16
17 .. image:: img/IPythonWidget.png
18
19 :param custom_banner: Custom welcome message to be printed at the top of
20 the console.
21 """
22
23 def __init__(self, parent=None, custom_banner=None, *args, **kwargs):
24 if parent is not None:
25 kwargs["parent"] = parent
26 super(IPythonWidget, self).__init__(*args, **kwargs)
27 if custom_banner is not None:
28 self.banner = custom_banner
29 self.setWindowTitle(self.banner)
30 self.kernel_manager = kernel_manager = QtInProcessKernelManager()
31 kernel_manager.start_kernel()
32 self.kernel_client = kernel_client = self._kernel_manager.client()
33 kernel_client.start_channels()
34
35 def stop():
36 kernel_client.stop_channels()
37 kernel_manager.shutdown_kernel()
38 self.exit_requested.connect(stop)
39
40 def sizeHint(self):
41 """Return a reasonable default size for usage in :class:`PlotWindow`"""
42 return QSize(500, 300)
43
44 def pushVariables(self, variable_dict):
45 """ Given a dictionary containing name / value pairs, push those
46 variables to the IPython console widget.
47
48 :param variable_dict: Dictionary of variables to be pushed to the
49 console's interactive namespace (```{variable_name: object, …}```)
50 """
51 self.kernel_manager.kernel.shell.push(variable_dict)
52
53
54 class IPythonDockWidget(QDockWidget):
55 """Dock Widget including a :class:`IPythonWidget` inside
56 a vertical layout.
57
58 .. image:: img/IPythonDockWidget.png
59
60 :param available_vars: Dictionary of variables to be pushed to the
61 console's interactive namespace: ``{"variable_name": object, …}``
62 :param custom_banner: Custom welcome message to be printed at the top of
63 the console
64 :param title: Dock widget title
65 :param parent: Parent :class:`qt.QMainWindow` containing this
66 :class:`qt.QDockWidget`
67 """
68 def __init__(self, parent=None, available_vars=None, custom_banner=None,
69 title="Console"):
70 super(IPythonDockWidget, self).__init__(title, parent)
71
72 self.ipyconsole = IPythonWidget(custom_banner=custom_banner)
73
74 self.layout().setContentsMargins(0, 0, 0, 0)
75 self.setWidget(self.ipyconsole)
76
77 if available_vars is not None:
78 self.ipyconsole.pushVariables(available_vars)
79 self.ipyconsole.pushVariables({"blah":self})
80
81 def showEvent(self, event):
82 """Make sure this widget is raised when it is shown
83 (when it is first created as a tab in PlotWindow or when it is shown
84 again after hiding).
85 """
86 self.raise_()
87
88 def print_process_id():
89 print ('Process ID is:', os.getpid())
90
91
92 if __name__ == "__main__":
93 init_resources()
94 app = SqpApplication_ctor()
95 QtGui.qApp = app
96 load_plugins(app)
97 main_window = MainWindow()
98 term = IPythonDockWidget(available_vars={"app":app, "main_window":main_window}, custom_banner="SciQLop IPython Console ")
99 main_window.addDockWidget(Qt.BottomDockWidgetArea, term)
100 main_window.show()
101 sys.exit(app.exec_())
102
@@ -0,0 +1,19
1 #include "numpy_wrappers.h"
2
3 // ScalarTimeSerie ScalarTimeSerie_from_np(PyObject* time, PyObject* values)
4 //{
5 // assert(time);
6 // assert(values);
7 // assert(PyArray_NDIM(time) == 1);
8 // assert(PyArray_NDIM(values) == 1);
9 // assert(PyArray_ISFLOAT(time));
10 // assert(PyArray_ISFLOAT(values));
11 // assert(PyArray_DIM(time, 0) == PyArray_DIM(values, 0));
12 // assert(PyArray_IS_C_CONTIGUOUS(time));
13 // assert(PyArray_IS_C_CONTIGUOUS(values));
14 // int size = PyArray_DIM(time, 0);
15 // ScalarTimeSerie ts(size);
16 // for (int i = 0; i < size; i++)
17 // {
18 // }
19 //}
@@ -0,0 +1,178
1 #ifndef NUMPY_WRAPPERS_H
2 #define NUMPY_WRAPPERS_H
3 #include <Data/ScalarTimeSerie.h>
4 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
5 #if defined(slots) && (defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__))
6 #pragma push_macro("slots")
7 #undef slots
8 extern "C"
9 {
10 /*
11 * Python 2 uses the "register" keyword, which is deprecated in C++ 11
12 * and forbidden in C++17.
13 */
14 #if defined(__clang__)
15 #pragma clang diagnostic push
16 #pragma clang diagnostic ignored "-Wdeprecated-register"
17 #endif
18
19 #include <Python.h>
20 #include <numpy/arrayobject.h>
21
22 #if defined(__clang__)
23 #pragma clang diagnostic pop
24 #endif
25 }
26 #else
27 #include <Python.h>
28 #include <numpy/arrayobject.h>
29 #endif
30 #include <assert.h>
31
32 inline int init_numpy()
33 {
34 import_array(); // PyError if not successful
35 return 0;
36 }
37 const static int numpy_initialized = init_numpy();
38 template <typename dest_type = PyObject>
39 struct PyObjectWrapper
40 {
41 private:
42 PyObject* _py_obj;
43
44 void inc_refcount()
45 {
46 if (_py_obj)
47 Py_IncRef(_py_obj);
48 }
49 void dec_refcount()
50 {
51 if (_py_obj)
52 Py_DecRef(_py_obj);
53 }
54
55 public:
56 PyObjectWrapper() : _py_obj { nullptr } {}
57 PyObjectWrapper(const PyObjectWrapper& other) : _py_obj { other._py_obj } { inc_refcount(); };
58 PyObjectWrapper(PyObjectWrapper&& other) : _py_obj { other._py_obj }
59 {
60 other._py_obj = nullptr;
61 }
62 PyObjectWrapper(PyObject* obj) : _py_obj { obj } { inc_refcount(); }
63 ~PyObjectWrapper() { dec_refcount(); }
64 PyObjectWrapper& operator=(PyObjectWrapper&& other)
65 {
66 this->_py_obj = other._py_obj;
67 other._py_obj = nullptr;
68 return *this;
69 }
70 PyObjectWrapper& operator=(const PyObjectWrapper& other)
71 {
72 dec_refcount();
73 this->_py_obj = other._py_obj;
74 inc_refcount();
75 return *this;
76 }
77
78 PyObject* py_object() { return _py_obj; }
79 inline dest_type* get() { return reinterpret_cast<dest_type*>(_py_obj); }
80 inline bool is_null() { return _py_obj == nullptr; }
81 };
82
83 struct NpArray
84 {
85 private:
86 PyObjectWrapper<PyArrayObject> _py_obj;
87 NpArray(NpArray& other) = delete;
88 NpArray(const NpArray& other) = delete;
89 NpArray(const NpArray&& other) = delete;
90
91 public:
92 static bool isNpArray(PyObject* obj)
93 {
94 return obj && PyArray_Check(reinterpret_cast<PyArrayObject*>(obj))
95 && PyArray_IS_C_CONTIGUOUS(reinterpret_cast<PyArrayObject*>(obj));
96 }
97 NpArray() : _py_obj { nullptr } {}
98 NpArray(NpArray&& other) : _py_obj { std::move(other._py_obj) } {}
99 explicit NpArray(PyObject* obj) : _py_obj { obj }
100 {
101 std::cout << "NpArray ctor" << std::endl;
102 assert(isNpArray(obj));
103 assert(PyArray_ISFLOAT(_py_obj.get()));
104 }
105
106 NpArray& operator=(const NpArray& other)
107 {
108 this->_py_obj = other._py_obj;
109 return *this;
110 }
111
112 NpArray& operator=(NpArray&& other)
113 {
114 this->_py_obj = std::move(other._py_obj);
115 return *this;
116 }
117
118 std::vector<std::size_t> shape()
119 {
120 std::vector<std::size_t> shape;
121 if (!_py_obj.is_null())
122 {
123 if (int ndim = PyArray_NDIM(_py_obj.get()); ndim > 0)
124 {
125 if (ndim < 10)
126 {
127 shape.resize(ndim);
128 std::copy_n(PyArray_SHAPE(_py_obj.get()), ndim, std::begin(shape));
129 }
130 }
131 }
132 return shape;
133 }
134
135 std::size_t flat_size()
136 {
137 auto s = this->shape();
138 return std::accumulate(std::cbegin(s), std::cend(s), 0);
139 }
140
141 double data(std::size_t pos)
142 {
143 if (!_py_obj.is_null())
144 {
145 return reinterpret_cast<double*>(PyArray_DATA(_py_obj.get()))[pos];
146 }
147 return nan("NAN");
148 }
149
150 std::vector<double> to_std_vect()
151 {
152 auto sz = flat_size();
153 std::vector<double> v(sz);
154 auto d_ptr = reinterpret_cast<double*>(PyArray_DATA(_py_obj.get()));
155 std::copy(d_ptr, d_ptr + sz, std::begin(v));
156 return v;
157 }
158
159 PyObject* py_object() { return _py_obj.py_object(); }
160 };
161
162 inline int test_np_array(NpArray& arr)
163 {
164 auto shape = arr.shape();
165 std::cout << "len(shape)=" << shape.size() << std::endl;
166 std::for_each(std::cbegin(shape), std::cend(shape), [](auto sz) {
167 static int i = 0;
168 std::cout << "shape[" << i++ << "]=" << sz << std::endl;
169 });
170 auto flatsize = std::accumulate(std::cbegin(shape), std::cend(shape), 0);
171 for (auto i = 0; i < flatsize; i++)
172 {
173 std::cout << "data[" << i << "]=" << arr.data(i) << std::endl;
174 }
175 return 1;
176 }
177
178 #endif //#ifndef NUMPY_WRAPPERS_H
@@ -0,0 +1,49
1 #!/bin/env python3
2 # taken from https://github.com/radareorg/cutter/blob/master/src/bindings/src_list.py
3
4
5 import os
6 import re
7 import sys
8
9
10 script_path = os.path.dirname(os.path.realpath(__file__))
11
12
13 def get_cpp_files_gen(args, include_package=True):
14 with open(os.path.join(script_path, "bindings.xml"),'r') as f:
15 txt = f.read()
16 package = re.findall("<typesystem *package=.*", txt)[0].split('"')[1]
17 types = re.findall('(.*object-type *name=.*|.*value-type *name=.*)', txt)
18 types = [t.split('"')[1] for t in types]
19
20 cpp_files_gen = [f"{package.lower()}_module_wrapper.cpp"]
21 cpp_files_gen.extend([f"{typename.lower()}_wrapper.cpp" for typename in types])
22
23 if include_package:
24 cpp_files_gen = [os.path.join(package, f) for f in cpp_files_gen]
25
26 if len(args) > 0:
27 cpp_files_gen = [os.path.join(args[0], f) for f in cpp_files_gen]
28
29 return cpp_files_gen
30
31
32 def cmd_cmake(args):
33 sys.stdout.write(";".join(get_cpp_files_gen(args)))
34
35
36 def cmd_qmake(args):
37 sys.stdout.write("\n".join(get_cpp_files_gen(args)) + "\n")
38
39
40 def cmd_meson(args):
41 sys.stdout.write(";".join(get_cpp_files_gen(args, include_package=False)))
42
43
44 cmds = {"cmake": cmd_cmake, "qmake": cmd_qmake, "meson": cmd_meson}
45
46 if len(sys.argv) < 2 or sys.argv[1] not in cmds:
47 print(f"""usage: {sys.argv[0]} [{"/".join(cmds.keys())}] [base path]""")
48 exit(1)
49 cmds[sys.argv[1]](sys.argv[2:])
@@ -0,0 +1,84
1
2 set(_module PySide2)
3
4 find_package(${_module} ${${_module}_FIND_VERSION} CONFIG QUIET)
5 set(_lib_target ${_module}::pyside2)
6
7 if(NOT ${_module}_FOUND)
8 include(PythonInfo)
9 find_python_site_packages(PYTHON_SITE_PACKAGES)
10 get_python_extension_suffix(PYTHON_EXTENSION_SUFFIX)
11 execute_process(
12 COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
13 from PySide2 import _config
14 print(_config.pyside_library_soversion.split('.')[0])
15 "
16 OUTPUT_VARIABLE ${_module}_FIND_VERSION_MAJOR
17 OUTPUT_STRIP_TRAILING_WHITESPACE)
18 execute_process(
19 COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
20 from PySide2 import _config
21 print(_config.pyside_library_soversion.split('.')[1])
22 "
23 OUTPUT_VARIABLE ${_module}_FIND_VERSION_MINOR
24 OUTPUT_STRIP_TRAILING_WHITESPACE)
25
26 find_library(PYSIDE_LIBRARY
27 NAMES
28 "pyside2${PYTHON_EXTENSION_SUFFIX}"
29 "libpyside2${PYTHON_EXTENSION_SUFFIX}"
30 "pyside2${PYTHON_EXTENSION_SUFFIX}.${${_module}_FIND_VERSION_MAJOR}.${${_module}_FIND_VERSION_MINOR}"
31 "libpyside2${PYTHON_EXTENSION_SUFFIX}.${${_module}_FIND_VERSION_MAJOR}.${${_module}_FIND_VERSION_MINOR}"
32 PATHS "${PYTHON_SITE_PACKAGES}/PySide2")
33
34 find_path(PYSIDE_INCLUDE_DIR
35 pyside.h
36 PATHS "${PYTHON_SITE_PACKAGES}/PySide2/include")
37
38 find_path(PYSIDE_TYPESYSTEMS
39 typesystem_core.xml
40 PATHS "${PYTHON_SITE_PACKAGES}/PySide2/typesystems")
41 endif()
42
43 if(TARGET ${_lib_target})
44 get_target_property(_is_imported ${_lib_target} IMPORTED)
45 if(_is_imported)
46 get_target_property(_imported_location ${_lib_target} IMPORTED_LOCATION)
47 if(NOT _imported_location)
48 message(STATUS "Target ${_lib_target} does not specify its IMPORTED_LOCATION! Trying to find it ourselves...")
49 set(_find_args)
50 if(${_module}_CONFIG)
51 get_filename_component(_pyside2_lib_dir "${${_module}_CONFIG}/../../../" ABSOLUTE)
52 set(_find_args PATHS "${_pyside2_lib_dir}")
53 endif()
54 find_library(PYSIDE_LIBRARY
55 NAMES
56 "pyside2${PYTHON_CONFIG_SUFFIX}"
57 "pyside2${PYTHON_CONFIG_SUFFIX}.${${_module}_FIND_VERSION_MAJOR}.${${_module}_FIND_VERSION_MINOR}"
58 ${_find_args})
59 if(NOT PYSIDE_LIBRARY)
60 set(_message_type WARNING)
61 if(${_module}_FIND_REQUIRED)
62 set(_message_type FATAL_ERROR)
63 endif()
64 message(${_message_type} "Failed to manually find library for ${_module}")
65 return()
66 endif()
67 message(STATUS "IMPORTED_LOCATION for ${_lib_target} found: ${PYSIDE_LIBRARY}")
68 set_target_properties(${_lib_target} PROPERTIES IMPORTED_LOCATION "${PYSIDE_LIBRARY}")
69 endif()
70 endif()
71 else()
72 include(FindPackageHandleStandardArgs)
73 find_package_handle_standard_args(${_module}
74 FOUND_VAR ${_module}_FOUND
75 REQUIRED_VARS PYSIDE_LIBRARY PYSIDE_INCLUDE_DIR PYSIDE_TYPESYSTEMS
76 VERSION_VAR ${_module}_VERSION)
77
78 add_library(${_module}::pyside2 INTERFACE IMPORTED)
79 set_target_properties(${_module}::pyside2 PROPERTIES
80 INTERFACE_INCLUDE_DIRECTORIES "${PYSIDE_INCLUDE_DIR}"
81 INTERFACE_LINK_LIBRARIES "${PYSIDE_LIBRARY}")
82 endif()
83
84 mark_as_advanced(PYSIDE_INCLUDE_DIR PYSIDE_LIBRARY PYSIDE_BINARY)
@@ -0,0 +1,106
1
2 set(_module Shiboken2)
3
4 find_package(${_module} ${${_module}_FIND_VERSION} CONFIG QUIET)
5 set(_executable_target ${_module}::shiboken2)
6 set(_lib_target ${_module}::libshiboken)
7
8 if(NOT ${_module}_FOUND)
9 include(PythonInfo)
10 find_python_site_packages(PYTHON_SITE_PACKAGES)
11 get_python_extension_suffix(PYTHON_EXTENSION_SUFFIX)
12
13 execute_process(
14 COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
15 from shiboken2 import _config
16 print(_config.shiboken_library_soversion.split('.')[0])
17 "
18 OUTPUT_VARIABLE ${_module}_FIND_VERSION_MAJOR
19 OUTPUT_STRIP_TRAILING_WHITESPACE)
20 execute_process(
21 COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
22 from shiboken2 import _config
23 print(_config.shiboken_library_soversion.split('.')[1])
24 "
25 OUTPUT_VARIABLE ${_module}_FIND_VERSION_MINOR
26 OUTPUT_STRIP_TRAILING_WHITESPACE)
27
28 find_library(SHIBOKEN_LIBRARY
29 NAMES
30 "libshiboken2${PYTHON_EXTENSION_SUFFIX}.${${_module}_FIND_VERSION_MAJOR}.${${_module}_FIND_VERSION_MINOR}"
31 "shiboken2${PYTHON_EXTENSION_SUFFIX}"
32 PATHS "${PYTHON_SITE_PACKAGES}/shiboken2")
33
34 find_path(SHIBOKEN_INCLUDE_DIR
35 shiboken.h
36 PATHS "${PYTHON_SITE_PACKAGES}/shiboken2_generator/include")
37
38 find_file(SHIBOKEN_BINARY
39 shiboken2
40 PATHS "${PYTHON_SITE_PACKAGES}/shiboken2_generator")
41 endif()
42
43 if(TARGET ${_executable_target})
44 get_target_property(_is_imported ${_executable_target} IMPORTED)
45 if(_is_imported)
46 get_target_property(_imported_location ${_executable_target} IMPORTED_LOCATION)
47 if(NOT _imported_location)
48 message(STATUS "Target ${_executable_target} does not specify its IMPORTED_LOCATION! Trying to find it ourselves...")
49 find_file(SHIBOKEN_BINARY
50 shiboken2
51 PATHS "${SHIBOKEN_SHARED_LIBRARY_DIR}/../bin"
52 NO_DEFAULT_PATH)
53 if(NOT SHIBOKEN_BINARY)
54 set(_message_type WARNING)
55 if(${_module}_FIND_REQUIRED)
56 set(_message_type FATAL_ERROR)
57 endif()
58 message(${_message_type} "Failed to manually find executable for ${_module}")
59 return()
60 endif()
61 message(STATUS "IMPORTED_LOCATION for ${_executable_target} found: ${SHIBOKEN_BINARY}")
62 set_target_properties(${_executable_target} PROPERTIES IMPORTED_LOCATION "${SHIBOKEN_BINARY}")
63 endif()
64 endif()
65
66 get_target_property(_is_imported ${_lib_target} IMPORTED)
67 if(_is_imported)
68 get_target_property(_imported_location ${_lib_target} IMPORTED_LOCATION)
69 if(NOT _imported_location)
70 message(STATUS "Target ${_lib_target} does not specify its IMPORTED_LOCATION! Trying to find it ourselves...")
71 find_library(SHIBOKEN_LIBRARY
72 NAMES
73 "shiboken2${SHIBOKEN_PYTHON_EXTENSION_SUFFIX}"
74 "shiboken2${SHIBOKEN_PYTHON_EXTENSION_SUFFIX}.${${_module}_FIND_VERSION_MAJOR}.${${_module}_FIND_VERSION_MINOR}"
75 PATHS "${SHIBOKEN_SHARED_LIBRARY_DIR}")
76 if(NOT SHIBOKEN_LIBRARY)
77 set(_message_type WARNING)
78 if(${_module}_FIND_REQUIRED)
79 set(_message_type FATAL_ERROR)
80 endif()
81 message(${_message_type} "Failed to manually find library for ${_module}")
82 return()
83 endif()
84 message(STATUS "IMPORTED_LOCATION for ${_lib_target} found: ${SHIBOKEN_LIBRARY}")
85 set_target_properties(${_lib_target} PROPERTIES IMPORTED_LOCATION "${SHIBOKEN_LIBRARY}")
86 endif()
87 endif()
88 else()
89 include(FindPackageHandleStandardArgs)
90 find_package_handle_standard_args(${_module}
91 FOUND_VAR ${_module}_FOUND
92 REQUIRED_VARS SHIBOKEN_LIBRARY SHIBOKEN_INCLUDE_DIR SHIBOKEN_BINARY
93 VERSION_VAR ${_module}_VERSION)
94
95 add_library(${_module}::libshiboken INTERFACE IMPORTED)
96 set_target_properties(${_module}::libshiboken PROPERTIES
97 INTERFACE_INCLUDE_DIRECTORIES "${SHIBOKEN_INCLUDE_DIR}"
98 INTERFACE_LINK_LIBRARIES "${SHIBOKEN_LIBRARY}")
99
100 add_executable(${_module}::shiboken2 IMPORTED)
101 set_target_properties(${_module}::shiboken2 PROPERTIES
102 IMPORTED_LOCATION "${SHIBOKEN_BINARY}")
103 endif()
104
105 mark_as_advanced(SHIBOKEN_INCLUDE_DIR SHIBOKEN_LIBRARY SHIBOKEN_BINARY)
106
@@ -0,0 +1,32
1
2 function(find_python_site_packages VAR)
3 if(Python_SITELIB)
4 set("${VAR}" "${Python_SITELIB}" PARENT_SCOPE)
5 return()
6 endif()
7
8 execute_process(
9 COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
10 from distutils import sysconfig
11 print(sysconfig.get_python_lib(prefix=None, plat_specific=True))"
12 OUTPUT_VARIABLE "${VAR}"
13 OUTPUT_STRIP_TRAILING_WHITESPACE)
14 set("${VAR}" "${${VAR}}" PARENT_SCOPE)
15 endfunction()
16
17 function(get_python_extension_suffix VAR)
18 # from PySide2 CMakeLists.txt
19 # Result of imp.get_suffixes() depends on the platform, but generally looks something like:
20 # [('.cpython-34m-x86_64-linux-gnu.so', 'rb', 3), ('.cpython-34m.so', 'rb', 3),
21 # ('.abi3.so', 'rb', 3), ('.so', 'rb', 3), ('.py', 'r', 1), ('.pyc', 'rb', 2)]
22 # We pick the first most detailed one, strip of the file extension part.
23
24 execute_process(
25 COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
26 import sysconfig
27 print(sysconfig.get_config_var('EXT_SUFFIX'))
28 "
29 OUTPUT_VARIABLE "${VAR}"
30 OUTPUT_STRIP_TRAILING_WHITESPACE)
31 set("${VAR}" "${${VAR}}" PARENT_SCOPE)
32 endfunction()
@@ -2,7 +2,8 include_directories(include)
2
2
3 FILE (GLOB_RECURSE app_SRCS
3 FILE (GLOB_RECURSE app_SRCS
4 include/*.h
4 include/*.h
5 src/*.cpp
5 src/MainWindow.cpp
6 src/toolbar.cpp
6 resources/*.qrc
7 resources/*.qrc
7 )
8 )
8
9
@@ -10,10 +11,12 QT5_WRAP_UI(UiGenerated_SRCS
10 ui/MainWindow.ui
11 ui/MainWindow.ui
11 )
12 )
12
13
14 add_library(sciqlopapp ${UiGenerated_SRCS} ${app_SRCS})
15
13 if(ENABLE_WIN32_CONSOLE)
16 if(ENABLE_WIN32_CONSOLE)
14 add_executable(sciqlopapp ${app_SRCS} ${UiGenerated_SRCS})
17 add_executable(sciqlop src/Main.cpp)
15 else()
18 else()
16 add_executable(sciqlopapp WIN32 ${app_SRCS} ${UiGenerated_SRCS})
19 add_executable(sciqlop WIN32 src/Main.cpp)
17 endif()
20 endif()
18
21
19 if(NOT BUILD_SHARED_LIBS)
22 if(NOT BUILD_SHARED_LIBS)
@@ -39,9 +42,20 target_link_libraries(sciqlopapp
39 sciqlopcore
42 sciqlopcore
40 )
43 )
41
44
42 install(TARGETS sciqlopapp DESTINATION ${CMAKE_INSTALL_BINDIR})
45 target_link_libraries(sciqlop
46 sciqlopapp
47 )
48
49 install(TARGETS sciqlopapp
50 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
51 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
52 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
53
54
55 install(TARGETS sciqlop DESTINATION ${CMAKE_INSTALL_BINDIR})
43 install(FILES resources/SciQLOP.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/)
56 install(FILES resources/SciQLOP.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/)
44 install(FILES resources/SciQLOP.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/)
57 install(FILES resources/SciQLOP.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/)
45 install(FILES resources/sciqlopLOGO.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/SciQLOP/icons/)
58 install(FILES resources/sciqlopLOGO.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/SciQLOP/icons/)
46
59
47
60
61 add_subdirectory(PySide2-bindings)
@@ -22,7 +22,8
22 #ifndef SCIQLOP_MAINWINDOW_H
22 #ifndef SCIQLOP_MAINWINDOW_H
23 #define SCIQLOP_MAINWINDOW_H
23 #define SCIQLOP_MAINWINDOW_H
24
24
25 #include <QListWidgetItem>
25 #include <PluginManager/PluginManager.h>
26 #include <QDir>
26 #include <QLoggingCategory>
27 #include <QLoggingCategory>
27 #include <QMainWindow>
28 #include <QMainWindow>
28 #include <QProgressBar>
29 #include <QProgressBar>
@@ -30,31 +31,33
30 #include <QThread>
31 #include <QThread>
31 #include <QVBoxLayout>
32 #include <QVBoxLayout>
32 #include <QWidget>
33 #include <QWidget>
34 #include <QtPlugin>
35 #include <SqpApplication.h>
33
36
34 #include <Common/spimpl.h>
37 #include <Common/spimpl.h>
35
38
36 #include <memory>
39 #include <memory>
37
40
38 Q_DECLARE_LOGGING_CATEGORY(LOG_MainWindow)
41 namespace Ui
39
42 {
40 namespace Ui {
41 class MainWindow;
43 class MainWindow;
42 } // namespace Ui
44 } // namespace Ui
43
45
44
46
45 class MainWindow : public QMainWindow {
47 class MainWindow : public QMainWindow
48 {
46 Q_OBJECT
49 Q_OBJECT
47
50
48 public:
51 public:
49 explicit MainWindow(QWidget *parent = nullptr);
52 explicit MainWindow(QWidget* parent = nullptr);
50 virtual ~MainWindow() override;
53 virtual ~MainWindow() override;
51 public slots:
54 public slots:
52
55
53 protected:
56 protected:
54 void changeEvent(QEvent *e) override;
57 void changeEvent(QEvent* e) override;
55 void closeEvent(QCloseEvent *event) override;
58 void closeEvent(QCloseEvent* event) override;
56
59
57 void keyPressEvent(QKeyEvent *event) override;
60 void keyPressEvent(QKeyEvent* event) override;
58
61
59 private:
62 private:
60 std::unique_ptr<Ui::MainWindow> m_Ui;
63 std::unique_ptr<Ui::MainWindow> m_Ui;
@@ -65,4 +68,53 private:
65 spimpl::unique_impl_ptr<MainWindowPrivate> impl;
68 spimpl::unique_impl_ptr<MainWindowPrivate> impl;
66 };
69 };
67
70
71 inline void init_resources()
72 {
73 #ifdef QT_STATICPLUGIN
74 #ifndef SQP_NO_PLUGINS
75 Q_IMPORT_PLUGIN(PythonProviders)
76 Q_INIT_RESOURCE(python_providers);
77 #endif
78 #endif
79 Q_INIT_RESOURCE(sqpguiresources);
80 SqpApplication::setOrganizationName("LPP");
81 SqpApplication::setOrganizationDomain("lpp.fr");
82 SqpApplication::setApplicationName("SciQLop");
83
84 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
85 }
86
87 inline void load_plugins(const SqpApplication& a)
88 {
89 // Loads plugins
90 auto pluginDir = QDir { a.applicationDirPath() };
91 auto pluginLookupPath = {
92 #if _WIN32 || _WIN64
93 a.applicationDirPath() + "/SciQLop"
94 #else
95 a.applicationDirPath() + "/../lib64/SciQLop",
96 a.applicationDirPath() + "/../lib64/sciqlop",
97 a.applicationDirPath() + "/../lib/SciQLop",
98 a.applicationDirPath() + "/../lib/sciqlop",
99 #endif
100 };
101
102 #if _WIN32 || _WIN64
103 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
104 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
105 #endif
106
107 PluginManager pluginManager {};
108
109 for (auto&& path : pluginLookupPath)
110 {
111 QDir directory { path };
112 if (directory.exists())
113 {
114 pluginManager.loadPlugins(directory);
115 }
116 }
117 pluginManager.loadStaticPlugins();
118 }
119
68 #endif // SCIQLOP_MAINWINDOW_H
120 #endif // SCIQLOP_MAINWINDOW_H
@@ -31,7 +31,6
31
31
32 #include <QLoggingCategory>
32 #include <QLoggingCategory>
33
33
34 Q_LOGGING_CATEGORY(LOG_Main, "Main")
35
34
36 namespace
35 namespace
37 {
36 {
@@ -43,56 +42,10 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
43
42
44 int main(int argc, char* argv[])
43 int main(int argc, char* argv[])
45 {
44 {
46 #ifdef QT_STATICPLUGIN
45 init_resources();
47 #ifndef SQP_NO_PLUGINS
48 Q_IMPORT_PLUGIN(PythonProviders)
49 Q_INIT_RESOURCE(python_providers);
50 #endif
51 #endif
52 Q_INIT_RESOURCE(sqpguiresources);
53
54 SqpApplication::setOrganizationName("LPP");
55 SqpApplication::setOrganizationDomain("lpp.fr");
56 SqpApplication::setApplicationName("SciQLop");
57
58 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
59
60 SqpApplication a { argc, argv };
46 SqpApplication a { argc, argv };
61
47 load_plugins(a);
62 MainWindow w;
48 MainWindow w;
63 w.show();
49 w.show();
64
65 // Loads plugins
66 auto pluginDir = QDir { a.applicationDirPath() };
67 auto pluginLookupPath = {
68 #if _WIN32 || _WIN64
69 a.applicationDirPath() + "/SciQLop"
70 #else
71 a.applicationDirPath() + "/../lib64/SciQLop",
72 a.applicationDirPath() + "/../lib64/sciqlop",
73 a.applicationDirPath() + "/../lib/SciQLop",
74 a.applicationDirPath() + "/../lib/sciqlop",
75 #endif
76 };
77
78 #if _WIN32 || _WIN64
79 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
80 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
81 #endif
82
83 PluginManager pluginManager {};
84
85 for (auto&& path : pluginLookupPath)
86 {
87 QDir directory { path };
88 if (directory.exists())
89 {
90 qCDebug(LOG_Main())
91 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
92 pluginManager.loadPlugins(directory);
93 }
94 }
95 pluginManager.loadStaticPlugins();
96
97 return a.exec();
50 return a.exec();
98 }
51 }
@@ -110,4 +110,11 private:
110 spimpl::unique_impl_ptr<SqpApplicationPrivate> impl;
110 spimpl::unique_impl_ptr<SqpApplicationPrivate> impl;
111 };
111 };
112
112
113 inline SqpApplication* SqpApplication_ctor()
114 {
115 static int argc;
116 static char** argv;
117 return new SqpApplication(argc, argv);
118 }
119
113 #endif // SCIQLOP_SQPAPPLICATION_H
120 #endif // SCIQLOP_SQPAPPLICATION_H
@@ -112,16 +112,6 void EventsModel::sort(int column, Qt::SortOrder order)
112 [inverse = order != Qt::SortOrder::AscendingOrder](
112 [inverse = order != Qt::SortOrder::AscendingOrder](
113 const std::unique_ptr<EventsModelItem>& a,
113 const std::unique_ptr<EventsModelItem>& a,
114 const std::unique_ptr<EventsModelItem>& b) {
114 const std::unique_ptr<EventsModelItem>& b) {
115 static int i = 0;
116 i++;
117 if (!a->event())
118 {
119 throw;
120 }
121 if (!b->event())
122 {
123 throw;
124 }
125 return (a->event()->name < b->event()->name) xor inverse;
115 return (a->event()->name < b->event()->name) xor inverse;
126 });
116 });
127 break;
117 break;
@@ -130,45 +120,13 void EventsModel::sort(int column, Qt::SortOrder order)
130 [inverse = order != Qt::SortOrder::AscendingOrder](
120 [inverse = order != Qt::SortOrder::AscendingOrder](
131 const std::unique_ptr<EventsModelItem>& a,
121 const std::unique_ptr<EventsModelItem>& a,
132 const std::unique_ptr<EventsModelItem>& b) {
122 const std::unique_ptr<EventsModelItem>& b) {
133 static int i = 0;
123 if (auto t1 = a->event()->startTime(); auto t2 = b->event()->startTime())
134 i++;
135 if (!a)
136 {
137 throw;
138 }
139 if (!b)
140 {
141 throw;
142 }
143 if (!a->event())
144 {
145 throw;
146 }
147 if (!b->event())
148 {
124 {
149 throw;
125 if (t1 and t2)
126 return bool((t1.value() < t2.value()) xor inverse);
150 }
127 }
151 return (a->event()->name < b->event()->name) xor inverse;
128 return true;
152 });
129 });
153 // std::sort(std::begin(_items), std::end(_items),
154 // [inverse = order != Qt::SortOrder::AscendingOrder](
155 // const std::unique_ptr<EventsModelItem>& a,
156 // const std::unique_ptr<EventsModelItem>& b) {
157 // static int i = 0;
158 // i++;
159 // if (a and b)
160 // {
161 // if (a->type == ItemType::Event and b->type == ItemType::Event)
162 // {
163 // if (auto e1 = a->event(); auto e2 = b->event())
164 // {
165 // return bool((e1->startTime() < e2->startTime()) xor
166 // inverse);
167 // }
168 // }
169 // }
170 // return false;
171 // });
172 break;
130 break;
173 case EventsModel::Columns::TEnd:
131 case EventsModel::Columns::TEnd:
174 std::sort(std::begin(_items), std::end(_items),
132 std::sort(std::begin(_items), std::end(_items),
@@ -2,9 +2,9 include(sciqlop_tests)
2 subdirs(GUITestUtils)
2 subdirs(GUITestUtils)
3 declare_test(simple_graph simple_graph simple_graph/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
3 declare_test(simple_graph simple_graph simple_graph/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
4 declare_test(multiple_sync_graph multiple_sync_graph multiple_sync_graph/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
4 declare_test(multiple_sync_graph multiple_sync_graph multiple_sync_graph/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
5
5 declare_test(catalogue_browser catalogue_browser catalogue/browser/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
6 if(NOT WIN32)
6 if(NOT WIN32)
7 declare_manual_test(event_list event_list catalogue/event_list/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
7 declare_manual_test(event_list event_list catalogue/event_list/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
8 declare_manual_test(repository_list repository_list catalogue/repository_list/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
8 declare_manual_test(repository_list repository_list catalogue/repository_list/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
9 declare_manual_test(catalogue_browser catalogue_browser catalogue/browser/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
9 declare_manual_test(catalogue_browser_m catalogue_browser_m catalogue/browser/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test")
10 endif() No newline at end of file
10 endif()
@@ -4,6 +4,7
4 #include <QString>
4 #include <QString>
5 #include <QWheelEvent>
5 #include <QWheelEvent>
6 #include <QtTest>
6 #include <QtTest>
7 #include <cstdlib>
7
8
8
9
9 #include <Common/cpp_utils.h>
10 #include <Common/cpp_utils.h>
@@ -14,6 +15,36
14 #include <Catalogue/CatalogueController.h>
15 #include <Catalogue/CatalogueController.h>
15 #include <Catalogue2/browser.h>
16 #include <Catalogue2/browser.h>
16
17
18 template <int EventsCount = 1000>
19 auto build_CatalogueBrowser_test()
20 {
21 sqpApp->catalogueController().add("test");
22 sqpApp->catalogueController().add("stuff");
23 sqpApp->catalogueController().add("default");
24 sqpApp->catalogueController().add("new catalogue", "default");
25 auto catalogue = sqpApp->catalogueController().add("new catalogue2", "default");
26 for (auto _ : std::array<char, EventsCount>())
27 {
28 static int i = 0;
29 auto event = CatalogueController::make_event_ptr();
30 event->name = std::string("Event ") + std::to_string(i++);
31 event->tags = { "tag1", "tag2" };
32 event->products = { CatalogueController::Event_t::Product_t {
33 std::string("Product2") + std::to_string(rand() % 30),
34 static_cast<double>(1532357932 + rand() % 100),
35 static_cast<double>(1532358932 + rand() % 100) },
36 CatalogueController::Event_t::Product_t {
37 std::string("Product2") + std::to_string(rand() % 30),
38 static_cast<double>(1532357932 + rand() % 200),
39 static_cast<double>(1532358932 + rand() % 200) },
40 CatalogueController::Event_t::Product_t {
41 std::string("Product2") + std::to_string(rand() % 30),
42 static_cast<double>(1532357932 + rand() % 70),
43 static_cast<double>(1532358932 + rand() % 70) } };
44 catalogue->add(event);
45 }
46 return std::make_unique<CataloguesBrowser>();
47 }
17
48
18 class A_CatalogueBrowser : public QObject
49 class A_CatalogueBrowser : public QObject
19 {
50 {
@@ -22,48 +53,33 public:
22 explicit A_CatalogueBrowser(QObject* parent = Q_NULLPTR) : QObject(parent) {}
53 explicit A_CatalogueBrowser(QObject* parent = Q_NULLPTR) : QObject(parent) {}
23
54
24 private slots:
55 private slots:
56 void can_sort_events()
57 {
58 auto w = build_CatalogueBrowser_test();
59 QVERIFY(prepare_gui_test(w.get()));
60 // GET_CHILD_WIDGET_FOR_GUI_TESTS((*w.get()),,,)
61 for (int i = 0; i < 1000000; i++)
62 {
63 QThread::usleep(100);
64 QCoreApplication::processEvents();
65 }
66 }
25 };
67 };
26
68
27 // QT_BEGIN_NAMESPACE
69 QT_BEGIN_NAMESPACE
28 // QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
70 QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
29 // QT_END_NAMESPACE
71 QT_END_NAMESPACE
30 // int main(int argc, char* argv[])
31 //{
32 // SqpApplication app { argc, argv };
33 // app.setAttribute(Qt::AA_Use96Dpi, true);
34 // QTEST_DISABLE_KEYPAD_NAVIGATION;
35 // QTEST_ADD_GPU_BLACKLIST_SUPPORT;
36 // An_EventList tc;
37 // QTEST_SET_MAIN_SOURCE_PATH;
38 // return QTest::qExec(&tc, argc, argv);
39 //}
40
41 #include "main.moc"
42
43
44 int main(int argc, char* argv[])
72 int main(int argc, char* argv[])
45 {
73 {
46 Q_INIT_RESOURCE(sqpguiresources);
74 Q_INIT_RESOURCE(sqpguiresources);
47 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
48
75
49 SqpApplication a { argc, argv };
76 SqpApplication app { argc, argv };
50 CataloguesBrowser w;
77 app.setAttribute(Qt::AA_Use96Dpi, true);
51 sqpApp->catalogueController().add("test");
78 QTEST_DISABLE_KEYPAD_NAVIGATION;
52 sqpApp->catalogueController().add("stuff");
79 QTEST_ADD_GPU_BLACKLIST_SUPPORT;
53 sqpApp->catalogueController().add("default");
80 A_CatalogueBrowser tc;
54 sqpApp->catalogueController().add("new catalogue", "default");
81 QTEST_SET_MAIN_SOURCE_PATH;
55 auto catalogue = sqpApp->catalogueController().add("new catalogue2", "default");
82 return QTest::qExec(&tc, argc, argv);
56 for (auto _ : std::array<char, 1000>())
57 {
58 static int i = 0;
59 auto event = CatalogueController::make_event_ptr();
60 event->name = std::string("Event ") + std::to_string(i++);
61 event->tags = {"tag1", "tag2"};
62 event->products = { CatalogueController::Event_t::Product_t { "Product1", 10., 11. },
63 CatalogueController::Event_t::Product_t { "Product2", 11., 12. },
64 CatalogueController::Event_t::Product_t { "Product3", 10.2, 11. } };
65 catalogue->add(event);
66 }
67 w.show();
68 return a.exec();
69 }
83 }
84
85 #include "main.moc"
@@ -27,10 +27,10 public:
27
27
28 PythonProvider(const PythonProvider& other) : _pythonFunction { other._pythonFunction } {}
28 PythonProvider(const PythonProvider& other) : _pythonFunction { other._pythonFunction } {}
29
29
30 std::shared_ptr<IDataProvider> clone() const override
30 // std::shared_ptr<IDataProvider> clone() const override
31 {
31 // {
32 return std::make_shared<PythonProvider>(*this);
32 // return std::make_shared<PythonProvider>(*this);
33 }
33 // }
34 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override
34 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override
35 {
35 {
36 auto product = parameters.m_Data.value("PRODUCT", "").toString().toStdString();
36 auto product = parameters.m_Data.value("PRODUCT", "").toString().toStdString();
General Comments 0
You need to be logged in to leave comments. Login now