From 81f0135ec54f56d14112929b69cfc1db82ce421c Mon Sep 17 00:00:00 2001 From: Michael Ezra Date: Sun, 29 May 2011 08:23:09 -0400 Subject: [PATCH] New feature: Color Labels (issue 684) and porting rank and inTrash to pp3 --- rtdata/images/cglabel1.png | Bin 0 -> 2903 bytes rtdata/images/cglabel2.png | Bin 0 -> 2904 bytes rtdata/images/cglabel3.png | Bin 0 -> 2910 bytes rtdata/images/cglabel4.png | Bin 0 -> 2913 bytes rtdata/images/cglabel5.png | Bin 0 -> 2911 bytes rtdata/images/clabel1.png | Bin 0 -> 2839 bytes rtdata/images/clabel2.png | Bin 0 -> 2842 bytes rtdata/images/clabel3.png | Bin 0 -> 2843 bytes rtdata/images/clabel4.png | Bin 0 -> 2841 bytes rtdata/images/clabel5.png | Bin 0 -> 2843 bytes rtdata/images/filterclear.png | Bin 0 -> 3542 bytes rtdata/images/nocolorlabel.png | Bin 0 -> 2803 bytes rtdata/images/uncolorlabel.png | Bin 0 -> 3022 bytes rtdata/images/unrated.png | Bin 505 -> 3196 bytes rtdata/languages/default | 25 +++- rtengine/procparams.cc | 14 ++ rtengine/procparams.h | 3 + rtgui/batchqueue.cc | 29 ++-- rtgui/browserfilter.cc | 4 +- rtgui/browserfilter.h | 2 + rtgui/cacheimagedata.cc | 12 +- rtgui/cacheimagedata.h | 4 +- rtgui/filebrowser.cc | 69 +++++++++- rtgui/filebrowser.h | 2 + rtgui/filecatalog.cc | 235 +++++++++++++++++++++++--------- rtgui/filecatalog.h | 16 ++- rtgui/filethumbnailbuttonset.cc | 29 +++- rtgui/filethumbnailbuttonset.h | 8 ++ rtgui/thumbnail.cc | 89 ++++++++++-- rtgui/thumbnail.h | 13 +- 30 files changed, 434 insertions(+), 120 deletions(-) create mode 100644 rtdata/images/cglabel1.png create mode 100644 rtdata/images/cglabel2.png create mode 100644 rtdata/images/cglabel3.png create mode 100644 rtdata/images/cglabel4.png create mode 100644 rtdata/images/cglabel5.png create mode 100644 rtdata/images/clabel1.png create mode 100644 rtdata/images/clabel2.png create mode 100644 rtdata/images/clabel3.png create mode 100644 rtdata/images/clabel4.png create mode 100644 rtdata/images/clabel5.png create mode 100644 rtdata/images/filterclear.png create mode 100644 rtdata/images/nocolorlabel.png create mode 100644 rtdata/images/uncolorlabel.png diff --git a/rtdata/images/cglabel1.png b/rtdata/images/cglabel1.png new file mode 100644 index 0000000000000000000000000000000000000000..e1b20bd042463147cb511b444b7e9670d3505412 GIT binary patch literal 2903 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 BVL1Q* literal 0 HcmV?d00001 diff --git a/rtdata/images/cglabel2.png b/rtdata/images/cglabel2.png new file mode 100644 index 0000000000000000000000000000000000000000..c78a099365f3adad2b2ab5f36e42a894d4618062 GIT binary patch literal 2904 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 LNkvXXu0mjfJi%sA literal 0 HcmV?d00001 diff --git a/rtdata/images/cglabel5.png b/rtdata/images/cglabel5.png new file mode 100644 index 0000000000000000000000000000000000000000..12d1ed2025bd43b6b2deedf4694b1485dab4eb66 GIT binary patch literal 2911 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 JPDHLkV1kF;XcGVc literal 0 HcmV?d00001 diff --git a/rtdata/images/clabel1.png b/rtdata/images/clabel1.png new file mode 100644 index 0000000000000000000000000000000000000000..693a12d5ecfd0a036972b708586a4e242b1a6dc8 GIT binary patch literal 2839 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 literal 0 HcmV?d00001 diff --git a/rtdata/images/clabel3.png b/rtdata/images/clabel3.png new file mode 100644 index 0000000000000000000000000000000000000000..9081446369368a0ee1bc33a7657ba11db5bd7e68 GIT binary patch literal 2843 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 literal 0 HcmV?d00001 diff --git a/rtdata/images/clabel4.png b/rtdata/images/clabel4.png new file mode 100644 index 0000000000000000000000000000000000000000..7f5e87785e675c62ff16ec209eb0105e3a1ebe32 GIT binary patch literal 2841 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 literal 0 HcmV?d00001 diff --git a/rtdata/images/clabel5.png b/rtdata/images/clabel5.png new file mode 100644 index 0000000000000000000000000000000000000000..44e4f5acb69155c680e4c23b525cf70274b84e88 GIT binary patch literal 2843 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 taUq+#V4u*Y00009a7bBm000XU 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 FV1gZ1GgSZp literal 0 HcmV?d00001 diff --git a/rtdata/images/uncolorlabel.png b/rtdata/images/uncolorlabel.png new file mode 100644 index 0000000000000000000000000000000000000000..44b4021a9cf8a875ecd6c4e1a4bb4e827797be5c GIT binary patch literal 3022 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 JPDHLkV1l@y)R+JO delta 459 zcmV;+0W|*n82JN`IDY^jV@Og>004&y004{)00AET003vA002H%00Brx000h50000A zoVJ}+0004hNkl3 zkxn3%PGF?mIjvjmkTzAxWSw&4$PQOcoUVzA)I>)kHPNxtHBolB>br8}pk%TRB$4g# zk6Z9CGw9!YC?4{@c<5#ZeY+Ms%yv|alZ5vyspf+-@1w@YhNsBN!DmMQ5C9@OzFv2_ z`MKDc?Kw+&G=I_?7`{w3K9VWs<1tBE}*1KY(vY_ z+fw)KVj)O}yG=uU0f6+Tcwxw=>RB`3yYcM54ge48#chmI^pF4m002ovPDHLkV1n5d B*LVN` diff --git a/rtdata/languages/default b/rtdata/languages/default index 28d489348..799de3535 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -83,17 +83,24 @@ FILEBROWSER_NEW_NAME;New name: FILEBROWSER_PARTIALPASTEPROFILE;Partial paste FILEBROWSER_PASTEPROFILE;Paste profile FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPCOLORLABEL;Color label +FILEBROWSER_POPUPCOLORLABEL0;Label: None +FILEBROWSER_POPUPCOLORLABEL1;Label: Red +FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +FILEBROWSER_POPUPCOLORLABEL3;Label: Green +FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +FILEBROWSER_POPUPCOLORLABEL5;Label: Purple FILEBROWSER_POPUPCOPYTO;Copy to... FILEBROWSER_POPUPMOVEEND;Move to end of queue FILEBROWSER_POPUPMOVEHEAD;Move to head of queue FILEBROWSER_POPUPMOVETO;Move to... FILEBROWSER_POPUPOPEN;Open FILEBROWSER_POPUPPROCESS;Put to processing queue -FILEBROWSER_POPUPRANK1;Rank 1 -FILEBROWSER_POPUPRANK2;Rank 2 -FILEBROWSER_POPUPRANK3;Rank 3 -FILEBROWSER_POPUPRANK4;Rank 4 -FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPRANK1;Rank 1 * +FILEBROWSER_POPUPRANK2;Rank 2 ** +FILEBROWSER_POPUPRANK3;Rank 3 *** +FILEBROWSER_POPUPRANK4;Rank 4 **** +FILEBROWSER_POPUPRANK5;Rank 5 ***** FILEBROWSER_POPUPREMOVE;Remove from filesystem FILEBROWSER_POPUPREMOVEINCLPROC;Remove from filesystem & batch result FILEBROWSER_POPUPREMOVESUBMENU;Remove @@ -108,7 +115,12 @@ FILEBROWSER_RENAMEDLGLABEL;Rename file FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: FILEBROWSER_SELECTDARKFRAME;Select dark frame... FILEBROWSER_SELECTFLATFIELD;Select flat field... -FILEBROWSER_SHOWDIRHINT;Show all images of the directory D +FILEBROWSER_SHOWCOLORLABEL1HINT;Show images labeled Red Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Show images labeled Yelow Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Show images labeled Green Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple Alt-5 +FILEBROWSER_SHOWDIRHINT;Show all images in the directory (clear all filters) D FILEBROWSER_SHOWEXIFINFO;Show EXIF info i FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star 1 @@ -117,6 +129,7 @@ FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star 3 FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star 4 FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star 5 FILEBROWSER_SHOWTRASHHINT;Show content of the trash T +FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label Alt-` FILEBROWSER_SHOWUNRANKHINT;Show unranked images ` FILEBROWSER_STARTPROCESSING;Start processing FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 4043cd976..c224183e9 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -254,6 +254,10 @@ void ProcParams::setDefaults () { exif.clear (); iptc.clear (); + + rank = 0; + colorlabel = 0; + inTrash = false; ppVersion = PPVERSION; } @@ -265,6 +269,10 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_string ("Version", "AppVersion", APPVERSION); keyFile.set_integer ("Version", "Version", PPVERSION); + keyFile.set_integer ("General", "Rank", rank); + keyFile.set_integer ("General", "ColorLabel", colorlabel); + keyFile.set_boolean ("General", "InTrash", inTrash); + // save tonecurve: keyFile.set_boolean ("Exposure", "Auto", toneCurve.autoexp); keyFile.set_double ("Exposure", "Clip", toneCurve.clip); @@ -535,6 +543,12 @@ if (keyFile.has_group ("Version")) { if (keyFile.has_key ("Version", "Version")) ppVersion = keyFile.get_integer ("Version", "Version"); } +if (keyFile.has_group ("General")) { + if (keyFile.has_key ("General", "Rank")) rank = keyFile.get_integer ("General", "Rank"); + if (keyFile.has_key ("General", "ColorLabel")) colorlabel = keyFile.get_integer ("General", "ColorLabel"); + if (keyFile.has_key ("General", "InTrash")) inTrash = keyFile.get_boolean ("General", "InTrash"); +} + if (keyFile.has_group ("Exposure")) { if (keyFile.has_key ("Exposure", "Auto")) toneCurve.autoexp = keyFile.get_boolean ("Exposure", "Auto"); if (keyFile.has_key ("Exposure", "Clip")) toneCurve.clip = keyFile.get_double ("Exposure", "Clip"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 155c0b92a..aa68c7dc3 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -466,6 +466,9 @@ class ProcParams { HSVEqualizerParams hsvequalizer; ///< hsv equalizer parameters std::vector exif; ///< List of modifications appplied on the exif tags of the input image std::vector iptc; ///< The IPTC tags and values to be saved to the output image + char rank; ///< Custom image quality ranking + char colorlabel; ///< Custom color label + bool inTrash; ///< Marks deleted image Glib::ustring appVersion; ///< Version of the application that generated the parameters int ppVersion; ///< Version of the PP file from which the parameters have been read diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 640eacb9b..0069b24a8 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -497,23 +497,22 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam } else if (options.savePathTemplate[ix]=='f') { path = path + filename; - } - else if (options.savePathTemplate[ix]=='r') { - CacheImageData cid; - char rank; - - if (cid.load(cacheMgr->getCacheFileName("data", origFileName, CacheManager::getMD5(origFileName))+".txt") == 1) { - rank = '0'; - } else { - if (!cid.inTrash) - rank = cid.rank + '0'; - else - rank = 'x'; - } - - path += rank; + } + else if (options.savePathTemplate[ix]=='r') { // rank from pparams + char rank; + rtengine::procparams::ProcParams pparams; + if( pparams.load(origFileName + paramFileExtension)==0 ){ + if (!pparams.inTrash) + rank = pparams.rank + '0'; + else + rank = 'x'; + } + else + rank = '0'; // if param file not loaded (e.g. does not exist), default to rank=0 + path += rank; } } + else path = path + options.savePathTemplate[ix]; ix++; diff --git a/rtgui/browserfilter.cc b/rtgui/browserfilter.cc index c39e40e5e..ac85a92f3 100644 --- a/rtgui/browserfilter.cc +++ b/rtgui/browserfilter.cc @@ -21,6 +21,8 @@ BrowserFilter::BrowserFilter () : exifFilterEnabled (false) { showTrash = true; - for (int i=0; i<6; i++) + for (int i=0; i<6; i++){ showRanked[i] = true; + showCLabeled[i] = true; + } } diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h index 61a9d5684..7106ce374 100644 --- a/rtgui/browserfilter.h +++ b/rtgui/browserfilter.h @@ -25,8 +25,10 @@ class BrowserFilter { public: bool showRanked[6]; + bool showCLabeled[6]; bool showTrash; bool showNotTrash; + bool showEdited[2]; bool exifFilterEnabled; ExifFilterSettings exifFilter; diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index fdfbd2a04..6bd273bf3 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -24,7 +24,7 @@ #include "version.h" CacheImageData::CacheImageData () - : md5(""), supported(false), format(FT_Invalid), rank(0), inTrash(false), recentlySaved(false), + : md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false), timeValid(false), exifValid(false), thumbImgType(0) { } @@ -41,8 +41,8 @@ int CacheImageData::load (const Glib::ustring& fname) { if (keyFile.has_key ("General", "Version")) version = keyFile.get_string ("General", "Version"); if (keyFile.has_key ("General", "Supported")) supported = keyFile.get_boolean ("General", "Supported"); if (keyFile.has_key ("General", "Format")) format = (ThFileType)keyFile.get_integer ("General", "Format"); - if (keyFile.has_key ("General", "Rank")) rank = keyFile.get_integer ("General", "Rank"); - if (keyFile.has_key ("General", "InTrash")) inTrash = keyFile.get_boolean ("General", "InTrash"); + if (keyFile.has_key ("General", "Rank")) rankOld = keyFile.get_integer ("General", "Rank"); + if (keyFile.has_key ("General", "InTrash")) inTrashOld = keyFile.get_boolean ("General", "InTrash"); if (keyFile.has_key ("General", "RecentlySaved")) recentlySaved = keyFile.get_boolean ("General", "RecentlySaved"); } @@ -104,10 +104,12 @@ int CacheImageData::save (const Glib::ustring& fname) { keyFile.set_string ("General", "Version", VERSION); // Application's version keyFile.set_boolean ("General", "Supported", supported); keyFile.set_integer ("General", "Format", format); - keyFile.set_integer ("General", "Rank", rank); - keyFile.set_boolean ("General", "InTrash", inTrash); keyFile.set_boolean ("General", "RecentlySaved", recentlySaved); + // remove the old implementation of Rank and InTrash from cache + if (keyFile.has_key ("General", "Rank")) keyFile.remove_key("General", "Rank"); + if (keyFile.has_key ("General", "InTrash")) keyFile.remove_key("General", "InTrash"); + if (timeValid) { keyFile.set_integer ("DateTime", "Year", year); keyFile.set_integer ("DateTime", "Month", month); diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index d27504a3b..3c24f973d 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -31,8 +31,8 @@ class CacheImageData { Glib::ustring version; bool supported; ThFileType format; - char rank; - bool inTrash; + char rankOld; // old implementation of rank + bool inTrashOld; // old implementation of inTrash bool recentlySaved; // time/date info diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 1171bf5b0..58aef36fa 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -53,6 +53,19 @@ FileBrowser::FileBrowser () pmenu->attach (*Gtk::manage(rank[3] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK3"))), 0, 1, p, p+1); p++; pmenu->attach (*Gtk::manage(rank[4] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK4"))), 0, 1, p, p+1); p++; pmenu->attach (*Gtk::manage(rank[5] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK5"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + + pmenu->attach (*Gtk::manage(colorlabel[0] = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPCOLORLABEL0"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(colorlabel[1] = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPCOLORLABEL1"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(colorlabel[2] = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPCOLORLABEL2"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(colorlabel[3] = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPCOLORLABEL3"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(colorlabel[4] = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPCOLORLABEL4"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(colorlabel[5] = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPCOLORLABEL5"))), 0, 1, p, p+1); p++; + + for (int i=1; i<=5; i++){//set color label images + colorlabel[i]->set_image(*Gtk::manage(new Gtk::Image (Glib::ustring::compose("%1%2%3%4",argv0,"/images/clabel",i,".png")))); + } + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; pmenu->attach (*Gtk::manage(trash = new Gtk::MenuItem (M("FILEBROWSER_POPUPTRASH"))), 0, 1, p, p+1); p++; pmenu->attach (*Gtk::manage(untrash = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNTRASH"))), 0, 1, p, p+1); p++; @@ -89,7 +102,10 @@ FileBrowser::FileBrowser () open->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), open)); for (int i=0; i<6; i++) - rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i])); + rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i])); + for (int i=0; i<6; i++) + colorlabel[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), colorlabel[i])); + trash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), trash)); untrash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), untrash)); develop->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), develop)); @@ -237,6 +253,7 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) { // add button set to the thumbbrowserentry entry->addButtonSet (new FileThumbnailButtonSet (entry)); entry->getThumbButtonSet()->setRank (entry->thumbnail->getRank()); + entry->getThumbButtonSet()->setColorLabel (entry->thumbnail->getColorLabel()); entry->getThumbButtonSet()->setInTrash (entry->thumbnail->getStage()==1); entry->getThumbButtonSet()->setButtonListener (this); entry->resize (getCurrentThumbSize()); @@ -340,7 +357,12 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) { if (m==rank[i]) { rankingRequested (mselected, i); return; - } + } + for (int i=0; i<6; i++) + if (m==colorlabel[i]) { + colorlabelRequested (mselected, i); + return; + } if (m==open) { std::vector entries; for (int i=0; i entry FileBrowserEntry* entry = (FileBrowserEntry*)entryb; // return false if basic filter settings are not satisfied - if (filter.showRanked[entry->thumbnail->getRank()]==false || (entry->thumbnail->getStage()==1 && !filter.showTrash) || (entry->thumbnail->getStage()==0 && !filter.showNotTrash)) + if (filter.showRanked[entry->thumbnail->getRank()]==false || filter.showCLabeled[entry->thumbnail->getColorLabel()]==false || (entry->thumbnail->getStage()==1 && !filter.showTrash) || (entry->thumbnail->getStage()==0 && !filter.showNotTrash)) return false; - + // check exif filter const CacheImageData* cfs = entry->thumbnail->getCacheImageData(); double tol = 0.01; @@ -662,11 +684,17 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) { // true -> entry void FileBrowser::toTrashRequested (std::vector tbe) { for (int i=0; ithumbnail->getStage()==1) + // try to load the last saved parameters from the cache or from the paramfile file + tbe[i]->thumbnail->createProcParamsForUpdate(); // this can execute customprofilebuilder to generate param file + + // no need to notify listeners as item goes to trash, likely to be deleted + + if (tbe[i]->thumbnail->getStage()==1) continue; tbe[i]->thumbnail->setStage (1); if (tbe[i]->getThumbButtonSet()) { tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + tbe[i]->getThumbButtonSet()->setColorLabel (tbe[i]->thumbnail->getColorLabel()); tbe[i]->getThumbButtonSet()->setInTrash (true); tbe[i]->thumbnail->updateCache(); // needed to save the rank to disk } @@ -678,11 +706,14 @@ void FileBrowser::toTrashRequested (std::vector tbe) { void FileBrowser::fromTrashRequested (std::vector tbe) { for (int i=0; ithumbnail->getStage()==0) continue; tbe[i]->thumbnail->setStage (0); if (tbe[i]->getThumbButtonSet()) { tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + tbe[i]->getThumbButtonSet()->setColorLabel (tbe[i]->thumbnail->getColorLabel()); tbe[i]->getThumbButtonSet()->setInTrash (false); tbe[i]->thumbnail->updateCache(); // needed to save the rank to disk } @@ -694,14 +725,40 @@ void FileBrowser::fromTrashRequested (std::vector tbe) { void FileBrowser::rankingRequested (std::vector tbe, int rank) { for (int i=0; ithumbnail->createProcParamsForUpdate(); // this can execute customprofilebuilder to generate param file + + // notify listeners TODO: should do this ONLY when params changed by customprofilebuilder? + tbe[i]->thumbnail->notifylisterners_procParamsChanged(FILEBROWSER); + tbe[i]->thumbnail->setRank (rank); tbe[i]->thumbnail->updateCache(); // needed to save the rank to disk + //TODO? - should update pparams instead? + if (tbe[i]->getThumbButtonSet()) tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); } applyFilter (filter); } +void FileBrowser::colorlabelRequested (std::vector tbe, int colorlabel) { + + for (int i=0; ithumbnail->createProcParamsForUpdate(); // this can execute customprofilebuilder to generate param file + + // notify listeners TODO: should do this ONLY when params changed by customprofilebuilder? + tbe[i]->thumbnail->notifylisterners_procParamsChanged(FILEBROWSER); + + tbe[i]->thumbnail->setColorLabel (colorlabel); + tbe[i]->thumbnail->updateCache(); // needed to save the colorlabel to disk + //TODO? - should update pparams instead? + if (tbe[i]->getThumbButtonSet()) + tbe[i]->getThumbButtonSet()->setColorLabel (tbe[i]->thumbnail->getColorLabel()); + } + applyFilter (filter); +} + void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionData) { if (actionCode>=0 && actionCode<=5) { // rank @@ -709,7 +766,7 @@ void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionD tbe.push_back ((FileBrowserEntry*)actionData); rankingRequested (tbe, actionCode); } - else if (actionCode==6 && tbl) { // to processin queue + else if (actionCode==6 && tbl) { // to processing queue std::vector tbe; tbe.push_back ((FileBrowserEntry*)actionData); tbl->developRequested (tbe); diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index ae683be10..389f2612f 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -53,6 +53,7 @@ class FileBrowser : public ThumbBrowserBase, public LWButtonListener { protected: Gtk::MenuItem* rank[6]; + Gtk::ImageMenuItem* colorlabel[6]; Gtk::MenuItem* trash; Gtk::MenuItem* untrash; Gtk::MenuItem* develop; @@ -95,6 +96,7 @@ class FileBrowser : public ThumbBrowserBase, public LWButtonListener { void toTrashRequested (std::vector tbe); void fromTrashRequested (std::vector tbe); void rankingRequested (std::vector tbe, int rank); + void colorlabelRequested (std::vector tbe, int colorlabel); void notifySelectionListener (); type_trash_changed m_trash_changed; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index c77395d59..f5746a7a7 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -87,23 +87,27 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : buttonBar->pack_start (*tbLeftPanel_1, Gtk::PACK_SHRINK); buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK); - bDir = Gtk::manage( new Gtk::ToggleButton () ); - bDir->set_active (true); - bDir->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/folder_bw.png"))); - bDir->set_relief (Gtk::RELIEF_NONE); - bDir->set_tooltip_markup (M("FILEBROWSER_SHOWDIRHINT")); - bDir->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); - bCateg[0] = bDir->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bDir)); - buttonBar->pack_start (*bDir, Gtk::PACK_SHRINK); + bFilterClear = Gtk::manage(new Gtk::ToggleButton ()); + bFilterClear->set_active (true); + bFilterClear->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/filterclear.png"))); + bFilterClear->set_relief (Gtk::RELIEF_NONE); + bFilterClear->set_tooltip_markup (M("FILEBROWSER_SHOWDIRHINT")); + bFilterClear->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + bCateg[0] = bFilterClear->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bFilterClear)); + buttonBar->pack_start (*bFilterClear, Gtk::PACK_SHRINK); buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); + fltrVbox1 = Gtk::manage (new Gtk::VBox()); + fltrRankbox = Gtk::manage (new Gtk::HBox()); + fltrLabelbox = Gtk::manage (new Gtk::HBox()); + bUnRanked = Gtk::manage( new Gtk::ToggleButton () ); bUnRanked->set_active (false); bUnRanked->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/unrated.png"))); bUnRanked->set_relief (Gtk::RELIEF_NONE); bUnRanked->set_tooltip_markup (M("FILEBROWSER_SHOWUNRANKHINT")); bCateg[1] = bUnRanked->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bUnRanked)); - buttonBar->pack_start (*bUnRanked, Gtk::PACK_SHRINK); + fltrRankbox->pack_start (*bUnRanked, Gtk::PACK_SHRINK); bUnRanked->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); for (int i=0; i<5; i++) { @@ -114,15 +118,49 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bRank[i] = Gtk::manage( new Gtk::ToggleButton () ); bRank[i]->set_image (*igranked[i]); bRank[i]->set_relief (Gtk::RELIEF_NONE); - buttonBar->pack_start (*bRank[i], Gtk::PACK_SHRINK); + fltrRankbox->pack_start (*bRank[i], Gtk::PACK_SHRINK); bCateg[i+2] = bRank[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bRank[i])); bRank[i]->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); } + + bUnCLabeled = Gtk::manage(new Gtk::ToggleButton ()); + bUnCLabeled->set_active (false); + bUnCLabeled->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/uncolorlabel.png"))); + bUnCLabeled->set_relief (Gtk::RELIEF_NONE); + bUnCLabeled->set_tooltip_markup (M("FILEBROWSER_SHOWUNCOLORHINT")); + bCateg[7] = bUnCLabeled->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bUnCLabeled)); + fltrLabelbox->pack_start (*bUnCLabeled, Gtk::PACK_SHRINK); + bUnCLabeled->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + + for (int i=0; i<5; i++) { + iCLabeled[i] = new Gtk::Image (Glib::ustring::compose("%1%2%3%4",argv0,"/images/clabel",i+1,".png")); + igCLabeled[i] = new Gtk::Image (Glib::ustring::compose("%1%2%3%4",argv0,"/images/cglabel",i+1,".png")); + iCLabeled[i]->show (); + igCLabeled[i]->show (); + bCLabel[i] = Gtk::manage(new Gtk::ToggleButton ()); + bCLabel[i]->set_image (*igCLabeled[i]); + bCLabel[i]->set_relief (Gtk::RELIEF_NONE); + fltrLabelbox->pack_start (*bCLabel[i], Gtk::PACK_SHRINK); + bCateg[i+8] = bCLabel[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bCLabel[i])); + bCLabel[i]->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + } + + fltrVbox1->pack_start (*fltrRankbox, Gtk::PACK_SHRINK,0); + fltrVbox1->pack_start (*fltrLabelbox, Gtk::PACK_SHRINK,0); + buttonBar->pack_start (*fltrVbox1, Gtk::PACK_SHRINK); + bRank[0]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK1HINT")); bRank[1]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK2HINT")); bRank[2]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK3HINT")); bRank[3]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK4HINT")); bRank[4]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK5HINT")); + + bCLabel[0]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL1HINT")); + bCLabel[1]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL2HINT")); + bCLabel[2]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL3HINT")); + bCLabel[3]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL4HINT")); + bCLabel[4]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL5HINT")); + buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); iTrashEmpty = new Gtk::Image(argv0+"/images/trash-show-empty.png") ; @@ -131,18 +169,33 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bTrash = Gtk::manage( new Gtk::ToggleButton () ); bTrash->set_image (*iTrashEmpty); bTrash->set_relief (Gtk::RELIEF_NONE); - bTrash->set_tooltip_markup (M("FILEBROWSER_SHOWTRASHHINT")); - bCateg[7] = bTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bTrash)); + bTrash->set_tooltip_markup (M("FILEBROWSER_SHOWTRASHHINT")); + bCateg[13] = bTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bTrash)); bTrash->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); buttonBar->pack_start (*bTrash, Gtk::PACK_SHRINK); buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); fileBrowser->trash_changed().connect( sigc::mem_fun(*this, &FileCatalog::trashChanged) ); - categoryButtons[0] = bDir; + // 0 - bFilterClear + // 1 - bUnRanked + // 2 - bRank[0] + // 3 - bRank[1] + // 4 - bRank[2] + // 5 - bRank[3] + // 6 - bRank[4] + // 7 - bUnCLabeled + // 8 - bCLabel[0] + // 9 - bCLabel[1] + // 10 - bCLabel[2] + // 11 - bCLabel[3] + // 12 - bCLabel[4] + // 13 - bTrash + categoryButtons[0] = bFilterClear; categoryButtons[1] = bUnRanked; - for (int i=0; i<5; i++) - categoryButtons[i+2] = bRank[i]; - categoryButtons[7] = bTrash; + for (int i=0; i<5; i++){ categoryButtons[i+2] = bRank[i];} + categoryButtons[7] = bUnCLabeled; + for (int i=0; i<5; i++){ categoryButtons[i+8] = bCLabel[i];} + categoryButtons[13] = bTrash; exifInfo = Gtk::manage(new Gtk::ToggleButton ()); exifInfo->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/info.png"))); @@ -214,7 +267,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : enabled = true; lastScrollPos = 0; - for (int i=0; i<8; i++) { + for (int i=0; i<14; i++) { hScrollPos[i] = 0; vScrollPos[i] = 0; } @@ -225,11 +278,12 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : #endif } -FileCatalog::~FileCatalog() -{ - for (int i=0; i<5; i++) { - delete iranked[i]; +FileCatalog::~FileCatalog(){ + for (int i=0; i<5; i++) { + delete iranked[i]; delete igranked[i]; + delete iCLabeled[i]; + delete igCLabeled[i]; } delete iTrashEmpty; delete iTrashFull; @@ -799,7 +853,7 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { //was shift key pressed bool shift_down = modifierKey & GDK_SHIFT_MASK; - for (int i=0; i<8; i++) + for (int i=0; i<14; i++) bCateg[i].block (true); //button is already toggled when entering this function, so we switch it back to its initial state @@ -813,9 +867,9 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { //we look how many stars are already toggled on, if any int toggled_stars_count=0, buttons=0, start_star=0, toggled_button=0; - for (int i=0; i<8; i++) { + for (int i=0; i<14; i++) { if (categoryButtons[i]->get_active()) { - if (i>0 && i<7) { + if (i>0 && i<13) { toggled_stars_count ++; start_star = i; } @@ -826,12 +880,12 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { //if no modifier key were pressed, we can switch-on the button, and clear all others if (!(control_down || shift_down)) { - for (int i=0; i<8; i++) { + for (int i=0; i<14; i++) { categoryButtons[i]->set_active (i==toggled_button); } } - //modifier key allowed only for stars - else if (toggled_button>0 && toggled_button<7) { + //modifier key allowed only for stars and color labels + else if (toggled_button>0 && toggled_button<13) { if (control_down) { //control is pressed if (toggled_stars_count == 1 && (buttons & (1 << toggled_button))) { @@ -848,17 +902,18 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { //no star selected //we deselect the 2 non star filters if (buttons & 1 ) categoryButtons[0]->set_active(false); - if (buttons & (1 << 7)) categoryButtons[7]->set_active(false); + if (buttons & (1 << 13)) categoryButtons[13]->set_active(false); //and we toggle on the star categoryButtons[toggled_button]->set_active (true); } } else { - //shift is pressed, only allowed if 0 or 1 star is selected + //shift is pressed, only allowed if 0 or 1 star & labels is selected if (!toggled_stars_count) { //we deselect the 2 non star filters if (buttons & 1 ) categoryButtons[0]->set_active(false); if (buttons & (1 << 7)) categoryButtons[7]->set_active(false); + if (buttons & (1 << 13)) categoryButtons[13]->set_active(false); //!!! verify if (1 << 13) is correct? //and we set the start star to 1 (unrated images) start_star = 1; //we act as if one star were selected @@ -873,11 +928,11 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { if (!(buttons & (1 << current_star))) categoryButtons[current_star]->set_active(true); } } - //if more than one star selected, do nothing + //if more than one star & color label is selected, do nothing } } - //so set the right images + // set the right images for (int i=0; i<5; i++) { bool active_now, active_before; active_now = bRank[i]->get_active(); @@ -886,6 +941,16 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { else if (!active_now && active_before) bRank[i]->set_image (*igranked[i]); } + + // set the right images + for (int i=0; i<5; i++) { + bool active_now, active_before; + active_now = bCLabel[i]->get_active(); + active_before = buttons & (1 << (i+8)); + if ( active_now && !active_before) bCLabel[i]->set_image (*iCLabeled[i]); + else if (!active_now && active_before) bCLabel[i]->set_image (*igCLabeled[i]); + } + fileBrowser->applyFilter (getFilter ()); _refreshProgressBar(); @@ -898,17 +963,40 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { fileBrowser->setScrollPosition (hScrollPos[lastScrollPos], vScrollPos[lastScrollPos]); } - for (int i=0; i<8; i++) + for (int i=0; i<14; i++) bCateg[i].block (false); } BrowserFilter FileCatalog::getFilter () { BrowserFilter filter; - filter.showRanked[0] = bDir->get_active() || bUnRanked->get_active () || bTrash->get_active (); + filter.showRanked[0] = bFilterClear->get_active() || bUnRanked->get_active () || bTrash->get_active () || \ + bUnCLabeled->get_active () || bCLabel[0]->get_active ()|| bCLabel[1]->get_active ()|| bCLabel[2]->get_active ()|| bCLabel[3]->get_active ()|| bCLabel[4]->get_active (); for (int i=1; i<=5; i++) - filter.showRanked[i] = bDir->get_active() || bRank[i-1]->get_active () || bTrash->get_active (); - filter.showTrash = bDir->get_active() || bTrash->get_active (); + filter.showRanked[i] = bFilterClear->get_active() || bRank[i-1]->get_active () || bTrash->get_active () || \ + bUnCLabeled->get_active () || bCLabel[0]->get_active ()|| bCLabel[1]->get_active ()|| bCLabel[2]->get_active ()|| bCLabel[3]->get_active ()|| bCLabel[4]->get_active (); + + filter.showCLabeled[0] = bFilterClear->get_active() || bUnCLabeled->get_active () || bTrash->get_active () || \ + bUnRanked->get_active () || bRank[0]->get_active () || bRank[1]->get_active () || bRank[2]->get_active () || bRank[3]->get_active () || bRank[4]->get_active (); + for (int i=1; i<=5; i++) + filter.showCLabeled[i] = bFilterClear->get_active() || bCLabel[i-1]->get_active () || bTrash->get_active () || \ + bUnRanked->get_active () || bRank[0]->get_active () || bRank[1]->get_active () || bRank[2]->get_active () || bRank[3]->get_active () || bRank[4]->get_active (); + + // handle AND logic between rank and color labels: + // only when both filters for rank and color labels are selected + if ((bUnCLabeled->get_active () || bCLabel[0]->get_active ()|| bCLabel[1]->get_active ()|| bCLabel[2]->get_active ()|| bCLabel[3]->get_active ()|| bCLabel[4]->get_active ()) \ + && (bUnRanked->get_active () || bRank[0]->get_active () || bRank[1]->get_active () || bRank[2]->get_active () || bRank[3]->get_active () || bRank[4]->get_active ()) ){ + + filter.showRanked[0] = bUnRanked->get_active (); + filter.showCLabeled[0] = bUnCLabeled->get_active (); + + for (int i=1; i<=5; i++){ + filter.showRanked[i] = bRank[i-1]->get_active (); + filter.showCLabeled[i] = bCLabel[i-1]->get_active (); + } + } + + filter.showTrash = bFilterClear->get_active() || bTrash->get_active (); filter.showNotTrash = !bTrash->get_active (); if (!filterPanel) filter.exifFilterEnabled = false; @@ -1210,37 +1298,62 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) { return true; } - switch(event->keyval) { - case GDK_1: - categoryButtonToggled(bRank[0]); - return true; - case GDK_2: - categoryButtonToggled(bRank[1]); - return true; - case GDK_3: - categoryButtonToggled(bRank[2]); - return true; - case GDK_4: - categoryButtonToggled(bRank[3]); - return true; - case GDK_5: - categoryButtonToggled(bRank[4]); - return true; - case GDK_grave: - categoryButtonToggled(bUnRanked); - return true; - - case GDK_Return: - case GDK_KP_Enter: - FileCatalog::buttonBrowsePathPressed (); - return true; + if (!alt) { + switch(event->keyval) { + case GDK_1: + categoryButtonToggled(bRank[0]); + return true; + case GDK_2: + categoryButtonToggled(bRank[1]); + return true; + case GDK_3: + categoryButtonToggled(bRank[2]); + return true; + case GDK_4: + categoryButtonToggled(bRank[3]); + return true; + case GDK_5: + categoryButtonToggled(bRank[4]); + return true; + case GDK_grave: + categoryButtonToggled(bUnRanked); + return true; + + case GDK_Return: + case GDK_KP_Enter: + FileCatalog::buttonBrowsePathPressed (); + return true; + } } - + + if (alt) { + switch(event->keyval) { + case GDK_1: + categoryButtonToggled(bCLabel[0]); + return true; + case GDK_2: + categoryButtonToggled(bCLabel[1]); + return true; + case GDK_3: + categoryButtonToggled(bCLabel[2]); + return true; + case GDK_4: + categoryButtonToggled(bCLabel[3]); + return true; + case GDK_5: + categoryButtonToggled(bCLabel[4]); + return true; + case GDK_grave: + categoryButtonToggled(bUnCLabeled); + return true; + } + } + if (!ctrl && !alt) { switch(event->keyval) { case GDK_d: case GDK_D: - categoryButtonToggled(bDir); + categoryButtonToggled(bFilterClear); return true; case GDK_t: case GDK_T: diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 11d2f3dde..36c90eb4a 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -73,16 +73,22 @@ class FileCatalog : public Gtk::VBox, Gtk::HBox* buttonBar; Gtk::HBox* buttonBar2; + Gtk::HBox* fltrRankbox; + Gtk::HBox* fltrLabelbox; + Gtk::VBox* fltrVbox1; Gtk::ToggleButton* tbLeftPanel_1; Gtk::ToggleButton* tbRightPanel_1; - Gtk::ToggleButton* bDir; + Gtk::ToggleButton* bFilterClear; Gtk::ToggleButton* bUnRanked; Gtk::ToggleButton* bRank[5]; + Gtk::ToggleButton* bUnCLabeled; + Gtk::ToggleButton* bCLabel[5];//color label Gtk::ToggleButton* bTrash; - Gtk::ToggleButton* categoryButtons[8]; + Gtk::ToggleButton* categoryButtons[14]; Gtk::ToggleButton* exifInfo; - sigc::connection bCateg[8]; + sigc::connection bCateg[14]; Gtk::Image* iranked[5], *igranked[5]; + Gtk::Image* iCLabeled[5], *igCLabeled[5]; Gtk::Image *iTrashEmpty, *iTrashFull; Gtk::Image *iRightArrow_red, *iRightArrow; Gtk::Image *iLeftPanel_1_Show, *iLeftPanel_1_Hide, *iRightPanel_1_Show, *iRightPanel_1_Hide; @@ -90,8 +96,8 @@ class FileCatalog : public Gtk::VBox, Gtk::Button* buttonBrowsePath; sigc::connection BrowsePathconn; - double hScrollPos[8]; - double vScrollPos[8]; + double hScrollPos[14]; + double vScrollPos[14]; int lastScrollPos; Gtk::VBox* trashButtonBox; diff --git a/rtgui/filethumbnailbuttonset.cc b/rtgui/filethumbnailbuttonset.cc index 78954cd3f..05a0c4a3b 100644 --- a/rtgui/filethumbnailbuttonset.cc +++ b/rtgui/filethumbnailbuttonset.cc @@ -30,6 +30,12 @@ Cairo::RefPtr FileThumbnailButtonSet::unRankIcon; Cairo::RefPtr FileThumbnailButtonSet::trashIcon; Cairo::RefPtr FileThumbnailButtonSet::unTrashIcon; Cairo::RefPtr FileThumbnailButtonSet::processIcon; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_0; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_1; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_2; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_3; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_4; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_5; FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) { @@ -40,6 +46,13 @@ FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) { trashIcon = safe_create_from_png (argv0+"/images/trash.png"); unTrashIcon = safe_create_from_png (argv0+"/images/undelete.png"); processIcon = safe_create_from_png (argv0+"/images/processing.png"); + + colorLabelIcon_0 = safe_create_from_png (argv0+"/images/nocolorlabel.png"); + colorLabelIcon_1 = safe_create_from_png (Glib::ustring::compose("%1%2%3%4",argv0,"/images/clabel",1,".png")); + colorLabelIcon_2 = safe_create_from_png (Glib::ustring::compose("%1%2%3%4",argv0,"/images/clabel",2,".png")); + colorLabelIcon_3 = safe_create_from_png (Glib::ustring::compose("%1%2%3%4",argv0,"/images/clabel",3,".png")); + colorLabelIcon_4 = safe_create_from_png (Glib::ustring::compose("%1%2%3%4",argv0,"/images/clabel",4,".png")); + colorLabelIcon_5 = safe_create_from_png (Glib::ustring::compose("%1%2%3%4",argv0,"/images/clabel",5,".png")); iconsLoaded = true; } @@ -49,6 +62,8 @@ FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) { add (new LWButton (rankIcon, i+1, myEntry, LWButton::Left)); add (new LWButton (trashIcon, 7, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPTRASH"))); + add (new LWButton (colorLabelIcon_0, 8, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPCOLORLABEL"))); + buttons[2]->setToolTip (M("FILEBROWSER_POPUPRANK1")); buttons[3]->setToolTip (M("FILEBROWSER_POPUPRANK2")); buttons[4]->setToolTip (M("FILEBROWSER_POPUPRANK3")); @@ -62,8 +77,18 @@ void FileThumbnailButtonSet::setRank (int stars) { buttons[i+1]->setIcon (i<=stars ? rankIcon : gRankIcon); } +void FileThumbnailButtonSet::setColorLabel (int colorLabel) { + + if (colorLabel==0) buttons[8]->setIcon (colorLabelIcon_0); //transparent label + if (colorLabel==1) buttons[8]->setIcon (colorLabelIcon_1); + if (colorLabel==2) buttons[8]->setIcon (colorLabelIcon_2); + if (colorLabel==3) buttons[8]->setIcon (colorLabelIcon_3); + if (colorLabel==4) buttons[8]->setIcon (colorLabelIcon_4); + if (colorLabel==5) buttons[8]->setIcon (colorLabelIcon_5); +} + void FileThumbnailButtonSet::setInTrash (bool inTrash) { - buttons[7]->setIcon (inTrash ? unTrashIcon : trashIcon); - buttons[7]->setToolTip (inTrash ? M("FILEBROWSER_POPUPUNTRASH") : M("FILEBROWSER_POPUPTRASH")); + buttons[7]->setIcon (inTrash ? unTrashIcon : trashIcon); + buttons[7]->setToolTip (inTrash ? M("FILEBROWSER_POPUPUNTRASH") : M("FILEBROWSER_POPUPTRASH")); } diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h index af377c7ba..7bd5ef817 100644 --- a/rtgui/filethumbnailbuttonset.h +++ b/rtgui/filethumbnailbuttonset.h @@ -35,9 +35,17 @@ class FileThumbnailButtonSet : public LWButtonSet { static Cairo::RefPtr trashIcon; static Cairo::RefPtr unTrashIcon; static Cairo::RefPtr processIcon; + + static Cairo::RefPtr colorLabelIcon_0; + static Cairo::RefPtr colorLabelIcon_1; + static Cairo::RefPtr colorLabelIcon_2; + static Cairo::RefPtr colorLabelIcon_3; + static Cairo::RefPtr colorLabelIcon_4; + static Cairo::RefPtr colorLabelIcon_5; FileThumbnailButtonSet (FileBrowserEntry* myEntry); void setRank (int stars); + void setColorLabel (int colorlabel); void setInTrash (bool inTrash); }; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 51d18a01f..f61496c45 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -42,7 +42,19 @@ Thumbnail::Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageDa loadProcParams (); _loadThumbnail (); generateExifDateTimeStrings (); - + + if (cfs.rankOld >= 0){ + // rank and inTrash were found in cache (old style), move them over to pparams + + // try to load the last saved parameters from the cache or from the paramfile file + createProcParamsForUpdate(); // this can execute customprofilebuilder to generate param file + + // TODO? should we call notifylisterners_procParamsChanged here? + + setRank(cfs.rankOld); + setStage(cfs.inTrashOld); + } + delete tpp; tpp = 0; } @@ -194,6 +206,11 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate() { return ldprof; } +void Thumbnail::notifylisterners_procParamsChanged(int whoChangedIt){ + for (int i=0; iprocParamsChanged (this, whoChangedIt); +} + void Thumbnail::loadProcParams () { // TODO: Check for Linux #ifdef WIN32 @@ -220,26 +237,62 @@ void Thumbnail::loadProcParams () { } void Thumbnail::clearProcParams (int whoClearedIt) { + +/* Clarification on current "clear profile" functionality: + a. if rank/colorlabel/inTrash are NOT set, + the "clear profile" will delete the pp3 file (as before). + + b. if any of the rank/colorlabel/inTrash ARE set, + the "clear profile" will lead to execution of ProcParams::setDefaults + (the CPB is NOT called) to set the params values and will preserve + rank/colorlabel/inTrash in the param file. */ + // TODO: Check for Linux #ifdef WIN32 Glib::Mutex::Lock lock(mutex); #endif + // preserve rank, colorlabel and inTrash across clear + int rank = getRank(); + int colorlabel = getColorLabel(); + int inTrash = getStage(); + + cfs.recentlySaved = false; pparamsValid = false; needsReProcessing = true; - // remove param file from cache - Glib::ustring fname_ = getCacheFileName ("profiles")+paramFileExtension; - if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) - safe_g_remove (fname_); - // remove param file located next to the file -// fname_ = removeExtension(fname) + paramFileExtension; - fname_ = fname + paramFileExtension; - if (safe_file_test(fname_, Glib::FILE_TEST_EXISTS)) - safe_g_remove (fname_); - fname_ = removeExtension(fname) + paramFileExtension; - if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) - safe_g_remove (fname_); + + //TODO: run though customprofilebuilder? + // probably not as this is the only option to set param values to default + + // reset the params to defaults + pparams.setDefaults(); + + // and restore rank and inTrash + setRank(rank); + setColorLabel(colorlabel); + setStage(inTrash); + + // params could get validated by rank/inTrash values restored above + if (pparamsValid) + { + updateCache(); + } + else + { + // remove param file from cache + Glib::ustring fname_ = getCacheFileName ("profiles")+paramFileExtension; + if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); + // remove param file located next to the file +// fname_ = removeExtension(fname) + paramFileExtension; + fname_ = fname + paramFileExtension; + if (safe_file_test(fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); + fname_ = removeExtension(fname) + paramFileExtension; + if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); + } for (int i=0; iprocParamsChanged (this, whoClearedIt); @@ -259,9 +312,19 @@ void Thumbnail::setProcParams (const ProcParams& pp, int whoChangedIt, bool upda if (pparams!=pp) cfs.recentlySaved = false; + // do not update rank, colorlabel and inTrash + int rank = getRank(); + int colorlabel = getColorLabel(); + int inTrash = getStage(); + pparams = pp; pparamsValid = true; needsReProcessing = true; + + setRank(rank); + setColorLabel(colorlabel); + setStage(inTrash); + if (updateCacheNow) updateCache (); diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 163b61618..38ba2d28b 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -87,6 +87,8 @@ class Thumbnail { void clearProcParams (int whoClearedIt=-1); void loadProcParams (); + void notifylisterners_procParamsChanged(int whoChangedIt); + bool isQuick() { return cfs.thumbImgType == CacheImageData::QUICK_THUMBNAIL; } bool isPParamsValid() { return pparamsValid; } bool isRecentlySaved (); @@ -117,11 +119,14 @@ class Thumbnail { const CacheImageData* getCacheImageData() { return &cfs; } std::string getMD5 () { return cfs.md5; } - int getRank () { return cfs.rank; } - void setRank (int rank) { cfs.rank = rank; } + int getRank () { return pparams.rank; } + void setRank (int rank) { if (pparams.rank != rank) { pparams.rank = rank; pparamsValid = true; } } - int getStage () { return cfs.inTrash; } - void setStage (int stage) { cfs.inTrash = stage; } + int getColorLabel () { return pparams.colorlabel; } + void setColorLabel (int colorlabel) { if (pparams.colorlabel != colorlabel) { pparams.colorlabel = colorlabel; pparamsValid = true; } } + + int getStage () { return pparams.inTrash; } + void setStage (int stage) { if (pparams.inTrash != stage) { pparams.inTrash = stage; pparamsValid = true; } } void addThumbnailListener (ThumbnailListener* tnl); void removeThumbnailListener (ThumbnailListener* tnl);