Extend the file browser so that it will only show the original image if several files of different formats are present.

This commit is contained in:
Adam Reichold
2015-11-08 11:32:14 +01:00
parent 4e0e3230cc
commit d3ac22531b
3 changed files with 127 additions and 11 deletions

View File

@@ -19,6 +19,7 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "filebrowser.h" #include "filebrowser.h"
#include <map>
#include <glibmm.h> #include <glibmm.h>
#include "options.h" #include "options.h"
#include "multilangmgr.h" #include "multilangmgr.h"
@@ -32,6 +33,96 @@
extern Options options; extern Options options;
namespace
{
const Glib::ustring* getOriginalExtension (const ThumbBrowserEntryBase* entry)
{
// We use the parsed extensions as a priority list,
// i.e. what comes earlier in the list is considered an original of what comes later.
typedef std::vector<Glib::ustring> ExtensionVector;
typedef ExtensionVector::const_iterator ExtensionIterator;
const ExtensionVector& originalExtensions = options.parsedExtensions;
// Extract extension from basename
const Glib::ustring basename = Glib::path_get_basename (entry->filename.lowercase());
const Glib::ustring::size_type pos = basename.find_last_of ('.');
if (pos >= basename.length () - 1) {
return NULL;
}
const Glib::ustring extension = basename.substr (pos + 1);
// Try to find a matching original extension
for (ExtensionIterator originalExtension = originalExtensions.begin(); originalExtension != originalExtensions.end(); ++originalExtension) {
if (*originalExtension == extension) {
return &*originalExtension;
}
}
return NULL;
}
ThumbBrowserEntryBase* selectOriginalEntry (ThumbBrowserEntryBase* original, ThumbBrowserEntryBase* candidate)
{
// The candidate will become the new original, if it has an original extension
// and if its extension is higher in the list than the old original.
if (const Glib::ustring* candidateExtension = getOriginalExtension (candidate)) {
if (original == NULL) {
return candidate;
} else if (const Glib::ustring* originalExtension = getOriginalExtension (original)) {
return candidateExtension < originalExtension ? candidate : original;
}
} else {
return original;
}
}
void findOriginalEntries (const std::vector<ThumbBrowserEntryBase*>& entries)
{
typedef std::vector<ThumbBrowserEntryBase*> EntryVector;
typedef EntryVector::const_iterator EntryIterator;
typedef std::map<Glib::ustring, EntryVector> BasenameMap;
typedef BasenameMap::const_iterator BasenameIterator;
// Sort all entries into buckets by basename without extension
BasenameMap byBasename;
for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) {
const Glib::ustring basename = Glib::path_get_basename ((*entry)->filename.lowercase());
const Glib::ustring::size_type pos = basename.find_last_of ('.');
if (pos >= basename.length () - 1) {
(*entry)->setOriginal (NULL);
continue;
}
const Glib::ustring withoutExtension = basename.substr (0, pos);
byBasename[withoutExtension].push_back (*entry);
}
// Find the original image for each bucket
for (BasenameIterator bucket = byBasename.begin (); bucket != byBasename.end (); ++bucket) {
const EntryVector& entries = bucket->second;
ThumbBrowserEntryBase* original = NULL;
// Select the most likely original in a first pass...
for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) {
original = selectOriginalEntry (original, *entry);
}
// ...and link all other images to it in a second pass.
for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) {
(*entry)->setOriginal (*entry != original ? original : NULL);
}
}
}
}
FileBrowser::FileBrowser () FileBrowser::FileBrowser ()
: tbl(NULL), numFiltered(0), partialPasteDlg(M("PARTIALPASTE_DIALOGLABEL")) : tbl(NULL), numFiltered(0), partialPasteDlg(M("PARTIALPASTE_DIALOGLABEL"))
{ {
@@ -1370,6 +1461,10 @@ void FileBrowser::applyFilter (const BrowserFilter& filter)
MYWRITERLOCK(l, entryRW); // Don't make this a writer lock! HOMBRE: Why? 'selected' is modified here MYWRITERLOCK(l, entryRW); // Don't make this a writer lock! HOMBRE: Why? 'selected' is modified here
#endif #endif
if (true/* TODO: filterOriginal */) {
findOriginalEntries(fd);
}
for (size_t i = 0; i < fd.size(); i++) { for (size_t i = 0; i < fd.size(); i++) {
if (checkFilter (fd[i])) { if (checkFilter (fd[i])) {
numFiltered++; numFiltered++;
@@ -1400,6 +1495,10 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry
FileBrowserEntry* entry = static_cast<FileBrowserEntry*>(entryb); FileBrowserEntry* entry = static_cast<FileBrowserEntry*>(entryb);
if (true/* TODO: filterOriginal */ && entry->getOriginal() != NULL) {
return false;
}
// return false if basic filter settings are not satisfied // return false if basic filter settings are not satisfied
if ((filter.showRanked[entry->thumbnail->getRank()] == false ) || if ((filter.showRanked[entry->thumbnail->getRank()] == false ) ||
(filter.showCLabeled[entry->thumbnail->getColorLabel()] == false ) || (filter.showCLabeled[entry->thumbnail->getColorLabel()] == false ) ||

View File

@@ -26,7 +26,7 @@ ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname)
prex(0), prey(0), upperMargin(6), borderWidth(1), textGap(6), sideMargin(8), lowerMargin(8), prex(0), prey(0), upperMargin(6), borderWidth(1), textGap(6), sideMargin(8), lowerMargin(8),
preview(NULL), dispname(Glib::path_get_basename (fname)), buttonSet(NULL), width(0), height(0), preview(NULL), dispname(Glib::path_get_basename (fname)), buttonSet(NULL), width(0), height(0),
exp_width(0), exp_height(0), startx(0), starty(0), ofsX(0), ofsY(0), redrawRequests(0), exp_width(0), exp_height(0), startx(0), starty(0), ofsX(0), ofsY(0), redrawRequests(0),
parent(NULL), bbSelected(false), bbFramed(false), bbPreview(NULL), parent(NULL), original(NULL), bbSelected(false), bbFramed(false), bbPreview(NULL),
thumbnail(NULL), filename(fname), shortname(dispname), exifline(""), datetimeline(""), thumbnail(NULL), filename(fname), shortname(dispname), exifline(""), datetimeline(""),
selected(false), drawable(false), filtered(false), framed(false), processing(false), italicstyle(false), selected(false), drawable(false), filtered(false), framed(false), processing(false), italicstyle(false),
edited(false), recentlysaved(false), updatepriority(false), withFilename(WFNAME_NONE) {} edited(false), recentlysaved(false), updatepriority(false), withFilename(WFNAME_NONE) {}
@@ -544,6 +544,17 @@ bool ThumbBrowserEntryBase::insideWindow (int x, int y, int w, int h)
return !(ofsX + startx > x + w || ofsX + startx + exp_width < x || ofsY + starty > y + h || ofsY + starty + exp_height < y); return !(ofsX + startx > x + w || ofsX + startx + exp_width < x || ofsY + starty > y + h || ofsY + starty + exp_height < y);
} }
std::vector<Glib::RefPtr<Gdk::Pixbuf> > ThumbBrowserEntryBase::getIconsOnImageArea()
{
return std::vector<Glib::RefPtr<Gdk::Pixbuf> >();
}
void ThumbBrowserEntryBase::getIconSize(int& w, int& h)
{
w = 0;
h = 0;
}
bool ThumbBrowserEntryBase::motionNotify (int x, int y) bool ThumbBrowserEntryBase::motionNotify (int x, int y)
{ {

View File

@@ -72,6 +72,7 @@ protected:
int redrawRequests; int redrawRequests;
ThumbBrowserBase* parent; ThumbBrowserBase* parent;
ThumbBrowserEntryBase* original;
Glib::RefPtr<Gdk::Pixmap> backBuffer; Glib::RefPtr<Gdk::Pixmap> backBuffer;
bool bbSelected, bbFramed; bool bbSelected, bbFramed;
@@ -168,22 +169,17 @@ public:
return shortname.casefold() > other.shortname.casefold(); return shortname.casefold() > other.shortname.casefold();
} }
ThumbBrowserEntryBase* getOriginal () const;
void setOriginal (ThumbBrowserEntryBase* original);
virtual void refreshThumbnailImage () {} virtual void refreshThumbnailImage () {}
virtual void refreshQuickThumbnailImage () {} virtual void refreshQuickThumbnailImage () {}
virtual void calcThumbnailSize () {} virtual void calcThumbnailSize () {}
virtual void drawProgressBar (Glib::RefPtr<Gdk::Window> win, Glib::RefPtr<Gdk::GC> gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) {} virtual void drawProgressBar (Glib::RefPtr<Gdk::Window> win, Glib::RefPtr<Gdk::GC> gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) {}
virtual std::vector<Glib::RefPtr<Gdk::Pixbuf> > getIconsOnImageArea () virtual std::vector<Glib::RefPtr<Gdk::Pixbuf> > getIconsOnImageArea ();
{ virtual void getIconSize (int& w, int& h);
std::vector<Glib::RefPtr<Gdk::Pixbuf> > r;
return r;
}
virtual void getIconSize (int& w, int& h)
{
w = 0;
h = 0;
}
virtual bool motionNotify (int x, int y); virtual bool motionNotify (int x, int y);
virtual bool pressNotify (int button, int type, int bstate, int x, int y); virtual bool pressNotify (int button, int type, int bstate, int x, int y);
@@ -191,4 +187,14 @@ public:
virtual Glib::ustring getToolTip (int x, int y); virtual Glib::ustring getToolTip (int x, int y);
}; };
inline ThumbBrowserEntryBase* ThumbBrowserEntryBase::getOriginal() const
{
return original;
}
inline void ThumbBrowserEntryBase::setOriginal(ThumbBrowserEntryBase* original)
{
this->original = original;
}
#endif #endif