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/>.
*/
#include "filebrowser.h"
#include <map>
#include <glibmm.h>
#include "options.h"
#include "multilangmgr.h"
@@ -32,6 +33,96 @@
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 ()
: 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
#endif
if (true/* TODO: filterOriginal */) {
findOriginalEntries(fd);
}
for (size_t i = 0; i < fd.size(); i++) {
if (checkFilter (fd[i])) {
numFiltered++;
@@ -1400,6 +1495,10 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry
FileBrowserEntry* entry = static_cast<FileBrowserEntry*>(entryb);
if (true/* TODO: filterOriginal */ && entry->getOriginal() != NULL) {
return false;
}
// return false if basic filter settings are not satisfied
if ((filter.showRanked[entry->thumbnail->getRank()] == false ) ||
(filter.showCLabeled[entry->thumbnail->getColorLabel()] == false ) ||