1 /*******************************************************************************************************
2 DkSettings.cpp
3 Created on: 07.07.2011
4
5 nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
6
7 Copyright (C) 2011-2016 Markus Diem <markus@nomacs.org>
8 Copyright (C) 2011-2016 Stefan Fiel <stefan@nomacs.org>
9 Copyright (C) 2011-2016 Florian Kleber <florian@nomacs.org>
10
11 This file is part of nomacs.
12
13 nomacs is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 nomacs is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
25
26 *******************************************************************************************************/
27
28 #include "DkSettings.h"
29 #include "DkUtils.h"
30
31 #pragma warning(push, 0) // no warnings from includes - begin
32 #include <iostream>
33 #include <cassert>
34
35 #include <QImageReader>
36 #include <QScreen>
37 #include <QDesktopServices>
38 #include <QTranslator>
39 #include <QFileInfo>
40 #include <QDebug>
41 #include <QTableView>
42 #include <QStandardItemModel>
43 #include <QStandardItem>
44 #include <QAbstractTableModel>
45 #include <QStyledItemDelegate>
46 #include <QDir>
47 #include <QApplication>
48 #include <QThreadPool>
49
50 #ifdef Q_OS_WIN
51 #include "Shobjidl.h"
52 #endif
53 #pragma warning(pop) // no warnings from includes - end
54
55 namespace nmc {
56
DkSettings()57 DkSettings::DkSettings() {
58
59 // cache settings path
60 mSettingsPath = settingsPath();
61 init();
62 }
63
init()64 void DkSettings::init() {
65 scamDataDesc = QStringList() <<
66 QT_TRANSLATE_NOOP("nmc::DkMetaData","Image Size") <<
67 QT_TRANSLATE_NOOP("nmc::DkMetaData","Orientation") <<
68 QT_TRANSLATE_NOOP("nmc::DkMetaData","Make") <<
69 QT_TRANSLATE_NOOP("nmc::DkMetaData","Model") <<
70 QT_TRANSLATE_NOOP("nmc::DkMetaData","Aperture Value") <<
71 QT_TRANSLATE_NOOP("nmc::DkMetaData","ISO") <<
72 QT_TRANSLATE_NOOP("nmc::DkMetaData","Flash") <<
73 QT_TRANSLATE_NOOP("nmc::DkMetaData","Focal Length") <<
74 QT_TRANSLATE_NOOP("nmc::DkMetaData","Exposure Mode") <<
75 QT_TRANSLATE_NOOP("nmc::DkMetaData","Exposure Time") <<
76 QT_TRANSLATE_NOOP("nmc::DkMetaData", "Compression");
77
78 sdescriptionDesc = QStringList() <<
79 QT_TRANSLATE_NOOP("nmc::DkMetaData","Rating") <<
80 QT_TRANSLATE_NOOP("nmc::DkMetaData","User Comment") <<
81 QT_TRANSLATE_NOOP("nmc::DkMetaData","Date Time") <<
82 QT_TRANSLATE_NOOP("nmc::DkMetaData","Date Time Original") <<
83 QT_TRANSLATE_NOOP("nmc::DkMetaData","Image Description") <<
84 QT_TRANSLATE_NOOP("nmc::DkMetaData","Creator") <<
85 QT_TRANSLATE_NOOP("nmc::DkMetaData","Creator Title") <<
86 QT_TRANSLATE_NOOP("nmc::DkMetaData","City") <<
87 QT_TRANSLATE_NOOP("nmc::DkMetaData","Country") <<
88 QT_TRANSLATE_NOOP("nmc::DkMetaData","Headline") <<
89 QT_TRANSLATE_NOOP("nmc::DkMetaData","Caption") <<
90 QT_TRANSLATE_NOOP("nmc::DkMetaData","Copyright") <<
91 QT_TRANSLATE_NOOP("nmc::DkMetaData","Keywords") <<
92 QT_TRANSLATE_NOOP("nmc::DkMetaData","Path") <<
93 QT_TRANSLATE_NOOP("nmc::DkMetaData","File Size");
94 }
95
dpiScaleFactor(QWidget * widget) const96 double DkSettings::dpiScaleFactor(QWidget *widget) const {
97
98 double dpi = 96.0;
99 if (widget) {
100 dpi = (double) widget->logicalDpiX();
101 } else {
102 QList<QScreen*> screens = QApplication::screens();
103 for(const QScreen* s : screens) {
104 if (s->logicalDotsPerInch() > dpi)
105 dpi = s->logicalDotsPerInch();
106 }
107 }
108 if (dpi < 96.0) dpi = 96.0;
109 return dpi / 96.0;
110 }
111
effectiveIconSize(QWidget * widget) const112 int DkSettings::effectiveIconSize(QWidget *widget) const {
113 return qRound(display_p.iconSize * dpiScaleFactor(widget));
114 }
115
effectiveThumbSize(QWidget * widget) const116 int DkSettings::effectiveThumbSize(QWidget *widget) const {
117 return qRound(display_p.thumbSize * dpiScaleFactor(widget));
118 }
119
effectiveThumbPreviewSize(QWidget * widget) const120 int DkSettings::effectiveThumbPreviewSize(QWidget *widget) const {
121 return qRound(display_p.thumbPreviewSize * dpiScaleFactor(widget));
122 }
123
translatedCamData() const124 QStringList DkSettings::translatedCamData() const {
125 return scamDataDesc;
126 }
127
translatedDescriptionData() const128 QStringList DkSettings::translatedDescriptionData() const {
129 return sdescriptionDesc;
130 }
131
initFileFilters()132 void DkSettings::initFileFilters() {
133
134 if (!app_p.openFilters.empty())
135 return;
136
137 QList<QByteArray> qtFormats = QImageReader::supportedImageFormats();
138
139 // formats we can save
140 if (qtFormats.contains("png")) app_p.saveFilters.append("PNG (*.png)");
141 if (qtFormats.contains("jpg")) app_p.saveFilters.append("JPEG (*.jpg *.jpeg *.jpe)");
142 if (qtFormats.contains("jp2")) app_p.saveFilters.append("JPEG 2000 (*.jp2 *.j2k *.jpf *.jpx *.jpm *.jpgx)");
143 if (qtFormats.contains("tif")) app_p.saveFilters.append("TIFF (*.tif *.tiff)");
144 if (qtFormats.contains("bmp")) app_p.saveFilters.append("Windows Bitmap (*.bmp)");
145 if (qtFormats.contains("ppm")) app_p.saveFilters.append("Portable Pixmap (*.ppm)");
146 if (qtFormats.contains("xbm")) app_p.saveFilters.append("X11 Bitmap (*.xbm)");
147 if (qtFormats.contains("xpm")) app_p.saveFilters.append("X11 Pixmap (*.xpm)");
148 if (qtFormats.contains("dds")) app_p.saveFilters.append("Direct Draw Surface (*.dds)");
149 if (qtFormats.contains("wbmp")) app_p.saveFilters.append("Wireless Bitmap (*.wbmp)");
150 //if (qtFormats.contains("icns")) app_p.saveFilters.append("Apple Icon Image (*.icns)");
151
152 if (qtFormats.contains("webp")) app_p.saveFilters.append("WebP (*.webp)");
153 if (qtFormats.contains("avif")) app_p.saveFilters.append("AV1 Image File Format (*.avif)");
154
155 #ifdef Q_OS_WIN
156 if (qtFormats.contains("ico")) app_p.saveFilters.append("Icon Files (*.ico)");
157 #endif
158
159 // formats we can load
160 app_p.openFilters += app_p.saveFilters;
161 if (qtFormats.contains("gif")) app_p.openFilters.append("Graphic Interchange Format (*.gif)");
162 if (qtFormats.contains("pbm")) app_p.openFilters.append("Portable Bitmap (*.pbm)");
163 if (qtFormats.contains("pgm")) app_p.openFilters.append("Portable Graymap (*.pgm)");
164 if (qtFormats.contains("tga")) app_p.openFilters.append("Truvision Graphics Adapter (*.tga)");
165 if (qtFormats.contains("mng")) app_p.openFilters.append("Multi-Image Network Graphics (*.mng)");
166 if (qtFormats.contains("cur")) app_p.openFilters.append("Windows Cursor Files (*.cur)");
167 if (qtFormats.contains("icns")) app_p.openFilters.append("Apple Icon Image (*.icns)");
168 if (qtFormats.contains("svgz")) app_p.openFilters.append("Scalable Vector Graphics (*.svg *.svgz)");
169 if (qtFormats.contains("avifs")) app_p.openFilters.append("AVIF image sequence (*.avifs)");
170
171 #ifndef Q_OS_WIN
172 if (qtFormats.contains("ico")) app_p.openFilters.append("Icon Files (*.ico)");
173 #endif
174
175 #ifdef WITH_LIBRAW
176 // raw format
177 app_p.rawFilters.append("Nikon Raw (*.nef *.nrw)");
178 app_p.rawFilters.append("Canon Raw (*.crw *.cr2 *.cr3)");
179 app_p.rawFilters.append("Sony Raw (*.arw)");
180 app_p.rawFilters.append("Digital Negativ (*.dng)");
181 app_p.rawFilters.append("Panasonic Raw (*.raw *.rw2)");
182 app_p.rawFilters.append("Minolta Raw (*.mrw)");
183 app_p.rawFilters.append("Samsung Raw (*.srw)");
184 app_p.rawFilters.append("Olympus Raw (*.orf)");
185 app_p.rawFilters.append("Hasselblad Raw (*.3fr)");
186 app_p.rawFilters.append("Sigma Raw (*.x3f)");
187 app_p.rawFilters.append("Leaf Raw (*.mos)");
188 app_p.rawFilters.append("Pentax Raw (*.pef)");
189 app_p.rawFilters.append("Phase One (*.iiq)");
190 app_p.rawFilters.append("Fujifilm Raw (*.raf)");
191
192 app_p.openFilters += app_p.rawFilters;
193 #endif
194
195 // stereo formats
196 app_p.openFilters.append("JPEG Stereo (*.jps)");
197 app_p.openFilters.append("PNG Stereo (*.pns)");
198 app_p.openFilters.append("Multi Picture Object (*.mpo)");
199
200 // other formats
201 app_p.openFilters.append("Adobe Photoshop (*.psd)");
202 app_p.openFilters.append("Large Document Format (*.psb)");
203
204 // archive formats
205 app_p.containerFilters.append("ZIP Archive (*.zip)");
206 app_p.containerFilters.append("Microsoft Word Document (*.docx)");
207 app_p.containerFilters.append("Microsoft PowerPoint Document (*.pptx)");
208 app_p.containerFilters.append("Microsoft Excel Document (*.xlsx)");
209 app_p.containerFilters.append("Comic Book Archive (*.cbz)");
210 app_p.containerFilters.append("Krita (*.kra)");
211
212 app_p.openFilters += app_p.containerFilters;
213
214 app_p.containerRawFilters = "*.docx *.pptx *.xlsx *.zip";
215
216 // exif filter as reported in #518 - afaik this is not a standard (typically it contains jpg/tiff)
217 app_p.openFilters.append("EXIF (*.exif)");
218
219 // finally: fabians filter & OpenCV vecs
220 app_p.openFilters.append("OpenCV Haar Training (*.vec)");
221 app_p.openFilters.append("Rohkost (*.roh)");
222
223 // drif images
224 app_p.openFilters.append("Developers Raw Image Format (*.drif)");
225
226 // load user filters
227 DefaultSettings settings;
228 app_p.openFilters += settings.value("ResourceSettings/userFilters", QStringList()).toStringList();
229
230 for (int idx = 0; idx < app_p.openFilters.size(); idx++) {
231
232 QString cFilter = app_p.openFilters[idx];
233 cFilter = cFilter.section(QRegExp("(\\(|\\))"), 1);
234 cFilter = cFilter.replace(")", "");
235 app_p.fileFilters += cFilter.split(" ");
236 }
237
238 QString allFilters = app_p.fileFilters.join(" ");
239
240 // add unknown formats from Qt plugins
241 for (int idx = 0; idx < qtFormats.size(); idx++) {
242
243 if (!allFilters.contains(qtFormats.at(idx))) {
244 app_p.openFilters.append("Image Format (*." + qtFormats.at(idx) + ")");
245 app_p.fileFilters.append("*." + qtFormats.at(idx));
246 }
247 }
248
249 app_p.openFilters.prepend("Image Files (" + app_p.fileFilters.join(" ") + ")");
250
251 //#ifdef Q_OS_WIN
252 // app_p.fileFilters.append("*.lnk");
253 //#endif
254
255 }
256
loadTranslation(const QString & fileName,QTranslator & translator)257 void DkSettings::loadTranslation(const QString& fileName, QTranslator& translator) {
258
259 QStringList translationDirs = getTranslationDirs();
260
261 for (int idx = 0; idx < translationDirs.size(); idx++) {
262
263 if (translator.load(fileName, translationDirs[idx])) {
264 qDebugClean() << "translation loaded from: " << translationDirs[idx] << "/" << fileName;
265 break;
266 }
267 }
268 }
269
getTranslationDirs()270 QStringList DkSettings::getTranslationDirs() {
271
272 QStringList trDirs;
273 trDirs << DkUtils::getTranslationPath();
274 trDirs << qApp->applicationDirPath();
275
276 QStringList rDirs;
277 rDirs << qApp->applicationDirPath();
278 rDirs << QStandardPaths::standardLocations(QStandardPaths::DataLocation);
279
280 for (const QString& d : rDirs)
281 trDirs << d + QDir::separator() + "translations";
282
283 trDirs.removeDuplicates();
284
285 return trDirs;
286 }
287
load()288 void DkSettings::load() {
289
290 DefaultSettings s;
291 load(s);
292 }
293
load(QSettings & settings,bool defaults)294 void DkSettings::load(QSettings& settings, bool defaults) {
295
296 applyDefaultsFromFile(); // copies entries from "default.ini" to the user settings file
297 setToDefaultSettings();
298 qInfoClean() << "loading settings from: " << settings.fileName();
299
300 settings.beginGroup("AppSettings");
301
302 app_p.showMenuBar = settings.value("showMenuBar", app_p.showMenuBar).toBool();
303 app_p.showToolBar = settings.value("showToolBar", app_p.showToolBar).toBool();
304 app_p.showStatusBar = settings.value("showStatusBar", app_p.showStatusBar).toBool();
305
306 QBitArray tmpShow = settings.value("showFileInfoLabel", app_p.showFileInfoLabel).toBitArray();
307 if (tmpShow.size() == app_p.showFileInfoLabel.size())
308 app_p.showFileInfoLabel = tmpShow;
309 tmpShow = settings.value("showScroller", app_p.showScroller).toBitArray();
310 if (tmpShow.size() == app_p.showScroller.size())
311 app_p.showScroller = tmpShow;
312 tmpShow = settings.value("showFilePreview", app_p.showFilePreview).toBitArray();
313 if (tmpShow.size() == app_p.showFilePreview.size())
314 app_p.showFilePreview = tmpShow;
315 tmpShow = settings.value("showMetaData", app_p.showMetaData).toBitArray();
316 if (tmpShow.size() == app_p.showMetaData.size())
317 app_p.showMetaData = tmpShow;
318 tmpShow = settings.value("showPlayer", app_p.showPlayer).toBitArray();
319 if (tmpShow.size() == app_p.showPlayer.size())
320 app_p.showPlayer = tmpShow;
321 tmpShow = settings.value("showHistogram", app_p.showHistogram).toBitArray();
322 if (tmpShow.size() == app_p.showHistogram.size())
323 app_p.showHistogram = tmpShow;
324 tmpShow = settings.value("showOverview", app_p.showOverview).toBitArray();
325 if (tmpShow.size() == app_p.showOverview.size())
326 app_p.showOverview = tmpShow;
327 tmpShow = settings.value("showComment", app_p.showComment).toBitArray();
328 if (tmpShow.size() == app_p.showComment.size())
329 app_p.showComment = tmpShow;
330 tmpShow = settings.value("showExplorer", app_p.showExplorer).toBitArray();
331 if (tmpShow.size() == app_p.showExplorer.size())
332 app_p.showExplorer = tmpShow;
333 tmpShow = settings.value("showMetaDataDock", app_p.showMetaDataDock).toBitArray();
334 if (tmpShow.size() == app_p.showMetaDataDock.size())
335 app_p.showMetaDataDock = tmpShow;
336 tmpShow = settings.value("showEditDock", app_p.showEditDock).toBitArray();
337 if (tmpShow.size() == app_p.showEditDock.size())
338 app_p.showEditDock = tmpShow;
339 tmpShow = settings.value("showHistoryDock", app_p.showHistoryDock).toBitArray();
340 if (tmpShow.size() == app_p.showHistoryDock.size())
341 app_p.showHistoryDock = tmpShow;
342 tmpShow = settings.value("showLogDock", app_p.showLogDock).toBitArray();
343 if (tmpShow.size() == app_p.showLogDock.size())
344 app_p.showLogDock = tmpShow;
345
346 app_p.hideAllPanels = settings.value("hideAllPanels", app_p.hideAllPanels).toBool();
347 app_p.closeOnEsc = settings.value("closeOnEsc", app_p.closeOnEsc).toBool();
348 app_p.showRecentFiles = settings.value("showRecentFiles", app_p.showRecentFiles).toBool();
349 app_p.useLogFile = settings.value("useLogFile", app_p.useLogFile).toBool();
350 app_p.defaultJpgQuality = settings.value("defaultJpgQuality", app_p.defaultJpgQuality).toInt();
351
352 QStringList tmpFileFilters = app_p.fileFilters;
353 QStringList tmpContainerFilters = app_p.containerRawFilters.split(" ");
354 for (int idx = 0; idx < tmpContainerFilters.size(); idx++) {
355 tmpFileFilters.removeAll(tmpContainerFilters.at(idx));
356 }
357 app_p.browseFilters = settings.value("browseFilters", tmpFileFilters).toStringList();
358
359 // double-check (if user removes all filters he can't browse anymore - so override this case)
360 if (app_p.browseFilters.empty())
361 app_p.browseFilters = tmpFileFilters;
362
363 app_p.registerFilters = settings.value("registerFilters", app_p.registerFilters).toStringList();
364 app_p.advancedSettings = settings.value("advancedSettings", app_p.advancedSettings).toBool();
365
366 settings.endGroup();
367 // Global Settings --------------------------------------------------------------------
368 settings.beginGroup("GlobalSettings");
369
370 global_p.skipImgs = settings.value("skipImgs", global_p.skipImgs).toInt();
371 global_p.checkOpenDuplicates = settings.value("checkOpenDuplicates", global_p.checkOpenDuplicates).toBool();
372 global_p.extendedTabs = settings.value("extendedTabs", global_p.extendedTabs).toBool();
373
374 global_p.loop = settings.value("loop", global_p.loop).toBool();
375 global_p.scanSubFolders = settings.value("scanRecursive", global_p.scanSubFolders).toBool();
376 global_p.lastDir = settings.value("lastDir", global_p.lastDir).toString();
377 global_p.searchHistory = settings.value("searchHistory", global_p.searchHistory).toStringList();
378 global_p.recentFolders = settings.value("recentFolders", global_p.recentFolders).toStringList();
379 global_p.pinnedFiles = settings.value("pinnedFiles", global_p.pinnedFiles).toStringList();
380 global_p.recentFiles = settings.value("recentFiles", global_p.recentFiles).toStringList();
381 global_p.logRecentFiles = settings.value("logRecentFiles", global_p.logRecentFiles).toBool();
382 global_p.askToSaveDeletedFiles = settings.value("askToSaveDeletedFiles", global_p.askToSaveDeletedFiles).toBool();
383 global_p.tmpPath = settings.value("tmpPath", global_p.tmpPath).toString();
384 global_p.language = settings.value("language", global_p.language).toString();
385 global_p.numThreads = settings.value("numThreads", global_p.numThreads).toInt();
386
387 global_p.sortMode = settings.value("sortMode", global_p.sortMode).toInt();
388 global_p.sortDir = settings.value("sortDir", global_p.sortDir).toInt();
389 global_p.setupPath = settings.value("setupPath", global_p.setupPath).toString();
390 global_p.setupVersion = settings.value("setupVersion", global_p.setupVersion).toString();
391 global_p.zoomOnWheel = settings.value("zoomOnWheel", global_p.zoomOnWheel).toBool();
392 global_p.horZoomSkips = settings.value("horZoomSkips", global_p.horZoomSkips).toBool();
393 global_p.doubleClickForFullscreen = settings.value("doubleClickForFullscreen", global_p.doubleClickForFullscreen).toBool();
394 global_p.showBgImage = settings.value("showBgImage", global_p.showBgImage).toBool();
395
396 settings.endGroup();
397 // Display Settings --------------------------------------------------------------------
398 settings.beginGroup("DisplaySettings");
399
400 display_p.keepZoom = settings.value("keepZoom", display_p.keepZoom).toInt();
401 display_p.invertZoom = settings.value("invertZoom", display_p.invertZoom).toBool();
402 display_p.zoomToFit = settings.value("zoomToFit", display_p.zoomToFit).toBool();
403 display_p.highlightColor = QColor::fromRgba(settings.value("highlightColorRGBA", display_p.highlightColor.rgba()).toInt());
404 display_p.hudBgColor = QColor::fromRgba(settings.value("bgColorWidgetRGBA", display_p.hudBgColor.rgba()).toInt());
405 display_p.hudFgdColor = QColor::fromRgba(settings.value("fontColorRGBA", display_p.hudFgdColor.rgba()).toInt());
406 display_p.bgColor = QColor::fromRgba(settings.value("bgColorNoMacsRGBA", display_p.bgColor.rgba()).toInt());
407 display_p.iconColor = QColor::fromRgba(settings.value("iconColorRGBA", display_p.iconColor.rgba()).toInt());
408 display_p.bgColorFrameless = QColor::fromRgba(settings.value("bgColorFramelessRGBA", display_p.bgColorFrameless.rgba()).toInt());
409 display_p.thumbSize = settings.value("thumbSize", display_p.thumbSize).toInt();
410 display_p.iconSize = settings.value("iconSize", display_p.iconSize).toInt();
411 display_p.thumbPreviewSize = settings.value("thumbPreviewSize", display_p.thumbPreviewSize).toInt();
412 //display_p.saveThumb = settings.value("saveThumb", display_p.saveThumb).toBool();
413 display_p.antiAliasing = settings.value("antiAliasing", display_p.antiAliasing).toBool();
414 display_p.highQualityAntiAliasing = settings.value("highQualityAntiAliasing", display_p.highQualityAntiAliasing).toBool();
415 display_p.showCrop = settings.value("showCrop", display_p.showCrop).toBool();
416 display_p.histogramStyle = settings.value("histogramStyle", display_p.histogramStyle).toInt();
417 display_p.tpPattern = settings.value("tpPattern", display_p.tpPattern).toBool();
418 display_p.showNavigation = settings.value("showNavigation", display_p.showNavigation).toBool();
419 display_p.themeName = settings.value("themeName312", display_p.themeName).toString();
420 display_p.showBorder = settings.value("showBorder", display_p.showBorder).toBool();
421 display_p.displaySquaredThumbs = settings.value("displaySquaredThumbs", display_p.displaySquaredThumbs).toBool();
422 display_p.showThumbLabel = settings.value("showThumbLabel", display_p.showThumbLabel).toBool();
423 display_p.showScrollBars = settings.value("showScrollBars", display_p.showScrollBars).toBool();
424 display_p.animationDuration = settings.value("fadeSec", display_p.animationDuration).toFloat();
425 display_p.alwaysAnimate = settings.value("alwaysAnimate", display_p.alwaysAnimate).toBool();
426 display_p.transition = (TransitionMode)settings.value("transition", display_p.transition).toInt();
427 display_p.defaultBackgroundColor = settings.value("useDefaultColor", display_p.defaultBackgroundColor).toBool();
428 display_p.defaultIconColor = settings.value("defaultIconColor", display_p.defaultIconColor).toBool();
429 display_p.interpolateZoomLevel = settings.value("interpolateZoomlevel", display_p.interpolateZoomLevel).toInt();
430
431 settings.endGroup();
432 // MetaData Settings --------------------------------------------------------------------
433 settings.beginGroup("MetaDataSettings");
434
435 meta_p.ignoreExifOrientation = settings.value("ignoreExifOrientation", meta_p.ignoreExifOrientation).toBool();
436 meta_p.saveExifOrientation = settings.value("saveExifOrientation", meta_p.saveExifOrientation).toBool();
437
438 settings.endGroup();
439 // SlideShow Settings --------------------------------------------------------------------
440 settings.beginGroup("SlideShowSettings");
441
442 slideShow_p.filter = settings.value("filter", slideShow_p.filter).toInt();
443 slideShow_p.time = settings.value("time", slideShow_p.time).toFloat();
444 slideShow_p.showPlayer = settings.value("showPlayer", slideShow_p.showPlayer).toBool();
445 slideShow_p.moveSpeed = settings.value("moveSpeed", slideShow_p.moveSpeed).toFloat();
446 slideShow_p.backgroundColor = QColor::fromRgba(settings.value("backgroundColorRGBA", slideShow_p.backgroundColor.rgba()).toInt());
447 slideShow_p.silentFullscreen = settings.value("silentFullscreen", slideShow_p.silentFullscreen).toBool();
448 QBitArray tmpDisplay = settings.value("display", slideShow_p.display).toBitArray();
449
450 if (tmpDisplay.size() == slideShow_p.display.size())
451 slideShow_p.display = tmpDisplay;
452
453 settings.endGroup();
454 // Synchronize Settings --------------------------------------------------------------------
455 settings.beginGroup("SynchronizeSettings");
456
457 sync_p.checkForUpdates = settings.value("checkForUpdates", sync_p.checkForUpdates).toBool();
458 sync_p.disableUpdateInteraction = settings.value("disableUpdateInteraction", sync_p.disableUpdateInteraction).toBool();
459 sync_p.updateDialogShown = settings.value("updateDialogShown", sync_p.updateDialogShown).toBool();
460 sync_p.lastUpdateCheck = settings.value("lastUpdateCheck", sync_p.lastUpdateCheck).toDate();
461 sync_p.syncAbsoluteTransform = settings.value("syncAbsoluteTransform", sync_p.syncAbsoluteTransform).toBool();
462 sync_p.switchModifier = settings.value("switchModifier", sync_p.switchModifier).toBool();
463 sync_p.syncActions = settings.value("syncActions", sync_p.syncActions).toBool();
464
465 settings.endGroup();
466 // Resource Settings --------------------------------------------------------------------
467 settings.beginGroup("ResourceSettings");
468
469 resources_p.cacheMemory = settings.value("cacheMemory", resources_p.cacheMemory).toFloat();
470 resources_p.historyMemory = settings.value("historyMemory", resources_p.historyMemory).toFloat();
471 resources_p.nativeDialog = settings.value("nativeDialog", resources_p.nativeDialog).toBool();
472 resources_p.maxImagesCached = settings.value("maxImagesCached", resources_p.maxImagesCached).toInt();
473 resources_p.waitForLastImg = settings.value("waitForLastImg", resources_p.waitForLastImg).toBool();
474 resources_p.filterRawImages = settings.value("filterRawImages", resources_p.filterRawImages).toBool();
475 resources_p.loadRawThumb = settings.value("loadRawThumb", resources_p.loadRawThumb).toInt();
476 resources_p.filterDuplicats = settings.value("filterDuplicates", resources_p.filterDuplicats).toBool();
477 resources_p.preferredExtension = settings.value("preferredExtension", resources_p.preferredExtension).toString();
478 resources_p.gammaCorrection = settings.value("gammaCorrection", resources_p.gammaCorrection).toBool();
479 resources_p.loadSavedImage = settings.value("loadSavedImage", resources_p.loadSavedImage).toInt();
480
481 if (sync_p.switchModifier) {
482 global_p.altMod = Qt::ControlModifier;
483 global_p.ctrlMod = Qt::AltModifier;
484 }
485 else {
486 global_p.altMod = Qt::AltModifier;
487 global_p.ctrlMod = Qt::ControlModifier;
488 }
489
490 settings.endGroup();
491
492 if (global_p.numThreads != -1)
493 QThreadPool::globalInstance()->setMaxThreadCount(global_p.numThreads);
494 else
495 global_p.numThreads = QThreadPool::globalInstance()->maxThreadCount();
496
497 // keep loaded settings in mind
498 if (defaults) {
499 app_d = app_p;
500 global_d = global_p;
501 display_d = display_p;
502 slideShow_d = slideShow_p;
503 sync_d = sync_p;
504 meta_d = meta_p;
505 resources_d = resources_p;
506 }
507 }
508
save(bool force)509 void DkSettings::save(bool force) {
510 DefaultSettings s;
511 save(s, force);
512 }
513
save(QSettings & settings,bool force)514 void DkSettings::save(QSettings& settings, bool force) {
515
516 if (DkSettingsManager::param().app().privateMode)
517 return;
518
519 settings.beginGroup("AppSettings");
520 if (force ||app_p.showMenuBar != app_d.showMenuBar)
521 settings.setValue("showMenuBar", app_p.showMenuBar);
522
523 if (app_p.currentAppMode != mode_frameless && app_p.currentAppMode != mode_frameless_fullscreen) {
524
525 if (force ||app_p.showToolBar != app_d.showToolBar)
526 settings.setValue("showToolBar", app_p.showToolBar);
527
528 if (force ||app_p.showStatusBar != app_d.showStatusBar)
529 settings.setValue("showStatusBar", app_p.showStatusBar);
530 }
531
532 if (force ||app_p.showFileInfoLabel != app_d.showFileInfoLabel)
533 settings.setValue("showFileInfoLabel", app_p.showFileInfoLabel);
534 if (force ||app_p.showFilePreview != app_d.showFilePreview)
535 settings.setValue("showFilePreview", app_p.showFilePreview);
536 if (force ||app_p.showScroller != app_d.showScroller)
537 settings.setValue("showScroller", app_p.showScroller);
538 if (force ||app_p.showMetaData != app_d.showMetaData)
539 settings.setValue("showMetaData", app_p.showMetaData);
540 if (force ||app_p.showPlayer != app_d.showPlayer)
541 settings.setValue("showPlayer", app_p.showPlayer);
542 if (force ||app_p.showHistogram != app_d.showHistogram)
543 settings.setValue("showHistogram", app_p.showHistogram);
544 if (force ||app_p.showComment != app_d.showComment)
545 settings.setValue("showComment", app_p.showComment);
546 if (force ||app_p.showOverview != app_d.showOverview)
547 settings.setValue("showOverview", app_p.showOverview);
548 if (force ||app_p.showExplorer != app_d.showExplorer)
549 settings.setValue("showExplorer", app_p.showExplorer);
550 if (force ||app_p.showMetaDataDock != app_d.showMetaDataDock)
551 settings.setValue("showMetaDataDock", app_p.showMetaDataDock);
552 if (force ||app_p.showEditDock != app_d.showEditDock)
553 settings.setValue("showEditDock", app_p.showEditDock);
554 if (force ||app_p.showHistoryDock != app_d.showHistoryDock)
555 settings.setValue("showHistoryDock", app_p.showHistoryDock);
556 if (force || app_p.showLogDock != app_d.showLogDock)
557 settings.setValue("showLogDock", app_p.showLogDock);
558 if (force || app_p.hideAllPanels != app_d.hideAllPanels)
559 settings.setValue("hideAllPanels", app_p.hideAllPanels);
560 if (force ||app_p.advancedSettings != app_d.advancedSettings)
561 settings.setValue("advancedSettings", app_p.advancedSettings);
562 if (force ||app_p.closeOnEsc != app_d.closeOnEsc)
563 settings.setValue("closeOnEsc", app_p.closeOnEsc);
564 if (force ||app_p.showRecentFiles != app_d.showRecentFiles)
565 settings.setValue("showRecentFiles", app_p.showRecentFiles);
566 if (force ||app_p.useLogFile != app_d.useLogFile)
567 settings.setValue("useLogFile", app_p.useLogFile);
568 if (force ||app_p.browseFilters != app_d.browseFilters)
569 settings.setValue("browseFilters", app_p.browseFilters);
570 if (force ||app_p.registerFilters != app_d.registerFilters)
571 settings.setValue("registerFilters", app_p.registerFilters);
572
573 // always save (user setting)
574 settings.setValue("defaultJpgQuality", app_p.defaultJpgQuality);
575 settings.setValue("appMode", app_p.appMode);
576 settings.setValue("currentAppMode", app_p.currentAppMode);
577
578 settings.endGroup();
579 // Global Settings --------------------------------------------------------------------
580 settings.beginGroup("GlobalSettings");
581
582 if (force ||global_p.skipImgs != global_d.skipImgs)
583 settings.setValue("skipImgs",global_p.skipImgs);
584 if (force ||global_p.checkOpenDuplicates != global_d.checkOpenDuplicates)
585 settings.setValue("checkOpenDuplicates",global_p.checkOpenDuplicates);
586 if (force ||global_p.extendedTabs != global_d.extendedTabs)
587 settings.setValue("extendedTabs", global_p.extendedTabs);
588 if (force ||global_p.loop != global_d.loop)
589 settings.setValue("loop",global_p.loop);
590 if (force ||global_p.scanSubFolders != global_d.scanSubFolders)
591 settings.setValue("scanRecursive",global_p.scanSubFolders);
592 if (force ||global_p.lastDir != global_d.lastDir)
593 settings.setValue("lastDir", global_p.lastDir);
594 if (force ||global_p.searchHistory != global_d.searchHistory)
595 settings.setValue("searchHistory", global_p.searchHistory);
596 if (force ||global_p.recentFolders != global_d.recentFolders)
597 settings.setValue("recentFolders", global_p.recentFolders);
598 if (force ||global_p.recentFiles != global_d.recentFiles)
599 settings.setValue("recentFiles", global_p.recentFiles);
600 if (force || global_p.pinnedFiles != global_d.pinnedFiles)
601 settings.setValue("pinnedFiles", global_p.pinnedFiles);
602 if (force ||global_p.logRecentFiles != global_d.logRecentFiles)
603 settings.setValue("logRecentFiles", global_p.logRecentFiles);
604 if (force ||global_p.askToSaveDeletedFiles != global_d.askToSaveDeletedFiles)
605 settings.setValue("askToSaveDeletedFiles", global_p.askToSaveDeletedFiles);
606 if (force ||global_p.tmpPath != global_d.tmpPath)
607 settings.setValue("tmpPath", global_p.tmpPath);
608 if (force ||global_p.language != global_d.language)
609 settings.setValue("language", global_p.language);
610 if (force ||global_p.numThreads != global_d.numThreads)
611 settings.setValue("numThreads", global_p.numThreads);
612 if (force ||global_p.sortMode != global_d.sortMode)
613 settings.setValue("sortMode", global_p.sortMode);
614 if (force ||global_p.sortDir != global_d.sortDir)
615 settings.setValue("sortDir", global_p.sortDir);
616 if (force ||global_p.setupPath != global_d.setupPath)
617 settings.setValue("setupPath", global_p.setupPath);
618 if (force ||global_p.setupVersion != global_d.setupVersion)
619 settings.setValue("setupVersion", global_p.setupVersion);
620 if (force ||global_p.zoomOnWheel != global_d.zoomOnWheel)
621 settings.setValue("zoomOnWheel", global_p.zoomOnWheel);
622 if (force ||global_p.horZoomSkips != global_d.horZoomSkips)
623 settings.setValue("horZoomSkips", global_p.horZoomSkips);
624 if (force ||global_p.doubleClickForFullscreen != global_d.doubleClickForFullscreen)
625 settings.setValue("doubleClickForFullscreen", global_p.doubleClickForFullscreen);
626 if (force ||global_p.showBgImage != global_d.showBgImage)
627 settings.setValue("showBgImage", global_p.showBgImage);
628
629 settings.endGroup();
630 // Display Settings --------------------------------------------------------------------
631 settings.beginGroup("DisplaySettings");
632
633 if (force ||display_p.keepZoom != display_d.keepZoom)
634 settings.setValue("keepZoom",display_p.keepZoom);
635 if (force ||display_p.invertZoom != display_d.invertZoom)
636 settings.setValue("invertZoom",display_p.invertZoom);
637 if (force ||display_p.zoomToFit != display_d.zoomToFit)
638 settings.setValue("zoomToFit",display_p.zoomToFit);
639 if (force ||display_p.highlightColor != display_d.highlightColor)
640 settings.setValue("highlightColorRGBA", display_p.highlightColor.rgba());
641 if (force ||display_p.hudBgColor != display_d.hudBgColor)
642 settings.setValue("bgColorWidgetRGBA", display_p.hudBgColor.rgba());
643 if (force ||display_p.hudFgdColor != display_d.hudFgdColor)
644 settings.setValue("fontColorRGBA", display_p.hudFgdColor.rgba());
645 if (force || display_p.bgColor != display_d.bgColor)
646 settings.setValue("bgColorNoMacsRGBA", display_p.bgColor.rgba());
647 if (force ||display_p.iconColor != display_d.iconColor)
648 settings.setValue("iconColorRGBA", display_p.iconColor.rgba());
649 if (force ||display_p.bgColorFrameless != display_d.bgColorFrameless)
650 settings.setValue("bgColorFramelessRGBA", display_p.bgColorFrameless.rgba());
651 if (force ||display_p.thumbSize != display_d.thumbSize)
652 settings.setValue("thumbSize", display_p.thumbSize);
653 if (force ||display_p.iconSize != display_d.iconSize)
654 settings.setValue("iconSize", display_p.iconSize);
655 if (force ||display_p.thumbPreviewSize != display_d.thumbPreviewSize)
656 settings.setValue("thumbPreviewSize", display_p.thumbPreviewSize);
657 //if (force ||display_p.saveThumb != display_d.saveThumb)
658 // settings.setValue("saveThumb", display_p.saveThumb);
659 if (force ||display_p.antiAliasing != display_d.antiAliasing)
660 settings.setValue("antiAliasing", display_p.antiAliasing);
661 if (force || display_p.highQualityAntiAliasing != display_d.highQualityAntiAliasing)
662 settings.setValue("highQualityAntiAliasing", display_p.highQualityAntiAliasing);
663 if (force ||display_p.showCrop != display_d.showCrop)
664 settings.setValue("showCrop", display_p.showCrop);
665 if (force ||display_p.histogramStyle != display_d.histogramStyle)
666 settings.setValue("histogramStyle", display_p.histogramStyle);
667 if (force ||display_p.tpPattern != display_d.tpPattern)
668 settings.setValue("tpPattern", display_p.tpPattern);
669 if (force || display_p.showNavigation != display_d.showNavigation)
670 settings.setValue("showNavigation", display_p.showNavigation);
671 if (force || display_p.themeName != display_d.themeName)
672 settings.setValue("themeName312", display_p.themeName);
673 if (force ||display_p.showBorder != display_d.showBorder)
674 settings.setValue("showBorder", display_p.showBorder);
675 if (force ||display_p.displaySquaredThumbs != display_d.displaySquaredThumbs)
676 settings.setValue("displaySquaredThumbs", display_p.displaySquaredThumbs);
677 if (force ||display_p.showThumbLabel != display_d.showThumbLabel)
678 settings.setValue("showThumbLabel", display_p.showThumbLabel);
679 if (force || display_p.showScrollBars != display_d.showScrollBars)
680 settings.setValue("showScrollBars", display_p.showScrollBars);
681 if (force ||display_p.alwaysAnimate != display_d.alwaysAnimate)
682 settings.setValue("alwaysAnimate", display_p.alwaysAnimate);
683 if (force ||display_p.animationDuration != display_d.animationDuration)
684 settings.setValue("fadeSec", display_p.animationDuration);
685 if (force ||display_p.transition != display_d.transition)
686 settings.setValue("transition", display_p.transition);
687 if (force ||display_p.defaultBackgroundColor != display_d.defaultBackgroundColor)
688 settings.setValue("useDefaultColor", display_p.defaultBackgroundColor);
689 if (force ||display_p.defaultIconColor != display_d.defaultIconColor)
690 settings.setValue("defaultIconColor", display_p.defaultIconColor);
691 if (force ||display_p.interpolateZoomLevel != display_d.interpolateZoomLevel)
692 settings.setValue("interpolateZoomlevel", display_p.interpolateZoomLevel);
693
694 settings.endGroup();
695 // MetaData Settings --------------------------------------------------------------------
696 settings.beginGroup("MetaDataSettings");
697
698 if (force ||meta_p.ignoreExifOrientation != meta_d.ignoreExifOrientation)
699 settings.setValue("ignoreExifOrientation", meta_p.ignoreExifOrientation);
700 if (force ||meta_p.saveExifOrientation != meta_d.saveExifOrientation)
701 settings.setValue("saveExifOrientation", meta_p.saveExifOrientation);
702
703 settings.endGroup();
704 // SlideShow Settings --------------------------------------------------------------------
705 settings.beginGroup("SlideShowSettings");
706
707 if (force ||slideShow_p.filter != slideShow_d.filter)
708 settings.setValue("filter", slideShow_p.filter);
709 if (force ||slideShow_p.time != slideShow_d.time)
710 settings.setValue("time", slideShow_p.time);
711 if (force || slideShow_p.showPlayer != slideShow_d.showPlayer)
712 settings.setValue("showPlayer", slideShow_p.showPlayer);
713 if (force ||slideShow_p.moveSpeed != slideShow_d.moveSpeed)
714 settings.setValue("moveSpeed", slideShow_p.moveSpeed);
715 if (force ||slideShow_p.display != slideShow_d.display)
716 settings.setValue("display", slideShow_p.display);
717 if (force ||slideShow_p.backgroundColor != slideShow_d.backgroundColor)
718 settings.setValue("backgroundColorRGBA", slideShow_p.backgroundColor.rgba());
719 if (force ||slideShow_p.silentFullscreen != slideShow_d.silentFullscreen)
720 settings.setValue("silentFullscreen", slideShow_p.silentFullscreen);
721
722 settings.endGroup();
723 // Sync Settings --------------------------------------------------------------------
724 settings.beginGroup("SynchronizeSettings");
725
726 //if (force ||sync_p.checkForUpdates != sync_d.checkForUpdates)
727 settings.setValue("checkForUpdates", sync_p.checkForUpdates);
728 //if (force || sync_p.disableUpdateInteraction != sync_d.disableUpdateInteraction)
729 settings.setValue("disableUpdateInteraction", sync_p.disableUpdateInteraction);
730 if (force ||sync_p.updateDialogShown != sync_d.updateDialogShown)
731 settings.setValue("updateDialogShown", sync_p.updateDialogShown);
732 if (force ||sync_p.lastUpdateCheck != sync_d.lastUpdateCheck)
733 settings.setValue("lastUpdateCheck", sync_p.lastUpdateCheck);
734 if (force ||sync_p.syncAbsoluteTransform != sync_d.syncAbsoluteTransform)
735 settings.setValue("syncAbsoluteTransform", sync_p.syncAbsoluteTransform);
736 if (force ||sync_p.switchModifier != sync_d.switchModifier)
737 settings.setValue("switchModifier", sync_p.switchModifier);
738 if (force ||sync_p.syncActions != sync_d.syncActions)
739 settings.setValue("syncActions", sync_p.syncActions);
740
741 settings.endGroup();
742 // Resource Settings --------------------------------------------------------------------
743 settings.beginGroup("ResourceSettings");
744
745 if (force ||resources_p.cacheMemory != resources_d.cacheMemory)
746 settings.setValue("cacheMemory", resources_p.cacheMemory);
747 if (force ||resources_p.historyMemory != resources_d.historyMemory)
748 settings.setValue("historyMemory", resources_p.historyMemory);
749 if (force || resources_p.nativeDialog != resources_d.nativeDialog)
750 settings.setValue("nativeDialog", resources_p.nativeDialog);
751 if (force ||resources_p.maxImagesCached != resources_d.maxImagesCached)
752 settings.setValue("maxImagesCached", resources_p.maxImagesCached);
753 if (force ||resources_p.waitForLastImg != resources_d.waitForLastImg)
754 settings.setValue("waitForLastImg", resources_p.waitForLastImg);
755 if (force ||resources_p.filterRawImages != resources_d.filterRawImages)
756 settings.setValue("filterRawImages", resources_p.filterRawImages);
757 if (force ||resources_p.loadRawThumb != resources_d.loadRawThumb)
758 settings.setValue("loadRawThumb", resources_p.loadRawThumb);
759 if (force ||resources_p.filterDuplicats != resources_d.filterDuplicats)
760 settings.setValue("filterDuplicates", resources_p.filterDuplicats);
761 if (force ||resources_p.preferredExtension != resources_d.preferredExtension)
762 settings.setValue("preferredExtension", resources_p.preferredExtension);
763 if (force ||resources_p.gammaCorrection != resources_d.gammaCorrection)
764 settings.setValue("gammaCorrection", resources_p.gammaCorrection);
765 if (force || resources_p.loadSavedImage != resources_d.loadSavedImage)
766 settings.setValue("loadSavedImage", resources_p.loadSavedImage);
767
768 settings.endGroup();
769
770 // keep loaded settings in mind
771 app_d = app_p;
772 global_d = global_p;
773 display_d = display_p;
774 slideShow_d = slideShow_p;
775 sync_d = sync_p;
776 meta_d = meta_p;
777 resources_d = resources_p;
778
779 qDebug() << "settings saved to" << settingsPath();
780 }
781
setToDefaultSettings()782 void DkSettings::setToDefaultSettings() {
783
784 app_p.showToolBar = true;
785 app_p.showStatusBar = false;
786 app_p.showMovieToolBar = false;
787 app_p.showFileInfoLabel = QBitArray(mode_end, false);
788 app_p.showFilePreview = QBitArray(mode_end, false);
789 app_p.showScroller = QBitArray(mode_end, false);
790 app_p.showMetaData = QBitArray(mode_end, false);
791 app_p.showPlayer = QBitArray(mode_end, false);
792 app_p.showHistogram = QBitArray(mode_end, false);
793 app_p.showComment = QBitArray(mode_end, false);
794 app_p.showOverview = QBitArray(mode_end, false);
795 app_p.showExplorer = QBitArray(mode_end, false);
796 app_p.showMetaDataDock = QBitArray(mode_end, false);
797 app_p.showEditDock = QBitArray(mode_end, false);
798 app_p.showHistoryDock = QBitArray(mode_end, false);
799 app_p.showLogDock = QBitArray(mode_end, false);
800 app_p.advancedSettings = false;
801 app_p.closeOnEsc = false;
802 app_p.hideAllPanels = false;
803 app_p.showRecentFiles = true;
804 app_p.browseFilters = QStringList();
805 app_p.showMenuBar = true;
806 app_p.useLogFile = false;
807
808 // now set default show options
809 app_p.showFileInfoLabel.setBit(mode_default, false);
810 app_p.showFileInfoLabel.setBit(mode_contrast, false);
811
812 app_p.appMode = 0;
813 app_p.privateMode = false;
814 app_p.defaultJpgQuality = 97;
815
816 global_p.skipImgs = 10;
817 global_p.numFiles = 50;
818 global_p.checkOpenDuplicates = true;
819 global_p.extendedTabs = false;
820 global_p.loop = true;
821 global_p.scanSubFolders = false;
822 global_p.lastDir = QString();
823 global_p.lastSaveDir = QString();
824 global_p.recentFiles = QStringList();
825 global_p.pinnedFiles = QStringList();
826 global_p.searchHistory = QStringList();
827 global_p.recentFolders = QStringList();
828 global_p.logRecentFiles = true;
829 global_p.askToSaveDeletedFiles = false;
830 global_p.tmpPath = "";
831 global_p.language = "en";
832 global_p.setupPath = "";
833 global_p.setupVersion = "";
834 global_p.numThreads = -1;
835 global_p.sortMode = sort_filename;
836 global_p.sortDir = sort_ascending;
837 global_p.zoomOnWheel = true;
838 global_p.horZoomSkips = true;
839 global_p.doubleClickForFullscreen = true;
840 global_p.showBgImage = true;
841
842 #ifdef Q_OS_LINUX
843 sync_p.switchModifier = true;
844 global_p.altMod = Qt::ControlModifier;
845 global_p.ctrlMod = Qt::AltModifier;
846 #else
847 sync_p.switchModifier = false;
848 global_p.altMod = Qt::AltModifier;
849 global_p.ctrlMod = Qt::ControlModifier;
850 #endif
851
852 display_p.keepZoom = zoom_keep_same_size;
853 display_p.invertZoom = false;
854 display_p.zoomToFit = false;
855 display_p.highlightColor = QColor(0, 204, 255);
856 display_p.hudBgColor = QColor(0, 0, 0, 100);
857 display_p.hudFgdColor = QColor(255, 255, 255);
858 display_p.bgColor = QColor(100, 100, 100, 255);
859 display_p.iconColor = QColor(100,100,100,255);
860 display_p.bgColorFrameless = QColor(0, 0, 0, 180);
861 display_p.thumbSize = 64;
862 display_p.iconSize = 16;
863 display_p.thumbPreviewSize = 64;
864 display_p.antiAliasing = true;
865 display_p.highQualityAntiAliasing = false;
866 display_p.showCrop = false;
867 display_p.histogramStyle = 0; // DkHistogram::DisplayMode::histogram_mode_simple
868 display_p.tpPattern = false;
869 display_p.showNavigation = true;
870 display_p.themeName = "Light-Theme.css";
871 display_p.showBorder = false;
872 display_p.displaySquaredThumbs = true;
873 display_p.showThumbLabel = false;
874 display_p.showScrollBars = false;
875 display_p.animationDuration = 0.5f;
876 display_p.alwaysAnimate = false;
877 display_p.transition = trans_swipe;
878 display_p.defaultBackgroundColor = true;
879 display_p.defaultIconColor = true;
880 display_p.interpolateZoomLevel = 200;
881
882 slideShow_p.filter = 0;
883 slideShow_p.time = 3.0;
884 slideShow_p.showPlayer = true;
885 slideShow_p.moveSpeed = 0; // TODO: set to 1 for finishing slideshow
886 slideShow_p.display = QBitArray(display_end, true);
887 slideShow_p.backgroundColor = QColor(51, 51, 51, 255);
888 slideShow_p.silentFullscreen = true;
889
890 meta_p.saveExifOrientation = true;
891 meta_p.ignoreExifOrientation = false;
892
893 sync_p.checkForUpdates = !isPortable(); // installed version should only check for updates by default
894 sync_p.disableUpdateInteraction = isPortable(); // installed version should only check for updates by default
895 sync_p.updateDialogShown = false;
896 sync_p.lastUpdateCheck = QDate(2018, 7, 14); // ; )
897 sync_p.syncAbsoluteTransform = true;
898 sync_p.syncActions = false;
899
900 resources_p.cacheMemory = 256;
901 resources_p.historyMemory = 128;
902 resources_p.nativeDialog = true;
903 resources_p.maxImagesCached = 5;
904 resources_p.filterRawImages = true;
905 resources_p.loadRawThumb = raw_thumb_always;
906 resources_p.filterDuplicats = false;
907 resources_p.preferredExtension = "*.jpg";
908 resources_p.gammaCorrection = true;
909 resources_p.loadSavedImage = ls_load_to_tab;
910 resources_p.waitForLastImg = true;
911
912 qDebug() << "ok... default settings are set";
913 }
914
applyDefaultsFromFile()915 void DkSettings::applyDefaultsFromFile() {
916
917 DefaultSettings ds;
918
919 if (ds.value("firstTime", true).toBool()) {
920
921 QString dsf = getDefaultSettingsFile();
922 if (!QFileInfo(dsf).exists()) {
923 qInfo() << "I could not find the default settings file: " << dsf;
924 }
925
926 QSettings defaultSettings(dsf, QSettings::IniFormat);
927 copySettings(defaultSettings, ds);
928
929 ds.setValue("firstTime", false);
930
931 qInfo() << "defaults loaded from" << dsf;
932 }
933 }
934
copySettings(const QSettings & src,QSettings & dst) const935 void DkSettings::copySettings(const QSettings & src, QSettings & dst) const {
936
937 // copy default settings
938 if (src.allKeys().count() > 0) {
939 QStringList keys = src.allKeys();
940
941 for (const QString& key : keys) {
942 dst.setValue(key, src.value(key));
943 }
944 }
945 }
946
getDefaultSettingsFile() const947 QString DkSettings::getDefaultSettingsFile() const {
948
949 return QFileInfo(QCoreApplication::applicationDirPath(), "default.ini").absoluteFilePath();
950 }
951
setNumThreads(int numThreads)952 void DkSettings::setNumThreads(int numThreads) {
953
954 if (numThreads != global_p.numThreads) {
955 global_p.numThreads = numThreads;
956 QThreadPool::globalInstance()->setMaxThreadCount(numThreads);
957 }
958 }
959
isPortable()960 bool DkSettings::isPortable() {
961
962 QFileInfo fi(QCoreApplication::applicationDirPath(), "settings.ini");
963 return fi.absoluteFilePath() == settingsPath();
964 }
965
settingsPath() const966 QString DkSettings::settingsPath() const {
967
968 if (!mSettingsPath.isEmpty())
969 return mSettingsPath;
970
971 QFileInfo fi(QCoreApplication::applicationDirPath(), "settings.ini");
972
973 if (fi.exists())
974 return fi.absoluteFilePath();
975
976 fi = QFileInfo(DkUtils::getAppDataPath(), "settings.ini");
977
978 return fi.absoluteFilePath();
979 }
980
app()981 DkSettings::App & DkSettings::app() {
982 return app_p;
983 }
984
global()985 DkSettings::Global & DkSettings::global() {
986 return global_p;
987 }
988
display()989 DkSettings::Display & DkSettings::display() {
990 return display_p;
991 }
992
slideShow()993 DkSettings::SlideShow & DkSettings::slideShow() {
994 return slideShow_p;
995 }
996
sync()997 DkSettings::Sync & DkSettings::sync() {
998 return sync_p;
999 }
1000
metaData()1001 DkSettings::MetaData & DkSettings::metaData() {
1002 return meta_p;
1003 }
1004
resources()1005 DkSettings::Resources & DkSettings::resources() {
1006 return resources_p;
1007 }
1008
DkSettingsManager()1009 DkSettingsManager::DkSettingsManager() {
1010
1011 mParams = new DkSettings();
1012 }
1013
instance()1014 DkSettingsManager& DkSettingsManager::instance() {
1015 static DkSettingsManager inst;
1016 return inst;
1017 }
1018
~DkSettingsManager()1019 DkSettingsManager::~DkSettingsManager() {
1020
1021 if (mParams) {
1022 delete mParams;
1023 mParams = 0;
1024 }
1025 }
1026
param()1027 DkSettings& DkSettingsManager::param() {
1028 return instance().settings();
1029 }
1030
settings()1031 DkSettings& DkSettingsManager::settings() {
1032 return *mParams;
1033 }
1034
init()1035 void DkSettingsManager::init() {
1036
1037 // init settings
1038 param().initFileFilters();
1039 DefaultSettings settings;
1040
1041 param().load(settings, true); // load defaults
1042
1043 int mode = settings.value("AppSettings/appMode", param().app().appMode).toInt();
1044 param().app().currentAppMode = mode;
1045
1046 // init debug
1047 DkUtils::initializeDebug();
1048
1049 if (nmc::DkSettingsManager::param().app().useLogFile)
1050 std::cout << "log is saved to: " << nmc::DkUtils::getLogFilePath().toStdString() << std::endl;
1051
1052 qInfo() << "Hi there";
1053 qInfoClean() << "my name is " << QApplication::organizationName() << " | " << QApplication::applicationName()
1054 << " v" << QApplication::applicationVersion() << (nmc::DkSettingsManager::param().isPortable() ? " (portable)" : " (installed)");
1055 }
1056
importSettings(const QString & settingsPath)1057 void DkSettingsManager::importSettings(const QString & settingsPath) {
1058
1059 QSettings settings(settingsPath, QSettings::IniFormat);
1060 param().load(settings);
1061 param().save(true);
1062
1063 qInfo() << "settings imported...";
1064 }
1065
1066 // -------------------------------------------------------------------- DkFileFilterHandling
registerFileAssociations()1067 void DkFileFilterHandling::registerFileAssociations() {
1068
1069 DkFileFilterHandling fh;
1070
1071 // register file associations
1072 QStringList rFilters = DkSettingsManager::param().app().openFilters;
1073
1074 // do not register containers such as *.pptx *.zip
1075 for (const QString& filter : DkSettingsManager::param().app().containerFilters)
1076 rFilters.removeAll(filter);
1077
1078 for (const QString& filter : rFilters) {
1079
1080 // remove the icon file -> otherwise icons might be destroyed (e.g. acrobat)
1081 if (!filter.contains("ico")) {
1082 fh.registerFileType(filter, QObject::tr("Image"), true);
1083 qInfo() << "registering" << filter;
1084 }
1085 }
1086
1087 qInfo() << "files registered...";
1088
1089 }
1090
registerNomacs(bool showDefaultApps)1091 void DkFileFilterHandling::registerNomacs(bool showDefaultApps) {
1092
1093 #ifdef Q_OS_WIN
1094
1095 // do not register if nomacs is portable
1096 if (DkSettingsManager::param().isPortable() && !showDefaultApps)
1097 return;
1098
1099 // TODO: this is still not working for me on win8??
1100 QString capName = "Capabilities";
1101 QString capPath = "Software\\" + QApplication::organizationName() + "\\" + QApplication::applicationName() + "\\" + capName;
1102 QSettings settings("HKEY_CURRENT_USER\\" + capPath, QSettings::NativeFormat);
1103
1104 settings.setValue("ApplicationDescription", QObject::tr("nomacs - Image Lounge is a lightweight image viewer."));
1105 settings.setValue("ApplicationName", QApplication::organizationName() + " " + QApplication::applicationName());
1106 settings.setValue("ApplicationIcon", QApplication::applicationFilePath() + ",0");
1107
1108 settings.beginGroup("FileAssociations");
1109 QStringList rFilters = DkSettingsManager::param().app().openFilters;
1110
1111 for (int idx = 0; idx < DkSettingsManager::param().app().containerFilters.size(); idx++)
1112 rFilters.removeAll(DkSettingsManager::param().app().containerFilters.at(idx));
1113
1114 for (int idx = 0; idx < rFilters.size(); idx++) {
1115
1116 // remove the icon file -> otherwise icons might be destroyed (e.g. acrobat)
1117 if (!rFilters.at(idx).contains("ico")) {
1118 QStringList extList = getExtensions(rFilters.at(idx));
1119
1120 for (QString cExt : extList)
1121 settings.setValue(cExt, "nomacs" + cExt + ".3");
1122 }
1123 }
1124 settings.endGroup();
1125
1126 QString softwarePath = "HKEY_CURRENT_USER\\Software\\";
1127 QSettings wsettings(softwarePath, QSettings::NativeFormat);
1128
1129 wsettings.beginGroup("RegisteredApplications");
1130 wsettings.setValue("nomacs.ImageLounge." + QApplication::applicationVersion(), capPath);
1131 wsettings.endGroup();
1132
1133 qDebug() << "nomacs registered ============================";
1134
1135 if (showDefaultApps) {
1136 showDefaultSoftware();
1137 }
1138 #endif
1139
1140 }
1141
showDefaultSoftware() const1142 void DkFileFilterHandling::showDefaultSoftware() const {
1143
1144 #ifdef Q_OS_WIN
1145 IApplicationActivationManager* manager = 0;
1146 CoCreateInstance(CLSID_ApplicationActivationManager,
1147 0,
1148 CLSCTX_LOCAL_SERVER,
1149 IID_IApplicationActivationManager,
1150 (LPVOID*)&manager);
1151
1152 if (manager) {
1153 DWORD pid = GetCurrentProcessId();
1154 manager->ActivateApplication(
1155 L"windows.immersivecontrolpanel_cw5n1h2txyewy"
1156 L"!microsoft.windows.immersivecontrolpanel",
1157 L"page=SettingsPageAppsDefaults", AO_NONE, &pid);
1158 qDebug() << "launching application registration...";
1159 }
1160 #endif
1161 }
1162
registerProgID(const QString & ext,const QString & friendlyName,bool add)1163 QString DkFileFilterHandling::registerProgID(const QString& ext, const QString& friendlyName, bool add) {
1164
1165 #ifdef Q_OS_WIN
1166
1167 QString nomacsPath = "HKEY_CURRENT_USER\\SOFTWARE\\Classes\\";
1168 QString nomacsKey = "nomacs" + ext + ".3";
1169
1170 QSettings settings(nomacsPath, QSettings::NativeFormat);
1171
1172 if (add) {
1173
1174 QString iconID = getIconID(ext);
1175
1176 settings.beginGroup(nomacsKey);
1177 settings.setValue("Default", friendlyName);
1178 //settings.setValue("AppUserModelID", "nomacs.ImageLounge");
1179 //settings.setValue("EditFlags", 1);
1180 //settings.setValue("CurVer", nomacsKey);
1181 settings.beginGroup("DefaultIcon");
1182 settings.setValue("Default",QDir::toNativeSeparators(QCoreApplication::applicationFilePath()) + "," + iconID);
1183 settings.endGroup();
1184 settings.beginGroup("shell");
1185 settings.beginGroup("open");
1186 settings.beginGroup("command");
1187 settings.setValue("Default", "\"" + QDir::toNativeSeparators(QCoreApplication::applicationFilePath()) + "\" \"%1\"");
1188 settings.endGroup();
1189 settings.endGroup();
1190 settings.endGroup();
1191
1192 //qDebug() << nomacsKey << " written";
1193 }
1194 else
1195 settings.remove(nomacsKey);
1196
1197 return nomacsKey;
1198 #else
1199 return QString();
1200 #endif
1201 }
1202
getIconID(const QString & ext) const1203 QString DkFileFilterHandling::getIconID(const QString& ext) const {
1204
1205 //qDebug() << "ID: " << ext;
1206 if (ext.contains(".jpg") || ext.contains(".jpeg")) {
1207 return "1";
1208 }
1209 else if (ext.contains(".gif") || ext.contains(".mng")) {
1210 return "2";
1211 }
1212 else if (ext.contains(".png")) {
1213 return "3";
1214 }
1215 else if (ext.contains(".tif") || ext.contains(".tiff") || ext.contains(".bmp") || ext.contains(".pgm") || ext.contains(".webp")) {
1216 return "4";
1217 }
1218 else if (!DkSettingsManager::param().app().rawFilters.filter(ext).empty()) {
1219 return "5";
1220 }
1221 else
1222 return "0";
1223 }
1224
registerExtension(const QString & ext,const QString & progKey,bool add)1225 void DkFileFilterHandling::registerExtension(const QString& ext, const QString& progKey, bool add) {
1226
1227 #ifdef Q_OS_WIN
1228
1229 QSettings settings2("HKEY_CURRENT_USER\\SOFTWARE\\Classes\\", QSettings::NativeFormat);
1230 settings2.beginGroup(ext);
1231 //if (add)
1232 // settings2.setValue("Default", progKey);
1233 settings2.beginGroup("OpenWithProgIds");
1234 //settings.beginGroup("nomacs.exe");
1235
1236 if (add)
1237 settings2.setValue(progKey, ""); // tell system that nomacs can handle this file type
1238 else
1239 settings2.remove(progKey);
1240 #endif
1241 }
1242
registerFileType(const QString & filterString,const QString & attribute,bool add)1243 void DkFileFilterHandling::registerFileType(const QString& filterString, const QString& attribute, bool add) {
1244
1245 #ifdef Q_OS_WIN
1246
1247 if (DkSettingsManager::param().app().privateMode)
1248 return;
1249
1250 QString friendlyName;
1251 QStringList extList = getExtensions(filterString, friendlyName);
1252 friendlyName += attribute;
1253
1254 // register a new progID
1255 QString progKey = registerProgID(extList.at(0), friendlyName, add);
1256
1257 // register the extension
1258 for (int idx = 0; idx < extList.size(); idx++) {
1259
1260 //qDebug() << "registering: " << extList.at(idx);
1261
1262 registerExtension(extList.at(idx), progKey, add);
1263 registerDefaultApp(extList.at(idx), progKey, add);
1264 setAsDefaultApp(extList.at(idx), progKey, add); // this is not working on Win8
1265 }
1266
1267 #endif
1268 }
1269
getExtensions(const QString & filter) const1270 QStringList DkFileFilterHandling::getExtensions(const QString& filter) const {
1271
1272 QString dummy;
1273 return getExtensions(filter, dummy);
1274 }
1275
getExtensions(const QString & filter,QString & friendlyName) const1276 QStringList DkFileFilterHandling::getExtensions(const QString& filter, QString& friendlyName) const {
1277
1278 QStringList tmp = filter.split("(");
1279
1280 if (tmp.size() != 2) {
1281 qDebug() << "WARNING: wrong filter string!";
1282 return QStringList();
1283 }
1284
1285 friendlyName = tmp.at(0);
1286 QString filters = tmp.at(1);
1287 filters.replace(")", "");
1288 filters.replace("*", "");
1289
1290 QStringList extList = filters.split(" ");
1291
1292 if (extList.empty()) {
1293 qDebug() << "nothing to do here, not registering: " << filter;
1294 return QStringList();
1295 }
1296
1297 return extList;
1298 }
1299
registerDefaultApp(const QString & ext,const QString &,bool add)1300 void DkFileFilterHandling::registerDefaultApp(const QString& ext, const QString&, bool add) {
1301
1302 #ifdef Q_OS_WIN
1303
1304 QSettings settings("HKEY_CURRENT_USER\\Software\\Classes\\Applications\\nomacs.exe", QSettings::NativeFormat);
1305
1306 if (add) {
1307 settings.beginGroup("SupportedTypes");
1308 settings.setValue(ext, "");
1309 //qDebug() << ext << "registered...";
1310 }
1311 else
1312 settings.remove(ext);
1313 #endif
1314
1315 }
1316
setAsDefaultApp(const QString & ext,const QString & progKey,bool add)1317 void DkFileFilterHandling::setAsDefaultApp(const QString& ext, const QString& progKey, bool add) {
1318
1319 #ifdef Q_OS_WIN
1320
1321 QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts", QSettings::NativeFormat);
1322 settings.beginGroup(ext);
1323
1324 if (add) {
1325 // windows 7 only
1326 settings.beginGroup("UserChoice");
1327 settings.setValue("ProgId", progKey);
1328 settings.endGroup();
1329
1330 settings.beginGroup("OpenWithProgids");
1331 settings.setValue("nomacs" + ext + ".3","");
1332 //qDebug() << "default app set";
1333 }
1334 else
1335 settings.setValue("Default", "");
1336 #endif
1337
1338 }
1339
1340 // -------------------------------------------------------------------- DefaultSettings
1341 #ifdef Q_OS_WIN
1342 // read the settings from a file on Windows
DefaultSettings()1343 DefaultSettings::DefaultSettings() : QSettings(DkSettingsManager::instance().param().settingsPath(), QSettings::IniFormat) {}
1344 #else
DefaultSettings()1345 DefaultSettings::DefaultSettings() : QSettings() {}
1346 #endif
1347
1348 // -------------------------------------------------------------------- DkThemeManager
getAvailableThemes() const1349 QStringList DkThemeManager::getAvailableThemes() const {
1350
1351 QDir td(themeDir());
1352 td.setNameFilters(QStringList() << "*.css");
1353
1354 QStringList themes = td.entryList(QDir::Files, QDir::Name);
1355
1356 return themes;
1357 }
1358
getCurrentThemeName() const1359 QString DkThemeManager::getCurrentThemeName() const {
1360 return DkSettingsManager::param().display().themeName;
1361 }
1362
themeDir() const1363 QString DkThemeManager::themeDir() const {
1364
1365 QStringList paths;
1366 paths << QCoreApplication::applicationDirPath();
1367 paths << QStandardPaths::standardLocations(QStandardPaths::DataLocation);
1368
1369 QDir themeDir;
1370
1371 for (const QString& p : paths) {
1372 themeDir = QDir(p + QDir::separator() + "themes");
1373
1374 if (themeDir.exists())
1375 break;
1376 }
1377
1378 return themeDir.absolutePath();
1379 }
1380
setCurrentTheme(const QString & themeName) const1381 void DkThemeManager::setCurrentTheme(const QString & themeName) const {
1382 DkSettingsManager::param().display().themeName = themeName;
1383 }
1384
loadTheme(const QString & themeName) const1385 QString DkThemeManager::loadTheme(const QString & themeName) const {
1386
1387 QString cssString;
1388 QFileInfo tfi(themeDir(), themeName);
1389 QFile theme(tfi.absoluteFilePath());
1390
1391 if (theme.open(QFile::ReadOnly)) {
1392
1393 QString ts = theme.readAll();
1394 cssString = parseColors(ts);
1395 cssString = cssString.trimmed();
1396
1397 qInfo() << "theme loaded from" << tfi.absoluteFilePath();
1398 }
1399 else
1400 qInfo() << "could not load theme from" << tfi.absoluteFilePath();
1401
1402 return cssString;
1403 }
1404
loadStylesheet() const1405 QString DkThemeManager::loadStylesheet() const {
1406
1407 QString cssString;
1408
1409 QFileInfo cssInfo(":/nomacs/stylesheet.css");
1410 QFile file(cssInfo.absoluteFilePath());
1411
1412 if (file.open(QFile::ReadOnly)) {
1413
1414 cssString = file.readAll();
1415 cssString = replaceColors(cssString);
1416
1417 qInfo() << "CSS loaded from: " << cssInfo.absoluteFilePath();
1418 }
1419
1420 file.close();
1421
1422 return cssString;
1423 }
1424
applyTheme() const1425 void DkThemeManager::applyTheme() const {
1426
1427 // add theme
1428 QString cssString = loadTheme(getCurrentThemeName());
1429
1430 DkSettings::Display& dp = DkSettingsManager::param().display();
1431
1432 // NOTE: it is important, that default.css does not contain
1433 // any line of code except for the color definitions
1434 // otherwise, we change the default palette here...
1435 if (!cssString.isEmpty()) {
1436
1437 cssString = replaceColors(cssString);
1438
1439 QPalette p = qApp->palette();
1440
1441 if (dp.themeBgdColor != QPalette().color(QPalette::Window)) {
1442 p.setColor(QPalette::Window, dp.themeBgdColor);
1443 p.setColor(QPalette::Base, dp.themeBgdColor);
1444 }
1445
1446 p.setColor(QPalette::WindowText, dp.themeFgdColor);
1447 p.setColor(QPalette::ButtonText, dp.themeFgdColor);
1448
1449 //p.setColor(QPalette::Button, QColor(0, 0, 0));
1450
1451 qApp->setPalette(p);
1452 }
1453
1454 QString cs = loadStylesheet();
1455 cs += cssString;
1456
1457 qApp->setStyleSheet(cs);
1458 }
1459
cleanThemeName(const QString & theme) const1460 QString DkThemeManager::cleanThemeName(const QString & theme) const {
1461
1462 QString t = theme;
1463 t = t.replace(".css", "");
1464 t = t.replace("-", " ");
1465
1466 return t;
1467 }
1468
cleanThemeNames(const QStringList & themes) const1469 QStringList DkThemeManager::cleanThemeNames(const QStringList & themes) const {
1470
1471 QStringList ctn;
1472
1473 for (const QString& t : themes)
1474 ctn << cleanThemeName(t);
1475
1476 return ctn;
1477 }
1478
parseColors(const QString & styleSheet) const1479 QString DkThemeManager::parseColors(const QString & styleSheet) const {
1480
1481 QStringList cs = styleSheet.split("--nomacs-color-def");
1482
1483 if (cs.size() == 3) {
1484
1485 // we expect something like this:
1486 /* overload color settings of nomacs */
1487 // --nomacs-color-def
1488 // HIGHLIGHT_COLOR: #ff0;
1489 // WINDOW_COLOR: #333;
1490 // --nomacs-color-def
1491 QStringList cols = cs[1].split(";");
1492
1493 for (auto str : cols) {
1494
1495 str = str.simplified();
1496
1497 // igonre blanks
1498 if (str.isEmpty())
1499 continue;
1500
1501 QStringList kv = str.split(":");
1502
1503 if (kv.size() != 2) {
1504 qWarning() << "could not parse color from" << str;
1505 qWarning() << "I expected a line like this: HUD_BACKGROUND_COLOR: #f00;";
1506 continue;
1507 }
1508
1509 QString cc = kv[1].simplified();
1510
1511 if (kv[0] == "HIGHLIGHT_COLOR" && cc != "default")
1512 DkSettingsManager::param().display().highlightColor.setNamedColor(cc);
1513 else if (kv[0] == "HUD_BACKGROUND_COLOR" && cc != "default")
1514 DkSettingsManager::param().display().hudBgColor.setNamedColor(cc);
1515 else if (kv[0] == "HUD_FOREGROUND_COLOR" && cc != "default")
1516 DkSettingsManager::param().display().hudFgdColor.setNamedColor(cc);
1517 else if (kv[0] == "BACKGROUND_COLOR") {
1518
1519 QColor c;
1520 c.setNamedColor(cc);
1521
1522 if (cc == "default")
1523 c = QPalette().color(QPalette::Window);
1524
1525 if (DkSettingsManager::param().display().defaultBackgroundColor)
1526 DkSettingsManager::param().display().bgColor = c;
1527 DkSettingsManager::param().display().themeBgdColor = c;
1528 }
1529 else if (kv[0] == "FOREGROUND_COLOR" && cc != "default")
1530 DkSettingsManager::param().display().themeFgdColor.setNamedColor(cc);
1531 else if (kv[0] == "ICON_COLOR" && cc != "default") {
1532 if (DkSettingsManager::param().display().defaultIconColor)
1533 DkSettingsManager::param().display().iconColor.setNamedColor(cc);
1534 }
1535 else if (cc != "default")
1536 qWarning() << "could not parse color:" << str;
1537 }
1538
1539 return cs[0] + cs[2];
1540 }
1541
1542 return styleSheet;
1543 }
1544
replaceColors(const QString & cssString) const1545 QString DkThemeManager::replaceColors(const QString & cssString) const {
1546
1547 QString cs = cssString;
1548
1549 QColor hc = DkSettingsManager::param().display().highlightColor;
1550 hc.setAlpha(150);
1551
1552 // replace color placeholders
1553 cs.replace("HIGHLIGHT_COLOR", DkUtils::colorToString(DkSettingsManager::param().display().highlightColor));
1554 cs.replace("HIGHLIGHT_LIGHT", DkUtils::colorToString(hc));
1555 cs.replace("HUD_BACKGROUND_COLOR", DkUtils::colorToString(DkSettingsManager::param().display().hudBgColor));
1556 cs.replace("HUD_FOREGROUND_COLOR", DkUtils::colorToString(DkSettingsManager::param().display().hudFgdColor));
1557 cs.replace("BACKGROUND_COLOR", DkUtils::colorToString(DkSettingsManager::param().display().bgColor));
1558 cs.replace("FOREGROUND_COLOR", DkUtils::colorToString(DkSettingsManager::param().display().themeFgdColor));
1559 cs.replace("WINDOW_COLOR", DkUtils::colorToString(QPalette().color(QPalette::Window)));
1560
1561 return cs;
1562 }
1563
1564 // -------------------------------------------------------------------- DkZoomConfig
DkZoomConfig()1565 DkZoomConfig::DkZoomConfig() {
1566
1567 mLevels = defaultLevels();
1568
1569 DefaultSettings ds;
1570 loadSettings(ds);
1571 }
1572
instance()1573 DkZoomConfig& DkZoomConfig::instance() {
1574 static DkZoomConfig inst;
1575 return inst;
1576 }
1577
~DkZoomConfig()1578 DkZoomConfig::~DkZoomConfig() {
1579
1580 DefaultSettings ds;
1581 saveSettings(ds);
1582 }
1583
nextFactor(double currentFactor,double delta) const1584 double DkZoomConfig::nextFactor(double currentFactor, double delta) const {
1585
1586 // do nothing?
1587 if (!mUseLevels)
1588 return delta;
1589
1590 assert(currentFactor != 0.0);
1591
1592 if (currentFactor == 0.0)
1593 return 1.0;
1594
1595 if (delta > 1) {
1596 for (double l : mLevels) {
1597
1598 if (currentFactor < l) {
1599 return l / currentFactor;
1600 }
1601 }
1602 }
1603 else if (delta < 1) {
1604
1605 for (int idx = mLevels.size() - 1; idx >= 0; idx--) {
1606
1607 if (currentFactor > mLevels[idx]) {
1608 return mLevels[idx] / currentFactor;
1609 }
1610 }
1611 }
1612
1613 // do nothing
1614 return 1.0;
1615 }
1616
defaultLevels() const1617 QVector<double> DkZoomConfig::defaultLevels() const {
1618
1619 QVector<double> levels;
1620
1621 levels << 0.0001;
1622 levels << 0.001;
1623 levels << 0.01;
1624 levels << 0.05;
1625 levels << 0.1;
1626 levels << 0.125;
1627 levels << 0.166;
1628 levels << 0.25;
1629 levels << 0.333;
1630 levels << 0.5;
1631 levels << 0.66;
1632 levels << 1;
1633 levels << 1.5;
1634 levels << 2;
1635 levels << 3;
1636 levels << 4;
1637 levels << 5;
1638 levels << 6;
1639 levels << 7;
1640 levels << 8;
1641 levels << 12;
1642 levels << 16;
1643 levels << 32;
1644 levels << 64;
1645 levels << 128;
1646
1647 return levels;
1648 }
1649
useLevels() const1650 bool DkZoomConfig::useLevels() const {
1651 return mUseLevels;
1652 }
1653
setUseLevels(bool useLevels)1654 void DkZoomConfig::setUseLevels(bool useLevels) {
1655 mUseLevels = useLevels;
1656 }
1657
setLevels(const QString & levelStr)1658 bool DkZoomConfig::setLevels(const QString & levelStr) {
1659
1660 QVector<double> levels;
1661 QStringList levelList = levelStr.split(",");
1662
1663 bool ok = false;
1664 for (const QString& s : levelList) {
1665 levels << s.toDouble(&ok);
1666 if (!ok)
1667 break;
1668 }
1669
1670 if (ok && checkLevels(levels)) {
1671 mLevels = levels;
1672 return true;
1673 }
1674
1675 return false;
1676 }
1677
levelsToString() const1678 QString DkZoomConfig::levelsToString() const {
1679
1680 QStringList levelStr;
1681 for (double l : mLevels)
1682 levelStr << QString::number(l);
1683
1684 return levelStr.join(",");
1685 }
1686
setLevelsToDefault()1687 void DkZoomConfig::setLevelsToDefault() {
1688
1689 mLevels = defaultLevels();
1690 }
1691
checkLevels(const QVector<double> & levels)1692 bool DkZoomConfig::checkLevels(const QVector<double>& levels) {
1693
1694 if (levels.isEmpty())
1695 return false;
1696
1697 double last = 0;
1698
1699 // levels must be monotonically increasing
1700 for (double l : levels) {
1701 if (l < last)
1702 return false;
1703 }
1704
1705 return true;
1706 }
1707
loadSettings(QSettings & settings)1708 void DkZoomConfig::loadSettings(QSettings & settings) {
1709
1710 settings.beginGroup("zooming");
1711 QString levelStr = settings.value("zoomLevels").toString();
1712 mUseLevels = settings.value("useLevels").toBool();
1713 settings.endGroup();
1714
1715 if (!setLevels(levelStr))
1716 qWarning() << "illegal zoom levels when loading from settings:" << levelStr;
1717 }
1718
saveSettings(QSettings & settings) const1719 void DkZoomConfig::saveSettings(QSettings & settings) const {
1720
1721 settings.beginGroup("zooming");
1722 settings.setValue("zoomLevels", levelsToString());
1723 settings.setValue("useLevels", mUseLevels);
1724 settings.endGroup();
1725 }
1726
1727 }
1728