summaryrefslogtreecommitdiffstats
path: root/kde/patch
diff options
context:
space:
mode:
author Eric Hameleers <alien@slackware.com>2020-07-31 16:13:18 +0200
committer Eric Hameleers <alien@slackware.com>2020-07-31 16:13:18 +0200
commit703149752c6265b36973d2c1f0f5a69721e3128a (patch)
tree7ded0d801771d5705f48ffbfb48f37dd4829439e /kde/patch
parentdd005500c624d127321ff3fe14a0c29bfa8d67f7 (diff)
parentcd7ff1719433fbb3b6a8304596be173bc1b91b00 (diff)
downloadktown-master.tar.gz
ktown-master.tar.xz
Merge branch 'elogind'HEADmaster
Diffstat (limited to 'kde/patch')
-rw-r--r--kde/patch/akonadi.patch12
-rw-r--r--kde/patch/akonadi/akonadi_mariadb_qtsql.patch91
-rw-r--r--kde/patch/akonadi/akonadi_rename-header.patch77
-rw-r--r--kde/patch/akonadi/akonadi_revert-abs-path.patch70
-rw-r--r--kde/patch/akonadi4.patch1
-rw-r--r--kde/patch/amarok.patch1
-rw-r--r--kde/patch/ark.patch8
-rw-r--r--kde/patch/ark/ark_cve-2020-16116.patch47
-rw-r--r--kde/patch/ark/ark_kdebug357057.patch37
-rw-r--r--kde/patch/baloo5.patch5
-rw-r--r--kde/patch/baloo5/baloo-4.96.0_kaboutdata.diff69
-rw-r--r--kde/patch/baloo5/baloo_def_indexing_disabled.patch12
-rw-r--r--kde/patch/calligra.patch15
-rw-r--r--kde/patch/calligra/calligra3_poppler-0.71.patch131
-rw-r--r--kde/patch/calligra/calligra3_poppler-0.72.patch29
-rw-r--r--kde/patch/calligra/calligra3_poppler-0.73.patch32
-rw-r--r--kde/patch/calligra/calligra3_qt511.patch135
-rw-r--r--kde/patch/calligra/calligra3_qt513.patch22
-rw-r--r--kde/patch/calligraplan.patch13
-rw-r--r--kde/patch/calligraplan/calligraplan.kcalcore.1.patch47
-rw-r--r--kde/patch/calligraplan/calligraplan.kcalcore.2.patch85
-rw-r--r--kde/patch/calligraplan/calligraplan.kcalendarcore.patch34
-rw-r--r--kde/patch/calligraplan/calligraplan.missingheader.patch25
-rw-r--r--kde/patch/calligraplan/calligraplan.qt-5.15.patch10
-rw-r--r--kde/patch/calligraplan/calligraplan.qt-511.patch125
-rw-r--r--kde/patch/cantor.patch4
-rw-r--r--kde/patch/cantor/cantor_julia.patch193
-rw-r--r--kde/patch/cantor/cantor_python.patch31
-rw-r--r--kde/patch/digikam.patch12
-rw-r--r--kde/patch/digikam/digikam_clang_fix.patch38
-rw-r--r--kde/patch/digikam/digikam_databasemodel.patch13337
-rw-r--r--kde/patch/digikam/digikam_imagemagick7.patch40
-rw-r--r--kde/patch/dolphin.patch1
-rw-r--r--kde/patch/falkon.patch2
-rw-r--r--kde/patch/falkon/falkon.qt-5.15.diff20
-rw-r--r--kde/patch/gwenview.patch4
-rw-r--r--kde/patch/gwenview/gwenview-17.04.1_dataloss.patch131
-rw-r--r--kde/patch/kaccounts-integration.patch4
-rw-r--r--kde/patch/kaccounts-integration/kaccounts-integration-15.08.3_service.patch28
-rw-r--r--kde/patch/kalgebra.patch1
-rw-r--r--kde/patch/kalzium.patch3
-rw-r--r--kde/patch/kalzium/kalzium_kf_5.31.patch156
-rw-r--r--kde/patch/kate.patch5
-rw-r--r--kde/patch/kate/kate-15.12.0.patch31
-rw-r--r--kde/patch/kcalc.patch5
-rw-r--r--kde/patch/kcalc/kcalc-kdebug_360105.patch15
-rw-r--r--kde/patch/kcalcore.patch4
-rw-r--r--kde/patch/kcalcore/kcalcore_libical3.patch109
-rw-r--r--kde/patch/kcoreaddons.patch5
-rw-r--r--kde/patch/kcoreaddons/kcoreaddons.kdebug_362161.patch27
-rw-r--r--kde/patch/kde-baseapps.patch5
-rw-r--r--kde/patch/kde-baseapps/dolphin_kdebug_327224.patch57
-rw-r--r--kde/patch/kde-cli-tools.patch6
-rw-r--r--kde/patch/kde-cli-tools/kde-cli-tools_ecm.patch11
-rw-r--r--kde/patch/kde-cli-tools/kde-cli-tools_kaboutdata.diff59
-rw-r--r--kde/patch/kde-dev-utils.patch3
-rw-r--r--kde/patch/kde-dev-utils/build_with_kf548.patch156
-rw-r--r--kde/patch/kde-gtk-config.patch4
-rw-r--r--kde/patch/kde-gtk-config/kde-gtk-config_loadcurrentsettings.patch622
-rw-r--r--kde/patch/kde-runtime.patch8
-rw-r--r--kde/patch/kde-runtime/kde-runtime.kdebug324470.diff49
-rw-r--r--kde/patch/kde-runtime/kde-runtime_gpgme.patch133
-rw-r--r--kde/patch/kde-workspace.patch4
-rw-r--r--kde/patch/kde-workspace/kde-workspace.desktopnames.diff34
-rw-r--r--kde/patch/kdeconnect-kde.patch1
-rw-r--r--kde/patch/kdelibs.patch3
-rw-r--r--kde/patch/kdelibs/fixbic-4.14.6.patch47
-rw-r--r--kde/patch/kdelibs/kdelibs.grantlee-qt4.include.path.patch11
-rw-r--r--kde/patch/kdelibs4support.patch4
-rw-r--r--kde/patch/kdelibs4support/update-FindGettext.patch36
-rw-r--r--kde/patch/kdenlive.patch4
-rw-r--r--kde/patch/kdenlive/kdenlive_gcc7.patch32
-rw-r--r--kde/patch/kdepim.patch4
-rw-r--r--kde/patch/kdepim/kdepim-install_kleopatra_headers.patch129
-rw-r--r--kde/patch/kdepimlibs.patch3
-rw-r--r--kde/patch/kdepimlibs/kdepimlibs_kmail_crash.patch59
-rw-r--r--kde/patch/kdepimlibs4.patch3
-rw-r--r--kde/patch/kdepimlibs4/kdepimlibs.libical3.diff184
-rw-r--r--kde/patch/kdeplasma-addons.patch4
-rw-r--r--kde/patch/kdeplasma-addons/random_generator_cve-2013-2120.patch76
-rw-r--r--kde/patch/kdesdk-kioslaves.patch3
-rw-r--r--kde/patch/kdesdk-kioslaves/svn19.patch87
-rw-r--r--kde/patch/kdev-python.patch4
-rw-r--r--kde/patch/kdev-python/kdev-python-5.4.4_python38.patch560
-rw-r--r--kde/patch/kdewebdev.patch6
-rw-r--r--kde/patch/kdewebdev/include-tidy.patch13
-rw-r--r--kde/patch/kholidays.patch8
-rw-r--r--kde/patch/kholidays/kholidays_depfreeze_revert.patch61
-rw-r--r--kde/patch/kholidays/kholidays_isnan.patch30
-rw-r--r--kde/patch/kinfocenter.patch1
-rw-r--r--kde/patch/kio.patch18
-rw-r--r--kde/patch/kio/kio_KDEBUG_399709.patch44
-rw-r--r--kde/patch/kio/kio_dolphin_servicemenus.patch126
-rw-r--r--kde/patch/kio/kio_fix_url_setpath.patch65
-rw-r--r--kde/patch/kio/kio_kdelibs4_docpatch.patch22
-rw-r--r--kde/patch/kirigami2.patch8
-rw-r--r--kde/patch/kirigami2/kirigami_iconview_crash.patch143
-rw-r--r--kde/patch/kirigami2/kirigami_scrollbar.patch25
-rw-r--r--kde/patch/kmail.patch4
-rw-r--r--kde/patch/kmail/kmail_kontact_kdebug_404881.patch75
-rw-r--r--kde/patch/kmplot.patch3
-rw-r--r--kde/patch/kmplot/kmplot_isnan.patch42
-rw-r--r--kde/patch/konsole.patch16
-rw-r--r--kde/patch/konsole/konsole.cursor.antialias.patch83
-rw-r--r--kde/patch/konsole/konsole.konsolepart.segfault.closing.after.contextmenu.patch43
-rw-r--r--kde/patch/konsole/konsole.konsolepart.segfault.closing.session.via.menu.patch58
-rw-r--r--kde/patch/konsole/konsole.term.is.konsole.patch24
-rw-r--r--kde/patch/kopete.patch9
-rw-r--r--kde/patch/kopete/kopete_kdebug376348.patch127
-rw-r--r--kde/patch/kopete/kopete_kdebug393372.patch30
-rw-r--r--kde/patch/korundum.patch5
-rw-r--r--kde/patch/korundum/korundum_ruby19.patch31
-rw-r--r--kde/patch/kpat.patch6
-rw-r--r--kde/patch/kpat/kpat_no_freecell_solver_dep.patch1475
-rw-r--r--kde/patch/krita.patch7
-rw-r--r--kde/patch/krita/krita_qt512.patch117
-rw-r--r--kde/patch/krita/krita_qt59.patch26
-rw-r--r--kde/patch/krita/krita_qtabletevents.patch67
-rw-r--r--kde/patch/krunner.patch4
-rw-r--r--kde/patch/krunner/krunner_KDEBUG_423003.patch54
-rw-r--r--kde/patch/kscreenlocker.patch13
-rw-r--r--kde/patch/kscreenlocker/kscreenlocker_CVE-2016-2312.patch36
-rw-r--r--kde/patch/kscreenlocker/kscreenlocker_crash_force_softrender.patch112
-rw-r--r--kde/patch/kscreenlocker/kscreenlocker_rendersettings.patch49
-rw-r--r--kde/patch/kstars.patch3
-rw-r--r--kde/patch/kstars/kstars_isnan.patch46
-rw-r--r--kde/patch/ksudoku.patch4
-rw-r--r--kde/patch/ksudoku/ksudoku_qwindowtitle.patch15
-rw-r--r--kde/patch/ktexteditor.patch3
-rw-r--r--kde/patch/ktexteditor/ktexteditor_fix_indentation.patch32
-rw-r--r--kde/patch/ktorrent.patch7
-rw-r--r--kde/patch/ktorrent/ktorrent_systray.patch24
-rw-r--r--kde/patch/ktorrent/ktorrent_taglib_linking.patch248
-rw-r--r--kde/patch/ktp-accounts-kcm.patch4
-rw-r--r--kde/patch/ktp-accounts-kcm/ktp-accounts-kcm_kdebug_351785.patch32
-rw-r--r--kde/patch/kwin.patch11
-rw-r--r--kde/patch/kwin/kwin_cmake310.patch52
-rw-r--r--kde/patch/kwin/kwin_qt59_rootwindow_events.patch63
-rw-r--r--kde/patch/kwin/kwin_replace_logind_with_ck2.patch85
-rw-r--r--kde/patch/libkdcraw.patch3
-rw-r--r--kde/patch/libkdcraw/libkdcraw_cmake_minver.patch7
-rw-r--r--kde/patch/libkexiv2.patch3
-rw-r--r--kde/patch/libkexiv2/libkexiv2_cmake_minver.patch7
-rw-r--r--kde/patch/libkface.patch1
-rw-r--r--kde/patch/libkleo.patch4
-rw-r--r--kde/patch/libkleo/libkleo_gcc7.patch27
-rw-r--r--kde/patch/libksysguard.patch4
-rw-r--r--kde/patch/libksysguard/libksysguard_isnan.patch176
-rw-r--r--kde/patch/marble.patch4
-rw-r--r--kde/patch/marble/marble_qt4.patch47
-rw-r--r--kde/patch/messagelib.patch4
-rw-r--r--kde/patch/messagelib/messagelib_CVE-2018-19516.patch20
-rw-r--r--kde/patch/okular.patch3
-rw-r--r--kde/patch/okular/cve-2020-9359.patch32
-rw-r--r--kde/patch/oxygen-gtk2.patch1
-rw-r--r--kde/patch/oxygen-gtk3.patch3
-rw-r--r--kde/patch/oxygen-gtk3/oxygen-gtk3-1.3.1_gtk3.8.patch29
-rw-r--r--kde/patch/perlqt.patch1
-rw-r--r--kde/patch/plasma-browser-integration.patch1
-rw-r--r--kde/patch/plasma-desktop.patch20
-rwxr-xr-xkde/patch/plasma-desktop/plasma-desktop-4.99.0_kfontinst_po.diff60
-rw-r--r--kde/patch/plasma-desktop/plasma-desktop_kdebug_401508.patch39
-rw-r--r--kde/patch/plasma-desktop/plasma-desktop_kdebug_416358.patch16
-rw-r--r--kde/patch/plasma-desktop/plasma-desktop_kdebug_417424.patch25
-rw-r--r--kde/patch/plasma-desktop/plasma-desktop_kdelibs4support.diff88
-rw-r--r--kde/patch/plasma-desktop/plasma-desktop_kickoff_kdebug_356398.patch24
-rw-r--r--kde/patch/plasma-framework.patch11
-rw-r--r--kde/patch/plasma-framework/plasma-framework_KDEBUG_357895.patch24
-rw-r--r--kde/patch/plasma-framework/plasma-framework_KDEBUG_359388.patch31
-rw-r--r--kde/patch/plasma-pa.patch5
-rw-r--r--kde/patch/plasma-pa/plasma-pa_enable_gsettings.patch583
-rw-r--r--kde/patch/plasma-wayland-protocols.patch2
-rw-r--r--kde/patch/plasma-wayland-protocols/plasma-wayland-protocols_add.missing.since.13.patch60
-rw-r--r--kde/patch/plasma-workspace.patch17
-rw-r--r--kde/patch/plasma-workspace/plasma-workspace.systray_cpubug.patch152
-rw-r--r--kde/patch/plasma-workspace/plasma-workspace_apply_767aa57.patch23
-rw-r--r--kde/patch/plasma-workspace/plasma-workspace_consolekit2.patch189
-rw-r--r--kde/patch/plasma-workspace/plasma-workspace_kdebug389815.patch32
-rw-r--r--kde/patch/plasma5-nm.patch14
-rw-r--r--kde/patch/plasma5-nm/plasma-nm-fixes.patch322
-rw-r--r--kde/patch/plasma5-nm/plasma-nm_modemmanager-qt_api.patch73
-rw-r--r--kde/patch/plasma5-nm/plasma-nm_networkmanager.patch17
-rw-r--r--kde/patch/plasma5-nm/plasma5-nm_KDEBUG_423093.patch31
-rw-r--r--kde/patch/powerdevil.patch4
-rw-r--r--kde/patch/powerdevil/powerdevil-5.12.4_firstrun.patch42
-rw-r--r--kde/patch/pykde4.patch1
-rw-r--r--kde/patch/qqc2-desktop-style.patch5
-rw-r--r--kde/patch/qqc2-desktop-style/qqc2-desktop-style_scrollbar.patch51
-rw-r--r--kde/patch/sddm-theme-breeze.patch2
-rw-r--r--kde/patch/sddm-theme-breeze/sddm-theme-breeze_path.diff10
-rw-r--r--kde/patch/spectacle.patch7
-rw-r--r--kde/patch/spectacle/spectacle_hidpi.patch28
-rw-r--r--kde/patch/spectacle/spectacle_rect_capture.patch52
-rw-r--r--kde/patch/strigi-multimedia.patch1
-rw-r--r--kde/patch/umbrello.patch10
-rw-r--r--kde/patch/umbrello/umbrello-4.11.4_listitem.patch13
-rw-r--r--kde/patch/umbrello/umbrello_qt510_kaboutdata_h.patch33
197 files changed, 512 insertions, 23441 deletions
diff --git a/kde/patch/akonadi.patch b/kde/patch/akonadi.patch
deleted file mode 100644
index ddab2a8..0000000
--- a/kde/patch/akonadi.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-# Remove hardcoded absolute path to stdlib header.
-# This is Windows-centric and breaks on any linux GCC upgrade.
-# Thanks to Gentoo where I found the following two patches at
-# https://packages.gentoo.org/packages/kde-apps/akonadi
-# No longer needed since 17.04.0.
-#cat $CWD/patch/akonadi/akonadi_revert-abs-path.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-#cat $CWD/patch/akonadi/akonadi_rename-header.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Temporary fix for non-working Akonadi in combination with mariadb 10.2.8
-# (actually this is a bug in qtsql, not in akonadi or mariadb):
-#cat $CWD/patch/akonadi/akonadi_mariadb_qtsql.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/akonadi/akonadi_mariadb_qtsql.patch b/kde/patch/akonadi/akonadi_mariadb_qtsql.patch
deleted file mode 100644
index 7ec6d7c..0000000
--- a/kde/patch/akonadi/akonadi_mariadb_qtsql.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-Patch taken from https://cgit.kde.org/akonadi.git/patch/?id=b145f47f000978b9d39edc1882849ec7f6b3ef79
-
-Upstream bug reports:
-https://bugs.kde.org/show_bug.cgi?id=383991
-https://bugreports.qt.io/browse/QTBUG-63108
-
-From b145f47f000978b9d39edc1882849ec7f6b3ef79 Mon Sep 17 00:00:00 2001
-From: Heinz Wiesinger <pprkut@liwjatan.at>
-Date: Sun, 17 Sep 2017 10:56:44 +0200
-Subject: Only remove init connections to the database on server shutdown.
-
-Summary:
-With MariaDB 10.2 libmysqlclient was replaced with libmariadb that
-changed how establishing database connections behaves. The MySQL
-QSQL driver calls mysql_server_end() on QSqlDatabase::removeDatabase()
-if the overall connection count dropped to 0 (which it does when
-the init connection is removed).
-A future QSqlDatabase:addDatabase() would call mysql_server_init()
-again, but this no longer works with libmariadb as that one only
-allows calling mysql_server_init() once. Future calls are simply
-ignored.
-
-In order to prevent this from happening we have to keep the
-init connection open until the server shuts down, so the connection
-count only drops to 0 at shutdown and mysql_server_end() isn't
-called before.
-
-This is a workaround for QTBUG-63108
-
-CCBUG: 383991
-
-Reviewers: dvratil, mlaurent
-
-Reviewed By: dvratil
-
-Subscribers: #kde_pim
-
-Tags: #kde_pim
-
-Differential Revision: https://phabricator.kde.org/D7858
----
- src/server/akonadi.cpp | 3 ++-
- src/server/storage/dbconfigmysql.cpp | 4 +++-
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/src/server/akonadi.cpp b/src/server/akonadi.cpp
-index 4364e63..bcb7e88 100644
---- a/src/server/akonadi.cpp
-+++ b/src/server/akonadi.cpp
-@@ -423,13 +423,14 @@ bool AkonadiServer::createDatabase()
- success = false;
- }
- }
-- QSqlDatabase::removeDatabase(initCon);
- return success;
- }
-
- void AkonadiServer::stopDatabaseProcess()
- {
- if (!DbConfig::configuredDatabase()->useInternalServer()) {
-+ // closing initConnection this late to work around QTBUG-63108
-+ QSqlDatabase::removeDatabase(QStringLiteral("initConnection"));
- return;
- }
-
-diff --git a/src/server/storage/dbconfigmysql.cpp b/src/server/storage/dbconfigmysql.cpp
-index 2bd231d..d565706 100644
---- a/src/server/storage/dbconfigmysql.cpp
-+++ b/src/server/storage/dbconfigmysql.cpp
-@@ -492,7 +492,6 @@ bool DbConfigMysql::startInternalServer()
- }
- }
-
-- QSqlDatabase::removeDatabase(initCon);
- return success;
- }
-
-@@ -520,6 +519,9 @@ void DbConfigMysql::stopInternalServer()
- return;
- }
-
-+ // closing initConnection this late to work around QTBUG-63108
-+ QSqlDatabase::removeDatabase(QStringLiteral("initConnection"));
-+
- disconnect(mDatabaseProcess, static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
- this, &DbConfigMysql::processFinished);
-
---
-cgit v0.11.2
-
-
diff --git a/kde/patch/akonadi/akonadi_rename-header.patch b/kde/patch/akonadi/akonadi_rename-header.patch
deleted file mode 100644
index 73347f0..0000000
--- a/kde/patch/akonadi/akonadi_rename-header.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-commit 248671e8200ff0883877b6d0e56700ef99ff3b51
-Author: Andreas Sturmlechner <andreas.sturmlechner@gmail.com>
-Date: Sat Jan 7 14:38:17 2017 +0100
-
- Rename exception.h to exceptionbase.h
-
- REVIEW: 129788
-
-diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
-index 6ac851e..fa996b9 100644
---- a/src/core/CMakeLists.txt
-+++ b/src/core/CMakeLists.txt
-@@ -95,7 +95,7 @@ ecm_generate_headers(AkonadiCore_base_HEADERS
- EntityDeletedAttribute
- EntityDisplayAttribute
- EntityHiddenAttribute
-- Exception
-+ ExceptionBase
- GidExtractorInterface
- IndexPolicyAttribute
- Item
-diff --git a/src/core/exception.cpp b/src/core/exception.cpp
-index f229c1a..14f7330 100644
---- a/src/core/exception.cpp
-+++ b/src/core/exception.cpp
-@@ -17,7 +17,7 @@
- 02110-1301, USA.
- */
-
--#include "exception.h"
-+#include "exceptionbase.h"
-
- #include <QString>
-
-diff --git a/src/core/exception.h b/src/core/exceptionbase.h
-similarity index 100%
-rename from src/core/exception.h
-rename to src/core/exceptionbase.h
-diff --git a/src/core/item.h b/src/core/item.h
-index de71cad..5ec62c8 100644
---- a/src/core/item.h
-+++ b/src/core/item.h
-@@ -23,7 +23,7 @@
-
- #include "akonadicore_export.h"
- #include "attribute.h"
--#include "exception.h"
-+#include "exceptionbase.h"
- #include "tag.h"
- #include "collection.h"
- #include "relation.h"
-diff --git a/src/core/itempayloadinternals_p.h b/src/core/itempayloadinternals_p.h
-index 0a4de3c..1626f10 100644
---- a/src/core/itempayloadinternals_p.h
-+++ b/src/core/itempayloadinternals_p.h
-@@ -32,7 +32,7 @@
-
- #include <boost/shared_ptr.hpp>
-
--#include "exception.h"
-+#include "exceptionbase.h"
-
- //@cond PRIVATE Doxygen 1.7.1 hangs processing this file. so skip it.
- //for more info, see https://bugzilla.gnome.org/show_bug.cgi?id=531637
-diff --git a/src/core/protocolhelper.cpp b/src/core/protocolhelper.cpp
-index f740e9d..c218f0c 100644
---- a/src/core/protocolhelper.cpp
-+++ b/src/core/protocolhelper.cpp
-@@ -23,7 +23,7 @@
- #include "collectionstatistics.h"
- #include "item_p.h"
- #include "collection_p.h"
--#include "exception.h"
-+#include "exceptionbase.h"
- #include "itemserializer_p.h"
- #include "itemserializerplugin.h"
- #include "servermanager.h"
diff --git a/kde/patch/akonadi/akonadi_revert-abs-path.patch b/kde/patch/akonadi/akonadi_revert-abs-path.patch
deleted file mode 100644
index 3b48253..0000000
--- a/kde/patch/akonadi/akonadi_revert-abs-path.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-commit d98e29a07f4acc3bf01f06f25b3eef5522397e2e
-Author: Andreas Sturmlechner <andreas.sturmlechner@gmail.com>
-Date: Thu Jan 5 22:41:02 2017 +0100
-
- Revert "Workaround an include loop on case-insensitive systems"
-
- Do not hardcode absolute patchs to GCC headers.
-
- This reverts commit 59b9d6b79425c9ec1e5df059a2593580048c4adf.
-
- REVIEW: 129788
-
-diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
-index 72589cd..6ac851e 100644
---- a/src/core/CMakeLists.txt
-+++ b/src/core/CMakeLists.txt
-@@ -257,21 +257,6 @@ ecm_generate_headers(AkonadiCore_jobs_HEADERS
- RELATIVE jobs
- )
-
--# This is a workaround for conflict between our "Exception" fancy header and
--# C++ stdlib's "exception" header which occurs in case-insensitive systems.
--# For that reason we generate std_exception.h file, which contains an absolute
--# path to the stdlib's exception header file, which resolves the ambiguity
--# when including <exception> from within Akonadi.
--include(FindStdlibInclude)
--findStdlibInclude("exception" std_exception_file)
--if (NOT "${std_exception_file}" STREQUAL "")
-- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/std_exception.h.in
-- ${CMAKE_CURRENT_BINARY_DIR}/std_exception.h
-- )
--else()
-- message(FATAL_ERROR "stdlib <exception> include absolute path not found")
--endif()
--
- set(akonadicore_dbus_xml ${Akonadi_SOURCE_DIR}/src/interfaces/org.freedesktop.Akonadi.NotificationManager.xml)
- qt5_add_dbus_interface(akonadicore_dbus_SRCS ${akonadicore_dbus_xml} notificationmanagerinterface)
-
-@@ -338,7 +323,6 @@ install(TARGETS
-
- install(FILES
- ${CMAKE_CURRENT_BINARY_DIR}/akonadicore_export.h
-- ${CMAKE_CURRENT_BINARY_DIR}/std_exception.h
- ${AkonadiCore_base_HEADERS}
- ${AkonadiCore_models_HEADERS}
- ${AkonadiCore_jobs_HEADERS}
-diff --git a/src/core/exception.h b/src/core/exception.h
-index d07ca71..2a376df 100644
---- a/src/core/exception.h
-+++ b/src/core/exception.h
-@@ -20,16 +20,11 @@
- #ifndef AKONADI_EXCEPTION_H
- #define AKONADI_EXCEPTION_H
-
--// The std_exception.h file is generated at build-time and #includes C++ stdlib
--// header "exception" by aboslute path. This is to workaround an include loop on
--// case-insensitive systems, where #include <exception> includes our "Exception"
--// fancy header instead of stdlib's exception, causing an endless loop of
--// includes between "Exception" and "exception.h".
--#include "std_exception.h"
--
- #include "akonadicore_export.h"
-+#include <QObject>
-+#include <QByteArray>
-+#include <exception>
-
--class QByteArray;
- class QString;
-
- namespace Akonadi
diff --git a/kde/patch/akonadi4.patch b/kde/patch/akonadi4.patch
index 388c3ea..8ff0118 100644
--- a/kde/patch/akonadi4.patch
+++ b/kde/patch/akonadi4.patch
@@ -1,4 +1,3 @@
# Backport a patch from git master since there will not be another
# official akonadi release after the current 1.13:
cat $CWD/patch/akonadi4/akonadi_dont-leak-old-external-payload-files.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/amarok.patch b/kde/patch/amarok.patch
index 9fc3963..7ede8ad 100644
--- a/kde/patch/amarok.patch
+++ b/kde/patch/amarok.patch
@@ -1,4 +1,3 @@
# Fix a crash in KDE 4.11:
# See also https://bugs.kde.org/show_bug.cgi?id=320855
cat $CWD/patch/amarok/amarok_kdebug_320855.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/ark.patch b/kde/patch/ark.patch
index 35ac2d3..3710075 100644
--- a/kde/patch/ark.patch
+++ b/kde/patch/ark.patch
@@ -1,7 +1,5 @@
-# Ark won't open RAR archives unless rar is installed (even for read access).
-# KDEBUG #357057 is fixed in 15.12.1; still needs unrar.
-#cat $CWD/patch/ark/ark_kdebug357057.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
# Fix a compilation issue in 18.04.0:
-cat $CWD/patch/ark/ark_include_memory.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
+#cat $CWD/patch/ark/ark_include_memory.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
+# Fix for CVE-2020-16116:
+cat $CWD/patch/ark/ark_cve-2020-16116.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
diff --git a/kde/patch/ark/ark_cve-2020-16116.patch b/kde/patch/ark/ark_cve-2020-16116.patch
new file mode 100644
index 0000000..b3feb1b
--- /dev/null
+++ b/kde/patch/ark/ark_cve-2020-16116.patch
@@ -0,0 +1,47 @@
+From 0df592524fed305d6fbe74ddf8a196bc9ffdb92f Mon Sep 17 00:00:00 2001
+From: Elvis Angelaccio <elvis.angelaccio@kde.org>
+Date: Wed, 29 Jul 2020 23:45:30 +0200
+Subject: [PATCH] Fix vulnerability to path traversal attacks
+
+Ark was vulnerable to directory traversal attacks because of
+missing validation of file paths in the archive.
+
+More details about this attack are available at:
+https://github.com/snyk/zip-slip-vulnerability
+
+Job::onEntry() is the only place where we can safely check the path of
+every entry in the archive. There shouldn't be a valid reason
+to have a "../" in an archive path, so we can just play safe and abort
+the LoadJob if we detect such an entry. This makes impossibile to
+extract this kind of malicious archives and perform the attack.
+
+Thanks to Albert Astals Cid for suggesting to use QDir::cleanPath()
+so that we can still allow loading of legitimate archives that
+contain "../" in their paths but still resolve inside the extraction folder.
+---
+ kerfuffle/jobs.cpp | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/kerfuffle/jobs.cpp b/kerfuffle/jobs.cpp
+index fdaa48695..f73b56f86 100644
+--- a/kerfuffle/jobs.cpp
++++ b/kerfuffle/jobs.cpp
+@@ -180,6 +180,14 @@ void Job::onError(const QString & message, const QString & details)
+
+ void Job::onEntry(Archive::Entry *entry)
+ {
++ const QString entryFullPath = entry->fullPath();
++ if (QDir::cleanPath(entryFullPath).contains(QLatin1String("../"))) {
++ qCWarning(ARK) << "Possibly malicious archive. Detected entry that could lead to a directory traversal attack:" << entryFullPath;
++ onError(i18n("Could not load the archive because it contains ill-formed entries and might be a malicious archive."), QString());
++ onFinished(false);
++ return;
++ }
++
+ emit newEntry(entry);
+ }
+
+--
+GitLab
+
+
diff --git a/kde/patch/ark/ark_kdebug357057.patch b/kde/patch/ark/ark_kdebug357057.patch
deleted file mode 100644
index 76c0bab..0000000
--- a/kde/patch/ark/ark_kdebug357057.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Elvis Angelaccio <elvis.angelaccio@kdemail.net>
-Date: Wed, 23 Dec 2015 16:19:29 +0000
-Subject: Fallback to read-only mode if there are no read-write executables
-X-Git-Url: http://quickgit.kde.org/?p=ark.git&a=commitdiff&h=087e5aab49c60ac5930742fe892fa930048e2f43
----
-Fallback to read-only mode if there are no read-write executables
-
-Commit 2d000a0 introduced executables check when loading a plugin. However the
-current behavior is too restrictive: if one wants only to open a rar or a
-zip archive, there is no need to require also the rar or zip program to be
-installed. Plus, some distributions (e.g. Archlinux) ship only unrar in their
-official repositories.
-
-With this commit, Ark is able to understand that e.g. unrar is installed but
-rar is not. In this case, Ark can and should fallback to read-only mode,
-to disable the Add/Delete actions in the toolbar.
-
-BUG: 357057
-FIXED-IN: 15.12.1
-
-CC: rthomsen6@gmail.com
----
-
-
---- a/kerfuffle/archive_kerfuffle.cpp
-+++ b/kerfuffle/archive_kerfuffle.cpp
-@@ -173,6 +173,9 @@
-
- if (iface->findExecutables(!isReadOnly)) {
- return new Archive(iface, isReadOnly, parent);
-+ } else if (!isReadOnly && iface->findExecutables(false)) {
-+ qCWarning(ARK) << "Failed to find read-write executables: falling back to read-only mode for read-write plugin" << pluginName;
-+ return new Archive(iface, true, parent);
- } else {
- qCWarning(ARK) << "Failed to find needed executables for plugin" << pluginName;
- }
-
diff --git a/kde/patch/baloo5.patch b/kde/patch/baloo5.patch
index 794bcd9..75aa4d1 100644
--- a/kde/patch/baloo5.patch
+++ b/kde/patch/baloo5.patch
@@ -1,3 +1,2 @@
-# Adapt to changes in KAboutData (will be fixed in next release):
-#cat $CWD/patch/baloo5/baloo-4.96.0_kaboutdata.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
+# Disable file indexing by default in Baloo:
+cat $CWD/patch/baloo5/baloo_def_indexing_disabled.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
diff --git a/kde/patch/baloo5/baloo-4.96.0_kaboutdata.diff b/kde/patch/baloo5/baloo-4.96.0_kaboutdata.diff
deleted file mode 100644
index 36ec0d1..0000000
--- a/kde/patch/baloo5/baloo-4.96.0_kaboutdata.diff
+++ /dev/null
@@ -1,69 +0,0 @@
-From: Andreas Hartmetz <ahartmetz@gmail.com>
-Date: Wed, 14 May 2014 02:36:57 +0000
-Subject: Adapt to changes in KAboutData.
-X-Git-Url: http://quickgit.kde.org/?p=baloo.git&a=commitdiff&h=46e3ea7828c8066e75bec87ba0a19d5ef3bd700a
----
-Adapt to changes in KAboutData.
----
-
-
---- a/src/file/kcm/kcm.cpp
-+++ b/src/file/kcm/kcm.cpp
-@@ -58,8 +58,8 @@
- : KCModule(parent, args)
- {
- KAboutData* about = new KAboutData(
-- "kcm_baloofile", "kcm_baloofile", i18n("Configure Desktop Search"),
-- "0.1", QString(), KAboutData::License_GPL,
-+ "kcm_baloofile", i18n("Configure Desktop Search"),
-+ "0.1", QString(), KAboutLicense::GPL,
- i18n("Copyright 2007-2010 Sebastian Trüg"));
- about->addAuthor(i18n("Sebastian Trüg"), QString(), "trueg@kde.org");
- about->addAuthor(i18n("Vishesh Handa"), QString(), "vhanda@kde.org");
-
---- a/src/file/main.cpp
-+++ b/src/file/main.cpp
-@@ -44,9 +44,9 @@
- lowerSchedulingPriority();
- lowerPriority();
-
-- KAboutData aboutData("baloo_file", "baloo_file", i18n("Baloo File"), "0.1",
-+ KAboutData aboutData("baloo_file", i18n("Baloo File"), "0.1",
- i18n("An application to handle file metadata"),
-- KAboutData::License_LGPL_V2);
-+ KAboutLicense::LGPL_V2);
- aboutData.addAuthor(i18n("Vishesh Handa"), i18n("Maintainer"), "me@vhanda.in", "http://vhanda.in");
-
- KAboutData::setApplicationData(aboutData);
-
---- a/src/tools/baloosearch/main.cpp
-+++ b/src/tools/baloosearch/main.cpp
-@@ -55,11 +55,10 @@
- int main(int argc, char* argv[])
- {
- KAboutData aboutData("baloosearch",
-- "baloosearch",
- i18n("Baloo Search"),
- "0.1",
- i18n("Baloo Search - A debugging tool"),
-- KAboutData::License_GPL,
-+ KAboutLicense::GPL,
- i18n("(c) 2013, Vishesh Handa"));
- aboutData.addAuthor(i18n("Vishesh Handa"), i18n("Maintainer"), "me@vhanda.in");
-
-
---- a/src/tools/balooshow/main.cpp
-+++ b/src/tools/balooshow/main.cpp
-@@ -46,11 +46,10 @@
- int main(int argc, char* argv[])
- {
- KAboutData aboutData("balooshow",
-- "balooshow",
- i18n("Baloo Show"),
- "0.1",
- i18n("The Baloo data Viewer - A debugging tool"),
-- KAboutData::License_GPL,
-+ KAboutLicense::GPL,
- i18n("(c) 2012, Vishesh Handa"));
- aboutData.addAuthor(i18n("Vishesh Handa"), i18n("Maintainer"), "me@vhanda.in");
-
diff --git a/kde/patch/baloo5/baloo_def_indexing_disabled.patch b/kde/patch/baloo5/baloo_def_indexing_disabled.patch
new file mode 100644
index 0000000..8a12e45
--- /dev/null
+++ b/kde/patch/baloo5/baloo_def_indexing_disabled.patch
@@ -0,0 +1,12 @@
+diff -uar baloo-5.72.0.orig/src/lib/baloosettings.kcfg baloo-5.72.0/src/lib/baloosettings.kcfg
+--- baloo-5.72.0.orig/src/lib/baloosettings.kcfg 2020-07-04 15:03:02.000000000 +0200
++++ baloo-5.72.0/src/lib/baloosettings.kcfg 2020-07-29 19:51:58.891567902 +0200
+@@ -9,7 +9,7 @@
+ <group name="Basic Settings">
+ <entry name="indexingEnabled" key="Indexing-Enabled" type="Bool">
+ <label>Indexing-Enabled</label>
+- <default>true</default>
++ <default>false</default>
+ </entry>
+ </group>
+ <group name="General">
diff --git a/kde/patch/calligra.patch b/kde/patch/calligra.patch
deleted file mode 100644
index a0a45af..0000000
--- a/kde/patch/calligra.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-# Fix build against Qt 5.11:
-#cat $CWD/patch/calligra/calligra3_qt511.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Fix build against Qt 5.13:
-#cat $CWD/patch/calligra/calligra3_qt513.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Fix build against poppler 0.71:
-#cat $CWD/patch/calligra/calligra3_poppler-0.71.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Fix build against poppler 0.72:
-#cat $CWD/patch/calligra/calligra3_poppler-0.72.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Fix build against poppler 0.73:
-#cat $CWD/patch/calligra/calligra3_poppler-0.73.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/calligra/calligra3_poppler-0.71.patch b/kde/patch/calligra/calligra3_poppler-0.71.patch
deleted file mode 100644
index 65284a3..0000000
--- a/kde/patch/calligra/calligra3_poppler-0.71.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-diff --git a/filters/karbon/pdf/PdfImport.cpp b/filters/karbon/pdf/PdfImport.cpp
-index 48b08dfa32d..e910dae0756 100644
---- a/filters/karbon/pdf/PdfImport.cpp
-+++ b/filters/karbon/pdf/PdfImport.cpp
-@@ -88,9 +88,9 @@ KoFilter::ConversionStatus PdfImport::convert(const QByteArray& from, const QByt
- SvgOutputDev * dev = new SvgOutputDev(m_chain->outputFile());
- if (dev->isOk()) {
- int rotate = 0;
-- GBool useMediaBox = gTrue;
-- GBool crop = gFalse;
-- GBool printing = gFalse;
-+ bool useMediaBox = true;
-+ bool crop = false;
-+ bool printing = false;
- pdfDoc->displayPages(dev, firstPage, lastPage, hDPI, vDPI, rotate, useMediaBox, crop, printing);
- dev->dumpContent();
- }
-diff --git a/filters/karbon/pdf/SvgOutputDev.cpp b/filters/karbon/pdf/SvgOutputDev.cpp
-index 5692824bc45..43205170991 100644
---- a/filters/karbon/pdf/SvgOutputDev.cpp
-+++ b/filters/karbon/pdf/SvgOutputDev.cpp
-@@ -39,7 +39,7 @@ class SvgOutputDev::Private
- {
- public:
- Private(const QString &fname)
-- : svgFile(fname), defs(0), body(0), state(gTrue)
-+ : svgFile(fname), defs(0), body(0), state(true)
- , brush(Qt::SolidPattern) {}
-
- ~Private() {
-@@ -52,7 +52,7 @@ public:
- QString defsData;
- QTextStream * defs;
- QTextStream * body;
-- GBool state;
-+ bool state;
- QSizeF pageSize;
- QPen pen;
- QBrush brush;
-@@ -62,7 +62,7 @@ SvgOutputDev::SvgOutputDev(const QString &fileName)
- : d(new Private(fileName))
- {
- if (! d->svgFile.open(QIODevice::WriteOnly)) {
-- d->state = gFalse;
-+ d->state = false;
- return;
- }
-
-@@ -75,24 +75,24 @@ SvgOutputDev::~SvgOutputDev()
- delete d;
- }
-
--GBool SvgOutputDev::isOk()
-+bool SvgOutputDev::isOk()
- {
- return d->state;
- }
-
--GBool SvgOutputDev::upsideDown()
-+bool SvgOutputDev::upsideDown()
- {
-- return gTrue;
-+ return true;
- }
-
--GBool SvgOutputDev::useDrawChar()
-+bool SvgOutputDev::useDrawChar()
- {
-- return gFalse;
-+ return false;
- }
-
--GBool SvgOutputDev::interpretType3Chars()
-+bool SvgOutputDev::interpretType3Chars()
- {
-- return gFalse;
-+ return false;
- }
-
- void SvgOutputDev::startPage(int pageNum, GfxState *state, XRef */*xref*/)
-@@ -480,7 +480,7 @@ void SvgOutputDev::drawString(GfxState * state, GooString * s)
-
- void SvgOutputDev::drawImage(GfxState *state, Object */*ref*/, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
-- int *maskColors, GBool /*inlineImg*/)
-+ int *maskColors, bool /*inlineImg*/)
- {
- ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
- imgStr->reset();
-@@ -549,7 +549,7 @@ void SvgOutputDev::drawImage(GfxState *state, Object */*ref*/, Stream *str,
-
- void SvgOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
-- GBool /*interpolate*/, int *maskColors, GBool inlineImg)
-+ bool /*interpolate*/, int *maskColors, bool inlineImg)
- {
- drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
- }
-diff --git a/filters/karbon/pdf/SvgOutputDev.h b/filters/karbon/pdf/SvgOutputDev.h
-index 2a4490848bf..cdb1d4e43b1 100644
---- a/filters/karbon/pdf/SvgOutputDev.h
-+++ b/filters/karbon/pdf/SvgOutputDev.h
-@@ -44,11 +44,11 @@ public:
- explicit SvgOutputDev(const QString &fileName);
- virtual ~SvgOutputDev();
-
-- GBool isOk();
-+ bool isOk();
-
-- virtual GBool upsideDown();
-- virtual GBool useDrawChar();
-- virtual GBool interpretType3Chars();
-+ virtual bool upsideDown();
-+ virtual bool useDrawChar();
-+ virtual bool interpretType3Chars();
- virtual void startPage(int pageNum, GfxState *state, XRef *xref);
- virtual void endPage();
-
-@@ -63,10 +63,10 @@ public:
- // images
- virtual void drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
-- int *maskColors, GBool inlineImg);
-+ int *maskColors, bool inlineImg);
- virtual void drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
-- GBool interpolate, int *maskColors, GBool inlineImg);
-+ bool interpolate, int *maskColors, bool inlineImg);
-
- // styles
- virtual void updateAll(GfxState *state);
diff --git a/kde/patch/calligra/calligra3_poppler-0.72.patch b/kde/patch/calligra/calligra3_poppler-0.72.patch
deleted file mode 100644
index 2cab98f..0000000
--- a/kde/patch/calligra/calligra3_poppler-0.72.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-diff --git a/filters/karbon/pdf/SvgOutputDev.cpp b/filters/karbon/pdf/SvgOutputDev.cpp
-index 80f01a5f76f..ea69228dbc1 100644
---- a/filters/karbon/pdf/SvgOutputDev.cpp
-+++ b/filters/karbon/pdf/SvgOutputDev.cpp
-@@ -407,7 +407,7 @@ void SvgOutputDev::drawString(GfxState * state, const GooString * s)
-
- QString str;
-
-- const char * p = s->getCString();
-+ const char * p = s->c_str();
- int len = s->getLength();
- CharCode code;
- Unicode *u = nullptr;
-@@ -459,11 +459,11 @@ void SvgOutputDev::drawString(GfxState * state, const GooString * s)
- *d->body << " y=\"" << y << "px\"";
-
- if (font && font->getFamily()) {
-- *d->body << " font-family=\"" << QString::fromLatin1(font->getFamily()->getCString()) << "\"";
-- //debugPdf << "font family:" << QString::fromLatin1( font->getFamily()->getCString() );
-+ *d->body << " font-family=\"" << QString::fromLatin1(font->getFamily()->c_str()) << "\"";
-+ //debugPdf << "font family:" << QString::fromLatin1( font->getFamily()->c_str() );
- } else if (font && font->getName()) {
-- *d->body << " font-family=\"" << QString::fromLatin1(font->getName()->getCString()) << "\"";
-- //debugPdf << "font name:" << QString::fromLatin1( font->getName()->getCString() );
-+ *d->body << " font-family=\"" << QString::fromLatin1(font->getName()->c_str()) << "\"";
-+ //debugPdf << "font name:" << QString::fromLatin1( font->getName()->c_str() );
- }
- *d->body << " font-size=\"" << qMax(state->getFontSize(), state->getTransformedFontSize()) << "px\"";
-
diff --git a/kde/patch/calligra/calligra3_poppler-0.73.patch b/kde/patch/calligra/calligra3_poppler-0.73.patch
deleted file mode 100644
index 86738de..0000000
--- a/kde/patch/calligra/calligra3_poppler-0.73.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From a1ddd91e6c354e8f0dda40f8a522053c3fa19c39 Mon Sep 17 00:00:00 2001
-From: Albert Astals Cid <aacid@kde.org>
-Date: Tue, 15 Jan 2019 22:24:08 +0100
-Subject: [PATCH] Guchar -> unsigned char
-
-It was just a typdef and it's now gone
----
- filters/karbon/pdf/SvgOutputDev.cpp | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/filters/karbon/pdf/SvgOutputDev.cpp b/filters/karbon/pdf/SvgOutputDev.cpp
-index 80f01a5f76f..1a5aa30bc40 100644
---- a/filters/karbon/pdf/SvgOutputDev.cpp
-+++ b/filters/karbon/pdf/SvgOutputDev.cpp
-@@ -496,7 +496,7 @@ void SvgOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
- if (maskColors) {
- for (int y = 0; y < height; y++) {
- dest = (unsigned int *)(buffer + y * 4 * width);
-- Guchar * pix = imgStr->getLine();
-+ unsigned char * pix = imgStr->getLine();
- colorMap->getRGBLine(pix, dest, width);
-
- for (int x = 0; x < width; x++) {
-@@ -515,7 +515,7 @@ void SvgOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
- } else {
- for (int y = 0; y < height; y++) {
- dest = (unsigned int *)(buffer + y * 4 * width);
-- Guchar * pix = imgStr->getLine();
-+ unsigned char * pix = imgStr->getLine();
- colorMap->getRGBLine(pix, dest, width);
- }
-
diff --git a/kde/patch/calligra/calligra3_qt511.patch b/kde/patch/calligra/calligra3_qt511.patch
deleted file mode 100644
index 0ddf0f2..0000000
--- a/kde/patch/calligra/calligra3_qt511.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From ee83e0f2c251072e47a2799619cdc79efe67e651 Mon Sep 17 00:00:00 2001
-From: David Faure <faure@kde.org>
-Date: Tue, 3 Apr 2018 00:31:19 +0200
-Subject: Fix compilation with Qt 5.11 (missing include)
-
----
- stage/part/KPrPresentationTool.cpp | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/stage/part/KPrPresentationTool.cpp b/stage/part/KPrPresentationTool.cpp
-index ae743da..3007f91 100644
---- a/stage/part/KPrPresentationTool.cpp
-+++ b/stage/part/KPrPresentationTool.cpp
-@@ -32,6 +32,7 @@
- #include <QDesktopServices>
- #include <QUrl>
- #include <QDBusConnection>
-+#include <QFrame>
-
- #include <KoShape.h>
- #include <KoShapeManager.h>
----
-From a7ebecb9fbee2190e649c44ed53f1299013baa30 Mon Sep 17 00:00:00 2001
-From: Andreas Sturmlechner <andreas.sturmlechner@gmail.com>
-Date: Sun, 18 Mar 2018 11:56:57 +0100
-Subject: Fix build with Qt 5.11 (missing headers)
-
-Reviewers: #calligra:_3.0, anthonyfieroni, danders
-
-Reviewed By: #calligra:_3.0, anthonyfieroni, danders
-
-Subscribers: anthonyfieroni, danders
-
-Tags: #calligra:_3.0
-
-Differential Revision: https://phabricator.kde.org/D11454
----
- libs/widgets/KoCsvImportDialog.cpp | 1 +
- libs/widgets/KoPageLayoutWidget.cpp | 2 ++
- plugins/chartshape/dialogs/TableEditorDialog.cpp | 1 +
- plugins/formulashape/FormulaToolWidget.cpp | 1 +
- sheets/dialogs/LayoutDialog.cpp | 1 +
- words/part/dialogs/KWAnchoringProperties.cpp | 1 +
- words/part/dialogs/KWRunAroundProperties.cpp | 2 ++
- 15 files changed, 18 insertions(+), 1 deletion(-)
-
-diff --git a/libs/widgets/KoCsvImportDialog.cpp b/libs/widgets/KoCsvImportDialog.cpp
-index 0ffdcf6..cdca006 100644
---- a/libs/widgets/KoCsvImportDialog.cpp
-+++ b/libs/widgets/KoCsvImportDialog.cpp
-@@ -21,6 +21,7 @@
- #include "KoCsvImportDialog.h"
-
- // Qt
-+#include <QButtonGroup>
- #include <QTextCodec>
- #include <QTextStream>
-
-diff --git a/libs/widgets/KoPageLayoutWidget.cpp b/libs/widgets/KoPageLayoutWidget.cpp
-index f91555c..a3816f9 100644
---- a/libs/widgets/KoPageLayoutWidget.cpp
-+++ b/libs/widgets/KoPageLayoutWidget.cpp
-@@ -23,6 +23,8 @@
-
- #include <KoUnit.h>
-
-+#include <QButtonGroup>
-+
- class Q_DECL_HIDDEN KoPageLayoutWidget::Private
- {
- public:
-diff --git a/plugins/chartshape/dialogs/TableEditorDialog.cpp b/plugins/chartshape/dialogs/TableEditorDialog.cpp
-index c0d5136..d2a772e 100644
---- a/plugins/chartshape/dialogs/TableEditorDialog.cpp
-+++ b/plugins/chartshape/dialogs/TableEditorDialog.cpp
-@@ -24,6 +24,7 @@
-
- // Qt
- #include <QAbstractItemModel>
-+#include <QAction>
-
- // Calligra
- #include <KoIcon.h>
-diff --git a/plugins/formulashape/FormulaToolWidget.cpp b/plugins/formulashape/FormulaToolWidget.cpp
-index ed10919..8f52177 100644
---- a/plugins/formulashape/FormulaToolWidget.cpp
-+++ b/plugins/formulashape/FormulaToolWidget.cpp
-@@ -30,6 +30,7 @@
- #include <QWidgetAction>
- #include <QTableWidget>
- #include <QAction>
-+#include <QHeaderView>
- #include <QMenu>
-
- FormulaToolWidget::FormulaToolWidget( KoFormulaTool* tool, QWidget* parent )
-diff --git a/sheets/dialogs/LayoutDialog.cpp b/sheets/dialogs/LayoutDialog.cpp
-index a0a9832..7d7db53 100644
---- a/sheets/dialogs/LayoutDialog.cpp
-+++ b/sheets/dialogs/LayoutDialog.cpp
-@@ -36,6 +36,7 @@
- #include <math.h>
-
- #include <QIntValidator>
-+#include <QButtonGroup>
- #include <QCheckBox>
- #include <QFrame>
- #include <QLabel>
-diff --git a/words/part/dialogs/KWAnchoringProperties.cpp b/words/part/dialogs/KWAnchoringProperties.cpp
-index d64208c..bfddb3a 100644
---- a/words/part/dialogs/KWAnchoringProperties.cpp
-+++ b/words/part/dialogs/KWAnchoringProperties.cpp
-@@ -35,6 +35,7 @@
-
- #include <kundo2command.h>
-
-+#include <QButtonGroup>
- #include <QComboBox>
-
- const int KWAnchoringProperties::vertRels[4][20] = {
-diff --git a/words/part/dialogs/KWRunAroundProperties.cpp b/words/part/dialogs/KWRunAroundProperties.cpp
-index e38599a..7e8b2d5 100644
---- a/words/part/dialogs/KWRunAroundProperties.cpp
-+++ b/words/part/dialogs/KWRunAroundProperties.cpp
-@@ -28,6 +28,8 @@
-
- #include <kundo2command.h>
-
-+#include <QButtonGroup>
-+
- KWRunAroundProperties::KWRunAroundProperties(FrameConfigSharedState *state)
- : m_state(state)
- {
---
-cgit v0.11.2
-
diff --git a/kde/patch/calligra/calligra3_qt513.patch b/kde/patch/calligra/calligra3_qt513.patch
deleted file mode 100644
index 987b353..0000000
--- a/kde/patch/calligra/calligra3_qt513.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 0c5430697bdcf41a45046107b28014e40c49a11a Mon Sep 17 00:00:00 2001
-From: David Faure <faure@kde.org>
-Date: Tue, 23 Jul 2019 13:02:34 +0200
-Subject: [PATCH] Fix compilation with Qt 5.13 (missing include)
-
----
- sheets/plugins/calendar/CalendarToolWidget.cpp | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/sheets/plugins/calendar/CalendarToolWidget.cpp b/sheets/plugins/calendar/CalendarToolWidget.cpp
-index b10b23022a2..0c5eeb68cf3 100644
---- a/sheets/plugins/calendar/CalendarToolWidget.cpp
-+++ b/sheets/plugins/calendar/CalendarToolWidget.cpp
-@@ -30,6 +30,7 @@
- #include <kdatepicker.h>
-
- #include <QPushButton>
-+#include <QDate>
-
- namespace Calligra
- {
-
diff --git a/kde/patch/calligraplan.patch b/kde/patch/calligraplan.patch
index 4cc1f85..5895d0c 100644
--- a/kde/patch/calligraplan.patch
+++ b/kde/patch/calligraplan.patch
@@ -1,11 +1,2 @@
-# Fix build against Qt 5.11 (fixed in 3.2.0):
-#cat $CWD/patch/calligraplan/calligraplan.qt-511.patch | patch -p2 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Fix build against kcalendarcore (fixed in 3.2.0):
-#cat $CWD/patch/calligraplan/calligraplan.kcalcore.1.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-#cat $CWD/patch/calligraplan/calligraplan.kcalcore.2.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-#cat $CWD/patch/calligraplan/calligraplan.kcalendarcore.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Fix missing include (fixed in 3.2.0):
-#cat $CWD/patch/calligraplan/calligraplan.missingheader.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
+# Fix build against Qt 5.15:
+cat $CWD/patch/calligraplan/calligraplan.qt-5.15.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
diff --git a/kde/patch/calligraplan/calligraplan.kcalcore.1.patch b/kde/patch/calligraplan/calligraplan.kcalcore.1.patch
deleted file mode 100644
index dcbe903..0000000
--- a/kde/patch/calligraplan/calligraplan.kcalcore.1.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 3a01affd66f8dfdcc124e23595217f3ae5a09723 Mon Sep 17 00:00:00 2001
-From: Dag Andersen <danders@get2net.dk>
-Date: Thu, 20 Jun 2019 10:52:00 +0200
-Subject: ICal: Adapt to api changes in KCalCore
-
----
- CMakeLists.txt | 37 +++++++++++-----------
- src/CMakeLists.txt | 4 +++
- .../filters/icalendar/export/icalendarexport.cpp | 5 +++
- 3 files changed, 27 insertions(+), 19 deletions(-)
-
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index 0dabbaf..49fa642 100644
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -75,6 +75,10 @@ if ("${KF5CalendarCore_VERSION}" VERSION_GREATER 5.6.40)
- set(HAVE_QDATETIME_KCALCORE TRUE)
- endif()
-
-+if ("${KF5CalendarCore_VERSION}" VERSION_GREATER 5.11.42)
-+ set(KCALCORE_HAVE_NO_PERSION_PTR TRUE)
-+endif()
-+
- if (PLANCHARTDEBUG)
- add_definitions(-DPLAN_CHART_DEBUG)
- endif ()
-diff --git a/src/plugins/filters/icalendar/export/icalendarexport.cpp b/src/plugins/filters/icalendar/export/icalendarexport.cpp
-index cd75598..ce29bfe 100644
---- a/src/plugins/filters/icalendar/export/icalendarexport.cpp
-+++ b/src/plugins/filters/icalendar/export/icalendarexport.cpp
-@@ -141,8 +141,13 @@ void ICalendarExport::createTodos(KCalCore::Calendar::Ptr cal, const Node *node,
- todo->setOrganizer(node->projectNode()->leader());
- }
- if ( node->type() != Node::Type_Project && ! node->leader().isEmpty()) {
-+#if KCALCORE_HAVE_NO_PERSION_PTR
-+ KCalCore::Person p = KCalCore::Person::fromFullName(node->leader());
-+ KCalCore::Attendee::Ptr a(new KCalCore::Attendee(p.name(), p.email()));
-+#else
- KCalCore::Person::Ptr p = KCalCore::Person::fromFullName(node->leader());
- KCalCore::Attendee::Ptr a(new KCalCore::Attendee(p->name(), p->email()));
-+#endif
- a->setRole(KCalCore::Attendee::NonParticipant);
- todo->addAttendee(a);
- }
---
-cgit v1.1
-
diff --git a/kde/patch/calligraplan/calligraplan.kcalcore.2.patch b/kde/patch/calligraplan/calligraplan.kcalcore.2.patch
deleted file mode 100644
index 5c118e1..0000000
--- a/kde/patch/calligraplan/calligraplan.kcalcore.2.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From a9eaf1c98ed408fd6e8897fa9e2f99ed17db1ebc Mon Sep 17 00:00:00 2001
-From: David Faure <faure@kde.org>
-Date: Tue, 23 Jul 2019 12:26:17 +0200
-Subject: Port to KCalCore API changes
-
-The code is in #if 0, but I tested compilation of this in the calligra
-stable branch:
-https://commits.kde.org/calligra/2d484fda1b31a72659088a4bfce5c3708e923cb0
-
-So you can use KCalCore again if you want :-)
-It's turning into a KF5 framework so the API will be stable from now on.
-
-CCMAIL: danders@get2net.dk
----
- .../filters/icalendar/export/icalendarexport.cpp | 20 +++++++++++++++++---
- 1 file changed, 17 insertions(+), 3 deletions(-)
-
-diff --git a/src/plugins/filters/icalendar/export/icalendarexport.cpp b/src/plugins/filters/icalendar/export/icalendarexport.cpp
-index b21320f..828b641 100644
---- a/src/plugins/filters/icalendar/export/icalendarexport.cpp
-+++ b/src/plugins/filters/icalendar/export/icalendarexport.cpp
-@@ -35,6 +35,7 @@
- #include <kcalcore/attachment.h>
- #include <kcalcore/icalformat.h>
- #include <kcalcore/memorycalendar.h>
-+#include <kcalcore_version.h>
-
- #include <QTextCodec>
- #include <QByteArray>
-@@ -355,14 +356,15 @@ void ICalendarExport::createTodos(KCalCore::Calendar::Ptr cal, const Node *node,
- todo->setOrganizer(node->projectNode()->leader());
- }
- if ( node->type() != Node::Type_Project && ! node->leader().isEmpty()) {
--#if KCALCORE_HAVE_NO_PERSION_PTR
-+#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 11, 80)
- KCalCore::Person p = KCalCore::Person::fromFullName(node->leader());
-- KCalCore::Attendee::Ptr a(new KCalCore::Attendee(p.name(), p.email()));
-+ KCalCore::Attendee a(p.name(), p.email());
-+ a.setRole(KCalCore::Attendee::NonParticipant);
- #else
- KCalCore::Person::Ptr p = KCalCore::Person::fromFullName(node->leader());
- KCalCore::Attendee::Ptr a(new KCalCore::Attendee(p->name(), p->email()));
--#endif
- a->setRole(KCalCore::Attendee::NonParticipant);
-+#endif
- todo->addAttendee(a);
- }
- DateTime st = node->startTime(id);
-@@ -381,13 +383,21 @@ void ICalendarExport::createTodos(KCalCore::Calendar::Ptr cal, const Node *node,
- const QList<Resource*> lst = task->requestedResources();
- foreach(const Resource *r, lst) {
- if (r->type() == Resource::Type_Work) {
-+#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 11, 80)
-+ todo->addAttendee(KCalCore::Attendee(r->name(), r->email()));
-+#else
- todo->addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee(r->name(), r->email())));
-+#endif
- }
- }
- } else {
- foreach(const Resource *r, s->resources()) {
- if (r->type() == Resource::Type_Work) {
-+#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 11, 80)
-+ todo->addAttendee(KCalCore::Attendee(r->name(), r->email()));
-+#else
- todo->addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee(r->name(), r->email())));
-+#endif
- }
- }
-
-@@ -398,7 +408,11 @@ void ICalendarExport::createTodos(KCalCore::Calendar::Ptr cal, const Node *node,
- todo->setPercentComplete(task->completion().percentFinished());
- }
- foreach(const Document *doc, node->documents().documents()) {
-+#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 11, 80)
-+ todo->addAttachment(KCalCore::Attachment(doc->url().url()));
-+#else
- todo->addAttachment(KCalCore::Attachment::Ptr(new KCalCore::Attachment(doc->url().url())));
-+#endif
- }
- if (! parent.isNull()) {
- todo->setRelatedTo(parent->uid(), KCalCore::Incidence::RelTypeParent);
---
-cgit v1.1
-
diff --git a/kde/patch/calligraplan/calligraplan.kcalendarcore.patch b/kde/patch/calligraplan/calligraplan.kcalendarcore.patch
deleted file mode 100644
index 42aa135..0000000
--- a/kde/patch/calligraplan/calligraplan.kcalendarcore.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 2f5505cf03ff865349d06e1d5c39007c52e7cd10 Mon Sep 17 00:00:00 2001
-From: Andreas Sturmlechner <asturm@gentoo.org>
-Date: Fri, 16 Aug 2019 15:49:09 +0200
-Subject: [PATCH] Fix headers after kcalcore->kcalendercore rename happened
-
----
- .../filters/icalendar/export/icalendarexport.cpp | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/src/plugins/filters/icalendar/export/icalendarexport.cpp b/src/plugins/filters/icalendar/export/icalendarexport.cpp
-index bb6b097d..729d6e50 100644
---- a/src/plugins/filters/icalendar/export/icalendarexport.cpp
-+++ b/src/plugins/filters/icalendar/export/icalendarexport.cpp
-@@ -31,11 +31,11 @@
- #include <kptdocuments.h>
- #include "kptdebug.h"
-
--#include <kcalcore/attendee.h>
--#include <kcalcore/attachment.h>
--#include <kcalcore/icalformat.h>
--#include <kcalcore/memorycalendar.h>
--#include <kcalcore_version.h>
-+#include <kcalendarcore/attendee.h>
-+#include <kcalendarcore/attachment.h>
-+#include <kcalendarcore/icalformat.h>
-+#include <kcalendarcore/memorycalendar.h>
-+#include <kcalcore_version.h>
-
- #include <QTextCodec>
- #include <QByteArray>
---
-2.22.1
-
-
diff --git a/kde/patch/calligraplan/calligraplan.missingheader.patch b/kde/patch/calligraplan/calligraplan.missingheader.patch
deleted file mode 100644
index b5941c5..0000000
--- a/kde/patch/calligraplan/calligraplan.missingheader.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From fe36bf6f0dc1f0c1e927850dd78093cfe3b7aae2 Mon Sep 17 00:00:00 2001
-From: Albert Astals Cid <aacid@kde.org>
-Date: Sun, 28 Jul 2019 00:07:33 +0200
-Subject: Fix compile on CI
-
-src/workpackage/view.h:148:31: error: field m_scheduleActions has incomplete type QMap<QAction*, KPlato::Schedule*>
----
- src/workpackage/view.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/src/workpackage/view.h b/src/workpackage/view.h
-index 6cae32b..cd2fc4e 100644
---- a/src/workpackage/view.h
-+++ b/src/workpackage/view.h
-@@ -24,6 +24,7 @@
-
- #include <KoView.h>
-
-+#include <QMap>
- #include <QStackedWidget>
-
- class QPrinter;
---
-cgit v1.1
-
diff --git a/kde/patch/calligraplan/calligraplan.qt-5.15.patch b/kde/patch/calligraplan/calligraplan.qt-5.15.patch
new file mode 100644
index 0000000..c8962a1
--- /dev/null
+++ b/kde/patch/calligraplan/calligraplan.qt-5.15.patch
@@ -0,0 +1,10 @@
+--- ./src/libs/ui/kptganttitemdelegate.cpp.orig 2019-12-12 05:48:13.000000000 -0600
++++ ./src/libs/ui/kptganttitemdelegate.cpp 2020-07-18 14:48:48.058351438 -0500
+@@ -28,6 +28,7 @@
+ #include <QModelIndex>
+ #include <QApplication>
+ #include <QPainter>
++#include <QPainterPath>
+ #include <QLocale>
+
+ #include <KLocalizedString>
diff --git a/kde/patch/calligraplan/calligraplan.qt-511.patch b/kde/patch/calligraplan/calligraplan.qt-511.patch
deleted file mode 100644
index c0776fa..0000000
--- a/kde/patch/calligraplan/calligraplan.qt-511.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From f53805bdc108b608e40f217e6a78e7e4df4284f2 Mon Sep 17 00:00:00 2001
-From: Andreas Sturmlechner <andreas.sturmlechner@gmail.com>
-Date: Sun, 18 Mar 2018 11:56:57 +0100
-Subject: [PATCH] Fix build with Qt 5.11 (missing headers)
-
-Reviewers: #calligra:_3.0
-
-Tags: #calligra:_3.0
-
-Differential Revision: https://phabricator.kde.org/D11454
----
- plan/src/kptview.h | 1 +
- plan/src/kptviewlist.cpp | 1 +
- plan/src/libs/ui/kptaccountseditor.cpp | 1 +
- plan/src/libs/ui/kptdocumentspanel.h | 1 +
- plan/src/libs/ui/kptitemviewsettup.cpp | 2 +-
- plan/src/libs/ui/kpttaskeditor.cpp | 1 +
- plan/src/libs/ui/reportsgenerator/ReportsGeneratorView.cpp | 1 +
- plan/src/libs/widgets/KoPageLayoutWidget.cpp | 2 ++
- 15 files changed, 18 insertions(+), 1 deletion(-)
-
-diff --git a/plan/src/kptview.h b/plan/src/kptview.h
-index 44d11935e71..a98e55342db 100644
---- a/plan/src/kptview.h
-+++ b/plan/src/kptview.h
-@@ -28,6 +28,7 @@
- #include "kptcontext.h"
- #include "kptviewbase.h"
-
-+#include <QActionGroup>
- #include <QDockWidget>
- #include <QMap>
-
-diff --git a/plan/src/kptviewlist.cpp b/plan/src/kptviewlist.cpp
-index f34e702e055..0e6db7b2ffe 100644
---- a/plan/src/kptviewlist.cpp
-+++ b/plan/src/kptviewlist.cpp
-@@ -25,6 +25,7 @@
- #include <QStyle>
- #include <QBrush>
- #include <QContextMenuEvent>
-+#include <QHeaderView>
- #include <QMenu>
-
- #include <kmessagebox.h>
-diff --git a/plan/src/libs/ui/kptaccountseditor.cpp b/plan/src/libs/ui/kptaccountseditor.cpp
-index 7991fafd779..54e3a87c94f 100644
---- a/plan/src/libs/ui/kptaccountseditor.cpp
-+++ b/plan/src/libs/ui/kptaccountseditor.cpp
-@@ -40,6 +40,7 @@
- #include <QContextMenuEvent>
- #include <QMenu>
- #include <QAction>
-+#include <QHeaderView>
-
- #include <KLocalizedString>
- #include <kactioncollection.h>
-diff --git a/plan/src/libs/ui/kptdocumentspanel.h b/plan/src/libs/ui/kptdocumentspanel.h
-index 00ea3af80b2..491cb1ebb86 100644
---- a/plan/src/libs/ui/kptdocumentspanel.h
-+++ b/plan/src/libs/ui/kptdocumentspanel.h
-@@ -26,6 +26,7 @@
-
- #include "kptdocuments.h"
-
-+#include <QModelIndexList>
- #include <QWidget>
- #include <kundo2qstack.h>
-
-diff --git a/plan/src/libs/ui/kptitemviewsettup.cpp b/plan/src/libs/ui/kptitemviewsettup.cpp
-index d1c3b1fc157..7c97a070b9a 100644
---- a/plan/src/libs/ui/kptitemviewsettup.cpp
-+++ b/plan/src/libs/ui/kptitemviewsettup.cpp
-@@ -25,9 +25,9 @@
-
- #include "KoPageLayoutWidget.h"
-
-+#include <QHeaderView>
- #include <QPushButton>
-
--
- namespace KPlato
- {
-
-diff --git a/plan/src/libs/ui/kpttaskeditor.cpp b/plan/src/libs/ui/kpttaskeditor.cpp
-index 21546118d33..91db5acbb18 100644
---- a/plan/src/libs/ui/kpttaskeditor.cpp
-+++ b/plan/src/libs/ui/kpttaskeditor.cpp
-@@ -45,6 +45,7 @@
- #include <QVBoxLayout>
- #include <QDragMoveEvent>
- #include <QAction>
-+#include <QHeaderView>
- #include <QMenu>
-
- #include <kactionmenu.h>
-diff --git a/plan/src/libs/ui/reportsgenerator/ReportsGeneratorView.cpp b/plan/src/libs/ui/reportsgenerator/ReportsGeneratorView.cpp
-index 344ebc2b599..9146f06ab8c 100644
---- a/plan/src/libs/ui/reportsgenerator/ReportsGeneratorView.cpp
-+++ b/plan/src/libs/ui/reportsgenerator/ReportsGeneratorView.cpp
-@@ -31,6 +31,7 @@
- #include <KFile>
-
- #include <QAction>
-+#include <QHeaderView>
- #include <QTreeView>
- #include <QStandardItemModel>
- #include <QModelIndex>
-diff --git a/plan/src/libs/widgets/KoPageLayoutWidget.cpp b/plan/src/libs/widgets/KoPageLayoutWidget.cpp
-index c9e17b748a9..b67e9848807 100644
---- a/plan/src/libs/widgets/KoPageLayoutWidget.cpp
-+++ b/plan/src/libs/widgets/KoPageLayoutWidget.cpp
-@@ -23,6 +23,8 @@
-
- #include <KoUnit.h>
-
-+#include <QButtonGroup>
-+
- class Q_DECL_HIDDEN KoPageLayoutWidget::Private
- {
- public:
---
-2.16.2
-
-
diff --git a/kde/patch/cantor.patch b/kde/patch/cantor.patch
deleted file mode 100644
index 54f2b47..0000000
--- a/kde/patch/cantor.patch
+++ /dev/null
@@ -1,4 +0,0 @@
-# Fix build against KF 5.31.0 (repaired in 16.12.3):
-#cat $CWD/patch/cantor/cantor_python.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-#cat $CWD/patch/cantor/cantor_julia.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/cantor/cantor_julia.patch b/kde/patch/cantor/cantor_julia.patch
deleted file mode 100644
index 5c381ca..0000000
--- a/kde/patch/cantor/cantor_julia.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-Patch taken from:
-https://gitweb.gentoo.org/repo/gentoo.git/plain/kde-apps/cantor/files/cantor-16.12.2-julia-kf-5.31.patch
-
-From 45322d9f58f50df3d4d5755d4199e579f6fd8646 Mon Sep 17 00:00:00 2001
-From: Andreas Sturmlechner <andreas.sturmlechner@gmail.com>
-Date: Sat, 11 Feb 2017 22:46:35 +0100
-Subject: [PATCH] [julia] Fix build with -fno-operator-names
-
-REVIEW: 129942
----
- src/backends/julia/juliaexpression.cpp | 6 +++---
- src/backends/julia/juliaextensions.cpp | 4 ++--
- src/backends/julia/juliahighlighter.cpp | 4 ++--
- src/backends/julia/juliakeywords.cpp | 10 +++++-----
- src/backends/julia/juliaserver/juliaserver.cpp | 4 ++--
- src/backends/julia/juliaserver/main.cpp | 4 ++--
- src/backends/julia/juliasession.cpp | 4 ++--
- 7 files changed, 18 insertions(+), 18 deletions(-)
-
-diff --git a/src/backends/julia/juliaexpression.cpp b/src/backends/julia/juliaexpression.cpp
-index 27cdd85..618200d 100644
---- a/src/backends/julia/juliaexpression.cpp
-+++ b/src/backends/julia/juliaexpression.cpp
-@@ -40,7 +40,7 @@ void JuliaExpression::evaluate()
-
- // Plots integration
- m_plot_filename.clear();
-- if (juliaSession->integratePlots() and checkPlotShowingCommands()) {
-+ if (juliaSession->integratePlots() && checkPlotShowingCommands()) {
- // Simply add plot saving command to the end of execution
- QStringList inlinePlotFormats;
- inlinePlotFormats << QLatin1String("svg");
-@@ -73,8 +73,8 @@ void JuliaExpression::finalize()
- setResult(new Cantor::TextResult(juliaSession->getOutput()));
- setStatus(Cantor::Expression::Error);
- } else {
-- if (not m_plot_filename.isEmpty()
-- and QFileInfo(m_plot_filename).exists()) {
-+ if (!m_plot_filename.isEmpty()
-+ && QFileInfo(m_plot_filename).exists()) {
- // If we have plot in result, show it
- setResult(
- new Cantor::ImageResult(QUrl::fromLocalFile(m_plot_filename)));
-diff --git a/src/backends/julia/juliaextensions.cpp b/src/backends/julia/juliaextensions.cpp
-index 4585c6f..ad5e3a9 100644
---- a/src/backends/julia/juliaextensions.cpp
-+++ b/src/backends/julia/juliaextensions.cpp
-@@ -138,7 +138,7 @@ QString JuliaPlotExtension::plotFunction2d(
- {
- auto new_left = left;
- auto new_right = right;
-- if (new_left.isEmpty() and new_right.isEmpty()) {
-+ if (new_left.isEmpty() && new_right.isEmpty()) {
- new_left = QLatin1String("-1");
- new_right = QLatin1String("1");
- } else if (new_left.isEmpty()) {
-@@ -165,7 +165,7 @@ QString JuliaPlotExtension::plotFunction3d(
- {
-
- auto update_interval = [](Interval &interval) {
-- if (interval.first.isEmpty() and interval.second.isEmpty()) {
-+ if (interval.first.isEmpty() && interval.second.isEmpty()) {
- interval.first = QLatin1String("-1");
- interval.second = QLatin1String("1");
- } else if (interval.first.isEmpty()) {
-diff --git a/src/backends/julia/juliahighlighter.cpp b/src/backends/julia/juliahighlighter.cpp
-index 4795361..f7d3622 100644
---- a/src/backends/julia/juliahighlighter.cpp
-+++ b/src/backends/julia/juliahighlighter.cpp
-@@ -98,7 +98,7 @@ void JuliaHighlighter::highlightBlock(const QString &text)
- while (pos < text.length()) {
- // Trying to close current environments
- bool triggered = false;
-- for (int i = 0; i < flags.size() and not triggered; i++) {
-+ for (int i = 0; i < flags.size() && !triggered; i++) {
- int flag = flags[i];
- QRegExp &regexp = regexps_ends[i];
- QTextCharFormat &format = formats[i];
-@@ -144,7 +144,7 @@ void JuliaHighlighter::highlightBlock(const QString &text)
- singleLineCommentStart.indexIn(text, pos);
-
- if (singleLineCommentStartPos != -1
-- and singleLineCommentStartPos < minPos) {
-+ && singleLineCommentStartPos < minPos) {
- // single line comment starts earlier
- setFormat(pos, text.length() - pos, commentFormat());
- break;
-diff --git a/src/backends/julia/juliakeywords.cpp b/src/backends/julia/juliakeywords.cpp
-index f0a5846..8a0efec 100644
---- a/src/backends/julia/juliakeywords.cpp
-+++ b/src/backends/julia/juliakeywords.cpp
-@@ -62,11 +62,11 @@ void JuliaKeywords::loadFromFile()
- const QStringRef name = xml.name();
-
- if (name == QLatin1String("keywords")
-- or name == QLatin1String("variables")
-- or name == QLatin1String("plot_showing_commands")) {
-+ || name == QLatin1String("variables")
-+ || name == QLatin1String("plot_showing_commands")) {
- while (xml.readNextStartElement()) {
- Q_ASSERT(
-- xml.isStartElement() and xml.name() == QLatin1String("word")
-+ xml.isStartElement() && xml.name() == QLatin1String("word")
- );
-
- const QString text = xml.readElementText();
-@@ -91,7 +91,7 @@ void JuliaKeywords::loadFromFile()
-
- void JuliaKeywords::addVariable(const QString &variable)
- {
-- if (not m_variables.contains(variable)) {
-+ if (!m_variables.contains(variable)) {
- m_variables << variable;
- }
- }
-@@ -104,7 +104,7 @@ void JuliaKeywords::clearVariables()
-
- void JuliaKeywords::addFunction(const QString &function)
- {
-- if (not m_functions.contains(function)) {
-+ if (!m_functions.contains(function)) {
- m_functions << function;
- }
- }
-diff --git a/src/backends/julia/juliaserver/juliaserver.cpp b/src/backends/julia/juliaserver/juliaserver.cpp
-index c9beb4c..91585cf 100644
---- a/src/backends/julia/juliaserver/juliaserver.cpp
-+++ b/src/backends/julia/juliaserver/juliaserver.cpp
-@@ -47,7 +47,7 @@ void JuliaServer::runJuliaCommand(const QString &command)
- {
- // Redirect stdout, stderr to temprorary files
- QTemporaryFile output, error;
-- if (not output.open() or not error.open()) {
-+ if (!output.open() || !error.open()) {
- qFatal("Unable to create temprorary files for stdout/stderr");
- return;
- }
-@@ -90,7 +90,7 @@ void JuliaServer::runJuliaCommand(const QString &command)
- bool is_nothing = jl_unbox_bool(
- static_cast<jl_value_t *>(jl_call2(equality, nothing, val))
- );
-- if (not is_nothing) {
-+ if (!is_nothing) {
- jl_static_show(JL_STDOUT, val);
- }
- m_was_exception = false;
-diff --git a/src/backends/julia/juliaserver/main.cpp b/src/backends/julia/juliaserver/main.cpp
-index ad7e4d9..11687ec 100644
---- a/src/backends/julia/juliaserver/main.cpp
-+++ b/src/backends/julia/juliaserver/main.cpp
-@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
- {
- QCoreApplication app(argc, argv);
-
-- if (not QDBusConnection::sessionBus().isConnected()) {
-+ if (!QDBusConnection::sessionBus().isConnected()) {
- qWarning() << "Can't connect to the D-Bus session bus.\n"
- "To start it, run: eval `dbus-launch --auto-syntax`";
- return 1;
-@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
- const QString &serviceName =
- QString::fromLatin1("org.kde.Cantor.Julia-%1").arg(app.applicationPid());
-
-- if (not QDBusConnection::sessionBus().registerService(serviceName)) {
-+ if (!QDBusConnection::sessionBus().registerService(serviceName)) {
- qWarning() << QDBusConnection::sessionBus().lastError().message();
- return 2;
- }
-diff --git a/src/backends/julia/juliasession.cpp b/src/backends/julia/juliasession.cpp
-index 425e6cb..9183e11 100644
---- a/src/backends/julia/juliasession.cpp
-+++ b/src/backends/julia/juliasession.cpp
-@@ -86,7 +86,7 @@ void JuliaSession::login()
- QDBusConnection::sessionBus()
- );
-
-- if (not m_interface->isValid()) {
-+ if (!m_interface->isValid()) {
- qWarning() << QDBusConnection::sessionBus().lastError().message();
- return;
- }
-@@ -213,7 +213,7 @@ bool JuliaSession::getWasException()
- {
- const QDBusReply<bool> &reply =
- m_interface->call(QLatin1String("getWasException"));
-- return reply.isValid() and reply.value();
-+ return reply.isValid() && reply.value();
- }
-
- void JuliaSession::listVariables()
---
-2.10.2
-
diff --git a/kde/patch/cantor/cantor_python.patch b/kde/patch/cantor/cantor_python.patch
deleted file mode 100644
index aa2b398..0000000
--- a/kde/patch/cantor/cantor_python.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-Patch taken from:
-https://gitweb.gentoo.org/repo/gentoo.git/plain/kde-apps/cantor/files/cantor-16.12.2-python-kf-5.31.patch
-
-commit 4b8ef6bed62daced90c7826985650c2a813d2996
-Author: Jonathan Riddell <jr@jriddell.org>
-Date: Wed Feb 8 14:56:48 2017 +0000
-
- remove modern C++ use to fix compile with current KDE policy
-
-diff --git a/src/backends/python/pythonhighlighter.cpp b/src/backends/python/pythonhighlighter.cpp
-index 4064524..87b10dd 100644
---- a/src/backends/python/pythonhighlighter.cpp
-+++ b/src/backends/python/pythonhighlighter.cpp
-@@ -87,7 +87,7 @@ void PythonHighlighter::highlightBlock(const QString &text)
- while (pos < text.length()) {
- // Trying to close current environments
- bool triggered = false;
-- for (int i = 0; i < flags.size() and not triggered; i++) {
-+ for (int i = 0; i < flags.size() && !triggered; i++) {
- int flag = flags[i];
- QRegExp &regexp = regexps[i];
- QTextCharFormat &format = formats[i];
-@@ -126,7 +126,7 @@ void PythonHighlighter::highlightBlock(const QString &text)
- singleLineCommentStart.indexIn(text, pos);
-
- if (singleLineCommentStartPos != -1
-- and singleLineCommentStartPos < minPos) {
-+ && singleLineCommentStartPos < minPos) {
- setFormat(pos, text.length() - pos, commentFormat());
- break;
- } else if (minRegexp) {
diff --git a/kde/patch/digikam.patch b/kde/patch/digikam.patch
deleted file mode 100644
index 8f50ec2..0000000
--- a/kde/patch/digikam.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-# Fix compilation with clang.
-# Fixed in digikam 5.5.0.
-#cat $CWD/patch/digikam/digikam_clang_fix.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Fix linking issue, backport from git master:
-#cd core
-# cat $CWD/patch/digikam/digikam_databasemodel.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-#cd -
-
-# Fix crashes with imagemagick 7 (fixed post digikam 6.4.0):
-cat $CWD/patch/digikam/digikam_imagemagick7.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/digikam/digikam_clang_fix.patch b/kde/patch/digikam/digikam_clang_fix.patch
deleted file mode 100644
index a4d77b0..0000000
--- a/kde/patch/digikam/digikam_clang_fix.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-Taken from:
-http://pkgs.fedoraproject.org/cgit/rpms/digikam.git/
-And added and extra '/core/' path componenent.
-
-From 86cd0d1d89c8b4d13f06dc8a353bdd99f13c4758 Mon Sep 17 00:00:00 2001
-From: Gilles Caulier <caulier.gilles@gmail.com>
-Date: Wed, 18 Jan 2017 10:13:20 +0100
-Subject: [PATCH 2/2] Fix compilation with clang
-
----
- libs/dmetadata/metaengine_p.cpp | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/core/libs/dmetadata/metaengine_p.cpp b/core/libs/dmetadata/metaengine_p.cpp
-index 2c83b58..2b44e06 100644
---- a/core/libs/dmetadata/metaengine_p.cpp
-+++ b/core/libs/dmetadata/metaengine_p.cpp
-@@ -49,7 +49,7 @@ extern "C"
- #include "digikam_debug.h"
-
- // Pragma directives to reduce warnings from Exiv2.
--#if not defined(__APPLE__) && defined(__GNUC__)
-+#if !defined(__APPLE__) && defined(__GNUC__)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- #endif
-@@ -723,7 +723,7 @@ void MetaEngine::Private::loadSidecarData(Exiv2::Image::AutoPtr xmpsidecar)
- } // namespace Digikam
-
- // Restore warnings
--#if not defined(__APPLE__) && defined(__GNUC__)
-+#if !defined(__APPLE__) && defined(__GNUC__)
- #pragma GCC diagnostic pop
- #endif
-
---
-2.9.3
-
diff --git a/kde/patch/digikam/digikam_databasemodel.patch b/kde/patch/digikam/digikam_databasemodel.patch
deleted file mode 100644
index 8b2fff7..0000000
--- a/kde/patch/digikam/digikam_databasemodel.patch
+++ /dev/null
@@ -1,13337 +0,0 @@
-From 7e00441c257e7e9e5dc5ab983fc06046fb72b0c5 Mon Sep 17 00:00:00 2001
-From: Gilles Caulier <caulier.gilles@gmail.com>
-Date: Sat, 22 Jul 2017 15:46:08 +0200
-Subject: fix broken linking stage under MacOS with macports. move database
- models into libdigikamdatabase. Let's others model in place to be included
- into libdigikamcore
-
----
- libs/database/CMakeLists.txt | 16 +-
- libs/database/models/imagefiltermodel.cpp | 1116 ++++++++++++++++++
- libs/database/models/imagefiltermodel.h | 299 +++++
- libs/database/models/imagefiltermodelpriv.cpp | 258 ++++
- libs/database/models/imagefiltermodelpriv.h | 159 +++
- libs/database/models/imagefiltermodelthreads.cpp | 40 +
- libs/database/models/imagefiltermodelthreads.h | 100 ++
- libs/database/models/imagefiltersettings.cpp | 952 +++++++++++++++
- libs/database/models/imagefiltersettings.h | 349 ++++++
- libs/database/models/imagelistmodel.cpp | 70 ++
- libs/database/models/imagelistmodel.h | 63 +
- libs/database/models/imagemodel.cpp | 1368 ++++++++++++++++++++++
- libs/database/models/imagemodel.h | 364 ++++++
- libs/database/models/imagesortsettings.cpp | 400 +++++++
- libs/database/models/imagesortsettings.h | 225 ++++
- libs/database/models/imagethumbnailmodel.cpp | 323 +++++
- libs/database/models/imagethumbnailmodel.h | 140 +++
- libs/database/models/imageversionsmodel.cpp | 183 +++
- libs/database/models/imageversionsmodel.h | 75 ++
- libs/models/CMakeLists.txt | 15 +-
- libs/models/imagefiltermodel.cpp | 1116 ------------------
- libs/models/imagefiltermodel.h | 299 -----
- libs/models/imagefiltermodelpriv.cpp | 258 ----
- libs/models/imagefiltermodelpriv.h | 159 ---
- libs/models/imagefiltermodelthreads.cpp | 40 -
- libs/models/imagefiltermodelthreads.h | 100 --
- libs/models/imagefiltersettings.cpp | 952 ---------------
- libs/models/imagefiltersettings.h | 349 ------
- libs/models/imagelistmodel.cpp | 70 --
- libs/models/imagelistmodel.h | 63 -
- libs/models/imagemodel.cpp | 1368 ----------------------
- libs/models/imagemodel.h | 364 ------
- libs/models/imagesortsettings.cpp | 400 -------
- libs/models/imagesortsettings.h | 225 ----
- libs/models/imagethumbnailmodel.cpp | 323 -----
- libs/models/imagethumbnailmodel.h | 140 ---
- libs/models/imageversionsmodel.cpp | 183 ---
- libs/models/imageversionsmodel.h | 75 --
- 38 files changed, 6499 insertions(+), 6500 deletions(-)
- create mode 100644 libs/database/models/imagefiltermodel.cpp
- create mode 100644 libs/database/models/imagefiltermodel.h
- create mode 100644 libs/database/models/imagefiltermodelpriv.cpp
- create mode 100644 libs/database/models/imagefiltermodelpriv.h
- create mode 100644 libs/database/models/imagefiltermodelthreads.cpp
- create mode 100644 libs/database/models/imagefiltermodelthreads.h
- create mode 100644 libs/database/models/imagefiltersettings.cpp
- create mode 100644 libs/database/models/imagefiltersettings.h
- create mode 100644 libs/database/models/imagelistmodel.cpp
- create mode 100644 libs/database/models/imagelistmodel.h
- create mode 100644 libs/database/models/imagemodel.cpp
- create mode 100644 libs/database/models/imagemodel.h
- create mode 100644 libs/database/models/imagesortsettings.cpp
- create mode 100644 libs/database/models/imagesortsettings.h
- create mode 100644 libs/database/models/imagethumbnailmodel.cpp
- create mode 100644 libs/database/models/imagethumbnailmodel.h
- create mode 100644 libs/database/models/imageversionsmodel.cpp
- create mode 100644 libs/database/models/imageversionsmodel.h
- delete mode 100644 libs/models/imagefiltermodel.cpp
- delete mode 100644 libs/models/imagefiltermodel.h
- delete mode 100644 libs/models/imagefiltermodelpriv.cpp
- delete mode 100644 libs/models/imagefiltermodelpriv.h
- delete mode 100644 libs/models/imagefiltermodelthreads.cpp
- delete mode 100644 libs/models/imagefiltermodelthreads.h
- delete mode 100644 libs/models/imagefiltersettings.cpp
- delete mode 100644 libs/models/imagefiltersettings.h
- delete mode 100644 libs/models/imagelistmodel.cpp
- delete mode 100644 libs/models/imagelistmodel.h
- delete mode 100644 libs/models/imagemodel.cpp
- delete mode 100644 libs/models/imagemodel.h
- delete mode 100644 libs/models/imagesortsettings.cpp
- delete mode 100644 libs/models/imagesortsettings.h
- delete mode 100644 libs/models/imagethumbnailmodel.cpp
- delete mode 100644 libs/models/imagethumbnailmodel.h
- delete mode 100644 libs/models/imageversionsmodel.cpp
- delete mode 100644 libs/models/imageversionsmodel.h
-
-diff --git a/libs/database/CMakeLists.txt b/libs/database/CMakeLists.txt
-index 7d05536..a431a36 100644
---- a/libs/database/CMakeLists.txt
-+++ b/libs/database/CMakeLists.txt
-@@ -13,6 +13,18 @@ endif (POLICY CMP0063)
- # Boost uses operator names (and, not, ...)
- string(REPLACE "-fno-operator-names" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-
-+set(libdatabasemodels_SRCS
-+ models/imagemodel.cpp
-+ models/imagefiltermodel.cpp
-+ models/imagefiltermodelpriv.cpp
-+ models/imagefiltermodelthreads.cpp
-+ models/imagefiltersettings.cpp
-+ models/imagelistmodel.cpp
-+ models/imagesortsettings.cpp
-+ models/imagethumbnailmodel.cpp
-+ models/imageversionsmodel.cpp
-+)
-+
- set(libdatabasecore_SRCS
- server/databaseserverstarter.cpp
- server/databaseservererror.cpp
-@@ -152,10 +164,10 @@ if(ENABLE_DBUS)
- include_directories($<TARGET_PROPERTY:Qt5::DBus,INTERFACE_INCLUDE_DIRECTORIES>)
- endif()
-
--add_library(digikamdatabase_src OBJECT ${digikamdatabase_LIB_SRCS})
-+add_library(digikamdatabase_src OBJECT ${digikamdatabase_LIB_SRCS} ${libdatabasemodels_SRCS})
- add_library(digikamdatabasemain_src OBJECT ${libdatabaseutils_SRCS} ${libimgqsort_SRCS})
- add_library(digikamdatabasecore_src OBJECT ${libdatabasecore_SRCS})
--add_library(digikamdatabase SHARED $<TARGET_OBJECTS:digikamdatabase_src> $<TARGET_OBJECTS:digikamdatabasemodels_src>)
-+add_library(digikamdatabase $<TARGET_OBJECTS:digikamdatabase_src>)
-
- generate_export_header(digikamdatabase
- BASE_NAME digikam_database
-diff --git a/libs/database/models/imagefiltermodel.cpp b/libs/database/models/imagefiltermodel.cpp
-new file mode 100644
-index 0000000..3d57e05
---- /dev/null
-+++ b/libs/database/models/imagefiltermodel.cpp
-@@ -0,0 +1,1116 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-+ * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-+ * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagefiltermodel.h"
-+#include "imagefiltermodelpriv.h"
-+#include "imagefiltermodelthreads.h"
-+
-+// Local includes
-+
-+#include "digikam_debug.h"
-+#include "coredbaccess.h"
-+#include "coredbchangesets.h"
-+#include "coredbwatch.h"
-+#include "imageinfolist.h"
-+#include "imagemodel.h"
-+
-+namespace Digikam
-+{
-+
-+ImageSortFilterModel::ImageSortFilterModel(QObject* parent)
-+ : DCategorizedSortFilterProxyModel(parent), m_chainedModel(0)
-+{
-+}
-+
-+void ImageSortFilterModel::setSourceImageModel(ImageModel* source)
-+{
-+ if (m_chainedModel)
-+ {
-+ m_chainedModel->setSourceImageModel(source);
-+ }
-+ else
-+ {
-+ setDirectSourceImageModel(source);
-+ }
-+}
-+
-+void ImageSortFilterModel::setSourceFilterModel(ImageSortFilterModel* source)
-+{
-+ if (source)
-+ {
-+ ImageModel* const model = sourceImageModel();
-+
-+ if (model)
-+ {
-+ source->setSourceImageModel(model);
-+ }
-+ }
-+
-+ m_chainedModel = source;
-+ setSourceModel(source);
-+}
-+
-+void ImageSortFilterModel::setDirectSourceImageModel(ImageModel* model)
-+{
-+ setSourceModel(model);
-+}
-+
-+void ImageSortFilterModel::setSourceModel(QAbstractItemModel* model)
-+{
-+ // made it protected, only setSourceImageModel is public
-+ DCategorizedSortFilterProxyModel::setSourceModel(model);
-+}
-+
-+ImageModel* ImageSortFilterModel::sourceImageModel() const
-+{
-+ if (m_chainedModel)
-+ {
-+ return m_chainedModel->sourceImageModel();
-+ }
-+
-+ return static_cast<ImageModel*>(sourceModel());
-+}
-+
-+ImageSortFilterModel* ImageSortFilterModel::sourceFilterModel() const
-+{
-+ return m_chainedModel;
-+}
-+
-+ImageFilterModel* ImageSortFilterModel::imageFilterModel() const
-+{
-+ // reimplemented in ImageFilterModel
-+ if (m_chainedModel)
-+ {
-+ return m_chainedModel->imageFilterModel();
-+ }
-+
-+ return 0;
-+}
-+
-+QModelIndex ImageSortFilterModel::mapToSourceImageModel(const QModelIndex& index) const
-+{
-+ if (m_chainedModel)
-+ {
-+ return m_chainedModel->mapToSourceImageModel(mapToSource(index));
-+ }
-+
-+ return mapToSource(index);
-+}
-+
-+QModelIndex ImageSortFilterModel::mapFromSourceImageModel(const QModelIndex& albummodel_index) const
-+{
-+ if (m_chainedModel)
-+ {
-+ return mapFromSource(m_chainedModel->mapFromSourceImageModel(albummodel_index));
-+ }
-+
-+ return mapFromSource(albummodel_index);
-+}
-+
-+
-+QModelIndex ImageSortFilterModel::mapFromDirectSourceToSourceImageModel(const QModelIndex& sourceModel_index) const
-+{
-+ if (m_chainedModel)
-+ {
-+ return m_chainedModel->mapToSourceImageModel(sourceModel_index);
-+ }
-+ return sourceModel_index;
-+}
-+
-+// -------------- Convenience mappers -------------------------------------------------------------------
-+
-+QList<QModelIndex> ImageSortFilterModel::mapListToSource(const QList<QModelIndex>& indexes) const
-+{
-+ QList<QModelIndex> sourceIndexes;
-+ foreach(const QModelIndex& index, indexes)
-+ {
-+ sourceIndexes << mapToSourceImageModel(index);
-+ }
-+ return sourceIndexes;
-+}
-+
-+QList<QModelIndex> ImageSortFilterModel::mapListFromSource(const QList<QModelIndex>& sourceIndexes) const
-+{
-+ QList<QModelIndex> indexes;
-+ foreach(const QModelIndex& index, sourceIndexes)
-+ {
-+ indexes << mapFromSourceImageModel(index);
-+ }
-+ return indexes;
-+}
-+
-+ImageInfo ImageSortFilterModel::imageInfo(const QModelIndex& index) const
-+{
-+ return sourceImageModel()->imageInfo(mapToSourceImageModel(index));
-+}
-+
-+qlonglong ImageSortFilterModel::imageId(const QModelIndex& index) const
-+{
-+ return sourceImageModel()->imageId(mapToSourceImageModel(index));
-+}
-+
-+QList<ImageInfo> ImageSortFilterModel::imageInfos(const QList<QModelIndex>& indexes) const
-+{
-+ QList<ImageInfo> infos;
-+ ImageModel* const model = sourceImageModel();
-+
-+ foreach(const QModelIndex& index, indexes)
-+ {
-+ infos << model->imageInfo(mapToSourceImageModel(index));
-+ }
-+
-+ return infos;
-+}
-+
-+QList<qlonglong> ImageSortFilterModel::imageIds(const QList<QModelIndex>& indexes) const
-+{
-+ QList<qlonglong> ids;
-+ ImageModel* const model = sourceImageModel();
-+
-+ foreach(const QModelIndex& index, indexes)
-+ {
-+ ids << model->imageId(mapToSourceImageModel(index));
-+ }
-+
-+ return ids;
-+}
-+
-+QModelIndex ImageSortFilterModel::indexForPath(const QString& filePath) const
-+{
-+ return mapFromSourceImageModel(sourceImageModel()->indexForPath(filePath));
-+}
-+
-+QModelIndex ImageSortFilterModel::indexForImageInfo(const ImageInfo& info) const
-+{
-+ return mapFromSourceImageModel(sourceImageModel()->indexForImageInfo(info));
-+}
-+
-+QModelIndex ImageSortFilterModel::indexForImageId(qlonglong id) const
-+{
-+ return mapFromSourceImageModel(sourceImageModel()->indexForImageId(id));
-+}
-+
-+QList<ImageInfo> ImageSortFilterModel::imageInfosSorted() const
-+{
-+ QList<ImageInfo> infos;
-+ const int size = rowCount();
-+ ImageModel* const model = sourceImageModel();
-+
-+ for (int i=0; i<size; ++i)
-+ {
-+ infos << model->imageInfo(mapToSourceImageModel(index(i, 0)));
-+ }
-+
-+ return infos;
-+}
-+
-+// --------------------------------------------------------------------------------------------
-+
-+ImageFilterModel::ImageFilterModel(QObject* parent)
-+ : ImageSortFilterModel(parent),
-+ d_ptr(new ImageFilterModelPrivate)
-+{
-+ d_ptr->init(this);
-+}
-+
-+ImageFilterModel::ImageFilterModel(ImageFilterModelPrivate& dd, QObject* parent)
-+ : ImageSortFilterModel(parent),
-+ d_ptr(&dd)
-+{
-+ d_ptr->init(this);
-+}
-+
-+ImageFilterModel::~ImageFilterModel()
-+{
-+ Q_D(ImageFilterModel);
-+ delete d;
-+}
-+
-+void ImageFilterModel::setDirectSourceImageModel(ImageModel* sourceModel)
-+{
-+ Q_D(ImageFilterModel);
-+
-+ if (d->imageModel)
-+ {
-+ d->imageModel->unsetPreprocessor(d);
-+ disconnect(d->imageModel, SIGNAL(modelReset()),
-+ this, SLOT(slotModelReset()));
-+ slotModelReset();
-+ }
-+
-+ d->imageModel = sourceModel;
-+
-+ if (d->imageModel)
-+ {
-+ d->imageModel->setPreprocessor(d);
-+
-+ connect(d->imageModel, SIGNAL(preprocess(QList<ImageInfo>,QList<QVariant>)),
-+ d, SLOT(preprocessInfos(QList<ImageInfo>,QList<QVariant>)));
-+
-+ connect(d->imageModel, SIGNAL(processAdded(QList<ImageInfo>,QList<QVariant>)),
-+ d, SLOT(processAddedInfos(QList<ImageInfo>,QList<QVariant>)));
-+
-+ connect(d, SIGNAL(reAddImageInfos(QList<ImageInfo>,QList<QVariant>)),
-+ d->imageModel, SLOT(reAddImageInfos(QList<ImageInfo>,QList<QVariant>)));
-+
-+ connect(d, SIGNAL(reAddingFinished()),
-+ d->imageModel, SLOT(reAddingFinished()));
-+
-+ connect(d->imageModel, SIGNAL(modelReset()),
-+ this, SLOT(slotModelReset()));
-+
-+ connect(d->imageModel, SIGNAL(imageChange(ImageChangeset,QItemSelection)),
-+ this, SLOT(slotImageChange(ImageChangeset)));
-+
-+ connect(d->imageModel, SIGNAL(imageTagChange(ImageTagChangeset,QItemSelection)),
-+ this, SLOT(slotImageTagChange(ImageTagChangeset)));
-+ }
-+
-+ setSourceModel(d->imageModel);
-+}
-+
-+QVariant ImageFilterModel::data(const QModelIndex& index, int role) const
-+{
-+ Q_D(const ImageFilterModel);
-+
-+ if (!index.isValid())
-+ {
-+ return QVariant();
-+ }
-+
-+ switch (role)
-+ {
-+ // Attention: This breaks should there ever be another filter model between this and the ImageModel
-+
-+ case DCategorizedSortFilterProxyModel::CategoryDisplayRole:
-+ return categoryIdentifier(d->imageModel->imageInfoRef(mapToSource(index)));
-+ case CategorizationModeRole:
-+ return d->sorter.categorizationMode;
-+ case SortOrderRole:
-+ return d->sorter.sortRole;
-+ //case CategoryCountRole:
-+ // return categoryCount(d->imageModel->imageInfoRef(mapToSource(index)));
-+ case CategoryAlbumIdRole:
-+ return d->imageModel->imageInfoRef(mapToSource(index)).albumId();
-+ case CategoryFormatRole:
-+ return d->imageModel->imageInfoRef(mapToSource(index)).format();
-+ case GroupIsOpenRole:
-+ return d->groupFilter.isAllOpen() ||
-+ d->groupFilter.isOpen(d->imageModel->imageInfoRef(mapToSource(index)).id());
-+ case ImageFilterModelPointerRole:
-+ return QVariant::fromValue(const_cast<ImageFilterModel*>(this));
-+ }
-+
-+ return DCategorizedSortFilterProxyModel::data(index, role);
-+}
-+
-+ImageFilterModel* ImageFilterModel::imageFilterModel() const
-+{
-+ return const_cast<ImageFilterModel*>(this);
-+}
-+
-+DatabaseFields::Set ImageFilterModel::suggestedWatchFlags() const
-+{
-+ DatabaseFields::Set watchFlags;
-+ watchFlags |= DatabaseFields::Name | DatabaseFields::FileSize | DatabaseFields::ModificationDate;
-+ watchFlags |= DatabaseFields::Rating | DatabaseFields::CreationDate | DatabaseFields::Orientation |
-+ DatabaseFields::Width | DatabaseFields::Height;
-+ watchFlags |= DatabaseFields::Comment;
-+ watchFlags |= DatabaseFields::ImageRelations;
-+ return watchFlags;
-+}
-+
-+// -------------- Filter settings --------------
-+
-+void ImageFilterModel::setDayFilter(const QList<QDateTime>& days)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setDayFilter(days);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setTagFilter(const QList<int>& includedTags, const QList<int>& excludedTags,
-+ ImageFilterSettings::MatchingCondition matchingCond,
-+ bool showUnTagged, const QList<int>& clTagIds, const QList<int>& plTagIds)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setTagFilter(includedTags, excludedTags, matchingCond, showUnTagged, clTagIds, plTagIds);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setRatingFilter(int rating, ImageFilterSettings::RatingCondition ratingCond, bool isUnratedExcluded)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setRatingFilter(rating, ratingCond, isUnratedExcluded);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setUrlWhitelist(const QList<QUrl> urlList, const QString& id)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setUrlWhitelist(urlList, id);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setIdWhitelist(const QList<qlonglong>& idList, const QString& id)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setIdWhitelist(idList, id);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setMimeTypeFilter(int mimeTypeFilter)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setMimeTypeFilter(mimeTypeFilter);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setGeolocationFilter(const ImageFilterSettings::GeolocationCondition& condition)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setGeolocationFilter(condition);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setTextFilter(const SearchTextFilterSettings& settings)
-+{
-+ Q_D(ImageFilterModel);
-+ d->filter.setTextFilter(settings);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+void ImageFilterModel::setImageFilterSettings(const ImageFilterSettings& settings)
-+{
-+ Q_D(ImageFilterModel);
-+
-+ {
-+ QMutexLocker lock(&d->mutex);
-+ d->version++;
-+ d->filter = settings;
-+ d->filterCopy = settings;
-+ d->versionFilterCopy = d->versionFilter;
-+ d->groupFilterCopy = d->groupFilter;
-+
-+ d->needPrepareComments = settings.isFilteringByText();
-+ d->needPrepareTags = settings.isFilteringByTags();
-+ d->needPrepareGroups = true;
-+ d->needPrepare = d->needPrepareComments || d->needPrepareTags || d->needPrepareGroups;
-+
-+ d->hasOneMatch = false;
-+ d->hasOneMatchForText = false;
-+ }
-+
-+ d->filterResults.clear();
-+
-+ //d->categoryCountHashInt.clear();
-+ //d->categoryCountHashString.clear();
-+ if (d->imageModel)
-+ {
-+ d->infosToProcess(d->imageModel->imageInfos());
-+ }
-+
-+ emit filterSettingsChanged(settings);
-+}
-+
-+void ImageFilterModel::setVersionManagerSettings(const VersionManagerSettings& settings)
-+{
-+ Q_D(ImageFilterModel);
-+ d->versionFilter.setVersionManagerSettings(settings);
-+ setVersionImageFilterSettings(d->versionFilter);
-+}
-+
-+void ImageFilterModel::setExceptionList(const QList<qlonglong>& idList, const QString& id)
-+{
-+ Q_D(ImageFilterModel);
-+ d->versionFilter.setExceptionList(idList, id);
-+ setVersionImageFilterSettings(d->versionFilter);
-+}
-+
-+void ImageFilterModel::setVersionImageFilterSettings(const VersionImageFilterSettings& settings)
-+{
-+ Q_D(ImageFilterModel);
-+ d->versionFilter = settings;
-+ slotUpdateFilter();
-+}
-+
-+bool ImageFilterModel::isGroupOpen(qlonglong group) const
-+{
-+ Q_D(const ImageFilterModel);
-+ return d->groupFilter.isOpen(group);
-+}
-+
-+bool ImageFilterModel::isAllGroupsOpen() const
-+{
-+ Q_D(const ImageFilterModel);
-+ return d->groupFilter.isAllOpen();
-+}
-+
-+void ImageFilterModel::setGroupOpen(qlonglong group, bool open)
-+{
-+ Q_D(ImageFilterModel);
-+ d->groupFilter.setOpen(group, open);
-+ setGroupImageFilterSettings(d->groupFilter);
-+}
-+
-+void ImageFilterModel::toggleGroupOpen(qlonglong group)
-+{
-+ setGroupOpen(group, !isGroupOpen(group));
-+}
-+
-+void ImageFilterModel::setAllGroupsOpen(bool open)
-+{
-+ Q_D(ImageFilterModel);
-+ d->groupFilter.setAllOpen(open);
-+ setGroupImageFilterSettings(d->groupFilter);
-+}
-+
-+void ImageFilterModel::setGroupImageFilterSettings(const GroupImageFilterSettings& settings)
-+{
-+ Q_D(ImageFilterModel);
-+ d->groupFilter = settings;
-+ slotUpdateFilter();
-+}
-+
-+void ImageFilterModel::slotUpdateFilter()
-+{
-+ Q_D(ImageFilterModel);
-+ setImageFilterSettings(d->filter);
-+}
-+
-+ImageFilterSettings ImageFilterModel::imageFilterSettings() const
-+{
-+ Q_D(const ImageFilterModel);
-+ return d->filter;
-+}
-+
-+ImageSortSettings ImageFilterModel::imageSortSettings() const
-+{
-+ Q_D(const ImageFilterModel);
-+ return d->sorter;
-+}
-+
-+VersionImageFilterSettings ImageFilterModel::versionImageFilterSettings() const
-+{
-+ Q_D(const ImageFilterModel);
-+ return d->versionFilter;
-+}
-+
-+GroupImageFilterSettings ImageFilterModel::groupImageFilterSettings() const
-+{
-+ Q_D(const ImageFilterModel);
-+ return d->groupFilter;
-+}
-+
-+void ImageFilterModel::slotModelReset()
-+{
-+ Q_D(ImageFilterModel);
-+ {
-+ QMutexLocker lock(&d->mutex);
-+ // discard all packages on the way that are marked as send out for re-add
-+ d->lastDiscardVersion = d->version;
-+ d->sentOutForReAdd = 0;
-+ // discard all packages on the way
-+ d->version++;
-+ d->sentOut = 0;
-+
-+ d->hasOneMatch = false;
-+ d->hasOneMatchForText = false;
-+ }
-+ d->filterResults.clear();
-+}
-+
-+bool ImageFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
-+{
-+ Q_D(const ImageFilterModel);
-+
-+ if (source_parent.isValid())
-+ {
-+ return false;
-+ }
-+
-+ qlonglong id = d->imageModel->imageId(source_row);
-+ QHash<qlonglong, bool>::const_iterator it = d->filterResults.constFind(id);
-+
-+ if (it != d->filterResults.constEnd())
-+ {
-+ return it.value();
-+ }
-+
-+ // usually done in thread and cache, unless source model changed
-+ ImageInfo info = d->imageModel->imageInfo(source_row);
-+ bool match = d->filter.matches(info);
-+ match = match ? d->versionFilter.matches(info) : false;
-+
-+ return match ? d->groupFilter.matches(info) : false;
-+}
-+
-+void ImageFilterModel::setSendImageInfoSignals(bool sendSignals)
-+{
-+ if (sendSignals)
-+ {
-+ connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)),
-+ this, SLOT(slotRowsInserted(QModelIndex,int,int)));
-+
-+ connect(this, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
-+ this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)));
-+ }
-+ else
-+ {
-+ disconnect(this, SIGNAL(rowsInserted(QModelIndex,int,int)),
-+ this, SLOT(slotRowsInserted(QModelIndex,int,int)));
-+
-+ disconnect(this, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
-+ this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)));
-+ }
-+}
-+
-+void ImageFilterModel::slotRowsInserted(const QModelIndex& /*parent*/, int start, int end)
-+{
-+ QList<ImageInfo> infos;
-+
-+ for (int i=start; i<=end; ++i)
-+ {
-+ infos << imageInfo(index(i, 0));
-+ }
-+
-+ emit imageInfosAdded(infos);
-+}
-+
-+void ImageFilterModel::slotRowsAboutToBeRemoved(const QModelIndex& /*parent*/, int start, int end)
-+{
-+ QList<ImageInfo> infos;
-+
-+ for (int i=start; i<=end; ++i)
-+ {
-+ infos << imageInfo(index(i, 0));
-+ }
-+
-+ emit imageInfosAboutToBeRemoved(infos);
-+}
-+
-+// -------------- Threaded preparation & filtering --------------
-+
-+void ImageFilterModel::addPrepareHook(ImageFilterModelPrepareHook* hook)
-+{
-+ Q_D(ImageFilterModel);
-+ QMutexLocker lock(&d->mutex);
-+ d->prepareHooks << hook;
-+}
-+
-+void ImageFilterModel::removePrepareHook(ImageFilterModelPrepareHook* hook)
-+{
-+ Q_D(ImageFilterModel);
-+ QMutexLocker lock(&d->mutex);
-+ d->prepareHooks.removeAll(hook);
-+}
-+
-+void ImageFilterModelPreparer::process(ImageFilterModelTodoPackage package)
-+{
-+ if (!checkVersion(package))
-+ {
-+ emit discarded(package);
-+ return;
-+ }
-+
-+ // get thread-local copy
-+ bool needPrepareTags, needPrepareComments, needPrepareGroups;
-+ QList<ImageFilterModelPrepareHook*> prepareHooks;
-+ {
-+ QMutexLocker lock(&d->mutex);
-+ needPrepareTags = d->needPrepareTags;
-+ needPrepareComments = d->needPrepareComments;
-+ needPrepareGroups = d->needPrepareGroups;
-+ prepareHooks = d->prepareHooks;
-+ }
-+
-+ //TODO: Make efficient!!
-+ if (needPrepareComments)
-+ {
-+ foreach(const ImageInfo& info, package.infos)
-+ {
-+ info.comment();
-+ }
-+ }
-+
-+ if (!checkVersion(package))
-+ {
-+ emit discarded(package);
-+ return;
-+ }
-+
-+ // The downside of QVector: At some point, we may need a QList for an API.
-+ // Nonetheless, QList and ImageInfo is fast. We could as well
-+ // reimplement ImageInfoList to ImageInfoVector (internally with templates?)
-+ ImageInfoList infoList;
-+
-+ if (needPrepareTags || needPrepareGroups)
-+ {
-+ infoList = package.infos.toList();
-+ }
-+
-+ if (needPrepareTags)
-+ {
-+ infoList.loadTagIds();
-+ }
-+
-+ if (needPrepareGroups)
-+ {
-+ infoList.loadGroupImageIds();
-+ }
-+
-+ foreach(ImageFilterModelPrepareHook* hook, prepareHooks)
-+ {
-+ hook->prepare(package.infos);
-+ }
-+
-+ emit processed(package);
-+}
-+
-+void ImageFilterModelFilterer::process(ImageFilterModelTodoPackage package)
-+{
-+ if (!checkVersion(package))
-+ {
-+ emit discarded(package);
-+ return;
-+ }
-+
-+ // get thread-local copy
-+ ImageFilterSettings localFilter;
-+ VersionImageFilterSettings localVersionFilter;
-+ GroupImageFilterSettings localGroupFilter;
-+ bool hasOneMatch;
-+ bool hasOneMatchForText;
-+ {
-+ QMutexLocker lock(&d->mutex);
-+ localFilter = d->filterCopy;
-+ localVersionFilter = d->versionFilterCopy;
-+ localGroupFilter = d->groupFilterCopy;
-+ hasOneMatch = d->hasOneMatch;
-+ hasOneMatchForText = d->hasOneMatchForText;
-+ }
-+
-+ // Actual filtering. The variants to spare checking hasOneMatch over and over again.
-+ if (hasOneMatch && hasOneMatchForText)
-+ {
-+ foreach(const ImageInfo& info, package.infos)
-+ {
-+ package.filterResults[info.id()] = localFilter.matches(info) &&
-+ localVersionFilter.matches(info) &&
-+ localGroupFilter.matches(info);
-+ }
-+ }
-+ else if (hasOneMatch)
-+ {
-+ bool matchForText;
-+
-+ foreach(const ImageInfo& info, package.infos)
-+ {
-+ package.filterResults[info.id()] = localFilter.matches(info, &matchForText) &&
-+ localVersionFilter.matches(info) &&
-+ localGroupFilter.matches(info);
-+
-+ if (matchForText)
-+ {
-+ hasOneMatchForText = true;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ bool result, matchForText;
-+
-+ foreach(const ImageInfo& info, package.infos)
-+ {
-+ result = localFilter.matches(info, &matchForText) &&
-+ localVersionFilter.matches(info) &&
-+ localGroupFilter.matches(info);
-+ package.filterResults[info.id()] = result;
-+
-+ if (result)
-+ {
-+ hasOneMatch = true;
-+ }
-+
-+ if (matchForText)
-+ {
-+ hasOneMatchForText = true;
-+ }
-+ }
-+ }
-+
-+ if (checkVersion(package))
-+ {
-+ QMutexLocker lock(&d->mutex);
-+ d->hasOneMatch = hasOneMatch;
-+ d->hasOneMatchForText = hasOneMatchForText;
-+ }
-+
-+ emit processed(package);
-+}
-+
-+// -------------- Sorting and Categorization -------------------------------------------------------
-+
-+void ImageFilterModel::setImageSortSettings(const ImageSortSettings& sorter)
-+{
-+ Q_D(ImageFilterModel);
-+ d->sorter = sorter;
-+ setCategorizedModel(d->sorter.categorizationMode != ImageSortSettings::NoCategories);
-+ invalidate();
-+}
-+
-+void ImageFilterModel::setCategorizationMode(ImageSortSettings::CategorizationMode mode)
-+{
-+ Q_D(ImageFilterModel);
-+ d->sorter.setCategorizationMode(mode);
-+ setImageSortSettings(d->sorter);
-+}
-+
-+void ImageFilterModel::setCategorizationSortOrder(ImageSortSettings::SortOrder order)
-+{
-+ Q_D(ImageFilterModel);
-+ d->sorter.setCategorizationSortOrder(order);
-+ setImageSortSettings(d->sorter);
-+}
-+
-+void ImageFilterModel::setSortRole(ImageSortSettings::SortRole role)
-+{
-+ Q_D(ImageFilterModel);
-+ d->sorter.setSortRole(role);
-+ setImageSortSettings(d->sorter);
-+}
-+
-+void ImageFilterModel::setSortOrder(ImageSortSettings::SortOrder order)
-+{
-+ Q_D(ImageFilterModel);
-+ d->sorter.setSortOrder(order);
-+ setImageSortSettings(d->sorter);
-+}
-+
-+void ImageFilterModel::setStringTypeNatural(bool natural)
-+{
-+ Q_D(ImageFilterModel);
-+ d->sorter.setStringTypeNatural(natural);
-+ setImageSortSettings(d->sorter);
-+}
-+
-+int ImageFilterModel::compareCategories(const QModelIndex& left, const QModelIndex& right) const
-+{
-+ // source indexes
-+ Q_D(const ImageFilterModel);
-+
-+ if (!d->sorter.isCategorized())
-+ {
-+ return 0;
-+ }
-+
-+ if (!left.isValid() || !right.isValid())
-+ {
-+ return -1;
-+ }
-+
-+ const ImageInfo& leftInfo = d->imageModel->imageInfoRef(left);
-+ const ImageInfo& rightInfo = d->imageModel->imageInfoRef(right);
-+
-+ // Check grouping
-+ qlonglong leftGroupImageId = leftInfo.groupImageId();
-+ qlonglong rightGroupImageId = rightInfo.groupImageId();
-+
-+ return compareInfosCategories(leftGroupImageId == -1 ? leftInfo : ImageInfo(leftGroupImageId),
-+ rightGroupImageId == -1 ? rightInfo : ImageInfo(rightGroupImageId));
-+}
-+
-+bool ImageFilterModel::subSortLessThan(const QModelIndex& left, const QModelIndex& right) const
-+{
-+ // source indexes
-+ Q_D(const ImageFilterModel);
-+
-+ if (!left.isValid() || !right.isValid())
-+ {
-+ return true;
-+ }
-+
-+ if (left == right)
-+ {
-+ return false;
-+ }
-+
-+ const ImageInfo& leftInfo = d->imageModel->imageInfoRef(left);
-+ const ImageInfo& rightInfo = d->imageModel->imageInfoRef(right);
-+
-+ if (leftInfo == rightInfo)
-+ {
-+ return d->sorter.lessThan(left.data(ImageModel::ExtraDataRole), right.data(ImageModel::ExtraDataRole));
-+ }
-+
-+ // Check grouping
-+ qlonglong leftGroupImageId = leftInfo.groupImageId();
-+ qlonglong rightGroupImageId = rightInfo.groupImageId();
-+
-+ // Either no grouping (-1), or same group image, or same image
-+ if (leftGroupImageId == rightGroupImageId)
-+ {
-+ return infosLessThan(leftInfo, rightInfo);
-+ }
-+
-+ // We have grouping to handle
-+
-+ // Is one grouped on the other? Sort behind leader.
-+ if (leftGroupImageId == rightInfo.id())
-+ {
-+ return false;
-+ }
-+ if (rightGroupImageId == leftInfo.id())
-+ {
-+ return true;
-+ }
-+
-+ // Use the group leader for sorting
-+ return infosLessThan(leftGroupImageId == -1 ? leftInfo : ImageInfo(leftGroupImageId),
-+ rightGroupImageId == -1 ? rightInfo : ImageInfo(rightGroupImageId));
-+}
-+
-+int ImageFilterModel::compareInfosCategories(const ImageInfo& left, const ImageInfo& right) const
-+{
-+ // Note: reimplemented in ImageAlbumFilterModel
-+ Q_D(const ImageFilterModel);
-+ return d->sorter.compareCategories(left, right);
-+}
-+
-+// Feel free to optimize. QString::number is 3x slower.
-+static inline QString fastNumberToString(int id)
-+{
-+ const int size = sizeof(int) * 2;
-+ char c[size+1];
-+ c[size] = '\0';
-+ char* p = c;
-+ int number = id;
-+
-+ for (int i=0; i<size; ++i)
-+ {
-+ *p = 'a' + (number & 0xF);
-+ number >>= 4;
-+ ++p;
-+ }
-+
-+ return QString::fromLatin1(c);
-+}
-+
-+QString ImageFilterModel::categoryIdentifier(const ImageInfo& i) const
-+{
-+ Q_D(const ImageFilterModel);
-+
-+ if (!d->sorter.isCategorized())
-+ {
-+ return QString();
-+ }
-+
-+ qlonglong groupedImageId = i.groupImageId();
-+ ImageInfo info = groupedImageId == -1 ? i : ImageInfo(groupedImageId);
-+
-+ switch (d->sorter.categorizationMode)
-+ {
-+ case ImageSortSettings::NoCategories:
-+ return QString();
-+ case ImageSortSettings::OneCategory:
-+ return QString();
-+ case ImageSortSettings::CategoryByAlbum:
-+ return fastNumberToString(info.albumId());
-+ case ImageSortSettings::CategoryByFormat:
-+ return info.format();
-+ default:
-+ return QString();
-+ }
-+}
-+
-+bool ImageFilterModel::infosLessThan(const ImageInfo& left, const ImageInfo& right) const
-+{
-+ Q_D(const ImageFilterModel);
-+ return d->sorter.lessThan(left, right);
-+}
-+
-+// -------------- Watching changes -----------------------------------------------------------------
-+
-+void ImageFilterModel::slotImageTagChange(const ImageTagChangeset& changeset)
-+{
-+ Q_D(ImageFilterModel);
-+
-+ if (!d->imageModel || d->imageModel->isEmpty())
-+ {
-+ return;
-+ }
-+
-+ // already scheduled to re-filter?
-+ if (d->updateFilterTimer->isActive())
-+ {
-+ return;
-+ }
-+
-+ // do we filter at all?
-+ if (!d->versionFilter.isFilteringByTags() &&
-+ !d->filter.isFilteringByTags() &&
-+ !d->filter.isFilteringByText())
-+ {
-+ return;
-+ }
-+
-+ // is one of our images affected?
-+ foreach(const qlonglong& id, changeset.ids())
-+ {
-+ // if one matching image id is found, trigger a refresh
-+ if (d->imageModel->hasImage(id))
-+ {
-+ d->updateFilterTimer->start();
-+ return;
-+ }
-+ }
-+}
-+
-+void ImageFilterModel::slotImageChange(const ImageChangeset& changeset)
-+{
-+ Q_D(ImageFilterModel);
-+
-+ if (!d->imageModel || d->imageModel->isEmpty())
-+ {
-+ return;
-+ }
-+
-+ // already scheduled to re-filter?
-+ if (d->updateFilterTimer->isActive())
-+ {
-+ return;
-+ }
-+
-+ // is one of the values affected that we filter or sort by?
-+ DatabaseFields::Set set = changeset.changes();
-+ bool sortAffected = (set & d->sorter.watchFlags());
-+ bool filterAffected = (set & d->filter.watchFlags()) || (set & d->groupFilter.watchFlags());
-+
-+ if (!sortAffected && !filterAffected)
-+ {
-+ return;
-+ }
-+
-+ // is one of our images affected?
-+ bool imageAffected = false;
-+
-+ foreach(const qlonglong& id, changeset.ids())
-+ {
-+ // if one matching image id is found, trigger a refresh
-+ if (d->imageModel->hasImage(id))
-+ {
-+ imageAffected = true;
-+ break;
-+ }
-+ }
-+
-+ if (!imageAffected)
-+ {
-+ return;
-+ }
-+
-+ if (filterAffected)
-+ {
-+ d->updateFilterTimer->start();
-+ }
-+ else
-+ {
-+ invalidate(); // just resort, reuse filter results
-+ }
-+}
-+
-+// -------------------------------------------------------------------------------------------------------
-+
-+NoDuplicatesImageFilterModel::NoDuplicatesImageFilterModel(QObject* parent)
-+ : ImageSortFilterModel(parent)
-+{
-+}
-+
-+bool NoDuplicatesImageFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
-+{
-+ QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
-+
-+ if (index.data(ImageModel::ExtraDataDuplicateCount).toInt() <= 1)
-+ {
-+ return true;
-+ }
-+
-+ QModelIndex previousIndex = sourceModel()->index(source_row - 1, 0, source_parent);
-+
-+ if (!previousIndex.isValid())
-+ {
-+ return true;
-+ }
-+
-+ if (sourceImageModel()->imageId(mapFromDirectSourceToSourceImageModel(index)) == sourceImageModel()->imageId(mapFromDirectSourceToSourceImageModel(previousIndex)))
-+ {
-+ return false;
-+ }
-+ return true;
-+}
-+
-+/*
-+void NoDuplicatesImageFilterModel::setSourceModel(QAbstractItemModel* model)
-+{
-+ if (sourceModel())
-+ {
-+ }
-+
-+ ImageSortFilterModel::setSourceModel(model);
-+
-+ if (sourceModel())
-+ {
-+ connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
-+ this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)));
-+ }
-+}
-+
-+void NoDuplicatesImageFilterModel::slotRowsAboutToBeRemoved(const QModelIndex& parent, int begin, int end)
-+{
-+ bool needInvalidate = false;
-+
-+ for (int i = begin; i<=end; ++i)
-+ {
-+ QModelIndex index = sourceModel()->index(i, 0, parent);
-+
-+ // filtered out by us?
-+ if (!mapFromSource(index).isValid())
-+ {
-+ continue;
-+ }
-+
-+ QModelIndex sourceIndex = mapFromDirectSourceToSourceImageModel(index);
-+ qlonglong id = sourceImageModel()->imageId(sourceIndex);
-+
-+ if (sourceImageModel()->numberOfIndexesForImageId(id) > 1)
-+ {
-+ needInvalidate = true;
-+ }
-+ }
-+}*/
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagefiltermodel.h b/libs/database/models/imagefiltermodel.h
-new file mode 100644
-index 0000000..d131b3e
---- /dev/null
-+++ b/libs/database/models/imagefiltermodel.h
-@@ -0,0 +1,299 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-+ * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-+ * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGEFILTERMODEL_H
-+#define IMAGEFILTERMODEL_H
-+
-+// Local includes
-+
-+#include "dcategorizedsortfilterproxymodel.h"
-+#include "textfilter.h"
-+#include "imagefiltersettings.h"
-+#include "imagemodel.h"
-+#include "imagesortsettings.h"
-+#include "digikam_export.h"
-+
-+namespace Digikam
-+{
-+
-+class ImageChangeset;
-+class ImageFilterModel;
-+class ImageTagChangeset;
-+
-+class DIGIKAM_DATABASE_EXPORT ImageFilterModelPrepareHook
-+{
-+public:
-+
-+ virtual ~ImageFilterModelPrepareHook() {};
-+ virtual void prepare(const QVector<ImageInfo>& infos) = 0;
-+};
-+
-+// -----------------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT ImageSortFilterModel : public DCategorizedSortFilterProxyModel
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ explicit ImageSortFilterModel(QObject* parent = 0);
-+
-+ void setSourceImageModel(ImageModel* model);
-+ ImageModel* sourceImageModel() const;
-+
-+ void setSourceFilterModel(ImageSortFilterModel* model);
-+ ImageSortFilterModel* sourceFilterModel() const;
-+
-+ QModelIndex mapToSourceImageModel(const QModelIndex& index) const;
-+ QModelIndex mapFromSourceImageModel(const QModelIndex& imagemodel_index) const;
-+ QModelIndex mapFromDirectSourceToSourceImageModel(const QModelIndex& sourceModel_index) const;
-+
-+ /// Convenience methods mapped to ImageModel.
-+ /// Mentioned indexes returned come from the source image model.
-+ QList<QModelIndex> mapListToSource(const QList<QModelIndex>& indexes) const;
-+ QList<QModelIndex> mapListFromSource(const QList<QModelIndex>& sourceIndexes) const;
-+
-+ ImageInfo imageInfo(const QModelIndex& index) const;
-+ qlonglong imageId(const QModelIndex& index) const;
-+ QList<ImageInfo> imageInfos(const QList<QModelIndex>& indexes) const;
-+ QList<qlonglong> imageIds(const QList<QModelIndex>& indexes) const;
-+
-+ QModelIndex indexForPath(const QString& filePath) const;
-+ QModelIndex indexForImageInfo(const ImageInfo& info) const;
-+ QModelIndex indexForImageId(qlonglong id) const;
-+
-+ /** Returns a list of all image infos, sorted according to this model.
-+ * If you do not need a sorted list, use ImageModel's imageInfos() method.
-+ */
-+ QList<ImageInfo> imageInfosSorted() const;
-+
-+ /// Returns this, any chained ImageFilterModel, or 0.
-+ virtual ImageFilterModel* imageFilterModel() const;
-+
-+protected:
-+
-+ /// Reimplement if needed. Called only when model shall be set as (direct) sourceModel.
-+ virtual void setDirectSourceImageModel(ImageModel* model);
-+
-+ // made protected
-+ virtual void setSourceModel(QAbstractItemModel* model);
-+
-+protected:
-+
-+ ImageSortFilterModel* m_chainedModel;
-+};
-+
-+// -----------------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT ImageFilterModel : public ImageSortFilterModel
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ enum ImageFilterModelRoles
-+ {
-+ /// Returns the current categorization mode
-+ CategorizationModeRole = ImageModel::FilterModelRoles + 1,
-+ /// Returns the current sort order
-+ SortOrderRole = ImageModel::FilterModelRoles + 2,
-+ // / Returns the number of items in the index' category
-+ //CategoryCountRole = ImageModel::FilterModelRoles + 3,
-+ /// Returns the id of the PAlbum of the index which is used for category
-+ CategoryAlbumIdRole = ImageModel::FilterModelRoles + 3,
-+ /// Returns the format of the index which is used for category
-+ CategoryFormatRole = ImageModel::FilterModelRoles + 4,
-+ /// Returns true if the given image is a group leader, and the group is opened
-+ GroupIsOpenRole = ImageModel::FilterModelRoles + 5,
-+ ImageFilterModelPointerRole = ImageModel::FilterModelRoles + 50
-+ };
-+
-+public:
-+
-+ explicit ImageFilterModel(QObject* parent = 0);
-+ ~ImageFilterModel();
-+
-+ /** Add a hook to get added images for preparation tasks before they are added in the model */
-+ void addPrepareHook(ImageFilterModelPrepareHook* hook);
-+ void removePrepareHook(ImageFilterModelPrepareHook* hook);
-+
-+ /** Returns a set of DatabaseFields suggested to set as watch flags on the source ImageModel.
-+ * The contained flags will be those that this model can sort or filter by. */
-+ DatabaseFields::Set suggestedWatchFlags() const;
-+
-+ ImageFilterSettings imageFilterSettings() const;
-+ VersionImageFilterSettings versionImageFilterSettings() const;
-+ GroupImageFilterSettings groupImageFilterSettings() const;
-+ ImageSortSettings imageSortSettings() const;
-+
-+ // group is identified by the id of its group leader
-+ bool isGroupOpen(qlonglong group) const;
-+ bool isAllGroupsOpen() const;
-+
-+ /// Enables sending imageInfosAdded and imageInfosAboutToBeRemoved
-+ void setSendImageInfoSignals(bool sendSignals);
-+
-+ virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-+ virtual ImageFilterModel* imageFilterModel() const;
-+
-+public Q_SLOTS:
-+
-+ /** Changes the current version image filter settings and refilters. */
-+ void setVersionImageFilterSettings(const VersionImageFilterSettings& settings);
-+
-+ /** Changes the current version image filter settings and refilters. */
-+ void setGroupImageFilterSettings(const GroupImageFilterSettings& settings);
-+
-+ /** Adjust the current ImageFilterSettings.
-+ * Equivalent to retrieving the current filter settings, adjusting the parameter
-+ * and calling setImageFilterSettings.
-+ * Provided for convenience.
-+ * It is encouraged to use setImageFilterSettings if you change more than one
-+ * parameter at a time.
-+ */
-+ void setDayFilter(const QList<QDateTime>& days);
-+ void setTagFilter(const QList<int>& includedTags, const QList<int>& excludedTags,
-+ ImageFilterSettings::MatchingCondition matchingCond, bool showUnTagged,
-+ const QList<int>& clTagIds, const QList<int>& plTagIds);
-+ void setRatingFilter(int rating, ImageFilterSettings::RatingCondition ratingCond, bool isUnratedExcluded);
-+ void setMimeTypeFilter(int mimeTypeFilter);
-+ void setGeolocationFilter(const ImageFilterSettings::GeolocationCondition& condition);
-+ void setTextFilter(const SearchTextFilterSettings& settings);
-+
-+ void setCategorizationMode(ImageSortSettings::CategorizationMode mode);
-+ void setCategorizationSortOrder(ImageSortSettings::SortOrder order);
-+ void setSortRole(ImageSortSettings::SortRole role);
-+ void setSortOrder(ImageSortSettings::SortOrder order);
-+ void setStringTypeNatural(bool natural);
-+ void setUrlWhitelist(const QList<QUrl> urlList, const QString& id);
-+ void setIdWhitelist(const QList<qlonglong>& idList, const QString& id);
-+
-+ void setVersionManagerSettings(const VersionManagerSettings& settings);
-+ void setExceptionList(const QList<qlonglong>& idlist, const QString& id);
-+
-+ void setGroupOpen(qlonglong group, bool open);
-+ void toggleGroupOpen(qlonglong group);
-+ void setAllGroupsOpen(bool open);
-+
-+ /** Changes the current image filter settings and refilters. */
-+ virtual void setImageFilterSettings(const ImageFilterSettings& settings);
-+
-+ /** Changes the current image sort settings and resorts. */
-+ virtual void setImageSortSettings(const ImageSortSettings& settings);
-+
-+Q_SIGNALS:
-+
-+ /// Signals that the set filter matches at least one index
-+ void filterMatches(bool matches);
-+
-+ /** Signals that the set text filter matches at least one entry.
-+ If no text filter is set, this signal is emitted
-+ with 'false' when filterMatches() is emitted.
-+ */
-+ void filterMatchesForText(bool matchesByText);
-+
-+ /** Emitted when the filter settings have been changed
-+ (the model may not yet have been updated)
-+ */
-+ void filterSettingsChanged(const ImageFilterSettings& settings);
-+
-+ /** These signals need to be explicitly enabled with setSendImageInfoSignals()
-+ */
-+ void imageInfosAdded(const QList<ImageInfo>& infos);
-+ void imageInfosAboutToBeRemoved(const QList<ImageInfo>& infos);
-+
-+public:
-+
-+ // Declared as public because of use in sub-classes.
-+ class ImageFilterModelPrivate;
-+
-+protected:
-+
-+ ImageFilterModelPrivate* const d_ptr;
-+
-+protected:
-+
-+ ImageFilterModel(ImageFilterModelPrivate& dd, QObject* parent);
-+
-+ virtual void setDirectSourceImageModel(ImageModel* model);
-+
-+ virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
-+
-+ virtual int compareCategories(const QModelIndex& left, const QModelIndex& right) const;
-+ virtual bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const;
-+ //virtual int categoryCount(const ImageInfo& info) const;
-+
-+ /** Reimplement to customize category sorting,
-+ * Return negative if category of left < category right,
-+ * Return 0 if left and right are in the same category, else return positive.
-+ */
-+ virtual int compareInfosCategories(const ImageInfo& left, const ImageInfo& right) const;
-+
-+ /** Reimplement to customize sorting. Do not take categories into account here.
-+ */
-+ virtual bool infosLessThan(const ImageInfo& left, const ImageInfo& right) const;
-+
-+ /** Returns a unique identifier for the category if info. The string need not be for user display.
-+ */
-+ virtual QString categoryIdentifier(const ImageInfo& info) const;
-+
-+protected Q_SLOTS:
-+
-+ void slotModelReset();
-+ void slotUpdateFilter();
-+
-+ void slotImageTagChange(const ImageTagChangeset& changeset);
-+ void slotImageChange(const ImageChangeset& changeset);
-+
-+ void slotRowsInserted(const QModelIndex& parent, int start, int end);
-+ void slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
-+
-+private:
-+
-+ Q_DECLARE_PRIVATE(ImageFilterModel)
-+};
-+
-+// -----------------------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT NoDuplicatesImageFilterModel : public ImageSortFilterModel
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ explicit NoDuplicatesImageFilterModel(QObject* parent = 0);
-+
-+protected:
-+
-+ virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
-+};
-+
-+} // namespace Digikam
-+
-+Q_DECLARE_METATYPE(Digikam::ImageFilterModel*)
-+
-+#endif // IMAGEMODEL_H
-diff --git a/libs/database/models/imagefiltermodelpriv.cpp b/libs/database/models/imagefiltermodelpriv.cpp
-new file mode 100644
-index 0000000..07d9e79
---- /dev/null
-+++ b/libs/database/models/imagefiltermodelpriv.cpp
-@@ -0,0 +1,258 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-+ * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-+ * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagefiltermodelpriv.h"
-+
-+// Local includes
-+
-+#include "digikam_debug.h"
-+#include "imagefiltermodelthreads.h"
-+
-+namespace Digikam
-+{
-+
-+ImageFilterModel::ImageFilterModelPrivate::ImageFilterModelPrivate()
-+{
-+ imageModel = 0;
-+ version = 0;
-+ lastDiscardVersion = 0;
-+ sentOut = 0;
-+ sentOutForReAdd = 0;
-+ updateFilterTimer = 0;
-+ needPrepare = false;
-+ needPrepareComments = false;
-+ needPrepareTags = false;
-+ needPrepareGroups = false;
-+ preparer = 0;
-+ filterer = 0;
-+ hasOneMatch = false;
-+ hasOneMatchForText = false;
-+
-+ setupWorkers();
-+}
-+
-+ImageFilterModel::ImageFilterModelPrivate::~ImageFilterModelPrivate()
-+{
-+ // facilitate thread stopping
-+ ++version;
-+ preparer->deactivate();
-+ filterer->deactivate();
-+ delete preparer;
-+ delete filterer;
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::init(ImageFilterModel* _q)
-+{
-+ q = _q;
-+
-+ updateFilterTimer = new QTimer(this);
-+ updateFilterTimer->setSingleShot(true);
-+ updateFilterTimer->setInterval(250);
-+
-+ connect(updateFilterTimer, SIGNAL(timeout()),
-+ q, SLOT(slotUpdateFilter()));
-+
-+ // inter-thread redirection
-+ qRegisterMetaType<ImageFilterModelTodoPackage>("ImageFilterModelTodoPackage");
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::preprocessInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ infosToProcess(infos, extraValues, true);
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::processAddedInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ // These have already been added, we just process them afterwards
-+ infosToProcess(infos, extraValues, false);
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::setupWorkers()
-+{
-+ preparer = new ImageFilterModelPreparer(this);
-+ filterer = new ImageFilterModelFilterer(this);
-+
-+ // A package in constructed in infosToProcess.
-+ // Normal flow is infosToProcess -> preparer::process -> filterer::process -> packageFinished.
-+ // If no preparation is needed, the first step is skipped.
-+ // If filter version changes, both will discard old package and send them to packageDiscarded.
-+
-+ connect(this, SIGNAL(packageToPrepare(ImageFilterModelTodoPackage)),
-+ preparer, SLOT(process(ImageFilterModelTodoPackage)));
-+
-+ connect(this, SIGNAL(packageToFilter(ImageFilterModelTodoPackage)),
-+ filterer, SLOT(process(ImageFilterModelTodoPackage)));
-+
-+ connect(preparer, SIGNAL(processed(ImageFilterModelTodoPackage)),
-+ filterer, SLOT(process(ImageFilterModelTodoPackage)));
-+
-+ connect(filterer, SIGNAL(processed(ImageFilterModelTodoPackage)),
-+ this, SLOT(packageFinished(ImageFilterModelTodoPackage)));
-+
-+ connect(preparer, SIGNAL(discarded(ImageFilterModelTodoPackage)),
-+ this, SLOT(packageDiscarded(ImageFilterModelTodoPackage)));
-+
-+ connect(filterer, SIGNAL(discarded(ImageFilterModelTodoPackage)),
-+ this, SLOT(packageDiscarded(ImageFilterModelTodoPackage)));
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::infosToProcess(const QList<ImageInfo>& infos)
-+{
-+ infosToProcess(infos, QList<QVariant>(), false);
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::infosToProcess(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues, bool forReAdd)
-+{
-+ if (infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ filterer->schedule();
-+
-+ if (needPrepare)
-+ {
-+ preparer->schedule();
-+ }
-+
-+ Q_ASSERT(extraValues.isEmpty() || infos.size() == extraValues.size());
-+
-+ // prepare and filter in chunks
-+ const int size = infos.size();
-+ const int maxChunkSize = needPrepare ? PrepareChunkSize : FilterChunkSize;
-+ const bool hasExtraValues = !extraValues.isEmpty();
-+ QList<ImageInfo>::const_iterator it = infos.constBegin(), end;
-+ QList<QVariant>::const_iterator xit = extraValues.constBegin(), xend;
-+ int index = 0;
-+ QVector<ImageInfo> infoVector;
-+ QVector<QVariant> extraValueVector;
-+
-+ while (it != infos.constEnd())
-+ {
-+ const int chunkSize = qMin(maxChunkSize, size - index);
-+ infoVector.resize(chunkSize);
-+ end = it + chunkSize;
-+ qCopy(it, end, infoVector.begin());
-+
-+ if (hasExtraValues)
-+ {
-+ extraValueVector.resize(chunkSize);
-+ xend = xit + chunkSize;
-+ qCopy(xit, xend, extraValueVector.begin());
-+ xit = xend;
-+ }
-+
-+ it = end;
-+ index += chunkSize;
-+
-+ ++sentOut;
-+
-+ if (forReAdd)
-+ {
-+ ++sentOutForReAdd;
-+ }
-+
-+ if (needPrepare)
-+ {
-+ emit packageToPrepare(ImageFilterModelTodoPackage(infoVector, extraValueVector, version, forReAdd));
-+ }
-+ else
-+ {
-+ emit packageToFilter(ImageFilterModelTodoPackage(infoVector, extraValueVector, version, forReAdd));
-+ }
-+ }
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::packageFinished(const ImageFilterModelTodoPackage& package)
-+{
-+ // check if it got discarded on the journey
-+ if (package.version != version)
-+ {
-+ packageDiscarded(package);
-+ return;
-+ }
-+
-+ // incorporate result
-+ QHash<qlonglong, bool>::const_iterator it = package.filterResults.constBegin();
-+
-+ for (; it != package.filterResults.constEnd(); ++it)
-+ {
-+ filterResults.insert(it.key(), it.value());
-+ }
-+
-+ // re-add if necessary
-+ if (package.isForReAdd)
-+ {
-+ emit reAddImageInfos(package.infos.toList(), package.extraValues.toList());
-+
-+ if (sentOutForReAdd == 1) // last package
-+ {
-+ emit reAddingFinished();
-+ }
-+ }
-+
-+ // decrement counters
-+ --sentOut;
-+
-+ if (package.isForReAdd)
-+ {
-+ --sentOutForReAdd;
-+ }
-+
-+ // If all packages have returned, filtered and readded, and no more are expected,
-+ // and there is need to tell the filter result to the view, do that
-+ if (sentOut == 0 && sentOutForReAdd == 0 && !imageModel->isRefreshing())
-+ {
-+ q->invalidate(); // use invalidate, not invalidateFilter only. Sorting may have changed as well.
-+ emit (q->filterMatches(hasOneMatch));
-+ emit (q->filterMatchesForText(hasOneMatchForText));
-+ filterer->deactivate();
-+ preparer->deactivate();
-+ }
-+}
-+
-+void ImageFilterModel::ImageFilterModelPrivate::packageDiscarded(const ImageFilterModelTodoPackage& package)
-+{
-+ // Either, the model was reset, or the filter changed
-+ // In the former case throw all away, in the latter case, recycle
-+ if (package.version > lastDiscardVersion)
-+ {
-+ // Recycle packages: Send again with current version
-+ // Do not increment sentOut or sentOutForReAdd here: it was not decremented!
-+
-+ if (needPrepare)
-+ {
-+ emit packageToPrepare(ImageFilterModelTodoPackage(package.infos, package.extraValues, version, package.isForReAdd));
-+ }
-+ else
-+ {
-+ emit packageToFilter(ImageFilterModelTodoPackage(package.infos, package.extraValues, version, package.isForReAdd));
-+ }
-+ }
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagefiltermodelpriv.h b/libs/database/models/imagefiltermodelpriv.h
-new file mode 100644
-index 0000000..a9e3f22
---- /dev/null
-+++ b/libs/database/models/imagefiltermodelpriv.h
-@@ -0,0 +1,159 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-11
-+ * Description : Qt item model for database entries - private shared header
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGEFILTERMODELPRIV_H
-+#define IMAGEFILTERMODELPRIV_H
-+
-+// Qt includes
-+
-+#include <QHash>
-+#include <QMutex>
-+#include <QMutexLocker>
-+#include <QSet>
-+#include <QThread>
-+#include <QTimer>
-+#include <QWaitCondition>
-+
-+// Local includes
-+
-+#include "imageinfo.h"
-+#include "imagefiltermodel.h"
-+
-+#include "digikam_export.h"
-+// Yes, we need the EXPORT macro in a private header because
-+// this private header is shared across binary objects.
-+// This does NOT make this classes here any more public!
-+
-+namespace Digikam
-+{
-+
-+const int PrepareChunkSize = 101;
-+const int FilterChunkSize = 2001;
-+
-+class ImageFilterModelTodoPackage
-+{
-+public:
-+
-+ ImageFilterModelTodoPackage()
-+ : version(0), isForReAdd(false)
-+ {
-+ }
-+
-+ ImageFilterModelTodoPackage(const QVector<ImageInfo>& infos, const QVector<QVariant>& extraValues, int version, bool isForReAdd)
-+ : infos(infos), extraValues(extraValues), version(version), isForReAdd(isForReAdd)
-+ {
-+ }
-+
-+ QVector<ImageInfo> infos;
-+ QVector<QVariant> extraValues;
-+ unsigned int version;
-+ bool isForReAdd;
-+ QHash<qlonglong, bool> filterResults;
-+};
-+
-+// ------------------------------------------------------------------------------------------------
-+
-+class ImageFilterModelPreparer;
-+class ImageFilterModelFilterer;
-+
-+class DIGIKAM_DATABASE_EXPORT ImageFilterModel::ImageFilterModelPrivate : public QObject
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ ImageFilterModelPrivate();
-+ ~ImageFilterModelPrivate();
-+
-+ void init(ImageFilterModel* q);
-+ void setupWorkers();
-+ void infosToProcess(const QList<ImageInfo>& infos);
-+ void infosToProcess(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues, bool forReAdd = true);
-+
-+public:
-+
-+ ImageFilterModel* q;
-+
-+ ImageModel* imageModel;
-+
-+ ImageFilterSettings filter;
-+ ImageSortSettings sorter;
-+ VersionImageFilterSettings versionFilter;
-+ GroupImageFilterSettings groupFilter;
-+
-+ volatile unsigned int version;
-+ unsigned int lastDiscardVersion;
-+ unsigned int lastFilteredVersion;
-+ int sentOut;
-+ int sentOutForReAdd;
-+
-+ QTimer* updateFilterTimer;
-+
-+ bool needPrepare;
-+ bool needPrepareComments;
-+ bool needPrepareTags;
-+ bool needPrepareGroups;
-+
-+ QMutex mutex;
-+ ImageFilterSettings filterCopy;
-+ VersionImageFilterSettings versionFilterCopy;
-+ GroupImageFilterSettings groupFilterCopy;
-+ ImageFilterModelPreparer* preparer;
-+ ImageFilterModelFilterer* filterer;
-+
-+ QHash<qlonglong, bool> filterResults;
-+ bool hasOneMatch;
-+ bool hasOneMatchForText;
-+
-+ QList<ImageFilterModelPrepareHook*> prepareHooks;
-+
-+/*
-+ QHash<int, QSet<qlonglong> > categoryCountHashInt;
-+ QHash<QString, QSet<qlonglong> > categoryCountHashString;
-+
-+public:
-+
-+ void cacheCategoryCount(int id, qlonglong imageid) const
-+ { const_cast<ImageFilterModelPrivate*>(this)->categoryCountHashInt[id].insert(imageid); }
-+ void cacheCategoryCount(const QString& id, qlonglong imageid) const
-+ { const_cast<ImageFilterModelPrivate*>(this)->categoryCountHashString[id].insert(imageid); }
-+*/
-+
-+public Q_SLOTS:
-+
-+ void preprocessInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void processAddedInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void packageFinished(const ImageFilterModelTodoPackage& package);
-+ void packageDiscarded(const ImageFilterModelTodoPackage& package);
-+
-+Q_SIGNALS:
-+
-+ void packageToPrepare(const ImageFilterModelTodoPackage& package);
-+ void packageToFilter(const ImageFilterModelTodoPackage& package);
-+ void reAddImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void reAddingFinished();
-+};
-+
-+} // namespace Digikam
-+
-+#endif // IMAGEFILTERMODELPRIV_H
-diff --git a/libs/database/models/imagefiltermodelthreads.cpp b/libs/database/models/imagefiltermodelthreads.cpp
-new file mode 100644
-index 0000000..aa5c462
---- /dev/null
-+++ b/libs/database/models/imagefiltermodelthreads.cpp
-@@ -0,0 +1,40 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-+ * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-+ * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagefiltermodel.h"
-+#include "imagefiltermodelpriv.h"
-+#include "imagefiltermodelthreads.h"
-+
-+namespace Digikam
-+{
-+
-+ImageFilterModelWorker::ImageFilterModelWorker(ImageFilterModel::ImageFilterModelPrivate* const d)
-+ : d(d)
-+{
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagefiltermodelthreads.h b/libs/database/models/imagefiltermodelthreads.h
-new file mode 100644
-index 0000000..83fa987
---- /dev/null
-+++ b/libs/database/models/imagefiltermodelthreads.h
-@@ -0,0 +1,100 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-11
-+ * Description : Qt item model for database entries - private header
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGEFILTERMODELTHREADS_H
-+#define IMAGEFILTERMODELTHREADS_H
-+
-+// Qt includes
-+
-+#include <QThread>
-+
-+// Local includes
-+
-+#include "digikam_export.h"
-+#include "workerobject.h"
-+
-+namespace Digikam
-+{
-+
-+class DIGIKAM_DATABASE_EXPORT ImageFilterModelWorker : public WorkerObject
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ explicit ImageFilterModelWorker(ImageFilterModel::ImageFilterModelPrivate* const d);
-+
-+ bool checkVersion(const ImageFilterModelTodoPackage& package)
-+ {
-+ return d->version == package.version;
-+ }
-+
-+public Q_SLOTS:
-+
-+ virtual void process(ImageFilterModelTodoPackage package) = 0;
-+
-+Q_SIGNALS:
-+
-+ void processed(const ImageFilterModelTodoPackage& package);
-+ void discarded(const ImageFilterModelTodoPackage& package);
-+
-+protected:
-+
-+ ImageFilterModel::ImageFilterModelPrivate* d;
-+};
-+
-+// -----------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT ImageFilterModelPreparer : public ImageFilterModelWorker
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ explicit ImageFilterModelPreparer(ImageFilterModel::ImageFilterModelPrivate* const d)
-+ : ImageFilterModelWorker(d)
-+ {
-+ }
-+
-+ void process(ImageFilterModelTodoPackage package);
-+};
-+
-+// ----------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT ImageFilterModelFilterer : public ImageFilterModelWorker
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ explicit ImageFilterModelFilterer(ImageFilterModel::ImageFilterModelPrivate* const d)
-+ : ImageFilterModelWorker(d)
-+ {
-+ }
-+
-+ void process(ImageFilterModelTodoPackage package);
-+};
-+
-+} // namespace Digikam
-+
-+#endif // IMAGEFILTERMODELTHREADS_H
-diff --git a/libs/database/models/imagefiltersettings.cpp b/libs/database/models/imagefiltersettings.cpp
-new file mode 100644
-index 0000000..b61e7f9
---- /dev/null
-+++ b/libs/database/models/imagefiltersettings.cpp
-@@ -0,0 +1,952 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Filter values for use with ImageFilterModel
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-+ * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-+ * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagefiltersettings.h"
-+
-+// C++ includes
-+
-+#include <cmath>
-+
-+// Qt includes
-+
-+#include <QDateTime>
-+
-+// Local includes
-+
-+#include "digikam_debug.h"
-+#include "coredbfields.h"
-+#include "digikam_globals.h"
-+#include "imageinfo.h"
-+#include "tagscache.h"
-+#include "versionmanagersettings.h"
-+
-+namespace Digikam
-+{
-+
-+ImageFilterSettings::ImageFilterSettings()
-+{
-+ m_untaggedFilter = false;
-+ m_isUnratedExcluded = false;
-+ m_ratingFilter = 0;
-+ m_mimeTypeFilter = MimeFilter::AllFiles;
-+ m_ratingCond = GreaterEqualCondition;
-+ m_matchingCond = OrCondition;
-+ m_geolocationCondition = GeolocationNoFilter;
-+}
-+
-+DatabaseFields::Set ImageFilterSettings::watchFlags() const
-+{
-+ DatabaseFields::Set set;
-+
-+ if (isFilteringByDay())
-+ {
-+ set |= DatabaseFields::CreationDate;
-+ }
-+
-+ if (isFilteringByText())
-+ {
-+ set |= DatabaseFields::Name;
-+ set |= DatabaseFields::Comment;
-+ }
-+
-+ if (isFilteringByRating())
-+ {
-+ set |= DatabaseFields::Rating;
-+ }
-+
-+ if (isFilteringByTypeMime())
-+ {
-+ set |= DatabaseFields::Category;
-+ set |= DatabaseFields::Format;
-+ }
-+
-+ if (isFilteringByGeolocation())
-+ {
-+ set |= DatabaseFields::ImagePositionsAll;
-+ }
-+
-+ if (isFilteringByColorLabels())
-+ {
-+ set |= DatabaseFields::ColorLabel;
-+ }
-+
-+ if (isFilteringByPickLabels())
-+ {
-+ set |= DatabaseFields::PickLabel;
-+ }
-+
-+ return set;
-+}
-+
-+bool ImageFilterSettings::isFilteringByDay() const
-+{
-+ if (!m_dayFilter.isEmpty())
-+ {
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool ImageFilterSettings::isFilteringByTags() const
-+{
-+ if (!m_includeTagFilter.isEmpty() || !m_excludeTagFilter.isEmpty() || m_untaggedFilter)
-+ {
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool ImageFilterSettings::isFilteringByColorLabels() const
-+{
-+ if (!m_colorLabelTagFilter.isEmpty())
-+ {
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool ImageFilterSettings::isFilteringByPickLabels() const
-+{
-+ if (!m_pickLabelTagFilter.isEmpty())
-+ {
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool ImageFilterSettings::isFilteringByText() const
-+{
-+ if (!m_textFilterSettings.text.isEmpty())
-+ {
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool ImageFilterSettings::isFilteringByTypeMime() const
-+{
-+ if (m_mimeTypeFilter != MimeFilter::AllFiles)
-+ {
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool ImageFilterSettings::isFilteringByGeolocation() const
-+{
-+ return (m_geolocationCondition != GeolocationNoFilter);
-+}
-+
-+bool ImageFilterSettings::isFilteringByRating() const
-+{
-+ if (m_ratingFilter != 0 || m_ratingCond != GreaterEqualCondition || m_isUnratedExcluded)
-+ {
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool ImageFilterSettings::isFilteringInternally() const
-+{
-+ return (isFiltering() || !m_urlWhitelists.isEmpty() || !m_idWhitelists.isEmpty());
-+}
-+
-+bool ImageFilterSettings::isFiltering() const
-+{
-+ return isFilteringByDay() ||
-+ isFilteringByTags() ||
-+ isFilteringByText() ||
-+ isFilteringByRating() ||
-+ isFilteringByTypeMime() ||
-+ isFilteringByColorLabels() ||
-+ isFilteringByPickLabels() ||
-+ isFilteringByGeolocation();
-+}
-+
-+void ImageFilterSettings::setDayFilter(const QList<QDateTime>& days)
-+{
-+ m_dayFilter.clear();
-+
-+ for (QList<QDateTime>::const_iterator it = days.constBegin(); it != days.constEnd(); ++it)
-+ {
-+ m_dayFilter.insert(*it, true);
-+ }
-+}
-+
-+void ImageFilterSettings::setTagFilter(const QList<int>& includedTags,
-+ const QList<int>& excludedTags,
-+ MatchingCondition matchingCondition,
-+ bool showUnTagged,
-+ const QList<int>& clTagIds,
-+ const QList<int>& plTagIds)
-+{
-+ m_includeTagFilter = includedTags;
-+ m_excludeTagFilter = excludedTags;
-+ m_matchingCond = matchingCondition;
-+ m_untaggedFilter = showUnTagged;
-+ m_colorLabelTagFilter = clTagIds;
-+ m_pickLabelTagFilter = plTagIds;
-+}
-+
-+void ImageFilterSettings::setRatingFilter(int rating, RatingCondition ratingCondition, bool isUnratedExcluded)
-+{
-+ m_ratingFilter = rating;
-+ m_ratingCond = ratingCondition;
-+ m_isUnratedExcluded = isUnratedExcluded;
-+}
-+
-+void ImageFilterSettings::setMimeTypeFilter(int mime)
-+{
-+ m_mimeTypeFilter = (MimeFilter::TypeMimeFilter)mime;
-+}
-+
-+void ImageFilterSettings::setGeolocationFilter(const GeolocationCondition& condition)
-+{
-+ m_geolocationCondition = condition;
-+}
-+
-+void ImageFilterSettings::setTextFilter(const SearchTextFilterSettings& settings)
-+{
-+ m_textFilterSettings = settings;
-+}
-+
-+void ImageFilterSettings::setTagNames(const QHash<int, QString>& hash)
-+{
-+ m_tagNameHash = hash;
-+}
-+
-+void ImageFilterSettings::setAlbumNames(const QHash<int, QString>& hash)
-+{
-+ m_albumNameHash = hash;
-+}
-+
-+void ImageFilterSettings::setUrlWhitelist(const QList<QUrl>& urlList, const QString& id)
-+{
-+ if (urlList.isEmpty())
-+ {
-+ m_urlWhitelists.remove(id);
-+ }
-+ else
-+ {
-+ m_urlWhitelists.insert(id, urlList);
-+ }
-+}
-+
-+void ImageFilterSettings::setIdWhitelist(const QList<qlonglong>& idList, const QString& id)
-+{
-+ if (idList.isEmpty())
-+ {
-+ m_idWhitelists.remove(id);
-+ }
-+ else
-+ {
-+ m_idWhitelists.insert(id, idList);
-+ }
-+}
-+
-+template <class ContainerA, class ContainerB>
-+bool containsAnyOf(const ContainerA& listA, const ContainerB& listB)
-+{
-+ foreach (const typename ContainerA::value_type& a, listA)
-+ {
-+ if (listB.contains(a))
-+ {
-+ return true;
-+ }
-+ }
-+ return false;
-+}
-+
-+template <class ContainerA, typename Value, class ContainerB>
-+bool containsNoneOfExcept(const ContainerA& list, const ContainerB& noneOfList, const Value& exception)
-+{
-+ foreach (const typename ContainerB::value_type& n, noneOfList)
-+ {
-+ if (n != exception && list.contains(n))
-+ {
-+ return false;
-+ }
-+ }
-+ return true;
-+}
-+
-+bool ImageFilterSettings::matches(const ImageInfo& info, bool* const foundText) const
-+{
-+ if (foundText)
-+ {
-+ *foundText = false;
-+ }
-+
-+ if (!isFilteringInternally())
-+ {
-+ return true;
-+ }
-+
-+ bool match = false;
-+
-+ if (!m_includeTagFilter.isEmpty() || !m_excludeTagFilter.isEmpty())
-+ {
-+ QList<int> tagIds = info.tagIds();
-+ QList<int>::const_iterator it;
-+
-+ match = m_includeTagFilter.isEmpty();
-+
-+ if (m_matchingCond == OrCondition)
-+ {
-+ for (it = m_includeTagFilter.begin(); it != m_includeTagFilter.end(); ++it)
-+ {
-+ if (tagIds.contains(*it))
-+ {
-+ match = true;
-+ break;
-+ }
-+ }
-+
-+ match |= (m_untaggedFilter && tagIds.isEmpty());
-+ }
-+ else // AND matching condition...
-+ {
-+ // m_untaggedFilter and non-empty tag filter, combined with AND, is logically no match
-+ if (!m_untaggedFilter)
-+ {
-+ for (it = m_includeTagFilter.begin(); it != m_includeTagFilter.end(); ++it)
-+ {
-+ if (!tagIds.contains(*it))
-+ {
-+ break;
-+ }
-+ }
-+
-+ if (it == m_includeTagFilter.end())
-+ {
-+ match = true;
-+ }
-+ }
-+ }
-+
-+ for (it = m_excludeTagFilter.begin(); it != m_excludeTagFilter.end(); ++it)
-+ {
-+ if (tagIds.contains(*it))
-+ {
-+ match = false;
-+ break;
-+ }
-+ }
-+ }
-+ else if (m_untaggedFilter)
-+ {
-+ match = !TagsCache::instance()->containsPublicTags(info.tagIds());
-+ }
-+ else
-+ {
-+ match = true;
-+ }
-+
-+ //-- Filter by pick labels ------------------------------------------------
-+
-+ if (!m_pickLabelTagFilter.isEmpty())
-+ {
-+ QList<int> tagIds = info.tagIds();
-+ bool matchPL = false;
-+
-+ if (containsAnyOf(m_pickLabelTagFilter, tagIds))
-+ {
-+ matchPL = true;
-+ }
-+ else if (!matchPL)
-+ {
-+ int noPickLabelTagId = TagsCache::instance()->tagForPickLabel(NoPickLabel);
-+
-+ if (m_pickLabelTagFilter.contains(noPickLabelTagId))
-+ {
-+ // Searching for "has no ColorLabel" requires special handling:
-+ // Scan that the tag ids contains none of the ColorLabel tags, except maybe the NoColorLabel tag
-+ matchPL = containsNoneOfExcept(tagIds, TagsCache::instance()->pickLabelTags(), noPickLabelTagId);
-+ }
-+ }
-+
-+ match &= matchPL;
-+ }
-+
-+ //-- Filter by color labels ------------------------------------------------
-+
-+ if (!m_colorLabelTagFilter.isEmpty())
-+ {
-+ QList<int> tagIds = info.tagIds();
-+ bool matchCL = false;
-+
-+ if (containsAnyOf(m_colorLabelTagFilter, tagIds))
-+ {
-+ matchCL = true;
-+ }
-+ else if (!matchCL)
-+ {
-+ int noColorLabelTagId = TagsCache::instance()->tagForColorLabel(NoColorLabel);
-+
-+ if (m_colorLabelTagFilter.contains(noColorLabelTagId))
-+ {
-+ // Searching for "has no ColorLabel" requires special handling:
-+ // Scan that the tag ids contains none of the ColorLabel tags, except maybe the NoColorLabel tag
-+ matchCL = containsNoneOfExcept(tagIds, TagsCache::instance()->colorLabelTags(), noColorLabelTagId);
-+ }
-+ }
-+
-+ match &= matchCL;
-+ }
-+
-+ //-- Filter by date -----------------------------------------------------------
-+
-+ if (!m_dayFilter.isEmpty())
-+ {
-+ match &= m_dayFilter.contains(QDateTime(info.dateTime().date(), QTime()));
-+ }
-+
-+ //-- Filter by rating ---------------------------------------------------------
-+
-+ if (m_ratingFilter >= 0)
-+ {
-+ // for now we treat -1 (no rating) just like a rating of 0.
-+ int rating = info.rating();
-+
-+ if (rating == -1)
-+ {
-+ rating = 0;
-+ }
-+
-+ if(m_isUnratedExcluded && rating == 0)
-+ {
-+ match = false;
-+ }
-+ else
-+ {
-+ if (m_ratingCond == GreaterEqualCondition)
-+ {
-+ // If the rating is not >=, i.e it is <, then it does not match.
-+ if (rating < m_ratingFilter)
-+ {
-+ match = false;
-+ }
-+ }
-+ else if (m_ratingCond == EqualCondition)
-+ {
-+ // If the rating is not =, i.e it is !=, then it does not match.
-+ if (rating != m_ratingFilter)
-+ {
-+ match = false;
-+ }
-+ }
-+ else
-+ {
-+ // If the rating is not <=, i.e it is >, then it does not match.
-+ if (rating > m_ratingFilter)
-+ {
-+ match = false;
-+ }
-+ }
-+ }
-+ }
-+
-+ // -- Filter by mime type -----------------------------------------------------
-+
-+ switch (m_mimeTypeFilter)
-+ {
-+ // info.format is a standardized string: Only one possibility per mime type
-+ case MimeFilter::ImageFiles:
-+ {
-+ if (info.category() != DatabaseItem::Image)
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::JPGFiles:
-+ {
-+ if (info.format() != QLatin1String("JPG"))
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::PNGFiles:
-+ {
-+ if (info.format() != QLatin1String("PNG"))
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::TIFFiles:
-+ {
-+ if (info.format() != QLatin1String("TIFF"))
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::DNGFiles:
-+ {
-+ if (info.format() != QLatin1String("RAW-DNG"))
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::NoRAWFiles:
-+ {
-+ if (info.format().startsWith(QLatin1String("RAW")))
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::RAWFiles:
-+ {
-+ if (!info.format().startsWith(QLatin1String("RAW")))
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::MoviesFiles:
-+ {
-+ if (info.category() != DatabaseItem::Video)
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::AudioFiles:
-+ {
-+ if (info.category() != DatabaseItem::Audio)
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ case MimeFilter::RasterFiles:
-+ {
-+ if (info.format() != QLatin1String("PSD") && // Adobe Photoshop Document
-+ info.format() != QLatin1String("PSB") && // Adobe Photoshop Big
-+ info.format() != QLatin1String("XCF") && // Gimp
-+ info.format() != QLatin1String("KRA") && // Krita
-+ info.format() != QLatin1String("ORA") // Open Raster
-+ )
-+ {
-+ match = false;
-+ }
-+
-+ break;
-+ }
-+ default:
-+ {
-+ // All Files: do nothing...
-+ break;
-+ }
-+ }
-+
-+ //-- Filter by geolocation ----------------------------------------------------
-+
-+ if (m_geolocationCondition!=GeolocationNoFilter)
-+ {
-+ if (m_geolocationCondition==GeolocationNoCoordinates)
-+ {
-+ if (info.hasCoordinates())
-+ {
-+ match = false;
-+ }
-+ }
-+ else if (m_geolocationCondition==GeolocationHasCoordinates)
-+ {
-+ if (!info.hasCoordinates())
-+ {
-+ match = false;
-+ }
-+ }
-+ }
-+
-+ //-- Filter by text -----------------------------------------------------------
-+
-+ if (!m_textFilterSettings.text.isEmpty())
-+ {
-+ bool textMatch = false;
-+
-+ // Image name
-+ if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageName &&
-+ info.name().contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-+ {
-+ textMatch = true;
-+ }
-+
-+ // Image title
-+ if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageTitle &&
-+ info.title().contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-+ {
-+ textMatch = true;
-+ }
-+
-+ // Image comment
-+ if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageComment &&
-+ info.comment().contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-+ {
-+ textMatch = true;
-+ }
-+
-+ // Tag names
-+ foreach(int id, info.tagIds())
-+ {
-+ if (m_textFilterSettings.textFields & SearchTextFilterSettings::TagName &&
-+ m_tagNameHash.value(id).contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-+ {
-+ textMatch = true;
-+ }
-+ }
-+
-+ // Album names
-+ if (m_textFilterSettings.textFields & SearchTextFilterSettings::AlbumName &&
-+ m_albumNameHash.value(info.albumId()).contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-+ {
-+ textMatch = true;
-+ }
-+
-+ // Image Aspect Ratio
-+ if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageAspectRatio)
-+ {
-+ QRegExp expRatio (QLatin1String("^\\d+:\\d+$"));
-+ QRegExp expFloat (QLatin1String("^\\d+(.\\d+)?$"));
-+
-+ if (expRatio.indexIn(m_textFilterSettings.text) > -1 && m_textFilterSettings.text.contains(QRegExp(QLatin1String(":\\d+"))))
-+ {
-+ QString trimmedTextFilterSettingsText = m_textFilterSettings.text;
-+ QStringList numberStringList = trimmedTextFilterSettingsText.split(QLatin1String(":"), QString::SkipEmptyParts);
-+
-+ if (numberStringList.length() == 2)
-+ {
-+ QString numString = (QString)numberStringList.at(0), denomString = (QString)numberStringList.at(1);
-+ bool canConverseNum = false;
-+ bool canConverseDenom = false;
-+ int num = numString.toInt(&canConverseNum, 10), denom = denomString.toInt(&canConverseDenom, 10);
-+
-+ if (canConverseNum && canConverseDenom)
-+ {
-+ if (fabs(info.aspectRatio() - (double)num / denom) < 0.1)
-+ textMatch = true;
-+ }
-+ }
-+ }
-+ else if (expFloat.indexIn(m_textFilterSettings.text) > -1)
-+ {
-+ QString trimmedTextFilterSettingsText = m_textFilterSettings.text;
-+ bool canConverse = false;
-+ double ratio = trimmedTextFilterSettingsText.toDouble(&canConverse);
-+
-+ if (canConverse)
-+ {
-+ if (fabs(info.aspectRatio() - ratio) < 0.1)
-+ textMatch = true;
-+ }
-+ }
-+ }
-+
-+ // Image Pixel Size
-+ // See bug #341053 for details.
-+
-+ if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImagePixelSize)
-+ {
-+ QSize size = info.dimensions();
-+ int pixelSize = size.height()*size.width();
-+ QString text = m_textFilterSettings.text;
-+
-+ if(text.contains(QRegExp(QLatin1String("^>\\d{1,15}$"))) && pixelSize > (text.remove(0,1)).toInt())
-+ {
-+ textMatch = true;
-+ }
-+ else if(text.contains(QRegExp(QLatin1String("^<\\d{1,15}$"))) && pixelSize < (text.remove(0,1)).toInt())
-+ {
-+ textMatch = true;
-+ }
-+ else if(text.contains(QRegExp(QLatin1String("^\\d+$"))) && pixelSize == text.toInt())
-+ {
-+ textMatch = true;
-+ }
-+ }
-+
-+ match &= textMatch;
-+
-+ if (foundText)
-+ {
-+ *foundText = textMatch;
-+ }
-+ }
-+
-+ // -- filter by URL-whitelists ------------------------------------------------
-+ // NOTE: whitelists are always AND for now.
-+
-+ if (match)
-+ {
-+ const QUrl url = info.fileUrl();
-+
-+ for (QHash<QString, QList<QUrl>>::const_iterator it = m_urlWhitelists.constBegin();
-+ it!=m_urlWhitelists.constEnd(); ++it)
-+ {
-+ match = it->contains(url);
-+
-+ if (!match)
-+ {
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (match)
-+ {
-+ const qlonglong id = info.id();
-+
-+ for (QHash<QString, QList<qlonglong> >::const_iterator it = m_idWhitelists.constBegin();
-+ it!=m_idWhitelists.constEnd(); ++it)
-+ {
-+ match = it->contains(id);
-+
-+ if (!match)
-+ {
-+ break;
-+ }
-+ }
-+ }
-+
-+ return match;
-+}
-+
-+// -------------------------------------------------------------------------------------------------
-+
-+VersionImageFilterSettings::VersionImageFilterSettings()
-+{
-+ m_includeTagFilter = 0;
-+ m_exceptionTagFilter = 0;
-+}
-+
-+VersionImageFilterSettings::VersionImageFilterSettings(const VersionManagerSettings& settings)
-+{
-+ setVersionManagerSettings(settings);
-+}
-+
-+bool VersionImageFilterSettings::operator==(const VersionImageFilterSettings& other) const
-+{
-+ return m_excludeTagFilter == other.m_excludeTagFilter &&
-+ m_exceptionLists == other.m_exceptionLists;
-+}
-+
-+bool VersionImageFilterSettings::matches(const ImageInfo& info) const
-+{
-+ if (!isFiltering())
-+ {
-+ return true;
-+ }
-+
-+ const qlonglong id = info.id();
-+
-+ for (QHash<QString, QList<qlonglong> >::const_iterator it = m_exceptionLists.constBegin();
-+ it != m_exceptionLists.constEnd(); ++it)
-+ {
-+ if (it->contains(id))
-+ {
-+ return true;
-+ }
-+ }
-+
-+ bool match = true;
-+ QList<int> tagIds = info.tagIds();
-+
-+ if (!tagIds.contains(m_includeTagFilter))
-+ {
-+ for (QList<int>::const_iterator it = m_excludeTagFilter.begin();
-+ it != m_excludeTagFilter.end(); ++it)
-+ {
-+ if (tagIds.contains(*it))
-+ {
-+ match = false;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (!match)
-+ {
-+ if (tagIds.contains(m_exceptionTagFilter))
-+ {
-+ match = true;
-+ }
-+ }
-+
-+ return match;
-+}
-+
-+bool VersionImageFilterSettings::isHiddenBySettings(const ImageInfo& info) const
-+{
-+ QList<int> tagIds = info.tagIds();
-+
-+ foreach(int tagId, m_excludeTagFilter)
-+ {
-+ if (tagIds.contains(tagId))
-+ {
-+ return true;
-+ }
-+ }
-+
-+ return false;
-+}
-+
-+bool VersionImageFilterSettings::isExemptedBySettings(const ImageInfo& info) const
-+{
-+ return info.tagIds().contains(m_exceptionTagFilter);
-+}
-+
-+void VersionImageFilterSettings::setVersionManagerSettings(const VersionManagerSettings& settings)
-+{
-+ m_excludeTagFilter.clear();
-+
-+ if (!settings.enabled)
-+ {
-+ return;
-+ }
-+
-+ if (!(settings.showInViewFlags & VersionManagerSettings::ShowOriginal))
-+ {
-+ m_excludeTagFilter << TagsCache::instance()->getOrCreateInternalTag(InternalTagName::originalVersion());
-+ }
-+
-+ if (!(settings.showInViewFlags & VersionManagerSettings::ShowIntermediates))
-+ {
-+ m_excludeTagFilter << TagsCache::instance()->getOrCreateInternalTag(InternalTagName::intermediateVersion());
-+ }
-+
-+ m_includeTagFilter = TagsCache::instance()->getOrCreateInternalTag(InternalTagName::currentVersion());
-+ m_exceptionTagFilter = TagsCache::instance()->getOrCreateInternalTag(InternalTagName::versionAlwaysVisible());
-+}
-+
-+void VersionImageFilterSettings::setExceptionList(const QList<qlonglong>& idList, const QString& id)
-+{
-+ if (idList.isEmpty())
-+ {
-+ m_exceptionLists.remove(id);
-+ }
-+ else
-+ {
-+ m_exceptionLists.insert(id, idList);
-+ }
-+}
-+
-+bool VersionImageFilterSettings::isFiltering() const
-+{
-+ return !m_excludeTagFilter.isEmpty();
-+}
-+
-+bool VersionImageFilterSettings::isFilteringByTags() const
-+{
-+ return isFiltering();
-+}
-+
-+// -------------------------------------------------------------------------------------------------
-+
-+GroupImageFilterSettings::GroupImageFilterSettings()
-+ : m_allOpen(false)
-+{
-+}
-+
-+bool GroupImageFilterSettings::operator==(const GroupImageFilterSettings& other) const
-+{
-+ return (m_allOpen == other.m_allOpen &&
-+ m_openGroups == other.m_openGroups);
-+}
-+
-+bool GroupImageFilterSettings::matches(const ImageInfo& info) const
-+{
-+ if (m_allOpen)
-+ {
-+ return true;
-+ }
-+
-+ if (info.isGrouped())
-+ {
-+ return m_openGroups.contains(info.groupImage().id());
-+ }
-+ return true;
-+}
-+
-+void GroupImageFilterSettings::setOpen(qlonglong group, bool open)
-+{
-+ if (open)
-+ {
-+ m_openGroups << group;
-+ }
-+ else
-+ {
-+ m_openGroups.remove(group);
-+ }
-+}
-+
-+bool GroupImageFilterSettings::isOpen(qlonglong group) const
-+{
-+ return m_openGroups.contains(group);
-+}
-+
-+void GroupImageFilterSettings::setAllOpen(bool open)
-+{
-+ m_allOpen = open;
-+}
-+
-+bool GroupImageFilterSettings::isAllOpen() const
-+{
-+ return m_allOpen;
-+}
-+
-+bool GroupImageFilterSettings::isFiltering() const
-+{
-+ return !m_allOpen;
-+}
-+
-+DatabaseFields::Set GroupImageFilterSettings::watchFlags() const
-+{
-+ return DatabaseFields::ImageRelations;
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagefiltersettings.h b/libs/database/models/imagefiltersettings.h
-new file mode 100644
-index 0000000..0e7beae
---- /dev/null
-+++ b/libs/database/models/imagefiltersettings.h
-@@ -0,0 +1,349 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Filter values for use with ImageFilterModel
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-+ * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-+ * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGEFILTERSETTINGS_H
-+#define IMAGEFILTERSETTINGS_H
-+
-+// Qt includes
-+
-+#include <QHash>
-+#include <QList>
-+#include <QMap>
-+#include <QString>
-+#include <QSet>
-+#include <QUrl>
-+
-+// Local includes
-+
-+#include "searchtextbar.h"
-+#include "mimefilter.h"
-+#include "digikam_export.h"
-+
-+namespace Digikam
-+{
-+
-+class ImageInfo;
-+class VersionManagerSettings;
-+
-+namespace DatabaseFields
-+{
-+ class Set;
-+}
-+
-+// ---------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT SearchTextFilterSettings : public SearchTextSettings
-+{
-+
-+public:
-+
-+ enum TextFilterFields
-+ {
-+ None = 0x00,
-+ ImageName = 0x01,
-+ ImageTitle = 0x02,
-+ ImageComment = 0x04,
-+ TagName = 0x08,
-+ AlbumName = 0x10,
-+ ImageAspectRatio = 0x20,
-+ ImagePixelSize = 0x40,
-+ All = ImageName | ImageTitle | ImageComment | TagName | AlbumName | ImageAspectRatio | ImagePixelSize
-+ };
-+
-+public:
-+
-+ SearchTextFilterSettings()
-+ {
-+ textFields = None;
-+ }
-+
-+ explicit SearchTextFilterSettings(const SearchTextSettings& settings)
-+ {
-+ caseSensitive = settings.caseSensitive;
-+ text = settings.text;
-+ textFields = None;
-+ }
-+
-+ TextFilterFields textFields;
-+};
-+
-+// ---------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT ImageFilterSettings
-+{
-+public:
-+
-+ ImageFilterSettings();
-+
-+ /**
-+ * Returns true if the given ImageInfo matches the filter criteria.
-+ * Optionally, foundText is set to true if it matched by text search.
-+ */
-+ bool matches(const ImageInfo& info, bool* const foundText = 0) const;
-+
-+public:
-+
-+ /// --- Tags filter ---
-+
-+ /// Possible logical matching condition used to sort tags id.
-+ enum MatchingCondition
-+ {
-+ OrCondition,
-+ AndCondition
-+ };
-+
-+ void setTagFilter(const QList<int>& includedTags,
-+ const QList<int>& excludedTags,
-+ MatchingCondition matchingCond,
-+ bool showUnTagged,
-+ const QList<int>& clTagIds,
-+ const QList<int>& plTagIds);
-+
-+public:
-+
-+ /// --- Rating filter ---
-+
-+ /// Possible conditions used to filter rating: >=, =, <=
-+ enum RatingCondition
-+ {
-+ GreaterEqualCondition,
-+ EqualCondition,
-+ LessEqualCondition
-+ };
-+
-+ void setRatingFilter(int rating, RatingCondition ratingCond, bool isUnratedExcluded);
-+
-+public:
-+
-+ /// --- Date filter ---
-+ void setDayFilter(const QList<QDateTime>& days);
-+
-+public:
-+
-+ /// --- Text filter ---
-+ void setTextFilter(const SearchTextFilterSettings& settings);
-+ void setTagNames(const QHash<int, QString>& tagNameHash);
-+ void setAlbumNames(const QHash<int, QString>& albumNameHash);
-+
-+public:
-+
-+ /// --- Mime filter ---
-+ void setMimeTypeFilter(int mimeTypeFilter);
-+
-+public:
-+
-+ /// --- Geolocation filter
-+ enum GeolocationCondition
-+ {
-+ GeolocationNoFilter = 0,
-+ GeolocationNoCoordinates = 1 << 1,
-+ GeolocationHasCoordinates = 1 << 2
-+ };
-+
-+ void setGeolocationFilter(const GeolocationCondition& condition);
-+
-+public:
-+
-+ /// Returns if the day is a filter criteria
-+ bool isFilteringByDay() const;
-+
-+ /// Returns if the type mime is a filter criteria
-+ bool isFilteringByTypeMime() const;
-+
-+ /// Returns whether geolocation is a filter criteria
-+ bool isFilteringByGeolocation() const;
-+
-+ /// Returns if the rating is a filter criteria
-+ bool isFilteringByRating() const;
-+
-+ /// Returns if the pick labels is a filter criteria
-+ bool isFilteringByPickLabels() const;
-+
-+ /// Returns if the color labels is a filter criteria
-+ bool isFilteringByColorLabels() const;
-+
-+ /// Returns if the tag is a filter criteria
-+ bool isFilteringByTags() const;
-+
-+ /// Returns if the text (including comment) is a filter criteria
-+ bool isFilteringByText() const;
-+
-+ /// Returns if images will be filtered by these criteria at all
-+ bool isFiltering() const;
-+
-+public:
-+
-+ /// --- URL whitelist filter
-+ void setUrlWhitelist(const QList<QUrl>& urlList, const QString& id);
-+
-+public:
-+
-+ /// --- ID whitelist filter
-+ void setIdWhitelist(const QList<qlonglong>& idList, const QString& id);
-+
-+public:
-+
-+ /// --- Change notification ---
-+
-+ /** Returns database fields a change in which would affect the current filtering.
-+ * To find out if an image tag change affects filtering, test isFilteringByTags().
-+ * The text filter will also be affected by changes in tags and album names.
-+ */
-+ DatabaseFields::Set watchFlags() const;
-+
-+private:
-+
-+ /**
-+ * @brief Returns whether some internal filtering (whitelist by id or URL) or normal filtering is going on
-+ */
-+ bool isFilteringInternally() const;
-+
-+private:
-+
-+ /// --- Tags filter ---
-+ bool m_untaggedFilter;
-+ QList<int> m_includeTagFilter;
-+ QList<int> m_excludeTagFilter;
-+ MatchingCondition m_matchingCond;
-+ QList<int> m_colorLabelTagFilter;
-+ QList<int> m_pickLabelTagFilter;
-+
-+ /// --- Rating filter ---
-+ int m_ratingFilter;
-+ RatingCondition m_ratingCond;
-+ bool m_isUnratedExcluded;
-+
-+ /// --- Date filter ---
-+ QMap<QDateTime, bool> m_dayFilter;
-+
-+ /// --- Text filter ---
-+ SearchTextFilterSettings m_textFilterSettings;
-+
-+ /// Helpers for text search: Set these if you want to search album or tag names with text search
-+ QHash<int, QString> m_tagNameHash;
-+ QHash<int, QString> m_albumNameHash;
-+
-+ /// --- Mime filter ---
-+ MimeFilter::TypeMimeFilter m_mimeTypeFilter;
-+
-+ /// --- Geolocation filter
-+ GeolocationCondition m_geolocationCondition;
-+
-+ /// --- URL whitelist filter
-+ QHash<QString,QList<QUrl>> m_urlWhitelists;
-+
-+ /// --- ID whitelist filter
-+ QHash<QString,QList<qlonglong> > m_idWhitelists;
-+};
-+
-+// ---------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT VersionImageFilterSettings
-+{
-+public:
-+
-+ VersionImageFilterSettings();
-+ explicit VersionImageFilterSettings(const VersionManagerSettings& settings);
-+
-+ bool operator==(const VersionImageFilterSettings& other) const;
-+
-+ /**
-+ * Returns true if the given ImageInfo matches the filter criteria.
-+ */
-+ bool matches(const ImageInfo& info) const;
-+
-+ bool isHiddenBySettings(const ImageInfo& info) const;
-+ bool isExemptedBySettings(const ImageInfo& info) const;
-+
-+ /// --- Tags filter ---
-+
-+ void setVersionManagerSettings(const VersionManagerSettings& settings);
-+
-+ /**
-+ * Add list with exceptions: These images will be exempted from filtering by this filter
-+ */
-+ void setExceptionList(const QList<qlonglong>& idlist, const QString& id);
-+
-+ /// Returns if images will be filtered by these criteria at all
-+ bool isFiltering() const;
-+
-+ /// Returns if the tag is a filter criteria
-+ bool isFilteringByTags() const;
-+
-+ /// DatabaseFields::Set watchFlags() const: Would return 0
-+
-+protected:
-+
-+ QList<int> m_excludeTagFilter;
-+ int m_includeTagFilter;
-+ int m_exceptionTagFilter;
-+ QHash<QString,QList<qlonglong> > m_exceptionLists;
-+};
-+
-+// ---------------------------------------------------------------------------------------
-+
-+class DIGIKAM_DATABASE_EXPORT GroupImageFilterSettings
-+{
-+public:
-+
-+ GroupImageFilterSettings();
-+
-+ bool operator==(const GroupImageFilterSettings& other) const;
-+
-+ /**
-+ * Returns true if the given ImageInfo matches the filter criteria.
-+ */
-+ bool matches(const ImageInfo& info) const;
-+
-+ /**
-+ * Open or close a group.
-+ */
-+ void setOpen(qlonglong group, bool open);
-+ bool isOpen(qlonglong group) const;
-+
-+ /**
-+ * Open all groups
-+ */
-+ void setAllOpen(bool open);
-+ bool isAllOpen() const;
-+
-+ /// Returns if images will be filtered by these criteria at all
-+ bool isFiltering() const;
-+
-+ DatabaseFields::Set watchFlags() const;
-+
-+protected:
-+
-+ bool m_allOpen;
-+ QSet<qlonglong> m_openGroups;
-+};
-+
-+} // namespace Digikam
-+
-+Q_DECLARE_METATYPE(Digikam::ImageFilterSettings::GeolocationCondition)
-+
-+#endif // IMAGEFILTERSETTINGS_H
-diff --git a/libs/database/models/imagelistmodel.cpp b/libs/database/models/imagelistmodel.cpp
-new file mode 100644
-index 0000000..fafce34
---- /dev/null
-+++ b/libs/database/models/imagelistmodel.cpp
-@@ -0,0 +1,70 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2010-12-06
-+ * Description : An image model based on a static list
-+ *
-+ * Copyright (C) 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagelistmodel.h"
-+
-+// Local includes
-+
-+#include "digikam_debug.h"
-+#include "coredbaccess.h"
-+#include "coredbchangesets.h"
-+#include "coredbwatch.h"
-+#include "imageinfo.h"
-+#include "imageinfolist.h"
-+
-+namespace Digikam
-+{
-+
-+ImageListModel::ImageListModel(QObject* parent)
-+ : ImageThumbnailModel(parent)
-+{
-+ connect(CoreDbAccess::databaseWatch(), SIGNAL(collectionImageChange(CollectionImageChangeset)),
-+ this, SLOT(slotCollectionImageChange(CollectionImageChangeset)));
-+}
-+
-+ImageListModel::~ImageListModel()
-+{
-+}
-+
-+void ImageListModel::slotCollectionImageChange(const CollectionImageChangeset& changeset)
-+{
-+ if (isEmpty())
-+ {
-+ return;
-+ }
-+
-+ switch (changeset.operation())
-+ {
-+ case CollectionImageChangeset::Added:
-+ break;
-+ case CollectionImageChangeset::Removed:
-+ case CollectionImageChangeset::RemovedAll:
-+ removeImageInfos(ImageInfoList(changeset.ids()));
-+ break;
-+
-+ default:
-+ break;
-+ }
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagelistmodel.h b/libs/database/models/imagelistmodel.h
-new file mode 100644
-index 0000000..a225b1b
---- /dev/null
-+++ b/libs/database/models/imagelistmodel.h
-@@ -0,0 +1,63 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2010-12-06
-+ * Description : An image model based on a static list
-+ *
-+ * Copyright (C) 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGELISTMODEL_H
-+#define IMAGELISTMODEL_H
-+
-+// Local includes
-+
-+#include "imagethumbnailmodel.h"
-+#include "digikam_export.h"
-+
-+namespace Digikam
-+{
-+
-+class ImageChangeset;
-+class CollectionImageChangeset;
-+
-+class DIGIKAM_DATABASE_EXPORT ImageListModel : public ImageThumbnailModel
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ explicit ImageListModel(QObject* parent = 0);
-+ ~ImageListModel();
-+
-+ // NOTE: necessary methods to add and remove ImageInfos to the model are inherited from ImageModel
-+
-+Q_SIGNALS:
-+
-+ /**
-+ * Emitted when images are removed from the model because they are removed in the database
-+ */
-+ void imageInfosRemoved(const QList<ImageInfo>& infos);
-+
-+protected Q_SLOTS:
-+
-+ void slotCollectionImageChange(const CollectionImageChangeset& changeset);
-+};
-+
-+} // namespace Digikam
-+
-+#endif // IMAGELISTMODEL_H
-diff --git a/libs/database/models/imagemodel.cpp b/libs/database/models/imagemodel.cpp
-new file mode 100644
-index 0000000..41b43cf
---- /dev/null
-+++ b/libs/database/models/imagemodel.cpp
-@@ -0,0 +1,1368 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagemodel.h"
-+
-+// Qt includes
-+
-+#include <QHash>
-+#include <QItemSelection>
-+
-+// Local includes
-+
-+#include "digikam_debug.h"
-+#include "coredbchangesets.h"
-+#include "coredbfields.h"
-+#include "coredbwatch.h"
-+#include "imageinfo.h"
-+#include "imageinfolist.h"
-+#include "abstractitemdragdrophandler.h"
-+
-+namespace Digikam
-+{
-+
-+class ImageModel::Private
-+{
-+public:
-+
-+ Private()
-+ {
-+ preprocessor = 0;
-+ keepFilePathCache = false;
-+ sendRemovalSignals = false;
-+ incrementalUpdater = 0;
-+ refreshing = false;
-+ reAdding = false;
-+ incrementalRefreshRequested = false;
-+ }
-+
-+ ImageInfoList infos;
-+ QList<QVariant> extraValues;
-+ QHash<qlonglong, int> idHash;
-+
-+ bool keepFilePathCache;
-+ QHash<QString, qlonglong> filePathHash;
-+
-+ bool sendRemovalSignals;
-+
-+ QObject* preprocessor;
-+ bool refreshing;
-+ bool reAdding;
-+ bool incrementalRefreshRequested;
-+
-+ DatabaseFields::Set watchFlags;
-+
-+ class ImageModelIncrementalUpdater* incrementalUpdater;
-+
-+ ImageInfoList pendingInfos;
-+ QList<QVariant> pendingExtraValues;
-+
-+ inline bool isValid(const QModelIndex& index)
-+ {
-+ if (!index.isValid())
-+ {
-+ return false;
-+ }
-+
-+ if (index.row() < 0 || index.row() >= infos.size())
-+ {
-+ qCDebug(DIGIKAM_GENERAL_LOG) << "Invalid index" << index;
-+ return false;
-+ }
-+
-+ return true;
-+ }
-+ inline bool extraValueValid(const QModelIndex& index)
-+ {
-+ // we assume isValid() being called before, no duplicate checks
-+ if (index.row() >= extraValues.size())
-+ {
-+ qCDebug(DIGIKAM_GENERAL_LOG) << "Invalid index for extraData" << index;
-+ return false;
-+ }
-+
-+ return true;
-+ }
-+};
-+
-+typedef QPair<int, int> IntPair; // to make foreach macro happy
-+typedef QList<IntPair> IntPairList;
-+
-+class ImageModelIncrementalUpdater
-+{
-+public:
-+
-+ explicit ImageModelIncrementalUpdater(ImageModel::Private* d);
-+
-+ void appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void aboutToBeRemovedInModel(const IntPairList& aboutToBeRemoved);
-+ QList<IntPair> oldIndexes();
-+
-+ static QList<IntPair> toContiguousPairs(const QList<int>& ids);
-+
-+public:
-+
-+ QHash<qlonglong, int> oldIds;
-+ QList<QVariant> oldExtraValues;
-+ QList<ImageInfo> newInfos;
-+ QList<QVariant> newExtraValues;
-+ QList<IntPairList> modelRemovals;
-+};
-+
-+ImageModel::ImageModel(QObject* parent)
-+ : QAbstractListModel(parent),
-+ d(new Private)
-+{
-+ connect(CoreDbAccess::databaseWatch(), SIGNAL(imageChange(ImageChangeset)),
-+ this, SLOT(slotImageChange(ImageChangeset)));
-+
-+ connect(CoreDbAccess::databaseWatch(), SIGNAL(imageTagChange(ImageTagChangeset)),
-+ this, SLOT(slotImageTagChange(ImageTagChangeset)));
-+}
-+
-+ImageModel::~ImageModel()
-+{
-+ delete d->incrementalUpdater;
-+ delete d;
-+}
-+
-+// ------------ Access methods -------------
-+
-+void ImageModel::setKeepsFilePathCache(bool keepCache)
-+{
-+ d->keepFilePathCache = keepCache;
-+}
-+
-+bool ImageModel::keepsFilePathCache() const
-+{
-+ return d->keepFilePathCache;
-+}
-+
-+bool ImageModel::isEmpty() const
-+{
-+ return d->infos.isEmpty();
-+}
-+
-+void ImageModel::setWatchFlags(const DatabaseFields::Set& set)
-+{
-+ d->watchFlags = set;
-+}
-+
-+ImageInfo ImageModel::imageInfo(const QModelIndex& index) const
-+{
-+ if (!d->isValid(index))
-+ {
-+ return ImageInfo();
-+ }
-+
-+ return d->infos.at(index.row());
-+}
-+
-+ImageInfo& ImageModel::imageInfoRef(const QModelIndex& index) const
-+{
-+ return d->infos[index.row()];
-+}
-+
-+qlonglong ImageModel::imageId(const QModelIndex& index) const
-+{
-+ if (!d->isValid(index))
-+ {
-+ return 0;
-+ }
-+
-+ return d->infos.at(index.row()).id();
-+}
-+
-+QList<ImageInfo> ImageModel::imageInfos(const QList<QModelIndex>& indexes) const
-+{
-+ QList<ImageInfo> infos;
-+
-+ foreach(const QModelIndex& index, indexes)
-+ {
-+ infos << imageInfo(index);
-+ }
-+
-+ return infos;
-+}
-+
-+QList<qlonglong> ImageModel::imageIds(const QList<QModelIndex>& indexes) const
-+{
-+ QList<qlonglong> ids;
-+
-+ foreach(const QModelIndex& index, indexes)
-+ {
-+ ids << imageId(index);
-+ }
-+
-+ return ids;
-+}
-+
-+ImageInfo ImageModel::imageInfo(int row) const
-+{
-+ if (row >= d->infos.size())
-+ {
-+ return ImageInfo();
-+ }
-+
-+ return d->infos.at(row);
-+}
-+
-+ImageInfo& ImageModel::imageInfoRef(int row) const
-+{
-+ return d->infos[row];
-+}
-+
-+qlonglong ImageModel::imageId(int row) const
-+{
-+ if (row < 0 || row >= d->infos.size())
-+ {
-+ return -1;
-+ }
-+
-+ return d->infos.at(row).id();
-+}
-+
-+QModelIndex ImageModel::indexForImageInfo(const ImageInfo& info) const
-+{
-+ return indexForImageId(info.id());
-+}
-+
-+QModelIndex ImageModel::indexForImageInfo(const ImageInfo& info, const QVariant& extraValue) const
-+{
-+ return indexForImageId(info.id(), extraValue);
-+}
-+
-+QList<QModelIndex> ImageModel::indexesForImageInfo(const ImageInfo& info) const
-+{
-+ return indexesForImageId(info.id());
-+}
-+
-+QModelIndex ImageModel::indexForImageId(qlonglong id) const
-+{
-+ int index = d->idHash.value(id, -1);
-+
-+ if (index != -1)
-+ {
-+ return createIndex(index, 0);
-+ }
-+
-+ return QModelIndex();
-+}
-+
-+QModelIndex ImageModel::indexForImageId(qlonglong id, const QVariant& extraValue) const
-+{
-+ if (d->extraValues.isEmpty())
-+ return indexForImageId(id);
-+
-+ QHash<qlonglong, int>::const_iterator it;
-+
-+ for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-+ {
-+ if (d->extraValues.at(it.value()) == extraValue)
-+ return createIndex(it.value(), 0);
-+ }
-+
-+ return QModelIndex();
-+}
-+
-+QList<QModelIndex> ImageModel::indexesForImageId(qlonglong id) const
-+{
-+ QList<QModelIndex> indexes;
-+ QHash<qlonglong, int>::const_iterator it;
-+
-+ for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-+ {
-+ indexes << createIndex(it.value(), 0);
-+ }
-+
-+ return indexes;
-+}
-+
-+int ImageModel::numberOfIndexesForImageInfo(const ImageInfo& info) const
-+{
-+ return numberOfIndexesForImageId(info.id());
-+}
-+
-+int ImageModel::numberOfIndexesForImageId(qlonglong id) const
-+{
-+ if (d->extraValues.isEmpty())
-+ {
-+ return 0;
-+ }
-+
-+ int count = 0;
-+ QHash<qlonglong,int>::const_iterator it;
-+
-+ for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-+ {
-+ ++count;
-+ }
-+
-+ return count;
-+}
-+
-+// static method
-+ImageInfo ImageModel::retrieveImageInfo(const QModelIndex& index)
-+{
-+ if (!index.isValid())
-+ {
-+ return ImageInfo();
-+ }
-+
-+ ImageModel* const model = index.data(ImageModelPointerRole).value<ImageModel*>();
-+ int row = index.data(ImageModelInternalId).toInt();
-+
-+ if (!model)
-+ {
-+ return ImageInfo();
-+ }
-+
-+ return model->imageInfo(row);
-+}
-+
-+// static method
-+qlonglong ImageModel::retrieveImageId(const QModelIndex& index)
-+{
-+ if (!index.isValid())
-+ {
-+ return 0;
-+ }
-+
-+ ImageModel* const model = index.data(ImageModelPointerRole).value<ImageModel*>();
-+ int row = index.data(ImageModelInternalId).toInt();
-+
-+ if (!model)
-+ {
-+ return 0;
-+ }
-+
-+ return model->imageId(row);
-+}
-+
-+QModelIndex ImageModel::indexForPath(const QString& filePath) const
-+{
-+ if (d->keepFilePathCache)
-+ {
-+ return indexForImageId(d->filePathHash.value(filePath));
-+ }
-+ else
-+ {
-+ const int size = d->infos.size();
-+
-+ for (int i=0; i<size; ++i)
-+ {
-+ if (d->infos.at(i).filePath() == filePath)
-+ {
-+ return createIndex(i, 0);
-+ }
-+ }
-+ }
-+
-+ return QModelIndex();
-+}
-+
-+QList<QModelIndex> ImageModel::indexesForPath(const QString& filePath) const
-+{
-+ if (d->keepFilePathCache)
-+ {
-+ return indexesForImageId(d->filePathHash.value(filePath));
-+ }
-+ else
-+ {
-+ QList<QModelIndex> indexes;
-+ const int size = d->infos.size();
-+
-+ for (int i=0; i<size; ++i)
-+ {
-+ if (d->infos.at(i).filePath() == filePath)
-+ {
-+ indexes << createIndex(i, 0);
-+ }
-+ }
-+
-+ return indexes;
-+ }
-+}
-+
-+ImageInfo ImageModel::imageInfo(const QString& filePath) const
-+{
-+ if (d->keepFilePathCache)
-+ {
-+ qlonglong id = d->filePathHash.value(filePath);
-+
-+ if (id)
-+ {
-+ int index = d->idHash.value(id, -1);
-+
-+ if (index != -1)
-+ {
-+ return d->infos.at(index);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ foreach(const ImageInfo& info, d->infos)
-+ {
-+ if (info.filePath() == filePath)
-+ {
-+ return info;
-+ }
-+ }
-+ }
-+
-+ return ImageInfo();
-+}
-+
-+QList<ImageInfo> ImageModel::imageInfos(const QString& filePath) const
-+{
-+ QList<ImageInfo> infos;
-+
-+ if (d->keepFilePathCache)
-+ {
-+ qlonglong id = d->filePathHash.value(filePath);
-+
-+ if (id)
-+ {
-+ foreach(int index, d->idHash.values(id))
-+ {
-+ infos << d->infos.at(index);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ foreach(const ImageInfo& info, d->infos)
-+ {
-+ if (info.filePath() == filePath)
-+ {
-+ infos << info;
-+ }
-+ }
-+ }
-+
-+ return infos;
-+}
-+
-+void ImageModel::addImageInfo(const ImageInfo& info)
-+{
-+ addImageInfos(QList<ImageInfo>() << info, QList<QVariant>());
-+}
-+
-+void ImageModel::addImageInfos(const QList<ImageInfo>& infos)
-+{
-+ addImageInfos(infos, QList<QVariant>());
-+}
-+
-+void ImageModel::addImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ if (infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ if (d->incrementalUpdater)
-+ {
-+ d->incrementalUpdater->appendInfos(infos, extraValues);
-+ }
-+ else
-+ {
-+ appendInfos(infos, extraValues);
-+ }
-+}
-+
-+void ImageModel::addImageInfoSynchronously(const ImageInfo& info)
-+{
-+ addImageInfosSynchronously(QList<ImageInfo>() << info, QList<QVariant>());
-+}
-+
-+void ImageModel::addImageInfosSynchronously(const QList<ImageInfo>& infos)
-+{
-+ addImageInfos(infos, QList<QVariant>());
-+}
-+
-+void ImageModel::addImageInfosSynchronously(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ if (infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ publiciseInfos(infos, extraValues);
-+ emit processAdded(infos, extraValues);
-+}
-+
-+void ImageModel::ensureHasImageInfo(const ImageInfo& info)
-+{
-+ ensureHasImageInfos(QList<ImageInfo>() << info, QList<QVariant>());
-+}
-+
-+void ImageModel::ensureHasImageInfos(const QList<ImageInfo>& infos)
-+{
-+ ensureHasImageInfos(infos, QList<QVariant>());
-+}
-+
-+void ImageModel::ensureHasImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ if (extraValues.isEmpty())
-+ {
-+ if (!d->pendingExtraValues.isEmpty())
-+ {
-+ qCDebug(DIGIKAM_GENERAL_LOG) << "ExtraValue / No Extra Value mismatch. Ignoring added infos.";
-+ return;
-+ }
-+ }
-+ else
-+ {
-+ if (d->pendingInfos.size() != d->pendingExtraValues.size())
-+ {
-+ qCDebug(DIGIKAM_GENERAL_LOG) << "ExtraValue / No Extra Value mismatch. Ignoring added infos.";
-+ return;
-+ }
-+ }
-+
-+ d->pendingInfos << infos;
-+ d->pendingExtraValues << extraValues;
-+ cleanSituationChecks();
-+}
-+
-+void ImageModel::clearImageInfos()
-+{
-+ d->infos.clear();
-+ d->extraValues.clear();
-+ d->idHash.clear();
-+ d->filePathHash.clear();
-+ delete d->incrementalUpdater;
-+ d->incrementalUpdater = 0;
-+ d->pendingInfos.clear();
-+ d->pendingExtraValues.clear();
-+ d->refreshing = false;
-+ d->reAdding = false;
-+ d->incrementalRefreshRequested = false;
-+
-+ beginResetModel();
-+ endResetModel();
-+
-+ imageInfosCleared();
-+}
-+
-+void ImageModel::setImageInfos(const QList<ImageInfo>& infos)
-+{
-+ clearImageInfos();
-+ addImageInfos(infos);
-+}
-+
-+QList<ImageInfo> ImageModel::imageInfos() const
-+{
-+ return d->infos;
-+}
-+
-+QList<qlonglong> ImageModel::imageIds() const
-+{
-+ return d->idHash.keys();
-+}
-+
-+bool ImageModel::hasImage(qlonglong id) const
-+{
-+ return d->idHash.contains(id);
-+}
-+
-+bool ImageModel::hasImage(const ImageInfo& info) const
-+{
-+ return d->idHash.contains(info.id());
-+}
-+
-+bool ImageModel::hasImage(const ImageInfo& info, const QVariant& extraValue) const
-+{
-+ return hasImage(info.id(), extraValue);
-+}
-+
-+bool ImageModel::hasImage(qlonglong id, const QVariant& extraValue) const
-+{
-+ if (d->extraValues.isEmpty())
-+ return hasImage(id);
-+
-+ QHash<qlonglong, int>::const_iterator it;
-+
-+ for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-+ {
-+ if (d->extraValues.at(it.value()) == extraValue)
-+ return true;
-+ }
-+
-+ return false;;
-+}
-+
-+QList<ImageInfo> ImageModel::uniqueImageInfos() const
-+{
-+ if (d->extraValues.isEmpty())
-+ {
-+ return d->infos;
-+ }
-+
-+ QList<ImageInfo> uniqueInfos;
-+ const int size = d->infos.size();
-+
-+ for (int i=0; i<size; ++i)
-+ {
-+ const ImageInfo& info = d->infos.at(i);
-+
-+ if (d->idHash.value(info.id()) == i)
-+ {
-+ uniqueInfos << info;
-+ }
-+ }
-+
-+ return uniqueInfos;
-+}
-+
-+void ImageModel::emitDataChangedForAll()
-+{
-+ if (d->infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ QModelIndex first = createIndex(0, 0);
-+ QModelIndex last = createIndex(d->infos.size() - 1, 0);
-+ emit dataChanged(first, last);
-+}
-+
-+void ImageModel::emitDataChangedForSelection(const QItemSelection& selection)
-+{
-+ if (!selection.isEmpty())
-+ {
-+ foreach(const QItemSelectionRange& range, selection)
-+ {
-+ emit dataChanged(range.topLeft(), range.bottomRight());
-+ }
-+ }
-+}
-+
-+void ImageModel::ensureHasGroupedImages(const ImageInfo& groupLeader)
-+{
-+ ensureHasImageInfos(groupLeader.groupedImages());
-+}
-+
-+// ------------ Preprocessing -------------
-+
-+void ImageModel::setPreprocessor(QObject* preprocessor)
-+{
-+ unsetPreprocessor(d->preprocessor);
-+ d->preprocessor = preprocessor;
-+}
-+
-+void ImageModel::unsetPreprocessor(QObject* preprocessor)
-+{
-+ if (preprocessor && d->preprocessor == preprocessor)
-+ {
-+ disconnect(this, SIGNAL(preprocess(QList<ImageInfo>,QList<QVariant>)), 0, 0);
-+ disconnect(d->preprocessor, 0, this, SLOT(reAddImageInfos(QList<ImageInfo>,QList<QVariant>)));
-+ disconnect(d->preprocessor, 0, this, SLOT(reAddingFinished()));
-+ }
-+}
-+
-+void ImageModel::appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ if (infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ if (d->preprocessor)
-+ {
-+ d->reAdding = true;
-+ emit preprocess(infos, extraValues);
-+ }
-+ else
-+ {
-+ publiciseInfos(infos, extraValues);
-+ }
-+}
-+
-+void ImageModel::appendInfosChecked(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ // This method does deduplication. It is private because in context of readding or refreshing it is of no use.
-+
-+ if (extraValues.isEmpty())
-+ {
-+ QList<ImageInfo> checkedInfos;
-+
-+ foreach (const ImageInfo& info, infos)
-+ {
-+ if (!hasImage(info))
-+ {
-+ checkedInfos << info;
-+ }
-+ }
-+
-+ appendInfos(checkedInfos, QList<QVariant>());
-+ }
-+ else
-+ {
-+ QList<ImageInfo> checkedInfos;
-+ QList<QVariant> checkedExtraValues;
-+ const int size = infos.size();
-+
-+ for (int i=0; i<size; i++)
-+ {
-+ if (!hasImage(infos[i], extraValues[i]))
-+ {
-+ checkedInfos << infos[i];
-+ checkedExtraValues << extraValues[i];
-+ }
-+ }
-+
-+ appendInfos(checkedInfos, checkedExtraValues);
-+ }
-+}
-+
-+void ImageModel::reAddImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ // addImageInfos -> appendInfos -> preprocessor -> reAddImageInfos
-+ publiciseInfos(infos, extraValues);
-+}
-+
-+void ImageModel::reAddingFinished()
-+{
-+ d->reAdding = false;
-+ cleanSituationChecks();
-+}
-+
-+void ImageModel::startRefresh()
-+{
-+ d->refreshing = true;
-+}
-+
-+void ImageModel::finishRefresh()
-+{
-+ d->refreshing = false;
-+ cleanSituationChecks();
-+}
-+
-+bool ImageModel::isRefreshing() const
-+{
-+ return d->refreshing;
-+}
-+
-+void ImageModel::cleanSituationChecks()
-+{
-+ // For starting an incremental refresh we want a clear situation:
-+ // Any remaining batches from non-incremental refreshing subclasses have been received in appendInfos(),
-+ // any batches sent to preprocessor for re-adding have been re-added.
-+ if (d->refreshing || d->reAdding)
-+ {
-+ return;
-+ }
-+
-+ if (!d->pendingInfos.isEmpty())
-+ {
-+ appendInfosChecked(d->pendingInfos, d->pendingExtraValues);
-+ d->pendingInfos.clear();
-+ d->pendingExtraValues.clear();
-+ cleanSituationChecks();
-+ return;
-+ }
-+
-+ if (d->incrementalRefreshRequested)
-+ {
-+ d->incrementalRefreshRequested = false;
-+ emit readyForIncrementalRefresh();
-+ }
-+ else
-+ {
-+ emit allRefreshingFinished();
-+ }
-+}
-+
-+void ImageModel::publiciseInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ if (infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ Q_ASSERT(infos.size() == extraValues.size() || (extraValues.isEmpty() && d->extraValues.isEmpty()));
-+
-+ emit imageInfosAboutToBeAdded(infos);
-+ const int firstNewIndex = d->infos.size();
-+ const int lastNewIndex = d->infos.size() + infos.size() - 1;
-+ beginInsertRows(QModelIndex(), firstNewIndex, lastNewIndex);
-+ d->infos << infos;
-+ d->extraValues << extraValues;
-+
-+ for (int i=firstNewIndex; i<=lastNewIndex; ++i)
-+ {
-+ const ImageInfo& info = d->infos.at(i);
-+ qlonglong id = info.id();
-+ d->idHash.insertMulti(id, i);
-+
-+ if (d->keepFilePathCache)
-+ {
-+ d->filePathHash[info.filePath()] = id;
-+ }
-+ }
-+
-+ endInsertRows();
-+ emit imageInfosAdded(infos);
-+}
-+
-+void ImageModel::requestIncrementalRefresh()
-+{
-+ if (d->reAdding)
-+ {
-+ d->incrementalRefreshRequested = true;
-+ }
-+ else
-+ {
-+ emit readyForIncrementalRefresh();
-+ }
-+}
-+
-+bool ImageModel::hasIncrementalRefreshPending() const
-+{
-+ return d->incrementalRefreshRequested;
-+}
-+
-+void ImageModel::startIncrementalRefresh()
-+{
-+ delete d->incrementalUpdater;
-+
-+ d->incrementalUpdater = new ImageModelIncrementalUpdater(d);
-+}
-+
-+void ImageModel::finishIncrementalRefresh()
-+{
-+ if (!d->incrementalUpdater)
-+ {
-+ return;
-+ }
-+
-+ // remove old entries
-+ QList<QPair<int, int> > pairs = d->incrementalUpdater->oldIndexes();
-+ removeRowPairs(pairs);
-+
-+ // add new indexes
-+ appendInfos(d->incrementalUpdater->newInfos, d->incrementalUpdater->newExtraValues);
-+
-+ delete d->incrementalUpdater;
-+ d->incrementalUpdater = 0;
-+}
-+
-+void ImageModel::removeIndex(const QModelIndex& index)
-+{
-+ removeIndexes(QList<QModelIndex>() << index);
-+}
-+
-+void ImageModel::removeIndexes(const QList<QModelIndex>& indexes)
-+{
-+ QList<int> listIndexes;
-+
-+ foreach(const QModelIndex& index, indexes)
-+ {
-+ if (d->isValid(index))
-+ {
-+ listIndexes << index.row();
-+ }
-+ }
-+
-+ if (listIndexes.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ removeRowPairsWithCheck(ImageModelIncrementalUpdater::toContiguousPairs(listIndexes));
-+}
-+
-+void ImageModel::removeImageInfo(const ImageInfo& info)
-+{
-+ removeImageInfos(QList<ImageInfo>() << info);
-+}
-+
-+void ImageModel::removeImageInfos(const QList<ImageInfo>& infos)
-+{
-+ QList<int> listIndexes;
-+
-+ foreach(const ImageInfo& info, infos)
-+ {
-+ QModelIndex index = indexForImageId(info.id());
-+
-+ if (index.isValid())
-+ {
-+ listIndexes << index.row();
-+ }
-+ }
-+ removeRowPairsWithCheck(ImageModelIncrementalUpdater::toContiguousPairs(listIndexes));
-+}
-+
-+void ImageModel::removeImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ if (extraValues.isEmpty())
-+ {
-+ removeImageInfos(infos);
-+ return;
-+ }
-+
-+ QList<int> listIndexes;
-+
-+ for (int i=0; i<infos.size(); ++i)
-+ {
-+ QModelIndex index = indexForImageId(infos.at(i).id(), extraValues.at(i));
-+
-+ if (index.isValid())
-+ {
-+ listIndexes << index.row();
-+ }
-+ }
-+
-+ removeRowPairsWithCheck(ImageModelIncrementalUpdater::toContiguousPairs(listIndexes));
-+}
-+
-+void ImageModel::setSendRemovalSignals(bool send)
-+{
-+ d->sendRemovalSignals = send;
-+}
-+
-+template <class List, typename T>
-+static bool pairsContain(const List& list, T value)
-+{
-+ typename List::const_iterator middle;
-+ typename List::const_iterator begin = list.begin();
-+ typename List::const_iterator end = list.end();
-+ int n = int(end - begin);
-+ int half;
-+
-+ while (n > 0)
-+ {
-+ half = n >> 1;
-+ middle = begin + half;
-+
-+ if (middle->first <= value && middle->second >= value)
-+ {
-+ return true;
-+ }
-+ else if (middle->second < value)
-+ {
-+ begin = middle + 1;
-+ n -= half + 1;
-+ }
-+ else
-+ {
-+ n = half;
-+ }
-+ }
-+
-+ return false;
-+}
-+
-+void ImageModel::removeRowPairsWithCheck(const QList<QPair<int, int> >& toRemove)
-+{
-+ if (d->incrementalUpdater)
-+ {
-+ d->incrementalUpdater->aboutToBeRemovedInModel(toRemove);
-+ }
-+
-+ removeRowPairs(toRemove);
-+}
-+
-+void ImageModel::removeRowPairs(const QList<QPair<int, int> >& toRemove)
-+{
-+ if (toRemove.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ // Remove old indexes
-+ // Keep in mind that when calling beginRemoveRows all structures announced to be removed
-+ // must still be valid, and this includes our hashes as well, which limits what we can optimize
-+
-+ int removedRows = 0, offset = 0;
-+ typedef QPair<int, int> IntPair; // to make foreach macro happy
-+
-+ foreach(const IntPair& pair, toRemove)
-+ {
-+ const int begin = pair.first - offset;
-+ const int end = pair.second - offset; // inclusive
-+ removedRows = end - begin + 1;
-+
-+ // when removing from the list, all subsequent indexes are affected
-+ offset += removedRows;
-+
-+ QList<ImageInfo> removedInfos;
-+
-+ if (d->sendRemovalSignals)
-+ {
-+ qCopy(d->infos.begin() + begin, d->infos.begin() + end, removedInfos.begin());
-+ emit imageInfosAboutToBeRemoved(removedInfos);
-+ }
-+
-+ imageInfosAboutToBeRemoved(begin, end);
-+ beginRemoveRows(QModelIndex(), begin, end);
-+
-+ // update idHash - which points to indexes of d->infos, and these change now!
-+ QHash<qlonglong, int>::iterator it;
-+
-+ for (it = d->idHash.begin(); it != d->idHash.end(); )
-+ {
-+ if (it.value() >= begin)
-+ {
-+ if (it.value() > end)
-+ {
-+ // after the removed interval: adjust index
-+ it.value() -= removedRows;
-+ }
-+ else
-+ {
-+ // in the removed interval
-+ it = d->idHash.erase(it);
-+ continue;
-+ }
-+ }
-+
-+ ++it;
-+ }
-+
-+ // remove from list
-+ d->infos.erase(d->infos.begin() + begin, d->infos.begin() + (end + 1));
-+
-+ if (!d->extraValues.isEmpty())
-+ {
-+ d->extraValues.erase(d->extraValues.begin() + begin, d->extraValues.begin() + (end + 1));
-+ }
-+
-+ endRemoveRows();
-+
-+ if (d->sendRemovalSignals)
-+ {
-+ emit imageInfosRemoved(removedInfos);
-+ }
-+ }
-+
-+ // tidy up: remove old indexes from file path hash now
-+ if (d->keepFilePathCache)
-+ {
-+ QHash<QString, qlonglong>::iterator it;
-+
-+ for (it = d->filePathHash.begin(); it != d->filePathHash.end(); )
-+ {
-+ if (pairsContain(toRemove, it.value()))
-+ {
-+ it = d->filePathHash.erase(it);
-+ }
-+ else
-+ {
-+ ++it;
-+ }
-+ }
-+ }
-+}
-+
-+ImageModelIncrementalUpdater::ImageModelIncrementalUpdater(ImageModel::Private* d)
-+{
-+ oldIds = d->idHash;
-+ oldExtraValues = d->extraValues;
-+}
-+
-+void ImageModelIncrementalUpdater::appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
-+{
-+ if (extraValues.isEmpty())
-+ {
-+ foreach(const ImageInfo& info, infos)
-+ {
-+ QHash<qlonglong,int>::iterator it = oldIds.find(info.id());
-+
-+ if (it != oldIds.end())
-+ {
-+ oldIds.erase(it);
-+ }
-+ else
-+ {
-+ newInfos << info;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ for (int i=0; i<infos.size(); ++i)
-+ {
-+ const ImageInfo& info = infos.at(i);
-+ bool found = false;
-+ QHash<qlonglong,int>::iterator it;
-+
-+ for (it = oldIds.find(info.id()); it != oldIds.end() && it.key() == info.id(); ++it)
-+ {
-+ // first check is for bug #262596. Not sure if needed.
-+ if (it.value() < oldExtraValues.size() && extraValues.at(i) == oldExtraValues.at(it.value()))
-+ {
-+ found = true;
-+ break;
-+ }
-+ }
-+
-+ if (found)
-+ {
-+ oldIds.erase(it);
-+ // do not erase from oldExtraValues - oldIds is a hash id -> index.
-+ }
-+ else
-+ {
-+ newInfos << info;
-+ newExtraValues << extraValues.at(i);
-+ }
-+ }
-+ }
-+}
-+
-+void ImageModelIncrementalUpdater::aboutToBeRemovedInModel(const IntPairList& toRemove)
-+{
-+ modelRemovals << toRemove;
-+}
-+
-+QList<QPair<int, int> > ImageModelIncrementalUpdater::oldIndexes()
-+{
-+ // first, apply all changes to indexes by direct removal in model
-+ // while the updater was active
-+ foreach(const IntPairList& list, modelRemovals)
-+ {
-+ int removedRows = 0, offset = 0;
-+
-+ foreach(const IntPair& pair, list)
-+ {
-+ const int begin = pair.first - offset;
-+ const int end = pair.second - offset; // inclusive
-+ removedRows = end - begin + 1;
-+
-+ // when removing from the list, all subsequent indexes are affected
-+ offset += removedRows;
-+
-+ // update idHash - which points to indexes of d->infos, and these change now!
-+ QHash<qlonglong, int>::iterator it;
-+
-+ for (it = oldIds.begin(); it != oldIds.end(); )
-+ {
-+ if (it.value() >= begin)
-+ {
-+ if (it.value() > end)
-+ {
-+ // after the removed interval: adjust index
-+ it.value() -= removedRows;
-+ }
-+ else
-+ {
-+ // in the removed interval
-+ it = oldIds.erase(it);
-+ continue;
-+ }
-+ }
-+
-+ ++it;
-+ }
-+ }
-+ }
-+
-+ modelRemovals.clear();
-+
-+ return toContiguousPairs(oldIds.values());
-+}
-+
-+QList<QPair<int, int> > ImageModelIncrementalUpdater::toContiguousPairs(const QList<int>& unsorted)
-+{
-+ // Take the given indices and return them as contiguous pairs [begin, end]
-+
-+ QList<QPair<int, int> > pairs;
-+
-+ if (unsorted.isEmpty())
-+ {
-+ return pairs;
-+ }
-+
-+ QList<int> indices(unsorted);
-+ qSort(indices);
-+
-+ QPair<int, int> pair(indices.first(), indices.first());
-+
-+ for (int i=1; i<indices.size(); ++i)
-+ {
-+ const int &index = indices.at(i);
-+
-+ if (index == pair.second + 1)
-+ {
-+ pair.second = index;
-+ continue;
-+ }
-+
-+ pairs << pair; // insert last pair
-+ pair.first = index;
-+ pair.second = index;
-+ }
-+
-+ pairs << pair;
-+
-+ return pairs;
-+}
-+
-+// ------------ QAbstractItemModel implementation -------------
-+
-+QVariant ImageModel::data(const QModelIndex& index, int role) const
-+{
-+ if (!d->isValid(index))
-+ {
-+ return QVariant();
-+ }
-+
-+ switch (role)
-+ {
-+ case Qt::DisplayRole:
-+ case Qt::ToolTipRole:
-+ return d->infos.at(index.row()).name();
-+
-+ case ImageModelPointerRole:
-+ return QVariant::fromValue(const_cast<ImageModel*>(this));
-+
-+ case ImageModelInternalId:
-+ return index.row();
-+
-+ case CreationDateRole:
-+ return d->infos.at(index.row()).dateTime();
-+
-+ case ExtraDataRole:
-+
-+ if (d->extraValueValid(index))
-+ {
-+ return d->extraValues.at(index.row());
-+ }
-+ else
-+ {
-+ return QVariant();
-+ }
-+
-+ case ExtraDataDuplicateCount:
-+ {
-+ qlonglong id = d->infos.at(index.row()).id();
-+ return numberOfIndexesForImageId(id);
-+ }
-+ }
-+
-+ return QVariant();
-+}
-+
-+QVariant ImageModel::headerData(int section, Qt::Orientation orientation, int role) const
-+{
-+ Q_UNUSED(section)
-+ Q_UNUSED(orientation)
-+ Q_UNUSED(role)
-+ return QVariant();
-+}
-+
-+int ImageModel::rowCount(const QModelIndex& parent) const
-+{
-+ if (parent.isValid())
-+ {
-+ return 0;
-+ }
-+
-+ return d->infos.size();
-+}
-+
-+Qt::ItemFlags ImageModel::flags(const QModelIndex& index) const
-+{
-+ if (!d->isValid(index))
-+ {
-+ return 0;
-+ }
-+
-+ Qt::ItemFlags f = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
-+
-+ f |= dragDropFlags(index);
-+
-+ return f;
-+}
-+
-+QModelIndex ImageModel::index(int row, int column, const QModelIndex& parent) const
-+{
-+ if (column != 0 || row < 0 || parent.isValid() || row >= d->infos.size())
-+ {
-+ return QModelIndex();
-+ }
-+
-+ return createIndex(row, 0);
-+}
-+
-+// ------------ Database watch -------------
-+
-+void ImageModel::slotImageChange(const ImageChangeset& changeset)
-+{
-+ if (d->infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ if (d->watchFlags & changeset.changes())
-+ {
-+ QItemSelection items;
-+
-+ foreach(const qlonglong& id, changeset.ids())
-+ {
-+ QModelIndex index = indexForImageId(id);
-+
-+ if (index.isValid())
-+ {
-+ items.select(index, index);
-+ }
-+ }
-+
-+ if (!items.isEmpty())
-+ {
-+ emitDataChangedForSelection(items);
-+ emit imageChange(changeset, items);
-+ }
-+ }
-+}
-+
-+void ImageModel::slotImageTagChange(const ImageTagChangeset& changeset)
-+{
-+ if (d->infos.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ QItemSelection items;
-+
-+ foreach(const qlonglong& id, changeset.ids())
-+ {
-+ QModelIndex index = indexForImageId(id);
-+
-+ if (index.isValid())
-+ {
-+ items.select(index, index);
-+ }
-+ }
-+
-+ if (!items.isEmpty())
-+ {
-+ emitDataChangedForSelection(items);
-+ emit imageTagChange(changeset, items);
-+ }
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagemodel.h b/libs/database/models/imagemodel.h
-new file mode 100644
-index 0000000..dcf94c2
---- /dev/null
-+++ b/libs/database/models/imagemodel.h
-@@ -0,0 +1,364 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGEMODEL_H
-+#define IMAGEMODEL_H
-+
-+// Qt includes
-+
-+#include <QAbstractListModel>
-+
-+// Local includes
-+
-+#include "dragdropimplementations.h"
-+#include "imageinfo.h"
-+#include "digikam_export.h"
-+
-+class QItemSelection;
-+
-+namespace Digikam
-+{
-+
-+class ImageChangeset;
-+class ImageTagChangeset;
-+
-+namespace DatabaseFields
-+{
-+class Set;
-+}
-+
-+class DIGIKAM_DATABASE_EXPORT ImageModel : public QAbstractListModel, public DragDropModelImplementation
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ enum ImageModelRoles
-+ {
-+ /// An ImageModel* pointer to this model
-+ ImageModelPointerRole = Qt::UserRole,
-+ ImageModelInternalId = Qt::UserRole + 1,
-+ /// Returns a thumbnail pixmap. May be implemented by subclasses.
-+ /// Returns either a valid pixmap or a null QVariant.
-+ ThumbnailRole = Qt::UserRole + 2,
-+ /// Returns a QDateTime with the creation date
-+ CreationDateRole = Qt::UserRole + 3,
-+ /// Return (optional) extraData field
-+ ExtraDataRole = Qt::UserRole + 5,
-+ /// Returns the number of duplicate indexes for the same image id
-+ ExtraDataDuplicateCount = Qt::UserRole + 6,
-+
-+ // Roles which are defined here but not implemented by ImageModel
-+ /// Returns position of item in Left Light Table preview.
-+ LTLeftPanelRole = Qt::UserRole + 50,
-+ /// Returns position of item in Right Light Table preview.
-+ LTRightPanelRole = Qt::UserRole + 51,
-+
-+ // For use by subclasses
-+ SubclassRoles = Qt::UserRole + 100,
-+ // For use by filter models
-+ FilterModelRoles = Qt::UserRole + 500
-+ };
-+
-+public:
-+
-+ explicit ImageModel(QObject* parent = 0);
-+ ~ImageModel();
-+
-+ /** If a cache is kept, lookup by file path is fast,
-+ * without a cache it is O(n). Default is false.
-+ */
-+ void setKeepsFilePathCache(bool keepCache);
-+ bool keepsFilePathCache() const;
-+
-+ /** Set a set of database fields to watch.
-+ * If either of these is changed, dataChanged() will be emitted.
-+ * Default is no flag (no signal will be emitted).
-+ */
-+ void setWatchFlags(const DatabaseFields::Set& set);
-+
-+ /** Returns the ImageInfo object, reference or image id from the underlying data
-+ * pointed to by the index.
-+ * If the index is not valid, imageInfo will return a null ImageInfo, imageId will
-+ * return 0, imageInfoRef must not be called with an invalid index.
-+ */
-+ ImageInfo imageInfo(const QModelIndex& index) const;
-+ ImageInfo& imageInfoRef(const QModelIndex& index) const;
-+ qlonglong imageId(const QModelIndex& index) const;
-+ QList<ImageInfo> imageInfos(const QList<QModelIndex>& indexes) const;
-+ QList<qlonglong> imageIds(const QList<QModelIndex>& indexes) const;
-+
-+ /** Returns the ImageInfo object, reference or image id from the underlying data
-+ * of the given row (parent is the invalid QModelIndex, column is 0).
-+ * Note that imageInfoRef will crash if index is invalid.
-+ */
-+ ImageInfo imageInfo(int row) const;
-+ ImageInfo& imageInfoRef(int row) const;
-+ qlonglong imageId(int row) const;
-+
-+ /** Return the index for the given ImageInfo or id, if contained in this model.
-+ */
-+ QModelIndex indexForImageInfo(const ImageInfo& info) const;
-+ QModelIndex indexForImageInfo(const ImageInfo& info, const QVariant& extraValue) const;
-+ QModelIndex indexForImageId(qlonglong id) const;
-+ QModelIndex indexForImageId(qlonglong id, const QVariant& extraValue) const;
-+ QList<QModelIndex> indexesForImageInfo(const ImageInfo& info) const;
-+ QList<QModelIndex> indexesForImageId(qlonglong id) const;
-+
-+ int numberOfIndexesForImageInfo(const ImageInfo& info) const;
-+ int numberOfIndexesForImageId(qlonglong id) const;
-+
-+ /** Returns the index or ImageInfo object from the underlying data
-+ * for the given file path. This is fast if keepsFilePathCache is enabled.
-+ * The file path is as returned by ImageInfo.filePath().
-+ * In case of multiple occurrences of the same file, the simpler variants return
-+ * any one found first, use the QList methods to retrieve all occurrences.
-+ */
-+ QModelIndex indexForPath(const QString& filePath) const;
-+ ImageInfo imageInfo(const QString& filePath) const;
-+ QList<QModelIndex> indexesForPath(const QString& filePath) const;
-+ QList<ImageInfo> imageInfos(const QString& filePath) const;
-+
-+ /** Main entry point for subclasses adding image infos to the model.
-+ * If you list entries not unique per image id, you must add an extraValue
-+ * so that every entry is unique by imageId and extraValues.
-+ * Please note that these methods do not prevent addition of duplicate entries.
-+ */
-+ void addImageInfo(const ImageInfo& info);
-+ void addImageInfos(const QList<ImageInfo>& infos);
-+ void addImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+
-+ /** Clears image infos and resets model.
-+ */
-+ void clearImageInfos();
-+
-+ /** Clears and adds the infos.
-+ */
-+ void setImageInfos(const QList<ImageInfo>& infos);
-+
-+ /**
-+ * Directly remove the given indexes or infos from the model.
-+ */
-+ void removeIndex(const QModelIndex& indexes);
-+ void removeIndexes(const QList<QModelIndex>& indexes);
-+ void removeImageInfo(const ImageInfo& info);
-+ void removeImageInfos(const QList<ImageInfo>& infos);
-+ void removeImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+
-+ /**
-+ * addImageInfo() is asynchronous if a prepocessor is set.
-+ * This method first adds the info, synchronously.
-+ * Only afterwards, the preprocessor will have the opportunity to process it.
-+ * This method also bypasses any incremental updates.
-+ * Please note that these methods do not prevent addition of duplicate entries.
-+ */
-+ void addImageInfoSynchronously(const ImageInfo& info);
-+ void addImageInfosSynchronously(const QList<ImageInfo>& infos);
-+ void addImageInfosSynchronously(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+
-+ /**
-+ * Add the given entries. Method returns immediately, the
-+ * addition may happen later asynchronously.
-+ * These methods prevent the addition of duplicate entries.
-+ */
-+ void ensureHasImageInfo(const ImageInfo& info);
-+ void ensureHasImageInfos(const QList<ImageInfo>& infos);
-+ void ensureHasImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+
-+ /**
-+ * Ensure that all images grouped on the given leader are contained in the model.
-+ */
-+ void ensureHasGroupedImages(const ImageInfo& groupLeader);
-+
-+ QList<ImageInfo> imageInfos() const;
-+ QList<qlonglong> imageIds() const;
-+ QList<ImageInfo> uniqueImageInfos() const;
-+
-+ bool hasImage(qlonglong id) const;
-+ bool hasImage(const ImageInfo& info) const;
-+ bool hasImage(const ImageInfo& info, const QVariant& extraValue) const;
-+ bool hasImage(qlonglong id, const QVariant& extraValue) const;
-+
-+ bool isEmpty() const;
-+
-+ // Drag and Drop
-+ DECLARE_MODEL_DRAG_DROP_METHODS
-+
-+ /**
-+ * Install an object as a preprocessor for ImageInfos added to this model.
-+ * For every QList of ImageInfos added to addImageInfo, the signal preprocess()
-+ * will be emitted. The preprocessor may process the items and shall then readd
-+ * them by calling reAddImageInfos(). It may take some time to process.
-+ * It shall discard any held infos when the modelReset() signal is sent.
-+ * It shall call readdFinished() when no reset occurred and all infos on the way have been readded.
-+ * This means that only after calling this method, you shall make three connections
-+ * (preprocess -> your slot, your signal -> reAddImageInfos, your signal -> reAddingFinished)
-+ * and make or already hold a connection modelReset() -> your slot.
-+ * There is only one preprocessor at a time, a previously set object will be disconnected.
-+ */
-+ void setPreprocessor(QObject* processor);
-+ void unsetPreprocessor(QObject* processor);
-+
-+ /**
-+ * Returns true if this model is currently refreshing.
-+ * For a preprocessor this means that, although the preprocessor may currently have
-+ * processed all it got, more batches are to be expected.
-+ */
-+ bool isRefreshing() const;
-+
-+ /**
-+ * Enable sending of imageInfosAboutToBeRemoved and imageInfosRemoved signals.
-+ * Default: false
-+ */
-+ void setSendRemovalSignals(bool send);
-+
-+ virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
-+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
-+ virtual Qt::ItemFlags flags(const QModelIndex& index) const;
-+ virtual QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
-+
-+ /** Retrieves the imageInfo object from the data() method of the given index.
-+ * The index may be from a QSortFilterProxyModel as long as an ImageModel is at the end. */
-+ static ImageInfo retrieveImageInfo(const QModelIndex& index);
-+ static qlonglong retrieveImageId(const QModelIndex& index);
-+
-+Q_SIGNALS:
-+
-+ /** Informs that ImageInfos will be added to the model.
-+ * This signal is sent before the model data is changed and views are informed.
-+ */
-+ void imageInfosAboutToBeAdded(const QList<ImageInfo>& infos);
-+
-+ /** Informs that ImageInfos have been added to the model.
-+ * This signal is sent after the model data is changed and views are informed.
-+ */
-+ void imageInfosAdded(const QList<ImageInfo>& infos);
-+
-+ /** Informs that ImageInfos will be removed from the model.
-+ * This signal is sent before the model data is changed and views are informed.
-+ * Note: You need to explicitly enable sending of this signal. It is not sent
-+ * in clearImageInfos().
-+ */
-+ void imageInfosAboutToBeRemoved(const QList<ImageInfo>& infos);
-+
-+ /** Informs that ImageInfos have been removed from the model.
-+ * This signal is sent after the model data is changed and views are informed. *
-+ * Note: You need to explicitly enable sending of this signal. It is not sent
-+ * in clearImageInfos().
-+ */
-+ void imageInfosRemoved(const QList<ImageInfo>& infos);
-+
-+ /** Connect to this signal only if you are the current preprocessor.
-+ */
-+ void preprocess(const QList<ImageInfo>& infos, const QList<QVariant>&);
-+ void processAdded(const QList<ImageInfo>& infos, const QList<QVariant>&);
-+
-+ /** If an ImageChangeset affected indexes of this model with changes as set in watchFlags(),
-+ * this signal contains the changeset and the affected indexes.
-+ */
-+ void imageChange(const ImageChangeset&, const QItemSelection&);
-+
-+ /** If an ImageTagChangeset affected indexes of this model,
-+ * this signal contains the changeset and the affected indexes.
-+ */
-+ void imageTagChange(const ImageTagChangeset&, const QItemSelection&);
-+
-+ /** Signals that the model is right now ready to start an incremental refresh.
-+ * This is guaranteed only for the scope of emitting this signal.
-+ */
-+ void readyForIncrementalRefresh();
-+
-+ /** Signals that the model has finished currently with all scheduled
-+ * refreshing, full or incremental, and all preprocessing.
-+ * The model is in polished, clean situation right now.
-+ */
-+ void allRefreshingFinished();
-+
-+public Q_SLOTS:
-+
-+ void reAddImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void reAddingFinished();
-+
-+protected:
-+
-+ /** Subclasses that add ImageInfos in batches shall call startRefresh()
-+ * when they start sending batches and finishRefresh() when they have finished.
-+ * No incremental refreshes will be started while listing.
-+ * A clearImageInfos() always stops listing, calling finishRefresh() is then not necessary.
-+ */
-+ void startRefresh();
-+ void finishRefresh();
-+
-+ /** As soon as the model is ready to start an incremental refresh, the signal
-+ * readyForIncrementalRefresh() will be emitted. The signal will be emitted inline
-+ * if the model is ready right now.
-+ */
-+ void requestIncrementalRefresh();
-+ bool hasIncrementalRefreshPending() const;
-+
-+ /** Starts an incremental refresh operation. You shall only call this method from a slot
-+ * connected to readyForIncrementalRefresh(). To initiate an incremental refresh,
-+ * call requestIncrementalRefresh().
-+ */
-+ void startIncrementalRefresh();
-+ void finishIncrementalRefresh();
-+
-+ void emitDataChangedForAll();
-+ void emitDataChangedForSelection(const QItemSelection& selection);
-+
-+ // Called when the internal storage is cleared
-+ virtual void imageInfosCleared() {};
-+
-+ // Called before rowsAboutToBeRemoved
-+ virtual void imageInfosAboutToBeRemoved(int /*begin*/, int /*end*/) {};
-+
-+protected Q_SLOTS:
-+
-+ virtual void slotImageChange(const ImageChangeset& changeset);
-+ virtual void slotImageTagChange(const ImageTagChangeset& changeset);
-+
-+private:
-+
-+ void appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void appendInfosChecked(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void publiciseInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-+ void cleanSituationChecks();
-+ void removeRowPairsWithCheck(const QList<QPair<int, int> >& toRemove);
-+ void removeRowPairs(const QList<QPair<int, int> >& toRemove);
-+
-+public:
-+
-+ // Declared public because it's used in ImageModelIncrementalUpdater class
-+ class Private;
-+
-+private:
-+
-+ Private* const d;
-+};
-+
-+} // namespace Digikam
-+
-+Q_DECLARE_METATYPE(Digikam::ImageModel*)
-+
-+#endif // IMAGEMODEL_H
-diff --git a/libs/database/models/imagesortsettings.cpp b/libs/database/models/imagesortsettings.cpp
-new file mode 100644
-index 0000000..39ee6e1
---- /dev/null
-+++ b/libs/database/models/imagesortsettings.cpp
-@@ -0,0 +1,400 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Filter values for use with ImageFilterModel
-+ *
-+ * Copyright (C) 2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagesortsettings.h"
-+
-+// Qt includes
-+
-+#include <QDateTime>
-+#include <QRectF>
-+
-+// Local includes
-+
-+#include "coredbfields.h"
-+#include "imageinfo.h"
-+
-+namespace Digikam
-+{
-+
-+ImageSortSettings::ImageSortSettings()
-+{
-+ categorizationMode = NoCategories;
-+ categorizationSortOrder = DefaultOrder;
-+ categorizationCaseSensitivity = Qt::CaseSensitive;
-+ sortRole = SortByFileName;
-+ sortOrder = DefaultOrder;
-+ strTypeNatural = true;
-+ sortCaseSensitivity = Qt::CaseSensitive;
-+ currentCategorizationSortOrder = Qt::AscendingOrder;
-+ currentSortOrder = Qt::AscendingOrder;
-+}
-+
-+bool ImageSortSettings::operator==(const ImageSortSettings& other) const
-+{
-+ return
-+ categorizationMode == other.categorizationMode &&
-+ categorizationSortOrder == other.categorizationSortOrder &&
-+ categorizationCaseSensitivity == other.categorizationCaseSensitivity &&
-+ sortRole == other.sortRole &&
-+ sortOrder == other.sortOrder &&
-+ sortCaseSensitivity == other.sortCaseSensitivity;
-+}
-+
-+void ImageSortSettings::setCategorizationMode(CategorizationMode mode)
-+{
-+ categorizationMode = mode;
-+
-+ if (categorizationSortOrder == DefaultOrder)
-+ {
-+ currentCategorizationSortOrder = defaultSortOrderForCategorizationMode(categorizationMode);
-+ }
-+}
-+
-+void ImageSortSettings::setCategorizationSortOrder(SortOrder order)
-+{
-+ categorizationSortOrder = order;
-+
-+ if (categorizationSortOrder == DefaultOrder)
-+ {
-+ currentCategorizationSortOrder = defaultSortOrderForCategorizationMode(categorizationMode);
-+ }
-+ else
-+ {
-+ currentCategorizationSortOrder = (Qt::SortOrder)categorizationSortOrder;
-+ }
-+}
-+
-+void ImageSortSettings::setSortRole(SortRole role)
-+{
-+ sortRole = role;
-+
-+ if (sortOrder == DefaultOrder)
-+ {
-+ currentSortOrder = defaultSortOrderForSortRole(sortRole);
-+ }
-+}
-+
-+void ImageSortSettings::setSortOrder(SortOrder order)
-+{
-+ sortOrder = order;
-+
-+ if (sortOrder == DefaultOrder)
-+ {
-+ currentSortOrder = defaultSortOrderForSortRole(sortRole);
-+ }
-+ else
-+ {
-+ currentSortOrder = (Qt::SortOrder)order;
-+ }
-+}
-+
-+void ImageSortSettings::setStringTypeNatural(bool natural)
-+{
-+ strTypeNatural = natural;
-+}
-+
-+Qt::SortOrder ImageSortSettings::defaultSortOrderForCategorizationMode(CategorizationMode mode)
-+{
-+ switch (mode)
-+ {
-+ case NoCategories:
-+ case OneCategory:
-+ case CategoryByAlbum:
-+ case CategoryByFormat:
-+ default:
-+ return Qt::AscendingOrder;
-+ }
-+}
-+
-+Qt::SortOrder ImageSortSettings::defaultSortOrderForSortRole(SortRole role)
-+{
-+ switch (role)
-+ {
-+ case SortByFileName:
-+ case SortByFilePath:
-+ return Qt::AscendingOrder;
-+ case SortByFileSize:
-+ return Qt::DescendingOrder;
-+ case SortByModificationDate:
-+ case SortByCreationDate:
-+ return Qt::AscendingOrder;
-+ case SortByRating:
-+ case SortByImageSize:
-+ return Qt::DescendingOrder;
-+ case SortByAspectRatio:
-+ return Qt::DescendingOrder;
-+ case SortBySimilarity:
-+ return Qt::DescendingOrder;
-+ default:
-+ return Qt::AscendingOrder;
-+ }
-+}
-+
-+int ImageSortSettings::compareCategories(const ImageInfo& left, const ImageInfo& right) const
-+{
-+ switch (categorizationMode)
-+ {
-+ case NoCategories:
-+ case OneCategory:
-+ return 0;
-+ case CategoryByAlbum:
-+ {
-+ int leftAlbum = left.albumId();
-+ int rightAlbum = right.albumId();
-+
-+ // return comparation result
-+ if (leftAlbum == rightAlbum)
-+ {
-+ return 0;
-+ }
-+ else if (lessThanByOrder(leftAlbum, rightAlbum, currentCategorizationSortOrder))
-+ {
-+ return -1;
-+ }
-+ else
-+ {
-+ return 1;
-+ }
-+ }
-+ case CategoryByFormat:
-+ {
-+ return naturalCompare(left.format(), right.format(),
-+ currentCategorizationSortOrder, categorizationCaseSensitivity, strTypeNatural);
-+ }
-+ default:
-+ return 0;
-+ }
-+}
-+
-+bool ImageSortSettings::lessThan(const ImageInfo& left, const ImageInfo& right) const
-+{
-+ int result = compare(left, right, sortRole);
-+
-+ if (result != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ // are they identical?
-+ if (left == right)
-+ {
-+ return false;
-+ }
-+
-+ // If left and right equal for first sort order, use a hierarchy of all sort orders
-+ if ( (result = compare(left, right, SortByFileName)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ if ( (result = compare(left, right, SortByCreationDate)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ if ( (result = compare(left, right, SortByModificationDate)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ if ( (result = compare(left, right, SortByFilePath)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ if ( (result = compare(left, right, SortByFileSize)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ if ( (result = compare(left, right, SortBySimilarity)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ return false;
-+}
-+
-+int ImageSortSettings::compare(const ImageInfo& left, const ImageInfo& right) const
-+{
-+ return compare(left, right, sortRole);
-+}
-+
-+int ImageSortSettings::compare(const ImageInfo& left, const ImageInfo& right, SortRole role) const
-+{
-+ switch (role)
-+ {
-+ case SortByFileName:
-+ {
-+ bool versioning = (left.name().contains(QLatin1String("_v"), Qt::CaseInsensitive) ||
-+ right.name().contains(QLatin1String("_v"), Qt::CaseInsensitive));
-+ return naturalCompare(left.name(), right.name(), currentSortOrder, sortCaseSensitivity, strTypeNatural, versioning);
-+ }
-+ case SortByFilePath:
-+ return naturalCompare(left.filePath(), right.filePath(), currentSortOrder, sortCaseSensitivity, strTypeNatural);
-+ case SortByFileSize:
-+ return compareByOrder(left.fileSize(), right.fileSize(), currentSortOrder);
-+ case SortByModificationDate:
-+ return compareByOrder(left.modDateTime(), right.modDateTime(), currentSortOrder);
-+ case SortByCreationDate:
-+ return compareByOrder(left.dateTime(), right.dateTime(), currentSortOrder);
-+ case SortByRating:
-+ // I have the feeling that inverting the sort order for rating is the natural order
-+ return - compareByOrder(left.rating(), right.rating(), currentSortOrder);
-+ case SortByImageSize:
-+ {
-+ QSize leftSize = left.dimensions();
-+ QSize rightSize = right.dimensions();
-+ int leftPixels = leftSize.width() * leftSize.height();
-+ int rightPixels = rightSize.width() * rightSize.height();
-+ return compareByOrder(leftPixels, rightPixels, currentSortOrder);
-+ }
-+ case SortByAspectRatio:
-+ {
-+ QSize leftSize = left.dimensions();
-+ QSize rightSize = right.dimensions();
-+ int leftAR = (double(leftSize.width()) / double(leftSize.height())) * 1000000;
-+ int rightAR = (double(rightSize.width()) / double(rightSize.height())) * 1000000;
-+ return compareByOrder(leftAR, rightAR, currentSortOrder);
-+ }
-+ case SortBySimilarity:
-+ {
-+ qlonglong leftReferenceImageId = left.currentReferenceImage();
-+ qlonglong rightReferenceImageId = right.currentReferenceImage();
-+ // make sure that the original image has always the highest similarity.
-+ double leftSimilarity = left.id() == leftReferenceImageId ? 1.1 : left.currentSimilarity();
-+ double rightSimilarity = right.id() == rightReferenceImageId ? 1.1 : right.currentSimilarity();
-+ return compareByOrder(leftSimilarity, rightSimilarity, currentSortOrder);
-+ }
-+ default:
-+ return 1;
-+ }
-+}
-+
-+bool ImageSortSettings::lessThan(const QVariant& left, const QVariant& right) const
-+{
-+ if (left.type() != right.type())
-+ {
-+ return false;
-+ }
-+
-+ switch (left.type())
-+ {
-+ case QVariant::Int:
-+ return compareByOrder(left.toInt(), right.toInt(), currentSortOrder);
-+ case QVariant::UInt:
-+ return compareByOrder(left.toUInt(), right.toUInt(), currentSortOrder);
-+ case QVariant::LongLong:
-+ return compareByOrder(left.toLongLong(), right.toLongLong(), currentSortOrder);
-+ case QVariant::ULongLong:
-+ return compareByOrder(left.toULongLong(), right.toULongLong(), currentSortOrder);
-+ case QVariant::Double:
-+ return compareByOrder(left.toDouble(), right.toDouble(), currentSortOrder);
-+ case QVariant::Date:
-+ return compareByOrder(left.toDate(), right.toDate(), currentSortOrder);
-+ case QVariant::DateTime:
-+ return compareByOrder(left.toDateTime(), right.toDateTime(), currentSortOrder);
-+ case QVariant::Time:
-+ return compareByOrder(left.toTime(), right.toTime(), currentSortOrder);
-+ case QVariant::Rect:
-+ case QVariant::RectF:
-+ {
-+ QRectF rectLeft = left.toRectF();
-+ QRectF rectRight = right.toRectF();
-+ int result;
-+
-+ if ((result = compareByOrder(rectLeft.top(), rectRight.top(), currentSortOrder)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ if ((result = compareByOrder(rectLeft.left(), rectRight.left(), currentSortOrder)) != 0)
-+ {
-+ return result < 0;
-+ }
-+
-+ QSizeF sizeLeft = rectLeft.size(), sizeRight = rectRight.size();
-+
-+ if ((result = compareByOrder(sizeLeft.width()*sizeLeft.height(), sizeRight.width()*sizeRight.height(), currentSortOrder)) != 0)
-+ {
-+ return result < 0;
-+ }
-+ // FIXME: fall through?? If not, add "break" here
-+ }
-+ default:
-+ return naturalCompare(left.toString(), right.toString(), currentSortOrder, sortCaseSensitivity, strTypeNatural);
-+ }
-+}
-+
-+DatabaseFields::Set ImageSortSettings::watchFlags() const
-+{
-+ DatabaseFields::Set set;
-+
-+ switch (sortRole)
-+ {
-+ case SortByFileName:
-+ set |= DatabaseFields::Name;
-+ break;
-+ case SortByFilePath:
-+ set |= DatabaseFields::Name;
-+ break;
-+ case SortByFileSize:
-+ set |= DatabaseFields::FileSize;
-+ break;
-+ case SortByModificationDate:
-+ set |= DatabaseFields::ModificationDate;
-+ break;
-+ case SortByCreationDate:
-+ set |= DatabaseFields::CreationDate;
-+ break;
-+ case SortByRating:
-+ set |= DatabaseFields::Rating;
-+ break;
-+ case SortByImageSize:
-+ set |= DatabaseFields::Width | DatabaseFields::Height;
-+ break;
-+ case SortByAspectRatio:
-+ set |= DatabaseFields::Width | DatabaseFields::Height;
-+ break;
-+ case SortBySimilarity:
-+ // TODO: Not sure what to do here....
-+ set |= DatabaseFields::Name;
-+ break;
-+ }
-+
-+ switch (categorizationMode)
-+ {
-+ case NoCategories:
-+ case OneCategory:
-+ case CategoryByAlbum:
-+ break;
-+ case CategoryByFormat:
-+ set |= DatabaseFields::Format;
-+ break;
-+ }
-+
-+ return set;
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagesortsettings.h b/libs/database/models/imagesortsettings.h
-new file mode 100644
-index 0000000..2a5fd8c
---- /dev/null
-+++ b/libs/database/models/imagesortsettings.h
-@@ -0,0 +1,225 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-05-31
-+ * Description : Sort settings for use with ImageFilterModel
-+ *
-+ * Copyright (C) 2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGESORTSETTINGS_H
-+#define IMAGESORTSETTINGS_H
-+
-+// Qt includes
-+
-+#include <QHash>
-+#include <QList>
-+#include <QMap>
-+#include <QString>
-+#include <QCollator>
-+
-+// Local includes
-+
-+#include "digikam_export.h"
-+
-+namespace Digikam
-+{
-+
-+class ImageInfo;
-+
-+namespace DatabaseFields
-+{
-+ class Set;
-+}
-+
-+class DIGIKAM_DATABASE_EXPORT ImageSortSettings
-+{
-+public:
-+
-+ ImageSortSettings();
-+
-+ bool operator==(const ImageSortSettings& other) const;
-+
-+ /** Compares the categories of left and right.
-+ * Return -1 if left is less than right, 0 if both fall in the same category,
-+ * and 1 if left is greater than right.
-+ * Adheres to set categorization mode and current category sort order.
-+ */
-+ int compareCategories(const ImageInfo& left, const ImageInfo& right) const;
-+
-+ /** Returns true if left is less than right.
-+ * Adheres to current sort role and sort order.
-+ */
-+ bool lessThan(const ImageInfo& left, const ImageInfo& right) const;
-+
-+ /** Compares the ImageInfos left and right.
-+ * Return -1 if left is less than right, 1 if left is greater than right,
-+ * and 0 if left equals right comparing the current sort role's value.
-+ * Adheres to set sort role and sort order.
-+ */
-+ int compare(const ImageInfo& left, const ImageInfo& right) const;
-+
-+ /** Returns true if left QVariant is less than right.
-+ * Adheres to current sort role and sort order.
-+ * Use for extraValue, if necessary.
-+ */
-+ bool lessThan(const QVariant& left, const QVariant& right) const;
-+
-+ enum SortOrder
-+ {
-+ AscendingOrder = Qt::AscendingOrder,
-+ DescendingOrder = Qt::DescendingOrder,
-+ DefaultOrder /// sort order depends on the chosen sort role
-+ };
-+
-+ /// --- Categories ---
-+
-+ enum CategorizationMode
-+ {
-+ NoCategories, /// categorization switched off
-+ OneCategory, /// all items in one global category
-+ CategoryByAlbum,
-+ CategoryByFormat
-+ };
-+
-+ CategorizationMode categorizationMode;
-+ SortOrder categorizationSortOrder;
-+
-+ void setCategorizationMode(CategorizationMode mode);
-+ void setCategorizationSortOrder(SortOrder order);
-+
-+ /// Only Ascending or Descending, never DefaultOrder
-+ Qt::SortOrder currentCategorizationSortOrder;
-+ Qt::CaseSensitivity categorizationCaseSensitivity;
-+
-+ bool isCategorized() const { return categorizationMode >= CategoryByAlbum; }
-+
-+ /// --- Image Sorting ---
-+
-+ enum SortRole
-+ {
-+ // Note: For legacy reasons, the order of the first five entries must remain unchanged
-+ SortByFileName,
-+ SortByFilePath,
-+ SortByCreationDate,
-+ SortByFileSize,
-+ SortByRating,
-+ SortByModificationDate,
-+ SortByImageSize, // pixel number
-+ SortByAspectRatio, // width / height * 100000
-+ SortBySimilarity
-+ };
-+
-+ SortRole sortRole;
-+ SortOrder sortOrder;
-+ bool strTypeNatural;
-+
-+ void setSortRole(SortRole role);
-+ void setSortOrder(SortOrder order);
-+ void setStringTypeNatural(bool natural);
-+
-+ Qt::SortOrder currentSortOrder;
-+ Qt::CaseSensitivity sortCaseSensitivity;
-+
-+ int compare(const ImageInfo& left, const ImageInfo& right, SortRole sortRole) const;
-+
-+ // --- ---
-+
-+ static Qt::SortOrder defaultSortOrderForCategorizationMode(CategorizationMode mode);
-+ static Qt::SortOrder defaultSortOrderForSortRole(SortRole role);
-+
-+ /// --- Change notification ---
-+
-+ /** Returns database fields a change in which would affect the current sorting.
-+ */
-+ DatabaseFields::Set watchFlags() const;
-+
-+ /// --- Utilities ---
-+
-+ /** Returns a < b if sortOrder is Ascending, or b < a if order is descending.
-+ */
-+ template <typename T>
-+ static inline bool lessThanByOrder(const T& a, const T& b, Qt::SortOrder sortOrder)
-+ {
-+ if (sortOrder == Qt::AscendingOrder)
-+ {
-+ return a < b;
-+ }
-+ else
-+ {
-+ return b < a;
-+ }
-+ }
-+
-+ /** Returns the usual compare result of -1, 0, or 1 for lessThan, equals and greaterThan.
-+ */
-+ template <typename T>
-+ static inline int compareValue(const T& a, const T& b)
-+ {
-+ if (a == b)
-+ {
-+ return 0;
-+ }
-+
-+ if (a < b)
-+ {
-+ return -1;
-+ }
-+ else
-+ {
-+ return 1;
-+ }
-+ }
-+
-+ /** Takes a typical result from a compare method (0 is equal, -1 is less than, 1 is greater than)
-+ * and applies the given sort order to it.
-+ */
-+ static inline int compareByOrder(int compareResult, Qt::SortOrder sortOrder)
-+ {
-+ if (sortOrder == Qt::AscendingOrder)
-+ {
-+ return compareResult;
-+ }
-+ else
-+ {
-+ return - compareResult;
-+ }
-+ }
-+
-+ template <typename T>
-+ static inline int compareByOrder(const T& a, const T& b, Qt::SortOrder sortOrder)
-+ {
-+ return compareByOrder(compareValue(a, b), sortOrder);
-+ }
-+
-+ /** Compares the two string by natural comparison and adheres to given sort order
-+ */
-+ static inline int naturalCompare(const QString& a, const QString& b, Qt::SortOrder sortOrder,
-+ Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive,
-+ bool natural = true, bool versioning = false)
-+ {
-+ QCollator collator;
-+ collator.setNumericMode(natural);
-+ collator.setIgnorePunctuation(versioning);
-+ collator.setCaseSensitivity(caseSensitive);
-+ return (compareByOrder(collator.compare(a, b), sortOrder));
-+ }
-+};
-+
-+} // namespace Digikam
-+
-+#endif // IMAGESORTSETTINGS_H
-diff --git a/libs/database/models/imagethumbnailmodel.cpp b/libs/database/models/imagethumbnailmodel.cpp
-new file mode 100644
-index 0000000..b7f5661
---- /dev/null
-+++ b/libs/database/models/imagethumbnailmodel.cpp
-@@ -0,0 +1,323 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries with support for thumbnail loading
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imagethumbnailmodel.h"
-+
-+// Qt includes
-+
-+#include <QHash>
-+
-+// Local includes
-+
-+#include "digikam_debug.h"
-+#include "thumbnailloadthread.h"
-+#include "digikam_export.h"
-+#include "digikam_globals.h"
-+
-+namespace Digikam
-+{
-+
-+class ImageThumbnailModel::ImageThumbnailModelPriv
-+{
-+public:
-+
-+ ImageThumbnailModelPriv() :
-+ thread(0),
-+ preloadThread(0),
-+ thumbSize(0),
-+ lastGlobalThumbSize(0),
-+ preloadThumbSize(0),
-+ emitDataChanged(true)
-+ {
-+ staticListContainingThumbnailRole << ImageModel::ThumbnailRole;
-+ }
-+
-+ ThumbnailLoadThread* thread;
-+ ThumbnailLoadThread* preloadThread;
-+ ThumbnailSize thumbSize;
-+ ThumbnailSize lastGlobalThumbSize;
-+ ThumbnailSize preloadThumbSize;
-+ QRect detailRect;
-+ QVector<int> staticListContainingThumbnailRole;
-+
-+ bool emitDataChanged;
-+
-+ int preloadThumbnailSize() const
-+ {
-+ if (preloadThumbSize.size())
-+ {
-+ return preloadThumbSize.size();
-+ }
-+
-+ return thumbSize.size();
-+ }
-+};
-+
-+ImageThumbnailModel::ImageThumbnailModel(QObject* parent)
-+ : ImageModel(parent), d(new ImageThumbnailModelPriv)
-+{
-+ setKeepsFilePathCache(true);
-+}
-+
-+ImageThumbnailModel::~ImageThumbnailModel()
-+{
-+ delete d->preloadThread;
-+ delete d;
-+}
-+
-+void ImageThumbnailModel::setThumbnailLoadThread(ThumbnailLoadThread* thread)
-+{
-+ d->thread = thread;
-+
-+ connect(d->thread, SIGNAL(signalThumbnailLoaded(LoadingDescription,QPixmap)),
-+ this, SLOT(slotThumbnailLoaded(LoadingDescription,QPixmap)));
-+}
-+
-+ThumbnailLoadThread* ImageThumbnailModel::thumbnailLoadThread() const
-+{
-+ return d->thread;
-+}
-+
-+ThumbnailSize ImageThumbnailModel::thumbnailSize() const
-+{
-+ return d->thumbSize;
-+}
-+
-+void ImageThumbnailModel::setThumbnailSize(const ThumbnailSize& size)
-+{
-+ d->lastGlobalThumbSize = size;
-+ d->thumbSize = size;
-+}
-+
-+void ImageThumbnailModel::setPreloadThumbnailSize(const ThumbnailSize& size)
-+{
-+ d->preloadThumbSize = size;
-+}
-+
-+void ImageThumbnailModel::setEmitDataChanged(bool emitSignal)
-+{
-+ d->emitDataChanged = emitSignal;
-+}
-+
-+void ImageThumbnailModel::setPreloadThumbnails(bool preload)
-+{
-+ if (preload)
-+ {
-+ if (!d->preloadThread)
-+ {
-+ d->preloadThread = new ThumbnailLoadThread;
-+ d->preloadThread->setPixmapRequested(false);
-+ d->preloadThread->setPriority(QThread::LowestPriority);
-+ }
-+
-+ connect(this, SIGNAL(allRefreshingFinished()),
-+ this, SLOT(preloadAllThumbnails()));
-+ }
-+ else
-+ {
-+ delete d->preloadThread;
-+ d->preloadThread = 0;
-+ disconnect(this, SIGNAL(allRefreshingFinished()),
-+ this, SLOT(preloadAllThumbnails()));
-+ }
-+}
-+
-+void ImageThumbnailModel::prepareThumbnails(const QList<QModelIndex>& indexesToPrepare)
-+{
-+ prepareThumbnails(indexesToPrepare, d->thumbSize);
-+}
-+
-+void ImageThumbnailModel::prepareThumbnails(const QList<QModelIndex>& indexesToPrepare, const ThumbnailSize& thumbSize)
-+{
-+ if (!d->thread)
-+ {
-+ return;
-+ }
-+
-+ QList<ThumbnailIdentifier> ids;
-+ foreach(const QModelIndex& index, indexesToPrepare)
-+ {
-+ ids << imageInfoRef(index).thumbnailIdentifier();
-+ }
-+ d->thread->findGroup(ids, thumbSize.size());
-+}
-+
-+void ImageThumbnailModel::preloadThumbnails(const QList<ImageInfo>& infos)
-+{
-+ if (!d->preloadThread)
-+ {
-+ return;
-+ }
-+
-+ QList<ThumbnailIdentifier> ids;
-+ foreach(const ImageInfo& info, infos)
-+ {
-+ ids << info.thumbnailIdentifier();
-+ }
-+ d->preloadThread->pregenerateGroup(ids, d->preloadThumbnailSize());
-+}
-+
-+void ImageThumbnailModel::preloadThumbnails(const QList<QModelIndex>& indexesToPreload)
-+{
-+ if (!d->preloadThread)
-+ {
-+ return;
-+ }
-+
-+ QList<ThumbnailIdentifier> ids;
-+ foreach(const QModelIndex& index, indexesToPreload)
-+ {
-+ ids << imageInfoRef(index).thumbnailIdentifier();
-+ }
-+ d->preloadThread->stopAllTasks();
-+ d->preloadThread->pregenerateGroup(ids, d->preloadThumbnailSize());
-+}
-+
-+void ImageThumbnailModel::preloadAllThumbnails()
-+{
-+ preloadThumbnails(imageInfos());
-+}
-+
-+void ImageThumbnailModel::imageInfosCleared()
-+{
-+ if (d->preloadThread)
-+ {
-+ d->preloadThread->stopAllTasks();
-+ }
-+}
-+
-+QVariant ImageThumbnailModel::data(const QModelIndex& index, int role) const
-+{
-+ if (role == ThumbnailRole && d->thread && index.isValid())
-+ {
-+ QPixmap thumbnail;
-+ ImageInfo info = imageInfo(index);
-+ QString path = info.filePath();
-+
-+ if (info.isNull())
-+ {
-+ return QVariant(QVariant::Pixmap);
-+ }
-+
-+ if (!d->detailRect.isNull())
-+ {
-+ if (d->thread->find(info.thumbnailIdentifier(), d->detailRect, thumbnail, d->thumbSize.size()))
-+ {
-+ return thumbnail;
-+ }
-+ }
-+ else
-+ {
-+ if (d->thread->find(info.thumbnailIdentifier(), thumbnail, d->thumbSize.size()))
-+ {
-+ return thumbnail;
-+ }
-+ }
-+
-+ return QVariant(QVariant::Pixmap);
-+ }
-+
-+ return ImageModel::data(index, role);
-+}
-+
-+bool ImageThumbnailModel::setData(const QModelIndex& index, const QVariant& value, int role)
-+{
-+ if (role == ThumbnailRole)
-+ {
-+ switch (value.type())
-+ {
-+ case QVariant::Invalid:
-+ d->thumbSize = d->lastGlobalThumbSize;
-+ d->detailRect = QRect();
-+ break;
-+
-+ case QVariant::Int:
-+
-+ if (value.isNull())
-+ {
-+ d->thumbSize = d->lastGlobalThumbSize;
-+ }
-+ else
-+ {
-+ d->thumbSize = value.toInt();
-+ }
-+ break;
-+
-+ case QVariant::Rect:
-+
-+ if (value.isNull())
-+ {
-+ d->detailRect = QRect();
-+ }
-+ else
-+ {
-+ d->detailRect = value.toRect();
-+ }
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+
-+ return ImageModel::setData(index, value, role);
-+}
-+
-+void ImageThumbnailModel::slotThumbnailLoaded(const LoadingDescription& loadingDescription, const QPixmap& thumb)
-+{
-+ if (thumb.isNull())
-+ {
-+ return;
-+ }
-+
-+ // In case of multiple occurrence, we currently do not know which thumbnail is this. Signal change on all.
-+ QModelIndexList indexes;
-+ ThumbnailIdentifier thumbId = loadingDescription.thumbnailIdentifier();
-+ if (thumbId.filePath.isEmpty())
-+ {
-+ indexes = indexesForImageId(thumbId.id);
-+ }
-+ else
-+ {
-+ indexes = indexesForPath(thumbId.filePath);
-+ }
-+ foreach(const QModelIndex& index, indexes)
-+ {
-+ if (thumb.isNull())
-+ {
-+ emit thumbnailFailed(index, loadingDescription.previewParameters.size);
-+ }
-+ else
-+ {
-+ emit thumbnailAvailable(index, loadingDescription.previewParameters.size);
-+
-+ if (d->emitDataChanged)
-+ {
-+ emit dataChanged(index, index, d->staticListContainingThumbnailRole);
-+ }
-+ }
-+ }
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imagethumbnailmodel.h b/libs/database/models/imagethumbnailmodel.h
-new file mode 100644
-index 0000000..366ca65
---- /dev/null
-+++ b/libs/database/models/imagethumbnailmodel.h
-@@ -0,0 +1,140 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2009-03-05
-+ * Description : Qt item model for database entries with support for thumbnail loading
-+ *
-+ * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-+ * Copyright (C) 2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGETHUMBNAILMODEL_H
-+#define IMAGETHUMBNAILMODEL_H
-+
-+// Local includes
-+
-+#include "imagemodel.h"
-+#include "thumbnailsize.h"
-+#include "digikam_export.h"
-+
-+namespace Digikam
-+{
-+
-+class LoadingDescription;
-+class ThumbnailLoadThread;
-+
-+class DIGIKAM_DATABASE_EXPORT ImageThumbnailModel : public ImageModel
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ /**
-+ * An ImageModel that supports thumbnail loading.
-+ * You need to set a ThumbnailLoadThread to enable thumbnail loading.
-+ * Adjust the thumbnail size to your needs.
-+ * Note that setKeepsFilePathCache is enabled per default.
-+ */
-+ explicit ImageThumbnailModel(QObject* parent);
-+ ~ImageThumbnailModel();
-+
-+ /** Enable thumbnail loading and set the thread that shall be used.
-+ * The thumbnail size of this thread will be adjusted.
-+ */
-+ void setThumbnailLoadThread(ThumbnailLoadThread* thread);
-+ ThumbnailLoadThread* thumbnailLoadThread() const;
-+
-+ /// Set the thumbnail size to use
-+ void setThumbnailSize(const ThumbnailSize& thumbSize);
-+
-+ /// If you want to fix a size for preloading, do it here.
-+ void setPreloadThumbnailSize(const ThumbnailSize& thumbSize);
-+
-+ void setExifRotate(bool rotate);
-+
-+ /**
-+ * Enable emitting dataChanged() when a thumbnail becomes available.
-+ * The thumbnailAvailable() signal will be emitted in any case.
-+ * Default is true.
-+ */
-+ void setEmitDataChanged(bool emitSignal);
-+
-+ /**
-+ * Enable preloading of thumbnails:
-+ * If preloading is enabled, for every entry in the model a thumbnail generation is started.
-+ * Default: false.
-+ */
-+ void setPreloadThumbnails(bool preload);
-+
-+ ThumbnailSize thumbnailSize() const;
-+
-+ /**
-+ * Handles the ThumbnailRole.
-+ * If the pixmap is available, returns it in the QVariant.
-+ * If it still needs to be loaded, returns a null QVariant and emits
-+ * thumbnailAvailable() as soon as it is available.
-+ */
-+ virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-+
-+ /**
-+ * You can override the current thumbnail size by giving an integer value for ThumbnailRole.
-+ * Set a null QVariant to use the thumbnail size set by setThumbnailSize() again.
-+ * The index given here is ignored for this purpose.
-+ */
-+ virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::DisplayRole);
-+
-+public Q_SLOTS:
-+
-+ /** Prepare the thumbnail loading for the given indexes
-+ */
-+ void prepareThumbnails(const QList<QModelIndex>& indexesToPrepare);
-+ void prepareThumbnails(const QList<QModelIndex>& indexesToPrepare, const ThumbnailSize& thumbSize);
-+
-+ /**
-+ * Preload thumbnail for the given infos resp. indexes.
-+ * Note: Use setPreloadThumbnails to automatically preload all entries in the model.
-+ * Note: This only ensures thumbnail generation. It is not guaranteed that pixmaps
-+ * are stored in the cache. For thumbnails that are expect to be drawn immediately,
-+ * include them in prepareThumbnails().
-+ * Note: Stops preloading of previously added thumbnails.
-+ */
-+ void preloadThumbnails(const QList<ImageInfo>&);
-+ void preloadThumbnails(const QList<QModelIndex>&);
-+ void preloadAllThumbnails();
-+
-+Q_SIGNALS:
-+
-+ void thumbnailAvailable(const QModelIndex& index, int requestedSize);
-+ void thumbnailFailed(const QModelIndex& index, int requestedSize);
-+
-+protected:
-+
-+ virtual void imageInfosCleared();
-+
-+protected Q_SLOTS:
-+
-+ void slotThumbnailLoaded(const LoadingDescription& loadingDescription, const QPixmap& thumb);
-+
-+private:
-+
-+ class ImageThumbnailModelPriv;
-+ ImageThumbnailModelPriv* const d;
-+};
-+
-+} // namespace Digikam
-+
-+#endif /* IMAGETHUMBNAILMODEL_H */
-diff --git a/libs/database/models/imageversionsmodel.cpp b/libs/database/models/imageversionsmodel.cpp
-new file mode 100644
-index 0000000..e6ba582
---- /dev/null
-+++ b/libs/database/models/imageversionsmodel.cpp
-@@ -0,0 +1,183 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2010-07-13
-+ * Description : Model for image versions
-+ *
-+ * Copyright (C) 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#include "imageversionsmodel.h"
-+
-+// KDE includes
-+
-+#include <klocalizedstring.h>
-+
-+// Local includes
-+
-+#include "digikam_debug.h"
-+#include "workingwidget.h"
-+
-+namespace Digikam
-+{
-+
-+class ImageVersionsModel::Private
-+{
-+public:
-+
-+ Private()
-+ {
-+ data = 0;
-+ paintTree = false;
-+ }
-+
-+ ///Complete paths with filenames and tree level
-+ QList<QPair<QString, int> >* data;
-+ ///This is for delegate to paint it as selected
-+ QString currentSelectedImage;
-+ ///If true, the delegate will paint items as a tree
-+ ///if false, it will be painted as a list
-+ bool paintTree;
-+};
-+
-+ImageVersionsModel::ImageVersionsModel(QObject* parent)
-+ : QAbstractListModel(parent),
-+ d(new Private)
-+{
-+ d->data = new QList<QPair<QString, int> >;
-+}
-+
-+ImageVersionsModel::~ImageVersionsModel()
-+{
-+ //qDeleteAll(d->data);
-+ delete d;
-+}
-+
-+Qt::ItemFlags ImageVersionsModel::flags(const QModelIndex& index) const
-+{
-+ if (!index.isValid())
-+ {
-+ return 0;
-+ }
-+
-+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
-+}
-+
-+QVariant ImageVersionsModel::data(const QModelIndex& index, int role) const
-+{
-+ if (!index.isValid())
-+ {
-+ return QVariant();
-+ }
-+
-+ if (role == Qt::DisplayRole && !d->data->isEmpty())
-+ {
-+ return d->data->at(index.row()).first;
-+ }
-+ else if (role == Qt::UserRole && !d->data->isEmpty())
-+ {
-+ return d->data->at(index.row()).second;
-+ }
-+ else if (role == Qt::DisplayRole && d->data->isEmpty())
-+ {
-+ //TODO: make this text Italic
-+ return QVariant(QString(i18n("No image selected")));
-+ }
-+
-+ return QVariant();
-+}
-+
-+int ImageVersionsModel::rowCount(const QModelIndex& parent) const
-+{
-+ Q_UNUSED(parent)
-+ return d->data->count();
-+}
-+
-+void ImageVersionsModel::setupModelData(QList<QPair<QString, int> >& data)
-+{
-+ beginResetModel();
-+
-+ d->data->clear();
-+
-+ if (!data.isEmpty())
-+ {
-+ d->data->append(data);
-+ }
-+ else
-+ {
-+ d->data->append(qMakePair(QString(i18n("This is the original image")), 0));
-+ }
-+
-+ endResetModel();
-+}
-+
-+void ImageVersionsModel::clearModelData()
-+{
-+ beginResetModel();
-+
-+ if (!d->data->isEmpty())
-+ {
-+ d->data->clear();
-+ }
-+
-+ endResetModel();
-+}
-+
-+void ImageVersionsModel::slotAnimationStep()
-+{
-+ emit dataChanged(createIndex(0, 0), createIndex(rowCount()-1, 1));
-+}
-+
-+QString ImageVersionsModel::currentSelectedImage() const
-+{
-+ return d->currentSelectedImage;
-+}
-+
-+void ImageVersionsModel::setCurrentSelectedImage(const QString& path)
-+{
-+ d->currentSelectedImage = path;
-+}
-+
-+QModelIndex ImageVersionsModel::currentSelectedImageIndex() const
-+{
-+ return index(listIndexOf(d->currentSelectedImage), 0);
-+}
-+
-+bool ImageVersionsModel::paintTree() const
-+{
-+ return d->paintTree;
-+}
-+
-+void ImageVersionsModel::setPaintTree(bool paint)
-+{
-+ d->paintTree = paint;
-+}
-+
-+int ImageVersionsModel::listIndexOf(const QString& item) const
-+{
-+ for (int i = 0; i < d->data->size(); ++i)
-+ {
-+ if (d->data->at(i).first == item)
-+ {
-+ return i;
-+ }
-+ }
-+
-+ return -1;
-+}
-+
-+} // namespace Digikam
-diff --git a/libs/database/models/imageversionsmodel.h b/libs/database/models/imageversionsmodel.h
-new file mode 100644
-index 0000000..ed08529
---- /dev/null
-+++ b/libs/database/models/imageversionsmodel.h
-@@ -0,0 +1,75 @@
-+/* ============================================================
-+ *
-+ * This file is a part of digiKam project
-+ * http://www.digikam.org
-+ *
-+ * Date : 2010-07-13
-+ * Description : Model for image versions
-+ *
-+ * Copyright (C) 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
-+ *
-+ * 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 2, 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.
-+ *
-+ * ============================================================ */
-+
-+#ifndef IMAGEVERSIONSMODEL_H
-+#define IMAGEVERSIONSMODEL_H
-+
-+// Qt includes
-+
-+#include <QModelIndex>
-+#include <QPixmap>
-+
-+// Local includes
-+
-+#include "digikam_export.h"
-+
-+namespace Digikam
-+{
-+
-+class DIGIKAM_DATABASE_EXPORT ImageVersionsModel : public QAbstractListModel
-+{
-+ Q_OBJECT
-+
-+public:
-+
-+ explicit ImageVersionsModel(QObject* parent = 0);
-+ ~ImageVersionsModel();
-+
-+ Qt::ItemFlags flags(const QModelIndex& index) const;
-+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
-+
-+ void setupModelData(QList<QPair<QString, int> >& data);
-+ void clearModelData();
-+
-+ QString currentSelectedImage() const;
-+ void setCurrentSelectedImage(const QString& path);
-+ QModelIndex currentSelectedImageIndex() const;
-+
-+ bool paintTree() const;
-+ int listIndexOf(const QString& item) const;
-+
-+public Q_SLOTS:
-+
-+ void slotAnimationStep();
-+ void setPaintTree(bool paint);
-+
-+private:
-+
-+ class Private;
-+ Private* const d;
-+};
-+
-+} // namespace Digikam
-+
-+#endif // IMAGEVERSIONSMODEL_H
-diff --git a/libs/models/CMakeLists.txt b/libs/models/CMakeLists.txt
-index cbabfaa..804456b 100644
---- a/libs/models/CMakeLists.txt
-+++ b/libs/models/CMakeLists.txt
-@@ -9,18 +9,6 @@ if (POLICY CMP0063)
- cmake_policy(SET CMP0063 NEW)
- endif (POLICY CMP0063)
-
--set(libdatabasemodels_SRCS
-- imagemodel.cpp
-- imagefiltermodel.cpp
-- imagefiltermodelpriv.cpp
-- imagefiltermodelthreads.cpp
-- imagefiltersettings.cpp
-- imagelistmodel.cpp
-- imagesortsettings.cpp
-- imagethumbnailmodel.cpp
-- imageversionsmodel.cpp
--)
--
- set(libalbummodels_SRCS
- imagealbummodel.cpp
- imagealbumfiltermodel.cpp
-@@ -52,5 +40,4 @@ endif()
- #for digikam core lib
- add_library(digikamgenericmodels_src OBJECT ${libgenericmodels_SRCS})
-
--add_library(digikamdatabasemodels_src OBJECT ${libdatabasemodels_SRCS})
--add_library(digikammodels_src OBJECT ${libalbummodels_SRCS} ${libgenericmodels_SRCS})
-+add_library(digikammodels_src OBJECT ${libalbummodels_SRCS} ${libgenericmodels_SRCS})
-diff --git a/libs/models/imagefiltermodel.cpp b/libs/models/imagefiltermodel.cpp
-deleted file mode 100644
-index 3d57e05..0000000
---- a/libs/models/imagefiltermodel.cpp
-+++ /dev/null
-@@ -1,1116 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-- * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-- * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagefiltermodel.h"
--#include "imagefiltermodelpriv.h"
--#include "imagefiltermodelthreads.h"
--
--// Local includes
--
--#include "digikam_debug.h"
--#include "coredbaccess.h"
--#include "coredbchangesets.h"
--#include "coredbwatch.h"
--#include "imageinfolist.h"
--#include "imagemodel.h"
--
--namespace Digikam
--{
--
--ImageSortFilterModel::ImageSortFilterModel(QObject* parent)
-- : DCategorizedSortFilterProxyModel(parent), m_chainedModel(0)
--{
--}
--
--void ImageSortFilterModel::setSourceImageModel(ImageModel* source)
--{
-- if (m_chainedModel)
-- {
-- m_chainedModel->setSourceImageModel(source);
-- }
-- else
-- {
-- setDirectSourceImageModel(source);
-- }
--}
--
--void ImageSortFilterModel::setSourceFilterModel(ImageSortFilterModel* source)
--{
-- if (source)
-- {
-- ImageModel* const model = sourceImageModel();
--
-- if (model)
-- {
-- source->setSourceImageModel(model);
-- }
-- }
--
-- m_chainedModel = source;
-- setSourceModel(source);
--}
--
--void ImageSortFilterModel::setDirectSourceImageModel(ImageModel* model)
--{
-- setSourceModel(model);
--}
--
--void ImageSortFilterModel::setSourceModel(QAbstractItemModel* model)
--{
-- // made it protected, only setSourceImageModel is public
-- DCategorizedSortFilterProxyModel::setSourceModel(model);
--}
--
--ImageModel* ImageSortFilterModel::sourceImageModel() const
--{
-- if (m_chainedModel)
-- {
-- return m_chainedModel->sourceImageModel();
-- }
--
-- return static_cast<ImageModel*>(sourceModel());
--}
--
--ImageSortFilterModel* ImageSortFilterModel::sourceFilterModel() const
--{
-- return m_chainedModel;
--}
--
--ImageFilterModel* ImageSortFilterModel::imageFilterModel() const
--{
-- // reimplemented in ImageFilterModel
-- if (m_chainedModel)
-- {
-- return m_chainedModel->imageFilterModel();
-- }
--
-- return 0;
--}
--
--QModelIndex ImageSortFilterModel::mapToSourceImageModel(const QModelIndex& index) const
--{
-- if (m_chainedModel)
-- {
-- return m_chainedModel->mapToSourceImageModel(mapToSource(index));
-- }
--
-- return mapToSource(index);
--}
--
--QModelIndex ImageSortFilterModel::mapFromSourceImageModel(const QModelIndex& albummodel_index) const
--{
-- if (m_chainedModel)
-- {
-- return mapFromSource(m_chainedModel->mapFromSourceImageModel(albummodel_index));
-- }
--
-- return mapFromSource(albummodel_index);
--}
--
--
--QModelIndex ImageSortFilterModel::mapFromDirectSourceToSourceImageModel(const QModelIndex& sourceModel_index) const
--{
-- if (m_chainedModel)
-- {
-- return m_chainedModel->mapToSourceImageModel(sourceModel_index);
-- }
-- return sourceModel_index;
--}
--
--// -------------- Convenience mappers -------------------------------------------------------------------
--
--QList<QModelIndex> ImageSortFilterModel::mapListToSource(const QList<QModelIndex>& indexes) const
--{
-- QList<QModelIndex> sourceIndexes;
-- foreach(const QModelIndex& index, indexes)
-- {
-- sourceIndexes << mapToSourceImageModel(index);
-- }
-- return sourceIndexes;
--}
--
--QList<QModelIndex> ImageSortFilterModel::mapListFromSource(const QList<QModelIndex>& sourceIndexes) const
--{
-- QList<QModelIndex> indexes;
-- foreach(const QModelIndex& index, sourceIndexes)
-- {
-- indexes << mapFromSourceImageModel(index);
-- }
-- return indexes;
--}
--
--ImageInfo ImageSortFilterModel::imageInfo(const QModelIndex& index) const
--{
-- return sourceImageModel()->imageInfo(mapToSourceImageModel(index));
--}
--
--qlonglong ImageSortFilterModel::imageId(const QModelIndex& index) const
--{
-- return sourceImageModel()->imageId(mapToSourceImageModel(index));
--}
--
--QList<ImageInfo> ImageSortFilterModel::imageInfos(const QList<QModelIndex>& indexes) const
--{
-- QList<ImageInfo> infos;
-- ImageModel* const model = sourceImageModel();
--
-- foreach(const QModelIndex& index, indexes)
-- {
-- infos << model->imageInfo(mapToSourceImageModel(index));
-- }
--
-- return infos;
--}
--
--QList<qlonglong> ImageSortFilterModel::imageIds(const QList<QModelIndex>& indexes) const
--{
-- QList<qlonglong> ids;
-- ImageModel* const model = sourceImageModel();
--
-- foreach(const QModelIndex& index, indexes)
-- {
-- ids << model->imageId(mapToSourceImageModel(index));
-- }
--
-- return ids;
--}
--
--QModelIndex ImageSortFilterModel::indexForPath(const QString& filePath) const
--{
-- return mapFromSourceImageModel(sourceImageModel()->indexForPath(filePath));
--}
--
--QModelIndex ImageSortFilterModel::indexForImageInfo(const ImageInfo& info) const
--{
-- return mapFromSourceImageModel(sourceImageModel()->indexForImageInfo(info));
--}
--
--QModelIndex ImageSortFilterModel::indexForImageId(qlonglong id) const
--{
-- return mapFromSourceImageModel(sourceImageModel()->indexForImageId(id));
--}
--
--QList<ImageInfo> ImageSortFilterModel::imageInfosSorted() const
--{
-- QList<ImageInfo> infos;
-- const int size = rowCount();
-- ImageModel* const model = sourceImageModel();
--
-- for (int i=0; i<size; ++i)
-- {
-- infos << model->imageInfo(mapToSourceImageModel(index(i, 0)));
-- }
--
-- return infos;
--}
--
--// --------------------------------------------------------------------------------------------
--
--ImageFilterModel::ImageFilterModel(QObject* parent)
-- : ImageSortFilterModel(parent),
-- d_ptr(new ImageFilterModelPrivate)
--{
-- d_ptr->init(this);
--}
--
--ImageFilterModel::ImageFilterModel(ImageFilterModelPrivate& dd, QObject* parent)
-- : ImageSortFilterModel(parent),
-- d_ptr(&dd)
--{
-- d_ptr->init(this);
--}
--
--ImageFilterModel::~ImageFilterModel()
--{
-- Q_D(ImageFilterModel);
-- delete d;
--}
--
--void ImageFilterModel::setDirectSourceImageModel(ImageModel* sourceModel)
--{
-- Q_D(ImageFilterModel);
--
-- if (d->imageModel)
-- {
-- d->imageModel->unsetPreprocessor(d);
-- disconnect(d->imageModel, SIGNAL(modelReset()),
-- this, SLOT(slotModelReset()));
-- slotModelReset();
-- }
--
-- d->imageModel = sourceModel;
--
-- if (d->imageModel)
-- {
-- d->imageModel->setPreprocessor(d);
--
-- connect(d->imageModel, SIGNAL(preprocess(QList<ImageInfo>,QList<QVariant>)),
-- d, SLOT(preprocessInfos(QList<ImageInfo>,QList<QVariant>)));
--
-- connect(d->imageModel, SIGNAL(processAdded(QList<ImageInfo>,QList<QVariant>)),
-- d, SLOT(processAddedInfos(QList<ImageInfo>,QList<QVariant>)));
--
-- connect(d, SIGNAL(reAddImageInfos(QList<ImageInfo>,QList<QVariant>)),
-- d->imageModel, SLOT(reAddImageInfos(QList<ImageInfo>,QList<QVariant>)));
--
-- connect(d, SIGNAL(reAddingFinished()),
-- d->imageModel, SLOT(reAddingFinished()));
--
-- connect(d->imageModel, SIGNAL(modelReset()),
-- this, SLOT(slotModelReset()));
--
-- connect(d->imageModel, SIGNAL(imageChange(ImageChangeset,QItemSelection)),
-- this, SLOT(slotImageChange(ImageChangeset)));
--
-- connect(d->imageModel, SIGNAL(imageTagChange(ImageTagChangeset,QItemSelection)),
-- this, SLOT(slotImageTagChange(ImageTagChangeset)));
-- }
--
-- setSourceModel(d->imageModel);
--}
--
--QVariant ImageFilterModel::data(const QModelIndex& index, int role) const
--{
-- Q_D(const ImageFilterModel);
--
-- if (!index.isValid())
-- {
-- return QVariant();
-- }
--
-- switch (role)
-- {
-- // Attention: This breaks should there ever be another filter model between this and the ImageModel
--
-- case DCategorizedSortFilterProxyModel::CategoryDisplayRole:
-- return categoryIdentifier(d->imageModel->imageInfoRef(mapToSource(index)));
-- case CategorizationModeRole:
-- return d->sorter.categorizationMode;
-- case SortOrderRole:
-- return d->sorter.sortRole;
-- //case CategoryCountRole:
-- // return categoryCount(d->imageModel->imageInfoRef(mapToSource(index)));
-- case CategoryAlbumIdRole:
-- return d->imageModel->imageInfoRef(mapToSource(index)).albumId();
-- case CategoryFormatRole:
-- return d->imageModel->imageInfoRef(mapToSource(index)).format();
-- case GroupIsOpenRole:
-- return d->groupFilter.isAllOpen() ||
-- d->groupFilter.isOpen(d->imageModel->imageInfoRef(mapToSource(index)).id());
-- case ImageFilterModelPointerRole:
-- return QVariant::fromValue(const_cast<ImageFilterModel*>(this));
-- }
--
-- return DCategorizedSortFilterProxyModel::data(index, role);
--}
--
--ImageFilterModel* ImageFilterModel::imageFilterModel() const
--{
-- return const_cast<ImageFilterModel*>(this);
--}
--
--DatabaseFields::Set ImageFilterModel::suggestedWatchFlags() const
--{
-- DatabaseFields::Set watchFlags;
-- watchFlags |= DatabaseFields::Name | DatabaseFields::FileSize | DatabaseFields::ModificationDate;
-- watchFlags |= DatabaseFields::Rating | DatabaseFields::CreationDate | DatabaseFields::Orientation |
-- DatabaseFields::Width | DatabaseFields::Height;
-- watchFlags |= DatabaseFields::Comment;
-- watchFlags |= DatabaseFields::ImageRelations;
-- return watchFlags;
--}
--
--// -------------- Filter settings --------------
--
--void ImageFilterModel::setDayFilter(const QList<QDateTime>& days)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setDayFilter(days);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setTagFilter(const QList<int>& includedTags, const QList<int>& excludedTags,
-- ImageFilterSettings::MatchingCondition matchingCond,
-- bool showUnTagged, const QList<int>& clTagIds, const QList<int>& plTagIds)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setTagFilter(includedTags, excludedTags, matchingCond, showUnTagged, clTagIds, plTagIds);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setRatingFilter(int rating, ImageFilterSettings::RatingCondition ratingCond, bool isUnratedExcluded)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setRatingFilter(rating, ratingCond, isUnratedExcluded);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setUrlWhitelist(const QList<QUrl> urlList, const QString& id)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setUrlWhitelist(urlList, id);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setIdWhitelist(const QList<qlonglong>& idList, const QString& id)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setIdWhitelist(idList, id);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setMimeTypeFilter(int mimeTypeFilter)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setMimeTypeFilter(mimeTypeFilter);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setGeolocationFilter(const ImageFilterSettings::GeolocationCondition& condition)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setGeolocationFilter(condition);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setTextFilter(const SearchTextFilterSettings& settings)
--{
-- Q_D(ImageFilterModel);
-- d->filter.setTextFilter(settings);
-- setImageFilterSettings(d->filter);
--}
--
--void ImageFilterModel::setImageFilterSettings(const ImageFilterSettings& settings)
--{
-- Q_D(ImageFilterModel);
--
-- {
-- QMutexLocker lock(&d->mutex);
-- d->version++;
-- d->filter = settings;
-- d->filterCopy = settings;
-- d->versionFilterCopy = d->versionFilter;
-- d->groupFilterCopy = d->groupFilter;
--
-- d->needPrepareComments = settings.isFilteringByText();
-- d->needPrepareTags = settings.isFilteringByTags();
-- d->needPrepareGroups = true;
-- d->needPrepare = d->needPrepareComments || d->needPrepareTags || d->needPrepareGroups;
--
-- d->hasOneMatch = false;
-- d->hasOneMatchForText = false;
-- }
--
-- d->filterResults.clear();
--
-- //d->categoryCountHashInt.clear();
-- //d->categoryCountHashString.clear();
-- if (d->imageModel)
-- {
-- d->infosToProcess(d->imageModel->imageInfos());
-- }
--
-- emit filterSettingsChanged(settings);
--}
--
--void ImageFilterModel::setVersionManagerSettings(const VersionManagerSettings& settings)
--{
-- Q_D(ImageFilterModel);
-- d->versionFilter.setVersionManagerSettings(settings);
-- setVersionImageFilterSettings(d->versionFilter);
--}
--
--void ImageFilterModel::setExceptionList(const QList<qlonglong>& idList, const QString& id)
--{
-- Q_D(ImageFilterModel);
-- d->versionFilter.setExceptionList(idList, id);
-- setVersionImageFilterSettings(d->versionFilter);
--}
--
--void ImageFilterModel::setVersionImageFilterSettings(const VersionImageFilterSettings& settings)
--{
-- Q_D(ImageFilterModel);
-- d->versionFilter = settings;
-- slotUpdateFilter();
--}
--
--bool ImageFilterModel::isGroupOpen(qlonglong group) const
--{
-- Q_D(const ImageFilterModel);
-- return d->groupFilter.isOpen(group);
--}
--
--bool ImageFilterModel::isAllGroupsOpen() const
--{
-- Q_D(const ImageFilterModel);
-- return d->groupFilter.isAllOpen();
--}
--
--void ImageFilterModel::setGroupOpen(qlonglong group, bool open)
--{
-- Q_D(ImageFilterModel);
-- d->groupFilter.setOpen(group, open);
-- setGroupImageFilterSettings(d->groupFilter);
--}
--
--void ImageFilterModel::toggleGroupOpen(qlonglong group)
--{
-- setGroupOpen(group, !isGroupOpen(group));
--}
--
--void ImageFilterModel::setAllGroupsOpen(bool open)
--{
-- Q_D(ImageFilterModel);
-- d->groupFilter.setAllOpen(open);
-- setGroupImageFilterSettings(d->groupFilter);
--}
--
--void ImageFilterModel::setGroupImageFilterSettings(const GroupImageFilterSettings& settings)
--{
-- Q_D(ImageFilterModel);
-- d->groupFilter = settings;
-- slotUpdateFilter();
--}
--
--void ImageFilterModel::slotUpdateFilter()
--{
-- Q_D(ImageFilterModel);
-- setImageFilterSettings(d->filter);
--}
--
--ImageFilterSettings ImageFilterModel::imageFilterSettings() const
--{
-- Q_D(const ImageFilterModel);
-- return d->filter;
--}
--
--ImageSortSettings ImageFilterModel::imageSortSettings() const
--{
-- Q_D(const ImageFilterModel);
-- return d->sorter;
--}
--
--VersionImageFilterSettings ImageFilterModel::versionImageFilterSettings() const
--{
-- Q_D(const ImageFilterModel);
-- return d->versionFilter;
--}
--
--GroupImageFilterSettings ImageFilterModel::groupImageFilterSettings() const
--{
-- Q_D(const ImageFilterModel);
-- return d->groupFilter;
--}
--
--void ImageFilterModel::slotModelReset()
--{
-- Q_D(ImageFilterModel);
-- {
-- QMutexLocker lock(&d->mutex);
-- // discard all packages on the way that are marked as send out for re-add
-- d->lastDiscardVersion = d->version;
-- d->sentOutForReAdd = 0;
-- // discard all packages on the way
-- d->version++;
-- d->sentOut = 0;
--
-- d->hasOneMatch = false;
-- d->hasOneMatchForText = false;
-- }
-- d->filterResults.clear();
--}
--
--bool ImageFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
--{
-- Q_D(const ImageFilterModel);
--
-- if (source_parent.isValid())
-- {
-- return false;
-- }
--
-- qlonglong id = d->imageModel->imageId(source_row);
-- QHash<qlonglong, bool>::const_iterator it = d->filterResults.constFind(id);
--
-- if (it != d->filterResults.constEnd())
-- {
-- return it.value();
-- }
--
-- // usually done in thread and cache, unless source model changed
-- ImageInfo info = d->imageModel->imageInfo(source_row);
-- bool match = d->filter.matches(info);
-- match = match ? d->versionFilter.matches(info) : false;
--
-- return match ? d->groupFilter.matches(info) : false;
--}
--
--void ImageFilterModel::setSendImageInfoSignals(bool sendSignals)
--{
-- if (sendSignals)
-- {
-- connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)),
-- this, SLOT(slotRowsInserted(QModelIndex,int,int)));
--
-- connect(this, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
-- this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)));
-- }
-- else
-- {
-- disconnect(this, SIGNAL(rowsInserted(QModelIndex,int,int)),
-- this, SLOT(slotRowsInserted(QModelIndex,int,int)));
--
-- disconnect(this, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
-- this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)));
-- }
--}
--
--void ImageFilterModel::slotRowsInserted(const QModelIndex& /*parent*/, int start, int end)
--{
-- QList<ImageInfo> infos;
--
-- for (int i=start; i<=end; ++i)
-- {
-- infos << imageInfo(index(i, 0));
-- }
--
-- emit imageInfosAdded(infos);
--}
--
--void ImageFilterModel::slotRowsAboutToBeRemoved(const QModelIndex& /*parent*/, int start, int end)
--{
-- QList<ImageInfo> infos;
--
-- for (int i=start; i<=end; ++i)
-- {
-- infos << imageInfo(index(i, 0));
-- }
--
-- emit imageInfosAboutToBeRemoved(infos);
--}
--
--// -------------- Threaded preparation & filtering --------------
--
--void ImageFilterModel::addPrepareHook(ImageFilterModelPrepareHook* hook)
--{
-- Q_D(ImageFilterModel);
-- QMutexLocker lock(&d->mutex);
-- d->prepareHooks << hook;
--}
--
--void ImageFilterModel::removePrepareHook(ImageFilterModelPrepareHook* hook)
--{
-- Q_D(ImageFilterModel);
-- QMutexLocker lock(&d->mutex);
-- d->prepareHooks.removeAll(hook);
--}
--
--void ImageFilterModelPreparer::process(ImageFilterModelTodoPackage package)
--{
-- if (!checkVersion(package))
-- {
-- emit discarded(package);
-- return;
-- }
--
-- // get thread-local copy
-- bool needPrepareTags, needPrepareComments, needPrepareGroups;
-- QList<ImageFilterModelPrepareHook*> prepareHooks;
-- {
-- QMutexLocker lock(&d->mutex);
-- needPrepareTags = d->needPrepareTags;
-- needPrepareComments = d->needPrepareComments;
-- needPrepareGroups = d->needPrepareGroups;
-- prepareHooks = d->prepareHooks;
-- }
--
-- //TODO: Make efficient!!
-- if (needPrepareComments)
-- {
-- foreach(const ImageInfo& info, package.infos)
-- {
-- info.comment();
-- }
-- }
--
-- if (!checkVersion(package))
-- {
-- emit discarded(package);
-- return;
-- }
--
-- // The downside of QVector: At some point, we may need a QList for an API.
-- // Nonetheless, QList and ImageInfo is fast. We could as well
-- // reimplement ImageInfoList to ImageInfoVector (internally with templates?)
-- ImageInfoList infoList;
--
-- if (needPrepareTags || needPrepareGroups)
-- {
-- infoList = package.infos.toList();
-- }
--
-- if (needPrepareTags)
-- {
-- infoList.loadTagIds();
-- }
--
-- if (needPrepareGroups)
-- {
-- infoList.loadGroupImageIds();
-- }
--
-- foreach(ImageFilterModelPrepareHook* hook, prepareHooks)
-- {
-- hook->prepare(package.infos);
-- }
--
-- emit processed(package);
--}
--
--void ImageFilterModelFilterer::process(ImageFilterModelTodoPackage package)
--{
-- if (!checkVersion(package))
-- {
-- emit discarded(package);
-- return;
-- }
--
-- // get thread-local copy
-- ImageFilterSettings localFilter;
-- VersionImageFilterSettings localVersionFilter;
-- GroupImageFilterSettings localGroupFilter;
-- bool hasOneMatch;
-- bool hasOneMatchForText;
-- {
-- QMutexLocker lock(&d->mutex);
-- localFilter = d->filterCopy;
-- localVersionFilter = d->versionFilterCopy;
-- localGroupFilter = d->groupFilterCopy;
-- hasOneMatch = d->hasOneMatch;
-- hasOneMatchForText = d->hasOneMatchForText;
-- }
--
-- // Actual filtering. The variants to spare checking hasOneMatch over and over again.
-- if (hasOneMatch && hasOneMatchForText)
-- {
-- foreach(const ImageInfo& info, package.infos)
-- {
-- package.filterResults[info.id()] = localFilter.matches(info) &&
-- localVersionFilter.matches(info) &&
-- localGroupFilter.matches(info);
-- }
-- }
-- else if (hasOneMatch)
-- {
-- bool matchForText;
--
-- foreach(const ImageInfo& info, package.infos)
-- {
-- package.filterResults[info.id()] = localFilter.matches(info, &matchForText) &&
-- localVersionFilter.matches(info) &&
-- localGroupFilter.matches(info);
--
-- if (matchForText)
-- {
-- hasOneMatchForText = true;
-- }
-- }
-- }
-- else
-- {
-- bool result, matchForText;
--
-- foreach(const ImageInfo& info, package.infos)
-- {
-- result = localFilter.matches(info, &matchForText) &&
-- localVersionFilter.matches(info) &&
-- localGroupFilter.matches(info);
-- package.filterResults[info.id()] = result;
--
-- if (result)
-- {
-- hasOneMatch = true;
-- }
--
-- if (matchForText)
-- {
-- hasOneMatchForText = true;
-- }
-- }
-- }
--
-- if (checkVersion(package))
-- {
-- QMutexLocker lock(&d->mutex);
-- d->hasOneMatch = hasOneMatch;
-- d->hasOneMatchForText = hasOneMatchForText;
-- }
--
-- emit processed(package);
--}
--
--// -------------- Sorting and Categorization -------------------------------------------------------
--
--void ImageFilterModel::setImageSortSettings(const ImageSortSettings& sorter)
--{
-- Q_D(ImageFilterModel);
-- d->sorter = sorter;
-- setCategorizedModel(d->sorter.categorizationMode != ImageSortSettings::NoCategories);
-- invalidate();
--}
--
--void ImageFilterModel::setCategorizationMode(ImageSortSettings::CategorizationMode mode)
--{
-- Q_D(ImageFilterModel);
-- d->sorter.setCategorizationMode(mode);
-- setImageSortSettings(d->sorter);
--}
--
--void ImageFilterModel::setCategorizationSortOrder(ImageSortSettings::SortOrder order)
--{
-- Q_D(ImageFilterModel);
-- d->sorter.setCategorizationSortOrder(order);
-- setImageSortSettings(d->sorter);
--}
--
--void ImageFilterModel::setSortRole(ImageSortSettings::SortRole role)
--{
-- Q_D(ImageFilterModel);
-- d->sorter.setSortRole(role);
-- setImageSortSettings(d->sorter);
--}
--
--void ImageFilterModel::setSortOrder(ImageSortSettings::SortOrder order)
--{
-- Q_D(ImageFilterModel);
-- d->sorter.setSortOrder(order);
-- setImageSortSettings(d->sorter);
--}
--
--void ImageFilterModel::setStringTypeNatural(bool natural)
--{
-- Q_D(ImageFilterModel);
-- d->sorter.setStringTypeNatural(natural);
-- setImageSortSettings(d->sorter);
--}
--
--int ImageFilterModel::compareCategories(const QModelIndex& left, const QModelIndex& right) const
--{
-- // source indexes
-- Q_D(const ImageFilterModel);
--
-- if (!d->sorter.isCategorized())
-- {
-- return 0;
-- }
--
-- if (!left.isValid() || !right.isValid())
-- {
-- return -1;
-- }
--
-- const ImageInfo& leftInfo = d->imageModel->imageInfoRef(left);
-- const ImageInfo& rightInfo = d->imageModel->imageInfoRef(right);
--
-- // Check grouping
-- qlonglong leftGroupImageId = leftInfo.groupImageId();
-- qlonglong rightGroupImageId = rightInfo.groupImageId();
--
-- return compareInfosCategories(leftGroupImageId == -1 ? leftInfo : ImageInfo(leftGroupImageId),
-- rightGroupImageId == -1 ? rightInfo : ImageInfo(rightGroupImageId));
--}
--
--bool ImageFilterModel::subSortLessThan(const QModelIndex& left, const QModelIndex& right) const
--{
-- // source indexes
-- Q_D(const ImageFilterModel);
--
-- if (!left.isValid() || !right.isValid())
-- {
-- return true;
-- }
--
-- if (left == right)
-- {
-- return false;
-- }
--
-- const ImageInfo& leftInfo = d->imageModel->imageInfoRef(left);
-- const ImageInfo& rightInfo = d->imageModel->imageInfoRef(right);
--
-- if (leftInfo == rightInfo)
-- {
-- return d->sorter.lessThan(left.data(ImageModel::ExtraDataRole), right.data(ImageModel::ExtraDataRole));
-- }
--
-- // Check grouping
-- qlonglong leftGroupImageId = leftInfo.groupImageId();
-- qlonglong rightGroupImageId = rightInfo.groupImageId();
--
-- // Either no grouping (-1), or same group image, or same image
-- if (leftGroupImageId == rightGroupImageId)
-- {
-- return infosLessThan(leftInfo, rightInfo);
-- }
--
-- // We have grouping to handle
--
-- // Is one grouped on the other? Sort behind leader.
-- if (leftGroupImageId == rightInfo.id())
-- {
-- return false;
-- }
-- if (rightGroupImageId == leftInfo.id())
-- {
-- return true;
-- }
--
-- // Use the group leader for sorting
-- return infosLessThan(leftGroupImageId == -1 ? leftInfo : ImageInfo(leftGroupImageId),
-- rightGroupImageId == -1 ? rightInfo : ImageInfo(rightGroupImageId));
--}
--
--int ImageFilterModel::compareInfosCategories(const ImageInfo& left, const ImageInfo& right) const
--{
-- // Note: reimplemented in ImageAlbumFilterModel
-- Q_D(const ImageFilterModel);
-- return d->sorter.compareCategories(left, right);
--}
--
--// Feel free to optimize. QString::number is 3x slower.
--static inline QString fastNumberToString(int id)
--{
-- const int size = sizeof(int) * 2;
-- char c[size+1];
-- c[size] = '\0';
-- char* p = c;
-- int number = id;
--
-- for (int i=0; i<size; ++i)
-- {
-- *p = 'a' + (number & 0xF);
-- number >>= 4;
-- ++p;
-- }
--
-- return QString::fromLatin1(c);
--}
--
--QString ImageFilterModel::categoryIdentifier(const ImageInfo& i) const
--{
-- Q_D(const ImageFilterModel);
--
-- if (!d->sorter.isCategorized())
-- {
-- return QString();
-- }
--
-- qlonglong groupedImageId = i.groupImageId();
-- ImageInfo info = groupedImageId == -1 ? i : ImageInfo(groupedImageId);
--
-- switch (d->sorter.categorizationMode)
-- {
-- case ImageSortSettings::NoCategories:
-- return QString();
-- case ImageSortSettings::OneCategory:
-- return QString();
-- case ImageSortSettings::CategoryByAlbum:
-- return fastNumberToString(info.albumId());
-- case ImageSortSettings::CategoryByFormat:
-- return info.format();
-- default:
-- return QString();
-- }
--}
--
--bool ImageFilterModel::infosLessThan(const ImageInfo& left, const ImageInfo& right) const
--{
-- Q_D(const ImageFilterModel);
-- return d->sorter.lessThan(left, right);
--}
--
--// -------------- Watching changes -----------------------------------------------------------------
--
--void ImageFilterModel::slotImageTagChange(const ImageTagChangeset& changeset)
--{
-- Q_D(ImageFilterModel);
--
-- if (!d->imageModel || d->imageModel->isEmpty())
-- {
-- return;
-- }
--
-- // already scheduled to re-filter?
-- if (d->updateFilterTimer->isActive())
-- {
-- return;
-- }
--
-- // do we filter at all?
-- if (!d->versionFilter.isFilteringByTags() &&
-- !d->filter.isFilteringByTags() &&
-- !d->filter.isFilteringByText())
-- {
-- return;
-- }
--
-- // is one of our images affected?
-- foreach(const qlonglong& id, changeset.ids())
-- {
-- // if one matching image id is found, trigger a refresh
-- if (d->imageModel->hasImage(id))
-- {
-- d->updateFilterTimer->start();
-- return;
-- }
-- }
--}
--
--void ImageFilterModel::slotImageChange(const ImageChangeset& changeset)
--{
-- Q_D(ImageFilterModel);
--
-- if (!d->imageModel || d->imageModel->isEmpty())
-- {
-- return;
-- }
--
-- // already scheduled to re-filter?
-- if (d->updateFilterTimer->isActive())
-- {
-- return;
-- }
--
-- // is one of the values affected that we filter or sort by?
-- DatabaseFields::Set set = changeset.changes();
-- bool sortAffected = (set & d->sorter.watchFlags());
-- bool filterAffected = (set & d->filter.watchFlags()) || (set & d->groupFilter.watchFlags());
--
-- if (!sortAffected && !filterAffected)
-- {
-- return;
-- }
--
-- // is one of our images affected?
-- bool imageAffected = false;
--
-- foreach(const qlonglong& id, changeset.ids())
-- {
-- // if one matching image id is found, trigger a refresh
-- if (d->imageModel->hasImage(id))
-- {
-- imageAffected = true;
-- break;
-- }
-- }
--
-- if (!imageAffected)
-- {
-- return;
-- }
--
-- if (filterAffected)
-- {
-- d->updateFilterTimer->start();
-- }
-- else
-- {
-- invalidate(); // just resort, reuse filter results
-- }
--}
--
--// -------------------------------------------------------------------------------------------------------
--
--NoDuplicatesImageFilterModel::NoDuplicatesImageFilterModel(QObject* parent)
-- : ImageSortFilterModel(parent)
--{
--}
--
--bool NoDuplicatesImageFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
--{
-- QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
--
-- if (index.data(ImageModel::ExtraDataDuplicateCount).toInt() <= 1)
-- {
-- return true;
-- }
--
-- QModelIndex previousIndex = sourceModel()->index(source_row - 1, 0, source_parent);
--
-- if (!previousIndex.isValid())
-- {
-- return true;
-- }
--
-- if (sourceImageModel()->imageId(mapFromDirectSourceToSourceImageModel(index)) == sourceImageModel()->imageId(mapFromDirectSourceToSourceImageModel(previousIndex)))
-- {
-- return false;
-- }
-- return true;
--}
--
--/*
--void NoDuplicatesImageFilterModel::setSourceModel(QAbstractItemModel* model)
--{
-- if (sourceModel())
-- {
-- }
--
-- ImageSortFilterModel::setSourceModel(model);
--
-- if (sourceModel())
-- {
-- connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
-- this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)));
-- }
--}
--
--void NoDuplicatesImageFilterModel::slotRowsAboutToBeRemoved(const QModelIndex& parent, int begin, int end)
--{
-- bool needInvalidate = false;
--
-- for (int i = begin; i<=end; ++i)
-- {
-- QModelIndex index = sourceModel()->index(i, 0, parent);
--
-- // filtered out by us?
-- if (!mapFromSource(index).isValid())
-- {
-- continue;
-- }
--
-- QModelIndex sourceIndex = mapFromDirectSourceToSourceImageModel(index);
-- qlonglong id = sourceImageModel()->imageId(sourceIndex);
--
-- if (sourceImageModel()->numberOfIndexesForImageId(id) > 1)
-- {
-- needInvalidate = true;
-- }
-- }
--}*/
--
--} // namespace Digikam
-diff --git a/libs/models/imagefiltermodel.h b/libs/models/imagefiltermodel.h
-deleted file mode 100644
-index d131b3e..0000000
---- a/libs/models/imagefiltermodel.h
-+++ /dev/null
-@@ -1,299 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-- * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-- * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGEFILTERMODEL_H
--#define IMAGEFILTERMODEL_H
--
--// Local includes
--
--#include "dcategorizedsortfilterproxymodel.h"
--#include "textfilter.h"
--#include "imagefiltersettings.h"
--#include "imagemodel.h"
--#include "imagesortsettings.h"
--#include "digikam_export.h"
--
--namespace Digikam
--{
--
--class ImageChangeset;
--class ImageFilterModel;
--class ImageTagChangeset;
--
--class DIGIKAM_DATABASE_EXPORT ImageFilterModelPrepareHook
--{
--public:
--
-- virtual ~ImageFilterModelPrepareHook() {};
-- virtual void prepare(const QVector<ImageInfo>& infos) = 0;
--};
--
--// -----------------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT ImageSortFilterModel : public DCategorizedSortFilterProxyModel
--{
-- Q_OBJECT
--
--public:
--
-- explicit ImageSortFilterModel(QObject* parent = 0);
--
-- void setSourceImageModel(ImageModel* model);
-- ImageModel* sourceImageModel() const;
--
-- void setSourceFilterModel(ImageSortFilterModel* model);
-- ImageSortFilterModel* sourceFilterModel() const;
--
-- QModelIndex mapToSourceImageModel(const QModelIndex& index) const;
-- QModelIndex mapFromSourceImageModel(const QModelIndex& imagemodel_index) const;
-- QModelIndex mapFromDirectSourceToSourceImageModel(const QModelIndex& sourceModel_index) const;
--
-- /// Convenience methods mapped to ImageModel.
-- /// Mentioned indexes returned come from the source image model.
-- QList<QModelIndex> mapListToSource(const QList<QModelIndex>& indexes) const;
-- QList<QModelIndex> mapListFromSource(const QList<QModelIndex>& sourceIndexes) const;
--
-- ImageInfo imageInfo(const QModelIndex& index) const;
-- qlonglong imageId(const QModelIndex& index) const;
-- QList<ImageInfo> imageInfos(const QList<QModelIndex>& indexes) const;
-- QList<qlonglong> imageIds(const QList<QModelIndex>& indexes) const;
--
-- QModelIndex indexForPath(const QString& filePath) const;
-- QModelIndex indexForImageInfo(const ImageInfo& info) const;
-- QModelIndex indexForImageId(qlonglong id) const;
--
-- /** Returns a list of all image infos, sorted according to this model.
-- * If you do not need a sorted list, use ImageModel's imageInfos() method.
-- */
-- QList<ImageInfo> imageInfosSorted() const;
--
-- /// Returns this, any chained ImageFilterModel, or 0.
-- virtual ImageFilterModel* imageFilterModel() const;
--
--protected:
--
-- /// Reimplement if needed. Called only when model shall be set as (direct) sourceModel.
-- virtual void setDirectSourceImageModel(ImageModel* model);
--
-- // made protected
-- virtual void setSourceModel(QAbstractItemModel* model);
--
--protected:
--
-- ImageSortFilterModel* m_chainedModel;
--};
--
--// -----------------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT ImageFilterModel : public ImageSortFilterModel
--{
-- Q_OBJECT
--
--public:
--
-- enum ImageFilterModelRoles
-- {
-- /// Returns the current categorization mode
-- CategorizationModeRole = ImageModel::FilterModelRoles + 1,
-- /// Returns the current sort order
-- SortOrderRole = ImageModel::FilterModelRoles + 2,
-- // / Returns the number of items in the index' category
-- //CategoryCountRole = ImageModel::FilterModelRoles + 3,
-- /// Returns the id of the PAlbum of the index which is used for category
-- CategoryAlbumIdRole = ImageModel::FilterModelRoles + 3,
-- /// Returns the format of the index which is used for category
-- CategoryFormatRole = ImageModel::FilterModelRoles + 4,
-- /// Returns true if the given image is a group leader, and the group is opened
-- GroupIsOpenRole = ImageModel::FilterModelRoles + 5,
-- ImageFilterModelPointerRole = ImageModel::FilterModelRoles + 50
-- };
--
--public:
--
-- explicit ImageFilterModel(QObject* parent = 0);
-- ~ImageFilterModel();
--
-- /** Add a hook to get added images for preparation tasks before they are added in the model */
-- void addPrepareHook(ImageFilterModelPrepareHook* hook);
-- void removePrepareHook(ImageFilterModelPrepareHook* hook);
--
-- /** Returns a set of DatabaseFields suggested to set as watch flags on the source ImageModel.
-- * The contained flags will be those that this model can sort or filter by. */
-- DatabaseFields::Set suggestedWatchFlags() const;
--
-- ImageFilterSettings imageFilterSettings() const;
-- VersionImageFilterSettings versionImageFilterSettings() const;
-- GroupImageFilterSettings groupImageFilterSettings() const;
-- ImageSortSettings imageSortSettings() const;
--
-- // group is identified by the id of its group leader
-- bool isGroupOpen(qlonglong group) const;
-- bool isAllGroupsOpen() const;
--
-- /// Enables sending imageInfosAdded and imageInfosAboutToBeRemoved
-- void setSendImageInfoSignals(bool sendSignals);
--
-- virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-- virtual ImageFilterModel* imageFilterModel() const;
--
--public Q_SLOTS:
--
-- /** Changes the current version image filter settings and refilters. */
-- void setVersionImageFilterSettings(const VersionImageFilterSettings& settings);
--
-- /** Changes the current version image filter settings and refilters. */
-- void setGroupImageFilterSettings(const GroupImageFilterSettings& settings);
--
-- /** Adjust the current ImageFilterSettings.
-- * Equivalent to retrieving the current filter settings, adjusting the parameter
-- * and calling setImageFilterSettings.
-- * Provided for convenience.
-- * It is encouraged to use setImageFilterSettings if you change more than one
-- * parameter at a time.
-- */
-- void setDayFilter(const QList<QDateTime>& days);
-- void setTagFilter(const QList<int>& includedTags, const QList<int>& excludedTags,
-- ImageFilterSettings::MatchingCondition matchingCond, bool showUnTagged,
-- const QList<int>& clTagIds, const QList<int>& plTagIds);
-- void setRatingFilter(int rating, ImageFilterSettings::RatingCondition ratingCond, bool isUnratedExcluded);
-- void setMimeTypeFilter(int mimeTypeFilter);
-- void setGeolocationFilter(const ImageFilterSettings::GeolocationCondition& condition);
-- void setTextFilter(const SearchTextFilterSettings& settings);
--
-- void setCategorizationMode(ImageSortSettings::CategorizationMode mode);
-- void setCategorizationSortOrder(ImageSortSettings::SortOrder order);
-- void setSortRole(ImageSortSettings::SortRole role);
-- void setSortOrder(ImageSortSettings::SortOrder order);
-- void setStringTypeNatural(bool natural);
-- void setUrlWhitelist(const QList<QUrl> urlList, const QString& id);
-- void setIdWhitelist(const QList<qlonglong>& idList, const QString& id);
--
-- void setVersionManagerSettings(const VersionManagerSettings& settings);
-- void setExceptionList(const QList<qlonglong>& idlist, const QString& id);
--
-- void setGroupOpen(qlonglong group, bool open);
-- void toggleGroupOpen(qlonglong group);
-- void setAllGroupsOpen(bool open);
--
-- /** Changes the current image filter settings and refilters. */
-- virtual void setImageFilterSettings(const ImageFilterSettings& settings);
--
-- /** Changes the current image sort settings and resorts. */
-- virtual void setImageSortSettings(const ImageSortSettings& settings);
--
--Q_SIGNALS:
--
-- /// Signals that the set filter matches at least one index
-- void filterMatches(bool matches);
--
-- /** Signals that the set text filter matches at least one entry.
-- If no text filter is set, this signal is emitted
-- with 'false' when filterMatches() is emitted.
-- */
-- void filterMatchesForText(bool matchesByText);
--
-- /** Emitted when the filter settings have been changed
-- (the model may not yet have been updated)
-- */
-- void filterSettingsChanged(const ImageFilterSettings& settings);
--
-- /** These signals need to be explicitly enabled with setSendImageInfoSignals()
-- */
-- void imageInfosAdded(const QList<ImageInfo>& infos);
-- void imageInfosAboutToBeRemoved(const QList<ImageInfo>& infos);
--
--public:
--
-- // Declared as public because of use in sub-classes.
-- class ImageFilterModelPrivate;
--
--protected:
--
-- ImageFilterModelPrivate* const d_ptr;
--
--protected:
--
-- ImageFilterModel(ImageFilterModelPrivate& dd, QObject* parent);
--
-- virtual void setDirectSourceImageModel(ImageModel* model);
--
-- virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
--
-- virtual int compareCategories(const QModelIndex& left, const QModelIndex& right) const;
-- virtual bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const;
-- //virtual int categoryCount(const ImageInfo& info) const;
--
-- /** Reimplement to customize category sorting,
-- * Return negative if category of left < category right,
-- * Return 0 if left and right are in the same category, else return positive.
-- */
-- virtual int compareInfosCategories(const ImageInfo& left, const ImageInfo& right) const;
--
-- /** Reimplement to customize sorting. Do not take categories into account here.
-- */
-- virtual bool infosLessThan(const ImageInfo& left, const ImageInfo& right) const;
--
-- /** Returns a unique identifier for the category if info. The string need not be for user display.
-- */
-- virtual QString categoryIdentifier(const ImageInfo& info) const;
--
--protected Q_SLOTS:
--
-- void slotModelReset();
-- void slotUpdateFilter();
--
-- void slotImageTagChange(const ImageTagChangeset& changeset);
-- void slotImageChange(const ImageChangeset& changeset);
--
-- void slotRowsInserted(const QModelIndex& parent, int start, int end);
-- void slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
--
--private:
--
-- Q_DECLARE_PRIVATE(ImageFilterModel)
--};
--
--// -----------------------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT NoDuplicatesImageFilterModel : public ImageSortFilterModel
--{
-- Q_OBJECT
--
--public:
--
-- explicit NoDuplicatesImageFilterModel(QObject* parent = 0);
--
--protected:
--
-- virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
--};
--
--} // namespace Digikam
--
--Q_DECLARE_METATYPE(Digikam::ImageFilterModel*)
--
--#endif // IMAGEMODEL_H
-diff --git a/libs/models/imagefiltermodelpriv.cpp b/libs/models/imagefiltermodelpriv.cpp
-deleted file mode 100644
-index 07d9e79..0000000
---- a/libs/models/imagefiltermodelpriv.cpp
-+++ /dev/null
-@@ -1,258 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-- * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-- * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagefiltermodelpriv.h"
--
--// Local includes
--
--#include "digikam_debug.h"
--#include "imagefiltermodelthreads.h"
--
--namespace Digikam
--{
--
--ImageFilterModel::ImageFilterModelPrivate::ImageFilterModelPrivate()
--{
-- imageModel = 0;
-- version = 0;
-- lastDiscardVersion = 0;
-- sentOut = 0;
-- sentOutForReAdd = 0;
-- updateFilterTimer = 0;
-- needPrepare = false;
-- needPrepareComments = false;
-- needPrepareTags = false;
-- needPrepareGroups = false;
-- preparer = 0;
-- filterer = 0;
-- hasOneMatch = false;
-- hasOneMatchForText = false;
--
-- setupWorkers();
--}
--
--ImageFilterModel::ImageFilterModelPrivate::~ImageFilterModelPrivate()
--{
-- // facilitate thread stopping
-- ++version;
-- preparer->deactivate();
-- filterer->deactivate();
-- delete preparer;
-- delete filterer;
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::init(ImageFilterModel* _q)
--{
-- q = _q;
--
-- updateFilterTimer = new QTimer(this);
-- updateFilterTimer->setSingleShot(true);
-- updateFilterTimer->setInterval(250);
--
-- connect(updateFilterTimer, SIGNAL(timeout()),
-- q, SLOT(slotUpdateFilter()));
--
-- // inter-thread redirection
-- qRegisterMetaType<ImageFilterModelTodoPackage>("ImageFilterModelTodoPackage");
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::preprocessInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- infosToProcess(infos, extraValues, true);
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::processAddedInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- // These have already been added, we just process them afterwards
-- infosToProcess(infos, extraValues, false);
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::setupWorkers()
--{
-- preparer = new ImageFilterModelPreparer(this);
-- filterer = new ImageFilterModelFilterer(this);
--
-- // A package in constructed in infosToProcess.
-- // Normal flow is infosToProcess -> preparer::process -> filterer::process -> packageFinished.
-- // If no preparation is needed, the first step is skipped.
-- // If filter version changes, both will discard old package and send them to packageDiscarded.
--
-- connect(this, SIGNAL(packageToPrepare(ImageFilterModelTodoPackage)),
-- preparer, SLOT(process(ImageFilterModelTodoPackage)));
--
-- connect(this, SIGNAL(packageToFilter(ImageFilterModelTodoPackage)),
-- filterer, SLOT(process(ImageFilterModelTodoPackage)));
--
-- connect(preparer, SIGNAL(processed(ImageFilterModelTodoPackage)),
-- filterer, SLOT(process(ImageFilterModelTodoPackage)));
--
-- connect(filterer, SIGNAL(processed(ImageFilterModelTodoPackage)),
-- this, SLOT(packageFinished(ImageFilterModelTodoPackage)));
--
-- connect(preparer, SIGNAL(discarded(ImageFilterModelTodoPackage)),
-- this, SLOT(packageDiscarded(ImageFilterModelTodoPackage)));
--
-- connect(filterer, SIGNAL(discarded(ImageFilterModelTodoPackage)),
-- this, SLOT(packageDiscarded(ImageFilterModelTodoPackage)));
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::infosToProcess(const QList<ImageInfo>& infos)
--{
-- infosToProcess(infos, QList<QVariant>(), false);
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::infosToProcess(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues, bool forReAdd)
--{
-- if (infos.isEmpty())
-- {
-- return;
-- }
--
-- filterer->schedule();
--
-- if (needPrepare)
-- {
-- preparer->schedule();
-- }
--
-- Q_ASSERT(extraValues.isEmpty() || infos.size() == extraValues.size());
--
-- // prepare and filter in chunks
-- const int size = infos.size();
-- const int maxChunkSize = needPrepare ? PrepareChunkSize : FilterChunkSize;
-- const bool hasExtraValues = !extraValues.isEmpty();
-- QList<ImageInfo>::const_iterator it = infos.constBegin(), end;
-- QList<QVariant>::const_iterator xit = extraValues.constBegin(), xend;
-- int index = 0;
-- QVector<ImageInfo> infoVector;
-- QVector<QVariant> extraValueVector;
--
-- while (it != infos.constEnd())
-- {
-- const int chunkSize = qMin(maxChunkSize, size - index);
-- infoVector.resize(chunkSize);
-- end = it + chunkSize;
-- qCopy(it, end, infoVector.begin());
--
-- if (hasExtraValues)
-- {
-- extraValueVector.resize(chunkSize);
-- xend = xit + chunkSize;
-- qCopy(xit, xend, extraValueVector.begin());
-- xit = xend;
-- }
--
-- it = end;
-- index += chunkSize;
--
-- ++sentOut;
--
-- if (forReAdd)
-- {
-- ++sentOutForReAdd;
-- }
--
-- if (needPrepare)
-- {
-- emit packageToPrepare(ImageFilterModelTodoPackage(infoVector, extraValueVector, version, forReAdd));
-- }
-- else
-- {
-- emit packageToFilter(ImageFilterModelTodoPackage(infoVector, extraValueVector, version, forReAdd));
-- }
-- }
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::packageFinished(const ImageFilterModelTodoPackage& package)
--{
-- // check if it got discarded on the journey
-- if (package.version != version)
-- {
-- packageDiscarded(package);
-- return;
-- }
--
-- // incorporate result
-- QHash<qlonglong, bool>::const_iterator it = package.filterResults.constBegin();
--
-- for (; it != package.filterResults.constEnd(); ++it)
-- {
-- filterResults.insert(it.key(), it.value());
-- }
--
-- // re-add if necessary
-- if (package.isForReAdd)
-- {
-- emit reAddImageInfos(package.infos.toList(), package.extraValues.toList());
--
-- if (sentOutForReAdd == 1) // last package
-- {
-- emit reAddingFinished();
-- }
-- }
--
-- // decrement counters
-- --sentOut;
--
-- if (package.isForReAdd)
-- {
-- --sentOutForReAdd;
-- }
--
-- // If all packages have returned, filtered and readded, and no more are expected,
-- // and there is need to tell the filter result to the view, do that
-- if (sentOut == 0 && sentOutForReAdd == 0 && !imageModel->isRefreshing())
-- {
-- q->invalidate(); // use invalidate, not invalidateFilter only. Sorting may have changed as well.
-- emit (q->filterMatches(hasOneMatch));
-- emit (q->filterMatchesForText(hasOneMatchForText));
-- filterer->deactivate();
-- preparer->deactivate();
-- }
--}
--
--void ImageFilterModel::ImageFilterModelPrivate::packageDiscarded(const ImageFilterModelTodoPackage& package)
--{
-- // Either, the model was reset, or the filter changed
-- // In the former case throw all away, in the latter case, recycle
-- if (package.version > lastDiscardVersion)
-- {
-- // Recycle packages: Send again with current version
-- // Do not increment sentOut or sentOutForReAdd here: it was not decremented!
--
-- if (needPrepare)
-- {
-- emit packageToPrepare(ImageFilterModelTodoPackage(package.infos, package.extraValues, version, package.isForReAdd));
-- }
-- else
-- {
-- emit packageToFilter(ImageFilterModelTodoPackage(package.infos, package.extraValues, version, package.isForReAdd));
-- }
-- }
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imagefiltermodelpriv.h b/libs/models/imagefiltermodelpriv.h
-deleted file mode 100644
-index a9e3f22..0000000
---- a/libs/models/imagefiltermodelpriv.h
-+++ /dev/null
-@@ -1,159 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-11
-- * Description : Qt item model for database entries - private shared header
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGEFILTERMODELPRIV_H
--#define IMAGEFILTERMODELPRIV_H
--
--// Qt includes
--
--#include <QHash>
--#include <QMutex>
--#include <QMutexLocker>
--#include <QSet>
--#include <QThread>
--#include <QTimer>
--#include <QWaitCondition>
--
--// Local includes
--
--#include "imageinfo.h"
--#include "imagefiltermodel.h"
--
--#include "digikam_export.h"
--// Yes, we need the EXPORT macro in a private header because
--// this private header is shared across binary objects.
--// This does NOT make this classes here any more public!
--
--namespace Digikam
--{
--
--const int PrepareChunkSize = 101;
--const int FilterChunkSize = 2001;
--
--class ImageFilterModelTodoPackage
--{
--public:
--
-- ImageFilterModelTodoPackage()
-- : version(0), isForReAdd(false)
-- {
-- }
--
-- ImageFilterModelTodoPackage(const QVector<ImageInfo>& infos, const QVector<QVariant>& extraValues, int version, bool isForReAdd)
-- : infos(infos), extraValues(extraValues), version(version), isForReAdd(isForReAdd)
-- {
-- }
--
-- QVector<ImageInfo> infos;
-- QVector<QVariant> extraValues;
-- unsigned int version;
-- bool isForReAdd;
-- QHash<qlonglong, bool> filterResults;
--};
--
--// ------------------------------------------------------------------------------------------------
--
--class ImageFilterModelPreparer;
--class ImageFilterModelFilterer;
--
--class DIGIKAM_DATABASE_EXPORT ImageFilterModel::ImageFilterModelPrivate : public QObject
--{
-- Q_OBJECT
--
--public:
--
-- ImageFilterModelPrivate();
-- ~ImageFilterModelPrivate();
--
-- void init(ImageFilterModel* q);
-- void setupWorkers();
-- void infosToProcess(const QList<ImageInfo>& infos);
-- void infosToProcess(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues, bool forReAdd = true);
--
--public:
--
-- ImageFilterModel* q;
--
-- ImageModel* imageModel;
--
-- ImageFilterSettings filter;
-- ImageSortSettings sorter;
-- VersionImageFilterSettings versionFilter;
-- GroupImageFilterSettings groupFilter;
--
-- volatile unsigned int version;
-- unsigned int lastDiscardVersion;
-- unsigned int lastFilteredVersion;
-- int sentOut;
-- int sentOutForReAdd;
--
-- QTimer* updateFilterTimer;
--
-- bool needPrepare;
-- bool needPrepareComments;
-- bool needPrepareTags;
-- bool needPrepareGroups;
--
-- QMutex mutex;
-- ImageFilterSettings filterCopy;
-- VersionImageFilterSettings versionFilterCopy;
-- GroupImageFilterSettings groupFilterCopy;
-- ImageFilterModelPreparer* preparer;
-- ImageFilterModelFilterer* filterer;
--
-- QHash<qlonglong, bool> filterResults;
-- bool hasOneMatch;
-- bool hasOneMatchForText;
--
-- QList<ImageFilterModelPrepareHook*> prepareHooks;
--
--/*
-- QHash<int, QSet<qlonglong> > categoryCountHashInt;
-- QHash<QString, QSet<qlonglong> > categoryCountHashString;
--
--public:
--
-- void cacheCategoryCount(int id, qlonglong imageid) const
-- { const_cast<ImageFilterModelPrivate*>(this)->categoryCountHashInt[id].insert(imageid); }
-- void cacheCategoryCount(const QString& id, qlonglong imageid) const
-- { const_cast<ImageFilterModelPrivate*>(this)->categoryCountHashString[id].insert(imageid); }
--*/
--
--public Q_SLOTS:
--
-- void preprocessInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void processAddedInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void packageFinished(const ImageFilterModelTodoPackage& package);
-- void packageDiscarded(const ImageFilterModelTodoPackage& package);
--
--Q_SIGNALS:
--
-- void packageToPrepare(const ImageFilterModelTodoPackage& package);
-- void packageToFilter(const ImageFilterModelTodoPackage& package);
-- void reAddImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void reAddingFinished();
--};
--
--} // namespace Digikam
--
--#endif // IMAGEFILTERMODELPRIV_H
-diff --git a/libs/models/imagefiltermodelthreads.cpp b/libs/models/imagefiltermodelthreads.cpp
-deleted file mode 100644
-index aa5c462..0000000
---- a/libs/models/imagefiltermodelthreads.cpp
-+++ /dev/null
-@@ -1,40 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-- * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-- * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagefiltermodel.h"
--#include "imagefiltermodelpriv.h"
--#include "imagefiltermodelthreads.h"
--
--namespace Digikam
--{
--
--ImageFilterModelWorker::ImageFilterModelWorker(ImageFilterModel::ImageFilterModelPrivate* const d)
-- : d(d)
--{
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imagefiltermodelthreads.h b/libs/models/imagefiltermodelthreads.h
-deleted file mode 100644
-index 83fa987..0000000
---- a/libs/models/imagefiltermodelthreads.h
-+++ /dev/null
-@@ -1,100 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-11
-- * Description : Qt item model for database entries - private header
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGEFILTERMODELTHREADS_H
--#define IMAGEFILTERMODELTHREADS_H
--
--// Qt includes
--
--#include <QThread>
--
--// Local includes
--
--#include "digikam_export.h"
--#include "workerobject.h"
--
--namespace Digikam
--{
--
--class DIGIKAM_DATABASE_EXPORT ImageFilterModelWorker : public WorkerObject
--{
-- Q_OBJECT
--
--public:
--
-- explicit ImageFilterModelWorker(ImageFilterModel::ImageFilterModelPrivate* const d);
--
-- bool checkVersion(const ImageFilterModelTodoPackage& package)
-- {
-- return d->version == package.version;
-- }
--
--public Q_SLOTS:
--
-- virtual void process(ImageFilterModelTodoPackage package) = 0;
--
--Q_SIGNALS:
--
-- void processed(const ImageFilterModelTodoPackage& package);
-- void discarded(const ImageFilterModelTodoPackage& package);
--
--protected:
--
-- ImageFilterModel::ImageFilterModelPrivate* d;
--};
--
--// -----------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT ImageFilterModelPreparer : public ImageFilterModelWorker
--{
-- Q_OBJECT
--
--public:
--
-- explicit ImageFilterModelPreparer(ImageFilterModel::ImageFilterModelPrivate* const d)
-- : ImageFilterModelWorker(d)
-- {
-- }
--
-- void process(ImageFilterModelTodoPackage package);
--};
--
--// ----------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT ImageFilterModelFilterer : public ImageFilterModelWorker
--{
-- Q_OBJECT
--
--public:
--
-- explicit ImageFilterModelFilterer(ImageFilterModel::ImageFilterModelPrivate* const d)
-- : ImageFilterModelWorker(d)
-- {
-- }
--
-- void process(ImageFilterModelTodoPackage package);
--};
--
--} // namespace Digikam
--
--#endif // IMAGEFILTERMODELTHREADS_H
-diff --git a/libs/models/imagefiltersettings.cpp b/libs/models/imagefiltersettings.cpp
-deleted file mode 100644
-index b61e7f9..0000000
---- a/libs/models/imagefiltersettings.cpp
-+++ /dev/null
-@@ -1,952 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Filter values for use with ImageFilterModel
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-- * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-- * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagefiltersettings.h"
--
--// C++ includes
--
--#include <cmath>
--
--// Qt includes
--
--#include <QDateTime>
--
--// Local includes
--
--#include "digikam_debug.h"
--#include "coredbfields.h"
--#include "digikam_globals.h"
--#include "imageinfo.h"
--#include "tagscache.h"
--#include "versionmanagersettings.h"
--
--namespace Digikam
--{
--
--ImageFilterSettings::ImageFilterSettings()
--{
-- m_untaggedFilter = false;
-- m_isUnratedExcluded = false;
-- m_ratingFilter = 0;
-- m_mimeTypeFilter = MimeFilter::AllFiles;
-- m_ratingCond = GreaterEqualCondition;
-- m_matchingCond = OrCondition;
-- m_geolocationCondition = GeolocationNoFilter;
--}
--
--DatabaseFields::Set ImageFilterSettings::watchFlags() const
--{
-- DatabaseFields::Set set;
--
-- if (isFilteringByDay())
-- {
-- set |= DatabaseFields::CreationDate;
-- }
--
-- if (isFilteringByText())
-- {
-- set |= DatabaseFields::Name;
-- set |= DatabaseFields::Comment;
-- }
--
-- if (isFilteringByRating())
-- {
-- set |= DatabaseFields::Rating;
-- }
--
-- if (isFilteringByTypeMime())
-- {
-- set |= DatabaseFields::Category;
-- set |= DatabaseFields::Format;
-- }
--
-- if (isFilteringByGeolocation())
-- {
-- set |= DatabaseFields::ImagePositionsAll;
-- }
--
-- if (isFilteringByColorLabels())
-- {
-- set |= DatabaseFields::ColorLabel;
-- }
--
-- if (isFilteringByPickLabels())
-- {
-- set |= DatabaseFields::PickLabel;
-- }
--
-- return set;
--}
--
--bool ImageFilterSettings::isFilteringByDay() const
--{
-- if (!m_dayFilter.isEmpty())
-- {
-- return true;
-- }
--
-- return false;
--}
--
--bool ImageFilterSettings::isFilteringByTags() const
--{
-- if (!m_includeTagFilter.isEmpty() || !m_excludeTagFilter.isEmpty() || m_untaggedFilter)
-- {
-- return true;
-- }
--
-- return false;
--}
--
--bool ImageFilterSettings::isFilteringByColorLabels() const
--{
-- if (!m_colorLabelTagFilter.isEmpty())
-- {
-- return true;
-- }
--
-- return false;
--}
--
--bool ImageFilterSettings::isFilteringByPickLabels() const
--{
-- if (!m_pickLabelTagFilter.isEmpty())
-- {
-- return true;
-- }
--
-- return false;
--}
--
--bool ImageFilterSettings::isFilteringByText() const
--{
-- if (!m_textFilterSettings.text.isEmpty())
-- {
-- return true;
-- }
--
-- return false;
--}
--
--bool ImageFilterSettings::isFilteringByTypeMime() const
--{
-- if (m_mimeTypeFilter != MimeFilter::AllFiles)
-- {
-- return true;
-- }
--
-- return false;
--}
--
--bool ImageFilterSettings::isFilteringByGeolocation() const
--{
-- return (m_geolocationCondition != GeolocationNoFilter);
--}
--
--bool ImageFilterSettings::isFilteringByRating() const
--{
-- if (m_ratingFilter != 0 || m_ratingCond != GreaterEqualCondition || m_isUnratedExcluded)
-- {
-- return true;
-- }
--
-- return false;
--}
--
--bool ImageFilterSettings::isFilteringInternally() const
--{
-- return (isFiltering() || !m_urlWhitelists.isEmpty() || !m_idWhitelists.isEmpty());
--}
--
--bool ImageFilterSettings::isFiltering() const
--{
-- return isFilteringByDay() ||
-- isFilteringByTags() ||
-- isFilteringByText() ||
-- isFilteringByRating() ||
-- isFilteringByTypeMime() ||
-- isFilteringByColorLabels() ||
-- isFilteringByPickLabels() ||
-- isFilteringByGeolocation();
--}
--
--void ImageFilterSettings::setDayFilter(const QList<QDateTime>& days)
--{
-- m_dayFilter.clear();
--
-- for (QList<QDateTime>::const_iterator it = days.constBegin(); it != days.constEnd(); ++it)
-- {
-- m_dayFilter.insert(*it, true);
-- }
--}
--
--void ImageFilterSettings::setTagFilter(const QList<int>& includedTags,
-- const QList<int>& excludedTags,
-- MatchingCondition matchingCondition,
-- bool showUnTagged,
-- const QList<int>& clTagIds,
-- const QList<int>& plTagIds)
--{
-- m_includeTagFilter = includedTags;
-- m_excludeTagFilter = excludedTags;
-- m_matchingCond = matchingCondition;
-- m_untaggedFilter = showUnTagged;
-- m_colorLabelTagFilter = clTagIds;
-- m_pickLabelTagFilter = plTagIds;
--}
--
--void ImageFilterSettings::setRatingFilter(int rating, RatingCondition ratingCondition, bool isUnratedExcluded)
--{
-- m_ratingFilter = rating;
-- m_ratingCond = ratingCondition;
-- m_isUnratedExcluded = isUnratedExcluded;
--}
--
--void ImageFilterSettings::setMimeTypeFilter(int mime)
--{
-- m_mimeTypeFilter = (MimeFilter::TypeMimeFilter)mime;
--}
--
--void ImageFilterSettings::setGeolocationFilter(const GeolocationCondition& condition)
--{
-- m_geolocationCondition = condition;
--}
--
--void ImageFilterSettings::setTextFilter(const SearchTextFilterSettings& settings)
--{
-- m_textFilterSettings = settings;
--}
--
--void ImageFilterSettings::setTagNames(const QHash<int, QString>& hash)
--{
-- m_tagNameHash = hash;
--}
--
--void ImageFilterSettings::setAlbumNames(const QHash<int, QString>& hash)
--{
-- m_albumNameHash = hash;
--}
--
--void ImageFilterSettings::setUrlWhitelist(const QList<QUrl>& urlList, const QString& id)
--{
-- if (urlList.isEmpty())
-- {
-- m_urlWhitelists.remove(id);
-- }
-- else
-- {
-- m_urlWhitelists.insert(id, urlList);
-- }
--}
--
--void ImageFilterSettings::setIdWhitelist(const QList<qlonglong>& idList, const QString& id)
--{
-- if (idList.isEmpty())
-- {
-- m_idWhitelists.remove(id);
-- }
-- else
-- {
-- m_idWhitelists.insert(id, idList);
-- }
--}
--
--template <class ContainerA, class ContainerB>
--bool containsAnyOf(const ContainerA& listA, const ContainerB& listB)
--{
-- foreach (const typename ContainerA::value_type& a, listA)
-- {
-- if (listB.contains(a))
-- {
-- return true;
-- }
-- }
-- return false;
--}
--
--template <class ContainerA, typename Value, class ContainerB>
--bool containsNoneOfExcept(const ContainerA& list, const ContainerB& noneOfList, const Value& exception)
--{
-- foreach (const typename ContainerB::value_type& n, noneOfList)
-- {
-- if (n != exception && list.contains(n))
-- {
-- return false;
-- }
-- }
-- return true;
--}
--
--bool ImageFilterSettings::matches(const ImageInfo& info, bool* const foundText) const
--{
-- if (foundText)
-- {
-- *foundText = false;
-- }
--
-- if (!isFilteringInternally())
-- {
-- return true;
-- }
--
-- bool match = false;
--
-- if (!m_includeTagFilter.isEmpty() || !m_excludeTagFilter.isEmpty())
-- {
-- QList<int> tagIds = info.tagIds();
-- QList<int>::const_iterator it;
--
-- match = m_includeTagFilter.isEmpty();
--
-- if (m_matchingCond == OrCondition)
-- {
-- for (it = m_includeTagFilter.begin(); it != m_includeTagFilter.end(); ++it)
-- {
-- if (tagIds.contains(*it))
-- {
-- match = true;
-- break;
-- }
-- }
--
-- match |= (m_untaggedFilter && tagIds.isEmpty());
-- }
-- else // AND matching condition...
-- {
-- // m_untaggedFilter and non-empty tag filter, combined with AND, is logically no match
-- if (!m_untaggedFilter)
-- {
-- for (it = m_includeTagFilter.begin(); it != m_includeTagFilter.end(); ++it)
-- {
-- if (!tagIds.contains(*it))
-- {
-- break;
-- }
-- }
--
-- if (it == m_includeTagFilter.end())
-- {
-- match = true;
-- }
-- }
-- }
--
-- for (it = m_excludeTagFilter.begin(); it != m_excludeTagFilter.end(); ++it)
-- {
-- if (tagIds.contains(*it))
-- {
-- match = false;
-- break;
-- }
-- }
-- }
-- else if (m_untaggedFilter)
-- {
-- match = !TagsCache::instance()->containsPublicTags(info.tagIds());
-- }
-- else
-- {
-- match = true;
-- }
--
-- //-- Filter by pick labels ------------------------------------------------
--
-- if (!m_pickLabelTagFilter.isEmpty())
-- {
-- QList<int> tagIds = info.tagIds();
-- bool matchPL = false;
--
-- if (containsAnyOf(m_pickLabelTagFilter, tagIds))
-- {
-- matchPL = true;
-- }
-- else if (!matchPL)
-- {
-- int noPickLabelTagId = TagsCache::instance()->tagForPickLabel(NoPickLabel);
--
-- if (m_pickLabelTagFilter.contains(noPickLabelTagId))
-- {
-- // Searching for "has no ColorLabel" requires special handling:
-- // Scan that the tag ids contains none of the ColorLabel tags, except maybe the NoColorLabel tag
-- matchPL = containsNoneOfExcept(tagIds, TagsCache::instance()->pickLabelTags(), noPickLabelTagId);
-- }
-- }
--
-- match &= matchPL;
-- }
--
-- //-- Filter by color labels ------------------------------------------------
--
-- if (!m_colorLabelTagFilter.isEmpty())
-- {
-- QList<int> tagIds = info.tagIds();
-- bool matchCL = false;
--
-- if (containsAnyOf(m_colorLabelTagFilter, tagIds))
-- {
-- matchCL = true;
-- }
-- else if (!matchCL)
-- {
-- int noColorLabelTagId = TagsCache::instance()->tagForColorLabel(NoColorLabel);
--
-- if (m_colorLabelTagFilter.contains(noColorLabelTagId))
-- {
-- // Searching for "has no ColorLabel" requires special handling:
-- // Scan that the tag ids contains none of the ColorLabel tags, except maybe the NoColorLabel tag
-- matchCL = containsNoneOfExcept(tagIds, TagsCache::instance()->colorLabelTags(), noColorLabelTagId);
-- }
-- }
--
-- match &= matchCL;
-- }
--
-- //-- Filter by date -----------------------------------------------------------
--
-- if (!m_dayFilter.isEmpty())
-- {
-- match &= m_dayFilter.contains(QDateTime(info.dateTime().date(), QTime()));
-- }
--
-- //-- Filter by rating ---------------------------------------------------------
--
-- if (m_ratingFilter >= 0)
-- {
-- // for now we treat -1 (no rating) just like a rating of 0.
-- int rating = info.rating();
--
-- if (rating == -1)
-- {
-- rating = 0;
-- }
--
-- if(m_isUnratedExcluded && rating == 0)
-- {
-- match = false;
-- }
-- else
-- {
-- if (m_ratingCond == GreaterEqualCondition)
-- {
-- // If the rating is not >=, i.e it is <, then it does not match.
-- if (rating < m_ratingFilter)
-- {
-- match = false;
-- }
-- }
-- else if (m_ratingCond == EqualCondition)
-- {
-- // If the rating is not =, i.e it is !=, then it does not match.
-- if (rating != m_ratingFilter)
-- {
-- match = false;
-- }
-- }
-- else
-- {
-- // If the rating is not <=, i.e it is >, then it does not match.
-- if (rating > m_ratingFilter)
-- {
-- match = false;
-- }
-- }
-- }
-- }
--
-- // -- Filter by mime type -----------------------------------------------------
--
-- switch (m_mimeTypeFilter)
-- {
-- // info.format is a standardized string: Only one possibility per mime type
-- case MimeFilter::ImageFiles:
-- {
-- if (info.category() != DatabaseItem::Image)
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::JPGFiles:
-- {
-- if (info.format() != QLatin1String("JPG"))
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::PNGFiles:
-- {
-- if (info.format() != QLatin1String("PNG"))
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::TIFFiles:
-- {
-- if (info.format() != QLatin1String("TIFF"))
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::DNGFiles:
-- {
-- if (info.format() != QLatin1String("RAW-DNG"))
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::NoRAWFiles:
-- {
-- if (info.format().startsWith(QLatin1String("RAW")))
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::RAWFiles:
-- {
-- if (!info.format().startsWith(QLatin1String("RAW")))
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::MoviesFiles:
-- {
-- if (info.category() != DatabaseItem::Video)
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::AudioFiles:
-- {
-- if (info.category() != DatabaseItem::Audio)
-- {
-- match = false;
-- }
--
-- break;
-- }
-- case MimeFilter::RasterFiles:
-- {
-- if (info.format() != QLatin1String("PSD") && // Adobe Photoshop Document
-- info.format() != QLatin1String("PSB") && // Adobe Photoshop Big
-- info.format() != QLatin1String("XCF") && // Gimp
-- info.format() != QLatin1String("KRA") && // Krita
-- info.format() != QLatin1String("ORA") // Open Raster
-- )
-- {
-- match = false;
-- }
--
-- break;
-- }
-- default:
-- {
-- // All Files: do nothing...
-- break;
-- }
-- }
--
-- //-- Filter by geolocation ----------------------------------------------------
--
-- if (m_geolocationCondition!=GeolocationNoFilter)
-- {
-- if (m_geolocationCondition==GeolocationNoCoordinates)
-- {
-- if (info.hasCoordinates())
-- {
-- match = false;
-- }
-- }
-- else if (m_geolocationCondition==GeolocationHasCoordinates)
-- {
-- if (!info.hasCoordinates())
-- {
-- match = false;
-- }
-- }
-- }
--
-- //-- Filter by text -----------------------------------------------------------
--
-- if (!m_textFilterSettings.text.isEmpty())
-- {
-- bool textMatch = false;
--
-- // Image name
-- if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageName &&
-- info.name().contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-- {
-- textMatch = true;
-- }
--
-- // Image title
-- if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageTitle &&
-- info.title().contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-- {
-- textMatch = true;
-- }
--
-- // Image comment
-- if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageComment &&
-- info.comment().contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-- {
-- textMatch = true;
-- }
--
-- // Tag names
-- foreach(int id, info.tagIds())
-- {
-- if (m_textFilterSettings.textFields & SearchTextFilterSettings::TagName &&
-- m_tagNameHash.value(id).contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-- {
-- textMatch = true;
-- }
-- }
--
-- // Album names
-- if (m_textFilterSettings.textFields & SearchTextFilterSettings::AlbumName &&
-- m_albumNameHash.value(info.albumId()).contains(m_textFilterSettings.text, m_textFilterSettings.caseSensitive))
-- {
-- textMatch = true;
-- }
--
-- // Image Aspect Ratio
-- if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImageAspectRatio)
-- {
-- QRegExp expRatio (QLatin1String("^\\d+:\\d+$"));
-- QRegExp expFloat (QLatin1String("^\\d+(.\\d+)?$"));
--
-- if (expRatio.indexIn(m_textFilterSettings.text) > -1 && m_textFilterSettings.text.contains(QRegExp(QLatin1String(":\\d+"))))
-- {
-- QString trimmedTextFilterSettingsText = m_textFilterSettings.text;
-- QStringList numberStringList = trimmedTextFilterSettingsText.split(QLatin1String(":"), QString::SkipEmptyParts);
--
-- if (numberStringList.length() == 2)
-- {
-- QString numString = (QString)numberStringList.at(0), denomString = (QString)numberStringList.at(1);
-- bool canConverseNum = false;
-- bool canConverseDenom = false;
-- int num = numString.toInt(&canConverseNum, 10), denom = denomString.toInt(&canConverseDenom, 10);
--
-- if (canConverseNum && canConverseDenom)
-- {
-- if (fabs(info.aspectRatio() - (double)num / denom) < 0.1)
-- textMatch = true;
-- }
-- }
-- }
-- else if (expFloat.indexIn(m_textFilterSettings.text) > -1)
-- {
-- QString trimmedTextFilterSettingsText = m_textFilterSettings.text;
-- bool canConverse = false;
-- double ratio = trimmedTextFilterSettingsText.toDouble(&canConverse);
--
-- if (canConverse)
-- {
-- if (fabs(info.aspectRatio() - ratio) < 0.1)
-- textMatch = true;
-- }
-- }
-- }
--
-- // Image Pixel Size
-- // See bug #341053 for details.
--
-- if (m_textFilterSettings.textFields & SearchTextFilterSettings::ImagePixelSize)
-- {
-- QSize size = info.dimensions();
-- int pixelSize = size.height()*size.width();
-- QString text = m_textFilterSettings.text;
--
-- if(text.contains(QRegExp(QLatin1String("^>\\d{1,15}$"))) && pixelSize > (text.remove(0,1)).toInt())
-- {
-- textMatch = true;
-- }
-- else if(text.contains(QRegExp(QLatin1String("^<\\d{1,15}$"))) && pixelSize < (text.remove(0,1)).toInt())
-- {
-- textMatch = true;
-- }
-- else if(text.contains(QRegExp(QLatin1String("^\\d+$"))) && pixelSize == text.toInt())
-- {
-- textMatch = true;
-- }
-- }
--
-- match &= textMatch;
--
-- if (foundText)
-- {
-- *foundText = textMatch;
-- }
-- }
--
-- // -- filter by URL-whitelists ------------------------------------------------
-- // NOTE: whitelists are always AND for now.
--
-- if (match)
-- {
-- const QUrl url = info.fileUrl();
--
-- for (QHash<QString, QList<QUrl>>::const_iterator it = m_urlWhitelists.constBegin();
-- it!=m_urlWhitelists.constEnd(); ++it)
-- {
-- match = it->contains(url);
--
-- if (!match)
-- {
-- break;
-- }
-- }
-- }
--
-- if (match)
-- {
-- const qlonglong id = info.id();
--
-- for (QHash<QString, QList<qlonglong> >::const_iterator it = m_idWhitelists.constBegin();
-- it!=m_idWhitelists.constEnd(); ++it)
-- {
-- match = it->contains(id);
--
-- if (!match)
-- {
-- break;
-- }
-- }
-- }
--
-- return match;
--}
--
--// -------------------------------------------------------------------------------------------------
--
--VersionImageFilterSettings::VersionImageFilterSettings()
--{
-- m_includeTagFilter = 0;
-- m_exceptionTagFilter = 0;
--}
--
--VersionImageFilterSettings::VersionImageFilterSettings(const VersionManagerSettings& settings)
--{
-- setVersionManagerSettings(settings);
--}
--
--bool VersionImageFilterSettings::operator==(const VersionImageFilterSettings& other) const
--{
-- return m_excludeTagFilter == other.m_excludeTagFilter &&
-- m_exceptionLists == other.m_exceptionLists;
--}
--
--bool VersionImageFilterSettings::matches(const ImageInfo& info) const
--{
-- if (!isFiltering())
-- {
-- return true;
-- }
--
-- const qlonglong id = info.id();
--
-- for (QHash<QString, QList<qlonglong> >::const_iterator it = m_exceptionLists.constBegin();
-- it != m_exceptionLists.constEnd(); ++it)
-- {
-- if (it->contains(id))
-- {
-- return true;
-- }
-- }
--
-- bool match = true;
-- QList<int> tagIds = info.tagIds();
--
-- if (!tagIds.contains(m_includeTagFilter))
-- {
-- for (QList<int>::const_iterator it = m_excludeTagFilter.begin();
-- it != m_excludeTagFilter.end(); ++it)
-- {
-- if (tagIds.contains(*it))
-- {
-- match = false;
-- break;
-- }
-- }
-- }
--
-- if (!match)
-- {
-- if (tagIds.contains(m_exceptionTagFilter))
-- {
-- match = true;
-- }
-- }
--
-- return match;
--}
--
--bool VersionImageFilterSettings::isHiddenBySettings(const ImageInfo& info) const
--{
-- QList<int> tagIds = info.tagIds();
--
-- foreach(int tagId, m_excludeTagFilter)
-- {
-- if (tagIds.contains(tagId))
-- {
-- return true;
-- }
-- }
--
-- return false;
--}
--
--bool VersionImageFilterSettings::isExemptedBySettings(const ImageInfo& info) const
--{
-- return info.tagIds().contains(m_exceptionTagFilter);
--}
--
--void VersionImageFilterSettings::setVersionManagerSettings(const VersionManagerSettings& settings)
--{
-- m_excludeTagFilter.clear();
--
-- if (!settings.enabled)
-- {
-- return;
-- }
--
-- if (!(settings.showInViewFlags & VersionManagerSettings::ShowOriginal))
-- {
-- m_excludeTagFilter << TagsCache::instance()->getOrCreateInternalTag(InternalTagName::originalVersion());
-- }
--
-- if (!(settings.showInViewFlags & VersionManagerSettings::ShowIntermediates))
-- {
-- m_excludeTagFilter << TagsCache::instance()->getOrCreateInternalTag(InternalTagName::intermediateVersion());
-- }
--
-- m_includeTagFilter = TagsCache::instance()->getOrCreateInternalTag(InternalTagName::currentVersion());
-- m_exceptionTagFilter = TagsCache::instance()->getOrCreateInternalTag(InternalTagName::versionAlwaysVisible());
--}
--
--void VersionImageFilterSettings::setExceptionList(const QList<qlonglong>& idList, const QString& id)
--{
-- if (idList.isEmpty())
-- {
-- m_exceptionLists.remove(id);
-- }
-- else
-- {
-- m_exceptionLists.insert(id, idList);
-- }
--}
--
--bool VersionImageFilterSettings::isFiltering() const
--{
-- return !m_excludeTagFilter.isEmpty();
--}
--
--bool VersionImageFilterSettings::isFilteringByTags() const
--{
-- return isFiltering();
--}
--
--// -------------------------------------------------------------------------------------------------
--
--GroupImageFilterSettings::GroupImageFilterSettings()
-- : m_allOpen(false)
--{
--}
--
--bool GroupImageFilterSettings::operator==(const GroupImageFilterSettings& other) const
--{
-- return (m_allOpen == other.m_allOpen &&
-- m_openGroups == other.m_openGroups);
--}
--
--bool GroupImageFilterSettings::matches(const ImageInfo& info) const
--{
-- if (m_allOpen)
-- {
-- return true;
-- }
--
-- if (info.isGrouped())
-- {
-- return m_openGroups.contains(info.groupImage().id());
-- }
-- return true;
--}
--
--void GroupImageFilterSettings::setOpen(qlonglong group, bool open)
--{
-- if (open)
-- {
-- m_openGroups << group;
-- }
-- else
-- {
-- m_openGroups.remove(group);
-- }
--}
--
--bool GroupImageFilterSettings::isOpen(qlonglong group) const
--{
-- return m_openGroups.contains(group);
--}
--
--void GroupImageFilterSettings::setAllOpen(bool open)
--{
-- m_allOpen = open;
--}
--
--bool GroupImageFilterSettings::isAllOpen() const
--{
-- return m_allOpen;
--}
--
--bool GroupImageFilterSettings::isFiltering() const
--{
-- return !m_allOpen;
--}
--
--DatabaseFields::Set GroupImageFilterSettings::watchFlags() const
--{
-- return DatabaseFields::ImageRelations;
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imagefiltersettings.h b/libs/models/imagefiltersettings.h
-deleted file mode 100644
-index 0e7beae..0000000
---- a/libs/models/imagefiltersettings.h
-+++ /dev/null
-@@ -1,349 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Filter values for use with ImageFilterModel
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- * Copyright (C) 2010 by Andi Clemens <andi dot clemens at gmail dot com>
-- * Copyright (C) 2011 by Michael G. Hansen <mike at mghansen dot de>
-- * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGEFILTERSETTINGS_H
--#define IMAGEFILTERSETTINGS_H
--
--// Qt includes
--
--#include <QHash>
--#include <QList>
--#include <QMap>
--#include <QString>
--#include <QSet>
--#include <QUrl>
--
--// Local includes
--
--#include "searchtextbar.h"
--#include "mimefilter.h"
--#include "digikam_export.h"
--
--namespace Digikam
--{
--
--class ImageInfo;
--class VersionManagerSettings;
--
--namespace DatabaseFields
--{
-- class Set;
--}
--
--// ---------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT SearchTextFilterSettings : public SearchTextSettings
--{
--
--public:
--
-- enum TextFilterFields
-- {
-- None = 0x00,
-- ImageName = 0x01,
-- ImageTitle = 0x02,
-- ImageComment = 0x04,
-- TagName = 0x08,
-- AlbumName = 0x10,
-- ImageAspectRatio = 0x20,
-- ImagePixelSize = 0x40,
-- All = ImageName | ImageTitle | ImageComment | TagName | AlbumName | ImageAspectRatio | ImagePixelSize
-- };
--
--public:
--
-- SearchTextFilterSettings()
-- {
-- textFields = None;
-- }
--
-- explicit SearchTextFilterSettings(const SearchTextSettings& settings)
-- {
-- caseSensitive = settings.caseSensitive;
-- text = settings.text;
-- textFields = None;
-- }
--
-- TextFilterFields textFields;
--};
--
--// ---------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT ImageFilterSettings
--{
--public:
--
-- ImageFilterSettings();
--
-- /**
-- * Returns true if the given ImageInfo matches the filter criteria.
-- * Optionally, foundText is set to true if it matched by text search.
-- */
-- bool matches(const ImageInfo& info, bool* const foundText = 0) const;
--
--public:
--
-- /// --- Tags filter ---
--
-- /// Possible logical matching condition used to sort tags id.
-- enum MatchingCondition
-- {
-- OrCondition,
-- AndCondition
-- };
--
-- void setTagFilter(const QList<int>& includedTags,
-- const QList<int>& excludedTags,
-- MatchingCondition matchingCond,
-- bool showUnTagged,
-- const QList<int>& clTagIds,
-- const QList<int>& plTagIds);
--
--public:
--
-- /// --- Rating filter ---
--
-- /// Possible conditions used to filter rating: >=, =, <=
-- enum RatingCondition
-- {
-- GreaterEqualCondition,
-- EqualCondition,
-- LessEqualCondition
-- };
--
-- void setRatingFilter(int rating, RatingCondition ratingCond, bool isUnratedExcluded);
--
--public:
--
-- /// --- Date filter ---
-- void setDayFilter(const QList<QDateTime>& days);
--
--public:
--
-- /// --- Text filter ---
-- void setTextFilter(const SearchTextFilterSettings& settings);
-- void setTagNames(const QHash<int, QString>& tagNameHash);
-- void setAlbumNames(const QHash<int, QString>& albumNameHash);
--
--public:
--
-- /// --- Mime filter ---
-- void setMimeTypeFilter(int mimeTypeFilter);
--
--public:
--
-- /// --- Geolocation filter
-- enum GeolocationCondition
-- {
-- GeolocationNoFilter = 0,
-- GeolocationNoCoordinates = 1 << 1,
-- GeolocationHasCoordinates = 1 << 2
-- };
--
-- void setGeolocationFilter(const GeolocationCondition& condition);
--
--public:
--
-- /// Returns if the day is a filter criteria
-- bool isFilteringByDay() const;
--
-- /// Returns if the type mime is a filter criteria
-- bool isFilteringByTypeMime() const;
--
-- /// Returns whether geolocation is a filter criteria
-- bool isFilteringByGeolocation() const;
--
-- /// Returns if the rating is a filter criteria
-- bool isFilteringByRating() const;
--
-- /// Returns if the pick labels is a filter criteria
-- bool isFilteringByPickLabels() const;
--
-- /// Returns if the color labels is a filter criteria
-- bool isFilteringByColorLabels() const;
--
-- /// Returns if the tag is a filter criteria
-- bool isFilteringByTags() const;
--
-- /// Returns if the text (including comment) is a filter criteria
-- bool isFilteringByText() const;
--
-- /// Returns if images will be filtered by these criteria at all
-- bool isFiltering() const;
--
--public:
--
-- /// --- URL whitelist filter
-- void setUrlWhitelist(const QList<QUrl>& urlList, const QString& id);
--
--public:
--
-- /// --- ID whitelist filter
-- void setIdWhitelist(const QList<qlonglong>& idList, const QString& id);
--
--public:
--
-- /// --- Change notification ---
--
-- /** Returns database fields a change in which would affect the current filtering.
-- * To find out if an image tag change affects filtering, test isFilteringByTags().
-- * The text filter will also be affected by changes in tags and album names.
-- */
-- DatabaseFields::Set watchFlags() const;
--
--private:
--
-- /**
-- * @brief Returns whether some internal filtering (whitelist by id or URL) or normal filtering is going on
-- */
-- bool isFilteringInternally() const;
--
--private:
--
-- /// --- Tags filter ---
-- bool m_untaggedFilter;
-- QList<int> m_includeTagFilter;
-- QList<int> m_excludeTagFilter;
-- MatchingCondition m_matchingCond;
-- QList<int> m_colorLabelTagFilter;
-- QList<int> m_pickLabelTagFilter;
--
-- /// --- Rating filter ---
-- int m_ratingFilter;
-- RatingCondition m_ratingCond;
-- bool m_isUnratedExcluded;
--
-- /// --- Date filter ---
-- QMap<QDateTime, bool> m_dayFilter;
--
-- /// --- Text filter ---
-- SearchTextFilterSettings m_textFilterSettings;
--
-- /// Helpers for text search: Set these if you want to search album or tag names with text search
-- QHash<int, QString> m_tagNameHash;
-- QHash<int, QString> m_albumNameHash;
--
-- /// --- Mime filter ---
-- MimeFilter::TypeMimeFilter m_mimeTypeFilter;
--
-- /// --- Geolocation filter
-- GeolocationCondition m_geolocationCondition;
--
-- /// --- URL whitelist filter
-- QHash<QString,QList<QUrl>> m_urlWhitelists;
--
-- /// --- ID whitelist filter
-- QHash<QString,QList<qlonglong> > m_idWhitelists;
--};
--
--// ---------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT VersionImageFilterSettings
--{
--public:
--
-- VersionImageFilterSettings();
-- explicit VersionImageFilterSettings(const VersionManagerSettings& settings);
--
-- bool operator==(const VersionImageFilterSettings& other) const;
--
-- /**
-- * Returns true if the given ImageInfo matches the filter criteria.
-- */
-- bool matches(const ImageInfo& info) const;
--
-- bool isHiddenBySettings(const ImageInfo& info) const;
-- bool isExemptedBySettings(const ImageInfo& info) const;
--
-- /// --- Tags filter ---
--
-- void setVersionManagerSettings(const VersionManagerSettings& settings);
--
-- /**
-- * Add list with exceptions: These images will be exempted from filtering by this filter
-- */
-- void setExceptionList(const QList<qlonglong>& idlist, const QString& id);
--
-- /// Returns if images will be filtered by these criteria at all
-- bool isFiltering() const;
--
-- /// Returns if the tag is a filter criteria
-- bool isFilteringByTags() const;
--
-- /// DatabaseFields::Set watchFlags() const: Would return 0
--
--protected:
--
-- QList<int> m_excludeTagFilter;
-- int m_includeTagFilter;
-- int m_exceptionTagFilter;
-- QHash<QString,QList<qlonglong> > m_exceptionLists;
--};
--
--// ---------------------------------------------------------------------------------------
--
--class DIGIKAM_DATABASE_EXPORT GroupImageFilterSettings
--{
--public:
--
-- GroupImageFilterSettings();
--
-- bool operator==(const GroupImageFilterSettings& other) const;
--
-- /**
-- * Returns true if the given ImageInfo matches the filter criteria.
-- */
-- bool matches(const ImageInfo& info) const;
--
-- /**
-- * Open or close a group.
-- */
-- void setOpen(qlonglong group, bool open);
-- bool isOpen(qlonglong group) const;
--
-- /**
-- * Open all groups
-- */
-- void setAllOpen(bool open);
-- bool isAllOpen() const;
--
-- /// Returns if images will be filtered by these criteria at all
-- bool isFiltering() const;
--
-- DatabaseFields::Set watchFlags() const;
--
--protected:
--
-- bool m_allOpen;
-- QSet<qlonglong> m_openGroups;
--};
--
--} // namespace Digikam
--
--Q_DECLARE_METATYPE(Digikam::ImageFilterSettings::GeolocationCondition)
--
--#endif // IMAGEFILTERSETTINGS_H
-diff --git a/libs/models/imagelistmodel.cpp b/libs/models/imagelistmodel.cpp
-deleted file mode 100644
-index fafce34..0000000
---- a/libs/models/imagelistmodel.cpp
-+++ /dev/null
-@@ -1,70 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2010-12-06
-- * Description : An image model based on a static list
-- *
-- * Copyright (C) 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagelistmodel.h"
--
--// Local includes
--
--#include "digikam_debug.h"
--#include "coredbaccess.h"
--#include "coredbchangesets.h"
--#include "coredbwatch.h"
--#include "imageinfo.h"
--#include "imageinfolist.h"
--
--namespace Digikam
--{
--
--ImageListModel::ImageListModel(QObject* parent)
-- : ImageThumbnailModel(parent)
--{
-- connect(CoreDbAccess::databaseWatch(), SIGNAL(collectionImageChange(CollectionImageChangeset)),
-- this, SLOT(slotCollectionImageChange(CollectionImageChangeset)));
--}
--
--ImageListModel::~ImageListModel()
--{
--}
--
--void ImageListModel::slotCollectionImageChange(const CollectionImageChangeset& changeset)
--{
-- if (isEmpty())
-- {
-- return;
-- }
--
-- switch (changeset.operation())
-- {
-- case CollectionImageChangeset::Added:
-- break;
-- case CollectionImageChangeset::Removed:
-- case CollectionImageChangeset::RemovedAll:
-- removeImageInfos(ImageInfoList(changeset.ids()));
-- break;
--
-- default:
-- break;
-- }
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imagelistmodel.h b/libs/models/imagelistmodel.h
-deleted file mode 100644
-index a225b1b..0000000
---- a/libs/models/imagelistmodel.h
-+++ /dev/null
-@@ -1,63 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2010-12-06
-- * Description : An image model based on a static list
-- *
-- * Copyright (C) 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGELISTMODEL_H
--#define IMAGELISTMODEL_H
--
--// Local includes
--
--#include "imagethumbnailmodel.h"
--#include "digikam_export.h"
--
--namespace Digikam
--{
--
--class ImageChangeset;
--class CollectionImageChangeset;
--
--class DIGIKAM_DATABASE_EXPORT ImageListModel : public ImageThumbnailModel
--{
-- Q_OBJECT
--
--public:
--
-- explicit ImageListModel(QObject* parent = 0);
-- ~ImageListModel();
--
-- // NOTE: necessary methods to add and remove ImageInfos to the model are inherited from ImageModel
--
--Q_SIGNALS:
--
-- /**
-- * Emitted when images are removed from the model because they are removed in the database
-- */
-- void imageInfosRemoved(const QList<ImageInfo>& infos);
--
--protected Q_SLOTS:
--
-- void slotCollectionImageChange(const CollectionImageChangeset& changeset);
--};
--
--} // namespace Digikam
--
--#endif // IMAGELISTMODEL_H
-diff --git a/libs/models/imagemodel.cpp b/libs/models/imagemodel.cpp
-deleted file mode 100644
-index 41b43cf..0000000
---- a/libs/models/imagemodel.cpp
-+++ /dev/null
-@@ -1,1368 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagemodel.h"
--
--// Qt includes
--
--#include <QHash>
--#include <QItemSelection>
--
--// Local includes
--
--#include "digikam_debug.h"
--#include "coredbchangesets.h"
--#include "coredbfields.h"
--#include "coredbwatch.h"
--#include "imageinfo.h"
--#include "imageinfolist.h"
--#include "abstractitemdragdrophandler.h"
--
--namespace Digikam
--{
--
--class ImageModel::Private
--{
--public:
--
-- Private()
-- {
-- preprocessor = 0;
-- keepFilePathCache = false;
-- sendRemovalSignals = false;
-- incrementalUpdater = 0;
-- refreshing = false;
-- reAdding = false;
-- incrementalRefreshRequested = false;
-- }
--
-- ImageInfoList infos;
-- QList<QVariant> extraValues;
-- QHash<qlonglong, int> idHash;
--
-- bool keepFilePathCache;
-- QHash<QString, qlonglong> filePathHash;
--
-- bool sendRemovalSignals;
--
-- QObject* preprocessor;
-- bool refreshing;
-- bool reAdding;
-- bool incrementalRefreshRequested;
--
-- DatabaseFields::Set watchFlags;
--
-- class ImageModelIncrementalUpdater* incrementalUpdater;
--
-- ImageInfoList pendingInfos;
-- QList<QVariant> pendingExtraValues;
--
-- inline bool isValid(const QModelIndex& index)
-- {
-- if (!index.isValid())
-- {
-- return false;
-- }
--
-- if (index.row() < 0 || index.row() >= infos.size())
-- {
-- qCDebug(DIGIKAM_GENERAL_LOG) << "Invalid index" << index;
-- return false;
-- }
--
-- return true;
-- }
-- inline bool extraValueValid(const QModelIndex& index)
-- {
-- // we assume isValid() being called before, no duplicate checks
-- if (index.row() >= extraValues.size())
-- {
-- qCDebug(DIGIKAM_GENERAL_LOG) << "Invalid index for extraData" << index;
-- return false;
-- }
--
-- return true;
-- }
--};
--
--typedef QPair<int, int> IntPair; // to make foreach macro happy
--typedef QList<IntPair> IntPairList;
--
--class ImageModelIncrementalUpdater
--{
--public:
--
-- explicit ImageModelIncrementalUpdater(ImageModel::Private* d);
--
-- void appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void aboutToBeRemovedInModel(const IntPairList& aboutToBeRemoved);
-- QList<IntPair> oldIndexes();
--
-- static QList<IntPair> toContiguousPairs(const QList<int>& ids);
--
--public:
--
-- QHash<qlonglong, int> oldIds;
-- QList<QVariant> oldExtraValues;
-- QList<ImageInfo> newInfos;
-- QList<QVariant> newExtraValues;
-- QList<IntPairList> modelRemovals;
--};
--
--ImageModel::ImageModel(QObject* parent)
-- : QAbstractListModel(parent),
-- d(new Private)
--{
-- connect(CoreDbAccess::databaseWatch(), SIGNAL(imageChange(ImageChangeset)),
-- this, SLOT(slotImageChange(ImageChangeset)));
--
-- connect(CoreDbAccess::databaseWatch(), SIGNAL(imageTagChange(ImageTagChangeset)),
-- this, SLOT(slotImageTagChange(ImageTagChangeset)));
--}
--
--ImageModel::~ImageModel()
--{
-- delete d->incrementalUpdater;
-- delete d;
--}
--
--// ------------ Access methods -------------
--
--void ImageModel::setKeepsFilePathCache(bool keepCache)
--{
-- d->keepFilePathCache = keepCache;
--}
--
--bool ImageModel::keepsFilePathCache() const
--{
-- return d->keepFilePathCache;
--}
--
--bool ImageModel::isEmpty() const
--{
-- return d->infos.isEmpty();
--}
--
--void ImageModel::setWatchFlags(const DatabaseFields::Set& set)
--{
-- d->watchFlags = set;
--}
--
--ImageInfo ImageModel::imageInfo(const QModelIndex& index) const
--{
-- if (!d->isValid(index))
-- {
-- return ImageInfo();
-- }
--
-- return d->infos.at(index.row());
--}
--
--ImageInfo& ImageModel::imageInfoRef(const QModelIndex& index) const
--{
-- return d->infos[index.row()];
--}
--
--qlonglong ImageModel::imageId(const QModelIndex& index) const
--{
-- if (!d->isValid(index))
-- {
-- return 0;
-- }
--
-- return d->infos.at(index.row()).id();
--}
--
--QList<ImageInfo> ImageModel::imageInfos(const QList<QModelIndex>& indexes) const
--{
-- QList<ImageInfo> infos;
--
-- foreach(const QModelIndex& index, indexes)
-- {
-- infos << imageInfo(index);
-- }
--
-- return infos;
--}
--
--QList<qlonglong> ImageModel::imageIds(const QList<QModelIndex>& indexes) const
--{
-- QList<qlonglong> ids;
--
-- foreach(const QModelIndex& index, indexes)
-- {
-- ids << imageId(index);
-- }
--
-- return ids;
--}
--
--ImageInfo ImageModel::imageInfo(int row) const
--{
-- if (row >= d->infos.size())
-- {
-- return ImageInfo();
-- }
--
-- return d->infos.at(row);
--}
--
--ImageInfo& ImageModel::imageInfoRef(int row) const
--{
-- return d->infos[row];
--}
--
--qlonglong ImageModel::imageId(int row) const
--{
-- if (row < 0 || row >= d->infos.size())
-- {
-- return -1;
-- }
--
-- return d->infos.at(row).id();
--}
--
--QModelIndex ImageModel::indexForImageInfo(const ImageInfo& info) const
--{
-- return indexForImageId(info.id());
--}
--
--QModelIndex ImageModel::indexForImageInfo(const ImageInfo& info, const QVariant& extraValue) const
--{
-- return indexForImageId(info.id(), extraValue);
--}
--
--QList<QModelIndex> ImageModel::indexesForImageInfo(const ImageInfo& info) const
--{
-- return indexesForImageId(info.id());
--}
--
--QModelIndex ImageModel::indexForImageId(qlonglong id) const
--{
-- int index = d->idHash.value(id, -1);
--
-- if (index != -1)
-- {
-- return createIndex(index, 0);
-- }
--
-- return QModelIndex();
--}
--
--QModelIndex ImageModel::indexForImageId(qlonglong id, const QVariant& extraValue) const
--{
-- if (d->extraValues.isEmpty())
-- return indexForImageId(id);
--
-- QHash<qlonglong, int>::const_iterator it;
--
-- for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-- {
-- if (d->extraValues.at(it.value()) == extraValue)
-- return createIndex(it.value(), 0);
-- }
--
-- return QModelIndex();
--}
--
--QList<QModelIndex> ImageModel::indexesForImageId(qlonglong id) const
--{
-- QList<QModelIndex> indexes;
-- QHash<qlonglong, int>::const_iterator it;
--
-- for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-- {
-- indexes << createIndex(it.value(), 0);
-- }
--
-- return indexes;
--}
--
--int ImageModel::numberOfIndexesForImageInfo(const ImageInfo& info) const
--{
-- return numberOfIndexesForImageId(info.id());
--}
--
--int ImageModel::numberOfIndexesForImageId(qlonglong id) const
--{
-- if (d->extraValues.isEmpty())
-- {
-- return 0;
-- }
--
-- int count = 0;
-- QHash<qlonglong,int>::const_iterator it;
--
-- for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-- {
-- ++count;
-- }
--
-- return count;
--}
--
--// static method
--ImageInfo ImageModel::retrieveImageInfo(const QModelIndex& index)
--{
-- if (!index.isValid())
-- {
-- return ImageInfo();
-- }
--
-- ImageModel* const model = index.data(ImageModelPointerRole).value<ImageModel*>();
-- int row = index.data(ImageModelInternalId).toInt();
--
-- if (!model)
-- {
-- return ImageInfo();
-- }
--
-- return model->imageInfo(row);
--}
--
--// static method
--qlonglong ImageModel::retrieveImageId(const QModelIndex& index)
--{
-- if (!index.isValid())
-- {
-- return 0;
-- }
--
-- ImageModel* const model = index.data(ImageModelPointerRole).value<ImageModel*>();
-- int row = index.data(ImageModelInternalId).toInt();
--
-- if (!model)
-- {
-- return 0;
-- }
--
-- return model->imageId(row);
--}
--
--QModelIndex ImageModel::indexForPath(const QString& filePath) const
--{
-- if (d->keepFilePathCache)
-- {
-- return indexForImageId(d->filePathHash.value(filePath));
-- }
-- else
-- {
-- const int size = d->infos.size();
--
-- for (int i=0; i<size; ++i)
-- {
-- if (d->infos.at(i).filePath() == filePath)
-- {
-- return createIndex(i, 0);
-- }
-- }
-- }
--
-- return QModelIndex();
--}
--
--QList<QModelIndex> ImageModel::indexesForPath(const QString& filePath) const
--{
-- if (d->keepFilePathCache)
-- {
-- return indexesForImageId(d->filePathHash.value(filePath));
-- }
-- else
-- {
-- QList<QModelIndex> indexes;
-- const int size = d->infos.size();
--
-- for (int i=0; i<size; ++i)
-- {
-- if (d->infos.at(i).filePath() == filePath)
-- {
-- indexes << createIndex(i, 0);
-- }
-- }
--
-- return indexes;
-- }
--}
--
--ImageInfo ImageModel::imageInfo(const QString& filePath) const
--{
-- if (d->keepFilePathCache)
-- {
-- qlonglong id = d->filePathHash.value(filePath);
--
-- if (id)
-- {
-- int index = d->idHash.value(id, -1);
--
-- if (index != -1)
-- {
-- return d->infos.at(index);
-- }
-- }
-- }
-- else
-- {
-- foreach(const ImageInfo& info, d->infos)
-- {
-- if (info.filePath() == filePath)
-- {
-- return info;
-- }
-- }
-- }
--
-- return ImageInfo();
--}
--
--QList<ImageInfo> ImageModel::imageInfos(const QString& filePath) const
--{
-- QList<ImageInfo> infos;
--
-- if (d->keepFilePathCache)
-- {
-- qlonglong id = d->filePathHash.value(filePath);
--
-- if (id)
-- {
-- foreach(int index, d->idHash.values(id))
-- {
-- infos << d->infos.at(index);
-- }
-- }
-- }
-- else
-- {
-- foreach(const ImageInfo& info, d->infos)
-- {
-- if (info.filePath() == filePath)
-- {
-- infos << info;
-- }
-- }
-- }
--
-- return infos;
--}
--
--void ImageModel::addImageInfo(const ImageInfo& info)
--{
-- addImageInfos(QList<ImageInfo>() << info, QList<QVariant>());
--}
--
--void ImageModel::addImageInfos(const QList<ImageInfo>& infos)
--{
-- addImageInfos(infos, QList<QVariant>());
--}
--
--void ImageModel::addImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- if (infos.isEmpty())
-- {
-- return;
-- }
--
-- if (d->incrementalUpdater)
-- {
-- d->incrementalUpdater->appendInfos(infos, extraValues);
-- }
-- else
-- {
-- appendInfos(infos, extraValues);
-- }
--}
--
--void ImageModel::addImageInfoSynchronously(const ImageInfo& info)
--{
-- addImageInfosSynchronously(QList<ImageInfo>() << info, QList<QVariant>());
--}
--
--void ImageModel::addImageInfosSynchronously(const QList<ImageInfo>& infos)
--{
-- addImageInfos(infos, QList<QVariant>());
--}
--
--void ImageModel::addImageInfosSynchronously(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- if (infos.isEmpty())
-- {
-- return;
-- }
--
-- publiciseInfos(infos, extraValues);
-- emit processAdded(infos, extraValues);
--}
--
--void ImageModel::ensureHasImageInfo(const ImageInfo& info)
--{
-- ensureHasImageInfos(QList<ImageInfo>() << info, QList<QVariant>());
--}
--
--void ImageModel::ensureHasImageInfos(const QList<ImageInfo>& infos)
--{
-- ensureHasImageInfos(infos, QList<QVariant>());
--}
--
--void ImageModel::ensureHasImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- if (extraValues.isEmpty())
-- {
-- if (!d->pendingExtraValues.isEmpty())
-- {
-- qCDebug(DIGIKAM_GENERAL_LOG) << "ExtraValue / No Extra Value mismatch. Ignoring added infos.";
-- return;
-- }
-- }
-- else
-- {
-- if (d->pendingInfos.size() != d->pendingExtraValues.size())
-- {
-- qCDebug(DIGIKAM_GENERAL_LOG) << "ExtraValue / No Extra Value mismatch. Ignoring added infos.";
-- return;
-- }
-- }
--
-- d->pendingInfos << infos;
-- d->pendingExtraValues << extraValues;
-- cleanSituationChecks();
--}
--
--void ImageModel::clearImageInfos()
--{
-- d->infos.clear();
-- d->extraValues.clear();
-- d->idHash.clear();
-- d->filePathHash.clear();
-- delete d->incrementalUpdater;
-- d->incrementalUpdater = 0;
-- d->pendingInfos.clear();
-- d->pendingExtraValues.clear();
-- d->refreshing = false;
-- d->reAdding = false;
-- d->incrementalRefreshRequested = false;
--
-- beginResetModel();
-- endResetModel();
--
-- imageInfosCleared();
--}
--
--void ImageModel::setImageInfos(const QList<ImageInfo>& infos)
--{
-- clearImageInfos();
-- addImageInfos(infos);
--}
--
--QList<ImageInfo> ImageModel::imageInfos() const
--{
-- return d->infos;
--}
--
--QList<qlonglong> ImageModel::imageIds() const
--{
-- return d->idHash.keys();
--}
--
--bool ImageModel::hasImage(qlonglong id) const
--{
-- return d->idHash.contains(id);
--}
--
--bool ImageModel::hasImage(const ImageInfo& info) const
--{
-- return d->idHash.contains(info.id());
--}
--
--bool ImageModel::hasImage(const ImageInfo& info, const QVariant& extraValue) const
--{
-- return hasImage(info.id(), extraValue);
--}
--
--bool ImageModel::hasImage(qlonglong id, const QVariant& extraValue) const
--{
-- if (d->extraValues.isEmpty())
-- return hasImage(id);
--
-- QHash<qlonglong, int>::const_iterator it;
--
-- for (it = d->idHash.constFind(id); it != d->idHash.constEnd() && it.key() == id; ++it)
-- {
-- if (d->extraValues.at(it.value()) == extraValue)
-- return true;
-- }
--
-- return false;;
--}
--
--QList<ImageInfo> ImageModel::uniqueImageInfos() const
--{
-- if (d->extraValues.isEmpty())
-- {
-- return d->infos;
-- }
--
-- QList<ImageInfo> uniqueInfos;
-- const int size = d->infos.size();
--
-- for (int i=0; i<size; ++i)
-- {
-- const ImageInfo& info = d->infos.at(i);
--
-- if (d->idHash.value(info.id()) == i)
-- {
-- uniqueInfos << info;
-- }
-- }
--
-- return uniqueInfos;
--}
--
--void ImageModel::emitDataChangedForAll()
--{
-- if (d->infos.isEmpty())
-- {
-- return;
-- }
--
-- QModelIndex first = createIndex(0, 0);
-- QModelIndex last = createIndex(d->infos.size() - 1, 0);
-- emit dataChanged(first, last);
--}
--
--void ImageModel::emitDataChangedForSelection(const QItemSelection& selection)
--{
-- if (!selection.isEmpty())
-- {
-- foreach(const QItemSelectionRange& range, selection)
-- {
-- emit dataChanged(range.topLeft(), range.bottomRight());
-- }
-- }
--}
--
--void ImageModel::ensureHasGroupedImages(const ImageInfo& groupLeader)
--{
-- ensureHasImageInfos(groupLeader.groupedImages());
--}
--
--// ------------ Preprocessing -------------
--
--void ImageModel::setPreprocessor(QObject* preprocessor)
--{
-- unsetPreprocessor(d->preprocessor);
-- d->preprocessor = preprocessor;
--}
--
--void ImageModel::unsetPreprocessor(QObject* preprocessor)
--{
-- if (preprocessor && d->preprocessor == preprocessor)
-- {
-- disconnect(this, SIGNAL(preprocess(QList<ImageInfo>,QList<QVariant>)), 0, 0);
-- disconnect(d->preprocessor, 0, this, SLOT(reAddImageInfos(QList<ImageInfo>,QList<QVariant>)));
-- disconnect(d->preprocessor, 0, this, SLOT(reAddingFinished()));
-- }
--}
--
--void ImageModel::appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- if (infos.isEmpty())
-- {
-- return;
-- }
--
-- if (d->preprocessor)
-- {
-- d->reAdding = true;
-- emit preprocess(infos, extraValues);
-- }
-- else
-- {
-- publiciseInfos(infos, extraValues);
-- }
--}
--
--void ImageModel::appendInfosChecked(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- // This method does deduplication. It is private because in context of readding or refreshing it is of no use.
--
-- if (extraValues.isEmpty())
-- {
-- QList<ImageInfo> checkedInfos;
--
-- foreach (const ImageInfo& info, infos)
-- {
-- if (!hasImage(info))
-- {
-- checkedInfos << info;
-- }
-- }
--
-- appendInfos(checkedInfos, QList<QVariant>());
-- }
-- else
-- {
-- QList<ImageInfo> checkedInfos;
-- QList<QVariant> checkedExtraValues;
-- const int size = infos.size();
--
-- for (int i=0; i<size; i++)
-- {
-- if (!hasImage(infos[i], extraValues[i]))
-- {
-- checkedInfos << infos[i];
-- checkedExtraValues << extraValues[i];
-- }
-- }
--
-- appendInfos(checkedInfos, checkedExtraValues);
-- }
--}
--
--void ImageModel::reAddImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- // addImageInfos -> appendInfos -> preprocessor -> reAddImageInfos
-- publiciseInfos(infos, extraValues);
--}
--
--void ImageModel::reAddingFinished()
--{
-- d->reAdding = false;
-- cleanSituationChecks();
--}
--
--void ImageModel::startRefresh()
--{
-- d->refreshing = true;
--}
--
--void ImageModel::finishRefresh()
--{
-- d->refreshing = false;
-- cleanSituationChecks();
--}
--
--bool ImageModel::isRefreshing() const
--{
-- return d->refreshing;
--}
--
--void ImageModel::cleanSituationChecks()
--{
-- // For starting an incremental refresh we want a clear situation:
-- // Any remaining batches from non-incremental refreshing subclasses have been received in appendInfos(),
-- // any batches sent to preprocessor for re-adding have been re-added.
-- if (d->refreshing || d->reAdding)
-- {
-- return;
-- }
--
-- if (!d->pendingInfos.isEmpty())
-- {
-- appendInfosChecked(d->pendingInfos, d->pendingExtraValues);
-- d->pendingInfos.clear();
-- d->pendingExtraValues.clear();
-- cleanSituationChecks();
-- return;
-- }
--
-- if (d->incrementalRefreshRequested)
-- {
-- d->incrementalRefreshRequested = false;
-- emit readyForIncrementalRefresh();
-- }
-- else
-- {
-- emit allRefreshingFinished();
-- }
--}
--
--void ImageModel::publiciseInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- if (infos.isEmpty())
-- {
-- return;
-- }
--
-- Q_ASSERT(infos.size() == extraValues.size() || (extraValues.isEmpty() && d->extraValues.isEmpty()));
--
-- emit imageInfosAboutToBeAdded(infos);
-- const int firstNewIndex = d->infos.size();
-- const int lastNewIndex = d->infos.size() + infos.size() - 1;
-- beginInsertRows(QModelIndex(), firstNewIndex, lastNewIndex);
-- d->infos << infos;
-- d->extraValues << extraValues;
--
-- for (int i=firstNewIndex; i<=lastNewIndex; ++i)
-- {
-- const ImageInfo& info = d->infos.at(i);
-- qlonglong id = info.id();
-- d->idHash.insertMulti(id, i);
--
-- if (d->keepFilePathCache)
-- {
-- d->filePathHash[info.filePath()] = id;
-- }
-- }
--
-- endInsertRows();
-- emit imageInfosAdded(infos);
--}
--
--void ImageModel::requestIncrementalRefresh()
--{
-- if (d->reAdding)
-- {
-- d->incrementalRefreshRequested = true;
-- }
-- else
-- {
-- emit readyForIncrementalRefresh();
-- }
--}
--
--bool ImageModel::hasIncrementalRefreshPending() const
--{
-- return d->incrementalRefreshRequested;
--}
--
--void ImageModel::startIncrementalRefresh()
--{
-- delete d->incrementalUpdater;
--
-- d->incrementalUpdater = new ImageModelIncrementalUpdater(d);
--}
--
--void ImageModel::finishIncrementalRefresh()
--{
-- if (!d->incrementalUpdater)
-- {
-- return;
-- }
--
-- // remove old entries
-- QList<QPair<int, int> > pairs = d->incrementalUpdater->oldIndexes();
-- removeRowPairs(pairs);
--
-- // add new indexes
-- appendInfos(d->incrementalUpdater->newInfos, d->incrementalUpdater->newExtraValues);
--
-- delete d->incrementalUpdater;
-- d->incrementalUpdater = 0;
--}
--
--void ImageModel::removeIndex(const QModelIndex& index)
--{
-- removeIndexes(QList<QModelIndex>() << index);
--}
--
--void ImageModel::removeIndexes(const QList<QModelIndex>& indexes)
--{
-- QList<int> listIndexes;
--
-- foreach(const QModelIndex& index, indexes)
-- {
-- if (d->isValid(index))
-- {
-- listIndexes << index.row();
-- }
-- }
--
-- if (listIndexes.isEmpty())
-- {
-- return;
-- }
--
-- removeRowPairsWithCheck(ImageModelIncrementalUpdater::toContiguousPairs(listIndexes));
--}
--
--void ImageModel::removeImageInfo(const ImageInfo& info)
--{
-- removeImageInfos(QList<ImageInfo>() << info);
--}
--
--void ImageModel::removeImageInfos(const QList<ImageInfo>& infos)
--{
-- QList<int> listIndexes;
--
-- foreach(const ImageInfo& info, infos)
-- {
-- QModelIndex index = indexForImageId(info.id());
--
-- if (index.isValid())
-- {
-- listIndexes << index.row();
-- }
-- }
-- removeRowPairsWithCheck(ImageModelIncrementalUpdater::toContiguousPairs(listIndexes));
--}
--
--void ImageModel::removeImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- if (extraValues.isEmpty())
-- {
-- removeImageInfos(infos);
-- return;
-- }
--
-- QList<int> listIndexes;
--
-- for (int i=0; i<infos.size(); ++i)
-- {
-- QModelIndex index = indexForImageId(infos.at(i).id(), extraValues.at(i));
--
-- if (index.isValid())
-- {
-- listIndexes << index.row();
-- }
-- }
--
-- removeRowPairsWithCheck(ImageModelIncrementalUpdater::toContiguousPairs(listIndexes));
--}
--
--void ImageModel::setSendRemovalSignals(bool send)
--{
-- d->sendRemovalSignals = send;
--}
--
--template <class List, typename T>
--static bool pairsContain(const List& list, T value)
--{
-- typename List::const_iterator middle;
-- typename List::const_iterator begin = list.begin();
-- typename List::const_iterator end = list.end();
-- int n = int(end - begin);
-- int half;
--
-- while (n > 0)
-- {
-- half = n >> 1;
-- middle = begin + half;
--
-- if (middle->first <= value && middle->second >= value)
-- {
-- return true;
-- }
-- else if (middle->second < value)
-- {
-- begin = middle + 1;
-- n -= half + 1;
-- }
-- else
-- {
-- n = half;
-- }
-- }
--
-- return false;
--}
--
--void ImageModel::removeRowPairsWithCheck(const QList<QPair<int, int> >& toRemove)
--{
-- if (d->incrementalUpdater)
-- {
-- d->incrementalUpdater->aboutToBeRemovedInModel(toRemove);
-- }
--
-- removeRowPairs(toRemove);
--}
--
--void ImageModel::removeRowPairs(const QList<QPair<int, int> >& toRemove)
--{
-- if (toRemove.isEmpty())
-- {
-- return;
-- }
--
-- // Remove old indexes
-- // Keep in mind that when calling beginRemoveRows all structures announced to be removed
-- // must still be valid, and this includes our hashes as well, which limits what we can optimize
--
-- int removedRows = 0, offset = 0;
-- typedef QPair<int, int> IntPair; // to make foreach macro happy
--
-- foreach(const IntPair& pair, toRemove)
-- {
-- const int begin = pair.first - offset;
-- const int end = pair.second - offset; // inclusive
-- removedRows = end - begin + 1;
--
-- // when removing from the list, all subsequent indexes are affected
-- offset += removedRows;
--
-- QList<ImageInfo> removedInfos;
--
-- if (d->sendRemovalSignals)
-- {
-- qCopy(d->infos.begin() + begin, d->infos.begin() + end, removedInfos.begin());
-- emit imageInfosAboutToBeRemoved(removedInfos);
-- }
--
-- imageInfosAboutToBeRemoved(begin, end);
-- beginRemoveRows(QModelIndex(), begin, end);
--
-- // update idHash - which points to indexes of d->infos, and these change now!
-- QHash<qlonglong, int>::iterator it;
--
-- for (it = d->idHash.begin(); it != d->idHash.end(); )
-- {
-- if (it.value() >= begin)
-- {
-- if (it.value() > end)
-- {
-- // after the removed interval: adjust index
-- it.value() -= removedRows;
-- }
-- else
-- {
-- // in the removed interval
-- it = d->idHash.erase(it);
-- continue;
-- }
-- }
--
-- ++it;
-- }
--
-- // remove from list
-- d->infos.erase(d->infos.begin() + begin, d->infos.begin() + (end + 1));
--
-- if (!d->extraValues.isEmpty())
-- {
-- d->extraValues.erase(d->extraValues.begin() + begin, d->extraValues.begin() + (end + 1));
-- }
--
-- endRemoveRows();
--
-- if (d->sendRemovalSignals)
-- {
-- emit imageInfosRemoved(removedInfos);
-- }
-- }
--
-- // tidy up: remove old indexes from file path hash now
-- if (d->keepFilePathCache)
-- {
-- QHash<QString, qlonglong>::iterator it;
--
-- for (it = d->filePathHash.begin(); it != d->filePathHash.end(); )
-- {
-- if (pairsContain(toRemove, it.value()))
-- {
-- it = d->filePathHash.erase(it);
-- }
-- else
-- {
-- ++it;
-- }
-- }
-- }
--}
--
--ImageModelIncrementalUpdater::ImageModelIncrementalUpdater(ImageModel::Private* d)
--{
-- oldIds = d->idHash;
-- oldExtraValues = d->extraValues;
--}
--
--void ImageModelIncrementalUpdater::appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues)
--{
-- if (extraValues.isEmpty())
-- {
-- foreach(const ImageInfo& info, infos)
-- {
-- QHash<qlonglong,int>::iterator it = oldIds.find(info.id());
--
-- if (it != oldIds.end())
-- {
-- oldIds.erase(it);
-- }
-- else
-- {
-- newInfos << info;
-- }
-- }
-- }
-- else
-- {
-- for (int i=0; i<infos.size(); ++i)
-- {
-- const ImageInfo& info = infos.at(i);
-- bool found = false;
-- QHash<qlonglong,int>::iterator it;
--
-- for (it = oldIds.find(info.id()); it != oldIds.end() && it.key() == info.id(); ++it)
-- {
-- // first check is for bug #262596. Not sure if needed.
-- if (it.value() < oldExtraValues.size() && extraValues.at(i) == oldExtraValues.at(it.value()))
-- {
-- found = true;
-- break;
-- }
-- }
--
-- if (found)
-- {
-- oldIds.erase(it);
-- // do not erase from oldExtraValues - oldIds is a hash id -> index.
-- }
-- else
-- {
-- newInfos << info;
-- newExtraValues << extraValues.at(i);
-- }
-- }
-- }
--}
--
--void ImageModelIncrementalUpdater::aboutToBeRemovedInModel(const IntPairList& toRemove)
--{
-- modelRemovals << toRemove;
--}
--
--QList<QPair<int, int> > ImageModelIncrementalUpdater::oldIndexes()
--{
-- // first, apply all changes to indexes by direct removal in model
-- // while the updater was active
-- foreach(const IntPairList& list, modelRemovals)
-- {
-- int removedRows = 0, offset = 0;
--
-- foreach(const IntPair& pair, list)
-- {
-- const int begin = pair.first - offset;
-- const int end = pair.second - offset; // inclusive
-- removedRows = end - begin + 1;
--
-- // when removing from the list, all subsequent indexes are affected
-- offset += removedRows;
--
-- // update idHash - which points to indexes of d->infos, and these change now!
-- QHash<qlonglong, int>::iterator it;
--
-- for (it = oldIds.begin(); it != oldIds.end(); )
-- {
-- if (it.value() >= begin)
-- {
-- if (it.value() > end)
-- {
-- // after the removed interval: adjust index
-- it.value() -= removedRows;
-- }
-- else
-- {
-- // in the removed interval
-- it = oldIds.erase(it);
-- continue;
-- }
-- }
--
-- ++it;
-- }
-- }
-- }
--
-- modelRemovals.clear();
--
-- return toContiguousPairs(oldIds.values());
--}
--
--QList<QPair<int, int> > ImageModelIncrementalUpdater::toContiguousPairs(const QList<int>& unsorted)
--{
-- // Take the given indices and return them as contiguous pairs [begin, end]
--
-- QList<QPair<int, int> > pairs;
--
-- if (unsorted.isEmpty())
-- {
-- return pairs;
-- }
--
-- QList<int> indices(unsorted);
-- qSort(indices);
--
-- QPair<int, int> pair(indices.first(), indices.first());
--
-- for (int i=1; i<indices.size(); ++i)
-- {
-- const int &index = indices.at(i);
--
-- if (index == pair.second + 1)
-- {
-- pair.second = index;
-- continue;
-- }
--
-- pairs << pair; // insert last pair
-- pair.first = index;
-- pair.second = index;
-- }
--
-- pairs << pair;
--
-- return pairs;
--}
--
--// ------------ QAbstractItemModel implementation -------------
--
--QVariant ImageModel::data(const QModelIndex& index, int role) const
--{
-- if (!d->isValid(index))
-- {
-- return QVariant();
-- }
--
-- switch (role)
-- {
-- case Qt::DisplayRole:
-- case Qt::ToolTipRole:
-- return d->infos.at(index.row()).name();
--
-- case ImageModelPointerRole:
-- return QVariant::fromValue(const_cast<ImageModel*>(this));
--
-- case ImageModelInternalId:
-- return index.row();
--
-- case CreationDateRole:
-- return d->infos.at(index.row()).dateTime();
--
-- case ExtraDataRole:
--
-- if (d->extraValueValid(index))
-- {
-- return d->extraValues.at(index.row());
-- }
-- else
-- {
-- return QVariant();
-- }
--
-- case ExtraDataDuplicateCount:
-- {
-- qlonglong id = d->infos.at(index.row()).id();
-- return numberOfIndexesForImageId(id);
-- }
-- }
--
-- return QVariant();
--}
--
--QVariant ImageModel::headerData(int section, Qt::Orientation orientation, int role) const
--{
-- Q_UNUSED(section)
-- Q_UNUSED(orientation)
-- Q_UNUSED(role)
-- return QVariant();
--}
--
--int ImageModel::rowCount(const QModelIndex& parent) const
--{
-- if (parent.isValid())
-- {
-- return 0;
-- }
--
-- return d->infos.size();
--}
--
--Qt::ItemFlags ImageModel::flags(const QModelIndex& index) const
--{
-- if (!d->isValid(index))
-- {
-- return 0;
-- }
--
-- Qt::ItemFlags f = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
--
-- f |= dragDropFlags(index);
--
-- return f;
--}
--
--QModelIndex ImageModel::index(int row, int column, const QModelIndex& parent) const
--{
-- if (column != 0 || row < 0 || parent.isValid() || row >= d->infos.size())
-- {
-- return QModelIndex();
-- }
--
-- return createIndex(row, 0);
--}
--
--// ------------ Database watch -------------
--
--void ImageModel::slotImageChange(const ImageChangeset& changeset)
--{
-- if (d->infos.isEmpty())
-- {
-- return;
-- }
--
-- if (d->watchFlags & changeset.changes())
-- {
-- QItemSelection items;
--
-- foreach(const qlonglong& id, changeset.ids())
-- {
-- QModelIndex index = indexForImageId(id);
--
-- if (index.isValid())
-- {
-- items.select(index, index);
-- }
-- }
--
-- if (!items.isEmpty())
-- {
-- emitDataChangedForSelection(items);
-- emit imageChange(changeset, items);
-- }
-- }
--}
--
--void ImageModel::slotImageTagChange(const ImageTagChangeset& changeset)
--{
-- if (d->infos.isEmpty())
-- {
-- return;
-- }
--
-- QItemSelection items;
--
-- foreach(const qlonglong& id, changeset.ids())
-- {
-- QModelIndex index = indexForImageId(id);
--
-- if (index.isValid())
-- {
-- items.select(index, index);
-- }
-- }
--
-- if (!items.isEmpty())
-- {
-- emitDataChangedForSelection(items);
-- emit imageTagChange(changeset, items);
-- }
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imagemodel.h b/libs/models/imagemodel.h
-deleted file mode 100644
-index dcf94c2..0000000
---- a/libs/models/imagemodel.h
-+++ /dev/null
-@@ -1,364 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGEMODEL_H
--#define IMAGEMODEL_H
--
--// Qt includes
--
--#include <QAbstractListModel>
--
--// Local includes
--
--#include "dragdropimplementations.h"
--#include "imageinfo.h"
--#include "digikam_export.h"
--
--class QItemSelection;
--
--namespace Digikam
--{
--
--class ImageChangeset;
--class ImageTagChangeset;
--
--namespace DatabaseFields
--{
--class Set;
--}
--
--class DIGIKAM_DATABASE_EXPORT ImageModel : public QAbstractListModel, public DragDropModelImplementation
--{
-- Q_OBJECT
--
--public:
--
-- enum ImageModelRoles
-- {
-- /// An ImageModel* pointer to this model
-- ImageModelPointerRole = Qt::UserRole,
-- ImageModelInternalId = Qt::UserRole + 1,
-- /// Returns a thumbnail pixmap. May be implemented by subclasses.
-- /// Returns either a valid pixmap or a null QVariant.
-- ThumbnailRole = Qt::UserRole + 2,
-- /// Returns a QDateTime with the creation date
-- CreationDateRole = Qt::UserRole + 3,
-- /// Return (optional) extraData field
-- ExtraDataRole = Qt::UserRole + 5,
-- /// Returns the number of duplicate indexes for the same image id
-- ExtraDataDuplicateCount = Qt::UserRole + 6,
--
-- // Roles which are defined here but not implemented by ImageModel
-- /// Returns position of item in Left Light Table preview.
-- LTLeftPanelRole = Qt::UserRole + 50,
-- /// Returns position of item in Right Light Table preview.
-- LTRightPanelRole = Qt::UserRole + 51,
--
-- // For use by subclasses
-- SubclassRoles = Qt::UserRole + 100,
-- // For use by filter models
-- FilterModelRoles = Qt::UserRole + 500
-- };
--
--public:
--
-- explicit ImageModel(QObject* parent = 0);
-- ~ImageModel();
--
-- /** If a cache is kept, lookup by file path is fast,
-- * without a cache it is O(n). Default is false.
-- */
-- void setKeepsFilePathCache(bool keepCache);
-- bool keepsFilePathCache() const;
--
-- /** Set a set of database fields to watch.
-- * If either of these is changed, dataChanged() will be emitted.
-- * Default is no flag (no signal will be emitted).
-- */
-- void setWatchFlags(const DatabaseFields::Set& set);
--
-- /** Returns the ImageInfo object, reference or image id from the underlying data
-- * pointed to by the index.
-- * If the index is not valid, imageInfo will return a null ImageInfo, imageId will
-- * return 0, imageInfoRef must not be called with an invalid index.
-- */
-- ImageInfo imageInfo(const QModelIndex& index) const;
-- ImageInfo& imageInfoRef(const QModelIndex& index) const;
-- qlonglong imageId(const QModelIndex& index) const;
-- QList<ImageInfo> imageInfos(const QList<QModelIndex>& indexes) const;
-- QList<qlonglong> imageIds(const QList<QModelIndex>& indexes) const;
--
-- /** Returns the ImageInfo object, reference or image id from the underlying data
-- * of the given row (parent is the invalid QModelIndex, column is 0).
-- * Note that imageInfoRef will crash if index is invalid.
-- */
-- ImageInfo imageInfo(int row) const;
-- ImageInfo& imageInfoRef(int row) const;
-- qlonglong imageId(int row) const;
--
-- /** Return the index for the given ImageInfo or id, if contained in this model.
-- */
-- QModelIndex indexForImageInfo(const ImageInfo& info) const;
-- QModelIndex indexForImageInfo(const ImageInfo& info, const QVariant& extraValue) const;
-- QModelIndex indexForImageId(qlonglong id) const;
-- QModelIndex indexForImageId(qlonglong id, const QVariant& extraValue) const;
-- QList<QModelIndex> indexesForImageInfo(const ImageInfo& info) const;
-- QList<QModelIndex> indexesForImageId(qlonglong id) const;
--
-- int numberOfIndexesForImageInfo(const ImageInfo& info) const;
-- int numberOfIndexesForImageId(qlonglong id) const;
--
-- /** Returns the index or ImageInfo object from the underlying data
-- * for the given file path. This is fast if keepsFilePathCache is enabled.
-- * The file path is as returned by ImageInfo.filePath().
-- * In case of multiple occurrences of the same file, the simpler variants return
-- * any one found first, use the QList methods to retrieve all occurrences.
-- */
-- QModelIndex indexForPath(const QString& filePath) const;
-- ImageInfo imageInfo(const QString& filePath) const;
-- QList<QModelIndex> indexesForPath(const QString& filePath) const;
-- QList<ImageInfo> imageInfos(const QString& filePath) const;
--
-- /** Main entry point for subclasses adding image infos to the model.
-- * If you list entries not unique per image id, you must add an extraValue
-- * so that every entry is unique by imageId and extraValues.
-- * Please note that these methods do not prevent addition of duplicate entries.
-- */
-- void addImageInfo(const ImageInfo& info);
-- void addImageInfos(const QList<ImageInfo>& infos);
-- void addImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
--
-- /** Clears image infos and resets model.
-- */
-- void clearImageInfos();
--
-- /** Clears and adds the infos.
-- */
-- void setImageInfos(const QList<ImageInfo>& infos);
--
-- /**
-- * Directly remove the given indexes or infos from the model.
-- */
-- void removeIndex(const QModelIndex& indexes);
-- void removeIndexes(const QList<QModelIndex>& indexes);
-- void removeImageInfo(const ImageInfo& info);
-- void removeImageInfos(const QList<ImageInfo>& infos);
-- void removeImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
--
-- /**
-- * addImageInfo() is asynchronous if a prepocessor is set.
-- * This method first adds the info, synchronously.
-- * Only afterwards, the preprocessor will have the opportunity to process it.
-- * This method also bypasses any incremental updates.
-- * Please note that these methods do not prevent addition of duplicate entries.
-- */
-- void addImageInfoSynchronously(const ImageInfo& info);
-- void addImageInfosSynchronously(const QList<ImageInfo>& infos);
-- void addImageInfosSynchronously(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
--
-- /**
-- * Add the given entries. Method returns immediately, the
-- * addition may happen later asynchronously.
-- * These methods prevent the addition of duplicate entries.
-- */
-- void ensureHasImageInfo(const ImageInfo& info);
-- void ensureHasImageInfos(const QList<ImageInfo>& infos);
-- void ensureHasImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
--
-- /**
-- * Ensure that all images grouped on the given leader are contained in the model.
-- */
-- void ensureHasGroupedImages(const ImageInfo& groupLeader);
--
-- QList<ImageInfo> imageInfos() const;
-- QList<qlonglong> imageIds() const;
-- QList<ImageInfo> uniqueImageInfos() const;
--
-- bool hasImage(qlonglong id) const;
-- bool hasImage(const ImageInfo& info) const;
-- bool hasImage(const ImageInfo& info, const QVariant& extraValue) const;
-- bool hasImage(qlonglong id, const QVariant& extraValue) const;
--
-- bool isEmpty() const;
--
-- // Drag and Drop
-- DECLARE_MODEL_DRAG_DROP_METHODS
--
-- /**
-- * Install an object as a preprocessor for ImageInfos added to this model.
-- * For every QList of ImageInfos added to addImageInfo, the signal preprocess()
-- * will be emitted. The preprocessor may process the items and shall then readd
-- * them by calling reAddImageInfos(). It may take some time to process.
-- * It shall discard any held infos when the modelReset() signal is sent.
-- * It shall call readdFinished() when no reset occurred and all infos on the way have been readded.
-- * This means that only after calling this method, you shall make three connections
-- * (preprocess -> your slot, your signal -> reAddImageInfos, your signal -> reAddingFinished)
-- * and make or already hold a connection modelReset() -> your slot.
-- * There is only one preprocessor at a time, a previously set object will be disconnected.
-- */
-- void setPreprocessor(QObject* processor);
-- void unsetPreprocessor(QObject* processor);
--
-- /**
-- * Returns true if this model is currently refreshing.
-- * For a preprocessor this means that, although the preprocessor may currently have
-- * processed all it got, more batches are to be expected.
-- */
-- bool isRefreshing() const;
--
-- /**
-- * Enable sending of imageInfosAboutToBeRemoved and imageInfosRemoved signals.
-- * Default: false
-- */
-- void setSendRemovalSignals(bool send);
--
-- virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-- virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
-- virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
-- virtual Qt::ItemFlags flags(const QModelIndex& index) const;
-- virtual QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
--
-- /** Retrieves the imageInfo object from the data() method of the given index.
-- * The index may be from a QSortFilterProxyModel as long as an ImageModel is at the end. */
-- static ImageInfo retrieveImageInfo(const QModelIndex& index);
-- static qlonglong retrieveImageId(const QModelIndex& index);
--
--Q_SIGNALS:
--
-- /** Informs that ImageInfos will be added to the model.
-- * This signal is sent before the model data is changed and views are informed.
-- */
-- void imageInfosAboutToBeAdded(const QList<ImageInfo>& infos);
--
-- /** Informs that ImageInfos have been added to the model.
-- * This signal is sent after the model data is changed and views are informed.
-- */
-- void imageInfosAdded(const QList<ImageInfo>& infos);
--
-- /** Informs that ImageInfos will be removed from the model.
-- * This signal is sent before the model data is changed and views are informed.
-- * Note: You need to explicitly enable sending of this signal. It is not sent
-- * in clearImageInfos().
-- */
-- void imageInfosAboutToBeRemoved(const QList<ImageInfo>& infos);
--
-- /** Informs that ImageInfos have been removed from the model.
-- * This signal is sent after the model data is changed and views are informed. *
-- * Note: You need to explicitly enable sending of this signal. It is not sent
-- * in clearImageInfos().
-- */
-- void imageInfosRemoved(const QList<ImageInfo>& infos);
--
-- /** Connect to this signal only if you are the current preprocessor.
-- */
-- void preprocess(const QList<ImageInfo>& infos, const QList<QVariant>&);
-- void processAdded(const QList<ImageInfo>& infos, const QList<QVariant>&);
--
-- /** If an ImageChangeset affected indexes of this model with changes as set in watchFlags(),
-- * this signal contains the changeset and the affected indexes.
-- */
-- void imageChange(const ImageChangeset&, const QItemSelection&);
--
-- /** If an ImageTagChangeset affected indexes of this model,
-- * this signal contains the changeset and the affected indexes.
-- */
-- void imageTagChange(const ImageTagChangeset&, const QItemSelection&);
--
-- /** Signals that the model is right now ready to start an incremental refresh.
-- * This is guaranteed only for the scope of emitting this signal.
-- */
-- void readyForIncrementalRefresh();
--
-- /** Signals that the model has finished currently with all scheduled
-- * refreshing, full or incremental, and all preprocessing.
-- * The model is in polished, clean situation right now.
-- */
-- void allRefreshingFinished();
--
--public Q_SLOTS:
--
-- void reAddImageInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void reAddingFinished();
--
--protected:
--
-- /** Subclasses that add ImageInfos in batches shall call startRefresh()
-- * when they start sending batches and finishRefresh() when they have finished.
-- * No incremental refreshes will be started while listing.
-- * A clearImageInfos() always stops listing, calling finishRefresh() is then not necessary.
-- */
-- void startRefresh();
-- void finishRefresh();
--
-- /** As soon as the model is ready to start an incremental refresh, the signal
-- * readyForIncrementalRefresh() will be emitted. The signal will be emitted inline
-- * if the model is ready right now.
-- */
-- void requestIncrementalRefresh();
-- bool hasIncrementalRefreshPending() const;
--
-- /** Starts an incremental refresh operation. You shall only call this method from a slot
-- * connected to readyForIncrementalRefresh(). To initiate an incremental refresh,
-- * call requestIncrementalRefresh().
-- */
-- void startIncrementalRefresh();
-- void finishIncrementalRefresh();
--
-- void emitDataChangedForAll();
-- void emitDataChangedForSelection(const QItemSelection& selection);
--
-- // Called when the internal storage is cleared
-- virtual void imageInfosCleared() {};
--
-- // Called before rowsAboutToBeRemoved
-- virtual void imageInfosAboutToBeRemoved(int /*begin*/, int /*end*/) {};
--
--protected Q_SLOTS:
--
-- virtual void slotImageChange(const ImageChangeset& changeset);
-- virtual void slotImageTagChange(const ImageTagChangeset& changeset);
--
--private:
--
-- void appendInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void appendInfosChecked(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void publiciseInfos(const QList<ImageInfo>& infos, const QList<QVariant>& extraValues);
-- void cleanSituationChecks();
-- void removeRowPairsWithCheck(const QList<QPair<int, int> >& toRemove);
-- void removeRowPairs(const QList<QPair<int, int> >& toRemove);
--
--public:
--
-- // Declared public because it's used in ImageModelIncrementalUpdater class
-- class Private;
--
--private:
--
-- Private* const d;
--};
--
--} // namespace Digikam
--
--Q_DECLARE_METATYPE(Digikam::ImageModel*)
--
--#endif // IMAGEMODEL_H
-diff --git a/libs/models/imagesortsettings.cpp b/libs/models/imagesortsettings.cpp
-deleted file mode 100644
-index 39ee6e1..0000000
---- a/libs/models/imagesortsettings.cpp
-+++ /dev/null
-@@ -1,400 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Filter values for use with ImageFilterModel
-- *
-- * Copyright (C) 2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2014 by Mohamed Anwer <m dot anwer at gmx dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagesortsettings.h"
--
--// Qt includes
--
--#include <QDateTime>
--#include <QRectF>
--
--// Local includes
--
--#include "coredbfields.h"
--#include "imageinfo.h"
--
--namespace Digikam
--{
--
--ImageSortSettings::ImageSortSettings()
--{
-- categorizationMode = NoCategories;
-- categorizationSortOrder = DefaultOrder;
-- categorizationCaseSensitivity = Qt::CaseSensitive;
-- sortRole = SortByFileName;
-- sortOrder = DefaultOrder;
-- strTypeNatural = true;
-- sortCaseSensitivity = Qt::CaseSensitive;
-- currentCategorizationSortOrder = Qt::AscendingOrder;
-- currentSortOrder = Qt::AscendingOrder;
--}
--
--bool ImageSortSettings::operator==(const ImageSortSettings& other) const
--{
-- return
-- categorizationMode == other.categorizationMode &&
-- categorizationSortOrder == other.categorizationSortOrder &&
-- categorizationCaseSensitivity == other.categorizationCaseSensitivity &&
-- sortRole == other.sortRole &&
-- sortOrder == other.sortOrder &&
-- sortCaseSensitivity == other.sortCaseSensitivity;
--}
--
--void ImageSortSettings::setCategorizationMode(CategorizationMode mode)
--{
-- categorizationMode = mode;
--
-- if (categorizationSortOrder == DefaultOrder)
-- {
-- currentCategorizationSortOrder = defaultSortOrderForCategorizationMode(categorizationMode);
-- }
--}
--
--void ImageSortSettings::setCategorizationSortOrder(SortOrder order)
--{
-- categorizationSortOrder = order;
--
-- if (categorizationSortOrder == DefaultOrder)
-- {
-- currentCategorizationSortOrder = defaultSortOrderForCategorizationMode(categorizationMode);
-- }
-- else
-- {
-- currentCategorizationSortOrder = (Qt::SortOrder)categorizationSortOrder;
-- }
--}
--
--void ImageSortSettings::setSortRole(SortRole role)
--{
-- sortRole = role;
--
-- if (sortOrder == DefaultOrder)
-- {
-- currentSortOrder = defaultSortOrderForSortRole(sortRole);
-- }
--}
--
--void ImageSortSettings::setSortOrder(SortOrder order)
--{
-- sortOrder = order;
--
-- if (sortOrder == DefaultOrder)
-- {
-- currentSortOrder = defaultSortOrderForSortRole(sortRole);
-- }
-- else
-- {
-- currentSortOrder = (Qt::SortOrder)order;
-- }
--}
--
--void ImageSortSettings::setStringTypeNatural(bool natural)
--{
-- strTypeNatural = natural;
--}
--
--Qt::SortOrder ImageSortSettings::defaultSortOrderForCategorizationMode(CategorizationMode mode)
--{
-- switch (mode)
-- {
-- case NoCategories:
-- case OneCategory:
-- case CategoryByAlbum:
-- case CategoryByFormat:
-- default:
-- return Qt::AscendingOrder;
-- }
--}
--
--Qt::SortOrder ImageSortSettings::defaultSortOrderForSortRole(SortRole role)
--{
-- switch (role)
-- {
-- case SortByFileName:
-- case SortByFilePath:
-- return Qt::AscendingOrder;
-- case SortByFileSize:
-- return Qt::DescendingOrder;
-- case SortByModificationDate:
-- case SortByCreationDate:
-- return Qt::AscendingOrder;
-- case SortByRating:
-- case SortByImageSize:
-- return Qt::DescendingOrder;
-- case SortByAspectRatio:
-- return Qt::DescendingOrder;
-- case SortBySimilarity:
-- return Qt::DescendingOrder;
-- default:
-- return Qt::AscendingOrder;
-- }
--}
--
--int ImageSortSettings::compareCategories(const ImageInfo& left, const ImageInfo& right) const
--{
-- switch (categorizationMode)
-- {
-- case NoCategories:
-- case OneCategory:
-- return 0;
-- case CategoryByAlbum:
-- {
-- int leftAlbum = left.albumId();
-- int rightAlbum = right.albumId();
--
-- // return comparation result
-- if (leftAlbum == rightAlbum)
-- {
-- return 0;
-- }
-- else if (lessThanByOrder(leftAlbum, rightAlbum, currentCategorizationSortOrder))
-- {
-- return -1;
-- }
-- else
-- {
-- return 1;
-- }
-- }
-- case CategoryByFormat:
-- {
-- return naturalCompare(left.format(), right.format(),
-- currentCategorizationSortOrder, categorizationCaseSensitivity, strTypeNatural);
-- }
-- default:
-- return 0;
-- }
--}
--
--bool ImageSortSettings::lessThan(const ImageInfo& left, const ImageInfo& right) const
--{
-- int result = compare(left, right, sortRole);
--
-- if (result != 0)
-- {
-- return result < 0;
-- }
--
-- // are they identical?
-- if (left == right)
-- {
-- return false;
-- }
--
-- // If left and right equal for first sort order, use a hierarchy of all sort orders
-- if ( (result = compare(left, right, SortByFileName)) != 0)
-- {
-- return result < 0;
-- }
--
-- if ( (result = compare(left, right, SortByCreationDate)) != 0)
-- {
-- return result < 0;
-- }
--
-- if ( (result = compare(left, right, SortByModificationDate)) != 0)
-- {
-- return result < 0;
-- }
--
-- if ( (result = compare(left, right, SortByFilePath)) != 0)
-- {
-- return result < 0;
-- }
--
-- if ( (result = compare(left, right, SortByFileSize)) != 0)
-- {
-- return result < 0;
-- }
--
-- if ( (result = compare(left, right, SortBySimilarity)) != 0)
-- {
-- return result < 0;
-- }
--
-- return false;
--}
--
--int ImageSortSettings::compare(const ImageInfo& left, const ImageInfo& right) const
--{
-- return compare(left, right, sortRole);
--}
--
--int ImageSortSettings::compare(const ImageInfo& left, const ImageInfo& right, SortRole role) const
--{
-- switch (role)
-- {
-- case SortByFileName:
-- {
-- bool versioning = (left.name().contains(QLatin1String("_v"), Qt::CaseInsensitive) ||
-- right.name().contains(QLatin1String("_v"), Qt::CaseInsensitive));
-- return naturalCompare(left.name(), right.name(), currentSortOrder, sortCaseSensitivity, strTypeNatural, versioning);
-- }
-- case SortByFilePath:
-- return naturalCompare(left.filePath(), right.filePath(), currentSortOrder, sortCaseSensitivity, strTypeNatural);
-- case SortByFileSize:
-- return compareByOrder(left.fileSize(), right.fileSize(), currentSortOrder);
-- case SortByModificationDate:
-- return compareByOrder(left.modDateTime(), right.modDateTime(), currentSortOrder);
-- case SortByCreationDate:
-- return compareByOrder(left.dateTime(), right.dateTime(), currentSortOrder);
-- case SortByRating:
-- // I have the feeling that inverting the sort order for rating is the natural order
-- return - compareByOrder(left.rating(), right.rating(), currentSortOrder);
-- case SortByImageSize:
-- {
-- QSize leftSize = left.dimensions();
-- QSize rightSize = right.dimensions();
-- int leftPixels = leftSize.width() * leftSize.height();
-- int rightPixels = rightSize.width() * rightSize.height();
-- return compareByOrder(leftPixels, rightPixels, currentSortOrder);
-- }
-- case SortByAspectRatio:
-- {
-- QSize leftSize = left.dimensions();
-- QSize rightSize = right.dimensions();
-- int leftAR = (double(leftSize.width()) / double(leftSize.height())) * 1000000;
-- int rightAR = (double(rightSize.width()) / double(rightSize.height())) * 1000000;
-- return compareByOrder(leftAR, rightAR, currentSortOrder);
-- }
-- case SortBySimilarity:
-- {
-- qlonglong leftReferenceImageId = left.currentReferenceImage();
-- qlonglong rightReferenceImageId = right.currentReferenceImage();
-- // make sure that the original image has always the highest similarity.
-- double leftSimilarity = left.id() == leftReferenceImageId ? 1.1 : left.currentSimilarity();
-- double rightSimilarity = right.id() == rightReferenceImageId ? 1.1 : right.currentSimilarity();
-- return compareByOrder(leftSimilarity, rightSimilarity, currentSortOrder);
-- }
-- default:
-- return 1;
-- }
--}
--
--bool ImageSortSettings::lessThan(const QVariant& left, const QVariant& right) const
--{
-- if (left.type() != right.type())
-- {
-- return false;
-- }
--
-- switch (left.type())
-- {
-- case QVariant::Int:
-- return compareByOrder(left.toInt(), right.toInt(), currentSortOrder);
-- case QVariant::UInt:
-- return compareByOrder(left.toUInt(), right.toUInt(), currentSortOrder);
-- case QVariant::LongLong:
-- return compareByOrder(left.toLongLong(), right.toLongLong(), currentSortOrder);
-- case QVariant::ULongLong:
-- return compareByOrder(left.toULongLong(), right.toULongLong(), currentSortOrder);
-- case QVariant::Double:
-- return compareByOrder(left.toDouble(), right.toDouble(), currentSortOrder);
-- case QVariant::Date:
-- return compareByOrder(left.toDate(), right.toDate(), currentSortOrder);
-- case QVariant::DateTime:
-- return compareByOrder(left.toDateTime(), right.toDateTime(), currentSortOrder);
-- case QVariant::Time:
-- return compareByOrder(left.toTime(), right.toTime(), currentSortOrder);
-- case QVariant::Rect:
-- case QVariant::RectF:
-- {
-- QRectF rectLeft = left.toRectF();
-- QRectF rectRight = right.toRectF();
-- int result;
--
-- if ((result = compareByOrder(rectLeft.top(), rectRight.top(), currentSortOrder)) != 0)
-- {
-- return result < 0;
-- }
--
-- if ((result = compareByOrder(rectLeft.left(), rectRight.left(), currentSortOrder)) != 0)
-- {
-- return result < 0;
-- }
--
-- QSizeF sizeLeft = rectLeft.size(), sizeRight = rectRight.size();
--
-- if ((result = compareByOrder(sizeLeft.width()*sizeLeft.height(), sizeRight.width()*sizeRight.height(), currentSortOrder)) != 0)
-- {
-- return result < 0;
-- }
-- // FIXME: fall through?? If not, add "break" here
-- }
-- default:
-- return naturalCompare(left.toString(), right.toString(), currentSortOrder, sortCaseSensitivity, strTypeNatural);
-- }
--}
--
--DatabaseFields::Set ImageSortSettings::watchFlags() const
--{
-- DatabaseFields::Set set;
--
-- switch (sortRole)
-- {
-- case SortByFileName:
-- set |= DatabaseFields::Name;
-- break;
-- case SortByFilePath:
-- set |= DatabaseFields::Name;
-- break;
-- case SortByFileSize:
-- set |= DatabaseFields::FileSize;
-- break;
-- case SortByModificationDate:
-- set |= DatabaseFields::ModificationDate;
-- break;
-- case SortByCreationDate:
-- set |= DatabaseFields::CreationDate;
-- break;
-- case SortByRating:
-- set |= DatabaseFields::Rating;
-- break;
-- case SortByImageSize:
-- set |= DatabaseFields::Width | DatabaseFields::Height;
-- break;
-- case SortByAspectRatio:
-- set |= DatabaseFields::Width | DatabaseFields::Height;
-- break;
-- case SortBySimilarity:
-- // TODO: Not sure what to do here....
-- set |= DatabaseFields::Name;
-- break;
-- }
--
-- switch (categorizationMode)
-- {
-- case NoCategories:
-- case OneCategory:
-- case CategoryByAlbum:
-- break;
-- case CategoryByFormat:
-- set |= DatabaseFields::Format;
-- break;
-- }
--
-- return set;
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imagesortsettings.h b/libs/models/imagesortsettings.h
-deleted file mode 100644
-index 2a5fd8c..0000000
---- a/libs/models/imagesortsettings.h
-+++ /dev/null
-@@ -1,225 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-05-31
-- * Description : Sort settings for use with ImageFilterModel
-- *
-- * Copyright (C) 2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGESORTSETTINGS_H
--#define IMAGESORTSETTINGS_H
--
--// Qt includes
--
--#include <QHash>
--#include <QList>
--#include <QMap>
--#include <QString>
--#include <QCollator>
--
--// Local includes
--
--#include "digikam_export.h"
--
--namespace Digikam
--{
--
--class ImageInfo;
--
--namespace DatabaseFields
--{
-- class Set;
--}
--
--class DIGIKAM_DATABASE_EXPORT ImageSortSettings
--{
--public:
--
-- ImageSortSettings();
--
-- bool operator==(const ImageSortSettings& other) const;
--
-- /** Compares the categories of left and right.
-- * Return -1 if left is less than right, 0 if both fall in the same category,
-- * and 1 if left is greater than right.
-- * Adheres to set categorization mode and current category sort order.
-- */
-- int compareCategories(const ImageInfo& left, const ImageInfo& right) const;
--
-- /** Returns true if left is less than right.
-- * Adheres to current sort role and sort order.
-- */
-- bool lessThan(const ImageInfo& left, const ImageInfo& right) const;
--
-- /** Compares the ImageInfos left and right.
-- * Return -1 if left is less than right, 1 if left is greater than right,
-- * and 0 if left equals right comparing the current sort role's value.
-- * Adheres to set sort role and sort order.
-- */
-- int compare(const ImageInfo& left, const ImageInfo& right) const;
--
-- /** Returns true if left QVariant is less than right.
-- * Adheres to current sort role and sort order.
-- * Use for extraValue, if necessary.
-- */
-- bool lessThan(const QVariant& left, const QVariant& right) const;
--
-- enum SortOrder
-- {
-- AscendingOrder = Qt::AscendingOrder,
-- DescendingOrder = Qt::DescendingOrder,
-- DefaultOrder /// sort order depends on the chosen sort role
-- };
--
-- /// --- Categories ---
--
-- enum CategorizationMode
-- {
-- NoCategories, /// categorization switched off
-- OneCategory, /// all items in one global category
-- CategoryByAlbum,
-- CategoryByFormat
-- };
--
-- CategorizationMode categorizationMode;
-- SortOrder categorizationSortOrder;
--
-- void setCategorizationMode(CategorizationMode mode);
-- void setCategorizationSortOrder(SortOrder order);
--
-- /// Only Ascending or Descending, never DefaultOrder
-- Qt::SortOrder currentCategorizationSortOrder;
-- Qt::CaseSensitivity categorizationCaseSensitivity;
--
-- bool isCategorized() const { return categorizationMode >= CategoryByAlbum; }
--
-- /// --- Image Sorting ---
--
-- enum SortRole
-- {
-- // Note: For legacy reasons, the order of the first five entries must remain unchanged
-- SortByFileName,
-- SortByFilePath,
-- SortByCreationDate,
-- SortByFileSize,
-- SortByRating,
-- SortByModificationDate,
-- SortByImageSize, // pixel number
-- SortByAspectRatio, // width / height * 100000
-- SortBySimilarity
-- };
--
-- SortRole sortRole;
-- SortOrder sortOrder;
-- bool strTypeNatural;
--
-- void setSortRole(SortRole role);
-- void setSortOrder(SortOrder order);
-- void setStringTypeNatural(bool natural);
--
-- Qt::SortOrder currentSortOrder;
-- Qt::CaseSensitivity sortCaseSensitivity;
--
-- int compare(const ImageInfo& left, const ImageInfo& right, SortRole sortRole) const;
--
-- // --- ---
--
-- static Qt::SortOrder defaultSortOrderForCategorizationMode(CategorizationMode mode);
-- static Qt::SortOrder defaultSortOrderForSortRole(SortRole role);
--
-- /// --- Change notification ---
--
-- /** Returns database fields a change in which would affect the current sorting.
-- */
-- DatabaseFields::Set watchFlags() const;
--
-- /// --- Utilities ---
--
-- /** Returns a < b if sortOrder is Ascending, or b < a if order is descending.
-- */
-- template <typename T>
-- static inline bool lessThanByOrder(const T& a, const T& b, Qt::SortOrder sortOrder)
-- {
-- if (sortOrder == Qt::AscendingOrder)
-- {
-- return a < b;
-- }
-- else
-- {
-- return b < a;
-- }
-- }
--
-- /** Returns the usual compare result of -1, 0, or 1 for lessThan, equals and greaterThan.
-- */
-- template <typename T>
-- static inline int compareValue(const T& a, const T& b)
-- {
-- if (a == b)
-- {
-- return 0;
-- }
--
-- if (a < b)
-- {
-- return -1;
-- }
-- else
-- {
-- return 1;
-- }
-- }
--
-- /** Takes a typical result from a compare method (0 is equal, -1 is less than, 1 is greater than)
-- * and applies the given sort order to it.
-- */
-- static inline int compareByOrder(int compareResult, Qt::SortOrder sortOrder)
-- {
-- if (sortOrder == Qt::AscendingOrder)
-- {
-- return compareResult;
-- }
-- else
-- {
-- return - compareResult;
-- }
-- }
--
-- template <typename T>
-- static inline int compareByOrder(const T& a, const T& b, Qt::SortOrder sortOrder)
-- {
-- return compareByOrder(compareValue(a, b), sortOrder);
-- }
--
-- /** Compares the two string by natural comparison and adheres to given sort order
-- */
-- static inline int naturalCompare(const QString& a, const QString& b, Qt::SortOrder sortOrder,
-- Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive,
-- bool natural = true, bool versioning = false)
-- {
-- QCollator collator;
-- collator.setNumericMode(natural);
-- collator.setIgnorePunctuation(versioning);
-- collator.setCaseSensitivity(caseSensitive);
-- return (compareByOrder(collator.compare(a, b), sortOrder));
-- }
--};
--
--} // namespace Digikam
--
--#endif // IMAGESORTSETTINGS_H
-diff --git a/libs/models/imagethumbnailmodel.cpp b/libs/models/imagethumbnailmodel.cpp
-deleted file mode 100644
-index b7f5661..0000000
---- a/libs/models/imagethumbnailmodel.cpp
-+++ /dev/null
-@@ -1,323 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries with support for thumbnail loading
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imagethumbnailmodel.h"
--
--// Qt includes
--
--#include <QHash>
--
--// Local includes
--
--#include "digikam_debug.h"
--#include "thumbnailloadthread.h"
--#include "digikam_export.h"
--#include "digikam_globals.h"
--
--namespace Digikam
--{
--
--class ImageThumbnailModel::ImageThumbnailModelPriv
--{
--public:
--
-- ImageThumbnailModelPriv() :
-- thread(0),
-- preloadThread(0),
-- thumbSize(0),
-- lastGlobalThumbSize(0),
-- preloadThumbSize(0),
-- emitDataChanged(true)
-- {
-- staticListContainingThumbnailRole << ImageModel::ThumbnailRole;
-- }
--
-- ThumbnailLoadThread* thread;
-- ThumbnailLoadThread* preloadThread;
-- ThumbnailSize thumbSize;
-- ThumbnailSize lastGlobalThumbSize;
-- ThumbnailSize preloadThumbSize;
-- QRect detailRect;
-- QVector<int> staticListContainingThumbnailRole;
--
-- bool emitDataChanged;
--
-- int preloadThumbnailSize() const
-- {
-- if (preloadThumbSize.size())
-- {
-- return preloadThumbSize.size();
-- }
--
-- return thumbSize.size();
-- }
--};
--
--ImageThumbnailModel::ImageThumbnailModel(QObject* parent)
-- : ImageModel(parent), d(new ImageThumbnailModelPriv)
--{
-- setKeepsFilePathCache(true);
--}
--
--ImageThumbnailModel::~ImageThumbnailModel()
--{
-- delete d->preloadThread;
-- delete d;
--}
--
--void ImageThumbnailModel::setThumbnailLoadThread(ThumbnailLoadThread* thread)
--{
-- d->thread = thread;
--
-- connect(d->thread, SIGNAL(signalThumbnailLoaded(LoadingDescription,QPixmap)),
-- this, SLOT(slotThumbnailLoaded(LoadingDescription,QPixmap)));
--}
--
--ThumbnailLoadThread* ImageThumbnailModel::thumbnailLoadThread() const
--{
-- return d->thread;
--}
--
--ThumbnailSize ImageThumbnailModel::thumbnailSize() const
--{
-- return d->thumbSize;
--}
--
--void ImageThumbnailModel::setThumbnailSize(const ThumbnailSize& size)
--{
-- d->lastGlobalThumbSize = size;
-- d->thumbSize = size;
--}
--
--void ImageThumbnailModel::setPreloadThumbnailSize(const ThumbnailSize& size)
--{
-- d->preloadThumbSize = size;
--}
--
--void ImageThumbnailModel::setEmitDataChanged(bool emitSignal)
--{
-- d->emitDataChanged = emitSignal;
--}
--
--void ImageThumbnailModel::setPreloadThumbnails(bool preload)
--{
-- if (preload)
-- {
-- if (!d->preloadThread)
-- {
-- d->preloadThread = new ThumbnailLoadThread;
-- d->preloadThread->setPixmapRequested(false);
-- d->preloadThread->setPriority(QThread::LowestPriority);
-- }
--
-- connect(this, SIGNAL(allRefreshingFinished()),
-- this, SLOT(preloadAllThumbnails()));
-- }
-- else
-- {
-- delete d->preloadThread;
-- d->preloadThread = 0;
-- disconnect(this, SIGNAL(allRefreshingFinished()),
-- this, SLOT(preloadAllThumbnails()));
-- }
--}
--
--void ImageThumbnailModel::prepareThumbnails(const QList<QModelIndex>& indexesToPrepare)
--{
-- prepareThumbnails(indexesToPrepare, d->thumbSize);
--}
--
--void ImageThumbnailModel::prepareThumbnails(const QList<QModelIndex>& indexesToPrepare, const ThumbnailSize& thumbSize)
--{
-- if (!d->thread)
-- {
-- return;
-- }
--
-- QList<ThumbnailIdentifier> ids;
-- foreach(const QModelIndex& index, indexesToPrepare)
-- {
-- ids << imageInfoRef(index).thumbnailIdentifier();
-- }
-- d->thread->findGroup(ids, thumbSize.size());
--}
--
--void ImageThumbnailModel::preloadThumbnails(const QList<ImageInfo>& infos)
--{
-- if (!d->preloadThread)
-- {
-- return;
-- }
--
-- QList<ThumbnailIdentifier> ids;
-- foreach(const ImageInfo& info, infos)
-- {
-- ids << info.thumbnailIdentifier();
-- }
-- d->preloadThread->pregenerateGroup(ids, d->preloadThumbnailSize());
--}
--
--void ImageThumbnailModel::preloadThumbnails(const QList<QModelIndex>& indexesToPreload)
--{
-- if (!d->preloadThread)
-- {
-- return;
-- }
--
-- QList<ThumbnailIdentifier> ids;
-- foreach(const QModelIndex& index, indexesToPreload)
-- {
-- ids << imageInfoRef(index).thumbnailIdentifier();
-- }
-- d->preloadThread->stopAllTasks();
-- d->preloadThread->pregenerateGroup(ids, d->preloadThumbnailSize());
--}
--
--void ImageThumbnailModel::preloadAllThumbnails()
--{
-- preloadThumbnails(imageInfos());
--}
--
--void ImageThumbnailModel::imageInfosCleared()
--{
-- if (d->preloadThread)
-- {
-- d->preloadThread->stopAllTasks();
-- }
--}
--
--QVariant ImageThumbnailModel::data(const QModelIndex& index, int role) const
--{
-- if (role == ThumbnailRole && d->thread && index.isValid())
-- {
-- QPixmap thumbnail;
-- ImageInfo info = imageInfo(index);
-- QString path = info.filePath();
--
-- if (info.isNull())
-- {
-- return QVariant(QVariant::Pixmap);
-- }
--
-- if (!d->detailRect.isNull())
-- {
-- if (d->thread->find(info.thumbnailIdentifier(), d->detailRect, thumbnail, d->thumbSize.size()))
-- {
-- return thumbnail;
-- }
-- }
-- else
-- {
-- if (d->thread->find(info.thumbnailIdentifier(), thumbnail, d->thumbSize.size()))
-- {
-- return thumbnail;
-- }
-- }
--
-- return QVariant(QVariant::Pixmap);
-- }
--
-- return ImageModel::data(index, role);
--}
--
--bool ImageThumbnailModel::setData(const QModelIndex& index, const QVariant& value, int role)
--{
-- if (role == ThumbnailRole)
-- {
-- switch (value.type())
-- {
-- case QVariant::Invalid:
-- d->thumbSize = d->lastGlobalThumbSize;
-- d->detailRect = QRect();
-- break;
--
-- case QVariant::Int:
--
-- if (value.isNull())
-- {
-- d->thumbSize = d->lastGlobalThumbSize;
-- }
-- else
-- {
-- d->thumbSize = value.toInt();
-- }
-- break;
--
-- case QVariant::Rect:
--
-- if (value.isNull())
-- {
-- d->detailRect = QRect();
-- }
-- else
-- {
-- d->detailRect = value.toRect();
-- }
-- break;
--
-- default:
-- break;
-- }
-- }
--
-- return ImageModel::setData(index, value, role);
--}
--
--void ImageThumbnailModel::slotThumbnailLoaded(const LoadingDescription& loadingDescription, const QPixmap& thumb)
--{
-- if (thumb.isNull())
-- {
-- return;
-- }
--
-- // In case of multiple occurrence, we currently do not know which thumbnail is this. Signal change on all.
-- QModelIndexList indexes;
-- ThumbnailIdentifier thumbId = loadingDescription.thumbnailIdentifier();
-- if (thumbId.filePath.isEmpty())
-- {
-- indexes = indexesForImageId(thumbId.id);
-- }
-- else
-- {
-- indexes = indexesForPath(thumbId.filePath);
-- }
-- foreach(const QModelIndex& index, indexes)
-- {
-- if (thumb.isNull())
-- {
-- emit thumbnailFailed(index, loadingDescription.previewParameters.size);
-- }
-- else
-- {
-- emit thumbnailAvailable(index, loadingDescription.previewParameters.size);
--
-- if (d->emitDataChanged)
-- {
-- emit dataChanged(index, index, d->staticListContainingThumbnailRole);
-- }
-- }
-- }
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imagethumbnailmodel.h b/libs/models/imagethumbnailmodel.h
-deleted file mode 100644
-index 366ca65..0000000
---- a/libs/models/imagethumbnailmodel.h
-+++ /dev/null
-@@ -1,140 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2009-03-05
-- * Description : Qt item model for database entries with support for thumbnail loading
-- *
-- * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
-- * Copyright (C) 2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGETHUMBNAILMODEL_H
--#define IMAGETHUMBNAILMODEL_H
--
--// Local includes
--
--#include "imagemodel.h"
--#include "thumbnailsize.h"
--#include "digikam_export.h"
--
--namespace Digikam
--{
--
--class LoadingDescription;
--class ThumbnailLoadThread;
--
--class DIGIKAM_DATABASE_EXPORT ImageThumbnailModel : public ImageModel
--{
-- Q_OBJECT
--
--public:
--
-- /**
-- * An ImageModel that supports thumbnail loading.
-- * You need to set a ThumbnailLoadThread to enable thumbnail loading.
-- * Adjust the thumbnail size to your needs.
-- * Note that setKeepsFilePathCache is enabled per default.
-- */
-- explicit ImageThumbnailModel(QObject* parent);
-- ~ImageThumbnailModel();
--
-- /** Enable thumbnail loading and set the thread that shall be used.
-- * The thumbnail size of this thread will be adjusted.
-- */
-- void setThumbnailLoadThread(ThumbnailLoadThread* thread);
-- ThumbnailLoadThread* thumbnailLoadThread() const;
--
-- /// Set the thumbnail size to use
-- void setThumbnailSize(const ThumbnailSize& thumbSize);
--
-- /// If you want to fix a size for preloading, do it here.
-- void setPreloadThumbnailSize(const ThumbnailSize& thumbSize);
--
-- void setExifRotate(bool rotate);
--
-- /**
-- * Enable emitting dataChanged() when a thumbnail becomes available.
-- * The thumbnailAvailable() signal will be emitted in any case.
-- * Default is true.
-- */
-- void setEmitDataChanged(bool emitSignal);
--
-- /**
-- * Enable preloading of thumbnails:
-- * If preloading is enabled, for every entry in the model a thumbnail generation is started.
-- * Default: false.
-- */
-- void setPreloadThumbnails(bool preload);
--
-- ThumbnailSize thumbnailSize() const;
--
-- /**
-- * Handles the ThumbnailRole.
-- * If the pixmap is available, returns it in the QVariant.
-- * If it still needs to be loaded, returns a null QVariant and emits
-- * thumbnailAvailable() as soon as it is available.
-- */
-- virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
--
-- /**
-- * You can override the current thumbnail size by giving an integer value for ThumbnailRole.
-- * Set a null QVariant to use the thumbnail size set by setThumbnailSize() again.
-- * The index given here is ignored for this purpose.
-- */
-- virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::DisplayRole);
--
--public Q_SLOTS:
--
-- /** Prepare the thumbnail loading for the given indexes
-- */
-- void prepareThumbnails(const QList<QModelIndex>& indexesToPrepare);
-- void prepareThumbnails(const QList<QModelIndex>& indexesToPrepare, const ThumbnailSize& thumbSize);
--
-- /**
-- * Preload thumbnail for the given infos resp. indexes.
-- * Note: Use setPreloadThumbnails to automatically preload all entries in the model.
-- * Note: This only ensures thumbnail generation. It is not guaranteed that pixmaps
-- * are stored in the cache. For thumbnails that are expect to be drawn immediately,
-- * include them in prepareThumbnails().
-- * Note: Stops preloading of previously added thumbnails.
-- */
-- void preloadThumbnails(const QList<ImageInfo>&);
-- void preloadThumbnails(const QList<QModelIndex>&);
-- void preloadAllThumbnails();
--
--Q_SIGNALS:
--
-- void thumbnailAvailable(const QModelIndex& index, int requestedSize);
-- void thumbnailFailed(const QModelIndex& index, int requestedSize);
--
--protected:
--
-- virtual void imageInfosCleared();
--
--protected Q_SLOTS:
--
-- void slotThumbnailLoaded(const LoadingDescription& loadingDescription, const QPixmap& thumb);
--
--private:
--
-- class ImageThumbnailModelPriv;
-- ImageThumbnailModelPriv* const d;
--};
--
--} // namespace Digikam
--
--#endif /* IMAGETHUMBNAILMODEL_H */
-diff --git a/libs/models/imageversionsmodel.cpp b/libs/models/imageversionsmodel.cpp
-deleted file mode 100644
-index e6ba582..0000000
---- a/libs/models/imageversionsmodel.cpp
-+++ /dev/null
-@@ -1,183 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2010-07-13
-- * Description : Model for image versions
-- *
-- * Copyright (C) 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#include "imageversionsmodel.h"
--
--// KDE includes
--
--#include <klocalizedstring.h>
--
--// Local includes
--
--#include "digikam_debug.h"
--#include "workingwidget.h"
--
--namespace Digikam
--{
--
--class ImageVersionsModel::Private
--{
--public:
--
-- Private()
-- {
-- data = 0;
-- paintTree = false;
-- }
--
-- ///Complete paths with filenames and tree level
-- QList<QPair<QString, int> >* data;
-- ///This is for delegate to paint it as selected
-- QString currentSelectedImage;
-- ///If true, the delegate will paint items as a tree
-- ///if false, it will be painted as a list
-- bool paintTree;
--};
--
--ImageVersionsModel::ImageVersionsModel(QObject* parent)
-- : QAbstractListModel(parent),
-- d(new Private)
--{
-- d->data = new QList<QPair<QString, int> >;
--}
--
--ImageVersionsModel::~ImageVersionsModel()
--{
-- //qDeleteAll(d->data);
-- delete d;
--}
--
--Qt::ItemFlags ImageVersionsModel::flags(const QModelIndex& index) const
--{
-- if (!index.isValid())
-- {
-- return 0;
-- }
--
-- return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
--}
--
--QVariant ImageVersionsModel::data(const QModelIndex& index, int role) const
--{
-- if (!index.isValid())
-- {
-- return QVariant();
-- }
--
-- if (role == Qt::DisplayRole && !d->data->isEmpty())
-- {
-- return d->data->at(index.row()).first;
-- }
-- else if (role == Qt::UserRole && !d->data->isEmpty())
-- {
-- return d->data->at(index.row()).second;
-- }
-- else if (role == Qt::DisplayRole && d->data->isEmpty())
-- {
-- //TODO: make this text Italic
-- return QVariant(QString(i18n("No image selected")));
-- }
--
-- return QVariant();
--}
--
--int ImageVersionsModel::rowCount(const QModelIndex& parent) const
--{
-- Q_UNUSED(parent)
-- return d->data->count();
--}
--
--void ImageVersionsModel::setupModelData(QList<QPair<QString, int> >& data)
--{
-- beginResetModel();
--
-- d->data->clear();
--
-- if (!data.isEmpty())
-- {
-- d->data->append(data);
-- }
-- else
-- {
-- d->data->append(qMakePair(QString(i18n("This is the original image")), 0));
-- }
--
-- endResetModel();
--}
--
--void ImageVersionsModel::clearModelData()
--{
-- beginResetModel();
--
-- if (!d->data->isEmpty())
-- {
-- d->data->clear();
-- }
--
-- endResetModel();
--}
--
--void ImageVersionsModel::slotAnimationStep()
--{
-- emit dataChanged(createIndex(0, 0), createIndex(rowCount()-1, 1));
--}
--
--QString ImageVersionsModel::currentSelectedImage() const
--{
-- return d->currentSelectedImage;
--}
--
--void ImageVersionsModel::setCurrentSelectedImage(const QString& path)
--{
-- d->currentSelectedImage = path;
--}
--
--QModelIndex ImageVersionsModel::currentSelectedImageIndex() const
--{
-- return index(listIndexOf(d->currentSelectedImage), 0);
--}
--
--bool ImageVersionsModel::paintTree() const
--{
-- return d->paintTree;
--}
--
--void ImageVersionsModel::setPaintTree(bool paint)
--{
-- d->paintTree = paint;
--}
--
--int ImageVersionsModel::listIndexOf(const QString& item) const
--{
-- for (int i = 0; i < d->data->size(); ++i)
-- {
-- if (d->data->at(i).first == item)
-- {
-- return i;
-- }
-- }
--
-- return -1;
--}
--
--} // namespace Digikam
-diff --git a/libs/models/imageversionsmodel.h b/libs/models/imageversionsmodel.h
-deleted file mode 100644
-index ed08529..0000000
---- a/libs/models/imageversionsmodel.h
-+++ /dev/null
-@@ -1,75 +0,0 @@
--/* ============================================================
-- *
-- * This file is a part of digiKam project
-- * http://www.digikam.org
-- *
-- * Date : 2010-07-13
-- * Description : Model for image versions
-- *
-- * Copyright (C) 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
-- *
-- * 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 2, 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.
-- *
-- * ============================================================ */
--
--#ifndef IMAGEVERSIONSMODEL_H
--#define IMAGEVERSIONSMODEL_H
--
--// Qt includes
--
--#include <QModelIndex>
--#include <QPixmap>
--
--// Local includes
--
--#include "digikam_export.h"
--
--namespace Digikam
--{
--
--class DIGIKAM_DATABASE_EXPORT ImageVersionsModel : public QAbstractListModel
--{
-- Q_OBJECT
--
--public:
--
-- explicit ImageVersionsModel(QObject* parent = 0);
-- ~ImageVersionsModel();
--
-- Qt::ItemFlags flags(const QModelIndex& index) const;
-- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-- int rowCount(const QModelIndex& parent = QModelIndex()) const;
--
-- void setupModelData(QList<QPair<QString, int> >& data);
-- void clearModelData();
--
-- QString currentSelectedImage() const;
-- void setCurrentSelectedImage(const QString& path);
-- QModelIndex currentSelectedImageIndex() const;
--
-- bool paintTree() const;
-- int listIndexOf(const QString& item) const;
--
--public Q_SLOTS:
--
-- void slotAnimationStep();
-- void setPaintTree(bool paint);
--
--private:
--
-- class Private;
-- Private* const d;
--};
--
--} // namespace Digikam
--
--#endif // IMAGEVERSIONSMODEL_H
---
-cgit v0.11.2
-
diff --git a/kde/patch/digikam/digikam_imagemagick7.patch b/kde/patch/digikam/digikam_imagemagick7.patch
deleted file mode 100644
index 04a7752..0000000
--- a/kde/patch/digikam/digikam_imagemagick7.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Antonio Rojas <arojas@archlinux.org>
-Date: Thu, 7 Nov 2019 09:25:02 +0100
-Subject: Properly initialize ExceptionInfo in libMagick
-
-Otherwise it will crash if some plugins can't be loaded.
-
-diff --git a/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp b/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp
-index 1858b4d..20ef01b 100644
---- a/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp
-+++ b/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp
-@@ -125,7 +125,7 @@ QMap<QString, QString> DImgImageMagickPlugin::extraAboutData() const
- QString mimes = typeMimes();
-
- QMap<QString, QString> map;
-- ExceptionInfo ex;
-+ ExceptionInfo ex = *AcquireExceptionInfo();
- size_t n = 0;
- const MagickInfo** inflst = GetMagickInfoList("*", &n, &ex);
-
-@@ -219,7 +219,7 @@ int DImgImageMagickPlugin::canRead(const QFileInfo& fileInfo, bool magic) const
- int DImgImageMagickPlugin::canWrite(const QString& format) const
- {
- QStringList formats;
-- ExceptionInfo ex;
-+ ExceptionInfo ex = *AcquireExceptionInfo();
- size_t n = 0;
- const MagickInfo** inflst = GetMagickInfoList("*", &n, &ex);
-
-@@ -266,7 +266,7 @@ DImgLoader* DImgImageMagickPlugin::loader(DImg* const image, const DRawDecoding&
- QStringList DImgImageMagickPlugin::decoderFormats() const
- {
- QStringList formats;
-- ExceptionInfo ex;
-+ ExceptionInfo ex = *AcquireExceptionInfo();
- size_t n = 0;
- const MagickInfo** inflst = GetMagickInfoList("*", &n, &ex);
-
---
-cgit v1.1
-
diff --git a/kde/patch/dolphin.patch b/kde/patch/dolphin.patch
index dfe3a2f..02a7950 100644
--- a/kde/patch/dolphin.patch
+++ b/kde/patch/dolphin.patch
@@ -1,3 +1,2 @@
# Let the user decide whether she wants to run Dolphin as root:
cat $CWD/patch/dolphin/dolphin_revert_noroot.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/falkon.patch b/kde/patch/falkon.patch
new file mode 100644
index 0000000..27a4668
--- /dev/null
+++ b/kde/patch/falkon.patch
@@ -0,0 +1,2 @@
+# Fix build against Qt 5.15:
+cat $CWD/patch/falkon/falkon.qt-5.15.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
diff --git a/kde/patch/falkon/falkon.qt-5.15.diff b/kde/patch/falkon/falkon.qt-5.15.diff
new file mode 100644
index 0000000..60f1699
--- /dev/null
+++ b/kde/patch/falkon/falkon.qt-5.15.diff
@@ -0,0 +1,20 @@
+--- ./src/lib/tools/qztools.cpp.orig 2019-03-19 13:06:45.000000000 -0500
++++ ./src/lib/tools/qztools.cpp 2020-07-18 15:00:08.881313780 -0500
+@@ -25,6 +25,7 @@
+ #include <QByteArray>
+ #include <QPixmap>
+ #include <QPainter>
++#include <QPainterPath>
+ #include <QBuffer>
+ #include <QFile>
+ #include <QDir>
+--- ./src/plugins/VerticalTabs/verticaltabsplugin.cpp.orig 2019-03-19 13:06:45.000000000 -0500
++++ ./src/plugins/VerticalTabs/verticaltabsplugin.cpp 2020-07-18 15:03:16.468303404 -0500
+@@ -31,6 +31,7 @@
+ #include "desktopfile.h"
+
+ #include <QSettings>
++#include <QFile>
+
+ VerticalTabsPlugin::VerticalTabsPlugin()
+ : QObject()
diff --git a/kde/patch/gwenview.patch b/kde/patch/gwenview.patch
deleted file mode 100644
index 04dfe50..0000000
--- a/kde/patch/gwenview.patch
+++ /dev/null
@@ -1,4 +0,0 @@
-# Prevent dataloss when importing pictures;
-# Will be fixed in 17.04.2:
-#cat $CWD/patch/gwenview/gwenview-17.04.1_dataloss.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/gwenview/gwenview-17.04.1_dataloss.patch b/kde/patch/gwenview/gwenview-17.04.1_dataloss.patch
deleted file mode 100644
index fa93428..0000000
--- a/kde/patch/gwenview/gwenview-17.04.1_dataloss.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From 6ce5d2f8d82f83c5a3d726ee5807ebaf7a6e3c6c Mon Sep 17 00:00:00 2001
-From: Henrik Fehlauer <rkflx@lab12.net>
-Date: Thu, 11 May 2017 22:40:15 +0200
-Subject: Avoid data loss when importing pictures
-
-Summary:
-Fix porting regressions, which left users of Gwenview Importer with:
-- failed import (import destination still empty)
-- additionally (when choosing "Delete" instead of "Keep" after import):
- pictures also removed from import source, with no way to recover
-
-Correct additional problems remaining after fixing the import failure:
-- hang on duplicate filenames
-- identically named files with different content are never imported
-- error dialog when deleting pictures from import source
-
-BUG: 379615
-
-In detail:
-
-1st problem (introduced in 017b4fe5dc7f4b6e876cfd7b108dcebbf609ae94):
-
- Initially, pictures are copied to a temporary folder
- (e.g. "foo/.gwenview_importer-IcQqvo/"), before being moved/renamed
- to the final destination (e.g. "foo/"), which is determined by
- calling "cd .." on the temporary folder.
-
- However, mistakenly this path contains a superfluous '/'
- (e.g. "foo/.gwenview_importer-IcQqvo//"), resulting in the final
- destination reading "foo/.gwenview_importer-IcQqvo/" instead of
- "foo/". On cleanup, the temporary folder is removed, simultaneously
- deleting all new pictures.
-
- Fix: Omit '/' where appropriate.
-
-2nd problem (broken by a3262e9b197ee97323ef8bf3a9dca1e13f61a74c):
-
- When trying to find a unique filename, the while loop "stat"ing the
- file repeats forever.
-
- Fix: Call "KIO::stat" and "KJobWidgets::setWindow"
- also inside the loop.
-
-3rd problem (introduced in 017b4fe5dc7f4b6e876cfd7b108dcebbf609ae94):
-
- If the destination directory already contains an identically named
- file, we try to find a different name by appending a number. For
- this, we need to strip the old filename from the full path.
- Unfortunately, only calling "path()" is incorrect, giving
- "foo/pict0001.jpg/pict0001_1.jpg", rather than "foo/pict0001_1.jpg".
-
- Fix: Use "adjusted(QUrl::RemoveFilename)".
-
-4th problem (broken by a3262e9b197ee97323ef8bf3a9dca1e13f61a74c):
-
- Although deletion works, we show a warning dialog stating failure.
-
- Fix: Invert the logic of "job->exec()", as the error handling should
- be skipped by "break"ing out of the while loop.
-
-Test Plan:
-Steps to reproduce (see https://bugs.kde.org/show_bug.cgi?id=379615) no longer result in data loss.
-
-Autotests for importer (separate review request in D5750) pass. Hopefully, this helps catching any future porting regressions.
-
-Reviewers: ltoscano, sandsmark, gateau
-
-Reviewed By: ltoscano
-
-Differential Revision: https://phabricator.kde.org/D5749
----
- importer/fileutils.cpp | 5 ++++-
- importer/importdialog.cpp | 2 +-
- importer/importer.cpp | 4 ++--
- 3 files changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/importer/fileutils.cpp b/importer/fileutils.cpp
-index 5293d56..a51a18c 100644
---- a/importer/fileutils.cpp
-+++ b/importer/fileutils.cpp
-@@ -128,7 +128,10 @@ RenameResult rename(const QUrl& src, const QUrl& dst_, QWidget* authWindow)
- }
- result = RenamedUnderNewName;
-
-- dst.setPath(dst.path() + '/' + prefix + QString::number(count) + suffix);
-+ dst.setPath(dst.adjusted(QUrl::RemoveFilename).path() + prefix + QString::number(count) + suffix);
-+ statJob = KIO::stat(dst);
-+ KJobWidgets::setWindow(statJob, authWindow);
-+
- ++count;
- }
-
-diff --git a/importer/importdialog.cpp b/importer/importdialog.cpp
-index ee6f7cd..5e9e847 100644
---- a/importer/importdialog.cpp
-+++ b/importer/importdialog.cpp
-@@ -121,7 +121,7 @@ public:
- QList<QUrl> urls = importedUrls + skippedUrls;
- while (true) {
- KIO::Job* job = KIO::del(urls);
-- if (!job->exec()) {
-+ if (job->exec()) {
- break;
- }
- // Deleting failed
-diff --git a/importer/importer.cpp b/importer/importer.cpp
-index 51c4b96..a7e1d4e 100644
---- a/importer/importer.cpp
-+++ b/importer/importer.cpp
-@@ -98,7 +98,7 @@ struct ImporterPrivate
- }
- mCurrentUrl = mUrlList.takeFirst();
- QUrl dst = mTempImportDirUrl;
-- dst.setPath(dst.path() + '/' + mCurrentUrl.fileName());
-+ dst.setPath(dst.path() + mCurrentUrl.fileName());
- KIO::Job* job = KIO::copy(mCurrentUrl, dst, KIO::HideProgressInfo);
- KJobWidgets::setWindow(job, mAuthWindow);
- QObject::connect(job, SIGNAL(result(KJob*)),
-@@ -122,7 +122,7 @@ struct ImporterPrivate
- } else {
- fileName = src.fileName();
- }
-- dst.setPath(dst.path() + '/' + fileName);
-+ dst.setPath(dst.path() + fileName);
-
- FileUtils::RenameResult result = FileUtils::rename(src, dst, mAuthWindow);
- switch (result) {
---
-cgit v0.11.2
-
-
diff --git a/kde/patch/kaccounts-integration.patch b/kde/patch/kaccounts-integration.patch
deleted file mode 100644
index 26b87d4..0000000
--- a/kde/patch/kaccounts-integration.patch
+++ /dev/null
@@ -1,4 +0,0 @@
-# A bug with 15.08.2/.3 breaks KDE Telepathy accounts connection .
-# Will be fixed in 15.12.0:
-#cat $CWD/patch/kaccounts-integration/kaccounts-integration-15.08.3_service.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kaccounts-integration/kaccounts-integration-15.08.3_service.patch b/kde/patch/kaccounts-integration/kaccounts-integration-15.08.3_service.patch
deleted file mode 100644
index e41d58b..0000000
--- a/kde/patch/kaccounts-integration/kaccounts-integration-15.08.3_service.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- a/src/jobs/createaccount.cpp
-+++ b/src/jobs/createaccount.cpp
-@@ -141,8 +141,8 @@
-
- m_done = true;
-
-+ connect(m_identity, &SignOn::Identity::credentialsStored, m_identity, &SignOn::Identity::queryInfo);
- m_identity->storeCredentials();
-- connect(m_identity, &SignOn::Identity::credentialsStored, m_identity, &SignOn::Identity::queryInfo);
- }
-
- void CreateAccount::pluginError(const QString &error)
-@@ -177,12 +177,12 @@
- return;
- }
-
-+ m_account->selectService();
-+
- if (m_account->displayName().isEmpty()) {
- m_account->setDisplayName(info.userName());
- }
- m_account->setValue("username", info.userName());
--
-- m_account->selectService();
- m_account->setCredentialsId(info.id());
-
- Accounts::AuthData authData = m_accInfo->authData();
-
diff --git a/kde/patch/kalgebra.patch b/kde/patch/kalgebra.patch
index 8365ff3..d17f482 100644
--- a/kde/patch/kalgebra.patch
+++ b/kde/patch/kalgebra.patch
@@ -2,4 +2,3 @@
# on other, it's not, requiring you to link both Curses and Readline libraries
# manually.
cat $CWD/patch/kalgebra/kalgebra_ncurses_linking.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kalzium.patch b/kde/patch/kalzium.patch
deleted file mode 100644
index 6593e9d..0000000
--- a/kde/patch/kalzium.patch
+++ /dev/null
@@ -1,3 +0,0 @@
-# Fix build against KF 5.31.0 (repaired in 16.12.3):
-#cat $CWD/patch/kalzium/kalzium_kf_5.31.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kalzium/kalzium_kf_5.31.patch b/kde/patch/kalzium/kalzium_kf_5.31.patch
deleted file mode 100644
index a3d4e00..0000000
--- a/kde/patch/kalzium/kalzium_kf_5.31.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-Patch taken from:
-https://gitweb.gentoo.org/repo/gentoo.git/plain/kde-apps/kalzium/files/kalzium-16.12.2-kf-5.31.patch
-
-From f233d458959548ab371e3faeca7313f746625afc Mon Sep 17 00:00:00 2001
-From: Heiko Becker <heirecka@exherbo.org>
-Date: Sun, 22 Jan 2017 14:46:24 +0100
-Subject: Fix build with extra-cmake-modules > 5.30
-
-Since a5f3a76e14799c68b5e8f74e375baa5f6f6ab4dc in
-extra-cmake-modules.git -fno-operator-names is passed to the build
-(when supported), causing a build error for kalzium.
-
-REVIEW: 129873
----
- src/calculator/titrationCalculator.cpp | 39 +++++++++++++++-------------------
- 1 file changed, 17 insertions(+), 22 deletions(-)
-
-diff --git a/src/calculator/titrationCalculator.cpp b/src/calculator/titrationCalculator.cpp
-index 44ea152..6ea9ac9 100644
---- a/src/calculator/titrationCalculator.cpp
-+++ b/src/calculator/titrationCalculator.cpp
-@@ -41,11 +41,6 @@
-
- using namespace std;
-
--#ifdef _MSC_VER
--#define and &&
--#define or ||
--#endif
--
- titrationCalculator::titrationCalculator(QWidget * parent) : QWidget(parent)
- {
- xmin = 0;
-@@ -112,7 +107,7 @@ void titrationCalculator::plot()
- }
- QString mreporto;
- int iter = 0;
-- if (uid.xaxis->text() == "" or uid.xaxis->text() == " ") {
-+ if (uid.xaxis->text() == "" || uid.xaxis->text() == " ") {
- uid.xaxis->setText(i18n("nothing"));
- }
- if (tmpy == 0) {
-@@ -121,11 +116,11 @@ void titrationCalculator::plot()
- //now we have to solve the system of equations NOTE:yvalue contains the equation of Y-axis variable
- //we iterates the process until you have an equation in one only unknown variable or a numeric expression
- mreporto = solve(yvalue);
-- while (end == 0 or lettere == 1) {
-+ while (end == 0 || lettere == 1) {
- QByteArray ba = mreporto.toLatin1();
- char *tmreport = ba.data();
- ++iter;
-- if (end == 1 or lettere == 0) {
-+ if (end == 1 || lettere == 0) {
- break;
- }
- if (iter > 100) {
-@@ -273,13 +268,13 @@ QString titrationCalculator::solve(char *yvalue)
- QString tempyval;
- QString ptem;
- for (int i = 0; strlen(yvalue) + 1; ++i) {
-- if (!(yvalue[i]=='q' or yvalue[i]=='w' or yvalue[i]=='e' or yvalue[i]=='r' or yvalue[i]=='t' or yvalue[i]=='y' or yvalue[i]=='u' or yvalue[i]=='i' or yvalue[i]=='o' or yvalue[i]=='p' or yvalue[i]=='a' or yvalue[i]=='s' or yvalue[i]=='d' or yvalue[i]=='f' or yvalue[i]=='g' or yvalue[i]=='h' or yvalue[i]=='j' or yvalue[i]=='k' or yvalue[i]=='l' or yvalue[i]=='z' or yvalue[i]=='x' or yvalue[i]=='c' or yvalue[i]=='v' or yvalue[i]=='b' or yvalue[i]=='n' or yvalue[i]=='m' or yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='^' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='Q' or yvalue[i]=='W' or yvalue[i]=='E' or yvalue[i]=='R' or yvalue[i]=='T' or yvalue[i]=='Y' or yvalue[i]=='U' or yvalue[i]=='I' or yvalue[i]=='O' or yvalue[i]=='P' or yvalue[i]=='A' or yvalue[i]=='S' or yvalue[i]=='D' or yvalue[i]=='F' or yvalue[i]=='G' or yvalue[i]=='H' or yvalue[i]=='J' or yvalue[i]=='K' or yvalue[i]=='L' or yvalue[i]=='Z' or yvalue[i]=='X' or yvalue[i]=='C' or yvalue[i]=='V' or yvalue[i]=='B' or yvalue[i]=='N' or yvalue[i]=='M' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',')) {
-+ if (!(yvalue[i]=='q' || yvalue[i]=='w' || yvalue[i]=='e' || yvalue[i]=='r' || yvalue[i]=='t' || yvalue[i]=='y' || yvalue[i]=='u' || yvalue[i]=='i' || yvalue[i]=='o' || yvalue[i]=='p' || yvalue[i]=='a' || yvalue[i]=='s' || yvalue[i]=='d' || yvalue[i]=='f' || yvalue[i]=='g' || yvalue[i]=='h' || yvalue[i]=='j' || yvalue[i]=='k' || yvalue[i]=='l' || yvalue[i]=='z' || yvalue[i]=='x' || yvalue[i]=='c' || yvalue[i]=='v' || yvalue[i]=='b' || yvalue[i]=='n' || yvalue[i]=='m' || yvalue[i]=='+' || yvalue[i]=='-' || yvalue[i]=='^' || yvalue[i]=='*' || yvalue[i]=='/' || yvalue[i]=='(' || yvalue[i]==')' || yvalue[i]=='Q' || yvalue[i]=='W' || yvalue[i]=='E' || yvalue[i]=='R' || yvalue[i]=='T' || yvalue[i]=='Y' || yvalue[i]=='U' || yvalue[i]=='I' || yvalue[i]=='O' || yvalue[i]=='P' || yvalue[i]=='A' || yvalue[i]=='S' || yvalue[i]=='D' || yvalue[i]=='F' || yvalue[i]=='G' || yvalue[i]=='H' || yvalue[i]=='J' || yvalue[i]=='K' || yvalue[i]=='L' || yvalue[i]=='Z' || yvalue[i]=='X' || yvalue[i]=='C' || yvalue[i]=='V' || yvalue[i]=='B' || yvalue[i]=='N' || yvalue[i]=='M' || yvalue[i]=='1' || yvalue[i]=='2' || yvalue[i]=='3' || yvalue[i]=='4' || yvalue[i]=='5' || yvalue[i]=='6' || yvalue[i]=='7' || yvalue[i]=='8' || yvalue[i]=='9' || yvalue[i]=='0' || yvalue[i]=='.' || yvalue[i]==',')) {
- break; //if current value is not a permitted value, this means that something is wrong
- }
-- if (yvalue[i]=='q' or yvalue[i]=='w' or yvalue[i]=='e' or yvalue[i]=='r' or yvalue[i]=='t' or yvalue[i]=='y' or yvalue[i]=='u' or yvalue[i]=='i' or yvalue[i]=='o' or yvalue[i]=='p' or yvalue[i]=='a' or yvalue[i]=='s' or yvalue[i]=='d' or yvalue[i]=='f' or yvalue[i]=='g' or yvalue[i]=='h' or yvalue[i]=='j' or yvalue[i]=='k' or yvalue[i]=='l' or yvalue[i]=='z' or yvalue[i]=='x' or yvalue[i]=='c' or yvalue[i]=='v' or yvalue[i]=='b' or yvalue[i]=='n' or yvalue[i]=='m' or yvalue[i]=='Q' or yvalue[i]=='W' or yvalue[i]=='E' or yvalue[i]=='R' or yvalue[i]=='T' or yvalue[i]=='Y' or yvalue[i]=='U' or yvalue[i]=='I' or yvalue[i]=='O' or yvalue[i]=='P' or yvalue[i]=='A' or yvalue[i]=='S' or yvalue[i]=='D' or yvalue[i]=='F' or yvalue[i]=='G' or yvalue[i]=='H' or yvalue[i]=='J' or yvalue[i]=='K' or yvalue[i]=='L' or yvalue[i]=='Z' or yvalue[i]=='X' or yvalue[i]=='C' or yvalue[i]=='V' or yvalue[i]=='B' or yvalue[i]=='N' or yvalue[i]=='M' or yvalue[i]=='.' or yvalue[i]==',') {
-+ if (yvalue[i]=='q' || yvalue[i]=='w' || yvalue[i]=='e' || yvalue[i]=='r' || yvalue[i]=='t' || yvalue[i]=='y' || yvalue[i]=='u' || yvalue[i]=='i' || yvalue[i]=='o' || yvalue[i]=='p' || yvalue[i]=='a' || yvalue[i]=='s' || yvalue[i]=='d' || yvalue[i]=='f' || yvalue[i]=='g' || yvalue[i]=='h' || yvalue[i]=='j' || yvalue[i]=='k' || yvalue[i]=='l' || yvalue[i]=='z' || yvalue[i]=='x' || yvalue[i]=='c' || yvalue[i]=='v' || yvalue[i]=='b' || yvalue[i]=='n' || yvalue[i]=='m' || yvalue[i]=='Q' || yvalue[i]=='W' || yvalue[i]=='E' || yvalue[i]=='R' || yvalue[i]=='T' || yvalue[i]=='Y' || yvalue[i]=='U' || yvalue[i]=='I' || yvalue[i]=='O' || yvalue[i]=='P' || yvalue[i]=='A' || yvalue[i]=='S' || yvalue[i]=='D' || yvalue[i]=='F' || yvalue[i]=='G' || yvalue[i]=='H' || yvalue[i]=='J' || yvalue[i]=='K' || yvalue[i]=='L' || yvalue[i]=='Z' || yvalue[i]=='X' || yvalue[i]=='C' || yvalue[i]=='V' || yvalue[i]=='B' || yvalue[i]=='N' || yvalue[i]=='M' || yvalue[i]=='.' || yvalue[i]==',') {
- lettere = 1; //if lettere == 0 then the equation contains only mnumbers
- }
-- if (yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='^' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',') {
-+ if (yvalue[i]=='+' || yvalue[i]=='-' || yvalue[i]=='^' || yvalue[i]=='*' || yvalue[i]=='/' || yvalue[i]=='(' || yvalue[i]==')' || yvalue[i]=='1' || yvalue[i]=='2' || yvalue[i]=='3' || yvalue[i]=='4' || yvalue[i]=='5' || yvalue[i]=='6' || yvalue[i]=='7' || yvalue[i]=='8' || yvalue[i]=='9' || yvalue[i]=='0' || yvalue[i]=='.' || yvalue[i]==',') {
- tempyval = tempyval + QString(yvalue[i]);
- } else {
- tempy = tempy + QString(yvalue[i]);
-@@ -302,7 +297,7 @@ QString titrationCalculator::solve(char *yvalue)
- end = 1;
- }
- if (tempy!=uid.xaxis->text()) {
-- if (yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='^' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',') {
-+ if (yvalue[i]=='+' || yvalue[i]=='-' || yvalue[i]=='^' || yvalue[i]=='*' || yvalue[i]=='/' || yvalue[i]=='(' || yvalue[i]==')' || yvalue[i]=='1' || yvalue[i]=='2' || yvalue[i]=='3' || yvalue[i]=='4' || yvalue[i]=='5' || yvalue[i]=='6' || yvalue[i]=='7' || yvalue[i]=='8' || yvalue[i]=='9' || yvalue[i]=='0' || yvalue[i]=='.' || yvalue[i]==',') {
- //actually nothing
- } else {
- end = 0;
-@@ -335,13 +330,13 @@ QString titrationCalculator::solvex(char *yvalue, QString dnum) {
- QString tempyval;
- tempy = "";
- for (int i = 0; strlen(yvalue) + 1; ++i) {
-- if (!(yvalue[i]=='q' or yvalue[i]=='w' or yvalue[i]=='e' or yvalue[i]=='r' or yvalue[i]=='t' or yvalue[i]=='y' or yvalue[i]=='u' or yvalue[i]=='i' or yvalue[i]=='o' or yvalue[i]=='p' or yvalue[i]=='a' or yvalue[i]=='s' or yvalue[i]=='d' or yvalue[i]=='f' or yvalue[i]=='g' or yvalue[i]=='h' or yvalue[i]=='j' or yvalue[i]=='k' or yvalue[i]=='l' or yvalue[i]=='z' or yvalue[i]=='x' or yvalue[i]=='c' or yvalue[i]=='v' or yvalue[i]=='b' or yvalue[i]=='n' or yvalue[i]=='m' or yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='^' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='Q' or yvalue[i]=='W' or yvalue[i]=='E' or yvalue[i]=='R' or yvalue[i]=='T' or yvalue[i]=='Y' or yvalue[i]=='U' or yvalue[i]=='I' or yvalue[i]=='O' or yvalue[i]=='P' or yvalue[i]=='A' or yvalue[i]=='S' or yvalue[i]=='D' or yvalue[i]=='F' or yvalue[i]=='G' or yvalue[i]=='H' or yvalue[i]=='J' or yvalue[i]=='K' or yvalue[i]=='L' or yvalue[i]=='Z' or yvalue[i]=='X' or yvalue[i]=='C' or yvalue[i]=='V' or yvalue[i]=='B' or yvalue[i]=='N' or yvalue[i]=='M' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',')) {
-+ if (!(yvalue[i]=='q' || yvalue[i]=='w' || yvalue[i]=='e' || yvalue[i]=='r' || yvalue[i]=='t' || yvalue[i]=='y' || yvalue[i]=='u' || yvalue[i]=='i' || yvalue[i]=='o' || yvalue[i]=='p' || yvalue[i]=='a' || yvalue[i]=='s' || yvalue[i]=='d' || yvalue[i]=='f' || yvalue[i]=='g' || yvalue[i]=='h' || yvalue[i]=='j' || yvalue[i]=='k' || yvalue[i]=='l' || yvalue[i]=='z' || yvalue[i]=='x' || yvalue[i]=='c' || yvalue[i]=='v' || yvalue[i]=='b' || yvalue[i]=='n' || yvalue[i]=='m' || yvalue[i]=='+' || yvalue[i]=='-' || yvalue[i]=='^' || yvalue[i]=='*' || yvalue[i]=='/' || yvalue[i]=='(' || yvalue[i]==')' || yvalue[i]=='Q' || yvalue[i]=='W' || yvalue[i]=='E' || yvalue[i]=='R' || yvalue[i]=='T' || yvalue[i]=='Y' || yvalue[i]=='U' || yvalue[i]=='I' || yvalue[i]=='O' || yvalue[i]=='P' || yvalue[i]=='A' || yvalue[i]=='S' || yvalue[i]=='D' || yvalue[i]=='F' || yvalue[i]=='G' || yvalue[i]=='H' || yvalue[i]=='J' || yvalue[i]=='K' || yvalue[i]=='L' || yvalue[i]=='Z' || yvalue[i]=='X' || yvalue[i]=='C' || yvalue[i]=='V' || yvalue[i]=='B' || yvalue[i]=='N' || yvalue[i]=='M' || yvalue[i]=='1' || yvalue[i]=='2' || yvalue[i]=='3' || yvalue[i]=='4' || yvalue[i]=='5' || yvalue[i]=='6' || yvalue[i]=='7' || yvalue[i]=='8' || yvalue[i]=='9' || yvalue[i]=='0' || yvalue[i]=='.' || yvalue[i]==',')) {
- break; //if current value is not a permitted value, this means that something is wrong
- }
-- if (yvalue[i]=='q' or yvalue[i]=='w' or yvalue[i]=='e' or yvalue[i]=='r' or yvalue[i]=='t' or yvalue[i]=='y' or yvalue[i]=='u' or yvalue[i]=='i' or yvalue[i]=='o' or yvalue[i]=='p' or yvalue[i]=='a' or yvalue[i]=='s' or yvalue[i]=='d' or yvalue[i]=='f' or yvalue[i]=='g' or yvalue[i]=='h' or yvalue[i]=='j' or yvalue[i]=='k' or yvalue[i]=='l' or yvalue[i]=='z' or yvalue[i]=='x' or yvalue[i]=='c' or yvalue[i]=='v' or yvalue[i]=='b' or yvalue[i]=='n' or yvalue[i]=='m' or yvalue[i]=='Q' or yvalue[i]=='W' or yvalue[i]=='E' or yvalue[i]=='R' or yvalue[i]=='T' or yvalue[i]=='Y' or yvalue[i]=='U' or yvalue[i]=='I' or yvalue[i]=='O' or yvalue[i]=='P' or yvalue[i]=='A' or yvalue[i]=='S' or yvalue[i]=='D' or yvalue[i]=='F' or yvalue[i]=='G' or yvalue[i]=='H' or yvalue[i]=='J' or yvalue[i]=='K' or yvalue[i]=='L' or yvalue[i]=='Z' or yvalue[i]=='X' or yvalue[i]=='C' or yvalue[i]=='V' or yvalue[i]=='B' or yvalue[i]=='N' or yvalue[i]=='M' or yvalue[i]=='.' or yvalue[i]==',') {
-+ if (yvalue[i]=='q' || yvalue[i]=='w' || yvalue[i]=='e' || yvalue[i]=='r' || yvalue[i]=='t' || yvalue[i]=='y' || yvalue[i]=='u' || yvalue[i]=='i' || yvalue[i]=='o' || yvalue[i]=='p' || yvalue[i]=='a' || yvalue[i]=='s' || yvalue[i]=='d' || yvalue[i]=='f' || yvalue[i]=='g' || yvalue[i]=='h' || yvalue[i]=='j' || yvalue[i]=='k' || yvalue[i]=='l' || yvalue[i]=='z' || yvalue[i]=='x' || yvalue[i]=='c' || yvalue[i]=='v' || yvalue[i]=='b' || yvalue[i]=='n' || yvalue[i]=='m' || yvalue[i]=='Q' || yvalue[i]=='W' || yvalue[i]=='E' || yvalue[i]=='R' || yvalue[i]=='T' || yvalue[i]=='Y' || yvalue[i]=='U' || yvalue[i]=='I' || yvalue[i]=='O' || yvalue[i]=='P' || yvalue[i]=='A' || yvalue[i]=='S' || yvalue[i]=='D' || yvalue[i]=='F' || yvalue[i]=='G' || yvalue[i]=='H' || yvalue[i]=='J' || yvalue[i]=='K' || yvalue[i]=='L' || yvalue[i]=='Z' || yvalue[i]=='X' || yvalue[i]=='C' || yvalue[i]=='V' || yvalue[i]=='B' || yvalue[i]=='N' || yvalue[i]=='M' || yvalue[i]=='.' || yvalue[i]==',') {
- tempy = tempy + yvalue[i]; //if lettere == 0 then the equation contains only mnumbers
- }
-- if (yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='^' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',') {
-+ if (yvalue[i]=='+' || yvalue[i]=='-' || yvalue[i]=='^' || yvalue[i]=='*' || yvalue[i]=='/' || yvalue[i]=='(' || yvalue[i]==')' || yvalue[i]=='1' || yvalue[i]=='2' || yvalue[i]=='3' || yvalue[i]=='4' || yvalue[i]=='5' || yvalue[i]=='6' || yvalue[i]=='7' || yvalue[i]=='8' || yvalue[i]=='9' || yvalue[i]=='0' || yvalue[i]=='.' || yvalue[i]==',') {
- if (!tempyolda.isEmpty()) {
- tempy = tempy + yvalue[i];
- if (tempyolda == uid.xaxis->text()) {
-@@ -359,7 +354,7 @@ QString titrationCalculator::solvex(char *yvalue, QString dnum) {
- tempyolda = tempyold;
- } else {
- tempyold = "";
-- if (((olda != 1) and (yvalue[i + 1] != '^')) or (yvalue[i] == '+' or yvalue[i] == '-' or yvalue[i] == '^' or yvalue[i] == '*' or yvalue[i] == '/' or yvalue[i] == '(' or yvalue[i] == ')')) {
-+ if (((olda != 1) && (yvalue[i + 1] != '^')) || (yvalue[i] == '+' || yvalue[i] == '-' || yvalue[i] == '^' || yvalue[i] == '*' || yvalue[i] == '/' || yvalue[i] == '(' || yvalue[i] == ')')) {
- tempyval = tempyval + QString(yvalue[i]);
- }
- }
-@@ -374,7 +369,7 @@ QString titrationCalculator::solvex(char *yvalue, QString dnum) {
- tempyold = "";
- olda = 1;
- }
-- if ((tempy==uid.xaxis->text()) and (!tempyolda.isEmpty())) {
-+ if ((tempy==uid.xaxis->text()) && (!tempyolda.isEmpty())) {
- if (yvalue[i + 1] != '^') {
- tempyval = tempyval + dnum;
- }
-@@ -611,7 +606,7 @@ void titrationCalculator::on_actionOpen_triggered()
- if (tmpchr != '|') {
- tempyval = tempyval + tmpchr;
- } else {
-- if ((tablea == 1) and (tempyval != QString("table1")) and (tempyval != QString("table2")) and (tempyval != QString("xaxis")) and (tempyval != QString("yaxis")) and (tempyval != QString("note"))) {
-+ if ((tablea == 1) && (tempyval != QString("table1")) && (tempyval != QString("table2")) && (tempyval != QString("xaxis")) && (tempyval != QString("yaxis")) && (tempyval != QString("note"))) {
- if ((i % 2) != 0) {
- QTableWidgetItem *titemo = uid.tableWidget->item((i - 1) / 2, 1);
- if (titemo) {
-@@ -626,7 +621,7 @@ void titrationCalculator::on_actionOpen_triggered()
- ++i;
- }
-
-- if ((tableb == 1) and (tempyval != QString("table1")) and (tempyval != QString("table2")) and (tempyval != QString("xaxis")) and (tempyval != QString("yaxis")) and (tempyval != QString("note"))) {
-+ if ((tableb == 1) && (tempyval != QString("table1")) && (tempyval != QString("table2")) && (tempyval != QString("xaxis")) && (tempyval != QString("yaxis")) && (tempyval != QString("note"))) {
- if ((i % 2) != 0) {
- QTableWidgetItem *titemo = uid.tableWidget_2->item((i - 1) / 2, 1);
- if (titemo) {
-@@ -641,13 +636,13 @@ void titrationCalculator::on_actionOpen_triggered()
- }
- ++i;
- }
-- if ((xax == 1) and (tempyval != QString("table1")) and (tempyval != QString("table2")) and (tempyval != QString("xaxis")) and (tempyval != QString("yaxis")) and (tempyval != QString("note"))) {
-+ if ((xax == 1) && (tempyval != QString("table1")) && (tempyval != QString("table2")) && (tempyval != QString("xaxis")) && (tempyval != QString("yaxis")) && (tempyval != QString("note"))) {
- uid.xaxis->setText(tempyval);
- }
-- if ((yax == 1) and (tempyval != QString("table1")) and (tempyval != QString("table2")) and (tempyval != QString("xaxis")) and (tempyval != QString("yaxis")) and (tempyval != QString("note"))) {
-+ if ((yax == 1) && (tempyval != QString("table1")) && (tempyval != QString("table2")) && (tempyval != QString("xaxis")) && (tempyval != QString("yaxis")) && (tempyval != QString("note"))) {
- uid.yaxis->setText(tempyval);
- }
-- if ((notea == 1) and (tempyval != QString("table1")) and (tempyval != QString("table2")) and (tempyval != QString("xaxis")) and (tempyval != QString("yaxis")) and (tempyval != QString("note"))) {
-+ if ((notea == 1) && (tempyval != QString("table1")) && (tempyval != QString("table2")) && (tempyval != QString("xaxis")) && (tempyval != QString("yaxis")) && (tempyval != QString("note"))) {
- uid.note->setText(tempyval);
- }
-
---
-cgit v0.11.2
-
-
diff --git a/kde/patch/kate.patch b/kde/patch/kate.patch
index 45c2f53..59df062 100644
--- a/kde/patch/kate.patch
+++ b/kde/patch/kate.patch
@@ -1,8 +1,3 @@
-# Last-minute fixes for opening and closing files:
-# Should be fixed after 15.12.0.
-#cat $CWD/patch/kate/kate-15.12.0.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
# Allow Kate to be started by the root user; disallowing this is not
# a decision that a developer should make for the user, it is patronizing:
cat $CWD/patch/kate/kate_runasroot.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kate/kate-15.12.0.patch b/kde/patch/kate/kate-15.12.0.patch
deleted file mode 100644
index 25067f4..0000000
--- a/kde/patch/kate/kate-15.12.0.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Michal Humpula <michal.humpula@hudrydum.cz>
-Date: Sun, 29 Nov 2015 10:24:42 +0000
-Subject: fix opening new files trough dbus
-X-Git-Url: http://quickgit.kde.org/?p=kate.git&a=commitdiff&h=d61b121264d7b43d41c1c6417a18bbfb9078eb9d
----
-fix opening new files trough dbus
-
-REVIEW: 126197
----
-
-
---- a/urlinfo.h
-+++ b/urlinfo.h
-@@ -33,7 +33,7 @@
- : cursor(KTextEditor::Cursor::invalid())
- {
- // convert to an url
-- const QRegularExpression withProtocol(QStringLiteral("^[a-zA-Z]+:")); // TODO: remove after Qt supports this on its own
-+ const QRegularExpression withProtocol(QStringLiteral("^[a-zA-Z]+://")); // TODO: remove after Qt supports this on its own
- if (withProtocol.match(path).hasMatch()) {
- url = QUrl::fromUserInput(path);
- } else {
-@@ -50,7 +50,7 @@
- int line = match.captured(1).toInt() - 1;
- // don't use an invalid column when the line is valid
- int column = qMax(0, match.captured(2).toInt() - 1);
-- url = QUrl::fromLocalFile(path);
-+ url = QUrl::fromLocalFile(QDir::current().absoluteFilePath(path));
- cursor = {line, column};
- }
- }
diff --git a/kde/patch/kcalc.patch b/kde/patch/kcalc.patch
deleted file mode 100644
index 8cc3873..0000000
--- a/kde/patch/kcalc.patch
+++ /dev/null
@@ -1,5 +0,0 @@
-# Fix issue where kcalc has a zero-sized window and appears not to start,
-# in combination with Qt 5.6.
-# Should be fixed after 16.04.0.
-#cat $CWD/patch/kcalc/kcalc-kdebug_360105.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kcalc/kcalc-kdebug_360105.patch b/kde/patch/kcalc/kcalc-kdebug_360105.patch
deleted file mode 100644
index a2ff272..0000000
--- a/kde/patch/kcalc/kcalc-kdebug_360105.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Fix issue where kcalc has a zero-sized window and appears not to start.
-
-Patch-by: Rex Dieter <rdieter@math.unl.edu>
-Gentoo-bug: 577782
-KDE-bug: 360105
-
---- a/kcalc.cpp
-+++ b/kcalc.cpp
-@@ -124,5 +124,5 @@ KCalculator::KCalculator(QWidget *parent
- updateGeometry();
-
-- setFixedSize(minimumSize());
-+ if ( ! minimumSize().isEmpty() ) setFixedSize(minimumSize());
-
- updateDisplay(UPDATE_FROM_CORE);
diff --git a/kde/patch/kcalcore.patch b/kde/patch/kcalcore.patch
deleted file mode 100644
index 051150d..0000000
--- a/kde/patch/kcalcore.patch
+++ /dev/null
@@ -1,4 +0,0 @@
-# Fix compile error against new libical 3:
-# Fixed in Applications 17.12.0:
-#cat $CWD/patch/kcalcore/kcalcore_libical3.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kcalcore/kcalcore_libical3.patch b/kde/patch/kcalcore/kcalcore_libical3.patch
deleted file mode 100644
index 0a5155f..0000000
--- a/kde/patch/kcalcore/kcalcore_libical3.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 27eaa211b23a6bb0bcba5a91cf7cadfc1e888e21 Mon Sep 17 00:00:00 2001
-From: Allen Winter <winter@kde.org>
-Date: Fri, 6 Oct 2017 10:39:20 -0400
-Subject: icalformat_p.cpp, icaltimezones.cpp - follow API changes in libical3
-
----
- src/icalformat_p.cpp | 11 ++++++-----
- src/icaltimezones.cpp | 10 ++++------
- 2 files changed, 10 insertions(+), 11 deletions(-)
-
-diff --git a/src/icalformat_p.cpp b/src/icalformat_p.cpp
-index bd1d8a3..c2e4548 100644
---- a/src/icalformat_p.cpp
-+++ b/src/icalformat_p.cpp
-@@ -2355,7 +2355,6 @@ icaltimetype ICalFormatImpl::writeICalDate(const QDate &date)
- t.second = 0;
-
- t.is_date = 1;
-- t.is_utc = 0;
- t.zone = nullptr;
-
- return t;
-@@ -2377,7 +2376,9 @@ icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &datetime, bool d
- t.second = datetime.time().second();
- }
- t.zone = nullptr; // zone is NOT set
-- t.is_utc = datetime.isUtc() ? 1 : 0;
-+ if ( datetime.isUtc() ) {
-+ t = icaltime_convert_to_zone(t, icaltimezone_get_utc_timezone());
-+ }
-
- // _dumpIcaltime( t );
-
-@@ -2450,7 +2452,7 @@ icalproperty *ICalFormatImpl::writeICalDateTimeProperty(const icalproperty_kind
- }
-
- KTimeZone ktz;
-- if (!t.is_utc) {
-+ if (!icaltime_is_utc(t)) {
- ktz = dt.timeZone();
- }
-
-@@ -2483,7 +2484,7 @@ QDateTime ICalFormatImpl::readICalDateTime(icalproperty *p, const icaltimetype &
- // _dumpIcaltime( t );
-
- KDateTime::Spec timeSpec;
-- if (t.is_utc || t.zone == icaltimezone_get_utc_timezone()) {
-+ if (icaltime_is_utc(t) || t.zone == icaltimezone_get_utc_timezone()) {
- timeSpec = KDateTime::UTC; // the time zone is UTC
- utc = false; // no need to convert to UTC
- } else {
-diff --git a/src/icaltimezones.cpp b/src/icaltimezones.cpp
-index 2f6d42f..f8f8d5d 100644
---- a/src/icaltimezones.cpp
-+++ b/src/icaltimezones.cpp
-@@ -54,7 +54,7 @@ static QDateTime toQDateTime(const icaltimetype &t)
- {
- return QDateTime(QDate(t.year, t.month, t.day),
- QTime(t.hour, t.minute, t.second),
-- (t.is_utc ? Qt::UTC : Qt::LocalTime));
-+ (icaltime_is_utc(t) ? Qt::UTC : Qt::LocalTime));
- }
-
- // Maximum date for time zone data.
-@@ -81,7 +81,6 @@ static icaltimetype writeLocalICalDateTime(const QDateTime &utc, int offset)
- t.second = local.time().second();
- t.is_date = 0;
- t.zone = nullptr;
-- t.is_utc = 0;
- return t;
- }
-
-@@ -888,7 +887,7 @@
- }
- case ICAL_LASTMODIFIED_PROPERTY: {
- const icaltimetype t = icalproperty_get_lastmodified(p);
-- if (t.is_utc) {
-+ if (icaltime_is_utc(t)) {
- data->d->lastModified = toQDateTime(t);
- } else {
- qCDebug(KCALCORE_LOG) << "LAST-MODIFIED not UTC";
-@@ -1261,7 +1260,7 @@ bool ICalTimeZoneParser::parsePhase(icalcomponent *c, ICalTimeZonePhase &phase)
- // Convert DTSTART to QDateTime, and from local time to UTC
- const QDateTime localStart = toQDateTime(dtstart); // local time
- dtstart.second -= prevOffset;
-- dtstart.is_utc = 1;
-+ dtstart = icaltime_convert_to_zone(dtstart, icaltimezone_get_utc_timezone());
- const QDateTime utcStart = toQDateTime(icaltime_normalize(dtstart)); // UTC
-
- transitions += utcStart;
-@@ -1286,13 +1285,12 @@ bool ICalTimeZoneParser::parsePhase(icalcomponent *c, ICalTimeZonePhase &phase)
- t.minute = dtstart.minute;
- t.second = dtstart.second;
- t.is_date = 0;
-- t.is_utc = 0; // dtstart is in local time
- }
- // RFC2445 states that RDATE must be in local time,
- // but we support UTC as well to be safe.
-- if (!t.is_utc) {
-+ if (!icaltime_is_utc(t)) {
- t.second -= prevOffset; // convert to UTC
-- t.is_utc = 1;
-+ t = icaltime_convert_to_zone(t, icaltimezone_get_utc_timezone());
- t = icaltime_normalize(t);
- }
- transitions += toQDateTime(t);
---
-cgit v0.11.2
-
diff --git a/kde/patch/kcoreaddons.patch b/kde/patch/kcoreaddons.patch
deleted file mode 100644
index 5cd190c..0000000
--- a/kde/patch/kcoreaddons.patch
+++ /dev/null
@@ -1,5 +0,0 @@
-# KDEBUG #362161 (fixed in Frameworks 5.22.0):
-# Fixes regression introduced in 9ae6d765b37135bbfe3a8b936e5a88b8a435e424
-# Since the rand() was not seeded, the numbers generated were predictable.
-#cat $CWD/patch/kcoreaddons/kcoreaddons.kdebug_362161.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kcoreaddons/kcoreaddons.kdebug_362161.patch b/kde/patch/kcoreaddons/kcoreaddons.kdebug_362161.patch
deleted file mode 100644
index 31bbcf7..0000000
--- a/kde/patch/kcoreaddons/kcoreaddons.kdebug_362161.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Albert Astals Cid <aacid@kde.org>
-Date: Tue, 26 Apr 2016 21:41:27 +0000
-Subject: Missing rand() -> qrand
-X-Git-Url: http://quickgit.kde.org/?p=kcoreaddons.git&a=commitdiff&h=78212436643af95779facd9593c82fb149c2213d
----
-Missing rand() -> qrand
-
-Fixes regression introduced in 9ae6d765b37135bbfe3a8b936e5a88b8a435e424
-
-Reviewed by Aleix
-
-BUGS: 362161
----
-
-
---- a/src/lib/randomness/krandom.cpp
-+++ b/src/lib/randomness/krandom.cpp
-@@ -51,7 +51,7 @@
- }
- qsrand(seed);
- }
-- return rand();
-+ return qrand();
- }
-
- QString KRandom::randomString(int length)
-
diff --git a/kde/patch/kde-baseapps.patch b/kde/patch/kde-baseapps.patch
deleted file mode 100644
index 988504d..0000000
--- a/kde/patch/kde-baseapps.patch
+++ /dev/null
@@ -1,5 +0,0 @@
-# Fix for bug https://bugs.kde.org/show_bug.cgi?id=327224
-# "Regression: Dolphin doesn't accept URLs containing a kio-slave as parameter"
-# Fixed in KDE 4.11.4.
-#cat $CWD/patch/kde-baseapps/dolphin_kdebug_327224.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kde-baseapps/dolphin_kdebug_327224.patch b/kde/patch/kde-baseapps/dolphin_kdebug_327224.patch
deleted file mode 100644
index 8210d87..0000000
--- a/kde/patch/kde-baseapps/dolphin_kdebug_327224.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-Revert "Files passed as arguments: Ignore unsupported files"
-
-This reverts commit cd9e50ae4f3ded5a78d0cfb09a67684a9c15d726.
-
-See bug#327224 for details.
-
---- a/dolphin/src/dolphinmainwindow.cpp
-+++ b/dolphin/src/dolphinmainwindow.cpp
-@@ -31,7 +31,6 @@
- #include "panels/information/informationpanel.h"
- #include "settings/dolphinsettingsdialog.h"
- #include "statusbar/dolphinstatusbar.h"
--#include "views/dolphinview.h"
- #include "views/dolphinviewactionhandler.h"
- #include "views/dolphinremoteencoding.h"
- #include "views/draganddrophelper.h"
-@@ -244,20 +243,8 @@
- return;
- }
-
-- // dirs could contain URLs that actually point to archives or other files.
-- // Replace them by URLs we can open where possible and filter the rest out.
-- QList<KUrl> urlsToOpen;
-- foreach (const KUrl& rawUrl, dirs) {
-- const KFileItem& item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, rawUrl);
-- item.determineMimeType();
-- const KUrl& url = DolphinView::openItemAsFolderUrl(item);
-- if (!url.isEmpty()) {
-- urlsToOpen.append(url);
-- }
-- }
--
-- if (urlsToOpen.count() == 1) {
-- m_activeViewContainer->setUrl(urlsToOpen.first());
-+ if (dirs.count() == 1) {
-+ m_activeViewContainer->setUrl(dirs.first());
- return;
- }
-
-@@ -267,12 +254,12 @@
-
- // Open each directory inside a new tab. If the "split view" option has been enabled,
- // always show two directories within one tab.
-- QList<KUrl>::const_iterator it = urlsToOpen.begin();
-- while (it != urlsToOpen.end()) {
-+ QList<KUrl>::const_iterator it = dirs.begin();
-+ while (it != dirs.end()) {
- openNewTab(*it);
- ++it;
-
-- if (hasSplitView && (it != urlsToOpen.end())) {
-+ if (hasSplitView && (it != dirs.end())) {
- const int tabIndex = m_viewTab.count() - 1;
- m_viewTab[tabIndex].secondaryView->setUrl(*it);
- ++it;
-
-
diff --git a/kde/patch/kde-cli-tools.patch b/kde/patch/kde-cli-tools.patch
deleted file mode 100644
index a76227d..0000000
--- a/kde/patch/kde-cli-tools.patch
+++ /dev/null
@@ -1,6 +0,0 @@
-# Remove CONFIG argument from find_package(KF5);
-# This is no longer wanted, since ECM has a FindKF5 module.
-#cat $CWD/patch/kde-cli-tools/kde-cli-tools_ecm.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-# Adjust for the change in KAboutData:
-#cat $CWD/patch/kde-cli-tools/kde-cli-tools_kaboutdata.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
diff --git a/kde/patch/kde-cli-tools/kde-cli-tools_ecm.patch b/kde/patch/kde-cli-tools/kde-cli-tools_ecm.patch
deleted file mode 100644
index 1ff1f84..0000000
--- a/kde/patch/kde-cli-tools/kde-cli-tools_ecm.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- kde-cli-tools-20140602git/CMakeLists.txt.orig 2014-06-02 13:45:49.000000000 +0200
-+++ kde-cli-tools-20140602git/CMakeLists.txt 2014-06-02 23:45:22.337682384 +0200
-@@ -21,7 +21,7 @@
- Test
- )
-
--find_package(KF5 CONFIG REQUIRED COMPONENTS
-+find_package(KF5 REQUIRED COMPONENTS
- Config
- Init
- KCMUtils
diff --git a/kde/patch/kde-cli-tools/kde-cli-tools_kaboutdata.diff b/kde/patch/kde-cli-tools/kde-cli-tools_kaboutdata.diff
deleted file mode 100644
index e88a512..0000000
--- a/kde/patch/kde-cli-tools/kde-cli-tools_kaboutdata.diff
+++ /dev/null
@@ -1,59 +0,0 @@
-diff -uar kde-cli-tools-20140602git.orig/kdesu/kdesu.cpp kde-cli-tools-20140602git/kdesu/kdesu.cpp
---- kde-cli-tools-20140602git.orig/kdesu/kdesu.cpp 2014-06-02 13:45:49.000000000 +0200
-+++ kde-cli-tools-20140602git/kdesu/kdesu.cpp 2014-06-03 00:41:16.998697492 +0200
-@@ -81,9 +81,9 @@
- if (duser.isEmpty())
- duser = "root";
-
-- KAboutData aboutData("kdesu", 0, i18n("KDE su"),
-+ KAboutData aboutData("kdesu", i18n("KDE su"),
- Version, i18n("Runs a program with elevated privileges."),
-- KAboutData::License_Artistic,
-+ KAboutLicense::Artistic,
- i18n("Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio"));
- aboutData.addAuthor(i18n("Geert Jansen"), i18n("Maintainer"),
- "jansen@kde.org", "http://www.stack.nl/~geertj/");
-diff -uar kde-cli-tools-20140602git.orig/kioclient/kioclient.cpp kde-cli-tools-20140602git/kioclient/kioclient.cpp
---- kde-cli-tools-20140602git.orig/kioclient/kioclient.cpp 2014-06-02 13:45:49.000000000 +0200
-+++ kde-cli-tools-20140602git/kioclient/kioclient.cpp 2014-06-03 00:41:50.446696159 +0200
-@@ -133,7 +133,7 @@
- QString programName = i18n("KIO Client");
- QString description = i18n("Command-line tool for network-transparent operations");
- QString version = "2.0";
-- KAboutData data(appName, appName, programName, version, description, KAboutData::License_LGPL_V2);
-+ KAboutData data(appName, programName, version, description, KAboutLicense::LGPL_V2);
-
- QCommandLineParser parser;
- parser.addOption(QCommandLineOption("noninteractive", i18n("Non-interactive use: no message boxes. If you don't want a"
-diff -uar kde-cli-tools-20140602git.orig/kreadconfig/kreadconfig.cpp kde-cli-tools-20140602git/kreadconfig/kreadconfig.cpp
---- kde-cli-tools-20140602git.orig/kreadconfig/kreadconfig.cpp 2014-06-02 13:45:49.000000000 +0200
-+++ kde-cli-tools-20140602git/kreadconfig/kreadconfig.cpp 2014-06-03 00:40:33.820702023 +0200
-@@ -53,10 +53,10 @@
- int main(int argc, char **argv)
- {
- QCoreApplication app(argc, argv);
-- KAboutData aboutData("kreadconfig", 0, i18n("KReadConfig"),
-+ KAboutData aboutData("kreadconfig", i18n("KReadConfig"),
- "1.0.1",
- i18n("Read KConfig entries - for use in shell scripts"),
-- KAboutData::License_GPL,
-+ KAboutLicense::GPL,
- i18n("(c) 2001 Red Hat, Inc."));
- aboutData.addAuthor(i18n("Bernhard Rosenkraenzer"), QString(), "bero@redhat.com");
-
-diff -uar kde-cli-tools-20140602git.orig/kreadconfig/kwriteconfig.cpp kde-cli-tools-20140602git/kreadconfig/kwriteconfig.cpp
---- kde-cli-tools-20140602git.orig/kreadconfig/kwriteconfig.cpp 2014-06-02 13:45:49.000000000 +0200
-+++ kde-cli-tools-20140602git/kreadconfig/kwriteconfig.cpp 2014-06-03 00:39:54.811701204 +0200
-@@ -31,10 +31,10 @@
- int main(int argc, char **argv)
- {
- QCoreApplication app(argc, argv);
-- KAboutData aboutData("kwriteconfig", 0, i18n("KWriteConfig"),
-+ KAboutData aboutData("kwriteconfig", i18n("KWriteConfig"),
- "1.0.0",
- i18n("Write KConfig entries - for use in shell scripts"),
-- KAboutData::License_GPL,
-+ KAboutLicense::GPL,
- i18n("(c) 2001 Red Hat, Inc. & Luís Pedro Coelho"));
- aboutData.addAuthor("Luís Pedro Coelho", QString(), "luis_pedro@netcabo.pt");
- aboutData.addAuthor("Bernhard Rosenkraenzer", i18n("Wrote kreadconfig on which this is based"), "bero@redhat.com");
diff --git a/kde/patch/kde-dev-utils.patch b/kde/patch/kde-dev-utils.patch
deleted file mode 100644
index c5cbc92..0000000
--- a/kde/patch/kde-dev-utils.patch
+++ /dev/null
@@ -1,3 +0,0 @@
-# Fix build against KF 5.48.0 (only relevant for 18.04.3):
-#cat $CWD/patch/kde-dev-utils/build_with_kf548.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kde-dev-utils/build_with_kf548.patch b/kde/patch/kde-dev-utils/build_with_kf548.patch
deleted file mode 100644
index e75838d..0000000
--- a/kde/patch/kde-dev-utils/build_with_kf548.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 369699a..00e1413 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -1,15 +1,18 @@
- cmake_minimum_required(VERSION 2.8.12)
-
- find_package(ECM 5.14 REQUIRED NO_MODULE)
- set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
-
- include(FeatureSummary)
- include(ECMInstallIcons)
- include(KDEInstallDirs)
- include(KDECMakeSettings)
- include(KDECompilerSettings NO_POLICY_SCOPE)
- include(ECMQtDeclareLoggingCategory)
-
-+# Required for ki18n_install(po) added on tarball generation
-+find_package(KF5 REQUIRED COMPONENTS I18n)
-+
- add_subdirectory(kpartloader)
- add_subdirectory(kuiviewer)
- ki18n_install(po)
-diff --git a/kpartloader/CMakeLists.txt b/kpartloader/CMakeLists.txt
-index 4e54d94..1fe4136 100644
---- a/kpartloader/CMakeLists.txt
-+++ b/kpartloader/CMakeLists.txt
-@@ -1,27 +1,26 @@
- project(kpartloader)
- ########### kpartloader ###############
-
- set(QT_MIN_VERSION "5.5.0")
-
- find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE
- COMPONENTS
- Core
- )
-
- find_package(KF5 REQUIRED
- COMPONENTS
- CoreAddons
-- I18n
- Parts
- WidgetsAddons
- )
-
- set(kpartloader_SRCS
- kpartloader.cpp
- )
-
- add_executable(kpartloader ${kpartloader_SRCS})
- target_link_libraries(kpartloader KF5::Parts)
- install(TARGETS kpartloader ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
- install(FILES kpartloaderui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/kpartloader)
-
-diff --git a/kuiviewer/CMakeLists.txt b/kuiviewer/CMakeLists.txt
-index fa72c59..3fe987e 100644
---- a/kuiviewer/CMakeLists.txt
-+++ b/kuiviewer/CMakeLists.txt
-@@ -1,96 +1,95 @@
- project(kuiviewer)
-
- set(QT_MIN_VERSION "5.5.0")
-
- include(ECMAddAppIcon)
-
- find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE
- COMPONENTS
- Core
- Designer
- UiTools
- )
-
- find_package(KF5 REQUIRED
- COMPONENTS
- CoreAddons
- KIO
-- I18n
- Parts
- )
-
- add_definitions(
- -DQT_DEPRECATED_WARNINGS
- -DQT_DISABLE_DEPRECATED_BEFORE=0x050500
- -DQT_NO_SIGNALS_SLOTS_KEYWORDS
- -DQT_STRICT_ITERATORS
- -DQT_USE_QSTRINGBUILDER
- -DQT_NO_CAST_TO_ASCII
- -DQT_NO_CAST_FROM_ASCII
- -DQT_NO_CAST_FROM_BYTEARRAY
- -DQT_NO_URL_CAST_FROM_STRING
- )
-
- ########### next target ###############
-
- set(kuiviewer_SRCS main.cpp kuiviewer.cpp )
-
- file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/*-apps-kuiviewer.png")
- ecm_add_app_icon(kuiviewer_SRCS ICONS ${ICONS_SRCS})
-
- add_executable(kuiviewer ${kuiviewer_SRCS})
-
- target_link_libraries(kuiviewer KF5::Parts )
-
- install(TARGETS kuiviewer ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} )
-
-
- ########### next target ###############
-
- set(kuiviewerpart_PART_SRCS kuiviewer_part.cpp )
-
- ecm_qt_declare_logging_category(kuiviewerpart_PART_SRCS
- HEADER kuiviewer_part_debug.h
- IDENTIFIER KUIVIEWERPART
- CATEGORY_NAME "kuiviewerpart"
- )
-
- add_library(kuiviewerpart MODULE ${kuiviewerpart_PART_SRCS})
-
- target_link_libraries(kuiviewerpart KF5::Parts Qt5::Designer Qt5::UiTools)
-
- install(TARGETS kuiviewerpart DESTINATION ${KDE_INSTALL_PLUGINDIR} )
-
-
- ########### next target ###############
-
- set(quithumbnail_PART_SRCS quicreator.cpp )
-
- add_library(quithumbnail MODULE ${quithumbnail_PART_SRCS})
-
- target_link_libraries(quithumbnail
- KF5::KIOWidgets
- Qt5::Designer
- Qt5::UiTools
- )
-
- install(TARGETS quithumbnail DESTINATION ${KDE_INSTALL_PLUGINDIR} )
-
-
- ########### install files ###############
-
- install( PROGRAMS org.kde.kuiviewer.desktop DESTINATION ${KDE_INSTALL_APPDIR} )
- install( FILES designerthumbnail.desktop kuiviewer_part.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
- install( FILES kuiviewer_part.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/kuiviewerpart )
- install( FILES kuiviewerui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/kuiviewer )
-
- ecm_install_icons(ICONS
- 16-apps-kuiviewer.png
- 32-apps-kuiviewer.png
- 48-apps-kuiviewer.png
- 64-apps-kuiviewer.png
- 128-apps-kuiviewer.png
- sc-apps-kuiviewer.svg
- DESTINATION ${KDE_INSTALL_ICONDIR}
- THEME hicolor
- )
diff --git a/kde/patch/kde-gtk-config.patch b/kde/patch/kde-gtk-config.patch
deleted file mode 100644
index a62e649..0000000
--- a/kde/patch/kde-gtk-config.patch
+++ /dev/null
@@ -1,4 +0,0 @@
-# Make the kde-gtk-config load the current config first:
-# Fixed in 5.11.2
-#cat $CWD/patch/kde-gtk-config/kde-gtk-config_loadcurrentsettings.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kde-gtk-config/kde-gtk-config_loadcurrentsettings.patch b/kde/patch/kde-gtk-config/kde-gtk-config_loadcurrentsettings.patch
deleted file mode 100644
index b5b074d..0000000
--- a/kde/patch/kde-gtk-config/kde-gtk-config_loadcurrentsettings.patch
+++ /dev/null
@@ -1,622 +0,0 @@
-From 0d0f812a1704c62c014bc87162b1280224b64f93 Mon Sep 17 00:00:00 2001
-From: Fabian Vogt <fabian@ritter-vogt.de>
-Date: Tue, 24 Oct 2017 13:25:32 +0200
-Subject: Revert "Make the kde-gtk-config kcm better at checking global gtk
- settings"
-
-Summary:
-This reverts commit 34357f74ee2d98128ff423b0ec6ddcbf4232c475.
-
-Reverting this fixes loading of the actually used GTK settings.
-
-BUG: 382291
-
-Test Plan:
-Opened kcmshell5 kde-gtk-config with and without this revert.
-Without, it shows Adwaita as theme, with it shows breeze.
-GTK uses breeze, so the behaviour with the revert is correct.
-
-Reviewers: #plasma, apol
-
-Subscribers: plasma-devel
-
-Tags: #plasma
-
-Differential Revision: https://phabricator.kde.org/D8443
----
- CMakeLists.txt | 2 +-
- src/abstractappearance.h | 5 +-
- src/appearancegtk2.cpp | 103 +++++++++++++---------------------
- src/appearancegtk2.h | 11 +---
- src/appearancegtk3.cpp | 143 +++++++++++++++++++++--------------------------
- src/appearancegtk3.h | 10 +---
- src/appearencegtk.cpp | 4 +-
- tests/CMakeLists.txt | 2 +-
- tests/configsavetest.cpp | 75 ++++++++++---------------
- tests/configsavetest.h | 8 +--
- 10 files changed, 144 insertions(+), 219 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 181cfc9..bf1ba29 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -51,7 +51,7 @@ ki18n_wrap_ui(kcm_SRCS
- )
- add_library(kcm_kdegtkconfig MODULE ${kcm_SRCS})
- target_compile_definitions(kcm_kdegtkconfig PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
--target_link_libraries(kcm_kdegtkconfig ${X11_Xcursor_LIB} KF5::ConfigCore KF5::I18n KF5::KIOWidgets KF5::NewStuff KF5::Archive KF5::NewStuff KF5::ConfigWidgets KF5::IconThemes)
-+target_link_libraries(kcm_kdegtkconfig ${X11_Xcursor_LIB} KF5::I18n KF5::KIOWidgets KF5::NewStuff KF5::Archive KF5::NewStuff KF5::ConfigWidgets KF5::IconThemes)
-
- kcoreaddons_desktop_to_json(kcm_kdegtkconfig kde-gtk-config.desktop)
-
-diff --git a/src/abstractappearance.h b/src/abstractappearance.h
-index 208342e..2961a09 100644
---- a/src/abstractappearance.h
-+++ b/src/abstractappearance.h
-@@ -30,11 +30,10 @@ class AbstractAppearance
- {
- public:
- virtual ~AbstractAppearance() {}
-- virtual bool loadSettings() = 0;
-- virtual bool saveSettings() const = 0;
-+ virtual QString defaultConfigFile() const = 0;
- virtual bool loadSettings(const QString& path) = 0;
- virtual bool saveSettings(const QString& path) const = 0;
--
-+
- /** @returns the installed themes' paths*/
- virtual QStringList installedThemes() const = 0;
-
-diff --git a/src/appearancegtk2.cpp b/src/appearancegtk2.cpp
-index 92cbee3..44a2239 100644
---- a/src/appearancegtk2.cpp
-+++ b/src/appearancegtk2.cpp
-@@ -30,38 +30,48 @@
- #include <QStandardPaths>
- #include <config.h>
-
--bool AppearanceGTK2::loadSettingsPrivate(const QString& path)
-+bool AppearanceGTK2::loadSettings(const QString& path)
- {
- QFile configFile(path);
-
-- if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text))
-- return false;
-+ bool canRead = configFile.open(QIODevice::ReadOnly | QIODevice::Text);
-
-- const QMap<QString, QString> foundSettings = readSettingsTuples(&configFile);
--
-- for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) {
-- if (it.key() == "gtk-theme-name")
-- m_settings["theme"] = *it;
-- else if (it.key() == "gtk-icon-theme-name")
-- m_settings["icon"] = *it;
-- else if (it.key() == "gtk-fallback-icon-theme")
-- m_settings["icon_fallback"] = *it;
-- else if (it.key() == "gtk-cursor-theme-name")
-- m_settings["cursor"] = *it;
-- else if (it.key() == "gtk-font-name")
-- m_settings["font"] = *it;
-- else if (it.key() == "gtk-toolbar-style")
-- m_settings["toolbar_style"] = *it;
-- else if (it.key() == "gtk-button-images")
-- m_settings["show_icons_buttons"] = *it;
-- else if(it.key() == "gtk-menu-images")
-- m_settings["show_icons_menus"] = *it;
-- else if (it.key() == "gtk-primary-button-warps-slider")
-- m_settings["primary_button_warps_slider"] = *it;
-- else
-- qWarning() << "unknown field" << it.key();
-+ if(canRead) {
-+// qDebug() << "The gtk2 config file exists...";
-+ const QMap<QString, QString> foundSettings = readSettingsTuples(&configFile);
-+ m_settings = QMap<QString, QString> {
-+ {"toolbar_style", "GTK_TOOLBAR_ICONS"},
-+ {"show_icons_buttons", "0"},
-+ {"show_icons_menus", "0"},
-+ {"primary_button_warps_slider", "false"}
-+ };
-+
-+ for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) {
-+ if (it.key() == "gtk-theme-name")
-+ m_settings["theme"] = *it;
-+ else if (it.key() == "gtk-icon-theme-name")
-+ m_settings["icon"] = *it;
-+ else if (it.key() == "gtk-fallback-icon-theme")
-+ m_settings["icon_fallback"] = *it;
-+ else if (it.key() == "gtk-cursor-theme-name")
-+ m_settings["cursor"] = *it;
-+ else if (it.key() == "gtk-font-name")
-+ m_settings["font"] = *it;
-+ else if (it.key() == "gtk-toolbar-style")
-+ m_settings["toolbar_style"] = *it;
-+ else if (it.key() == "gtk-button-images")
-+ m_settings["show_icons_buttons"] = *it;
-+ else if(it.key() == "gtk-menu-images")
-+ m_settings["show_icons_menus"] = *it;
-+ else if (it.key() == "gtk-primary-button-warps-slider")
-+ m_settings["primary_button_warps_slider"] = *it;
-+ else
-+ qWarning() << "unknown field" << it.key();
-+ }
-+
- }
-- return true;
-+
-+ return canRead;
- }
-
- QString AppearanceGTK2::themesGtkrcFile(const QString& themeName) const
-@@ -82,7 +92,7 @@ QString AppearanceGTK2::themesGtkrcFile(const QString& themeName) const
- return QString();
- }
-
--bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const
-+bool AppearanceGTK2::saveSettings(const QString& gtkrcFile) const
- {
- QFile gtkrc(gtkrcFile);
- gtkrc.remove();
-@@ -107,14 +117,14 @@ bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const
- flow << "include \"/etc/gtk-2.0/gtkrc\"\n"; //We include the /etc's config file
-
- int nameEnd = m_settings["font"].lastIndexOf(QRegExp(" ([0-9]+|bold|italic)"));
-- const auto fontFamily = m_settings["font"].leftRef(nameEnd);
-+ QString fontFamily = m_settings["font"].left(nameEnd);
-
- //TODO: is this really needed?
- flow << "style \"user-font\" \n"
- << "{\n"
- << "\tfont_name=\""<< fontFamily << "\"\n"
- << "}\n";
--
-+
- flow << "widget_class \"*\" style \"user-font\"\n";
- flow << "gtk-font-name=\"" << m_settings["font"] << "\"\n";
- flow << "gtk-theme-name=\"" << m_settings["theme"] << "\"\n";
-@@ -144,16 +154,6 @@ bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const
- return true;
- }
-
--void AppearanceGTK2::reset()
--{
-- m_settings = QMap<QString, QString> {
-- {"toolbar_style", "GTK_TOOLBAR_ICONS"},
-- {"show_icons_buttons", "0"},
-- {"show_icons_menus", "0"},
-- {"primary_button_warps_slider", "false"}
-- };
--}
--
- QString AppearanceGTK2::defaultConfigFile() const
- {
- return QDir::homePath()+"/.gtkrc-2.0";
-@@ -183,26 +183,3 @@ QStringList AppearanceGTK2::installedThemes() const
-
- return paths;
- }
--
--bool AppearanceGTK2::loadSettings()
--{
-- reset();
--
-- return loadSettingsPrivate("/etc/gtk-2.0/gtkrc") && loadSettingsPrivate(defaultConfigFile());
--}
--
--bool AppearanceGTK2::saveSettings() const
--{
-- return saveSettings(defaultConfigFile());
--}
--
--bool AppearanceGTK2::loadSettings(const QString& gtkrcFile)
--{
-- reset();
-- return loadSettingsPrivate(gtkrcFile);
--}
--
--bool AppearanceGTK2::saveSettings(const QString& gtkrcFile) const
--{
-- return saveSettingsPrivate(gtkrcFile);
--}
-diff --git a/src/appearancegtk2.h b/src/appearancegtk2.h
-index 7df49bf..8bc28ee 100644
---- a/src/appearancegtk2.h
-+++ b/src/appearancegtk2.h
-@@ -29,17 +29,10 @@ class AppearanceGTK2 : public AbstractAppearance
- {
- bool loadSettings(const QString& path) override;
- bool saveSettings(const QString& path) const override;
-- bool loadSettings() override;
-- bool saveSettings() const override;
-+ QString defaultConfigFile() const override;
- QStringList installedThemes() const override;
--
-+
- QString themesGtkrcFile(const QString& themeName) const;
--
--private:
-- void reset();
-- QString defaultConfigFile() const;
-- bool loadSettingsPrivate(const QString& path);
-- bool saveSettingsPrivate(const QString& path) const;
- };
-
- #endif // APPEARANCEGTK2_H
-diff --git a/src/appearancegtk3.cpp b/src/appearancegtk3.cpp
-index 7df48c3..fa1bde5 100644
---- a/src/appearancegtk3.cpp
-+++ b/src/appearancegtk3.cpp
-@@ -25,8 +25,6 @@
- #include <QDir>
- #include <QDebug>
- #include <QStandardPaths>
--#include <KSharedConfig>
--#include <KConfigGroup>
-
- QStringList AppearanceGTK3::installedThemes() const
- {
-@@ -53,65 +51,76 @@ QStringList AppearanceGTK3::installedThemes() const
- return themes;
- }
-
--bool AppearanceGTK3::saveSettings(const KSharedConfig::Ptr& file) const
--{
-- KConfigGroup group(file, "Settings");
--
-- group.writeEntry("gtk-font-name", m_settings["font"]);
-- group.writeEntry("gtk-theme-name", m_settings["theme"]);
-- group.writeEntry("gtk-icon-theme-name", m_settings["icon"]);
-- group.writeEntry("gtk-fallback-icon-theme", m_settings["icon_fallback"]);
-- group.writeEntry("gtk-cursor-theme-name", m_settings["cursor"]);
-- group.writeEntry("gtk-toolbar-style", m_settings["toolbar_style"]);
-- group.writeEntry("gtk-menu-images", m_settings["show_icons_menus"]);
-- group.writeEntry("gtk-button-images", m_settings["show_icons_buttons"]);
-- group.writeEntry("gtk-primary-button-warps-slider", m_settings["primary_button_warps_slider"]);
-- group.writeEntry("gtk-application-prefer-dark-theme", m_settings["application_prefer_dark_theme"]);
--
-- const bool sync = group.sync();
-- Q_ASSERT(sync);
-- return true;
--}
--
--bool AppearanceGTK3::loadSettings(const KSharedConfig::Ptr& file)
-+bool AppearanceGTK3::saveSettings(const QString& file) const
- {
-- KConfigGroup group(file, "Settings");
--
-- if (!file || !group.isValid()) {
-- qWarning() << "Cannot open the GTK3 config file" << file;
-+ //Opening GTK3 config file $ENV{XDG_CONFIG_HOME}/gtk-3.0/m_settings.ini
-+ QDir::home().mkpath(file.left(file.lastIndexOf('/'))); //we make sure the path exists
-+ QFile file_gtk3(file);
-+
-+ if(!file_gtk3.open(QIODevice::WriteOnly | QIODevice::Text)) {
-+ qWarning() << "Couldn't open GTK3 config file for writing at:" << file_gtk3.fileName();
- return false;
- }
-+ QTextStream flow3(&file_gtk3);
-+ flow3 << "[Settings]\n";
-+ flow3 << "gtk-font-name=" << m_settings["font"] << "\n";
-+ flow3 << "gtk-theme-name=" << m_settings["theme"] << "\n";
-+ flow3 << "gtk-icon-theme-name="<< m_settings["icon"] << "\n";
-+ flow3 << "gtk-fallback-icon-theme=" << m_settings["icon_fallback"] << "\n";
-+ flow3 << "gtk-cursor-theme-name=" << m_settings["cursor"] << "\n";
-+ flow3 << "gtk-toolbar-style=" << m_settings["toolbar_style"] << "\n";
-+ flow3 << "gtk-menu-images=" << m_settings["show_icons_menus"] << "\n";
-+ flow3 << "gtk-button-images=" << m_settings["show_icons_buttons"] << "\n";
-+ flow3 << "gtk-primary-button-warps-slider=" << m_settings["primary_button_warps_slider"] << "\n";
-+ flow3 << "gtk-application-prefer-dark-theme=" << m_settings["application_prefer_dark_theme"] << "\n";
-
-- m_settings = QMap<QString, QString> {
-- {"toolbar_style", "GTK_TOOLBAR_ICONS"},
-- {"show_icons_buttons", "0"},
-- {"show_icons_menus", "0"},
-- {"primary_button_warps_slider", "false"},
-- {"application_prefer_dark_theme", "false"}
-- };
--
-- m_settings["theme"] = group.readEntry("gtk-theme-name");
-- m_settings["icon"] = group.readEntry("gtk-icon-theme-name");
-- m_settings["icon_fallback"] = group.readEntry("gtk-fallback-icon-theme");
-- m_settings["cursor"] = group.readEntry("gtk-cursor-theme-name");
-- m_settings["font"] = group.readEntry("gtk-font-name");
-- m_settings["toolbar_style"] = group.readEntry("gtk-toolbar-style");
-- m_settings["show_icons_buttons"] = group.readEntry("gtk-button-images");
-- m_settings["show_icons_menus"] = group.readEntry("gtk-menu-images");
-- m_settings["primary_button_warps_slider"] = group.readEntry("gtk-primary-button-warps-slider");
-- m_settings["application_prefer_dark_theme"] = group.readEntry("gtk-application-prefer-dark-theme");
-- for(auto it = m_settings.begin(); it != m_settings.end(); ) {
-- if (it.value().isEmpty())
-- it = m_settings.erase(it);
-- else
-- ++it;
-- }
- return true;
- }
-
--QString AppearanceGTK3::configFileName() const
-+bool AppearanceGTK3::loadSettings(const QString& path)
- {
-- return QStringLiteral("gtk-3.0/settings.ini");
-+ QFile fileGtk3(path);
-+ bool canRead=fileGtk3.open(QIODevice::ReadOnly | QIODevice::Text);
-+
-+ if(canRead) {
-+ const QMap<QString, QString> foundSettings = readSettingsTuples(&fileGtk3);
-+
-+ m_settings = QMap<QString, QString> {
-+ {"toolbar_style", "GTK_TOOLBAR_ICONS"},
-+ {"show_icons_buttons", "0"},
-+ {"show_icons_menus", "0"},
-+ {"primary_button_warps_slider", "false"},
-+ {"application_prefer_dark_theme", "false"}
-+ };
-+
-+ for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) {
-+ if (it.key() == "gtk-theme-name")
-+ m_settings["theme"] = *it;
-+ else if (it.key() == "gtk-icon-theme-name")
-+ m_settings["icon"] = *it;
-+ else if (it.key() == "gtk-fallback-icon-theme")
-+ m_settings["icon_fallback"] = *it;
-+ else if (it.key() == "gtk-cursor-theme-name")
-+ m_settings["cursor"] = *it;
-+ else if (it.key() == "gtk-font-name")
-+ m_settings["font"] = *it;
-+ else if (it.key() == "gtk-toolbar-style")
-+ m_settings["toolbar_style"] = *it;
-+ else if (it.key() == "gtk-button-images")
-+ m_settings["show_icons_buttons"] = *it;
-+ else if (it.key() == "gtk-menu-images")
-+ m_settings["show_icons_menus"] = *it;
-+ else if (it.key() == "gtk-primary-button-warps-slider")
-+ m_settings["primary_button_warps_slider"] = *it;
-+ else if (it.key() == "gtk-application-prefer-dark-theme")
-+ m_settings["application_prefer_dark_theme"] = *it;
-+ else
-+ qWarning() << "unknown field" << it.key();
-+ }
-+ } else
-+ qWarning() << "Cannot open the GTK3 config file" << path;
-+
-+ return canRead;
- }
-
- QString AppearanceGTK3::defaultConfigFile() const
-@@ -120,7 +129,7 @@ QString AppearanceGTK3::defaultConfigFile() const
- if(root.isEmpty())
- root = QFileInfo(QDir::home(), ".config").absoluteFilePath();
-
-- return root + '/' + configFileName();
-+ return root+"/gtk-3.0/settings.ini";
- }
-
- bool AppearanceGTK3::getApplicationPreferDarkTheme() const
-@@ -132,29 +141,3 @@ void AppearanceGTK3::setApplicationPreferDarkTheme(const bool& enable)
- {
- m_settings["application_prefer_dark_theme"] = enable ? "true" : "false";
- }
--
--bool AppearanceGTK3::saveSettings(const QString& file) const
--{
-- auto cfg = KSharedConfig::openConfig(file);
-- return saveSettings(cfg);
--}
--
--bool AppearanceGTK3::loadSettings(const QString& path)
--{
-- auto cfg = KSharedConfig::openConfig(path);
-- return loadSettings(cfg);
--}
--
--bool AppearanceGTK3::loadSettings()
--{
-- auto cfg = KSharedConfig::openConfig(configFileName());
-- cfg->setReadDefaults(true);
-- return loadSettings(cfg);
--}
--
--bool AppearanceGTK3::saveSettings() const
--{
-- auto cfg = KSharedConfig::openConfig(configFileName());
-- cfg->setReadDefaults(true);
-- return saveSettings(cfg);
--}
-diff --git a/src/appearancegtk3.h b/src/appearancegtk3.h
-index 3ce5a05..d4562b1 100644
---- a/src/appearancegtk3.h
-+++ b/src/appearancegtk3.h
-@@ -23,7 +23,6 @@
- #ifndef APPEARANCEGTK3_H
- #define APPEARANCEGTK3_H
-
--#include <KSharedConfig>
- #include "abstractappearance.h"
-
- class AppearanceGTK3 : public AbstractAppearance
-@@ -31,18 +30,11 @@ class AppearanceGTK3 : public AbstractAppearance
-
- public:
- QStringList installedThemes() const override;
-- bool saveSettings() const override;
-- bool loadSettings() override;
- bool saveSettings(const QString& file) const override;
- bool loadSettings(const QString& path) override;
-+ QString defaultConfigFile() const override;
- bool getApplicationPreferDarkTheme() const;
- void setApplicationPreferDarkTheme(const bool& enable);
--
--private:
-- QString defaultConfigFile() const;
-- QString configFileName() const;
-- bool saveSettings(const KSharedConfig::Ptr& file) const;
-- bool loadSettings(const KSharedConfig::Ptr& file);
- };
-
- #endif // APPEARANCEGTK3_H
-diff --git a/src/appearencegtk.cpp b/src/appearencegtk.cpp
-index 95a6604..2e26a5a 100644
---- a/src/appearencegtk.cpp
-+++ b/src/appearencegtk.cpp
-@@ -64,7 +64,7 @@ bool AppearenceGTK::loadFileConfig()
- {
- bool correct = false;
- foreach(AbstractAppearance* app, m_app) {
-- bool c = app->loadSettings();
-+ bool c = app->loadSettings(app->defaultConfigFile());
- correct = correct || c;
- }
- // qDebug() << "loading..." << correct;
-@@ -75,7 +75,7 @@ bool AppearenceGTK::saveFileConfig()
- {
- bool correct = true;
- foreach(AbstractAppearance* app, m_app) {
-- bool c = app->saveSettings();
-+ bool c = app->saveSettings(app->defaultConfigFile());
- correct = correct && c;
- }
- // qDebug() << "saving..." << correct;
-diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
-index 151725d..05bf8f1 100644
---- a/tests/CMakeLists.txt
-+++ b/tests/CMakeLists.txt
-@@ -2,7 +2,7 @@ macro(add_kgc_test name)
- add_executable(${name} ${name}.cpp ${ARGV})
- add_test(${name} ${name})
- ecm_mark_as_test(${name})
-- target_link_libraries(${name} Qt5::Core Qt5::Gui Qt5::Test KF5::ConfigCore)
-+ target_link_libraries(${name} Qt5::Core Qt5::Gui Qt5::Test)
- target_include_directories(${name} PRIVATE ${CMAKE_BINARY_DIR})
- endmacro(add_kgc_test)
-
-diff --git a/tests/configsavetest.cpp b/tests/configsavetest.cpp
-index 1fe8f4f..d5d8460 100644
---- a/tests/configsavetest.cpp
-+++ b/tests/configsavetest.cpp
-@@ -9,40 +9,33 @@
-
- QTEST_GUILESS_MAIN(ConfigSaveTest);
-
--ConfigSaveTest::ConfigSaveTest()
--{
-- QStandardPaths::setTestModeEnabled(true);
--}
--
--static void fillValues(QScopedPointer<AbstractAppearance>& a)
-+void ConfigSaveTest::fillValues(AbstractAppearance* a)
- {
- a->setFont("a");
- a->setIcon("a");
- a->setTheme("a");
- a->setToolbarStyle("a");
- a->setIconFallback("a");
-- a->setCursor("a");
- a->setShowIconsInButtons(true);
- a->setShowIconsInMenus(true);
- a->setPrimaryButtonWarpsSlider(true);
-
-- auto a3 = dynamic_cast<AppearanceGTK3*>(a.data());
-+ auto a3 = dynamic_cast<AppearanceGTK3*>(a);
- if (a3) {
- a3->setApplicationPreferDarkTheme(false);
- }
- }
-
--void compareAppearances(QScopedPointer<AbstractAppearance>& reloaded, QScopedPointer<AbstractAppearance>& instance)
-+bool compareAppearances(AbstractAppearance* a, AbstractAppearance* b)
- {
-- QCOMPARE(reloaded->getFont(), instance->getFont());
-- QCOMPARE(reloaded->getIcon(), instance->getIcon());
-- QCOMPARE(reloaded->getTheme(), instance->getTheme());
-- QCOMPARE(reloaded->getCursor(), instance->getCursor());
-- QCOMPARE(reloaded->getToolbarStyle(), instance->getToolbarStyle());
-- QCOMPARE(reloaded->getIconFallback(), instance->getIconFallback());
-- QCOMPARE(reloaded->getShowIconsInButtons(), instance->getShowIconsInButtons());
-- QCOMPARE(reloaded->getShowIconsInMenus(), instance->getShowIconsInMenus());
-- QCOMPARE(reloaded->getPrimaryButtonWarpsSlider(), instance->getPrimaryButtonWarpsSlider());
-+ return a->getFont() == b->getFont()
-+ && a->getIcon() == b->getIcon()
-+ && a->getTheme() == b->getTheme()
-+ && a->getToolbarStyle() == b->getToolbarStyle()
-+ && a->getIconFallback() == b->getIconFallback()
-+ && a->getShowIconsInButtons() == b->getShowIconsInButtons()
-+ && a->getShowIconsInMenus() == b->getShowIconsInMenus()
-+ && a->getPrimaryButtonWarpsSlider() == b->getPrimaryButtonWarpsSlider();
- }
-
- QByteArray readFile(const QString& path)
-@@ -53,35 +46,23 @@ QByteArray readFile(const QString& path)
- return f.readAll();
- }
-
--void ConfigSaveTest::testGtk2()
-+void ConfigSaveTest::testOpen()
- {
-- const QString pathA = QDir::current().absoluteFilePath("test-gtk2")
-- , pathB = QDir::current().absoluteFilePath("testB-gtk2");
--
-- QScopedPointer<AbstractAppearance> instance(new AppearanceGTK2);
-- fillValues(instance);
-- QVERIFY(instance->saveSettings(pathA));
--
-- QScopedPointer<AbstractAppearance> reloaded(new AppearanceGTK2);
-- QVERIFY(reloaded->loadSettings(pathA));
-- compareAppearances(reloaded, instance);
-- QVERIFY(reloaded->saveSettings(pathB));
-- QCOMPARE(readFile(pathA), readFile(pathB));
--}
--
--void ConfigSaveTest::testGtk3()
--{
-- QScopedPointer<AbstractAppearance> instance(new AppearanceGTK3);
-- fillValues(instance);
-- const QString pathA = QDir::current().absoluteFilePath("test-gtk3")
-- , pathB = QDir::current().absoluteFilePath("testB-gtk3");
-- QVERIFY(instance->saveSettings(pathA));
--
-- QScopedPointer<AbstractAppearance> reloaded(new AppearanceGTK3);
-- QVERIFY(QFile::exists(pathA));
-- QVERIFY(reloaded->loadSettings(pathA));
-- compareAppearances(reloaded, instance);
-- QVERIFY(reloaded->saveSettings(pathB));
-+ QVector<AbstractAppearance*> instances;
-+ instances << new AppearanceGTK2 << new AppearanceGTK3;
-+ fillValues(instances[0]);
-+ fillValues(instances[1]);
-+ QVERIFY(instances[0]->saveSettings("test-gtk2"));
-+ QVERIFY(instances[1]->saveSettings("test-gtk3"));
-
-- QCOMPARE(readFile(pathA), readFile(pathB));
-+ QVector<AbstractAppearance*> reloaded;
-+ reloaded << new AppearanceGTK2 << new AppearanceGTK3;
-+ QVERIFY(reloaded[0]->loadSettings("test-gtk2"));
-+ QVERIFY(reloaded[1]->loadSettings("test-gtk3"));
-+ QVERIFY(compareAppearances(reloaded[0], instances[0]));
-+ QVERIFY(compareAppearances(reloaded[1], instances[1]));
-+ QVERIFY(reloaded[0]->saveSettings("testB-gtk2"));
-+ QVERIFY(reloaded[1]->saveSettings("testB-gtk3"));
-+ QCOMPARE(readFile("test-gtk2"), readFile("testB-gtk2"));
-+ QCOMPARE(readFile("test-gtk3"), readFile("testB-gtk3"));
- }
-diff --git a/tests/configsavetest.h b/tests/configsavetest.h
-index 342b408..39fb4c2 100644
---- a/tests/configsavetest.h
-+++ b/tests/configsavetest.h
-@@ -11,11 +11,11 @@ class AbstractAppearance;
- class ConfigSaveTest : public QObject
- {
- Q_OBJECT
--public:
-- ConfigSaveTest();
- private slots:
-- void testGtk2();
-- void testGtk3();
-+ void testOpen();
-+
-+private:
-+ void fillValues(AbstractAppearance* a);
- };
-
- #endif // CONFIGSAVETEST_H
---
-cgit v0.11.2
-
diff --git a/kde/patch/kde-runtime.patch b/kde/patch/kde-runtime.patch
index c3b6101..3201d76 100644
--- a/kde/patch/kde-runtime.patch
+++ b/kde/patch/kde-runtime.patch
@@ -1,10 +1,2 @@
-# Fix KDE bug 324470 - solved in KDE 4.11.2.
-# - Minimize/maximize by clicking taskbar entries requires double click.
-#cat $CWD/patch/kde-runtime/kde-runtime.kdebug324470.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
# Fix compilation against NetworkManager 1.0.6:
cat $CWD/patch/kde-runtime/kde-runtime_networkmanager.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
-## Fix compilation against gpgme 1.7+:
-#cat $CWD/patch/kde-runtime/kde-runtime_gpgme.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kde-runtime/kde-runtime.kdebug324470.diff b/kde/patch/kde-runtime/kde-runtime.kdebug324470.diff
deleted file mode 100644
index 4269df8..0000000
--- a/kde/patch/kde-runtime/kde-runtime.kdebug324470.diff
+++ /dev/null
@@ -1,49 +0,0 @@
-commit be1a5d484c70f4f6a383150810afbfbb367db2ac
-Author: Eike Hein <hein@kde.org>
-Date: Tue Sep 3 20:29:23 2013 +0200
-
- Discard the recorded events in the item-local handlers.
-
- Solves problems with identical events being ignored due to
- QGraphicsView's reuse of QGraphicsSceneMouseEvent instances.
-
- CCMAIL:rdieter@fedoraproject.org
- BUG:324470
- BUG:324471
-
-diff --git a/plasma/declarativeimports/qtextracomponents/mouseeventlistener.cpp b/plasma/declarativeimports/qtextracomponents/mouseeventlistener.cpp
-index b534845..36530e0 100644
---- a/plasma/declarativeimports/qtextracomponents/mouseeventlistener.cpp
-+++ b/plasma/declarativeimports/qtextracomponents/mouseeventlistener.cpp
-@@ -90,6 +90,7 @@ bool MouseEventListener::containsMouse() const
- void MouseEventListener::mousePressEvent(QGraphicsSceneMouseEvent *me)
- {
- if (m_lastEvent == me) {
-+ m_lastEvent = 0;
- return;
- }
-
-@@ -112,6 +113,7 @@ void MouseEventListener::mousePressEvent(QGraphicsSceneMouseEvent *me)
- void MouseEventListener::mouseMoveEvent(QGraphicsSceneMouseEvent *me)
- {
- if (m_lastEvent == me) {
-+ m_lastEvent = 0;
- return;
- }
-
-@@ -122,6 +124,7 @@ void MouseEventListener::mouseMoveEvent(QGraphicsSceneMouseEvent *me)
- void MouseEventListener::mouseReleaseEvent(QGraphicsSceneMouseEvent *me)
- {
- if (m_lastEvent == me) {
-+ m_lastEvent = 0;
- return;
- }
-
-@@ -138,6 +141,7 @@ void MouseEventListener::mouseReleaseEvent(QGraphicsSceneMouseEvent *me)
- void MouseEventListener::wheelEvent(QGraphicsSceneWheelEvent *we)
- {
- if (m_lastEvent == we) {
-+ m_lastEvent = 0;
- return;
- }
-
diff --git a/kde/patch/kde-runtime/kde-runtime_gpgme.patch b/kde/patch/kde-runtime/kde-runtime_gpgme.patch
deleted file mode 100644
index b1703ed..0000000
--- a/kde/patch/kde-runtime/kde-runtime_gpgme.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-commit 1b80d1d0b961f8e28186928ede2b87af292c3de4
-Author: Antonio Rojas <arojas@archlinux.org>
-Date: Thu Nov 10 16:58:10 2016 +0100
-
- Allow building kwalletd against gpgme++ from gpgme 1.7
-
- REVIEW: 129339
-
-diff --git a/kwalletd/CMakeLists.txt b/kwalletd/CMakeLists.txt
-index 73aec82..ae8c745 100644
---- a/kwalletd/CMakeLists.txt
-+++ b/kwalletd/CMakeLists.txt
-@@ -5,11 +5,18 @@ find_package(Gpgme) # Called by FindQGpgme, but since we call some gpgme
- # functions ourselves we need to link against it directly.
- find_package(QGpgme) # provided by kdepimlibs
-
--if (GPGME_FOUND AND QGPGME_FOUND)
-+if (NOT QGPGME_FOUND)
-+find_package(Gpgmepp) # provided by gpgme 1.7
-+endif (NOT QGPGME_FOUND)
-+
-+if ((GPGME_FOUND AND QGPGME_FOUND) OR Gpgmepp_FOUND)
- add_definitions(-DHAVE_QGPGME)
-- include_directories(${GPGME_INCLUDES} ${QGPGME_INCLUDE_DIR})
-+ include_directories(${GPGME_INCLUDES})
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
--endif(GPGME_FOUND AND QGPGME_FOUND)
-+endif((GPGME_FOUND AND QGPGME_FOUND) OR Gpgmepp_FOUND)
-+if (GPGME_FOUND AND QGPGME_FOUND)
-+ include_directories(${QGPGME_INCLUDE_DIR})
-+endif (GPGME_FOUND AND QGPGME_FOUND)
-
- ########### build backends #########
- add_subdirectory(backend)
-@@ -37,7 +44,7 @@ kde4_add_ui_files(kwalletd_KDEINIT_SRCS
- kwalletwizardpagepassword.ui
- )
-
--if (GPGME_FOUND AND QGPGME_FOUND)
-+if ((GPGME_FOUND AND QGPGME_FOUND) OR Gpgmepp_FOUND)
- set(kwalletd_KDEINIT_SRCS
- ${kwalletd_KDEINIT_SRCS}
- knewwalletdialog.cpp
-@@ -48,7 +55,7 @@ if (GPGME_FOUND AND QGPGME_FOUND)
- knewwalletdialogintro.ui
- knewwalletdialoggpg.ui
- )
--endif(GPGME_FOUND AND QGPGME_FOUND)
-+endif((GPGME_FOUND AND QGPGME_FOUND) OR Gpgmepp_FOUND)
-
- find_file(kwallet_xml org.kde.KWallet.xml HINTS ${KDE4_DBUS_INTERFACES_DIR} )
-
-@@ -57,8 +64,12 @@ qt4_add_dbus_adaptor( kwalletd_KDEINIT_SRCS ${kwallet_xml} kwalletd.h KWalletD )
- kde4_add_kdeinit_executable( kwalletd NOGUI ${kwalletd_KDEINIT_SRCS} )
-
- target_link_libraries(kdeinit_kwalletd ${KDE4_KDEUI_LIBS} kwalletbackend )
--if (GPGME_FOUND AND QGPGME_FOUND)
-- target_link_libraries(kdeinit_kwalletd ${QGPGME_LIBRARIES} )
-+if(GPGME_FOUND AND QGPGME_FOUND)
-+target_link_libraries(kdeinit_kwalletd ${QGPGME_LIBRARIES} )
-+else(GPGME_FOUND AND QGPGME_FOUND)
-+if(Gpgmepp_FOUND)
-+target_link_libraries(kdeinit_kwalletd Gpgmepp)
-+endif(Gpgmepp_FOUND)
- endif(GPGME_FOUND AND QGPGME_FOUND)
-
- install(TARGETS kdeinit_kwalletd ${INSTALL_TARGETS_DEFAULT_ARGS})
-@@ -73,4 +84,4 @@ install( FILES kwalletd.notifyrc DESTINATION ${DATA_INSTALL_DIR}/kwalletd )
- install( FILES kwallet-4.13.upd DESTINATION ${DATA_INSTALL_DIR}/kconf_update)
-
- add_subdirectory(tests)
--add_subdirectory(autotests)
-\ No newline at end of file
-+add_subdirectory(autotests)
-diff --git a/kwalletd/backend/CMakeLists.txt b/kwalletd/backend/CMakeLists.txt
-index 4db348f..7347b12 100644
---- a/kwalletd/backend/CMakeLists.txt
-+++ b/kwalletd/backend/CMakeLists.txt
-@@ -22,6 +22,10 @@ kde4_add_library(kwalletbackend SHARED ${kwalletbackend_LIB_SRCS})
- target_link_libraries(kwalletbackend ${KDE4_KDEUI_LIBS} ${LIBGCRYPT_LIBRARIES})
- if(QGPGME_FOUND)
- target_link_libraries(kwalletbackend ${QGPGME_LIBRARIES} )
-+else(QGPGME_FOUND)
-+if(Gpgmepp_FOUND)
-+target_link_libraries(kwalletbackend Gpgmepp)
-+endif(Gpgmepp_FOUND)
- endif(QGPGME_FOUND)
-
- # link with advapi32 on windows
-diff --git a/kwalletd/backend/backendpersisthandler.cpp b/kwalletd/backend/backendpersisthandler.cpp
-index b7f63f8..9608af0 100644
---- a/kwalletd/backend/backendpersisthandler.cpp
-+++ b/kwalletd/backend/backendpersisthandler.cpp
-@@ -33,6 +33,7 @@
- #include <gpgme++/data.h>
- #include <gpgme++/encryptionresult.h>
- #include <gpgme++/decryptionresult.h>
-+#include <boost/shared_ptr.hpp>
- #endif
- #include "backendpersisthandler.h"
- #include "kwalletbackend.h"
-diff --git a/kwalletd/kwalletwizard.cpp b/kwalletd/kwalletwizard.cpp
-index 78de78d..821b666 100644
---- a/kwalletd/kwalletwizard.cpp
-+++ b/kwalletd/kwalletwizard.cpp
-@@ -40,6 +40,7 @@
- #include <kdebug.h>
- #include <kmessagebox.h>
- #include <gpgme.h>
-+#include <boost/shared_ptr.hpp>
- #endif
-
- class PageIntro : public QWizardPage
-commit cf28801cd34730da07a2c01704ca3114630f4fe7
-Author: Antonio Rojas <arojas@archlinux.org>
-Date: Thu Nov 10 18:54:41 2016 +0100
-
- Compiling against gmgpe 1.7 requires c++11
-
-diff --git a/kwalletd/CMakeLists.txt b/kwalletd/CMakeLists.txt
-index ae8c745..88d944e 100644
---- a/kwalletd/CMakeLists.txt
-+++ b/kwalletd/CMakeLists.txt
-@@ -17,6 +17,9 @@ endif((GPGME_FOUND AND QGPGME_FOUND) OR Gpgmepp_FOUND)
- if (GPGME_FOUND AND QGPGME_FOUND)
- include_directories(${QGPGME_INCLUDE_DIR})
- endif (GPGME_FOUND AND QGPGME_FOUND)
-+if (Gpgmepp_FOUND)
-+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
-+endif (Gpgmepp_FOUND)
-
- ########### build backends #########
- add_subdirectory(backend)
diff --git a/kde/patch/kde-workspace.patch b/kde/patch/kde-workspace.patch
index 4a355d1..bebecfe 100644
--- a/kde/patch/kde-workspace.patch
+++ b/kde/patch/kde-workspace.patch
@@ -4,9 +4,5 @@ cat $CWD/patch/kde-workspace/kde-workspace.kdm.server.timeout.diff | patch -p1 -
# Always show 'remaining time' in the popup of the battery plasmoid:
cat $CWD/patch/kde-workspace/kde-workspace.batteryapplet.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-# Fix crash when DesktopNames isn't set (fixed in 4.11.10):
-#cat $CWD/patch/kde-workspace/kde-workspace.desktopnames.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
# In Plasma 5 we do not need the Plasma 4 core apps, they conflict.
cat $CWD/patch/kde-workspace/kde-workspace.no.plasma4.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kde-workspace/kde-workspace.desktopnames.diff b/kde/patch/kde-workspace/kde-workspace.desktopnames.diff
deleted file mode 100644
index 59aef1c..0000000
--- a/kde/patch/kde-workspace/kde-workspace.desktopnames.diff
+++ /dev/null
@@ -1,34 +0,0 @@
-commit e1724800ecf3c6a7035dfa7bcaa50b2a8f48688f
-Author: David Faure <faure@kde.org>
-Date: Fri May 2 10:26:38 2014 +0200
-
- Fix crash when DesktopNames isn't set
-
- BUG: 334159
- FIXED-IN: 4.11.10
-
-diff --git a/kdm/backend/client.c b/kdm/backend/client.c
-index 335cc3e..a2d06c2 100644
---- a/kdm/backend/client.c
-+++ b/kdm/backend/client.c
-@@ -1810,12 +1810,14 @@ startClient(volatile int *pid)
- !(sessargs = iniEntry(str, "Desktop Entry", "Exec", 0)))
- sessargs = "";
- buf = iniEntry(str, "Desktop Entry", "DesktopNames", 0);
-- for (buf2 = buf; *buf2; ++buf2) {
-- if (*buf2 == ';')
-- *buf2 = ':';
-+ if (buf) {
-+ for (buf2 = buf; *buf2; ++buf2) {
-+ if (*buf2 == ';')
-+ *buf2 = ':';
-+ }
-+ userEnviron = setEnv(userEnviron, "XDG_CURRENT_DESKTOP", buf);
-+ free(buf);
- }
-- userEnviron = setEnv(userEnviron, "XDG_CURRENT_DESKTOP", buf);
-- free(buf);
- free(str);
- free(fname);
- goto gotit;
-
diff --git a/kde/patch/kdeconnect-kde.patch b/kde/patch/kdeconnect-kde.patch
index 47f98f5..122440d 100644
--- a/kde/patch/kdeconnect-kde.patch
+++ b/kde/patch/kdeconnect-kde.patch
@@ -1,3 +1,2 @@
# Fix remote device browsing with openssh 8.2:
cat $CWD/patch/kdeconnect-kde/kdeconnect-kde_openssh-8.2.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
diff --git a/kde/patch/kdelibs.patch b/kde/patch/kdelibs.patch
index 44e201e..4f1fc45 100644
--- a/kde/patch/kdelibs.patch
+++ b/kde/patch/kdelibs.patch
@@ -25,3 +25,6 @@ cat $CWD/patch/kdelibs/kdelibs.2c3762feddf7e66cf6b64d9058f625a715694a00.patch |
# Support TLS v1.1 and TLS v1.2:
cat $CWD/patch/kdelibs/kde4libs-4.14.26.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
+
+# Fix for the relocated grantlee-qt4 includes:
+cat $CWD/patch/kdelibs/kdelibs.grantlee-qt4.include.path.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
diff --git a/kde/patch/kdelibs/fixbic-4.14.6.patch b/kde/patch/kdelibs/fixbic-4.14.6.patch
deleted file mode 100644
index 585ce51..0000000
--- a/kde/patch/kdelibs/fixbic-4.14.6.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-diff --git a/khtml/dom/dom_string.h b/khtml/dom/dom_string.h
-index 087f697..b269213 100644
---- a/khtml/dom/dom_string.h
-+++ b/khtml/dom/dom_string.h
-@@ -124,10 +124,23 @@ public:
- bool endsWith(const DOMString& str) const;
- bool startsWith(const DOMString& str) const;
-
-- // http://www.w3.org/TR/html/infrastructure.html#urls
-+ /**
-+ * Return a parsed url.
-+ * Used to parse SRC url attribute,
-+ * see http://www.w3.org/TR/html/infrastructure.html#urls
-+ *
-+ * @since 4.14.6
-+ */
- DOMString parsedUrl() const;
-
- /**
-+ * @deprecated, use parsedUrl()
-+ */
-+#ifndef KDE_NO_DEPRECATED
-+ KDE_DEPRECATED DOMString trimSpaces() const;
-+#endif
-+
-+ /**
- * @internal get a handle to the imlementation of the DOMString
- * Use at own risk!!!
- */
-diff --git a/khtml/dom/dom_string.cpp b/khtml/dom/dom_string.cpp
-index a3c4abd..4da676b 100644
---- a/khtml/dom/dom_string.cpp
-+++ b/khtml/dom/dom_string.cpp
-@@ -336,6 +336,13 @@ DOMString DOMString::parsedUrl() const
- return out;
- }
-
-+#ifndef KDE_NO_DEPRECATED
-+DOMString DOMString::trimSpaces() const
-+{
-+ return parsedUrl();
-+}
-+#endif
-+
- // ------------------------------------------------------------------------
-
- bool DOM::strcasecmp( const DOMString &as, const DOMString &bs )
diff --git a/kde/patch/kdelibs/kdelibs.grantlee-qt4.include.path.patch b/kde/patch/kdelibs/kdelibs.grantlee-qt4.include.path.patch
new file mode 100644
index 0000000..fd7375f
--- /dev/null
+++ b/kde/patch/kdelibs/kdelibs.grantlee-qt4.include.path.patch
@@ -0,0 +1,11 @@
+--- ./kdeui/tests/proxymodeltestsuite/modeleventlogger.cpp.orig 2017-11-04 20:51:22.000000000 -0500
++++ ./kdeui/tests/proxymodeltestsuite/modeleventlogger.cpp 2020-07-12 14:19:32.175099684 -0500
+@@ -30,7 +30,7 @@
+ #include <QDebug>
+
+ #ifdef Grantlee_FOUND
+-#include <grantlee_core.h>
++#include <grantlee-qt4/grantlee_core.h>
+ #include "grantlee_paths.h"
+
+ /**
diff --git a/kde/patch/kdelibs4support.patch b/kde/patch/kdelibs4support.patch
index 8e9fe7b..7d6626e 100644
--- a/kde/patch/kdelibs4support.patch
+++ b/kde/patch/kdelibs4support.patch
@@ -1,6 +1,2 @@
-# Make FindGettext compatible with the one provided by CMake:
-# Fixed in 5.1.0.
-#cat $CWD/patch/kdelibs4support/update-FindGettext.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
-
# Allow cmake to find our doctools:
cat $CWD/patch/kdelibs4support/FindDocBookXML4.cmake.diff | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
diff --git a/kde/patch/kdelibs4support/update-FindGettext.patch b/kde/patch/kdelibs4support/update-FindGettext.patch
deleted file mode 100644
index 1b75cd8..0000000
--- a/kde/patch/kdelibs4support/update-FindGettext.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: Alex Merry <alex.merry@kde.org>
-Date: Fri, 04 Jul 2014 10:10:27 +0000
-Subject: Make FindGettext compatible with the one provided by CMake
-X-Git-Url: http://quickgit.kde.org/?p=kdelibs4support.git&a=commitdiff&h=581ee6b370d8b5627196c8d6d8760d3655f6daea
----
-Make FindGettext compatible with the one provided by CMake
-
-This version will accept the old GETTEXT_PROCESS_PO_FILES() syntax (no
-PO_FILES argument), but will also accept the new syntax required by
-CMake's version of this file. It will also warn when PO_FILES is not
-given.
-
-REVIEW: 119111
----
-
-
---- a/cmake/modules/FindGettext.cmake
-+++ b/cmake/modules/FindGettext.cmake
-@@ -212,7 +212,16 @@
- LIST(REMOVE_AT _args 0 1)
- ENDIF("${_tmp}" STREQUAL "INSTALL_DESTINATION")
-
--# message(STATUS "2 all ${_addToAll} dest ${_installDest} args: ${_args}")
-+ LIST(GET _args 0 _tmp)
-+ IF("${_tmp}" STREQUAL "PO_FILES")