diff --git a/.clang-format b/.clang-format
index 548068d..b8140ac 100644
--- a/.clang-format
+++ b/.clang-format
@@ -31,11 +31,11 @@ BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
- AfterClass: false
+ AfterClass: true
AfterControlStatement: Never
AfterEnum: false
- AfterFunction: false
- AfterNamespace: false
+ AfterFunction: true
+ AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
@@ -51,10 +51,6 @@ BraceWrapping:
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Custom
-BraceWrapping:
- AfterClass: true
- AfterFunction: true
- AfterNamespace: true
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
diff --git a/.gitmodules b/.gitmodules
index 672e543..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,9 +0,0 @@
-[submodule "subprojects/nlohmann_json"]
- path = subprojects/nlohmann_json
- url = https://github.com/nlohmann/json.git
-[submodule "subprojects/singleapplication"]
- path = subprojects/singleapplication/singleapplication.git
- url = https://github.com/itay-grudev/SingleApplication.git
-[submodule "subprojects/csv-parser"]
- path = subprojects/csv-parser
- url = https://github.com/vincentlaucsb/csv-parser.git
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 43f0c12..41f34ac 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -65,7 +65,37 @@
"condition_variable": "cpp",
"mutex": "cpp",
"hash_map": "cpp",
- "future": "cpp"
+ "future": "cpp",
+ "bit": "cpp",
+ "compare": "cpp",
+ "concepts": "cpp",
+ "forward_list": "cpp",
+ "map": "cpp",
+ "set": "cpp",
+ "string": "cpp",
+ "unordered_set": "cpp",
+ "iterator": "cpp",
+ "memory_resource": "cpp",
+ "random": "cpp",
+ "semaphore": "cpp",
+ "stop_token": "cpp",
+ "__bit_reference": "cpp",
+ "__bits": "cpp",
+ "__config": "cpp",
+ "__debug": "cpp",
+ "__errc": "cpp",
+ "__hash_table": "cpp",
+ "__locale": "cpp",
+ "__mutex_base": "cpp",
+ "__node_handle": "cpp",
+ "__split_buffer": "cpp",
+ "__threading_support": "cpp",
+ "__tree": "cpp",
+ "__tuple": "cpp",
+ "__verbose_abort": "cpp",
+ "format": "cpp",
+ "ios": "cpp",
+ "locale": "cpp"
},
"C_Cpp.clang_format_path": "/usr/bin/clang-format",
"cmake.configureOnOpen": true,
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d13e95..86b072a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,14 @@
-cmake_minimum_required(VERSION 3.8)
+cmake_minimum_required(VERSION 3.30)
-project(kima2 VERSION 1.6.0)
+project(kima2 VERSION 1.9.2)
set(CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
-#include(InstallRequiredSystemLibraries)
+# For SingleApplication and nlohmann_json
+include(FetchContent)
if(MSVC)
add_compile_options(/W4 /WX)
@@ -17,6 +18,7 @@ else()
endif()
configure_file(config.h.in ${PROJECT_BINARY_DIR}/config.h)
+configure_file(de.rustysoft.kima2.metainfo.xml.in ${PROJECT_BINARY_DIR}/de.rustysoft.kima2.metainfo.xml)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
@@ -28,7 +30,6 @@ if(KIMA2_USE_EXTERNAL_JSON)
find_package(nlohmann_json REQUIRED)
endif()
-add_subdirectory(subprojects)
add_subdirectory(src)
#if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE MATCHES Debug)
@@ -79,6 +80,8 @@ else(WIN32 AND NOT UNIX)
DESTINATION share/${PROJECT_NAME})
install(FILES "${CMAKE_SOURCE_DIR}/misc/kima2.svg"
DESTINATION share/icons/hicolor/scalable/apps)
+ install(FILES de.rustysoft.kima2.metainfo.xml
+ DESTINATION share/metainfo)
endif (WIN32 AND NOT UNIX)
if( MINGW )
@@ -95,10 +98,9 @@ if( MINGW )
${MINGW_PATH}/libwinpthread-1.dll
${MINGW_PATH}/libsqlite3-0.dll
${MINGW_PATH}/libusb-1.0.dll
- ${MINGW_PATH}/libxlnt.dll
- ${MINGW_PATH}/libicuuc71.dll
- ${MINGW_PATH}/libicuin71.dll
- ${MINGW_PATH}/libicudt71.dll
+ ${MINGW_PATH}/libicuuc76.dll
+ ${MINGW_PATH}/libicuin76.dll
+ ${MINGW_PATH}/libicudt76.dll
${MINGW_PATH}/libpcre2-16-0.dll
${MINGW_PATH}/libpcre2-8-0.dll
${MINGW_PATH}/zlib1.dll
@@ -109,13 +111,12 @@ if( MINGW )
${MINGW_PATH}/libgraphite2.dll
${MINGW_PATH}/libbz2-1.dll
${MINGW_PATH}/libintl-8.dll
- ${MINGW_PATH}/libpcre-1.dll
${MINGW_PATH}/libdouble-conversion.dll
${MINGW_PATH}/libzstd.dll
${MINGW_PATH}/libmd4c.dll
${MINGW_PATH}/libbrotlicommon.dll
${MINGW_PATH}/libbrotlidec.dll
- ${MINGW_PATH}/libfmt.dll
+ #${MINGW_PATH}/libfmt.dll
${MINGW_PATH}/libb2-1.dll
${MINGW_PATH}/libiconv-2.dll)
install(FILES ${MINGW_PATH}/../share/qt6/plugins/platforms/qwindows.dll
@@ -123,14 +124,13 @@ if( MINGW )
DESTINATION bin/platforms)
#install(FILES ${MINGW_PATH}/../share/qt6/plugins/printsupport/windowsprintersupport.dll
# DESTINATION bin/printsupport)
- install(FILES ${MINGW_PATH}/../share/qt5/translations/qtbase_de.qm
+ install(FILES ${MINGW_PATH}/../share/qt6/translations/qtbase_de.qm
${MINGW_PATH}/../share/qt6/translations/qt_de.qm
${MINGW_PATH}/../share/qt6/translations/qt_help_de.qm
${MINGW_PATH}/../share/qt6/translations/qtmultimedia_de.qm
- #${MINGW_PATH}/../share/qt6/translations/qtquickcontrols_de.qm
- #${MINGW_PATH}/../share/qt6/translations/qtscript_de.qm
- #${MINGW_PATH}/../share/qt6/translations/qtxmlpatterns_de.qm
- DESTINATION bin/translations)
+ DESTINATION bin/share/qt6/translations)
+ install(FILES ${MINGW_PATH}/../share/qt6/plugins/styles/qmodernwindowsstyle.dll
+ DESTINATION bin/styles)
endif( MINGW )
include(InstallRequiredSystemLibraries)
diff --git a/LICENSE b/LICENSE
index e6d4fba..0b127da 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright © 2018-2022 Martin Brodbeck
+Copyright © 2018-2025 Martin Brodbeck
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der
zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt,
diff --git a/README.md b/README.md
index 28369cf..3c0dd87 100644
--- a/README.md
+++ b/README.md
@@ -13,19 +13,16 @@ Verkaufsdaten nach dem Verkaufsende auszutauschen.
Ebenso können über einen ESC/POS-Drucker Quittungen ausgestellt werden.
## Installation
-Auf [rustysoft.de](https://www.rustysoft.de/software/kima2/) werden verschiedene Installationspakete (Arch Linux,
-Ubuntu, Windows) angeboten. Bitte die Hinweise dort beachten.
+Auf [rustysoft.de](https://www.rustysoft.de/software/kima2/) werden die Installationsmöglichkeiten (Flatpak, Windows-Installer) erläutert. Bitte die Hinweise dort beachten.
-### Selbst compilieren
+## Selbst compilieren
KIMA2 benötigt folgende Libraries:
-* Qt5
-* boost >= 1.62
+* Qt 6
+* boost >= 1.80
* libusb-1.0
-* xlnt >= 1.3.0
* nlohmann-json (als 3rdparty submodule vorhanden)
-Da Features aus C++17 verwendet werden sowie std::filesystem, sollte als Compiler mindestens
-GCC 8 verwendet werden.
+Da Features aus C++20 sowie von neueren Compilern verwendet werden, sollte als Compiler mindestens GCC 14 verwendet werden.
Die Installationsschritte unter Linux sind wie folgt:
```
@@ -37,4 +34,4 @@ sudo make install
```
Unter Windows muss vorab MinGW eingerichtet werden (z. B. MSYS2). Nach der Compilierung kann mit
-`cpack -G NSIS` ein Installationspaket erstellt werden.
\ No newline at end of file
+`cpack -G NSIS` ein Installationspaket erstellt werden.
diff --git a/de.rustysoft.kima2.metainfo.xml.in b/de.rustysoft.kima2.metainfo.xml.in
new file mode 100644
index 0000000..9f228f7
--- /dev/null
+++ b/de.rustysoft.kima2.metainfo.xml.in
@@ -0,0 +1,27 @@
+
+
+ de.rustysoft.kima2
+
+ KIMA2
+ A small cash point program for children’s stuff markets
+
+ MIT
+ GPL-3.0-or-later
+
+
+
+
+
+
+
+ A small cash point program for children's stuff markets. German language only.
+
+
+
+ de.rustysoft.kima2.desktop
+
+
+ https://rustysoft.de/images/software/kima2/screenshot.png
+
+
+
diff --git a/manual/Benutzerhandbuch.odt b/manual/Benutzerhandbuch.odt
index 37dac87..c2defc2 100644
Binary files a/manual/Benutzerhandbuch.odt and b/manual/Benutzerhandbuch.odt differ
diff --git a/manual/Benutzerhandbuch.pdf b/manual/Benutzerhandbuch.pdf
index 9c7b987..793f996 100644
Binary files a/manual/Benutzerhandbuch.pdf and b/manual/Benutzerhandbuch.pdf differ
diff --git a/meson.build b/meson.build
deleted file mode 100644
index 1ff5920..0000000
--- a/meson.build
+++ /dev/null
@@ -1,33 +0,0 @@
-project('kima2', 'cpp', default_options : ['cpp_std=c++20'], version : '1.6.0')
-
-conf_data = configuration_data()
-conf_data.set('PROJECT_VERSION', '"' + meson.project_version() + '"')
-configure_file(output : 'config.h',
- configuration : conf_data)
-configuration_inc = include_directories('.')
-
-#csv = cmake.subproject('csv-parser')
-#csv_lib = csv.dependency('csv')
-
-nlohmann_lib = dependency('nlohmann_json', version : '>=3.5.0', required : false)
-
-if not nlohmann_lib.found()
- nlohmann_inc = include_directories('subprojects/nlohmann_json/single_include')
- nlohmann_lib = declare_dependency(include_directories : nlohmann_inc)
-endif
-
-csv_inc = include_directories('subprojects/csv-parser/single_include')
-csv_dep = declare_dependency(include_directories : csv_inc)
-
-singleapp_proj = subproject('singleapplication')
-singleapp_lib = singleapp_proj.get_variable('singleapp_lib')
-singleapp_dep = singleapp_proj.get_variable('singleapp_dep')
-
-subdir('src')
-
-if build_machine.system() == 'linux'
- install_data('misc/kima2.svg', install_dir : get_option('datadir') / 'icons/hicolor/scalable/apps')
- install_data('misc/kima2.desktop', install_dir : get_option('datadir') / 'applications')
- install_data('manual/Benutzerhandbuch.pdf', install_dir : get_option('datadir') / 'kima2')
-endif
-
diff --git a/misc/PKGBUILD b/misc/PKGBUILD
index f679f03..a50410c 100644
--- a/misc/PKGBUILD
+++ b/misc/PKGBUILD
@@ -1,21 +1,27 @@
# Maintainer: Martin Brodbeck
pkgname=kima2
-pkgver=1.5.0
+pkgver=1.7.1
pkgrel=1
pkgdesc="A small cash point program for children's things markets (German only)"
arch=('i686' 'x86_64')
-url="http://www.rustysoft.de/?01_kima2"
+url="http://www.rustysoft.de/software/kima2"
license=('custom')
-depends=('glibc' 'libusb' 'qt5-base' 'sqlite3' 'xlnt')
+depends=('glibc' 'libusb' 'qt6-base' 'sqlite3')
makedepends=('boost>=1.62')
-source=($pkgname-$pkgver.tar.gz)
-md5sums=('c0e6a64b5037675edce4ba8bc4639bd3')
+source=(git+https://git.rustysoft.de/martin/kima2)
+sha256sums=('SKIP')
build() {
- if [ ! -d $pkgname/build ]; then
- mkdir $pkgname/build
+ cd $pkgname
+
+ git checkout v$pkgver
+ git submodule init
+ git submodule update
+
+ if [ -d build ]; then
+ rm -rf build
fi
- cd $pkgname/build
+ mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DKIMA2_USE_EXTERNAL_JSON=OFF ..
make
diff --git a/misc/kima2.desktop b/misc/kima2.desktop
index 004ab5f..becabdf 100644
--- a/misc/kima2.desktop
+++ b/misc/kima2.desktop
@@ -3,8 +3,8 @@ Type=Application
Name=KIMA2
GenericName=Cash Point Program
GenericName[de]=Kassenprogramm
-Comment=A small cash point program
-Comment[de]=Ein kleines Kassenprogramm
+Comment=A small cash point program for children's stuff markets
+Comment[de]=Ein kleines Kassenprogramm für Kindersachenmärkte
Exec=kima2
Icon=kima2
Categories=Office;
diff --git a/misc/kima2.spec b/misc/kima2.spec
index 0c3feff..2c586a8 100644
--- a/misc/kima2.spec
+++ b/misc/kima2.spec
@@ -13,7 +13,6 @@ BuildRequires: boost-date-time
BuildRequires: sqlite-devel
BuildRequires: libusb-devel
BuildRequires: qt5-qtdeclarative-devel
-#BuildRequires: pkgconfig(xlnt)
#BuildRequires: pkgconfig(pthreads)
%description
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 90b6fbc..681cf5c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,23 +1,14 @@
set(Boost_USE_STATIC_LIBS ON)
-find_package(Boost 1.62 REQUIRED)
+find_package(Boost 1.78 REQUIRED)
find_package(SQLite3 REQUIRED)
-# Because csv-parser needs threads:
-set(THREADS_PREFER_PTHREAD_FLAG ON)
-find_package(Threads REQUIRED)
+FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz)
+FetchContent_MakeAvailable(json)
-find_package(fmt)
+add_library(core STATIC)
-
-if (MINGW)
- find_package(XLNT REQUIRED STATIC)
-else (MINGW)
- find_package(PkgConfig REQUIRED)
- pkg_check_modules(XLNT REQUIRED xlnt>=1.3)
-endif (MINGW)
-
-set(CORE_SOURCES
+target_sources(core PRIVATE
database.cpp
entity.cpp
entityint.cpp
@@ -26,20 +17,16 @@ set(CORE_SOURCES
article.cpp
sale.cpp
marketplace.cpp
- excelreader.cpp
csvreader.cpp
jsonutil.cpp
utils.cpp
)
-
-add_library(core STATIC ${CORE_SOURCES})
-target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/csv-parser/single_include)
if (WIN32)
- target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARY} Threads::Threads fmt::fmt)
+ target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json)
target_link_libraries(core PRIVATE bcrypt)
else()
- target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARIES} Threads::Threads fmt::fmt)
+ target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json)
endif()
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
diff --git a/src/core/csvreader.cpp b/src/core/csvreader.cpp
index 5e092c9..6c2cdf6 100644
--- a/src/core/csvreader.cpp
+++ b/src/core/csvreader.cpp
@@ -3,7 +3,8 @@
#include
-#include
+// #include
+#include
#ifdef DELETE
#undef DELETE
@@ -13,17 +14,16 @@ namespace fs = std::filesystem;
std::size_t CsvReader::readSellersFromFile(const fs::path &filePath, Marketplace *market)
{
- csv::CSVFormat format;
- format.delimiter(';');
#if defined(_WIN64) || defined(_WIN32)
// Windows: Somhow this is necessary in order to open file names with umlauts
auto wide = filePath.wstring();
std::string fileName(wide.begin(), wide.end());
- csv::CSVReader csvReader(fileName, format);
+ std::ifstream infile(fileName);
#else
- csv::CSVReader csvReader(filePath.string(), format);
+ // csv::CSVReader csvReader(filePath.string(), format);
+ std::ifstream infile(filePath.string());
#endif
for (auto &seller : market->getSellers()) {
@@ -32,28 +32,35 @@ std::size_t CsvReader::readSellersFromFile(const fs::path &filePath, Marketplace
market->storeToDb(true);
- for (csv::CSVRow &row : csvReader) {
- if (!row[0].is_int()) {
+ std::string line;
+
+ while (getline(infile, line)) {
+ std::vector strs;
+ boost::split(strs, line, boost::is_any_of(";"));
+
+ auto seller = std::make_unique();
+
+ try {
+ int sellerNo = std::stoi(strs[0]);
+ seller->setSellerNo(sellerNo);
+ } catch (std::invalid_argument const &ex) {
continue;
}
- auto seller = std::make_unique();
- seller->setSellerNo(row[0].get());
- if (row[1].is_int()) {
- seller->setNumArticlesOffered(row[1].get());
- } else {
+ if (isNumber(strs[1]))
+ seller->setNumArticlesOffered(std::stoi(strs[1]));
+ else
seller->setNumArticlesOffered(0);
- }
// If both, first name and last name, are empty, use N. N.
// Else, use the real values.
- if (row[2].get().empty() && row[3].get().empty()) {
+ if (strs[2].empty() && strs[2].empty()) {
seller->setFirstName("N.");
seller->setLastName("N.");
} else {
- std::string firstName = row[2].get();
+ std::string firstName = strs[2];
seller->setFirstName(trim(firstName));
- std::string lastName = row[3].get();
+ std::string lastName = strs[3];
seller->setLastName(trim(lastName));
}
diff --git a/src/core/database.cpp b/src/core/database.cpp
index 863bc5d..d6b7384 100644
--- a/src/core/database.cpp
+++ b/src/core/database.cpp
@@ -2,7 +2,7 @@
#include
#include
-#include
+#include
#include
#include
#include
@@ -47,7 +47,7 @@ void Database::newDb()
fs::path destPath = sourcePath.parent_path() / sourcePath.stem();
auto chronoTime = std::chrono::system_clock::now();
- std::string timeString = fmt::format("{0:%FT%H-%M-%S}", chronoTime);
+ std::string timeString = std::format("{0:%FT%H-%M-%S}", chronoTime);
destPath += std::string("_") += timeString += ".db";
diff --git a/src/core/excelreader.cpp b/src/core/excelreader.cpp
deleted file mode 100644
index f2d9372..0000000
--- a/src/core/excelreader.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "excelreader.h"
-#include "utils.h"
-
-#include
-#include
-
-namespace fs = std::filesystem;
-
-std::size_t ExcelReader::readSellersFromFile(const fs::path &filePath, Marketplace *market)
-{
- xlnt::workbook wb;
- std::ifstream mystream(filePath, std::ios::binary);
- if (!mystream.is_open()) {
- throw std::runtime_error("Could not open Excel file");
- }
- wb.load(mystream);
-
- for (auto &seller : market->getSellers()) {
- seller->setState(Seller::State::DELETE);
- }
-
- market->storeToDb(true);
- auto ws = wb.sheet_by_index(0);
-
- for (auto row : ws.rows(true)) {
- // Skip the row if the first value is not a number (= seller no)
- if (row[0].data_type() != xlnt::cell::type::number) {
- continue;
- }
-
- auto seller = std::make_unique();
- seller->setSellerNo(row[0].value());
- seller->setNumArticlesOffered(row[1].value());
-
- // If both, first name and last name, are empty, use N. N.
- // Else, use the real values.
- if (row[2].value().empty() && row[3].value().empty()) {
- seller->setFirstName("N.");
- seller->setLastName("N.");
- } else {
- std::string firstName = row[2].value();
- seller->setFirstName(trim(firstName));
- std::string lastName = row[3].value();
- seller->setLastName(trim(lastName));
- }
-
- market->getSellers().push_back(std::move(seller));
- }
-
- // Add one additional seller "RESERVE RESERVE"
- auto seller = std::make_unique();
- seller->setSellerNo(market->getNextSellerNo());
- seller->setFirstName("RESERVE");
- seller->setLastName("RESERVE");
- market->getSellers().push_back(std::move(seller));
-
- // If there was no special seller "Sonderkonto" in import data, then create one
- auto specialSeller = market->findSellerWithSellerNo(0);
- if (!specialSeller) {
- auto seller = std::make_unique();
- seller->setSellerNo(0);
- seller->setLastName("Sonderkonto");
- seller->setFirstName("Sonderkonto");
- seller->setNumArticlesOffered(0);
- market->getSellers().push_back(std::move(seller));
- }
-
- market->sortSellers();
- market->storeToDb();
-
- return market->getSellers().size() - 1; // minus 1 because we don't count the "special" seller
-}
diff --git a/src/core/excelreader.h b/src/core/excelreader.h
deleted file mode 100644
index 1d2eefd..0000000
--- a/src/core/excelreader.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef EXCEL_READER_H
-#define EXCEL_READER_H
-
-#include "marketplace.h"
-#include "seller.h"
-
-#include
-#include
-#include
-#include
-
-class ExcelReader
-{
-public:
- static std::size_t readSellersFromFile(const std::filesystem::path &filePath,
- Marketplace *market);
-};
-
-#endif
\ No newline at end of file
diff --git a/src/core/jsonutil.cpp b/src/core/jsonutil.cpp
index bd24b4e..095a7b0 100644
--- a/src/core/jsonutil.cpp
+++ b/src/core/jsonutil.cpp
@@ -102,8 +102,10 @@ void JsonUtil::importSales(const std::filesystem::path &filePath, Marketplace *m
int source_no = jsonValues["source_no"];
if (source_no == cashPointNo) {
- throw std::runtime_error("Die Kassen-Nr. der zu imporierenden Daten wird von dieser Kasse "
- "hier bereits verwendet.");
+ std::string ret = "Die Kassen-Nr. ";
+ ret += std::to_string(source_no);
+ ret += " der zu imporierenden Daten wird von dieser Kasse hier bereits verwendet.";
+ throw std::runtime_error(ret);
}
market->setSalesToDelete(jsonValues["source_no"]);
diff --git a/src/core/meson.build b/src/core/meson.build
deleted file mode 100644
index b54f484..0000000
--- a/src/core/meson.build
+++ /dev/null
@@ -1,13 +0,0 @@
-boost = dependency('boost', modules: ['date_time'], static: true)
-xlnt = dependency('xlnt')
-sqlite = dependency('sqlite3')
-
-src = ['database.cpp', 'entity.cpp', 'entityint.cpp', 'entityuuid.cpp',
- 'seller.cpp', 'article.cpp', 'sale.cpp', 'marketplace.cpp',
- 'excelreader.cpp', 'csvreader.cpp', 'jsonutil.cpp', 'utils.cpp']
-
-core_inc = include_directories('..')
-
-core_lib = static_library('core', src, dependencies: [boost, xlnt, sqlite, nlohmann_lib, csv_dep])
-
-core_dep = declare_dependency(link_with: core_lib, include_directories : core_inc)
diff --git a/src/core/utils.cpp b/src/core/utils.cpp
index 75242f3..1725924 100644
--- a/src/core/utils.cpp
+++ b/src/core/utils.cpp
@@ -2,13 +2,13 @@
#include
#include
-#include
+#include
#include
#include
#include
-using namespace fmt;
+//using namespace fmt;
std::string formatCentAsEuroString(const int cent, int width)
{
@@ -32,7 +32,7 @@ std::string formatCentAsEuroString(const int cent, int width)
#else
std::locale myLocale{"de_DE.utf8"};
#endif
- return fmt::format(myLocale, "{:{}.2Lf} €", cent / 100.0L, width);
+ return std::format(myLocale, "{:{}.2Lf} €", cent / 100.0L, width);
}
std::string <rim(std::string &str, const std::string &chars)
@@ -61,3 +61,10 @@ bool case_insensitive_match(std::string s1, std::string s2)
return true; // The strings are same
return false; // not matched
}
+
+bool isNumber(const std::string &str)
+{
+ return !str.empty() && std::find_if(str.begin(), str.end(), [](unsigned char c) {
+ return !std::isdigit(c);
+ }) == str.end();
+}
\ No newline at end of file
diff --git a/src/core/utils.h b/src/core/utils.h
index 3a9ac21..0adfd75 100644
--- a/src/core/utils.h
+++ b/src/core/utils.h
@@ -10,5 +10,6 @@ std::string <rim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
std::string &rtrim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
std::string &trim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
bool case_insensitive_match(std::string s1, std::string s2);
+bool isNumber(const std::string &str);
#endif
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index bde8dfc..edd2102 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -9,40 +9,43 @@ set(CMAKE_AUTORCC ON)
# Find the QtWidgets library
find_package(Qt6 COMPONENTS Widgets Network PrintSupport CONFIG REQUIRED)
-#find_package(Qt5Widgets CONFIG REQUIRED)
-#find_package(Qt5PrintSupport CONFIG REQUIRED)
# For SingleApplication:
-#find_package(Qt5Network CONFIG REQUIRED)
-set(QAPPLICATION_CLASS QApplication)
+set(QT_DEFAULT_MAJOR_VERSION 6 CACHE STRING "Qt version to use, defaults to 6")
+set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication")
+FetchContent_Declare(
+ SingleApplication
+ GIT_REPOSITORY https://github.com/itay-grudev/SingleApplication
+ GIT_TAG v3.5.2
+)
+FetchContent_MakeAvailable(SingleApplication)
add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
-set(GUI_SOURCES
- kima2.cpp
- mainwindow.cpp
- mainwindow.ui
- sellerdialog.cpp
- sellerdialog.ui
- sellermodel.cpp
- pricedialog.cpp
- pricedialog.ui
- basketmodel.cpp
- salemodel.cpp
- reportdialog.cpp
- reportdialog.ui
- reportmodel.cpp
- settingsdialog.cpp
- settingsdialog.ui
- ../../kima2.qrc
- ${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git/singleapplication.cpp
- ${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git/singleapplication_p.cpp
+add_executable(kima2)
+
+target_sources(kima2 PRIVATE
+ kima2.cpp
+ mainwindow.cpp
+ mainwindow.ui
+ sellerdialog.cpp
+ sellerdialog.ui
+ sellermodel.cpp
+ pricedialog.cpp
+ pricedialog.ui
+ basketmodel.cpp
+ salemodel.cpp
+ reportdialog.cpp
+ reportdialog.ui
+ reportmodel.cpp
+ settingsdialog.cpp
+ settingsdialog.ui
+ ../../kima2.qrc
+ kima2.rc
)
-add_executable(kima2 ${GUI_SOURCES} kima2.rc)
target_include_directories(kima2 PRIVATE ${PROJECT_BINARY_DIR})
-target_include_directories(kima2 PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git)
-# target_link_libraries(kima2 core printer Qt5::Widgets Qt5::PrintSupport Qt5::Network stdc++fs)
-target_link_libraries(kima2 core printer Qt::Core Qt::PrintSupport Qt::Network stdc++fs)
+
+target_link_libraries(kima2 core printer Qt::Core Qt::PrintSupport Qt::Network SingleApplication::SingleApplication)
if(WIN32)
set_target_properties(kima2 PROPERTIES LINK_FLAGS "-mwindows")
diff --git a/src/gui/kima2.cpp b/src/gui/kima2.cpp
index bd5b470..d2826bd 100644
--- a/src/gui/kima2.cpp
+++ b/src/gui/kima2.cpp
@@ -13,29 +13,22 @@
#include
#include
+using namespace Qt::Literals::StringLiterals;
+
int main(int argc, char *argv[])
{
- SingleApplication kimaApp(argc, argv);
+ SingleApplication kimaApp(argc, argv, false, SingleApplication::Mode::User | SingleApplication::ExcludeAppPath | SingleApplication::ExcludeAppVersion);
// QCoreApplication::setOrganizationName("RustySoft");
QCoreApplication::setOrganizationDomain("rustysoft.de");
QCoreApplication::setApplicationName("kima2");
- QTranslator qTranslator;
- QLocale german(QLocale::German);
-#ifdef __linux__
- bool retVal =
- qTranslator.load("qt_" + german.name(), QLibraryInfo::path(QLibraryInfo::TranslationsPath));
- if (!retVal) {
- throw std::runtime_error("Could not load translation.");
+ QTranslator qtTranslator;
+
+ if (qtTranslator.load(QLocale::system(), u"qtbase"_s, u"_"_s,
+ QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
+ kimaApp.installTranslator(&qtTranslator);
}
-#endif
-#ifdef _WIN32
- QApplication::setStyle(QStyleFactory::create("Fusion"));
- qTranslator.load("qt_" + german.name(),
- QApplication::applicationDirPath() + QDir::separator() + "translations");
-#endif
- kimaApp.installTranslator(&qTranslator);
QSettings settings{};
while (!settings.contains("global/cashPointNo")) {
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
index 526fe1b..ca9031e 100644
--- a/src/gui/mainwindow.cpp
+++ b/src/gui/mainwindow.cpp
@@ -9,7 +9,6 @@
#include
#include
-#include
#include
#include
#include
@@ -100,14 +99,13 @@ MainWindow::MainWindow()
for (auto location : locations) {
if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) {
QDesktopServices::openUrl(
- QUrl(QString("file:///") + location + QString("/Benutzerhandbuch.pdf"),
- QUrl::TolerantMode));
+ QUrl::fromLocalFile(location + QString("/Benutzerhandbuch.pdf")));
}
}
});
connect(m_ui.licenseAction, &QAction::triggered, this, [this]() {
QString licenseText(
- "Copyright © 2018-2022 Martin Brodbeck\n\n"
+ "Copyright © 2018-2025 Martin Brodbeck\n\n"
"Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der "
"zugehörigen Dokumentationen (die \"Software\") erhält, die Erlaubnis erteilt, "
"sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, "
@@ -137,12 +135,8 @@ MainWindow::MainWindow()
this->setWindowTitle("KIMA2 - Kasse Nr. " +
QSettings().value("global/cashPointNo").toString());
});
- connect(m_ui.importSellerExcelAction, &QAction::triggered, this,
- &MainWindow::onImportSellerExcelActionTriggered);
- connect(m_ui.importSellerJsonAction, &QAction::triggered, this,
- &MainWindow::onImportSellerJsonActionTriggered);
- connect(m_ui.exportSellerJsonAction, &QAction::triggered, this,
- &MainWindow::onExportSellerJsonActionTriggered);
+ connect(m_ui.importSellerAction, &QAction::triggered, this,
+ &MainWindow::onImportSellerActionTriggered);
connect(m_ui.exportSalesJsonAction, &QAction::triggered, this,
&MainWindow::onExportSalesJsonActionTriggered);
connect(m_ui.importSalesJsonAction, &QAction::triggered, this,
@@ -345,7 +339,8 @@ void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
m_ui.basketView->model()->removeRow(iter->row());
}
- m_ui.basketSumLabel->setText(m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
+ m_ui.basketSumLabel->setText(
+ m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
m_ui.sellerNoEdit->setFocus();
}
@@ -428,7 +423,8 @@ void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
dynamic_cast(m_ui.basketView->model())->cancelSale();
- m_ui.basketSumLabel->setText(m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
+ m_ui.basketSumLabel->setText(
+ m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
m_ui.sellerNoEdit->setFocus();
}
@@ -445,7 +441,7 @@ void MainWindow::onAbout()
">info@rustysoft.de>
");
}
-void MainWindow::onImportSellerExcelActionTriggered()
+void MainWindow::onImportSellerActionTriggered()
{
if (!m_marketplace->getSales().empty()) {
QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
@@ -455,9 +451,9 @@ void MainWindow::onImportSellerExcelActionTriggered()
return;
}
- auto filename = QFileDialog::getOpenFileName(
- this, "Verkäufer importieren", QString(),
- "Alle unterstützte Dateien (*.xlsx *.csv);;Excel Dateien (*.xlsx);;CSV Dateien (*.csv)");
+ auto filename =
+ QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
+ "Alle unterstützte Dateien (*.csv);;CSV Dateien (*.csv)");
if (filename.isEmpty())
return;
@@ -469,86 +465,19 @@ void MainWindow::onImportSellerExcelActionTriggered()
#endif
std::size_t numImported{};
- if (case_insensitive_match(filePath.extension().string(), std::string(".xlsx"))) {
- try {
- numImported = ExcelReader::readSellersFromFile(filePath, m_marketplace.get());
- } catch (const std::exception &e) {
- QMessageBox(QMessageBox::Icon::Critical, "Fehler beim Importieren",
- "Beim Import aus der Excel-Datei ist ein Fehler aufgetreten. "
- "Sie könnten ggf. versuchen, die Daten aus einer .csv Datei zu imporieren.",
- QMessageBox::StandardButton::Ok, this)
- .exec();
- std::cerr << e.what() << std::endl;
- return;
- }
- } else {
- numImported = CsvReader::readSellersFromFile(filePath, m_marketplace.get());
- }
+ numImported = CsvReader::readSellersFromFile(filePath, m_marketplace.get());
updateStatLabel();
using namespace std::string_literals;
std::ostringstream msg;
- msg << "Aus der Excel/CSV-Datei wurden "s << std::to_string(numImported)
+ msg << "Aus der CSV-Datei wurden "s << std::to_string(numImported)
<< " Verkäufer importiert.";
QMessageBox(QMessageBox::Icon::Information, "Verkäufer erfolgreich importiert",
msg.str().c_str(), QMessageBox::StandardButton::Ok, this)
.exec();
}
-void MainWindow::onImportSellerJsonActionTriggered()
-{
- if (!m_marketplace->getSales().empty()) {
- QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
- "Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.",
- QMessageBox::StandardButton::Ok, this)
- .exec();
- return;
- }
-
- auto filename = QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
- "JSON Dateien (*.json)");
-
- if (filename.isEmpty())
- return;
-
-#if defined(_WIN64) || defined(_WIN32)
- fs::path filePath(filename.toStdWString());
-#else
- fs::path filePath(filename.toStdString());
-#endif
-
- std::size_t numImported{};
- numImported = JsonUtil::importSellers(filePath, m_marketplace.get());
-
- updateStatLabel();
-
- using namespace std::string_literals;
- std::ostringstream msg;
- msg << "Aus der JSON-Datei wurden "s << std::to_string(numImported)
- << " Verkäufer importiert.";
- QMessageBox(QMessageBox::Icon::Information, "Verkäufer erfolgreich importiert",
- msg.str().c_str(), QMessageBox::StandardButton::Ok, this)
- .exec();
-}
-
-void MainWindow::onExportSellerJsonActionTriggered()
-{
- auto filename = QFileDialog::getSaveFileName(
- this, "Verkäufer exportieren", QString("kima2_verkaeufer.json"), "JSON Dateien (*.json)");
-
- if (filename.isEmpty())
- return;
-
-#if defined(_WIN64) || defined(_WIN32)
- fs::path filePath(filename.toStdWString());
-#else
- fs::path filePath(filename.toStdString());
-#endif
-
- JsonUtil::exportSellers(filePath, m_marketplace.get());
-}
-
void MainWindow::onExportSalesJsonActionTriggered()
{
QSettings settings;
@@ -575,27 +504,30 @@ void MainWindow::onImportSalesJsonActionTriggered()
{
QSettings settings;
- auto filename = QFileDialog::getOpenFileName(this, "Umsätze/Transaktionen importieren",
+ auto filenames = QFileDialog::getOpenFileNames(this, "Umsätze/Transaktionen importieren",
QString(), "JSON Dateien (*.json)");
- if (filename.isEmpty())
+ if (filenames.isEmpty())
return;
+ for(auto filename: filenames) {
#if defined(_WIN64) || defined(_WIN32)
- fs::path filePath(filename.toStdWString());
+ fs::path filePath(filename.toStdWString());
#else
- fs::path filePath(filename.toStdString());
+ fs::path filePath(filename.toStdString());
#endif
- delete m_ui.salesView->model();
- try {
- JsonUtil::importSales(filePath, m_marketplace.get(),
- settings.value("global/cashPointNo").toInt());
- } catch (std::runtime_error &err) {
- QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
- this)
- .exec();
+ delete m_ui.salesView->model();
+ try {
+ JsonUtil::importSales(filePath, m_marketplace.get(),
+ settings.value("global/cashPointNo").toInt());
+ } catch (std::runtime_error &err) {
+ QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
+ this)
+ .exec();
+ }
}
+
setSaleModel();
updateStatLabel();
}
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
index 1fba01a..42ac25f 100644
--- a/src/gui/mainwindow.h
+++ b/src/gui/mainwindow.h
@@ -39,9 +39,7 @@ class MainWindow : public QMainWindow
void checkSellerNo(bool ctrlPressed = false);
void onPaidButtonTriggered();
void onGivenSpinBoxValueChanged(double value);
- void onImportSellerExcelActionTriggered();
- void onImportSellerJsonActionTriggered();
- void onExportSellerJsonActionTriggered();
+ void onImportSellerActionTriggered();
void onExportSalesJsonActionTriggered();
void onImportSalesJsonActionTriggered();
void setSaleModel();
diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui
index a77a297..49ba0fc 100644
--- a/src/gui/mainwindow.ui
+++ b/src/gui/mainwindow.ui
@@ -423,7 +423,7 @@ drucken
0
0
817
- 30
+ 24
diff --git a/src/gui/meson.build b/src/gui/meson.build
deleted file mode 100644
index 18bfcee..0000000
--- a/src/gui/meson.build
+++ /dev/null
@@ -1,23 +0,0 @@
-qt5 = import('qt5')
-qt5_dep = dependency('qt5', modules: ['Core', 'Gui', 'PrintSupport', 'Network'])
-
-thread_dep = dependency('threads')
-
-
-src = ['kima2.cpp', 'mainwindow.cpp', 'sellerdialog.cpp', 'sellermodel.cpp',
- 'pricedialog.cpp', 'basketmodel.cpp', 'salemodel.cpp', 'reportdialog.cpp',
- 'reportmodel.cpp', 'settingsdialog.cpp']
-
-ui = ['mainwindow.ui', 'sellerdialog.ui', 'pricedialog.ui', 'reportdialog.ui', 'settingsdialog.ui']
-
-processed = qt5.preprocess(moc_headers : ['basketmodel.h', 'mainwindow.h', 'pricedialog.h',
- 'reportdialog.h', 'sellerdialog.h', 'settingsdialog.h',
- 'sellermodel.h', 'salemodel.h'],
- ui_files : ui,
- qresources : '../../kima2.qrc',
- dependencies: qt5_dep)
-
-kima2 = executable('kima2', sources : [src, processed],
- dependencies : [qt5_dep, singleapp_dep, core_dep, printer_dep, thread_dep],
- include_directories : [configuration_inc],
- install : true)
diff --git a/src/gui/reportdialog.cpp b/src/gui/reportdialog.cpp
index 682c737..2c13baf 100644
--- a/src/gui/reportdialog.cpp
+++ b/src/gui/reportdialog.cpp
@@ -201,7 +201,7 @@ void ReportDialog::onPrintSellerReceiptButtonClicked()
return;
auto indexes = selModel->selectedRows();
- auto &seller = m_market->getSellers().at(indexes[0].row());
+ std::ranges::sort(indexes);
auto printerDevice =
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
@@ -214,10 +214,14 @@ void ReportDialog::onPrintSellerReceiptButtonClicked()
printer = std::make_unique();
}
- if (printer->isValid())
- printer->printSellerReceipt(
- seller.get(), feeInPercent, maxFeeInEuro * 100,
- settings.value("global/commune", "Dettingen").toString().toStdString());
+ if (printer->isValid()) {
+ for (const auto &index : indexes) {
+ auto &seller = m_market->getSellers().at(index.row());
+ printer->printSellerReceipt(
+ seller.get(), feeInPercent, maxFeeInEuro * 100,
+ settings.value("global/commune", "Dettingen").toString().toStdString());
+ }
+ }
}
void ReportDialog::onReportViewSelectionChanged(const QItemSelection &selected,
diff --git a/src/gui/reportdialog.ui b/src/gui/reportdialog.ui
index d5d27b6..5ac21c8 100644
--- a/src/gui/reportdialog.ui
+++ b/src/gui/reportdialog.ui
@@ -19,7 +19,7 @@
-
- QAbstractItemView::SingleSelection
+ QAbstractItemView::ExtendedSelection
QAbstractItemView::SelectRows
diff --git a/src/meson.build b/src/meson.build
deleted file mode 100644
index 439c81e..0000000
--- a/src/meson.build
+++ /dev/null
@@ -1,3 +0,0 @@
-subdir('core')
-subdir('printer')
-subdir('gui')
diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt
index 9dfaa3e..6205d41 100644
--- a/src/printer/CMakeLists.txt
+++ b/src/printer/CMakeLists.txt
@@ -1,6 +1,6 @@
set(Boost_USE_STATIC_LIBS ON)
-find_package(Boost 1.62 REQUIRED)
+find_package(Boost 1.78 REQUIRED)
if(WIN32)
find_package(LIBUSB REQUIRED)
@@ -9,15 +9,15 @@ else()
pkg_check_modules(LibUSB REQUIRED libusb-1.0)
endif()
-set(PRINTER_SOURCES
- posprinter.cpp
- utils.cpp
+add_library(printer STATIC)
+target_sources(printer PRIVATE
+ posprinter.cpp
+ utils.cpp
)
-add_library(printer STATIC ${PRINTER_SOURCES})
if(WIN32)
target_link_libraries(printer core ${LIBUSB_1_LIBRARIES})
else()
target_link_libraries(printer core ${LibUSB_LIBRARIES})
endif()
-target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
+target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/.. ${Boost_INCLUDE_DIRS})
diff --git a/src/printer/meson.build b/src/printer/meson.build
deleted file mode 100644
index 64f0602..0000000
--- a/src/printer/meson.build
+++ /dev/null
@@ -1,9 +0,0 @@
-libusb = dependency('libusb-1.0')
-
-src = ['posprinter.cpp', 'utils.cpp']
-
-printer_inc = include_directories('..')
-
-printer_lib = static_library('printer', src, dependencies: [libusb, core_dep])
-
-printer_dep = declare_dependency(link_with : printer_lib, include_directories : printer_inc)
diff --git a/src/printer/posprinter.cpp b/src/printer/posprinter.cpp
index 368d483..61926fc 100644
--- a/src/printer/posprinter.cpp
+++ b/src/printer/posprinter.cpp
@@ -19,6 +19,8 @@ const std::string PosPrinter::Command::RIGHT_ALIGN = {0x1b, 0x61, 0x02};
const std::string PosPrinter::Command::FONT_SIZE_BIG = {0x1b, 0x21, 0x10};
const std::string PosPrinter::Command::FONT_SIZE_NORMAL = {0x1b, 0x21, 0x00};
const std::string PosPrinter::Command::FEED = {0x1b, 0x64, 0x03};
+const std::string PosPrinter::Command::PARTIAL_CUT = {0x1b, 0x69};
+const std::string PosPrinter::Command::FULL_CUT = {0x1b, 0x6d};
PosPrinter::PosPrinter() : PosPrinter(PrinterDevice()) {}
@@ -202,7 +204,7 @@ void PosPrinter::printSellerReceipt(Seller* seller, const int percent, const int
<< marketFeeAsString(seller->sumInCents(), percent, maxFeeInCent) << "\n";
commandStream << "\nAuszahlung............. "
<< paymentAsString(seller->sumInCents(), percent, maxFeeInCent) << "\n";
- commandStream << Command::FEED;
+ commandStream << Command::FEED << Command::FEED;
write(commandStream.str());
}
diff --git a/src/printer/posprinter.h b/src/printer/posprinter.h
index 4ddd083..1cdbff6 100644
--- a/src/printer/posprinter.h
+++ b/src/printer/posprinter.h
@@ -49,6 +49,8 @@ class PosPrinter
static const std::string FONT_SIZE_BIG;
static const std::string FONT_SIZE_NORMAL;
static const std::string FEED;
+ static const std::string PARTIAL_CUT;
+ static const std::string FULL_CUT;
};
private:
diff --git a/subprojects/CMakeLists.txt b/subprojects/CMakeLists.txt
deleted file mode 100644
index 6ef42eb..0000000
--- a/subprojects/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-if(NOT KIMA2_USE_EXTERNAL_JSON)
- set(JSON_BuildTests OFF CACHE INTERNAL "")
- add_subdirectory(nlohmann_json EXCLUDE_FROM_ALL)
-endif()
-#add_subdirectory(csv-parser)
diff --git a/subprojects/csv-parser b/subprojects/csv-parser
deleted file mode 160000
index ea547fd..0000000
--- a/subprojects/csv-parser
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit ea547fdb16c7baf99bd9ced5febba52cc5da3ca3
diff --git a/subprojects/nlohmann_json b/subprojects/nlohmann_json
deleted file mode 160000
index bc889af..0000000
--- a/subprojects/nlohmann_json
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bc889afb4c5bf1c0d8ee29ef35eaaf4c8bef8a5d
diff --git a/subprojects/singleapplication/meson.build b/subprojects/singleapplication/meson.build
deleted file mode 100644
index 1b43463..0000000
--- a/subprojects/singleapplication/meson.build
+++ /dev/null
@@ -1,27 +0,0 @@
-project('singleapplication')
-
-qt5 = import('qt5')
-dep_qt5 = dependency('qt5', modules: ['Core', 'Widgets', 'Network'])
-
-singleapp_inc = include_directories('singleapplication.git')
-
-singleapp_moc = qt5.preprocess(
- moc_headers: ['singleapplication.git/singleapplication.h', 'singleapplication.git/singleapplication_p.h'],
- moc_extra_arguments: ['-DQAPPLICATION_CLASS=QApplication'],
- dependencies: dep_qt5
-)
-
-singleapp_lib = static_library('SingleApplication',
- ['singleapplication.git/singleapplication.cpp', 'singleapplication.git/singleapplication_p.cpp', singleapp_moc],
- include_directories: singleapp_inc,
- cpp_args : '-DQAPPLICATION_CLASS=QApplication',
- dependencies: dep_qt5
-)
-
-singleapp_dep = declare_dependency(
- include_directories: singleapp_inc,
- link_with: singleapp_lib
-)
-
-# On windows, SingleApplication needs to be linked against advapi32. This is
-# done by adding 'advapi32' to cpp_winlibs, where it should be by default.
diff --git a/subprojects/singleapplication/singleapplication.git b/subprojects/singleapplication/singleapplication.git
deleted file mode 160000
index a3ed916..0000000
--- a/subprojects/singleapplication/singleapplication.git
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit a3ed916f591c300e97b873fde36863fa37b49fa9