From feb99f287cf7ce282916c4bef8dd1bdb7d48e5cbb5b60a667504f630fc4aa26e Mon Sep 17 00:00:00 2001 From: Christophe Giboudeaux Date: Tue, 18 Jan 2022 09:47:00 +0000 Subject: [PATCH] Accepting request 946946 from home:darix:playground - added https://github.com/dtschump/gmic/commit/56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch make it search in /usr/share/gmic/ with all clients. - prepare gimp 3 support - install also the denoise data file - introduce a new gmic-data subpackage and require it from all the frontends so we can access it more easily once this is resolved: https://discuss.pixls.us/t/fixing-more-things-in-gmic-packaging/28894 - make bash-completion noarch - move shared options for all the gmic-qt versions into a define to reduce duplication - Rework patches: - drop old patches with git generated copies: - 5e34754707b78358ef818d542d1e81d008bb2d12.patch - dont-set-gmic_build.patch - gmic-krita5.patch - make-build-without-gmic-cpp.patch - new patches: - gmic-make-build-without-gmic-cpp.patch - gmic-qt-make-it-work-without-gmic-cpp.patch - krita5.patch - Update krita patch so we can apply it as normal patch without breaking other gmic-qt instances - Remove unneeded BuildRequires fftw3-devel and cmake(KF5CoreAddons) - Use simpler syntax for the pkg version comparison - enable building with Krita 5 new BR: krita-devel new patches: - 5e34754707b78358ef818d542d1e81d008bb2d12.patch - gmic-krita5.patch - Add dont-set-gmic_build.patch: Make gmic-qt flavors build without gmic.cpp. This should help with getting the new krita plugin built - enable opencv support xshm support - Add BuildRequires xorg-x11-devel - add missing files for to make the devel package work: make-build-without-gmic-cpp.patch - also track series for easier patching - Add Conflicts for krita >= 5 as it needs the intree version of gmic-qt now - Update to 3.0.1 https://discuss.pixls.us/t/on-the-road-to-3-1/28221 OBS-URL: https://build.opensuse.org/request/show/946946 OBS-URL: https://build.opensuse.org/package/show/graphics/gmic?expand=0&rev=65 --- ...340ecb1fbbe6fce87d0a5c8d35dd13359577.patch | 30 + gmic-make-build-without-gmic-cpp.patch | 34 + gmic-qt-make-it-work-without-gmic-cpp.patch | 523 +++++++ gmic.changes | 89 ++ gmic.spec | 143 +- gmic_3.0.0.tar.gz | 3 - gmic_3.0.1.tar.gz | 3 + krita5.patch | 1306 +++++++++++++++++ series | 4 + 9 files changed, 2099 insertions(+), 36 deletions(-) create mode 100644 56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch create mode 100644 gmic-make-build-without-gmic-cpp.patch create mode 100644 gmic-qt-make-it-work-without-gmic-cpp.patch delete mode 100644 gmic_3.0.0.tar.gz create mode 100644 gmic_3.0.1.tar.gz create mode 100644 krita5.patch create mode 100644 series diff --git a/56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch b/56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch new file mode 100644 index 0000000..1b17e5f --- /dev/null +++ b/56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch @@ -0,0 +1,30 @@ +From 56f7340ecb1fbbe6fce87d0a5c8d35dd13359577 Mon Sep 17 00:00:00 2001 +From: David Tschumperle +Date: Sun, 16 Jan 2022 20:52:13 +0100 +Subject: [PATCH] Add '/usr/share/gmic/' to the list of folders to explore when + trying to load resource files. + +--- + src/gmic_stdlib.gmic | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/gmic_stdlib.gmic b/src/gmic_stdlib.gmic +index 36e024f4..ce8e3eb9 100644 +--- a/src/gmic_stdlib.gmic ++++ b/src/gmic_stdlib.gmic +@@ -3765,9 +3765,13 @@ _input_glob : + path_test1=$_path_rc + path_test2=${-path_gimp}plug-ins/ + path_test3=${-path_gimp}plug-ins/gmic_gimp_qt/ +- path_test4=$g_path_unix ++ if !${-is_windows} ++ path_test4=/usr/share/gmic/ ++ path_test5=$g_path_unix ++ fi + file_found=0 +- repeat 5 ++ repeat inf ++ if ['${path_test$>}']==0 break fi + file=${path_test$>}$basename + l[] i $file file_found=1 onfail endl + if $file_found break fi diff --git a/gmic-make-build-without-gmic-cpp.patch b/gmic-make-build-without-gmic-cpp.patch new file mode 100644 index 0000000..ef9719c --- /dev/null +++ b/gmic-make-build-without-gmic-cpp.patch @@ -0,0 +1,34 @@ +Index: gmic-3.0.1/src/gmic.h +=================================================================== +--- gmic-3.0.1.orig/src/gmic.h ++++ gmic-3.0.1/src/gmic.h +@@ -258,12 +258,12 @@ inline double gmic_mp_store(const Ts *co + + #endif // #if cimg_OS==2 + ++#endif // #ifndef gmic_build ++ + // Define some special character codes used for replacement in double quoted strings. + const char gmic_dollar = 23, gmic_lbrace = 24, gmic_rbrace = 25, gmic_comma = 26, gmic_dquote = 28, + gmic_store = 29; // <- this one is only used in variable names. + +-#endif // #ifndef gmic_build +- + // Define main libgmic class 'gmic'. + //---------------------------------- + #define gmic_image cimg_library::CImg + +Index: gmic-3.0.1/CMakeLists.txt +=================================================================== +--- gmic-3.0.1.orig/CMakeLists.txt ++++ gmic-3.0.1/CMakeLists.txt +@@ -165,7 +165,7 @@ if(BUILD_LIB) + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ) +- install(FILES src/gmic.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") ++ install(FILES src/gmic.h src/CImg.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + endif() + + + diff --git a/gmic-qt-make-it-work-without-gmic-cpp.patch b/gmic-qt-make-it-work-without-gmic-cpp.patch new file mode 100644 index 0000000..d266810 --- /dev/null +++ b/gmic-qt-make-it-work-without-gmic-cpp.patch @@ -0,0 +1,523 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 5de581b..2b46de0 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -29,17 +29,24 @@ else() + message("Building for target host application: " ${GMIC_QT_HOST}) + endif() + +-if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../src/gmic.cpp") +- set (GMIC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../src" CACHE STRING "Define the path to the gmic headers") ++option(ENABLE_SYSTEM_GMIC "Find GMIC shared library installed on the system" ON) ++ ++if (ENABLE_SYSTEM_GMIC) ++ option(ENABLE_DYNAMIC_LINKING "Dynamically link the binaries to the GMIC shared library" ON) + else() ++ option(ENABLE_DYNAMIC_LINKING "Dynamically link the binaries to the GMIC shared library" OFF) ++ ++ set (GMIC_LIB_PATH "${GMIC_PATH}" CACHE STRING "Define the path to the GMIC shared library") ++ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../src/gmic.cpp") ++ set (GMIC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../src" CACHE STRING "Define the path to the gmic headers") ++ else() + set (GMIC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../gmic/src" CACHE STRING "Define the path to the gmic headers") +-endif() ++ endif() + +-message("G'MIC path: " ${GMIC_PATH}) ++ message("G'MIC path: " ${GMIC_PATH}) ++endif() + +-option(ENABLE_DYNAMIC_LINKING "Dynamically link the binaries to the GMIC shared library" OFF) + option(ENABLE_CURL "Add support for curl" ON) +-set (GMIC_LIB_PATH "${GMIC_PATH}" CACHE STRING "Define the path to the GMIC shared library") + + option(ENABLE_ASAN "Enable -fsanitize=address (if debug build)" ON) + option(ENABLE_FFTW3 "Enable FFTW3 library support" ON) +@@ -61,55 +68,57 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") + endif() + + +-# +-# Look for G'MIC repository +-# +-get_filename_component(GMIC_ABSOLUTE_PATH ${GMIC_PATH} ABSOLUTE BASEDIR ${CMAKE_SOURCE_DIR}) +-if (EXISTS ${GMIC_ABSOLUTE_PATH}/gmic.cpp) +- message("Found G'MIC repository") +-else() +- get_filename_component(TARGET_CLONE_DIR ${GMIC_ABSOLUTE_PATH}/.. ABSOLUTE) +- message("") +- message("Cannot find G'MIC repository in " ${GMIC_ABSOLUTE_PATH} ) +- message("") +- message("You should try:") +- message("") +- message(" git clone https://github.com/dtschump/gmic.git " ${TARGET_CLONE_DIR}/gmic ) +- message("") +- message(FATAL_ERROR "\nG'MIC repository not found") +-endif() ++if (NOT ENABLE_SYSTEM_GMIC) ++ # ++ # Look for G'MIC repository ++ # ++ get_filename_component(GMIC_ABSOLUTE_PATH ${GMIC_PATH} ABSOLUTE BASEDIR ${CMAKE_SOURCE_DIR}) ++ if (EXISTS ${GMIC_ABSOLUTE_PATH}/gmic.cpp) ++ message("Found G'MIC repository") ++ else() ++ get_filename_component(TARGET_CLONE_DIR ${GMIC_ABSOLUTE_PATH}/.. ABSOLUTE) ++ message("") ++ message("Cannot find G'MIC repository in " ${GMIC_ABSOLUTE_PATH} ) ++ message("") ++ message("You should try:") ++ message("") ++ message(" git clone https://github.com/dtschump/gmic.git " ${TARGET_CLONE_DIR}/gmic ) ++ message("") ++ message(FATAL_ERROR "\nG'MIC repository not found") ++ endif() + +-# +-# Look for CImg.h and gmic_stdlib_community.h +-# +-set(GMIC_FILES CImg.h gmic_stdlib_community.h) +-foreach(F ${GMIC_FILES}) ++ # ++ # Look for CImg.h and gmic_stdlib_community.h ++ # ++ set(GMIC_FILES CImg.h gmic_stdlib_community.h) ++ foreach(F ${GMIC_FILES}) + if(EXISTS ${GMIC_ABSOLUTE_PATH}/${F}) +- message("Found " ${GMIC_PATH}/${F}) ++ message("Found " ${GMIC_PATH}/${F}) + else() +- message(${F} " not found") +- execute_process(COMMAND make -C ${GMIC_ABSOLUTE_PATH} ${F}) +- if(EXISTS ${GMIC_ABSOLUTE_PATH}/${F}) ++ message(${F} " not found") ++ execute_process(COMMAND make -C ${GMIC_ABSOLUTE_PATH} ${F}) ++ if(EXISTS ${GMIC_ABSOLUTE_PATH}/${F}) + message("Found " ${GMIC_PATH}/${F}) +- else() ++ else() + message(FATAL_ERROR "\nCannot obtain " ${GMIC_PATH}/${F}) +- endif() ++ endif() + endif() +-endforeach() ++ endforeach() + +-# +-# Ensure that gmic and CImg are the same version +-# +-file(STRINGS ${GMIC_ABSOLUTE_PATH}/CImg.h CIMG_VERSION REGEX "cimg_version ") +-string(REGEX REPLACE ".*cimg_version " "" CIMG_VERSION ${CIMG_VERSION}) +-message("CImg version is [" ${CIMG_VERSION} "]") ++ # ++ # Ensure that gmic and CImg are the same version ++ # ++ file(STRINGS ${GMIC_ABSOLUTE_PATH}/CImg.h CIMG_VERSION REGEX "cimg_version ") ++ string(REGEX REPLACE ".*cimg_version " "" CIMG_VERSION ${CIMG_VERSION}) ++ message("CImg version is [" ${CIMG_VERSION} "]") + +-file(STRINGS ${GMIC_ABSOLUTE_PATH}/gmic.h GMIC_VERSION REGEX "gmic_version ") +-string(REGEX REPLACE ".*gmic_version " "" GMIC_VERSION ${GMIC_VERSION}) +-message("G'MIC version is [" ${GMIC_VERSION} "]") ++ file(STRINGS ${GMIC_ABSOLUTE_PATH}/gmic.h GMIC_VERSION REGEX "gmic_version ") ++ string(REGEX REPLACE ".*gmic_version " "" GMIC_VERSION ${GMIC_VERSION}) ++ message("G'MIC version is [" ${GMIC_VERSION} "]") + +-if (NOT(${GMIC_VERSION} EQUAL ${CIMG_VERSION})) ++ if (NOT(${GMIC_VERSION} EQUAL ${CIMG_VERSION})) + message(FATAL_ERROR "\nVersion numbers of files 'gmic.h' (" ${GMIC_VERSION} ") and 'CImg.h' (" ${CIMG_VERSION} ") mismatch") ++ endif() + endif() + + +@@ -128,6 +137,13 @@ endif() + + # Required packages + ++# ++# Gmic ++# ++if (ENABLE_SYSTEM_GMIC) ++ find_package(Gmic REQUIRED CONFIG) ++endif (ENABLE_SYSTEM_GMIC) ++ + # + # Threads + # +@@ -281,7 +297,6 @@ if(ENABLE_CURL) + endif() + endif() + +-add_definitions(-Dgmic_build) + add_definitions(-Dgmic_community) + add_definitions(-Dcimg_use_abort) + add_definitions(-Dgmic_is_parallel) +@@ -360,14 +375,19 @@ elseif (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + else() + string(REPLACE "-O2" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + string(REPLACE "-O3" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") +- set_source_files_properties(${GMIC_PATH}/gmic.cpp PROPERTIES COMPILE_FLAGS "-Ofast") ++ if (NOT ENABLE_SYSTEM_GMIC) ++ set_source_files_properties(${GMIC_PATH}/gmic.cpp PROPERTIES COMPILE_FLAGS "-Ofast") ++ endif (NOT ENABLE_SYSTEM_GMIC) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2") + endif() + else() + message(FATAL_ERROR "Build type not recognized (${CMAKE_BUILD_TYPE})") + endif() + +-include_directories(${CMAKE_SOURCE_DIR}/src ${GMIC_PATH}) ++if (NOT ENABLE_SYSTEM_GMIC) ++ include_directories(${GMIC_PATH}) ++endif (NOT ENABLE_SYSTEM_GMIC) ++include_directories(${CMAKE_SOURCE_DIR}/src) + + set (gmic_qt_SRCS + +@@ -443,11 +463,19 @@ set (gmic_qt_SRCS + src/Widgets/ProgressInfoWindow.h + src/Widgets/VisibleTagSelector.h + src/ZoomConstraint.h ++) + +- ${GMIC_PATH}/gmic.h +- ${GMIC_PATH}/CImg.h +- ${GMIC_PATH}/gmic_stdlib_community.h ++if (NOT ENABLE_SYSTEM_GMIC) ++ set(gmic_qt_SRCS ++ ${gmic_qt_SRCS} ++ ${GMIC_PATH}/gmic.h ++ ${GMIC_PATH}/CImg.h ++ ${GMIC_PATH}/gmic_stdlib_community.h ++ ) ++endif() + ++set(gmic_qt_SRCS ++ ${gmic_qt_SRCS} + src/ClickableLabel.cpp + src/Common.cpp + src/OverrideCursor.cpp +@@ -540,7 +568,9 @@ if(ENABLE_DYNAMIC_LINKING) + ${gmic_qt_LIBRARIES} + "gmic" + ) +- link_directories(${GMIC_LIB_PATH}) ++ if (NOT ENABLE_SYSTEM_GMIC) ++ link_directories(${GMIC_LIB_PATH}) ++ endif() + else(ENABLE_DYNAMIC_LINKING) + set(gmic_qt_SRCS + ${gmic_qt_SRCS} +diff --git a/gmic_qt.pro b/gmic_qt.pro +index 53308cd..bb4ae61 100644 +--- a/gmic_qt.pro ++++ b/gmic_qt.pro +@@ -68,7 +68,7 @@ equals( HOST, "gimp3" ) { + + DEFINES += cimg_use_cpp11=1 + DEFINES += cimg_use_fftw3 cimg_use_zlib +-DEFINES += gmic_build cimg_use_abort gmic_is_parallel cimg_use_curl cimg_use_png ++DEFINES += cimg_use_abort gmic_is_parallel cimg_use_curl cimg_use_png + DEFINES += cimg_appname="\\\"gmic\\\"" + + equals(TIMING, "on") { +diff --git a/src/CroppedActiveLayerProxy.cpp b/src/CroppedActiveLayerProxy.cpp +index a5ae94e..eaf3b8e 100644 +--- a/src/CroppedActiveLayerProxy.cpp ++++ b/src/CroppedActiveLayerProxy.cpp +@@ -27,6 +27,7 @@ + #include + #include "Common.h" + #include "Host/GmicQtHost.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/CroppedImageListProxy.cpp b/src/CroppedImageListProxy.cpp +index b1ae9f6..a2482d0 100644 +--- a/src/CroppedImageListProxy.cpp ++++ b/src/CroppedImageListProxy.cpp +@@ -28,6 +28,7 @@ + #include + #include "Common.h" + #include "Host/GmicQtHost.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/FilterSelector/FavesModelReader.cpp b/src/FilterSelector/FavesModelReader.cpp +index 184c95b..dfed485 100644 +--- a/src/FilterSelector/FavesModelReader.cpp ++++ b/src/FilterSelector/FavesModelReader.cpp +@@ -38,6 +38,7 @@ + #include "FilterSelector/FavesModel.h" + #include "Logger.h" + #include "Utils.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/FilterSelector/FiltersModelReader.cpp b/src/FilterSelector/FiltersModelReader.cpp +index 871efb0..277274b 100644 +--- a/src/FilterSelector/FiltersModelReader.cpp ++++ b/src/FilterSelector/FiltersModelReader.cpp +@@ -38,6 +38,7 @@ + #include "LanguageSettings.h" + #include "Logger.h" + #include "Utils.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/FilterSyncRunner.cpp b/src/FilterSyncRunner.cpp +index 1b40c4a..5d1e19a 100644 +--- a/src/FilterSyncRunner.cpp ++++ b/src/FilterSyncRunner.cpp +@@ -30,6 +30,7 @@ + #include "GmicStdlib.h" + #include "Logger.h" + #include "Misc.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/FilterThread.cpp b/src/FilterThread.cpp +index de4c2c7..aad0964 100644 +--- a/src/FilterThread.cpp ++++ b/src/FilterThread.cpp +@@ -29,6 +29,7 @@ + #include "GmicStdlib.h" + #include "Logger.h" + #include "Misc.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/GmicProcessor.cpp b/src/GmicProcessor.cpp +index e0bf1f1..98879b3 100644 +--- a/src/GmicProcessor.cpp ++++ b/src/GmicProcessor.cpp +@@ -42,6 +42,7 @@ + #include "Logger.h" + #include "Misc.h" + #include "OverrideCursor.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/GmicQt.cpp b/src/GmicQt.cpp +index e836072..5925e94 100644 +--- a/src/GmicQt.cpp ++++ b/src/GmicQt.cpp +@@ -45,6 +45,7 @@ + #include "Updater.h" + #include "Widgets/InOutPanel.h" + #include "Widgets/ProgressInfoWindow.h" ++#include "CImg.h" + #include "gmic.h" + #ifdef _IS_MACOS_ + #include +diff --git a/src/GmicStdlib.cpp b/src/GmicStdlib.cpp +index 4abe758..02ab2d0 100644 +--- a/src/GmicStdlib.cpp ++++ b/src/GmicStdlib.cpp +@@ -31,6 +31,7 @@ + #include + #include "Common.h" + #include "Utils.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/HeadlessProcessor.cpp b/src/HeadlessProcessor.cpp +index 446d1a8..930facb 100644 +--- a/src/HeadlessProcessor.cpp ++++ b/src/HeadlessProcessor.cpp +@@ -40,6 +40,7 @@ + #include "ParametersCache.h" + #include "Updater.h" + #include "Widgets/ProgressInfoWindow.h" ++#include "CImg.h" + #include "gmic.h" + + #ifdef _IS_WINDOWS_ +diff --git a/src/Host/8bf/host_8bf.cpp b/src/Host/8bf/host_8bf.cpp +index 816f10b..7bc7b09 100644 +--- a/src/Host/8bf/host_8bf.cpp ++++ b/src/Host/8bf/host_8bf.cpp +@@ -42,6 +42,7 @@ + #include "Host/GmicQtHost.h" + #include "ImageTools.h" + #include "GmicQt.h" ++#include "CImg.h" + #include "gmic.h" + + struct Gmic8bfLayer +diff --git a/src/Host/Gimp/host_gimp.cpp b/src/Host/Gimp/host_gimp.cpp +index cd19443..cd0c9c6 100644 +--- a/src/Host/Gimp/host_gimp.cpp ++++ b/src/Host/Gimp/host_gimp.cpp +@@ -38,6 +38,7 @@ + #include "Host/GmicQtHost.h" + #include "ImageTools.h" + #include "GmicQt.h" ++#include "CImg.h" + #include "gmic.h" + + /* +diff --git a/src/Host/Krita/host_krita.cpp b/src/Host/Krita/host_krita.cpp +index afb2a64..0cfc031 100644 +--- a/src/Host/Krita/host_krita.cpp ++++ b/src/Host/Krita/host_krita.cpp +@@ -41,6 +41,7 @@ + #include "Common.h" + #include "Host/GmicQtHost.h" + #include "GmicQt.h" ++#include "CImg.h" + #include "gmic.h" + + /* +diff --git a/src/Host/None/ImageDialog.cpp b/src/Host/None/ImageDialog.cpp +index 973c0ae..55bac48 100644 +--- a/src/Host/None/ImageDialog.cpp ++++ b/src/Host/None/ImageDialog.cpp +@@ -31,6 +31,7 @@ + #include + #include "Common.h" + #include "JpegQualityDialog.h" ++#include "CImg.h" + #include "gmic.h" + + namespace gmic_qt_standalone +diff --git a/src/Host/None/host_none.cpp b/src/Host/None/host_none.cpp +index 35b68ea..300e69a 100644 +--- a/src/Host/None/host_none.cpp ++++ b/src/Host/None/host_none.cpp +@@ -40,6 +40,7 @@ + #include "GmicQt.h" + #include "Host/GmicQtHost.h" + #include "Host/None/ImageDialog.h" ++#include "CImg.h" + #include "gmic.h" + + #define STRINGIFY(X) #X +diff --git a/src/Host/PaintDotNet/host_paintdotnet.cpp b/src/Host/PaintDotNet/host_paintdotnet.cpp +index 60bdab7..fe5eb3c 100644 +--- a/src/Host/PaintDotNet/host_paintdotnet.cpp ++++ b/src/Host/PaintDotNet/host_paintdotnet.cpp +@@ -33,6 +33,7 @@ + #include "Host/GmicQtHost.h" + #include "MainWindow.h" + #include "GmicQt.h" ++#include "CImg.h" + #include "gmic.h" + #include + +diff --git a/src/ImageTools.cpp b/src/ImageTools.cpp +index f27ce72..ff592b0 100644 +--- a/src/ImageTools.cpp ++++ b/src/ImageTools.cpp +@@ -27,6 +27,7 @@ + #include + #include + #include "GmicStdlib.h" ++#include "CImg.h" + #include "gmic.h" + + /* +diff --git a/src/Logger.cpp b/src/Logger.cpp +index ddff5d9..81a4af4 100644 +--- a/src/Logger.cpp ++++ b/src/Logger.cpp +@@ -29,6 +29,7 @@ + #include "Common.h" + #include "Utils.h" + #include "GmicQt.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp +index 33db6e4..4f5e650 100644 +--- a/src/MainWindow.cpp ++++ b/src/MainWindow.cpp +@@ -61,6 +61,7 @@ + #include "Utils.h" + #include "Widgets/VisibleTagSelector.h" + #include "ui_mainwindow.h" ++#include "CImg.h" + #include "gmic.h" + + namespace +diff --git a/src/Misc.cpp b/src/Misc.cpp +index 3a4148b..c59b272 100644 +--- a/src/Misc.cpp ++++ b/src/Misc.cpp +@@ -38,6 +38,7 @@ + #include "Globals.h" + #include "HtmlTranslator.h" + #include "Logger.h" ++#include "CImg.h" + #include "gmic.h" + + namespace +diff --git a/src/ParametersCache.cpp b/src/ParametersCache.cpp +index c7bcad8..8d2fc45 100644 +--- a/src/ParametersCache.cpp ++++ b/src/ParametersCache.cpp +@@ -35,6 +35,7 @@ + #include "Globals.h" + #include "Logger.h" + #include "Utils.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/Updater.cpp b/src/Updater.cpp +index 47f6882..2f8e7de 100644 +--- a/src/Updater.cpp ++++ b/src/Updater.cpp +@@ -33,6 +33,7 @@ + #include "Logger.h" + #include "Misc.h" + #include "Utils.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/Utils.cpp b/src/Utils.cpp +index dc0e1e4..ee6a119 100644 +--- a/src/Utils.cpp ++++ b/src/Utils.cpp +@@ -36,6 +36,7 @@ + #include "Common.h" + #include "Host/GmicQtHost.h" + #include "Logger.h" ++#include "CImg.h" + #include "gmic.h" + + #ifdef _IS_WINDOWS_ +diff --git a/src/Widgets/PreviewWidget.cpp b/src/Widgets/PreviewWidget.cpp +index 6415b46..f87edac 100644 +--- a/src/Widgets/PreviewWidget.cpp ++++ b/src/Widgets/PreviewWidget.cpp +@@ -42,6 +42,7 @@ + #include "Logger.h" + #include "Misc.h" + #include "OverrideCursor.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt +diff --git a/src/Widgets/ProgressInfoWindow.cpp b/src/Widgets/ProgressInfoWindow.cpp +index 5095528..341e2e0 100644 +--- a/src/Widgets/ProgressInfoWindow.cpp ++++ b/src/Widgets/ProgressInfoWindow.cpp +@@ -38,6 +38,7 @@ + #include "HeadlessProcessor.h" + #include "Updater.h" + #include "ui_progressinfowindow.h" ++#include "CImg.h" + #include "gmic.h" + + namespace GmicQt diff --git a/gmic.changes b/gmic.changes index 276e368..9599fa0 100644 --- a/gmic.changes +++ b/gmic.changes @@ -1,3 +1,92 @@ +------------------------------------------------------------------- +Sun Jan 16 21:16:02 UTC 2022 - Marcus Rueckert + +- added https://github.com/dtschump/gmic/commit/56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch + make it search in /usr/share/gmic/ with all clients. + +------------------------------------------------------------------- +Sat Jan 15 18:48:24 UTC 2022 - Marcus Rueckert + +- prepare gimp 3 support +- install also the denoise data file +- introduce a new gmic-data subpackage and require it from all the + frontends so we can access it more easily once this is resolved: + https://discuss.pixls.us/t/fixing-more-things-in-gmic-packaging/28894 +- make bash-completion noarch + +------------------------------------------------------------------- +Fri Jan 14 18:44:35 UTC 2022 - Marcus Rueckert + +- move shared options for all the gmic-qt versions into a define + to reduce duplication + +------------------------------------------------------------------- +Fri Jan 14 18:41:47 UTC 2022 - Marcus Rueckert + +- Rework patches: + - drop old patches with git generated copies: + - 5e34754707b78358ef818d542d1e81d008bb2d12.patch + - dont-set-gmic_build.patch + - gmic-krita5.patch + - make-build-without-gmic-cpp.patch + - new patches: + - gmic-make-build-without-gmic-cpp.patch + - gmic-qt-make-it-work-without-gmic-cpp.patch + - krita5.patch +- Update krita patch so we can apply it as normal patch without + breaking other gmic-qt instances + +------------------------------------------------------------------- +Fri Jan 14 17:39:09 UTC 2022 - Marcus Rueckert + +- Remove unneeded BuildRequires fftw3-devel and cmake(KF5CoreAddons) + +------------------------------------------------------------------- +Fri Jan 14 17:31:52 UTC 2022 - Marcus Rueckert + +- Use simpler syntax for the pkg version comparison + +------------------------------------------------------------------- +Fri Jan 14 16:36:21 UTC 2022 - Marcus Rueckert + +- enable building with Krita 5 + new BR: krita-devel + new patches: + - 5e34754707b78358ef818d542d1e81d008bb2d12.patch + - gmic-krita5.patch + +------------------------------------------------------------------- +Fri Jan 14 11:01:21 UTC 2022 - Marcus Rueckert + +- Add dont-set-gmic_build.patch: + Make gmic-qt flavors build without gmic.cpp. This should help + with getting the new krita plugin built + +------------------------------------------------------------------- +Thu Jan 13 22:27:47 UTC 2022 - Marcus Rueckert + +- enable opencv support xshm support + - Add BuildRequires xorg-x11-devel + +------------------------------------------------------------------- +Thu Jan 13 22:26:56 UTC 2022 - Marcus Rueckert + +- add missing files for to make the devel package work: + make-build-without-gmic-cpp.patch +- also track series for easier patching + +------------------------------------------------------------------- +Thu Jan 13 21:41:27 UTC 2022 - Marcus Rueckert + +- Add Conflicts for krita >= 5 as it needs the intree version of + gmic-qt now + +------------------------------------------------------------------- +Thu Jan 13 21:25:00 UTC 2022 - Marcus Rueckert + +- Update to 3.0.1 + https://discuss.pixls.us/t/on-the-road-to-3-1/28221 + ------------------------------------------------------------------- Mon Dec 13 09:47:22 UTC 2021 - Christophe Giboudeaux diff --git a/gmic.spec b/gmic.spec index 5939bef..255dcc2 100644 --- a/gmic.spec +++ b/gmic.spec @@ -1,7 +1,7 @@ # # spec file for package gmic # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,9 +16,31 @@ # -%global _gimpplugindir %(gimptool-2.0 --gimpplugindir)/plug-ins +%if %{pkg_vcmp krita >= 5} +%bcond_without krita5 +%else +%bcond_with krita5 +%endif + +%if %{pkg_vcmp gimp >= 2.99} +%define gimp_suffix 3 +%global _gimpplugindir %(gimptool-2.99 --gimpplugindir)/plug-ins/ +%else +%global _gimpplugindir %(gimptool-2.0 --gimpplugindir)/plug-ins/ +%endif + +%if %{with krita5} +%define hostapps gimp%{?gimp_suffix} +%else +%define hostapps gimp%{?gimp_suffix} krita +%endif + +%define gmic_qt_options -DENABLE_SYSTEM_GMIC=OFF -DENABLE_DYNAMIC_LINKING=ON -DGMIC_PATH=%{_builddir}/%{name}-%{version}/src -DGMIC_LIB_PATH=%{_builddir}/%{name}-%{version}/build + +%define gmic_datadir %{_datadir}/gmic + Name: gmic -Version: 3.0.0 +Version: 3.0.1 Release: 0 Summary: GREYC's Magick for Image Computing (denoise and others) # gmic-qt is GPL-3.0-or-later, zart is CECILL-2.0, libgmic and cli program are @@ -29,10 +51,32 @@ URL: https://gmic.eu # Git URL: https://github.com/dtschump/gmic Source0: https://gmic.eu/files/source/gmic_%{version}.tar.gz Source1: gmic_qt.png +Source99: series +# PATCH-FIX-UPSTREAM gmic-make-build-without-gmic-cpp.patch - all those changes are already merged +Patch1: gmic-make-build-without-gmic-cpp.patch +# PATCH-FIX-UPSTREAM gmic-qt-make-it-work-without-gmic-cpp.patch - https://github.com/c-koi/gmic-qt/pull/134 +Patch2: gmic-qt-make-it-work-without-gmic-cpp.patch +# PATCH-FIX-UPSTREAM krita.patch - Will be sent upstream soon. For now https://github.com/darix/gmic-qt/tree/krita5 +Patch3: krita5.patch +# PATCH-FIX-UPSTREAM 56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch - Already upstream +Patch4: https://github.com/dtschump/gmic/commit/56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch BuildRequires: cmake >= 3.14.0 BuildRequires: fftw3-threads-devel +# +# BR for pkg_vcmp +# +# Those 2 are used for the pkg_vcmp conditionals above and also the rich expressions in the BuildRequiresb below +# +BuildRequires: gimp +BuildRequires: krita +# +#/BR for pkg_vcmp +# BuildRequires: pkgconfig BuildRequires: update-desktop-files +BuildRequires: (krita-devel if krita >= 5) +BuildRequires: (pkgconfig(gimp-2.0) if gimp < 2.99) +BuildRequires: (pkgconfig(gimp-3.0) if gimp >= 2.99) BuildRequires: cmake(Qt5Core) BuildRequires: cmake(Qt5Gui) BuildRequires: cmake(Qt5LinguistTools) @@ -42,7 +86,6 @@ BuildRequires: cmake(Qt5Xml) BuildRequires: pkgconfig(GraphicsMagick++) BuildRequires: pkgconfig(OpenEXR) BuildRequires: pkgconfig(fftw3) -BuildRequires: pkgconfig(gimp-2.0) BuildRequires: pkgconfig(libcurl) BuildRequires: pkgconfig(libjpeg) BuildRequires: pkgconfig(libpng) @@ -61,6 +104,8 @@ BuildRequires: pkgconfig(opencv4) BuildRequires: pkgconfig(zlib) %endif %endif +BuildRequires: xorg-x11-devel +Requires: gmic-data = %{version} %description G'MIC is a framework for image processing, providing @@ -91,10 +136,11 @@ uses the gmic functionality provided by the gmic library. Summary: GMIC plugin for gimp License: GPL-3.0-or-later Group: Productivity/Graphics/Bitmap Editors -Requires: gimp +%requires_eq gimp # This package was only available in the 'graphics' repo Provides: gmic-gimp = %{version} Obsoletes: gmic-gimp < %{version} +Requires: gmic-data = %{version} %description -n gimp-plugin-gmic This is a plugin for gimp that exposes many of the nice gmic features @@ -104,7 +150,8 @@ for interactive use in gimp. Summary: GMIC plugin for krita License: GPL-3.0-or-later Group: Productivity/Graphics/Bitmap Editors -Requires: krita +%requires_eq krita +Requires: gmic-data = %{version} %description -n krita-plugin-gmic This is a plugin for krita to provide gmic features. @@ -115,72 +162,94 @@ License: CECILL-2.1 Group: Productivity/Graphics/Bitmap Editors Requires: bash-completion Supplements: (%{name} and bash-completion) +BuildArch: noarch %description bash-completion -This package contain de bash completion command for gmic. +This package contains the bash completion command for gmic. + +%package data +Summary: Shared data files for the various gmic frontends +License: CECILL-2.1 +Group: Productivity/Graphics/Bitmap Editors +BuildArch: noarch + +%description data +This package contains shared data files for the various gmic frontends. %prep -%autosetup -p1 +%setup -q +%patch1 -p1 +pushd gmic-qt +%patch2 -p1 +%patch3 -p1 +popd +%patch4 -p1 %build # Build gmic %cmake \ -DENABLE_DYNAMIC_LINKING=ON \ - -DBUILD_LIB_STATIC=OFF + -DBUILD_LIB_STATIC=OFF \ + -DENABLE_OPENCV:BOOL=ON \ + -DENABLE_XSHM:BOOL=ON %cmake_build cd .. # Build gmic{_gimp|_krita}_qt pushd gmic-qt -%cmake \ - -DENABLE_DYNAMIC_LINKING=ON \ - -DGMIC_PATH=%{_builddir}/%{name}-%{version}/src \ - -DGMIC_LIB_PATH=%{_builddir}/%{name}-%{version}/build \ - -DGMIC_QT_HOST=gimp + +%cmake %{gmic_qt_options} -DGMIC_QT_HOST=none %cmake_build cd .. -%cmake \ - -DENABLE_DYNAMIC_LINKING=ON \ - -DGMIC_PATH=%{_builddir}/%{name}-%{version}/src \ - -DGMIC_LIB_PATH=%{_builddir}/%{name}-%{version}/build \ - -DGMIC_QT_HOST=krita +for hostapp in %{hostapps} ; do +%cmake %{gmic_qt_options} -DGMIC_QT_HOST=${hostapp} %cmake_build cd .. +done -%cmake \ - -DENABLE_DYNAMIC_LINKING=ON \ - -DGMIC_PATH=%{_builddir}/%{name}-%{version}/src \ - -DGMIC_LIB_PATH=%{_builddir}/%{name}-%{version}/build \ - -DGMIC_QT_HOST=none -%cmake_build +%if %{with krita5} + +%cmake_kf5 -d plugin-build -- -DCMAKE_INSTALL_LOCALEDIR=%{_kf5_localedir} %{gmic_qt_options} -DGMIC_QT_HOST=krita-plugin -DCMAKE_BUILD_TYPE=RelWithDebInfo +%make_jobs cd .. +%endif popd %install %cmake_install +%if %{with krita5} +pushd gmic-qt/plugin-build +%make_install +popd +%else +# krita plugin +install -m 0755 build/gmic_krita_qt %{buildroot}%{_bindir}/gmic_krita_qt +%endif + install -D -m 0644 %{SOURCE1} %{buildroot}%{_datadir}/pixmaps/gmic_qt.png %suse_update_desktop_file -c gmic_qt "G'Mic Qt" "G'MIC Qt GUI" "gmic_qt %%F" gmic_qt "Qt;Graphics;Photography;" # Film color lookup tables -install -d -m 0755 %{buildroot}%{_gimpplugindir} -install -m 0644 resources/gmic_cluts.gmz %{buildroot}%{_gimpplugindir}/gmic_cluts.gmz +install -d -m 0755 \ + %{buildroot}%{_gimpplugindir} \ + %{buildroot}%{gmic_datadir}/ + +for file in gmic_cluts.gmz gmic_denoise_cnn.gmz ; do + install -m 0644 resources/${file} %{buildroot}%{gmic_datadir}/${file} +done # qt_gmic pushd gmic-qt install -m 0755 build/gmic_qt %{buildroot}%{_bindir}/gmic_qt -# krita plugin -install -m 0755 build/gmic_krita_qt %{buildroot}%{_bindir}/gmic_krita_qt - # gimp plugin -install -d -m 0755 %{buildroot}%{_gimpplugindir} install -m 0755 build/gmic_gimp_qt %{buildroot}%{_gimpplugindir}/gmic_gimp_qt popd @@ -196,20 +265,28 @@ popd %{_datadir}/applications/gmic_qt.desktop %{_datadir}/pixmaps/gmic_qt.png +%files data +%license COPYING +%{gmic_datadir} + %files -n gimp-plugin-gmic %license COPYING -%{_gimpplugindir}/gmic_gimp_qt -%{_gimpplugindir}/gmic_cluts.gmz +%{_gimpplugindir}/ %files -n krita-plugin-gmic %license COPYING +%if %{with krita5} +%{_libdir}/kritaplugins/krita_gmic_qt.so +%else %{_bindir}/gmic_krita_qt +%endif %files -n libgmic1 %license COPYING %{_libdir}/libgmic.so.* %files -n libgmic-devel +%{_includedir}/CImg.h %{_includedir}/gmic.h %{_libdir}/libgmic.so %{_libdir}/cmake/gmic/ diff --git a/gmic_3.0.0.tar.gz b/gmic_3.0.0.tar.gz deleted file mode 100644 index 5678a65..0000000 --- a/gmic_3.0.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3f056bb9e6dbf0674af4c8dce59f4198172187662f7fbb36cc63ebc8c1b71120 -size 10225122 diff --git a/gmic_3.0.1.tar.gz b/gmic_3.0.1.tar.gz new file mode 100644 index 0000000..48a96bc --- /dev/null +++ b/gmic_3.0.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cc20a20e3ab53ce485ccf6e044a30141b3d62cf7743b83bb04906ff29453035 +size 10457923 diff --git a/krita5.patch b/krita5.patch new file mode 100644 index 0000000..cbf59d6 --- /dev/null +++ b/krita5.patch @@ -0,0 +1,1306 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 2b46de0..b5974b7 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -22,7 +22,7 @@ endif() + + message("Build type is " ${CMAKE_BUILD_TYPE}) + +-set (GMIC_QT_HOST "gimp" CACHE STRING "Define for which host qmic-qt will be built: gimp, gimp3 (experimental), krita, none, paintdotnet or 8bf.") ++set (GMIC_QT_HOST "gimp" CACHE STRING "Define for which host qmic-qt will be built: gimp, gimp3 (experimental), krita, krita-plugin, none, paintdotnet or 8bf.") + if (${GMIC_QT_HOST} STREQUAL "none") + message("Building standalone version.") + else() +@@ -656,6 +656,71 @@ elseif (${GMIC_QT_HOST} STREQUAL "krita") + ${gmic_qt_LIBRARIES} + ) + install(TARGETS gmic_krita_qt RUNTIME DESTINATION bin) ++ install(FILES gmic_krita_qt.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) ++ ++elseif (${GMIC_QT_HOST} STREQUAL "krita-plugin") ++ set(MIN_FRAMEWORKS_VERSION 5.44.0) ++ ++ find_package(ECM 5.22 REQUIRED NOMODULE) ++ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) ++ ++ include(KDEInstallDirs) ++ include(KDECMakeSettings) ++ ++ if (ANDROID) ++ set (KRITA_PLUGIN_INSTALL_DIR ${LIB_INSTALL_DIR}) ++ else() ++ set (KRITA_PLUGIN_INSTALL_DIR ${LIB_INSTALL_DIR}/kritaplugins) ++ endif() ++ ++ find_package(KF5 ${MIN_FRAMEWORKS_VERSION} REQUIRED COMPONENTS ++ CoreAddons ++ ) ++ ++ message(STATUS "Looking for Krita QMic libraries in: ${CMAKE_PREFIX_PATH}") ++ ++ find_library(KIS_IMAGE_INTERFACE_LIBRARY ++ NAMES kritaqmicinterface ++ REQUIRED) ++ ++ find_path(KIS_IMAGE_INTERFACE_DIR ++ NAMES kis_qmic_plugin_interface.h ++ REQUIRED) ++ ++ set_package_properties(kritaqmicinterface PROPERTIES ++ URL "http://www.krita.org" ++ DESCRIPTION "Krita GMic core library" ++ ) ++ ++ set (gmic_qt_SRCS ${gmic_qt_SRCS} src/Host/KritaPlugin/host.cpp src/Host/KritaPlugin/gmicqttoolplugin.cpp) ++ set (gmic_qt_SRCS ${gmic_qt_SRCS} ) ++ qt5_wrap_ui(gmic_qt_SRCS ${gmic_qt_FORMS}) ++ add_definitions(-DGMIC_HOST=krita-plugin) ++ add_definitions(-D_GMIC_QT_DISABLE_THEMING_) ++ add_definitions(-D_GMIC_QT_CONSENT_TO_UPDATE_FIRST_) ++ add_definitions(-D_GMIC_QT_DISABLE_TRANSLATION_) ++ add_definitions(-D_GMIC_USE_HOSTED_SETTINGS_) ++ add_library(krita_gmic_qt MODULE ${gmic_qt_SRCS} ${gmic_qt_QRC} ${qmic_qt_QM}) ++ target_include_directories( ++ krita_gmic_qt ++ PUBLIC ++ ${KIS_IMAGE_INTERFACE_DIR} ++ ) ++ target_link_libraries( ++ krita_gmic_qt ++ PRIVATE ++ ${gmic_qt_LIBRARIES} ++ ${KIS_IMAGE_INTERFACE_LIBRARY} ++ KF5::CoreAddons ++ ) ++ if (ANDROID) ++ target_link_libraries( ++ krita_gmic_qt ++ PRIVATE ++ log ++ ) ++ endif() ++ install(TARGETS krita_gmic_qt DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) # plugin + + elseif (${GMIC_QT_HOST} STREQUAL "none") + +@@ -699,7 +764,7 @@ elseif (${GMIC_QT_HOST} STREQUAL "8bf") + ) + + else() +- message(FATAL_ERROR "GMIC_QT_HOST is not defined as gimp, gimp3, krita, none, paintdotnet or 8bf") ++ message(FATAL_ERROR "GMIC_QT_HOST is not defined as gimp, gimp3, krita, krita-plugin, none, paintdotnet or 8bf") + endif() + + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) +diff --git a/gmic_krita_qt.desktop b/gmic_krita_qt.desktop +new file mode 100644 +index 0000000..579d427 +--- /dev/null ++++ b/gmic_krita_qt.desktop +@@ -0,0 +1,9 @@ ++[Desktop Entry] ++Name=gmic_krita_qt ++Exec=gmic_krita_qt ++GenericName=G'Mic plugin for Krita ++Comment=G'Mic plugin for Krita ++Type=Application ++Icon=gmic_krita_qt ++Categories=Qt;KDE;Graphics; ++StartupNotify=false +diff --git a/src/DialogSettings.cpp b/src/DialogSettings.cpp +index b3d8c53..e4050b4 100644 +--- a/src/DialogSettings.cpp ++++ b/src/DialogSettings.cpp +@@ -93,11 +93,7 @@ DialogSettings::DialogSettings(QWidget * parent) : QDialog(parent), ui(new Ui::D + #ifdef _GMIC_QT_DEBUG_ + ui->cbUpdatePeriodicity->addItem(tr("At launch (debug)"), QVariant(0)); + #endif +- for (int i = 0; i < ui->cbUpdatePeriodicity->count(); ++i) { +- if (_updatePeriodicity == ui->cbUpdatePeriodicity->itemData(i).toInt()) { +- ui->cbUpdatePeriodicity->setCurrentIndex(i); +- } +- } ++ ui->cbUpdatePeriodicity->setCurrentIndex(ui->cbUpdatePeriodicity->findData(_updatePeriodicity)); + + ui->outputMessages->setToolTip(tr("Output messages")); + ui->outputMessages->addItem(tr("Quiet (default)"), (int)OutputMessageMode::Quiet); +@@ -118,9 +114,12 @@ DialogSettings::DialogSettings(QWidget * parent) : QDialog(parent), ui(new Ui::D + + ui->rbLeftPreview->setChecked(_previewPosition == MainWindow::PreviewPosition::Left); + ui->rbRightPreview->setChecked(_previewPosition == MainWindow::PreviewPosition::Right); +- const bool savedDarkTheme = QSettings().value(DARK_THEME_KEY, GmicQtHost::DarkThemeIsDefault).toBool(); ++ const bool savedDarkTheme = GMIC_SETTINGS_INLINE.value(DARK_THEME_KEY, GmicQtHost::DarkThemeIsDefault).toBool(); + ui->rbDarkTheme->setChecked(savedDarkTheme); + ui->rbDefaultTheme->setChecked(!savedDarkTheme); ++#ifdef _GMIC_QT_DISABLE_THEMING_ ++ ui->groupBoxTheme->setEnabled(false); ++#endif + ui->cbNativeColorDialogs->setChecked(_nativeColorDialogs); + ui->cbNativeColorDialogs->setToolTip(tr("Check to use Native/OS color dialog, uncheck to use Qt's")); + ui->cbShowLogos->setChecked(_logosAreVisible); +@@ -130,9 +129,17 @@ DialogSettings::DialogSettings(QWidget * parent) : QDialog(parent), ui(new Ui::D + + connect(ui->pbOk, SIGNAL(clicked()), this, SLOT(onOk())); + connect(ui->rbLeftPreview, SIGNAL(toggled(bool)), this, SLOT(onRadioLeftPreviewToggled(bool))); ++#ifdef _GMIC_QT_DISABLE_UPDATES_ ++ ui->pbUpdate->setEnabled(false); ++#else + connect(ui->pbUpdate, SIGNAL(clicked(bool)), this, SLOT(onUpdateClicked())); ++#endif + ++#ifdef _GMIC_QT_DISABLE_UPDATES_ ++ ui->cbUpdatePeriodicity->setEnabled(false); ++#else + connect(ui->cbUpdatePeriodicity, SIGNAL(currentIndexChanged(int)), this, SLOT(onUpdatePeriodicityChanged(int))); ++#endif + + connect(ui->labelPreviewLeft, SIGNAL(clicked()), ui->rbLeftPreview, SLOT(click())); + connect(ui->labelPreviewRight, SIGNAL(clicked()), ui->rbRightPreview, SLOT(click())); +@@ -141,7 +148,9 @@ DialogSettings::DialogSettings(QWidget * parent) : QDialog(parent), ui(new Ui::D + + connect(Updater::getInstance(), SIGNAL(updateIsDone(int)), this, SLOT(enableUpdateButton())); + ++#ifndef _GMIC_QT_DISABLE_THEMING_ + connect(ui->rbDarkTheme, SIGNAL(toggled(bool)), this, SLOT(onDarkThemeToggled(bool))); ++#endif + + connect(ui->cbShowLogos, SIGNAL(toggled(bool)), this, SLOT(onLogosVisibleToggled(bool))); + +@@ -151,12 +160,21 @@ DialogSettings::DialogSettings(QWidget * parent) : QDialog(parent), ui(new Ui::D + + connect(ui->outputMessages, SIGNAL(currentIndexChanged(int)), this, SLOT(onOutputMessageModeChanged(int))); + ++#ifdef _GMIC_QT_DISABLE_UPDATES_ ++ ui->cbNotifyFailedUpdate->setEnabled(false); ++#else + connect(ui->cbNotifyFailedUpdate, SIGNAL(toggled(bool)), this, SLOT(onNotifyStartupUpdateFailedToggle(bool))); ++#endif + ++#ifdef _GMIC_QT_DISABLE_TRANSLATION_ ++ ui->languageSelector->setEnabled(false); ++#else + ui->languageSelector->selectLanguage(_languageCode); + ui->languageSelector->enableFilterTranslation(_filterTranslationEnabled); ++#endif + +- if (_darkThemeEnabled) { ++#ifndef _GMIC_QT_DISABLE_THEMING_ ++ if (DialogSettings::darkThemeEnabled()) { + QPalette p = ui->cbNativeColorDialogs->palette(); + p.setColor(QPalette::Text, DialogSettings::CheckBoxTextColor); + p.setColor(QPalette::Base, DialogSettings::CheckBoxBaseColor); +@@ -170,6 +188,7 @@ DialogSettings::DialogSettings(QWidget * parent) : QDialog(parent), ui(new Ui::D + ui->cbShowLogos->setPalette(p); + ui->cbNotifyFailedUpdate->setPalette(p); + } ++#endif + ui->pbOk->setFocus(); + ui->tabWidget->setCurrentIndex(0); + } +@@ -181,7 +200,7 @@ DialogSettings::~DialogSettings() + + void DialogSettings::loadSettings(UserInterfaceMode userInterfaceMode) + { +- QSettings settings; ++ GMIC_SETTINGS(settings); + if (settings.value("Config/PreviewPosition", "Left").toString() == "Left") { + _previewPosition = MainWindow::PreviewPosition::Left; + } else { +@@ -271,11 +290,13 @@ void DialogSettings::onOk() + + void DialogSettings::done(int r) + { +- QSettings settings; ++ GMIC_SETTINGS(settings); + saveSettings(settings); + settings.setValue(DARK_THEME_KEY, ui->rbDarkTheme->isChecked()); ++#ifndef _GMIC_QT_DISABLE_TRANSLATION_ + settings.setValue(LANGUAGE_CODE_KEY, ui->languageSelector->selectedLanguageCode()); + settings.setValue(ENABLE_FILTER_TRANSLATION, ui->languageSelector->translateFiltersEnabled()); ++#endif + QDialog::done(r); + } + +@@ -350,7 +371,11 @@ void DialogSettings::onColorDialogsToggled(bool on) + + bool DialogSettings::darkThemeEnabled() + { ++#ifdef _GMIC_QT_DISABLE_THEMING_ ++ return GmicQtHost::DarkThemeIsDefault; ++#else + return _darkThemeEnabled; ++#endif + } + + QString DialogSettings::languageCode() +diff --git a/src/FilterParameters/BoolParameter.cpp b/src/FilterParameters/BoolParameter.cpp +index 7f24464..3ba8313 100644 +--- a/src/FilterParameters/BoolParameter.cpp ++++ b/src/FilterParameters/BoolParameter.cpp +@@ -59,12 +59,14 @@ bool BoolParameter::addTo(QWidget * widget, int row) + delete _label; + _checkBox = new QCheckBox(_name, widget); + _checkBox->setChecked(_value); ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + QPalette p = _checkBox->palette(); + p.setColor(QPalette::Text, DialogSettings::CheckBoxTextColor); + p.setColor(QPalette::Base, DialogSettings::CheckBoxBaseColor); + _checkBox->setPalette(p); + } ++#endif + _grid->addWidget(_checkBox, row, 0, 1, 3); + connectCheckBox(); + return true; +diff --git a/src/FilterParameters/FloatParameter.cpp b/src/FilterParameters/FloatParameter.cpp +index c47fc9c..67a0a3e 100644 +--- a/src/FilterParameters/FloatParameter.cpp ++++ b/src/FilterParameters/FloatParameter.cpp +@@ -72,13 +72,14 @@ bool FloatParameter::addTo(QWidget * widget, int row) + _slider->setMinimumWidth(SLIDER_MIN_WIDTH); + _slider->setRange(0, SLIDER_MAX_RANGE); + _slider->setValue(static_cast(SLIDER_MAX_RANGE * (_value - _min) / (_max - _min))); ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + QPalette p = _slider->palette(); + p.setColor(QPalette::Button, QColor(100, 100, 100)); + p.setColor(QPalette::Highlight, QColor(130, 130, 130)); + _slider->setPalette(p); + } +- ++#endif + _spinBox = new CustomDoubleSpinBox(widget, _min, _max); + _spinBox->setSingleStep(double(_max - _min) / 100.0); + _spinBox->setValue((double)_value); +diff --git a/src/FilterParameters/IntParameter.cpp b/src/FilterParameters/IntParameter.cpp +index 0a32a65..b12058d 100644 +--- a/src/FilterParameters/IntParameter.cpp ++++ b/src/FilterParameters/IntParameter.cpp +@@ -80,12 +80,14 @@ bool IntParameter::addTo(QWidget * widget, int row) + + _spinBox = new CustomSpinBox(widget, _min, _max); + _spinBox->setValue(_value); ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + QPalette p = _slider->palette(); + p.setColor(QPalette::Button, QColor(100, 100, 100)); + p.setColor(QPalette::Highlight, QColor(130, 130, 130)); + _slider->setPalette(p); + } ++#endif + _grid->addWidget(_label = new QLabel(_name, widget), row, 0, 1, 1); + _grid->addWidget(_slider, row, 1, 1, 1); + _grid->addWidget(_spinBox, row, 2, 1, 1); +diff --git a/src/FilterParameters/NoteParameter.cpp b/src/FilterParameters/NoteParameter.cpp +index 34d3424..bd1df33 100644 +--- a/src/FilterParameters/NoteParameter.cpp ++++ b/src/FilterParameters/NoteParameter.cpp +@@ -87,14 +87,14 @@ bool NoteParameter::initFromText(const QString & filterName, const char * text, + _text = list[1].trimmed(); // Notes are never translated + _text.remove(QRegExp("^\"")).remove(QRegExp("\"$")).replace(QString("\\\""), "\""); + _text.replace(QString("\\n"), "
"); +- ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + _text.replace(QRegExp("color\\s*=\\s*\"purple\""), QString("color=\"#ff00ff\"")); + _text.replace(QRegExp("foreground\\s*=\\s*\"purple\""), QString("foreground=\"#ff00ff\"")); + _text.replace(QRegExp("color\\s*=\\s*\"blue\""), QString("color=\"#9b9bff\"")); + _text.replace(QRegExp("foreground\\s*=\\s*\"blue\""), QString("foreground=\"#9b9bff\"")); + } +- ++#endif + _text.replace(QRegExp("color\\s*=\\s*\""), QString("style=\"color:")); + _text.replace(QRegExp("foreground\\s*=\\s*\""), QString("style=\"color:")); + _text = HtmlTranslator::fromUtf8Escapes(_text); +diff --git a/src/FilterParameters/SeparatorParameter.cpp b/src/FilterParameters/SeparatorParameter.cpp +index 40347f7..941b280 100644 +--- a/src/FilterParameters/SeparatorParameter.cpp ++++ b/src/FilterParameters/SeparatorParameter.cpp +@@ -58,9 +58,11 @@ bool SeparatorParameter::addTo(QWidget * widget, int row) + _frame->setSizePolicy(sizePolicy); + _frame->setFrameShape(QFrame::HLine); + _frame->setFrameShadow(QFrame::Sunken); ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + _frame->setStyleSheet("QFrame{ border-top: 0px none #a0a0a0; border-bottom: 2px solid rgb(160,160,160);}"); + } ++#endif + _grid->addWidget(_frame, row, 0, 1, 3); + return true; + } +diff --git a/src/FilterSelector/FiltersPresenter.cpp b/src/FilterSelector/FiltersPresenter.cpp +index e39270f..18e722e 100644 +--- a/src/FilterSelector/FiltersPresenter.cpp ++++ b/src/FilterSelector/FiltersPresenter.cpp +@@ -416,7 +416,7 @@ void FiltersPresenter::expandFaveFolder() + void FiltersPresenter::expandPreviousSessionExpandedFolders() + { + if (_filtersView) { +- QList expandedFolderPaths = QSettings().value("Config/ExpandedFolders", QStringList()).toStringList(); ++ QList expandedFolderPaths = GMIC_SETTINGS_INLINE.value("Config/ExpandedFolders", QStringList()).toStringList(); + _filtersView->expandFolders(expandedFolderPaths); + } + } +diff --git a/src/Globals.h b/src/Globals.h +index 9d38982..782a732 100644 +--- a/src/Globals.h ++++ b/src/Globals.h +@@ -55,7 +55,13 @@ const char WarningPrefix = '!'; + #define ONE_WEEK_HOURS (7 * 24) + #define TWO_WEEKS_HOURS (14 * 24) + #define ONE_MONTH_HOURS (30 * 24) ++#ifdef _GMIC_QT_CONSENT_TO_UPDATE_FIRST_ ++#define INTERNET_DEFAULT_PERIODICITY INTERNET_NEVER_UPDATE_PERIODICITY ++#define INTERNET_DEFAULT_REFRESH_UPDATE 0 ++#else + #define INTERNET_DEFAULT_PERIODICITY ONE_MONTH_HOURS ++#define INTERNET_DEFAULT_REFRESH_UPDATE 1 ++#endif + + #define PREVIEW_MAX_ZOOM_FACTOR 40.0 + +@@ -64,4 +70,17 @@ const char WarningPrefix = '!'; + #define KEYPOINTS_INTERACTIVE_MIDDLE_DELAY_MS ((KEYPOINTS_INTERACTIVE_LOWER_DELAY_MS + KEYPOINTS_INTERACTIVE_UPPER_DELAY_MS) / 2) + #define KEYPOINTS_INTERACTIVE_AVERAGING_COUNT 6 + ++#ifdef _GMIC_USE_HOSTED_SETTINGS_ ++#ifdef Q_OS_MACOS ++#define GMIC_SETTINGS(x) QSettings x(GMIC_QT_ORGANISATION_DOMAIN, GMIC_QT_APPLICATION_NAME) ++#define GMIC_SETTINGS_INLINE QSettings(GMIC_QT_ORGANISATION_DOMAIN, GMIC_QT_APPLICATION_NAME) ++#else ++#define GMIC_SETTINGS(x) QSettings x(GMIC_QT_ORGANISATION_NAME, GMIC_QT_APPLICATION_NAME) ++#define GMIC_SETTINGS_INLINE QSettings(GMIC_QT_ORGANISATION_NAME, GMIC_QT_APPLICATION_NAME) ++#endif ++#else ++#define GMIC_SETTINGS(x) QSettings x ++#define GMIC_SETTINGS_INLINE QSettings() ++#endif ++ + #endif // GMIC_QT_GLOBALS_H +diff --git a/src/GmicQt.cpp b/src/GmicQt.cpp +index 5925e94..9ac512c 100644 +--- a/src/GmicQt.cpp ++++ b/src/GmicQt.cpp +@@ -88,7 +88,7 @@ RunParameters lastAppliedFilterRunParameters(ReturnedRunParametersFlag flag) + { + configureApplication(); + RunParameters parameters; +- QSettings settings; ++ GMIC_SETTINGS(settings); + const QString path = settings.value(QString("LastExecution/host_%1/FilterPath").arg(GmicQtHost::ApplicationShortname)).toString(); + parameters.filterPath = path.toStdString(); + QString args = settings.value(QString("LastExecution/host_%1/Arguments").arg(GmicQtHost::ApplicationShortname)).toString(); +@@ -198,7 +198,7 @@ int run(UserInterfaceMode interfaceMode, // + LanguageSettings::installTranslators(); + MainWindow mainWindow; + mainWindow.setPluginParameters(parameters); +- if (QSettings().value("Config/MainWindowMaximized", false).toBool()) { ++ if (GMIC_SETTINGS_INLINE.value("Config/MainWindowMaximized", false).toBool()) { + mainWindow.showMaximized(); + } else { + mainWindow.show(); +@@ -546,10 +546,12 @@ namespace + + void configureApplication() + { ++#ifndef _GMIC_USE_HOSTED_SETTINGS_ + QCoreApplication::setOrganizationName(GMIC_QT_ORGANISATION_NAME); + QCoreApplication::setOrganizationDomain(GMIC_QT_ORGANISATION_DOMAIN); + QCoreApplication::setApplicationName(GMIC_QT_APPLICATION_NAME); + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); ++#endif + } + + void disableModes(const std::list & disabledInputModes, // +diff --git a/src/HeadlessProcessor.cpp b/src/HeadlessProcessor.cpp +index 930facb..fc45aaa 100644 +--- a/src/HeadlessProcessor.cpp ++++ b/src/HeadlessProcessor.cpp +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include "Globals.h" + #include "Common.h" + #include "DialogSettings.h" + #include "FilterParameters/FilterParametersWidget.h" +@@ -72,7 +73,7 @@ HeadlessProcessor::~HeadlessProcessor() + + bool HeadlessProcessor::setPluginParameters(const RunParameters & parameters) + { +- QSettings settings; ++ GMIC_SETTINGS(settings); + _path = QString::fromStdString(parameters.filterPath); + _inputMode = (parameters.inputMode == InputMode::Unspecified) ? DefaultInputMode : parameters.inputMode; + _outputMode = (parameters.outputMode == OutputMode::Unspecified) ? DefaultOutputMode : parameters.outputMode; +@@ -239,7 +240,7 @@ void HeadlessProcessor::onProcessingFinished() + GmicQtHost::outputImages(images, _filterThread->imageNames(), _outputMode); + _processingCompletedProperly = true; + } +- QSettings settings; ++ GMIC_SETTINGS(settings); + if (!status.isEmpty() && !_hash.isEmpty()) { + ParametersCache::setValues(_hash, status); + ParametersCache::save(); +@@ -272,7 +273,9 @@ void HeadlessProcessor::endApplication(const QString & errorMessage) + if (!errorMessage.isEmpty()) { + Logger::error(errorMessage); + } ++#ifndef _GMIC_USE_HOSTED_SETTINGS_ + QCoreApplication::exit(!errorMessage.isEmpty()); ++#endif + } + + } // namespace GmicQt +diff --git a/src/Host/KritaPlugin/gmicqttoolplugin.cpp b/src/Host/KritaPlugin/gmicqttoolplugin.cpp +new file mode 100644 +index 0000000..6ef6a4e +--- /dev/null ++++ b/src/Host/KritaPlugin/gmicqttoolplugin.cpp +@@ -0,0 +1,204 @@ ++/* ++ * This file is part of G'MIC-Qt, a generic plug-in for raster graphics ++ * editors, offering hundreds of filters thanks to the underlying G'MIC ++ * image processing framework. ++ * ++ * Copyright (C) 2020-2021 L. E. Segovia ++ * ++ * Description: Krita painting suite plugin for G'Mic-Qt. ++ * ++ * G'MIC-Qt 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. ++ * ++ * G'MIC-Qt 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 ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef Q_OS_ANDROID ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++#include "DialogSettings.h" ++#include "GmicQt.h" ++#include "Globals.h" ++#include "HeadlessProcessor.h" ++#include "Host/GmicQtHost.h" ++#include "LanguageSettings.h" ++#include "Logger.h" ++#include "MainWindow.h" ++#include "Widgets/InOutPanel.h" ++#include "Widgets/ProgressInfoWindow.h" ++#include "gmicqttoolplugin.h" ++ ++#include "kpluginfactory.h" ++ ++K_PLUGIN_FACTORY_WITH_JSON(KritaGmicPluginFactory, ++ "gmicqttoolplugin.json", ++ registerPlugin();) ++ ++KritaGmicPlugin::KritaGmicPlugin(QObject *parent, const QVariantList &) ++ : QObject(parent) ++{ ++} ++ ++int KritaGmicPlugin::launch(std::shared_ptr i, bool headless) ++{ ++#ifdef Q_OS_ANDROID ++ /* Since on Android stdout and stderr redirect to null, un-redirect them */ ++ /* based on https://stackoverflow.com/a/gmic-qt/31777050 */ ++ ++ std::array oldFd; ++ std::array newStdout, newStderr; ++ ++ auto redir_worker = [](std::array &fd, android_LogPriority lvl) { ++ ssize_t rdsz; ++ std::array buf{}; ++ while ((rdsz = read(fd[0], buf.data(), buf.size() - 1)) > 0) { ++ if (buf[rdsz - 1] == '\n') ++ --rdsz; ++ buf[rdsz] = 0; /* add null-terminator */ ++ __android_log_write( ++ lvl, qPrintable(GmicQtHost::ApplicationName), buf.data()); ++ } ++ }; ++ ++ /* make stdout line-buffered and stderr unbuffered */ ++ setvbuf(stdout, 0, _IOLBF, 0); ++ setvbuf(stderr, 0, _IOLBF, 0); ++ ++ /* create the pipe and redirect stdout and stderr */ ++ dup2(1, oldFd[0]); ++ dup2(2, oldFd[1]); ++ pipe(newStdout.data()); ++ pipe(newStderr.data()); ++ dup2(newStdout[1], 1); ++ dup2(newStderr[1], 2); ++ ++ /* spawn the logging thread */ ++ auto newStdoutRedir = ++ std::thread(redir_worker, std::ref(newStdout), ANDROID_LOG_DEBUG); ++ auto newStderrRedir = ++ std::thread(redir_worker, std::ref(newStderr), ANDROID_LOG_WARN); ++ newStdoutRedir.detach(); ++ newStderrRedir.detach(); ++#endif ++ ++ using namespace GmicQt; ++ ++ std::list disabledInputModes; ++ disabledInputModes.push_back(GmicQt::InputMode::NoInput); ++ // disabledInputModes.push_back(GmicQt::Active); ++ // disabledInputModes.push_back(GmicQt::All); ++ // disabledInputModes.push_back(GmicQt::ActiveAndBelow); ++ // disabledInputModes.push_back(GmicQt::ActiveAndAbove); ++ disabledInputModes.push_back(GmicQt::InputMode::AllVisible); ++ disabledInputModes.push_back(GmicQt::InputMode::AllInvisible); ++ ++ std::list disabledOutputModes; ++ // disabledOutputModes.push_back(GmicQt::OutputMode::InPlace); ++ disabledOutputModes.push_back(GmicQt::OutputMode::NewImage); ++ disabledOutputModes.push_back(GmicQt::OutputMode::NewLayers); ++ disabledOutputModes.push_back(GmicQt::OutputMode::NewActiveLayers); ++ ++ int status = 0; ++ GmicQtHost::iface = i; ++ if (headless) { ++ GmicQt::RunParameters parameters = GmicQt::lastAppliedFilterRunParameters( ++ GmicQt::ReturnedRunParametersFlag::AfterFilterExecution); ++ { ++ for (const GmicQt::InputMode & mode : disabledInputModes) { ++ GmicQt::InOutPanel::disableInputMode(mode); ++ } ++ for (const GmicQt::OutputMode & mode : disabledOutputModes) { ++ GmicQt::InOutPanel::disableOutputMode(mode); ++ } ++ } ++ DialogSettings::loadSettings(GmicQt::UserInterfaceMode::ProgressDialog); ++ Logger::setMode(DialogSettings::outputMessageMode()); ++ LanguageSettings::installTranslators(); ++ ++ HeadlessProcessor processor(nullptr); ++ if (!processor.setPluginParameters(parameters)) { ++ Logger::error(processor.error()); ++ return 1; ++ } ++ ++ QPointer progressWindow(new ProgressInfoWindow(&processor)); ++ // We want a non modal dialog here. ++ progressWindow->setWindowFlags(Qt::Tool | Qt::Dialog); ++ progressWindow->setWindowModality(Qt::ApplicationModal); ++ // Make it destroy itself on close (signaling the event loop) ++ progressWindow->setAttribute(Qt::WA_DeleteOnClose); ++ ++ processor.startProcessing(); ++ ++ QEventLoop loop; ++ connect(progressWindow, SIGNAL(destroyed()), &loop, SLOT(quit())); ++ status = loop.exec(); ++ } else { ++ GmicQt::RunParameters parameters = GmicQt::lastAppliedFilterRunParameters( ++ GmicQt::ReturnedRunParametersFlag::AfterFilterExecution); ++ { ++ for (const GmicQt::InputMode & mode : disabledInputModes) { ++ GmicQt::InOutPanel::disableInputMode(mode); ++ } ++ for (const GmicQt::OutputMode & mode : disabledOutputModes) { ++ GmicQt::InOutPanel::disableOutputMode(mode); ++ } ++ } ++ DialogSettings::loadSettings(GmicQt::UserInterfaceMode::Full); ++ Logger::setMode(DialogSettings::outputMessageMode()); ++ LanguageSettings::installTranslators(); ++ ++ QPointer mainWindow(new MainWindow()); ++ mainWindow->setPluginParameters(parameters); ++ // We want a non modal dialog here. ++ mainWindow->setWindowFlags(Qt::Tool | Qt::Dialog); ++ mainWindow->setWindowModality(Qt::ApplicationModal); ++ // Make it destroy itself on close (signaling the event loop) ++ mainWindow->setAttribute(Qt::WA_DeleteOnClose); ++ ++ if (GMIC_SETTINGS_INLINE.value("Config/MainWindowMaximized", false).toBool()) { ++ mainWindow->showMaximized(); ++ } else { ++ mainWindow->show(); ++ } ++ ++ // Wait than main widget is closed. ++ QEventLoop loop; ++ connect(mainWindow, SIGNAL(destroyed()), &loop, SLOT(quit())); ++ status = loop.exec(); ++ } ++ ++ GmicQtHost::sharedMemorySegments.clear(); ++ GmicQtHost::iface.reset(); ++ ++#ifdef Q_OS_ANDROID ++ /* un-redirect stdout and stderr */ ++ dup2(oldFd[0], 1); ++ dup2(oldFd[1], 2); ++#endif ++ ++ return status; ++} ++ ++#include "gmicqttoolplugin.moc" +diff --git a/src/Host/KritaPlugin/gmicqttoolplugin.h b/src/Host/KritaPlugin/gmicqttoolplugin.h +new file mode 100644 +index 0000000..bea9056 +--- /dev/null ++++ b/src/Host/KritaPlugin/gmicqttoolplugin.h +@@ -0,0 +1,55 @@ ++/* ++ * This file is part of G'MIC-Qt, a generic plug-in for raster graphics ++ * editors, offering hundreds of filters thanks to the underlying G'MIC ++ * image processing framework. ++ * ++ * Copyright (C) 2020-2021 L. E. Segovia ++ * ++ * Description: Krita painting suite plugin for G'Mic-Qt. ++ * ++ * G'MIC-Qt 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. ++ * ++ * G'MIC-Qt 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 . ++ * ++ */ ++ ++#ifndef GMICQT_TOOL_PLUGIN_H ++#define GMICQT_TOOL_PLUGIN_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++namespace GmicQtHost ++{ ++extern QVector sharedMemorySegments; ++extern std::shared_ptr iface; ++} // namespace GmicQtHost ++ ++class KritaGmicPlugin : public QObject, public KisQmicPluginInterface ++{ ++ Q_OBJECT ++ Q_INTERFACES(KisQmicPluginInterface) ++ ++public: ++ KritaGmicPlugin(QObject *parent, const QVariantList &); ++ ++ int launch(std::shared_ptr iface, ++ bool headless = false) override; ++}; ++ ++#endif +diff --git a/src/Host/KritaPlugin/gmicqttoolplugin.json b/src/Host/KritaPlugin/gmicqttoolplugin.json +new file mode 100644 +index 0000000..4639d5e +--- /dev/null ++++ b/src/Host/KritaPlugin/gmicqttoolplugin.json +@@ -0,0 +1,9 @@ ++{ ++ "Id": "GMic-Qt Krita Plugin", ++ "Type": "Service", ++ "X-KDE-Library": "gmic_krita_qt", ++ "X-KDE-ServiceTypes": [ ++ "Krita/GMic" ++ ], ++ "X-Krita-Version": "28" ++} +diff --git a/src/Host/KritaPlugin/host.cpp b/src/Host/KritaPlugin/host.cpp +new file mode 100644 +index 0000000..7206922 +--- /dev/null ++++ b/src/Host/KritaPlugin/host.cpp +@@ -0,0 +1,188 @@ ++/* ++ * Copyright (C) 2017 Boudewijn Rempt ++ * Copyright (C) 2020-2021 L. E. Segovia ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public License ++ * along with this library; see the file COPYING.LIB. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "GmicQt.h" ++#include "Host/GmicQtHost.h" ++#include "CImg.h" ++#include "gmic.h" ++#include "kis_qmic_interface.h" ++ ++/* ++ * No messages are sent in the plugin version of GMic. ++ * Instead, a list of KisQMicImageSP (shared pointers to KisQMic instances) ++ * are sent. These have: ++ * ++ * layer name ++ * shared pointer to data ++ * width ++ * height ++ * a mutex to control access. ++ * ++ * For the sake of debuggability, the overall control flow has been maintained. ++ */ ++ ++namespace GmicQtHost ++{ ++const QString ApplicationName = QStringLiteral("Krita"); ++const char *const ApplicationShortname = GMIC_QT_XSTRINGIFY(GMIC_HOST); ++const bool DarkThemeIsDefault = false; ++ ++QVector sharedMemorySegments; ++std::shared_ptr iface; ++ ++void getLayersExtent(int *width, int *height, GmicQt::InputMode mode) ++{ ++ const auto size = iface->gmic_qt_get_image_size(); ++ *width = size.width(); ++ *height = size.height(); ++ ++ // qDebug() << "gmic-qt: layers extent:" << *width << *height; ++} ++ ++void getCroppedImages(gmic_list &images, ++ gmic_list &imageNames, ++ double x, ++ double y, ++ double width, ++ double height, ++ GmicQt::InputMode mode) ++{ ++ // qDebug() << "gmic-qt: get_cropped_images:" << x << y << width << height; ++ ++ const bool entireImage = x < 0 && y < 0 && width < 0 && height < 0; ++ if (entireImage) { ++ x = 0.0; ++ y = 0.0; ++ width = 1.0; ++ height = 1.0; ++ } ++ ++ // Create a message for Krita ++ QRectF cropRect = {x, y, width, height}; ++ auto imagesList = ++ iface->gmic_qt_get_cropped_images(static_cast(mode), cropRect); ++ ++ if (imagesList.isEmpty()) { ++ qWarning() << "\tgmic-qt: empty answer!"; ++ return; ++ } ++ ++ // qDebug() << "\tgmic-qt: " << answer; ++ ++ images.assign(imagesList.size()); ++ imageNames.assign(imagesList.size()); ++ ++ // qDebug() << "\tgmic-qt: imagelist size" << imagesList.size(); ++ ++ // Get the layers as prepared by Krita in G'Mic format ++ for (int i = 0; i < imagesList.length(); ++i) { ++ const auto &layer = imagesList[i]; ++ QByteArray ba = layer->m_layerName.toUtf8().toHex(); ++ gmic_image::string(ba.constData()).move_to(imageNames[i]); ++ ++ // Fill images from the shared memory areas ++ ++ { ++ QMutexLocker lock(&layer->m_mutex); ++ ++ // qDebug() << "Memory segment" << (quintptr)image.data() << image->size() ++ // << (quintptr)&image->m_data << (quintptr)image->m_data.get(); ++ ++ // convert the data to the list of float ++ gmic_image gimg; ++ gimg.assign(layer->m_width, layer->m_height, 1, 4); ++ const size_t length = ++ layer->m_width * layer->m_height * 4U * sizeof(float); ++ std::memcpy(gimg._data, layer->constData(), length); ++ gimg.move_to(images[i]); ++ } ++ } ++ ++ iface->gmic_qt_detach(); ++ ++ // qDebug() << "\tgmic-qt: Images size" << images.size() << ", names size" << ++ // imageNames.size(); ++} ++ ++void outputImages(gmic_list &images, ++ const gmic_list &imageNames, ++ GmicQt::OutputMode mode) ++{ ++ // qDebug() << "qmic-qt-output-images"; ++ ++ sharedMemorySegments.clear(); ++ ++ // qDebug() << "\tqmic-qt: shared memory" << sharedMemorySegments.count(); ++ ++ // Create qsharedmemory segments for each image ++ // Create a message for Krita based on mode, the keys of the qsharedmemory ++ // segments and the imageNames ++ QVector layers; ++ ++ for (uint i = 0; i < images.size(); ++i) { ++ // qDebug() << "\tgmic-qt: image number" << i; ++ ++ gmic_image gimg = images.at(i); ++ ++ QString layerName((const char *)imageNames[i]); ++ ++ KisQMicImageSP m = KisQMicImageSP::create( ++ layerName, gimg._width, gimg._height, gimg._spectrum); ++ sharedMemorySegments << m; ++ ++ { ++ QMutexLocker lock(&m->m_mutex); ++ ++ const size_t length = ++ gimg._width * gimg._height * gimg._spectrum * sizeof(float); ++ std::memcpy(m->m_data, gimg._data, length); ++ } ++ ++ layers << m; ++ } ++ ++ iface->gmic_qt_output_images(static_cast(mode), layers); ++} ++ ++void showMessage(const char *) ++{ ++ // May be left empty for Krita. ++ // Only used by launchPluginHeadless(), called in the non-interactive ++ // script mode of GIMP. ++} ++ ++void applyColorProfile(cimg_library::CImg &) ++{ ++} ++ ++} // namespace GmicQtHost +diff --git a/src/Host/None/JpegQualityDialog.cpp b/src/Host/None/JpegQualityDialog.cpp +index b351994..3ea120d 100644 +--- a/src/Host/None/JpegQualityDialog.cpp ++++ b/src/Host/None/JpegQualityDialog.cpp +@@ -1,6 +1,7 @@ + #include "JpegQualityDialog.h" + #include + #include "ui_jpegqualitydialog.h" ++#include "Globals.h" + int JpegQualityDialog::_permanentQuality = -1; + int JpegQualityDialog::_selectedQuality = -1; + +@@ -14,7 +15,7 @@ JpegQualityDialog::JpegQualityDialog(QWidget * parent) : QDialog(parent), ui(new + ui->spinBox->setRange(0, 100); + + if (_selectedQuality == -1) { +- _selectedQuality = QSettings().value(JPEG_QUALITY_KEY, 85).toInt(); ++ _selectedQuality = GMIC_SETTINGS_INLINE.value(JPEG_QUALITY_KEY, 85).toInt(); + } + + ui->slider->setValue(_selectedQuality); +@@ -24,7 +25,7 @@ JpegQualityDialog::JpegQualityDialog(QWidget * parent) : QDialog(parent), ui(new + connect(ui->spinBox, QOverload::of(&QSpinBox::valueChanged), ui->slider, &QSlider::setValue); + connect(ui->pbOk, &QPushButton::clicked, [this]() { + _selectedQuality = ui->spinBox->value(); +- QSettings().setValue(JPEG_QUALITY_KEY, _selectedQuality); ++ GMIC_SETTINGS_INLINE.setValue(JPEG_QUALITY_KEY, _selectedQuality); + }); + connect(ui->pbOk, &QPushButton::clicked, this, &QDialog::accept); + connect(ui->pbCancel, &QPushButton::clicked, this, &QDialog::reject); +diff --git a/src/LanguageSettings.cpp b/src/LanguageSettings.cpp +index e18f31f..8c6f8f2 100644 +--- a/src/LanguageSettings.cpp ++++ b/src/LanguageSettings.cpp +@@ -23,6 +23,7 @@ + * + */ + ++#include "Globals.h" + #include "LanguageSettings.h" + #include + #include +@@ -66,7 +67,11 @@ const QMap & LanguageSettings::availableLanguages() + + QString LanguageSettings::configuredTranslator() + { +- QString code = QSettings().value(LANGUAGE_CODE_KEY, QString()).toString(); ++#ifndef _GMIC_QT_DISABLE_TRANSLATION_ ++ QString code = GMIC_SETTINGS_INLINE.value(LANGUAGE_CODE_KEY, QString()).toString(); ++#else ++ QString code; ++#endif + if (code.isEmpty()) { + code = systemDefaultAndAvailableLanguageCode(); + if (code.isEmpty()) { +@@ -105,7 +110,7 @@ void LanguageSettings::installTranslators() + if (!lang.isEmpty() && (lang != "en")) { + installQtTranslator(lang); + installTranslator(QString(":/translations/%1.qm").arg(lang)); +- if (QSettings().value(ENABLE_FILTER_TRANSLATION, false).toBool()) { ++ if (GMIC_SETTINGS_INLINE.value(ENABLE_FILTER_TRANSLATION, false).toBool()) { + installTranslator(QString(":/translations/filters/%1.qm").arg(lang)); + } + } +diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp +index 4f5e650..d614cd8 100644 +--- a/src/MainWindow.cpp ++++ b/src/MainWindow.cpp +@@ -185,8 +185,12 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent), ui(new Ui::MainW + updateShortcutF5->setContext(Qt::ApplicationShortcut); + QShortcut * updateShortcutCtrlR = new QShortcut(QKeySequence("Ctrl+R"), this); + updateShortcutCtrlR->setContext(Qt::ApplicationShortcut); ++#ifdef _GMIC_QT_DISABLE_UPDATES_ ++ ui->tbUpdateFilters->setEnabled(false); ++#else + connect(updateShortcutF5, &QShortcut::activated, [this]() { ui->tbUpdateFilters->animateClick(); }); + connect(updateShortcutCtrlR, &QShortcut::activated, [this]() { ui->tbUpdateFilters->animateClick(); }); ++#endif + ui->tbUpdateFilters->setToolTip(updateText); + } + +@@ -274,6 +278,7 @@ void MainWindow::setIcons() + ui->tbExpandCollapse->setIcon(_expandIcon); + } + ++#ifndef _GMIC_QT_DISABLE_THEMING_ + void MainWindow::setDarkTheme() + { + // SHOW(QStyleFactory::keys()); +@@ -326,6 +331,7 @@ void MainWindow::setDarkTheme() + ui->vSplitterLine->setStyleSheet("QFrame{ border-top: 0px none #a0a0a0; border-bottom: 1px solid rgb(160,160,160);}"); + DialogSettings::UnselectedFilterTextColor = DialogSettings::UnselectedFilterTextColor.darker(150); + } ++#endif + + void MainWindow::setPluginParameters(const RunParameters & parameters) + { +@@ -380,7 +386,7 @@ void MainWindow::buildFiltersTree() + _filtersPresenter->importGmicGTKFaves(); + _filtersPresenter->saveFaves(); + _gtkFavesShouldBeImported = false; +- QSettings().setValue(FAVES_IMPORT_KEY, true); ++ GMIC_SETTINGS_INLINE.setValue(FAVES_IMPORT_KEY, true); + } + + _filtersPresenter->toggleSelectionMode(withVisibility); +@@ -478,7 +484,7 @@ void MainWindow::onStartupFiltersUpdateFinished(int status) + } else if (status == (int)Updater::UpdateStatus::NotNecessary) { + } + +- if (QSettings().value(FAVES_IMPORT_KEY, false).toBool() || !FavesModelReader::gmicGTKFaveFileAvailable()) { ++ if (GMIC_SETTINGS_INLINE.value(FAVES_IMPORT_KEY, false).toBool() || !FavesModelReader::gmicGTKFaveFileAvailable()) { + _gtkFavesShouldBeImported = false; + } else { + _gtkFavesShouldBeImported = askUserForGTKFavesImport(); +@@ -495,7 +501,7 @@ void MainWindow::onStartupFiltersUpdateFinished(int status) + } + + // Retrieve and select previously selected filter +- QString hash = QSettings().value("SelectedFilter", QString()).toString(); ++ QString hash = GMIC_SETTINGS_INLINE.value("SelectedFilter", QString()).toString(); + if (_newSession || !_lastExecutionOK) { + hash.clear(); + } +@@ -560,7 +566,9 @@ void MainWindow::onEscapeKeyPressed() + } else { + _processor.cancel(); + ui->previewWidget->displayOriginalImage(); ++#ifndef _GMIC_QT_DISABLE_UPDATES_ + ui->tbUpdateFilters->setEnabled(true); ++#endif + } + } + } +@@ -672,7 +680,9 @@ void MainWindow::onPreviewUpdateRequested(bool synchronous) + ui->previewWidget->displayOriginalImage(); + return; + } ++#ifndef _GMIC_QT_DISABLE_UPDATES_ + ui->tbUpdateFilters->setEnabled(false); ++#endif + + const FiltersPresenter::Filter currentFilter = _filtersPresenter->currentFilter(); + GmicProcessor::FilterContext context; +@@ -734,7 +744,9 @@ void MainWindow::onPreviewImageAvailable() + } + ui->previewWidget->setPreviewImage(_processor.previewImage()); + ui->previewWidget->enableRightClick(); ++#ifndef _GMIC_QT_DISABLE_UPDATES_ + ui->tbUpdateFilters->setEnabled(true); ++#endif + if (_pendingActionAfterCurrentProcessing == ProcessingAction::Close) { + close(); + } +@@ -744,7 +756,9 @@ void MainWindow::onPreviewError(const QString & message) + { + ui->previewWidget->setPreviewErrorMessage(message); + ui->previewWidget->enableRightClick(); ++#ifndef _GMIC_QT_DISABLE_UPDATES_ + ui->tbUpdateFilters->setEnabled(true); ++#endif + if (_pendingActionAfterCurrentProcessing == ProcessingAction::Close) { + close(); + } +@@ -970,7 +984,7 @@ void MainWindow::saveCurrentParameters() + + void MainWindow::saveSettings() + { +- QSettings settings; ++ GMIC_SETTINGS(settings); + + _filtersPresenter->saveSettings(settings); + +@@ -1011,7 +1025,7 @@ void MainWindow::saveSettings() + + void MainWindow::loadSettings() + { +- QSettings settings; ++ GMIC_SETTINGS(settings); + _filtersPresenter->loadSettings(settings); + + _lastExecutionOK = settings.value("LastExecution/ExitedNormally", true).toBool(); +@@ -1027,9 +1041,11 @@ void MainWindow::loadSettings() + if (settings.value("Config/PreviewPosition", "Left").toString() == "Left") { + setPreviewPosition(PreviewPosition::Left); + } ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + setDarkTheme(); + } ++#endif + if (!DialogSettings::logosAreVisible()) { + ui->logosLabel->hide(); + } +@@ -1069,7 +1085,7 @@ void MainWindow::loadSettings() + ui->splitter->setSizes(sizes); + } + +- ui->cbInternetUpdate->setChecked(settings.value("Config/RefreshInternetUpdate", true).toBool()); ++ ui->cbInternetUpdate->setChecked(settings.value(REFRESH_USING_INTERNET_KEY, INTERNET_DEFAULT_REFRESH_UPDATE).toBool()); + } + + void MainWindow::setPreviewPosition(MainWindow::PreviewPosition position) +@@ -1131,7 +1147,7 @@ void MainWindow::setPreviewPosition(MainWindow::PreviewPosition position) + void MainWindow::adjustVerticalSplitter() + { + QList sizes; +- QSettings settings; ++ GMIC_SETTINGS(settings); + sizes.push_back(settings.value(QString("Config/ParamsVerticalSplitterSizeTop"), -1).toInt()); + sizes.push_back(settings.value(QString("Config/ParamsVerticalSplitterSizeBottom"), -1).toInt()); + const int splitterHeight = ui->verticalSplitter->height(); +@@ -1252,12 +1268,16 @@ void MainWindow::showEvent(QShowEvent * event) + Updater::setOutputMessageMode(DialogSettings::outputMessageMode()); + int ageLimit; + { +- QSettings settings; ++ GMIC_SETTINGS(settings); + ageLimit = settings.value(INTERNET_UPDATE_PERIODICITY_KEY, INTERNET_DEFAULT_PERIODICITY).toInt(); + } ++#ifndef _GMIC_QT_DISABLE_UPDATES_ + const bool useNetwork = (ageLimit != INTERNET_NEVER_UPDATE_PERIODICITY); ++#else ++ const bool useNetwork = false; ++#endif + ui->progressInfoWidget->startFiltersUpdateAnimationAndShow(); +- Updater::getInstance()->startUpdate(ageLimit, 4, useNetwork); ++ Updater::getInstance()->startUpdate(ageLimit, 60, useNetwork); + } + + void MainWindow::resizeEvent(QResizeEvent * e) +@@ -1274,17 +1294,19 @@ bool MainWindow::askUserForGTKFavesImport() + QMessageBox::Yes | QMessageBox::No, this); + messageBox.setDefaultButton(QMessageBox::Yes); + QCheckBox * cb = new QCheckBox(tr("Don't ask again")); ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + QPalette p = cb->palette(); + p.setColor(QPalette::Text, DialogSettings::CheckBoxTextColor); + p.setColor(QPalette::Base, DialogSettings::CheckBoxBaseColor); + cb->setPalette(p); + } ++#endif + messageBox.setCheckBox(cb); + int choice = messageBox.exec(); + if (choice != QMessageBox::Yes) { + if (cb->isChecked()) { +- QSettings().setValue(FAVES_IMPORT_KEY, true); ++ GMIC_SETTINGS_INLINE.setValue(FAVES_IMPORT_KEY, true); + } + return false; + } +diff --git a/src/MainWindow.h b/src/MainWindow.h +index a72f762..3819510 100644 +--- a/src/MainWindow.h ++++ b/src/MainWindow.h +@@ -71,7 +71,9 @@ public: + explicit MainWindow(QWidget * parent = nullptr); + ~MainWindow() override; + void updateFiltersFromSources(int ageLimit, bool useNetwork); ++#ifndef _GMIC_QT_DISABLE_THEMING_ + void setDarkTheme(); ++#endif + void setPluginParameters(const RunParameters & parameters); + + public slots: +diff --git a/src/Tags.cpp b/src/Tags.cpp +index 4092ccc..d33e460 100644 +--- a/src/Tags.cpp ++++ b/src/Tags.cpp +@@ -148,7 +148,10 @@ QAction * TagAssets::action(QObject * parent, TagColor color, IconMark mark) + if ((color == TagColor::None) || (color == TagColor::Count)) { + return nullptr; + } +- return new QAction(menuIcon(color, mark), QObject::tr("%1 Tag").arg(colorName(color)), parent); ++ QAction *action = new QAction(menuIcon(color, mark), QObject::tr("%1 Tag").arg(colorName(color)), parent); ++ if (qApp->testAttribute(Qt::AA_DontShowIconsInMenus)) ++ action->setIconVisibleInMenu(true); ++ return action; + } + + QString TagAssets::colorName(TagColor color) +diff --git a/src/Widgets/InOutPanel.cpp b/src/Widgets/InOutPanel.cpp +index a388052..67bdcd1 100644 +--- a/src/Widgets/InOutPanel.cpp ++++ b/src/Widgets/InOutPanel.cpp +@@ -158,10 +158,12 @@ void InOutPanel::onResetButtonClicked() + setState(InputOutputState::Default, true); + } + ++#ifndef _GMIC_QT_DISABLE_THEMING_ + void InOutPanel::setDarkTheme() + { + ui->tbReset->setIcon(LOAD_ICON("view-refresh")); + } ++#endif + + void InOutPanel::setDefaultInputMode() + { +diff --git a/src/Widgets/InOutPanel.h b/src/Widgets/InOutPanel.h +index 381bc64..7939d3a 100644 +--- a/src/Widgets/InOutPanel.h ++++ b/src/Widgets/InOutPanel.h +@@ -79,7 +79,9 @@ public slots: + void onInputModeSelected(int); + void onOutputModeSelected(int); + void onResetButtonClicked(); ++#ifndef _GMIC_QT_DISABLE_THEMING_ + void setDarkTheme(); ++#endif + + private: + static void setDefaultInputMode(); +diff --git a/src/Widgets/ProgressInfoWindow.cpp b/src/Widgets/ProgressInfoWindow.cpp +index 341e2e0..cdde227 100644 +--- a/src/Widgets/ProgressInfoWindow.cpp ++++ b/src/Widgets/ProgressInfoWindow.cpp +@@ -60,9 +60,11 @@ ProgressInfoWindow::ProgressInfoWindow(HeadlessProcessor * processor) : QMainWin + connect(processor, &HeadlessProcessor::done, this, &ProgressInfoWindow::onProcessingFinished); + _isShown = false; + ++#ifndef _GMIC_QT_DISABLE_THEMING_ + if (DialogSettings::darkThemeEnabled()) { + setDarkTheme(); + } ++#endif + } + + ProgressInfoWindow::~ProgressInfoWindow() +@@ -86,6 +88,7 @@ void ProgressInfoWindow::closeEvent(QCloseEvent * event) + event->accept(); + } + ++#ifndef _GMIC_QT_DISABLE_THEMING_ + void ProgressInfoWindow::setDarkTheme() + { + qApp->setStyle(QStyleFactory::create("Fusion")); +@@ -108,6 +111,7 @@ void ProgressInfoWindow::setDarkTheme() + p.setColor(QPalette::Disabled, QPalette::WindowText, QColor(110, 110, 110)); + qApp->setPalette(p); + } ++#endif + + void ProgressInfoWindow::onCancelClicked(bool) + { +diff --git a/src/Widgets/ProgressInfoWindow.h b/src/Widgets/ProgressInfoWindow.h +index 2fe13cd..d1c67ad 100644 +--- a/src/Widgets/ProgressInfoWindow.h ++++ b/src/Widgets/ProgressInfoWindow.h +@@ -57,7 +57,9 @@ public: + protected: + void showEvent(QShowEvent *) override; + void closeEvent(QCloseEvent *) override; ++#ifndef _GMIC_QT_DISABLE_THEMING_ + void setDarkTheme(); ++#endif + + public slots: + void onCancelClicked(bool); +diff --git a/ui/dialogsettings.ui b/ui/dialogsettings.ui +index 8345152..17d8bb8 100644 +--- a/ui/dialogsettings.ui ++++ b/ui/dialogsettings.ui +@@ -108,7 +108,7 @@ + + + +- ++ + + Theme + diff --git a/series b/series new file mode 100644 index 0000000..d883c03 --- /dev/null +++ b/series @@ -0,0 +1,4 @@ +gmic-make-build-without-gmic-cpp.patch +gmic-qt-make-it-work-without-gmic-cpp.patch +krita5.patch +56f7340ecb1fbbe6fce87d0a5c8d35dd13359577.patch