147
164
private Gtk.Table table = new Gtk.Table(0, 0, false);
148
165
private Gtk.ComboBox quality_combo;
149
166
private Gtk.ComboBox constraint_combo;
167
private Gtk.ComboBox format_combo;
150
168
private Gtk.Entry pixels_entry;
151
169
private Gtk.Widget ok_button;
152
170
private bool in_insert = false;
154
public ExportDialog(string title, int default_scale = DEFAULT_SCALE,
155
ScaleConstraint default_constraint = DEFAULT_CONSTRAINT,
156
Jpeg.Quality default_quality = DEFAULT_QUALITY) {
172
public ExportDialog(string title) {
157
173
this.title = title;
158
174
has_separator = false;
159
175
allow_grow = false;
161
// use defaults for controls
162
current_scale = default_scale;
163
current_constraint = default_constraint;
164
current_quality = default_quality;
167
177
quality_combo = new Gtk.ComboBox.text();
169
179
foreach (Jpeg.Quality quality in QUALITY_ARRAY) {
190
205
// register after preparation to avoid signals during init
191
206
constraint_combo.changed += on_constraint_changed;
207
format_combo.changed += on_format_changed;
192
208
pixels_entry.changed += on_pixels_changed;
193
209
pixels_entry.insert_text += on_pixels_insert_text;
194
210
pixels_entry.activate += on_activate;
197
add_label(_("_Quality:"), 0, 0, quality_combo);
198
add_control(quality_combo, 1, 0);
213
add_label(_("_Format:"), 0, 0, format_combo);
214
add_control(format_combo, 1, 0);
216
add_label(_("_Quality:"), 0, 1, quality_combo);
217
add_control(quality_combo, 1, 1);
200
add_label(_("_Scaling constraint:"), 0, 1, constraint_combo);
201
add_control(constraint_combo, 1, 1);
219
add_label(_("_Scaling constraint:"), 0, 2, constraint_combo);
220
add_control(constraint_combo, 1, 2);
203
222
Gtk.Label pixels_label = new Gtk.Label.with_mnemonic(_(" _pixels"));
204
223
pixels_label.set_mnemonic_widget(pixels_entry);
225
244
ok_button.grab_focus();
228
public bool execute(out int scale, out ScaleConstraint constraint, out Jpeg.Quality quality) {
246
// unlike other parameters, which should be persisted across dialog executions, format
247
// must be set each time the dialog is executed, so that the format displayed in the
248
// format combo box matches the format of the backing photo -- this is why it's passed
249
// qualified as ref and not as out
250
public bool execute(out int scale, out ScaleConstraint constraint, out Jpeg.Quality quality,
251
ref PhotoFileFormat user_format) {
254
if (!user_format.can_write())
255
user_format = PhotoFileFormat.get_system_default_format();
258
foreach (PhotoFileFormat format in PhotoFileFormat.get_writable()) {
259
if (format == user_format)
260
format_combo.set_active(ctr);
231
265
bool ok = (run() == Gtk.ResponseType.OK);
277
315
private void on_constraint_changed() {
278
bool original = (CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL);
316
bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL;
317
bool jpeg = format_combo.get_active_text() ==
318
PhotoFileFormat.JFIF.get_properties().get_user_visible_name();
279
319
pixels_entry.sensitive = !original;
280
quality_combo.sensitive = !original;
320
quality_combo.sensitive = !original && jpeg;
282
322
ok_button.sensitive = true;
284
324
on_pixels_changed();
327
private void on_format_changed() {
328
bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL;
329
bool jpeg = format_combo.get_active_text() ==
330
PhotoFileFormat.JFIF.get_properties().get_user_visible_name();
331
quality_combo.sensitive = !original && jpeg;
287
334
private void on_activate() {
288
335
response(Gtk.ResponseType.OK);
483
public abstract class TextEntryDialog : Gtk.Dialog {
527
public abstract class TextEntryDialogMediator {
528
private TextEntryDialog dialog;
530
public TextEntryDialogMediator(string title, string label, string? initial_text = null) {
531
Gtk.Builder builder = AppWindow.create_builder();
532
dialog = builder.get_object("text_entry_dialog1") as TextEntryDialog;
533
dialog.set_builder(builder);
534
dialog.setup(on_modify_validate, title, label, initial_text);
537
protected virtual bool on_modify_validate(string text) {
541
protected string? _execute() {
542
return dialog.execute();
546
public class TextEntryDialog : Gtk.Dialog {
547
public delegate bool OnModifyValidateType(string text);
549
private OnModifyValidateType on_modify_validate;
484
550
private Gtk.Entry entry;
486
public TextEntryDialog(string title, string label, string? initial_text = null) {
489
add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
490
Gtk.STOCK_OK, Gtk.ResponseType.OK);
551
private Gtk.Builder builder;
553
public void set_builder(Gtk.Builder builder) {
554
this.builder = builder;
557
public void setup(OnModifyValidateType? modify_validate, string title, string label,
558
string? initial_text) {
491
559
set_title(title);
493
Gtk.Label name_label = new Gtk.Label(label);
494
entry = new Gtk.Entry();
496
if (initial_text != null)
497
entry.set_text(initial_text);
499
entry.set_activates_default(true);
500
entry.changed += on_entry_changed;
502
Gtk.HBox query = new Gtk.HBox(false, 0);
503
query.pack_start(name_label, false, false, 3);
504
query.pack_start(entry, false, false, 3);
560
set_parent_window(AppWindow.get_instance().get_parent_window());
561
on_modify_validate = modify_validate;
563
Gtk.Label name_label = builder.get_object("label") as Gtk.Label;
564
name_label.set_text(label);
566
entry = builder.get_object("entry") as Gtk.Entry;
567
entry.set_text(initial_text != null ? initial_text : "");
506
570
set_default_response(Gtk.ResponseType.OK);
508
vbox.pack_start(query, true, false, 6);
511
protected string? _execute() {
573
public string? execute() {
512
574
string? text = null;
514
576
// validate entry to start with
515
577
set_response_sensitive(Gtk.ResponseType.OK, on_modify_validate(entry.get_text()));
520
if (run() != Gtk.ResponseType.OK)
581
if (run() == Gtk.ResponseType.OK)
523
582
text = entry.get_text();
524
if (on_ok_validate(text))
535
private void on_entry_changed() {
589
public void on_entry_changed() {
536
590
set_response_sensitive(Gtk.ResponseType.OK, on_modify_validate(entry.get_text()));
539
protected virtual bool on_modify_validate(string text) {
543
protected virtual bool on_ok_validate(string text) {
548
public class EventRenameDialog : TextEntryDialog {
594
public class EventRenameDialog : TextEntryDialogMediator {
549
595
public EventRenameDialog(string? event_name) {
550
596
base (_("Rename Event"), _("Name:"), event_name);
553
public string? execute() {
599
public virtual string? execute() {
554
600
return _execute();
604
public class PhotoRenameDialog : TextEntryDialogMediator {
605
public PhotoRenameDialog(string? photo_name) {
606
base (_("Rename Photo"), _("Name:"), photo_name);
609
public virtual string? execute() {
610
return _execute().strip();
558
614
// Returns: Gtk.ResponseType.YES (trash photos), Gtk.ResponseType.NO (only remove photos) and
559
615
// Gtk.ResponseType.CANCEL.
560
public Gtk.ResponseType remove_photos_dialog(Gtk.Window owner, int count) {
616
public Gtk.ResponseType empty_trash_dialog(Gtk.Window owner, int count) {
561
617
string msg = ngettext(
562
618
"This will remove the photo from your Shotwell library. Would you also like to move the file to your desktop trash?\n\nThis action cannot be undone.",
563
"This will remove the selected photos from your Shotwell library. Would you also like to move the files to your desktop trash?\n\nThis action cannot be undone.",
619
"This will remove %d photos from your Shotwell library. Would you also like to move the files to your desktop trash?\n\nThis action cannot be undone.",
620
count).printf(count);
565
621
string trash_action = ngettext("_Trash File", "_Trash Files", count);
567
623
Gtk.MessageDialog dialog = new Gtk.MessageDialog(owner, Gtk.DialogFlags.MODAL,
568
624
Gtk.MessageType.WARNING, Gtk.ButtonsType.CANCEL, "%s", msg);
569
625
dialog.add_button(_("Only _Remove"), Gtk.ResponseType.NO);
570
626
dialog.add_button(trash_action, Gtk.ResponseType.YES);
571
dialog.title = _("Remove");
627
dialog.title = _("Empty Trash");
573
629
Gtk.ResponseType result = (Gtk.ResponseType) dialog.run();
1228
public class PreferencesDialog {
1229
private Gtk.Dialog dialog;
1230
private Gtk.Builder builder;
1231
private Gtk.Adjustment bg_color_adjustment;
1232
private bool display_borders;
1234
public PreferencesDialog() {
1235
builder = AppWindow.create_builder();
1237
dialog = builder.get_object("preferences_dialog") as Gtk.Dialog;
1238
dialog.set_parent_window(AppWindow.get_instance().get_parent_window());
1240
bg_color_adjustment = builder.get_object("bg_color_adjustment") as Gtk.Adjustment;
1241
bg_color_adjustment.set_value(bg_color_adjustment.get_upper() -
1242
Config.get_instance().get_bg_color().red);
1243
bg_color_adjustment.value_changed += on_value_changed;
1245
Gtk.CheckButton display_borders_button =
1246
builder.get_object("display_borders") as Gtk.CheckButton;
1247
display_borders = Config.get_instance().get_display_borders();
1248
display_borders_button.set_active(display_borders);
1249
display_borders_button.toggled += on_display_borders_toggled;
1252
public void execute() {
1255
if (dialog.run() == Gtk.ResponseType.CLOSE)
1256
Config.get_instance().commit_bg_color();
1261
private void on_value_changed() {
1262
set_background_color(bg_color_adjustment.get_upper() - bg_color_adjustment.get_value());
1265
private void set_background_color(double bg_color_value) {
1266
Config.get_instance().set_bg_color(to_grayscale((uint16) bg_color_value));
1269
private Gdk.Color to_grayscale(uint16 color_value) {
1270
Gdk.Color color = Gdk.Color();
1272
color.red = color_value;
1273
color.green = color_value;
1274
color.blue = color_value;
1279
private void on_display_borders_toggled() {
1280
display_borders = !display_borders;
1281
Config.get_instance().set_display_borders(display_borders);