diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK)
index 8806f0f11..b1c58da85 100644
--- a/rtdata/languages/English (UK)
+++ b/rtdata/languages/English (UK)
@@ -712,3 +712,13 @@ HISTOGRAM_BUTTON_L;L
###
CURVEEDITOR_NURBS;Control cage
+
+###
+
+MAIN_BUTTON_SAVE_TOOLTIP;Save current image Ctrl+S
+MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Add current image to processing queue Ctrl+Q
+MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor Ctrl+E
+
+###
+
+SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists
diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US)
index cfa30f8d8..059aaa914 100644
--- a/rtdata/languages/English (US)
+++ b/rtdata/languages/English (US)
@@ -721,3 +721,6 @@ MAIN_BUTTON_SAVE_TOOLTIP;Save current image Ctrl+S
MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Add current image to processing queue Ctrl+Q
MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor Ctrl+E
+###
+
+SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists
diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index 07d2f5b4a..0becaf548 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -723,3 +723,6 @@ MAIN_BUTTON_SAVE_TOOLTIP;Enregistrer l'image courante Ctrl+S
MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Ajouter l'image courante à la file de traitement Ctrl+Q
MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Éditer l'image courante dans l'éditeur externe Ctrl+E
+###
+
+SAVEDLG_AUTOSUFFIX;Ajouter automatiquement un suffixe si le fichier existe déjà
diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc
index 9a934c85f..8cfed601d 100644
--- a/rtengine/dcraw.cc
+++ b/rtengine/dcraw.cc
@@ -6099,7 +6099,7 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ "Canon EOS", 0, 0,
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
{ "Canon PowerShot A530", 0, 0,
- { 0 } }, /* don't want the A5 matrix */
+ { 0 } }, /* don't want the A5 matrix */
{ "Canon PowerShot A50", 0, 0,
{ -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
{ "Canon PowerShot A5", 0, 0,
@@ -8937,7 +8937,7 @@ dcrMutex->lock ();
ifname = fname;//strdup (fname);
image = NULL;
-
+
exif_base = -1;
ciff_base = -1;
ciff_len = -1;
@@ -9012,23 +9012,23 @@ dcrMutex->lock ();
if (filters) {
ri->allocation = (short unsigned int*)calloc(height*width, sizeof(unsigned short));
ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*));
- for (int i=0; idata[i] = ri->allocation + i*width;
- for (int row = 0; row < height; row++)
- for (int col = 0; col < width; col++)
+ for (int row = 0; row < height; row++)
+ for (int col = 0; col < width; col++)
if (ISGREEN(ri,row,col))
ri->data[row][col] = image[row*width+col][1];
else if (ISRED(ri,row,col))
ri->data[row][col] = image[row*width+col][0];
- else
+ else
ri->data[row][col] = image[row*width+col][2];
}
else {
ri->allocation = (short unsigned int*)calloc(3*height*width, sizeof(unsigned short));
ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*));
- for (int i=0; idata[i] = ri->allocation + 3*i*width;
- for (int row = 0; row < height; row++)
+ for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++) {
ri->data[row][3*col+0] = image[row*width+col][0];
ri->data[row][3*col+1] = image[row*width+col][1];
@@ -9079,7 +9079,7 @@ dcrMutex->lock ();
exif_base = -1;
ciff_base = -1;
ciff_len = -1;
-
+
half_size = 1;
bright = 1.0;
verbose = settings->verbose;
@@ -9165,8 +9165,8 @@ t1.set ();
fclose (ifp);
dcrMutex->unlock ();
return NULL;
- }
-
+ }
+
use_camera_wb = 0;
highlight = 1;
half_size = 0;
@@ -9180,7 +9180,7 @@ t1.set ();
}
t2.set();
-
+
iheight = ::height;
iwidth = ::width;
@@ -9193,7 +9193,7 @@ t2.set();
if (zero_is_bad) remove_zeroes();
rtengine::Thumbnail* tpp = new rtengine::Thumbnail;
-
+
tpp->isRaw = true;
tpp->embProfileLength = 0;
if (profile_length) {
@@ -9207,12 +9207,12 @@ t2.set();
tpp->embProfile = NULL;
tpp->embProfileData = NULL;
}
-
+
fclose(ifp);
tpp->redMultiplier = pre_mul[0];
tpp->greenMultiplier = pre_mul[1];
tpp->blueMultiplier = pre_mul[2];
-
+
t3.set ();
scale_colors();
@@ -9221,13 +9221,13 @@ t3.set ();
unsigned filter = filters;
int firstgreen = 1;
// locate first green location in the first row
- while (!FISGREEN(filter,1,firstgreen))
+ while (!FISGREEN(filter,1,firstgreen))
firstgreen++;
int skip = 1;
if (fixwh==1) // fix height, scale width
skip = (::height-firstgreen-1) / h;
- else
+ else
skip = (::width-firstgreen-1) / w;
if (skip%2)
skip--;
@@ -9237,7 +9237,7 @@ t3.set ();
int hskip = skip, vskip = skip;
if (!strcmp (model, "D1X"))
hskip *=2;
-
+
rml.exifBase = exif_base;
rml.ciffBase = ciff_base;
rml.ciffLength = ciff_len;
@@ -9245,7 +9245,7 @@ t3.set ();
tpp->camwbGreen = tpp->greenMultiplier / pre_mul[1];
tpp->camwbBlue = tpp->blueMultiplier / pre_mul[2];
- tpp->defGain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]);
+ tpp->defGain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]);
tpp->gammaCorrected = true;
int ix = 0;
@@ -9272,7 +9272,7 @@ t3.set ();
tmpImg->g[y][x] = g;
tmpImg->b[y][x] = b;
}
- }
+ }
}
else {
for (int row=1, y=0; row< ::height-1 && yg[y][x] = image[ofs][1];
tmpImg->b[y][x] = image[ofs][2];
}
- }
+ }
}
-
+
if (fuji_width) {
int fw = fuji_width / hskip;
double step = sqrt(0.5);
@@ -9298,7 +9298,7 @@ t3.set ();
for (int col=0; col < wide; col++) {
unsigned ur = r = fw + (row-col)*step;
unsigned uc = c = (row+col)*step;
- if (ur > tmph-2 || uc > tmpw-2)
+ if (ur > tmph-2 || uc > tmpw-2)
continue;
double fr = r - ur;
double fc = c - uc;
@@ -9311,22 +9311,22 @@ t3.set ();
delete tmpImg;
tmpImg = fImg;
}
-
-
+
+
if (fixwh==1) // fix height, scale width
w = tmpw * h / tmph;
else
h = tmph * w / tmpw;
-
+
tpp->thumbImg = tmpImg->resize (w, h, TI_Bilinear);
delete tmpImg;
if (fuji_width)
tpp->scale = (double)(::height - fuji_width) / sqrt(0.5) / h;
else
- tpp->scale = (double)::height / h;
-
-t4.set ();
+ tpp->scale = (double)::height / h;
+
+t4.set ();
// generate histogram for auto exposure
tpp->aeHistCompression = 3;
@@ -9348,7 +9348,7 @@ t4.set ();
start = 8;
end = ::width-8;
}
- for (int j=start; jaeHistogram[image[i* ::width+j][1]>>tpp->aeHistCompression]+=gadd;
else if (FISRED(filter,i,j))
@@ -9356,7 +9356,7 @@ t4.set ();
else if (FISBLUE(filter,i,j))
tpp->aeHistogram[image[i* ::width+j][2]>>tpp->aeHistCompression]+=badd;
}
-
+
t5.set ();
// generate autoWB
@@ -9376,7 +9376,7 @@ t5.set ();
start = 32;
end = ::width-32;
}
- for (int j=start; jdefGain * image[i* ::width+j][1];
if (d>64000)
@@ -9404,7 +9404,7 @@ t5.set ();
double reds = pow (avg_r/rn, 1.0/6.0) * tpp->camwbRed;
double greens = pow (avg_g/gn, 1.0/6.0) * tpp->camwbGreen;
double blues = pow (avg_b/bn, 1.0/6.0) * tpp->camwbBlue;
-
+
double rm = rgb_cam[0][0]*reds + rgb_cam[0][1]*greens + rgb_cam[0][2]*blues;
double gm = rgb_cam[1][0]*reds + rgb_cam[1][1]*greens + rgb_cam[1][2]*blues;
double bm = rgb_cam[2][0]*reds + rgb_cam[2][1]*greens + rgb_cam[2][2]*blues;
@@ -9413,7 +9413,7 @@ t5.set ();
t6.set ();
-if (settings->verbose) printf ("0: %d, 1: %d, 2: %d, 3: %d, 4: %d, 5: %d All: %d\n", t1.etime(t0), t2.etime(t1), t3.etime(t2), t4.etime(t3), t5.etime(t4), t6.etime(t5), t6.etime(t0));
+if (settings->verbose) printf ("0: %d, 1: %d, 2: %d, 3: %d, 4: %d, 5: %d All: %d\n", t1.etime(t0), t2.etime(t1), t3.etime(t2), t4.etime(t3), t5.etime(t4), t6.etime(t5), t6.etime(t0));
int deg = 0;
if (flip==5)
@@ -9434,7 +9434,7 @@ if (settings->verbose) printf ("0: %d, 1: %d, 2: %d, 3: %d, 4: %d, 5: %d All: %d
tpp->colorMatrix[a][b] = rgb_cam[a][b];
tpp->init ();
-
+
free (image);
dcrMutex->unlock ();
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index d9458024a..e79fefb5f 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -201,7 +201,16 @@ void ImProcCoordinator::updatePreviewImage (int todo) {
progress ("Conversion to RGB...",100*readyphase/numofphases);
if (todo!=CROP) {
previmg->getMutex().lock();
- ipf.lab2rgb (nprevl, previmg);
+ try
+ {
+ ipf.lab2rgb (nprevl, previmg);
+ }
+ catch(char * str)
+ {
+ progress ("Error converting file...",0);
+ mProcessing.unlock ();
+ return;
+ }
previmg->getMutex().unlock();
}
if (!resultValid) {
diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc
index 659d839a2..c03c346f4 100644
--- a/rtengine/iplab2rgb.cc
+++ b/rtengine/iplab2rgb.cc
@@ -38,6 +38,9 @@ extern const Settings* settings;
void ImProcFunctions::lab2rgb (LabImage* lab, Image8* image) {
+ if (chroma_scale == 0)
+ throw "Division by zero exception";
+
if (monitorTransform) {
int ix = 0;
short* buffer = new short [3*lab->W];
diff --git a/rtengine/loadinitial.cc.orig b/rtengine/loadinitial.cc.orig
new file mode 100644
index 000000000..308005e30
--- /dev/null
+++ b/rtengine/loadinitial.cc.orig
@@ -0,0 +1,43 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2004-2010 Gabor Horvath
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+#include
+#include
+#include
+
+namespace rtengine {
+
+InitialImage* InitialImage::load (const Glib::ustring& fname, bool isRaw, int* errorCode, ProgressListener* pl) {
+
+ ImageSource* isrc;
+
+ if (!isRaw)
+ isrc = new StdImageSource ();
+ else
+ isrc = new RawImageSource ();
+
+ isrc->setProgressListener (pl);
+ *errorCode = isrc->load (fname);
+ if (*errorCode) {
+ delete isrc;
+ return NULL;
+ }
+ return isrc;
+}
+}
+
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index b64238e3b..8ac174d4f 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -222,7 +222,7 @@ void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl) {
void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl) {
if (bpl)
- Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl), 0, false, true, Glib::THREAD_PRIORITY_NORMAL);
+ Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl), 0, false, true, Glib::THREAD_PRIORITY_LOW);
}
}
diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc
index 61713d845..c2999933c 100644
--- a/rtgui/batchqueue.cc
+++ b/rtgui/batchqueue.cc
@@ -197,14 +197,17 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) {
if (img && fname!="") {
int err = 0;
if (saveFormat.format=="tif")
- err = img->saveAsTIFF (fname, saveFormat.tiffBits);
+ err = img->saveAsTIFF (fname, saveFormat.tiffBits,saveFormat.tiffUncompressed);
else if (saveFormat.format=="png")
err = img->saveAsPNG (fname, saveFormat.pngCompression, saveFormat.pngBits);
else if (saveFormat.format=="jpg")
err = img->saveAsJPEG (fname, saveFormat.jpegQuality);
img->free ();
if (!err && saveFormat.saveParams)
- processing->params.save (removeExtension(fname) + paramFileExtension);
+ // We keep the extension to avoid overwriting the profile when we have
+ // the same output filename with different extension
+ //processing->params.save (removeExtension(fname) + paramFileExtension);
+ processing->params.save (fname + paramFileExtension);
if (processing->thumbnail) {
processing->thumbnail->imageDeveloped ();
processing->thumbnail->imageRemovedFromQueue ();
diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc
index f98cab189..2f4a42170 100644
--- a/rtgui/bqentryupdater.cc
+++ b/rtgui/bqentryupdater.cc
@@ -59,7 +59,7 @@ void BatchQueueEntryUpdater::process () {
if (stopped)
#undef THREAD_PRIORITY_NORMAL
- thread = Glib::Thread::create(sigc::mem_fun(*this, &BatchQueueEntryUpdater::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL);
+ thread = Glib::Thread::create(sigc::mem_fun(*this, &BatchQueueEntryUpdater::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_LOW);
}
void BatchQueueEntryUpdater::process_ () {
diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc
index 16b4d6172..7d6ae81d7 100644
--- a/rtgui/editorpanel.cc
+++ b/rtgui/editorpanel.cc
@@ -1,961 +1,961 @@
-/*
- * This file is part of RawTherapee.
- *
- * Copyright (c) 2004-2010 Gabor Horvath
- *
- * RawTherapee is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * RawTherapee is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with RawTherapee. If not, see .
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace rtengine::procparams;
-
-EditorPanel::EditorPanel (FilePanel* filePanel) : beforePreviewHandler(NULL), beforeIarea(NULL), parent(NULL), beforeIpc(NULL) {
-
- epih = new EditorPanelIdleHelper;
- epih->epanel = this;
- epih->destroyed = false;
- epih->pending = 0;
-
-// construct toolpanelcoordinator
- tpc = new ToolPanelCoordinator ();
-
-// build GUI
- // build left side panel
- leftbox = new Gtk::VBox ();
- leftbox->set_border_width (4);
-
- histogramPanel = Gtk::manage (new HistogramPanel ());
- histogramPanel->set_size_request (-1, 150);
-// leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4);
-
- profilep = Gtk::manage (new ProfilePanel ());
- Gtk::Frame* ppframe = Gtk::manage (new Gtk::Frame ());
- ppframe->add (*profilep);
- ppframe->set_label (M("PROFILEPANEL_LABEL"));
-// leftbox->pack_start (*ppframe, Gtk::PACK_SHRINK, 4);
-
- navigator = Gtk::manage (new Navigator ());
- navigator->previewWindow->set_size_request (-1, 150);
- leftbox->pack_start (*navigator, Gtk::PACK_SHRINK, 4);
-
- history = Gtk::manage (new History ());
- leftbox->pack_start (*history);
-
- leftbox->show_all ();
-
- // build the middle of the screen
- Gtk::VBox* editbox = Gtk::manage (new Gtk::VBox ());
-
- info = Gtk::manage (new Gtk::ToggleButton ());
- Gtk::Image* infoimg = Gtk::manage (new Gtk::Image (argv0+"/images/info.png"));
- info->add (*infoimg);
- info->set_relief(Gtk::RELIEF_NONE);
- info->set_tooltip_markup (M("MAIN_TOOLTIP_QINFO"));
-
- beforeAfter = Gtk::manage (new Gtk::ToggleButton ());
- Gtk::Image* beforeAfterIcon = Gtk::manage (new Gtk::Image (argv0+"/images/beforeafter.png"));
- beforeAfter->add(*beforeAfterIcon);
- beforeAfter->set_relief(Gtk::RELIEF_NONE);
- beforeAfter->set_tooltip_markup (M("MAIN_TOOLTIP_TOGGLE"));
-
-
- Gtk::VSeparator* vsept = Gtk::manage (new Gtk::VSeparator ());
- Gtk::VSeparator* vsepz = Gtk::manage (new Gtk::VSeparator ());
- Gtk::VSeparator* vsepi = Gtk::manage (new Gtk::VSeparator ());
- Gtk::VSeparator* vseph = Gtk::manage (new Gtk::VSeparator ());
-
- hidehp = Gtk::manage (new Gtk::ToggleButton ());
- Gtk::Label* hidehpLabel = Gtk::manage (new Gtk::Label ());
- hidehpLabel->set_markup ("H");
- Gtk::Image* hpimg = Gtk::manage (new Gtk::Image (argv0+"/images/left.png"));
- Gtk::HBox* hidehpBox = Gtk::manage (new Gtk::HBox ());
- hidehpBox->pack_start (*hpimg, Gtk::PACK_SHRINK, 2);
- hidehpBox->pack_start (*hidehpLabel, Gtk::PACK_SHRINK, 2);
- hidehp->add (*hidehpBox);
- hidehp->set_relief(Gtk::RELIEF_NONE);
- hidehp->set_active (options.showHistory);
- hidehp->set_tooltip_markup (M("MAIN_TOOLTIP_HIDEHP"));
-
- Gtk::VSeparator* vsepcl = Gtk::manage (new Gtk::VSeparator ());
- Gtk::VSeparator* vsepz2 = Gtk::manage (new Gtk::VSeparator ());
-
- iarea = new ImageAreaPanel ();
-
- Gtk::HBox* toolBarPanel = Gtk::manage (new Gtk::HBox ());
- toolBarPanel->pack_start (*hidehp, Gtk::PACK_SHRINK, 1);
- toolBarPanel->pack_start (*vseph, Gtk::PACK_SHRINK, 2);
- toolBarPanel->pack_start (*info, Gtk::PACK_SHRINK, 1);
- toolBarPanel->pack_start (*beforeAfter, Gtk::PACK_SHRINK, 1);
- toolBarPanel->pack_start (*vsepi, Gtk::PACK_SHRINK, 2);
- toolBarPanel->pack_start (*tpc->getToolBar(), Gtk::PACK_SHRINK, 1);
- toolBarPanel->pack_start (*vsept, Gtk::PACK_SHRINK, 2);
- toolBarPanel->pack_end (*tpc->coarse, Gtk::PACK_SHRINK, 4);
- toolBarPanel->pack_end (*vsepcl, Gtk::PACK_SHRINK, 4);
- toolBarPanel->pack_end (*iarea->imageArea->indClippedPanel, Gtk::PACK_SHRINK, 0);
- toolBarPanel->pack_end (*vsepz, Gtk::PACK_SHRINK, 2);
-
- afterBox = Gtk::manage (new Gtk::VBox ());
- afterBox->pack_start (*iarea);
-
- beforeAfterBox = Gtk::manage (new Gtk::HBox());
- beforeAfterBox->pack_start (*afterBox);
-
- editbox->pack_start (*toolBarPanel, Gtk::PACK_SHRINK);
- editbox->pack_start (*beforeAfterBox);
-
- // build right side panel
- vboxright = new Gtk::VBox (false, 0);
- vboxright->set_border_width (4);
- vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4);
- vboxright->pack_start (*ppframe, Gtk::PACK_SHRINK, 4);
- // main notebook
- vboxright->pack_start (*tpc->toolPanelNotebook);
-
- // Save buttons
- Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ());
-
- Gtk::HBox * saveButtonBox = Gtk::manage(new Gtk::HBox());
- saveButtonBox->pack_start(*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)), Gtk::PACK_SHRINK, 2);
- saveButtonBox->pack_start(*Gtk::manage (new Gtk::Label (M("MAIN_BUTTON_SAVE"))), Gtk::PACK_SHRINK, 2);
- saveimgas = Gtk::manage (new Gtk::Button ());
- saveimgas->add(*saveButtonBox);
- saveimgas->set_tooltip_markup(M("MAIN_BUTTON_SAVE_TOOLTIP"));
-
- Gtk::HBox * queueButtonBox = Gtk::manage(new Gtk::HBox());
- queueButtonBox->pack_start(*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-execute"), Gtk::ICON_SIZE_BUTTON)), Gtk::PACK_SHRINK, 2);
- queueButtonBox->pack_start(*Gtk::manage (new Gtk::Label (M("MAIN_BUTTON_PUTTOQUEUE"))), Gtk::PACK_SHRINK, 2);
- queueimg = Gtk::manage (new Gtk::Button ());
- queueimg->add(*queueButtonBox);
- queueimg->set_tooltip_markup(M("MAIN_BUTTON_PUTTOQUEUE_TOOLTIP"));
-
- Gtk::HBox * sendToEditorButtonBox = Gtk::manage(new Gtk::HBox());
- sendToEditorButtonBox->pack_start(*Gtk::manage (new Gtk::Image (argv0+"/images/gimp.png")), Gtk::PACK_SHRINK, 2);
- sendToEditorButtonBox->pack_start(*Gtk::manage (new Gtk::Label (M("MAIN_BUTTON_SENDTOEDITOR"))), Gtk::PACK_SHRINK, 2);
- sendtogimp = Gtk::manage (new Gtk::Button ());
- sendtogimp->add(*sendToEditorButtonBox);
- sendtogimp->set_tooltip_markup(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP"));
-
- iops->pack_start (*saveimgas, Gtk::PACK_SHRINK);
- iops->pack_start (*queueimg, Gtk::PACK_SHRINK);
- iops->pack_start (*sendtogimp, Gtk::PACK_SHRINK);
-
- // Status box
- statusBox = Gtk::manage (new Gtk::HBox ());
- progressLabel = Gtk::manage (new Gtk::Label(""));
- statusBox->pack_start (*progressLabel);
- red = new Gtk::Image (argv0+"/images/red.png");
- green = new Gtk::Image (argv0+"/images/green.png");
- red->show ();
- green->show ();
- statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4);
- iops->pack_start(*statusBox, Gtk::PACK_SHRINK, 4);
-
- // Zoom panel
- iops->pack_end (*iarea->imageArea->zoomPanel, Gtk::PACK_SHRINK, 1);
- iops->pack_end (*vsepz2, Gtk::PACK_SHRINK, 2);
-
-
- editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 4);
- editbox->pack_start (*iops, Gtk::PACK_SHRINK, 4);
- editbox->show_all ();
-
- // build screen
- hpanedl = Gtk::manage (new Gtk::HPaned());
- hpanedr = Gtk::manage (new Gtk::HPaned());
- leftbox->reference ();
- vboxright->reference ();
- if (options.showHistory) {
- hpanedl->pack1(*leftbox, false, true);
- hpanedl->set_position (options.historyPanelWidth);
- }
-
- ipc = NULL;
- btpCoordinator = new BatchToolPanelCoordinator (filePanel);
- fCatalog = new FileCatalog (btpCoordinator->coarse, btpCoordinator->getToolBar()); //, filePanel->fileCatalog->fileBrowser);
- filePanel->dirBrowser->addDirSelectionListener (fCatalog);
- // fCatalog->setFilterPanel (filePanel->filterPanel);
- fCatalog->setImageAreaToolListener (btpCoordinator);
- fCatalog->setFileSelectionListener (filePanel);
- fCatalog->setFileSelectionChangeListener (btpCoordinator);
- fCatalog->setEnabled(true);
-
- Gtk::VPaned * viewpaned = Gtk::manage (new Gtk::VPaned());
- viewpaned->pack1(*fCatalog, false, true);
- viewpaned->pack2(*editbox, true, true);
-
- Gtk::Frame* vbfr = Gtk::manage (new Gtk::Frame ());
- vbfr->add (*viewpaned);
- hpanedl->pack2(*vbfr, true, true);
-
- hpanedr->pack1(*hpanedl, true, true);
- hpanedr->pack2(*vboxright, false, true);
-
- pack_start (*hpanedr);
- show_all ();
-
- // save as dialog
- if (Glib::file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR))
- saveAsDialog = new SaveAsDialog (options.lastSaveAsPath);
- else
- saveAsDialog = new SaveAsDialog (Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES));
-
- saveAsDialog->set_default_size (options.saveAsDialogWidth, options.saveAsDialogHeight);
-
-// connect listeners
- profilep->setProfileChangeListener (tpc);
- history->setProfileChangeListener (tpc);
- history->setHistoryBeforeLineListener (this);
- tpc->addPParamsChangeListener (profilep);
- tpc->addPParamsChangeListener (history);
- tpc->addPParamsChangeListener (this);
- iarea->imageArea->setCropGUIListener (tpc->getCropGUIListener());
- iarea->imageArea->setPointerMotionListener (navigator);
- iarea->imageArea->setImageAreaToolListener (tpc);
-
-// initialize components
- info->set_active (options.showInfo);
- tpc->readOptions ();
-
-// connect event handlers
- info->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::info_toggled) );
- beforeAfter->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::beforeAfterToggled) );
- hidehp->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::hideHistoryActivated) );
- saveimgas->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::saveAsPressed) );
- queueimg->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::queueImgPressed) );
- sendtogimp->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::sendToGimpPressed) );
-
-}
-
-bool EditorPanel::beforeClosing () {
-
- options.toolPanelWidth = vboxright->get_width ();
- return true;
-}
-
-EditorPanel::~EditorPanel () {
-
- history->setHistoryBeforeLineListener (NULL);
- // the order is important!
- delete iarea;
- delete beforeIarea;
-
- if (ipc)
- ipc->setPreviewImageListener (NULL);
- if (beforeIpc)
- beforeIpc->setPreviewImageListener (NULL);
-
- delete previewHandler;
- delete beforePreviewHandler;
-
- if (ipc)
- close ();
-
- if (epih->pending)
- epih->destroyed = true;
- else
- delete epih;
-
- delete tpc;
-
- delete red;
- delete green;
- delete leftbox;
- delete vboxright;
-
- delete saveAsDialog;
-}
-
-void EditorPanel::on_realize () {
-
- Gtk::VBox::on_realize ();
- vboxright->set_size_request (options.toolPanelWidth, -1);
-}
-
-void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) {
-
- if (ipc) close();
- // initialize everything
- openThm = tmb;
- openThm->increaseRef ();
-
- previewHandler = new PreviewHandler ();
-
- this->isrc = isrc;
- ipc = rtengine::StagedImageProcessor::create (isrc);
- ipc->setProgressListener (this);
- ipc->setPreviewImageListener (previewHandler);
- ipc->setPreviewScale (10);
- tpc->initImage (ipc, tmb->getType()==FT_Raw);
- ipc->setHistogramListener (this);
-
-// iarea->fitZoom (); // tell to the editorPanel that the next image has to be fitted to the screen
- iarea->imageArea->setPreviewHandler (previewHandler);
- iarea->imageArea->setImProcCoordinator (ipc);
- navigator->previewWindow->setPreviewHandler (previewHandler);
- navigator->previewWindow->setImageArea (iarea->imageArea);
-
- // try to load the last saved parameters from the cache or from the paramfile file
- ProcParams* ldprof = NULL;
- if (openThm->hasProcParams()) {
- ldprof = new ProcParams ();
- *ldprof = openThm->getProcParams ();
- }
-
- // initialize profile
- if (openThm->getType()!=FT_Raw)
- profilep->initProfile (options.defProfImg, ldprof, NULL);
- else
- profilep->initProfile (options.defProfRaw, ldprof, NULL);
-
- openThm->addThumbnailListener (this);
- info_toggled ();
-
- if (beforeIarea)
- {
- beforeAfterToggled();
- beforeAfterToggled();
- }
-
- Gtk::Allocation r;
- iarea->imageArea->on_resized(r);
- //iarea->show_all();
- //hpanedl->show_all();
- //show_all();
-
-}
-
-void EditorPanel::close () {
-
- if (ipc)
- {
- saveProfile ();
- // close image processor and the current thumbnail
- tpc->closeImage (); // this call stops image processing
- tpc->writeOptions ();
-
- if (ipc)
- ipc->setPreviewImageListener (NULL);
-
- if (beforeIpc)
- beforeIpc->setPreviewImageListener (NULL);
-
- delete previewHandler;
- previewHandler= NULL;
-// delete beforePreviewHandler;
-// beforePreviewHandler = NULL;
-
- delete iarea->imageArea->mainCropWindow;
- iarea->imageArea->mainCropWindow = NULL;
-
- rtengine::StagedImageProcessor::destroy (ipc);
- ipc = NULL;
-
- iarea->imageArea->setPreviewHandler (NULL);
- iarea->imageArea->setImProcCoordinator (NULL);
- navigator->previewWindow->setPreviewHandler (NULL);
- // navigator->previewWindow->setImageArea (NULL);
-
- openThm->removeThumbnailListener (this);
- openThm->decreaseRef ();
-
-
- }
-}
-
-void EditorPanel::saveProfile () {
-
- ProcParams params;
- ipc->getParams (¶ms);
-
- if (options.saveParamsFile)
- params.save (openThm->getFileName() + paramFileExtension);
- if (openThm && options.saveParamsCache)
- openThm->setProcParams (params, EDITOR);
-}
-
-Glib::ustring EditorPanel::getShortName () {
-
- return Glib::path_get_basename (openThm->getFileName ());
-}
-
-Glib::ustring EditorPanel::getFileName () {
-
- return openThm->getFileName ();
-}
-
-// TODO!!!
-void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) {
-
-// if (ev!=EvPhotoLoaded)
-// saveLabel->set_markup (Glib::ustring("") + M("MAIN_BUTTON_SAVE") + "");
-}
-
-struct spsparams {
- bool state;
- EditorPanelIdleHelper* epih;
-};
-
-int setprocstate (void* data) {
-
- gdk_threads_enter ();
- spsparams* p = (spsparams*)data;
-
- if (p->epih->destroyed) {
- if (p->epih->pending == 1)
- delete p->epih;
- else
- p->epih->pending--;
- delete p;
- gdk_threads_leave ();
- return 0;
- }
-
- p->epih->epanel->refreshProcessingState (p->state);
- p->epih->pending--;
- delete p;
- gdk_threads_leave ();
- return 0;
-}
-
-void EditorPanel::setProgressState (int state) {
-
- epih->pending++;
-
- spsparams* p = new spsparams;
- p->state = state;
- p->epih = epih;
- g_idle_add (setprocstate, p);
-}
-
-void EditorPanel::refreshProcessingState (bool state) {
-
- // Set proc params of thumbnail. It saves it into the cache and updates the file browser.
- if (ipc && openThm && !state && tpc->getChangedState()) {
- rtengine::procparams::ProcParams pparams;
- ipc->getParams (&pparams);
- openThm->setProcParams (pparams, EDITOR, false);
- }
-
- // change state of the led
- std::vector children = (std::vector) statusBox->get_children();
- if (children.size()>=1) {
- Gtk::Widget* wlast = children[children.size()-1];
- if (wlast)
- statusBox->remove (*wlast);
- }
- if (state)
- statusBox->pack_end (*red, Gtk::PACK_SHRINK, 4);
- else
- statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4);
-}
-
-struct errparams {
- Glib::ustring descr;
- EditorPanelIdleHelper* epih;
-};
-
-void EditorPanel::displayError (Glib::ustring descr) {
-
- if (parent) {
- Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, descr, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
- msgd->set_title (M("MAIN_MSG_CANNOTSAVE"));
- msgd->run ();
- delete msgd;
- }
-}
-
-int disperror (void* data) {
-
- gdk_threads_enter ();
- errparams* p = (errparams*)data;
-
- if (p->epih->destroyed) {
- if (p->epih->pending == 1)
- delete p->epih;
- else
- p->epih->pending--;
- delete p;
- gdk_threads_leave ();
- return 0;
- }
-
- p->epih->epanel->displayError (p->descr);
- p->epih->pending--;
- delete p;
- gdk_threads_leave ();
- return 0;
-}
-
-void EditorPanel::error (Glib::ustring descr) {
-
- epih->pending++;
- errparams* p = new errparams;
- p->descr = descr;
- p->epih = epih;
- g_idle_add (disperror, p);
-}
-
-void EditorPanel::info_toggled () {
-
- Glib::ustring infoString;
-
- const rtengine::ImageMetaData* idata = ipc->getInitialImage()->getMetaData();
- if (idata && idata->hasExif())
- infoString = Glib::ustring::compose ("%1 %2\nF/%3 %4 sec\n%5: %6\n%7: %8 mm\n",
- Glib::ustring(idata->getMake()), Glib::ustring(idata->getModel()),
- Glib::ustring(idata->apertureToString(idata->getFNumber())), Glib::ustring(idata->shutterToString(idata->getShutterSpeed())),
- M("QINFO_ISO"), idata->getISOSpeed(),
- M("QINFO_FOCALLENGTH"), idata->getFocalLen())
- + Glib::ustring::compose ("%1: %2", M("QINFO_LENS"), Glib::ustring(idata->getLens()));
- else
- infoString = M("QINFO_NOEXIF");
-
- iarea->imageArea->setInfoText (infoString);
- iarea->imageArea->infoEnabled (info->get_active ());
-}
-
-void EditorPanel::hideHistoryActivated () {
-
- removeIfThere (hpanedl, leftbox, false);
- if (hidehp->get_active())
- hpanedl->pack1 (*leftbox, false, true);
- options.showHistory = hidehp->get_active();
-}
-
-bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
-
- bool ctrl = event->state & GDK_CONTROL_MASK;
- bool shift = event->state & GDK_SHIFT_MASK;
-
- if (!ctrl) {
- switch(event->keyval) {
- case GDK_h:
- case GDK_H:
- hidehp->set_active (!hidehp->get_active());
- return true;
- case GDK_w:
- case GDK_W:
- tpc->getToolBar()->wb_pressed ();
- return true;
- case GDK_c:
- case GDK_C:
- tpc->getToolBar()->crop_pressed ();
- return true;
- case GDK_s:
- case GDK_S:
- tpc->getToolBar()->stra_pressed ();
- return true;
- case GDK_n:
- case GDK_N:
- tpc->getToolBar()->hand_pressed ();
- return true;
- case GDK_i:
- case GDK_I:
- info->set_active (!info->get_active());
- return true;
- case GDK_b:
- case GDK_B:
- beforeAfter->set_active (!beforeAfter->get_active());
- return true;
- case GDK_plus:
- case GDK_equal:
- iarea->imageArea->zoomPanel->zoomInClicked();
- return true;
- case GDK_minus:
- case GDK_underscore:
- iarea->imageArea->zoomPanel->zoomOutClicked();
- return true;
- case GDK_1:
- iarea->imageArea->zoomPanel->zoom11Clicked();
- return true;
- case GDK_f:
- case GDK_F:
- iarea->imageArea->zoomPanel->zoomFitClicked();
- return true;
- }
- }
- else {
- switch (event->keyval) {
- case GDK_s:
- saveAsPressed();
- return true;
- case GDK_q:
- queueImgPressed();
- return true;
- case GDK_e:
- sendToGimpPressed();
- return true;
- case GDK_z:
- history->undo ();
- return true;
- case GDK_Z:
- history->redo ();
- return true;
- }
- }
-
- return false;
-}
-
-void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt) {
-
- if (whoChangedIt!=EDITOR)
- tpc->profileChange (&openThm->getProcParams(), rtengine::EvProfileChangeNotification, M("PROGRESSDLG_PROFILECHANGEDINBROWSER"));
-}
-
-bool EditorPanel::idle_saveImage (ProgressConnector *pc, Glib::ustring fname, SaveFormat sf, bool findNewNameIfNeeded){
- rtengine::IImage16* img = pc->returnValue();
- delete pc;
- if( img )
- saveImage( img, fname, sf, findNewNameIfNeeded);
- else{
- Glib::ustring msg_ = Glib::ustring("") + fname + ": Error during image processing\n";
- Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
- msgd.run ();
-
- saveimgas->set_sensitive(true);
- sendtogimp->set_sensitive(true);
-
- }
- return false;
-}
-
-BatchQueueEntry* EditorPanel::createBatchQueueEntry () {
-
- rtengine::procparams::ProcParams pparams;
- ipc->getParams (&pparams);
- rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
- int prevh = options.maxThumbnailHeight;
- int prevw = prevh;
- guint8* prev = NULL;//(guint8*) previewHandler->getImagePreview (prevw, prevh);
- double tmpscale;
- rtengine::IImage8* img = openThm->processThumbImage (pparams, options.maxThumbnailHeight, tmpscale);
- if (img) {
- prevw = img->getWidth ();
- prevh = img->getHeight ();
- prev = new guint8 [prevw*prevh*3];
- memcpy (prev, img->getData (), prevw*prevh*3);
- img->free();
- }
- return new BatchQueueEntry (job, pparams, openThm->getFileName(), prev, prevw, prevh, openThm);
-}
-
-int EditorPanel::saveImage (rtengine::IImage16* img, Glib::ustring& fname, SaveFormat sf, bool findNewNameIfNeeded) {
-
- Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format);
- if (findNewNameIfNeeded) {
- int tries = 1;
- while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) {
- fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format);
- tries++;
- }
- if (tries==1000)
- return -1000;
- }
- ProgressConnector *ld = new ProgressConnector();
- img->setSaveProgressListener (parent->getProgressListener());
- if (sf.format=="tif")
- ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsTIFF), fileName, sf.tiffBits, sf.tiffUncompressed),
- sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_imageSaved), ld, img, fileName,sf));
- else if (sf.format=="png")
- ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsPNG), fileName, sf.pngCompression, sf.pngBits),
- sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_imageSaved), ld, img, fileName,sf));
- else if (sf.format=="jpg")
- ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsJPEG), fileName, sf.jpegQuality),
- sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_imageSaved), ld, img, fileName,sf));
- return 0;
-}
-
-bool EditorPanel::idle_imageSaved(ProgressConnector *pc,rtengine::IImage16* img,Glib::ustring fname, SaveFormat sf){
- img->free ();
- if (! pc->returnValue() ) {
- openThm->imageDeveloped ();
- // save processing parameters, if needed
- if (sf.saveParams) {
- rtengine::procparams::ProcParams pparams;
- ipc->getParams (&pparams);
- pparams.save (removeExtension (fname) + ".out" + paramFileExtension);
- }
- }else{
- Glib::ustring msg_ = Glib::ustring("") + fname + ": Error during image saving\n";
- Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
- msgd.run ();
- }
- saveimgas->set_sensitive(true);
- sendtogimp->set_sensitive(true);
- parent->setProgressStr("");
- parent->setProgress(0.);
- delete pc;
- return false;
-}
-
-void EditorPanel::saveAsPressed () {
-
- // obtaining short name without extension
- saveAsDialog->setInitialFileName (removeExtension (Glib::path_get_basename (openThm->getFileName())));
- saveAsDialog->run ();
- Glib::ustring fname = saveAsDialog->getFileName ();
- if (fname=="")
- return;
-
- options.lastSaveAsPath = saveAsDialog->getDirectory ();
- options.saveAsDialogWidth = saveAsDialog->get_width();
- options.saveAsDialogHeight = saveAsDialog->get_height();
-
- SaveFormat sf = saveAsDialog->getFormat ();
- if (getExtension (fname)!=sf.format)
- fname = fname + "." + sf.format;
-
- options.saveFormat = sf;
-
- if (saveAsDialog->getImmediately ()) {
- // check if it exists
- if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) {
- Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + "";
- Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
- int response = msgd.run ();
- if (response==Gtk::RESPONSE_NO)
- return;
- }
- // save image
- rtengine::procparams::ProcParams pparams;
- ipc->getParams (&pparams);
- rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
- fname = removeExtension (fname);
- ProgressConnector *ld = new ProgressConnector();
- ld->startFunc(sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, parent->getProgressListener() ),
- sigc::bind(sigc::mem_fun( *this,&EditorPanel::idle_saveImage ),ld,fname,sf,false ));
- saveimgas->set_sensitive(false);
- sendtogimp->set_sensitive(false);
- }
- else {
- BatchQueueEntry* bqe = createBatchQueueEntry ();
- bqe->outFileName = fname;
- bqe->saveFormat = saveAsDialog->getFormat ();
- parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ());
- }
- // ask parent to redraw file browser
- // ... or does it automatically when the tab is switched to it
-}
-
-void EditorPanel::queueImgPressed () {
-
- saveProfile ();
- parent->addBatchQueueJob (createBatchQueueEntry ());
-}
-
-void EditorPanel::sendToGimpPressed () {
- // develop image
- rtengine::procparams::ProcParams pparams;
- ipc->getParams (&pparams);
- rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
- ProgressConnector *ld = new ProgressConnector();
- ld->startFunc(sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, parent->getProgressListener() ),
- sigc::bind(sigc::mem_fun( *this,&EditorPanel::idle_sendToGimp ),ld ));
- saveimgas->set_sensitive(false);
- sendtogimp->set_sensitive(false);
-}
-
-bool EditorPanel::idle_sendToGimp( ProgressConnector *pc){
-
- rtengine::IImage16* img = pc->returnValue();
- delete pc;
- if (img) {
- // get file name base
- Glib::ustring shortname = removeExtension (Glib::path_get_basename (openThm->getFileName()));
- Glib::ustring dirname = Glib::get_tmp_dir ();
- Glib::ustring fname = Glib::build_filename (dirname, shortname);
-
- SaveFormat sf;
- sf.format = "tif";
- sf.tiffBits = 16;
-
- Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format);
-
- int tries = 1;
- while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) {
- fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format);
- tries++;
- }
- if (tries==1000){
- img->free ();
- return false;
- }
-
- ProgressConnector *ld = new ProgressConnector();
- img->setSaveProgressListener (parent->getProgressListener());
- ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsTIFF), fileName, sf.tiffBits, sf.tiffUncompressed),
- sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_sentToGimp), ld, img, fileName));
- }else{
- Glib::ustring msg_ = Glib::ustring(" Error during image processing\n");
- Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
- msgd.run ();
- saveimgas->set_sensitive(true);
- sendtogimp->set_sensitive(true);
- }
- return false;
-}
-
-bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* img,Glib::ustring filename){
- img->free ();
- int errore = pc->returnValue();
- delete pc;
- if (!errore) {
- saveimgas->set_sensitive(true);
- sendtogimp->set_sensitive(true);
- parent->setProgressStr("");
- parent->setProgress(0.);
- bool success=false;
- Glib::ustring cmdLine;
- // start gimp
- if (options.editorToSendTo==1) {
-#ifdef _WIN32
- cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), "gimp-win-remote") + "\" gimp-2.4.exe" + " \"" + filename + "\"";
-#else
- cmdLine = Glib::ustring("gimp-remote ") + " \"" + filename + "\"";
-#endif
- success = safe_spawn_command_line_async (cmdLine);
- if (!success){
-#ifdef _WIN32
- int ver = 12;
- while (!success && ver) {
- cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), Glib::ustring::compose("gimp-2.%1.exe",ver)) + "\" \"" + filename + "\"";
- ver--;
- success = safe_spawn_command_line_async (cmdLine);
- }
-#elif defined __APPLE__
- cmdLine = Glib::ustring("gimp ") + " \"" + filename + "\"";
- success = safe_spawn_command_line_async (cmdLine);
-#else
- cmdLine = Glib::ustring("gimp ") + " \"" + filename + "\"";
- success = safe_spawn_command_line_async (cmdLine);
-#endif
- }
- }
- else if (options.editorToSendTo==2) {
-#ifdef __APPLE__
- cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir,"Photoshop.app\' ") + "\'" + filename + "\'";
-#else
- cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir,"Photoshop.exe") + "\" \"" + filename + "\"";
-#endif
- success = safe_spawn_command_line_async (cmdLine);
- }
- else if (options.editorToSendTo==3) {
-#ifdef __APPLE__
- cmdLine = Glib::ustring("") + options.customEditorProg + filename;
-#else
- cmdLine = Glib::ustring("\"") + options.customEditorProg + "\" \"" + filename + "\"";
-#endif
- success = safe_spawn_command_line_async (cmdLine);
- }
-
- if (!success) {
- Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
- msgd->set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY"));
- msgd->set_title (M("MAIN_BUTTON_SENDTOEDITOR"));
- msgd->run ();
- delete msgd;
- }
-
- }
-
- return false;
-}
-
-void EditorPanel::saveOptions () {
-
- close();
- options.historyPanelWidth = hpanedl->get_position ();
- options.toolPanelWidth = vboxright->get_width ();
- if (options.startupDir==STARTUPDIR_LAST && fCatalog->lastSelectedDir ()!="")
- options.startupPath = fCatalog->lastSelectedDir ();
- fCatalog->closeDir ();
-}
-
-void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) {
-
- if (beforeIpc) {
- ProcParams* pparams = beforeIpc->getParamsForUpdate (rtengine::EvProfileChanged);
- *pparams = params;
- beforeIpc->paramsUpdateReady ();
- }
-}
-
-void EditorPanel::beforeAfterToggled () {
-
- removeIfThere (beforeAfterBox, beforeBox, false);
- removeIfThere (afterBox, afterLabel, false);
-
- if (beforeIarea) {
- if (beforeIpc)
- beforeIpc->stopProcessing ();
- iarea->setBeforeAfterViews (NULL, iarea);
- delete beforeIarea;
- beforeIarea = NULL;
- if (beforeIpc)
- beforeIpc->setPreviewImageListener (NULL);
- delete beforePreviewHandler;
- beforePreviewHandler = NULL;
- if (beforeIpc)
- rtengine::StagedImageProcessor::destroy (beforeIpc);
- beforeIpc = NULL;
- }
-
- if (beforeAfter->get_active ()) {
-
- beforeIarea = new ImageAreaPanel ();
-
- beforeLabel = Gtk::manage (new Gtk::Label ());
- beforeLabel->set_markup (Glib::ustring("") + M("GENERAL_BEFORE") + "");
- beforeBox = Gtk::manage (new Gtk::VBox ());
- beforeBox->pack_start (*beforeLabel, Gtk::PACK_SHRINK, 2);
- beforeBox->pack_start (*beforeIarea);
-
- afterLabel = Gtk::manage (new Gtk::Label ());
- afterLabel->set_markup (Glib::ustring("") + M("GENERAL_AFTER") + "");
- afterBox->pack_start (*afterLabel, Gtk::PACK_SHRINK, 2);
- afterBox->reorder_child (*afterLabel, 0);
-
- beforeAfterBox->pack_start (*beforeBox);
- beforeAfterBox->reorder_child (*beforeBox, 0);
- beforeAfterBox->show_all ();
-
- beforePreviewHandler = new PreviewHandler ();
- isrc->increaseRef ();
- beforeIpc = rtengine::StagedImageProcessor::create (isrc);
- beforeIpc->setPreviewScale (10);
- beforeIpc->setPreviewImageListener (beforePreviewHandler);
- beforeIarea->imageArea->setPreviewHandler (beforePreviewHandler);
- beforeIarea->imageArea->setImProcCoordinator (beforeIpc);
-
- iarea->setBeforeAfterViews (beforeIarea, iarea);
- beforeIarea->setBeforeAfterViews (beforeIarea, iarea);
-
- rtengine::procparams::ProcParams params;
- if (history->getBeforeLineParams (params))
- historyBeforeLineChanged (params);
- }
-}
-
-void EditorPanel::histogramChanged (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh, unsigned int* bcrgb, unsigned int* bcl) {
-
- histogramPanel->histogramChanged (rh, gh, bh, lh);
- tpc->updateCurveBackgroundHistogram (bcrgb, bcl);
-}
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2004-2010 Gabor Horvath
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace rtengine::procparams;
+
+EditorPanel::EditorPanel (FilePanel* filePanel) : beforePreviewHandler(NULL), beforeIarea(NULL), parent(NULL), beforeIpc(NULL) {
+
+ epih = new EditorPanelIdleHelper;
+ epih->epanel = this;
+ epih->destroyed = false;
+ epih->pending = 0;
+
+// construct toolpanelcoordinator
+ tpc = new ToolPanelCoordinator ();
+
+// build GUI
+ // build left side panel
+ leftbox = new Gtk::VBox ();
+ leftbox->set_border_width (4);
+
+ histogramPanel = Gtk::manage (new HistogramPanel ());
+ histogramPanel->set_size_request (-1, 150);
+// leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4);
+
+ profilep = Gtk::manage (new ProfilePanel ());
+ Gtk::Frame* ppframe = Gtk::manage (new Gtk::Frame ());
+ ppframe->add (*profilep);
+ ppframe->set_label (M("PROFILEPANEL_LABEL"));
+// leftbox->pack_start (*ppframe, Gtk::PACK_SHRINK, 4);
+
+ navigator = Gtk::manage (new Navigator ());
+ navigator->previewWindow->set_size_request (-1, 150);
+ leftbox->pack_start (*navigator, Gtk::PACK_SHRINK, 4);
+
+ history = Gtk::manage (new History ());
+ leftbox->pack_start (*history);
+
+ leftbox->show_all ();
+
+ // build the middle of the screen
+ Gtk::VBox* editbox = Gtk::manage (new Gtk::VBox ());
+
+ info = Gtk::manage (new Gtk::ToggleButton ());
+ Gtk::Image* infoimg = Gtk::manage (new Gtk::Image (argv0+"/images/info.png"));
+ info->add (*infoimg);
+ info->set_relief(Gtk::RELIEF_NONE);
+ info->set_tooltip_markup (M("MAIN_TOOLTIP_QINFO"));
+
+ beforeAfter = Gtk::manage (new Gtk::ToggleButton ());
+ Gtk::Image* beforeAfterIcon = Gtk::manage (new Gtk::Image (argv0+"/images/beforeafter.png"));
+ beforeAfter->add(*beforeAfterIcon);
+ beforeAfter->set_relief(Gtk::RELIEF_NONE);
+ beforeAfter->set_tooltip_markup (M("MAIN_TOOLTIP_TOGGLE"));
+
+
+ Gtk::VSeparator* vsept = Gtk::manage (new Gtk::VSeparator ());
+ Gtk::VSeparator* vsepz = Gtk::manage (new Gtk::VSeparator ());
+ Gtk::VSeparator* vsepi = Gtk::manage (new Gtk::VSeparator ());
+ Gtk::VSeparator* vseph = Gtk::manage (new Gtk::VSeparator ());
+
+ hidehp = Gtk::manage (new Gtk::ToggleButton ());
+ Gtk::Label* hidehpLabel = Gtk::manage (new Gtk::Label ());
+ hidehpLabel->set_markup ("H");
+ Gtk::Image* hpimg = Gtk::manage (new Gtk::Image (argv0+"/images/left.png"));
+ Gtk::HBox* hidehpBox = Gtk::manage (new Gtk::HBox ());
+ hidehpBox->pack_start (*hpimg, Gtk::PACK_SHRINK, 2);
+ hidehpBox->pack_start (*hidehpLabel, Gtk::PACK_SHRINK, 2);
+ hidehp->add (*hidehpBox);
+ hidehp->set_relief(Gtk::RELIEF_NONE);
+ hidehp->set_active (options.showHistory);
+ hidehp->set_tooltip_markup (M("MAIN_TOOLTIP_HIDEHP"));
+
+ Gtk::VSeparator* vsepcl = Gtk::manage (new Gtk::VSeparator ());
+ Gtk::VSeparator* vsepz2 = Gtk::manage (new Gtk::VSeparator ());
+
+ iarea = new ImageAreaPanel ();
+
+ Gtk::HBox* toolBarPanel = Gtk::manage (new Gtk::HBox ());
+ toolBarPanel->pack_start (*hidehp, Gtk::PACK_SHRINK, 1);
+ toolBarPanel->pack_start (*vseph, Gtk::PACK_SHRINK, 2);
+ toolBarPanel->pack_start (*info, Gtk::PACK_SHRINK, 1);
+ toolBarPanel->pack_start (*beforeAfter, Gtk::PACK_SHRINK, 1);
+ toolBarPanel->pack_start (*vsepi, Gtk::PACK_SHRINK, 2);
+ toolBarPanel->pack_start (*tpc->getToolBar(), Gtk::PACK_SHRINK, 1);
+ toolBarPanel->pack_start (*vsept, Gtk::PACK_SHRINK, 2);
+ toolBarPanel->pack_end (*tpc->coarse, Gtk::PACK_SHRINK, 4);
+ toolBarPanel->pack_end (*vsepcl, Gtk::PACK_SHRINK, 4);
+ toolBarPanel->pack_end (*iarea->imageArea->indClippedPanel, Gtk::PACK_SHRINK, 0);
+ toolBarPanel->pack_end (*vsepz, Gtk::PACK_SHRINK, 2);
+
+ afterBox = Gtk::manage (new Gtk::VBox ());
+ afterBox->pack_start (*iarea);
+
+ beforeAfterBox = Gtk::manage (new Gtk::HBox());
+ beforeAfterBox->pack_start (*afterBox);
+
+ editbox->pack_start (*toolBarPanel, Gtk::PACK_SHRINK);
+ editbox->pack_start (*beforeAfterBox);
+
+ // build right side panel
+ vboxright = new Gtk::VBox (false, 0);
+ vboxright->set_border_width (4);
+ vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4);
+ vboxright->pack_start (*ppframe, Gtk::PACK_SHRINK, 4);
+ // main notebook
+ vboxright->pack_start (*tpc->toolPanelNotebook);
+
+ // Save buttons
+ Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ());
+
+ Gtk::HBox * saveButtonBox = Gtk::manage(new Gtk::HBox());
+ saveButtonBox->pack_start(*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)), Gtk::PACK_SHRINK, 2);
+ saveButtonBox->pack_start(*Gtk::manage (new Gtk::Label (M("MAIN_BUTTON_SAVE"))), Gtk::PACK_SHRINK, 2);
+ saveimgas = Gtk::manage (new Gtk::Button ());
+ saveimgas->add(*saveButtonBox);
+ saveimgas->set_tooltip_markup(M("MAIN_BUTTON_SAVE_TOOLTIP"));
+
+ Gtk::HBox * queueButtonBox = Gtk::manage(new Gtk::HBox());
+ queueButtonBox->pack_start(*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-execute"), Gtk::ICON_SIZE_BUTTON)), Gtk::PACK_SHRINK, 2);
+ queueButtonBox->pack_start(*Gtk::manage (new Gtk::Label (M("MAIN_BUTTON_PUTTOQUEUE"))), Gtk::PACK_SHRINK, 2);
+ queueimg = Gtk::manage (new Gtk::Button ());
+ queueimg->add(*queueButtonBox);
+ queueimg->set_tooltip_markup(M("MAIN_BUTTON_PUTTOQUEUE_TOOLTIP"));
+
+ Gtk::HBox * sendToEditorButtonBox = Gtk::manage(new Gtk::HBox());
+ sendToEditorButtonBox->pack_start(*Gtk::manage (new Gtk::Image (argv0+"/images/gimp.png")), Gtk::PACK_SHRINK, 2);
+ sendToEditorButtonBox->pack_start(*Gtk::manage (new Gtk::Label (M("MAIN_BUTTON_SENDTOEDITOR"))), Gtk::PACK_SHRINK, 2);
+ sendtogimp = Gtk::manage (new Gtk::Button ());
+ sendtogimp->add(*sendToEditorButtonBox);
+ sendtogimp->set_tooltip_markup(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP"));
+
+ iops->pack_start (*saveimgas, Gtk::PACK_SHRINK);
+ iops->pack_start (*queueimg, Gtk::PACK_SHRINK);
+ iops->pack_start (*sendtogimp, Gtk::PACK_SHRINK);
+
+ // Status box
+ statusBox = Gtk::manage (new Gtk::HBox ());
+ progressLabel = Gtk::manage (new Gtk::Label(""));
+ statusBox->pack_start (*progressLabel);
+ red = new Gtk::Image (argv0+"/images/red.png");
+ green = new Gtk::Image (argv0+"/images/green.png");
+ red->show ();
+ green->show ();
+ statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4);
+ iops->pack_start(*statusBox, Gtk::PACK_SHRINK, 4);
+
+ // Zoom panel
+ iops->pack_end (*iarea->imageArea->zoomPanel, Gtk::PACK_SHRINK, 1);
+ iops->pack_end (*vsepz2, Gtk::PACK_SHRINK, 2);
+
+
+ editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 4);
+ editbox->pack_start (*iops, Gtk::PACK_SHRINK, 4);
+ editbox->show_all ();
+
+ // build screen
+ hpanedl = Gtk::manage (new Gtk::HPaned());
+ hpanedr = Gtk::manage (new Gtk::HPaned());
+ leftbox->reference ();
+ vboxright->reference ();
+ if (options.showHistory) {
+ hpanedl->pack1(*leftbox, false, true);
+ hpanedl->set_position (options.historyPanelWidth);
+ }
+
+ ipc = NULL;
+ btpCoordinator = new BatchToolPanelCoordinator (filePanel);
+ fCatalog = new FileCatalog (btpCoordinator->coarse, btpCoordinator->getToolBar()); //, filePanel->fileCatalog->fileBrowser);
+ filePanel->dirBrowser->addDirSelectionListener (fCatalog);
+ // fCatalog->setFilterPanel (filePanel->filterPanel);
+ fCatalog->setImageAreaToolListener (btpCoordinator);
+ fCatalog->setFileSelectionListener (filePanel);
+ fCatalog->setFileSelectionChangeListener (btpCoordinator);
+ fCatalog->setEnabled(true);
+
+ Gtk::VPaned * viewpaned = Gtk::manage (new Gtk::VPaned());
+ viewpaned->pack1(*fCatalog, false, true);
+ viewpaned->pack2(*editbox, true, true);
+
+ Gtk::Frame* vbfr = Gtk::manage (new Gtk::Frame ());
+ vbfr->add (*viewpaned);
+ hpanedl->pack2(*vbfr, true, true);
+
+ hpanedr->pack1(*hpanedl, true, true);
+ hpanedr->pack2(*vboxright, false, true);
+
+ pack_start (*hpanedr);
+ show_all ();
+
+ // save as dialog
+ if (Glib::file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR))
+ saveAsDialog = new SaveAsDialog (options.lastSaveAsPath);
+ else
+ saveAsDialog = new SaveAsDialog (Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES));
+
+ saveAsDialog->set_default_size (options.saveAsDialogWidth, options.saveAsDialogHeight);
+
+// connect listeners
+ profilep->setProfileChangeListener (tpc);
+ history->setProfileChangeListener (tpc);
+ history->setHistoryBeforeLineListener (this);
+ tpc->addPParamsChangeListener (profilep);
+ tpc->addPParamsChangeListener (history);
+ tpc->addPParamsChangeListener (this);
+ iarea->imageArea->setCropGUIListener (tpc->getCropGUIListener());
+ iarea->imageArea->setPointerMotionListener (navigator);
+ iarea->imageArea->setImageAreaToolListener (tpc);
+
+// initialize components
+ info->set_active (options.showInfo);
+ tpc->readOptions ();
+
+// connect event handlers
+ info->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::info_toggled) );
+ beforeAfter->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::beforeAfterToggled) );
+ hidehp->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::hideHistoryActivated) );
+ saveimgas->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::saveAsPressed) );
+ queueimg->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::queueImgPressed) );
+ sendtogimp->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::sendToGimpPressed) );
+
+}
+
+bool EditorPanel::beforeClosing () {
+
+ options.toolPanelWidth = vboxright->get_width ();
+ return true;
+}
+
+EditorPanel::~EditorPanel () {
+
+ history->setHistoryBeforeLineListener (NULL);
+ // the order is important!
+ delete iarea;
+ delete beforeIarea;
+
+ if (ipc)
+ ipc->setPreviewImageListener (NULL);
+ if (beforeIpc)
+ beforeIpc->setPreviewImageListener (NULL);
+
+ delete previewHandler;
+ delete beforePreviewHandler;
+
+ if (ipc)
+ close ();
+
+ if (epih->pending)
+ epih->destroyed = true;
+ else
+ delete epih;
+
+ delete tpc;
+
+ delete red;
+ delete green;
+ delete leftbox;
+ delete vboxright;
+
+ delete saveAsDialog;
+}
+
+void EditorPanel::on_realize () {
+
+ Gtk::VBox::on_realize ();
+ vboxright->set_size_request (options.toolPanelWidth, -1);
+}
+
+void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) {
+
+ if (ipc) close();
+ // initialize everything
+ openThm = tmb;
+ openThm->increaseRef ();
+
+ previewHandler = new PreviewHandler ();
+
+ this->isrc = isrc;
+ ipc = rtengine::StagedImageProcessor::create (isrc);
+ ipc->setProgressListener (this);
+ ipc->setPreviewImageListener (previewHandler);
+ ipc->setPreviewScale (10);
+ tpc->initImage (ipc, tmb->getType()==FT_Raw);
+ ipc->setHistogramListener (this);
+
+// iarea->fitZoom (); // tell to the editorPanel that the next image has to be fitted to the screen
+ iarea->imageArea->setPreviewHandler (previewHandler);
+ iarea->imageArea->setImProcCoordinator (ipc);
+ navigator->previewWindow->setPreviewHandler (previewHandler);
+ navigator->previewWindow->setImageArea (iarea->imageArea);
+
+ // try to load the last saved parameters from the cache or from the paramfile file
+ ProcParams* ldprof = NULL;
+ if (openThm->hasProcParams()) {
+ ldprof = new ProcParams ();
+ *ldprof = openThm->getProcParams ();
+ }
+
+ // initialize profile
+ if (openThm->getType()!=FT_Raw)
+ profilep->initProfile (options.defProfImg, ldprof, NULL);
+ else
+ profilep->initProfile (options.defProfRaw, ldprof, NULL);
+
+ openThm->addThumbnailListener (this);
+ info_toggled ();
+
+ if (beforeIarea)
+ {
+ beforeAfterToggled();
+ beforeAfterToggled();
+ }
+
+ Gtk::Allocation r;
+ iarea->imageArea->on_resized(r);
+ //iarea->show_all();
+ //hpanedl->show_all();
+ //show_all();
+
+}
+
+void EditorPanel::close () {
+
+ if (ipc)
+ {
+ saveProfile ();
+ // close image processor and the current thumbnail
+ tpc->closeImage (); // this call stops image processing
+ tpc->writeOptions ();
+
+ if (ipc)
+ ipc->setPreviewImageListener (NULL);
+
+ if (beforeIpc)
+ beforeIpc->setPreviewImageListener (NULL);
+
+ delete previewHandler;
+ previewHandler= NULL;
+// delete beforePreviewHandler;
+// beforePreviewHandler = NULL;
+
+ delete iarea->imageArea->mainCropWindow;
+ iarea->imageArea->mainCropWindow = NULL;
+
+ rtengine::StagedImageProcessor::destroy (ipc);
+ ipc = NULL;
+
+ iarea->imageArea->setPreviewHandler (NULL);
+ iarea->imageArea->setImProcCoordinator (NULL);
+ navigator->previewWindow->setPreviewHandler (NULL);
+ // navigator->previewWindow->setImageArea (NULL);
+
+ openThm->removeThumbnailListener (this);
+ openThm->decreaseRef ();
+
+
+ }
+}
+
+void EditorPanel::saveProfile () {
+
+ ProcParams params;
+ ipc->getParams (¶ms);
+
+ if (options.saveParamsFile)
+ params.save (openThm->getFileName() + paramFileExtension);
+ if (openThm && options.saveParamsCache)
+ openThm->setProcParams (params, EDITOR);
+}
+
+Glib::ustring EditorPanel::getShortName () {
+
+ return Glib::path_get_basename (openThm->getFileName ());
+}
+
+Glib::ustring EditorPanel::getFileName () {
+
+ return openThm->getFileName ();
+}
+
+// TODO!!!
+void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) {
+
+// if (ev!=EvPhotoLoaded)
+// saveLabel->set_markup (Glib::ustring("") + M("MAIN_BUTTON_SAVE") + "");
+}
+
+struct spsparams {
+ bool state;
+ EditorPanelIdleHelper* epih;
+};
+
+int setprocstate (void* data) {
+
+ gdk_threads_enter ();
+ spsparams* p = (spsparams*)data;
+
+ if (p->epih->destroyed) {
+ if (p->epih->pending == 1)
+ delete p->epih;
+ else
+ p->epih->pending--;
+ delete p;
+ gdk_threads_leave ();
+ return 0;
+ }
+
+ p->epih->epanel->refreshProcessingState (p->state);
+ p->epih->pending--;
+ delete p;
+ gdk_threads_leave ();
+ return 0;
+}
+
+void EditorPanel::setProgressState (int state) {
+
+ epih->pending++;
+
+ spsparams* p = new spsparams;
+ p->state = state;
+ p->epih = epih;
+ g_idle_add (setprocstate, p);
+}
+
+void EditorPanel::refreshProcessingState (bool state) {
+
+ // Set proc params of thumbnail. It saves it into the cache and updates the file browser.
+ if (ipc && openThm && !state && tpc->getChangedState()) {
+ rtengine::procparams::ProcParams pparams;
+ ipc->getParams (&pparams);
+ openThm->setProcParams (pparams, EDITOR, false);
+ }
+
+ // change state of the led
+ std::vector children = (std::vector) statusBox->get_children();
+ if (children.size()>=1) {
+ Gtk::Widget* wlast = children[children.size()-1];
+ if (wlast)
+ statusBox->remove (*wlast);
+ }
+ if (state)
+ statusBox->pack_end (*red, Gtk::PACK_SHRINK, 4);
+ else
+ statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4);
+}
+
+struct errparams {
+ Glib::ustring descr;
+ EditorPanelIdleHelper* epih;
+};
+
+void EditorPanel::displayError (Glib::ustring descr) {
+
+ if (parent) {
+ Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, descr, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+ msgd->set_title (M("MAIN_MSG_CANNOTSAVE"));
+ msgd->run ();
+ delete msgd;
+ }
+}
+
+int disperror (void* data) {
+
+ gdk_threads_enter ();
+ errparams* p = (errparams*)data;
+
+ if (p->epih->destroyed) {
+ if (p->epih->pending == 1)
+ delete p->epih;
+ else
+ p->epih->pending--;
+ delete p;
+ gdk_threads_leave ();
+ return 0;
+ }
+
+ p->epih->epanel->displayError (p->descr);
+ p->epih->pending--;
+ delete p;
+ gdk_threads_leave ();
+ return 0;
+}
+
+void EditorPanel::error (Glib::ustring descr) {
+
+ epih->pending++;
+ errparams* p = new errparams;
+ p->descr = descr;
+ p->epih = epih;
+ g_idle_add (disperror, p);
+}
+
+void EditorPanel::info_toggled () {
+
+ Glib::ustring infoString;
+
+ const rtengine::ImageMetaData* idata = ipc->getInitialImage()->getMetaData();
+ if (idata && idata->hasExif())
+ infoString = Glib::ustring::compose ("%1 %2\nF/%3 %4 sec\n%5: %6\n%7: %8 mm\n",
+ Glib::ustring(idata->getMake()), Glib::ustring(idata->getModel()),
+ Glib::ustring(idata->apertureToString(idata->getFNumber())), Glib::ustring(idata->shutterToString(idata->getShutterSpeed())),
+ M("QINFO_ISO"), idata->getISOSpeed(),
+ M("QINFO_FOCALLENGTH"), idata->getFocalLen())
+ + Glib::ustring::compose ("%1: %2", M("QINFO_LENS"), Glib::ustring(idata->getLens()));
+ else
+ infoString = M("QINFO_NOEXIF");
+
+ iarea->imageArea->setInfoText (infoString);
+ iarea->imageArea->infoEnabled (info->get_active ());
+}
+
+void EditorPanel::hideHistoryActivated () {
+
+ removeIfThere (hpanedl, leftbox, false);
+ if (hidehp->get_active())
+ hpanedl->pack1 (*leftbox, false, true);
+ options.showHistory = hidehp->get_active();
+}
+
+bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
+
+ bool ctrl = event->state & GDK_CONTROL_MASK;
+ bool shift = event->state & GDK_SHIFT_MASK;
+
+ if (!ctrl) {
+ switch(event->keyval) {
+ case GDK_h:
+ case GDK_H:
+ hidehp->set_active (!hidehp->get_active());
+ return true;
+ case GDK_w:
+ case GDK_W:
+ tpc->getToolBar()->wb_pressed ();
+ return true;
+ case GDK_c:
+ case GDK_C:
+ tpc->getToolBar()->crop_pressed ();
+ return true;
+ case GDK_s:
+ case GDK_S:
+ tpc->getToolBar()->stra_pressed ();
+ return true;
+ case GDK_n:
+ case GDK_N:
+ tpc->getToolBar()->hand_pressed ();
+ return true;
+ case GDK_i:
+ case GDK_I:
+ info->set_active (!info->get_active());
+ return true;
+ case GDK_b:
+ case GDK_B:
+ beforeAfter->set_active (!beforeAfter->get_active());
+ return true;
+ case GDK_plus:
+ case GDK_equal:
+ iarea->imageArea->zoomPanel->zoomInClicked();
+ return true;
+ case GDK_minus:
+ case GDK_underscore:
+ iarea->imageArea->zoomPanel->zoomOutClicked();
+ return true;
+ case GDK_1:
+ iarea->imageArea->zoomPanel->zoom11Clicked();
+ return true;
+ case GDK_f:
+ case GDK_F:
+ iarea->imageArea->zoomPanel->zoomFitClicked();
+ return true;
+ }
+ }
+ else {
+ switch (event->keyval) {
+ case GDK_s:
+ saveAsPressed();
+ return true;
+ case GDK_q:
+ queueImgPressed();
+ return true;
+ case GDK_e:
+ sendToGimpPressed();
+ return true;
+ case GDK_z:
+ history->undo ();
+ return true;
+ case GDK_Z:
+ history->redo ();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt) {
+
+ if (whoChangedIt!=EDITOR)
+ tpc->profileChange (&openThm->getProcParams(), rtengine::EvProfileChangeNotification, M("PROGRESSDLG_PROFILECHANGEDINBROWSER"));
+}
+
+bool EditorPanel::idle_saveImage (ProgressConnector *pc, Glib::ustring fname, SaveFormat sf, bool findNewNameIfNeeded){
+ rtengine::IImage16* img = pc->returnValue();
+ delete pc;
+ if( img )
+ saveImage( img, fname, sf, findNewNameIfNeeded);
+ else{
+ Glib::ustring msg_ = Glib::ustring("") + fname + ": Error during image processing\n";
+ Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+ msgd.run ();
+
+ saveimgas->set_sensitive(true);
+ sendtogimp->set_sensitive(true);
+
+ }
+ return false;
+}
+
+BatchQueueEntry* EditorPanel::createBatchQueueEntry () {
+
+ rtengine::procparams::ProcParams pparams;
+ ipc->getParams (&pparams);
+ rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
+ int prevh = options.maxThumbnailHeight;
+ int prevw = prevh;
+ guint8* prev = NULL;//(guint8*) previewHandler->getImagePreview (prevw, prevh);
+ double tmpscale;
+ rtengine::IImage8* img = openThm->processThumbImage (pparams, options.maxThumbnailHeight, tmpscale);
+ if (img) {
+ prevw = img->getWidth ();
+ prevh = img->getHeight ();
+ prev = new guint8 [prevw*prevh*3];
+ memcpy (prev, img->getData (), prevw*prevh*3);
+ img->free();
+ }
+ return new BatchQueueEntry (job, pparams, openThm->getFileName(), prev, prevw, prevh, openThm);
+}
+
+int EditorPanel::saveImage (rtengine::IImage16* img, Glib::ustring& fname, SaveFormat sf, bool findNewNameIfNeeded) {
+
+ Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format);
+ if (findNewNameIfNeeded) {
+ int tries = 1;
+ while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) {
+ fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format);
+ tries++;
+ }
+ if (tries==1000)
+ return -1000;
+ }
+ ProgressConnector *ld = new ProgressConnector();
+ img->setSaveProgressListener (parent->getProgressListener());
+ if (sf.format=="tif")
+ ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsTIFF), fileName, sf.tiffBits, sf.tiffUncompressed),
+ sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_imageSaved), ld, img, fileName,sf));
+ else if (sf.format=="png")
+ ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsPNG), fileName, sf.pngCompression, sf.pngBits),
+ sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_imageSaved), ld, img, fileName,sf));
+ else if (sf.format=="jpg")
+ ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsJPEG), fileName, sf.jpegQuality),
+ sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_imageSaved), ld, img, fileName,sf));
+ return 0;
+}
+
+bool EditorPanel::idle_imageSaved(ProgressConnector *pc,rtengine::IImage16* img,Glib::ustring fname, SaveFormat sf){
+ img->free ();
+ if (! pc->returnValue() ) {
+ openThm->imageDeveloped ();
+ // save processing parameters, if needed
+ if (sf.saveParams) {
+ rtengine::procparams::ProcParams pparams;
+ ipc->getParams (&pparams);
+ pparams.save (removeExtension (fname) + ".out" + paramFileExtension);
+ }
+ }else{
+ Glib::ustring msg_ = Glib::ustring("") + fname + ": Error during image saving\n";
+ Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+ msgd.run ();
+ }
+ saveimgas->set_sensitive(true);
+ sendtogimp->set_sensitive(true);
+ parent->setProgressStr("");
+ parent->setProgress(0.);
+ delete pc;
+ return false;
+}
+
+void EditorPanel::saveAsPressed () {
+
+ // obtaining short name without extension
+ saveAsDialog->setInitialFileName (removeExtension (Glib::path_get_basename (openThm->getFileName())));
+ saveAsDialog->run ();
+ Glib::ustring fname = saveAsDialog->getFileName ();
+ if (fname=="")
+ return;
+
+ options.lastSaveAsPath = saveAsDialog->getDirectory ();
+ options.saveAsDialogWidth = saveAsDialog->get_width();
+ options.saveAsDialogHeight = saveAsDialog->get_height();
+
+ SaveFormat sf = saveAsDialog->getFormat ();
+ if (getExtension (fname)!=sf.format)
+ fname = fname + "." + sf.format;
+
+ options.saveFormat = sf;
+
+ if (saveAsDialog->getImmediately ()) {
+ // check if it exists
+ if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) {
+ Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + "";
+ Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
+ int response = msgd.run ();
+ if (response==Gtk::RESPONSE_NO)
+ return;
+ }
+ // save image
+ rtengine::procparams::ProcParams pparams;
+ ipc->getParams (&pparams);
+ rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
+ fname = removeExtension (fname);
+ ProgressConnector *ld = new ProgressConnector();
+ ld->startFunc(sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, parent->getProgressListener() ),
+ sigc::bind(sigc::mem_fun( *this,&EditorPanel::idle_saveImage ),ld,fname,sf,false ));
+ saveimgas->set_sensitive(false);
+ sendtogimp->set_sensitive(false);
+ }
+ else {
+ BatchQueueEntry* bqe = createBatchQueueEntry ();
+ bqe->outFileName = fname;
+ bqe->saveFormat = saveAsDialog->getFormat ();
+ parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ());
+ }
+ // ask parent to redraw file browser
+ // ... or does it automatically when the tab is switched to it
+}
+
+void EditorPanel::queueImgPressed () {
+
+ saveProfile ();
+ parent->addBatchQueueJob (createBatchQueueEntry ());
+}
+
+void EditorPanel::sendToGimpPressed () {
+ // develop image
+ rtengine::procparams::ProcParams pparams;
+ ipc->getParams (&pparams);
+ rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
+ ProgressConnector *ld = new ProgressConnector();
+ ld->startFunc(sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, parent->getProgressListener() ),
+ sigc::bind(sigc::mem_fun( *this,&EditorPanel::idle_sendToGimp ),ld ));
+ saveimgas->set_sensitive(false);
+ sendtogimp->set_sensitive(false);
+}
+
+bool EditorPanel::idle_sendToGimp( ProgressConnector *pc){
+
+ rtengine::IImage16* img = pc->returnValue();
+ delete pc;
+ if (img) {
+ // get file name base
+ Glib::ustring shortname = removeExtension (Glib::path_get_basename (openThm->getFileName()));
+ Glib::ustring dirname = Glib::get_tmp_dir ();
+ Glib::ustring fname = Glib::build_filename (dirname, shortname);
+
+ SaveFormat sf;
+ sf.format = "tif";
+ sf.tiffBits = 16;
+
+ Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format);
+
+ int tries = 1;
+ while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) {
+ fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format);
+ tries++;
+ }
+ if (tries==1000){
+ img->free ();
+ return false;
+ }
+
+ ProgressConnector *ld = new ProgressConnector();
+ img->setSaveProgressListener (parent->getProgressListener());
+ ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsTIFF), fileName, sf.tiffBits, sf.tiffUncompressed),
+ sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_sentToGimp), ld, img, fileName));
+ }else{
+ Glib::ustring msg_ = Glib::ustring(" Error during image processing\n");
+ Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+ msgd.run ();
+ saveimgas->set_sensitive(true);
+ sendtogimp->set_sensitive(true);
+ }
+ return false;
+}
+
+bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* img,Glib::ustring filename){
+ img->free ();
+ int errore = pc->returnValue();
+ delete pc;
+ if (!errore) {
+ saveimgas->set_sensitive(true);
+ sendtogimp->set_sensitive(true);
+ parent->setProgressStr("");
+ parent->setProgress(0.);
+ bool success=false;
+ Glib::ustring cmdLine;
+ // start gimp
+ if (options.editorToSendTo==1) {
+#ifdef _WIN32
+ cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), "gimp-win-remote") + "\" gimp-2.4.exe" + " \"" + filename + "\"";
+#else
+ cmdLine = Glib::ustring("gimp-remote ") + " \"" + filename + "\"";
+#endif
+ success = safe_spawn_command_line_async (cmdLine);
+ if (!success){
+#ifdef _WIN32
+ int ver = 12;
+ while (!success && ver) {
+ cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), Glib::ustring::compose("gimp-2.%1.exe",ver)) + "\" \"" + filename + "\"";
+ ver--;
+ success = safe_spawn_command_line_async (cmdLine);
+ }
+#elif defined __APPLE__
+ cmdLine = Glib::ustring("gimp ") + " \"" + filename + "\"";
+ success = safe_spawn_command_line_async (cmdLine);
+#else
+ cmdLine = Glib::ustring("gimp ") + " \"" + filename + "\"";
+ success = safe_spawn_command_line_async (cmdLine);
+#endif
+ }
+ }
+ else if (options.editorToSendTo==2) {
+#ifdef __APPLE__
+ cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir,"Photoshop.app\' ") + "\'" + filename + "\'";
+#else
+ cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir,"Photoshop.exe") + "\" \"" + filename + "\"";
+#endif
+ success = safe_spawn_command_line_async (cmdLine);
+ }
+ else if (options.editorToSendTo==3) {
+#ifdef __APPLE__
+ cmdLine = Glib::ustring("") + options.customEditorProg + filename;
+#else
+ cmdLine = Glib::ustring("\"") + options.customEditorProg + "\" \"" + filename + "\"";
+#endif
+ success = safe_spawn_command_line_async (cmdLine);
+ }
+
+ if (!success) {
+ Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+ msgd->set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY"));
+ msgd->set_title (M("MAIN_BUTTON_SENDTOEDITOR"));
+ msgd->run ();
+ delete msgd;
+ }
+
+ }
+
+ return false;
+}
+
+void EditorPanel::saveOptions () {
+
+ close();
+ options.historyPanelWidth = hpanedl->get_position ();
+ options.toolPanelWidth = vboxright->get_width ();
+ if (options.startupDir==STARTUPDIR_LAST && fCatalog->lastSelectedDir ()!="")
+ options.startupPath = fCatalog->lastSelectedDir ();
+ fCatalog->closeDir ();
+}
+
+void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) {
+
+ if (beforeIpc) {
+ ProcParams* pparams = beforeIpc->getParamsForUpdate (rtengine::EvProfileChanged);
+ *pparams = params;
+ beforeIpc->paramsUpdateReady ();
+ }
+}
+
+void EditorPanel::beforeAfterToggled () {
+
+ removeIfThere (beforeAfterBox, beforeBox, false);
+ removeIfThere (afterBox, afterLabel, false);
+
+ if (beforeIarea) {
+ if (beforeIpc)
+ beforeIpc->stopProcessing ();
+ iarea->setBeforeAfterViews (NULL, iarea);
+ delete beforeIarea;
+ beforeIarea = NULL;
+ if (beforeIpc)
+ beforeIpc->setPreviewImageListener (NULL);
+ delete beforePreviewHandler;
+ beforePreviewHandler = NULL;
+ if (beforeIpc)
+ rtengine::StagedImageProcessor::destroy (beforeIpc);
+ beforeIpc = NULL;
+ }
+
+ if (beforeAfter->get_active ()) {
+
+ beforeIarea = new ImageAreaPanel ();
+
+ beforeLabel = Gtk::manage (new Gtk::Label ());
+ beforeLabel->set_markup (Glib::ustring("") + M("GENERAL_BEFORE") + "");
+ beforeBox = Gtk::manage (new Gtk::VBox ());
+ beforeBox->pack_start (*beforeLabel, Gtk::PACK_SHRINK, 2);
+ beforeBox->pack_start (*beforeIarea);
+
+ afterLabel = Gtk::manage (new Gtk::Label ());
+ afterLabel->set_markup (Glib::ustring("") + M("GENERAL_AFTER") + "");
+ afterBox->pack_start (*afterLabel, Gtk::PACK_SHRINK, 2);
+ afterBox->reorder_child (*afterLabel, 0);
+
+ beforeAfterBox->pack_start (*beforeBox);
+ beforeAfterBox->reorder_child (*beforeBox, 0);
+ beforeAfterBox->show_all ();
+
+ beforePreviewHandler = new PreviewHandler ();
+ isrc->increaseRef ();
+ beforeIpc = rtengine::StagedImageProcessor::create (isrc);
+ beforeIpc->setPreviewScale (10);
+ beforeIpc->setPreviewImageListener (beforePreviewHandler);
+ beforeIarea->imageArea->setPreviewHandler (beforePreviewHandler);
+ beforeIarea->imageArea->setImProcCoordinator (beforeIpc);
+
+ iarea->setBeforeAfterViews (beforeIarea, iarea);
+ beforeIarea->setBeforeAfterViews (beforeIarea, iarea);
+
+ rtengine::procparams::ProcParams params;
+ if (history->getBeforeLineParams (params))
+ historyBeforeLineChanged (params);
+ }
+}
+
+void EditorPanel::histogramChanged (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh, unsigned int* bcrgb, unsigned int* bcl) {
+
+ histogramPanel->histogramChanged (rh, gh, bh, lh);
+ tpc->updateCurveBackgroundHistogram (bcrgb, bcl);
+}
diff --git a/rtgui/options.cc b/rtgui/options.cc
index 72be1277f..88164e918 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -90,6 +90,7 @@ void Options::setDefaults () {
maxCacheEntries = 10000;
thumbnailFormat = FT_Custom16;
thumbInterp = 1;
+ autoSuffix = false;
saveParamsFile = false;
saveParamsCache = true;
paramsLoadLocation = PLL_Cache;
@@ -198,6 +199,7 @@ if (keyFile.has_group ("Output")) {
if (keyFile.has_key ("Output", "Path")) savePathTemplate = keyFile.get_string ("Output", "Path");
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", "AutoSuffix")) autoSuffix = keyFile.get_boolean("Output", "AutoSuffix");
if (keyFile.has_key ("Output", "UsePathTemplate")) saveUsePathTemplate = keyFile.get_boolean("Output", "UsePathTemplate");
if (keyFile.has_key ("Output", "LastSaveAsPath")) lastSaveAsPath = keyFile.get_string ("Output", "LastSaveAsPath");
}
@@ -357,6 +359,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_boolean ("Output", "SaveProcParams", saveFormat.saveParams);
keyFile.set_string ("Output", "PathTemplate", savePathTemplate);
keyFile.set_string ("Output", "PathFolder", savePathFolder);
+ keyFile.set_boolean("Output", "AutoSuffix", autoSuffix);
keyFile.set_boolean("Output", "UsePathTemplate", saveUsePathTemplate);
keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath);
diff --git a/rtgui/options.h b/rtgui/options.h
index e7d05e78c..75ff029fb 100644
--- a/rtgui/options.h
+++ b/rtgui/options.h
@@ -95,6 +95,7 @@ class Options {
Glib::ustring language;
Glib::ustring theme;
static Glib::ustring cacheBaseDir;
+ bool autoSuffix;
bool saveParamsFile;
bool saveParamsCache;
PPLoadLocation paramsLoadLocation;
diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc
index e190128d8..f3baa9c4d 100644
--- a/rtgui/previewwindow.cc
+++ b/rtgui/previewwindow.cc
@@ -1,219 +1,215 @@
-/*
- * This file is part of RawTherapee.
- *
- * Copyright (c) 2004-2010 Gabor Horvath
- *
- * RawTherapee is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * RawTherapee is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with RawTherapee. If not, see .
- */
-#include
-#include
-#include
-
-PreviewWindow::PreviewWindow () : previewHandler(NULL), mainCropWin(NULL),cCropMoving(NULL),cNormal(NULL), isMoving(false) {
-
- rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &PreviewWindow::on_resized) );
-}
-
-PreviewWindow::~PreviewWindow () {
-
- if( cCropMoving )
- delete cCropMoving;
- if( cNormal )
- delete cNormal;
-
-}
-
-void PreviewWindow::on_realize () {
-
- Gtk::DrawingArea::on_realize ();
- add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK);
- cCropMoving = new Gdk::Cursor (Gdk::FLEUR);
-#ifdef _WIN32
- cNormal = new Gdk::Cursor (Gdk::ARROW);
-#else
- cNormal = new Gdk::Cursor (Gdk::ARROW);
-#endif
-}
-
-void PreviewWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) {
-
- if (mainCropWin) {
- int cropX, cropY, cropW, cropH;
- mainCropWin->getCropRectangle (cropX, cropY, cropW, cropH);
- // translate it to screen coordinates
- x = imgX + cropX*zoom;
- y = imgY + cropY*zoom;
- w = cropW * zoom;
- h = cropH * zoom;
- }
-}
-
-void PreviewWindow::updatePreviewImage () {
-
- int W = get_width(), H = get_height();
- Glib::RefPtr wind = get_window();
- if( ! wind )
- return;
- backBuffer = Gdk::Pixmap::create (wind, W, H, -1);
- backBuffer->draw_rectangle (get_style()->get_base_gc(Gtk::STATE_NORMAL), true, 0, 0, W, H);
- if (previewHandler) {
- Glib::RefPtr resPixbuf = previewHandler->getRoughImage (W, H, zoom);
- if (resPixbuf) {
- imgW = resPixbuf->get_width();
- imgH = resPixbuf->get_height();
- imgX = (W-imgW)/2;
- imgY = (H-imgH)/2;
- backBuffer->draw_pixbuf (get_style()->get_base_gc(Gtk::STATE_NORMAL), resPixbuf, 0, 0, imgX, imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
- Cairo::RefPtr cr = backBuffer->create_cairo_context();
- if (previewHandler->getCropParams().enabled)
- drawCrop (cr, imgX, imgY, imgW, imgH, 0, 0, zoom, previewHandler->getCropParams());
- }
- }
-}
-
-void PreviewWindow::setPreviewHandler (PreviewHandler* ph) {
-
- previewHandler = ph;
- if (previewHandler)
- previewHandler->addPreviewImageListener (this);
-}
-
-void PreviewWindow::on_resized (Gtk::Allocation& req) {
-
- updatePreviewImage ();
- queue_draw ();
-}
-
-bool PreviewWindow::on_expose_event (GdkEventExpose* event) {
-
- if (backBuffer) {
- Glib::RefPtr window = get_window();
-
- int bufferW, bufferH;
- backBuffer->get_size (bufferW, bufferH);
-
- if (!mainCropWin) {
- mainCropWin = imageArea->getMainCropWindow ();
- if (mainCropWin)
- mainCropWin->addCropWindowListener (this);
- }
-
- if (get_width()!=bufferW && get_height()!=bufferH)
- updatePreviewImage ();
-
- window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1);
-
- if (mainCropWin) {
- Cairo::RefPtr cr = get_window()->create_cairo_context();
- int x, y, w, h;
- getObservedFrameArea (x, y, w, h);
- cr->set_source_rgb (1.0, 1.0, 1.0);
- cr->set_line_width (3);
- cr->rectangle (x-1.5, y-1.5, w+2, h+2);
- cr->stroke ();
- cr->set_source_rgb (1.0, 0.0, 0.0);
- cr->set_line_width (1);
- cr->rectangle (x-1.5, y-1.5, w+2, h+2);
- cr->stroke ();
- }
- }
- return true;
-}
-
-void PreviewWindow::previewImageChanged () {
-
- updatePreviewImage ();
- queue_draw ();
-}
-
-void PreviewWindow::setImageArea (ImageArea* ia) {
-
- imageArea = ia;
- mainCropWin = ia->getMainCropWindow ();
- if (mainCropWin)
- mainCropWin->addCropWindowListener (this);
-}
-
-void PreviewWindow::cropPositionChanged (CropWindow* w) {
-
- queue_draw ();
-}
-
-void PreviewWindow::cropWindowSizeChanged (CropWindow* w) {
-
- queue_draw ();
-}
-
-void PreviewWindow::cropZoomChanged (CropWindow* w) {
-
- queue_draw ();
-}
-
-bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event) {
-
- if (!mainCropWin)
- return true;
-
- int x, y, w, h;
- getObservedFrameArea (x, y, w, h);
- bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6;
- bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6;
-
- if (isMoving)
- mainCropWin->remoteMove ((event->x - press_x)/zoom, (event->y - press_y)/zoom);
- else if (inside && !moreInside)
- get_window()->set_cursor (*cCropMoving);
- else
- get_window()->set_cursor (*cNormal);
- return true;
-}
-
-bool PreviewWindow::on_button_press_event (GdkEventButton* event) {
-
- if (!mainCropWin)
- return true;
-
- int x, y, w, h;
- getObservedFrameArea (x, y, w, h);
- bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6;
- bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6;
-
- if (!isMoving) {
- isMoving = true;
- if (!inside || moreInside) {
- mainCropWin->remoteMove ((event->x - (x+w/2))/zoom, (event->y - (y+h/2))/zoom);
- press_x = x+w/2;
- press_y = y+h/2;
- }
- else {
- press_x = event->x;
- press_y = event->y;
- }
- get_window()->set_cursor (*cCropMoving);
- }
- return true;
-}
-
-bool PreviewWindow::on_button_release_event (GdkEventButton* event) {
-
- if (!mainCropWin)
- return true;
-
- if (isMoving) {
- isMoving = false;
- get_window()->set_cursor (*cNormal);
- mainCropWin->remoteMoveReady ();
- }
- return true;
-}
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2004-2010 Gabor Horvath
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+#include
+#include
+#include
+
+PreviewWindow::PreviewWindow () : previewHandler(NULL), mainCropWin(NULL),cCropMoving(NULL),cNormal(NULL), isMoving(false) {
+
+ rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &PreviewWindow::on_resized) );
+}
+
+PreviewWindow::~PreviewWindow () {
+
+ if( cCropMoving )
+ delete cCropMoving;
+ if( cNormal )
+ delete cNormal;
+
+}
+
+void PreviewWindow::on_realize () {
+
+ Gtk::DrawingArea::on_realize ();
+ add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK);
+ cCropMoving = new Gdk::Cursor (Gdk::FLEUR);
+ cNormal = new Gdk::Cursor (Gdk::ARROW);
+}
+
+void PreviewWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) {
+
+ if (mainCropWin) {
+ int cropX, cropY, cropW, cropH;
+ mainCropWin->getCropRectangle (cropX, cropY, cropW, cropH);
+ // translate it to screen coordinates
+ x = imgX + cropX*zoom;
+ y = imgY + cropY*zoom;
+ w = cropW * zoom;
+ h = cropH * zoom;
+ }
+}
+
+void PreviewWindow::updatePreviewImage () {
+
+ int W = get_width(), H = get_height();
+ Glib::RefPtr wind = get_window();
+ if( ! wind )
+ return;
+ backBuffer = Gdk::Pixmap::create (wind, W, H, -1);
+ backBuffer->draw_rectangle (get_style()->get_base_gc(Gtk::STATE_NORMAL), true, 0, 0, W, H);
+ if (previewHandler) {
+ Glib::RefPtr resPixbuf = previewHandler->getRoughImage (W, H, zoom);
+ if (resPixbuf) {
+ imgW = resPixbuf->get_width();
+ imgH = resPixbuf->get_height();
+ imgX = (W-imgW)/2;
+ imgY = (H-imgH)/2;
+ backBuffer->draw_pixbuf (get_style()->get_base_gc(Gtk::STATE_NORMAL), resPixbuf, 0, 0, imgX, imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
+ Cairo::RefPtr cr = backBuffer->create_cairo_context();
+ if (previewHandler->getCropParams().enabled)
+ drawCrop (cr, imgX, imgY, imgW, imgH, 0, 0, zoom, previewHandler->getCropParams());
+ }
+ }
+}
+
+void PreviewWindow::setPreviewHandler (PreviewHandler* ph) {
+
+ previewHandler = ph;
+ if (previewHandler)
+ previewHandler->addPreviewImageListener (this);
+}
+
+void PreviewWindow::on_resized (Gtk::Allocation& req) {
+
+ updatePreviewImage ();
+ queue_draw ();
+}
+
+bool PreviewWindow::on_expose_event (GdkEventExpose* event) {
+
+ if (backBuffer) {
+ Glib::RefPtr window = get_window();
+
+ int bufferW, bufferH;
+ backBuffer->get_size (bufferW, bufferH);
+
+ if (!mainCropWin) {
+ mainCropWin = imageArea->getMainCropWindow ();
+ if (mainCropWin)
+ mainCropWin->addCropWindowListener (this);
+ }
+
+ if (get_width()!=bufferW && get_height()!=bufferH)
+ updatePreviewImage ();
+
+ window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1);
+
+ if (mainCropWin) {
+ Cairo::RefPtr cr = get_window()->create_cairo_context();
+ int x, y, w, h;
+ getObservedFrameArea (x, y, w, h);
+ cr->set_source_rgb (1.0, 1.0, 1.0);
+ cr->set_line_width (3);
+ cr->rectangle (x-1.5, y-1.5, w+2, h+2);
+ cr->stroke ();
+ cr->set_source_rgb (1.0, 0.0, 0.0);
+ cr->set_line_width (1);
+ cr->rectangle (x-1.5, y-1.5, w+2, h+2);
+ cr->stroke ();
+ }
+ }
+ return true;
+}
+
+void PreviewWindow::previewImageChanged () {
+
+ updatePreviewImage ();
+ queue_draw ();
+}
+
+void PreviewWindow::setImageArea (ImageArea* ia) {
+
+ imageArea = ia;
+ mainCropWin = ia->getMainCropWindow ();
+ if (mainCropWin)
+ mainCropWin->addCropWindowListener (this);
+}
+
+void PreviewWindow::cropPositionChanged (CropWindow* w) {
+
+ queue_draw ();
+}
+
+void PreviewWindow::cropWindowSizeChanged (CropWindow* w) {
+
+ queue_draw ();
+}
+
+void PreviewWindow::cropZoomChanged (CropWindow* w) {
+
+ queue_draw ();
+}
+
+bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event) {
+
+ if (!mainCropWin)
+ return true;
+
+ int x, y, w, h;
+ getObservedFrameArea (x, y, w, h);
+ bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6;
+ bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6;
+
+ if (isMoving)
+ mainCropWin->remoteMove ((event->x - press_x)/zoom, (event->y - press_y)/zoom);
+ else if (inside && !moreInside)
+ get_window()->set_cursor (*cCropMoving);
+ else
+ get_window()->set_cursor (*cNormal);
+ return true;
+}
+
+bool PreviewWindow::on_button_press_event (GdkEventButton* event) {
+
+ if (!mainCropWin)
+ return true;
+
+ int x, y, w, h;
+ getObservedFrameArea (x, y, w, h);
+ bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6;
+ bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6;
+
+ if (!isMoving) {
+ isMoving = true;
+ if (!inside || moreInside) {
+ mainCropWin->remoteMove ((event->x - (x+w/2))/zoom, (event->y - (y+h/2))/zoom);
+ press_x = x+w/2;
+ press_y = y+h/2;
+ }
+ else {
+ press_x = event->x;
+ press_y = event->y;
+ }
+ get_window()->set_cursor (*cCropMoving);
+ }
+ return true;
+}
+
+bool PreviewWindow::on_button_release_event (GdkEventButton* event) {
+
+ if (!mainCropWin)
+ return true;
+
+ if (isMoving) {
+ isMoving = false;
+ get_window()->set_cursor (*cNormal);
+ mainCropWin->remoteMoveReady ();
+ }
+ return true;
+}
diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc
index 021a54207..d985100cf 100644
--- a/rtgui/saveasdlg.cc
+++ b/rtgui/saveasdlg.cc
@@ -22,6 +22,8 @@
extern Options options;
SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
+ set_title(M("GENERAL_SAVE"));
+
Gtk::VBox* vbox = get_vbox ();
fchooser = new Gtk::FileChooserWidget (Gtk::FILE_CHOOSER_ACTION_SAVE);
@@ -41,6 +43,16 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
Gtk::HSeparator* hsep1 = new Gtk::HSeparator ();
vbox->pack_start (*hsep1, Gtk::PACK_SHRINK, 2);
+// Unique filename option
+// ~~~~~~~~~~~~~~~~~~~~~~
+ autoSuffix = new Gtk::CheckButton (M("SAVEDLG_AUTOSUFFIX"));
+ autoSuffix->set_active(options.autoSuffix);
+
+ vbox->pack_start (*autoSuffix, Gtk::PACK_SHRINK, 4);
+
+ Gtk::HSeparator* hsep2 = new Gtk::HSeparator ();
+ vbox->pack_start (*hsep2, Gtk::PACK_SHRINK, 2);
+
// Output Options
// ~~~~~~~~~~~~~~
formatOpts = new SaveFormatPanel ();
@@ -49,8 +61,8 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
vbox->pack_start (*formatOpts, Gtk::PACK_SHRINK, 4);
- Gtk::HSeparator* hsep2 = new Gtk::HSeparator ();
- vbox->pack_start (*hsep2, Gtk::PACK_SHRINK, 2);
+ Gtk::HSeparator* hsep3 = new Gtk::HSeparator ();
+ vbox->pack_start (*hsep3, Gtk::PACK_SHRINK, 2);
// queue/immediate
// ~~~~~~~~~~~~~
@@ -83,6 +95,11 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
show_all_children ();
}
+bool SaveAsDialog::getAutoSuffix () {
+
+ return autoSuffix->get_active();
+}
+
bool SaveAsDialog::getImmediately () {
return immediately->get_active ();
diff --git a/rtgui/saveasdlg.h b/rtgui/saveasdlg.h
index 7df8d8392..1914461c4 100644
--- a/rtgui/saveasdlg.h
+++ b/rtgui/saveasdlg.h
@@ -28,6 +28,7 @@ class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener {
protected:
Gtk::FileChooserWidget* fchooser;
+ Gtk::CheckButton* autoSuffix;
SaveFormatPanel* formatOpts;
Glib::ustring fname;
Gtk::FileFilter filter_jpg;
@@ -43,6 +44,7 @@ class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener {
Glib::ustring getFileName ();
Glib::ustring getDirectory ();
SaveFormat getFormat ();
+ bool getAutoSuffix ();
bool getImmediately ();
bool getToHeadOfQueue ();
bool getToTailOfQueue ();
diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc
index a7aab6efc..861d4a12c 100644
--- a/rtgui/thumbbrowserbase.cc
+++ b/rtgui/thumbbrowserbase.cc
@@ -401,7 +401,7 @@ bool ThumbBrowserBase::Internal::on_expose_event(GdkEventExpose* event) {
dirty = false;
- Glib::RefPtr window = get_window();
+ Glib::RefPtr window = get_window();
int w = get_width();
int h = get_height();
@@ -411,14 +411,14 @@ bool ThumbBrowserBase::Internal::on_expose_event(GdkEventExpose* event) {
Glib::RefPtr context = get_pango_context ();
context->set_font_description (get_style()->get_font());
for (int i=0; ifd.size(); i++) {
- if (!parent->fd[i]->drawable || !parent->fd[i]->insideWindow (0, 0, w, h))
+ if (!parent->fd[i]->drawable || !parent->fd[i]->insideWindow (0, 0, w, h))
parent->fd[i]->updatepriority = false;
else {
parent->fd[i]->updatepriority = true;
parent->fd[i]->draw ();
}
}
-
+
return true;
}
diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc
index 8e9039d31..e94f2605b 100644
--- a/rtgui/thumbbrowserentrybase.cc
+++ b/rtgui/thumbbrowserentrybase.cc
@@ -344,8 +344,8 @@ void ThumbBrowserEntryBase::draw () {
Glib::RefPtr gc_ = Gdk::GC::create (w->get_window());
- Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL);
- Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED);
+ // Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL);
+ // Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED);
Gdk::Color bgn = w->get_style()->get_bg(Gtk::STATE_NORMAL);
Gdk::Color bgs = w->get_style()->get_bg(Gtk::STATE_SELECTED);