/* * 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 #include #endif Options options; Glib::ustring versionString = VERSION; Glib::ustring paramFileExtension = ".pp3"; Options::Options () { setDefaults (); } const char *DefaultLanguage = "English (US)"; void Options::setDefaults () { font = "sans, 10"; windowWidth = 900; windowHeight = 560; windowMaximized = false; firstRun = true; savesParamsAtExit = true; saveFormat.format = "jpg"; saveFormat.jpegQuality = 100; saveFormat.pngCompression = 6; saveFormat.pngBits = 8; saveFormat.tiffBits = 8; saveFormat.tiffUncompressed = true; saveFormat.saveParams = true; // was false saveFormatBatch.format = "jpg"; saveFormatBatch.jpegQuality = 100; saveFormatBatch.pngCompression = 6; saveFormatBatch.pngBits = 8; saveFormatBatch.tiffBits = 8; saveFormatBatch.tiffUncompressed = true; saveFormatBatch.saveParams = true; // was false savePathTemplate = "%p1/converted/%f"; savePathFolder = ""; saveUsePathTemplate = true; defProfRaw = "default"; defProfImg = "neutral"; dateFormat = "%y-%m-%d"; adjusterDelay = 0; startupDir = STARTUPDIR_LAST; // was STARTUPDIR_HOME ; an empty startupPath is now correctly handled (open in the Home dir) startupPath = ""; profilePath = "profiles"; dirBrowserWidth = 200; dirBrowserHeight = 150; preferencesWidth = 0; preferencesHeight = 0; toolPanelWidth = 300; browserToolPanelWidth = 300; browserToolPanelHeight = 300; historyPanelWidth = 230; // was 150 lastScale = 5; // was 4 panAccelFactor = 5; lastCropSize = 1; fbOnlyRaw = false; fbShowDateTime = true; fbShowBasicExif = true; fbShowExpComp = true; fbShowHidden = false; fbArrangement = 2; // was 0 multiUser = true; version = VERSION; thumbSize = 240; // was 80 thumbSizeTab = 80; showHistory = true; showFilePanelState = 0; // Not used anymore ; was the thumb strip state showInfo = true; // was false cropPPI = 600; // was 300 showClippedHighlights = false; showClippedShadows = false; highlightThreshold = 253; // was 254 shadowThreshold = 8; // was 0 bgcolor = 0; blinkClipped = false; // was true 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; // TODO: Should this be TRUE for worst case screen resolution or FALSE for nicer interface by default ??? useSystemTheme = true; maxThumbnailHeight = 400; maxCacheEntries = 20000; // was 10000 thumbnailFormat = FT_Custom; // was FT_Custom16 thumbInterp = 1; autoSuffix = false; 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; // was true 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 = true; internalThumbIfUntouched = true; // if TRUE, only fast, internal preview images are taken if the image is not edited yet showFileNames = true; tabbedUI = true; // was false; multiDisplayMode = 0; tunnelMetaData = false; histogramPosition = 2; histogramBar = true; showProfileSelector = true; FileBrowserToolbarSingleRow = true; hideTPVScrollbar = false; UseIconNoText = true; whiteBalanceSpotSize = 8; squareDetailWindow = false; menuGroupRank = true; menuGroupLabel = true; menuGroupFileOperations = true; menuGroupProfileOperations = true; cutOverlayBrush = std::vector (4); cutOverlayBrush[3] = 0.667; // :-p sndEnable=true; sndLngEditProcDoneSecs=3.0; // 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_LD_EDGETOLERANCE 0, // ADDSET_WB_TEMPERATURE 0, // ADDSET_WB_GREEN 0, // ADDSET_CBOOST_AMOUNT 0, // ADDSET_CS_BLUEYELLOW 0, // ADDSET_CS_GREENMAGENTA 0, // ADDSET_ROTATE_DEGREE 0, // ADDSET_DIST_AMOUNT 0, // ADDSET_PERSPECTIVE 0, // ADDSET_CA 0, // ADDSET_VIGN_AMOUNT 0, // ADDSET_LC_SATURATION 0, // ADDSET_TC_SATURATION 0, // ADDSET_TC_HLCOMPAMOUNT 0, // ADDSET_TC_HLCOMPTHRESH 0, // ADDSET_TC_SHCOMP 0, // ADDSET_DIRPYREQ 0, // ADDSET_DIRPYRDN_CHLUM 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_VIBRANCE_PSTHRESHOLD 0, // ADDSET_FREE_OUPUT_GAMMA 0, // ADDSET_FREE_OUTPUT_SLOPE }; 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"; #else rtSettings.iccDirectory = "/usr/share/color/icc"; #endif rtSettings.colorimetricIntent = 1; rtSettings.monitorProfile = ""; rtSettings.autoMonitorProfile = false; rtSettings.LCMSSafeMode = true; 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_gBT709"; rtSettings.bruce = "Bruce"; rtSettings.beta = "BetaRGB"; rtSettings.best = "BestRGB"; rtSettings.verbose = false; rtSettings.gamutICC = true; } 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_integer ("Clipping Indication", "HighlightThreshold", highlightThreshold); keyFile.set_integer ("Clipping Indication", "ShadowThreshold", shadowThreshold); keyFile.set_boolean ("Clipping Indication", "BlinkClipped", blinkClipped); keyFile.set_string ("Output", "Format", saveFormat.format); keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); 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", "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", "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_string ("Profiles", "RawDefault", defProfRaw); keyFile.set_string ("Profiles", "ImgDefault", defProfImg); keyFile.set_boolean ("Profiles", "SaveParamsWithFile", saveParamsFile); keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache); keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation); keyFile.set_string ("Profiles", "CustomProfileBuilder", customProfileBuilder); 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_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_integer ("GUI", "HistogramPosition", histogramPosition); keyFile.set_boolean ("GUI", "HistogramBar", histogramBar); 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); //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_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); keyFile.set_boolean ("Color Management", "LCMSSafeMode", rtSettings.LCMSSafeMode); keyFile.set_string ("Color Management", "RT_Adobe_RGB", rtSettings.adobe); keyFile.set_string ("Color Management", "RT_Pro_Photo", rtSettings.prophoto); keyFile.set_string ("Color Management", "RT_Pro_Photo10", rtSettings.prophoto10); keyFile.set_string ("Color Management", "Wide_Gamut", rtSettings.widegamut); keyFile.set_string ("Color Management", "RT_S_rgb", rtSettings.srgb); keyFile.set_string ("Color Management", "RT_S_rgb10", rtSettings.srgb10); keyFile.set_string ("Color Management", "B_eta", rtSettings.beta); keyFile.set_string ("Color Management", "B_est", rtSettings.best); keyFile.set_string ("Color Management", "B_ruce", rtSettings.bruce); keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize); keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC); 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); FILE *f = safe_g_fopen (fname, "wt"); if (f==NULL) return 1; else { fprintf (f, "%s", keyFile.to_data().c_str()); fclose (f); return 0; } } Glib::ustring Options::rtdir; Glib::ustring Options::cacheBaseDir; void Options::load () { // Find the application data path #ifdef WIN32 /* * If LOCALAPPDATA exists, RT run on a WinVista/7 system, so we use LOCALAPPDATA as is * otherwise RT run on a Win2000/XP system, so we rebuild the path like this: %USERPROFILE%\Local Settings\Application Data * * Folder redirection is then fully supported on WinVista/7, but not on Win2000/XP */ const gchar* dataPath; Glib::ustring dPath; // ->ODUIS: How to make that commented out code work ? /*WCHAR path[MAX_PATH] = {0}; if (SHGetSpecialFolderPathW(NULL, path, CSIDL_LOCAL_APPDATA, false)) { dPath = path; printf("SHGetSpecialFolderPathW: \"%s\"\n", dPath.c_str()); } else { printf("SHGetSpecialFolderPathW: Fail!\n"); }*/ dataPath = g_getenv("RT_CACHE"); if (dataPath != NULL) rtdir = Glib::ustring(dataPath); else { dataPath = g_getenv("LOCALAPPDATA"); if (dataPath != NULL) rtdir = Glib::ustring(dataPath) + Glib::ustring("\\") + Glib::ustring(CACHEFOLDERNAME); else { dataPath = g_getenv("USERPROFILE"); if (dataPath != NULL) rtdir = Glib::ustring(dataPath) + Glib::ustring("\\Local Settings\\Application Data\\") + Glib::ustring(CACHEFOLDERNAME); } } #else rtdir = Glib::ustring(g_get_user_config_dir ()) + Glib::ustring("/") + Glib::ustring(CACHEFOLDERNAME); #endif // Set the cache folder in RT's base folder cacheBaseDir = argv0 + "/cache"; // Read the global option file (the one located in the application's base folder) options.readFromFile (argv0+"/options"); // 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 (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)) { // Recreate the user's profile folder Glib::ustring profdir = rtdir + "/profiles"; safe_g_mkdir_with_parents (profdir, 511); // Save the option file options.saveToFile (rtdir + "/options"); } // Modify the path of the cache folder to the user's personal folder #ifdef WIN32 cacheBaseDir = rtdir + "/cache"; #else cacheBaseDir = Glib::ustring(g_get_user_cache_dir()) + Glib::ustring("/") + Glib::ustring(CACHEFOLDERNAME); #endif } //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); } void Options::save () { if (options.multiUser==false) { options.saveToFile (argv0+"/options"); } else { options.saveToFile (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.length()) { // 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; }