File indexing completed on 2024-05-12 15:55:35
0001 // SPDX-FileCopyrightText: 2003 Lukáš Tinkl <lukas@kde.org> 0002 // SPDX-FileCopyrightText: 2003-2007 Dirk Mueller <mueller@kde.org> 0003 // SPDX-FileCopyrightText: 2003-2005 Stephan Binner <binner@kde.org> 0004 // SPDX-FileCopyrightText: 2003-2022 Jesper K. Pedersen <jesper.pedersen@kdab.com> 0005 // SPDX-FileCopyrightText: 2006-2008 Tuomas Suutari <tuomas@nepnep.net> 0006 // SPDX-FileCopyrightText: 2007 Rafael Fernández López <ereslibre@kde.org> 0007 // SPDX-FileCopyrightText: 2007-2009 Laurent Montel <montel@kde.org> 0008 // SPDX-FileCopyrightText: 2007-2010 Jan Kundrát <jkt@flaska.net> 0009 // SPDX-FileCopyrightText: 2008 David Faure <faure@kde.org> 0010 // SPDX-FileCopyrightText: 2008 Henner Zeller <h.zeller@acm.org> 0011 // SPDX-FileCopyrightText: 2009-2012 Miika Turkia <miika.turkia@gmail.com> 0012 // SPDX-FileCopyrightText: 2010 Pino Toscano <pino@kde.org> 0013 // SPDX-FileCopyrightText: 2010 Wes Hardaker <kpa@capturedonearth.com> 0014 // SPDX-FileCopyrightText: 2011 Andreas Neustifter <andreas.neustifter@gmail.com> 0015 // SPDX-FileCopyrightText: 2012-2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0016 // SPDX-FileCopyrightText: 2014-2022 Tobias Leupold <tl@stonemx.de> 0017 // SPDX-FileCopyrightText: 2018 Antoni Bella Pérez <antonibella5@yahoo.com> 0018 // SPDX-FileCopyrightText: 2019 Robert Krawitz <rlk@alum.mit.edu> 0019 // 0020 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0021 0022 #include "SettingsData.h" 0023 0024 #include "Logging.h" 0025 0026 #include <KConfig> 0027 #include <KConfigGroup> 0028 #include <KLocalizedString> 0029 #include <KSharedConfig> 0030 #include <QStringList> 0031 #include <QThread> 0032 #include <type_traits> 0033 0034 namespace 0035 { 0036 // when used from an application with different component name 0037 // (e.g. kpa-thumbnailtool), we need to explicitly set the component name: 0038 const QString configFile = QString::fromLatin1("kphotoalbumrc"); 0039 } 0040 #define STR(x) QString::fromLatin1(x) 0041 0042 #define cfgValue(GROUP, OPTION, DEFAULT) \ 0043 KSharedConfig::openConfig(configFile)->group(GROUP).readEntry(OPTION, DEFAULT) 0044 0045 #define setValue(GROUP, OPTION, VALUE) \ 0046 do { \ 0047 KConfigGroup group = KSharedConfig::openConfig(configFile)->group(GROUP); \ 0048 group.writeEntry(OPTION, VALUE); \ 0049 group.sync(); \ 0050 } while (0) 0051 0052 #define getValueFunc_(TYPE, FUNC, GROUP, OPTION, DEFAULT) \ 0053 TYPE SettingsData::FUNC() const \ 0054 { \ 0055 return static_cast<TYPE>(cfgValue(GROUP, OPTION, DEFAULT)); \ 0056 } 0057 0058 #define setValueFunc_(FUNC, TYPE, GROUP, OPTION, VALUE) \ 0059 void SettingsData::FUNC(const TYPE v) \ 0060 { \ 0061 setValue(GROUP, OPTION, VALUE); \ 0062 } 0063 0064 #define getValueFunc(TYPE, FUNC, GROUP, DEFAULT) getValueFunc_(TYPE, FUNC, #GROUP, #FUNC, DEFAULT) 0065 #define setValueFunc(FUNC, TYPE, GROUP, OPTION) setValueFunc_(FUNC, TYPE, #GROUP, #OPTION, v) 0066 0067 // TODO(mfwitten): document parameters. 0068 #define property_(GET_TYPE, GET_FUNC, GET_VALUE, SET_FUNC, SET_TYPE, SET_VALUE, GROUP, OPTION, GET_DEFAULT_1, GET_DEFAULT_2, GET_DEFAULT_2_TYPE) \ 0069 GET_TYPE SettingsData::GET_FUNC() const \ 0070 { \ 0071 const KConfigGroup g = KSharedConfig::openConfig(configFile)->group(GROUP); \ 0072 \ 0073 if (!g.hasKey(OPTION)) \ 0074 return GET_DEFAULT_1; \ 0075 \ 0076 GET_DEFAULT_2_TYPE v = g.readEntry(OPTION, static_cast<GET_DEFAULT_2_TYPE>(GET_DEFAULT_2)); \ 0077 return static_cast<GET_TYPE>(GET_VALUE); \ 0078 } \ 0079 setValueFunc_(SET_FUNC, SET_TYPE, GROUP, OPTION, SET_VALUE) 0080 0081 #define property(GET_TYPE, GET_FUNC, SET_FUNC, SET_TYPE, SET_VALUE, GROUP, OPTION, GET_DEFAULT) \ 0082 getValueFunc_(GET_TYPE, GET_FUNC, GROUP, OPTION, GET_DEFAULT) \ 0083 setValueFunc_(SET_FUNC, SET_TYPE, GROUP, OPTION, SET_VALUE) 0084 0085 #define property_copy(GET_FUNC, SET_FUNC, TYPE, GROUP, GET_DEFAULT) \ 0086 property(TYPE, GET_FUNC, SET_FUNC, TYPE, v, #GROUP, #GET_FUNC, GET_DEFAULT) 0087 0088 #define property_ref_(GET_FUNC, SET_FUNC, TYPE, GROUP, GET_DEFAULT) \ 0089 property(TYPE, GET_FUNC, SET_FUNC, TYPE &, v, GROUP, #GET_FUNC, GET_DEFAULT) 0090 0091 #define property_ref(GET_FUNC, SET_FUNC, TYPE, GROUP, GET_DEFAULT) \ 0092 property(TYPE, GET_FUNC, SET_FUNC, TYPE &, v, #GROUP, #GET_FUNC, GET_DEFAULT) 0093 0094 #define property_enum(GET_FUNC, SET_FUNC, TYPE, GROUP, GET_DEFAULT) \ 0095 property(TYPE, GET_FUNC, SET_FUNC, TYPE, static_cast<int>(v), #GROUP, #GET_FUNC, static_cast<int>(GET_DEFAULT)) 0096 0097 #define property_sset(GET_FUNC, SET_FUNC, GROUP, GET_DEFAULT) \ 0098 property_(StringSet, GET_FUNC, (StringSet { v.begin(), v.end() }), SET_FUNC, StringSet &, (QStringList { v.begin(), v.end() }), #GROUP, #GET_FUNC, GET_DEFAULT, QStringList(), QStringList) 0099 0100 /** 0101 * smoothScale() is called from the image loading thread, therefore we need 0102 * to cache it this way, rather than going to KConfig. 0103 */ 0104 static bool _smoothScale = true; 0105 0106 using namespace Settings; 0107 0108 const WindowType Settings::MainWindow = "MainWindow"; 0109 const WindowType Settings::AnnotationDialog = "AnnotationDialog"; 0110 0111 SettingsData *SettingsData::s_instance = nullptr; 0112 0113 SettingsData *SettingsData::instance() 0114 { 0115 if (!s_instance) 0116 qFatal("SettingsData: instance called before loading a setup!"); 0117 0118 return s_instance; 0119 } 0120 0121 bool SettingsData::ready() 0122 { 0123 return s_instance; 0124 } 0125 0126 void SettingsData::setup(const QString &imageDirectory, DB::UIDelegate &delegate) 0127 { 0128 if (!s_instance) 0129 s_instance = new SettingsData(imageDirectory, delegate); 0130 } 0131 0132 SettingsData::SettingsData(const QString &imageDirectory, DB::UIDelegate &delegate) 0133 : m_trustTimeStamps(false) 0134 , m_hasAskedAboutTimeStamps(false) 0135 , m_UI(delegate) 0136 { 0137 m_hasAskedAboutTimeStamps = false; 0138 0139 const QString s = STR("/"); 0140 m_imageDirectory = imageDirectory.endsWith(s) ? imageDirectory : imageDirectory + s; 0141 0142 _smoothScale = cfgValue("Viewer", "smoothScale", true); 0143 0144 // Split the list of Exif comments that should be stripped automatically to a list 0145 0146 QStringList commentsToStrip = cfgValue("General", "commentsToStrip", QString::fromLatin1("Exif_JPEG_PICTURE-,-OLYMPUS DIGITAL CAMERA-,-JENOPTIK DIGITAL CAMERA-,-")).split(QString::fromLatin1("-,-"), Qt::SkipEmptyParts); 0147 for (QString &comment : commentsToStrip) 0148 comment.replace(QString::fromLatin1(",,"), QString::fromLatin1(",")); 0149 0150 m_EXIFCommentsToStrip = commentsToStrip; 0151 } 0152 0153 ///////////////// 0154 //// General //// 0155 ///////////////// 0156 0157 // clang-format off 0158 property_copy(useEXIFRotate, setUseEXIFRotate, bool, General, true) 0159 property_copy(useEXIFComments, setUseEXIFComments, bool, General, true) 0160 property_copy(stripEXIFComments, setStripEXIFComments, bool, General, true) 0161 property_copy(commentsToStrip, setCommentsToStrip, QString, General, "" /* see constructor */) 0162 property_copy(searchForImagesOnStart, setSearchForImagesOnStart, bool, General, true) 0163 property_copy(ignoreFileExtension, setIgnoreFileExtension, bool, General, false) 0164 property_copy(skipSymlinks, setSkipSymlinks, bool, General, false) 0165 property_copy(skipRawIfOtherMatches, setSkipRawIfOtherMatches, bool, General, false) 0166 property_copy(useRawThumbnail, setUseRawThumbnail, bool, General, true) 0167 property_copy(useRawThumbnailSize, setUseRawThumbnailSize, QSize, General, QSize(1024, 768)) 0168 property_copy(useCompressedIndexXML, setUseCompressedIndexXML, bool, General, true) 0169 property_copy(compressBackup, setCompressBackup, bool, General, true) 0170 property_copy(showSplashScreen, setShowSplashScreen, bool, General, true) 0171 property_copy(showHistogram, setShowHistogram, bool, General, true) 0172 property_copy(autoSave, setAutoSave, int, General, 5) 0173 property_copy(backupCount, setBackupCount, int, General, 5) 0174 property_enum(tTimeStamps, setTTimeStamps, TimeStampTrust, General, Always) 0175 property_copy(excludeDirectories, setExcludeDirectories, QString, General, QString::fromLatin1("xml,ThumbNails,.thumbs")) 0176 property_copy(browserUseNaturalSortOrder, setBrowserUseNaturalSortOrder, bool, General, true); 0177 #ifdef KPA_ENABLE_REMOTECONTROL 0178 property_copy(recentAndroidAddress, setRecentAndroidAddress, QString, General, QString()) 0179 property_copy(listenForAndroidDevicesOnStartup, setListenForAndroidDevicesOnStartup, bool, General, false) 0180 #endif 0181 getValueFunc(QString, colorScheme, General, QString()) 0182 void SettingsData::setColorScheme(const QString &path) { 0183 if (path != colorScheme()) 0184 { 0185 setValue("General", "colorScheme", path); 0186 Q_EMIT colorSchemeChanged(); 0187 } 0188 } 0189 0190 getValueFunc(QSize, histogramSize, General, QSize(15, 30)) 0191 getValueFunc(ViewSortType, viewSortType, General, static_cast<int>(SortLastUse)) 0192 getValueFunc(AnnotationDialog::MatchType, matchType, General, static_cast<int>(AnnotationDialog::MatchFromWordStart)) 0193 getValueFunc(bool, histogramUseLinearScale, General, false) 0194 0195 // clang-format on 0196 void SettingsData::setHistogramUseLinearScale(const bool useLinearScale) 0197 { 0198 if (useLinearScale == histogramUseLinearScale()) 0199 return; 0200 0201 setValue("General", "histogramUseLinearScale", useLinearScale); 0202 Q_EMIT histogramScaleChanged(); 0203 } 0204 0205 void SettingsData::setHistogramSize(const QSize &size) 0206 { 0207 if (size == histogramSize()) 0208 return; 0209 0210 setValue("General", "histogramSize", size); 0211 Q_EMIT histogramSizeChanged(size); 0212 } 0213 0214 void SettingsData::setViewSortType(const ViewSortType tp) 0215 { 0216 if (tp == viewSortType()) 0217 return; 0218 0219 setValue("General", "viewSortType", static_cast<int>(tp)); 0220 Q_EMIT viewSortTypeChanged(tp); 0221 } 0222 void SettingsData::setMatchType(const AnnotationDialog::MatchType mt) 0223 { 0224 if (mt == matchType()) 0225 return; 0226 0227 setValue("General", "matchType", static_cast<int>(mt)); 0228 Q_EMIT matchTypeChanged(mt); 0229 } 0230 0231 bool SettingsData::trustTimeStamps() 0232 { 0233 if (tTimeStamps() == Always) 0234 return true; 0235 else if (tTimeStamps() == Never) 0236 return false; 0237 else { 0238 if (!m_hasAskedAboutTimeStamps) { 0239 const QString txt = i18n("When reading time information of images, their Exif info is used. " 0240 "Exif info may, however, not be supported by your KPhotoAlbum installation, " 0241 "or no valid information may be in the file. " 0242 "As a backup, KPhotoAlbum may use the timestamp of the image - this may, " 0243 "however, not be valid in case the image is scanned in. " 0244 "So the question is, should KPhotoAlbum trust the time stamp on your images?"); 0245 const QString logMsg = QString::fromUtf8("Trust timestamps for this session?"); 0246 auto answer = uiDelegate().questionYesNo(DB::LogMessage { BaseLog(), logMsg }, txt, i18n("Trust Time Stamps?")); 0247 if (answer == DB::UserFeedback::Confirm) 0248 m_trustTimeStamps = true; 0249 else 0250 m_trustTimeStamps = false; 0251 m_hasAskedAboutTimeStamps = true; 0252 } 0253 return m_trustTimeStamps; 0254 } 0255 } 0256 0257 //////////////////////////////// 0258 //// File Version Detection //// 0259 //////////////////////////////// 0260 0261 // clang-format off 0262 property_copy(detectModifiedFiles, setDetectModifiedFiles, bool, FileVersionDetection, true) 0263 property_copy(modifiedFileComponent, setModifiedFileComponent, QString, FileVersionDetection, "^(.*)-edited.([^.]+)$") 0264 property_copy(originalFileComponent, setOriginalFileComponent, QString, FileVersionDetection, "\\1.\\2") 0265 property_copy(moveOriginalContents, setMoveOriginalContents, bool, FileVersionDetection, false) 0266 property_copy(autoStackNewFiles, setAutoStackNewFiles, bool, FileVersionDetection, true) 0267 property_copy(copyFileComponent, setCopyFileComponent, QString, FileVersionDetection, "(.[^.]+)$") 0268 property_copy(copyFileReplacementComponent, setCopyFileReplacementComponent, QString, FileVersionDetection, "-edited\\1") 0269 property_copy(loadOptimizationPreset, setLoadOptimizationPreset, int, FileVersionDetection, 0) 0270 property_copy(overlapLoadMD5, setOverlapLoadMD5, bool, FileVersionDetection, false) 0271 property_copy(preloadThreadCount, setPreloadThreadCount, int, FileVersionDetection, 1) 0272 property_copy(thumbnailPreloadThreadCount, setThumbnailPreloadThreadCount, int, FileVersionDetection, 1) 0273 property_copy(thumbnailBuilderThreadCount, setThumbnailBuilderThreadCount, int, FileVersionDetection, 0) 0274 // clang-format on 0275 0276 //////////////////// 0277 //// Thumbnails //// 0278 //////////////////// 0279 0280 // clang-format off 0281 //property_copy(displayLabels, setDisplayLabels, bool, Thumbnails, true) 0282 getValueFunc_(bool, displayLabels, groupForDatabase("Thumbnails"), "displayLabels", true) 0283 //property_copy(displayCategories, setDisplayCategories, bool, Thumbnails, false) 0284 getValueFunc_(bool, displayCategories, groupForDatabase("Thumbnails"), "displayCategories", false) 0285 0286 // clang-format on 0287 0288 void SettingsData::setDisplayLabels(bool value) 0289 { 0290 const bool changed = value != displayLabels(); 0291 setValue(groupForDatabase("Thumbnails"), "displayLabels", value); 0292 if (changed) 0293 Q_EMIT displayLabelsChanged(value); 0294 } 0295 0296 void SettingsData::setDisplayCategories(bool value) 0297 { 0298 const bool changed = value != displayCategories(); 0299 setValue(groupForDatabase("Thumbnails"), "displayCategories", value); 0300 if (changed) 0301 Q_EMIT displayCategoriesChanged(value); 0302 } 0303 // clang-format off 0304 property_copy(autoShowThumbnailView, setAutoShowThumbnailView, int, Thumbnails, 20) 0305 property_copy(showNewestThumbnailFirst, setShowNewestFirst, bool, Thumbnails, false) 0306 property_copy(thumbnailDisplayGrid, setThumbnailDisplayGrid, bool, Thumbnails, false) 0307 property_copy(previewSize, setPreviewSize, int, Thumbnails, 256) 0308 property_copy(thumbnailSpace, setThumbnailSpace, int, Thumbnails, 4) 0309 // not available via GUI, but should be consistent (and maybe confgurable for powerusers): 0310 property_copy(minimumThumbnailSize, setMinimumThumbnailSize, int, Thumbnails, 32) 0311 property_copy(maximumThumbnailSize, setMaximumThumbnailSize, int, Thumbnails, 4096) 0312 property_enum(thumbnailAspectRatio, setThumbnailAspectRatio, ThumbnailAspectRatio, Thumbnails, Aspect_3_2) 0313 property_copy(incrementalThumbnails, setIncrementalThumbnails, bool, Thumbnails, true) 0314 0315 // database specific so that changing it doesn't invalidate the thumbnail cache for other databases: 0316 getValueFunc_(int, thumbnailSize, groupForDatabase("Thumbnails"), "thumbSize", 256) 0317 // clang-format on 0318 0319 void SettingsData::setThumbnailSize(int value) 0320 { 0321 // enforce limits: 0322 value = qBound(minimumThumbnailSize(), value, maximumThumbnailSize()); 0323 0324 if (value != thumbnailSize()) 0325 Q_EMIT thumbnailSizeChanged(value); 0326 setValue(groupForDatabase("Thumbnails"), "thumbSize", value); 0327 } 0328 0329 int SettingsData::actualThumbnailSize() const 0330 { 0331 // this is database specific since it's a derived value of thumbnailSize 0332 int retval = cfgValue(groupForDatabase("Thumbnails"), "actualThumbSize", 0); 0333 // if no value has been set, use thumbnailSize 0334 if (retval == 0) 0335 retval = thumbnailSize(); 0336 return retval; 0337 } 0338 0339 void SettingsData::setActualThumbnailSize(int value) 0340 { 0341 // enforce limits: 0342 value = qBound(minimumThumbnailSize(), value, thumbnailSize()); 0343 0344 if (value != actualThumbnailSize()) { 0345 setValue(groupForDatabase("Thumbnails"), "actualThumbSize", value); 0346 Q_EMIT actualThumbnailSizeChanged(value); 0347 } 0348 } 0349 0350 //////////////// 0351 //// Viewer //// 0352 //////////////// 0353 0354 // clang-format off 0355 property_ref(viewerSize, setViewerSize, QSize, Viewer, QSize(1024, 768)) 0356 property_ref(slideShowSize, setSlideShowSize, QSize, Viewer, QSize(1024, 768)) 0357 property_copy(launchViewerFullScreen, setLaunchViewerFullScreen, bool, Viewer, false) 0358 property_copy(launchSlideShowFullScreen, setLaunchSlideShowFullScreen, bool, Viewer, true) 0359 property_copy(showInfoBox, setShowInfoBox, bool, Viewer, true) 0360 property_copy(showLabel, setShowLabel, bool, Viewer, true) 0361 property_copy(showDescription, setShowDescription, bool, Viewer, true) 0362 property_copy(showDate, setShowDate, bool, Viewer, true) 0363 property_copy(showImageSize, setShowImageSize, bool, Viewer, true) 0364 property_copy(showRating, setShowRating, bool, Viewer, true) 0365 property_copy(showTime, setShowTime, bool, Viewer, true) 0366 property_copy(showFilename, setShowFilename, bool, Viewer, false) 0367 property_copy(showEXIF, setShowEXIF, bool, Viewer, true) 0368 property_copy(slideShowInterval, setSlideShowInterval, int, Viewer, 5) 0369 property_copy(viewerCacheSize, setViewerCacheSize, int, Viewer, 195) 0370 property_copy(infoBoxWidth, setInfoBoxWidth, int, Viewer, 400) 0371 property_copy(infoBoxHeight, setInfoBoxHeight, int, Viewer, 300) 0372 property_enum(infoBoxPosition, setInfoBoxPosition, Position, Viewer, Bottom) 0373 property_enum(viewerStandardSize, setViewerStandardSize, StandardViewSize, Viewer, FullSize) 0374 //property_enum(videoBackend, setVideoBackend, VideoBackend, Viewer, VideoBackend::NotConfigured) 0375 setValueFunc_(setVideoBackend, VideoBackend, "Viewer", "videoBackend", static_cast<int>(v)) 0376 // clang-format on 0377 0378 VideoBackend SettingsData::videoBackend() const 0379 { 0380 auto value = static_cast<VideoBackend>(cfgValue("Viewer", "videoBackend", static_cast<int>(VideoBackend::NotConfigured))); 0381 // validate input: 0382 switch (value) { 0383 case VideoBackend::NotConfigured: 0384 case VideoBackend::Phonon: 0385 case VideoBackend::QtAV: 0386 case VideoBackend::VLC: 0387 break; 0388 default: 0389 qCWarning(BaseLog) << "Ignoring invalid configuration value for Viewer.videoBackend..."; 0390 value = VideoBackend::NotConfigured; 0391 } 0392 return value; 0393 } 0394 0395 bool SettingsData::smoothScale() const 0396 { 0397 return _smoothScale; 0398 } 0399 0400 void SettingsData::setSmoothScale(bool b) 0401 { 0402 _smoothScale = b; 0403 setValue("Viewer", "smoothScale", b); 0404 } 0405 0406 //////////////////// 0407 //// Categories //// 0408 //////////////////// 0409 0410 // clang-format off 0411 //property_ref(untaggedCategory, setUntaggedCategory, QString, General, i18n("Events")) 0412 getValueFunc_(QString, untaggedCategory, "General", "untaggedCategory", i18n("Events")) 0413 void SettingsData::setUntaggedCategory(const QString &value) 0414 { 0415 const bool changed = value != untaggedCategory(); 0416 setValue("General", "untaggedCategory", value); 0417 if (changed) 0418 Q_EMIT untaggedTagChanged(value, untaggedTag()); 0419 } 0420 0421 //property_ref(untaggedTag, setUntaggedTag, QString, General, i18n("untagged")) 0422 getValueFunc_(QString, untaggedTag, "General", "untaggedTag", i18n("untagged")) 0423 void SettingsData::setUntaggedTag(const QString &value) 0424 { 0425 const bool changed = value != untaggedTag(); 0426 setValue("General", "untaggedTag", value); 0427 if (changed) 0428 Q_EMIT untaggedTagChanged(untaggedCategory(), value); 0429 } 0430 0431 property_copy(untaggedImagesTagVisible, setUntaggedImagesTagVisible, bool, General, false) 0432 // clang-format on 0433 0434 ////////////// 0435 //// Exif //// 0436 ////////////// 0437 0438 // clang-format off 0439 property_sset(exifForViewer, setExifForViewer, Exif, StringSet()) 0440 property_sset(exifForDialog, setExifForDialog, Exif, StringSet()) 0441 property_ref(iptcCharset, setIptcCharset, QString, Exif, QString()) 0442 // clang-format on 0443 0444 ///////////////////// 0445 //// Exif Import //// 0446 ///////////////////// 0447 0448 // clang-format off 0449 property_copy(updateExifData, setUpdateExifData, bool, ExifImport, true) 0450 property_copy(updateImageDate, setUpdateImageDate, bool, ExifImport, false) 0451 property_copy(useModDateIfNoExif, setUseModDateIfNoExif, bool, ExifImport, true) 0452 property_copy(updateOrientation, setUpdateOrientation, bool, ExifImport, false) 0453 property_copy(updateDescription, setUpdateDescription, bool, ExifImport, false) 0454 // clang-format on 0455 0456 /////////////////////// 0457 //// Miscellaneous //// 0458 /////////////////////// 0459 0460 // clang-format off 0461 property_ref_(HTMLBaseDir, setHTMLBaseDir, QString, groupForDatabase("HTML Settings"), QString::fromLatin1("%1/public_html").arg(QString::fromLocal8Bit(qgetenv("HOME")))) 0462 property_ref_(HTMLBaseURL, setHTMLBaseURL, QString, groupForDatabase("HTML Settings"), STR("file://%1").arg(HTMLBaseDir())) 0463 property_ref_(HTMLDestURL, setHTMLDestURL, QString, groupForDatabase("HTML Settings"), STR("file://%1").arg(HTMLBaseDir())) 0464 property_ref_(HTMLCopyright, setHTMLCopyright, QString, groupForDatabase("HTML Settings"), QString()) 0465 property_ref_(HTMLDate, setHTMLDate, int, groupForDatabase("HTML Settings"), true) 0466 property_ref_(HTMLTheme, setHTMLTheme, int, groupForDatabase("HTML Settings"), -1) 0467 property_ref_(HTMLKimFile, setHTMLKimFile, int, groupForDatabase("HTML Settings"), true) 0468 property_ref_(HTMLInlineMovies, setHTMLInlineMovies, int, groupForDatabase("HTML Settings"), true) 0469 property_ref_(HTML5Video, setHTML5Video, int, groupForDatabase("HTML Settings"), true) 0470 property_ref_(HTML5VideoGenerate, setHTML5VideoGenerate, int, groupForDatabase("HTML Settings"), true) 0471 property_ref_(HTMLThumbSize, setHTMLThumbSize, int, groupForDatabase("HTML Settings"), 128) 0472 property_ref_(HTMLNumOfCols, setHTMLNumOfCols, int, groupForDatabase("HTML Settings"), 5) 0473 property_ref_(HTMLSizes, setHTMLSizes, QString, groupForDatabase("HTML Settings"), QString()) 0474 property_ref_(HTMLIncludeSelections, setHTMLIncludeSelections, QString, groupForDatabase("HTML Settings"), QString()) 0475 // clang-format on 0476 0477 QDate SettingsData::fromDate() const 0478 { 0479 QString date = cfgValue("Miscellaneous", "fromDate", QString()); 0480 return date.isEmpty() ? QDate(QDate::currentDate().year(), 1, 1) : QDate::fromString(date, Qt::ISODate); 0481 } 0482 0483 void SettingsData::setFromDate(const QDate &date) 0484 { 0485 if (date.isValid()) 0486 setValue("Miscellaneous", "fromDate", date.toString(Qt::ISODate)); 0487 } 0488 0489 QDate SettingsData::toDate() const 0490 { 0491 QString date = cfgValue("Miscellaneous", "toDate", QString()); 0492 return date.isEmpty() ? QDate(QDate::currentDate().year() + 1, 1, 1) : QDate::fromString(date, Qt::ISODate); 0493 } 0494 0495 void SettingsData::setToDate(const QDate &date) 0496 { 0497 if (date.isValid()) 0498 setValue("Miscellaneous", "toDate", date.toString(Qt::ISODate)); 0499 } 0500 0501 QString SettingsData::imageDirectory() const 0502 { 0503 return m_imageDirectory; 0504 } 0505 0506 QString SettingsData::groupForDatabase(const char *setting) const 0507 { 0508 return STR("%1 - %2").arg(STR(setting), imageDirectory()); 0509 } 0510 0511 QVariantMap SettingsData::currentLock() const 0512 { 0513 // duplicating logic from ImageSearchInfo here is not ideal 0514 // FIXME(jzarl): review the whole database view lock mechanism 0515 const auto group = groupForDatabase("Privacy Settings"); 0516 QVariantMap keyValuePairs; 0517 keyValuePairs[STR("label")] = cfgValue(group, "label", {}); 0518 keyValuePairs[STR("description")] = cfgValue(group, "description", {}); 0519 // reading a QVariant containing a stringlist is asking too much of cfgValue: 0520 const auto config = KSharedConfig::openConfig(configFile)->group(group); 0521 const QStringList categories = config.readEntry<QStringList>(QString::fromUtf8("categories"), QStringList()); 0522 keyValuePairs[STR("categories")] = QVariant(categories); 0523 for (QStringList::ConstIterator it = categories.constBegin(); it != categories.constEnd(); ++it) { 0524 keyValuePairs[*it] = cfgValue(group, *it, {}); 0525 } 0526 return keyValuePairs; 0527 } 0528 0529 void SettingsData::setCurrentLock(const QVariantMap &pairs, bool exclude) 0530 { 0531 for (QVariantMap::const_iterator it = pairs.cbegin(); it != pairs.cend(); ++it) { 0532 setValue(groupForDatabase("Privacy Settings"), it.key(), it.value()); 0533 } 0534 setValue(groupForDatabase("Privacy Settings"), "exclude", exclude); 0535 } 0536 0537 bool SettingsData::lockExcludes() const 0538 { 0539 return cfgValue(groupForDatabase("Privacy Settings"), "exclude", false); 0540 } 0541 0542 getValueFunc_(bool, locked, groupForDatabase("Privacy Settings"), "locked", false) 0543 0544 void SettingsData::setLocked(bool lock, bool force) 0545 { 0546 if (lock == locked() && !force) 0547 return; 0548 0549 setValue(groupForDatabase("Privacy Settings"), "locked", lock); 0550 Q_EMIT locked(lock, lockExcludes()); 0551 } 0552 0553 void SettingsData::setWindowGeometry(WindowType win, const QRect &geometry) 0554 { 0555 setValue("Window Geometry", win, geometry); 0556 } 0557 0558 QRect SettingsData::windowGeometry(WindowType win) const 0559 { 0560 return cfgValue("Window Geometry", win, QRect()); 0561 } 0562 0563 double Settings::SettingsData::getThumbnailAspectRatio() const 0564 { 0565 double ratio = 1.0; 0566 switch (Settings::SettingsData::instance()->thumbnailAspectRatio()) { 0567 case Settings::Aspect_16_9: 0568 ratio = 9.0 / 16; 0569 break; 0570 case Settings::Aspect_4_3: 0571 ratio = 3.0 / 4; 0572 break; 0573 case Settings::Aspect_3_2: 0574 ratio = 2.0 / 3; 0575 break; 0576 case Settings::Aspect_9_16: 0577 ratio = 16 / 9.0; 0578 break; 0579 case Settings::Aspect_3_4: 0580 ratio = 4 / 3.0; 0581 break; 0582 case Settings::Aspect_2_3: 0583 ratio = 3 / 2.0; 0584 break; 0585 case Settings::Aspect_1_1: 0586 ratio = 1.0; 0587 break; 0588 } 0589 return ratio; 0590 } 0591 0592 QStringList Settings::SettingsData::EXIFCommentsToStrip() 0593 { 0594 return m_EXIFCommentsToStrip; 0595 } 0596 0597 void Settings::SettingsData::setEXIFCommentsToStrip(QStringList EXIFCommentsToStrip) 0598 { 0599 m_EXIFCommentsToStrip = EXIFCommentsToStrip; 0600 } 0601 0602 bool Settings::SettingsData::getOverlapLoadMD5() const 0603 { 0604 switch (Settings::SettingsData::instance()->loadOptimizationPreset()) { 0605 case Settings::LoadOptimizationSlowNVME: 0606 case Settings::LoadOptimizationFastNVME: 0607 return true; 0608 case Settings::LoadOptimizationManual: 0609 return Settings::SettingsData::instance()->overlapLoadMD5(); 0610 case Settings::LoadOptimizationHardDisk: 0611 case Settings::LoadOptimizationNetwork: 0612 case Settings::LoadOptimizationSataSSD: 0613 default: 0614 return false; 0615 } 0616 } 0617 0618 int Settings::SettingsData::getPreloadThreadCount() const 0619 { 0620 switch (Settings::SettingsData::instance()->loadOptimizationPreset()) { 0621 case Settings::LoadOptimizationManual: 0622 return Settings::SettingsData::instance()->preloadThreadCount(); 0623 case Settings::LoadOptimizationSlowNVME: 0624 case Settings::LoadOptimizationFastNVME: 0625 case Settings::LoadOptimizationSataSSD: 0626 return qMax(1, qMin(16, QThread::idealThreadCount())); 0627 case Settings::LoadOptimizationHardDisk: 0628 case Settings::LoadOptimizationNetwork: 0629 default: 0630 return 1; 0631 } 0632 } 0633 0634 int Settings::SettingsData::getThumbnailPreloadThreadCount() const 0635 { 0636 switch (Settings::SettingsData::instance()->loadOptimizationPreset()) { 0637 case Settings::LoadOptimizationManual: 0638 return Settings::SettingsData::instance()->thumbnailPreloadThreadCount(); 0639 case Settings::LoadOptimizationSlowNVME: 0640 case Settings::LoadOptimizationFastNVME: 0641 case Settings::LoadOptimizationSataSSD: 0642 return qMax(1, qMin(16, QThread::idealThreadCount() / 2)); 0643 case Settings::LoadOptimizationHardDisk: 0644 case Settings::LoadOptimizationNetwork: 0645 default: 0646 return 1; 0647 } 0648 } 0649 0650 int Settings::SettingsData::getThumbnailBuilderThreadCount() const 0651 { 0652 switch (Settings::SettingsData::instance()->loadOptimizationPreset()) { 0653 case Settings::LoadOptimizationManual: 0654 return Settings::SettingsData::instance()->thumbnailBuilderThreadCount(); 0655 case Settings::LoadOptimizationSlowNVME: 0656 case Settings::LoadOptimizationFastNVME: 0657 case Settings::LoadOptimizationSataSSD: 0658 case Settings::LoadOptimizationHardDisk: 0659 case Settings::LoadOptimizationNetwork: 0660 default: 0661 return qMax(1, qMin(16, QThread::idealThreadCount() - 1)); 0662 } 0663 } 0664 0665 DB::UIDelegate &SettingsData::uiDelegate() const 0666 { 0667 return m_UI; 0668 } 0669 0670 // vi:expandtab:tabstop=4 shiftwidth=4: 0671 0672 #include "moc_SettingsData.cpp"