Solving issue 1657: "Destination save path forgotten for photos in queue when RT crashes". Also allow to set the Saving parameters or not, when sent to the queue with the "Save as" dialog box

This commit is contained in:
natureh 510 2013-03-31 17:25:10 +02:00
parent c5af5476de
commit 0a20574ff0
14 changed files with 287 additions and 43 deletions

View File

@ -5,6 +5,7 @@ ABOUT_TAB_RELEASENOTES;Notes de version
ABOUT_TAB_SPLASH;Splash ABOUT_TAB_SPLASH;Splash
ADJUSTER_RESET_TO_DEFAULT;Réglages par défaut ADJUSTER_RESET_TO_DEFAULT;Réglages par défaut
BATCHQUEUE_AUTOSTART;Démarrage auto BATCHQUEUE_AUTOSTART;Démarrage auto
BATCHQUEUE_DESTFILENAME;Chemin et nom de fichier
BATCH_PROCESSING;Traitement par lot BATCH_PROCESSING;Traitement par lot
CURVEEDITOR_CURVES;Courbes CURVEEDITOR_CURVES;Courbes
CURVEEDITOR_CURVE;Courbe CURVEEDITOR_CURVE;Courbe
@ -870,6 +871,7 @@ QINFO_LENS;Objectif
QINFO_NOEXIF;Données EXIF non disponibles. QINFO_NOEXIF;Données EXIF non disponibles.
SAVEDLG_AUTOSUFFIX;Ajouter automatiquement un suffixe si le fichier existe déjà SAVEDLG_AUTOSUFFIX;Ajouter automatiquement un suffixe si le fichier existe déjà
SAVEDLG_FILEFORMAT;Format de fichier SAVEDLG_FILEFORMAT;Format de fichier
SAVEDLG_FORCEFORMATOPTS;Forcer les options d'enregistrement
SAVEDLG_JPEGQUAL;Qualité JPEG SAVEDLG_JPEGQUAL;Qualité JPEG
SAVEDLG_JPGFILTER;Fichiers JPEG SAVEDLG_JPGFILTER;Fichiers JPEG
SAVEDLG_PNGCOMPR;Compression PNG SAVEDLG_PNGCOMPR;Compression PNG

View File

@ -5,6 +5,7 @@ ABOUT_TAB_RELEASENOTES;Release Notes
ABOUT_TAB_SPLASH;Splash ABOUT_TAB_SPLASH;Splash
ADJUSTER_RESET_TO_DEFAULT;Reset to default ADJUSTER_RESET_TO_DEFAULT;Reset to default
BATCHQUEUE_AUTOSTART;Auto start BATCHQUEUE_AUTOSTART;Auto start
BATCHQUEUE_DESTFILENAME;Path and file name
BATCH_PROCESSING;Batch Processing BATCH_PROCESSING;Batch Processing
CURVEEDITOR_CURVES;Curves CURVEEDITOR_CURVES;Curves
CURVEEDITOR_CURVE;Curve CURVEEDITOR_CURVE;Curve
@ -867,6 +868,7 @@ QINFO_LENS;Lens
QINFO_NOEXIF;Exif data not available. QINFO_NOEXIF;Exif data not available.
SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists
SAVEDLG_FILEFORMAT;File format SAVEDLG_FILEFORMAT;File format
SAVEDLG_FORCEFORMATOPTS;Force saving options
SAVEDLG_JPEGQUAL;JPEG Quality SAVEDLG_JPEGQUAL;JPEG Quality
SAVEDLG_JPGFILTER;JPEG files SAVEDLG_JPGFILTER;JPEG files
SAVEDLG_PNGCOMPR;PNG Compression SAVEDLG_PNGCOMPR;PNG Compression

View File

@ -129,16 +129,28 @@ void BatchQueue::addEntries ( std::vector<BatchQueueEntry*> &entries, bool head)
bool BatchQueue::saveBatchQueue( ) bool BatchQueue::saveBatchQueue( )
{ {
Glib::ustring savedQueueFile; Glib::ustring savedQueueFile;
savedQueueFile = options.rtdir+"/batch/queue"; savedQueueFile = options.rtdir+"/batch/queue.csv";
FILE *f = safe_g_fopen (savedQueueFile, "wt"); FILE *f = safe_g_fopen (savedQueueFile, "wt");
if (f==NULL) if (f==NULL)
return false; return false;
// method is already running with entryLock, so no need to lock again if (fd.size())
// The column's header is mandatory (the first line will be skipped when loaded)
fprintf(f,"input image full path|param file full path|output image full path|file format|jpeg quality|jpeg subsampling|"
"png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|<end of line>\n");
// method is already running with entryLock, so no need to lock again
for (std::vector<ThumbBrowserEntryBase*>::iterator pos=fd.begin(); pos!=fd.end(); pos++){ for (std::vector<ThumbBrowserEntryBase*>::iterator pos=fd.begin(); pos!=fd.end(); pos++){
BatchQueueEntry* bqe = reinterpret_cast<BatchQueueEntry*>(*pos); BatchQueueEntry* bqe = reinterpret_cast<BatchQueueEntry*>(*pos);
fprintf(f,"%s;%s\n", bqe->filename.c_str(),bqe->savedParamsFile.c_str() ); // Warning: for code's simplicity in loadBatchQueue, each field must end by the '|' character, safer than ';' or ',' since it can't be used in paths
fprintf(f,"%s|%s|%s|%s|%d|%d|%d|%d|%d|%d|%d|%d|\n",
bqe->filename.c_str(),bqe->savedParamsFile.c_str(), bqe->outFileName.c_str(), bqe->saveFormat.format.c_str(),
bqe->saveFormat.jpegQuality, bqe->saveFormat.jpegSubSamp,
bqe->saveFormat.pngBits, bqe->saveFormat.pngCompression,
bqe->saveFormat.tiffBits, bqe->saveFormat.tiffUncompressed,
bqe->saveFormat.saveParams, bqe->forceFormatOpts
);
} }
fclose (f); fclose (f);
return true; return true;
@ -153,22 +165,118 @@ void BatchQueue::loadBatchQueue( )
#endif #endif
Glib::ustring savedQueueFile; Glib::ustring savedQueueFile;
savedQueueFile = options.rtdir+"/batch/queue"; savedQueueFile = options.rtdir+"/batch/queue.csv";
FILE *f = safe_g_fopen (savedQueueFile, "rt"); FILE *f = safe_g_fopen (savedQueueFile, "rt");
if (f!=NULL) { if (f!=NULL) {
char *buffer = new char[1024]; char *buffer = new char[1024];
unsigned numLoaded=0; unsigned numLoaded=0;
// skipping the first line
bool firstLine=true;
while (fgets (buffer, 1024, f)){ while (fgets (buffer, 1024, f)){
char *p = strchr(buffer,';' );
if( p ){
char *le = buffer + strlen(buffer);
while( --le > buffer && (*le == '\n' || *le == '\r') );
std::string _source(buffer, p-buffer );
std::string _paramsFile(p+1, (le +1)- (p+1) );
Glib::ustring source(_source);
Glib::ustring paramsFile(_paramsFile);
if (firstLine) {
// skipping the column's title line
firstLine=false;
continue;
}
size_t pos;
Glib::ustring source;
Glib::ustring paramsFile;
Glib::ustring outputFile;
Glib::ustring saveFmt(options.saveFormat.format);
int jpegQuality=options.saveFormat.jpegQuality, jpegSubSamp =options.saveFormat.jpegSubSamp;
int pngBits =options.saveFormat.pngBits, pngCompression =options.saveFormat.pngCompression;
int tiffBits =options.saveFormat.tiffBits, tiffUncompressed=options.saveFormat.tiffUncompressed;
int saveParams =options.saveFormat.saveParams;
int forceFormatOpts =options.forceFormatOpts;
Glib::ustring currLine(buffer);
int a = 0;
if (currLine.rfind('\n') != Glib::ustring::npos) a++;
if (currLine.rfind('\r') != Glib::ustring::npos) a++;
if (a)
currLine = currLine.substr(0, currLine.length()-a);
// Looking for the image's full path
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
source = currLine.substr(0, pos);
currLine = currLine.substr(pos+1);
// Looking for the procparams' full path
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
paramsFile = currLine.substr(0, pos);
currLine = currLine.substr(pos+1);
// Looking for the full output path; if empty, it'll use the template string
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
outputFile = currLine.substr(0, pos);
currLine = currLine.substr(pos+1);
// No need to bother reading the last options, they will be ignored if outputFile is empty!
if (!outputFile.empty()) {
// Looking for the saving format
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
saveFmt = currLine.substr(0, pos);
currLine = currLine.substr(pos+1);
// Looking for the jpeg quality
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
jpegQuality = atoi(currLine.substr(0, pos).c_str());
currLine = currLine.substr(pos+1);
// Looking for the jpeg subsampling
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
jpegSubSamp = atoi(currLine.substr(0, pos).c_str());
currLine = currLine.substr(pos+1);
// Looking for the png bit depth
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
pngBits = atoi(currLine.substr(0, pos).c_str());
currLine = currLine.substr(pos+1);
// Looking for the png compression
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
pngCompression = atoi(currLine.substr(0, pos).c_str());
currLine = currLine.substr(pos+1);
// Looking for the tiff bit depth
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
tiffBits = atoi(currLine.substr(0, pos).c_str());
currLine = currLine.substr(pos+1);
// Looking for the tiff uncompression
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
tiffUncompressed = atoi(currLine.substr(0, pos).c_str());
currLine = currLine.substr(pos+1);
// Looking out if we have to save the procparams
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
saveParams = atoi(currLine.substr(0, pos).c_str());
currLine = currLine.substr(pos+1);
// Looking out if we have to to use the format options
pos = currLine.find('|');
if (pos != Glib::ustring::npos) {
forceFormatOpts = atoi(currLine.substr(0, pos).c_str());
// currLine = currLine.substr(pos+1);
}}}}}}}}}}}}}
if( !source.empty() && !paramsFile.empty() ){
rtengine::procparams::ProcParams pparams; rtengine::procparams::ProcParams pparams;
if( pparams.load( paramsFile ) ) if( pparams.load( paramsFile ) )
continue; continue;
@ -194,6 +302,20 @@ void BatchQueue::loadBatchQueue( )
entry->resize(options.thumbSize); entry->resize(options.thumbSize);
entry->savedParamsFile = paramsFile; entry->savedParamsFile = paramsFile;
entry->selected = false; entry->selected = false;
entry->outFileName = outputFile;
if (!outputFile.empty()) {
entry->saveFormat.format = saveFmt;
entry->saveFormat.jpegQuality = jpegQuality;
entry->saveFormat.jpegSubSamp = jpegSubSamp;
entry->saveFormat.pngBits = pngBits;
entry->saveFormat.pngCompression = pngCompression;
entry->saveFormat.tiffBits = tiffBits;
entry->saveFormat.tiffUncompressed = tiffUncompressed!=0;
entry->saveFormat.saveParams = saveParams!=0;
entry->forceFormatOpts = forceFormatOpts!=0;
}
else
entry->forceFormatOpts = false;
fd.push_back(entry); fd.push_back(entry);
BatchQueueButtonSet* bqbs = new BatchQueueButtonSet(entry); BatchQueueButtonSet* bqbs = new BatchQueueButtonSet(entry);
@ -379,8 +501,14 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) {
fname = autoCompleteFileName (s, saveFormat.format); fname = autoCompleteFileName (s, saveFormat.format);
} }
else { // use the save-as filename with automatic completion for uniqueness else { // use the save-as filename with automatic completion for uniqueness
fname = autoCompleteFileName (removeExtension(processing->outFileName), getExtension(processing->outFileName)); if (processing->forceFormatOpts)
saveFormat = processing->saveFormat; saveFormat = processing->saveFormat;
else
saveFormat = options.saveFormatBatch;
// The output filename's extension is forced to the current or selected output format,
// despite what the user have set in the fielneame's field of the "Save as" dialgo box
fname = autoCompleteFileName (removeExtension(processing->outFileName), saveFormat.format);
//fname = autoCompleteFileName (removeExtension(processing->outFileName), getExtension(processing->outFileName));
} }
//printf ("fname=%s, %s\n", fname.c_str(), removeExtension(fname).c_str()); //printf ("fname=%s, %s\n", fname.c_str(), removeExtension(fname).c_str());

View File

@ -21,11 +21,16 @@
#include <cstring> #include <cstring>
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "multilangmgr.h"
bool BatchQueueEntry::iconsLoaded(false);
Glib::RefPtr<Gdk::Pixbuf> BatchQueueEntry::savedAsIcon;
BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thm) BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thm)
: ThumbBrowserEntryBase(fname), : ThumbBrowserEntryBase(fname),
opreview(previmg), origpw(prevw), origph(prevh), opreview(previmg), origpw(prevw), origph(prevh),
job(pjob), progress(0), outFileName("") { job(pjob), progress(0), outFileName(""), forceFormatOpts(false) {
thumbnail=thm; thumbnail=thm;
params = pparams; params = pparams;
@ -38,8 +43,13 @@ BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine:
bqih->pending = 0; bqih->pending = 0;
#endif #endif
if (!iconsLoaded) {
savedAsIcon = safe_create_from_file ("gtk-save.png");
iconsLoaded = true;
}
if (thumbnail) if (thumbnail)
thumbnail->increaseRef (); thumbnail->increaseRef ();
} }
BatchQueueEntry::~BatchQueueEntry () { BatchQueueEntry::~BatchQueueEntry () {
@ -107,6 +117,55 @@ void BatchQueueEntry::removeButtonSet () {
buttonSet = NULL; buttonSet = NULL;
} }
std::vector<Glib::RefPtr<Gdk::Pixbuf> > BatchQueueEntry::getIconsOnImageArea () {
std::vector<Glib::RefPtr<Gdk::Pixbuf> > ret;
if (!outFileName.empty())
ret.push_back (savedAsIcon);
return ret;
}
void BatchQueueEntry::getIconSize (int& w, int& h) {
w = savedAsIcon->get_width ();
h = savedAsIcon->get_height ();
}
Glib::ustring BatchQueueEntry::getToolTip (int x, int y) {
// get the parent class' tooltip first
Glib::ustring tooltip = ThumbBrowserEntryBase::getToolTip(x, y);
// add the saving param options
if (!outFileName.empty()) {
tooltip += Glib::ustring::compose("\n\n%1: %2", M("BATCHQUEUE_DESTFILENAME"), outFileName);
if (forceFormatOpts) {
tooltip += Glib::ustring::compose("\n\n%1: %2 (%3 bits)", M("SAVEDLG_FILEFORMAT"), saveFormat.format,
saveFormat.format == "png" ? saveFormat.pngBits :
saveFormat.format == "tif" ? saveFormat.tiffBits : 8);
if (saveFormat.format == "jpg") {
tooltip += Glib::ustring::compose("\n%1: %2\n%3: %4",
M("SAVEDLG_JPEGQUAL"), saveFormat.jpegQuality,
M("SAVEDLG_SUBSAMP"),
saveFormat.jpegSubSamp==1 ? M("SAVEDLG_SUBSAMP_1") :
saveFormat.jpegSubSamp==2 ? M("SAVEDLG_SUBSAMP_2") :
M("SAVEDLG_SUBSAMP_3"));
}
else if (saveFormat.format == "png")
tooltip += Glib::ustring::compose("\n%1: %2", M("SAVEDLG_PNGCOMPR"), saveFormat.pngCompression);
else if (saveFormat.format == "tif") {
if (saveFormat.tiffUncompressed)
tooltip += Glib::ustring::compose("\n%1", M("SAVEDLG_TIFFUNCOMPRESSED"));
}
}
}
return tooltip;
}
#ifndef WIN32 #ifndef WIN32
struct BQUpdateParam { struct BQUpdateParam {

View File

@ -37,14 +37,19 @@ class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListen
guint8* opreview; guint8* opreview;
int origpw, origph; int origpw, origph;
BatchQueueEntryIdleHelper* bqih; BatchQueueEntryIdleHelper* bqih;
static bool iconsLoaded;
public: public:
static Glib::RefPtr<Gdk::Pixbuf> savedAsIcon;
rtengine::ProcessingJob* job; rtengine::ProcessingJob* job;
rtengine::procparams::ProcParams params; rtengine::procparams::ProcParams params;
Glib::ustring savedParamsFile; Glib::ustring savedParamsFile;
double progress; double progress;
Glib::ustring outFileName; Glib::ustring outFileName;
SaveFormat saveFormat; SaveFormat saveFormat;
bool forceFormatOpts;
BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thm=NULL); BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thm=NULL);
~BatchQueueEntry (); ~BatchQueueEntry ();
@ -56,6 +61,10 @@ public:
void removeButtonSet (); void removeButtonSet ();
virtual std::vector<Glib::RefPtr<Gdk::Pixbuf> > getIconsOnImageArea ();
virtual void getIconSize (int& w, int& h);
virtual Glib::ustring getToolTip (int x, int y);
// bqentryupdatelistener interface // bqentryupdatelistener interface
void updateImage (guint8* img, int w, int h); void updateImage (guint8* img, int w, int h);
void _updateImage (guint8* img, int w, int h); // inside gtk thread void _updateImage (guint8* img, int w, int h); // inside gtk thread

View File

@ -1084,6 +1084,7 @@ void EditorPanel::saveAsPressed () {
lastSaveAsFileName = Glib::path_get_basename (removeExtension (fnameOut)); lastSaveAsFileName = Glib::path_get_basename (removeExtension (fnameOut));
SaveFormat sf = saveAsDialog->getFormat (); SaveFormat sf = saveAsDialog->getFormat ();
options.saveFormat = sf; options.saveFormat = sf;
options.forceFormatOpts = saveAsDialog->getForceFormatOpts ();
if (result != Gtk::RESPONSE_OK) if (result != Gtk::RESPONSE_OK)
break; break;
@ -1132,6 +1133,7 @@ void EditorPanel::saveAsPressed () {
BatchQueueEntry* bqe = createBatchQueueEntry (); BatchQueueEntry* bqe = createBatchQueueEntry ();
bqe->outFileName = fnameOut; bqe->outFileName = fnameOut;
bqe->saveFormat = saveAsDialog->getFormat (); bqe->saveFormat = saveAsDialog->getFormat ();
bqe->forceFormatOpts = saveAsDialog->getForceFormatOpts ();
parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ()); parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ());
fnameOK = true; fnameOK = true;
} }

View File

@ -27,7 +27,7 @@
#define CROPRESIZEBORDER 4 #define CROPRESIZEBORDER 4
bool FileBrowserEntry::iconsLoaded = false; bool FileBrowserEntry::iconsLoaded(false);
Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::editedIcon; Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::editedIcon;
Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::recentlySavedIcon; Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::recentlySavedIcon;
Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::enqueuedIcon; Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::enqueuedIcon;

View File

@ -77,9 +77,9 @@ public:
void refreshThumbnailImage (); void refreshThumbnailImage ();
void refreshQuickThumbnailImage (); void refreshQuickThumbnailImage ();
void calcThumbnailSize (); void calcThumbnailSize ();
std::vector<Glib::RefPtr<Gdk::Pixbuf> > getIconsOnImageArea (); virtual std::vector<Glib::RefPtr<Gdk::Pixbuf> > getIconsOnImageArea ();
void getIconSize (int& w, int& h); virtual void getIconSize (int& w, int& h);
// thumbnaillistener interface // thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt); void procParamsChanged (Thumbnail* thm, int whoChangedIt);
@ -87,9 +87,9 @@ public:
void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams);
void _updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); // inside gtk thread void _updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); // inside gtk thread
bool motionNotify (int x, int y); virtual bool motionNotify (int x, int y);
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);
bool releaseNotify (int button, int type, int bstate, int x, int y); virtual bool releaseNotify (int button, int type, int bstate, int x, int y);
}; };
#endif #endif

View File

@ -269,6 +269,7 @@ void Options::setDefaults () {
maxCacheEntries = 20000; maxCacheEntries = 20000;
thumbInterp = 1; thumbInterp = 1;
autoSuffix = false; autoSuffix = false;
forceFormatOpts = false;
saveMethodNum = 0; // 0->immediate, 1->putToQueuHead, 2->putToQueueTail saveMethodNum = 0; // 0->immediate, 1->putToQueuHead, 2->putToQueueTail
saveParamsFile = true; // was false, but saving the procparams files next to the file make more sense when reorganizing file tree than in a cache saveParamsFile = true; // was false, but saving the procparams files next to the file make more sense when reorganizing file tree than in a cache
saveParamsCache = false; // there's no need to save the procparams files in a cache if saveParamsFile is true saveParamsCache = false; // there's no need to save the procparams files in a cache if saveParamsFile is true
@ -493,7 +494,7 @@ int Options::readFromFile (Glib::ustring fname) {
if (!keyFile.load_from_file (fname)) if (!keyFile.load_from_file (fname))
return 1; return 1;
} }
catch (Glib::FileError) { catch (Glib::FileError &err) {
return 1; return 1;
} }
@ -555,6 +556,7 @@ if (keyFile.has_group ("Output")) {
if (keyFile.has_key ("Output", "PathTemplate")) savePathTemplate = keyFile.get_string ("Output", "PathTemplate"); if (keyFile.has_key ("Output", "PathTemplate")) savePathTemplate = keyFile.get_string ("Output", "PathTemplate");
if (keyFile.has_key ("Output", "PathFolder")) savePathFolder = keyFile.get_string ("Output", "PathFolder"); if (keyFile.has_key ("Output", "PathFolder")) savePathFolder = keyFile.get_string ("Output", "PathFolder");
if (keyFile.has_key ("Output", "AutoSuffix")) autoSuffix = keyFile.get_boolean("Output", "AutoSuffix"); if (keyFile.has_key ("Output", "AutoSuffix")) autoSuffix = keyFile.get_boolean("Output", "AutoSuffix");
if (keyFile.has_key ("Output", "ForceFormatOpts")) forceFormatOpts = keyFile.get_boolean("Output", "ForceFormatOpts");
if (keyFile.has_key ("Output", "SaveMethodNum")) saveMethodNum = keyFile.get_integer("Output", "SaveMethodNum"); if (keyFile.has_key ("Output", "SaveMethodNum")) saveMethodNum = keyFile.get_integer("Output", "SaveMethodNum");
if (keyFile.has_key ("Output", "UsePathTemplate")) saveUsePathTemplate = keyFile.get_boolean("Output", "UsePathTemplate"); if (keyFile.has_key ("Output", "UsePathTemplate")) saveUsePathTemplate = keyFile.get_boolean("Output", "UsePathTemplate");
if (keyFile.has_key ("Output", "LastSaveAsPath")) lastSaveAsPath = keyFile.get_string ("Output", "LastSaveAsPath"); if (keyFile.has_key ("Output", "LastSaveAsPath")) lastSaveAsPath = keyFile.get_string ("Output", "LastSaveAsPath");
@ -853,6 +855,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_string ("Output", "PathTemplate", savePathTemplate); keyFile.set_string ("Output", "PathTemplate", savePathTemplate);
keyFile.set_string ("Output", "PathFolder", savePathFolder); keyFile.set_string ("Output", "PathFolder", savePathFolder);
keyFile.set_boolean ("Output", "AutoSuffix", autoSuffix); keyFile.set_boolean ("Output", "AutoSuffix", autoSuffix);
keyFile.set_boolean ("Output", "ForceFormatOpts", forceFormatOpts);
keyFile.set_integer ("Output", "SaveMethodNum", saveMethodNum); keyFile.set_integer ("Output", "SaveMethodNum", saveMethodNum);
keyFile.set_boolean ("Output", "UsePathTemplate", saveUsePathTemplate); keyFile.set_boolean ("Output", "UsePathTemplate", saveUsePathTemplate);
keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath); keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath);

View File

@ -141,6 +141,7 @@ class Options {
bool useSystemTheme; bool useSystemTheme;
static Glib::ustring cacheBaseDir; static Glib::ustring cacheBaseDir;
bool autoSuffix; bool autoSuffix;
bool forceFormatOpts;
int saveMethodNum; int saveMethodNum;
bool saveParamsFile; bool saveParamsFile;
bool saveParamsCache; bool saveParamsCache;

View File

@ -53,11 +53,6 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
formatChanged (options.saveFormat.format); formatChanged (options.saveFormat.format);
// Unique filename option
// ~~~~~~~~~~~~~~~~~~~~~~
autoSuffix = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_AUTOSUFFIX")) );
autoSuffix->set_active(options.autoSuffix);
// Output Options // Output Options
// ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~
formatOpts = Gtk::manage( new SaveFormatPanel () ); formatOpts = Gtk::manage( new SaveFormatPanel () );
@ -65,7 +60,7 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
formatOpts->setListener (this); formatOpts->setListener (this);
// queue/immediate // queue/immediate
// ~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~
saveMethod[0] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_SAVEIMMEDIATELY")) ); saveMethod[0] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_SAVEIMMEDIATELY")) );
saveMethod[1] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUEHEAD")) ); saveMethod[1] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUEHEAD")) );
saveMethod[2] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUETAIL")) ); saveMethod[2] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUETAIL")) );
@ -77,8 +72,26 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
if (options.saveMethodNum >= 0 && options.saveMethodNum < 3) if (options.saveMethodNum >= 0 && options.saveMethodNum < 3)
saveMethod[options.saveMethodNum]->set_active (true); saveMethod[options.saveMethodNum]->set_active (true);
saveMethod[0]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::saveImmediatlyClicked) );
saveMethod[1]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::putToQueueClicked) );
saveMethod[2]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::putToQueueClicked) );
// Force output format option
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
forceFormatOpts = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_FORCEFORMATOPTS")) );
forceFormatOpts->set_active(options.forceFormatOpts);
forceFormatOpts->set_sensitive(options.saveMethodNum>0);
forceFormatOpts->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::forceFmtOptsSwitched) );
// update sensitivity of the SaveFormatPanel
formatOpts->set_sensitive(options.saveMethodNum==0 || options.forceFormatOpts);
// Unique filename option
// ~~~~~~~~~~~~~~~~~~~~~~
autoSuffix = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_AUTOSUFFIX")) );
autoSuffix->set_active(options.autoSuffix);
// buttons // buttons
// ~~~~~~ // ~~~~~~~
Gtk::Button* ok = Gtk::manage( new Gtk::Button (M("GENERAL_OK")) ); Gtk::Button* ok = Gtk::manage( new Gtk::Button (M("GENERAL_OK")) );
Gtk::Button* cancel = Gtk::manage( new Gtk::Button (M("GENERAL_CANCEL")) ); Gtk::Button* cancel = Gtk::manage( new Gtk::Button (M("GENERAL_CANCEL")) );
@ -98,6 +111,7 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
vbox_bottomRight->pack_start (*saveMethod[2], Gtk::PACK_SHRINK, 2); vbox_bottomRight->pack_start (*saveMethod[2], Gtk::PACK_SHRINK, 2);
vbox_bottomRight->pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 5); vbox_bottomRight->pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 5);
} }
vbox_bottomRight->pack_start (*forceFormatOpts, Gtk::PACK_SHRINK, 4);
vbox_bottomRight->pack_start (*autoSuffix, Gtk::PACK_SHRINK, 4); vbox_bottomRight->pack_start (*autoSuffix, Gtk::PACK_SHRINK, 4);
Gtk::HBox* hbox_bottom = Gtk::manage( new Gtk::HBox() ); Gtk::HBox* hbox_bottom = Gtk::manage( new Gtk::HBox() );
@ -116,6 +130,25 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
} }
void SaveAsDialog::saveImmediatlyClicked () {
forceFormatOpts->set_sensitive(false);
formatOpts->set_sensitive(true);
}
void SaveAsDialog::putToQueueClicked () {
forceFormatOpts->set_sensitive(true);
formatOpts->set_sensitive(forceFormatOpts->get_active());
}
void SaveAsDialog::forceFmtOptsSwitched () {
formatOpts->set_sensitive(forceFormatOpts->get_active());
}
bool SaveAsDialog::getForceFormatOpts () {
return forceFormatOpts->get_active();
}
bool SaveAsDialog::getAutoSuffix () { bool SaveAsDialog::getAutoSuffix () {
return autoSuffix->get_active(); return autoSuffix->get_active();

View File

@ -29,6 +29,7 @@ class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener {
protected: protected:
Gtk::FileChooserWidget* fchooser; Gtk::FileChooserWidget* fchooser;
Gtk::CheckButton* autoSuffix; Gtk::CheckButton* autoSuffix;
Gtk::CheckButton* forceFormatOpts;
SaveFormatPanel* formatOpts; SaveFormatPanel* formatOpts;
Glib::ustring fname; Glib::ustring fname;
Gtk::FileFilter filter_jpg; Gtk::FileFilter filter_jpg;
@ -38,18 +39,22 @@ class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener {
* 1 -> putToQueueHead * 1 -> putToQueueHead
* 2 -> putToQueueTail * 2 -> putToQueueTail
*/ */
void forceFmtOptsSwitched ();
void saveImmediatlyClicked ();
void putToQueueClicked ();
public: public:
SaveAsDialog (Glib::ustring initialDir); SaveAsDialog (Glib::ustring initialDir);
Glib::ustring getFileName (); Glib::ustring getFileName ();
Glib::ustring getDirectory (); Glib::ustring getDirectory ();
SaveFormat getFormat (); SaveFormat getFormat ();
bool getAutoSuffix (); bool getForceFormatOpts ();
bool getImmediately (); bool getAutoSuffix ();
bool getToHeadOfQueue (); bool getImmediately ();
bool getToTailOfQueue (); bool getToHeadOfQueue ();
int getSaveMethodNum (); bool getToTailOfQueue ();
int getSaveMethodNum ();
void setInitialFileName (Glib::ustring iname); void setInitialFileName (Glib::ustring iname);
void setImagePath (Glib::ustring ipath); void setImagePath (Glib::ustring ipath);

View File

@ -133,7 +133,7 @@ void ThumbBrowserEntryBase::updateBackBuffer () {
if (!bbIcons.empty()) { if (!bbIcons.empty()) {
int iwidth = igap; int iwidth = igap;
int iheight = 0; int iheight = 0;
for (size_t i=0; i<bbIcons.size(); i++) { for (size_t i=0; i<bbIcons.size(); i++) {
iwidth += bbIcons[i]->get_width() + igap; iwidth += bbIcons[i]->get_width() + igap;
if (bbIcons[i]->get_height() > iheight) if (bbIcons[i]->get_height() > iheight)
iheight = bbIcons[i]->get_height(); iheight = bbIcons[i]->get_height();

View File

@ -133,7 +133,7 @@ protected:
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);
virtual bool releaseNotify (int button, int type, int bstate, int x, int y); virtual bool releaseNotify (int button, int type, int bstate, int x, int y);
Glib::ustring getToolTip (int x, int y); virtual Glib::ustring getToolTip (int x, int y);
}; };
#endif #endif