Batch queue improvements: keyboard shortcuts and a sequence index; on behalf of Adam Reichold (issue 1915)
This commit is contained in:
@@ -783,7 +783,7 @@ PREFERENCES_MULTITAB;Multiple Editor Tabs Mode
|
|||||||
PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the selected folder
|
PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the selected folder
|
||||||
PREFERENCES_OUTDIRFOLDER;Save to folder
|
PREFERENCES_OUTDIRFOLDER;Save to folder
|
||||||
PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n<b>%f</b>, <b>%d1</b>, <b>%d2</b>, ..., <b>%p1</b>, <b>%p2</b>, ..., <b>%r</b>\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\n\nFor example, if the photo being processed has the following pathname:\n<b><i>/home/tom/photos/2010-10-31/dsc0042.nef</i></b>\nthe meaning of the formatting strings are:\n<b>%d4</b> = <i>home</i>\n<b>%d3</b> = <i>tom</i>\n<b>%d2</b> = <i>photos</i>\n<b>%d1</b> = <i>2010-10-31</i>\n<b>%f</b> = <i>dsc0042</i>\n<b>%p1</b> = <i>/home/tom/photos/2010-10-31/</i>\n<b>%p2</b> = <i>/home/tom/photos/</i>\n<b>%p3</b> = <i>/home/tom/</i>\n<b>%p4</b> = <i>/home/</i>\n\n<b>%r</b> will be replaced by the rank of the photo. If the photo is unranked, %r will be replaced by '0'. If the photo is in the trash bin, %r will be replaced by 'x'.\n\nIf you want to save the output image where the original is, write:\n<b>%p1/%f</b>\n\nIf you want to save the output image in a directory named "<i>converted</i>" located in the directory of the opened image, write:\n<b>%p1/converted/%f</b>\n\nIf you want to save the output image in a directory named "<i>/home/tom/photos/converted/2010-10-31</i>", write:\n<b>%p2/converted/%d1/%f</b>
|
PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n<b>%f</b>, <b>%d1</b>, <b>%d2</b>, ..., <b>%p1</b>, <b>%p2</b>, ..., <b>%r</b>\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\n\nFor example, if the photo being processed has the following pathname:\n<b><i>/home/tom/photos/2010-10-31/dsc0042.nef</i></b>\nthe meaning of the formatting strings are:\n<b>%d4</b> = <i>home</i>\n<b>%d3</b> = <i>tom</i>\n<b>%d2</b> = <i>photos</i>\n<b>%d1</b> = <i>2010-10-31</i>\n<b>%f</b> = <i>dsc0042</i>\n<b>%p1</b> = <i>/home/tom/photos/2010-10-31/</i>\n<b>%p2</b> = <i>/home/tom/photos/</i>\n<b>%p3</b> = <i>/home/tom/</i>\n<b>%p4</b> = <i>/home/</i>\n\n<b>%r</b> will be replaced by the rank of the photo. If the photo is unranked, %r will be replaced by '0'. If the photo is in the trash bin, %r will be replaced by 'x'.\n\nIf you want to save the output image where the original is, write:\n<b>%p1/%f</b>\n\nIf you want to save the output image in a directory named "<i>converted</i>" located in the directory of the opened image, write:\n<b>%p1/converted/%f</b>\n\nIf you want to save the output image in a directory named "<i>/home/tom/photos/converted/2010-10-31</i>", write:\n<b>%p2/converted/%d1/%f</b>
|
||||||
PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n<b>%f</b>, <b>%d1</b>, <b>%d2</b>, ..., <b>%p1</b>, <b>%p2</b>, ..., <b>%r</b>\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\n\nFor example, if the photo being processed has the following pathname:\n<b><i>/home/tom/photos/2010-10-31/dsc0042.nef</i></b>\nthe meaning of the formatting strings are:\n<b>%d4</b> = <i>home</i>\n<b>%d3</b> = <i>tom</i>\n<b>%d2</b> = <i>photos</i>\n<b>%d1</b> = <i>2010-10-31</i>\n<b>%f</b> = <i>dsc0042</i>\n<b>%p1</b> = <i>/home/tom/photos/2010-10-31/</i>\n<b>%p2</b> = <i>/home/tom/photos/</i>\n<b>%p3</b> = <i>/home/tom/</i>\n<b>%p4</b> = <i>/home/</i>\n\n<b>%r</b> will be replaced by the rank of the photo. If the photo is unranked, %r will be replaced by '0'. If the photo is in the trash bin, %r will be replaced by 'x'.\n\nIf you want to save the output image where the original is, write:\n<b>%p1/%f</b>\n\nIf you want to save the output image in a directory named "<i>converted</i>" located in the directory of the opened image, write:\n<b>%p1/converted/%f</b>\n\nIf you want to save the output image in a directory named "<i>/home/tom/photos/converted/2010-10-31</i>", write:\n<b>%p2/converted/%d1/%f</b>
|
PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n<b>%f</b>, <b>%d1</b>, <b>%d2</b>, ..., <b>%p1</b>, <b>%p2</b>, ..., <b>%r</b>, <b>%s1</b>, <b>%s2</b>, ...\n\nThese formatting strings refer to the different parts of the photo's pathname, some attributes of the photo or an arbitrary sequence index in the batch job.\n\nFor example, if the photo being processed has the following pathname:\n<b><i>/home/tom/photos/2010-10-31/dsc0042.nef</i></b>\nthe meaning of the formatting strings are:\n<b>%d4</b> = <i>home</i>\n<b>%d3</b> = <i>tom</i>\n<b>%d2</b> = <i>photos</i>\n<b>%d1</b> = <i>2010-10-31</i>\n<b>%f</b> = <i>dsc0042</i>\n<b>%p1</b> = <i>/home/tom/photos/2010-10-31/</i>\n<b>%p2</b> = <i>/home/tom/photos/</i>\n<b>%p3</b> = <i>/home/tom/</i>\n<b>%p4</b> = <i>/home/</i>\n\n<b>%r</b> will be replaced by the rank of the photo. If the photo is unranked, %r will be replaced by '0'. If the photo is in the trash bin, %r will be replaced by 'x'.\n\n<b>%s1</b>, <b>%s2</b>, etc. will be replaced by a sequence index which is padded to between 1 and 9 digits. The sequence index will start at one each time the queue processing is started and is incremented by one for each image processed.\n\nIf you want to save the output image where the original is, write:\n<b>%p1/%f</b>\n\nIf you want to save the output image in a directory named "<i>converted</i>" located in the directory of the opened image, write:\n<b>%p1/converted/%f</b>\n\nIf you want to save the output image in a directory named "<i>/home/tom/photos/converted/2010-10-31</i>", write:\n<b>%p2/converted/%d1/%f</b>
|
||||||
PREFERENCES_OUTDIRTEMPLATE;Use template
|
PREFERENCES_OUTDIRTEMPLATE;Use template
|
||||||
PREFERENCES_OUTDIR;Output Directory
|
PREFERENCES_OUTDIR;Output Directory
|
||||||
PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails
|
PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails
|
||||||
|
@@ -21,6 +21,10 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "../rtengine/rt_math.h"
|
#include "../rtengine/rt_math.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "batchqueue.h"
|
#include "batchqueue.h"
|
||||||
#include "multilangmgr.h"
|
#include "multilangmgr.h"
|
||||||
#include "filecatalog.h"
|
#include "filecatalog.h"
|
||||||
@@ -32,7 +36,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rtengine;
|
using namespace rtengine;
|
||||||
|
|
||||||
BatchQueue::BatchQueue () : processing(NULL), listener(NULL) {
|
BatchQueue::BatchQueue () : processing(NULL), sequence(0), listener(NULL) {
|
||||||
|
|
||||||
int p = 0;
|
int p = 0;
|
||||||
pmenu = new Gtk::Menu ();
|
pmenu = new Gtk::Menu ();
|
||||||
@@ -52,6 +56,14 @@ BatchQueue::BatchQueue () : processing(NULL), listener(NULL) {
|
|||||||
|
|
||||||
pmenu->show_all ();
|
pmenu->show_all ();
|
||||||
|
|
||||||
|
// Accelerators
|
||||||
|
pmaccelgroup = Gtk::AccelGroup::create ();
|
||||||
|
pmenu->set_accel_group (pmaccelgroup);
|
||||||
|
selall->add_accelerator ("activate", pmenu->get_accel_group(), GDK_a, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
|
||||||
|
head->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Home, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE);
|
||||||
|
tail->add_accelerator ("activate", pmenu->get_accel_group(), GDK_End, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE);
|
||||||
|
cancel->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE);
|
||||||
|
|
||||||
cancel->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::cancelItems), &selected));
|
cancel->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::cancelItems), &selected));
|
||||||
head->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::headItems), &selected));
|
head->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::headItems), &selected));
|
||||||
tail->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::tailItems), &selected));
|
tail->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::tailItems), &selected));
|
||||||
@@ -101,6 +113,29 @@ void BatchQueue::rightClicked (ThumbBrowserEntryBase* entry) {
|
|||||||
pmenu->popup (3, this->eventTime);
|
pmenu->popup (3, this->eventTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BatchQueue::keyPressed (GdkEventKey* event) {
|
||||||
|
bool ctrl = event->state & GDK_CONTROL_MASK;
|
||||||
|
|
||||||
|
if ((event->keyval==GDK_A || event->keyval==GDK_a) && ctrl) {
|
||||||
|
selectAll ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (event->keyval==GDK_Home) {
|
||||||
|
headItems (&selected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (event->keyval==GDK_End) {
|
||||||
|
tailItems (&selected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (event->keyval==GDK_Delete) {
|
||||||
|
cancelItems (&selected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BatchQueue::addEntries ( std::vector<BatchQueueEntry*> &entries, bool head, bool save)
|
void BatchQueue::addEntries ( std::vector<BatchQueueEntry*> &entries, bool head, bool save)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -501,8 +536,9 @@ void BatchQueue::startProcessing () {
|
|||||||
BatchQueueEntry* next;
|
BatchQueueEntry* next;
|
||||||
|
|
||||||
next = static_cast<BatchQueueEntry*>(fd[0]);
|
next = static_cast<BatchQueueEntry*>(fd[0]);
|
||||||
// tag it as processing
|
// tag it as processing and set sequence
|
||||||
next->processing = true;
|
next->processing = true;
|
||||||
|
next->sequence = sequence = 1;
|
||||||
processing = next;
|
processing = next;
|
||||||
// remove from selection
|
// remove from selection
|
||||||
if (processing->selected) {
|
if (processing->selected) {
|
||||||
@@ -532,7 +568,7 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) {
|
|||||||
Glib::ustring fname;
|
Glib::ustring fname;
|
||||||
SaveFormat saveFormat;
|
SaveFormat saveFormat;
|
||||||
if (processing->outFileName=="") { // auto file name
|
if (processing->outFileName=="") { // auto file name
|
||||||
Glib::ustring s = calcAutoFileNameBase (processing->filename);
|
Glib::ustring s = calcAutoFileNameBase (processing->filename, processing->sequence);
|
||||||
saveFormat = options.saveFormatBatch;
|
saveFormat = options.saveFormatBatch;
|
||||||
fname = autoCompleteFileName (s, saveFormat.format);
|
fname = autoCompleteFileName (s, saveFormat.format);
|
||||||
}
|
}
|
||||||
@@ -592,8 +628,9 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) {
|
|||||||
}
|
}
|
||||||
else if (listener && listener->canStartNext ()) {
|
else if (listener && listener->canStartNext ()) {
|
||||||
BatchQueueEntry* next = static_cast<BatchQueueEntry*>(fd[0]);
|
BatchQueueEntry* next = static_cast<BatchQueueEntry*>(fd[0]);
|
||||||
// tag it as selected
|
// tag it as selected and set sequence
|
||||||
next->processing = true;
|
next->processing = true;
|
||||||
|
next->sequence = ++sequence;
|
||||||
processing = next;
|
processing = next;
|
||||||
// remove from selection
|
// remove from selection
|
||||||
if (processing->selected) {
|
if (processing->selected) {
|
||||||
@@ -640,7 +677,7 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) {
|
|||||||
|
|
||||||
// Calculates automatic filename of processed batch entry, but just the base name
|
// Calculates automatic filename of processed batch entry, but just the base name
|
||||||
// example output: "c:\out\converted\dsc0121"
|
// example output: "c:\out\converted\dsc0121"
|
||||||
Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileName) {
|
Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence) {
|
||||||
|
|
||||||
std::vector<Glib::ustring> pa;
|
std::vector<Glib::ustring> pa;
|
||||||
std::vector<Glib::ustring> da;
|
std::vector<Glib::ustring> da;
|
||||||
@@ -717,6 +754,19 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam
|
|||||||
rank = '0'; // if param file not loaded (e.g. does not exist), default to rank=0
|
rank = '0'; // if param file not loaded (e.g. does not exist), default to rank=0
|
||||||
path += rank;
|
path += rank;
|
||||||
}
|
}
|
||||||
|
else if (options.savePathTemplate[ix]=='s') { // sequence
|
||||||
|
std::ostringstream seqstr;
|
||||||
|
|
||||||
|
int w = options.savePathTemplate[ix+1]-'0';
|
||||||
|
|
||||||
|
if (w>=1 && w<=9) {
|
||||||
|
ix++;
|
||||||
|
seqstr << std::setw (w) << std::setfill ('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
seqstr << sequence;
|
||||||
|
path += seqstr.str ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@@ -44,6 +44,7 @@ class BatchQueue : public ThumbBrowserBase,
|
|||||||
int getThumbnailHeight ();
|
int getThumbnailHeight ();
|
||||||
|
|
||||||
BatchQueueEntry* processing; // holds the currently processed image
|
BatchQueueEntry* processing; // holds the currently processed image
|
||||||
|
int sequence; // holds the current sequence index
|
||||||
|
|
||||||
Glib::ustring nameTemplate;
|
Glib::ustring nameTemplate;
|
||||||
|
|
||||||
@@ -53,6 +54,8 @@ class BatchQueue : public ThumbBrowserBase,
|
|||||||
Gtk::MenuItem* selall;
|
Gtk::MenuItem* selall;
|
||||||
Gtk::Menu* pmenu;
|
Gtk::Menu* pmenu;
|
||||||
|
|
||||||
|
Glib::RefPtr<Gtk::AccelGroup> pmaccelgroup;
|
||||||
|
|
||||||
BatchQueueListener* listener;
|
BatchQueueListener* listener;
|
||||||
|
|
||||||
Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format);
|
Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format);
|
||||||
@@ -84,6 +87,7 @@ class BatchQueue : public ThumbBrowserBase,
|
|||||||
rtengine::ProcessingJob* imageReady (rtengine::IImage16* img);
|
rtengine::ProcessingJob* imageReady (rtengine::IImage16* img);
|
||||||
void setProgress (double p);
|
void setProgress (double p);
|
||||||
void rightClicked (ThumbBrowserEntryBase* entry);
|
void rightClicked (ThumbBrowserEntryBase* entry);
|
||||||
|
bool keyPressed (GdkEventKey* event);
|
||||||
void buttonPressed (LWButton* button, int actionCode, void* actionData);
|
void buttonPressed (LWButton* button, int actionCode, void* actionData);
|
||||||
void redrawNeeded (LWButton* button);
|
void redrawNeeded (LWButton* button);
|
||||||
|
|
||||||
@@ -92,7 +96,7 @@ class BatchQueue : public ThumbBrowserBase,
|
|||||||
bool loadBatchQueue ();
|
bool loadBatchQueue ();
|
||||||
void resizeLoadedQueue();
|
void resizeLoadedQueue();
|
||||||
|
|
||||||
static Glib::ustring calcAutoFileNameBase (const Glib::ustring& origFileName);
|
static Glib::ustring calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence = 0);
|
||||||
static int calcMaxThumbnailHeight();
|
static int calcMaxThumbnailHeight();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ Glib::RefPtr<Gdk::Pixbuf> BatchQueueEntry::savedAsIcon;
|
|||||||
BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm)
|
BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm)
|
||||||
: ThumbBrowserEntryBase(fname),
|
: ThumbBrowserEntryBase(fname),
|
||||||
opreview(NULL), origpw(prevw), origph(prevh), opreviewDone(false),
|
opreview(NULL), origpw(prevw), origph(prevh), opreviewDone(false),
|
||||||
job(pjob), progress(0), outFileName(""), forceFormatOpts(false) {
|
job(pjob), progress(0), outFileName(""), sequence(0), forceFormatOpts(false) {
|
||||||
|
|
||||||
thumbnail=thm;
|
thumbnail=thm;
|
||||||
params = pparams;
|
params = pparams;
|
||||||
|
@@ -49,6 +49,7 @@ public:
|
|||||||
Glib::ustring savedParamsFile;
|
Glib::ustring savedParamsFile;
|
||||||
double progress;
|
double progress;
|
||||||
Glib::ustring outFileName;
|
Glib::ustring outFileName;
|
||||||
|
int sequence;
|
||||||
SaveFormat saveFormat;
|
SaveFormat saveFormat;
|
||||||
bool forceFormatOpts;
|
bool forceFormatOpts;
|
||||||
|
|
||||||
|
@@ -274,3 +274,7 @@ void BatchQueuePanel::formatChanged (Glib::ustring f) {
|
|||||||
options.saveFormatBatch = saveFormatPanel->getFormat ();
|
options.saveFormatBatch = saveFormatPanel->getFormat ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BatchQueuePanel::handleShortcutKey (GdkEventKey* event) {
|
||||||
|
return batchQueue->keyPressed (event);
|
||||||
|
}
|
||||||
|
@@ -68,6 +68,8 @@ class BatchQueuePanel : public Gtk::VBox,
|
|||||||
void pathFolderChanged ();
|
void pathFolderChanged ();
|
||||||
void formatChanged (Glib::ustring f);
|
void formatChanged (Glib::ustring f);
|
||||||
void updateTab (int qsize);
|
void updateTab (int qsize);
|
||||||
|
|
||||||
|
bool handleShortcutKey (GdkEventKey* event);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -421,7 +421,7 @@ bool RTWindow::keyPressed (GdkEventKey* event) {
|
|||||||
return fpanel->handleShortcutKey (event);
|
return fpanel->handleShortcutKey (event);
|
||||||
}
|
}
|
||||||
else if (mainNB->get_current_page() == mainNB->page_num(*bpanel)) {
|
else if (mainNB->get_current_page() == mainNB->page_num(*bpanel)) {
|
||||||
return false;
|
return bpanel->handleShortcutKey (event);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EditorPanel* ep = static_cast<EditorPanel*>(mainNB->get_nth_page (mainNB->get_current_page()));
|
EditorPanel* ep = static_cast<EditorPanel*>(mainNB->get_nth_page (mainNB->get_current_page()));
|
||||||
|
Reference in New Issue
Block a user