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 }