From 2c61b82924747a0b7677a1f5605c3cb064f884ea Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Sun, 6 Oct 2024 19:26:44 +0300 Subject: [PATCH 01/13] Add appdata file --- packaging/CMakeLists.txt | 6 ++++- packaging/macaw.me.squawk.appdata.xml | 33 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 packaging/macaw.me.squawk.appdata.xml diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index 4965b37..4bb9c87 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -1,3 +1,7 @@ configure_file(squawk.desktop squawk.desktop COPYONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) \ No newline at end of file +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) + +configure_file(macaw.me.squawk.appdata.xml macaw.me.squawk.appdata.xml COPYONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/macaw.me.squawk.appdata.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo) diff --git a/packaging/macaw.me.squawk.appdata.xml b/packaging/macaw.me.squawk.appdata.xml new file mode 100644 index 0000000..c188496 --- /dev/null +++ b/packaging/macaw.me.squawk.appdata.xml @@ -0,0 +1,33 @@ + + + macaw.me.squawk + CC0-1.0 + GPL-3.0+ + Squawk + Desktop Qt based XMPP messenger + +

+ Squawk is a lightweight XMPP desktop messenger. + The primary objective of this project is to offer + you a fast and user-friendly messaging experience + that closely aligns with your system’s style, while + also minimizing resource consumption. +

+

+ Squawk is still at a very early stage and might not suit + everyone but you are welcome to try it out. +

+
+ macaw.me.squawk.desktop + + + https://macaw.me/projects/squawk/0.2.2.png + View XMPP contacts and conversations + + + https://macaw.me/projects/squawk/ + + squawk + + blue@macaw.me +
From 80838595413188936f95cfc8a2352824db595d8d Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Mon, 7 Oct 2024 13:45:15 +0300 Subject: [PATCH 02/13] Fix license text error --- external/simpleCrypt/simplecrypt.cpp | 2 +- external/simpleCrypt/simplecrypt.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/external/simpleCrypt/simplecrypt.cpp b/external/simpleCrypt/simplecrypt.cpp index 19a96be..093403e 100644 --- a/external/simpleCrypt/simplecrypt.cpp +++ b/external/simpleCrypt/simplecrypt.cpp @@ -19,7 +19,7 @@ DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR #######; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/external/simpleCrypt/simplecrypt.h b/external/simpleCrypt/simplecrypt.h index d75bdc2..0052618 100644 --- a/external/simpleCrypt/simplecrypt.h +++ b/external/simpleCrypt/simplecrypt.h @@ -19,7 +19,7 @@ DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR #######; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From ff9a591d6de95d75bfbe7ee0d99fad32887d2673 Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Sun, 6 Oct 2024 20:54:18 +0300 Subject: [PATCH 03/13] Private libraries directory --- core/passwordStorageEngines/wrappers/CMakeLists.txt | 2 +- plugins/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/passwordStorageEngines/wrappers/CMakeLists.txt b/core/passwordStorageEngines/wrappers/CMakeLists.txt index e8420da..432079f 100644 --- a/core/passwordStorageEngines/wrappers/CMakeLists.txt +++ b/core/passwordStorageEngines/wrappers/CMakeLists.txt @@ -1,4 +1,4 @@ add_library(kwalletWrapper SHARED kwallet.cpp) target_link_libraries(kwalletWrapper PRIVATE KF5::Wallet) -install(TARGETS kwalletWrapper LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(TARGETS kwalletWrapper LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/squawk) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 388c258..565651e 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -2,7 +2,7 @@ if (WITH_KIO) add_library(openFileManagerWindowJob SHARED openfilemanagerwindowjob.cpp) target_link_libraries(openFileManagerWindowJob PRIVATE KF5::KIOWidgets) - install(TARGETS openFileManagerWindowJob LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(TARGETS openFileManagerWindowJob LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/squawk) endif () if (WITH_KCONFIG) @@ -10,5 +10,5 @@ if (WITH_KCONFIG) target_link_libraries(colorSchemeTools PRIVATE KF5::ConfigCore) target_link_libraries(colorSchemeTools PRIVATE KF5::ConfigWidgets) - install(TARGETS colorSchemeTools LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(TARGETS colorSchemeTools LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/squawk) endif() From 3cc7db8eff99f8d414a8798f3272fd41a6ad66c8 Mon Sep 17 00:00:00 2001 From: blue Date: Sun, 27 Oct 2024 19:31:47 +0200 Subject: [PATCH 04/13] A workaround to store plugins in a subdirectory --- CMakeLists.txt | 7 ++++++- core/passwordStorageEngines/kwallet.cpp | 3 ++- core/squawk.h | 6 ++---- shared/global.cpp | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e2465cf..aa028e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.16) project(squawk VERSION 0.2.3 LANGUAGES CXX) cmake_policy(SET CMP0076 NEW) @@ -211,6 +211,11 @@ if(CMAKE_COMPILER_IS_GNUCXX) target_compile_options(squawk PRIVATE ${COMPILE_OPTIONS}) endif(CMAKE_COMPILER_IS_GNUCXX) +# I am not really sure about this solution +# This should enable plugins to be found in path like /usr/lib/squawk instead of just /usr/lib +set(PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/squawk") +add_compile_definitions(PLUGIN_PATH="${PLUGIN_PATH}") + add_subdirectory(main) add_subdirectory(core) add_subdirectory(external/simpleCrypt) diff --git a/core/passwordStorageEngines/kwallet.cpp b/core/passwordStorageEngines/kwallet.cpp index 0dfe071..c92085b 100644 --- a/core/passwordStorageEngines/kwallet.cpp +++ b/core/passwordStorageEngines/kwallet.cpp @@ -28,7 +28,8 @@ Core::PSE::KWallet::CreateFolder Core::PSE::KWallet::createFolder = 0; Core::PSE::KWallet::SetFolder Core::PSE::KWallet::setFolder = 0; Core::PSE::KWallet::SupportState Core::PSE::KWallet::sState = Core::PSE::KWallet::initial; -QLibrary Core::PSE::KWallet::lib("kwalletWrapper"); + +QLibrary Core::PSE::KWallet::lib(QString("%1/kwalletWrapper").arg(PLUGIN_PATH)); Core::PSE::KWallet::KWallet(): QObject(), diff --git a/core/squawk.h b/core/squawk.h index 2ee122e..f00500e 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -42,10 +42,8 @@ #include "passwordStorageEngines/kwallet.h" #endif -namespace Core -{ -class Squawk : public QObject -{ +namespace Core { +class Squawk : public QObject { Q_OBJECT public: diff --git a/shared/global.cpp b/shared/global.cpp index 6618426..8277ff5 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -50,12 +50,12 @@ Shared::Global* Shared::Global::instance = 0; const std::set Shared::Global::supportedImagesExts = {"png", "jpg", "webp", "jpeg", "gif", "svg"}; #ifdef WITH_KIO -QLibrary Shared::Global::openFileManagerWindowJob("openFileManagerWindowJob"); +QLibrary Shared::Global::openFileManagerWindowJob(QString("%1/openFileManagerWindowJob").arg(PLUGIN_PATH)); Shared::Global::HighlightInFileManager Shared::Global::hfm = 0; #endif #ifdef WITH_KCONFIG -QLibrary Shared::Global::colorSchemeTools("colorSchemeTools"); +QLibrary Shared::Global::colorSchemeTools(QString("%1/colorSchemeTools").arg(PLUGIN_PATH)); Shared::Global::CreatePreview Shared::Global::createPreview = 0; Shared::Global::DeletePreview Shared::Global::deletePreview = 0; Shared::Global::ColorSchemeName Shared::Global::colorSchemeName = 0; From 85ff6c25ba598695ebc0c40e8e889e7118c530f9 Mon Sep 17 00:00:00 2001 From: blue Date: Sun, 27 Oct 2024 20:02:34 +0200 Subject: [PATCH 05/13] find boos cmake new policy magick instead of convert rendering images --- CMakeLists.txt | 3 ++- main/root.cpp | 15 +++++++-------- resources/CMakeLists.txt | 33 +++++++++++++++------------------ 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa028e8..7b00bfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(squawk VERSION 0.2.3 LANGUAGES CXX) cmake_policy(SET CMP0076 NEW) cmake_policy(SET CMP0077 NEW) cmake_policy(SET CMP0079 NEW) +cmake_policy(SET CMP0167 NEW) set(CMAKE_CXX_STANDARD 17) set(QT_VERSION_MAJOR 5) @@ -33,7 +34,7 @@ option(SYSTEM_LMDBAL "Use system lmdbal lib" ON) option(WITH_KWALLET "Build KWallet support module" ON) option(WITH_KIO "Build KIO support module" ON) option(WITH_KCONFIG "Build KConfig support module" ON) -option(WITH_OMEMO "Build OMEMO support module" OFF) #it should be off by default untill I sourt the problems out +option(WITH_OMEMO "Build OMEMO support module" OFF) #it should be off by default untill I sort the problems out # Dependencies ## Qt diff --git a/main/root.cpp b/main/root.cpp index d43ae2f..87d97bb 100644 --- a/main/root.cpp +++ b/main/root.cpp @@ -58,6 +58,7 @@ Root::~Root() { delete gui; if (core != nullptr) delete core; + delete coreThread; } delete global; @@ -72,13 +73,13 @@ void Root::initializeTranslation() { bool found = false; for (QString share : shares) { found = currentTranslator.load(QLocale(), QLatin1String("squawk"), ".", share + "/l10n"); - if (found) { + if (found) break; - } } - if (!found) { + + if (!found) currentTranslator.load(QLocale(), QLatin1String("squawk"), ".", QCoreApplication::applicationDirPath()); - } + installTranslator(¤tTranslator); } @@ -94,18 +95,16 @@ bool Root::initializeSettings() { QVariant vs = settings.value("style"); if (vs.isValid()) { QString style = vs.toString().toLower(); - if (style != "system") { + if (style != "system") Shared::Global::setStyle(style); - } } if (Shared::Global::supported("colorSchemeTools")) { QVariant vt = settings.value("theme"); if (vt.isValid()) { QString theme = vt.toString(); - if (theme.toLower() != "system") { + if (theme.toLower() != "system") Shared::Global::setTheme(theme); - } } } diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 9288650..717abf2 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -3,11 +3,8 @@ target_sources(squawk PRIVATE resources.qrc) configure_file(images/logo.svg squawk.svg COPYONLY) configure_file(squawk.rc squawk.rc COPYONLY) -if(WIN32) - set(CONVERT_BIN magick convert) -else(WIN32) - set(CONVERT_BIN convert) -endif(WIN32) +set(CONVERT_BIN magick) + execute_process(COMMAND ${CONVERT_BIN} -background none -size 48x48 squawk.svg squawk48.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) execute_process(COMMAND ${CONVERT_BIN} -background none -size 64x64 squawk.svg squawk64.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) execute_process(COMMAND ${CONVERT_BIN} -background none -size 128x128 squawk.svg squawk128.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) @@ -18,20 +15,20 @@ if (WIN32) set(SQUAWK_WIN_RC "${CMAKE_CURRENT_BINARY_DIR}/squawk.rc") set(SQUAWK_WIN_RC "${SQUAWK_WIN_RC}" PARENT_SCOPE) target_sources(squawk PRIVATE ${SQUAWK_WIN_RC}) -endif(WIN32) +endif (WIN32) if (APPLE) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/icns.iconset") - execute_process(COMMAND convert -background none -size 16x16 squawk.svg icns.iconset/icon_16x16.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !32x32 squawk.svg "icns.iconset/icon_16x16@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !32x32 squawk.svg "icns.iconset/icon_32x32.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !64x64 squawk.svg "icns.iconset/icon_32x32@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !128x128 squawk.svg "icns.iconset/icon_128x128.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !256x256 squawk.svg "icns.iconset/icon_128x128@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !256x256 squawk.svg "icns.iconset/icon_256x256.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !512x512 squawk.svg "icns.iconset/icon_256x256@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !512x512 squawk.svg "icns.iconset/icon_512x512.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND convert -background none -resize !1024x1024 squawk.svg "icns.iconset/icon_512x512@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -size 16x16 squawk.svg icns.iconset/icon_16x16.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !32x32 squawk.svg "icns.iconset/icon_16x16@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !32x32 squawk.svg "icns.iconset/icon_32x32.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !64x64 squawk.svg "icns.iconset/icon_32x32@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !128x128 squawk.svg "icns.iconset/icon_128x128.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !256x256 squawk.svg "icns.iconset/icon_128x128@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !256x256 squawk.svg "icns.iconset/icon_256x256.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !512x512 squawk.svg "icns.iconset/icon_256x256@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !512x512 squawk.svg "icns.iconset/icon_512x512.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + execute_process(COMMAND ${CONVERT_BIN} -background none -resize !1024x1024 squawk.svg "icns.iconset/icon_512x512@2x.png" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) execute_process(COMMAND iconutil -c icns "icns.iconset" -o "squawk.icns" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(MACOSX_BUNDLE_ICON_FILE squawk.icns) set(MACOSX_BUNDLE_ICON_FILE ${MACOSX_BUNDLE_ICON_FILE} PARENT_SCOPE) @@ -47,8 +44,8 @@ if (APPLE) MACOSX_BUNDLE_ICON_FILE "${MACOSX_BUNDLE_ICON_FILE}" # TODO MACOSX_BUNDLE_BUNDLE_NAME "Squawk" MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/MacOSXBundleInfo.plist.in) - endif(APPLE) - endif() + endif (APPLE) + endif () endif (APPLE) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) From 9a44ae1fa59d09ae83a05149b4f16b4633ab28af Mon Sep 17 00:00:00 2001 From: blue Date: Sun, 17 Nov 2024 20:25:33 +0200 Subject: [PATCH 06/13] SimpleCrypt password jamming is now optional --- CMakeLists.txt | 9 +++++-- core/squawk.cpp | 22 ++++++++++++++--- core/squawk.h | 1 - shared/global.cpp | 44 ++++++++++++++++++--------------- shared/global.h | 2 +- ui/widgets/accounts/account.cpp | 23 +++++++++-------- 6 files changed, 62 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b00bfc..b537fe0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ option(WITH_KWALLET "Build KWallet support module" ON) option(WITH_KIO "Build KIO support module" ON) option(WITH_KCONFIG "Build KConfig support module" ON) option(WITH_OMEMO "Build OMEMO support module" OFF) #it should be off by default untill I sort the problems out +option(WITH_SIMPLE_CRYPT "Builds with SimpleCrypt to obfuscate password" ON) # Dependencies ## Qt @@ -176,13 +177,18 @@ target_link_libraries(squawk Qt${QT_VERSION_MAJOR}::Xml LMDBAL::LMDBAL QXmpp::QXmpp - simpleCrypt ) if (WITH_OMEMO) target_link_libraries(squawk PRIVATE QXmpp::Omemo) endif () +if (WITH_SIMPLE_CRYPT) + target_compile_definitions(squawk PRIVATE WITH_SIMPLE_CRYPT) + add_subdirectory(external/simpleCrypt) + target_link_libraries(squawk PRIVATE simpleCrypt) +endif () + ## Link thread libraries on Linux if(UNIX AND NOT APPLE) set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -219,7 +225,6 @@ add_compile_definitions(PLUGIN_PATH="${PLUGIN_PATH}") add_subdirectory(main) add_subdirectory(core) -add_subdirectory(external/simpleCrypt) add_subdirectory(packaging) add_subdirectory(plugins) add_subdirectory(resources) diff --git a/core/squawk.cpp b/core/squawk.cpp index 1888487..5978651 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -22,6 +22,10 @@ #include #include +#ifdef WITH_SIMPLE_CRYPT +#include "external/simpleCrypt/simplecrypt.h" +#endif + Core::Squawk::Squawk(QObject* parent): QObject(parent), accounts(), @@ -71,7 +75,6 @@ void Core::Squawk::stop() { QSettings settings; settings.beginGroup("core"); settings.beginWriteArray("accounts"); - SimpleCrypt crypto(passwordHash); for (std::deque::size_type i = 0; i < accounts.size(); ++i) { settings.setArrayIndex(i); Account* acc = accounts[i]; @@ -84,7 +87,13 @@ void Core::Squawk::stop() { password = acc->getPassword(); break; case Shared::AccountPassword::jammed: - password = crypto.encryptToString(acc->getPassword()); +#ifdef WITH_SIMPLE_CRYPT2 + password = SimpleCrypt(passwordHash).encryptToString(acc->getPassword()); +#else + qDebug() << "The password for account" << acc->getName() << "is set to be jammed, but Squawk was compiled without SimpleCrypt support"; + qDebug("Can not encode password, setting this account to always ask password mode"); + ap = Shared::AccountPassword::alwaysAsk; +#endif break; default: break; @@ -697,17 +706,24 @@ void Core::Squawk::readSettings() { settings.value("passwordType", static_cast(Shared::AccountPassword::plain)).toInt() ); + QString name = settings.value("name").toString(); QString password = settings.value("password", "").toString(); if (passwordType == Shared::AccountPassword::jammed) { +#ifdef WITH_SIMPLE_CRYPT SimpleCrypt crypto(passwordHash); password = crypto.decryptToString(password); +#else + qDebug() << "The password for account" << name << "is jammed, but Squawk was compiled without SimpleCrypt support"; + qDebug("Can not decode password, setting this account to always ask password mode"); + passwordType = Shared::AccountPassword::alwaysAsk; +#endif } addAccount( settings.value("login").toString(), settings.value("server").toString(), password, - settings.value("name").toString(), + name, settings.value("resource").toString(), settings.value("active").toBool(), passwordType diff --git a/core/squawk.h b/core/squawk.h index f00500e..8586498 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -33,7 +33,6 @@ #include "shared/global.h" #include "shared/info.h" #include "shared/clientinfo.h" -#include "external/simpleCrypt/simplecrypt.h" #include #include diff --git a/shared/global.cpp b/shared/global.cpp index 8277ff5..efa85cf 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -21,6 +21,13 @@ #include "enums.h" #include "ui/models/roster.h" + +#ifdef WITH_SIMPLE_CRYPT +#define SIMPLE_CRYPT_ENABLED true +#else +#define SIMPLE_CRYPT_ENABLED false +#endif + #ifdef WITH_OMEMO constexpr bool OMEMO_SUPPORT = true; #else @@ -36,11 +43,10 @@ QFont getFont (QFontDatabase::SystemFont type, bool bold = false, bool italic = if (factor != 1.0) { float ps = font.pointSizeF(); - if (ps != -1) { + if (ps != -1) font.setPointSizeF(ps * factor); - } else { + else font.setPointSize(font.pointSize() * factor); - } } return font; @@ -148,10 +154,11 @@ Shared::Global::Global(): smallFontMetrics(smallFont), headerFontMetrics(headerFont), titleFontMetrics(titleFont), - pluginSupport({ + optionalFeatures({ {"KWallet", false}, {"openFileManagerWindowJob", false}, - {"colorSchemeTools", false} + {"colorSchemeTools", false}, + {"simpleCryptJammedPassword", SIMPLE_CRYPT_ENABLED} }), fileCache() { @@ -197,8 +204,7 @@ Shared::Global::Global(): static const QSize defaultIconFileInfoHeight(50, 50); -Shared::Global::FileInfo Shared::Global::getFileInfo(const QString& path) -{ +Shared::Global::FileInfo Shared::Global::getFileInfo(const QString& path) { std::map::const_iterator itr = instance->fileCache.find(path); if (itr == instance->fileCache.end()) { QMimeDatabase db; @@ -275,17 +281,17 @@ QString Shared::Global::getName(EncryptionProtocol ep) { } void Shared::Global::setSupported(const QString& pluginName, bool support) { - std::map::iterator itr = instance->pluginSupport.find(pluginName); - if (itr != instance->pluginSupport.end()) { + std::map::iterator itr = instance->optionalFeatures.find(pluginName); + if (itr != instance->optionalFeatures.end()) { itr->second = support; } } bool Shared::Global::supported(const QString& pluginName) { - std::map::iterator itr = instance->pluginSupport.find(pluginName); - if (itr != instance->pluginSupport.end()) { + std::map::iterator itr = instance->optionalFeatures.find(pluginName); + if (itr != instance->optionalFeatures.end()) return itr->second; - } + return false; } @@ -325,11 +331,10 @@ void Shared::Global::highlightInFileManager(const QString& path) QString output = proc.readLine().simplified(); QString folder; - if (info.isDir()) { + if (info.isDir()) folder = info.canonicalFilePath(); - } else { + else folder = info.canonicalPath(); - } if (output.contains(dolphinReg)) { //there is a bug on current (21.04.0) dolphin, it works correct only if you already have dolphin launched @@ -389,20 +394,19 @@ void Shared::Global::setTheme(const QString& path) { } void Shared::Global::setStyle(const QString& style) { - if (style.toLower() == "system") { + if (style.toLower() == "system") QApplication::setStyle(getInstance()->defaultSystemStyle); - } else { + else QApplication::setStyle(style); - } } #define FROM_INT_INPL(Enum) \ template<> \ Enum Shared::Global::fromInt(int src) \ { \ - if (src < static_cast(Enum##Lowest) || src > static_cast(Enum##Highest)) { \ + if (src < static_cast(Enum##Lowest) || src > static_cast(Enum##Highest)) \ throw EnumOutOfRange(#Enum); \ - } \ + \ return static_cast(src); \ } \ template<> \ diff --git a/shared/global.h b/shared/global.h index 6d23c2f..627903f 100644 --- a/shared/global.h +++ b/shared/global.h @@ -135,7 +135,7 @@ namespace Shared { private: static Global* instance; - std::map pluginSupport; + std::map optionalFeatures; std::map fileCache; #ifdef WITH_KIO diff --git a/ui/widgets/accounts/account.cpp b/ui/widgets/accounts/account.cpp index 164af6c..2d70603 100644 --- a/ui/widgets/accounts/account.cpp +++ b/ui/widgets/accounts/account.cpp @@ -26,6 +26,7 @@ Account::Account(): m_ui->setupUi(this); connect(m_ui->passwordType, qOverload(&QComboBox::currentIndexChanged), this, &Account::onComboboxChange); + QStandardItemModel *model = static_cast(m_ui->passwordType->model()); for (int i = static_cast(Shared::AccountPasswordLowest); i < static_cast(Shared::AccountPasswordHighest) + 1; ++i) { Shared::AccountPassword ap = static_cast(i); @@ -34,18 +35,19 @@ Account::Account(): m_ui->passwordType->setCurrentIndex(static_cast(Shared::AccountPassword::plain)); if (!Shared::Global::supported("KWallet")) { - QStandardItemModel *model = static_cast(m_ui->passwordType->model()); QStandardItem *item = model->item(static_cast(Shared::AccountPassword::kwallet)); item->setFlags(item->flags() & ~Qt::ItemIsEnabled); } + + if (!Shared::Global::supported("simpleCryptJammedPassword")) { + QStandardItem *item = model->item(static_cast(Shared::AccountPassword::jammed)); + item->setFlags(item->flags() & ~Qt::ItemIsEnabled); + } } -Account::~Account() -{ -} +Account::~Account() {} -QMap Account::value() const -{ +QMap Account::value() const { QMap map; map["login"] = m_ui->login->text(); map["password"] = m_ui->password->text(); @@ -58,13 +60,11 @@ QMap Account::value() const return map; } -void Account::lockId() -{ +void Account::lockId() { m_ui->name->setReadOnly(true);; } -void Account::setData(const QMap& data) -{ +void Account::setData(const QMap& data) { m_ui->login->setText(data.value("login").toString()); m_ui->password->setText(data.value("password").toString()); m_ui->server->setText(data.value("server").toString()); @@ -73,8 +73,7 @@ void Account::setData(const QMap& data) m_ui->passwordType->setCurrentIndex(data.value("passwordType").toInt()); } -void Account::onComboboxChange(int index) -{ +void Account::onComboboxChange(int index) { QString description = Shared::Global::getDescription(Shared::Global::fromInt(index)); m_ui->comment->setText(description); } From 3cce057545dd654be5e41c71ba091aac512e8c20 Mon Sep 17 00:00:00 2001 From: blue Date: Mon, 18 Nov 2024 22:43:46 +0200 Subject: [PATCH 07/13] fix: omitting from attribute not to wreck the stream fix: build without kwallet --- core/handlers/messagehandler.cpp | 2 +- core/squawk.cpp | 4 ++-- core/squawk.h | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index 094f671..ae6c695 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -431,7 +431,7 @@ QMap Core::MessageHandler::getChanges(Shared::Message& data, } QXmppMessage Core::MessageHandler::createPacket(const Shared::Message& data, const QDateTime& time, const QString& originalId) const { - QXmppMessage msg(acc->getFullJid(), data.getTo(), data.getBody(), data.getThread()); + QXmppMessage msg(QString(), data.getTo(), data.getBody(), data.getThread()); QString id(data.getId()); if (originalId.size() > 0) diff --git a/core/squawk.cpp b/core/squawk.cpp index 5978651..1d1abe5 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -33,10 +33,10 @@ Core::Squawk::Squawk(QObject* parent): state(Shared::Availability::offline), network(), isInitialized(false), - clientCache(), #ifdef WITH_KWALLET - kwallet() + kwallet(), #endif + clientCache() { connect(&network, &NetworkAccess::loadFileProgress, this, &Squawk::fileProgress); connect(&network, &NetworkAccess::loadFileError, this, &Squawk::fileError); diff --git a/core/squawk.h b/core/squawk.h index 8586498..983f5ab 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -137,11 +137,12 @@ private: Shared::Availability state; NetworkAccess network; bool isInitialized; - ClientCache clientCache; #ifdef WITH_KWALLET PSE::KWallet kwallet; #endif + + ClientCache clientCache; private slots: void addAccount( From a04693e39dec21c95afd147af7022788c0b537ec Mon Sep 17 00:00:00 2001 From: blue Date: Tue, 19 Nov 2024 18:45:11 +0200 Subject: [PATCH 08/13] fix: build without KConfig is possible once more --- shared/defines.h | 5 +---- shared/global.cpp | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/shared/defines.h b/shared/defines.h index 227a714..8ead3f6 100644 --- a/shared/defines.h +++ b/shared/defines.h @@ -16,9 +16,6 @@ * along with this program. If not, see . */ -#ifndef SHARED_DEFINES_H -#define SHARED_DEFINES_H +#pragma once #define SHARED_UNUSED(x) (void)(x) - -#endif diff --git a/shared/global.cpp b/shared/global.cpp index efa85cf..362bf81 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -19,6 +19,7 @@ #include "global.h" #include +#include "defines.h" #include "enums.h" #include "ui/models/roster.h" @@ -361,27 +362,32 @@ void Shared::Global::highlightInFileManager(const QString& path) } QIcon Shared::Global::createThemePreview(const QString& path) { +#ifdef WITH_KCONFIG if (supported("colorSchemeTools")) { QIcon* icon = createPreview(path); QIcon localIcon = *icon; deletePreview(icon); return localIcon; - } else { - return QIcon(); } +#endif + + return QIcon(); } QString Shared::Global::getColorSchemeName(const QString& path) { +#ifdef WITH_KCONFIG if (supported("colorSchemeTools")) { QString res; colorSchemeName(path, res); return res; - } else { - return ""; } +#endif + + return ""; } void Shared::Global::setTheme(const QString& path) { +#ifdef WITH_KCONFIG if (supported("colorSchemeTools")) { if (path.toLower() == "system") { QApplication::setPalette(getInstance()->defaultSystemPalette); @@ -391,6 +397,10 @@ void Shared::Global::setTheme(const QString& path) { QApplication::setPalette(pallete); } } +#else + SHARED_UNUSED(path); + qDebug("setTheme() was called, but this version of squawk was compiled without KConfig support, ignoring"); +#endif } void Shared::Global::setStyle(const QString& style) { From d4cec645b5a6f7d6ef490b262c5a43e901013df6 Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 14 Dec 2024 01:53:04 +0200 Subject: [PATCH 09/13] qt6 build --- CMakeLists.txt | 41 ++- core/CMakeLists.txt | 6 +- core/account.cpp | 1 + core/components/CMakeLists.txt | 5 +- core/components/networkaccess.cpp | 4 +- core/handlers/messagehandler.cpp | 8 +- core/handlers/messagehandler.h | 3 +- core/passwordStorageEngines/CMakeLists.txt | 7 +- core/passwordStorageEngines/kwallet.h | 2 +- .../wrappers/CMakeLists.txt | 3 +- .../wrappers/kwallet.cpp | 2 +- core/squawk.cpp | 26 +- core/utils/CMakeLists.txt | 9 + core/utils/jammer.cpp | 94 +++++++ core/utils/jammer.h | 44 ++++ external/simpleCrypt/CMakeLists.txt | 10 - external/simpleCrypt/simplecrypt.cpp | 248 ------------------ external/simpleCrypt/simplecrypt.h | 226 ---------------- plugins/CMakeLists.txt | 6 +- plugins/colorschemetools.cpp | 6 +- shared/CMakeLists.txt | 5 +- shared/clientid.h | 6 +- shared/clientinfo.h | 6 +- shared/enums.h | 4 +- shared/global.cpp | 11 +- shared/messageinfo.cpp | 16 ++ shared/messageinfo.h | 4 + ui/utils/progress.cpp | 2 +- ui/widgets/accounts/account.cpp | 5 - ui/widgets/conversation.cpp | 4 +- ui/widgets/messageline/feedview.cpp | 32 ++- ui/widgets/messageline/feedview.h | 11 +- ui/widgets/messageline/messagedelegate.cpp | 2 +- ui/widgets/settings/settingslist.cpp | 35 +-- ui/widgets/settings/settingslist.h | 17 +- 35 files changed, 279 insertions(+), 632 deletions(-) create mode 100644 core/utils/CMakeLists.txt create mode 100644 core/utils/jammer.cpp create mode 100644 core/utils/jammer.h delete mode 100644 external/simpleCrypt/CMakeLists.txt delete mode 100644 external/simpleCrypt/simplecrypt.cpp delete mode 100644 external/simpleCrypt/simplecrypt.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b537fe0..a62c800 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ cmake_policy(SET CMP0079 NEW) cmake_policy(SET CMP0167 NEW) set(CMAKE_CXX_STANDARD 17) -set(QT_VERSION_MAJOR 5) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) @@ -35,7 +34,6 @@ option(WITH_KWALLET "Build KWallet support module" ON) option(WITH_KIO "Build KIO support module" ON) option(WITH_KCONFIG "Build KConfig support module" ON) option(WITH_OMEMO "Build OMEMO support module" OFF) #it should be off by default untill I sort the problems out -option(WITH_SIMPLE_CRYPT "Builds with SimpleCrypt to obfuscate password" ON) # Dependencies ## Qt @@ -69,9 +67,9 @@ endif () ## KIO if (WITH_KIO) - find_package(KF5KIO CONFIG) + find_package(KF${QT_VERSION_MAJOR}KIO CONFIG) - if (NOT KF5KIO_FOUND) + if (NOT KF${QT_VERSION_MAJOR}KIO_FOUND) set(WITH_KIO OFF) message("KIO package wasn't found, KIO support modules wouldn't be built") else () @@ -82,9 +80,9 @@ endif () ## KWallet if (WITH_KWALLET) - find_package(KF5Wallet CONFIG) + find_package(KF${QT_VERSION_MAJOR}Wallet CONFIG) - if (NOT KF5Wallet_FOUND) + if (NOT KF${QT_VERSION_MAJOR}Wallet_FOUND) set(WITH_KWALLET OFF) message("KWallet package wasn't found, KWallet support module wouldn't be built") else () @@ -95,13 +93,13 @@ endif () ## KConfig if (WITH_KCONFIG) - find_package(KF5Config CONFIG) - if (NOT KF5Config_FOUND) + find_package(KF${QT_VERSION_MAJOR}Config CONFIG) + if (NOT KF${QT_VERSION_MAJOR}Config_FOUND) set(WITH_KCONFIG OFF) message("KConfig package wasn't found, KConfig support modules wouldn't be built") else() - find_package(KF5ConfigWidgets CONFIG) - if (NOT KF5ConfigWidgets_FOUND) + find_package(KF${QT_VERSION_MAJOR}ConfigWidgets CONFIG) + if (NOT KF${QT_VERSION_MAJOR}ConfigWidgets_FOUND) set(WITH_KCONFIG OFF) message("KConfigWidgets package wasn't found, KConfigWidgets support modules wouldn't be built") else() @@ -115,12 +113,12 @@ endif() ## QXmpp if (SYSTEM_QXMPP) if (WITH_OMEMO) - find_package(QXmpp CONFIG COMPONENTS Omemo) + find_package(QXmppQt${QT_VERSION_MAJOR} CONFIG COMPONENTS Omemo) else () - find_package(QXmpp CONFIG) + find_package(QXmppQt${QT_VERSION_MAJOR} CONFIG) endif () - if (NOT QXmpp_FOUND) + if (NOT QXmppQt${QT_VERSION_MAJOR}_FOUND) set(SYSTEM_QXMPP OFF) message("QXmpp package wasn't found, trying to build with bundled QXmpp") else () @@ -152,8 +150,8 @@ endif () ## LMDBAL if (SYSTEM_LMDBAL) - find_package(lmdbal) - if (NOT lmdbal_FOUND) + find_package(lmdbalqt${QT_VERSION_MAJOR}) + if (NOT lmdbalqt${QT_VERSION_MAJOR}_FOUND) set(SYSTEM_LMDBAL OFF) message("LMDBAL package wasn't found, trying to build with bundled LMDBAL") else () @@ -163,9 +161,11 @@ else() message("Building with bundled LMDBAL") set(BUILD_STATIC ON) add_subdirectory(external/lmdbal) - add_library(LMDBAL::LMDBAL ALIAS LMDBAL) + add_library(LMDBALQT${QT_VERSION_MAJOR}::LMDBALQT${QT_VERSION_MAJOR} ALIAS LMDBAL) endif() +find_package(OpenSSL REQUIRED) + ## Linking target_link_libraries(squawk PRIVATE @@ -175,7 +175,8 @@ target_link_libraries(squawk Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Xml - LMDBAL::LMDBAL + LMDBALQT${QT_VERSION_MAJOR}::LMDBALQT${QT_VERSION_MAJOR} + OpenSSL::Crypto QXmpp::QXmpp ) @@ -183,12 +184,6 @@ if (WITH_OMEMO) target_link_libraries(squawk PRIVATE QXmpp::Omemo) endif () -if (WITH_SIMPLE_CRYPT) - target_compile_definitions(squawk PRIVATE WITH_SIMPLE_CRYPT) - add_subdirectory(external/simpleCrypt) - target_link_libraries(squawk PRIVATE simpleCrypt) -endif () - ## Link thread libraries on Linux if(UNIX AND NOT APPLE) set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index a02bfe6..8baa5ad 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -23,10 +23,7 @@ set(HEADER_FILES squawk.h ) -target_sources(squawk PRIVATE - ${SOURCE_FILES} - ${HEADER_FILES} -) +target_sources(squawk PRIVATE ${SOURCE_FILES}) target_include_directories(squawk PRIVATE ${LMDB_INCLUDE_DIRS}) @@ -34,3 +31,4 @@ add_subdirectory(handlers) add_subdirectory(passwordStorageEngines) add_subdirectory(components) add_subdirectory(delayManager) +add_subdirectory(utils) diff --git a/core/account.cpp b/core/account.cpp index 8082aeb..6143fa6 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -81,6 +81,7 @@ Core::Account::Account( config.setDomain(p_server); config.setPassword(p_password); config.setAutoAcceptSubscriptions(true); + config.setIgnoreSslErrors(true); //config.setAutoReconnectionEnabled(false); delay = new DelayManager::Manager(getBareJid()); QObject::connect(delay, &DelayManager::Manager::gotInfo, this, &Account::infoReady); diff --git a/core/components/CMakeLists.txt b/core/components/CMakeLists.txt index 77d290b..751a01f 100644 --- a/core/components/CMakeLists.txt +++ b/core/components/CMakeLists.txt @@ -12,7 +12,4 @@ set(HEADER_FILES archive.h ) -target_sources(squawk PRIVATE - ${SOURCE_FILES} - ${HEADER_FILES} -) +target_sources(squawk PRIVATE ${SOURCE_FILES}) diff --git a/core/components/networkaccess.cpp b/core/components/networkaccess.cpp index 0771dfa..59e2448 100644 --- a/core/components/networkaccess.cpp +++ b/core/components/networkaccess.cpp @@ -550,10 +550,8 @@ void Core::NetworkAccess::moveFilesDirectory(const QString& newPath) { QDir dir(currentPath); bool success = true; qDebug() << "moving" << currentPath << "to" << newPath; - for (QFileInfo fileInfo : dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System)) { - QString fileName = fileInfo.fileName(); + for (QString fileName : dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System)) success = dir.rename(fileName, newPath + QDir::separator() + fileName) && success; - } if (!success) qDebug() << "couldn't move downloads directory, most probably downloads will be broken"; diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index ae6c695..b9ae3b6 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -492,7 +492,7 @@ void Core::MessageHandler::prepareUpload(const Shared::Message& data, bool newMe QFileInfo file(path); if (file.exists() && file.isReadable()) { pendingStateMessages.insert(std::make_pair(id, jid)); - uploadingSlotsQueue.emplace_back(path, id); + uploadingSlotsQueue.emplace_back(file, id); if (uploadingSlotsQueue.size() == 1) acc->um->requestUploadSlot(file); } else { @@ -505,10 +505,10 @@ void Core::MessageHandler::onUploadSlotReceived(const QXmppHttpUploadSlotIq& slo if (uploadingSlotsQueue.size() == 0) { qDebug() << "HTTP Upload manager of account" << acc->name << "reports about success requesting upload slot, but none was requested"; } else { - const std::pair& pair = uploadingSlotsQueue.front(); + const std::pair& pair = uploadingSlotsQueue.front(); const QString& mId = pair.second; QString palJid = pendingStateMessages.at(mId); - acc->network->uploadFile({acc->name, palJid, mId}, pair.first, slot.putUrl(), slot.getUrl(), slot.putHeaders()); + acc->network->uploadFile({acc->name, palJid, mId}, pair.first.path(), slot.putUrl(), slot.getUrl(), slot.putHeaders()); uploadingSlotsQueue.pop_front(); if (uploadingSlotsQueue.size() > 0) @@ -522,7 +522,7 @@ void Core::MessageHandler::onUploadSlotRequestFailed(const QXmppHttpUploadReques qDebug() << "HTTP Upload manager of account" << acc->name << "reports about an error requesting upload slot, but none was requested"; qDebug() << err; } else { - const std::pair& pair = uploadingSlotsQueue.front(); + const std::pair& pair = uploadingSlotsQueue.front(); qDebug() << "Error requesting upload slot for file" << pair.first << "in account" << acc->name << ":" << err; handleUploadError(pendingStateMessages.at(pair.second), pair.second, err); diff --git a/core/handlers/messagehandler.h b/core/handlers/messagehandler.h index 15f99bf..917b98d 100644 --- a/core/handlers/messagehandler.h +++ b/core/handlers/messagehandler.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -81,7 +82,7 @@ private: Account* acc; std::map pendingStateMessages; //key is message id, value is JID std::map pendingCorrectionMessages; //key is new mesage, value is originalOne - std::deque> uploadingSlotsQueue; + std::deque> uploadingSlotsQueue; }; } diff --git a/core/passwordStorageEngines/CMakeLists.txt b/core/passwordStorageEngines/CMakeLists.txt index 2afda3f..2a38931 100644 --- a/core/passwordStorageEngines/CMakeLists.txt +++ b/core/passwordStorageEngines/CMakeLists.txt @@ -1,9 +1,6 @@ if (WITH_KWALLET) - target_sources(squawk PRIVATE - kwallet.cpp - kwallet.h - ) + target_sources(squawk PRIVATE kwallet.cpp) add_subdirectory(wrappers) - target_include_directories(squawk PRIVATE $) + target_include_directories(squawk PRIVATE $) endif () diff --git a/core/passwordStorageEngines/kwallet.h b/core/passwordStorageEngines/kwallet.h index 28475d2..1f047e6 100644 --- a/core/passwordStorageEngines/kwallet.h +++ b/core/passwordStorageEngines/kwallet.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace Core { namespace PSE { diff --git a/core/passwordStorageEngines/wrappers/CMakeLists.txt b/core/passwordStorageEngines/wrappers/CMakeLists.txt index 432079f..6280cc0 100644 --- a/core/passwordStorageEngines/wrappers/CMakeLists.txt +++ b/core/passwordStorageEngines/wrappers/CMakeLists.txt @@ -1,4 +1,5 @@ add_library(kwalletWrapper SHARED kwallet.cpp) -target_link_libraries(kwalletWrapper PRIVATE KF5::Wallet) + +target_link_libraries(kwalletWrapper PRIVATE KF${QT_VERSION_MAJOR}::Wallet) install(TARGETS kwalletWrapper LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/squawk) diff --git a/core/passwordStorageEngines/wrappers/kwallet.cpp b/core/passwordStorageEngines/wrappers/kwallet.cpp index d899985..5c7bc99 100644 --- a/core/passwordStorageEngines/wrappers/kwallet.cpp +++ b/core/passwordStorageEngines/wrappers/kwallet.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#include +#include extern "C" KWallet::Wallet* openWallet(const QString &name, WId w, KWallet::Wallet::OpenType ot = KWallet::Wallet::Synchronous) { return KWallet::Wallet::openWallet(name, w, ot); diff --git a/core/squawk.cpp b/core/squawk.cpp index 1d1abe5..1851eb3 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -22,9 +22,7 @@ #include #include -#ifdef WITH_SIMPLE_CRYPT -#include "external/simpleCrypt/simplecrypt.h" -#endif +#include "utils/jammer.h" Core::Squawk::Squawk(QObject* parent): QObject(parent), @@ -87,18 +85,14 @@ void Core::Squawk::stop() { password = acc->getPassword(); break; case Shared::AccountPassword::jammed: -#ifdef WITH_SIMPLE_CRYPT2 - password = SimpleCrypt(passwordHash).encryptToString(acc->getPassword()); -#else - qDebug() << "The password for account" << acc->getName() << "is set to be jammed, but Squawk was compiled without SimpleCrypt support"; - qDebug("Can not encode password, setting this account to always ask password mode"); - ap = Shared::AccountPassword::alwaysAsk; -#endif + password = Jammer::encrypt(acc->getPassword(), passwordHash); break; default: break; } + qDebug() << "Saving password for" << acc->getName() << password; + settings.setValue("name", acc->getName()); settings.setValue("server", acc->getServer()); settings.setValue("login", acc->getLogin()); @@ -708,16 +702,8 @@ void Core::Squawk::readSettings() { QString name = settings.value("name").toString(); QString password = settings.value("password", "").toString(); - if (passwordType == Shared::AccountPassword::jammed) { -#ifdef WITH_SIMPLE_CRYPT - SimpleCrypt crypto(passwordHash); - password = crypto.decryptToString(password); -#else - qDebug() << "The password for account" << name << "is jammed, but Squawk was compiled without SimpleCrypt support"; - qDebug("Can not decode password, setting this account to always ask password mode"); - passwordType = Shared::AccountPassword::alwaysAsk; -#endif - } + if (passwordType == Shared::AccountPassword::jammed) + password = Jammer::decrypt(password, passwordHash); addAccount( settings.value("login").toString(), diff --git a/core/utils/CMakeLists.txt b/core/utils/CMakeLists.txt new file mode 100644 index 0000000..e030130 --- /dev/null +++ b/core/utils/CMakeLists.txt @@ -0,0 +1,9 @@ +set(SOURCE_FILES + jammer.cpp +) + +set(HEADER_FILES + jammer.h +) + +target_sources(squawk PRIVATE ${SOURCE_FILES}) diff --git a/core/utils/jammer.cpp b/core/utils/jammer.cpp new file mode 100644 index 0000000..1714c6b --- /dev/null +++ b/core/utils/jammer.cpp @@ -0,0 +1,94 @@ +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "jammer.h" + +#include + +#include +#include + +struct CipherCtxDeleter { + void operator()(EVP_CIPHER_CTX* ctx) const { + EVP_CIPHER_CTX_free(ctx); + } +}; +typedef std::unique_ptr CipherCtx; + +QString Core::Jammer::encrypt(const QString& plaintext, qint64 key) { + QByteArray encryptedData = process(plaintext.toUtf8(), intToKey(key), true); + + return QString::fromUtf8(encryptedData.toHex()); +} + +QString Core::Jammer::decrypt(const QString& ciphertext, qint64 key) { + QByteArray encryptedData = QByteArray::fromHex(ciphertext.toUtf8()); + QByteArray decryptedData = process(encryptedData, intToKey(key), false); + + return QString::fromUtf8(decryptedData); +} + +std::string Core::Jammer::getOpenSSLErrorString() { + unsigned long errCode = ERR_get_error(); + if (errCode == 0) { + return "No OpenSSL error"; + } + const char *errMsg = ERR_reason_error_string(errCode); + return errMsg ? std::string(errMsg) : "Unknown OpenSSL error"; +} + +QByteArray Core::Jammer::process(const QByteArray& input, const QByteArray& key, bool encrypt) { + CipherCtx ctx(EVP_CIPHER_CTX_new()); + if (!ctx) + throw std::runtime_error("Failed to create password jammer context"); + + QByteArray output(input.size() + 16, 0); + int outputLength = 0; + int finalLength = 0; + + if (!ctx) + throw std::runtime_error("Failed to create EVP_CIPHER_CTX: " + getOpenSSLErrorString()); + + if (EVP_CipherInit_ex(ctx.get(), EVP_chacha20(), nullptr, toUChar(key), nullptr, encrypt) != 1) + throw std::runtime_error("EVP_CipherInit_ex failed. " + getOpenSSLErrorString()); + + if (EVP_CipherUpdate(ctx.get(), toUChar(output), &outputLength, toUChar(input), input.size()) != 1) + throw std::runtime_error("EVP_CipherUpdate failed. " + getOpenSSLErrorString()); + + if (EVP_CipherFinal_ex(ctx.get(), toUChar(output) + outputLength, &finalLength) != 1) + throw std::runtime_error("EVP_CipherFinal_ex failed. " + getOpenSSLErrorString()); + + output.resize(outputLength + finalLength); + + return output; +} + +QByteArray Core::Jammer::intToKey(qint64 key, int keySize) { + QByteArray keyBytes(reinterpret_cast(&key), sizeof(key)); + while (keyBytes.size() < keySize) + keyBytes.append(keyBytes); + + keyBytes.truncate(keySize); + return keyBytes; +} + +unsigned char* Core::Jammer::toUChar(QByteArray& data) { + return reinterpret_cast(data.data());} + +const unsigned char* Core::Jammer::toUChar(const QByteArray& data) { + return reinterpret_cast(data.constData());} diff --git a/core/utils/jammer.h b/core/utils/jammer.h new file mode 100644 index 0000000..456c14b --- /dev/null +++ b/core/utils/jammer.h @@ -0,0 +1,44 @@ +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +#include +#include + +namespace Core { + +class Jammer { +public: + static QString encrypt(const QString& plaintext, qint64 key); + static QString decrypt(const QString& ciphertext, qint64 key); + +private: + Jammer() = delete; + + static QByteArray process(const QByteArray& input, const QByteArray& key, bool encrypt); + static QByteArray intToKey(qint64 key, int keySize = 32); + + static unsigned char* toUChar(QByteArray& data); + static const unsigned char* toUChar(const QByteArray& data); + static std::string getOpenSSLErrorString(); +}; + +} diff --git a/external/simpleCrypt/CMakeLists.txt b/external/simpleCrypt/CMakeLists.txt deleted file mode 100644 index 5f274ba..0000000 --- a/external/simpleCrypt/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(simplecrypt LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) - -find_package(Qt5 COMPONENTS Core REQUIRED) - -add_library(simpleCrypt STATIC simplecrypt.cpp simplecrypt.h) - -target_link_libraries(simpleCrypt Qt5::Core) diff --git a/external/simpleCrypt/simplecrypt.cpp b/external/simpleCrypt/simplecrypt.cpp deleted file mode 100644 index 093403e..0000000 --- a/external/simpleCrypt/simplecrypt.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - Copyright (c) 2011, Andre Somers - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the Rathenau Instituut, Andre Somers nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "simplecrypt.h" -#include -#include -#include -#include -#include -#include - -SimpleCrypt::SimpleCrypt(): -m_key(0), -m_compressionMode(CompressionAuto), -m_protectionMode(ProtectionChecksum), -m_lastError(ErrorNoError) {} - -SimpleCrypt::SimpleCrypt(quint64 key): -m_key(key), -m_compressionMode(CompressionAuto), -m_protectionMode(ProtectionChecksum), -m_lastError(ErrorNoError) -{ - splitKey(); -} - -void SimpleCrypt::setKey(quint64 key) -{ - m_key = key; - splitKey(); -} - -void SimpleCrypt::splitKey() -{ - m_keyParts.clear(); - m_keyParts.resize(8); - for (int i=0;i<8;i++) { - quint64 part = m_key; - for (int j=i; j>0; j--) - part = part >> 8; - part = part & 0xff; - m_keyParts[i] = static_cast(part); - } -} - -QByteArray SimpleCrypt::encryptToByteArray(const QString& plaintext) -{ - QByteArray plaintextArray = plaintext.toUtf8(); - return encryptToByteArray(plaintextArray); -} - -QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext) -{ - if (m_keyParts.isEmpty()) { - qWarning() << "No key set."; - m_lastError = ErrorNoKeySet; - return QByteArray(); - } - - - QByteArray ba = plaintext; - - CryptoFlags flags = CryptoFlagNone; - if (m_compressionMode == CompressionAlways) { - ba = qCompress(ba, 9); //maximum compression - flags |= CryptoFlagCompression; - } else if (m_compressionMode == CompressionAuto) { - QByteArray compressed = qCompress(ba, 9); - if (compressed.count() < ba.count()) { - ba = compressed; - flags |= CryptoFlagCompression; - } - } - - QByteArray integrityProtection; - if (m_protectionMode == ProtectionChecksum) { - flags |= CryptoFlagChecksum; - QDataStream s(&integrityProtection, QIODevice::WriteOnly); - s << qChecksum(ba.constData(), ba.length()); - } else if (m_protectionMode == ProtectionHash) { - flags |= CryptoFlagHash; - QCryptographicHash hash(QCryptographicHash::Sha1); - hash.addData(ba); - - integrityProtection += hash.result(); - } - - //prepend a random char to the string - char randomChar = char(QRandomGenerator::global()->generate() & 0xFF); - ba = randomChar + integrityProtection + ba; - - int pos(0); - char lastChar(0); - - int cnt = ba.count(); - - while (pos < cnt) { - ba[pos] = ba.at(pos) ^ m_keyParts.at(pos % 8) ^ lastChar; - lastChar = ba.at(pos); - ++pos; - } - - QByteArray resultArray; - resultArray.append(char(0x03)); //version for future updates to algorithm - resultArray.append(char(flags)); //encryption flags - resultArray.append(ba); - - m_lastError = ErrorNoError; - return resultArray; -} - -QString SimpleCrypt::encryptToString(const QString& plaintext) -{ - QByteArray plaintextArray = plaintext.toUtf8(); - QByteArray cypher = encryptToByteArray(plaintextArray); - QString cypherString = QString::fromLatin1(cypher.toBase64()); - return cypherString; -} - -QString SimpleCrypt::encryptToString(QByteArray plaintext) -{ - QByteArray cypher = encryptToByteArray(plaintext); - QString cypherString = QString::fromLatin1(cypher.toBase64()); - return cypherString; -} - -QString SimpleCrypt::decryptToString(const QString &cyphertext) -{ - QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1()); - QByteArray plaintextArray = decryptToByteArray(cyphertextArray); - QString plaintext = QString::fromUtf8(plaintextArray, plaintextArray.size()); - - return plaintext; -} - -QString SimpleCrypt::decryptToString(QByteArray cypher) -{ - QByteArray ba = decryptToByteArray(cypher); - QString plaintext = QString::fromUtf8(ba, ba.size()); - - return plaintext; -} - -QByteArray SimpleCrypt::decryptToByteArray(const QString& cyphertext) -{ - QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1()); - QByteArray ba = decryptToByteArray(cyphertextArray); - - return ba; -} - -QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher) -{ - if (m_keyParts.isEmpty()) { - qWarning() << "No key set."; - m_lastError = ErrorNoKeySet; - return QByteArray(); - } - - QByteArray ba = cypher; - - if( cypher.count() < 3 ) - return QByteArray(); - - char version = ba.at(0); - - if (version !=3) { //we only work with version 3 - m_lastError = ErrorUnknownVersion; - qWarning() << "Invalid version or not a cyphertext."; - return QByteArray(); - } - - CryptoFlags flags = CryptoFlags(ba.at(1)); - - ba = ba.mid(2); - int pos(0); - int cnt(ba.count()); - char lastChar = 0; - - while (pos < cnt) { - char currentChar = ba[pos]; - ba[pos] = ba.at(pos) ^ lastChar ^ m_keyParts.at(pos % 8); - lastChar = currentChar; - ++pos; - } - - ba = ba.mid(1); //chop off the random number at the start - - bool integrityOk(true); - if (flags.testFlag(CryptoFlagChecksum)) { - if (ba.length() < 2) { - m_lastError = ErrorIntegrityFailed; - return QByteArray(); - } - quint16 storedChecksum; - { - QDataStream s(&ba, QIODevice::ReadOnly); - s >> storedChecksum; - } - ba = ba.mid(2); - quint16 checksum = qChecksum(ba.constData(), ba.length()); - integrityOk = (checksum == storedChecksum); - } else if (flags.testFlag(CryptoFlagHash)) { - if (ba.length() < 20) { - m_lastError = ErrorIntegrityFailed; - return QByteArray(); - } - QByteArray storedHash = ba.left(20); - ba = ba.mid(20); - QCryptographicHash hash(QCryptographicHash::Sha1); - hash.addData(ba); - integrityOk = (hash.result() == storedHash); - } - - if (!integrityOk) { - m_lastError = ErrorIntegrityFailed; - return QByteArray(); - } - - if (flags.testFlag(CryptoFlagCompression)) - ba = qUncompress(ba); - - m_lastError = ErrorNoError; - return ba; -} diff --git a/external/simpleCrypt/simplecrypt.h b/external/simpleCrypt/simplecrypt.h deleted file mode 100644 index 0052618..0000000 --- a/external/simpleCrypt/simplecrypt.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - Copyright (c) 2011, Andre Somers - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the Rathenau Instituut, Andre Somers nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SIMPLECRYPT_H -#define SIMPLECRYPT_H -#include -#include -#include -#include - -/** - @ short Simple encrypt*ion and decryption of strings and byte arrays - - This class provides a simple implementation of encryption and decryption - of strings and byte arrays. - - @warning The encryption provided by this class is NOT strong encryption. It may - help to shield things from curious eyes, but it will NOT stand up to someone - determined to break the encryption. Don't say you were not warned. - - The class uses a 64 bit key. Simply create an instance of the class, set the key, - and use the encryptToString() method to calculate an encrypted version of the input string. - To decrypt that string again, use an instance of SimpleCrypt initialized with - the same key, and call the decryptToString() method with the encrypted string. If the key - matches, the decrypted version of the string will be returned again. - - If you do not provide a key, or if something else is wrong, the encryption and - decryption function will return an empty string or will return a string containing nonsense. - lastError() will return a value indicating if the method was succesful, and if not, why not. - - SimpleCrypt is prepared for the case that the encryption and decryption - algorithm is changed in a later version, by prepending a version identifier to the cypertext. - */ -class SimpleCrypt -{ -public: - /** - CompressionMode describes if compression will be applied to the data to be - encrypted. - */ - enum CompressionMode { - CompressionAuto, /*!< Only apply compression if that results in a shorter plaintext. */ - CompressionAlways, /*!< Always apply compression. Note that for short inputs, a compression may result in longer data */ - CompressionNever /*!< Never apply compression. */ - }; - /** - IntegrityProtectionMode describes measures taken to make it possible to detect problems with the data - or wrong decryption keys. - - Measures involve adding a checksum or a cryptograhpic hash to the data to be encrypted. This - increases the length of the resulting cypertext, but makes it possible to check if the plaintext - appears to be valid after decryption. - */ - enum IntegrityProtectionMode { - ProtectionNone, /*!< The integerity of the encrypted data is not protected. It is not really possible to detect a wrong key, for instance. */ - ProtectionChecksum,/*!< A simple checksum is used to verify that the data is in order. If not, an empty string is returned. */ - ProtectionHash /*!< A cryptographic hash is used to verify the integrity of the data. This method produces a much stronger, but longer check */ - }; - /** - Error describes t*he type of error that occured. - */ - enum Error { - ErrorNoError, /*!< No error occurred. */ - ErrorNoKeySet, /*!< No key was set. You can not encrypt or decrypt without a valid key. */ - ErrorUnknownVersion, /*!< The version of this data is unknown, or the data is otherwise not valid. */ - ErrorIntegrityFailed, /*!< The integrity check of the data failed. Perhaps the wrong key was used. */ - }; - - /** - Constructor. * - - Constructs a SimpleCrypt instance without a valid key set on it. - */ - SimpleCrypt(); - /** - Constructor. * - - Constructs a SimpleCrypt instance and initializes it with the given @arg key. - */ - explicit SimpleCrypt(quint64 key); - - /** - ( Re-) initializes* the key with the given @arg key. - */ - void setKey(quint64 key); - /** - Returns true if SimpleCrypt has been initialized with a key. - */ - bool hasKey() const {return !m_keyParts.isEmpty();} - - /** - Sets the compress*ion mode to use when encrypting data. The default mode is Auto. - - Note that decryption is not influenced by this mode, as the decryption recognizes - what mode was used when encrypting. - */ - void setCompressionMode(CompressionMode mode) {m_compressionMode = mode;} - /** - Returns the CompressionMode that is currently in use. - */ - CompressionMode compressionMode() const {return m_compressionMode;} - - /** - Sets the integrity mode to use when encrypting data. The default mode is Checksum. - - Note that decryption is not influenced by this mode, as the decryption recognizes - what mode was used when encrypting. - */ - void setIntegrityProtectionMode(IntegrityProtectionMode mode) {m_protectionMode = mode;} - /** - Returns the IntegrityProtectionMode that is currently in use. - */ - IntegrityProtectionMode integrityProtectionMode() const {return m_protectionMode;} - - /** - Returns the last *error that occurred. - */ - Error lastError() const {return m_lastError;} - - /** - Encrypts the @arg* plaintext string with the key the class was initialized with, and returns - a cyphertext the result. The result is a base64 encoded version of the binary array that is the - actual result of the string, so it can be stored easily in a text format. - */ - QString encryptToString(const QString& plaintext) ; - /** - Encrypts the @arg* plaintext QByteArray with the key the class was initialized with, and returns - a cyphertext the result. The result is a base64 encoded version of the binary array that is the - actual result of the encryption, so it can be stored easily in a text format. - */ - QString encryptToString(QByteArray plaintext) ; - /** - Encrypts the @arg* plaintext string with the key the class was initialized with, and returns - a binary cyphertext in a QByteArray the result. - - This method returns a byte array, that is useable for storing a binary format. If you need - a string you can store in a text file, use encryptToString() instead. - */ - QByteArray encryptToByteArray(const QString& plaintext) ; - /** - Encrypts the @arg* plaintext QByteArray with the key the class was initialized with, and returns - a binary cyphertext in a QByteArray the result. - - This method returns a byte array, that is useable for storing a binary format. If you need - a string you can store in a text file, use encryptToString() instead. - */ - QByteArray encryptToByteArray(QByteArray plaintext) ; - - /** - Decrypts a cypher*text string encrypted with this class with the set key back to the - plain text version. - - If an error occured, such as non-matching keys between encryption and decryption, - an empty string or a string containing nonsense may be returned. - */ - QString decryptToString(const QString& cyphertext) ; - /** - Decrypts a cypher*text string encrypted with this class with the set key back to the - plain text version. - - If an error occured, such as non-matching keys between encryption and decryption, - an empty string or a string containing nonsense may be returned. - */ - QByteArray decryptToByteArray(const QString& cyphertext) ; - /** - Decrypts a cypher*text binary encrypted with this class with the set key back to the - plain text version. - - If an error occured, such as non-matching keys between encryption and decryption, - an empty string or a string containing nonsense may be returned. - */ - QString decryptToString(QByteArray cypher) ; - /** - Decrypts a cypher*text binary encrypted with this class with the set key back to the - plain text version. - - If an error occured, such as non-matching keys between encryption and decryption, - an empty string or a string containing nonsense may be returned. - */ - QByteArray decryptToByteArray(QByteArray cypher) ; - - //enum to describe options that have been used for the encryption. Currently only one, but - //that only leaves room for future extensions like adding a cryptographic hash... - enum CryptoFlag{CryptoFlagNone = 0, - CryptoFlagCompression = 0x01, - CryptoFlagChecksum = 0x02, - CryptoFlagHash = 0x04 - }; - Q_DECLARE_FLAGS(CryptoFlags, CryptoFlag); -private: - - void splitKey(); - - quint64 m_key; - QVector m_keyParts; - CompressionMode m_compressionMode; - IntegrityProtectionMode m_protectionMode; - Error m_lastError; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(SimpleCrypt::CryptoFlags) - -#endif // SimpleCrypt_H diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 565651e..9eb9070 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,14 +1,14 @@ if (WITH_KIO) add_library(openFileManagerWindowJob SHARED openfilemanagerwindowjob.cpp) - target_link_libraries(openFileManagerWindowJob PRIVATE KF5::KIOWidgets) + target_link_libraries(openFileManagerWindowJob PRIVATE KF${QT_VERSION_MAJOR}::KIOWidgets) install(TARGETS openFileManagerWindowJob LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/squawk) endif () if (WITH_KCONFIG) add_library(colorSchemeTools SHARED colorschemetools.cpp) - target_link_libraries(colorSchemeTools PRIVATE KF5::ConfigCore) - target_link_libraries(colorSchemeTools PRIVATE KF5::ConfigWidgets) + target_link_libraries(colorSchemeTools PRIVATE KF${QT_VERSION_MAJOR}::ConfigCore) + target_link_libraries(colorSchemeTools PRIVATE KF${QT_VERSION_MAJOR}::ConfigWidgets) install(TARGETS colorSchemeTools LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/squawk) endif() diff --git a/plugins/colorschemetools.cpp b/plugins/colorschemetools.cpp index ea2c23e..76eba9b 100644 --- a/plugins/colorschemetools.cpp +++ b/plugins/colorschemetools.cpp @@ -20,9 +20,9 @@ #include #include -#include -#include -#include +#include +#include +#include QPixmap createPixmap(int size, const QBrush& window, const QBrush& button, const QBrush& view, const QBrush& selection); diff --git a/shared/CMakeLists.txt b/shared/CMakeLists.txt index 2ef3970..45fcfd0 100644 --- a/shared/CMakeLists.txt +++ b/shared/CMakeLists.txt @@ -39,7 +39,4 @@ set(HEADER_FILES defines.h ) -target_sources(squawk PRIVATE - ${SOURCE_FILES} - ${HEADER_FILES} -) +target_sources(squawk PRIVATE ${SOURCE_FILES} ${HEADER_FILES}) diff --git a/shared/clientid.h b/shared/clientid.h index 5188b1c..05bed45 100644 --- a/shared/clientid.h +++ b/shared/clientid.h @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef SHARED_CLIENTID_H -#define SHARED_CLIENTID_H +#pragma once #include #include +#include namespace Shared { @@ -54,5 +54,3 @@ Q_DECLARE_METATYPE(Shared::ClientId) QDataStream& operator << (QDataStream& stream, const Shared::ClientId& info); QDataStream& operator >> (QDataStream& stream, Shared::ClientId& info); - -#endif // SHARED_CLIENTID_H diff --git a/shared/clientinfo.h b/shared/clientinfo.h index 288e9fa..ca66c6d 100644 --- a/shared/clientinfo.h +++ b/shared/clientinfo.h @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef SHARED_CLIENTINFO_H -#define SHARED_CLIENTINFO_H +#pragma once #include +#include #include #include @@ -54,5 +54,3 @@ private: QDataStream& operator << (QDataStream& stream, const Shared::ClientInfo& info); QDataStream& operator >> (QDataStream& stream, Shared::ClientInfo& info); - -#endif // SHARED_CLIENTINFO_H diff --git a/shared/enums.h b/shared/enums.h index 43d1583..6f5e9db 100644 --- a/shared/enums.h +++ b/shared/enums.h @@ -101,8 +101,8 @@ enum class Avatar { valid }; Q_ENUM_NS(Avatar) -static const Avatar AvatarHighest = Avatar::valid; -static const Avatar AvatarLowest = Avatar::empty; +static const Avatar AvatarHighest = Avatar::valid; +static const Avatar AvatarLowest = Avatar::empty; static const std::deque messageStateThemeIcons = {"state-offline", "state-sync", "state-ok", "state-error"}; diff --git a/shared/global.cpp b/shared/global.cpp index 362bf81..f0e3230 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -23,12 +23,6 @@ #include "enums.h" #include "ui/models/roster.h" -#ifdef WITH_SIMPLE_CRYPT -#define SIMPLE_CRYPT_ENABLED true -#else -#define SIMPLE_CRYPT_ENABLED false -#endif - #ifdef WITH_OMEMO constexpr bool OMEMO_SUPPORT = true; #else @@ -158,8 +152,7 @@ Shared::Global::Global(): optionalFeatures({ {"KWallet", false}, {"openFileManagerWindowJob", false}, - {"colorSchemeTools", false}, - {"simpleCryptJammedPassword", SIMPLE_CRYPT_ENABLED} + {"colorSchemeTools", false} }), fileCache() { @@ -324,7 +317,7 @@ void Shared::Global::highlightInFileManager(const QString& path) qDebug() << "requested to highlight in file manager url" << path << "but it's not supported: squawk wasn't compiled to support it, trying fallback"; #endif - QFileInfo info = path; + QFileInfo info(path); if (info.exists()) { QProcess proc; proc.start("xdg-mime", query); diff --git a/shared/messageinfo.cpp b/shared/messageinfo.cpp index 7502a6e..a26f23f 100644 --- a/shared/messageinfo.cpp +++ b/shared/messageinfo.cpp @@ -43,3 +43,19 @@ Shared::MessageInfo & Shared::MessageInfo::operator=(const Shared::MessageInfo& return *this; } + +QDataStream& operator >> (QDataStream& in, Shared::MessageInfo& info) { + in >> info.account; + in >> info.jid; + in >> info.messageId; + + return in; +} + +QDataStream& operator <<( QDataStream& out, const Shared::MessageInfo& info) { + out << info.account; + out << info.jid; + out << info.messageId; + + return out; +} diff --git a/shared/messageinfo.h b/shared/messageinfo.h index 3cf75bc..f06371b 100644 --- a/shared/messageinfo.h +++ b/shared/messageinfo.h @@ -19,6 +19,7 @@ #pragma once #include +#include namespace Shared { struct MessageInfo { @@ -34,3 +35,6 @@ struct MessageInfo { }; } + +QDataStream& operator << (QDataStream& out, const Shared::MessageInfo& info); +QDataStream& operator >> (QDataStream& in, Shared::MessageInfo& info); diff --git a/ui/utils/progress.cpp b/ui/utils/progress.cpp index 73e4d02..676376b 100644 --- a/ui/utils/progress.cpp +++ b/ui/utils/progress.cpp @@ -49,7 +49,7 @@ Progress::Progress(quint16 p_size, QWidget* parent): QGridLayout* layout = new QGridLayout(); setLayout(layout); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setVerticalSpacing(0); layout->setHorizontalSpacing(0); diff --git a/ui/widgets/accounts/account.cpp b/ui/widgets/accounts/account.cpp index 2d70603..1e2c4c7 100644 --- a/ui/widgets/accounts/account.cpp +++ b/ui/widgets/accounts/account.cpp @@ -38,11 +38,6 @@ Account::Account(): QStandardItem *item = model->item(static_cast(Shared::AccountPassword::kwallet)); item->setFlags(item->flags() & ~Qt::ItemIsEnabled); } - - if (!Shared::Global::supported("simpleCryptJammedPassword")) { - QStandardItem *item = model->item(static_cast(Shared::AccountPassword::jammed)); - item->setFlags(item->flags() & ~Qt::ItemIsEnabled); - } } Account::~Account() {} diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp index 7214a40..cedcf21 100644 --- a/ui/widgets/conversation.cpp +++ b/ui/widgets/conversation.cpp @@ -500,7 +500,7 @@ void Conversation::onFeedContext(const QPoint& pos) { } QString path = Shared::resolvePath(item->getAttachPath()); - if (path.size() > 0) { + if (!path.isEmpty()) { showMenu = true; QAction* open = contextMenu->addAction(Shared::icon("document-preview"), tr("Open")); connect(open, &QAction::triggered, [path]() { @@ -513,7 +513,7 @@ void Conversation::onFeedContext(const QPoint& pos) { }); } - bool hasAttach = item->getAttachPath() > 0 || item->getOutOfBandUrl() > 0; + bool hasAttach = !item->getAttachPath().isEmpty() || !item->getOutOfBandUrl().isEmpty(); //the only mandatory condition - is for the message to be outgoing, the rest is just a good intention on the server if (item->getOutgoing() && !hasAttach && index.row() < 100 && item->getTime().daysTo(QDateTime::currentDateTimeUtc()) < 20) { showMenu = true; diff --git a/ui/widgets/messageline/feedview.cpp b/ui/widgets/messageline/feedview.cpp index 41e4484..3c56d84 100644 --- a/ui/widgets/messageline/feedview.cpp +++ b/ui/widgets/messageline/feedview.cpp @@ -141,7 +141,15 @@ void FeedView::updateGeometries() { const QStyle* st = style(); QSize layoutBounds = maximumViewportSize(); - QStyleOptionViewItem option = viewOptions(); + + + QStyleOptionViewItem option; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + initViewItemOption(&option); +#else + option = viewOptions(); +#endif + option.rect.setHeight(maxMessageHeight); option.rect.setWidth(layoutBounds.width()); int frameAroundContents = 0; @@ -182,7 +190,7 @@ void FeedView::updateGeometries() { previousOffset += elementMargin; } lastDate = currentDate; - QSize messageSize = itemDelegate(index)->sizeHint(option, index); + QSize messageSize = itemDelegateForIndex(index)->sizeHint(option, index); uint32_t offsetX(0); if (specialDelegate) { if (index.data(Models::MessageFeed::SentByMe).toBool()) @@ -232,7 +240,7 @@ bool FeedView::tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewIt previousOffset += elementMargin; } lastDate = currentDate; - QSize messageSize = itemDelegate(index)->sizeHint(option, index); + QSize messageSize = itemDelegateForIndex(index)->sizeHint(option, index); if (previousOffset + messageSize.height() + elementMargin > totalHeight) return false; @@ -288,8 +296,14 @@ void FeedView::paintEvent(QPaintEvent* event) { } } + QStyleOptionViewItem option; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + initViewItemOption(&option); +#else + option = viewOptions(); +#endif + QPainter painter(vp); - QStyleOptionViewItem option = viewOptions(); option.features = QStyleOptionViewItem::WrapText; QPoint cursor = vp->mapFromGlobal(QCursor::pos()); @@ -319,7 +333,7 @@ void FeedView::paintEvent(QPaintEvent* event) { stripe.setWidth(viewportRect.width()); bool mouseOver = stripe.contains(cursor) && viewportRect.contains(cursor); option.state.setFlag(QStyle::State_MouseOver, mouseOver); - itemDelegate(index)->paint(&painter, option, index); + itemDelegateForIndex(index)->paint(&painter, option, index); if (!lastDate.isNull() && currentDate.daysTo(lastDate) > 0) drawDateDevider(option.rect.bottom(), lastDate, painter); @@ -380,7 +394,7 @@ void FeedView::mouseMoveEvent(QMouseEvent* event) { if (!isVisible()) return; - dragEndPoint = event->localPos().toPoint(); + dragEndPoint = event->position().toPoint(); if (mousePressed) { QPoint distance = dragStartPoint - dragEndPoint; if (distance.manhattanLength() > 5) @@ -423,7 +437,7 @@ void FeedView::mousePressEvent(QMouseEvent* event) { mousePressed = event->button() == Qt::LeftButton; if (mousePressed) { - dragStartPoint = event->localPos().toPoint(); + dragStartPoint = event->position().toPoint(); if (specialDelegate && specialModel) { MessageDelegate* del = static_cast(itemDelegate()); QString lastSelectedId = del->clearSelection(); @@ -441,7 +455,7 @@ void FeedView::mouseDoubleClickEvent(QMouseEvent* event) { QAbstractItemView::mouseDoubleClickEvent(event); mousePressed = event->button() == Qt::LeftButton; if (mousePressed) { - dragStartPoint = event->localPos().toPoint(); + dragStartPoint = event->position().toPoint(); if (specialDelegate && specialModel) { MessageDelegate* del = static_cast(itemDelegate()); QString lastSelectedId = del->clearSelection(); @@ -469,7 +483,7 @@ void FeedView::mouseReleaseEvent(QMouseEvent* event) { if (mousePressed) { if (!dragging && specialDelegate) { - QPoint point = event->localPos().toPoint(); + QPoint point = event->position().toPoint(); QModelIndex index = indexAt(point); if (index.isValid()) { QRect rect = visualRect(index); diff --git a/ui/widgets/messageline/feedview.h b/ui/widgets/messageline/feedview.h index a39afc8..19645c0 100644 --- a/ui/widgets/messageline/feedview.h +++ b/ui/widgets/messageline/feedview.h @@ -16,8 +16,7 @@ * along with this program. If not, see . */ -#ifndef FEEDVIEW_H -#define FEEDVIEW_H +#pragma once #include #include @@ -30,11 +29,7 @@ #include #include -/** - * @todo write docs - */ -class FeedView : public QAbstractItemView -{ +class FeedView : public QAbstractItemView { Q_OBJECT public: FeedView(QWidget* parent = nullptr); @@ -111,5 +106,3 @@ private: static const std::set geometryChangingRoles; }; - -#endif //FEEDVIEW_H diff --git a/ui/widgets/messageline/messagedelegate.cpp b/ui/widgets/messageline/messagedelegate.cpp index b89b438..b82a992 100644 --- a/ui/widgets/messageline/messagedelegate.cpp +++ b/ui/widgets/messageline/messagedelegate.cpp @@ -659,7 +659,7 @@ QLabel * MessageDelegate::getStatusIcon(const Models::FeedItem& data) const { QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast(data.state)])); QString tt = Shared::Global::getName(data.state); if (data.state == Shared::Message::State::error) { - if (data.error > 0) + if (data.error.size() > 0) tt += ": " + data.error; } if (result->toolTip() != tt) { //If i just assign pixmap every time unconditionally diff --git a/ui/widgets/settings/settingslist.cpp b/ui/widgets/settings/settingslist.cpp index ee2e3ed..ae071ff 100644 --- a/ui/widgets/settings/settingslist.cpp +++ b/ui/widgets/settings/settingslist.cpp @@ -21,36 +21,39 @@ SettingsList::SettingsList(QWidget* parent): QListWidget(parent), lastWidth(0) -{ +{} +SettingsList::~SettingsList() {} + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +void SettingsList::initViewItemOption(QStyleOptionViewItem* option) const { + QListWidget::initViewItemOption(option); + if (!iconSize().isValid()) + option->decorationSize.setWidth(lastWidth); + + option->rect.setWidth(lastWidth); } - -SettingsList::~SettingsList() -{ -} - -QStyleOptionViewItem SettingsList::viewOptions() const -{ +#else +QStyleOptionViewItem SettingsList::viewOptions() const { QStyleOptionViewItem option = QListWidget::viewOptions(); - if (!iconSize().isValid()) { + if (!iconSize().isValid()) option.decorationSize.setWidth(lastWidth); - } + option.rect.setWidth(lastWidth); return option; } +#endif -void SettingsList::resizeEvent(QResizeEvent* event) -{ +void SettingsList::resizeEvent(QResizeEvent* event) { lastWidth = event->size().width(); QListWidget::resizeEvent(event); } -QRect SettingsList::visualRect(const QModelIndex& index) const -{ +QRect SettingsList::visualRect(const QModelIndex& index) const { QRect res = QListWidget::visualRect(index); - if (index.isValid()) { + if (index.isValid()) res.setWidth(lastWidth); - } + return res; } diff --git a/ui/widgets/settings/settingslist.h b/ui/widgets/settings/settingslist.h index 64c9d57..14ebf55 100644 --- a/ui/widgets/settings/settingslist.h +++ b/ui/widgets/settings/settingslist.h @@ -16,29 +16,28 @@ * along with this program. If not, see . */ -#ifndef UI_SETTINGSLIST_H -#define UI_SETTINGSLIST_H +#pragma once #include #include +#include -/** - * @todo write docs - */ -class SettingsList : public QListWidget -{ +class SettingsList : public QListWidget { Q_OBJECT public: SettingsList(QWidget* parent = nullptr); ~SettingsList(); protected: +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + void initViewItemOption(QStyleOptionViewItem* option) const override; +#else QStyleOptionViewItem viewOptions() const override; +#endif + void resizeEvent(QResizeEvent * event) override; QRect visualRect(const QModelIndex & index) const override; private: int lastWidth; }; - -#endif // UI_SETTINGSLIST_H From 321f0b03c8200fa166371f5df78d6641b10e7654 Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 14 Dec 2024 18:08:50 +0200 Subject: [PATCH 10/13] Fix build for qt 5, removed some debug messages --- CHANGELOG.md | 8 ++++++ CMakeLists.txt | 2 +- README.md | 5 ++-- core/account.cpp | 4 +-- core/squawk.cpp | 2 -- packaging/Archlinux/PKGBUILD | 16 ++++++------ packaging/squawk.desktop | 2 +- ui/widgets/messageline/feedview.cpp | 39 +++++++++++++++++++++++++---- 8 files changed, 57 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ca1542..6599bb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Squawk 0.2.4 (UNRELEASED) +### Bug fixes +- messages to the mucs get sent once again + +### Improvements +- it's possible to build against Qt 6 now +- got rid of deprecated SimpleCrypt library + ## Squawk 0.2.3 (February 04, 2024) ### Bug fixes - "Add contact" and "Join conference" menu are enabled once again (pavavno)! diff --git a/CMakeLists.txt b/CMakeLists.txt index a62c800..4eb833a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(squawk VERSION 0.2.3 LANGUAGES CXX) +project(squawk VERSION 0.2.4 LANGUAGES CXX) cmake_policy(SET CMP0076 NEW) cmake_policy(SET CMP0077 NEW) diff --git a/README.md b/README.md index 655304f..08bf735 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ ### Prerequisites -- QT 5.12 *(lower versions might work but it wasn't tested)* -- CMake 3.4 or higher +- QT 5 or 6 +- CMake 3.10 or higher - qxmpp 1.1.0 or higher - LMDBAL (my own [library](https://git.macaw.me/blue/lmdbal) for lmdb) - KDE Frameworks: kwallet (optional) @@ -108,6 +108,7 @@ Here is the list of keys you can pass to configuration phase of `cmake ..`: - `WITH_KIO` - `True` builds the `KIO` capability module if `KIO` is installed and if not goes to `False`. `False` disables `KIO` support (default is `True`) - `WITH_KCONFIG` - `True` builds the `KConfig` and `KConfigWidgets` capability module if such packages are installed and if not goes to `False`. `False` disables `KConfig` and `KConfigWidgets` support (default is `True`) - `WITH_OMEMO` - `True` builds the OMEMO encryption, requires `qxmpp` of version >= 1.5.0 built with OMEMO support. `False` disables OMEMO support (default is `False`) +- `QT_VERSION_MAJOR` - `6` builds against Qt 6, `5` builds against Qt 6, corresponding version of lmdbal and qxmpp should be installed. By default it picks your system default Qt ## License diff --git a/core/account.cpp b/core/account.cpp index 6143fa6..e3d14e1 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -81,8 +81,8 @@ Core::Account::Account( config.setDomain(p_server); config.setPassword(p_password); config.setAutoAcceptSubscriptions(true); - config.setIgnoreSslErrors(true); - //config.setAutoReconnectionEnabled(false); + // config.setIgnoreSslErrors(true); + // config.setAutoReconnectionEnabled(false); delay = new DelayManager::Manager(getBareJid()); QObject::connect(delay, &DelayManager::Manager::gotInfo, this, &Account::infoReady); QObject::connect(delay, &DelayManager::Manager::gotOwnInfo, this, &Account::infoReady); diff --git a/core/squawk.cpp b/core/squawk.cpp index 1851eb3..7f04d9a 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -91,8 +91,6 @@ void Core::Squawk::stop() { break; } - qDebug() << "Saving password for" << acc->getName() << password; - settings.setValue("name", acc->getName()); settings.setValue("server", acc->getServer()); settings.setValue("login", acc->getLogin()); diff --git a/packaging/Archlinux/PKGBUILD b/packaging/Archlinux/PKGBUILD index 29ed800..86f2abf 100644 --- a/packaging/Archlinux/PKGBUILD +++ b/packaging/Archlinux/PKGBUILD @@ -1,19 +1,19 @@ # Maintainer: Yury Gubich pkgname=squawk -pkgver=0.2.3 +pkgver=0.2.4 pkgrel=1 pkgdesc="An XMPP desktop messenger, written on pure c++ (qt)" arch=('i686' 'x86_64') url="https://git.macaw.me/blue/squawk" license=('GPL3') -depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdbal' 'qxmpp-qt5') -makedepends=('cmake>=3.3' 'imagemagick' 'qt5-tools' 'boost') -optdepends=('kwallet5: secure password storage (requires rebuild)' - 'kconfig5: system themes support (requires rebuild)' - 'kconfigwidgets5: system themes support (requires rebuild)' - 'kio5: better show in folder action (requires rebuild)') +depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdbal-qt6' 'qxmpp-qt6') +makedepends=('cmake>=3.3' 'imagemagick' 'qt6-tools' 'boost') +optdepends=('kwallet6: secure password storage (requires rebuild)' + 'kconfig6: system themes support (requires rebuild)' + 'kconfigwidgets6: system themes support (requires rebuild)' + 'kio6: better show in folder action (requires rebuild)') -source=("$pkgname-$pkgver.tar.gz::https://git.macaw.me/blue/$pkgname/archive/$pkgver.tar.gz") +source=("$pkgname-$pkgver-$pkgrel.tar.gz::https://git.macaw.me/blue/$pkgname/archive/$pkgver.tar.gz") sha256sums=('SKIP') build() { cd "$srcdir/squawk" diff --git a/packaging/squawk.desktop b/packaging/squawk.desktop index ba0f13c..c64f9ab 100644 --- a/packaging/squawk.desktop +++ b/packaging/squawk.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=Application -Version=1.0 +Version=0.2.4 Name=Squawk GenericName=Instant Messenger GenericName[ru]=Мгновенные сообщения diff --git a/ui/widgets/messageline/feedview.cpp b/ui/widgets/messageline/feedview.cpp index 3c56d84..29ec9c6 100644 --- a/ui/widgets/messageline/feedview.cpp +++ b/ui/widgets/messageline/feedview.cpp @@ -190,7 +190,11 @@ void FeedView::updateGeometries() { previousOffset += elementMargin; } lastDate = currentDate; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QSize messageSize = itemDelegateForIndex(index)->sizeHint(option, index); +#else + QSize messageSize = itemDelegate(index)->sizeHint(option, index); +#endif uint32_t offsetX(0); if (specialDelegate) { if (index.data(Models::MessageFeed::SentByMe).toBool()) @@ -240,7 +244,11 @@ bool FeedView::tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewIt previousOffset += elementMargin; } lastDate = currentDate; - QSize messageSize = itemDelegateForIndex(index)->sizeHint(option, index); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QSize messageSize = itemDelegateForIndex(index)->sizeHint(option, index); +#else + QSize messageSize = itemDelegate(index)->sizeHint(option, index); +#endif if (previousOffset + messageSize.height() + elementMargin > totalHeight) return false; @@ -333,7 +341,12 @@ void FeedView::paintEvent(QPaintEvent* event) { stripe.setWidth(viewportRect.width()); bool mouseOver = stripe.contains(cursor) && viewportRect.contains(cursor); option.state.setFlag(QStyle::State_MouseOver, mouseOver); - itemDelegateForIndex(index)->paint(&painter, option, index); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + itemDelegateForIndex(index)->paint(&painter, option, index); +#else + itemDelegate(index)->paint(&painter, option, index); +#endif if (!lastDate.isNull() && currentDate.daysTo(lastDate) > 0) drawDateDevider(option.rect.bottom(), lastDate, painter); @@ -393,8 +406,12 @@ void FeedView::setAnchorHovered(Shared::Hover type) { void FeedView::mouseMoveEvent(QMouseEvent* event) { if (!isVisible()) return; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + dragEndPoint = event->position().toPoint(); +#else + dragEndPoint = event->localPos().toPoint(); +#endif - dragEndPoint = event->position().toPoint(); if (mousePressed) { QPoint distance = dragStartPoint - dragEndPoint; if (distance.manhattanLength() > 5) @@ -437,7 +454,11 @@ void FeedView::mousePressEvent(QMouseEvent* event) { mousePressed = event->button() == Qt::LeftButton; if (mousePressed) { - dragStartPoint = event->position().toPoint(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + dragStartPoint = event->position().toPoint(); +#else + dragStartPoint = event->localPos().toPoint(); +#endif if (specialDelegate && specialModel) { MessageDelegate* del = static_cast(itemDelegate()); QString lastSelectedId = del->clearSelection(); @@ -455,7 +476,11 @@ void FeedView::mouseDoubleClickEvent(QMouseEvent* event) { QAbstractItemView::mouseDoubleClickEvent(event); mousePressed = event->button() == Qt::LeftButton; if (mousePressed) { - dragStartPoint = event->position().toPoint(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + dragStartPoint = event->position().toPoint(); +#else + dragStartPoint = event->localPos().toPoint(); +#endif if (specialDelegate && specialModel) { MessageDelegate* del = static_cast(itemDelegate()); QString lastSelectedId = del->clearSelection(); @@ -483,7 +508,11 @@ void FeedView::mouseReleaseEvent(QMouseEvent* event) { if (mousePressed) { if (!dragging && specialDelegate) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QPoint point = event->position().toPoint(); +#else + QPoint point = event->localPos().toPoint(); +#endif QModelIndex index = indexAt(point); if (index.isValid()) { QRect rect = visualRect(index); From a8060b393ca606e0683f4762c9f0f163bb966430 Mon Sep 17 00:00:00 2001 From: blue Date: Sun, 9 Feb 2025 19:51:30 +0200 Subject: [PATCH 11/13] Updated LMDBAL --- external/lmdbal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/lmdbal b/external/lmdbal index d62eddc..3ae1fd1 160000 --- a/external/lmdbal +++ b/external/lmdbal @@ -1 +1 @@ -Subproject commit d62eddc47edbec9f8c071459e045578f61ab58df +Subproject commit 3ae1fd15c0f4f753227d6fd5bafa4968c7310b92 From 066ab487fcc7cb07b65548bc1785412dccd24708 Mon Sep 17 00:00:00 2001 From: blue Date: Thu, 20 Feb 2025 21:37:38 +0200 Subject: [PATCH 12/13] Defaulted to qt6, fix some deprecations --- CHANGELOG.md | 3 +- CMakeLists.txt | 15 +++--- README.md | 2 +- core/handlers/messagehandler.cpp | 49 +++++++++++++------- core/handlers/messagehandler.h | 1 + packaging/Archlinux/PKGBUILD | 2 +- ui/utils/flowlayout.cpp | 78 ++++++++++++-------------------- 7 files changed, 76 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6599bb5..44c00ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,9 @@ - messages to the mucs get sent once again ### Improvements -- it's possible to build against Qt 6 now +- it's possible to build against Qt 6 now, Qt6 is the default - got rid of deprecated SimpleCrypt library +- look up for proper stanzaID ## Squawk 0.2.3 (February 04, 2024) ### Bug fixes diff --git a/CMakeLists.txt b/CMakeLists.txt index 4eb833a..7d764ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,15 +36,18 @@ option(WITH_KCONFIG "Build KConfig support module" ON) option(WITH_OMEMO "Build OMEMO support module" OFF) #it should be off by default untill I sort the problems out # Dependencies -## Qt -if (NOT DEFINED QT_VERSION_MAJOR) - find_package(QT NAMES Qt6 Qt5 CONFIG REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core) -else () - find_package(Qt${QT_VERSION_MAJOR} CONFIG REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core) +## Qt, detect and prefer Qt6 if available +find_package(Qt6 QUIET CONFIG COMPONENTS Widgets DBus Gui Xml Network Core) +if (Qt6_FOUND) + set(QT_VERSION_MAJOR 6) +else() + find_package(Qt5 REQUIRED CONFIG COMPONENTS Widgets DBus Gui Xml Network Core) + set(QT_VERSION_MAJOR 5) endif() -find_package(Boost COMPONENTS) +message(STATUS "Building against Qt${QT_VERSION_MAJOR}") +find_package(Boost COMPONENTS) target_include_directories(squawk PRIVATE ${Boost_INCLUDE_DIRS}) ## OMEMO diff --git a/README.md b/README.md index 08bf735..b65e5e9 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ Here is the list of keys you can pass to configuration phase of `cmake ..`: - `WITH_KIO` - `True` builds the `KIO` capability module if `KIO` is installed and if not goes to `False`. `False` disables `KIO` support (default is `True`) - `WITH_KCONFIG` - `True` builds the `KConfig` and `KConfigWidgets` capability module if such packages are installed and if not goes to `False`. `False` disables `KConfig` and `KConfigWidgets` support (default is `True`) - `WITH_OMEMO` - `True` builds the OMEMO encryption, requires `qxmpp` of version >= 1.5.0 built with OMEMO support. `False` disables OMEMO support (default is `False`) -- `QT_VERSION_MAJOR` - `6` builds against Qt 6, `5` builds against Qt 6, corresponding version of lmdbal and qxmpp should be installed. By default it picks your system default Qt +- `QT_VERSION_MAJOR` - `6` builds against Qt 6, `5` builds against Qt 6, corresponding version of lmdbal and qxmpp should be installed (default is `6`) ## License diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index b9ae3b6..34f7fd1 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -164,19 +164,7 @@ bool Core::MessageHandler::handleGroupMessage(const QXmppMessage& msg, bool outg } void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing, bool forwarded, bool guessing) const { - const QDateTime& time(source.stamp()); - QString id; -#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0) - id = source.originId(); - if (id.size() == 0) - id = source.id(); - - target.setStanzaId(source.stanzaId()); - qDebug() << "initializing message with originId:" << source.originId() << ", id:" << source.id() << ", stansaId:" << source.stanzaId(); -#else - id = source.id(); -#endif - target.setId(id); + initializeIDs(target, source); QString messageId = target.getId(); if (messageId.size() == 0) { target.generateRandomId(); //TODO out of desperation, I need at least a random ID @@ -197,6 +185,7 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp if (guessing) outgoing = target.getFromJid() == acc->getBareJid(); + const QDateTime& time(source.stamp()); target.setOutgoing(outgoing); if (time.isValid()) target.setTime(time); @@ -210,6 +199,37 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp target.setOutOfBandUrl(oob); } +void Core::MessageHandler::initializeIDs(Shared::Message& target, const QXmppMessage& source) const { + QString id; +#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0) + id = source.originId(); + if (id.size() == 0) + id = source.id(); + + QString stanzaID; +#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0) + // here I'm looking preferably for id generated by myself, but if there isn't - any is better than nothing + QVector sIDs = source.stanzaIds(); + for (const QXmppStanzaId& sID : sIDs) { + bool match = sID.by == acc->getBareJid(); + if (stanzaID.isEmpty() || match) + stanzaID = sID.id; + + if (match) + break; + } +#else + stanzaID = source.stanzaId(); +#endif + target.setStanzaId(stanzaID); + qDebug() << "initializing message with originId:" << source.originId() << ", id:" << source.id() << ", stanzaId:" << stanzaID; +#else + id = source.id(); +#endif + target.setId(id); +} + + void Core::MessageHandler::logMessage(const QXmppMessage& msg, const QString& reason) { qDebug() << reason; qDebug() << "- from: " << msg.from(); @@ -219,9 +239,6 @@ void Core::MessageHandler::logMessage(const QXmppMessage& msg, const QString& re qDebug() << "- state: " << msg.state(); qDebug() << "- stamp: " << msg.stamp(); qDebug() << "- id: " << msg.id(); -#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0) - qDebug() << "- stanzaId: " << msg.stanzaId(); -#endif qDebug() << "- outOfBandUrl: " << msg.outOfBandUrl(); qDebug() << "=============================="; } diff --git a/core/handlers/messagehandler.h b/core/handlers/messagehandler.h index 917b98d..3555548 100644 --- a/core/handlers/messagehandler.h +++ b/core/handlers/messagehandler.h @@ -77,6 +77,7 @@ private: bool handlePendingMessageError(const QString& id, const QString& errorText); std::pair scheduleSending(const Shared::Message& message, const QDateTime& sendTime, const QString& originalId); bool adjustPendingMessage(const QString& messageId, const QMap& data, bool final); + void initializeIDs(Shared::Message& target, const QXmppMessage& source) const; private: Account* acc; diff --git a/packaging/Archlinux/PKGBUILD b/packaging/Archlinux/PKGBUILD index 86f2abf..0defdc3 100644 --- a/packaging/Archlinux/PKGBUILD +++ b/packaging/Archlinux/PKGBUILD @@ -6,7 +6,7 @@ pkgdesc="An XMPP desktop messenger, written on pure c++ (qt)" arch=('i686' 'x86_64') url="https://git.macaw.me/blue/squawk" license=('GPL3') -depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdbal-qt6' 'qxmpp-qt6') +depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdbal-qt6' 'qxmpp') makedepends=('cmake>=3.3' 'imagemagick' 'qt6-tools' 'boost') optdepends=('kwallet6: secure password storage (requires rebuild)' 'kconfig6: system themes support (requires rebuild)' diff --git a/ui/utils/flowlayout.cpp b/ui/utils/flowlayout.cpp index ad7715e..34f978a 100644 --- a/ui/utils/flowlayout.cpp +++ b/ui/utils/flowlayout.cpp @@ -33,96 +33,78 @@ FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing): setContentsMargins(margin, margin, margin, margin); } -FlowLayout::~FlowLayout() -{ +FlowLayout::~FlowLayout() { QLayoutItem *item; - while ((item = takeAt(0))) { + while ((item = takeAt(0))) delete item; - } } -void FlowLayout::addItem(QLayoutItem *item) -{ +void FlowLayout::addItem(QLayoutItem *item) { itemList.append(item); } -int FlowLayout::horizontalSpacing() const -{ - if (m_hSpace >= 0) { +int FlowLayout::horizontalSpacing() const { + if (m_hSpace >= 0) return m_hSpace; - } else { + else return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); - } } -int FlowLayout::verticalSpacing() const -{ - if (m_vSpace >= 0) { +int FlowLayout::verticalSpacing() const { + if (m_vSpace >= 0) return m_vSpace; - } else { + else return smartSpacing(QStyle::PM_LayoutVerticalSpacing); - } } -int FlowLayout::count() const -{ +int FlowLayout::count() const { return itemList.size(); } -QLayoutItem *FlowLayout::itemAt(int index) const -{ +QLayoutItem *FlowLayout::itemAt(int index) const { return itemList.value(index); } -QLayoutItem *FlowLayout::takeAt(int index) -{ - if (index >= 0 && index < itemList.size()) { +QLayoutItem *FlowLayout::takeAt(int index) { + if (index >= 0 && index < itemList.size()) return itemList.takeAt(index); - } + return nullptr; } -Qt::Orientations FlowLayout::expandingDirections() const -{ +Qt::Orientations FlowLayout::expandingDirections() const { return Qt::Orientations(); } -bool FlowLayout::hasHeightForWidth() const -{ +bool FlowLayout::hasHeightForWidth() const { return true; } -int FlowLayout::heightForWidth(int width) const -{ +int FlowLayout::heightForWidth(int width) const { int height = doLayout(QRect(0, 0, width, 0), true); return height; } -void FlowLayout::setGeometry(const QRect &rect) -{ +void FlowLayout::setGeometry(const QRect &rect) { QLayout::setGeometry(rect); doLayout(rect, false); } -QSize FlowLayout::sizeHint() const -{ +QSize FlowLayout::sizeHint() const { return minimumSize(); } -QSize FlowLayout::minimumSize() const -{ +QSize FlowLayout::minimumSize() const { QSize size; - for (const QLayoutItem *item : qAsConst(itemList)) { + for (const QLayoutItem *item : std::as_const(itemList)) size = size.expandedTo(item->minimumSize()); - } const QMargins margins = contentsMargins(); size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); return size; } -int FlowLayout::doLayout(const QRect &rect, bool testOnly) const -{ +int FlowLayout::doLayout(const QRect &rect, bool testOnly) const { int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); @@ -130,16 +112,16 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const int y = effectiveRect.y(); int lineHeight = 0; - for (QLayoutItem *item : qAsConst(itemList)) { + for (QLayoutItem *item : std::as_const(itemList)) { const QWidget *wid = item->widget(); int spaceX = horizontalSpacing(); - if (spaceX == -1) { + if (spaceX == -1) spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); - } + int spaceY = verticalSpacing(); - if (spaceY == -1) { + if (spaceY == -1) spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); - } + int nextX = x + item->sizeHint().width() + spaceX; if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { x = effectiveRect.x(); @@ -148,9 +130,8 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const lineHeight = 0; } - if (!testOnly) { + if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); - } x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); @@ -158,8 +139,7 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const return y + lineHeight - rect.y() + bottom; } -int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const -{ +int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const { QObject *parent = this->parent(); if (!parent) { return -1; From c147e02187361db659db292211c520c23d18a4c6 Mon Sep 17 00:00:00 2001 From: blue Date: Mon, 5 May 2025 18:20:08 +0300 Subject: [PATCH 13/13] Minor changes --- {.gitea => .forgejo}/workflows/release.yml | 0 .gitmodules | 7 ++----- CMakeLists.txt | 3 ++- external/lmdbal | 2 +- external/qxmpp | 2 +- main/root.cpp | 19 +++++++++++++------ 6 files changed, 19 insertions(+), 14 deletions(-) rename {.gitea => .forgejo}/workflows/release.yml (100%) diff --git a/.gitea/workflows/release.yml b/.forgejo/workflows/release.yml similarity index 100% rename from .gitea/workflows/release.yml rename to .forgejo/workflows/release.yml diff --git a/.gitmodules b/.gitmodules index 448dae5..3742a90 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "external/qxmpp"] path = external/qxmpp - url = https://github.com/qxmpp-project/qxmpp.git -[submodule "external/storage"] - path = external/storage - url = https://git.macaw.me/blue/storage + url = https://invent.kde.org/libraries/qxmpp/ [submodule "external/lmdbal"] path = external/lmdbal - url = gitea@git.macaw.me:blue/lmdbal.git + url = https://git.macaw.me/blue/lmdbal diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d764ac..5eb98a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,7 +207,8 @@ if(CMAKE_COMPILER_IS_GNUCXX) list(APPEND COMPILE_OPTIONS -O3) endif() if (CMAKE_BUILD_TYPE STREQUAL Debug) - list(APPEND COMPILE_OPTIONS -g) + list(APPEND COMPILE_OPTIONS -O0) + list(APPEND COMPILE_OPTIONS -g3) list(APPEND COMPILE_OPTIONS -Wall) list(APPEND COMPILE_OPTIONS -Wextra) endif() diff --git a/external/lmdbal b/external/lmdbal index 3ae1fd1..3701fb9 160000 --- a/external/lmdbal +++ b/external/lmdbal @@ -1 +1 @@ -Subproject commit 3ae1fd15c0f4f753227d6fd5bafa4968c7310b92 +Subproject commit 3701fb92a1498bd737828d8d1df63d4c4d8f02c7 diff --git a/external/qxmpp b/external/qxmpp index 0cd7379..ca1bdb3 160000 --- a/external/qxmpp +++ b/external/qxmpp @@ -1 +1 @@ -Subproject commit 0cd7379bd78aa01af7e84f2fad6269ef0c0ba49c +Subproject commit ca1bdb3e46c71ceb334e6dc52291850f0c96cb50 diff --git a/main/root.cpp b/main/root.cpp index 87d97bb..f71951c 100644 --- a/main/root.cpp +++ b/main/root.cpp @@ -64,9 +64,14 @@ Root::~Root() { delete global; } - void Root::initializeTranslation() { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + bool defaultLoaded = defaultTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::path(QLibraryInfo::TranslationsPath)); + if (!defaultLoaded) + qDebug() << "Couldn't load default translation"; +#else defaultTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); +#endif installTranslator(&defaultTranslator); QStringList shares = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); @@ -78,15 +83,17 @@ void Root::initializeTranslation() { } if (!found) - currentTranslator.load(QLocale(), QLatin1String("squawk"), ".", QCoreApplication::applicationDirPath()); + found = currentTranslator.load(QLocale(), QLatin1String("squawk"), ".", QCoreApplication::applicationDirPath()); - - installTranslator(¤tTranslator); + if (found) + installTranslator(¤tTranslator); + else + qDebug() << "Couldn't load current translation"; } void Root::initializeAppIcon() { - for (std::vector::size_type i = 0; i < appIconSizes.size(); ++i) - appIcon.addFile(":images/logo.svg", QSize(appIconSizes[i], appIconSizes[i])); + for (unsigned int appIconSize : appIconSizes) + appIcon.addFile(":images/logo.svg", QSize(appIconSize, appIconSize)); Root::setWindowIcon(appIcon); }