src/MainWindow.vala (5617B) - raw
1 /*
2 * xmpedit
3 * Copyright 2010 Dan Callaghan <djc@djc.id.au>
4 * Released under GPLv2
5 */
6
7 namespace Xmpedit {
8
9 private const string STOCK_CLOSE_WITHOUT_SAVING = "xmpedit-close-without-saving";
10
11 public class MainWindow : Gtk.Window {
12
13 private File file;
14 private ImageMetadata image_metadata;
15 private Gtk.Table table;
16 private Gtk.Image image_preview;
17 private MetadataTreeView tree_view;
18 private PropertyDetailView detail_view;
19
20 static construct {
21 add_stock();
22 }
23
24 public MainWindow(string path) throws GLib.Error {
25 Object(type: Gtk.WindowType.TOPLEVEL);
26 file = File.new_for_path(path);
27 image_metadata = new ImageMetadata(path);
28 image_metadata.load();
29 table = new Gtk.Table(/* rows */ 2, /* cols */ 2, /* homogeneous */ false);
30
31 title = file.get_basename();
32 default_width = 640;
33 default_height = 480;
34 allow_shrink = true;
35
36 image_preview = new Gtk.Image.from_pixbuf(new Gdk.Pixbuf.from_file_at_scale(path, 320, 320, /* preserve aspect */ true));
37 ((Atk.Object) image_preview.get_accessible())
38 .set_name("Image preview");
39 ((Atk.Object) image_preview.get_accessible())
40 .set_role(Atk.Role.IMAGE);
41 ((Atk.Image) image_preview.get_accessible())
42 .set_image_description(@"Preview of $(file.get_basename())");
43 table.attach(image_preview,
44 1, 2, 0, 1,
45 Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, 0,
46 10, 10);
47
48 tree_view = new MetadataTreeView.connected_to(image_metadata);
49 ((Atk.Object) tree_view.get_accessible())
50 .set_name("Image properties");
51 var tree_view_scrolled = new Gtk.ScrolledWindow(null, null);
52 tree_view_scrolled.add(tree_view);
53 tree_view_scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
54 var revert_button = new Gtk.Button.from_stock(Gtk.Stock.REVERT_TO_SAVED);
55 revert_button.clicked.connect(() => {
56 image_metadata.revert();
57 tree_view.set_cursor(new Gtk.TreePath.first(), null, false);
58 });
59 var save_button = new Gtk.Button.from_stock(Gtk.Stock.SAVE);
60 save_button.clicked.connect(() => {
61 image_metadata.save();
62 });
63 revert_button.sensitive = false;
64 save_button.sensitive = false;
65 image_metadata.notify.connect((p) => {
66 if (p.name == "dirty") {
67 revert_button.sensitive = image_metadata.dirty;
68 save_button.sensitive = image_metadata.dirty;
69 }
70 });
71 var left_button_box = new Gtk.HButtonBox();
72 left_button_box.spacing = 5;
73 left_button_box.layout_style = Gtk.ButtonBoxStyle.END;
74 left_button_box.add(revert_button);
75 left_button_box.add(save_button);
76 var left_vbox = new Gtk.VBox(/* homogeneous */ false, /* spacing */ 0);
77 left_vbox.pack_start(tree_view_scrolled, /* expand */ true, /* fill */ true);
78 left_vbox.pack_start(left_button_box, /* expand */ false, /* fill */ false,
79 /* padding */ 5);
80 table.attach(left_vbox,
81 0, 1, 0, 2,
82 Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
83 0, 0);
84
85 detail_view = new PropertyDetailView.connected_to(image_metadata, tree_view);
86 table.attach(detail_view,
87 1, 2, 1, 2,
88 Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
89 Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
90 0, 0);
91
92 add(table);
93 show_all();
94
95 delete_event.connect(() => {
96 if (image_metadata.dirty) {
97 var dialog = new Gtk.MessageDialog.with_markup(
98 /* parent */ this, Gtk.DialogFlags.MODAL,
99 Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE,
100 "<big><b>Your changes to image \"%s\" have not been saved.</b></big>\n\n" +
101 "Save changes before closing?",
102 file.get_basename());
103 dialog.add_button(STOCK_CLOSE_WITHOUT_SAVING, 1);
104 dialog.add_button(Gtk.Stock.CANCEL, 2);
105 dialog.add_button(Gtk.Stock.SAVE, 3);
106 dialog.set_default_response(3);
107 var response = dialog.run();
108 dialog.destroy();
109 switch (response) {
110 case 3: // save
111 image_metadata.save();
112 return false;
113 case 1: // close
114 return false;
115 case 2: // cancel
116 default:
117 return true;
118 }
119 }
120 return false;
121 });
122
123 add_stock();
124 }
125
126 private static Gtk.StockItem[] STOCK = {
127 Gtk.StockItem() {
128 stock_id = STOCK_CLOSE_WITHOUT_SAVING,
129 label = "Close _without saving",
130 modifier = 0,
131 keyval = 0,
132 translation_domain = null
133 }
134 };
135
136 /** Create custom stock entries used in the application. */
137 private static void add_stock() {
138 Gtk.Stock.add_static(STOCK);
139
140 var icon_factory = new Gtk.IconFactory();
141 icon_factory.add(STOCK_CLOSE_WITHOUT_SAVING,
142 Gtk.IconFactory.lookup_default(Gtk.Stock.CLOSE));
143 icon_factory.add_default();
144 }
145
146 }
147
148 }