diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech
index f0a9608fa..0a267f6dd 100644
--- a/rtdata/languages/Czech
+++ b/rtdata/languages/Czech
@@ -36,7 +36,7 @@
#35 2015-11-24 updated by mkyral
#36 2016-10-18 updated by mkyral
#37 2017-01-10 updated by mkyral
-
+#38 2017-04-26 updated by mkyral
ABOUT_TAB_BUILD;Verze
ABOUT_TAB_CREDITS;Zásluhy
ABOUT_TAB_LICENSE;Licence
@@ -71,6 +71,15 @@ CURVEEDITOR_TOOLTIPPASTE;Vložit křivku ze schránky.
CURVEEDITOR_TOOLTIPSAVE;Uložit současnou křivku.
CURVEEDITOR_TYPE;Typ
DIRBROWSER_FOLDERS;Složky
+DYNPROFILEEDITOR_DELETE;Smazat
+DYNPROFILEEDITOR_EDIT;Upravit
+DYNPROFILEEDITOR_EDIT_RULE;Upravit pravidlo dynamického profilu
+DYNPROFILEEDITOR_ENTRY_TOOLTIP;Porovnávání rozlišuje velikost písmen.\nPro vložení regulárního výrazu přidejte\nprefix "re:".
+DYNPROFILEEDITOR_MOVE_DOWN;Posunout dolů
+DYNPROFILEEDITOR_MOVE_UP;Posunout nahoru
+DYNPROFILEEDITOR_NEW;Nový
+DYNPROFILEEDITOR_NEW_RULE;Nové pravidlo dynamického profilu
+DYNPROFILEEDITOR_PROFILE;Profil zpracování
EDITWINDOW_TITLE;Editace obrázku
EDIT_OBJECT_TOOLTIP;V náhledovém okně zobrazí widget umožňující přizpůsobení nástroje.
EDIT_PIPETTE_TOOLTIP;Pro přidání bodu na křivku, podržte klávesu Ctrl a klikněte levým tlačítkem na vybraný bod v náhledu obrázku.\nPro úpravu bodu podržte klávesu Ctrl a klikněte levým tlačítkem na odpovídající oblast v náhledu, následně uvolněte klávesu Ctrl (pokud si přejete jemné změny) a za stálého držení levého tlačítka myši pohybujte myší nahoru a dolů což bude posouvat bod na křivce nahoru a dolů.
@@ -97,6 +106,7 @@ EXIFPANEL_RESETALL;Obnovit vše
EXIFPANEL_RESETALLHINT;Obnoví původní hodnoty u všech štítků.
EXIFPANEL_RESETHINT;Obnoví původní hodnoty u vybraných štítků.
EXIFPANEL_SUBDIRECTORY;Podadresář
+EXPORT_BYPASS;Kroky zpracování pro přeskočení
EXPORT_BYPASS_ALL;Vybrat / Zrušit výběr všeho
EXPORT_BYPASS_DEFRINGE;Vynechat odstranění lemu
EXPORT_BYPASS_DIRPYRDENOISE;Vynechat redukci šumu
@@ -119,8 +129,12 @@ EXPORT_FASTEXPORTOPTIONS;Volby rychlého exportu
EXPORT_INSTRUCTIONS;Volba rychlého exportu umožňuje potlačit vybrané nastavení procesu vyvolání a zkrátit tak čas a zdroje potřebné pro zpracování fronty tím, že se pro vyvolání použije nastavení rychlého exportu. Tato metoda je doporučována pro rychlejší vyvolání obrázků v nižším rozlišení v případě, že je důležitá rychlost, nebo pokud je požadováno vyvolání jednoho nebo více obrázků v nižším rozlišení bez změny uložených parametrů vyvolání.
EXPORT_MAXHEIGHT;Maximální výška:
EXPORT_MAXWIDTH;Maximální šířka:
+EXPORT_PIPELINE;Fronta zpracování
EXPORT_PUTTOQUEUEFAST; Vložit do fronty pro rychlý export
EXPORT_RAW_DMETHOD;Metoda demozajkování
+EXPORT_USE_FAST_PIPELINE;Vyhrazený (kompletní zpracování zmenšeného obrázku)
+EXPORT_USE_FAST_PIPELINE_TIP;Použije vyhrazenou frontu zpracování v režimu rychlého exportu a vymění tak kvalitu za rychlost. Zmenšení obrázku se provede co nejdříve po zahájení zpracování, na rozdíl od standardního zpracování, kde se provádí až na závěr. Zrychlení může být velmi významné, ale připravte se na artefakty a celkové zhoršení kvality výstupu.
+EXPORT_USE_NORMAL_PIPELINE;Standardní (přeskočí některé kroky, zmenší až na konci)
EXTPROGTARGET_1;raw
EXTPROGTARGET_2;Zpracování fronty
FILEBROWSER_ADDDELTEMPLATE;Přidat/Smazat šablony...
@@ -143,7 +157,6 @@ FILEBROWSER_DELETEDLGMSG;Jste si jisti, že chcete vymazat %1 vybraných
FILEBROWSER_DELETEDLGMSGINCLPROC;Jste si jisti, že chcete vymazat %1 vybraných souborů včetně výstupů dávkového zpracování?
FILEBROWSER_EMPTYTRASH;Vysypat koš
FILEBROWSER_EMPTYTRASHHINT;Trvale smazat soubory z koše,
-FILEBROWSER_EXEC_CPB;Vlastní generátor profilu
FILEBROWSER_EXTPROGMENU;Otevřít pomocí
FILEBROWSER_FLATFIELD;Flat Field
FILEBROWSER_MOVETODARKFDIR;Přesunout do složky tmavých snímků
@@ -193,6 +206,7 @@ FILEBROWSER_RANK3_TOOLTIP;Hodnocení 3 *\nZkratka: Shift-3
FILEBROWSER_RANK4_TOOLTIP;Hodnocení 4 *\nZkratka: Shift-4
FILEBROWSER_RANK5_TOOLTIP;Hodnocení 5 *\nZkratka: Shift-5
FILEBROWSER_RENAMEDLGLABEL;Přejmenování souboru
+FILEBROWSER_RESETDEFAULTPROFILE;Vrátit se k původnímu
FILEBROWSER_SELECTDARKFRAME;Výběr tmavého snímku...
FILEBROWSER_SELECTFLATFIELD;Výběr Flat Field...
FILEBROWSER_SHOWCOLORLABEL1HINT;Ukázat obrázky s červeným štítkem.\nZkratka: Alt-1
@@ -710,6 +724,38 @@ HISTORY_MSG_440;Metoda KdDÚ
HISTORY_MSG_441;Retinex - Přenos zisku
HISTORY_MSG_442;Retinex - Měřítko
HISTORY_MSG_443;Kompenzace výstupního černého bodu
+HISTORY_MSG_444;VB - Zdůraznění teploty
+HISTORY_MSG_445;Raw Dílčí snímek
+HISTORY_MSG_446;EvPixelShiftMotion
+HISTORY_MSG_447;EvPixelShiftMotionCorrection
+HISTORY_MSG_448;EvPixelShiftStddevFactorGreen
+HISTORY_MSG_449;PS přizpůsobení ISO
+HISTORY_MSG_450;EvPixelShiftNreadIso
+HISTORY_MSG_451;EvPixelShiftPrnu
+HISTORY_MSG_452;PS Ukázat pohyb
+HISTORY_MSG_453;PS Zobrazit jen masku
+HISTORY_MSG_454;EvPixelShiftAutomatic
+HISTORY_MSG_455;EvPixelShiftNonGreenHorizontal
+HISTORY_MSG_456;EvPixelShiftNonGreenVertical
+HISTORY_MSG_457;PS Kontrola červená/modrá
+HISTORY_MSG_458;EvPixelShiftStddevFactorRed
+HISTORY_MSG_459;EvPixelShiftStddevFactorBlue
+HISTORY_MSG_460;EvPixelShiftGreenAmaze
+HISTORY_MSG_461;EvPixelShiftNonGreenAmaze
+HISTORY_MSG_462;PS Kontrola zelená
+HISTORY_MSG_463;EvPixelShiftRedBlueWeight
+HISTORY_MSG_464;PS Maska pohybové neostrosti
+HISTORY_MSG_465;PS Poloměr rozostření
+HISTORY_MSG_466;EvPixelShiftSum
+HISTORY_MSG_467;EvPixelShiftExp0
+HISTORY_MSG_468;PS Vyplnit díry
+HISTORY_MSG_469;PS Medián
+HISTORY_MSG_470;EvPixelShiftMedian3
+HISTORY_MSG_471;PS korekce pohybu
+HISTORY_MSG_472;PS plynulé přechody
+HISTORY_MSG_473;PS Použít LMMSE
+HISTORY_MSG_474;PS korekce
+HISTORY_MSG_475;PS korekce kanálu
HISTORY_NEWSNAPSHOT;Přidat
HISTORY_NEWSNAPSHOT_TOOLTIP;Zkratka: Alt-s
HISTORY_SNAPSHOT;Snímek
@@ -766,7 +812,7 @@ MAIN_BUTTON_SAVE_TOOLTIP;Uložit současný obrázek.\nZkratka: Ctrl+s
MAIN_BUTTON_SENDTOEDITOR;Upravit obrázek v externím editoru
MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Editovat současný obrázek v externím editoru.\nZkratka: Ctrl+e
MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Zobrazit/skrýt všechny postranní panely.\nZkratka: m
-MAIN_BUTTON_UNFULLSCREEN;Ukončit mód celé obrazovky
+MAIN_BUTTON_UNFULLSCREEN;Ukončit režim celé obrazovky
MAIN_FRAME_BATCHQUEUE;Fronta
MAIN_FRAME_BATCHQUEUE_TOOLTIP;Fronta zpracování.\nZkratka: Ctrl-F3
MAIN_FRAME_EDITOR;Editor
@@ -890,8 +936,8 @@ PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtr vypálených pixelů
PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtrovat linkové rušení
PARTIALPASTE_PRSHARPENING;Doostření po změně velikosti
PARTIALPASTE_RAWCACORR_AUTO;Automatická korekce CA
-PARTIALPASTE_RAWCACORR_CABLUE;CA modrá
-PARTIALPASTE_RAWCACORR_CARED;CA červená
+PARTIALPASTE_RAWCACORR_CAAUTOSTRENGTH;CA Síla automatická korekce
+PARTIALPASTE_RAWCACORR_CAREDBLUE;CA červená a modrá
PARTIALPASTE_RAWEXPOS_BLACK;Úrovně černé
PARTIALPASTE_RAWEXPOS_LINEAR;Korekce bílého bodu
PARTIALPASTE_RAWEXPOS_PRESER;Zachování světel
@@ -900,7 +946,9 @@ PARTIALPASTE_RAW_DCBENHANCE;Vylepšení DCB
PARTIALPASTE_RAW_DCBITERATIONS;Průchody DCB
PARTIALPASTE_RAW_DMETHOD;Metoda demozajkování
PARTIALPASTE_RAW_FALSECOLOR;Potlačení chybných barev
+PARTIALPASTE_RAW_IMAGENUM;Dílčí snímek
PARTIALPASTE_RAW_LMMSEITERATIONS;Kroky rozšíření LMMSE
+PARTIALPASTE_RAW_PIXELSHIFT;PixelShift
PARTIALPASTE_RESIZE;Změna velikosti
PARTIALPASTE_RETINEX;Retinex
PARTIALPASTE_RGBCURVES;RGB křivky
@@ -979,9 +1027,11 @@ PREFERENCES_DIRSOFTWARE;Instalační složka
PREFERENCES_EDITORCMDLINE;Jiný příkaz
PREFERENCES_EDITORLAYOUT;Rozvržení editoru
PREFERENCES_EXPAUT;Expert
+PREFERENCES_EXTENDEDZOOMLEVELS;Použít jemné úrovně zvětšení v režimu "Přizpůsobení obrazovce"
+PREFERENCES_EXTENDEDZOOMLEVELS_TOOLTIP;Dovolí lépe vyplnit okno editoru ve všech režimech "přizpůsobit obrazovce". Ovšem kvalita náhledu může být mírně zhoršená v závislosti na vypočteném faktoru zvětšení.
PREFERENCES_EXTERNALEDITOR;Externí editor
PREFERENCES_FBROWSEROPTS;Volby prohlížeče souborů / náhledů
-PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Jednořádková lišta nástrojů v prohlížeči souborů (vypněte na nízkých rozlišeních)
+PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Jednořádková lišta nástrojů v prohlížeči souborů\n(vypněte na nízkých rozlišeních)
PREFERENCES_FILEFORMAT;Formát souboru
PREFERENCES_FILMSIMULATION;Simulace filmu
PREFERENCES_FLATFIELD;Flat Field
@@ -1051,7 +1101,7 @@ PREFERENCES_OUTDIR;Výstupní složka
PREFERENCES_OUTDIRFOLDER;Ulož do souboru
PREFERENCES_OUTDIRFOLDERHINT;Uložit obrázky do vybrané složky.
PREFERENCES_OUTDIRTEMPLATE;Použít šablonu
-PREFERENCES_OUTDIRTEMPLATEHINT;Lze použít následující formátovací řetězce:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nTyto formátovací řetězce reprezentují různé části cesty k uložené fotografii, některé vlastnosti fotografie nebo pořadí v dávce.\n\nNapříklad pokud má zpracovávaná fotografie následující cestu:\n/home/tomas/fotky/2010-10-31/dsc0042.nef,\nmají jednotlivé formátovací řetězce tento význam:\n%d4 = home\n%d3 = tomas\n%d2 = fotky\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tomas/fotky/2010-10-31/\n%p2 = /home/tomas/fotky/\n%p3 = /home/tomas/\n%p4 = /home/\n\n%r bude nahrazeno hodnocením fotografie. Pokud není fotografie ohodnocena, bude %r nahrazeno '0'. Pokud je fotografie v koši, bude %r nahrazeno 'x'.\n\n%s1, %s2, atd. bude nahrazeno pořadím v dávce doplněném na 1 až 9 číslic. Každé spuštění zpracování fronty jej vždy nastaví na jedna a po každé zpracované fotografii se o jedna zvýší .\n\nPokud si přejete uložit výstupní obrázek vedle originálu, napište:\n%p1/%f\n\nPokud si jej ale přejete uložit do adresáře "zpracovano" ve stejném adresáři jako otevřený obrázek, napište:\n%p1/zpracovano/%f\n\nPro uložení výstupního obrázku do adresáře "/home/tom/fotky/zpracovano/2010-10-31", napište:\n%p2/zpracovano/%d1/%f
+PREFERENCES_OUTDIRTEMPLATEHINT;Lze použít následující formátovací řetězce:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nTyto formátovací řetězce reprezentují různé části cesty k uložené fotografii, některé vlastnosti fotografie nebo pořadí v dávce.\n\nNapříklad pokud má zpracovávaná fotografie následující cestu:\n/home/tomas/fotky/2010-10-31/dsc0042.nef,\nmají jednotlivé formátovací řetězce tento význam:\n%d4 = home\n%d3 = tomas\n%d2 = fotky\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tomas/fotky/2010-10-31/\n%p2 = /home/tomas/fotky/\n%p3 = /home/tomas/\n%p4 = /home/\n\n%r bude nahrazeno hodnocením fotografie. Pokud není fotografie ohodnocena, bude %r nahrazeno '0'. Pokud je fotografie v koši, bude %r nahrazeno 'x'.\n\n%s1, %s2, atd. bude nahrazeno pořadím v dávce doplněném na 1 až 9 číslic. Každé spuštění zpracování fronty jej vždy nastaví na jedna a po každé zpracované fotografii se o jedna zvýší .\n\nPokud si přejete uložit výstupní obrázek vedle originálu, napište:\n%p1/%f\n\nPokud si jej ale přejete uložit do adresáře "zpracovano" ve stejném adresáři jako otevřený obrázek, napište:\n%p1/zpracovano/%f\n\nPro uložení výstupního obrázku do adresáře\n"/home/tom/fotky/zpracovano/2010-10-31", napište:\n%p2/zpracovano/%d1/%f
PREFERENCES_OVERLAY_FILENAMES;Překrýt jména souborů na náhledech v prohlížeči souborů
PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Překrýt jména souborů na náhledech v editoru
PREFERENCES_OVERWRITEOUTPUTFILE;Přepsat existující soubory
@@ -1070,9 +1120,11 @@ PREFERENCES_PRINTER;Tiskárna (obtah)
PREFERENCES_PROFILEHANDLING;Řízení profilů zpracování
PREFERENCES_PROFILELOADPR;Priorita nahrávání profilů zpracování
PREFERENCES_PROFILEPRCACHE;Profil v mezipaměti
-PREFERENCES_PROFILEPRFILE;Profil uložený se zdrojovým souborem
-PREFERENCES_PROFILESAVECACHE;Ukládat parametry zpracování do mezipaměti
-PREFERENCES_PROFILESAVEINPUT;Ukládat parametry zpracování spolu se zdrojovým souborem
+PREFERENCES_PROFILEPRFILE;Profil uložený se vstupním souborem
+PREFERENCES_PROFILESAVEBOTH;Ukládat profil zpracování do mezipaměti a zároveň i se vstupním souborem
+PREFERENCES_PROFILESAVECACHE;Ukládat profil zpracování do mezipaměti
+PREFERENCES_PROFILESAVEINPUT;Ukládat profil zpracování spolu se vstupním souborem
+PREFERENCES_PROFILESAVELOCATION;Místo uložení profilů zpracování
PREFERENCES_PROFILE_NONE;Nic
PREFERENCES_PROPERTY;Vlastnost
PREFERENCES_PRTINTENT;Reprodukční záměr
@@ -1082,7 +1134,7 @@ PREFERENCES_REMEMBERZOOMPAN;Zapamatovat si procento přiblížení a posun obrá
PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Zapamatovat si procento přiblížení a posun aktuálního obrázku a použít tyto hodnoty při otevírání nového obrázku.\n\nTato volba funguje pouze v režimu "Mód jedné karty editoru" a volba "Metoda demozajkování pro náhled při přiblížení menším než 100%" je nastavena na "Stejně jako v PP3".
PREFERENCES_RGBDTL_LABEL;Maximální počet vláken pro redukci šumu a úrovně vlnky
PREFERENCES_RGBDTL_TOOLTIP;Pro automatické nastavení maximálního možného počtu vláken ponechte nastaveno na "0". Čím více vláken běží paralelně, tím rychlejší je výpočet. Paměťové nároky najdete na RawPedii.
-PREFERENCES_SELECTFONT;Vyberte globální písmo
+PREFERENCES_SELECTFONT;Vyberte hlavní písmo
PREFERENCES_SELECTFONT_COLPICKER;Vybrat písmo pro Průzkumníka barev
PREFERENCES_SELECTLANG;Volba jazyka
PREFERENCES_SELECTTHEME;Zvolit vzhled
@@ -1108,6 +1160,7 @@ PREFERENCES_STARTUPIMDIR;Složka obrázků při spuštění
PREFERENCES_STDAUT;Běžný
PREFERENCES_TAB_BROWSER;Prohlížeč souborů
PREFERENCES_TAB_COLORMGR;Správa barev
+PREFERENCES_TAB_DYNAMICPROFILE;Pravidla dynamických profilů
PREFERENCES_TAB_GENERAL;Obecné
PREFERENCES_TAB_IMPROC;Zpracování obrázku
PREFERENCES_TAB_PERFORMANCE;Výkon a kvalita
@@ -1136,6 +1189,7 @@ PROFILEPANEL_MODE_TIP;Režim uplatnění profilu zpracování.\n\nTlačítko je
PROFILEPANEL_MYPROFILES;Mé profily
PROFILEPANEL_PASTEPPASTE;Parametry pro vložení
PROFILEPANEL_PCUSTOM;Vlastní
+PROFILEPANEL_PDYNAMIC;Dynamiký
PROFILEPANEL_PFILE;Ze souboru
PROFILEPANEL_PINTERNAL;Neutrální
PROFILEPANEL_PLASTSAVED;Poslední uschovaný
@@ -1328,7 +1382,7 @@ TP_COLORAPP_SURROUND_DIM;Tlumené
TP_COLORAPP_SURROUND_EXDARK;Velmi tmavé
TP_COLORAPP_SURROUND_TOOLTIP;Změní tóny a barvy dle podmínek prohlížení na výstupním zařízení\n\nPrůměrné: Průměrné osvětlení prostředí (standardní). Obrázek nebude změněn.\n\nTlumené: Tlumené prostředí (TV). Obrázek bude mírně ztmaven.\n\nTmavé: Tmavé prostředí (projektor). Obrázek bude více tmavý.\n\nVelmi tmavé: Velmi tmavé prostředí (cutsheet). Obrázek bude velmi tmavý.
TP_COLORAPP_SURSOURCE;Tmavé okolí
-TP_COLORAPP_SURSOURCE_TOOLTIP;Může být použito pokud má zdrojový obrázek tmavý okraj.
+TP_COLORAPP_SURSOURCE_TOOLTIP;Může být použito, pokud má vstupní obrázek tmavý okraj.
TP_COLORAPP_TCMODE_BRIGHTNESS;Jas
TP_COLORAPP_TCMODE_CHROMA;Barevnost
TP_COLORAPP_TCMODE_COLORF;Pestrobarevnost
@@ -1678,21 +1732,84 @@ TP_RAWEXPOS_LINEAR;Korekce bílého bodu
TP_RAWEXPOS_PRESER;Zachování světel
TP_RAWEXPOS_RGB;Červená, telená, modrá
TP_RAWEXPOS_TWOGREEN;Spojit zelené
+TP_RAW_1PASSMEDIUM;Jeden průchod (střední)
+TP_RAW_3PASSBEST;Tři průchody (nejlepší)
+TP_RAW_AHD;AHD
+TP_RAW_AMAZE;AMaZE
+TP_RAW_DCB;DCB
TP_RAW_DCBENHANCE;Vylepšení DCB
TP_RAW_DCBITERATIONS;Počet průchodů DCB
TP_RAW_DMETHOD;Metoda
TP_RAW_DMETHOD_PROGRESSBAR;%1 demozajkování...
TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Vylepšení demozajkování...
-TP_RAW_DMETHOD_TOOLTIP;Poznámka: IGV a LMMSE jsou určeny pro obrázky s vysokým ISO, kde pomáhají redukci šumu minimalizovat posterizaci a vyžehlený vzhled.
+TP_RAW_DMETHOD_TOOLTIP;Poznámka: IGV a LMMSE jsou určeny pro obrázky s vysokým ISO, kde pomáhají redukci šumu minimalizovat posterizaci a vyžehlený vzhled.\n\nPixel Shift je určen pro soubory Pentax Pixel Shift.\nPro soubory neobsahující Pixel Shift data je použita metoda AMaZE.
+TP_RAW_EAHD;EAHD
TP_RAW_FALSECOLOR;Počet kroků potlačování chybných barev
+TP_RAW_FAST;Rychlá
TP_RAW_HD;Práh
TP_RAW_HD_TOOLTIP;Nižší hodnoty učiní detekci vypálených/mrtvých bodů agresivnější, ale falešná hlášení mohou vést k artefaktům. Pokud po povolení filtru vypálených/mrtvých bodů zpozorujete výskyt artefaktů, postupně snižujte prahovou hodnotu až do jejich vymizení.
+TP_RAW_HPHD;HPHD
+TP_RAW_IGV;IGV
+TP_RAW_IMAGENUM;Dílčí snímek
+TP_RAW_IMAGENUM_TOOLTIP;Některé Raw soubory mohou obsahovat několik dílčích snímků (HDR, Pixel Shift, Dual Pixel, Dual Sensitivity). Tímto tlačítkem vyberete konkrétní dílčí snímek.
TP_RAW_LABEL;Demozajkování
+TP_RAW_LMMSE;LMMSE
TP_RAW_LMMSEITERATIONS;Kroky rozšíření LMMSE
TP_RAW_LMMSE_TOOLTIP;Přidá gamu (krok 1) - přidá mediány (kroky 2, až 4) a následně přidá (kroky 5 a 6) vyčištění artefaktů a vylepšení poměru signálu a šumu.
+TP_RAW_MONO;Mono
+TP_RAW_NONE;Žádná (zobrazí strukturu senzoru)
+TP_RAW_PIXELSHIFT;Pixel Shift
+TP_RAW_PIXELSHIFTADAPTIVE;Přizpůsobivá detekce
+TP_RAW_PIXELSHIFTBLUR;Maska pohybové neostrosti
+TP_RAW_PIXELSHIFTBLUR_TOOLTIP;Maska pohybové neostrosti
+TP_RAW_PIXELSHIFTEPERISO;Přizpůsobení ISO
+TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;Výchozí hodnota (0,0) by měla dostačovat pro základní hodnoty ISO.\nDetekci pohybu na vyšších hodnotách ISO vylepšíte navýšením této hodnoty.\nZvyšujte po malých krocích a sledujte přitom masku pohybu.
+TP_RAW_PIXELSHIFTEQUALBRIGHT;Vyrovnat jas snímků
+TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Korekce po kanálech
+TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Zapnuto: Nezávislá korekce jednotlivých RGB kanálů.\nVypnuto: Použije se stejná hodnota pro všechny kanály.
+TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Vyrovná jas ostatních snímků podle jasu vybraného snímku.\nPokud jsou ve snímku přeexponované oblasti, vyberte jasnější snímek abyste zamezili výskytu purpurové barvy v přeexponovaných oblastech nebo povolte korekci pohybu.
+TP_RAW_PIXELSHIFTEXP0;Testovací
+TP_RAW_PIXELSHIFTGREEN;Kontrolovat zelený kanál na pohyb
+TP_RAW_PIXELSHIFTHOLEFILL;Vyplnit díry v masce pohybu
+TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Vyplnit díry v masce pohybu
+TP_RAW_PIXELSHIFTLMMSE;Použít LMMSE pro části s pohybem
+TP_RAW_PIXELSHIFTLMMSE_TOOLTIP;Pro oblasti s pohybem použít LMMSE namísto AMaZE.\nUžitečné pro fotografie s vysokým ISO.
+TP_RAW_PIXELSHIFTMASKTHRESHOLD;3x3 nový práh
+TP_RAW_PIXELSHIFTMEDIAN;Medián
+TP_RAW_PIXELSHIFTMEDIAN3;Vyjmout vybraný snímek z mediánu
+TP_RAW_PIXELSHIFTMEDIAN3_TOOLTIP;Vyjme vybraný snímek z mediánu.\nUžitečné, pokud se pohybující se objekty překrývají jen ve druhém a třetím.
+TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Pro oblasti s pohybem použijte medián všech snímků namísto vybraného.\nOdstraní objekty, které jsou na všech snímcích na různých místech.\nVytvoří efekt pohybu pro pomalu se pohybující (překrývající se) objekty.
+TP_RAW_PIXELSHIFTMM_AUTO;Automatická
+TP_RAW_PIXELSHIFTMM_CUSTOM;Vlastní
+TP_RAW_PIXELSHIFTMM_OFF;Vypnuto
+TP_RAW_PIXELSHIFTMOTION;Úroveň kontroly pohybu (zastaralé)
+TP_RAW_PIXELSHIFTMOTIONCORRECTION;Míra korekce pohybu v zelené
+TP_RAW_PIXELSHIFTMOTIONCORRECTION_TOOLTIP;1 = 2 pixely\n3 = mřížka 3x3\n5 = mřížka 5x5
+TP_RAW_PIXELSHIFTMOTIONMETHOD;Korekce pohybu
+TP_RAW_PIXELSHIFTMOTION_TOOLTIP;0 znamená bez detekce pohybu\n1 - 99 znamená, že pohybu bude detekován dle této hodnoty. Pro zvýšení míry detekce použijte vyšší hodnotu\n100 znamená, že bude použito AMaZE demozajkování snímku
+TP_RAW_PIXELSHIFTNONGREENAMAZE;Kontrolovat červené/modré AMaZE
+TP_RAW_PIXELSHIFTNONGREENCROSS;Kontrolovat pohyb v červeném a modrém kanálu
+TP_RAW_PIXELSHIFTNONGREENCROSS2;Kontrolovat zelené amaze
+TP_RAW_PIXELSHIFTNONGREENHORIZONTAL;Kontrolovat červenou/modrou vodorovně
+TP_RAW_PIXELSHIFTNONGREENVERTICAL;Kontrolovat červenou/modrou svisle
+TP_RAW_PIXELSHIFTNREADISO;nRead
+TP_RAW_PIXELSHIFTPRNU;PRNU (%)
+TP_RAW_PIXELSHIFTREDBLUEWEIGHT;Váha červené a modré
+TP_RAW_PIXELSHIFTSHOWMOTION;Ukázat pohyb
+TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Zobrazit pouze masku
+TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Ukázat masku pohybu bez obrázku
+TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Překryje obrázek maskou, která ukazuje oblasti s pohybem
+TP_RAW_PIXELSHIFTSIGMA;Poloměr rozostření
+TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;Výchozí poloměr 1,0 většinou dobře funguje pro základní ISO. U snímků s vyšším ISO poloměr zvětšete.\nHodnota 5,0 je dobrým výchozím bodem pro snímky pořízené na vysoké ISO.\nBěhem změny hodnoty poloměru sledujte masku pohybu.
+TP_RAW_PIXELSHIFTSMOOTH;Hladké přechody
+TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Plynulé přechody mezi místy s pohybem a bez něj.\nNastavte 0 pro zakázání plynulých přechodů\nNastavte 1 pro použití AMaZE/LMMSE nebo Median
+TP_RAW_PIXELSHIFTSTDDEVFACTORBLUE;StdDev faktor modrý
+TP_RAW_PIXELSHIFTSTDDEVFACTORGREEN;StdDev faktor zelený
+TP_RAW_PIXELSHIFTSTDDEVFACTORRED;StdDev faktor červený
TP_RAW_SENSOR_BAYER_LABEL;Snímač s Bayerovou maskou
TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;Tří průchodová dává lepší výsledky (doporučeno pro fotky s nízkým ISO).\nJednoprůchodová je téměř k nerozeznání od tří průchodové pro vysoké ISO a je rychlejší.
TP_RAW_SENSOR_XTRANS_LABEL;Senzory s X-Trans maticí
+TP_RAW_VNG4;VNG4
TP_RESIZE_APPLIESTO;Aplikovat na:
TP_RESIZE_CROPPEDAREA;Oblast ořezu
TP_RESIZE_FITBOX;Výřez
@@ -2057,6 +2174,8 @@ TP_WBALANCE_SOLUX41;Solux 4100K
TP_WBALANCE_SOLUX47;Solux 4700K (vendor)
TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery)
TP_WBALANCE_SPOTWB;Bodové vyvážení
+TP_WBALANCE_TEMPBIAS;AVB - Zdůraznění teploty
+TP_WBALANCE_TEMPBIAS_TOOLTIP;Dovolí ovlivnit výpočet "automatického vyvážení bílé"\nzdůrazněním teplejší nebo chladnější teploty. Toto zdůraznění\nje vyjádřeno v procentech vypočtené teploty a výsledek\nlze vyjádřit vzorcem "vypočtenáTeplota + vypočtenáTeplota * zdůraznění".
TP_WBALANCE_TEMPERATURE;Teplota
TP_WBALANCE_TUNGSTEN;Wolfram
TP_WBALANCE_WATER1;Pod vodou 1
@@ -2069,130 +2188,3 @@ ZOOMPANEL_ZOOMFITCROPSCREEN;Přizpůsobit obrazovce\nZkratka: Alt-ff
ZOOMPANEL_ZOOMIN;Přiblížit\nZkratka: +
ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: -
-
-!!!!!!!!!!!!!!!!!!!!!!!!!
-! Untranslated keys follow; remove the ! prefix after an entry is translated.
-!!!!!!!!!!!!!!!!!!!!!!!!!
-
-!DYNPROFILEEDITOR_DELETE;Delete
-!DYNPROFILEEDITOR_EDIT;Edit
-!DYNPROFILEEDITOR_EDIT_RULE;Edit Dynamic Profile Rule
-!DYNPROFILEEDITOR_ENTRY_TOOLTIP;The matching is case insensitive.\nUse the "re:" prefix to enter\na regular expression.
-!DYNPROFILEEDITOR_MOVE_DOWN;Move Down
-!DYNPROFILEEDITOR_MOVE_UP;Move Up
-!DYNPROFILEEDITOR_NEW;New
-!DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule
-!DYNPROFILEEDITOR_PROFILE;Processing Profile
-!EXPORT_BYPASS;Processing steps to bypass
-!EXPORT_PIPELINE;Processing pipeline
-!EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image)
-!EXPORT_USE_FAST_PIPELINE_TIP;Use a dedicated processing pipeline for images in Fast Export mode, that trades speed for quality. Resizing of the image is done as early as possible, instead of doing it at the end like in the normal pipeline. The speedup can be significant, but be prepared to see artifacts and a general degradation of output quality.
-!EXPORT_USE_NORMAL_PIPELINE;Standard (bypass some steps, resize at the end)
-!FILEBROWSER_RESETDEFAULTPROFILE;Reset to default
-!HISTORY_MSG_444;WB - Temp bias
-!HISTORY_MSG_445;Raw Sub-Image
-!HISTORY_MSG_446;EvPixelShiftMotion
-!HISTORY_MSG_447;EvPixelShiftMotionCorrection
-!HISTORY_MSG_448;EvPixelShiftStddevFactorGreen
-!HISTORY_MSG_449;PS ISO adaption
-!HISTORY_MSG_450;EvPixelShiftNreadIso
-!HISTORY_MSG_451;EvPixelShiftPrnu
-!HISTORY_MSG_452;PS Show motion
-!HISTORY_MSG_453;PS Show mask only
-!HISTORY_MSG_454;EvPixelShiftAutomatic
-!HISTORY_MSG_455;EvPixelShiftNonGreenHorizontal
-!HISTORY_MSG_456;EvPixelShiftNonGreenVertical
-!HISTORY_MSG_457;PS Check red/blue
-!HISTORY_MSG_458;EvPixelShiftStddevFactorRed
-!HISTORY_MSG_459;EvPixelShiftStddevFactorBlue
-!HISTORY_MSG_460;EvPixelShiftGreenAmaze
-!HISTORY_MSG_461;EvPixelShiftNonGreenAmaze
-!HISTORY_MSG_462;PS Check green
-!HISTORY_MSG_463;EvPixelShiftRedBlueWeight
-!HISTORY_MSG_464;PS Blur motion mask
-!HISTORY_MSG_465;PS Blur radius
-!HISTORY_MSG_466;EvPixelShiftSum
-!HISTORY_MSG_467;EvPixelShiftExp0
-!HISTORY_MSG_468;PS Fill holes
-!HISTORY_MSG_469;PS Median
-!HISTORY_MSG_470;EvPixelShiftMedian3
-!HISTORY_MSG_471;PS Motion correction
-!HISTORY_MSG_472;PS Smooth transitions
-!HISTORY_MSG_473;PS Use lmmse
-!HISTORY_MSG_474;PS Equalize
-!HISTORY_MSG_475;PS Equalize channel
-!PARTIALPASTE_RAWCACORR_CAAUTOSTRENGTH;CA auto-correction strength
-!PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue
-!PARTIALPASTE_RAW_IMAGENUM;Sub-image
-!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift
-!PREFERENCES_EXTENDEDZOOMLEVELS;Use finer-grained zoom levels for "fit to screen" zooming
-!PREFERENCES_EXTENDEDZOOMLEVELS_TOOLTIP;This allows to better fill the editor window when using one of the "fit to screen" zoom modes. However, the preview quality might be slightly degraded, depending on the actual zoom factor computed.
-!PREFERENCES_PROFILESAVEBOTH;Save processing profile both to the cache and next to the input file
-!PREFERENCES_PROFILESAVELOCATION;Processing profile saving location
-!PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules
-!PROFILEPANEL_PDYNAMIC;Dynamic
-!TP_RAW_1PASSMEDIUM;1-Pass (Medium)
-!TP_RAW_3PASSBEST;3-Pass (Best)
-!TP_RAW_AHD;AHD
-!TP_RAW_AMAZE;AMaZE
-!TP_RAW_DCB;DCB
-!TP_RAW_EAHD;EAHD
-!TP_RAW_FAST;Fast
-!TP_RAW_HPHD;HPHD
-!TP_RAW_IGV;IGV
-!TP_RAW_IMAGENUM;Sub-image
-!TP_RAW_IMAGENUM_TOOLTIP;Some raw files might embed several sub-images (HDR, Pixel Shift, Dual Pixel, Dual Sensitivity). Use this button to select the sub-image.
-!TP_RAW_LMMSE;LMMSE
-!TP_RAW_MONO;Mono
-!TP_RAW_NONE;None (Shows sensor pattern)
-!TP_RAW_PIXELSHIFT;Pixel Shift
-!TP_RAW_PIXELSHIFTADAPTIVE;Adaptive detection
-!TP_RAW_PIXELSHIFTBLUR;Blur motion mask
-!TP_RAW_PIXELSHIFTBLUR_TOOLTIP;Blur motion mask
-!TP_RAW_PIXELSHIFTEPERISO;ISO adaption
-!TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;The default value (0.0) should work fine for base ISO.\nIncrease the value to improve motion detection for higher ISO.\nIncrease in small steps and watch the motion mask while increasing.
-!TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalize brightness of frames
-!TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalize per channel
-!TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Enabled: Equalize the channels (RGB) individually.\nDisabled: Use same equalization factor for all channels.
-!TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalize the brightness of the frames to the brightness of the selected frame.\nIf there are overexposed areas in the frames select the brightest frame to avoid magenta colour cast in overexposed areas or enable motion correction.
-!TP_RAW_PIXELSHIFTEXP0;Experimental
-!TP_RAW_PIXELSHIFTGREEN;Check green channel for motion
-!TP_RAW_PIXELSHIFTHOLEFILL;Fill holes in motion mask
-!TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Fill holes in motion mask
-!TP_RAW_PIXELSHIFTLMMSE;Use lmmse for motion parts
-!TP_RAW_PIXELSHIFTLMMSE_TOOLTIP;Use lmmse instead of amaze for motion areas.\nUseful for High ISO images.
-!TP_RAW_PIXELSHIFTMASKTHRESHOLD;3x3 new threshold
-!TP_RAW_PIXELSHIFTMEDIAN;Median
-!TP_RAW_PIXELSHIFTMEDIAN3;Exclude selected frame from median
-!TP_RAW_PIXELSHIFTMEDIAN3_TOOLTIP;Excludes selected frame from median.\nUseful if moving objects overlap in frame 2 and 3
-!TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Use median of all frames instead of selected frame for regions with motion.\nRemoves objects which are at different places in all frames.\nGives motion effect on slow moving (overlapping) objects.
-!TP_RAW_PIXELSHIFTMM_AUTO;Automatic
-!TP_RAW_PIXELSHIFTMM_CUSTOM;Custom
-!TP_RAW_PIXELSHIFTMM_OFF;Off
-!TP_RAW_PIXELSHIFTMOTION;Motion detection level (deprecated)
-!TP_RAW_PIXELSHIFTMOTIONCORRECTION;Green motion correction size
-!TP_RAW_PIXELSHIFTMOTIONCORRECTION_TOOLTIP;1 = 2 pixels\n3 = 3x3 grid\n5 = 5x5 grid
-!TP_RAW_PIXELSHIFTMOTIONMETHOD;Motion Correction
-!TP_RAW_PIXELSHIFTMOTION_TOOLTIP;0 means no motion detection\n1 - 99 means motion will be detected according to this value. Increase value to increase detection rate\n100 means the Amaze demosaiced frame will be used
-!TP_RAW_PIXELSHIFTNONGREENAMAZE;Check red/blue amaze
-!TP_RAW_PIXELSHIFTNONGREENCROSS;Check red/blue channels for motion
-!TP_RAW_PIXELSHIFTNONGREENCROSS2;Check green amaze
-!TP_RAW_PIXELSHIFTNONGREENHORIZONTAL;Check red/blue horizontal
-!TP_RAW_PIXELSHIFTNONGREENVERTICAL;Check red/blue vertical
-!TP_RAW_PIXELSHIFTNREADISO;nRead
-!TP_RAW_PIXELSHIFTPRNU;PRNU (%)
-!TP_RAW_PIXELSHIFTREDBLUEWEIGHT;Red&Blue weight
-!TP_RAW_PIXELSHIFTSHOWMOTION;Show motion
-!TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Show mask only
-!TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Shows the motion mask without the image
-!TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Overlays the image with a mask showing the regions with motion
-!TP_RAW_PIXELSHIFTSIGMA;Blur radius
-!TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;Default radius of 1.0 usually fits good for base ISO. Increase value for high ISO shots,\n5.0 is a good starting point for high ISO shots.\nWatch motion mask while changing the value.
-!TP_RAW_PIXELSHIFTSMOOTH;Smooth transitions
-!TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Smooth transitions between areas with and without motion.\nSet to 0 to disable smooth transitions\nSet to 1 to get Amaze/lmmse or Median
-!TP_RAW_PIXELSHIFTSTDDEVFACTORBLUE;StdDev factor Blue
-!TP_RAW_PIXELSHIFTSTDDEVFACTORGREEN;StdDev factor Green
-!TP_RAW_PIXELSHIFTSTDDEVFACTORRED;StdDev factor Red
-!TP_RAW_VNG4;VNG4
-!TP_WBALANCE_TEMPBIAS;AWB temperature bias
-!TP_WBALANCE_TEMPBIAS_TOOLTIP;Allows to alter the computation of the "auto white balance"\nby biasing it towards warmer or cooler temperatures. The bias\nis expressed as a percentage of the computed temperature,\nso that the result is given by "computedTemp + computedTemp * bias".
diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt
index 273abb65f..c9a2b395b 100644
--- a/rtengine/CMakeLists.txt
+++ b/rtengine/CMakeLists.txt
@@ -50,6 +50,7 @@ set(RTENGINESOURCEFILES
dfmanager.cc
diagonalcurves.cc
dirpyr_equalizer.cc
+ dynamicprofile.cc
expo_before_b.cc
fast_demo.cc
ffmanager.cc
@@ -98,6 +99,7 @@ set(RTENGINESOURCEFILES
previewimage.cc
processingjob.cc
procparams.cc
+ profilestore.cc
rawimage.cc
rawimagesource.cc
refreshmap.cc
diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc
new file mode 100644
index 000000000..5ac408da5
--- /dev/null
+++ b/rtengine/dynamicprofile.cc
@@ -0,0 +1,261 @@
+/* -*- C++ -*-
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2017 Alberto Griggio
+ *
+ * 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 "../rtengine/dynamicprofile.h"
+
+#include
+#include
+
+using namespace rtengine;
+using namespace rtengine::procparams;
+
+namespace
+{
+
+const int ISO_MAX = 512000;
+const double FNUMBER_MAX = 100.0;
+const double FOCALLEN_MAX = 10000.0;
+const double SHUTTERSPEED_MAX = 1000.0;
+const double EXPCOMP_MIN = -20.0;
+const double EXPCOMP_MAX = 20.0;
+
+} // namespace
+
+DynamicProfileRules dynamicProfileRules;
+
+bool DynamicProfileRule::Optional::operator() (const Glib::ustring &val) const
+{
+ if (!enabled) {
+ return true;
+ }
+
+ if (value.find ("re:") == 0) {
+ // this is a regexp
+ return Glib::Regex::match_simple (value.substr (3), val, Glib::REGEX_CASELESS);
+ } else {
+ // normal string comparison
+ return value.casefold() == val.casefold();
+ }
+}
+
+
+DynamicProfileRule::DynamicProfileRule():
+ serial_number (0),
+ iso (0, ISO_MAX),
+ fnumber (0, FNUMBER_MAX),
+ focallen (0, FOCALLEN_MAX),
+ shutterspeed (0, SHUTTERSPEED_MAX),
+ expcomp (EXPCOMP_MIN, EXPCOMP_MAX)
+{
+}
+
+
+bool DynamicProfileRule::operator< (const DynamicProfileRule &other) const
+{
+ return serial_number < other.serial_number;
+}
+
+
+bool DynamicProfileRule::matches (const rtengine::ImageMetaData *im) const
+{
+ return (iso (im->getISOSpeed())
+ && fnumber (im->getFNumber())
+ && focallen (im->getFocalLen())
+ && shutterspeed (im->getShutterSpeed())
+ && expcomp (im->getExpComp())
+ && camera (im->getCamera())
+ && lens (im->getLens()));
+}
+
+namespace
+{
+
+void get_int_range (DynamicProfileRule::Range &dest,
+ const Glib::KeyFile &kf, const Glib::ustring &group,
+ const Glib::ustring &key)
+{
+ try {
+ int min = kf.get_integer (group, key + "_min");
+ int max = kf.get_integer (group, key + "_max");
+
+ if (min <= max) {
+ dest.min = min;
+ dest.max = max;
+ }
+ } catch (Glib::KeyFileError &e) {
+ }
+}
+
+
+void get_double_range (DynamicProfileRule::Range &dest,
+ const Glib::KeyFile &kf, const Glib::ustring &group,
+ const Glib::ustring &key)
+{
+ try {
+ double min = kf.get_double (group, key + "_min");
+ double max = kf.get_double (group, key + "_max");
+
+ if (min <= max) {
+ dest.min = min;
+ dest.max = max;
+ }
+ } catch (Glib::KeyFileError &e) {
+ }
+}
+
+
+void get_optional (DynamicProfileRule::Optional &dest,
+ const Glib::KeyFile &kf, const Glib::ustring &group,
+ const Glib::ustring &key)
+{
+ try {
+ bool e = kf.get_boolean (group, key + "_enabled");
+
+ if (e) {
+ Glib::ustring s = kf.get_string (group, key + "_value");
+ dest.enabled = e;
+ dest.value = s;
+ }
+ } catch (Glib::KeyFileError &) {
+ }
+}
+
+void set_int_range (Glib::KeyFile &kf, const Glib::ustring &group,
+ const Glib::ustring &key,
+ const DynamicProfileRule::Range &val)
+{
+ kf.set_integer (group, key + "_min", val.min);
+ kf.set_integer (group, key + "_max", val.max);
+}
+
+void set_double_range (Glib::KeyFile &kf, const Glib::ustring &group,
+ const Glib::ustring &key,
+ const DynamicProfileRule::Range &val)
+{
+ kf.set_double (group, key + "_min", val.min);
+ kf.set_double (group, key + "_max", val.max);
+}
+
+void set_optional (Glib::KeyFile &kf, const Glib::ustring &group,
+ const Glib::ustring &key,
+ const DynamicProfileRule::Optional &val)
+{
+ kf.set_boolean (group, key + "_enabled", val.enabled);
+ kf.set_string (group, key + "_value", val.value);
+}
+
+} // namespace
+
+bool DynamicProfileRules::loadRules()
+{
+ dynamicRules.clear();
+ Glib::KeyFile kf;
+
+ try {
+ if (!kf.load_from_file (Glib::build_filename (Options::rtdir, "dynamicprofile.cfg"))) {
+ return false;
+ }
+ } catch (Glib::Error &e) {
+ return false;
+ }
+
+ if (options.rtSettings.verbose) {
+ printf ("loading dynamic profiles...\n");
+ }
+
+ auto groups = kf.get_groups();
+
+ for (auto group : groups) {
+ // groups are of the form "rule N", where N is a positive integer
+ if (group.find ("rule ") != 0) {
+ return false;
+ }
+
+ std::istringstream buf (group.c_str() + 5);
+ int serial = 0;
+
+ if (! (buf >> serial) || !buf.eof()) {
+ return false;
+ }
+
+ if (options.rtSettings.verbose) {
+ printf (" loading rule %d\n", serial);
+ }
+
+ dynamicRules.emplace_back (DynamicProfileRule());
+ DynamicProfileRule &rule = dynamicRules.back();
+ rule.serial_number = serial;
+ get_int_range (rule.iso, kf, group, "iso");
+ get_double_range (rule.fnumber, kf, group, "fnumber");
+ get_double_range (rule.focallen, kf, group, "focallen");
+ get_double_range (rule.shutterspeed, kf, group, "shutterspeed");
+ get_double_range (rule.expcomp, kf, group, "expcomp");
+ get_optional (rule.camera, kf, group, "camera");
+ get_optional (rule.lens, kf, group, "lens");
+
+ try {
+ rule.profilepath = kf.get_string (group, "profilepath");
+ } catch (Glib::KeyFileError &) {
+ dynamicRules.pop_back();
+ }
+ }
+
+ std::sort (dynamicRules.begin(), dynamicRules.end());
+ rulesLoaded = true;
+ return true;
+}
+
+bool DynamicProfileRules::storeRules()
+{
+ if (options.rtSettings.verbose) {
+ printf ("saving dynamic profiles...\n");
+ }
+
+ Glib::KeyFile kf;
+
+ for (auto &rule : dynamicRules) {
+ std::ostringstream buf;
+ buf << "rule " << rule.serial_number;
+ Glib::ustring group = buf.str();
+ set_int_range (kf, group, "iso", rule.iso);
+ set_double_range (kf, group, "fnumber", rule.fnumber);
+ set_double_range (kf, group, "focallen", rule.focallen);
+ set_double_range (kf, group, "shutterspeed", rule.shutterspeed);
+ set_double_range (kf, group, "expcomp", rule.expcomp);
+ set_optional (kf, group, "camera", rule.camera);
+ set_optional (kf, group, "lens", rule.lens);
+ kf.set_string (group, "profilepath", rule.profilepath);
+ }
+
+ return kf.save_to_file (Glib::build_filename (Options::rtdir, "dynamicprofile.cfg"));
+}
+
+const std::vector &DynamicProfileRules::getRules()
+{
+ if (!rulesLoaded) {
+ loadRules();
+ }
+
+ return dynamicRules;
+}
+
+void DynamicProfileRules::setRules (const std::vector &r)
+{
+ dynamicRules = r;
+}
diff --git a/rtgui/dynamicprofile.h b/rtengine/dynamicprofile.h
similarity index 63%
rename from rtgui/dynamicprofile.h
rename to rtengine/dynamicprofile.h
index 4c5e552e4..cfe46d9ba 100644
--- a/rtgui/dynamicprofile.h
+++ b/rtengine/dynamicprofile.h
@@ -21,18 +21,18 @@
#include
#include
-#include "options.h"
+#include "../rtgui/options.h"
-
-class DynamicProfileRule {
+class DynamicProfileRule
+{
public:
template
struct Range {
T min;
T max;
- explicit Range(T l=T(), T u=T()): min(l), max(u) {}
+ explicit Range (T l = T(), T u = T()): min (l), max (u) {}
- bool operator()(T val) const
+ bool operator() (T val) const
{
return val >= min && val <= max;
}
@@ -41,15 +41,15 @@ public:
struct Optional {
Glib::ustring value;
bool enabled;
- explicit Optional(const Glib::ustring v="", bool e=false):
- value(v), enabled(e) {}
+ explicit Optional (const Glib::ustring v = "", bool e = false):
+ value (v), enabled (e) {}
- bool operator()(const Glib::ustring &val) const;
+ bool operator() (const Glib::ustring &val) const;
};
-
+
DynamicProfileRule();
- bool matches(const rtengine::ImageMetaData *im) const;
- bool operator<(const DynamicProfileRule &other) const;
+ bool matches (const rtengine::ImageMetaData *im) const;
+ bool operator< (const DynamicProfileRule &other) const;
int serial_number;
Range iso;
@@ -62,13 +62,18 @@ public:
Glib::ustring profilepath;
};
+class DynamicProfileRules
+{
+protected:
+ /** cache for dynamic profile rules */
+ std::vector dynamicRules;
+ bool rulesLoaded;
-bool loadDynamicProfileRules(std::vector &out);
-bool storeDynamicProfileRules(
- const std::vector &rules);
-
-rtengine::procparams::PartialProfile *loadDynamicProfile(
- const rtengine::ImageMetaData *im);
-
+public:
+ bool loadRules();
+ bool storeRules();
+ const std::vector &getRules();
+ void setRules (const std::vector &r);
+};
#endif // _DYNAMICPROFILE_H_
diff --git a/rtengine/init.cc b/rtengine/init.cc
index 4c66cea68..2d157c762 100644
--- a/rtengine/init.cc
+++ b/rtengine/init.cc
@@ -16,6 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see .
*/
+#include "../rtgui/profilestorecombobox.h"
#include "rtengine.h"
#include "iccstore.h"
#include "dcp.h"
@@ -27,7 +28,7 @@
#include "dfmanager.h"
#include "ffmanager.h"
#include "rtthumbnail.h"
-#include "../rtgui/profilestore.h"
+#include "profilestore.h"
#include "../rtgui/threadutils.h"
namespace rtengine
@@ -40,6 +41,7 @@ MyMutex* lcmsMutex = nullptr;
int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir, bool loadAll)
{
settings = s;
+ ProfileStore::getInstance()->init (loadAll);
ICCStore::getInstance()->init (s->iccDirectory, Glib::build_filename (baseDir, "iccprofiles"), loadAll);
DCPStore::getInstance()->init (Glib::build_filename (baseDir, "dcpprofiles"), loadAll);
diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc
new file mode 100644
index 000000000..984ab9423
--- /dev/null
+++ b/rtengine/profilestore.cc
@@ -0,0 +1,535 @@
+/*
+ * 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 "profilestore.h"
+
+#include "dynamicprofile.h"
+#include "../rtgui/options.h"
+#include "../rtgui/multilangmgr.h"
+
+using namespace rtengine;
+using namespace rtengine::procparams;
+
+ProfileStore::ProfileStore () : storeState (STORESTATE_NOTINITIALIZED), internalDefaultProfile (nullptr), internalDefaultEntry (nullptr), internalDynamicEntry (nullptr), loadAll (true)
+{
+ internalDefaultProfile = new AutoPartialProfile();
+ internalDefaultProfile->set (true);
+}
+
+ProfileStore* ProfileStore::getInstance()
+{
+ static ProfileStore instance;
+ return &instance;
+}
+
+
+bool ProfileStore::init (bool loadAll)
+{
+ if (storeState == STORESTATE_DELETED) {
+ return false;
+ }
+
+ this->loadAll = loadAll;
+
+ if (storeState == STORESTATE_NOTINITIALIZED && loadAll) {
+ storeState = STORESTATE_BEINGINITIALIZED;
+ _parseProfiles ();
+ storeState = STORESTATE_INITIALIZED;
+ }
+
+ return storeState == STORESTATE_INITIALIZED;
+}
+
+ProfileStore::~ProfileStore ()
+{
+ if (storeState == STORESTATE_NOTINITIALIZED) {
+ return;
+ }
+
+ // This lock prevent object's suppression while scanning the directories
+ storeState = STORESTATE_DELETED;
+
+ {
+ MyMutex::MyLock lock (parseMutex);
+
+ clearProfileList ();
+ partProfiles.clear ();
+ clearFileList();
+ delete internalDefaultProfile;
+ delete internalDefaultEntry;
+ delete internalDynamicEntry;
+ }
+}
+
+/*
+ * Public method to parse the profiles' directories
+ * Since there's a race condition in the multithreaded environment on this object,
+ * parseProfiles may need to ask for initialization of this object, and then will
+ * ask a mutex lock on it, has it been initialized by this call or not
+ *
+ * This method will scan the directory tree again and update the profile list. When finished,
+ * the listeners will be called in order to update with the new list
+ */
+void ProfileStore::parseProfiles ()
+{
+
+ for (auto listener : listeners) {
+ listener->storeCurrentValue();
+ }
+
+ init (true); // safe even if already initialized
+
+ for (auto listener : listeners) {
+ listener->updateProfileList();
+ listener->restoreValue();
+ }
+}
+
+void ProfileStore::_parseProfiles ()
+{
+ // clear loaded profiles
+ folders.clear();
+ clearFileList();
+ clearProfileList ();
+
+ folders.push_back ("<<< ROOT >>>"); // Fake path, so parentFolderId == 0 will be used to attach a ProfileStoreEntry to the root container, not sub-menu
+
+ Glib::ustring p1 = options.getUserProfilePath();
+ Glib::ustring p2 = options.getGlobalProfilePath();
+ bool displayLevel0 = options.useBundledProfiles && !p1.empty() && !p2.empty() && p1 != p2;
+
+ Glib::ustring virtualPath ("${U}");
+ Glib::ustring currDir ("${U}");
+ parseDir (p1, virtualPath, currDir, 0, 0, displayLevel0);
+
+ if (displayLevel0) {
+ virtualPath = "${G}";
+ currDir = "${G}";
+ parseDir (p2, virtualPath, currDir, 0, 0, displayLevel0);
+ }
+
+ // sort profiles
+ std::sort (entries.begin(), entries.end(), SortProfiles() );
+
+ // entries and partProfiles are empty, but the entry and profiles already exist (they have survived to clearFileList and clearProfileList)
+ if (!internalDefaultEntry) {
+ internalDefaultEntry = new ProfileStoreEntry (Glib::ustring ("(") + M ("PROFILEPANEL_PINTERNAL") + Glib::ustring (")"), PSET_FILE, 0, 0);
+ }
+
+ entries.push_back (internalDefaultEntry);
+ partProfiles[internalDefaultEntry] = internalDefaultProfile;
+
+ if (!internalDynamicEntry) {
+ internalDynamicEntry = new ProfileStoreEntry (Glib::ustring ("(") + M ("PROFILEPANEL_PDYNAMIC") + Glib::ustring (")"), PSET_FILE, 0, 0);
+ // do not add it to the entries. This is here only for the preferences dialog
+ }
+
+ // Check if the default profiles has been found.
+ if (findEntryFromFullPathU (options.defProfRaw) == nullptr) {
+ options.setDefProfRawMissing (true);
+
+ if (options.rtSettings.verbose) {
+ printf ("WARNING: Default profile \"%s\" for raw images not found!\n", options.defProfRaw.c_str());
+ }
+ }
+
+ if (findEntryFromFullPathU (options.defProfImg) == nullptr) {
+ options.setDefProfImgMissing (true);
+
+ if (options.rtSettings.verbose) {
+ printf ("WARNING: Default profile \"%s\" for standard images not found!\n", options.defProfImg.c_str());
+ }
+ }
+}
+
+/// @return Returns true if some files has been found (directories are ignored)
+bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath, Glib::ustring& currDir, unsigned int parentId, unsigned char level, bool displayLevel0)
+{
+ bool fileFound = false;
+
+ // reload the available profiles from the profile dir
+ if (!realPath.empty() && Glib::file_test (realPath, Glib::FILE_TEST_EXISTS) && Glib::file_test (realPath, Glib::FILE_TEST_IS_DIR)) {
+ unsigned int folder = 0; // folder's own Id
+
+ // add this entry to the folder list
+ folders.push_back (virtualPath);
+ folder = (unsigned int) (folders.size()) - 1;
+
+ if (level > 0 || displayLevel0) {
+ // replace the virtual folder name by a localized text
+ if (currDir == "${U}") {
+ currDir = M ("PROFILEPANEL_MYPROFILES");
+ } else if (currDir == "${G}") {
+ currDir = M ("PROFILEPANEL_GLOBALPROFILES");
+ }
+
+ // add this localized text to the file list
+ entries.push_back ( new ProfileStoreEntry (currDir, PSET_FOLDER, parentId, folder) );
+ }
+
+ // walking through the directory
+ Glib::Dir* dir = nullptr;
+ dir = new Glib::Dir (realPath);
+
+ for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) {
+ currDir = *i;
+
+ if (currDir == "." || currDir == "..") {
+ continue;
+ }
+
+ Glib::ustring fname = Glib::build_filename (realPath, currDir);
+
+ if (Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) {
+ Glib::ustring vp (Glib::build_filename (virtualPath, currDir));
+ Glib::ustring rp (Glib::build_filename (realPath, currDir));
+ fileFound = parseDir (rp, vp, currDir, folder, level + 1, 0);
+ } else {
+ size_t lastdot = currDir.find_last_of ('.');
+
+ if (lastdot != Glib::ustring::npos && lastdot == currDir.length() - 4 && currDir.substr (lastdot).casefold() == paramFileExtension) {
+ // file found
+ if ( options.rtSettings.verbose ) {
+ printf ("Processing file %s...", fname.c_str());
+ }
+
+ Glib::ustring name = currDir.substr (0, lastdot);
+
+ // create the partial profile
+ AutoPartialProfile *pProf = new AutoPartialProfile();
+ int res = pProf->load (fname);
+
+ if (!res && pProf->pparams->ppVersion >= 220) {
+ fileFound = true;
+
+ if ( options.rtSettings.verbose ) {
+ printf ("OK\n");
+ }
+
+ // adding this file to the list
+ ProfileStoreEntry* filePSE = new ProfileStoreEntry (name, PSET_FILE, folder, 0);
+ entries.push_back (filePSE);
+
+ // map the partial profile
+ partProfiles[filePSE] = pProf;
+ //partProfiles.insert( std::pair (filePSE, pProf) );
+ } else if ( options.rtSettings.verbose ) {
+ printf ("failed!\n");
+ }
+ }
+ }
+ }
+
+ delete dir;
+ }
+
+ if (!fileFound && (level > 0 || displayLevel0)) {
+ // no files found in this level, we delete the subdirectory entry
+ folders.pop_back();
+ entries.pop_back();
+ }
+
+ return fileFound;
+}
+
+int ProfileStore::findFolderId (const Glib::ustring &path)
+{
+ // initialization must have been done when calling this
+ for (std::vector::iterator i = folders.begin(); i != folders.end(); ++i) {
+ if (*i == path) {
+ return i - folders.begin();
+ }
+ }
+
+ return -1;
+}
+
+/** @brief Return the ProfileStoreEntry object that match the given file and path
+ *
+ * @param fullPath Path of the file; the filename may end by the standard extension,
+ * but have to begin with a virtual location ( ${G} or ${U} )
+ * Will return null on invalid path or if the entry can't be found
+ */
+const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU (Glib::ustring path)
+{
+ if (path.empty()) {
+ return nullptr;
+ }
+
+ if (storeState == STORESTATE_NOTINITIALIZED) {
+ parseProfiles();
+ }
+
+ if (path == DEFPROFILE_INTERNAL || path == DEFPROFILE_DYNAMIC) {
+ return internalDefaultEntry;
+ }
+
+ // consistently apply casefold() to make sure dot position is correct
+ const Glib::ustring casefolded_path = path.casefold();
+ const Glib::ustring::size_type lastdot_pos = casefolded_path.find_last_of ('.');
+
+ if (
+ lastdot_pos != Glib::ustring::npos
+ && lastdot_pos <= casefolded_path.size() - 4
+ && !casefolded_path.compare (lastdot_pos, 4, paramFileExtension)
+ ) {
+ // removing the extension
+ // now use dot position without casefold()
+ path = path.substr (0, path.find_last_of ('.'));
+ }
+
+ // dir separator may come from options file and may be \ or /, we convert them to G_DIR_SEPARATOR_S
+ if (path.size() > 4 && (path[4] == '/' || path[4] == '\\')) {
+ path = path.substr (0, 4) + G_DIR_SEPARATOR_S + path.substr (5);
+ }
+
+ // removing the filename
+ Glib::ustring fName = Glib::path_get_basename (path);
+
+ if (!fName.empty()) {
+ path = path.substr (0, path.length() - fName.length());
+ } else {
+ // path is malformed, returning NULL;
+ return nullptr;
+ }
+
+ path = Glib::path_get_dirname (path);
+
+ // 1. find the path in the folder list
+ int parentFolderId = findFolderId (path);
+
+ if (parentFolderId == -1) {
+ return nullptr;
+ }
+
+ // 2. find the entry that match the given filename and parentFolderId
+ if (parentFolderId >= 0) {
+ for (auto entry : entries) {
+ if (entry->parentFolderId == parentFolderId && entry->label == fName) {
+ return entry;
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+/** Protected version of findEntryFromFullPathU */
+const ProfileStoreEntry* ProfileStore::findEntryFromFullPath (Glib::ustring path)
+{
+ MyMutex::MyLock lock (parseMutex);
+ return findEntryFromFullPathU (path);
+}
+
+const PartialProfile* ProfileStore::getProfile (Glib::ustring path)
+{
+
+ if (storeState == STORESTATE_NOTINITIALIZED) {
+ parseProfiles();
+ }
+
+ const ProfileStoreEntry *pse = findEntryFromFullPath (path);
+
+ if (!pse) {
+ return nullptr;
+ }
+
+ return getProfile (pse);
+}
+
+const PartialProfile* ProfileStore::getProfile (const ProfileStoreEntry* entry)
+{
+
+ if (storeState == STORESTATE_NOTINITIALIZED) {
+ parseProfiles();
+ }
+
+ MyMutex::MyLock lock (parseMutex);
+
+ if (entry == internalDefaultEntry) {
+ return internalDefaultProfile;
+ }
+
+ std::map::iterator iter = partProfiles.find (entry);
+
+ if (iter != partProfiles.end()) {
+ return iter->second;
+ } else {
+ // This shouldn't happen!
+#ifndef NDEBUG
+ printf ("WARNING! Profile not found!\n");
+#endif
+ return nullptr;
+ }
+}
+
+/** @brief Get a pointer to the profile's vector list
+ *
+ * This method grants you unique access to the vector list through Mutex locking.
+ * When you're done with the file list, you MUST call the releaseFileList method to release the lock.
+ */
+const std::vector* ProfileStore::getFileList ()
+{
+
+ if (storeState == STORESTATE_NOTINITIALIZED) {
+ parseProfiles();
+ }
+
+ parseMutex.lock();
+
+ return &entries;
+}
+
+void ProfileStore::releaseFileList()
+{
+ parseMutex.unlock();
+}
+
+/*
+ * Send back a pointer to the default procparams for raw or standard images.
+ * If the profile doesn't already exist in the profile list,
+ * it will add it with default internal values, so this method never fails
+ */
+const ProcParams* ProfileStore::getDefaultProcParams (bool isRaw)
+{
+
+ //Note: the mutex is locked in getProfile, called below
+ // eventual initialization is done there too
+
+ const PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg);
+
+ if (!pProf) {
+ pProf = internalDefaultProfile;
+ }
+
+ return pProf->pparams;
+}
+
+/*
+ * Send back a pointer to the default partial profile for raw or standard images.
+ * If it doesn't already exist in the profile list, it will add it with default internal values,
+ * so this method will never fails
+ */
+const PartialProfile* ProfileStore::getDefaultPartialProfile (bool isRaw)
+{
+
+ //Note: the mutex is locked in getProfile, called below
+ // eventual initialization is done there too
+
+ const PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg);
+
+ if (!pProf) {
+ pProf = internalDefaultProfile;
+ }
+
+ return pProf;
+}
+
+const Glib::ustring ProfileStore::getPathFromId (int folderId)
+{
+ // initialization must have been done when calling this
+ return folders.at (folderId);
+}
+
+
+void ProfileStore::clearFileList()
+{
+ for (auto entry : entries) {
+ if (entry != internalDefaultEntry) {
+ delete entry;
+ }
+ }
+
+ entries.clear();
+}
+
+void ProfileStore::clearProfileList()
+{
+ for (auto partProfile : partProfiles) {
+ if (partProfile.second != internalDefaultProfile) {
+ delete partProfile.second;
+ }
+ }
+
+ partProfiles.clear();
+}
+
+void ProfileStore::addListener (ProfileStoreListener *listener)
+{
+ listeners.push_back (listener);
+}
+
+void ProfileStore::removeListener (ProfileStoreListener *listener)
+{
+ listeners.remove (listener);
+}
+
+void ProfileStore::dumpFolderList()
+{
+ printf ("Folder list:\n------------\n");
+
+ for (unsigned int i = 0; i < folders.size(); i++) {
+ printf (" #%3ud - %s\n", i, folders.at (i).c_str());
+ }
+
+ printf ("\n");
+}
+
+PartialProfile *ProfileStore::loadDynamicProfile (const ImageMetaData *im)
+{
+ if (storeState == STORESTATE_NOTINITIALIZED) {
+ parseProfiles();
+ }
+
+ PartialProfile *ret = new PartialProfile (true, true);
+
+ if (!rulesLoaded) {
+ loadRules();
+ }
+
+ for (auto rule : dynamicRules) {
+ if (rule.matches (im)) {
+ if (options.rtSettings.verbose) {
+ printf ("found matching profile %s\n", rule.profilepath.c_str());
+ }
+
+ const PartialProfile *p = getProfile (rule.profilepath);
+
+ if (p != nullptr) {
+ p->applyTo (ret->pparams);
+ } else {
+ printf ("ERROR loading matching profile from: %s\n", rule.profilepath.c_str());
+ }
+ }
+ }
+
+ return ret;
+}
+
+ProfileStoreEntry::ProfileStoreEntry() : label (""), type (PSET_FOLDER), parentFolderId (0), folderId (0) {}
+
+ProfileStoreEntry::ProfileStoreEntry (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) : label (label), type (type), parentFolderId (parentFolder), folderId (folder) {}
+
+void ProfileStoreEntry::setValues (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder)
+{
+ this->label = label;
+ this->type = type;
+ parentFolderId = parentFolder;
+ folderId = folder;
+}
+
diff --git a/rtgui/profilestore.h b/rtengine/profilestore.h
similarity index 67%
rename from rtgui/profilestore.h
rename to rtengine/profilestore.h
index ad569c180..c6627b4c8 100644
--- a/rtgui/profilestore.h
+++ b/rtengine/profilestore.h
@@ -23,16 +23,14 @@
#include
#include
-#include "../rtengine/rtengine.h"
-#include "../rtengine/noncopyable.h"
-
-#include "threadutils.h"
-#include "paramsedited.h"
-#include "guiutils.h"
+#include "rtengine.h"
+#include "noncopyable.h"
+#include "dynamicprofile.h"
// forward decl
class DynamicProfileRule;
+class DynamicProfileRules;
/** @brief This will implement callback functions for the ProfileStore
*
@@ -83,7 +81,7 @@ public:
* @param parentFolder index of the elements's path in the folder list
* @param folder index of the folder's own path in the folder list
*/
- ProfileStoreEntry(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder);
+ ProfileStoreEntry (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder);
/** @brief Set the values of the object after its instantiation
* @param label Label to be used in menu or combobox; also used as profile's filename
@@ -91,31 +89,7 @@ public:
* @param parentFolder index of the elements's path in the folder list
* @param folder index of the folder's own path in the folder list
*/
- void setValues(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder);
-};
-
-
-/**
- * @brief subclass of Gtk::Label with extra fields for Combobox and Menu, to link with a ProfileStoreEntry
- */
-class ProfileStoreLabel : public Gtk::Label
-{
-
-public:
- const ProfileStoreEntry *entry;
-
-#ifndef NDEBUG
- ProfileStoreLabel() : Gtk::Label("*** error ***"), entry(nullptr) {}
-#else
- ProfileStoreLabel() : Gtk::Label(""), entry(NULL) {}
-#endif
-
- /** @brief Create a new ProfileStoreLabel
- *
- * @param entry Pointer to the ProfileStoreEntry object, be it a directory or a file
- */
- explicit ProfileStoreLabel(const ProfileStoreEntry *entry);
- ProfileStoreLabel (const ProfileStoreLabel &other);
+ void setValues (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder);
};
@@ -124,12 +98,12 @@ public:
* This store can be queried by the GUI to display a Tree of the profiles available
* in the user's and system's profile directory and subdirectories.
*/
-class ProfileStore :
- public rtengine::NonCopyable
+class ProfileStore : public rtengine::NonCopyable, public DynamicProfileRules
{
typedef enum {
STORESTATE_NOTINITIALIZED,
+ STORESTATE_LIGHTWEIGHT,
STORESTATE_BEINGINITIALIZED,
STORESTATE_INITIALIZED,
STORESTATE_DELETED
@@ -137,13 +111,13 @@ class ProfileStore :
private:
struct SortProfiles {
- bool operator ()(const ProfileStoreEntry* const a1, const ProfileStoreEntry* const a2)
+ bool operator () (const ProfileStoreEntry* const a1, const ProfileStoreEntry* const a2)
{
return a1->parentFolderId == a2->parentFolderId ? a1->label < a2->label : a1->parentFolderId < a2->parentFolderId;
}
};
- MyMutex *parseMutex;
+ MyMutex parseMutex;
StoreState storeState;
rtengine::procparams::AutoPartialProfile *internalDefaultProfile;
ProfileStoreEntry *internalDefaultEntry;
@@ -164,8 +138,8 @@ private:
/** List of the client of this store */
std::list listeners;
- /** cache for dynamic profile rules */
- std::unique_ptr> dynamicRules;
+ /** whereas we have to load all profile at init time or one by one upon request */
+ bool loadAll;
/** @brief Method to recursively parse a profile folder with a level depth arbitrarily limited to 3
*
@@ -182,24 +156,26 @@ private:
void _parseProfiles ();
void clearFileList ();
void clearProfileList ();
- const ProfileStoreEntry* findEntryFromFullPathU(Glib::ustring path);
+ const ProfileStoreEntry* findEntryFromFullPathU (Glib::ustring path);
public:
ProfileStore();
~ProfileStore();
- bool init ();
+ static ProfileStore* getInstance();
+
+ bool init (bool loadAll = true);
void parseProfiles ();
- int findFolderId(const Glib::ustring &path);
- const ProfileStoreEntry* findEntryFromFullPath(Glib::ustring path);
+ int findFolderId (const Glib::ustring &path);
+ const ProfileStoreEntry* findEntryFromFullPath (Glib::ustring path);
const rtengine::procparams::PartialProfile* getProfile (Glib::ustring path);
const rtengine::procparams::PartialProfile* getProfile (const ProfileStoreEntry* entry);
const std::vector* getFileList ();
void releaseFileList ();
const rtengine::procparams::ProcParams* getDefaultProcParams (bool isRaw);
const rtengine::procparams::PartialProfile* getDefaultPartialProfile (bool isRaw);
- const Glib::ustring getPathFromId(int folderId);
+ const Glib::ustring getPathFromId (int folderId);
const ProfileStoreEntry* getInternalDefaultPSE()
{
return internalDefaultEntry;
@@ -210,53 +186,12 @@ public:
return internalDynamicEntry;
}
- const std::vector &getDynamicProfileRules() const;
- void setDynamicProfileRules(const std::vector &r);
+ void addListener (ProfileStoreListener *listener);
+ void removeListener (ProfileStoreListener *listener);
- void addListener(ProfileStoreListener *listener);
- void removeListener(ProfileStoreListener *listener);
+ rtengine::procparams::PartialProfile* loadDynamicProfile (const rtengine::ImageMetaData *im);
void dumpFolderList();
-
};
-class ProfileStoreComboBox : public MyComboBox
-{
-
-protected:
- class MethodColumns : public Gtk::TreeModel::ColumnRecord
- {
- public:
- Gtk::TreeModelColumn label;
- Gtk::TreeModelColumn profileStoreEntry;
- MethodColumns()
- {
- add(label);
- add(profileStoreEntry);
- }
- };
-
- Glib::RefPtr refTreeModel;
- MethodColumns methodColumns;
- void refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList);
- Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse);
- Gtk::TreeIter findRowFromFullPath_(Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name);
-
-public:
- ProfileStoreComboBox();
- void updateProfileList();
- Glib::ustring getCurrentLabel();
- const ProfileStoreEntry* getSelectedEntry();
- Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse);
- Gtk::TreeIter findRowFromFullPath (Glib::ustring path);
- Glib::ustring getFullPathFromActiveRow ();
- bool setActiveRowFromFullPath (Glib::ustring oldPath);
- bool setActiveRowFromEntry (const ProfileStoreEntry *pse);
- bool setInternalEntry ();
- Gtk::TreeIter getRowFromLabel(Glib::ustring name);
- Gtk::TreeIter addRow(const ProfileStoreEntry *profileStoreEntry);
-};
-
-extern ProfileStore profileStore;
-
#endif
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index e7a71c81e..efbba78d1 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -1416,11 +1416,12 @@ private:
}
params.wavelet.strength *= scale_factor;
params.dirpyrDenoise.luma *= scale_factor;
- params.dirpyrDenoise.Ldetail += (100 - params.dirpyrDenoise.Ldetail) * scale_factor;
- //params.dirpyrDenoise.smethod = "shal";
- for (auto &p : params.dirpyrDenoise.lcurve) {
- p *= scale_factor;
+ //params.dirpyrDenoise.Ldetail += (100 - params.dirpyrDenoise.Ldetail) * scale_factor;
+ auto &lcurve = params.dirpyrDenoise.lcurve;
+ for (size_t i = 2; i < lcurve.size(); i += 4) {
+ lcurve[i] *= min(scale_factor * 2, 1.0);
}
+ noiseLCurve.Set(lcurve);
const char *medmethods[] = { "soft", "33", "55soft", "55", "77", "99" };
if (params.dirpyrDenoise.median) {
auto &key = params.dirpyrDenoise.methodmed == "RGB" ? params.dirpyrDenoise.rgbmethod : params.dirpyrDenoise.medmethod;
diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt
index 300491e85..c317f8525 100644
--- a/rtgui/CMakeLists.txt
+++ b/rtgui/CMakeLists.txt
@@ -46,7 +46,6 @@ set(NONCLISOURCEFILES
dirpyrdenoise.cc
dirpyrequalizer.cc
distortion.cc
- dynamicprofile.cc
dynamicprofilepanel.cc
edit.cc
editorpanel.cc
@@ -107,7 +106,7 @@ set(NONCLISOURCEFILES
previewmodepanel.cc
previewwindow.cc
profilepanel.cc
- profilestore.cc
+ profilestorecombobox.cc
prsharpening.cc
rawcacorrection.cc
rawexposure.cc
@@ -219,15 +218,15 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY
# Create new executables targets
add_executable(rth ${EXTRA_SRC_NONCLI} ${NONCLISOURCEFILES})
-#add_executable(rth-cli ${EXTRA_SRC_CLI} ${CLISOURCEFILES})
+add_executable(rth-cli ${EXTRA_SRC_CLI} ${CLISOURCEFILES})
# Add dependencies to executables targets
add_dependencies(rth UpdateInfo)
-#add_dependencies(rth-cli UpdateInfo)
+add_dependencies(rth-cli UpdateInfo)
# Set executables targets properties, i.e. output filename and compile flags
set_target_properties(rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee)
-#set_target_properties(rth-cli PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee-cli)
+set_target_properties(rth-cli PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee-cli)
# Add linked libraries dependencies to executables targets
target_link_libraries(rth rtengine
@@ -251,25 +250,25 @@ target_link_libraries(rth rtengine
${ZLIB_LIBRARIES}
)
-#target_link_libraries(rth-cli rtengine
-# ${CAIROMM_LIBRARIES}
-# ${EXPAT_LIBRARIES}
-# ${EXTRA_LIB_RTGUI}
-# ${FFTW3F_LIBRARIES}
-# ${GIOMM_LIBRARIES}
-# ${GIO_LIBRARIES}
-# ${GLIB2_LIBRARIES}
-# ${GLIBMM_LIBRARIES}
-# ${GOBJECT_LIBRARIES}
-# ${GTHREAD_LIBRARIES}
-# ${IPTCDATA_LIBRARIES}
-# ${JPEG_LIBRARIES}
-# ${LCMS_LIBRARIES}
-# ${PNG_LIBRARIES}
-# ${TIFF_LIBRARIES}
-# ${ZLIB_LIBRARIES}
-# )
+target_link_libraries(rth-cli rtengine
+ ${CAIROMM_LIBRARIES}
+ ${EXPAT_LIBRARIES}
+ ${EXTRA_LIB_RTGUI}
+ ${FFTW3F_LIBRARIES}
+ ${GIOMM_LIBRARIES}
+ ${GIO_LIBRARIES}
+ ${GLIB2_LIBRARIES}
+ ${GLIBMM_LIBRARIES}
+ ${GOBJECT_LIBRARIES}
+ ${GTHREAD_LIBRARIES}
+ ${IPTCDATA_LIBRARIES}
+ ${JPEG_LIBRARIES}
+ ${LCMS_LIBRARIES}
+ ${PNG_LIBRARIES}
+ ${TIFF_LIBRARIES}
+ ${ZLIB_LIBRARIES}
+ )
# Install executables
install(TARGETS rth DESTINATION ${BINDIR})
-#install(TARGETS rth-cli DESTINATION ${BINDIR})
+install(TARGETS rth-cli DESTINATION ${BINDIR})
diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc
index eee97c2ad..d5a728a97 100644
--- a/rtgui/bayerprocess.cc
+++ b/rtgui/bayerprocess.cc
@@ -945,21 +945,53 @@ void BayerProcess::pixelShiftMotionMethodChanged ()
void BayerProcess::FrameCountChanged(int n, int frameNum)
{
- GThreadLock lock;
- imageNumber->block (true);
+ struct Data {
+ BayerProcess *me;
+ int n;
+ int frameNum;
+ };
+ const auto func = [](gpointer data) -> gboolean {
+ Data *d = static_cast(data);
+ BayerProcess *me = d->me;
+ me->imageNumber->block (true);
+ int n = d->n;
+ int frameNum = d->frameNum;
- imageNumber->remove_all();
- imageNumber->append("1");
- for(int i = 2; i <= std::min(n, 4); ++i) {
- std::ostringstream entry;
- entry << i;
- imageNumber->append(entry.str());
- }
- imageNumber->set_active(std::min(frameNum, n - 1));
- if(n == 1) {
- imageNumberBox->hide();
- } else {
- imageNumberBox->show();
- }
- imageNumber->block (false);
+ me->imageNumber->remove_all();
+ me->imageNumber->append("1");
+ for(int i = 2; i <= std::min(n, 4); ++i) {
+ std::ostringstream entry;
+ entry << i;
+ me->imageNumber->append(entry.str());
+ }
+ me->imageNumber->set_active(std::min(frameNum, n - 1));
+ if(n == 1) {
+ me->imageNumberBox->hide();
+ } else {
+ me->imageNumberBox->show();
+ }
+ me->imageNumber->block (false);
+ delete d;
+ return FALSE;
+ };
+
+ idle_register.add(func, new Data { this, n, frameNum });
+
+ // GThreadLock lock;
+ // imageNumber->block (true);
+
+ // imageNumber->remove_all();
+ // imageNumber->append("1");
+ // for(int i = 2; i <= std::min(n, 4); ++i) {
+ // std::ostringstream entry;
+ // entry << i;
+ // imageNumber->append(entry.str());
+ // }
+ // imageNumber->set_active(std::min(frameNum, n - 1));
+ // if(n == 1) {
+ // imageNumberBox->hide();
+ // } else {
+ // imageNumberBox->show();
+ // }
+ // imageNumber->block (false);
}
diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h
index 3d15802a5..6d9dd6062 100644
--- a/rtgui/bayerprocess.h
+++ b/rtgui/bayerprocess.h
@@ -74,6 +74,8 @@ protected:
Adjuster* pixelShiftRedBlueWeight;
#endif
int oldMethod;
+
+ IdleRegister idle_register;
public:
BayerProcess ();
diff --git a/rtgui/dynamicprofile.cc b/rtgui/dynamicprofile.cc
deleted file mode 100644
index 4439a1562..000000000
--- a/rtgui/dynamicprofile.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-/* -*- C++ -*-
- * This file is part of RawTherapee.
- *
- * Copyright (c) 2017 Alberto Griggio
- *
- * 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 "dynamicprofile.h"
-#include "profilestore.h"
-#include
-#include
-
-using namespace rtengine;
-using namespace rtengine::procparams;
-
-namespace {
-
-const int ISO_MAX = 512000;
-const double FNUMBER_MAX = 100.0;
-const double FOCALLEN_MAX = 10000.0;
-const double SHUTTERSPEED_MAX = 1000.0;
-const double EXPCOMP_MIN = -20.0;
-const double EXPCOMP_MAX = 20.0;
-
-} // namespace
-
-
-bool DynamicProfileRule::Optional::operator()(const Glib::ustring &val) const
-{
- if (!enabled) {
- return true;
- }
- if (value.find("re:") == 0) {
- // this is a regexp
- return Glib::Regex::match_simple(value.substr(3), val,
- Glib::REGEX_CASELESS);
- } else {
- // normal string comparison
- return value.casefold() == val.casefold();
- }
-}
-
-
-DynamicProfileRule::DynamicProfileRule():
- serial_number(0),
- iso(0, ISO_MAX),
- fnumber(0, FNUMBER_MAX),
- focallen(0, FOCALLEN_MAX),
- shutterspeed(0, SHUTTERSPEED_MAX),
- expcomp(EXPCOMP_MIN, EXPCOMP_MAX)
-{
-}
-
-
-bool DynamicProfileRule::operator<(const DynamicProfileRule &other) const
-{
- return serial_number < other.serial_number;
-}
-
-
-bool DynamicProfileRule::matches(const rtengine::ImageMetaData *im) const
-{
- return (iso(im->getISOSpeed())
- && fnumber(im->getFNumber())
- && focallen(im->getFocalLen())
- && shutterspeed(im->getShutterSpeed())
- && expcomp(im->getExpComp())
- && camera(im->getCamera())
- && lens(im->getLens()));
-}
-
-namespace {
-
-void get_int_range(DynamicProfileRule::Range &dest,
- const Glib::KeyFile &kf, const Glib::ustring &group,
- const Glib::ustring &key)
-{
- try {
- int min = kf.get_integer(group, key + "_min");
- int max = kf.get_integer(group, key + "_max");
- if (min <= max) {
- dest.min = min;
- dest.max = max;
- }
- } catch (Glib::KeyFileError &e) {
- }
-}
-
-
-void get_double_range(DynamicProfileRule::Range &dest,
- const Glib::KeyFile &kf, const Glib::ustring &group,
- const Glib::ustring &key)
-{
- try {
- double min = kf.get_double(group, key + "_min");
- double max = kf.get_double(group, key + "_max");
- if (min <= max) {
- dest.min = min;
- dest.max = max;
- }
- } catch (Glib::KeyFileError &e) {
- }
-}
-
-
-void get_optional(DynamicProfileRule::Optional &dest,
- const Glib::KeyFile &kf, const Glib::ustring &group,
- const Glib::ustring &key)
-{
- try {
- bool e = kf.get_boolean(group, key + "_enabled");
- if (e) {
- Glib::ustring s = kf.get_string(group, key + "_value");
- dest.enabled = e;
- dest.value = s;
- }
- } catch (Glib::KeyFileError &) {
- }
-}
-
-void set_int_range(Glib::KeyFile &kf, const Glib::ustring &group,
- const Glib::ustring &key,
- const DynamicProfileRule::Range &val)
-{
- kf.set_integer(group, key + "_min", val.min);
- kf.set_integer(group, key + "_max", val.max);
-}
-
-void set_double_range(Glib::KeyFile &kf, const Glib::ustring &group,
- const Glib::ustring &key,
- const DynamicProfileRule::Range &val)
-{
- kf.set_double(group, key + "_min", val.min);
- kf.set_double(group, key + "_max", val.max);
-}
-
-void set_optional(Glib::KeyFile &kf, const Glib::ustring &group,
- const Glib::ustring &key,
- const DynamicProfileRule::Optional &val)
-{
- kf.set_boolean(group, key + "_enabled", val.enabled);
- kf.set_string(group, key + "_value", val.value);
-}
-
-} // namespace
-
-
-bool loadDynamicProfileRules(std::vector &out)
-{
- out.clear();
- Glib::KeyFile kf;
- try {
- if (!kf.load_from_file(
- Glib::build_filename(Options::rtdir, "dynamicprofile.cfg"))) {
- return false;
- }
- } catch (Glib::Error &e) {
- return false;
- }
- if (options.rtSettings.verbose) {
- printf("loading dynamic profiles...\n");
- }
- auto groups = kf.get_groups();
- for (auto group : groups) {
- // groups are of the form "rule N", where N is a positive integer
- if (group.find("rule ") != 0) {
- return false;
- }
- std::istringstream buf(group.c_str() + 5);
- int serial = 0;
- if (!(buf >> serial) || !buf.eof()) {
- return false;
- }
- if (options.rtSettings.verbose) {
- printf(" loading rule %d\n", serial);
- }
-
- out.emplace_back(DynamicProfileRule());
- DynamicProfileRule &rule = out.back();
- rule.serial_number = serial;
- get_int_range(rule.iso, kf, group, "iso");
- get_double_range(rule.fnumber, kf, group, "fnumber");
- get_double_range(rule.focallen, kf, group, "focallen");
- get_double_range(rule.shutterspeed, kf, group, "shutterspeed");
- get_double_range(rule.expcomp, kf, group, "expcomp");
- get_optional(rule.camera, kf, group, "camera");
- get_optional(rule.lens, kf, group, "lens");
- try {
- rule.profilepath = kf.get_string(group, "profilepath");
- } catch (Glib::KeyFileError &) {
- out.pop_back();
- }
- }
- std::sort(out.begin(), out.end());
- return true;
-}
-
-
-bool storeDynamicProfileRules(const std::vector &rules)
-{
- if (options.rtSettings.verbose) {
- printf("saving dynamic profiles...\n");
- }
- Glib::KeyFile kf;
- for (auto &rule : rules) {
- std::ostringstream buf;
- buf << "rule " << rule.serial_number;
- Glib::ustring group = buf.str();
- set_int_range(kf, group, "iso", rule.iso);
- set_double_range(kf, group, "fnumber", rule.fnumber);
- set_double_range(kf, group, "focallen", rule.focallen);
- set_double_range(kf, group, "shutterspeed", rule.shutterspeed);
- set_double_range(kf, group, "expcomp", rule.expcomp);
- set_optional(kf, group, "camera", rule.camera);
- set_optional(kf, group, "lens", rule.lens);
- kf.set_string(group, "profilepath", rule.profilepath);
- }
- return kf.save_to_file(
- Glib::build_filename(Options::rtdir, "dynamicprofile.cfg"));
-}
-
-
-PartialProfile *loadDynamicProfile(const ImageMetaData *im)
-{
- PartialProfile *ret = new PartialProfile(true, true);
- for (auto &rule : profileStore.getDynamicProfileRules()) {
- if (rule.matches(im)) {
- if (options.rtSettings.verbose) {
- printf("found matching profile %s\n",
- rule.profilepath.c_str());
- }
- const PartialProfile *p =
- profileStore.getProfile(rule.profilepath);
- if (p != nullptr) {
- p->applyTo(ret->pparams);
- } else {
- printf("ERROR loading matching profile from: %s\n",
- rule.profilepath.c_str());
- }
- }
- }
- return ret;
-}
diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc
index 172c06f47..db3a19ed0 100644
--- a/rtgui/dynamicprofilepanel.cc
+++ b/rtgui/dynamicprofilepanel.cc
@@ -19,8 +19,9 @@
#include "dynamicprofilepanel.h"
#include "multilangmgr.h"
-#include "profilestore.h"
+#include "../rtengine/profilestore.h"
#include "../rtengine/rtengine.h"
+#include "../rtengine/dynamicprofile.h"
#include
#include
@@ -29,65 +30,63 @@
// DynamicProfilePanel::EditDialog
//-----------------------------------------------------------------------------
-DynamicProfilePanel::EditDialog::EditDialog(const Glib::ustring &title,
- Gtk::Window &parent):
- Gtk::Dialog(title, parent)
+DynamicProfilePanel::EditDialog::EditDialog (const Glib::ustring &title, Gtk::Window &parent):
+ Gtk::Dialog (title, parent)
{
- profilepath_ = Gtk::manage(new ProfileStoreComboBox());
- Gtk::HBox *hb = Gtk::manage(new Gtk::HBox());
- hb->pack_start(*Gtk::manage(new Gtk::Label(M("DYNPROFILEEDITOR_PROFILE"))),
- false, false, 4);
- hb->pack_start(*profilepath_, true, true, 2);
- get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4);
+ profilepath_ = Gtk::manage (new ProfileStoreComboBox());
+ Gtk::HBox *hb = Gtk::manage (new Gtk::HBox());
+ hb->pack_start (*Gtk::manage (new Gtk::Label (M ("DYNPROFILEEDITOR_PROFILE"))), false, false, 4);
+ hb->pack_start (*profilepath_, true, true, 2);
+ get_content_area()->pack_start (*hb, Gtk::PACK_SHRINK, 4);
- add_optional(M("EXIFFILTER_CAMERA"), has_camera_, camera_);
- add_optional(M("EXIFFILTER_LENS"), has_lens_, lens_);
-
- add_range(M("EXIFFILTER_ISO"), iso_min_, iso_max_);
- add_range(M("EXIFFILTER_APERTURE"), fnumber_min_, fnumber_max_);
- add_range(M("EXIFFILTER_FOCALLEN"), focallen_min_, focallen_max_);
- add_range(M("EXIFFILTER_SHUTTER"), shutterspeed_min_, shutterspeed_max_);
- add_range(M("EXIFFILTER_EXPOSURECOMPENSATION"), expcomp_min_, expcomp_max_);
+ add_optional (M ("EXIFFILTER_CAMERA"), has_camera_, camera_);
+ add_optional (M ("EXIFFILTER_LENS"), has_lens_, lens_);
- add_button(M("GENERAL_OK"), 1);
- add_button(M("GENERAL_CANCEL"), 2);
+ add_range (M ("EXIFFILTER_ISO"), iso_min_, iso_max_);
+ add_range (M ("EXIFFILTER_APERTURE"), fnumber_min_, fnumber_max_);
+ add_range (M ("EXIFFILTER_FOCALLEN"), focallen_min_, focallen_max_);
+ add_range (M ("EXIFFILTER_SHUTTER"), shutterspeed_min_, shutterspeed_max_);
+ add_range (M ("EXIFFILTER_EXPOSURECOMPENSATION"), expcomp_min_, expcomp_max_);
+
+ add_button (M ("GENERAL_OK"), 1);
+ add_button (M ("GENERAL_CANCEL"), 2);
set_ranges();
-
+
show_all_children();
}
-void DynamicProfilePanel::EditDialog::set_rule(
+void DynamicProfilePanel::EditDialog::set_rule (
const DynamicProfileRule &rule)
{
- iso_min_->set_value(rule.iso.min);
- iso_max_->set_value(rule.iso.max);
+ iso_min_->set_value (rule.iso.min);
+ iso_max_->set_value (rule.iso.max);
- fnumber_min_->set_value(rule.fnumber.min);
- fnumber_max_->set_value(rule.fnumber.max);
+ fnumber_min_->set_value (rule.fnumber.min);
+ fnumber_max_->set_value (rule.fnumber.max);
- focallen_min_->set_value(rule.focallen.min);
- focallen_max_->set_value(rule.focallen.max);
+ focallen_min_->set_value (rule.focallen.min);
+ focallen_max_->set_value (rule.focallen.max);
- shutterspeed_min_->set_value(rule.shutterspeed.min);
- shutterspeed_max_->set_value(rule.shutterspeed.max);
+ shutterspeed_min_->set_value (rule.shutterspeed.min);
+ shutterspeed_max_->set_value (rule.shutterspeed.max);
- expcomp_min_->set_value(rule.expcomp.min);
- expcomp_max_->set_value(rule.expcomp.max);
+ expcomp_min_->set_value (rule.expcomp.min);
+ expcomp_max_->set_value (rule.expcomp.max);
- has_camera_->set_active(rule.camera.enabled);
- camera_->set_text(rule.camera.value);
+ has_camera_->set_active (rule.camera.enabled);
+ camera_->set_text (rule.camera.value);
- has_lens_->set_active(rule.lens.enabled);
- lens_->set_text(rule.lens.value);
+ has_lens_->set_active (rule.lens.enabled);
+ lens_->set_text (rule.lens.value);
profilepath_->updateProfileList();
- if (!profilepath_->setActiveRowFromFullPath(rule.profilepath)) {
+
+ if (!profilepath_->setActiveRowFromFullPath (rule.profilepath)) {
profilepath_->setInternalEntry();
}
}
-
DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule()
{
@@ -97,7 +96,7 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule()
ret.fnumber.min = fnumber_min_->get_value();
ret.fnumber.max = fnumber_max_->get_value();
-
+
ret.focallen.min = focallen_min_->get_value();
ret.focallen.max = focallen_max_->get_value();
@@ -112,7 +111,7 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule()
ret.lens.enabled = has_lens_->get_active();
ret.lens.value = lens_->get_text();
-
+
ret.profilepath = profilepath_->getFullPathFromActiveRow();
return ret;
@@ -121,20 +120,20 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule()
void DynamicProfilePanel::EditDialog::set_ranges()
{
DynamicProfileRule default_rule;
- iso_min_->set_digits(0);
- iso_max_->set_digits(0);
- iso_min_->set_increments(1, 10);
- iso_max_->set_increments(1, 10);
- iso_min_->set_range(default_rule.iso.min, default_rule.iso.max);
- iso_max_->set_range(default_rule.iso.min, default_rule.iso.max);
- iso_min_->set_value(default_rule.iso.min);
- iso_max_->set_value(default_rule.iso.max);
+ iso_min_->set_digits (0);
+ iso_max_->set_digits (0);
+ iso_min_->set_increments (1, 10);
+ iso_max_->set_increments (1, 10);
+ iso_min_->set_range (default_rule.iso.min, default_rule.iso.max);
+ iso_max_->set_range (default_rule.iso.min, default_rule.iso.max);
+ iso_min_->set_value (default_rule.iso.min);
+ iso_max_->set_value (default_rule.iso.max);
-#define DOIT_(name) \
- name ## _min_->set_digits(1); \
- name ## _max_->set_digits(1); \
- name ## _min_->set_increments(0.1, 1); \
- name ## _max_->set_increments(0.1, 1); \
+#define DOIT_(name) \
+ name ## _min_->set_digits(1); \
+ name ## _max_->set_digits(1); \
+ name ## _min_->set_increments(0.1, 1); \
+ name ## _max_->set_increments(0.1, 1); \
name ## _min_->set_range(default_rule. name .min, \
default_rule. name .max); \
name ## _max_->set_range(default_rule. name .min, \
@@ -142,45 +141,42 @@ void DynamicProfilePanel::EditDialog::set_ranges()
name ## _min_->set_value(default_rule. name .min); \
name ## _max_->set_value(default_rule. name .max)
- DOIT_(fnumber);
- DOIT_(focallen);
- DOIT_(shutterspeed);
- DOIT_(expcomp);
+ DOIT_ (fnumber);
+ DOIT_ (focallen);
+ DOIT_ (shutterspeed);
+ DOIT_ (expcomp);
#undef DOIT_
- shutterspeed_min_->set_digits(4);
- shutterspeed_max_->set_digits(4);
+ shutterspeed_min_->set_digits (4);
+ shutterspeed_max_->set_digits (4);
profilepath_->setInternalEntry();
}
-void DynamicProfilePanel::EditDialog::add_range(const Glib::ustring &name,
+void DynamicProfilePanel::EditDialog::add_range (const Glib::ustring &name,
Gtk::SpinButton *&from, Gtk::SpinButton *&to)
{
- Gtk::HBox *hb = Gtk::manage(new Gtk::HBox());
- hb->pack_start(*Gtk::manage(new Gtk::Label(name)), false, false, 4);
- from = Gtk::manage(new Gtk::SpinButton());
- to = Gtk::manage(new Gtk::SpinButton());
- from->set_numeric(true);
- to->set_numeric(true);
- hb->pack_start(*from, true, true, 2);
- hb->pack_start(*Gtk::manage(new Gtk::Label(" - ")),
- false, false, 4);
- hb->pack_start(*to, true, true, 2);
- get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4);
+ Gtk::HBox *hb = Gtk::manage (new Gtk::HBox());
+ hb->pack_start (*Gtk::manage (new Gtk::Label (name)), false, false, 4);
+ from = Gtk::manage (new Gtk::SpinButton());
+ to = Gtk::manage (new Gtk::SpinButton());
+ from->set_numeric (true);
+ to->set_numeric (true);
+ hb->pack_start (*from, true, true, 2);
+ hb->pack_start (*Gtk::manage (new Gtk::Label (" - ")), false, false, 4);
+ hb->pack_start (*to, true, true, 2);
+ get_content_area()->pack_start (*hb, Gtk::PACK_SHRINK, 4);
}
-
-void DynamicProfilePanel::EditDialog::add_optional(const Glib::ustring &name,
- Gtk::CheckButton *&check, Gtk::Entry *&field)
+void DynamicProfilePanel::EditDialog::add_optional (const Glib::ustring &name, Gtk::CheckButton *&check, Gtk::Entry *&field)
{
- check = Gtk::manage (new Gtk::CheckButton(name));
- Gtk::HBox *hb = Gtk::manage(new Gtk::HBox());
- hb->pack_start(*check, Gtk::PACK_SHRINK, 4);
- field = Gtk::manage(new Gtk::Entry());
- hb->pack_start(*field, true, true, 2);
- get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4);
- field->set_tooltip_text(M("DYNPROFILEEDITOR_ENTRY_TOOLTIP"));
+ check = Gtk::manage (new Gtk::CheckButton (name));
+ Gtk::HBox *hb = Gtk::manage (new Gtk::HBox());
+ hb->pack_start (*check, Gtk::PACK_SHRINK, 4);
+ field = Gtk::manage (new Gtk::Entry());
+ hb->pack_start (*field, true, true, 2);
+ get_content_area()->pack_start (*hb, Gtk::PACK_SHRINK, 4);
+ field->set_tooltip_text (M ("DYNPROFILEEDITOR_ENTRY_TOOLTIP"));
}
@@ -189,121 +185,135 @@ void DynamicProfilePanel::EditDialog::add_optional(const Glib::ustring &name,
//-----------------------------------------------------------------------------
DynamicProfilePanel::DynamicProfilePanel():
- vbox_(Gtk::ORIENTATION_VERTICAL),
- button_up_(M("DYNPROFILEEDITOR_MOVE_UP")),
- button_down_(M("DYNPROFILEEDITOR_MOVE_DOWN")),
- button_new_(M("DYNPROFILEEDITOR_NEW")),
- button_edit_(M("DYNPROFILEEDITOR_EDIT")),
- button_delete_(M("DYNPROFILEEDITOR_DELETE"))
+ vbox_ (Gtk::ORIENTATION_VERTICAL),
+ button_up_ (M ("DYNPROFILEEDITOR_MOVE_UP")),
+ button_down_ (M ("DYNPROFILEEDITOR_MOVE_DOWN")),
+ button_new_ (M ("DYNPROFILEEDITOR_NEW")),
+ button_edit_ (M ("DYNPROFILEEDITOR_EDIT")),
+ button_delete_ (M ("DYNPROFILEEDITOR_DELETE"))
{
- add(vbox_);
+ add (vbox_);
- treeview_.set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_VERTICAL);
- scrolledwindow_.add(treeview_);
+ treeview_.set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_VERTICAL);
+ scrolledwindow_.add (treeview_);
- scrolledwindow_.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ scrolledwindow_.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- vbox_.pack_start(scrolledwindow_);
- vbox_.pack_start(buttonbox_, Gtk::PACK_SHRINK);
+ vbox_.pack_start (scrolledwindow_);
+ vbox_.pack_start (buttonbox_, Gtk::PACK_SHRINK);
- buttonbox_.pack_start(button_new_, Gtk::PACK_SHRINK);
- buttonbox_.pack_start(button_edit_, Gtk::PACK_SHRINK);
- buttonbox_.pack_start(button_delete_, Gtk::PACK_SHRINK);
- buttonbox_.pack_start(button_up_, Gtk::PACK_SHRINK);
- buttonbox_.pack_start(button_down_, Gtk::PACK_SHRINK);
- buttonbox_.set_border_width(5);
- buttonbox_.set_layout(Gtk::BUTTONBOX_END);
- button_up_.signal_clicked().connect(
- sigc::mem_fun(*this, &DynamicProfilePanel::on_button_up));
- button_down_.signal_clicked().connect(
- sigc::mem_fun(*this, &DynamicProfilePanel::on_button_down));
- button_new_.signal_clicked().connect(
- sigc::mem_fun(*this, &DynamicProfilePanel::on_button_new));
- button_edit_.signal_clicked().connect(
- sigc::mem_fun(*this, &DynamicProfilePanel::on_button_edit));
- button_delete_.signal_clicked().connect(
- sigc::mem_fun(*this, &DynamicProfilePanel::on_button_delete));
+ buttonbox_.pack_start (button_new_, Gtk::PACK_SHRINK);
+ buttonbox_.pack_start (button_edit_, Gtk::PACK_SHRINK);
+ buttonbox_.pack_start (button_delete_, Gtk::PACK_SHRINK);
+ buttonbox_.pack_start (button_up_, Gtk::PACK_SHRINK);
+ buttonbox_.pack_start (button_down_, Gtk::PACK_SHRINK);
+ buttonbox_.set_border_width (5);
+ buttonbox_.set_layout (Gtk::BUTTONBOX_END);
+ button_up_.signal_clicked().connect (
+ sigc::mem_fun (*this, &DynamicProfilePanel::on_button_up));
+ button_down_.signal_clicked().connect (
+ sigc::mem_fun (*this, &DynamicProfilePanel::on_button_down));
+ button_new_.signal_clicked().connect (
+ sigc::mem_fun (*this, &DynamicProfilePanel::on_button_new));
+ button_edit_.signal_clicked().connect (
+ sigc::mem_fun (*this, &DynamicProfilePanel::on_button_edit));
+ button_delete_.signal_clicked().connect (
+ sigc::mem_fun (*this, &DynamicProfilePanel::on_button_delete));
- treemodel_ = Gtk::ListStore::create(columns_);
- treeview_.set_model(treemodel_);
+ treemodel_ = Gtk::ListStore::create (columns_);
+ treeview_.set_model (treemodel_);
+
+ auto cell = Gtk::manage (new Gtk::CellRendererText());
+ int cols_count = treeview_.append_column ( M ("DYNPROFILEEDITOR_PROFILE"), *cell);
+ auto col = treeview_.get_column (cols_count - 1);
- auto cell = Gtk::manage(new Gtk::CellRendererText());
- int cols_count = treeview_.append_column(
- M("DYNPROFILEEDITOR_PROFILE"), *cell);
- auto col = treeview_.get_column(cols_count - 1);
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_profilepath));
}
- cell = Gtk::manage(new Gtk::CellRendererText());
- cols_count = treeview_.append_column(
- M("EXIFFILTER_CAMERA"), *cell);
- col = treeview_.get_column(cols_count - 1);
+
+ cell = Gtk::manage (new Gtk::CellRendererText());
+ cols_count = treeview_.append_column (
+ M ("EXIFFILTER_CAMERA"), *cell);
+ col = treeview_.get_column (cols_count - 1);
+
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_camera));
}
- cell = Gtk::manage(new Gtk::CellRendererText());
- cols_count = treeview_.append_column(M("EXIFFILTER_LENS"), *cell);
- col = treeview_.get_column(cols_count - 1);
+
+ cell = Gtk::manage (new Gtk::CellRendererText());
+ cols_count = treeview_.append_column (M ("EXIFFILTER_LENS"), *cell);
+ col = treeview_.get_column (cols_count - 1);
+
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_lens));
}
- cell = Gtk::manage(new Gtk::CellRendererText());
- cols_count = treeview_.append_column(M("EXIFFILTER_ISO"), *cell);
- col = treeview_.get_column(cols_count - 1);
+
+ cell = Gtk::manage (new Gtk::CellRendererText());
+ cols_count = treeview_.append_column (M ("EXIFFILTER_ISO"), *cell);
+ col = treeview_.get_column (cols_count - 1);
+
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_iso));
}
- cell = Gtk::manage(new Gtk::CellRendererText());
- cols_count = treeview_.append_column(M("EXIFFILTER_APERTURE"), *cell);
- col = treeview_.get_column(cols_count - 1);
+
+ cell = Gtk::manage (new Gtk::CellRendererText());
+ cols_count = treeview_.append_column (M ("EXIFFILTER_APERTURE"), *cell);
+ col = treeview_.get_column (cols_count - 1);
+
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_fnumber));
}
- cell = Gtk::manage(new Gtk::CellRendererText());
- cols_count = treeview_.append_column(M("EXIFFILTER_FOCALLEN"), *cell);
- col = treeview_.get_column(cols_count - 1);
+
+ cell = Gtk::manage (new Gtk::CellRendererText());
+ cols_count = treeview_.append_column (M ("EXIFFILTER_FOCALLEN"), *cell);
+ col = treeview_.get_column (cols_count - 1);
+
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_focallen));
}
- cell = Gtk::manage(new Gtk::CellRendererText());
- cols_count = treeview_.append_column(M("EXIFFILTER_SHUTTER"), *cell);
- col = treeview_.get_column(cols_count - 1);
+
+ cell = Gtk::manage (new Gtk::CellRendererText());
+ cols_count = treeview_.append_column (M ("EXIFFILTER_SHUTTER"), *cell);
+ col = treeview_.get_column (cols_count - 1);
+
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_shutterspeed));
}
- cell = Gtk::manage(new Gtk::CellRendererText());
- cols_count = treeview_.append_column(
- M("EXIFFILTER_EXPOSURECOMPENSATION"), *cell);
- col = treeview_.get_column(cols_count - 1);
+
+ cell = Gtk::manage (new Gtk::CellRendererText());
+ cols_count = treeview_.append_column (
+ M ("EXIFFILTER_EXPOSURECOMPENSATION"), *cell);
+ col = treeview_.get_column (cols_count - 1);
+
if (col) {
- col->set_cell_data_func(
- *cell, sigc::mem_fun(
+ col->set_cell_data_func (
+ *cell, sigc::mem_fun (
*this, &DynamicProfilePanel::render_expcomp));
}
-
+
show_all_children();
- for (auto &r : profileStore.getDynamicProfileRules()) {
- add_rule(r);
+ for (auto &r : ProfileStore::getInstance()->getRules()) {
+ add_rule (r);
}
}
-void DynamicProfilePanel::update_rule(Gtk::TreeModel::Row row,
+void DynamicProfilePanel::update_rule (Gtk::TreeModel::Row row,
const DynamicProfileRule &rule)
{
row[columns_.iso] = rule.iso;
@@ -316,15 +326,15 @@ void DynamicProfilePanel::update_rule(Gtk::TreeModel::Row row,
row[columns_.profilepath] = rule.profilepath;
}
-void DynamicProfilePanel::add_rule(const DynamicProfileRule &rule)
+void DynamicProfilePanel::add_rule (const DynamicProfileRule &rule)
{
- auto row = *(treemodel_->append());
- update_rule(row, rule);
+ auto row = * (treemodel_->append());
+ update_rule (row, rule);
}
-DynamicProfileRule DynamicProfilePanel::to_rule(Gtk::TreeModel::Row row,
- int serial)
+DynamicProfileRule DynamicProfilePanel::to_rule (Gtk::TreeModel::Row row,
+ int serial)
{
DynamicProfileRule ret;
ret.serial_number = serial;
@@ -340,13 +350,14 @@ DynamicProfileRule DynamicProfilePanel::to_rule(Gtk::TreeModel::Row row,
}
-void DynamicProfilePanel::render_profilepath(
+void DynamicProfilePanel::render_profilepath (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
auto row = *iter;
- Gtk::CellRendererText *ct = static_cast(cell);
+ Gtk::CellRendererText *ct = static_cast (cell);
auto value = row[columns_.profilepath];
- auto pse = profileStore.findEntryFromFullPath(value);
+ auto pse = ProfileStore::getInstance()->findEntryFromFullPath (value);
+
if (pse != nullptr) {
ct->property_text() = pse->label;
} else {
@@ -368,54 +379,56 @@ void DynamicProfilePanel::render_profilepath(
}
-namespace {
+namespace
+{
template
-Glib::ustring to_str(V n, int precision=1)
+Glib::ustring to_str (V n, int precision = 1)
{
std::ostringstream buf;
- buf << std::setprecision(precision) << std::fixed << n;
+ buf << std::setprecision (precision) << std::fixed << n;
return buf.str();
}
} // namespace
-void DynamicProfilePanel::render_iso(
+void DynamicProfilePanel::render_iso (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
- RENDER_RANGE_(int, iso, to_str);
+ RENDER_RANGE_ (int, iso, to_str);
}
-void DynamicProfilePanel::render_fnumber(
+void DynamicProfilePanel::render_fnumber (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
- RENDER_RANGE_(double, fnumber,
- [](double f)
- { return std::string("f/") +
- rtengine::ImageMetaData::apertureToString(f); });
+ RENDER_RANGE_ (double, fnumber,
+ [] (double f) {
+ return std::string ("f/") +
+ rtengine::ImageMetaData::apertureToString (f);
+ });
}
-void DynamicProfilePanel::render_focallen(
+void DynamicProfilePanel::render_focallen (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
- RENDER_RANGE_(double, focallen, to_str);
+ RENDER_RANGE_ (double, focallen, to_str);
}
-void DynamicProfilePanel::render_shutterspeed(
+void DynamicProfilePanel::render_shutterspeed (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
- RENDER_RANGE_(double, shutterspeed,
- rtengine::ImageMetaData::shutterToString);
+ RENDER_RANGE_ (double, shutterspeed,
+ rtengine::ImageMetaData::shutterToString);
}
-void DynamicProfilePanel::render_expcomp(
+void DynamicProfilePanel::render_expcomp (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
- RENDER_RANGE_(double, expcomp, to_str);
+ RENDER_RANGE_ (double, expcomp, to_str);
}
#undef RENDER_RANGE_
@@ -430,17 +443,17 @@ void DynamicProfilePanel::render_expcomp(
ct->property_text() = ""; \
}
-void DynamicProfilePanel::render_camera(
+void DynamicProfilePanel::render_camera (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
- RENDER_OPTIONAL_(camera);
+ RENDER_OPTIONAL_ (camera);
}
-void DynamicProfilePanel::render_lens(
+void DynamicProfilePanel::render_lens (
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
{
- RENDER_OPTIONAL_(lens);
+ RENDER_OPTIONAL_ (lens);
}
#undef RENDER_OPTIONAL_
@@ -448,28 +461,34 @@ void DynamicProfilePanel::render_lens(
void DynamicProfilePanel::on_button_up()
{
auto s = treeview_.get_selection();
+
if (!s->count_selected_rows()) {
return;
}
+
auto it = s->get_selected();
+
if (it != treemodel_->children().begin()) {
auto it2 = it;
--it2;
- treemodel_->iter_swap(it, it2);
+ treemodel_->iter_swap (it, it2);
}
}
void DynamicProfilePanel::on_button_down()
{
auto s = treeview_.get_selection();
+
if (!s->count_selected_rows()) {
return;
}
+
auto it = s->get_selected();
auto it2 = it;
++it2;
+
if (it2 != treemodel_->children().end()) {
- treemodel_->iter_swap(it, it2);
+ treemodel_->iter_swap (it, it2);
}
}
@@ -477,22 +496,25 @@ void DynamicProfilePanel::on_button_down()
void DynamicProfilePanel::on_button_delete()
{
auto s = treeview_.get_selection();
+
if (!s->count_selected_rows()) {
return;
}
+
auto it = s->get_selected();
- treemodel_->erase(it);
+ treemodel_->erase (it);
}
void DynamicProfilePanel::on_button_new()
{
- EditDialog d(M("DYNPROFILEEDITOR_NEW_RULE"),
- static_cast(*get_toplevel()));
+ EditDialog d (M ("DYNPROFILEEDITOR_NEW_RULE"),
+ static_cast (*get_toplevel()));
int status = d.run();
+
if (status == 1) {
DynamicProfileRule rule = d.get_rule();
- add_rule(rule);
+ add_rule (rule);
}
}
@@ -500,16 +522,19 @@ void DynamicProfilePanel::on_button_new()
void DynamicProfilePanel::on_button_edit()
{
auto s = treeview_.get_selection();
+
if (!s->count_selected_rows()) {
return;
}
- EditDialog d(M("DYNPROFILEEDITOR_EDIT_RULE"),
- static_cast(*get_toplevel()));
- Gtk::TreeModel::Row row = *(s->get_selected());
- d.set_rule(to_rule(row));
+
+ EditDialog d (M ("DYNPROFILEEDITOR_EDIT_RULE"),
+ static_cast (*get_toplevel()));
+ Gtk::TreeModel::Row row = * (s->get_selected());
+ d.set_rule (to_rule (row));
int status = d.run();
+
if (status == 1) {
- update_rule(row, d.get_rule());
+ update_rule (row, d.get_rule());
}
}
@@ -518,15 +543,16 @@ void DynamicProfilePanel::save()
{
std::vector rules;
int serial = 1;
+
for (auto row : treemodel_->children()) {
- rules.emplace_back(to_rule(row, serial++));
+ rules.emplace_back (to_rule (row, serial++));
}
- if (!storeDynamicProfileRules(rules)) {
- printf("Error in saving dynamic profile rules\n");
- } else {
- profileStore.setDynamicProfileRules(rules);
- if (options.rtSettings.verbose) {
- printf("Saved %d dynamic profile rules\n", int(rules.size()));
- }
+
+ ProfileStore::getInstance()->setRules (rules);
+
+ if (!ProfileStore::getInstance()->storeRules()) {
+ printf ("Error in saving dynamic profile rules\n");
+ } else if (options.rtSettings.verbose) {
+ printf ("Saved %d dynamic profile rules\n", int (rules.size()));
}
}
diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h
index 72ff95b9a..dca62f1e6 100644
--- a/rtgui/dynamicprofilepanel.h
+++ b/rtgui/dynamicprofilepanel.h
@@ -20,20 +20,20 @@
#define _DYNAMICPROFILEPANEL_H_
#include
-#include "dynamicprofile.h"
-#include "profilestore.h"
+#include "../rtengine/dynamicprofile.h"
+#include "profilestorecombobox.h"
-class DynamicProfilePanel: public Gtk::VBox {
+class DynamicProfilePanel: public Gtk::VBox
+{
public:
DynamicProfilePanel();
void save();
private:
- void update_rule(Gtk::TreeModel::Row row,
- const DynamicProfileRule &rule);
- void add_rule(const DynamicProfileRule &rule);
- DynamicProfileRule to_rule(Gtk::TreeModel::Row row, int serial=0);
-
+ void update_rule (Gtk::TreeModel::Row row, const DynamicProfileRule &rule);
+ void add_rule (const DynamicProfileRule &rule);
+ DynamicProfileRule to_rule (Gtk::TreeModel::Row row, int serial = 0);
+
void on_button_quit();
void on_button_up();
void on_button_down();
@@ -41,18 +41,19 @@ private:
void on_button_edit();
void on_button_delete();
- class DynamicProfileColumns: public Gtk::TreeModel::ColumnRecord {
+ class DynamicProfileColumns: public Gtk::TreeModel::ColumnRecord
+ {
public:
DynamicProfileColumns()
{
- add(iso);
- add(fnumber);
- add(focallen);
- add(shutterspeed);
- add(expcomp);
- add(camera);
- add(lens);
- add(profilepath);
+ add (iso);
+ add (fnumber);
+ add (focallen);
+ add (shutterspeed);
+ add (expcomp);
+ add (camera);
+ add (lens);
+ add (profilepath);
}
Gtk::TreeModelColumn> iso;
@@ -66,35 +67,26 @@ private:
};
// cell renderers
- void render_iso(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
- void render_fnumber(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
- void render_focallen(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
- void render_shutterspeed(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
- void render_expcomp(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
- void render_camera(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
- void render_lens(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
- void render_profilepath(Gtk::CellRenderer* cell,
- const Gtk::TreeModel::iterator& iter);
+ void render_iso (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
+ void render_fnumber (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
+ void render_focallen (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
+ void render_shutterspeed (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
+ void render_expcomp (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
+ void render_camera (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
+ void render_lens (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
+ void render_profilepath (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
- class EditDialog: public Gtk::Dialog {
+ class EditDialog: public Gtk::Dialog
+ {
public:
- EditDialog(const Glib::ustring &title, Gtk::Window &parent);
- void set_rule(const DynamicProfileRule &rule);
+ EditDialog (const Glib::ustring &title, Gtk::Window &parent);
+ void set_rule (const DynamicProfileRule &rule);
DynamicProfileRule get_rule();
private:
void set_ranges();
- void add_range(const Glib::ustring &name,
- Gtk::SpinButton *&from, Gtk::SpinButton *&to);
- void add_optional(const Glib::ustring &name,
- Gtk::CheckButton *&check, Gtk::Entry *&field);
+ void add_range (const Glib::ustring &name, Gtk::SpinButton *&from, Gtk::SpinButton *&to);
+ void add_optional (const Glib::ustring &name, Gtk::CheckButton *&check, Gtk::Entry *&field);
Gtk::SpinButton *iso_min_;
Gtk::SpinButton *iso_max_;
diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc
index d96a89d09..dd37a740b 100644
--- a/rtgui/filebrowser.cc
+++ b/rtgui/filebrowser.cc
@@ -134,7 +134,7 @@ FileBrowser::FileBrowser ()
fbih->destroyed = false;
fbih->pending = 0;
- profileStore.addListener(this);
+ ProfileStore::getInstance()->addListener(this);
int p = 0;
pmenu = new Gtk::Menu ();
@@ -457,7 +457,7 @@ FileBrowser::~FileBrowser ()
{
idle_register.destroy();
- profileStore.removeListener(this);
+ ProfileStore::getInstance()->removeListener(this);
delete pmenu;
delete pmenuColorLabels;
delete[] amiExtProg;
@@ -1346,7 +1346,7 @@ void FileBrowser::applyMenuItemActivated (ProfileStoreLabel *label)
{
MYREADERLOCK(l, entryRW);
- const rtengine::procparams::PartialProfile* partProfile = profileStore.getProfile (label->entry);
+ const rtengine::procparams::PartialProfile* partProfile = ProfileStore::getInstance()->getProfile (label->entry);
if (partProfile->pparams && !selected.empty()) {
if (bppcl) {
@@ -1376,7 +1376,7 @@ void FileBrowser::applyPartialMenuItemActivated (ProfileStoreLabel *label)
}
}
- const rtengine::procparams::PartialProfile* srcProfiles = profileStore.getProfile (label->entry);
+ const rtengine::procparams::PartialProfile* srcProfiles = ProfileStore::getInstance()->getProfile (label->entry);
if (srcProfiles->pparams) {
@@ -1982,7 +1982,7 @@ void FileBrowser::updateProfileList ()
// submenu applmenu
int p = 0;
- const std::vector *profEntries = profileStore.getFileList(); // lock and get a pointer to the profiles' list
+ const std::vector *profEntries = ProfileStore::getInstance()->getFileList(); // lock and get a pointer to the profiles' list
std::map subMenuList; // store the Gtk::Menu that Gtk::MenuItem will have to be attached to
@@ -2067,7 +2067,7 @@ void FileBrowser::updateProfileList ()
applypartprof->set_submenu (*(subMenuList.at(0)));
}
- profileStore.releaseFileList();
+ ProfileStore::getInstance()->releaseFileList();
subMenuList.clear();
}
diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h
index faede2d8c..4bad832eb 100644
--- a/rtgui/filebrowser.h
+++ b/rtgui/filebrowser.h
@@ -29,7 +29,7 @@
#include "partialpastedlg.h"
#include "exportpanel.h"
#include "extprog.h"
-#include "profilestore.h"
+#include "profilestorecombobox.h"
class ProfileStoreLabel;
class FileBrowser;
diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc
index 8e4ae3613..91284e983 100644
--- a/rtgui/guiutils.cc
+++ b/rtgui/guiutils.cc
@@ -45,12 +45,6 @@ IdleRegister::~IdleRegister()
void IdleRegister::add(GSourceFunc function, gpointer data, gint priority)
{
- struct DataWrapper {
- IdleRegister* const self;
- GSourceFunc function;
- gpointer data;
- };
-
const auto dispatch = [](gpointer data) -> gboolean {
DataWrapper* const data_wrapper = static_cast(data);
@@ -80,9 +74,11 @@ void IdleRegister::add(GSourceFunc function, gpointer data, gint priority)
void IdleRegister::destroy()
{
mutex.lock();
- for (const auto id : ids) {
+ for (const auto& id : ids) {
g_source_remove(id.second);
+ delete id.first;
}
+ ids.clear();
mutex.unlock();
}
diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h
index b2ebaa80a..a6ec916f0 100644
--- a/rtgui/guiutils.h
+++ b/rtgui/guiutils.h
@@ -54,7 +54,13 @@ public:
void destroy();
private:
- std::map ids;
+ struct DataWrapper {
+ IdleRegister* const self;
+ GSourceFunc function;
+ gpointer data;
+ };
+
+ std::map ids;
MyMutex mutex;
};
diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc
index 3a601e18e..91dfc9204 100644
--- a/rtgui/main-cli.cc
+++ b/rtgui/main-cli.cc
@@ -49,6 +49,9 @@
#include "conio.h"
#endif
+// Set this to 1 to make RT work when started with Eclipse and arguments, at least on Windows platform
+#define ECLIPSE_ARGS 0
+
extern Options options;
// stores path to data files
@@ -175,7 +178,11 @@ int main(int argc, char **argv)
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
if (argc > 1 || options.rtSettings.verbose) {
- if (options.rtSettings.verbose || ( !Glib::file_test (fname_to_utf8 (argv[1]), Glib::FILE_TEST_EXISTS ) && !Glib::file_test (fname_to_utf8 (argv[1]), Glib::FILE_TEST_IS_DIR))) {
+ Glib::ustring fname(fname_to_utf8 (argv[1]));
+#if ECLIPSE_ARGS
+ fname = fname.substr(1, fname.length()-2);
+#endif
+ if (options.rtSettings.verbose || ( !Glib::file_test (fname, Glib::FILE_TEST_EXISTS ) && !Glib::file_test (fname, Glib::FILE_TEST_IS_DIR))) {
bool stdoutRedirectedtoFile = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == 0x0001);
bool stderrRedirectedtoFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == 0x0001);
@@ -191,8 +198,7 @@ int main(int argc, char **argv)
break;
}
- if(Console) {
- AllocConsole();
+ if(Console && AllocConsole()) {
AttachConsole( GetCurrentProcessId() ) ;
// Don't allow CTRL-C in console to terminate RT
SetConsoleCtrlHandler( NULL, true );
@@ -268,8 +274,12 @@ void deleteProcParams(std::vector &pparam
bool dontLoadCache( int argc, char **argv )
{
- for( int iArg = 1; iArg < argc; iArg++) {
- if( argv[iArg][0] == '-' && argv[iArg][1] == 'q' ) {
+ for (int iArg = 1; iArg < argc; iArg++) {
+ Glib::ustring currParam(argv[iArg]);
+#if ECLIPSE_ARGS
+ currParam = currParam.substr(1, currParam.length()-2);
+#endif
+ if( currParam.at(0) == '-' && currParam.at(1) == 'q' ) {
return true;
}
}
@@ -288,6 +298,7 @@ int processLineParams( int argc, char **argv )
bool sideProcParams = false;
bool copyParamsFile = false;
bool skipIfNoSidecar = false;
+ bool allExtensions = false;
bool useDefault = false;
unsigned int sideCarFilePos = 0;
int compression = 92;
@@ -297,16 +308,22 @@ int processLineParams( int argc, char **argv )
unsigned errors = 0;
for( int iArg = 1; iArg < argc; iArg++) {
- if( argv[iArg][0] == '-' ) {
- switch( argv[iArg][1] ) {
+ Glib::ustring currParam(argv[iArg]);
+#if ECLIPSE_ARGS
+ currParam = currParam.substr(1, currParam.length()-2);
+#endif
+ if( currParam.at(0) == '-' ) {
+ switch( currParam.at(1) ) {
case 'O':
copyParamsFile = true;
case 'o': // outputfile or dir
if( iArg + 1 < argc ) {
iArg++;
- outputPath = fname_to_utf8 (argv[iArg]);
-
+ outputPath = Glib::ustring(fname_to_utf8(argv[iArg]));
+#if ECLIPSE_ARGS
+ outputPath = outputPath.substr(1, outputPath.length()-2);
+#endif
if( Glib::file_test (outputPath, Glib::FILE_TEST_IS_DIR)) {
outputDirectory = true;
}
@@ -319,7 +336,10 @@ int processLineParams( int argc, char **argv )
// RT stop if any of them can't be loaded for any reason.
if( iArg + 1 < argc ) {
iArg++;
- Glib::ustring fname = fname_to_utf8 (argv[iArg]);
+ Glib::ustring fname(fname_to_utf8(argv[iArg]));
+#if ECLIPSE_ARGS
+ fname = fname.substr(1, fname.length()-2);
+#endif
if (fname.at(0) == '-') {
std::cerr << "Error: filename missing next to the -p switch" << std::endl;
@@ -359,16 +379,20 @@ int processLineParams( int argc, char **argv )
overwriteFiles = true;
break;
+ case 'a':
+ allExtensions = true;
+ break;
+
case 'j':
- if (strlen(argv[iArg]) > 2 && argv[iArg][2] == 's') {
- if (strlen(argv[iArg]) == 3) {
+ if (currParam.length() > 2 && currParam.at(2) == 's') {
+ if (currParam.length() == 3) {
std::cerr << "Error: the -js switch requires a mandatory value!" << std::endl;
deleteProcParams(processingParams);
return -3;
}
// looking for the subsampling parameter
- sscanf(&argv[iArg][3], "%d", &subsampling);
+ subsampling = atoi(currParam.substr(3).c_str());
if (subsampling < 1 || subsampling > 3) {
std::cerr << "Error: the value accompanying the -js switch has to be in the [1-3] range!" << std::endl;
@@ -377,7 +401,7 @@ int processLineParams( int argc, char **argv )
}
} else {
outputType = "jpg";
- sscanf(&argv[iArg][2], "%d", &compression);
+ compression = atoi(currParam.substr(2).c_str());
if (compression < 0 || compression > 100) {
std::cerr << "Error: the value accompanying the -j switch has to be in the [0-100] range!" << std::endl;
@@ -389,7 +413,7 @@ int processLineParams( int argc, char **argv )
break;
case 'b':
- sscanf(&argv[iArg][2], "%d", &bits);
+ bits = atoi(currParam.substr(2).c_str());
if (bits != 8 && bits != 16) {
std::cerr << "Error: specify -b8 for 8-bit or -b16 for 16-bit output." << std::endl;
@@ -401,7 +425,7 @@ int processLineParams( int argc, char **argv )
case 't':
outputType = "tif";
- compression = ((argv[iArg][2] != 'z') ? 0 : 1);
+ compression = ((currParam.at(2) != 'z') ? 0 : 1);
break;
case 'n':
@@ -412,16 +436,35 @@ int processLineParams( int argc, char **argv )
case 'f':
fast_export = true;
break;
-
+
case 'c': // MUST be last option
while (iArg + 1 < argc) {
iArg++;
+ Glib::ustring argument(fname_to_utf8(argv[iArg]));
+#if ECLIPSE_ARGS
+ argument = argument.substr(1, argument.length()-2);
+#endif
- const auto argument = fname_to_utf8 (argv[iArg]);
+ if (!Glib::file_test (argument, Glib::FILE_TEST_EXISTS)) {
+ std::cout << "\"" << argument << "\" doesn't exist !" << std::endl;
+ continue;
+ }
if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) {
- inputFiles.emplace_back (argument);
+ bool notAll = allExtensions && !options.is_parse_extention (argument);
+ bool notRetained = !allExtensions && !options.has_retained_extention (argument);
+ if (notAll || notRetained) {
+ if (notAll) {
+ std::cout << "\"" << argument << "\" is not one of the file format to process: skipped" << std::endl;
+ } else if (notRetained) {
+ std::cout << "\"" << argument << "\" is not one of the retained file format to process: skipped" << std::endl;
+ }
+ }
+ else {
+ inputFiles.emplace_back (argument);
+ }
continue;
+
}
if (Glib::file_test (argument, Glib::FILE_TEST_IS_DIR)) {
@@ -438,19 +481,28 @@ int processLineParams( int argc, char **argv )
while (auto file = enumerator->next_file ()) {
const auto fileName = Glib::build_filename (argument, file->get_name ());
+ bool isDir = Glib::file_test (fileName, Glib::FILE_TEST_IS_DIR);
+ bool notAll = allExtensions && !options.is_parse_extention (fileName);
+ bool notRetained = !allExtensions && !options.has_retained_extention (fileName);
- if (Glib::file_test (fileName, Glib::FILE_TEST_IS_DIR)) {
+ if (isDir || notAll || notRetained) {
+ if (isDir) {
+ std::cout << "\"" << fileName << "\" is a directory: skipped" << std::endl;
+ } else if (notAll) {
+ std::cout << "\"" << fileName << "\" is not one of the file format to process: skipped" << std::endl;
+ } else if (notRetained) {
+ std::cout << "\"" << fileName << "\" is not one of the retained file format to process: skipped" << std::endl;
+ }
continue;
+
}
- // skip files without extension and sidecar files
- auto lastdot = fileName.find_last_of('.');
- if (lastdot == Glib::ustring::npos) {
- continue;
- }
-
- if (fileName.substr (lastdot).compare (paramFileExtension) == 0) {
- continue;
+ if (sideProcParams && skipIfNoSidecar) {
+ // look for the sidecar proc params
+ if (!Glib::file_test(fileName + paramFileExtension, Glib::FILE_TEST_EXISTS)) {
+ std::cout << "\"" << fileName << "\" has no side-car file: image skipped" << std::endl;
+ continue;
+ }
}
inputFiles.emplace_back (fileName);
@@ -500,12 +552,16 @@ int processLineParams( int argc, char **argv )
std::cout << " " << Glib::path_get_basename(argv[0]) << " [-o