Merge lp:~meese/pantheon-photos/fix-1321029 into lp:~pantheon-photos/pantheon-photos/trunk

Proposed by meese
Status: Merged
Approved by: Corentin Noël
Approved revision: 2554
Merged at revision: 2570
Proposed branch: lp:~meese/pantheon-photos/fix-1321029
Merge into: lp:~pantheon-photos/pantheon-photos/trunk
Diff against target: 1283 lines (+452/-455)
9 files modified
src/CollectionPage.vala (+102/-60)
src/DesktopIntegration.vala (+1/-1)
src/Dialogs.vala (+0/-93)
src/Page.vala (+2/-1)
src/Photo.vala (+9/-7)
src/PhotoPage.vala (+94/-60)
src/Resources.vala (+235/-227)
ui/collection.ui (+4/-2)
ui/photo_context.ui (+5/-4)
To merge this branch: bzr merge lp:~meese/pantheon-photos/fix-1321029
Reviewer Review Type Date Requested Status
Corentin Noël Approve
meese Needs Resubmitting
Review via email: mp+227405@code.launchpad.net

Commit message

Replaces external editor in photo context menu with full open with menu, fixes bug 1321029

Description of the change

Replaces external editor in photo context menu with full open with menu, fixes bug 1321029

To post a comment you must log in.
2549. By meese

fix format issue

Revision history for this message
Corentin Noël (tintou) wrote :

The implementation is right, I found some issues with the codestyle.
I would prefer the use of Gtk.Image.from_gicon as explained in the inline diff: IMO currently the icons are too gib and are inconsistent with the open with menu from Files, using IconSize.MENU will fix this for sure.

review: Needs Fixing
2550. By meese

standardizes the get icon method and smaller size, fixes code style issues

Revision history for this message
meese (meese) wrote :

fixed and I changed the code style to match the file but if I updated the entire file to follow http://elementaryos.org/docs/code/code-style would that be okay too?

review: Needs Resubmitting
2551. By meese

fix for updated master code style change

2552. By meese

manual merge from master

Revision history for this message
Corentin Noël (tintou) wrote :

Only a few typo remaining and it's okay!

2553. By meese

style fixes

Revision history for this message
Corentin Noël (tintou) wrote :

Well, Daniel says that showing the pantheon-photos entry is a bug

review: Needs Fixing
2554. By meese

fixes pantheon photos showing in open with menu

Revision history for this message
Corentin Noël (tintou) wrote :

It's now working fine !

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/CollectionPage.vala'
2--- src/CollectionPage.vala 2014-08-08 21:13:09 +0000
3+++ src/CollectionPage.vala 2014-08-12 01:17:16 +0000
4@@ -38,9 +38,6 @@
5 init_toolbar ("/CollectionToolbar");
6
7 show_all ();
8-
9- // watch for updates to the external app settings
10- Config.Facade.get_instance ().external_app_changed.connect (on_external_app_changed);
11 }
12
13 public override Gtk.Toolbar get_toolbar () {
14@@ -200,17 +197,13 @@
15 adjust_date_time.label = Resources.ADJUST_DATE_TIME_MENU;
16 actions += adjust_date_time;
17
18- Gtk.ActionEntry external_edit = { "ExternalEdit", Gtk.Stock.EDIT, TRANSLATABLE, "<Ctrl>Return",
19- TRANSLATABLE, on_external_edit
20- };
21- external_edit.label = Resources.EXTERNAL_EDIT_MENU;
22- actions += external_edit;
23+ Gtk.ActionEntry open_with = { "OpenWith", null, TRANSLATABLE, null, null, null };
24+ open_with.label = Resources.OPEN_WITH_MENU;
25+ actions += open_with;
26
27- Gtk.ActionEntry edit_raw = { "ExternalEditRAW", null, TRANSLATABLE, "<Ctrl><Shift>Return",
28- TRANSLATABLE, on_external_edit_raw
29- };
30- edit_raw.label = Resources.EXTERNAL_EDIT_RAW_MENU;
31- actions += edit_raw;
32+ Gtk.ActionEntry open_with_raw = { "OpenWithRaw", null, TRANSLATABLE, null, null, null };
33+ open_with_raw.label = Resources.OPEN_WITH_RAW_MENU;
34+ actions += open_with_raw;
35
36 Gtk.ActionEntry slideshow = { "Slideshow", null, TRANSLATABLE, "F5", TRANSLATABLE,
37 on_slideshow
38@@ -233,6 +226,94 @@
39 return groups;
40 }
41
42+ public override Gtk.Menu? get_item_context_menu () {
43+ Gtk.Menu menu = (Gtk.Menu) ui.get_widget ("/CollectionContextMenu");
44+ assert (menu != null);
45+
46+ Gtk.MenuItem open_with_menu_item = (Gtk.MenuItem) ui.get_widget ("/CollectionContextMenu/OpenWith");
47+ populate_external_app_menu ((Gtk.Menu)open_with_menu_item.get_submenu (), false);
48+ open_with_menu_item.show ();
49+
50+ if (((Photo) get_view ().get_selected_at (0).get_source ()).get_master_file_format () == PhotoFileFormat.RAW) {
51+ Gtk.MenuItem open_with_raw_menu_item = (Gtk.MenuItem) ui.get_widget ("/CollectionContextMenu/OpenWithRaw");
52+ populate_external_app_menu ((Gtk.Menu)open_with_raw_menu_item.get_submenu (), true);
53+ open_with_raw_menu_item.show ();
54+ }
55+
56+ return menu;
57+ }
58+
59+ private void populate_external_app_menu (Gtk.Menu menu, bool raw) {
60+ Gtk.MenuItem parent = menu.get_attach_widget () as Gtk.MenuItem;
61+ SortedList<AppInfo> external_apps;
62+ string[] mime_types;
63+
64+ // get list of all applications for the given mime types
65+ if (raw)
66+ mime_types = PhotoFileFormat.RAW.get_mime_types ();
67+ else
68+ mime_types = PhotoFileFormat.get_editable_mime_types ();
69+ assert (mime_types.length != 0);
70+ external_apps = DesktopIntegration.get_apps_for_mime_types (mime_types);
71+
72+ if (external_apps.size == 0) {
73+ parent.sensitive = false;
74+ return;
75+ }
76+
77+ foreach (Gtk.Widget item in menu.get_children ())
78+ menu.remove (item);
79+ parent.sensitive = true;
80+
81+ foreach (AppInfo app in external_apps) {
82+ Gtk.ImageMenuItem item_app = new Gtk.ImageMenuItem.with_label (app.get_name ());
83+ Gtk.Image image = new Gtk.Image.from_gicon (app.get_icon (), Gtk.IconSize.MENU);
84+ item_app.always_show_image = true;
85+ item_app.set_image (image);
86+ item_app.activate.connect (() => {
87+ if (raw)
88+ on_open_with_raw (app.get_commandline ());
89+ else
90+ on_open_with (app.get_commandline ());
91+ });
92+ menu.add (item_app);
93+ }
94+ menu.show_all ();
95+ }
96+
97+ private void on_open_with (string app) {
98+ if (get_view ().get_selected_count () != 1)
99+ return;
100+
101+ Photo photo = (Photo) get_view ().get_selected_at (0).get_source ();
102+ try {
103+ AppWindow.get_instance ().set_busy_cursor ();
104+ photo.open_with_external_editor (app);
105+ AppWindow.get_instance ().set_normal_cursor ();
106+ } catch (Error err) {
107+ AppWindow.get_instance ().set_normal_cursor ();
108+ open_external_editor_error_dialog (err, photo);
109+ }
110+ }
111+
112+ private void on_open_with_raw (string app) {
113+ if (get_view ().get_selected_count () != 1)
114+ return;
115+
116+ Photo photo = (Photo) get_view ().get_selected_at (0).get_source ();
117+ if (photo.get_master_file_format () != PhotoFileFormat.RAW)
118+ return;
119+
120+ try {
121+ AppWindow.get_instance ().set_busy_cursor ();
122+ photo.open_with_raw_external_editor (app);
123+ AppWindow.get_instance ().set_normal_cursor ();
124+ } catch (Error err) {
125+ AppWindow.get_instance ().set_normal_cursor ();
126+ AppWindow.error_message (Resources.launch_editor_failed (err));
127+ }
128+ }
129+
130 private bool selection_has_video () {
131 return MediaSourceCollection.has_video ((Gee.Collection<MediaSource>) get_view ().get_selected_sources ());
132 }
133@@ -275,14 +356,12 @@
134 // don't allow duplication of the selection if it contains a video -- videos are huge and
135 // and they're not editable anyway, so there seems to be no use case for duplicating them
136 set_action_sensitive ("Duplicate", has_selected && (!selection_has_videos));
137- set_action_visible ("ExternalEdit", (!primary_is_video));
138- set_action_sensitive ("ExternalEdit",
139- one_selected && !is_string_empty (Config.Facade.get_instance ().get_external_photo_app ()));
140- set_action_visible ("ExternalEditRAW",
141+ set_action_visible ("OpenWith", (!primary_is_video));
142+ set_action_sensitive ("OpenWith", one_selected);
143+ set_action_visible ("OpenWithRaw",
144 one_selected && (!primary_is_video)
145 && ((Photo) get_view ().get_selected_at (0).get_source ()).get_master_file_format () ==
146- PhotoFileFormat.RAW
147- && !is_string_empty (Config.Facade.get_instance ().get_external_raw_app ()));
148+ PhotoFileFormat.RAW);
149 set_action_sensitive ("Revert", (!selection_has_videos) && can_revert_selected ());
150 set_action_sensitive ("Enhance", (!selection_has_videos) && has_selected);
151 set_action_sensitive ("CopyColorAdjustments", (!selection_has_videos) && one_selected &&
152@@ -345,12 +424,6 @@
153 }
154 }
155
156- private void on_external_app_changed () {
157- int selected_count = get_view ().get_selected_count ();
158-
159- set_action_sensitive ("ExternalEdit", selected_count == 1 && Config.Facade.get_instance ().get_external_photo_app () != "");
160- }
161-
162 // see #2020
163 // double clcik = switch to photo page
164 // Super + double click = open in external editor
165@@ -378,7 +451,8 @@
166
167 if (activator == CheckerboardPage.Activator.MOUSE) {
168 if (modifiers.super_pressed)
169- on_external_edit ();
170+ //last used
171+ on_open_with (Config.Facade.get_instance ().get_external_photo_app ());
172 else
173 LibraryWindow.get_app ().switch_to_photo_page (this, photo);
174 } else if (activator == CheckerboardPage.Activator.KEYBOARD) {
175@@ -649,39 +723,6 @@
176 }
177 }
178
179- private void on_external_edit () {
180- if (get_view ().get_selected_count () != 1)
181- return;
182-
183- Photo photo = (Photo) get_view ().get_selected_at (0).get_source ();
184- try {
185- AppWindow.get_instance ().set_busy_cursor ();
186- photo.open_with_external_editor ();
187- AppWindow.get_instance ().set_normal_cursor ();
188- } catch (Error err) {
189- AppWindow.get_instance ().set_normal_cursor ();
190- open_external_editor_error_dialog (err, photo);
191- }
192- }
193-
194- private void on_external_edit_raw () {
195- if (get_view ().get_selected_count () != 1)
196- return;
197-
198- Photo photo = (Photo) get_view ().get_selected_at (0).get_source ();
199- if (photo.get_master_file_format () != PhotoFileFormat.RAW)
200- return;
201-
202- try {
203- AppWindow.get_instance ().set_busy_cursor ();
204- photo.open_with_raw_external_editor ();
205- AppWindow.get_instance ().set_normal_cursor ();
206- } catch (Error err) {
207- AppWindow.get_instance ().set_normal_cursor ();
208- AppWindow.error_message (Resources.launch_editor_failed (err));
209- }
210- }
211-
212 public void on_set_background () {
213 Gee.ArrayList<LibraryPhoto> photos = new Gee.ArrayList<LibraryPhoto> ();
214 MediaSourceCollection.filter_media ((Gee.Collection<MediaSource>) get_view ().get_selected_sources (),
215@@ -747,4 +788,5 @@
216 public override SearchViewFilter get_search_view_filter () {
217 return search_filter;
218 }
219-}
220\ No newline at end of file
221+}
222+
223
224=== modified file 'src/DesktopIntegration.vala'
225--- src/DesktopIntegration.vala 2014-08-08 21:13:09 +0000
226+++ src/DesktopIntegration.vala 2014-08-12 01:17:16 +0000
227@@ -72,7 +72,7 @@
228 }
229
230 // dont add Shotwell to app list
231- if (!already_contains && !external_app.get_name ().contains (_ (Resources.APP_TITLE)))
232+ if (!already_contains && !external_app.get_name ().contains (_(Resources.APP_DIRECT_ROLE)))
233 external_apps.add (external_app);
234 }
235 }
236
237=== modified file 'src/Dialogs.vala'
238--- src/Dialogs.vala 2014-08-09 14:07:36 +0000
239+++ src/Dialogs.vala 2014-08-12 01:17:16 +0000
240@@ -2198,10 +2198,6 @@
241 private Gtk.Builder builder;
242 private Gtk.Adjustment bg_color_adjustment;
243 private Gtk.Scale bg_color_slider;
244- private Gtk.ComboBox photo_editor_combo;
245- private Gtk.ComboBox raw_editor_combo;
246- private SortedList<AppInfo> external_raw_apps;
247- private SortedList<AppInfo> external_photo_apps;
248 private Gtk.FileChooserButton library_dir_button;
249 private Gtk.ComboBoxText dir_pattern_combo;
250 private Gtk.Entry dir_pattern_entry;
251@@ -2268,8 +2264,6 @@
252
253 close_button = builder.get_object ("close_button") as Gtk.Button;
254
255- photo_editor_combo = builder.get_object ("external_photo_editor_combo") as Gtk.ComboBox;
256- raw_editor_combo = builder.get_object ("external_raw_editor_combo") as Gtk.ComboBox;
257
258 Gtk.Label pattern_help = builder.get_object ("pattern_help") as Gtk.Label;
259
260@@ -2316,8 +2310,6 @@
261
262 populate_preference_options ();
263
264- photo_editor_combo.changed.connect (on_photo_editor_changed);
265- raw_editor_combo.changed.connect (on_raw_editor_changed);
266
267 Gtk.CheckButton auto_import_button = builder.get_object ("autoimport") as Gtk.CheckButton;
268 auto_import_button.set_active (Config.Facade.get_instance ().get_auto_import_from_library ());
269@@ -2333,11 +2325,6 @@
270 }
271
272 public void populate_preference_options () {
273- populate_app_combo_box (photo_editor_combo, PhotoFileFormat.get_editable_mime_types (),
274- Config.Facade.get_instance ().get_external_photo_app (), out external_photo_apps);
275-
276- populate_app_combo_box (raw_editor_combo, PhotoFileFormat.RAW.get_mime_types (),
277- Config.Facade.get_instance ().get_external_raw_app (), out external_raw_apps);
278
279 setup_dir_pattern (dir_pattern_combo, dir_pattern_entry);
280
281@@ -2355,64 +2342,6 @@
282 return true;
283 }
284
285- private void populate_app_combo_box (Gtk.ComboBox combo_box, string[] mime_types,
286- string current_app_executable, out SortedList<AppInfo> external_apps) {
287- // get list of all applications for the given mime types
288- assert (mime_types.length != 0);
289- external_apps = DesktopIntegration.get_apps_for_mime_types (mime_types);
290-
291- if (external_apps.size == 0)
292- return;
293-
294- // populate application ComboBox with app names and icons
295- Gtk.CellRendererPixbuf pixbuf_renderer = new Gtk.CellRendererPixbuf ();
296- Gtk.CellRendererText text_renderer = new Gtk.CellRendererText ();
297- combo_box.clear ();
298- combo_box.pack_start (pixbuf_renderer, false);
299- combo_box.pack_start (text_renderer, false);
300- combo_box.add_attribute (pixbuf_renderer, "pixbuf", 0);
301- combo_box.add_attribute (text_renderer, "text", 1);
302-
303- // TODO: need more space between icons and text
304- Gtk.ListStore combo_store = new Gtk.ListStore (2, typeof (Gdk.Pixbuf), typeof (string));
305- Gtk.TreeIter iter;
306-
307- int current_app = -1;
308-
309- foreach (AppInfo app in external_apps) {
310- combo_store.append (out iter);
311-
312- Icon app_icon = app.get_icon ();
313- try {
314- if (app_icon is FileIcon) {
315- combo_store.set_value (iter, 0, scale_pixbuf (new Gdk.Pixbuf.from_file (
316- ((FileIcon) app_icon).get_file ().get_path ()), Resources.DEFAULT_ICON_SCALE,
317- Gdk.InterpType.BILINEAR, false));
318- } else if (app_icon is ThemedIcon) {
319- Gdk.Pixbuf icon_pixbuf =
320- Gtk.IconTheme.get_default ().load_icon (((ThemedIcon) app_icon).get_names ()[0],
321- Resources.DEFAULT_ICON_SCALE, Gtk.IconLookupFlags.FORCE_SIZE);
322-
323- combo_store.set_value (iter, 0, icon_pixbuf);
324- }
325- } catch (GLib.Error error) {
326- warning ("Error loading icon pixbuf: " + error.message);
327- }
328-
329- combo_store.set_value (iter, 1, app.get_name ());
330-
331- if (app.get_commandline () == current_app_executable)
332- current_app = external_apps.index_of (app);
333- }
334-
335- // TODO: allow users to choose unlisted applications like Nautilus's "Open with -> Other Application..."
336-
337- combo_box.set_model (combo_store);
338-
339- if (current_app != -1)
340- combo_box.set_active (current_app);
341- }
342-
343 private void setup_dir_pattern (Gtk.ComboBox combo_box, Gtk.Entry entry) {
344 string? pattern = Config.Facade.get_instance ().get_directory_pattern ();
345 bool found = false;
346@@ -2574,28 +2503,6 @@
347 return color;
348 }
349
350- private void on_photo_editor_changed () {
351- int photo_app_choice_index = (photo_editor_combo.get_active () < external_photo_apps.size) ?
352- photo_editor_combo.get_active () : external_photo_apps.size;
353-
354- AppInfo app = external_photo_apps.get_at (photo_app_choice_index);
355-
356- Config.Facade.get_instance ().set_external_photo_app (DesktopIntegration.get_app_open_command (app));
357-
358- debug ("setting external photo editor to: %s", DesktopIntegration.get_app_open_command (app));
359- }
360-
361- private void on_raw_editor_changed () {
362- int raw_app_choice_index = (raw_editor_combo.get_active () < external_raw_apps.size) ?
363- raw_editor_combo.get_active () : external_raw_apps.size;
364-
365- AppInfo app = external_raw_apps.get_at (raw_app_choice_index);
366-
367- Config.Facade.get_instance ().set_external_raw_app (app.get_commandline ());
368-
369- debug ("setting external raw editor to: %s", app.get_commandline ());
370- }
371-
372 private RawDeveloper raw_developer_from_combo () {
373 if (default_raw_developer_combo.get_active () == 0)
374 return RawDeveloper.CAMERA;
375
376=== modified file 'src/Page.vala'
377--- src/Page.vala 2014-08-08 21:13:09 +0000
378+++ src/Page.vala 2014-08-12 01:17:16 +0000
379@@ -2621,4 +2621,5 @@
380 private void on_export_completed () {
381 exporter = null;
382 }
383-}
384\ No newline at end of file
385+}
386+
387
388=== modified file 'src/Photo.vala'
389--- src/Photo.vala 2014-08-08 21:13:09 +0000
390+++ src/Photo.vala 2014-08-12 01:17:16 +0000
391@@ -3653,9 +3653,7 @@
392 return generate_unique_file (backing.get_parent (), editable_basename, out collision);
393 }
394
395- private static bool launch_editor (File file, PhotoFileFormat file_format) throws Error {
396- string commandline = file_format == PhotoFileFormat.RAW ? Config.Facade.get_instance ().get_external_raw_app () :
397- Config.Facade.get_instance ().get_external_photo_app ();
398+ private static bool launch_editor (File file, PhotoFileFormat file_format, string commandline) throws Error {
399
400 if (is_string_empty (commandline))
401 return false;
402@@ -3690,12 +3688,14 @@
403 }
404
405 // Opens with Ufraw, etc.
406- public void open_with_raw_external_editor () throws Error {
407- launch_editor (get_master_file (), get_master_file_format ());
408+ public void open_with_raw_external_editor (string external_editor) throws Error {
409+ //store last used
410+ Config.Facade.get_instance ().set_external_raw_app (external_editor);
411+ launch_editor (get_master_file (), get_master_file_format (), external_editor);
412 }
413
414 // Opens with GIMP, etc.
415- public void open_with_external_editor () throws Error {
416+ public void open_with_external_editor (string external_editor) throws Error {
417 File current_editable_file = null;
418 File create_editable_file = null;
419 PhotoFileFormat editable_file_format;
420@@ -3747,7 +3747,9 @@
421 if (editable_monitor == null)
422 start_monitoring_editable (current_editable_file);
423
424- launch_editor (current_editable_file, get_file_format ());
425+ //store last used
426+ Config.Facade.get_instance ().set_external_photo_app (external_editor);
427+ launch_editor (current_editable_file, get_file_format (), external_editor);
428 }
429
430 public void revert_to_master (bool notify = true) {
431
432=== modified file 'src/PhotoPage.vala'
433--- src/PhotoPage.vala 2014-08-09 13:57:30 +0000
434+++ src/PhotoPage.vala 2014-08-12 01:17:16 +0000
435@@ -2335,9 +2335,6 @@
436 LibraryPhoto.global.item_destroyed.connect (on_photo_destroyed);
437 LibraryPhoto.global.items_altered.connect (on_metadata_altered);
438
439- // watch for updates to the external app settings
440- Config.Facade.get_instance ().external_app_changed.connect (on_external_app_changed);
441-
442 // Filter out trashed files.
443 get_view ().install_view_filter (filter);
444 LibraryPhoto.global.items_unlinking.connect (on_photo_unlinking);
445@@ -2347,7 +2344,6 @@
446 ~LibraryPhotoPage () {
447 LibraryPhoto.global.item_destroyed.disconnect (on_photo_destroyed);
448 LibraryPhoto.global.items_altered.disconnect (on_metadata_altered);
449- Config.Facade.get_instance ().external_app_changed.disconnect (on_external_app_changed);
450 }
451
452 public bool not_trashed_view_filter (DataView view) {
453@@ -2523,19 +2519,7 @@
454 };
455 adjust_date_time.label = Resources.ADJUST_DATE_TIME_MENU;
456 actions += adjust_date_time;
457-
458- Gtk.ActionEntry external_edit = { "ExternalEdit", Gtk.Stock.EDIT, TRANSLATABLE,
459- "<Ctrl>Return", TRANSLATABLE, on_external_edit
460- };
461- external_edit.label = Resources.EXTERNAL_EDIT_MENU;
462- actions += external_edit;
463-
464- Gtk.ActionEntry edit_raw = { "ExternalEditRAW", null, TRANSLATABLE, "<Ctrl><Shift>Return",
465- TRANSLATABLE, on_external_edit_raw
466- };
467- edit_raw.label = Resources.EXTERNAL_EDIT_RAW_MENU;
468- actions += edit_raw;
469-
470+
471 Gtk.ActionEntry send_to = { "SendTo", "document-send", TRANSLATABLE, null,
472 TRANSLATABLE, on_send_to
473 };
474@@ -2673,6 +2657,14 @@
475 raw_developer.label = _ ("_Developer");
476 actions += raw_developer;
477
478+ Gtk.ActionEntry open_with = { "OpenWith", null, TRANSLATABLE, null, null, null };
479+ open_with.label = Resources.OPEN_WITH_MENU;
480+ actions += open_with;
481+
482+ Gtk.ActionEntry open_with_raw = { "OpenWithRaw", null, TRANSLATABLE, null, null, null };
483+ open_with_raw.label = Resources.OPEN_WITH_RAW_MENU;
484+ actions += open_with_raw;
485+
486 // These are identical to add_tags and send_to, except that they have
487 // different mnemonics and are _only_ for use in the context menu.
488 Gtk.ActionEntry send_to_context_menu = { "SendToContextMenu", "document-send", TRANSLATABLE, null,
489@@ -2764,8 +2756,8 @@
490 bool rotate_possible = has_photo () ? is_rotate_available (get_photo ()) : false;
491 bool is_raw = has_photo () && get_photo ().get_master_file_format () == PhotoFileFormat.RAW;
492
493- set_action_sensitive ("ExternalEdit",
494- has_photo () && Config.Facade.get_instance ().get_external_photo_app () != "");
495+ set_action_sensitive ("OpenWith",
496+ has_photo ());
497
498 set_action_sensitive ("Revert", has_photo () ?
499 (get_photo ().has_transformations () || get_photo ().has_editable ()) : false);
500@@ -2795,8 +2787,8 @@
501
502 update_flag_action ();
503
504- set_action_visible ("ExternalEditRAW",
505- is_raw && Config.Facade.get_instance ().get_external_raw_app () != "");
506+ set_action_visible ("OpenWithRaw",
507+ is_raw);
508
509 base.update_actions (selected_count, count);
510 }
511@@ -2961,8 +2953,8 @@
512 set_action_sensitive ("Adjust", sensitivity);
513 set_action_sensitive ("EditTitle", sensitivity);
514 set_action_sensitive ("AdjustDateTime", sensitivity);
515- set_action_sensitive ("ExternalEdit", sensitivity);
516- set_action_sensitive ("ExternalEditRAW", sensitivity);
517+ set_action_sensitive ("OpenWith", sensitivity);
518+ set_action_sensitive ("OpenWithRaw", sensitivity);
519 set_action_sensitive ("Revert", sensitivity);
520
521 set_action_sensitive ("Rate", sensitivity);
522@@ -3088,6 +3080,16 @@
523 private Gtk.Menu get_context_menu () {
524 Gtk.Menu menu = (Gtk.Menu) ui.get_widget ("/PhotoContextMenu");
525 assert (menu != null);
526+
527+ Gtk.MenuItem open_with_menu_item = (Gtk.MenuItem) ui.get_widget ("/PhotoContextMenu/OpenWith");
528+ populate_external_app_menu ((Gtk.Menu)open_with_menu_item.get_submenu (), false);
529+ open_with_menu_item.show ();
530+
531+ if (has_photo () && get_photo ().get_master_file_format () == PhotoFileFormat.RAW) {
532+ Gtk.MenuItem open_with_raw_menu_item = (Gtk.MenuItem) ui.get_widget ("/PhotoContextMenu/OpenWithRaw");
533+ populate_external_app_menu ((Gtk.Menu)open_with_raw_menu_item.get_submenu (), true);
534+ open_with_raw_menu_item.show ();
535+ }
536 return menu;
537 }
538
539@@ -3103,6 +3105,75 @@
540 return true;
541 }
542
543+ private void populate_external_app_menu (Gtk.Menu menu, bool raw) {
544+ Gtk.MenuItem parent = menu.get_attach_widget () as Gtk.MenuItem;
545+ SortedList<AppInfo> external_apps;
546+ string[] mime_types;
547+
548+ // get list of all applications for the given mime types
549+ if (raw)
550+ mime_types = PhotoFileFormat.RAW.get_mime_types ();
551+ else
552+ mime_types = PhotoFileFormat.get_editable_mime_types ();
553+ assert (mime_types.length != 0);
554+ external_apps = DesktopIntegration.get_apps_for_mime_types (mime_types);
555+
556+ if (external_apps.size == 0) {
557+ parent.sensitive = false;
558+ return;
559+ }
560+
561+ foreach (Gtk.Widget item in menu.get_children ())
562+ menu.remove (item);
563+ parent.sensitive = true;
564+
565+ foreach (AppInfo app in external_apps) {
566+ Gtk.ImageMenuItem item_app = new Gtk.ImageMenuItem.with_label (app.get_name ());
567+ Gtk.Image image = new Gtk.Image.from_gicon (app.get_icon (), Gtk.IconSize.MENU);
568+ item_app.always_show_image = true;
569+ item_app.set_image (image);
570+ item_app.activate.connect ( () => {
571+ if (raw)
572+ on_open_with_raw (app.get_commandline ());
573+ else
574+ on_open_with (app.get_commandline ());
575+ });
576+ menu.add (item_app);
577+ }
578+ menu.show_all ();
579+ }
580+
581+ private void on_open_with (string app) {
582+ if (!has_photo ())
583+ return;
584+
585+ try {
586+ AppWindow.get_instance ().set_busy_cursor ();
587+ get_photo ().open_with_external_editor (app);
588+ AppWindow.get_instance ().set_normal_cursor ();
589+ } catch (Error err) {
590+ AppWindow.get_instance ().set_normal_cursor ();
591+ open_external_editor_error_dialog (err, get_photo ());
592+ }
593+ }
594+
595+ private void on_open_with_raw (string app) {
596+ if (!has_photo ())
597+ return;
598+
599+ if (get_photo ().get_master_file_format () != PhotoFileFormat.RAW)
600+ return;
601+
602+ try {
603+ AppWindow.get_instance ().set_busy_cursor ();
604+ get_photo ().open_with_raw_external_editor (app);
605+ AppWindow.get_instance ().set_normal_cursor ();
606+ } catch (Error err) {
607+ AppWindow.get_instance ().set_normal_cursor ();
608+ AppWindow.error_message (Resources.launch_editor_failed (err));
609+ }
610+ }
611+
612 private void return_to_collection () {
613 // Return to the previous page if it exists.
614 if (null != return_page)
615@@ -3192,43 +3263,6 @@
616 }
617 }
618
619- private void on_external_app_changed () {
620- set_action_sensitive ("ExternalEdit", has_photo () &&
621- Config.Facade.get_instance ().get_external_photo_app () != "");
622- }
623-
624- private void on_external_edit () {
625- if (!has_photo ())
626- return;
627-
628- try {
629- AppWindow.get_instance ().set_busy_cursor ();
630- get_photo ().open_with_external_editor ();
631- AppWindow.get_instance ().set_normal_cursor ();
632- } catch (Error err) {
633- AppWindow.get_instance ().set_normal_cursor ();
634- open_external_editor_error_dialog (err, get_photo ());
635- }
636-
637- }
638-
639- private void on_external_edit_raw () {
640- if (!has_photo ())
641- return;
642-
643- if (get_photo ().get_master_file_format () != PhotoFileFormat.RAW)
644- return;
645-
646- try {
647- AppWindow.get_instance ().set_busy_cursor ();
648- get_photo ().open_with_raw_external_editor ();
649- AppWindow.get_instance ().set_normal_cursor ();
650- } catch (Error err) {
651- AppWindow.get_instance ().set_normal_cursor ();
652- AppWindow.error_message (Resources.launch_editor_failed (err));
653- }
654- }
655-
656 private void on_send_to () {
657 if (has_photo ())
658 DesktopIntegration.send_to ((Gee.Collection<Photo>) get_view ().get_selected_sources ());
659
660=== modified file 'src/Resources.vala'
661--- src/Resources.vala 2014-08-08 21:13:09 +0000
662+++ src/Resources.vala 2014-08-12 01:17:16 +0000
663@@ -13,9 +13,9 @@
664 extern const string? _GIT_VERSION;
665
666 namespace Resources {
667-public const string APP_TITLE = _ ("Photos");
668-public const string APP_LIBRARY_ROLE = _ ("Photo Manager");
669-public const string APP_DIRECT_ROLE = _ ("Photo Viewer");
670+public const string APP_TITLE = _("Photos");
671+public const string APP_LIBRARY_ROLE = _("Photo Manager");
672+public const string APP_DIRECT_ROLE = _("Photo Viewer");
673 public const string APP_VERSION = _VERSION;
674
675 #if _GITVERSION
676@@ -24,7 +24,7 @@
677 public const string? GIT_VERSION = null;
678 #endif
679
680-public const string COPYRIGHT = _ ("Copyright 2009-2013 Yorba Foundation");
681+public const string COPYRIGHT = _("Copyright 2009-2013 Yorba Foundation");
682 public const string APP_GETTEXT_PACKAGE = GETTEXT_PACKAGE;
683
684 public const string YORBA_URL = "http://www.yorba.org";
685@@ -136,250 +136,258 @@
686 public const string ICON_FLAGGED_PAGE = "flag-page";
687 public const string ICON_FLAGGED_TRINKET = "flag-trinket.png";
688
689-public const string ROTATE_CW_MENU = _ ("Rotate _Right");
690-public const string ROTATE_CW_LABEL = _ ("Rotate");
691-public const string ROTATE_CW_FULL_LABEL = _ ("Rotate Right");
692-public const string ROTATE_CW_TOOLTIP = _ ("Rotate the photos right (press Ctrl to rotate left)");
693-
694-public const string ROTATE_CCW_MENU = _ ("Rotate _Left");
695-public const string ROTATE_CCW_LABEL = _ ("Rotate");
696-public const string ROTATE_CCW_FULL_LABEL = _ ("Rotate Left");
697-public const string ROTATE_CCW_TOOLTIP = _ ("Rotate the photos left");
698-
699-public const string HFLIP_MENU = _ ("Flip Hori_zontally");
700-public const string HFLIP_LABEL = _ ("Flip Horizontally");
701-
702-public const string VFLIP_MENU = _ ("Flip Verti_cally");
703-public const string VFLIP_LABEL = _ ("Flip Vertically");
704-
705-public const string ENHANCE_MENU = _ ("_Enhance");
706-public const string ENHANCE_LABEL = _ ("Enhance");
707-public const string ENHANCE_TOOLTIP = _ ("Automatically improve the photo's appearance");
708-
709-public const string COPY_ADJUSTMENTS_MENU = _ ("_Copy Color Adjustments");
710-public const string COPY_ADJUSTMENTS_LABEL = _ ("Copy Color Adjustments");
711-public const string COPY_ADJUSTMENTS_TOOLTIP = _ ("Copy the color adjustments applied to the photo");
712-
713-public const string PASTE_ADJUSTMENTS_MENU = _ ("_Paste Color Adjustments");
714-public const string PASTE_ADJUSTMENTS_LABEL = _ ("Paste Color Adjustments");
715-public const string PASTE_ADJUSTMENTS_TOOLTIP = _ ("Apply copied color adjustments to the selected photos");
716-
717-public const string CROP_MENU = _ ("_Crop");
718-public const string CROP_LABEL = _ ("Crop");
719-public const string CROP_TOOLTIP = _ ("Crop the photo's size");
720-
721-public const string STRAIGHTEN_MENU = _ ("_Straighten");
722-public const string STRAIGHTEN_LABEL = _ ("Straighten");
723-public const string STRAIGHTEN_TOOLTIP = _ ("Straighten the photo");
724-
725-public const string RED_EYE_MENU = _ ("_Red-eye");
726-public const string RED_EYE_LABEL = _ ("Red-eye");
727-public const string RED_EYE_TOOLTIP = _ ("Reduce or eliminate any red-eye effects in the photo");
728-
729-public const string ADJUST_MENU = _ ("_Adjust");
730-public const string ADJUST_LABEL = _ ("Adjust");
731-public const string ADJUST_TOOLTIP = _ ("Adjust the photo's color and tone");
732-
733-public const string REVERT_MENU = _ ("Re_vert to Original");
734-public const string REVERT_LABEL = _ ("Revert to Original");
735-
736-public const string REVERT_EDITABLE_MENU = _ ("Revert External E_dits");
737-public const string REVERT_EDITABLE_TOOLTIP = _ ("Revert to the master photo");
738-
739-public const string SET_BACKGROUND_MENU = _ ("Set as _Desktop Background");
740-public const string SET_BACKGROUND_TOOLTIP = _ ("Set selected image to be the new desktop background");
741-public const string SET_BACKGROUND_SLIDESHOW_MENU = _ ("Set as _Desktop Slideshow...");
742-
743-public const string UNDO_MENU = _ ("_Undo");
744-public const string UNDO_LABEL = _ ("Undo");
745-
746-public const string REDO_MENU = _ ("_Redo");
747-public const string REDO_LABEL = _ ("Redo");
748-
749-public const string RENAME_EVENT_MENU = _ ("Re_name Event...");
750-public const string RENAME_EVENT_LABEL = _ ("Rename Event");
751-
752-public const string MAKE_KEY_PHOTO_MENU = _ ("Make _Key Photo for Event");
753-public const string MAKE_KEY_PHOTO_LABEL = _ ("Make Key Photo for Event");
754-
755-public const string NEW_EVENT_MENU = _ ("_New Event");
756-public const string NEW_EVENT_LABEL = _ ("New Event");
757-
758-public const string SET_PHOTO_EVENT_LABEL = _ ("Move Photos");
759-public const string SET_PHOTO_EVENT_TOOLTIP = _ ("Move photos to an event");
760-
761-public const string MERGE_MENU = _ ("_Merge Events");
762-public const string MERGE_LABEL = _ ("Merge");
763-public const string MERGE_TOOLTIP = _ ("Combine events into a single event");
764-
765-public const string RATING_MENU = _ ("_Set Rating");
766-public const string RATING_LABEL = _ ("Set Rating");
767-public const string RATING_TOOLTIP = _ ("Change the rating of your photo");
768-
769-public const string INCREASE_RATING_MENU = _ ("_Increase");
770-public const string INCREASE_RATING_LABEL = _ ("Increase Rating");
771-
772-public const string DECREASE_RATING_MENU = _ ("_Decrease");
773-public const string DECREASE_RATING_LABEL = _ ("Decrease Rating");
774-
775-public const string RATE_UNRATED_MENU = _ ("_Unrated");
776-public const string RATE_UNRATED_COMBO_BOX = _ ("Unrated");
777-public const string RATE_UNRATED_LABEL = _ ("Rate Unrated");
778-public const string RATE_UNRATED_PROGRESS = _ ("Setting as unrated");
779-public const string RATE_UNRATED_TOOLTIP = _ ("Remove any ratings");
780-
781-public const string RATE_REJECTED_MENU = _ ("_Rejected");
782-public const string RATE_REJECTED_COMBO_BOX = _ ("Rejected");
783-public const string RATE_REJECTED_LABEL = _ ("Rate Rejected");
784-public const string RATE_REJECTED_PROGRESS = _ ("Setting as rejected");
785-public const string RATE_REJECTED_TOOLTIP = _ ("Set rating to rejected");
786-
787-public const string DISPLAY_REJECTED_ONLY_MENU = _ ("Rejected Only");
788-public const string DISPLAY_REJECTED_ONLY_LABEL = _ ("Rejected Only");
789-public const string DISPLAY_REJECTED_ONLY_TOOLTIP = _ ("Show only rejected photos");
790-
791-public const string DISPLAY_REJECTED_OR_HIGHER_MENU = _ ("All + Rejected");
792-public const string DISPLAY_REJECTED_OR_HIGHER_LABEL = _ ("Show all photos, including rejected");
793-public const string DISPLAY_REJECTED_OR_HIGHER_TOOLTIP = _ ("Show all photos, including rejected");
794-
795-public const string DISPLAY_UNRATED_OR_HIGHER_MENU = _ ("All Photos");
796-public const string DISPLAY_UNRATED_OR_HIGHER_LABEL = _ ("Show all photos");
797-public const string DISPLAY_UNRATED_OR_HIGHER_TOOLTIP = _ ("Show all photos");
798-
799-public const string VIEW_RATINGS_MENU = _ ("_Ratings");
800-public const string VIEW_RATINGS_TOOLTIP = _ ("Display each photo's rating");
801-
802-public const string FILTER_PHOTOS_MENU = _ ("_Filter Photos");
803-public const string FILTER_PHOTOS_LABEL = _ ("Filter Photos");
804-public const string FILTER_PHOTOS_TOOLTIP = _ ("Limit the number of photos displayed based on a filter");
805-
806-public const string DUPLICATE_PHOTO_MENU = _ ("_Duplicate");
807-public const string DUPLICATE_PHOTO_LABEL = _ ("Duplicate");
808-public const string DUPLICATE_PHOTO_TOOLTIP = _ ("Make a duplicate of the photo");
809-
810-public const string EXPORT_MENU = _ ("_Export...");
811-
812-public const string PRINT_MENU = _ ("_Print...");
813-
814-public const string PUBLISH_MENU = _ ("Pu_blish...");
815-public const string PUBLISH_LABEL = _ ("Publish");
816-public const string PUBLISH_TOOLTIP = _ ("Publish to various websites");
817-
818-public const string EDIT_TITLE_MENU = _ ("Edit _Title...");
819-public const string EDIT_TITLE_LABEL = _ ("Edit Title");
820-
821-public const string EDIT_COMMENT_MENU = _ ("Edit _Comment...");
822-public const string EDIT_COMMENT_LABEL = _ ("Edit Comment");
823-
824-public const string EDIT_EVENT_COMMENT_MENU = _ ("Edit Event _Comment...");
825-public const string EDIT_EVENT_COMMENT_LABEL = _ ("Edit Event Comment");
826-
827-public const string ADJUST_DATE_TIME_MENU = _ ("_Adjust Date and Time...");
828-public const string ADJUST_DATE_TIME_LABEL = _ ("Adjust Date and Time");
829-
830-public const string ADD_TAGS_MENU = _ ("Add _Tags...");
831-public const string ADD_TAGS_CONTEXT_MENU = _ ("_Add Tags...");
832-public const string ADD_TAGS_TITLE = _ ("Add Tags");
833-
834-public const string PREFERENCES_MENU = _ ("_Preferences");
835-
836-public const string EXTERNAL_EDIT_MENU = _ ("Open With E_xternal Editor");
837-
838-public const string EXTERNAL_EDIT_RAW_MENU = _ ("Open With RA_W Editor");
839-
840-public const string SEND_TO_MENU = _ ("Send _To...");
841-public const string SEND_TO_CONTEXT_MENU = _ ("Send T_o...");
842-
843-public const string FIND_MENU = _ ("_Find...");
844-public const string FIND_LABEL = _ ("Find");
845-public const string FIND_TOOLTIP = _ ("Find an image by typing text that appears in its name or tags");
846-
847-public const string FLAG_MENU = _ ("_Flag");
848-
849-public const string UNFLAG_MENU = _ ("Un_flag");
850+public const string ROTATE_CW_MENU = _("Rotate _Right");
851+public const string ROTATE_CW_LABEL = _("Rotate");
852+public const string ROTATE_CW_FULL_LABEL = _("Rotate Right");
853+public const string ROTATE_CW_TOOLTIP = _("Rotate the photos right (press Ctrl to rotate left)");
854+
855+public const string ROTATE_CCW_MENU = _("Rotate _Left");
856+public const string ROTATE_CCW_LABEL = _("Rotate");
857+public const string ROTATE_CCW_FULL_LABEL = _("Rotate Left");
858+public const string ROTATE_CCW_TOOLTIP = _("Rotate the photos left");
859+
860+public const string HFLIP_MENU = _("Flip Hori_zontally");
861+public const string HFLIP_LABEL = _("Flip Horizontally");
862+
863+public const string VFLIP_MENU = _("Flip Verti_cally");
864+public const string VFLIP_LABEL = _("Flip Vertically");
865+
866+public const string ENHANCE_MENU = _("_Enhance");
867+public const string ENHANCE_LABEL = _("Enhance");
868+public const string ENHANCE_TOOLTIP = _("Automatically improve the photo's appearance");
869+
870+public const string COPY_ADJUSTMENTS_MENU = _("_Copy Color Adjustments");
871+public const string COPY_ADJUSTMENTS_LABEL = _("Copy Color Adjustments");
872+public const string COPY_ADJUSTMENTS_TOOLTIP = _("Copy the color adjustments applied to the photo");
873+
874+public const string PASTE_ADJUSTMENTS_MENU = _("_Paste Color Adjustments");
875+public const string PASTE_ADJUSTMENTS_LABEL = _("Paste Color Adjustments");
876+public const string PASTE_ADJUSTMENTS_TOOLTIP = _("Apply copied color adjustments to the selected photos");
877+
878+public const string CROP_MENU = _("_Crop");
879+public const string CROP_LABEL = _("Crop");
880+public const string CROP_TOOLTIP = _("Crop the photo's size");
881+
882+public const string STRAIGHTEN_MENU = _("_Straighten");
883+public const string STRAIGHTEN_LABEL = _("Straighten");
884+public const string STRAIGHTEN_TOOLTIP = _("Straighten the photo");
885+
886+public const string RED_EYE_MENU = _("_Red-eye");
887+public const string RED_EYE_LABEL = _("Red-eye");
888+public const string RED_EYE_TOOLTIP = _("Reduce or eliminate any red-eye effects in the photo");
889+
890+public const string ADJUST_MENU = _("_Adjust");
891+public const string ADJUST_LABEL = _("Adjust");
892+public const string ADJUST_TOOLTIP = _("Adjust the photo's color and tone");
893+
894+public const string REVERT_MENU = _("Re_vert to Original");
895+public const string REVERT_LABEL = _("Revert to Original");
896+
897+public const string REVERT_EDITABLE_MENU = _("Revert External E_dits");
898+public const string REVERT_EDITABLE_TOOLTIP = _("Revert to the master photo");
899+
900+public const string SET_BACKGROUND_MENU = _("Set as _Desktop Background");
901+public const string SET_BACKGROUND_TOOLTIP = _("Set selected image to be the new desktop background");
902+public const string SET_BACKGROUND_SLIDESHOW_MENU = _("Set as _Desktop Slideshow...");
903+
904+public const string UNDO_MENU = _("_Undo");
905+public const string UNDO_LABEL = _("Undo");
906+
907+public const string REDO_MENU = _("_Redo");
908+public const string REDO_LABEL = _("Redo");
909+
910+public const string RENAME_EVENT_MENU = _("Re_name Event...");
911+public const string RENAME_EVENT_LABEL = _("Rename Event");
912+
913+public const string MAKE_KEY_PHOTO_MENU = _("Make _Key Photo for Event");
914+public const string MAKE_KEY_PHOTO_LABEL = _("Make Key Photo for Event");
915+
916+public const string NEW_EVENT_MENU = _("_New Event");
917+public const string NEW_EVENT_LABEL = _("New Event");
918+
919+public const string SET_PHOTO_EVENT_LABEL = _("Move Photos");
920+public const string SET_PHOTO_EVENT_TOOLTIP = _("Move photos to an event");
921+
922+public const string MERGE_MENU = _("_Merge Events");
923+public const string MERGE_LABEL = _("Merge");
924+public const string MERGE_TOOLTIP = _("Combine events into a single event");
925+
926+public const string RATING_MENU = _("_Set Rating");
927+public const string RATING_LABEL = _("Set Rating");
928+public const string RATING_TOOLTIP = _("Change the rating of your photo");
929+
930+public const string INCREASE_RATING_MENU = _("_Increase");
931+public const string INCREASE_RATING_LABEL = _("Increase Rating");
932+
933+public const string DECREASE_RATING_MENU = _("_Decrease");
934+public const string DECREASE_RATING_LABEL = _("Decrease Rating");
935+
936+public const string RATE_UNRATED_MENU = _("_Unrated");
937+public const string RATE_UNRATED_COMBO_BOX = _("Unrated");
938+public const string RATE_UNRATED_LABEL = _("Rate Unrated");
939+public const string RATE_UNRATED_PROGRESS = _("Setting as unrated");
940+public const string RATE_UNRATED_TOOLTIP = _("Remove any ratings");
941+
942+public const string RATE_REJECTED_MENU = _("_Rejected");
943+public const string RATE_REJECTED_COMBO_BOX = _("Rejected");
944+public const string RATE_REJECTED_LABEL = _("Rate Rejected");
945+public const string RATE_REJECTED_PROGRESS = _("Setting as rejected");
946+public const string RATE_REJECTED_TOOLTIP = _("Set rating to rejected");
947+
948+public const string DISPLAY_REJECTED_ONLY_MENU = _("Rejected Only");
949+public const string DISPLAY_REJECTED_ONLY_LABEL = _("Rejected Only");
950+public const string DISPLAY_REJECTED_ONLY_TOOLTIP = _("Show only rejected photos");
951+
952+public const string DISPLAY_REJECTED_OR_HIGHER_MENU = _("All + Rejected");
953+public const string DISPLAY_REJECTED_OR_HIGHER_LABEL = _("Show all photos, including rejected");
954+public const string DISPLAY_REJECTED_OR_HIGHER_TOOLTIP = _("Show all photos, including rejected");
955+
956+public const string DISPLAY_UNRATED_OR_HIGHER_MENU = _("All Photos");
957+public const string DISPLAY_UNRATED_OR_HIGHER_LABEL = _("Show all photos");
958+public const string DISPLAY_UNRATED_OR_HIGHER_TOOLTIP = _("Show all photos");
959+
960+public const string VIEW_RATINGS_MENU = _("_Ratings");
961+public const string VIEW_RATINGS_TOOLTIP = _("Display each photo's rating");
962+
963+public const string FILTER_PHOTOS_MENU = _("_Filter Photos");
964+public const string FILTER_PHOTOS_LABEL = _("Filter Photos");
965+public const string FILTER_PHOTOS_TOOLTIP = _("Limit the number of photos displayed based on a filter");
966+
967+public const string DUPLICATE_PHOTO_MENU = _("_Duplicate");
968+public const string DUPLICATE_PHOTO_LABEL = _("Duplicate");
969+public const string DUPLICATE_PHOTO_TOOLTIP = _("Make a duplicate of the photo");
970+
971+public const string EXPORT_MENU = _("_Export...");
972+
973+public const string PRINT_MENU = _("_Print...");
974+
975+public const string PUBLISH_MENU = _("Pu_blish...");
976+public const string PUBLISH_LABEL = _("Publish");
977+public const string PUBLISH_TOOLTIP = _("Publish to various websites");
978+
979+public const string EDIT_TITLE_MENU = _("Edit _Title...");
980+public const string EDIT_TITLE_LABEL = _("Edit Title");
981+
982+public const string EDIT_COMMENT_MENU = _("Edit _Comment...");
983+public const string EDIT_COMMENT_LABEL = _("Edit Comment");
984+
985+public const string EDIT_EVENT_COMMENT_MENU = _("Edit Event _Comment...");
986+public const string EDIT_EVENT_COMMENT_LABEL = _("Edit Event Comment");
987+
988+public const string ADJUST_DATE_TIME_MENU = _("_Adjust Date and Time...");
989+public const string ADJUST_DATE_TIME_LABEL = _("Adjust Date and Time");
990+
991+public const string ADD_TAGS_MENU = _("Add _Tags...");
992+public const string ADD_TAGS_CONTEXT_MENU = _("_Add Tags...");
993+public const string ADD_TAGS_TITLE = _("Add Tags");
994+
995+public const string PREFERENCES_MENU = _("_Preferences");
996+
997+public const string EXTERNAL_EDIT_MENU = _("Open With E_xternal Editor");
998+
999+public const string EXTERNAL_EDIT_RAW_MENU = _("Open With RA_W Editor");
1000+
1001+public const string OPEN_WITH_MENU = _("_Open With...");
1002+public const string OPEN_WITH_LABEL = _("Open With");
1003+public const string OPEN_WITH_TOOLTIP = _("Open photo with external editor");
1004+
1005+public const string OPEN_WITH_RAW_MENU = _("_Open With RAW Editor...");
1006+public const string OPEN_WITH_RAW_LABEL = _("Open With Raw Editor");
1007+public const string OPEN_WITH_RAW_TOOLTIP = _("Open photo with external RAW editor");
1008+
1009+public const string SEND_TO_MENU = _("Send _To...");
1010+public const string SEND_TO_CONTEXT_MENU = _("Send T_o...");
1011+
1012+public const string FIND_MENU = _("_Find...");
1013+public const string FIND_LABEL = _("Find");
1014+public const string FIND_TOOLTIP = _("Find an image by typing text that appears in its name or tags");
1015+
1016+public const string FLAG_MENU = _("_Flag");
1017+
1018+public const string UNFLAG_MENU = _("Un_flag");
1019
1020 public string launch_editor_failed (Error err) {
1021- return _ ("Unable to launch editor: %s").printf (err.message);
1022+ return _("Unable to launch editor: %s").printf (err.message);
1023 }
1024
1025 public string add_tags_label (string[] names) {
1026 if (names.length == 1)
1027- return _ ("Add Tag \"%s\"").printf (HierarchicalTagUtilities.get_basename (names[0]));
1028+ return _("Add Tag \"%s\"").printf (HierarchicalTagUtilities.get_basename (names[0]));
1029 else if (names.length == 2)
1030- return _ ("Add Tags \"%s\" and \"%s\"").printf (
1031+ return _("Add Tags \"%s\" and \"%s\"").printf (
1032 HierarchicalTagUtilities.get_basename (names[0]),
1033 HierarchicalTagUtilities.get_basename (names[1]));
1034 else
1035- return _ ("Add Tags");
1036+ return _("Add Tags");
1037 }
1038
1039 public string delete_tag_menu (string name) {
1040- return _ ("_Delete Tag \"%s\"").printf (name);
1041+ return _("_Delete Tag \"%s\"").printf (name);
1042 }
1043
1044 public string delete_tag_label (string name) {
1045- return _ ("Delete Tag \"%s\"").printf (name);
1046+ return _("Delete Tag \"%s\"").printf (name);
1047 }
1048
1049-public const string DELETE_TAG_TITLE = _ ("Delete Tag");
1050-public const string DELETE_TAG_SIDEBAR_MENU = _ ("_Delete");
1051+public const string DELETE_TAG_TITLE = _("Delete Tag");
1052+public const string DELETE_TAG_SIDEBAR_MENU = _("_Delete");
1053
1054-public const string NEW_CHILD_TAG_SIDEBAR_MENU = _ ("_New");
1055+public const string NEW_CHILD_TAG_SIDEBAR_MENU = _("_New");
1056
1057 public string rename_tag_menu (string name) {
1058- return _ ("Re_name Tag \"%s\"...").printf (name);
1059+ return _("Re_name Tag \"%s\"...").printf (name);
1060 }
1061
1062 public string rename_tag_label (string old_name, string new_name) {
1063- return _ ("Rename Tag \"%s\" to \"%s\"").printf (old_name, new_name);
1064+ return _("Rename Tag \"%s\" to \"%s\"").printf (old_name, new_name);
1065 }
1066
1067-public const string RENAME_TAG_SIDEBAR_MENU = _ ("_Rename...");
1068+public const string RENAME_TAG_SIDEBAR_MENU = _("_Rename...");
1069
1070-public const string MODIFY_TAGS_MENU = _ ("Modif_y Tags...");
1071-public const string MODIFY_TAGS_LABEL = _ ("Modify Tags");
1072+public const string MODIFY_TAGS_MENU = _("Modif_y Tags...");
1073+public const string MODIFY_TAGS_LABEL = _("Modify Tags");
1074
1075 public string tag_photos_label (string name, int count) {
1076- return ((count == 1) ? _ ("Tag Photo as \"%s\"") : _ ("Tag Photos as \"%s\"")).printf (name);
1077+ return ((count == 1) ? _("Tag Photo as \"%s\"") : _("Tag Photos as \"%s\"")).printf (name);
1078 }
1079
1080 public string tag_photos_tooltip (string name, int count) {
1081- return ((count == 1) ? _ ("Tag the selected photo as \"%s\"") :
1082- _ ("Tag the selected photos as \"%s\"")).printf (name);
1083+ return ((count == 1) ? _("Tag the selected photo as \"%s\"") :
1084+ _("Tag the selected photos as \"%s\"")).printf (name);
1085 }
1086
1087 public string untag_photos_menu (string name, int count) {
1088- return ((count == 1) ? _ ("Remove Tag \"%s\" From _Photo") :
1089- _ ("Remove Tag \"%s\" From _Photos")).printf (name);
1090+ return ((count == 1) ? _("Remove Tag \"%s\" From _Photo") :
1091+ _("Remove Tag \"%s\" From _Photos")).printf (name);
1092 }
1093
1094 public string untag_photos_label (string name, int count) {
1095- return ((count == 1) ? _ ("Remove Tag \"%s\" From Photo") :
1096- _ ("Remove Tag \"%s\" From Photos")).printf (name);
1097+ return ((count == 1) ? _("Remove Tag \"%s\" From Photo") :
1098+ _("Remove Tag \"%s\" From Photos")).printf (name);
1099 }
1100
1101 public static string rename_tag_exists_message (string name) {
1102- return _ ("Unable to rename tag to \"%s\" because the tag already exists.").printf (name);
1103+ return _("Unable to rename tag to \"%s\" because the tag already exists.").printf (name);
1104 }
1105
1106 public static string rename_search_exists_message (string name) {
1107- return _ ("Unable to rename search to \"%s\" because the search already exists.").printf (name);
1108+ return _("Unable to rename search to \"%s\" because the search already exists.").printf (name);
1109 }
1110
1111-public const string DEFAULT_SAVED_SEARCH_NAME = _ ("Smart Album");
1112-
1113-public const string DELETE_SAVED_SEARCH_DIALOG_TITLE = _ ("Delete Album");
1114-
1115-public const string DELETE_SEARCH_MENU = _ ("_Delete");
1116-public const string EDIT_SEARCH_MENU = _ ("_Edit...");
1117-public const string RENAME_SEARCH_MENU = _ ("Re_name...");
1118+public const string DEFAULT_SAVED_SEARCH_NAME = _("Smart Album");
1119+
1120+public const string DELETE_SAVED_SEARCH_DIALOG_TITLE = _("Delete Album");
1121+
1122+public const string DELETE_SEARCH_MENU = _("_Delete");
1123+public const string EDIT_SEARCH_MENU = _("_Edit...");
1124+public const string RENAME_SEARCH_MENU = _("Re_name...");
1125
1126 public string rename_search_label (string old_name, string new_name) {
1127- return _ ("Rename Search \"%s\" to \"%s\"").printf (old_name, new_name);
1128+ return _("Rename Search \"%s\" to \"%s\"").printf (old_name, new_name);
1129 }
1130
1131 public string delete_search_label (string name) {
1132- return _ ("Delete Search \"%s\"").printf (name);
1133+ return _("Delete Search \"%s\"").printf (name);
1134 }
1135
1136 private unowned string rating_menu (Rating rating) {
1137@@ -568,15 +576,15 @@
1138
1139 private void generate_rating_strings () {
1140 string menu_base = "%s";
1141- string label_base = _ ("Rate %s");
1142- string tooltip_base = _ ("Set rating to %s");
1143- string progress_base = _ ("Setting rating to %s");
1144+ string label_base = _("Rate %s");
1145+ string tooltip_base = _("Set rating to %s");
1146+ string progress_base = _("Setting rating to %s");
1147 string display_rating_menu_base = "%s";
1148- string display_rating_label_base = _ ("Display %s");
1149- string display_rating_tooltip_base = _ ("Only show photos with a rating of %s");
1150- string display_rating_or_higher_menu_base = _ ("%s or Better");
1151- string display_rating_or_higher_label_base = _ ("Display %s or Better");
1152- string display_rating_or_higher_tooltip_base = _ ("Only show photos with a rating of %s or better");
1153+ string display_rating_label_base = _("Display %s");
1154+ string display_rating_tooltip_base = _("Only show photos with a rating of %s");
1155+ string display_rating_or_higher_menu_base = _("%s or Better");
1156+ string display_rating_or_higher_label_base = _("Display %s or Better");
1157+ string display_rating_or_higher_tooltip_base = _("Only show photos with a rating of %s or better");
1158
1159 RATE_ONE_MENU = menu_base.printf (get_stars (Rating.ONE));
1160 RATE_TWO_MENU = menu_base.printf (get_stars (Rating.TWO));
1161@@ -666,26 +674,26 @@
1162 private string DISPLAY_FIVE_OR_HIGHER_LABEL;
1163 private string DISPLAY_FIVE_OR_HIGHER_TOOLTIP;
1164
1165-public const string DELETE_PHOTOS_MENU = _ ("_Delete");
1166-public const string DELETE_FROM_TRASH_TOOLTIP = _ ("Remove the selected photos from the trash");
1167-public const string DELETE_FROM_LIBRARY_TOOLTIP = _ ("Remove the selected photos from the library");
1168-
1169-public const string RESTORE_PHOTOS_MENU = _ ("_Restore");
1170-public const string RESTORE_PHOTOS_TOOLTIP = _ ("Move the selected photos back into the library");
1171-
1172-public const string JUMP_TO_FILE_MENU = _ ("Show in File Mana_ger");
1173-public const string JUMP_TO_FILE_TOOLTIP = _ ("Open the selected photo's directory in the file manager");
1174+public const string DELETE_PHOTOS_MENU = _("_Delete");
1175+public const string DELETE_FROM_TRASH_TOOLTIP = _("Remove the selected photos from the trash");
1176+public const string DELETE_FROM_LIBRARY_TOOLTIP = _("Remove the selected photos from the library");
1177+
1178+public const string RESTORE_PHOTOS_MENU = _("_Restore");
1179+public const string RESTORE_PHOTOS_TOOLTIP = _("Move the selected photos back into the library");
1180+
1181+public const string JUMP_TO_FILE_MENU = _("Show in File Mana_ger");
1182+public const string JUMP_TO_FILE_TOOLTIP = _("Open the selected photo's directory in the file manager");
1183
1184 public string jump_to_file_failed (Error err) {
1185- return _ ("Unable to open in file manager: %s").printf (err.message);
1186+ return _("Unable to open in file manager: %s").printf (err.message);
1187 }
1188
1189-public const string REMOVE_FROM_LIBRARY_MENU = _ ("R_emove From Library");
1190-
1191-public const string MOVE_TO_TRASH_MENU = _ ("_Move to Trash");
1192-
1193-public const string SELECT_ALL_MENU = _ ("Select _All");
1194-public const string SELECT_ALL_TOOLTIP = _ ("Select all items");
1195+public const string REMOVE_FROM_LIBRARY_MENU = _("R_emove From Library");
1196+
1197+public const string MOVE_TO_TRASH_MENU = _("_Move to Trash");
1198+
1199+public const string SELECT_ALL_MENU = _("Select _All");
1200+public const string SELECT_ALL_TOOLTIP = _("Select all items");
1201
1202 private Gtk.IconFactory factory = null;
1203 private Gee.HashMap<string, Gdk.Pixbuf> icon_cache = null;
1204@@ -768,31 +776,31 @@
1205 /// Locale-specific time format for 12-hour time, i.e. 8:31 PM
1206 /// Precede modifier with a dash ("-") to pad with spaces, otherwise will pad with zeroes
1207 /// See http://developer.gnome.org/glib/2.32/glib-GDateTime.html#g-date-time-format
1208- HH_MM_FORMAT_STRING = _ ("%-I:%M %p");
1209+ HH_MM_FORMAT_STRING = _("%-I:%M %p");
1210
1211 /// Locale-specific time format for 12-hour time with seconds, i.e. 8:31:42 PM
1212 /// Precede modifier with a dash ("-") to pad with spaces, otherwise will pad with zeroes
1213 /// See http://developer.gnome.org/glib/2.32/glib-GDateTime.html#g-date-time-format
1214- HH_MM_SS_FORMAT_STRING = _ ("%-I:%M:%S %p");
1215+ HH_MM_SS_FORMAT_STRING = _("%-I:%M:%S %p");
1216
1217 /// Locale-specific calendar date format, i.e. "Tue Mar 08, 2006"
1218 /// See http://developer.gnome.org/glib/2.32/glib-GDateTime.html#g-date-time-format
1219- LONG_DATE_FORMAT_STRING = _ ("%a %b %d, %Y");
1220+ LONG_DATE_FORMAT_STRING = _("%a %b %d, %Y");
1221
1222 /// Locale-specific starting date format for multi-date strings,
1223 /// i.e. the "Tue Mar 08" in "Tue Mar 08 - 10, 2006"
1224 /// See http://developer.gnome.org/glib/2.32/glib-GDateTime.html#g-date-time-format
1225- START_MULTIDAY_DATE_FORMAT_STRING = _ ("%a %b %d");
1226+ START_MULTIDAY_DATE_FORMAT_STRING = _("%a %b %d");
1227
1228 /// Locale-specific ending date format for multi-date strings,
1229 /// i.e. the "10, 2006" in "Tue Mar 08 - 10, 2006"
1230 /// See http://developer.gnome.org/glib/2.32/glib-GDateTime.html#g-date-time-format
1231- END_MULTIDAY_DATE_FORMAT_STRING = _ ("%d, %Y");
1232+ END_MULTIDAY_DATE_FORMAT_STRING = _("%d, %Y");
1233
1234 /// Locale-specific calendar date format for multi-month strings,
1235 /// i.e. the "Tue Mar 08" in "Tue Mar 08 to Mon Apr 06, 2006"
1236 /// See http://developer.gnome.org/glib/2.32/glib-GDateTime.html#g-date-time-format
1237- START_MULTIMONTH_DATE_FORMAT_STRING = _ ("%a %b %d");
1238+ START_MULTIMONTH_DATE_FORMAT_STRING = _("%a %b %d");
1239
1240 // ...put everything back like we found it.
1241 if (old_messages != null) {
1242
1243=== modified file 'ui/collection.ui'
1244--- ui/collection.ui 2014-07-27 04:42:53 +0000
1245+++ ui/collection.ui 2014-08-12 01:17:16 +0000
1246@@ -33,8 +33,10 @@
1247 <menuitem name="ContextEditTitle" action="EditTitle" />
1248 <menuitem name="ContextEditComment" action="EditComment" />
1249 <menuitem name="AdjustDateTime" action="AdjustDateTime" />
1250- <menuitem name="ContextExternalEdit" action="ExternalEdit" />
1251- <menuitem name="ContextExternalEditRAW" action="ExternalEditRAW" />
1252+ <menu name="OpenWith" action="OpenWith">
1253+ </menu>
1254+ <menu name="OpenWithRaw" action="OpenWithRaw">
1255+ </menu>
1256 <separator />
1257 <menuitem name="NewEvent" action="NewEvent" />
1258 <menuitem name="ContextJumpToEvent" action="CommonJumpToEvent" />
1259
1260=== modified file 'ui/photo_context.ui'
1261--- ui/photo_context.ui 2014-07-27 04:42:53 +0000
1262+++ ui/photo_context.ui 2014-08-12 01:17:16 +0000
1263@@ -30,9 +30,10 @@
1264 <separator />
1265 <menuitem name="ContextEditTitle" action="EditTitle" />
1266 <menuitem name="ContextEditComment" action="EditComment" />
1267- <menuitem name="AdjustDateTime" action="AdjustDateTime" />
1268- <menuitem name="ContextExternalEdit" action="ExternalEdit" />
1269- <menuitem name="ContextExternalEditRAW" action="ExternalEditRAW" />
1270+ <menu name="OpenWith" action="OpenWith">
1271+ </menu>
1272+ <menu name="OpenWithRaw" action="OpenWithRaw">
1273+ </menu>
1274 <separator />
1275 <placeholder name="ContextJumpPlaceholder" />
1276 <menuitem name="ContextSendTo" action="SendToContextMenu" />
1277@@ -40,4 +41,4 @@
1278 <menuitem name="ContextMoveToTrash" action="MoveToTrash" />
1279 </popup>
1280
1281-</ui>
1282\ No newline at end of file
1283+</ui>

Subscribers

People subscribed via source and target branches

to all changes: