/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ #include "options.h" #include #include #include #include "multilangmgr.h" #include "../rtengine/safekeyfile.h" #include "addsetids.h" #include "guiutils.h" #include "../rtengine/safegtk.h" #include "version.h" #ifdef WIN32 #include // for GCC32 #ifndef _WIN32_IE #define _WIN32_IE 0x0600 #endif #include #endif // User's settings directory, including images' profiles if used Glib::ustring Options::rtdir; // User's cached datas' directory Glib::ustring Options::cacheBaseDir; Options options; Glib::ustring versionString = VERSION; Glib::ustring versionSuffixString = VERSION_SUFFIX; Glib::ustring paramFileExtension = ".pp3"; Options::Options () { defProfRawMissing = false; defProfImgMissing = false; setDefaults (); } const char *DefaultLanguage = "English (US)"; inline bool Options::checkProfilePath(Glib::ustring &path) { if (path.empty()) return false; Glib::ustring p = getUserProfilePath(); if (!p.empty() && safe_file_test (path+paramFileExtension, Glib::FILE_TEST_EXISTS)) return true; p = getGlobalProfilePath(); if (!p.empty() && safe_file_test (path+paramFileExtension, Glib::FILE_TEST_EXISTS)) return true; else return false; } bool Options::checkDirPath(Glib::ustring &path, Glib::ustring errString) { if (safe_file_test (path, Glib::FILE_TEST_EXISTS) && safe_file_test (path, Glib::FILE_TEST_IS_DIR)) return true; else { if (!errString.empty()) printf("%s\n", errString.c_str()); return false; } } void Options::updatePaths() { Glib::ustring tmpPath; userProfilePath = ""; globalProfilePath = ""; if (Glib::path_is_absolute(profilePath)) { // absolute path if (!checkDirPath (profilePath, "")) { safe_g_mkdir_with_parents (profilePath, 511); if (!checkDirPath (profilePath, "")) // had problems with mkdir_with_parents return value on OS X, just check dir again printf("Error: user's profiles' directory \"%s\" creation failed\n", profilePath.c_str()); } if (checkDirPath (profilePath, "Error: the specified user's profiles' path doesn't point to a directory or doesn't exist!\n")) { if (multiUser) { userProfilePath = profilePath; tmpPath = Glib::build_filename(argv0, "profiles"); if(checkDirPath (tmpPath, "Error: the global's profiles' path doesn't point to a directory or doesn't exist!\n")) { if (userProfilePath != tmpPath) globalProfilePath = tmpPath; } } else { globalProfilePath = profilePath; } } else { tmpPath = Glib::build_filename(argv0, "profiles"); if(checkDirPath (tmpPath, "Error: the global's profiles' path doesn't point to a directory or doesn't exist!\n")) { globalProfilePath = tmpPath; } } } else { // relative paths if (multiUser) { tmpPath = Glib::build_filename(rtdir, profilePath); if (!checkDirPath (tmpPath, "")) { safe_g_mkdir_with_parents (tmpPath, 511); if (!checkDirPath (tmpPath, "")) printf("Error: user's profiles' directory \"%s\" creation failed\n", tmpPath.c_str()); } if(checkDirPath (tmpPath, "Error: the specified user's profiles' path doesn't point to a directory!\n")) { userProfilePath = tmpPath; } tmpPath = Glib::build_filename(argv0, "profiles"); if(checkDirPath (tmpPath, "Error: the specified user's profiles' path doesn't point to a directory or doesn't exist!\n")) { globalProfilePath = tmpPath; } } else { // common directory // directory name set in options is ignored, we use the default directory name tmpPath = Glib::build_filename(argv0, "profiles"); if(checkDirPath (tmpPath, "Error: no global profiles' directory found!\n")) { globalProfilePath = tmpPath; } } } Glib::ustring preferredPath = getPreferredProfilePath(); // Paths are updated only if the user or global profile path is set if (lastRgbCurvesDir.empty() || !safe_file_test (lastRgbCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastRgbCurvesDir, Glib::FILE_TEST_IS_DIR)) lastRgbCurvesDir = preferredPath; if (lastLabCurvesDir.empty() || !safe_file_test (lastLabCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastLabCurvesDir, Glib::FILE_TEST_IS_DIR)) lastLabCurvesDir = preferredPath; if (lastPFCurvesDir.empty() || !safe_file_test (lastPFCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastPFCurvesDir, Glib::FILE_TEST_IS_DIR)) lastPFCurvesDir = preferredPath; if (lastHsvCurvesDir.empty() || !safe_file_test (lastHsvCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastHsvCurvesDir, Glib::FILE_TEST_IS_DIR)) lastHsvCurvesDir = preferredPath; if (lastToneCurvesDir.empty() || !safe_file_test (lastToneCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastToneCurvesDir, Glib::FILE_TEST_IS_DIR)) lastToneCurvesDir = preferredPath; if (lastProfilingReferenceDir.empty() || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_IS_DIR)) lastProfilingReferenceDir = preferredPath; if (lastVibranceCurvesDir.empty() || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_IS_DIR)) lastVibranceCurvesDir = preferredPath; if (loadSaveProfilePath.empty() || !safe_file_test (loadSaveProfilePath, Glib::FILE_TEST_EXISTS) || !safe_file_test (loadSaveProfilePath, Glib::FILE_TEST_IS_DIR)) loadSaveProfilePath = preferredPath; if (lastBWCurvesDir.empty() || !safe_file_test (lastBWCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastBWCurvesDir, Glib::FILE_TEST_IS_DIR)) lastBWCurvesDir = preferredPath; } Glib::ustring Options::getPreferredProfilePath() { if (!userProfilePath.empty()) return userProfilePath; else if (!globalProfilePath.empty()) return globalProfilePath; else return ""; } /** @brief Get the absolute path of the given filename or the "Neutral" special value * *@param profName path + filename of the procparam to look for. A filename without path can be provided for backward compatibility. * In this case, this parameter will be update with the new format. *@return Send back the absolute path of the given filename or "Neutral" if "Neutral" has been set to profName. Implementor will have * 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. */ Glib::ustring Options::findProfilePath(Glib::ustring &profName) { if (profName.empty()) return ""; if (profName == DEFPROFILE_INTERNAL) return profName; Glib::ustring p = profName.substr(0, 4); if (p=="${U}") { // the path starts by the User virtual path p = getUserProfilePath(); Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension); if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) return Glib::path_get_dirname(fullPath); } else if (p=="${G}") { // the path starts by the User virtual path p = getGlobalProfilePath(); Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension); if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) return Glib::path_get_dirname(fullPath); } else { // compatibility case -> convert the path to the new format p = getUserProfilePath(); Glib::ustring fullPath = Glib::build_filename(p, profName + paramFileExtension); if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { // update the profile path profName = Glib::build_filename("${U}", profName); return Glib::path_get_dirname(fullPath); } p = getGlobalProfilePath(); fullPath = Glib::build_filename(p, profName + paramFileExtension); if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { profName = Glib::build_filename("${G}", profName); return Glib::path_get_dirname(fullPath); } } return ""; } void Options::setDefaults () { font = "sans, 8"; windowWidth = 1200; windowHeight = 680; windowMaximized = true; saveAsDialogWidth = 920; saveAsDialogHeight = 680; savesParamsAtExit = true; saveFormat.format = "jpg"; saveFormat.jpegQuality = 90; saveFormat.jpegSubSamp = 2; saveFormat.pngCompression = 6; saveFormat.pngBits = 8; saveFormat.tiffBits = 8; saveFormat.tiffUncompressed = true; saveFormat.saveParams = true; saveFormatBatch.format = "jpg"; saveFormatBatch.jpegQuality = 90; saveFormatBatch.jpegSubSamp = 2; saveFormatBatch.pngCompression = 6; saveFormatBatch.pngBits = 8; saveFormatBatch.tiffBits = 16; saveFormatBatch.tiffUncompressed = true; saveFormatBatch.saveParams = true; savePathTemplate = "%p1/converted/%f"; savePathFolder = ""; saveUsePathTemplate = true; defProfRaw = DEFPROFILE_RAW; defProfImg = DEFPROFILE_IMG; dateFormat = "%y-%m-%d"; adjusterDelay = 0; startupDir = STARTUPDIR_LAST; startupPath = ""; useBundledProfiles = true; dirBrowserWidth = 260; dirBrowserHeight = 350; preferencesWidth = 800; preferencesHeight = 0; toolPanelWidth = 390; browserToolPanelWidth = 430; browserToolPanelHeight = 600; browserToolPanelOpened = true;; browserDirPanelOpened = true; historyPanelWidth = 330; lastScale = 5; panAccelFactor = 5; lastCropSize = 1; fbOnlyRaw = false; fbShowDateTime = true; fbShowBasicExif = true; fbShowExpComp = false; fbShowHidden = false; fbArrangement = 2; // was 0 multiUser = true; profilePath = "profiles"; loadSaveProfilePath = ""; // will be corrected in load as otherwise construction fails version = "0.0.0.0"; // temporary value; will be correctly set in RTWindow::on_realize thumbSize = 240; thumbSizeTab = 180; thumbSizeQueue = 160; sameThumbSize = false; // preferring speed of switch between file browser and single editor tab showHistory = true; showFilePanelState = 0; // Not used anymore ; was the thumb strip state showInfo = true; cropPPI = 600; showClippedHighlights = false; showClippedShadows = false; highlightThreshold = 253; // was 254 shadowThreshold = 8; // was 0 bgcolor = 0; blinkClipped = false; language = DefaultLanguage; languageAutoDetect= langMgr.isOSLanguageDetectSupported(); lastSaveAsPath = ""; overwriteOutputFile = false; // if TRUE, existing output JPGs/PNGs are overwritten, instead of adding ..-1.jpg, -2.jpg etc. theme = "25-Gray-Gray"; slimUI = false; useSystemTheme = false; maxThumbnailHeight = 400; maxCacheEntries = 20000; thumbInterp = 1; autoSuffix = true; forceFormatOpts = true; saveMethodNum = 0; // 0->immediate, 1->putToQueuHead, 2->putToQueueTail saveParamsFile = true; // was false, but saving the procparams files next to the file make more sense when reorganizing file tree than in a cache saveParamsCache = false; // there's no need to save the procparams files in a cache if saveParamsFile is true paramsLoadLocation = PLL_Input; // was PLL_Cache procQueueEnabled = false; gimpDir = ""; psDir = ""; customEditorProg = ""; editorToSendTo = 1; liveThumbnails = true; favoriteDirs.clear(); tpOpen.clear (); //crvOpen.clear (); parseExtensions.clear (); parseExtensionsEnabled.clear (); parsedExtensions.clear (); renameUseTemplates = false; renameTemplates.clear (); thumbnailZoomRatios.clear (); thumbnailZoomRatios.push_back (0.2); thumbnailZoomRatios.push_back (0.3); thumbnailZoomRatios.push_back (0.45); thumbnailZoomRatios.push_back (0.6); thumbnailZoomRatios.push_back (0.8); thumbnailZoomRatios.push_back (1.0); overlayedFileNames = false; internalThumbIfUntouched = true; // if TRUE, only fast, internal preview images are taken if the image is not edited yet showFileNames = true; tabbedUI = false; mainNBVertical = true; multiDisplayMode = 0; tunnelMetaData = true; histogramPosition = 1; histogramBar = true; histogramFullMode = false; rgbDenoiseThreadLimit = 0; filledProfile = false; showProfileSelector = true; FileBrowserToolbarSingleRow = false; hideTPVScrollbar = false; UseIconNoText = true; whiteBalanceSpotSize = 8; squareDetailWindow = true; menuGroupRank = true; menuGroupLabel = true; menuGroupFileOperations = true; menuGroupProfileOperations = true; menuGroupExtProg = true; fastexport_bypass_sharpening = true; fastexport_bypass_sharpenEdge = true; fastexport_bypass_sharpenMicro = true; //fastexport_bypass_lumaDenoise = true; //fastexport_bypass_colorDenoise = true; fastexport_bypass_defringe = true; fastexport_bypass_dirpyrDenoise = true; fastexport_bypass_sh_hq = true; fastexport_bypass_dirpyrequalizer = true; //fastexport_bypass_raw_all_enhance = true; fastexport_bypass_raw_ccSteps = true; fastexport_bypass_raw_dcb_iterations = true; fastexport_bypass_raw_dcb_enhance = true; fastexport_bypass_raw_lmmse_iterations = true; fastexport_bypass_raw_ca = true; fastexport_bypass_raw_linenoise = true; fastexport_bypass_raw_greenthresh = true; fastexport_bypass_raw_df = true; fastexport_bypass_raw_ff = true; fastexport_raw_dmethod = "fast"; fastexport_icm_input = "(camera)"; fastexport_icm_working = "ProPhoto"; fastexport_icm_output = "RT_sRGB"; fastexport_icm_gamma = "default"; fastexport_resize_enabled = true; fastexport_resize_scale = 1; fastexport_resize_appliesTo = "Cropped area"; fastexport_resize_method = "Lanczos"; fastexport_resize_dataspec = 3; fastexport_resize_width = 900; fastexport_resize_height = 900; cutOverlayBrush = std::vector (4); cutOverlayBrush[3] = 0.667; // :-p navGuideBrush = std::vector (4); //default to red navGuideBrush[0] = 1.0; navGuideBrush[1] = 0.0; navGuideBrush[2] = 0.0; navGuideBrush[3] = 1.0; sndEnable=true; sndLngEditProcDoneSecs=3.0; #ifdef __linux__ sndBatchQueueDone = "complete"; sndLngEditProcDone = "window-attention"; #endif // Reminder: 0 = SET mode, 1 = ADD mode int babehav[] = { 0, // ADDSET_TC_EXPCOMP 0, // ADDSET_TC_BRIGHTNESS 0, // ADDSET_TC_BLACKLEVEL 0, // ADDSET_TC_CONTRAST 0, // ADDSET_SH_HIGHLIGHTS 0, // ADDSET_SH_SHADOWS 0, // ADDSET_SH_LOCALCONTRAST 0, // ADDSET_LC_BRIGHTNESS 0, // ADDSET_LC_CONTRAST 0, // ADDSET_SHARP_AMOUNT 0, // ADDSET_WB_TEMPERATURE 0, // ADDSET_WB_GREEN 0, // ADDSET_ROTATE_DEGREE 0, // ADDSET_DIST_AMOUNT 0, // ADDSET_PERSPECTIVE 0, // ADDSET_CA 0, // ADDSET_VIGN_AMOUNT 0, // ADDSET_VIGN_RADIUS 0, // ADDSET_VIGN_STRENGTH 0, // ADDSET_VIGN_CENTER 0, // ADDSET_LC_CHROMATICITY 0, // ADDSET_TC_SATURATION 0, // ADDSET_TC_HLCOMPAMOUNT 0, // ADDSET_TC_HLCOMPTHRESH 0, // ADDSET_TC_SHCOMP 0, // ADDSET_DIRPYREQ 0, // ADDSET_DIRPYRDN_LUMA 0, // ADDSET_DIRPYRDN_LUDET 0, // ADDSET_DIRPYRDN_CHROMA 0, // ADDSET_DIRPYRDN_CHROMARED 0, // ADDSET_DIRPYRDN_CHROMABLUE 0, // ADDSET_DIRPYRDN_GAMMA 0, // ADDSET_CHMIXER 0, // ADDSET_PREPROCESS_GREENEQUIL 0, // ADDSET_PREPROCESS_LINEDENOISE 0, // ADDSET_RAWCACORR 0, // ADDSET_RAWEXPOS_LINEAR 0, // ADDSET_RAWEXPOS_PRESER 0, // ADDSET_RAWEXPOS_BLACKS 0, // ADDSET_SHARPENEDGE_AMOUNT 0, // ADDSET_SHARPENMICRO_AMOUNT 0, // ADDSET_SHARPENEDGE_PASS 0, // ADDSET_SHARPENMICRO_UNIFORMITY 0, // ADDSET_VIBRANCE_PASTELS 0, // ADDSET_VIBRANCE_SATURATED 0, // ADDSET_FREE_OUPUT_GAMMA 0, // ADDSET_FREE_OUTPUT_SLOPE 0, // ADDSET_CAT_DEGREE 0, // ADDSET_CAT_ADAPSCEN 0, // ADDSET_CAT_ADAPLUM 0, // ADDSET_CAT_LIGHT 0, // ADDSET_CAT_RSTPRO 0, // ADDSET_CAT_BADPIX 0, // ADDSET_CAT_JLIGHT 0, // ADDSET_CAT_CHROMA 0, // ADDSET_CAT_CONTRAST 0, // ADDSET_CAT_CHROMA_S 0, // ADDSET_CAT_CHROMA_M 0, // ADDSET_CAT_HUE 0, // ADDSET_CAT_BADPIX 0, // ADDSET_WB_EQUAL 0, // ADDSET_GRADIENT_DEGREE 0, // ADDSET_GRADIENT_FEATHER 0, // ADDSET_GRADIENT_STRENGTH 0, // ADDSET_GRADIENT_CENTER 0, // ADDSET_PCVIGNETTE_STRENGTH 0, // ADDSET_PCVIGNETTE_FEATHER 0, // ADDSET_PCVIGNETTE_ROUNDNESS 0, // ADDSET_BLACKWHITE_HUES 0, // ADDSET_BLACKWHITE_GAMMA 0, // ADDSET_DIRPYREQ_THRESHOLD 0, // ADDSET_DIRPYREQ_SKINPROTECT }; baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); rtSettings.darkFramesPath = ""; rtSettings.flatFieldsPath = ""; #ifdef WIN32 const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows" if (sysRoot!=NULL) rtSettings.iccDirectory = Glib::ustring(sysRoot) + Glib::ustring("\\System32\\spool\\drivers\\color"); else rtSettings.iccDirectory = "C:\\WINDOWS\\System32\\spool\\drivers\\color"; #elif defined __APPLE__ rtSettings.iccDirectory = "/library/ColorSync/Profiles/Displays"; #else rtSettings.iccDirectory = "/usr/share/color/icc"; #endif rtSettings.colorimetricIntent = 1; rtSettings.viewingdevice=0; rtSettings.viewingdevicegrey=3; rtSettings.monitorProfile = ""; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" rtSettings.prophoto10 = "RT_Large_g10"; // these names appear in the menu "output profile" rtSettings.srgb10 = "RT_sRGB_g10"; rtSettings.widegamut = "WideGamutRGB"; rtSettings.srgb = "RT_sRGB"; rtSettings.bruce = "Bruce"; rtSettings.beta = "BetaRGB"; rtSettings.best = "BestRGB"; rtSettings.verbose = false; rtSettings.gamutICC = true; rtSettings.gamutLch = true; rtSettings.amchroma = 40;//between 20 and 140 low values increase effect..and also artefacts, high values reduces rtSettings.artifact_cbdl = 4.; rtSettings.level0_cbdl = 0; rtSettings.level123_cbdl = 30; rtSettings.ciecamfloat = true; rtSettings.protectred = 60; rtSettings.protectredh = 0.3; rtSettings.CRI_color =0; rtSettings.autocielab=true; rtSettings.denoiselabgamma=2; rtSettings.HistogramWorking = false; // rtSettings.ciebadpixgauss=false; rtSettings.rgbcurveslumamode_gamut=true; lastIccDir = rtSettings.iccDirectory; lastDarkframeDir = rtSettings.darkFramesPath; lastFlatfieldDir = rtSettings.flatFieldsPath; // rtSettings.bw_complementary = true; // There is no reasonable default for curves. We can still suppose that they will take place // in a subdirectory of the user's own ProcParams presets, i.e. in a subdirectory // of the one pointed to by the "profile" field. // The following fields will then be initialized when "profile" will have its final value, // at the end of the "updatePaths" method. lastRgbCurvesDir = ""; lastLabCurvesDir = ""; lastPFCurvesDir = ""; lastHsvCurvesDir = ""; lastToneCurvesDir = ""; lastVibranceCurvesDir = ""; lastProfilingReferenceDir = ""; lastBWCurvesDir = ""; } Options* Options::copyFrom (Options* other) { *this = *other; return this; } void Options::filterOutParsedExtensions () { parsedExtensions.clear(); for (unsigned int i=0; i pext = parseExtensions; keyFile.set_string_list ("File Browser", "ParseExtensions", pext); Glib::ArrayHandle pextena = parseExtensionsEnabled; keyFile.set_integer_list ("File Browser", "ParseExtensionsEnabled", pextena); keyFile.set_integer ("File Browser", "ThumbnailArrangement", fbArrangement); keyFile.set_integer ("File Browser", "ThumbnailInterpolation", thumbInterp); keyFile.set_boolean ("File Browser", "LiveThumbnails", liveThumbnails); Glib::ArrayHandle pfav = favoriteDirs; keyFile.set_string_list ("File Browser", "FavoriteDirs", pfav); Glib::ArrayHandle pren = renameTemplates; keyFile.set_string_list ("File Browser", "RenameTemplates", pren); keyFile.set_boolean ("File Browser", "RenameUseTemplates", renameUseTemplates); Glib::ArrayHandle ptzoom = thumbnailZoomRatios; keyFile.set_double_list ("File Browser", "ThumbnailZoomRatios", ptzoom); keyFile.set_boolean ("File Browser", "OverlayedFileNames", overlayedFileNames); keyFile.set_boolean ("File Browser", "ShowFileNames", showFileNames ); keyFile.set_boolean ("File Browser", "InternalThumbIfUntouched", internalThumbIfUntouched ); keyFile.set_boolean ("File Browser", "menuGroupRank", menuGroupRank); keyFile.set_boolean ("File Browser", "menuGroupLabel", menuGroupLabel); keyFile.set_boolean ("File Browser", "menuGroupFileOperations", menuGroupFileOperations); keyFile.set_boolean ("File Browser", "menuGroupProfileOperations", menuGroupProfileOperations); keyFile.set_boolean ("File Browser", "menuGroupExtProg", menuGroupExtProg); keyFile.set_integer ("Clipping Indication", "HighlightThreshold", highlightThreshold); keyFile.set_integer ("Clipping Indication", "ShadowThreshold", shadowThreshold); keyFile.set_boolean ("Clipping Indication", "BlinkClipped", blinkClipped); keyFile.set_integer ("Performance", "RgbDenoiseThreadLimit", rgbDenoiseThreadLimit); keyFile.set_string ("Output", "Format", saveFormat.format); keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); keyFile.set_integer ("Output", "JpegSubSamp", saveFormat.jpegSubSamp); keyFile.set_integer ("Output", "PngCompression", saveFormat.pngCompression); keyFile.set_integer ("Output", "PngBps", saveFormat.pngBits); keyFile.set_integer ("Output", "TiffBps", saveFormat.tiffBits); keyFile.set_boolean ("Output", "TiffUncompressed", saveFormat.tiffUncompressed); keyFile.set_boolean ("Output", "SaveProcParams", saveFormat.saveParams); keyFile.set_string ("Output", "FormatBatch", saveFormatBatch.format); keyFile.set_integer ("Output", "JpegQualityBatch", saveFormatBatch.jpegQuality); keyFile.set_integer ("Output", "JpegSubSampBatch", saveFormatBatch.jpegSubSamp); keyFile.set_integer ("Output", "PngCompressionBatch", saveFormatBatch.pngCompression); keyFile.set_integer ("Output", "PngBpsBatch", saveFormatBatch.pngBits); keyFile.set_integer ("Output", "TiffBpsBatch", saveFormatBatch.tiffBits); keyFile.set_boolean ("Output", "TiffUncompressedBatch", saveFormatBatch.tiffUncompressed); keyFile.set_boolean ("Output", "SaveProcParamsBatch", saveFormatBatch.saveParams); keyFile.set_string ("Output", "PathTemplate", savePathTemplate); keyFile.set_string ("Output", "PathFolder", savePathFolder); keyFile.set_boolean ("Output", "AutoSuffix", autoSuffix); keyFile.set_boolean ("Output", "ForceFormatOpts", forceFormatOpts); keyFile.set_integer ("Output", "SaveMethodNum", saveMethodNum); keyFile.set_boolean ("Output", "UsePathTemplate", saveUsePathTemplate); keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath); keyFile.set_boolean ("Output", "OverwriteOutputFile", overwriteOutputFile); keyFile.set_boolean ("Output", "TunnelMetaData", tunnelMetaData); keyFile.set_string ("Profiles", "Directory", profilePath); keyFile.set_boolean ("Profiles", "UseBundledProfiles", useBundledProfiles); keyFile.set_string ("Profiles", "LoadSaveProfilePath", loadSaveProfilePath); keyFile.set_string ("Profiles", "RawDefault", defProfRaw); keyFile.set_string ("Profiles", "ImgDefault", defProfImg); keyFile.set_boolean ("Profiles", "FilledProfile", filledProfile); keyFile.set_boolean ("Profiles", "SaveParamsWithFile", saveParamsFile); keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache); keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation); keyFile.set_string ("Profiles", "CustomProfileBuilderPath", CPBPath); keyFile.set_integer ("Profiles", "CustomProfileBuilderKeys", CPBKeys); keyFile.set_string ("GUI", "Font", font); keyFile.set_integer ("GUI", "WindowWidth", windowWidth); keyFile.set_integer ("GUI", "WindowHeight", windowHeight); keyFile.set_boolean ("GUI", "WindowMaximized", windowMaximized); keyFile.set_integer ("GUI", "DirBrowserWidth", dirBrowserWidth); keyFile.set_integer ("GUI", "DirBrowserHeight", dirBrowserHeight); keyFile.set_integer ("GUI", "PreferencesWidth", preferencesWidth); keyFile.set_integer ("GUI", "PreferencesHeight", preferencesHeight); keyFile.set_integer ("GUI", "SaveAsDialogWidth", saveAsDialogWidth); keyFile.set_integer ("GUI", "SaveAsDialogHeight", saveAsDialogHeight); keyFile.set_integer ("GUI", "ToolPanelWidth", toolPanelWidth); keyFile.set_integer ("GUI", "BrowserToolPanelWidth", browserToolPanelWidth); keyFile.set_integer ("GUI", "BrowserToolPanelHeight", browserToolPanelHeight); keyFile.set_boolean ("GUI", "BrowserToolPanelOpened", browserToolPanelOpened); keyFile.set_boolean ("GUI", "BrowserDirPanelOpened", browserDirPanelOpened); keyFile.set_integer ("GUI", "HistoryPanelWidth", historyPanelWidth); keyFile.set_integer ("GUI", "LastPreviewScale", lastScale); keyFile.set_integer ("GUI", "PanAccelFactor", panAccelFactor); keyFile.set_integer ("GUI", "LastCropSize", lastCropSize); keyFile.set_boolean ("GUI", "ShowHistory", showHistory); keyFile.set_integer ("GUI", "ShowFilePanelState", showFilePanelState); keyFile.set_boolean ("GUI", "ShowInfo", showInfo); keyFile.set_boolean ("GUI", "MainNBVertical", mainNBVertical); keyFile.set_boolean ("GUI", "ShowClippedHighlights", showClippedHighlights); keyFile.set_boolean ("GUI", "ShowClippedShadows", showClippedShadows); keyFile.set_integer ("GUI", "FrameColor", bgcolor); keyFile.set_boolean ("GUI", "ProcessingQueueEnbled", procQueueEnabled); Glib::ArrayHandle tpopen = tpOpen; keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode); keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush); keyFile.set_double_list ("GUI", "NavGuideBrush", navGuideBrush); keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition); keyFile.set_boolean ("GUI", "HistogramBar", histogramBar); keyFile.set_boolean ("GUI", "HistogramFullMode", histogramFullMode); keyFile.set_boolean ("GUI", "ShowProfileSelector", showProfileSelector); keyFile.set_boolean ("GUI", "SquareDetailWindow", squareDetailWindow); keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow); keyFile.set_boolean ("GUI", "HideTPVScrollbar", hideTPVScrollbar); keyFile.set_boolean ("GUI", "UseIconNoText", UseIconNoText); keyFile.set_boolean ("GUI", "HistogramWorking", rtSettings.HistogramWorking); //Glib::ArrayHandle crvopen = crvOpen; //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); keyFile.set_integer ("Crop Settings", "PPI", cropPPI); keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory); keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile); keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); keyFile.set_string ("Color Management", "AdobeRGB", rtSettings.adobe); keyFile.set_string ("Color Management", "ProPhoto", rtSettings.prophoto); keyFile.set_string ("Color Management", "ProPhoto10", rtSettings.prophoto10); keyFile.set_string ("Color Management", "WideGamut", rtSettings.widegamut); keyFile.set_string ("Color Management", "sRGB", rtSettings.srgb); keyFile.set_string ("Color Management", "sRGB10", rtSettings.srgb10); keyFile.set_string ("Color Management", "Beta", rtSettings.beta); keyFile.set_string ("Color Management", "Best", rtSettings.best); keyFile.set_string ("Color Management", "Bruce", rtSettings.bruce); keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize); keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC); // keyFile.set_boolean ("Color Management", "BWcomplement", rtSettings.bw_complementary); keyFile.set_boolean ("Color Management", "Ciecamfloat", rtSettings.ciecamfloat); keyFile.set_boolean ("Color Management", "GamutLch", rtSettings.gamutLch); keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred); keyFile.set_integer ("Color Management", "Amountchroma", rtSettings.amchroma); keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); keyFile.set_integer ("Color Management", "CRI", rtSettings.CRI_color); keyFile.set_integer ("Color Management", "DenoiseLabgamma", rtSettings.denoiselabgamma); // keyFile.set_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); keyFile.set_double ("Color Management", "CBDLArtif", rtSettings.artifact_cbdl); keyFile.set_double ("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); keyFile.set_double ("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); Glib::ArrayHandle bab = baBehav; keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); keyFile.set_boolean ("Sounds", "Enable", sndEnable); keyFile.set_string ("Sounds", "BatchQueueDone", sndBatchQueueDone); keyFile.set_string ("Sounds", "LngEditProcDone", sndLngEditProcDone); keyFile.set_double ("Sounds", "LngEditProcDoneSecs", sndLngEditProcDoneSecs); keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpening" , fastexport_bypass_sharpening ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenEdge" , fastexport_bypass_sharpenEdge ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenMicro" , fastexport_bypass_sharpenMicro ); //keyFile.set_boolean ("Fast Export", "fastexport_bypass_lumaDenoise" , fastexport_bypass_lumaDenoise ); //keyFile.set_boolean ("Fast Export", "fastexport_bypass_colorDenoise" , fastexport_bypass_colorDenoise ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_defringe" , fastexport_bypass_defringe ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrDenoise" , fastexport_bypass_dirpyrDenoise ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_sh_hq" , fastexport_bypass_sh_hq ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrequalizer" , fastexport_bypass_dirpyrequalizer ); //keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_all_enhance" , fastexport_bypass_raw_all_enhance ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ccSteps" , fastexport_bypass_raw_ccSteps ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_dcb_iterations" , fastexport_bypass_raw_dcb_iterations); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_dcb_enhance" , fastexport_bypass_raw_dcb_enhance ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_lmmse_iterations" , fastexport_bypass_raw_lmmse_iterations); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ca" , fastexport_bypass_raw_ca ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_linenoise" , fastexport_bypass_raw_linenoise ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_greenthresh" , fastexport_bypass_raw_greenthresh ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_df" , fastexport_bypass_raw_df ); keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ff" , fastexport_bypass_raw_ff ); keyFile.set_string ("Fast Export", "fastexport_raw_dmethod" , fastexport_raw_dmethod ); keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); keyFile.set_string ("Fast Export", "fastexport_resize_appliesTo" , fastexport_resize_appliesTo ); keyFile.set_string ("Fast Export", "fastexport_resize_method" , fastexport_resize_method ); keyFile.set_integer ("Fast Export", "fastexport_resize_dataspec" , fastexport_resize_dataspec ); keyFile.set_integer ("Fast Export", "fastexport_resize_width" , fastexport_resize_width ); keyFile.set_integer ("Fast Export", "fastexport_resize_height" , fastexport_resize_height ); keyFile.set_string ("Dialogs", "LastIccDir", lastIccDir); keyFile.set_string ("Dialogs", "LastDarkframeDir", lastDarkframeDir); keyFile.set_string ("Dialogs", "LastFlatfieldDir", lastFlatfieldDir); keyFile.set_string ("Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir); keyFile.set_string ("Dialogs", "LastLabCurvesDir", lastLabCurvesDir); keyFile.set_string ("Dialogs", "LastPFCurvesDir", lastPFCurvesDir); keyFile.set_string ("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); keyFile.set_string ("Dialogs", "LastBWCurvesDir", lastBWCurvesDir); keyFile.set_string ("Dialogs", "LastToneCurvesDir", lastToneCurvesDir); keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); FILE *f = safe_g_fopen (fname, "wt"); if (f==NULL) { if (options.rtSettings.verbose) printf("Options::saveToFile / Error: unable to open file \"%s\" with write access!\n", fname.c_str()); return 1; } else { fprintf (f, "%s", keyFile.to_data().c_str()); fclose (f); return 0; } } bool Options::load () { // Find the application data path const gchar* path; Glib::ustring dPath; path = g_getenv("RT_SETTINGS"); if (path != NULL) { rtdir = Glib::ustring(path); if (!Glib::path_is_absolute(rtdir)) return false; } else { #ifdef WIN32 WCHAR pathW[MAX_PATH]={0}; char pathA[MAX_PATH]; if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_LOCAL_APPDATA,false)) { WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); rtdir = Glib::build_filename(Glib::ustring(pathA), Glib::ustring(CACHEFOLDERNAME)); } #else rtdir = Glib::build_filename(Glib::ustring(g_get_user_config_dir ()), Glib::ustring(CACHEFOLDERNAME)); #endif } if (options.rtSettings.verbose) printf("Settings directory (rtdir) = %s\n", rtdir.c_str()); // Set the cache folder in RT's base folder cacheBaseDir = Glib::build_filename(argv0, "cache"); // Read the global option file (the one located in the application's base folder) options.readFromFile (Glib::build_filename(argv0, "options")); // Modify the path of the cache folder to the one provided in RT_CACHE environment variable path = g_getenv("RT_CACHE"); if (path != NULL) { cacheBaseDir = Glib::ustring(path); if (!Glib::path_is_absolute(cacheBaseDir)) return false; } // No environment variable provided, so falling back to the multi user mode, is enabled else if (options.multiUser) { #ifdef WIN32 cacheBaseDir = Glib::build_filename(rtdir, "cache"); #else cacheBaseDir = Glib::build_filename(Glib::ustring(g_get_user_cache_dir()), Glib::ustring(CACHEFOLDERNAME)); #endif } // Check if RT is installed in Multi-User mode if (options.multiUser) { // Read the user option file (the one located somewhere in the user's home folder) // Those values supersets those of the global option file int r = options.readFromFile (Glib::build_filename(rtdir, "options")); // If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it if (r && !safe_g_mkdir_with_parents (rtdir, 511)) { // Save the option file options.saveToFile (Glib::build_filename(rtdir, "options")); } #ifdef __APPLE__ // make sure .local/share exists on OS X so we don't get problems with recently-used.xbel safe_g_mkdir_with_parents (g_get_user_data_dir(), 511); #endif } if (options.rtSettings.verbose) printf("Cache directory (cacheBaseDir) = %s\n", cacheBaseDir.c_str()); // Update profile's path and recreate it if necessary options.updatePaths(); // Check default Raw and Img procparams existence if (options.defProfRaw.empty()) options.defProfRaw = DEFPROFILE_INTERNAL; else { Glib::ustring tmpFName = options.findProfilePath(options.defProfRaw); if (!tmpFName.empty()) { if (options.rtSettings.verbose) printf("Raws' default profile \"%s\" found\n", options.defProfRaw.c_str()); } else { if (options.rtSettings.verbose) printf("Raws' default profile \"%s\" not found or not set -> using Internal values\n", options.defProfRaw.c_str()); options.defProfRaw = DEFPROFILE_INTERNAL; options.defProfRawMissing = true; } } if (options.defProfImg.empty()) options.defProfImg = DEFPROFILE_INTERNAL; else { Glib::ustring tmpFName = options.findProfilePath(options.defProfImg); if (!tmpFName.empty()) { if (options.rtSettings.verbose) printf("Images' default profile \"%s\" found\n", options.defProfImg.c_str()); } else { if (options.rtSettings.verbose) printf("Images' default profile \"%s\" not found or not set -> using Internal values\n", options.defProfImg.c_str()); options.defProfImg = DEFPROFILE_INTERNAL; options.defProfImgMissing = true; } } //We handle languages using a hierarchy of translations. The top of the hierarchy is default. This includes a default translation for all items // (most likely using simple English). The next level is the language: for instance, English, French, Chinese, etc. This file should contain a // generic translation for all items which differ from default. Finally there is the locale. This is region-specific items which differ from the // language file. These files must be name in the format (), where Language is the name of the language which it inherits from, // and LC is the local code. Some examples of this would be English (US) (American English), French (FR) (Franch French), French (CA) (Canadian // French), etc. // // Each level will only contain the differences between itself and its parent translation. For instance, English (UK) or English (CA) may // include the translation "HISTORY_MSG_34;Avoid Colour Clipping" where English would translate it as "HISTORY_MSG_34;Avoid Color Clipping" (note // the difference in the spelling of 'colour'). // // It is important that when naming the translation files, that you stick to the format or (). We depend on that to figure // out which are the parent translations. Furthermore, there must be a file for each locale () -- you cannot have // 'French (CA)' unless there is a file 'French'. Glib::ustring defaultTranslation = argv0 + "/languages/default"; Glib::ustring languageTranslation = ""; Glib::ustring localeTranslation = ""; if (options.languageAutoDetect) options.language=langMgr.getOSUserLanguage(); if (!options.language.empty()){ std::vector langPortions = Glib::Regex::split_simple(" ", options.language); if (langPortions.size() >= 1){ languageTranslation = argv0 + "/languages/" + langPortions.at(0); } if (langPortions.size() >= 2){ localeTranslation = argv0 + "/languages/" + options.language; } } langMgr.load(localeTranslation, new MultiLangMgr(languageTranslation, new MultiLangMgr(defaultTranslation))); rtengine::init (&options.rtSettings, argv0, rtdir); return true; } void Options::save () { if (options.multiUser==false) { options.saveToFile (Glib::build_filename(argv0, "options")); } else { options.saveToFile (Glib::build_filename(rtdir, "options")); } } /* * return true if fname ends with one of the retained image file extensions */ bool Options::has_retained_extention (Glib::ustring fname) { Glib::ustring ext = getExtension(fname).lowercase(); if (!ext.empty()) { // there is an extension to the filename // look out if it has one of the retained extensions for (unsigned int i=0; i=(int)parseExtensionsEnabled.size() || parseExtensionsEnabled[j]; return false; }