1 /* Copyright 2009-2010 Yorba Foundation
3 * This software is licensed under the GNU Lesser General Public License
4 * (version 2.1 or later). See the COPYING file in this distribution.
7 namespace DialogUtils {
8 public struct filter_description_struct {
10 public string extension;
13 Gtk.FileFilter add_filter(Gtk.FileChooserDialog d, string name, string? extension) {
14 Gtk.FileFilter filter = new Gtk.FileFilter();
15 filter.set_name(name);
16 if (extension != null) {
17 filter.add_pattern("*." + extension);
19 filter.add_pattern("*");
25 void add_filters(filter_description_struct[] filter_descriptions, Gtk.FileChooserDialog d,
26 Gee.ArrayList<Gtk.FileFilter> filters, bool allow_all) {
28 int length = filter_descriptions.length;
29 for (int i=0;i<length;++i) {
30 Gtk.FileFilter filter = add_filter(d, filter_descriptions[i].name,
31 filter_descriptions[i].extension);
36 add_filter(d, "All files", null);
37 //don't add to filters. filters should have same number of items as filter_descriptions
40 assert(filter_descriptions.length == filters.size);
42 d.set_filter(filters[0]);
45 public bool open(Gtk.Window parent, filter_description_struct[] filter_descriptions,
46 bool allow_multiple, bool allow_all, out GLib.SList<string> filenames) {
47 bool return_value = false;
48 Hildon.FileChooserDialog file_chooser = new Hildon.FileChooserDialog(parent, Gtk.FileChooserAction.OPEN);
49 file_chooser.set_title("Open Files");
50 //file_chooser.set_parent(parent);
51 //file_chooser.set_current_folder(GLib.Environment.get_home_dir());
52 //file_chooser.set_safe_folder(GLib.Environment.get_home_dir());
53 file_chooser.set_show_upnp(true);
54 Gee.ArrayList<Gtk.FileFilter> filters = new Gee.ArrayList<Gtk.FileFilter>();
55 add_filters(filter_descriptions, (Gtk.FileChooserDialog)file_chooser, filters, allow_all);
56 file_chooser.set_select_multiple(allow_multiple);
57 if (file_chooser.run() == Gtk.ResponseType.OK) {
59 filenames = file_chooser.get_filenames();
61 file_chooser.destroy();
65 public bool save(Gtk.Window parent, string title, bool create_directory,
66 filter_description_struct[] filter_descriptions, ref string filename) {
67 bool return_value = false;
70 Hildon.FileChooserDialog file_chooser = new Hildon.FileChooserDialog(parent, Gtk.FileChooserAction.SAVE);
71 file_chooser.set_title(title);
72 file_chooser.set_show_upnp(false);
73 if (filename != null) {
74 file_chooser.set_current_folder(Path.get_dirname(filename));
76 //file_chooser.set_current_folder(GLib.Environment.get_home_dir());
78 int length = filter_descriptions.length;
79 Gee.ArrayList<Gtk.FileFilter> filters = new Gee.ArrayList<Gtk.FileFilter>();
81 // add_filters(filter_descriptions, (Gtk.FileChooserDialog)file_chooser, filters, false);
83 //all this extra code is because the dialog doesn't append the extension for us
84 //in the filename, so we can't use d.set_do_overwrite_confirmation
86 while (file_chooser.run() == Gtk.ResponseType.OK) {
87 string local_filename = file_chooser.get_filename();
88 if (create_directory) {
89 if (GLib.DirUtils.create(local_filename, 0777) != 0) {
90 error("Could not create directory", GLib.strerror(GLib.errno));;
91 file_chooser.present();
94 local_filename = Path.build_filename(local_filename,
95 Path.get_basename(local_filename));
98 unowned Gtk.FileFilter selected_filter = file_chooser.get_filter();
101 foreach (Gtk.FileFilter file_filter in filters) {
102 if (file_filter == selected_filter) {
110 local_filename = append_extension(local_filename, filter_descriptions[i].extension);
111 if (!FileUtils.test(local_filename, FileTest.EXISTS) ||
112 confirm_replace(parent, local_filename)) {
114 filename = local_filename;
118 file_chooser.present();
121 file_chooser.destroy();
125 string bold_message(string message) {
126 return message; //"<span weight=\"bold\" size=\"larger\">" + message + "</span>";
129 public void warning(string major_message, string? minor_message) {
130 string message = bold_message(major_message);
131 if (minor_message != null) {
132 message = message + "\n\n" + minor_message;
134 Gtk.Widget banner = Hildon.Banner.show_information_with_markup(null, null, message);
135 ((Hildon.Banner)banner).set_timeout(1000 * 2);
138 public void error(string major_message, string? minor_message) {
139 string message = bold_message(major_message);
140 if (minor_message != null) {
141 message = message + "\n\n" + minor_message;
143 Gtk.Widget banner = Hildon.Banner.show_information_with_markup(null, null, message);
144 ((Hildon.Banner)banner).set_timeout(1000 * 2);
147 Gtk.ResponseType run_dialog(Gtk.Window? parent, Gtk.MessageType type,
148 string? title, string message, ButtonStruct[] buttons) {
149 //string the_message = bold_message(message);
150 if (null == title) title = "Message";
151 Hildon.Dialog dialog = new Hildon.Dialog();
152 dialog.set_parent(parent);
153 dialog.set_title(title);
154 Gtk.VBox content = (Gtk.VBox)dialog.get_content_area();
155 Gtk.Label label = new Gtk.Label(message);
156 //label.use_markup = true;
157 label.single_line_mode = false;
158 label.set_line_wrap(true);
162 int length = buttons.length;
163 for (int i = 0; i < length; ++i) {
164 dialog.add_button(buttons[i].title, buttons[i].type);
168 Gtk.ResponseType response = (Gtk.ResponseType) dialog.run();
174 Gtk.ResponseType two_button_dialog(string message, string first_button, string second_button) {
175 Hildon.Dialog d = new Hildon.Dialog();
177 Gtk.VBox contents = (Gtk.VBox)d.get_content_area();
178 Gtk.VBox vbox = new Gtk.VBox(true, 4);
179 Gtk.Label label = new Gtk.Label(message);
180 label.use_markup = true;
181 label.single_line_mode = false;
182 label.set_line_wrap(true);
183 vbox.pack_start(label);
185 d.add_buttons(first_button, Gtk.ResponseType.NO,
186 second_button, Gtk.ResponseType.YES);
189 Gtk.ResponseType r = (Gtk.ResponseType) d.run();
195 public Gtk.ResponseType delete_keep(string message) {
196 return two_button_dialog(message, "Keep", Gtk.STOCK_DELETE);
199 public Gtk.ResponseType add_cancel(string message) {
200 return two_button_dialog(message, Gtk.STOCK_CANCEL, Gtk.STOCK_ADD);
203 public Gtk.ResponseType delete_cancel(string message) {
204 return two_button_dialog(message, Gtk.STOCK_CANCEL, Gtk.STOCK_DELETE);
207 public bool confirm_replace(Gtk.Window? parent, string filename) {
208 return Gtk.ResponseType.YES == two_button_dialog("<big><b>A file named \"%s\" already exists. Do you want to replace it?</b></big>", "Cancel", "Replace");
211 struct ButtonStruct {
212 public ButtonStruct(string title, Gtk.ResponseType type) {
218 public Gtk.ResponseType type;
221 public Gtk.ResponseType save_close_cancel(Gtk.Window? parent, string? title, string message) {
222 ButtonStruct[] buttons = {
223 ButtonStruct(Gtk.STOCK_CLOSE, Gtk.ResponseType.NO),
224 ButtonStruct(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL),
225 ButtonStruct(Gtk.STOCK_SAVE, Gtk.ResponseType.ACCEPT)
228 return run_dialog(parent, Gtk.MessageType.WARNING, title, message, buttons);
231 Gtk.Alignment get_aligned_label(float x, float y, float exp_x, float exp_y, string text,
233 Gtk.Label l = new Gtk.Label(text);
234 l.set_line_wrap(true);
236 l.selectable = selectable;
238 Gtk.Alignment a = new Gtk.Alignment(x, y, exp_x, exp_y);
244 void add_label_to_table(Gtk.Table t, string str, int x, int y, int xpad, int ypad,
246 Gtk.Alignment a = get_aligned_label(0.0f, 0.0f, 0.0f, 0.0f, str, selectable);
247 t.attach(a, x, x + 1, y, y + 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, xpad, ypad);
250 public void show_clip_properties(Gtk.Window parent, ClipView? selected_clip,
251 Model.ClipFile ? clip_file, Fraction? frames_per_second) {
252 Hildon.Dialog d = new Hildon.Dialog.with_buttons("Clip Properties", parent,
253 Gtk.DialogFlags.MODAL, Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT);
254 if (selected_clip != null) {
255 clip_file = selected_clip.clip.clipfile;
258 d.set("has-separator", false);
260 Gtk.Table t = new Gtk.Table(10, 2, false);
262 int tab_padding = 25;
264 for (int i = 0; i < 10; i++)
265 t.set_row_spacing(i, 10);
268 add_label_to_table(t, "<b>Clip</b>", 0, row++, 5, 0, false);
270 if (selected_clip != null) {
271 add_label_to_table(t, "<i>Name:</i>", 0, row, tab_padding, 0, false);
272 add_label_to_table(t, "%s".printf(selected_clip.clip.name), 1, row++, 5, 0, true);
275 add_label_to_table(t, "<i>Location:</i>", 0, row, tab_padding, 0, false);
276 add_label_to_table(t, "%s".printf(clip_file.filename), 1, row++, 5, 0, true);
278 if (selected_clip != null) {
279 add_label_to_table(t, "<i>Timeline length:</i>", 0, row, tab_padding, 0, false);
281 string length_string = "";
282 string actual_length = "";
284 if (frames_per_second != null && frames_per_second.numerator > 0) {
285 TimeCode time = frame_to_time (time_to_frame_with_rate(selected_clip.clip.duration,
286 frames_per_second), frames_per_second);
287 length_string = time.to_string();
288 time = frame_to_time(time_to_frame_with_rate(
289 selected_clip.clip.clipfile.length, frames_per_second), frames_per_second);
290 actual_length = time.to_string();
292 length_string = time_to_string(selected_clip.clip.duration);
293 actual_length = time_to_string(selected_clip.clip.clipfile.length);
296 add_label_to_table(t, "%s".printf(length_string), 1, row++, 5, 0, true);
298 if (selected_clip.clip.is_trimmed()) {
299 add_label_to_table(t, "<i>Actual length:</i>", 0, row, tab_padding, 0, false);
300 add_label_to_table(t, "%s".printf(actual_length), 1, row++, 5, 0, true);
304 if (clip_file.has_caps_structure(Model.MediaType.VIDEO)) {
305 add_label_to_table(t, "<b>Video</b>", 0, row++, 5, 0, false);
308 if (clip_file.get_dimensions(out w, out h)) {
309 add_label_to_table(t, "<i>Dimensions:</i>", 0, row, tab_padding, 0, false);
310 add_label_to_table(t, "%d x %d".printf(w, h), 1, row++, 5, 0, true);
314 if (clip_file.get_frame_rate(out r)) {
315 add_label_to_table(t, "<i>Frame rate:</i>", 0, row, tab_padding, 0, false);
317 if (r.numerator % r.denominator != 0)
318 add_label_to_table(t,
319 "%.2f frames per second".printf(r.numerator / (float)r.denominator),
320 1, row++, 5, 0, true);
322 add_label_to_table(t,
323 "%d frames per second".printf(r.numerator / r.denominator),
324 1, row++, 5, 0, true);
328 if (clip_file.has_caps_structure(Model.MediaType.AUDIO)) {
329 add_label_to_table(t, "<b>Audio</b>", 0, row++, 5, 0, false);
332 if (clip_file.get_sample_rate(out rate)) {
333 add_label_to_table(t, "<i>Sample rate:</i>", 0, row, tab_padding, 0, false);
334 add_label_to_table(t, "%d Hz".printf(rate), 1, row++, 5, 0, true);
338 if (clip_file.get_num_channels_string(out s)) {
339 add_label_to_table(t, "<i>Number of channels:</i>", 0, row, tab_padding, 0, false);
340 add_label_to_table(t, "%s".printf(s), 1, row++, 5, 0, true);
344 d.vbox.pack_start(t, false, false, 0);