322 lines
9.9 KiB
C++
322 lines
9.9 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 (Glib::Error &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;
|
|
}
|