rawTherapee/rtgui/saveasdlg.cc
Hombre 8b2eac9a3d Pipette and "On Preview Widgets" branch. See issue 227
The pipette part is already working quite nice but need to be finished. The widgets part needs more work...
2014-01-21 23:37:36 +01:00

291 lines
9.8 KiB
C++

/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "saveasdlg.h"
#include "multilangmgr.h"
#include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h"
extern Options options;
SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
set_title(M("GENERAL_SAVE"));
Gtk::VBox* vbox = get_vbox ();
fchooser = Gtk::manage( new Gtk::FileChooserWidget (Gtk::FILE_CHOOSER_ACTION_SAVE) );
fchooser->set_current_folder (initialDir);
fchooser->signal_file_activated().connect(sigc::mem_fun(*this,&SaveAsDialog::okPressed));
filter_jpg.set_name(M("SAVEDLG_JPGFILTER"));
filter_jpg.add_pattern("*.jpg");
filter_jpg.add_pattern("*.JPG");
filter_jpg.add_pattern("*.jpeg");
filter_jpg.add_pattern("*.JPEG");
filter_jpg.add_pattern("*.jpe");
filter_jpg.add_pattern("*.JPE");
filter_tif.set_name(M("SAVEDLG_JPGFILTER"));
filter_tif.add_pattern("*.tif");
filter_tif.add_pattern("*.TIF");
filter_tif.add_pattern("*.tiff");
filter_tif.add_pattern("*.TIFF");
filter_png.set_name(M("SAVEDLG_JPGFILTER"));
filter_png.add_pattern("*.png");
filter_png.add_pattern("*.PNG");
formatChanged (options.saveFormat.format);
// Output Options
// ~~~~~~~~~~~~~~
formatOpts = Gtk::manage( new SaveFormatPanel () );
formatOpts->init (options.saveFormat);
formatOpts->setListener (this);
// queue/immediate
// ~~~~~~~~~~~~~~~
saveMethod[0] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_SAVEIMMEDIATELY")) );
saveMethod[1] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUEHEAD")) );
saveMethod[2] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUETAIL")) );
Gtk::RadioButton::Group g = saveMethod[0]->get_group();
saveMethod[1]->set_group (g);
saveMethod[2]->set_group (g);
if (options.saveMethodNum >= 0 && options.saveMethodNum < 3)
saveMethod[options.saveMethodNum]->set_active (true);
saveMethod[0]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::saveImmediatlyClicked) );
saveMethod[1]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::putToQueueClicked) );
saveMethod[2]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::putToQueueClicked) );
// Force output format option
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
forceFormatOpts = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_FORCEFORMATOPTS")) );
forceFormatOpts->set_active(options.forceFormatOpts);
forceFormatOpts->set_sensitive(options.saveMethodNum>0);
forceFormatOpts->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::forceFmtOptsSwitched) );
// update sensitivity of the SaveFormatPanel
formatOpts->set_sensitive(options.saveMethodNum==0 || options.forceFormatOpts);
// Unique filename option
// ~~~~~~~~~~~~~~~~~~~~~~
autoSuffix = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_AUTOSUFFIX")) );
autoSuffix->set_active(options.autoSuffix);
// buttons
// ~~~~~~~
Gtk::Button* ok = Gtk::manage( new Gtk::Button (M("GENERAL_OK")) );
Gtk::Button* cancel = Gtk::manage( new Gtk::Button (M("GENERAL_CANCEL")) );
ok->set_image (*Gtk::manage(new RTImage ("gtk-apply.png")));
cancel->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png")));
ok->set_tooltip_markup (M("TP_SAVEDIALOG_OK_TIP"));
ok->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::okPressed) );
cancel->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::cancelPressed) );
// pack everything
// ~~~~~~~~~~~~~~~
Gtk::VBox* vbox_bottomRight = Gtk::manage(new Gtk::VBox ());
// There is no queue in simple mode, so no need to choose
if (!simpleEditor) {
vbox_bottomRight->pack_start (*saveMethod[0], Gtk::PACK_SHRINK, 2);
vbox_bottomRight->pack_start (*saveMethod[1], Gtk::PACK_SHRINK, 2);
vbox_bottomRight->pack_start (*saveMethod[2], Gtk::PACK_SHRINK, 2);
vbox_bottomRight->pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 5);
}
vbox_bottomRight->pack_start (*forceFormatOpts, Gtk::PACK_SHRINK, 4);
vbox_bottomRight->pack_start (*autoSuffix, Gtk::PACK_SHRINK, 4);
Gtk::HBox* hbox_bottom = Gtk::manage( new Gtk::HBox() );
hbox_bottom->pack_start (*formatOpts, Gtk::PACK_SHRINK, 2);
hbox_bottom->pack_start (*Gtk::manage(new Gtk::VSeparator ()), Gtk::PACK_SHRINK, 2);
hbox_bottom->pack_start (*vbox_bottomRight, Gtk::PACK_SHRINK, 2);
vbox->pack_start (*fchooser);
vbox->pack_start (*hbox_bottom, Gtk::PACK_SHRINK, 2);
get_action_area()->pack_end (*ok, Gtk::PACK_SHRINK, 4);
get_action_area()->pack_end (*cancel, Gtk::PACK_SHRINK, 4);
set_border_width (4);
show_all_children ();
signal_key_press_event().connect( sigc::mem_fun(*this, &SaveAsDialog::keyPressed) );
}
void SaveAsDialog::saveImmediatlyClicked () {
forceFormatOpts->set_sensitive(false);
formatOpts->set_sensitive(true);
}
void SaveAsDialog::putToQueueClicked () {
forceFormatOpts->set_sensitive(true);
formatOpts->set_sensitive(forceFormatOpts->get_active());
}
void SaveAsDialog::forceFmtOptsSwitched () {
formatOpts->set_sensitive(forceFormatOpts->get_active());
}
bool SaveAsDialog::getForceFormatOpts () {
return forceFormatOpts->get_active();
}
bool SaveAsDialog::getAutoSuffix () {
return autoSuffix->get_active();
}
bool SaveAsDialog::getImmediately () {
return simpleEditor ? true : saveMethod[0]->get_active ();
}
bool SaveAsDialog::getToHeadOfQueue () {
return saveMethod[1]->get_active ();
}
bool SaveAsDialog::getToTailOfQueue () {
return saveMethod[2]->get_active ();
}
int SaveAsDialog::getSaveMethodNum () {
if (simpleEditor)
return 0;
for (int i = 0; i < 3; i++)
if (saveMethod[i]->get_active())
return i;
return -1;
}
Glib::ustring SaveAsDialog::getFileName () {
return fname;
}
Glib::ustring SaveAsDialog::getDirectory () {
return fchooser->get_current_folder ();
}
SaveFormat SaveAsDialog::getFormat () {
return formatOpts->getFormat ();
}
void SaveAsDialog::okPressed () {
fname = fchooser->get_filename();
// checking if the filename field is empty. The user have to click Cancel if he don't want to specify a filename
// NB: There seem to be a bug in Gtkmm2.22 / FileChooserWidget : if you suppress the filename entry and
// click on a folder in the list, the filename field is empty but get_filename will return the folder's path :/
if (!fname.length() || safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) {
Glib::ustring msg_ = Glib::ustring("<b>") + M("MAIN_MSG_EMPTYFILENAME") + "</b>";
Gtk::MessageDialog msgd (*this, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
msgd.run ();
return;
}
// resolve extension ambiguities
SaveFormat sf = formatOpts->getFormat ();
Glib::ustring extLower = getExtension (fname).lowercase ();
bool extIsEmpty = (extLower == "");
bool extIsJpeg = (extLower == "jpg" || extLower == "jpeg" || extLower == "jpe");
bool extIsTiff = (extLower == "tif" || extLower == "tiff");
bool extIsPng = (extLower == "png");
if (extIsEmpty || !(extIsJpeg || extIsTiff || extIsPng)) {
// extension is either empty or unfamiliar.
fname += Glib::ustring (".") + sf.format;
} else if ( !(sf.format == "jpg" && extIsJpeg)
&& !(sf.format == "tif" && extIsTiff)
&& !(sf.format == "png" && extIsPng ) ) {
// create dialog to warn user that the filename may have two extensions on the end.
Glib::ustring msg_ = Glib::ustring ("<b>") + M("GENERAL_WARNING") + ": "
+ M("SAVEDLG_WARNFILENAME") + " \"" + Glib::path_get_basename (fname)
+ "." + sf.format + "\"</b>";
Gtk::MessageDialog msgd (*this, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK_CANCEL, true);
if (msgd.run () == Gtk::RESPONSE_OK)
fname += Glib::ustring (".") + sf.format;
else
return;
}
response (Gtk::RESPONSE_OK);
}
void SaveAsDialog::cancelPressed () {
fname = fchooser->get_filename();
response (Gtk::RESPONSE_CANCEL);
}
void SaveAsDialog::formatChanged (Glib::ustring f) {
if (f=="jpg")
fchooser->set_filter (filter_jpg);
else if (f=="png")
fchooser->set_filter (filter_png);
else if (f=="tif")
fchooser->set_filter (filter_tif);
}
void SaveAsDialog::setInitialFileName (Glib::ustring fname) {
fchooser->set_current_name(fname);
}
void SaveAsDialog::setImagePath (Glib::ustring ipath) {
Glib::ustring path = Glib::path_get_dirname(ipath);
//Add the image's path to the Shortcut list
#ifdef WIN32
// Dirty workaround, waiting for a clean solution by using exceptions!
if (!safe_is_shortcut_dir(path))
#endif
try {
fchooser->add_shortcut_folder(path);
}
catch (Gtk::FileChooserError &err) {}
}
bool SaveAsDialog::keyPressed (GdkEventKey* event) {
bool ctrl = event->state & GDK_CONTROL_MASK;
if (ctrl){
switch(event->keyval) {
case GDK_Return: // Ctrl-Enter equivalent to pressing OK button
case GDK_KP_Enter:
SaveAsDialog::okPressed();
return true;
}
}
return false;
}