Merge lp:~gue5t/midori/fix-download-open into lp:midori

Proposed by gue5t gue5t
Status: Merged
Approved by: Paweł Forysiuk
Approved revision: 6587
Merged at revision: 6588
Proposed branch: lp:~gue5t/midori/fix-download-open
Merge into: lp:midori
Diff against target: 215 lines (+51/-20)
3 files modified
extensions/open-with.vala (+36/-11)
midori/midori-download.vala (+10/-8)
midori/midori-tab.vala (+5/-1)
To merge this branch: bzr merge lp:~gue5t/midori/fix-download-open
Reviewer Review Type Date Requested Status
Paweł Forysiuk Approve
Review via email: mp+209383@code.launchpad.net

Commit message

Document open-with extension functions and fix "open" download action

Description of the change

This documents lots of unexplained open-with guts and fixes incorrect handling of error conditions which caused "open" on download dialogs to fail.

To post a comment you must log in.
lp:~gue5t/midori/fix-download-open updated
6587. By gue5t <email address hidden>

Allow pre-emption of open-with navigation handling by in-browser uri handlers

Revision history for this message
Paweł Forysiuk (tuxator) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'extensions/open-with.vala'
2--- extensions/open-with.vala 2014-03-03 02:51:58 +0000
3+++ extensions/open-with.vala 2014-03-06 20:48:25 +0000
4@@ -16,6 +16,10 @@
5 #endif
6
7 namespace ExternalApplications {
8+ /* Spawn the application specified by @app_info on the uri, trying to
9+ remember the association between the content-type and the application
10+ chosen
11+ Returns whether the application was spawned successfully. */
12 bool open_app_info (AppInfo app_info, string uri, string content_type) {
13 Midori.URI.recursive_fork_protection (uri, true);
14
15@@ -23,12 +27,17 @@
16 var uris = new List<File> ();
17 uris.append (File.new_for_uri (uri));
18 app_info.launch (uris, null);
19+ } catch (Error error) {
20+ warning ("Failed to open \"%s\": %s", uri, error.message);
21+ return false;
22+ }
23+ /* Failing to save the association is a non-fatal error so report success */
24+ try {
25 new Associations ().remember (content_type, app_info);
26- return true;
27 } catch (Error error) {
28- warning ("Failed to open \"%s\": %s", uri, error.message);
29- return false;
30+ warning ("Failed to save association for \"%s\": %s", uri, error.message);
31 }
32+ return true;
33 }
34
35 class Associations : Object {
36@@ -51,6 +60,8 @@
37 }
38 }
39
40+ /* Determine a handler command-line for @content_type and spawn it on @uri.
41+ Returns whether a handler was found and spawned successfully. */
42 public bool open (string content_type, string uri) {
43 Midori.URI.recursive_fork_protection (uri, true);
44 try {
45@@ -69,17 +80,19 @@
46 }
47 }
48
49+ /* Save @app_info in the persistent store as the handler for @content_type */
50 public void remember (string content_type, AppInfo app_info) throws Error {
51 keyfile.set_string ("mimes", content_type, get_commandline (app_info));
52 FileUtils.set_contents (filename, keyfile.to_data ());
53 }
54
55- public void custom (string content_type, string commandline, string name, string uri) {
56+ /* Save @commandline in the persistent store as the handler for @content_type */
57+ public void remember_custom_commandline (string content_type, string commandline, string name, string uri) {
58 keyfile.set_string ("mimes", content_type, commandline);
59 try {
60 FileUtils.set_contents (filename, keyfile.to_data ());
61 } catch (Error error) {
62- warning ("Failed to add remember custom command line for \"%s\": %s", uri, error.message);
63+ warning ("Failed to remember custom command line for \"%s\": %s", uri, error.message);
64 }
65 open (content_type, uri);
66 }
67@@ -88,6 +101,8 @@
68 public Associations () {
69 }
70
71+ /* Find a handler application for @content_type and spawn it on @uri.
72+ Returns whether a handler was found and spawned successfully. */
73 public bool open (string content_type, string uri) {
74 var app_info = AppInfo.get_default_for_type (content_type, false);
75 if (app_info == null)
76@@ -95,18 +110,20 @@
77 return open_app_info (app_info, uri, content_type);
78 }
79
80+ /* Save @app_info as the last-used handler for @content_type */
81 public void remember (string content_type, AppInfo app_info) throws Error {
82 app_info.set_as_last_used_for_type (content_type);
83 app_info.set_as_default_for_type (content_type);
84 }
85
86- public void custom (string content_type, string commandline, string name, string uri) {
87+ /* Save @commandline as a new system MIME handler for @content_type */
88+ public void remember_custom_commandline (string content_type, string commandline, string name, string uri) {
89 try {
90 var app_info = AppInfo.create_from_commandline (commandline, name,
91 "%u" in commandline ? AppInfoCreateFlags.SUPPORTS_URIS : AppInfoCreateFlags.NONE);
92 open_app_info (app_info, uri, content_type);
93 } catch (Error error) {
94- warning ("Failed to add custom command line for \"%s\": %s", uri, error.message);
95+ warning ("Failed to remember custom command line for \"%s\": %s", uri, error.message);
96 }
97 }
98 }
99@@ -116,6 +133,7 @@
100 return app_info.get_commandline () ?? app_info.get_executable ();
101 }
102
103+ /* Generate markup of the application's name followed by a description line. */
104 static string describe_app_info (AppInfo app_info) {
105 string name = app_info.get_display_name () ?? (Path.get_basename (app_info.get_executable ()));
106 string desc = app_info.get_description () ?? get_commandline (app_info);
107@@ -267,7 +285,7 @@
108 if (accept) {
109 string name = dialog.name_entry.text;
110 string commandline = dialog.commandline_entry.text;
111- new Associations ().custom (content_type, commandline, name, uri);
112+ new Associations ().remember_custom_commandline (content_type, commandline, name, uri);
113 customized (app_info, content_type, uri);
114 }
115 dialog.destroy ();
116@@ -628,6 +646,7 @@
117 return ContentType.from_mime_type (mime_type);
118 }
119
120+ /* Returns %TRUE if the attempt to download and open failed immediately, %FALSE otherwise */
121 bool open_with_type (string uri, string content_type, Gtk.Widget widget, NextStep next_step) {
122 #if HAVE_WEBKIT2
123 return open_now (uri, content_type, widget, next_step);
124@@ -646,22 +665,28 @@
125 }
126 else if (download.status == WebKit.DownloadStatus.ERROR)
127 Midori.show_message_dialog (Gtk.MessageType.ERROR,
128- _("Error downloading the image!"),
129- _("Can not download selected image."), false);
130+ _("Download error"),
131+ _("Cannot open '%s' because the download failed.") + download.destination_uri, false);
132 });
133 download.start ();
134 return true;
135 #endif
136 }
137
138+ /* If @next_step is %NextStep.TRY_OPEN, tries to pick a handler automatically.
139+ If the automatic handler did not exist or could not run, asks for an application.
140+ Returns whether an application was found and launched successfully. */
141 bool open_now (string uri, string content_type, Gtk.Widget widget, NextStep next_step) {
142 if (next_step == NextStep.TRY_OPEN && (new Associations ()).open (content_type, uri))
143 return true;
144+ /* if opening directly failed or wasn't tried, ask for an association */
145 if (open_with (uri, content_type, widget) != null)
146 return true;
147 return false;
148 }
149
150+ /* Returns the application chosen to open the uri+content_type if the application
151+ was spawned successfully, %NULL if none was chosen or running was unsuccessful. */
152 AppInfo? open_with (string uri, string content_type, Gtk.Widget widget) {
153 var dialog = new ChooserDialog (uri, content_type, widget);
154
155@@ -743,7 +768,7 @@
156 }
157
158 public void tab_added (Midori.Browser browser, Midori.View view) {
159- view.web_view.navigation_policy_decision_requested.connect (navigation_requested);
160+ view.web_view.navigation_policy_decision_requested.connect_after (navigation_requested);
161 view.open_uri.connect (open_uri);
162 view.context_menu.connect (context_menu);
163 }
164
165=== modified file 'midori/midori-download.vala'
166--- midori/midori-download.vala 2014-02-22 22:35:42 +0000
167+++ midori/midori-download.vala 2014-03-06 20:48:25 +0000
168@@ -209,20 +209,22 @@
169 #endif
170 }
171
172+ /* returns whether an application was successfully launched to handle the file */
173 public static bool open (WebKit.Download download, Gtk.Widget widget) throws Error {
174 #if !HAVE_WEBKIT2
175- if (!has_wrong_checksum (download)) {
176+ if (has_wrong_checksum (download)) {
177+ Sokoke.message_dialog (Gtk.MessageType.WARNING,
178+ _("The downloaded file is erroneous."),
179+ _("The checksum provided with the link did not match. This means the file is probably incomplete or was modified afterwards."),
180+ true);
181+ return true;
182+ } else {
183 var browser = widget.get_toplevel ();
184 Tab? tab = null;
185- browser.get ("tab", tab);
186+ browser.get ("tab", &tab);
187 if (tab != null)
188- tab.open_uri (download.destination_uri);
189+ return tab.open_uri (download.destination_uri);
190 }
191-
192- Sokoke.message_dialog (Gtk.MessageType.WARNING,
193- _("The downloaded file is erroneous."),
194- _("The checksum provided with the link did not match. This means the file is probably incomplete or was modified afterwards."),
195- true);
196 #endif
197 return false;
198 }
199
200=== modified file 'midori/midori-tab.vala'
201--- midori/midori-tab.vala 2014-02-22 22:35:42 +0000
202+++ midori/midori-tab.vala 2014-03-06 20:48:25 +0000
203@@ -88,7 +88,11 @@
204 }
205 }
206
207- /* Since: 0.5.8 */
208+ /* Emitted when a uri is attempted to be loaded.
209+ Returns FALSE if the URI could not be handled by Midori or any
210+ external application.
211+ Since: 0.5.8
212+ */
213 public signal bool open_uri (string uri);
214 public signal void console_message (string message, int line, string source_id);
215 public signal void attach_inspector (WebKit.WebView inspector_view);

Subscribers

People subscribed via source and target branches

to all changes: