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:
@@ -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 ) ||
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user