diff --git a/rtdata/languages/default b/rtdata/languages/default index 3bdbb137b..c39f0f78e 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -30,6 +30,7 @@ EDITWINDOW_TITLE;Image Edit EXIFFILTER_APERTURE;Aperture EXIFFILTER_CAMERA;Camera EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) EXIFFILTER_FILETYPE;File Type EXIFFILTER_FOCALLEN;Focal Length EXIFFILTER_ISO;ISO diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 1ed792cd8..ca326d926 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -338,15 +338,21 @@ std::string ImageMetaData::shutterToString (double shutter) { return buffer; } -std::string ImageMetaData::expcompToString (double expcomp) { +std::string ImageMetaData::expcompToString (double expcomp, bool maskZeroexpcomp) { char buffer[256]; - if (expcomp!=0.0){ - sprintf (buffer, "%0.1f", expcomp); + if (maskZeroexpcomp==true){ + if (expcomp!=0.0){ + sprintf (buffer, "%0.2f", expcomp); + return buffer; + } + else + return ""; + } + else{ + sprintf (buffer, "%0.2f", expcomp); return buffer; } - else - return ""; } double ImageMetaData::shutterFromString (std::string s) { diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 191175f6a..3ed12d967 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -93,7 +93,7 @@ namespace rtengine { /** Functions to convert between floating point and string representation of shutter and aperture */ static double shutterFromString (std::string shutter); /** Functions to convert between floating point and string representation of exposure compensation */ - static std::string expcompToString (double expcomp); + static std::string expcompToString (double expcomp, bool maskZeroexpcomp); /** Reads metadata from file. * @param fname is the name of the file diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 6bd273bf3..07540dcdc 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -69,6 +69,7 @@ int CacheImageData::load (const Glib::ustring& fname) { if (keyFile.has_key ("ExifInfo", "Shutter")) shutter = keyFile.get_double ("ExifInfo", "Shutter"); if (keyFile.has_key ("ExifInfo", "FocalLen")) focalLen = keyFile.get_double ("ExifInfo", "FocalLen"); if (keyFile.has_key ("ExifInfo", "ISO")) iso = keyFile.get_integer ("ExifInfo", "ISO"); + if (keyFile.has_key ("ExifInfo", "ExpComp")) expcomp = keyFile.get_string ("ExifInfo", "ExpComp"); } if (keyFile.has_key ("ExifInfo", "Lens")) lens = keyFile.get_string ("ExifInfo", "Lens"); if (keyFile.has_key ("ExifInfo", "Camera")) camera = keyFile.get_string ("ExifInfo", "Camera"); @@ -126,6 +127,7 @@ int CacheImageData::save (const Glib::ustring& fname) { keyFile.set_double ("ExifInfo", "Shutter", shutter); keyFile.set_double ("ExifInfo", "FocalLen", focalLen); keyFile.set_integer ("ExifInfo", "ISO", iso); + keyFile.set_string ("ExifInfo", "ExpComp", expcomp); } keyFile.set_string ("ExifInfo", "Lens", lens); keyFile.set_string ("ExifInfo", "Camera", camera); diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 3c24f973d..c89462f65 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -54,6 +54,7 @@ class CacheImageData { Glib::ustring lens; Glib::ustring camera; Glib::ustring filetype; + Glib::ustring expcomp; // additional info on raw images int rotate; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 7e69eae00..0159bdf6f 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -681,11 +681,11 @@ void EditorPanel::info_toggled () { M("QINFO_ISO"), idata->getISOSpeed(), idata->getFocalLen()); - expcomp = Glib::ustring(idata->expcompToString(idata->getExpComp())); + expcomp = Glib::ustring(idata->expcompToString(idata->getExpComp(),true)); // maskZeroexpcomp if (expcomp!=""){ infoString2 = Glib::ustring::compose("%1 %2EV", infoString2, - Glib::ustring(idata->expcompToString(idata->getExpComp()))); + expcomp /*Glib::ustring(idata->expcompToString(idata->getExpComp()))*/); } infoString3 = Glib::ustring::compose ("%1%2", diff --git a/rtgui/exiffiltersettings.cc b/rtgui/exiffiltersettings.cc index d519d0c1a..5033b5c86 100644 --- a/rtgui/exiffiltersettings.cc +++ b/rtgui/exiffiltersettings.cc @@ -34,12 +34,14 @@ void ExifFilterSettings::clear () { focalTo = 0; lenses.clear (); cameras.clear (); + expcomp.clear (); filetypes.clear (); filterFNumber = false; filterShutter = false; filterFocalLen = false; filterISO = false; + filterExpComp = false; filterCamera = false; filterLens = false; filterFiletype = false; diff --git a/rtgui/exiffiltersettings.h b/rtgui/exiffiltersettings.h index 9cd123663..da049df05 100644 --- a/rtgui/exiffiltersettings.h +++ b/rtgui/exiffiltersettings.h @@ -25,9 +25,10 @@ class ExifFilterSettings { public: - std::set filetypes; + std::set filetypes; std::set cameras; std::set lenses; + std::set expcomp; double fnumberFrom; double fnumberTo; double shutterFrom; @@ -41,6 +42,7 @@ class ExifFilterSettings { bool filterShutter; bool filterFocalLen; bool filterISO; + bool filterExpComp; bool filterCamera; bool filterLens; bool filterFiletype; diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 2a3987060..2f204d5af 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -824,16 +824,18 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) { // true -> entry if (!cfs->exifValid) return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0) && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0) - && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype)>0); - + && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype)>0) + && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp)>0); + return (!filter.exifFilter.filterShutter || (rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom-tol2 && rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo+tol2)) && (!filter.exifFilter.filterFNumber || (rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) >= filter.exifFilter.fnumberFrom-tol2 && rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) <= filter.exifFilter.fnumberTo+tol2)) && (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom-tol && cfs->focalLen <= filter.exifFilter.focalTo+tol)) && (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo)) + && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp)>0) && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0) && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0) - && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype)>0); + && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype)>0); } void FileBrowser::toTrashRequested (std::vector tbe) { diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 183043a5d..7ee06aee7 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -600,6 +600,7 @@ void FileCatalog::previewReadyUI (int dir_id, FileBrowserEntry* fdn) { dirEFS.filetypes.insert (cfs->filetype); dirEFS.cameras.insert (cfs->camera); dirEFS.lenses.insert (cfs->lens); + dirEFS.expcomp.insert (cfs->expcomp); previewsLoaded++; g_idle_add (refreshProgressBarUI, this); diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc index 57b768ab6..1f9e46fd0 100644 --- a/rtgui/filterpanel.cc +++ b/rtgui/filterpanel.cc @@ -78,6 +78,17 @@ FilterPanel::FilterPanel () : listener (NULL) { fvb->pack_start (*fhb, Gtk::PACK_SHRINK, 0); pack_start (*fvb, Gtk::PACK_SHRINK, 4); + enaExpComp = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_EXPOSURECOMPENSATION")+":")); + Gtk::VBox* evb = Gtk::manage(new Gtk::VBox ()); + evb->pack_start (*enaExpComp, Gtk::PACK_SHRINK, 0); + expcomp = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + expcomp->set_headers_visible (false); + Gtk::ScrolledWindow* sexpcomp = Gtk::manage(new Gtk::ScrolledWindow()); + sexpcomp->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + sexpcomp->add(*expcomp); + evb->pack_start (*sexpcomp, Gtk::PACK_SHRINK, 0); + pack_start (*evb, Gtk::PACK_SHRINK, 4); + enaCamera = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_CAMERA")+":")); Gtk::VBox* cvb = Gtk::manage(new Gtk::VBox ()); cvb->pack_start (*enaCamera, Gtk::PACK_SHRINK, 0); @@ -112,21 +123,23 @@ FilterPanel::FilterPanel () : listener (NULL) { pack_start (*ftvb, Gtk::PACK_SHRINK, 4); conns = 0; - sChange[conns++] = fnumberFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = fnumberTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = shutterFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = shutterTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = isoFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = isoTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = focalFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = focalTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); - sChange[conns++] = filetype->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = fnumberFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = fnumberTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = shutterFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = shutterTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = isoFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = isoTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = focalFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = focalTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = expcomp->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = filetype->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); sChange[conns++] = camera->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); sChange[conns++] = lens->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); sChange[conns++] = enaFNumber->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); sChange[conns++] = enaShutter->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); sChange[conns++] = enaFocalLen->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); sChange[conns++] = enaISO->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaExpComp->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); sChange[conns++] = enaCamera->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); sChange[conns++] = enaLens->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); sChange[conns++] = enabled->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); @@ -167,6 +180,9 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) { focalTo->set_text (Glib::ustring::format (defefs.focalTo)); curefs.focalTo = defefs.focalTo; +// enaCompExp->set_active (curefs.filterExpComp); + Glib::RefPtr eselection = expcomp->get_selection (); + // enaFiletype->set_active (curefs.filterFiletype); Glib::RefPtr ftselection = filetype->get_selection (); @@ -176,6 +192,14 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) { // enaLens->set_active (curefs.filterLens); Glib::RefPtr lselection = lens->get_selection (); if( updateLists ){ + expcomp->clear_items(); + curefs.expcomp.clear(); + for (std::set::iterator i = defefs.expcomp.begin(); i!=defefs.expcomp.end(); i++) { + expcomp->append_text (*i); + curefs.expcomp.insert(*i); + } + eselection->select_all(); + lens->clear_items(); curefs.lenses.clear(); for (std::set::iterator i = defefs.lenses.begin(); i!=defefs.lenses.end(); i++) { @@ -200,6 +224,14 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) { } ftselection->select_all(); }else{ + for( Gtk::TreeModel::Children::iterator iter = expcomp->get_model()->children().begin(); iter != expcomp->get_model()->children().end();iter++){ + Glib::ustring v; + iter->get_value(0,v); + if( defefs.expcomp.find( v ) != defefs.expcomp.end() ) + eselection->select( iter ); + else + eselection->unselect( iter ); + } for( Gtk::TreeModel::Children::iterator iter = lens->get_model()->children().begin(); iter != lens->get_model()->children().end();iter++){ Glib::ustring v; iter->get_value(0,v); @@ -253,6 +285,7 @@ ExifFilterSettings FilterPanel::getFilter () { efs.filterShutter = enaShutter->get_active (); efs.filterFocalLen = enaFocalLen->get_active (); efs.filterISO = enaISO->get_active (); + efs.filterExpComp = enaExpComp->get_active (); efs.filterCamera = enaCamera->get_active (); efs.filterLens = enaLens->get_active (); efs.filterFiletype = enaFiletype->get_active (); @@ -260,9 +293,15 @@ ExifFilterSettings FilterPanel::getFilter () { std::vector sel = camera->get_selected (); for (int i=0; iget_text (sel[i])); + + sel = expcomp->get_selected (); + for (int i=0; iget_text (sel[i])); + sel = lens->get_selected (); for (int i=0; iget_text (sel[i])); + sel = filetype->get_selected (); for (int i=0; iget_text (sel[i])); diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h index cd29abeda..c511be332 100644 --- a/rtgui/filterpanel.h +++ b/rtgui/filterpanel.h @@ -31,9 +31,10 @@ class FilterPanelListener { class FilterPanel : public Gtk::VBox { protected: - Gtk::ListViewText* filetype; + Gtk::ListViewText* filetype; Gtk::ListViewText* camera; Gtk::ListViewText* lens; + Gtk::ListViewText* expcomp; Gtk::Entry* fnumberFrom; Gtk::Entry* fnumberTo; Gtk::Entry* shutterFrom; @@ -47,12 +48,13 @@ class FilterPanel : public Gtk::VBox { Gtk::CheckButton* enaShutter; Gtk::CheckButton* enaFocalLen; Gtk::CheckButton* enaISO; + Gtk::CheckButton* enaExpComp; Gtk::CheckButton* enaCamera; Gtk::CheckButton* enaLens; Gtk::CheckButton* enaFiletype; int conns; - sigc::connection sChange[20]; + sigc::connection sChange[22]; ExifFilterSettings curefs; FilterPanelListener* listener; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 8896d5cbb..8e7d00eff 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -548,6 +548,7 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataL cfs.fnumber = idata->getFNumber (); cfs.focalLen = idata->getFocalLen (); cfs.iso = idata->getISOSpeed (); + cfs.expcomp = idata->expcompToString (idata->getExpComp(), false); // do not mask Zero expcomp cfs.year = 1900 + idata->getDateTime().tm_year; cfs.month = idata->getDateTime().tm_mon + 1; cfs.day = idata->getDateTime().tm_mday; @@ -575,9 +576,9 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataL } // get image filetype std::string::size_type idx; - idx = fname.rfind('.'); - if(idx != std::string::npos){cfs.filetype = fname.substr(idx+1);} - else {cfs.filetype="";} + idx = fname.rfind('.'); + if(idx != std::string::npos){cfs.filetype = fname.substr(idx+1);} + else {cfs.filetype="";} delete idata; return deg;