1 /*
2 * This file is part of RawTherapee.
3 *
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
5 *
6 * RawTherapee is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * RawTherapee is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "options.h"
20 #include <cstdio>
21 #include <glib/gstdio.h>
22 #include <sstream>
23 #include <iostream>
24 #include "multilangmgr.h"
25 #include "addsetids.h"
26 #include "guiutils.h"
27 #include "version.h"
28 #include "../rtengine/metadata.h"
29
30 #ifdef _OPENMP
31 #include <omp.h>
32 #endif
33
34
35
36 #ifdef WIN32
37 #include <windows.h>
38 // for GCC32
39 #ifndef _WIN32_IE
40 #define _WIN32_IE 0x0600
41 #endif
42 #include <Shlobj.h>
43 #endif
44
45 // User's settings directory, including images' profiles if used
46 Glib::ustring Options::rtdir;
47 // User's cached datas' directory
48 Glib::ustring Options::cacheBaseDir;
49
50 Options options;
51 Glib::ustring versionString = RTVERSION;
52 Glib::ustring paramFileExtension = ".arp";
53
54
RenameOptions()55 Options::RenameOptions::RenameOptions()
56 {
57 pattern = "%f.%e";
58 sidecars = "";
59 name_norm = 0;
60 ext_norm = 0;
61 allow_whitespace = false;
62 on_existing = 0;
63 progressive_number = 1;
64 }
65
66
Options()67 Options::Options()
68 {
69 defProfError = 0;
70 setDefaults();
71 }
72
73 const char *DefaultLanguage = "English (US)";
74
checkProfilePath(Glib::ustring & path)75 inline bool Options::checkProfilePath(Glib::ustring &path)
76 {
77 if (path.empty()) {
78 return false;
79 }
80
81 Glib::ustring p = getUserProfilePath();
82
83 if (!p.empty() && Glib::file_test(path + paramFileExtension, Glib::FILE_TEST_EXISTS)) {
84 return true;
85 }
86
87 p = getGlobalProfilePath();
88
89 return !p.empty() && Glib::file_test(path + paramFileExtension, Glib::FILE_TEST_EXISTS);
90 }
91
checkDirPath(Glib::ustring & path,Glib::ustring errString)92 bool Options::checkDirPath(Glib::ustring &path, Glib::ustring errString)
93 {
94 if (Glib::file_test(path, Glib::FILE_TEST_EXISTS) && Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) {
95 return true;
96 } else {
97 if (!errString.empty()) {
98 std::cerr << errString << std::endl;
99 }
100
101 return false;
102 }
103 }
104
updatePaths()105 void Options::updatePaths()
106 {
107
108 Glib::ustring tmpPath;
109
110 userProfilePath = "";
111 globalProfilePath = "";
112
113 if (Glib::path_is_absolute(profilePath)) {
114 // absolute path
115 if (!checkDirPath(profilePath, "")) {
116 g_mkdir_with_parents(profilePath.c_str(), 511);
117
118 if (!checkDirPath(profilePath, "")) { // had problems with mkdir_with_parents return value on OS X, just check dir again
119 Glib::ustring msg = Glib::ustring::compose("Creation of the user's processing profile directory \"%1\" failed!\n", profilePath);
120 throw Error(msg);
121 }
122 }
123
124 if (checkDirPath(profilePath, "Error: the user's processing profile path doesn't point to a directory or doesn't exist!\n")) {
125 userProfilePath = profilePath;
126 tmpPath = Glib::build_filename(argv0, "profiles");
127
128 if (checkDirPath(tmpPath, "Error: the global's processing profile path doesn't point to a directory or doesn't exist!\n")) {
129 if (userProfilePath != tmpPath) {
130 globalProfilePath = tmpPath;
131 }
132 }
133 } else {
134 tmpPath = Glib::build_filename(argv0, "profiles");
135
136 if (checkDirPath(tmpPath, "Error: the global's processing profile path doesn't point to a directory or doesn't exist!\n")) {
137 globalProfilePath = tmpPath;
138 }
139 }
140 } else {
141 // relative paths
142 tmpPath = Glib::build_filename(rtdir, profilePath);
143
144 if (!checkDirPath(tmpPath, "")) {
145 g_mkdir_with_parents(tmpPath.c_str(), 511);
146
147 if (!checkDirPath(tmpPath, "")) {
148 Glib::ustring msg = Glib::ustring::compose("Creation of the user's processing profile directory \"%1\" failed!\n", tmpPath.c_str());
149 throw Error(msg);
150 }
151 }
152
153 if (checkDirPath(tmpPath, "Error: the user's processing profile path doesn't point to a directory!\n")) {
154 userProfilePath = tmpPath;
155 }
156
157 tmpPath = Glib::build_filename(argv0, "profiles");
158
159 if (checkDirPath(tmpPath, "Error: the user's processing profile path doesn't point to a directory or doesn't exist!\n")) {
160 globalProfilePath = tmpPath;
161 }
162 }
163
164 Glib::ustring preferredPath = getPreferredProfilePath();
165
166 // Paths are updated only if the user or global profile path is set
167 if (lastRgbCurvesDir.empty() || !Glib::file_test(lastRgbCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastRgbCurvesDir, Glib::FILE_TEST_IS_DIR)) {
168 lastRgbCurvesDir = preferredPath;
169 }
170
171 if (lastLabCurvesDir.empty() || !Glib::file_test(lastLabCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastLabCurvesDir, Glib::FILE_TEST_IS_DIR)) {
172 lastLabCurvesDir = preferredPath;
173 }
174
175 if (lastPFCurvesDir.empty() || !Glib::file_test(lastPFCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastPFCurvesDir, Glib::FILE_TEST_IS_DIR)) {
176 lastPFCurvesDir = preferredPath;
177 }
178
179 if (lastHsvCurvesDir.empty() || !Glib::file_test(lastHsvCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastHsvCurvesDir, Glib::FILE_TEST_IS_DIR)) {
180 lastHsvCurvesDir = preferredPath;
181 }
182
183 if (lastToneCurvesDir.empty() || !Glib::file_test(lastToneCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastToneCurvesDir, Glib::FILE_TEST_IS_DIR)) {
184 lastToneCurvesDir = preferredPath;
185 }
186
187 if (lastProfilingReferenceDir.empty() || !Glib::file_test(lastProfilingReferenceDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastProfilingReferenceDir, Glib::FILE_TEST_IS_DIR)) {
188 lastProfilingReferenceDir = preferredPath;
189 }
190
191 if (loadSaveProfilePath.empty() || !Glib::file_test(loadSaveProfilePath, Glib::FILE_TEST_EXISTS) || !Glib::file_test(loadSaveProfilePath, Glib::FILE_TEST_IS_DIR)) {
192 loadSaveProfilePath = preferredPath;
193 }
194
195 if (lastICCProfCreatorDir.empty() || !Glib::file_test(lastICCProfCreatorDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastICCProfCreatorDir, Glib::FILE_TEST_IS_DIR)) {
196 lastICCProfCreatorDir = preferredPath;
197 }
198 }
199
getPreferredProfilePath()200 Glib::ustring Options::getPreferredProfilePath()
201 {
202 if (!userProfilePath.empty()) {
203 return userProfilePath;
204 } else if (!globalProfilePath.empty()) {
205 return globalProfilePath;
206 } else {
207 return "";
208 }
209 }
210
211 /** @brief Get the absolute path of the given filename or the "Neutral" special value
212 *
213 *@param profName path + filename of the procparam to look for. A filename without path can be provided for backward compatibility.
214 * In this case, this parameter will be updated with the new format.
215 *@return Send back the absolute path of the given filename or "Neutral" if "Neutral" has been set to profName. Implementor will have
216 * to test for this particular value. If the absolute path is invalid (e.g. the file doesn't exist), it will return an empty string.
217 */
findProfilePath(Glib::ustring & profName)218 Glib::ustring Options::findProfilePath(Glib::ustring &profName)
219 {
220 if (profName.empty()) {
221 return "";
222 }
223
224 if (profName == DEFPROFILE_INTERNAL) {
225 return profName;
226 }
227
228 if (profName == DEFPROFILE_DYNAMIC) {
229 return profName;
230 }
231
232 Glib::ustring p = profName.substr(0, 4);
233
234 if (p == "${U}") {
235 // the path starts by the User virtual path
236 p = getUserProfilePath();
237 Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension);
238
239 if (!p.empty() && Glib::file_test(fullPath, Glib::FILE_TEST_EXISTS)) {
240 return Glib::path_get_dirname(fullPath);
241 }
242 } else if (p == "${G}") {
243 // the path starts by the User virtual path
244 p = getGlobalProfilePath();
245 Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension);
246
247 if (!p.empty() && Glib::file_test(fullPath, Glib::FILE_TEST_EXISTS)) {
248 return Glib::path_get_dirname(fullPath);
249 }
250 } else {
251 // compatibility case -> convert the path to the new format
252 p = getUserProfilePath();
253 Glib::ustring fullPath = Glib::build_filename(p, profName + paramFileExtension);
254
255 if (!p.empty() && Glib::file_test(fullPath, Glib::FILE_TEST_EXISTS)) {
256 // update the profile path
257 profName = Glib::build_filename("${U}", profName);
258 return Glib::path_get_dirname(fullPath);
259 }
260
261 p = getGlobalProfilePath();
262 fullPath = Glib::build_filename(p, profName + paramFileExtension);
263
264 if (!p.empty() && Glib::file_test(fullPath, Glib::FILE_TEST_EXISTS)) {
265 profName = Glib::build_filename("${G}", profName);
266 return Glib::path_get_dirname(fullPath);
267 }
268 }
269
270 return "";
271
272 }
273
setDefaults()274 void Options::setDefaults()
275 {
276 windowWidth = 1200;
277 windowHeight = 680;
278 windowX = 0;
279 windowY = 0;
280 windowMaximized = true;
281 windowMonitor = 0;
282 meowMonitor = -1;
283 meowFullScreen = false;
284 meowMaximized = true;
285 meowWidth = 1200;
286 meowHeight = 680;
287 meowX = 0;
288 meowY = 0;
289 saveAsDialogWidth = 920;
290 saveAsDialogHeight = 680;
291 saveFormat.format = "jpg";
292 saveFormat.jpegQuality = 92;
293 saveFormat.jpegSubSamp = 2;
294 saveFormat.pngBits = 8;
295 saveFormat.tiffBits = 16;
296 saveFormat.tiffFloat = false;
297 saveFormat.tiffUncompressed = true;
298 saveFormat.saveParams = true;
299
300 saveFormatBatch.format = "jpg";
301 saveFormatBatch.jpegQuality = 92;
302 saveFormatBatch.jpegSubSamp = 2;
303 saveFormatBatch.pngBits = 8;
304 saveFormatBatch.tiffBits = 16;
305 saveFormatBatch.tiffFloat = false;
306 saveFormatBatch.tiffUncompressed = true;
307 saveFormatBatch.saveParams = true;
308
309 savePathTemplate = "%p1/converted/%f";
310 savePathFolder = "";
311 saveUsePathTemplate = true;
312 defProfRaw = DEFPROFILE_RAW;
313 defProfImg = DEFPROFILE_IMG;
314 dateFormat = "%Y-%m-%d";
315 adjusterMinDelay = 100;
316 adjusterMaxDelay = 200;
317 startupDir = STARTUPDIR_LAST;
318 startupPath = "";
319 useBundledProfiles = true;
320 detailWindowWidth = -1;
321 detailWindowHeight = -1;
322 dirBrowserWidth = 260;
323 dirBrowserHeight = 350;
324 dirBrowserSortType = Gtk::SORT_ASCENDING;
325 preferencesWidth = 800;
326 preferencesHeight = 600;
327 toolPanelWidth = 400;
328 browserToolPanelWidth = 465;
329 browserToolPanelHeight = 600;
330 browserToolPanelOpened = true;
331 browserDirPanelOpened = true;
332 editorFilmStripOpened = true;
333 inspectorDirPanelOpened = true;
334 historyPanelWidth = 330;
335 fontFamily = "default";
336 fontSize = 10;
337 CPFontFamily = "default";
338 CPFontSize = 8;
339 pseudoHiDPISupport = false;
340 lastScale = 5;
341 panAccelFactor = 5;
342 rememberZoomAndPan = true;
343 fbShowDateTime = true;
344 fbShowBasicExif = true;
345 fbShowExpComp = false;
346 #ifdef WIN32
347 // use windows setting for visibility of hidden files/folders
348 SHELLFLAGSTATE sft = { 0 };
349 SHGetSettings(&sft, SSF_SHOWALLOBJECTS);
350 fbShowHidden = sft.fShowAllObjects;
351 #else
352 fbShowHidden = false;
353 #endif
354 navRGBUnit = NavigatorUnit::PERCENT;
355 navLCHUnit = NavigatorUnit::PERCENT;
356 multiUser = true;
357 profilePath = "profiles";
358 loadSaveProfilePath = ""; // will be corrected in load as otherwise construction fails
359 lastCopyMovePath = "";
360 version = "0.0.0.0"; // temporary value; will be correctly set in RTWindow::on_realize
361 thumbSize = 160;
362 thumbSizeTab = 160;
363 thumbSizeQueue = 160;
364 sameThumbSize = false; // preferring speed of switch between file browser and single editor tab
365 thumbnailOrder = ThumbnailOrder::FILENAME;
366 showHistory = true;
367 showInfo = true;
368 cropPPI = 600;
369 showClippedHighlights = false;
370 showClippedShadows = false;
371 highlightThreshold = 253; // was 254
372 shadowThreshold = 8; // was 0
373 bgcolor = 1;
374 language = DefaultLanguage;
375 languageAutoDetect = langMgr.isOSLanguageDetectSupported();
376 lastSaveAsPath = "";
377 overwriteOutputFile = false; // if TRUE, existing output JPGs/PNGs are overwritten, instead of adding ..-1.jpg, -2.jpg etc.
378 theme = "RawTherapee";
379 maxThumbnailHeight = 250;
380 maxThumbnailWidth = 800;
381 maxCacheEntries = 20000;
382 thumbInterp = 1;
383 autoSuffix = true;
384 forceFormatOpts = true;
385 saveMethodNum = 0; // 0->immediate, 1->putToQueuHead, 2->putToQueueTail
386 saveParamsFile = true; // was false, but saving the procparams files next to the file make more sense when reorganizing file tree than in a cache
387 saveParamsCache = false; // there's no need to save the procparams files in a cache if saveParamsFile is true
388 paramsLoadLocation = PLL_Input; // was PLL_Cache
389 params_out_embed = false;
390 params_sidecar_strip_extension = false;
391 procQueueEnabled = false;
392 gimpDir = "";
393 psDir = "";
394 customEditorProg = "";
395 CPBKeys = CPBKT_TID;
396 editorToSendTo = 1;
397 editor_out_dir = EDITOR_OUT_DIR_TEMP;
398 editor_custom_out_dir = "";
399 editor_float32 = false;
400 editor_bypass_output_profile = false;
401 favoriteDirs.clear();
402 tpOpen.clear();
403 autoSaveTpOpen = true;
404 //crvOpen.clear ();
405 parseExtensions.clear();
406 favorites.clear();
407 parseExtensionsEnabled.clear();
408 parsedExtensions.clear();
409 parsedExtensionsSet.clear();
410 thumbnailZoomRatios.clear();
411 thumbnailZoomRatios.push_back(0.2);
412 thumbnailZoomRatios.push_back(0.3);
413 thumbnailZoomRatios.push_back(0.45);
414 thumbnailZoomRatios.push_back(0.6);
415 thumbnailZoomRatios.push_back(0.8);
416 thumbnailZoomRatios.push_back(1.0);
417 overlayedFileNames = false;
418 filmStripOverlayedFileNames = false;
419 internalThumbIfUntouched = true; // if TRUE, only fast, internal preview images are taken if the image is not edited yet
420 showFileNames = true;
421 filmStripShowFileNames = false;
422 tabbedUI = false;
423 mainNBVertical = true;
424 multiDisplayMode = 0;
425 histogramPosition = 1;
426 histogramRed = true;
427 histogramGreen = true;
428 histogramBlue = true;
429 histogramLuma = false;
430 histogramChroma = false;
431 //histogramRAW = false;
432 histogramBar = true;
433 histogramHeight = 200;
434 histogramDrawMode = 0;
435 histogram_scaling_factor = 10.0;
436 histogramScopeType = ScopeType::HISTOGRAM;
437 histogramShowOptionButtons = false;
438 histogramTraceBrightness = 1;
439 curvebboxpos = 1;
440 prevdemo = PD_Sidecar;
441 rgbDenoiseThreadLimit = 0;
442 #if defined( _OPENMP ) && defined( __x86_64__ )
443 clutCacheSize = omp_get_num_procs();
444 #else
445 clutCacheSize = 1;
446 #endif
447 thumb_update_thread_limit = 0;
448 thumb_delay_update = false;
449 thumb_lazy_caching = true;
450 filledProfile = false;
451 maxInspectorBuffers = 2; // a rather conservative value for low specced systems...
452 inspectorDelay = 0;
453 serializeTiffRead = true;
454 denoiseZoomedOut = true;
455 wb_preview_mode = WB_BEFORE_HIGH_DETAIL;
456
457 FileBrowserToolbarSingleRow = false;
458 hideTPVScrollbar = false;
459 whiteBalanceSpotSize = 8;
460 showFilmStripToolBar = false;
461 menuGroupRank = true;
462 menuGroupLabel = true;
463 menuGroupFileOperations = true;
464 menuGroupProfileOperations = true;
465 menuGroupExtProg = true;
466
467 ICCPC_primariesPreset = "sRGB",
468 ICCPC_redPrimaryX = 0.6400;
469 ICCPC_redPrimaryY = 0.3300;
470 ICCPC_greenPrimaryX = 0.3000;
471 ICCPC_greenPrimaryY = 0.6000;
472 ICCPC_bluePrimaryX = 0.1500;
473 ICCPC_bluePrimaryY = 0.0600;
474 ICCPC_gammaPreset = "Custom";
475 ICCPC_gamma = 2.4;
476 ICCPC_slope = 12.92;
477 ICCPC_profileVersion = "v4";
478 ICCPC_illuminant = "DEF";
479 ICCPC_description = "";
480 ICCPC_copyright = Options::getICCProfileCopyright();
481 ICCPC_appendParamsToDesc = false;
482
483 fastexport_bypass_sharpening = true;
484 fastexport_bypass_defringe = true;
485 fastexport_bypass_dirpyrDenoise = true;
486 fastexport_bypass_localContrast = true;
487 fastexport_raw_bayer_method = "fast";
488 //fastexport_bypass_raw_bayer_all_enhance = true;
489 fastexport_bypass_raw_bayer_dcb_iterations = true;
490 fastexport_bypass_raw_bayer_dcb_enhance = true;
491 fastexport_bypass_raw_bayer_lmmse_iterations = true;
492 fastexport_bypass_raw_bayer_linenoise = true;
493 fastexport_bypass_raw_bayer_greenthresh = true;
494 fastexport_raw_xtrans_method = "fast";
495 fastexport_bypass_raw_ccSteps = true;
496 fastexport_bypass_raw_ca = true;
497 fastexport_bypass_raw_df = true;
498 fastexport_bypass_raw_ff = true;
499 fastexport_icm_input_profile = "(camera)";
500 fastexport_icm_working_profile = "ProPhoto";
501 fastexport_icm_output_profile = options.rtSettings.srgb;
502 fastexport_icm_outputIntent = rtengine::RI_RELATIVE;
503 fastexport_icm_outputBPC = true;
504 fastexport_resize_enabled = true;
505 fastexport_resize_scale = 1;
506 fastexport_resize_appliesTo = "Cropped area";
507 fastexport_resize_dataspec = 3;
508 fastexport_resize_width = 900;
509 fastexport_resize_height = 900;
510 fastexport_use_fast_pipeline = true;
511
512 clutsDir = "./cluts";
513
514 cutOverlayBrush = std::vector<double> (4);
515 cutOverlayBrush[3] = 0.667; // :-p
516
517 navGuideBrush = std::vector<double> (4);
518 //default to red
519 navGuideBrush[0] = 1.0;
520 navGuideBrush[1] = 0.0;
521 navGuideBrush[2] = 0.0;
522 navGuideBrush[3] = 1.0;
523
524 sndEnable = true;
525 sndLngEditProcDoneSecs = 3.0;
526 #ifdef __linux__
527 sndBatchQueueDone = "complete";
528 sndLngEditProcDone = "window-attention";
529 #endif
530
531 rtSettings.darkFramesPath = "";
532 rtSettings.flatFieldsPath = "";
533 #ifdef WIN32
534 const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows"
535
536 if (sysRoot != NULL) {
537 rtSettings.iccDirectory = Glib::ustring(sysRoot) + Glib::ustring("\\System32\\spool\\drivers\\color");
538 } else {
539 rtSettings.iccDirectory = "C:\\WINDOWS\\System32\\spool\\drivers\\color";
540 }
541
542 #elif defined __APPLE__
543 rtSettings.iccDirectory = "/library/ColorSync/Profiles/Displays";
544 #else
545 rtSettings.iccDirectory = "/usr/share/color/icc";
546 #endif
547
548 rtSettings.monitorIccDirectory = rtSettings.iccDirectory;
549
550 rtSettings.printerProfile = Glib::ustring();
551 rtSettings.printerIntent = rtengine::RI_RELATIVE;
552 rtSettings.printerBPC = true;
553 rtSettings.monitorProfile = Glib::ustring();
554 rtSettings.monitorIntent = rtengine::RI_RELATIVE;
555 rtSettings.monitorBPC = true;
556 rtSettings.autoMonitorProfile = false;
557 rtSettings.adobe = "RTv2_Medium"; // put the name of yours profiles (here windows)
558 rtSettings.prophoto = "RTv2_Large"; // these names appear in the menu "output profile"
559 rtSettings.widegamut = "RTv2_Wide";
560 rtSettings.srgb = "RTv4_sRGB";
561 rtSettings.bruce = "RTv2_Bruce";
562 rtSettings.beta = "RTv2_Beta";
563 rtSettings.best = "RTv2_Best";
564 rtSettings.rec2020 = "RTv2_Rec2020";
565 rtSettings.ACESp0 = "RTv2_ACES-AP0";
566 rtSettings.ACESp1 = "RTv2_ACES-AP1";
567 rtSettings.verbose = false;
568
569 rtSettings.HistogramWorking = false;
570
571 // #4327 - Noise Reduction settings removed from Preferences
572 rtSettings.nrauto = 10; // between 2 and 20
573 rtSettings.nrautomax = 40; // between 5 and 100
574 rtSettings.nrhigh = 0.9;//0.45; // between 0.1 and 0.9
575 rtSettings.nrwavlevel = 2;//1; // integer between 0 and 2
576 rtSettings.leveldnv = 2;
577 rtSettings.leveldnti = 0;
578 rtSettings.leveldnaut = 0;
579 rtSettings.leveldnliss = 0;
580 rtSettings.leveldnautsimpl = 0;
581
582 lastIccDir = rtSettings.iccDirectory;
583 lastDarkframeDir = rtSettings.darkFramesPath;
584 lastFlatfieldDir = rtSettings.flatFieldsPath;
585
586 // There is no reasonable default for curves. We can still suppose that they will take place
587 // in a subdirectory of the user's own ProcParams presets, i.e. in a subdirectory
588 // of the one pointed to by the "profile" field.
589 // The following fields will then be initialized when "profile" will have its final value,
590 // at the end of the "updatePaths" method.
591 lastRgbCurvesDir = "";
592 lastLabCurvesDir = "";
593 lastPFCurvesDir = "";
594 lastHsvCurvesDir = "";
595 lastToneCurvesDir = "";
596 lastProfilingReferenceDir = "";
597 lastLensProfileDir = "";
598 lastICCProfCreatorDir = "";
599 gimpPluginShowInfoDialog = true;
600 maxRecentFolders = 15;
601 rtSettings.lensfunDbDirectory = ""; // set also in main.cc and main-cli.cc
602
603 rtSettings.thumbnail_inspector_mode = rtengine::Settings::ThumbnailInspectorMode::JPEG;
604 rtSettings.thumbnail_inspector_raw_curve = rtengine::Settings::ThumbnailInspectorRawCurve::LINEAR;
605 thumbnail_inspector_zoom_fit = false;
606 thumbnail_inspector_show_info = false;
607 thumbnail_inspector_enable_cms = false;
608 thumbnail_inspector_show_histogram = false;
609 thumbnail_inspector_hover = false;
610
611 thumbnail_rating_mode = Options::ThumbnailRatingMode::XMP;
612 #if defined WIN32 || defined __APPLE__
613 rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle::STD;
614 #else
615 rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle::EXT;
616 #endif
617 rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::READ;
618 rtSettings.exiftool_path = "exiftool";
619 #ifdef WIN32
620 rtSettings.exiftool_path += ".exe";
621 #endif
622
623 browser_width_for_inspector = 0;
624
625 batch_queue_use_profile = false;
626 batch_queue_profile_path = "";
627
628 toolpanels_disable = false;
629 adjuster_force_linear = false;
630
631 error_message_duration = 5000;
632 max_error_messages = 3;
633
634 falseColorsMap = {
635 {2, "#FFFFFF"},
636 {10, "#0000FF"},
637 {20, "#2290FF"},
638 {42, "#4B4B4B"},
639 {48, "#FF11FC"},
640 {52, "#7B7B7B"},
641 {58, "#00FF00"},
642 {78, "#ADADAD"},
643 {84, "#AEAE00"},
644 {94, "#FFFF00"},
645 {100, "#FF7F00"},
646 {108, "#FF0000"}
647 };
648
649 renaming = RenameOptions();
650 sidecar_autosave_interval = 0;
651 }
652
copyFrom(Options * other)653 Options* Options::copyFrom(Options* other)
654 {
655 *this = *other;
656 return this;
657 }
658
filterOutParsedExtensions()659 void Options::filterOutParsedExtensions()
660 {
661 parsedExtensions.clear();
662 parsedExtensionsSet.clear();
663
664 for (unsigned int i = 0; i < parseExtensions.size(); i++)
665 if (parseExtensionsEnabled[i]) {
666 parsedExtensions.push_back(parseExtensions[i].lowercase());
667 parsedExtensionsSet.emplace(parseExtensions[i].lowercase());
668 }
669 }
670
readFromFile(Glib::ustring fname)671 void Options::readFromFile(Glib::ustring fname)
672 {
673 setlocale(LC_NUMERIC, "C"); // to set decimal point to "."
674
675 Glib::KeyFile keyFile;
676
677 if (!Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) {
678 Glib::ustring msg = Glib::ustring::compose("Options file %1 does not exist", fname);
679 throw Error(msg);
680 }
681
682 try {
683 if (keyFile.load_from_file(fname)) {
684
685 // --------------------------------------------------------------------------------------------------------
686
687 if (keyFile.has_group("General")) {
688 if (keyFile.has_key("General", "TabbedEditor")) {
689 tabbedUI = keyFile.get_boolean("General", "TabbedEditor");
690 }
691
692 if (keyFile.has_key("General", "StartupDirectory")) {
693 if (keyFile.get_string("General", "StartupDirectory") == "home") {
694 startupDir = STARTUPDIR_HOME;
695 } else if (keyFile.get_string("General", "StartupDirectory") == "current") {
696 startupDir = STARTUPDIR_CURRENT;
697 } else if (keyFile.get_string("General", "StartupDirectory") == "last") {
698 startupDir = STARTUPDIR_LAST;
699 } else if (keyFile.get_string("General", "StartupDirectory") == "custom") {
700 startupDir = STARTUPDIR_CUSTOM;
701 }
702 }
703
704 if (keyFile.has_key("General", "StartupPath")) {
705 startupPath = keyFile.get_string("General", "StartupPath");
706 }
707
708 if (keyFile.has_key("General", "DateFormat")) {
709 dateFormat = keyFile.get_string("General", "DateFormat");
710 }
711
712 if (keyFile.has_key("General", "AdjusterMinDelay")) {
713 adjusterMinDelay = keyFile.get_integer("General", "AdjusterMinDelay");
714 }
715
716 if (keyFile.has_key("General", "AdjusterMaxDelay")) {
717 adjusterMaxDelay = keyFile.get_integer("General", "AdjusterMaxDelay");
718 }
719
720 if (keyFile.has_key("General", "MultiUser")) {
721 multiUser = keyFile.get_boolean("General", "MultiUser");
722 }
723
724 if (keyFile.has_key("General", "Version")) {
725 version = keyFile.get_string("General", "Version");
726 }
727
728 if (keyFile.has_key("General", "Language")) {
729 language = keyFile.get_string("General", "Language");
730 }
731
732 if (keyFile.has_key("General", "LanguageAutoDetect")) {
733 languageAutoDetect = keyFile.get_boolean("General", "LanguageAutoDetect");
734 }
735
736 if (keyFile.has_key("General", "Theme")) {
737 theme = keyFile.get_string("General", "Theme");
738 }
739
740 if (keyFile.has_key("General", "DarkFramesPath")) {
741 rtSettings.darkFramesPath = keyFile.get_string("General", "DarkFramesPath");
742 }
743
744 if (keyFile.has_key("General", "FlatFieldsPath")) {
745 rtSettings.flatFieldsPath = keyFile.get_string("General", "FlatFieldsPath");
746 }
747
748 if (keyFile.has_key("General", "Verbose")) {
749 rtSettings.verbose = keyFile.get_boolean("General", "Verbose");
750 }
751
752 if (keyFile.has_key("General", "ErrorMessageDuration")) {
753 error_message_duration = keyFile.get_integer("General", "ErrorMessageDuration");
754 }
755
756 if (keyFile.has_key("General", "MaxErrorMessages")) {
757 max_error_messages = keyFile.get_integer("General", "MaxErrorMessages");
758 }
759 }
760
761 if (keyFile.has_group("External Editor")) {
762 if (keyFile.has_key("External Editor", "EditorKind")) {
763 editorToSendTo = keyFile.get_integer("External Editor", "EditorKind");
764 }
765
766 if (keyFile.has_key("External Editor", "GimpDir")) {
767 gimpDir = keyFile.get_string("External Editor", "GimpDir");
768 }
769
770 if (keyFile.has_key("External Editor", "PhotoshopDir")) {
771 psDir = keyFile.get_string("External Editor", "PhotoshopDir");
772 }
773
774 if (keyFile.has_key("External Editor", "CustomEditor")) {
775 customEditorProg = keyFile.get_string("External Editor", "CustomEditor");
776 }
777
778 if (keyFile.has_key("External Editor", "OutputDir")) {
779 int v = keyFile.get_integer("External Editor", "OutputDir");
780 if (v < int(EDITOR_OUT_DIR_TEMP) || v > int(EDITOR_OUT_DIR_CUSTOM)) {
781 editor_out_dir = EDITOR_OUT_DIR_TEMP;
782 } else {
783 editor_out_dir = EditorOutDir(v);
784 }
785 }
786
787 if (keyFile.has_key("External Editor", "CustomOutputDir")) {
788 editor_custom_out_dir = keyFile.get_string("External Editor", "CustomOutputDir");
789 }
790
791 if (keyFile.has_key("External Editor", "Float32")) {
792 editor_float32 = keyFile.get_boolean("External Editor", "Float32");
793 }
794
795 if (keyFile.has_key("External Editor", "BypassOutputProfile")) {
796 editor_bypass_output_profile = keyFile.get_boolean("External Editor", "BypassOutputProfile");
797 }
798 }
799
800 if (keyFile.has_group("Output")) {
801 if (keyFile.has_key("Output", "Format")) {
802 saveFormat.format = keyFile.get_string("Output", "Format");
803 }
804
805 if (keyFile.has_key("Output", "JpegQuality")) {
806 saveFormat.jpegQuality = keyFile.get_integer("Output", "JpegQuality");
807 }
808
809 if (keyFile.has_key("Output", "JpegSubSamp")) {
810 saveFormat.jpegSubSamp = keyFile.get_integer("Output", "JpegSubSamp");
811 }
812
813 if (keyFile.has_key("Output", "PngBps")) {
814 saveFormat.pngBits = keyFile.get_integer("Output", "PngBps");
815 }
816
817 if (keyFile.has_key("Output", "TiffBps")) {
818 saveFormat.tiffBits = keyFile.get_integer("Output", "TiffBps");
819 }
820
821 if (keyFile.has_key ("Output", "TiffFloat")) {
822 saveFormat.tiffFloat = keyFile.get_boolean ("Output", "TiffFloat");
823 }
824
825 if (keyFile.has_key("Output", "TiffUncompressed")) {
826 saveFormat.tiffUncompressed = keyFile.get_boolean("Output", "TiffUncompressed");
827 }
828
829 if (keyFile.has_key("Output", "SaveProcParams")) {
830 saveFormat.saveParams = keyFile.get_boolean("Output", "SaveProcParams");
831 }
832
833
834 if (keyFile.has_key("Output", "FormatBatch")) {
835 saveFormatBatch.format = keyFile.get_string("Output", "FormatBatch");
836 }
837
838 if (keyFile.has_key("Output", "JpegQualityBatch")) {
839 saveFormatBatch.jpegQuality = keyFile.get_integer("Output", "JpegQualityBatch");
840 }
841
842 if (keyFile.has_key("Output", "JpegSubSampBatch")) {
843 saveFormatBatch.jpegSubSamp = keyFile.get_integer("Output", "JpegSubSampBatch");
844 }
845
846 if (keyFile.has_key("Output", "PngBpsBatch")) {
847 saveFormatBatch.pngBits = keyFile.get_integer("Output", "PngBpsBatch");
848 }
849
850 if (keyFile.has_key("Output", "TiffBpsBatch")) {
851 saveFormatBatch.tiffBits = keyFile.get_integer("Output", "TiffBpsBatch");
852 }
853
854 if (keyFile.has_key ("Output", "TiffFloatBatch")) {
855 saveFormatBatch.tiffFloat = keyFile.get_boolean ("Output", "TiffFloatBatch");
856 }
857
858 if (keyFile.has_key("Output", "TiffUncompressedBatch")) {
859 saveFormatBatch.tiffUncompressed = keyFile.get_boolean("Output", "TiffUncompressedBatch");
860 }
861
862 if (keyFile.has_key("Output", "SaveProcParamsBatch")) {
863 saveFormatBatch.saveParams = keyFile.get_boolean("Output", "SaveProcParamsBatch");
864 }
865
866 if (keyFile.has_key("Output", "Path")) {
867 savePathTemplate = keyFile.get_string("Output", "Path");
868 }
869
870 if (keyFile.has_key("Output", "PathTemplate")) {
871 savePathTemplate = keyFile.get_string("Output", "PathTemplate");
872 }
873
874 if (keyFile.has_key("Output", "PathFolder")) {
875 savePathFolder = keyFile.get_string("Output", "PathFolder");
876 }
877
878 if (keyFile.has_key("Output", "AutoSuffix")) {
879 autoSuffix = keyFile.get_boolean("Output", "AutoSuffix");
880 }
881
882 if (keyFile.has_key("Output", "ForceFormatOpts")) {
883 forceFormatOpts = keyFile.get_boolean("Output", "ForceFormatOpts");
884 }
885
886 if (keyFile.has_key("Output", "SaveMethodNum")) {
887 saveMethodNum = keyFile.get_integer("Output", "SaveMethodNum");
888 }
889
890 if (keyFile.has_key("Output", "UsePathTemplate")) {
891 saveUsePathTemplate = keyFile.get_boolean("Output", "UsePathTemplate");
892 }
893
894 if (keyFile.has_key("Output", "LastSaveAsPath")) {
895 lastSaveAsPath = keyFile.get_string("Output", "LastSaveAsPath");
896 }
897
898 if (keyFile.has_key("Output", "OverwriteOutputFile")) {
899 overwriteOutputFile = keyFile.get_boolean("Output", "OverwriteOutputFile");
900 }
901
902 if (keyFile.has_key("Output", "BatchQueueUseProfile")) {
903 batch_queue_use_profile = keyFile.get_boolean("Output", "BatchQueueUseProfile");
904 }
905
906 if (keyFile.has_key("Output", "BatchQueueProfile")) {
907 batch_queue_profile_path = keyFile.get_string("Output", "BatchQueueProfile");
908 }
909
910 if (keyFile.has_key("Output", "ProcParamsAutosaveInterval")) {
911 sidecar_autosave_interval = keyFile.get_integer("Output", "ProcParamsAutosaveInterval");
912 }
913 }
914
915 if (keyFile.has_group("Profiles")) {
916 if (keyFile.has_key("Profiles", "Directory")) {
917 profilePath = keyFile.get_string("Profiles", "Directory");
918 }
919
920 if (keyFile.has_key("Profiles", "UseBundledProfiles")) {
921 useBundledProfiles = keyFile.get_boolean("Profiles", "UseBundledProfiles");
922 }
923
924 if (keyFile.has_key("Profiles", "LoadSaveProfilePath")) {
925 loadSaveProfilePath = keyFile.get_string("Profiles", "LoadSaveProfilePath");
926 }
927
928 if (keyFile.has_key("Profiles", "RawDefault")) {
929 defProfRaw = keyFile.get_string("Profiles", "RawDefault");
930 }
931
932 if (keyFile.has_key("Profiles", "ImgDefault")) {
933 defProfImg = keyFile.get_string("Profiles", "ImgDefault");
934 }
935
936 if (keyFile.has_key("Profiles", "FilledProfile")) {
937 filledProfile = keyFile.get_boolean("Profiles", "FilledProfile");
938 }
939
940 if (keyFile.has_key("Profiles", "SaveParamsWithFile")) {
941 saveParamsFile = keyFile.get_boolean("Profiles", "SaveParamsWithFile");
942 }
943
944 if (keyFile.has_key("Profiles", "SaveParamsToCache")) {
945 saveParamsCache = keyFile.get_boolean("Profiles", "SaveParamsToCache");
946 }
947
948 if (keyFile.has_key("Profiles", "LoadParamsFromLocation")) {
949 paramsLoadLocation = (PPLoadLocation)keyFile.get_integer("Profiles", "LoadParamsFromLocation");
950 }
951
952 if (keyFile.has_key("Profiles", "EmbedParamsInMetadata")) {
953 params_out_embed = keyFile.get_boolean("Profiles", "EmbedParamsInMetadata");
954 }
955
956 if (keyFile.has_key("Profiles", "ParamsSidecarStripExtension")) {
957 params_sidecar_strip_extension = keyFile.get_boolean("Profiles", "ParamsSidecarStripExtension");
958 }
959
960 if (keyFile.has_key("Profiles", "CustomProfileBuilder")) {
961 CPBPath = keyFile.get_string("Profiles", "CustomProfileBuilder"); // for backward compatibility only
962 }
963
964 if (keyFile.has_key("Profiles", "CustomProfileBuilderPath")) {
965 CPBPath = keyFile.get_string("Profiles", "CustomProfileBuilderPath");
966 }
967
968 if (keyFile.has_key("Profiles", "CustomProfileBuilderKeys")) {
969 CPBKeys = (CPBKeyType)keyFile.get_integer("Profiles", "CustomProfileBuilderKeys");
970 }
971 }
972
973 if (keyFile.has_group("File Browser")) {
974 if (keyFile.has_key("File Browser", "ThumbnailSize")) {
975 thumbSize = keyFile.get_integer("File Browser", "ThumbnailSize");
976 }
977
978 if (keyFile.has_key("File Browser", "ThumbnailSizeTab")) {
979 thumbSizeTab = keyFile.get_integer("File Browser", "ThumbnailSizeTab");
980 }
981
982 if (keyFile.has_key("File Browser", "ThumbnailSizeQueue")) {
983 thumbSizeQueue = keyFile.get_integer("File Browser", "ThumbnailSizeQueue");
984 }
985
986 if (keyFile.has_key("File Browser", "SameThumbSize")) {
987 sameThumbSize = keyFile.get_integer("File Browser", "SameThumbSize");
988 }
989
990 if (keyFile.has_key("File Browser", "ThumbnailOrder")) {
991 thumbnailOrder = ThumbnailOrder(keyFile.get_integer("File Browser", "ThumbnailOrder"));
992 }
993
994 if (keyFile.has_key("File Browser", "BrowserShowsDate")) {
995 fbShowDateTime = keyFile.get_boolean("File Browser", "BrowserShowsDate");
996 }
997
998 if (keyFile.has_key("File Browser", "BrowserShowsExif")) {
999 fbShowBasicExif = keyFile.get_boolean("File Browser", "BrowserShowsExif");
1000 }
1001
1002 if (keyFile.has_key("File Browser", "BrowserShowsExpComp")) {
1003 fbShowExpComp = keyFile.get_boolean("File Browser", "BrowserShowsExpComp");
1004 }
1005
1006 #ifndef WIN32
1007 if (keyFile.has_key("File Browser", "BrowserShowsHidden")) {
1008 fbShowHidden = keyFile.get_boolean("File Browser", "BrowserShowsHidden");
1009 }
1010 #endif
1011
1012 if (keyFile.has_key("File Browser", "MaxPreviewHeight")) {
1013 maxThumbnailHeight = keyFile.get_integer("File Browser", "MaxPreviewHeight");
1014 }
1015
1016 if (keyFile.has_key("File Browser", "MaxPreviewWidth")) {
1017 maxThumbnailWidth = keyFile.get_integer("File Browser", "MaxPreviewWidth");
1018 }
1019
1020 if (keyFile.has_key("File Browser", "MaxCacheEntries")) {
1021 maxCacheEntries = keyFile.get_integer("File Browser", "MaxCacheEntries");
1022 }
1023
1024 if (keyFile.has_key("File Browser", "ParseExtensions")) {
1025 auto l = keyFile.get_string_list("File Browser", "ParseExtensions");
1026 if (!l.empty()) {
1027 parseExtensions = l;
1028 }
1029 }
1030
1031 if (keyFile.has_key("File Browser", "ParseExtensionsEnabled")) {
1032 auto l = keyFile.get_integer_list("File Browser", "ParseExtensionsEnabled");
1033 if (!l.empty()) {
1034 parseExtensionsEnabled = l;
1035 }
1036 }
1037
1038 if (keyFile.has_key("File Browser", "ThumbnailInterpolation")) {
1039 thumbInterp = keyFile.get_integer("File Browser", "ThumbnailInterpolation");
1040 }
1041
1042 if (keyFile.has_key("File Browser", "FavoriteDirs")) {
1043 favoriteDirs = keyFile.get_string_list("File Browser", "FavoriteDirs");
1044 }
1045
1046 if (keyFile.has_key("File Browser", "ThumbnailZoomRatios")) {
1047 thumbnailZoomRatios = keyFile.get_double_list("File Browser", "ThumbnailZoomRatios");
1048 }
1049
1050 if (keyFile.has_key("File Browser", "OverlayedFileNames")) {
1051 overlayedFileNames = keyFile.get_boolean("File Browser", "OverlayedFileNames");
1052 }
1053
1054 if (keyFile.has_key("File Browser", "FilmStripOverlayedFileNames")) {
1055 filmStripOverlayedFileNames = keyFile.get_boolean("File Browser", "FilmStripOverlayedFileNames");
1056 }
1057
1058 if (keyFile.has_key("File Browser", "ShowFileNames")) {
1059 showFileNames = keyFile.get_boolean("File Browser", "ShowFileNames");
1060 }
1061
1062 if (keyFile.has_key("File Browser", "FilmStripShowFileNames")) {
1063 filmStripShowFileNames = keyFile.get_boolean("File Browser", "FilmStripShowFileNames");
1064 }
1065
1066 if (keyFile.has_key("File Browser", "InternalThumbIfUntouched")) {
1067 internalThumbIfUntouched = keyFile.get_boolean("File Browser", "InternalThumbIfUntouched");
1068 }
1069
1070 if (keyFile.has_key("File Browser", "menuGroupRank")) {
1071 menuGroupRank = keyFile.get_boolean("File Browser", "menuGroupRank");
1072 }
1073
1074 if (keyFile.has_key("File Browser", "menuGroupLabel")) {
1075 menuGroupLabel = keyFile.get_boolean("File Browser", "menuGroupLabel");
1076 }
1077
1078 if (keyFile.has_key("File Browser", "menuGroupFileOperations")) {
1079 menuGroupFileOperations = keyFile.get_boolean("File Browser", "menuGroupFileOperations");
1080 }
1081
1082 if (keyFile.has_key("File Browser", "menuGroupProfileOperations")) {
1083 menuGroupProfileOperations = keyFile.get_boolean("File Browser", "menuGroupProfileOperations");
1084 }
1085
1086 if (keyFile.has_key("File Browser", "menuGroupExtProg")) {
1087 menuGroupExtProg = keyFile.get_boolean("File Browser", "menuGroupExtProg");
1088 }
1089
1090 if (keyFile.has_key("File Browser", "MaxRecentFolders")) {
1091 maxRecentFolders = keyFile.get_integer("File Browser", "MaxRecentFolders");
1092 }
1093
1094 recentFolders.reserve(maxRecentFolders + 10); // reserve some more than maxRecentFolders, because at runtime it stores more than that
1095
1096 if (keyFile.has_key("File Browser", "RecentFolders")) {
1097 recentFolders = keyFile.get_string_list("File Browser", "RecentFolders");
1098 }
1099
1100 if (keyFile.has_key("File Browser", "ThumbnailRatingMode")) {
1101 auto s = keyFile.get_string("File Browser", "ThumbnailRatingMode");
1102 if (s == "procparams") {
1103 thumbnail_rating_mode = ThumbnailRatingMode::PROCPARAMS;
1104 } else if (s == "xmp") {
1105 thumbnail_rating_mode = ThumbnailRatingMode::XMP;
1106 } else {
1107 thumbnail_rating_mode = ThumbnailRatingMode::PROCPARAMS;
1108 }
1109 }
1110 }
1111
1112 if (keyFile.has_group("Clipping Indication")) {
1113 if (keyFile.has_key("Clipping Indication", "HighlightThreshold")) {
1114 highlightThreshold = keyFile.get_integer("Clipping Indication", "HighlightThreshold");
1115 }
1116
1117 if (keyFile.has_key("Clipping Indication", "ShadowThreshold")) {
1118 shadowThreshold = keyFile.get_integer("Clipping Indication", "ShadowThreshold");
1119 }
1120 }
1121
1122 if (keyFile.has_group("Performance")) {
1123 if (keyFile.has_key("Performance", "RgbDenoiseThreadLimit")) {
1124 rgbDenoiseThreadLimit = keyFile.get_integer("Performance", "RgbDenoiseThreadLimit");
1125 }
1126
1127 if (keyFile.has_key("Performance", "ClutCacheSize")) {
1128 clutCacheSize = keyFile.get_integer("Performance", "ClutCacheSize");
1129 }
1130
1131 if (keyFile.has_key("Performance", "MaxInspectorBuffers")) {
1132 maxInspectorBuffers = keyFile.get_integer("Performance", "MaxInspectorBuffers");
1133 }
1134
1135 if (keyFile.has_key("Performance", "InspectorDelay")) {
1136 inspectorDelay = keyFile.get_integer("Performance", "InspectorDelay");
1137 }
1138
1139 if (keyFile.has_key("Performance", "PreviewDemosaicFromSidecar")) {
1140 prevdemo = (prevdemo_t)keyFile.get_integer("Performance", "PreviewDemosaicFromSidecar");
1141 }
1142
1143 if (keyFile.has_key("Performance", "SerializeTiffRead")) {
1144 serializeTiffRead = keyFile.get_boolean("Performance", "SerializeTiffRead");
1145 }
1146
1147 if (keyFile.has_key("Performance", "DenoiseZoomedOut")) {
1148 denoiseZoomedOut = keyFile.get_boolean("Performance", "DenoiseZoomedOut");
1149 }
1150
1151 if (keyFile.has_key("Performance", "WBPreviewMode")) {
1152 int v = keyFile.get_integer("Performance", "WBPreviewMode");
1153 wb_preview_mode = WBPreviewMode(rtengine::LIM(v, int(WB_AFTER), int(WB_BEFORE_HIGH_DETAIL)));
1154 }
1155
1156 if (keyFile.has_key("Performance", "ThumbUpdateThreadLimit")) {
1157 thumb_update_thread_limit = keyFile.get_integer("Performance", "ThumbUpdateThreadLimit");
1158 }
1159
1160 if (keyFile.has_key("Performance", "ThumbDelayUpdate")) {
1161 thumb_delay_update = keyFile.get_boolean("Performance", "ThumbDelayUpdate");
1162 }
1163
1164 if (keyFile.has_key("Performance", "ThumbLazyCaching")) {
1165 thumb_lazy_caching = keyFile.get_boolean("Performance", "ThumbLazyCaching");
1166 }
1167 }
1168
1169 if (keyFile.has_group("Inspector")) {
1170 if (keyFile.has_key("Inspector", "Mode")) {
1171 rtSettings.thumbnail_inspector_mode = static_cast<rtengine::Settings::ThumbnailInspectorMode>(keyFile.get_integer("Inspector", "Mode"));
1172 }
1173
1174 if (keyFile.has_key("Inspector", "RawCurve")) {
1175 rtSettings.thumbnail_inspector_raw_curve = static_cast<rtengine::Settings::ThumbnailInspectorRawCurve>(keyFile.get_integer("Inspector", "RawCurve"));
1176 }
1177
1178 if (keyFile.has_key("Inspector", "ZoomFit")) {
1179 thumbnail_inspector_zoom_fit = keyFile.get_boolean("Inspector", "ZoomFit");
1180 }
1181
1182 if (keyFile.has_key("Inspector", "ShowInfo")) {
1183 thumbnail_inspector_show_info = keyFile.get_boolean("Inspector", "ShowInfo");
1184 }
1185
1186 if (keyFile.has_key("Inspector", "ShowHistogram")) {
1187 thumbnail_inspector_show_histogram = keyFile.get_boolean("Inspector", "ShowHistogram");
1188 }
1189
1190 if (keyFile.has_key("Inspector", "EnableCMS")) {
1191 thumbnail_inspector_enable_cms = keyFile.get_boolean("Inspector", "EnableCMS");
1192 }
1193
1194 if (keyFile.has_key("Inspector", "BrowserWidth")) {
1195 browser_width_for_inspector = keyFile.get_integer("Inspector", "BrowserWidth");
1196 }
1197
1198 if (keyFile.has_key("Inspector", "ThumbnailHover")) {
1199 thumbnail_inspector_hover = keyFile.get_boolean("Inspector", "ThumbnailHover");
1200 }
1201 }
1202
1203 if (keyFile.has_group("GUI")) {
1204 if (keyFile.has_key("GUI", "Favorites")) {
1205 favorites = keyFile.get_string_list("GUI", "Favorites");
1206 }
1207
1208 if (keyFile.has_key("GUI", "WindowWidth")) {
1209 windowWidth = keyFile.get_integer("GUI", "WindowWidth");
1210 }
1211
1212 if (keyFile.has_key("GUI", "WindowHeight")) {
1213 windowHeight = keyFile.get_integer("GUI", "WindowHeight");
1214 }
1215
1216 if (keyFile.has_key("GUI", "WindowX")) {
1217 windowX = keyFile.get_integer("GUI", "WindowX");
1218 }
1219
1220 if (keyFile.has_key("GUI", "WindowY")) {
1221 windowY = keyFile.get_integer("GUI", "WindowY");
1222 }
1223
1224 if (keyFile.has_key("GUI", "WindowMonitor")) {
1225 windowMonitor = keyFile.get_integer("GUI", "WindowMonitor");
1226 }
1227
1228 if (keyFile.has_key("GUI", "MeowMonitor")) {
1229 meowMonitor = keyFile.get_integer("GUI", "MeowMonitor");
1230 }
1231
1232 if (keyFile.has_key("GUI", "MeowFullScreen")) {
1233 meowFullScreen = keyFile.get_boolean("GUI", "MeowFullScreen");
1234 }
1235
1236 if (keyFile.has_key("GUI", "MeowMaximized")) {
1237 meowMaximized = keyFile.get_boolean("GUI", "MeowMaximized");
1238 }
1239
1240 if (keyFile.has_key("GUI", "MeowWidth")) {
1241 meowWidth = keyFile.get_integer("GUI", "MeowWidth");
1242 }
1243
1244 if (keyFile.has_key("GUI", "MeowHeight")) {
1245 meowHeight = keyFile.get_integer("GUI", "MeowHeight");
1246 }
1247
1248 if (keyFile.has_key("GUI", "MeowX")) {
1249 meowX = keyFile.get_integer("GUI", "MeowX");
1250 }
1251
1252 if (keyFile.has_key("GUI", "MeowY")) {
1253 meowY = keyFile.get_integer("GUI", "MeowY");
1254 }
1255
1256 if (keyFile.has_key("GUI", "WindowMaximized")) {
1257 windowMaximized = keyFile.get_boolean("GUI", "WindowMaximized");
1258 }
1259
1260 if (keyFile.has_key("GUI", "DetailWindowWidth")) {
1261 detailWindowWidth = keyFile.get_integer("GUI", "DetailWindowWidth");
1262 }
1263
1264 if (keyFile.has_key("GUI", "DetailWindowHeight")) {
1265 detailWindowHeight = keyFile.get_integer("GUI", "DetailWindowHeight");
1266 }
1267
1268 if (keyFile.has_key("GUI", "DirBrowserWidth")) {
1269 dirBrowserWidth = keyFile.get_integer("GUI", "DirBrowserWidth");
1270 }
1271
1272 if (keyFile.has_key("GUI", "DirBrowserHeight")) {
1273 dirBrowserHeight = keyFile.get_integer("GUI", "DirBrowserHeight");
1274 }
1275
1276 if (keyFile.has_key("GUI", "SortType")) {
1277 dirBrowserSortType = static_cast<Gtk::SortType>(keyFile.get_integer("GUI", "SortType"));
1278 }
1279
1280 if (keyFile.has_key("GUI", "PreferencesWidth")) {
1281 preferencesWidth = keyFile.get_integer("GUI", "PreferencesWidth");
1282 }
1283
1284 if (keyFile.has_key("GUI", "PreferencesHeight")) {
1285 preferencesHeight = keyFile.get_integer("GUI", "PreferencesHeight");
1286 }
1287
1288 if (keyFile.has_key("GUI", "SaveAsDialogWidth")) {
1289 saveAsDialogWidth = keyFile.get_integer("GUI", "SaveAsDialogWidth");
1290 }
1291
1292 if (keyFile.has_key("GUI", "SaveAsDialogHeight")) {
1293 saveAsDialogHeight = keyFile.get_integer("GUI", "SaveAsDialogHeight");
1294 }
1295
1296 if (keyFile.has_key("GUI", "ToolPanelWidth")) {
1297 toolPanelWidth = keyFile.get_integer("GUI", "ToolPanelWidth");
1298 }
1299
1300 if (keyFile.has_key("GUI", "BrowserToolPanelWidth")) {
1301 browserToolPanelWidth = keyFile.get_integer("GUI", "BrowserToolPanelWidth");
1302 }
1303
1304 if (keyFile.has_key("GUI", "BrowserToolPanelHeight")) {
1305 browserToolPanelHeight = keyFile.get_integer("GUI", "BrowserToolPanelHeight");
1306 }
1307
1308 if (keyFile.has_key("GUI", "BrowserToolPanelOpened")) {
1309 browserToolPanelOpened = keyFile.get_boolean("GUI", "BrowserToolPanelOpened");
1310 }
1311
1312 if (keyFile.has_key("GUI", "BrowserDirPanelOpened")) {
1313 browserDirPanelOpened = keyFile.get_boolean("GUI", "BrowserDirPanelOpened");
1314 }
1315
1316 if (keyFile.has_key("GUI", "EditorFilmStripOpened")) {
1317 editorFilmStripOpened = keyFile.get_boolean("GUI", "EditorFilmStripOpened");
1318 }
1319
1320 if (keyFile.has_key("GUI", "InspectorDirPanelOpened")) {
1321 inspectorDirPanelOpened = keyFile.get_boolean("GUI", "InspectorDirPanelOpened");
1322 }
1323
1324 if (keyFile.has_key("GUI", "HistoryPanelWidth")) {
1325 historyPanelWidth = keyFile.get_integer("GUI", "HistoryPanelWidth");
1326 }
1327
1328 if (keyFile.has_key("GUI", "FontFamily")) {
1329 fontFamily = keyFile.get_string("GUI", "FontFamily");
1330 }
1331
1332 if (keyFile.has_key("GUI", "FontSize")) {
1333 fontSize = keyFile.get_integer("GUI", "FontSize");
1334 }
1335
1336 if (keyFile.has_key("GUI", "CPFontFamily")) {
1337 CPFontFamily = keyFile.get_string("GUI", "CPFontFamily");
1338 }
1339
1340 if (keyFile.has_key("GUI", "CPFontSize")) {
1341 CPFontSize = keyFile.get_integer("GUI", "CPFontSize");
1342 }
1343
1344 if (keyFile.has_key("GUI", "PseudoHiDPISupport")) {
1345 pseudoHiDPISupport = keyFile.get_boolean("GUI", "PseudoHiDPISupport");
1346 }
1347
1348 if (keyFile.has_key("GUI", "LastPreviewScale")) {
1349 lastScale = keyFile.get_integer("GUI", "LastPreviewScale");
1350 }
1351
1352 if (keyFile.has_key("GUI", "PanAccelFactor")) {
1353 panAccelFactor = keyFile.get_integer("GUI", "PanAccelFactor");
1354 }
1355
1356 if (keyFile.has_key("GUI", "RememberZoomAndPan")) {
1357 rememberZoomAndPan = keyFile.get_boolean("GUI", "RememberZoomAndPan");
1358 }
1359
1360 if (keyFile.has_key("GUI", "ShowHistory")) {
1361 showHistory = keyFile.get_boolean("GUI", "ShowHistory");
1362 }
1363
1364 if (keyFile.has_key("GUI", "ShowInfo")) {
1365 showInfo = keyFile.get_boolean("GUI", "ShowInfo");
1366 }
1367
1368 if (keyFile.has_key("GUI", "MainNBVertical")) {
1369 mainNBVertical = keyFile.get_boolean("GUI", "MainNBVertical");
1370 }
1371
1372 if (keyFile.has_key("GUI", "ShowClippedHighlights")) {
1373 showClippedHighlights = keyFile.get_boolean("GUI", "ShowClippedHighlights");
1374 }
1375
1376 if (keyFile.has_key("GUI", "ShowClippedShadows")) {
1377 showClippedShadows = keyFile.get_boolean("GUI", "ShowClippedShadows");
1378 }
1379
1380 if (keyFile.has_key("GUI", "FrameColor")) {
1381 bgcolor = rtengine::LIM(keyFile.get_integer("GUI", "FrameColor"), 1, 3);
1382 }
1383
1384 if (keyFile.has_key("GUI", "ProcessingQueueEnbled")) {
1385 procQueueEnabled = keyFile.get_boolean("GUI", "ProcessingQueueEnbled");
1386 }
1387
1388 if (keyFile.has_key("GUI", "ToolPanelsExpanded")) {
1389 tpOpen = keyFile.get_integer_list("GUI", "ToolPanelsExpanded");
1390 }
1391
1392 if (keyFile.has_key("GUI", "ToolPanelsExpandedAutoSave")) {
1393 autoSaveTpOpen = keyFile.get_boolean("GUI", "ToolPanelsExpandedAutoSave");
1394 }
1395
1396 if (keyFile.has_key("GUI", "MultiDisplayMode")) {
1397 multiDisplayMode = keyFile.get_integer("GUI", "MultiDisplayMode");
1398 }
1399
1400 //if (keyFile.has_key ("GUI", "CurvePanelsExpanded")) crvOpen = keyFile.get_integer_list ("GUI", "CurvePanelsExpanded");
1401 if (keyFile.has_key("GUI", "CutOverlayBrush")) {
1402 cutOverlayBrush = keyFile.get_double_list("GUI", "CutOverlayBrush");
1403 }
1404
1405 if (keyFile.has_key("GUI", "NavGuideBrush")) {
1406 navGuideBrush = keyFile.get_double_list("GUI", "NavGuideBrush");
1407 }
1408
1409 if (keyFile.has_key("GUI", "HistogramPosition")) {
1410 histogramPosition = keyFile.get_integer("GUI", "HistogramPosition");
1411 }
1412
1413 if (keyFile.has_key("GUI", "HistogramRed")) {
1414 histogramRed = keyFile.get_boolean("GUI", "HistogramRed");
1415 }
1416
1417 if (keyFile.has_key("GUI", "HistogramGreen")) {
1418 histogramGreen = keyFile.get_boolean("GUI", "HistogramGreen");
1419 }
1420
1421 if (keyFile.has_key("GUI", "HistogramBlue")) {
1422 histogramBlue = keyFile.get_boolean("GUI", "HistogramBlue");
1423 }
1424
1425 if (keyFile.has_key("GUI", "HistogramLuma")) {
1426 histogramLuma = keyFile.get_boolean("GUI", "HistogramLuma");
1427 }
1428
1429 if (keyFile.has_key("GUI", "HistogramChroma")) {
1430 histogramChroma = keyFile.get_boolean("GUI", "HistogramChroma");
1431 }
1432
1433 if (keyFile.has_key("GUI", "HistogramRAW")) {
1434 //histogramRAW = keyFile.get_boolean("GUI", "HistogramRAW");
1435 if (keyFile.get_boolean("GUI", "HistogramRAW")) {
1436 histogramScopeType = ScopeType::HISTOGRAM_RAW;
1437 }
1438 }
1439
1440 if (keyFile.has_key("GUI", "HistogramBar")) {
1441 histogramBar = keyFile.get_boolean("GUI", "HistogramBar");
1442 }
1443
1444 if (keyFile.has_key ("GUI", "HistogramHeight")) {
1445 histogramHeight = keyFile.get_integer ("GUI", "HistogramHeight");
1446 }
1447
1448 if (keyFile.has_key ("GUI", "HistogramDrawMode")) {
1449 histogramDrawMode = keyFile.get_integer ("GUI", "HistogramDrawMode");
1450 }
1451
1452 if (keyFile.has_key("GUI", "HistogramScalingFactor")) {
1453 histogram_scaling_factor = keyFile.get_double("GUI", "HistogramScalingFactor");
1454 }
1455
1456 if (keyFile.has_key("GUI", "NavigatorRGBUnit")) {
1457 navRGBUnit = (NavigatorUnit)keyFile.get_integer("GUI", "NavigatorRGBUnit");
1458 }
1459
1460 if (keyFile.has_key("GUI", "NavigatorLCHUnit")) {
1461 navLCHUnit = (NavigatorUnit)keyFile.get_integer("GUI", "NavigatorLCHUnit");
1462 }
1463
1464 if (keyFile.has_key("GUI", "HistogramScopeType")) {
1465 histogramScopeType = static_cast<ScopeType>(keyFile.get_integer("GUI", "HistogramScopeType"));
1466 }
1467
1468 if (keyFile.has_key("GUI", "HistogramShowOptionButtons")) {
1469 histogramShowOptionButtons = keyFile.get_boolean("GUI", "HistogramShowOptionButtons");
1470 }
1471
1472 if (keyFile.has_key("GUI", "HistogramTraceBrightness")) {
1473 histogramTraceBrightness = keyFile.get_double("GUI", "HistogramTraceBrightness");
1474 }
1475
1476 if (keyFile.has_key("GUI", "ShowFilmStripToolBar")) {
1477 showFilmStripToolBar = keyFile.get_boolean("GUI", "ShowFilmStripToolBar");
1478 }
1479
1480 if (keyFile.has_key("GUI", "FileBrowserToolbarSingleRow")) {
1481 FileBrowserToolbarSingleRow = keyFile.get_boolean("GUI", "FileBrowserToolbarSingleRow");
1482 }
1483
1484 if (keyFile.has_key("GUI", "HideTPVScrollbar")) {
1485 hideTPVScrollbar = keyFile.get_boolean("GUI", "HideTPVScrollbar");
1486 }
1487
1488 if (keyFile.has_key("GUI", "HistogramWorking")) {
1489 rtSettings.HistogramWorking = keyFile.get_boolean("GUI", "HistogramWorking");
1490 }
1491
1492 if (keyFile.has_key("GUI", "CurveBBoxPosition")) {
1493 curvebboxpos = keyFile.get_integer("GUI", "CurveBBoxPosition");
1494 }
1495
1496 if (keyFile.has_key("GUI", "ToolPanelsDisable")) {
1497 toolpanels_disable = keyFile.get_boolean("GUI", "ToolPanelsDisable");
1498 }
1499
1500 if (keyFile.has_key("GUI", "AdjusterForceLinear")) {
1501 adjuster_force_linear = keyFile.get_boolean("GUI", "AdjusterForceLinear");
1502 }
1503 }
1504
1505 if (keyFile.has_group("Crop Settings")) {
1506 if (keyFile.has_key("Crop Settings", "PPI")) {
1507 cropPPI = keyFile.get_integer("Crop Settings", "PPI");
1508 }
1509 }
1510
1511 if (keyFile.has_group("Color Management")) {
1512 if (keyFile.has_key("Color Management", "ICCDirectory")) {
1513 rtSettings.iccDirectory = keyFile.get_string("Color Management", "ICCDirectory");
1514 }
1515 if (keyFile.has_key("Color Management", "MonitorICCDirectory")) {
1516 rtSettings.monitorIccDirectory = keyFile.get_string("Color Management", "MonitorICCDirectory");
1517 } else {
1518 rtSettings.monitorIccDirectory = rtSettings.iccDirectory;
1519 }
1520
1521 if (keyFile.has_key("Color Management", "PrinterIntent")) {
1522 rtSettings.printerIntent = static_cast<rtengine::RenderingIntent>(keyFile.get_integer("Color Management", "PrinterIntent"));
1523 }
1524
1525 if (keyFile.has_key("Color Management", "PrinterBPC")) {
1526 rtSettings.printerBPC = keyFile.get_boolean("Color Management", "PrinterBPC");
1527 }
1528
1529 if (keyFile.has_key("Color Management", "PrinterProfile")) {
1530 rtSettings.printerProfile = keyFile.get_string("Color Management", "PrinterProfile");
1531 }
1532
1533 if (keyFile.has_key("Color Management", "MonitorProfile")) {
1534 rtSettings.monitorProfile = keyFile.get_string("Color Management", "MonitorProfile");
1535 }
1536
1537 if (keyFile.has_key("Color Management", "AutoMonitorProfile")) {
1538 rtSettings.autoMonitorProfile = keyFile.get_boolean("Color Management", "AutoMonitorProfile");
1539 }
1540
1541 if (keyFile.has_key("Color Management", "Intent")) {
1542 rtSettings.monitorIntent = static_cast<rtengine::RenderingIntent>(keyFile.get_integer("Color Management", "Intent"));
1543 }
1544
1545 if (keyFile.has_key("Color Management", "MonitorBPC")) {
1546 rtSettings.monitorBPC = keyFile.get_boolean("Color Management", "MonitorBPC");
1547 }
1548
1549 if (keyFile.has_key("Color Management", "WhiteBalanceSpotSize")) {
1550 whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize");
1551 }
1552
1553 if (keyFile.has_key("Color Management", "ClutsDirectory")) {
1554 clutsDir = keyFile.get_string("Color Management", "ClutsDirectory");
1555 }
1556 }
1557
1558 if (keyFile.has_group("ICC Profile Creator")) {
1559 if (keyFile.has_key("ICC Profile Creator", "PimariesPreset")) {
1560 ICCPC_primariesPreset = keyFile.get_string("ICC Profile Creator", "PimariesPreset");
1561 }
1562 if (keyFile.has_key("ICC Profile Creator", "RedPrimaryX")) {
1563 ICCPC_redPrimaryX = keyFile.get_double("ICC Profile Creator", "RedPrimaryX");
1564 }
1565 if (keyFile.has_key("ICC Profile Creator", "RedPrimaryY")) {
1566 ICCPC_redPrimaryY = keyFile.get_double("ICC Profile Creator", "RedPrimaryY");
1567 }
1568 if (keyFile.has_key("ICC Profile Creator", "GreenPrimaryX")) {
1569 ICCPC_greenPrimaryX = keyFile.get_double("ICC Profile Creator", "GreenPrimaryX");
1570 }
1571 if (keyFile.has_key("ICC Profile Creator", "GreenPrimaryY")) {
1572 ICCPC_greenPrimaryY = keyFile.get_double("ICC Profile Creator", "GreenPrimaryY");
1573 }
1574 if (keyFile.has_key("ICC Profile Creator", "BluePrimaryX")) {
1575 ICCPC_bluePrimaryX = keyFile.get_double("ICC Profile Creator", "BluePrimaryX");
1576 }
1577 if (keyFile.has_key("ICC Profile Creator", "BluePrimaryY")) {
1578 ICCPC_bluePrimaryY = keyFile.get_double("ICC Profile Creator", "BluePrimaryY");
1579 }
1580 if (keyFile.has_key("ICC Profile Creator", "GammaPreset")) {
1581 ICCPC_gammaPreset = keyFile.get_string("ICC Profile Creator", "GammaPreset");
1582 }
1583 if (keyFile.has_key("ICC Profile Creator", "Gamma")) {
1584 ICCPC_gamma = keyFile.get_double("ICC Profile Creator", "Gamma");
1585 }
1586 if (keyFile.has_key("ICC Profile Creator", "Slope")) {
1587 ICCPC_slope = keyFile.get_double("ICC Profile Creator", "Slope");
1588 }
1589 if (keyFile.has_key("ICC Profile Creator", "ProfileVersion")) {
1590 ICCPC_profileVersion = keyFile.get_string("ICC Profile Creator", "ProfileVersion");
1591 }
1592 if (keyFile.has_key("ICC Profile Creator", "Illuminant")) {
1593 ICCPC_illuminant = keyFile.get_string("ICC Profile Creator", "Illuminant");
1594 }
1595 if (keyFile.has_key("ICC Profile Creator", "Description")) {
1596 ICCPC_description = keyFile.get_string("ICC Profile Creator", "Description");
1597 }
1598 if (keyFile.has_key("ICC Profile Creator", "Copyright")) {
1599 ICCPC_copyright = keyFile.get_string("ICC Profile Creator", "Copyright");
1600 }
1601 if (keyFile.has_key("ICC Profile Creator", "AppendParamsToDesc")) {
1602 ICCPC_appendParamsToDesc = keyFile.get_boolean("ICC Profile Creator", "AppendParamsToDesc");
1603 }
1604 }
1605
1606 if (keyFile.has_group("Sounds")) {
1607 if (keyFile.has_key("Sounds", "Enable")) {
1608 sndEnable = keyFile.get_boolean("Sounds", "Enable");
1609 }
1610
1611 if (keyFile.has_key("Sounds", "BatchQueueDone")) {
1612 sndBatchQueueDone = keyFile.get_string("Sounds", "BatchQueueDone");
1613 }
1614
1615 if (keyFile.has_key("Sounds", "LngEditProcDone")) {
1616 sndLngEditProcDone = keyFile.get_string("Sounds", "LngEditProcDone");
1617 }
1618
1619 if (keyFile.has_key("Sounds", "LngEditProcDoneSecs")) {
1620 sndLngEditProcDoneSecs = keyFile.get_double("Sounds", "LngEditProcDoneSecs");
1621 }
1622 }
1623
1624 if (keyFile.has_group("Fast Export")) {
1625 if (keyFile.has_key("Fast Export", "fastexport_bypass_sharpening")) {
1626 fastexport_bypass_sharpening = keyFile.get_boolean("Fast Export", "fastexport_bypass_sharpening");
1627 }
1628
1629 if (keyFile.has_key("Fast Export", "fastexport_bypass_defringe")) {
1630 fastexport_bypass_defringe = keyFile.get_boolean("Fast Export", "fastexport_bypass_defringe");
1631 }
1632
1633 if (keyFile.has_key("Fast Export", "fastexport_bypass_dirpyrDenoise")) {
1634 fastexport_bypass_dirpyrDenoise = keyFile.get_boolean("Fast Export", "fastexport_bypass_dirpyrDenoise");
1635 }
1636
1637 if (keyFile.has_key("Fast Export", "fastexport_bypass_localContrast")) {
1638 fastexport_bypass_localContrast = keyFile.get_boolean("Fast Export", "fastexport_bypass_localContrast");
1639 }
1640
1641 if (keyFile.has_key("Fast Export", "fastexport_raw_dmethod")) {
1642 fastexport_raw_bayer_method = keyFile.get_string("Fast Export", "fastexport_raw_dmethod");
1643 }
1644
1645 if (keyFile.has_key("Fast Export", "fastexport_raw_bayer_method")) {
1646 fastexport_raw_bayer_method = keyFile.get_string("Fast Export", "fastexport_raw_bayer_method");
1647 }
1648
1649 //if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_bayer_all_enhance" )) fastexport_bypass_raw_bayer_all_enhance = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_all_enhance" );
1650 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_dcb_iterations")) {
1651 fastexport_bypass_raw_bayer_dcb_iterations = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_dcb_iterations");
1652 }
1653
1654 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations")) {
1655 fastexport_bypass_raw_bayer_dcb_iterations = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations");
1656 }
1657
1658 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_dcb_enhance")) {
1659 fastexport_bypass_raw_bayer_dcb_enhance = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_dcb_enhance");
1660 }
1661
1662 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance")) {
1663 fastexport_bypass_raw_bayer_dcb_enhance = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance");
1664 }
1665
1666 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_lmmse_iterations")) {
1667 fastexport_bypass_raw_bayer_lmmse_iterations = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_lmmse_iterations");
1668 }
1669
1670 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations")) {
1671 fastexport_bypass_raw_bayer_lmmse_iterations = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations");
1672 }
1673
1674 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_linenoise")) {
1675 fastexport_bypass_raw_bayer_linenoise = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_linenoise");
1676 }
1677
1678 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_bayer_linenoise")) {
1679 fastexport_bypass_raw_bayer_linenoise = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_bayer_linenoise");
1680 }
1681
1682 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_greenthresh")) {
1683 fastexport_bypass_raw_bayer_greenthresh = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_greenthresh");
1684 }
1685
1686 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_bayer_greenthresh")) {
1687 fastexport_bypass_raw_bayer_greenthresh = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_bayer_greenthresh");
1688 }
1689
1690 if (keyFile.has_key("Fast Export", "fastexport_raw_xtrans_method")) {
1691 fastexport_raw_xtrans_method = keyFile.get_string("Fast Export", "fastexport_raw_xtrans_method");
1692 }
1693
1694 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_ccSteps")) {
1695 fastexport_bypass_raw_ccSteps = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_ccSteps");
1696 }
1697
1698 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_ca")) {
1699 fastexport_bypass_raw_ca = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_ca");
1700 }
1701
1702 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_df")) {
1703 fastexport_bypass_raw_df = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_df");
1704 }
1705
1706 if (keyFile.has_key("Fast Export", "fastexport_bypass_raw_ff")) {
1707 fastexport_bypass_raw_ff = keyFile.get_boolean("Fast Export", "fastexport_bypass_raw_ff");
1708 }
1709
1710 if (keyFile.has_key("Fast Export", "fastexport_icm_input")) {
1711 fastexport_icm_input_profile = keyFile.get_string("Fast Export", "fastexport_icm_input");
1712 }
1713
1714 if (keyFile.has_key("Fast Export", "fastexport_icm_working")) {
1715 fastexport_icm_working_profile = keyFile.get_string("Fast Export", "fastexport_icm_working");
1716 }
1717
1718 if (keyFile.has_key("Fast Export", "fastexport_icm_output")) {
1719 fastexport_icm_output_profile = keyFile.get_string("Fast Export", "fastexport_icm_output");
1720 }
1721
1722 if (keyFile.has_key("Fast Export", "fastexport_icm_output_intent")) {
1723 fastexport_icm_outputIntent = static_cast<rtengine::RenderingIntent>(keyFile.get_integer("Fast Export", "fastexport_icm_output_intent"));
1724 }
1725
1726 if (keyFile.has_key("Fast Export", "fastexport_icm_output_bpc")) {
1727 fastexport_icm_outputBPC = keyFile.get_boolean("Fast Export", "fastexport_icm_output_bpc");
1728 }
1729
1730 if (keyFile.has_key("Fast Export", "fastexport_resize_enabled")) {
1731 fastexport_resize_enabled = keyFile.get_boolean("Fast Export", "fastexport_resize_enabled");
1732 }
1733
1734 if (keyFile.has_key("Fast Export", "fastexport_resize_scale")) {
1735 fastexport_resize_scale = keyFile.get_double("Fast Export", "fastexport_resize_scale");
1736 }
1737
1738 if (keyFile.has_key("Fast Export", "fastexport_resize_appliesTo")) {
1739 fastexport_resize_appliesTo = keyFile.get_string("Fast Export", "fastexport_resize_appliesTo");
1740 }
1741
1742 if (keyFile.has_key("Fast Export", "fastexport_resize_dataspec")) {
1743 fastexport_resize_dataspec = keyFile.get_integer("Fast Export", "fastexport_resize_dataspec");
1744 }
1745
1746 if (keyFile.has_key("Fast Export", "fastexport_resize_width")) {
1747 fastexport_resize_width = keyFile.get_integer("Fast Export", "fastexport_resize_width");
1748 }
1749
1750 if (keyFile.has_key("Fast Export", "fastexport_resize_height")) {
1751 fastexport_resize_height = keyFile.get_integer("Fast Export", "fastexport_resize_height");
1752 }
1753
1754 if (keyFile.has_key("Fast Export", "fastexport_use_fast_pipeline")) {
1755 fastexport_use_fast_pipeline = keyFile.get_integer("Fast Export", "fastexport_use_fast_pipeline");
1756 }
1757 }
1758
1759 if (keyFile.has_group("Dialogs")) {
1760 safeDirGet(keyFile, "Dialogs", "LastIccDir", lastIccDir);
1761 safeDirGet(keyFile, "Dialogs", "LastDarkframeDir", lastDarkframeDir);
1762 safeDirGet(keyFile, "Dialogs", "LastFlatfieldDir", lastFlatfieldDir);
1763 safeDirGet(keyFile, "Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir);
1764 safeDirGet(keyFile, "Dialogs", "LastLabCurvesDir", lastLabCurvesDir);
1765 safeDirGet(keyFile, "Dialogs", "LastPFCurvesDir", lastPFCurvesDir);
1766 safeDirGet(keyFile, "Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir);
1767
1768 safeDirGet(keyFile, "Dialogs", "LastToneCurvesDir", lastToneCurvesDir);
1769 safeDirGet(keyFile, "Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
1770 safeDirGet(keyFile, "Dialogs", "LastLensProfileDir", lastLensProfileDir);
1771 safeDirGet(keyFile, "Dialogs", "LastICCProfCreatorDir", lastICCProfCreatorDir);
1772 safeDirGet(keyFile, "Dialogs", "LastCopyMovePath", lastCopyMovePath);
1773
1774 if (keyFile.has_key("Dialogs", "GimpPluginShowInfoDialog")) {
1775 gimpPluginShowInfoDialog = keyFile.get_boolean("Dialogs", "GimpPluginShowInfoDialog");
1776 }
1777 }
1778
1779 if (keyFile.has_group("Lensfun")) {
1780 if (keyFile.has_key("Lensfun", "DBDirectory")) {
1781 rtSettings.lensfunDbDirectory = keyFile.get_string("Lensfun", "DBDirectory");
1782 }
1783 }
1784
1785 if (keyFile.has_group("Metadata")) {
1786 if (keyFile.has_key("Metadata", "XMPSidecarStyle")) {
1787 std::string val = keyFile.get_string("Metadata", "XMPSidecarStyle");
1788 if (val == "ext") {
1789 rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle::EXT;
1790 } else {
1791 rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle::STD;
1792 }
1793 }
1794 if (keyFile.has_key("Metadata", "XMPSynchronization")) {
1795 std::string val = keyFile.get_string("Metadata", "XMPSynchronization");
1796 if (val == "read") {
1797 rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::READ;
1798 } else if (val == "readwrite") {
1799 rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::READ_WRITE;
1800 } else {
1801 rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::NONE;
1802 }
1803 }
1804 if (keyFile.has_key("Metadata", "ExiftoolPath")) {
1805 rtSettings.exiftool_path = keyFile.get_string("Metadata", "ExiftoolPath");
1806 }
1807 }
1808
1809 if (keyFile.has_group("False Colors Map")) {
1810 const Glib::ustring g = "False Colors Map";
1811 falseColorsMap.clear();
1812 for (auto key : keyFile.get_keys(g)) {
1813 if (key.find("IRE_") == 0) {
1814 size_t end = 0;
1815 std::string s = key.substr(4);
1816 int ire = std::stoi(s, &end);
1817 if (end >= s.size()) {
1818 falseColorsMap[ire] = keyFile.get_string(g, key);
1819 }
1820 }
1821 }
1822 if (falseColorsMap.empty() ||
1823 falseColorsMap.rbegin()->first < 108) {
1824 falseColorsMap[108] = "#000000";
1825 }
1826 }
1827
1828 if (keyFile.has_group("Renaming")) {
1829 const char *g = "Renaming";
1830 if (keyFile.has_key(g, "Pattern")) {
1831 renaming.pattern = keyFile.get_string(g, "Pattern");
1832 }
1833 if (keyFile.has_key(g, "Sidecars")) {
1834 renaming.sidecars = keyFile.get_string(g, "Sidecars");
1835 }
1836 if (keyFile.has_key(g, "NameNormalization")) {
1837 renaming.name_norm = keyFile.get_integer(g, "NameNormalization");
1838 }
1839 if (keyFile.has_key(g, "ExtNormalization")) {
1840 renaming.ext_norm = keyFile.get_integer(g, "ExtNormalization");
1841 }
1842 if (keyFile.has_key(g, "AllowWhitespace")) {
1843 renaming.allow_whitespace = keyFile.get_boolean(g, "AllowWhitespace");
1844 }
1845 if (keyFile.has_key(g, "OnExisting")) {
1846 renaming.on_existing = keyFile.get_integer(g, "OnExisting");
1847 }
1848 if (keyFile.has_key(g, "ProgressiveNumber")) {
1849 renaming.progressive_number = keyFile.get_integer(g, "ProgressiveNumber");
1850 }
1851 }
1852
1853 // --------------------------------------------------------------------------------------------------------
1854
1855 filterOutParsedExtensions();
1856
1857 return;
1858
1859 }
1860 } catch (Glib::Error &err) {
1861 Glib::ustring msg = Glib::ustring::compose("Options::readFromFile / Error code %1 while reading values from \"%2\":\n%3", err.code(), fname, err.what());
1862
1863 if (options.rtSettings.verbose) {
1864 printf("%s\n", msg.c_str());
1865 }
1866
1867 throw Error(msg);
1868 } catch (...) {
1869 Glib::ustring msg = Glib::ustring::compose("Options::readFromFile / Unknown exception while trying to load \"%1\"!", fname);
1870
1871 if (options.rtSettings.verbose) {
1872 printf("%s\n", msg.c_str());
1873 }
1874
1875 throw Error(msg);
1876 }
1877 }
1878
safeDirGet(const Glib::KeyFile & keyFile,const Glib::ustring & section,const Glib::ustring & entryName,Glib::ustring & destination)1879 bool Options::safeDirGet(const Glib::KeyFile& keyFile, const Glib::ustring& section,
1880 const Glib::ustring& entryName, Glib::ustring& destination)
1881 {
1882 try {
1883
1884 if (keyFile.has_key(section, entryName) && !keyFile.get_string(section, entryName).empty()) {
1885 destination = keyFile.get_string(section, entryName);
1886 return true;
1887 }
1888
1889 } catch (Glib::KeyFileError&) {}
1890
1891 return false;
1892 }
1893
saveToFile(Glib::ustring fname)1894 void Options::saveToFile(Glib::ustring fname)
1895 {
1896
1897 Glib::ustring keyData;
1898
1899 try {
1900
1901 Glib::KeyFile keyFile;
1902
1903 keyFile.set_boolean("General", "TabbedEditor", tabbedUI);
1904
1905 if (startupDir == STARTUPDIR_HOME) {
1906 keyFile.set_string("General", "StartupDirectory", "home");
1907 } else if (startupDir == STARTUPDIR_CURRENT) {
1908 keyFile.set_string("General", "StartupDirectory", "current");
1909 } else if (startupDir == STARTUPDIR_CUSTOM) {
1910 keyFile.set_string("General", "StartupDirectory", "custom");
1911 } else if (startupDir == STARTUPDIR_LAST) {
1912 keyFile.set_string("General", "StartupDirectory", "last");
1913 }
1914
1915 keyFile.set_string("General", "StartupPath", startupPath);
1916 keyFile.set_string("General", "DateFormat", dateFormat);
1917 keyFile.set_integer("General", "AdjusterMinDelay", adjusterMinDelay);
1918 keyFile.set_integer("General", "AdjusterMaxDelay", adjusterMaxDelay);
1919 keyFile.set_boolean("General", "MultiUser", multiUser);
1920 keyFile.set_string("General", "Language", language);
1921 keyFile.set_boolean("General", "LanguageAutoDetect", languageAutoDetect);
1922 keyFile.set_string("General", "Theme", theme);
1923 keyFile.set_string("General", "Version", RTVERSION);
1924 keyFile.set_string("General", "DarkFramesPath", rtSettings.darkFramesPath);
1925 keyFile.set_string("General", "FlatFieldsPath", rtSettings.flatFieldsPath);
1926 keyFile.set_boolean("General", "Verbose", rtSettings.verbose);
1927 keyFile.set_integer("General", "ErrorMessageDuration", error_message_duration);
1928 keyFile.set_integer("General", "MaxErrorMessages", max_error_messages);
1929 keyFile.set_integer("External Editor", "EditorKind", editorToSendTo);
1930 keyFile.set_string("External Editor", "GimpDir", gimpDir);
1931 keyFile.set_string("External Editor", "PhotoshopDir", psDir);
1932 keyFile.set_string("External Editor", "CustomEditor", customEditorProg);
1933 keyFile.set_integer("External Editor", "OutputDir", int(editor_out_dir));
1934 keyFile.set_string("External Editor", "CustomOutputDir", editor_custom_out_dir);
1935 keyFile.set_boolean("External Editor", "Float32", editor_float32);
1936 keyFile.set_boolean("External Editor", "BypassOutputProfile", editor_bypass_output_profile);
1937
1938 keyFile.set_boolean("File Browser", "BrowserShowsDate", fbShowDateTime);
1939 keyFile.set_boolean("File Browser", "BrowserShowsExif", fbShowBasicExif);
1940 keyFile.set_boolean("File Browser", "BrowserShowsExpComp", fbShowExpComp);
1941 #ifndef WIN32
1942 keyFile.set_boolean("File Browser", "BrowserShowsHidden", fbShowHidden);
1943 #endif
1944 keyFile.set_integer("File Browser", "ThumbnailSize", thumbSize);
1945 keyFile.set_integer("File Browser", "ThumbnailSizeTab", thumbSizeTab);
1946 keyFile.set_integer("File Browser", "ThumbnailSizeQueue", thumbSizeQueue);
1947 keyFile.set_integer("File Browser", "SameThumbSize", sameThumbSize);
1948 keyFile.set_integer("File Browser", "ThumbnailOrder", int(thumbnailOrder));
1949 keyFile.set_integer("File Browser", "MaxPreviewHeight", maxThumbnailHeight);
1950 keyFile.set_integer("File Browser", "MaxPreviewWidth", maxThumbnailWidth);
1951 keyFile.set_integer("File Browser", "MaxCacheEntries", maxCacheEntries);
1952 Glib::ArrayHandle<Glib::ustring> pext = parseExtensions;
1953 keyFile.set_string_list("File Browser", "ParseExtensions", pext);
1954 Glib::ArrayHandle<int> pextena = parseExtensionsEnabled;
1955 keyFile.set_integer_list("File Browser", "ParseExtensionsEnabled", pextena);
1956 keyFile.set_integer("File Browser", "ThumbnailInterpolation", thumbInterp);
1957 Glib::ArrayHandle<Glib::ustring> pfav = favoriteDirs;
1958 keyFile.set_string_list("File Browser", "FavoriteDirs", pfav);
1959 Glib::ArrayHandle<double> ptzoom = thumbnailZoomRatios;
1960 keyFile.set_double_list("File Browser", "ThumbnailZoomRatios", ptzoom);
1961 keyFile.set_boolean("File Browser", "OverlayedFileNames", overlayedFileNames);
1962 keyFile.set_boolean("File Browser", "FilmStripOverlayedFileNames", filmStripOverlayedFileNames);
1963 keyFile.set_boolean("File Browser", "ShowFileNames", showFileNames);
1964 keyFile.set_boolean("File Browser", "FilmStripShowFileNames", filmStripShowFileNames);
1965 keyFile.set_boolean("File Browser", "InternalThumbIfUntouched", internalThumbIfUntouched);
1966 keyFile.set_boolean("File Browser", "menuGroupRank", menuGroupRank);
1967 keyFile.set_boolean("File Browser", "menuGroupLabel", menuGroupLabel);
1968 keyFile.set_boolean("File Browser", "menuGroupFileOperations", menuGroupFileOperations);
1969 keyFile.set_boolean("File Browser", "menuGroupProfileOperations", menuGroupProfileOperations);
1970 keyFile.set_boolean("File Browser", "menuGroupExtProg", menuGroupExtProg);
1971 keyFile.set_integer("File Browser", "MaxRecentFolders", maxRecentFolders);
1972 {
1973 std::vector<Glib::ustring> temp;
1974 temp.reserve(maxRecentFolders);
1975
1976 for (unsigned int i = 0; i < std::min(recentFolders.size(), maxRecentFolders); i++) {
1977 temp.push_back(recentFolders[i]);
1978 }
1979
1980 keyFile.set_string_list("File Browser", "RecentFolders", temp);
1981 }
1982 switch (thumbnail_rating_mode) {
1983 case ThumbnailRatingMode::XMP:
1984 keyFile.set_string("File Browser", "ThumbnailRatingMode", "xmp");
1985 break;
1986 default: // ThumbnailRatingMode::PROCPARAMS
1987 keyFile.set_string("File Browser", "ThumbnailRatingMode", "procparams");
1988 break;
1989 }
1990 keyFile.set_integer("Clipping Indication", "HighlightThreshold", highlightThreshold);
1991 keyFile.set_integer("Clipping Indication", "ShadowThreshold", shadowThreshold);
1992
1993 keyFile.set_integer("Performance", "RgbDenoiseThreadLimit", rgbDenoiseThreadLimit);
1994 keyFile.set_integer("Performance", "ClutCacheSize", clutCacheSize);
1995 keyFile.set_integer("Performance", "MaxInspectorBuffers", maxInspectorBuffers);
1996 keyFile.set_integer("Performance", "InspectorDelay", inspectorDelay);
1997 keyFile.set_integer("Performance", "PreviewDemosaicFromSidecar", prevdemo);
1998 keyFile.set_boolean("Performance", "SerializeTiffRead", serializeTiffRead);
1999 keyFile.set_boolean("Performance", "DenoiseZoomedOut", denoiseZoomedOut);
2000 keyFile.set_integer("Performance", "ThumbUpdateThreadLimit", thumb_update_thread_limit);
2001 keyFile.set_boolean("Performance", "ThumbDelayUpdate", thumb_delay_update);
2002 keyFile.set_boolean("Performance", "ThumbLazyCaching", thumb_lazy_caching);
2003
2004 keyFile.set_integer("Performance", "WBPreviewMode", wb_preview_mode);
2005 keyFile.set_integer("Inspector", "Mode", int(rtSettings.thumbnail_inspector_mode));
2006 keyFile.set_integer("Inspector", "RawCurve", int(rtSettings.thumbnail_inspector_raw_curve));
2007 keyFile.set_boolean("Inspector", "ZoomFit", thumbnail_inspector_zoom_fit);
2008 keyFile.set_boolean("Inspector", "ShowInfo", thumbnail_inspector_show_info);
2009 keyFile.set_boolean("Inspector", "ShowHistogram", thumbnail_inspector_show_histogram);
2010 keyFile.set_boolean("Inspector", "EnableCMS", thumbnail_inspector_enable_cms);
2011 keyFile.set_integer("Inspector", "BrowserWidth", browser_width_for_inspector);
2012 keyFile.set_boolean("Inspector", "ThumbnailHover", thumbnail_inspector_hover);
2013
2014 keyFile.set_string("Output", "Format", saveFormat.format);
2015 keyFile.set_integer("Output", "JpegQuality", saveFormat.jpegQuality);
2016 keyFile.set_integer("Output", "JpegSubSamp", saveFormat.jpegSubSamp);
2017 keyFile.set_integer("Output", "PngBps", saveFormat.pngBits);
2018 keyFile.set_integer("Output", "TiffBps", saveFormat.tiffBits);
2019 keyFile.set_boolean("Output", "TiffFloat", saveFormat.tiffFloat);
2020 keyFile.set_boolean("Output", "TiffUncompressed", saveFormat.tiffUncompressed);
2021 keyFile.set_boolean("Output", "SaveProcParams", saveFormat.saveParams);
2022
2023 keyFile.set_string("Output", "FormatBatch", saveFormatBatch.format);
2024 keyFile.set_integer("Output", "JpegQualityBatch", saveFormatBatch.jpegQuality);
2025 keyFile.set_integer("Output", "JpegSubSampBatch", saveFormatBatch.jpegSubSamp);
2026 keyFile.set_integer("Output", "PngBpsBatch", saveFormatBatch.pngBits);
2027 keyFile.set_integer("Output", "TiffBpsBatch", saveFormatBatch.tiffBits);
2028 keyFile.set_boolean("Output", "TiffFloatBatch", saveFormatBatch.tiffFloat);
2029 keyFile.set_boolean("Output", "TiffUncompressedBatch", saveFormatBatch.tiffUncompressed);
2030 keyFile.set_boolean("Output", "SaveProcParamsBatch", saveFormatBatch.saveParams);
2031
2032 keyFile.set_string("Output", "PathTemplate", savePathTemplate);
2033 keyFile.set_string("Output", "PathFolder", savePathFolder);
2034 keyFile.set_boolean("Output", "AutoSuffix", autoSuffix);
2035 keyFile.set_boolean("Output", "ForceFormatOpts", forceFormatOpts);
2036 keyFile.set_integer("Output", "SaveMethodNum", saveMethodNum);
2037 keyFile.set_boolean("Output", "UsePathTemplate", saveUsePathTemplate);
2038 keyFile.set_string("Output", "LastSaveAsPath", lastSaveAsPath);
2039 keyFile.set_boolean("Output", "OverwriteOutputFile", overwriteOutputFile);
2040 keyFile.set_boolean("Output", "BatchQueueUseProfile", batch_queue_use_profile);
2041 keyFile.set_string("Output", "BatchQueueProfile", batch_queue_profile_path);
2042 keyFile.set_integer("Output", "ProcParamsAutosaveInterval", sidecar_autosave_interval);
2043
2044 keyFile.set_string("Profiles", "Directory", profilePath);
2045 keyFile.set_boolean("Profiles", "UseBundledProfiles", useBundledProfiles);
2046 keyFile.set_string("Profiles", "LoadSaveProfilePath", loadSaveProfilePath);
2047 keyFile.set_string("Profiles", "RawDefault", defProfRaw);
2048 keyFile.set_string("Profiles", "ImgDefault", defProfImg);
2049 keyFile.set_boolean("Profiles", "FilledProfile", filledProfile);
2050 keyFile.set_boolean("Profiles", "SaveParamsWithFile", saveParamsFile);
2051 keyFile.set_boolean("Profiles", "SaveParamsToCache", saveParamsCache);
2052 keyFile.set_integer("Profiles", "LoadParamsFromLocation", paramsLoadLocation);
2053 keyFile.set_boolean("Profiles", "EmbedParamsInMetadata", params_out_embed);
2054 keyFile.set_boolean("Profiles", "ParamsSidecarStripExtension", params_sidecar_strip_extension);
2055 keyFile.set_string("Profiles", "CustomProfileBuilderPath", CPBPath);
2056 keyFile.set_integer("Profiles", "CustomProfileBuilderKeys", CPBKeys);
2057
2058 Glib::ArrayHandle<Glib::ustring> ahfavorites = favorites;
2059 keyFile.set_string_list("GUI", "Favorites", ahfavorites);
2060 keyFile.set_integer("GUI", "WindowWidth", windowWidth);
2061 keyFile.set_integer("GUI", "WindowHeight", windowHeight);
2062 keyFile.set_integer("GUI", "WindowX", windowX);
2063 keyFile.set_integer("GUI", "WindowY", windowY);
2064 keyFile.set_integer("GUI", "WindowMonitor", windowMonitor);
2065 keyFile.set_integer("GUI", "MeowMonitor", meowMonitor);
2066 keyFile.set_boolean("GUI", "MeowFullScreen", meowFullScreen);
2067 keyFile.set_boolean("GUI", "MeowMaximized", meowMaximized);
2068 keyFile.set_integer("GUI", "MeowWidth", meowWidth);
2069 keyFile.set_integer("GUI", "MeowHeight", meowHeight);
2070 keyFile.set_integer("GUI", "MeowX", meowX);
2071 keyFile.set_integer("GUI", "MeowY", meowY);
2072 keyFile.set_boolean("GUI", "WindowMaximized", windowMaximized);
2073 keyFile.set_integer("GUI", "DetailWindowWidth", detailWindowWidth);
2074 keyFile.set_integer("GUI", "DetailWindowHeight", detailWindowHeight);
2075 keyFile.set_integer("GUI", "DirBrowserWidth", dirBrowserWidth);
2076 keyFile.set_integer("GUI", "DirBrowserHeight", dirBrowserHeight);
2077 keyFile.set_integer("GUI", "SortType", dirBrowserSortType);
2078 keyFile.set_integer("GUI", "PreferencesWidth", preferencesWidth);
2079 keyFile.set_integer("GUI", "PreferencesHeight", preferencesHeight);
2080 keyFile.set_integer("GUI", "SaveAsDialogWidth", saveAsDialogWidth);
2081 keyFile.set_integer("GUI", "SaveAsDialogHeight", saveAsDialogHeight);
2082 keyFile.set_integer("GUI", "ToolPanelWidth", toolPanelWidth);
2083 keyFile.set_integer("GUI", "BrowserToolPanelWidth", browserToolPanelWidth);
2084 keyFile.set_integer("GUI", "BrowserToolPanelHeight", browserToolPanelHeight);
2085 keyFile.set_boolean("GUI", "BrowserToolPanelOpened", browserToolPanelOpened);
2086 keyFile.set_boolean("GUI", "EditorFilmStripOpened", editorFilmStripOpened);
2087 keyFile.set_boolean("GUI", "BrowserDirPanelOpened", browserDirPanelOpened);
2088 keyFile.set_boolean("GUI", "InspectorDirPanelOpened", inspectorDirPanelOpened);
2089 keyFile.set_integer("GUI", "HistoryPanelWidth", historyPanelWidth);
2090 keyFile.set_string("GUI", "FontFamily", fontFamily);
2091 keyFile.set_integer("GUI", "FontSize", fontSize);
2092 keyFile.set_string("GUI", "CPFontFamily", CPFontFamily);
2093 keyFile.set_integer("GUI", "CPFontSize", CPFontSize);
2094 keyFile.set_boolean("GUI", "PseudoHiDPISupport", pseudoHiDPISupport);
2095 keyFile.set_integer("GUI", "LastPreviewScale", lastScale);
2096 keyFile.set_integer("GUI", "PanAccelFactor", panAccelFactor);
2097 keyFile.set_boolean("GUI", "RememberZoomAndPan", rememberZoomAndPan);
2098 keyFile.set_boolean("GUI", "ShowHistory", showHistory);
2099 keyFile.set_boolean("GUI", "ShowInfo", showInfo);
2100 keyFile.set_boolean("GUI", "MainNBVertical", mainNBVertical);
2101 keyFile.set_boolean("GUI", "ShowClippedHighlights", showClippedHighlights);
2102 keyFile.set_boolean("GUI", "ShowClippedShadows", showClippedShadows);
2103 keyFile.set_integer("GUI", "FrameColor", bgcolor);
2104 keyFile.set_boolean("GUI", "ProcessingQueueEnbled", procQueueEnabled);
2105 Glib::ArrayHandle<int> tpopen = tpOpen;
2106 keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen);
2107 keyFile.set_boolean ("GUI", "ToolPanelsExpandedAutoSave", autoSaveTpOpen);
2108 keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode);
2109 keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush);
2110 keyFile.set_double_list ("GUI", "NavGuideBrush", navGuideBrush);
2111 keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition);
2112 keyFile.set_boolean ("GUI", "HistogramRed", histogramRed);
2113 keyFile.set_boolean ("GUI", "HistogramGreen", histogramGreen);
2114 keyFile.set_boolean ("GUI", "HistogramBlue", histogramBlue);
2115 keyFile.set_boolean ("GUI", "HistogramLuma", histogramLuma);
2116 keyFile.set_boolean ("GUI", "HistogramChroma", histogramChroma);
2117 //keyFile.set_boolean ("GUI", "HistogramRAW", histogramRAW);
2118 keyFile.set_boolean ("GUI", "HistogramBar", histogramBar);
2119 keyFile.set_integer ("GUI", "HistogramHeight", histogramHeight);
2120 keyFile.set_integer ("GUI", "HistogramDrawMode", histogramDrawMode);
2121 keyFile.set_double("GUI", "HistogramScalingFactor", histogram_scaling_factor);
2122 keyFile.set_integer("GUI", "HistogramScopeType", rtengine::toUnderlying(histogramScopeType));
2123 keyFile.set_boolean("GUI", "HistogramShowOptionButtons", histogramShowOptionButtons);
2124 keyFile.set_double("GUI", "HistogramTraceBrightness", histogramTraceBrightness);
2125 keyFile.set_integer ("GUI", "NavigatorRGBUnit", (int)navRGBUnit);
2126 keyFile.set_integer ("GUI", "NavigatorLCHUnit", (int)navLCHUnit);
2127 keyFile.set_boolean ("GUI", "ShowFilmStripToolBar", showFilmStripToolBar);
2128 keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow);
2129 keyFile.set_boolean ("GUI", "HideTPVScrollbar", hideTPVScrollbar);
2130 keyFile.set_boolean ("GUI", "HistogramWorking", rtSettings.HistogramWorking);
2131 keyFile.set_integer ("GUI", "CurveBBoxPosition", curvebboxpos);
2132 keyFile.set_boolean("GUI", "ToolPanelsDisable", toolpanels_disable);
2133 keyFile.set_boolean("GUI", "AdjusterForceLinear", adjuster_force_linear);
2134
2135 //Glib::ArrayHandle<int> crvopen = crvOpen;
2136 //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen);
2137
2138 keyFile.set_integer("Crop Settings", "PPI", cropPPI);
2139
2140 keyFile.set_string("Color Management", "PrinterProfile", rtSettings.printerProfile);
2141 keyFile.set_integer("Color Management", "PrinterIntent", rtSettings.printerIntent);
2142 keyFile.set_boolean("Color Management", "PrinterBPC", rtSettings.printerBPC);
2143
2144 keyFile.set_string("Color Management", "ICCDirectory", rtSettings.iccDirectory);
2145 keyFile.set_string("Color Management", "MonitorICCDirectory", rtSettings.monitorIccDirectory);
2146 keyFile.set_string("Color Management", "MonitorProfile", rtSettings.monitorProfile);
2147 keyFile.set_boolean("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile);
2148 keyFile.set_integer("Color Management", "Intent", rtSettings.monitorIntent);
2149 keyFile.set_boolean("Color Management", "MonitorBPC", rtSettings.monitorBPC);
2150
2151 keyFile.set_integer("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize);
2152 keyFile.set_string("Color Management", "ClutsDirectory", clutsDir);
2153
2154 keyFile.set_string("ICC Profile Creator", "PimariesPreset", ICCPC_primariesPreset);
2155 keyFile.set_double("ICC Profile Creator", "RedPrimaryX", ICCPC_redPrimaryX);
2156 keyFile.set_double("ICC Profile Creator", "RedPrimaryY", ICCPC_redPrimaryY);
2157 keyFile.set_double("ICC Profile Creator", "GreenPrimaryX", ICCPC_greenPrimaryX);
2158 keyFile.set_double("ICC Profile Creator", "GreenPrimaryY", ICCPC_greenPrimaryY);
2159 keyFile.set_double("ICC Profile Creator", "BluePrimaryX", ICCPC_bluePrimaryX);
2160 keyFile.set_double("ICC Profile Creator", "BluePrimaryY", ICCPC_bluePrimaryY);
2161 keyFile.set_string("ICC Profile Creator", "GammaPreset", ICCPC_gammaPreset);
2162 keyFile.set_double("ICC Profile Creator", "Gamma", ICCPC_gamma);
2163 keyFile.set_double("ICC Profile Creator", "Slope", ICCPC_slope);
2164 keyFile.set_string("ICC Profile Creator", "ProfileVersion", ICCPC_profileVersion);
2165 keyFile.set_string("ICC Profile Creator", "Illuminant", ICCPC_illuminant);
2166 keyFile.set_string("ICC Profile Creator", "Description", ICCPC_description);
2167 keyFile.set_string("ICC Profile Creator", "Copyright", ICCPC_copyright);
2168 keyFile.set_boolean("ICC Profile Creator", "AppendParamsToDesc", ICCPC_appendParamsToDesc);
2169
2170 keyFile.set_boolean("Sounds", "Enable", sndEnable);
2171 keyFile.set_string("Sounds", "BatchQueueDone", sndBatchQueueDone);
2172 keyFile.set_string("Sounds", "LngEditProcDone", sndLngEditProcDone);
2173 keyFile.set_double("Sounds", "LngEditProcDoneSecs", sndLngEditProcDoneSecs);
2174
2175 keyFile.set_boolean("Fast Export", "fastexport_bypass_sharpening", fastexport_bypass_sharpening);
2176 keyFile.set_boolean("Fast Export", "fastexport_bypass_defringe", fastexport_bypass_defringe);
2177 keyFile.set_boolean("Fast Export", "fastexport_bypass_dirpyrDenoise", fastexport_bypass_dirpyrDenoise);
2178 keyFile.set_boolean("Fast Export", "fastexport_bypass_localContrast", fastexport_bypass_localContrast);
2179 keyFile.set_string("Fast Export", "fastexport_raw_bayer_method", fastexport_raw_bayer_method);
2180 //keyFile.set_boolean ("Fast Export", "fastexport_bypass_bayer_raw_all_enhance" , fastexport_bypass_raw_bayer_all_enhance);
2181 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations", fastexport_bypass_raw_bayer_dcb_iterations);
2182 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance", fastexport_bypass_raw_bayer_dcb_enhance);
2183 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations", fastexport_bypass_raw_bayer_lmmse_iterations);
2184 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_bayer_linenoise", fastexport_bypass_raw_bayer_linenoise);
2185 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_bayer_greenthresh", fastexport_bypass_raw_bayer_greenthresh);
2186 keyFile.set_string("Fast Export", "fastexport_raw_xtrans_method", fastexport_raw_xtrans_method);
2187 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_ccSteps", fastexport_bypass_raw_ccSteps);
2188 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_ca", fastexport_bypass_raw_ca);
2189 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_df", fastexport_bypass_raw_df);
2190 keyFile.set_boolean("Fast Export", "fastexport_bypass_raw_ff", fastexport_bypass_raw_ff);
2191 keyFile.set_string("Fast Export", "fastexport_icm_input", fastexport_icm_input_profile);
2192 keyFile.set_string("Fast Export", "fastexport_icm_working", fastexport_icm_working_profile);
2193 keyFile.set_string("Fast Export", "fastexport_icm_output", fastexport_icm_output_profile);
2194 keyFile.set_integer("Fast Export", "fastexport_icm_output_intent", fastexport_icm_outputIntent);
2195 keyFile.set_boolean("Fast Export", "fastexport_icm_output_bpc", fastexport_icm_outputBPC);
2196 keyFile.set_boolean("Fast Export", "fastexport_resize_enabled", fastexport_resize_enabled);
2197 keyFile.set_double("Fast Export", "fastexport_resize_scale", fastexport_resize_scale);
2198 keyFile.set_string("Fast Export", "fastexport_resize_appliesTo", fastexport_resize_appliesTo);
2199 keyFile.set_integer("Fast Export", "fastexport_resize_dataspec", fastexport_resize_dataspec);
2200 keyFile.set_integer("Fast Export", "fastexport_resize_width", fastexport_resize_width);
2201 keyFile.set_integer("Fast Export", "fastexport_resize_height", fastexport_resize_height);
2202 keyFile.set_integer("Fast Export", "fastexport_use_fast_pipeline", fastexport_use_fast_pipeline);
2203
2204 keyFile.set_string("Dialogs", "LastIccDir", lastIccDir);
2205 keyFile.set_string("Dialogs", "LastDarkframeDir", lastDarkframeDir);
2206 keyFile.set_string("Dialogs", "LastFlatfieldDir", lastFlatfieldDir);
2207 keyFile.set_string("Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir);
2208 keyFile.set_string("Dialogs", "LastLabCurvesDir", lastLabCurvesDir);
2209 keyFile.set_string("Dialogs", "LastPFCurvesDir", lastPFCurvesDir);
2210 keyFile.set_string("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir);
2211 keyFile.set_string("Dialogs", "LastToneCurvesDir", lastToneCurvesDir);
2212 keyFile.set_string("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
2213 keyFile.set_string("Dialogs", "LastLensProfileDir", lastLensProfileDir);
2214 keyFile.set_string("Dialogs", "LastICCProfCreatorDir", lastICCProfCreatorDir);
2215 keyFile.set_string("Dialogs", "LastCopyMovePath", lastCopyMovePath);
2216 keyFile.set_boolean("Dialogs", "GimpPluginShowInfoDialog", gimpPluginShowInfoDialog);
2217
2218 keyFile.set_string("Lensfun", "DBDirectory", rtSettings.lensfunDbDirectory);
2219
2220 switch (rtSettings.xmp_sidecar_style) {
2221 case rtengine::Settings::XmpSidecarStyle::EXT:
2222 keyFile.set_string("Metadata", "XMPSidecarStyle", "ext");
2223 break;
2224 default:
2225 keyFile.set_string("Metadata", "XMPSidecarStyle", "std");
2226 }
2227
2228 switch (rtSettings.metadata_xmp_sync) {
2229 case rtengine::Settings::MetadataXmpSync::READ:
2230 keyFile.set_string("Metadata", "XMPSynchronization", "read");
2231 break;
2232 case rtengine::Settings::MetadataXmpSync::READ_WRITE:
2233 keyFile.set_string("Metadata", "XMPSynchronization", "readwrite");
2234 break;
2235 default:
2236 keyFile.set_string("Metadata", "XMPSynchronization", "none");
2237 }
2238
2239 keyFile.set_string("Metadata", "ExiftoolPath", rtSettings.exiftool_path);
2240
2241 for (auto &p : falseColorsMap) {
2242 keyFile.set_string("False Colors Map", "IRE_" + std::to_string(p.first), p.second);
2243 }
2244
2245 keyFile.set_string("Renaming", "Pattern", renaming.pattern);
2246 keyFile.set_string("Renaming", "Sidecars", renaming.sidecars);
2247 keyFile.set_integer("Renaming", "NameNormalization", renaming.name_norm);
2248 keyFile.set_integer("Renaming", "ExtNormalization", renaming.ext_norm);
2249 keyFile.set_boolean("Renaming", "AllowWhitespace", renaming.allow_whitespace);
2250 keyFile.set_integer("Renaming", "OnExisting", renaming.on_existing);
2251 keyFile.set_integer("Renaming", "ProgressiveNumber", renaming.progressive_number);
2252
2253 keyData = keyFile.to_data();
2254
2255 } catch (Glib::KeyFileError &e) {
2256 throw Error(e.what());
2257 }
2258
2259 FILE *f = g_fopen(fname.c_str(), "wt");
2260
2261 if (f == nullptr) {
2262 std::cout << "Warning! Unable to save your preferences to: " << fname << std::endl;
2263 Glib::ustring msg_ = Glib::ustring::compose(M("MAIN_MSG_WRITEFAILED"), fname.c_str());
2264 throw Error(msg_);
2265 } else {
2266 fprintf(f, "%s", keyData.c_str());
2267 fclose(f);
2268 }
2269
2270 if (options.rtSettings.verbose) {
2271 std::cout << "options saved to " << fname << std::endl;
2272 }
2273 }
2274
load(bool lightweight,int verbose)2275 void Options::load(bool lightweight, int verbose)
2276 {
2277 if (verbose >= 0) {
2278 options.rtSettings.verbose = verbose;
2279 }
2280
2281 // Find the application data path
2282
2283 const gchar* path;
2284 Glib::ustring dPath;
2285
2286 path = g_getenv("ART_SETTINGS");
2287
2288 if (path != nullptr) {
2289 rtdir = Glib::ustring(path);
2290
2291 if (!Glib::path_is_absolute(rtdir)) {
2292 Glib::ustring msg = Glib::ustring::compose("Settings path %1 is not absolute", rtdir);
2293 throw Error(msg);
2294 }
2295 } else {
2296 #ifdef WIN32
2297 WCHAR pathW[MAX_PATH] = {0};
2298
2299 if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_LOCAL_APPDATA, false)) {
2300 char pathA[MAX_PATH];
2301 WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
2302 rtdir = Glib::build_filename(Glib::ustring(pathA), Glib::ustring(CACHEFOLDERNAME));
2303 }
2304
2305 #else
2306 rtdir = Glib::build_filename(Glib::ustring(g_get_user_config_dir()), Glib::ustring(CACHEFOLDERNAME));
2307 #endif
2308 }
2309
2310 if (options.rtSettings.verbose) {
2311 printf("Settings directory (rtdir) = %s\n", rtdir.c_str());
2312 }
2313
2314 // Set the cache folder in RT's base folder
2315 cacheBaseDir = Glib::build_filename(argv0, "mycache");
2316
2317 // Read the global option file (the one located in the application's base folder)
2318 try {
2319 options.readFromFile(Glib::build_filename(argv0, "options"));
2320 } catch (Options::Error &) {
2321 // ignore errors here
2322 }
2323
2324 if (!options.multiUser && path == nullptr) {
2325 rtdir = Glib::build_filename(argv0, "mysettings");
2326 }
2327
2328 // Modify the path of the cache folder to the one provided in ART_CACHE environment variable
2329 path = g_getenv("ART_CACHE");
2330
2331 if (path != nullptr) {
2332 cacheBaseDir = Glib::ustring(path);
2333
2334 if (!Glib::path_is_absolute(cacheBaseDir)) {
2335 Glib::ustring msg = Glib::ustring::compose("Cache base dir %1 is not absolute", cacheBaseDir);
2336 throw Error(msg);
2337 }
2338 }
2339 // No environment variable provided, so falling back to the multi user mode, if enabled
2340 else if (options.multiUser) {
2341 #ifdef WIN32
2342 cacheBaseDir = Glib::build_filename(rtdir, "cache");
2343 #else
2344 cacheBaseDir = Glib::build_filename(Glib::ustring(g_get_user_cache_dir()), Glib::ustring(CACHEFOLDERNAME));
2345 #endif
2346 }
2347
2348 // Read the user option file (the one located somewhere in the user's home folder)
2349 // Those values supersets those of the global option file
2350 try {
2351 options.readFromFile(Glib::build_filename(rtdir, "options"));
2352 if (verbose >= 0) {
2353 options.rtSettings.verbose = verbose;
2354 }
2355 } catch (Options::Error &) {
2356 // If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it
2357 if (!g_mkdir_with_parents(rtdir.c_str(), 511)) {
2358 // Save the option file
2359 options.saveToFile(Glib::build_filename(rtdir, "options"));
2360 }
2361 }
2362
2363 #ifdef __APPLE__
2364
2365 if (options.multiUser) {
2366 // make sure .local/share exists on OS X so we don't get problems with recently-used.xbel
2367 g_mkdir_with_parents(g_get_user_data_dir(), 511);
2368 }
2369
2370 #endif
2371
2372 if (options.rtSettings.verbose) {
2373 printf("Cache directory (cacheBaseDir) = %s\n", cacheBaseDir.c_str());
2374 }
2375
2376 // Update profile's path and recreate it if necessary
2377 options.updatePaths();
2378
2379 // Check default Raw and Img procparams existence
2380 if (options.defProfRaw.empty()) {
2381 options.defProfRaw = DEFPROFILE_RAW;
2382 } else {
2383 if (!options.findProfilePath(options.defProfRaw).empty()) {
2384 if (options.rtSettings.verbose) {
2385 std::cout << "Default profile for raw images \"" << options.defProfRaw << "\" found" << std::endl;
2386 }
2387 } else {
2388 if (options.defProfRaw != DEFPROFILE_RAW) {
2389 options.setDefProfRawMissing(true);
2390
2391 Glib::ustring dpr(DEFPROFILE_RAW);
2392
2393 if (options.findProfilePath(dpr).empty()) {
2394 options.setBundledDefProfRawMissing(true);
2395 }
2396 } else {
2397 options.setBundledDefProfRawMissing(true);
2398 }
2399 }
2400 }
2401
2402 if (options.defProfImg.empty()) {
2403 options.defProfImg = DEFPROFILE_IMG;
2404 } else {
2405 if (!options.findProfilePath(options.defProfImg).empty()) {
2406 if (options.rtSettings.verbose) {
2407 std::cout << "Default profile for non-raw images \"" << options.defProfImg << "\" found" << std::endl;
2408 }
2409 } else {
2410 if (options.defProfImg != DEFPROFILE_IMG) {
2411 options.setDefProfImgMissing(true);
2412
2413 Glib::ustring dpi(DEFPROFILE_IMG);
2414
2415 if (options.findProfilePath(dpi).empty()) {
2416 options.setBundledDefProfImgMissing(true);
2417 }
2418 } else {
2419 options.setBundledDefProfImgMissing(true);
2420 }
2421 }
2422 }
2423
2424 // We handle languages using a hierarchy of translations. The top of the hierarchy is default. This includes a default translation for all items
2425 // (most likely using simple English). The next level is the language: for instance, English, French, Chinese, etc. This file should contain a
2426 // generic translation for all items which differ from default. Finally there is the locale. This is region-specific items which differ from the
2427 // language file. These files must be name in the format <Language> (<LC>), where Language is the name of the language which it inherits from,
2428 // and LC is the local code. Some examples of this would be English (US) (American English), French (FR) (France French), French (CA) (Canadian
2429 // French), etc.
2430 //
2431 // Each level will only contain the differences between itself and its parent translation. For instance, English (UK) or English (CA) may
2432 // include the translation "HISTORY_MSG_34;Avoid Colour Clipping" where English would translate it as "HISTORY_MSG_34;Avoid Color Clipping" (note
2433 // the difference in the spelling of 'colour').
2434 //
2435 // It is important that when naming the translation files, that you stick to the format <Language> or <Language> (<LC>). We depend on that to figure
2436 // out which are the parent translations. Furthermore, there must be a file <Language> for each locale <Language> (<LC>) -- you cannot have
2437 // 'French (CA)' unless there is a file 'French'.
2438
2439 Glib::ustring defaultTranslation = Glib::build_filename(argv0, "languages", "default");
2440 Glib::ustring languageTranslation = "";
2441 Glib::ustring localeTranslation = "";
2442
2443 if (options.languageAutoDetect) {
2444 options.language = langMgr.getOSUserLanguage();
2445 }
2446
2447 if (!options.language.empty()) {
2448 std::vector<Glib::ustring> langPortions = Glib::Regex::split_simple(" ", options.language);
2449
2450 if (langPortions.size() >= 1) {
2451 languageTranslation = Glib::build_filename(argv0, "languages", langPortions.at(0));
2452 }
2453
2454 if (langPortions.size() >= 2) {
2455 localeTranslation = Glib::build_filename(argv0, "languages", options.language);
2456 }
2457 }
2458
2459 langMgr.load(options.language, {localeTranslation, languageTranslation, defaultTranslation});
2460
2461 rtengine::init(&options.rtSettings, argv0, rtdir, !lightweight);
2462 }
2463
save()2464 void Options::save()
2465 {
2466 options.saveToFile(Glib::build_filename(rtdir, "options"));
2467 }
2468
2469 /*
2470 * return true if ext is a parsed extension (retained or not)
2471 */
is_parse_extention(Glib::ustring fname)2472 bool Options::is_parse_extention(Glib::ustring fname)
2473 {
2474 Glib::ustring ext = getExtension(fname).lowercase();
2475
2476 if (!ext.empty()) {
2477 // there is an extension to the filename
2478
2479 // look out if it has one of the listed extensions (selected or not)
2480 for (unsigned int i = 0; i < parseExtensions.size(); i++) {
2481 if (ext == parseExtensions[i]) {
2482 return true;
2483 }
2484 }
2485 }
2486
2487 return false;
2488 }
2489
2490 /*
2491 * return true if fname ends with one of the retained image file extensions
2492 */
has_retained_extention(const Glib::ustring & fname)2493 bool Options::has_retained_extention(const Glib::ustring& fname)
2494 {
2495 return parsedExtensionsSet.find(getExtension(fname).lowercase()) != parsedExtensionsSet.end();
2496 }
2497
2498 // Pattern matches "5.1" from "5.1-23-g12345678", when comparing option.version to RTVERSION
is_new_version()2499 bool Options::is_new_version() {
2500 const std::string vs[] = {versionString, version};
2501 std::vector<std::string> vMajor;
2502
2503 for (const auto& v : vs) {
2504 vMajor.emplace_back(v, 0, v.find_first_not_of("0123456789."));
2505 }
2506
2507 return vMajor.size() == 2 && vMajor[0] != vMajor[1];
2508 }
2509
2510 /*
2511 * return true if ext is an enabled extension
2512 */
is_extention_enabled(const Glib::ustring & ext)2513 bool Options::is_extention_enabled(const Glib::ustring& ext)
2514 {
2515 return parsedExtensionsSet.find(ext.lowercase()) != parsedExtensionsSet.end();
2516 }
2517
getUserProfilePath()2518 Glib::ustring Options::getUserProfilePath()
2519 {
2520 return userProfilePath;
2521 }
2522
getGlobalProfilePath()2523 Glib::ustring Options::getGlobalProfilePath()
2524 {
2525 return globalProfilePath;
2526 }
2527
is_defProfRawMissing()2528 bool Options::is_defProfRawMissing()
2529 {
2530 return defProfError & rtengine::toUnderlying(DefProfError::defProfRawMissing);
2531 }
is_defProfImgMissing()2532 bool Options::is_defProfImgMissing()
2533 {
2534 return defProfError & rtengine::toUnderlying(DefProfError::defProfImgMissing);
2535 }
setDefProfRawMissing(bool value)2536 void Options::setDefProfRawMissing(bool value)
2537 {
2538 if (value) {
2539 defProfError |= rtengine::toUnderlying(DefProfError::defProfRawMissing);
2540 } else {
2541 defProfError &= ~rtengine::toUnderlying(DefProfError::defProfRawMissing);
2542 }
2543 }
setDefProfImgMissing(bool value)2544 void Options::setDefProfImgMissing(bool value)
2545 {
2546 if (value) {
2547 defProfError |= rtengine::toUnderlying(DefProfError::defProfImgMissing);
2548 } else {
2549 defProfError &= ~rtengine::toUnderlying(DefProfError::defProfImgMissing);
2550 }
2551 }
is_bundledDefProfRawMissing()2552 bool Options::is_bundledDefProfRawMissing()
2553 {
2554 return defProfError & rtengine::toUnderlying(DefProfError::bundledDefProfRawMissing);
2555 }
is_bundledDefProfImgMissing()2556 bool Options::is_bundledDefProfImgMissing()
2557 {
2558 return defProfError & rtengine::toUnderlying(DefProfError::bundledDefProfImgMissing);
2559 }
setBundledDefProfRawMissing(bool value)2560 void Options::setBundledDefProfRawMissing(bool value)
2561 {
2562 if (value) {
2563 defProfError |= rtengine::toUnderlying(DefProfError::bundledDefProfRawMissing);
2564 } else {
2565 defProfError &= ~rtengine::toUnderlying(DefProfError::bundledDefProfRawMissing);
2566 }
2567 }
setBundledDefProfImgMissing(bool value)2568 void Options::setBundledDefProfImgMissing(bool value)
2569 {
2570 if (value) {
2571 defProfError |= rtengine::toUnderlying(DefProfError::bundledDefProfImgMissing);
2572 } else {
2573 defProfError &= ~rtengine::toUnderlying(DefProfError::bundledDefProfImgMissing);
2574 }
2575 }
getICCProfileCopyright()2576 Glib::ustring Options::getICCProfileCopyright()
2577 {
2578 Glib::Date now;
2579 now.set_time_current();
2580 return Glib::ustring::compose("Copyright RawTherapee %1, CC0", now.get_year());
2581 }
2582
2583
getParamFile(const Glib::ustring & fname)2584 Glib::ustring Options::getParamFile(const Glib::ustring &fname)
2585 {
2586 if (params_sidecar_strip_extension) {
2587 return removeExtension(fname) + paramFileExtension;
2588 } else {
2589 return fname + paramFileExtension;
2590 }
2591 }
2592
2593
getXmpSidecarFile(const Glib::ustring & fname)2594 Glib::ustring Options::getXmpSidecarFile(const Glib::ustring &fname)
2595 {
2596 return rtengine::Exiv2Metadata::xmpSidecarPath(fname);
2597 }
2598