2 * This file is part of RawTherapee.
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
6 * RawTherapee is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * RawTherapee is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
19 #include <profilepanel.h>
21 #include <profilestore.h>
22 #include <clipboard.h>
23 #include <multilangmgr.h>
26 using namespace rtengine
;
27 using namespace rtengine::procparams
;
29 extern Glib::ustring argv0
;
31 ProfilePanel::ProfilePanel () {
35 profiles
= Gtk::manage (new Gtk::ComboBoxText ());
36 Gtk::HBox
* hbox
= Gtk::manage (new Gtk::HBox ());
38 // pack_start (*profiles, Gtk::PACK_SHRINK, 4);
40 pack_start (*hbox
, Gtk::PACK_SHRINK
, 4);
42 save
= Gtk::manage (new Gtk::Button ());
43 save
->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON
)));
44 load
= Gtk::manage (new Gtk::Button ());
45 load
->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON
)));
46 copy
= Gtk::manage (new Gtk::Button ());
47 copy
->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-copy"), Gtk::ICON_SIZE_BUTTON
)));
48 paste
= Gtk::manage (new Gtk::Button ());
49 paste
->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-paste"), Gtk::ICON_SIZE_BUTTON
)));
51 hbox
->pack_start (*profiles
);
52 hbox
->pack_start (*load
, Gtk::PACK_SHRINK
, 1);
53 hbox
->pack_start (*save
, Gtk::PACK_SHRINK
, 1);
54 hbox
->pack_start (*copy
, Gtk::PACK_SHRINK
, 1);
55 hbox
->pack_start (*paste
, Gtk::PACK_SHRINK
, 1);
57 load
->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::load_clicked
) );
58 save
->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::save_clicked
) );
59 copy
->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::copy_clicked
) );
60 paste
->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::paste_clicked
) );
67 refreshProfileList ();
69 profiles
->set_active (0);
70 old
= profiles
->get_active_text();
71 changeconn
= profiles
->signal_changed().connect( sigc::mem_fun(*this, &ProfilePanel::selection_changed
) );
73 save
->set_tooltip_text (M("PROFILEPANEL_TOOLTIPSAVE"));
74 load
->set_tooltip_text (M("PROFILEPANEL_TOOLTIPLOAD"));
75 copy
->set_tooltip_text (M("PROFILEPANEL_TOOLTIPCOPY"));
76 paste
->set_tooltip_text (M("PROFILEPANEL_TOOLTIPPASTE"));
81 ProfilePanel::~ProfilePanel () {
88 void ProfilePanel::refreshProfileList () {
90 Glib::ustring oldsel
= profiles
->get_active_text ();
91 changeconn
.block (true);
94 profiles
->clear_items ();
97 // re-parse profile directories (deletes old ones)
98 profileStore
.parseProfiles ();
99 pparams
= profileStore
.getProfileNames ();
100 for (int i
=0; i
<pparams
.size(); i
++)
101 profiles
->append_text (pparams
[i
]);
104 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
106 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")");
108 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")");
110 profiles
->set_active_text (oldsel
);
111 changeconn
.block (false);
114 void ProfilePanel::save_clicked () {
116 Gtk::FileChooserDialog
dialog(M("PROFILEPANEL_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE
);
117 if (options
.multiUser
)
118 dialog
.set_current_folder (Options::rtdir
+ "/" + options
.profilePath
);
120 dialog
.set_current_folder (GET_DATA_PATH(argv0
) + "/" + options
.profilePath
);
122 //Add response buttons the the dialog:
123 dialog
.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL
);
124 dialog
.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK
);
126 //Add filters, so that only certain file types can be selected:
128 Gtk::FileFilter filter_pp
;
129 filter_pp
.set_name(M("PROFILEPANEL_FILEDLGFILTERPP"));
130 filter_pp
.add_pattern("*.pp2");
131 dialog
.add_filter(filter_pp
);
133 Gtk::FileFilter filter_any
;
134 filter_any
.set_name(M("PROFILEPANEL_FILEDLGFILTERANY"));
135 filter_any
.add_pattern("*");
136 dialog
.add_filter(filter_any
);
138 // dialog.set_do_overwrite_confirmation (true);
140 savedialog
= &dialog
;
142 int result
= dialog
.run();
144 if (result
==Gtk::RESPONSE_OK
) {
146 std::string fname
= dialog
.get_filename();
149 int dotpos
= fname
.find_last_of ('.');
150 if (dotpos
==Glib::ustring::npos
)
152 int dirpos1
= fname
.find_last_of ('/');
153 if (dirpos1
!=Glib::ustring::npos
&& dirpos1
>dotpos
)
155 int dirpos2
= fname
.find_last_of ('\\');
156 if (dirpos2
!=Glib::ustring::npos
&& dirpos2
>dotpos
)
160 fname
= fname
+ ".pp2";
162 if (Glib::file_test (fname
, Glib::FILE_TEST_EXISTS
)) {
163 Glib::ustring msg_
= Glib::ustring("<b>") + fname
+ ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + "</b>";
164 Gtk::MessageDialog
msgd (msg_
, true, Gtk::MESSAGE_WARNING
, Gtk::BUTTONS_YES_NO
, true);
165 int response
= msgd
.run ();
166 if (response
==Gtk::RESPONSE_NO
)
170 ProcParams
* toSave
= NULL
;
171 if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")")
173 else if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")")
175 else if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")")
178 toSave
= profileStore
.getProfile (profiles
->get_active_text());
181 toSave
->save (fname
);
182 refreshProfileList ();
187 void ProfilePanel::copy_clicked () {
189 ProcParams
* toSave
= NULL
;
190 if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")")
192 else if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")")
194 else if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")")
197 toSave
= profileStore
.getProfile (profiles
->get_active_text());
200 clipboard
.setProcParams (*toSave
);
203 void ProfilePanel::load_clicked () {
205 Gtk::FileChooserDialog
dialog(M("PROFILEPANEL_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN
);
206 if (options
.multiUser
)
207 dialog
.set_current_folder (Options::rtdir
+ "/" + options
.profilePath
);
209 dialog
.set_current_folder (GET_DATA_PATH(argv0
) + "/" + options
.profilePath
);
211 //Add response buttons the the dialog:
212 dialog
.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL
);
213 dialog
.add_button(Gtk::StockID("gtk-open"), Gtk::RESPONSE_OK
);
215 //Add filters, so that only certain file types can be selected:
217 Gtk::FileFilter filter_pp
;
218 filter_pp
.set_name(M("PROFILEPANEL_FILEDLGFILTERPP"));
219 filter_pp
.add_pattern("*.pp2");
220 dialog
.add_filter(filter_pp
);
222 Gtk::FileFilter filter_any
;
223 filter_any
.set_name(M("PROFILEPANEL_FILEDLGFILTERANY"));
224 filter_any
.add_pattern("*");
225 dialog
.add_filter(filter_any
);
227 int result
= dialog
.run();
229 if (result
==Gtk::RESPONSE_OK
) {
231 custom
= new ProcParams ();
232 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
234 custom
->load (dialog
.get_filename());
235 profiles
->set_active_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
236 old
= profiles
->get_active_text();
237 changeTo (custom
, M("PROFILEPANEL_PFILE"));
241 void ProfilePanel::paste_clicked () {
243 if (!clipboard
.hasProcParams())
247 custom
= new ProcParams ();
248 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
250 *custom
= clipboard
.getProcParams ();
251 profiles
->set_active_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
252 old
= profiles
->get_active_text();
253 changeTo (custom
, M("HISTORY_FROMCLIPBOARD"));
256 void ProfilePanel::changeTo (ProcParams
* newpp
, Glib::ustring profname
) {
261 // Keep transformation parameters while changing the profile
263 /* int cropx = working->crop_x;
264 int cropy = working->crop_y;
265 int cropw = working->crop_w;
266 int croph = working->crop_h;
267 bool crope = working->crop_enabled;
268 int rotcor = working->rotate_coarse;
269 double rotfine = working->rotate_fine;
270 double lenscorr = working->lens_distortion;
271 bool hflip = working->horizontal_flip;
272 bool vflip = working->vertical_flip;
274 working->copy (newpp);
276 working->crop_x = cropx;
277 working->crop_y = cropy;
278 working->crop_w = cropw;
279 working->crop_h = croph;
280 working->crop_enabled = crope;
281 working->rotate_coarse = rotcor;
282 working->rotate_fine = rotfine;
283 working->lens_distortion = lenscorr;
284 working->horizontal_flip = hflip;
285 working->vertical_flip = vflip;
288 tpc
->profileChange (newpp
, EvProfileChanged
, profname
);
291 void ProfilePanel::selection_changed () {
293 if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") {
295 changeTo (custom
, Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
297 else if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")")
298 changeTo (lastsaved
, Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")");
299 else if (profiles
->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")")
300 changeTo (lastphoto
, Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")");
302 ProcParams
* s
= profileStore
.getProfile (profiles
->get_active_text());
304 changeTo (s
, profiles
->get_active_text());
306 old
= profiles
->get_active_text ();
310 void ProfilePanel::procParamsChanged (rtengine::procparams::ProcParams
* p
, rtengine::ProcEvent ev
, Glib::ustring descr
, ParamsEdited
* paramsEdited
) {
312 // to prevent recursion filter out the events caused by the profilepanel
313 if (ev
==EvProfileChanged
|| ev
==EvPhotoLoaded
)
316 if (profiles
->get_active_text() != Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") {
319 custom
= new ProcParams ();
320 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
323 profiles
->set_active_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")");
324 old
= profiles
->get_active_text();
330 void ProfilePanel::initProfile (const Glib::ustring
& profname
, ProcParams
* lastSaved
, ProcParams
* lastPhoto
) {
332 changeconn
.block (true);
334 profiles
->clear_items ();
337 pparams
= profileStore
.getProfileNames ();
338 for (int i
=0; i
<pparams
.size(); i
++)
339 profiles
->append_text (pparams
[i
]);
344 lastsaved
= lastSaved
;
346 lastphoto
= lastPhoto
;
348 Glib::ustring defline
= profname
;
349 ProcParams
* defprofile
= profileStore
.getProfile (profname
);
352 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")");
355 defline
= Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")";
356 defprofile
= lastsaved
;
357 profiles
->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")");
362 tpc
->setDefaults (lastsaved
);
364 tpc
->setDefaults (profileStore
.getProfile (profname
));
368 profiles
->set_active_text (defline
);
369 changeconn
.block (false);
371 tpc
->profileChange (defprofile
, EvPhotoLoaded
, defline
);
374 // select first valid profile
376 profiles
->set_active (0);
377 ProcParams
* s
= profileStore
.getProfile (profiles
->get_active_text());
379 s
= new ProcParams ();
380 changeconn
.block (false);
382 tpc
->profileChange (s
, EvPhotoLoaded
, profiles
->get_active_text());