Merge lp:~vikoadi/switchboard-plug-locale/missing-locale into lp:~elementary-apps/switchboard-plug-locale/trunk
- missing-locale
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Corentin Noël |
Approved revision: | 61 |
Merged at revision: | 56 |
Proposed branch: | lp:~vikoadi/switchboard-plug-locale/missing-locale |
Merge into: | lp:~elementary-apps/switchboard-plug-locale/trunk |
Diff against target: |
536 lines (+291/-16) 7 files modified
src/CMakeLists.txt (+2/-1) src/Installer/UbuntuInstaller.vala (+84/-7) src/Installer/aptd-client.vala (+10/-0) src/Plug.vala (+50/-6) src/Utils.vala (+37/-1) src/Widgets/InstallInfoBar.vala (+71/-0) src/Widgets/LanguageList.vala (+37/-1) |
To merge this branch: | bzr merge lp:~vikoadi/switchboard-plug-locale/missing-locale |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Corentin Noël | Approve | ||
Danielle Foré | ux | Approve | |
elementary Pantheon team | code | Pending | |
Review via email: mp+244280@code.launchpad.net |
Commit message
Suggest installation of incomplete language packages in InfoBar
Description of the change
Suggest installation of incomplete language packages in InfoBar
this one use "check-
- 55. By Viko Adi Rahmawan
-
clean code style
PerfectCarl (name-is-carl) wrote : | # |
- 56. By Viko Adi Rahmawan
-
asynchronously query missing language packages
Danielle Foré (danrabbit) wrote : | # |
Maybe a better string would be like "Install Language Support" or "Complete Install" or something. I'm not sure "Install Missing" sounds right as an English string since "missing" is an adjective and not a noun.
Otherwise, I think this is an acceptable fix.
David Gomes (davidgomes) wrote : | # |
Shouldn't this better clarify which packages it is installing? It seemed really simple for me, but I have no idea, as a user, of what just happened.
Viko Adi Rahmawan (vikoadi) wrote : | # |
I would love to hear UX sugestion on how we list installed packaged,
How do we list missing package?
How do we show installation progress?
How do we cancel installation?
- 57. By Viko Adi Rahmawan
-
change install button label, cleaning code
- 58. By Viko Adi Rahmawan
-
show installation and removal progress
- 59. By Viko Adi Rahmawan
-
code cleaning
Viko Adi Rahmawan (vikoadi) wrote : | # |
show installation and removal progress
provide cancel button
- 60. By Viko Adi Rahmawan
-
oops, forget to bzr add
Viko Adi Rahmawan (vikoadi) wrote : | # |
add InstallInfobar.vala
- 61. By Viko Adi Rahmawan
-
add copyright text
Corentin Noël (tintou) wrote : | # |
It does the job, needed feature.
Corentin Noël (tintou) : | # |
Preview Diff
1 | === modified file 'src/CMakeLists.txt' |
2 | --- src/CMakeLists.txt 2014-06-09 19:13:14 +0000 |
3 | +++ src/CMakeLists.txt 2014-12-14 05:12:27 +0000 |
4 | @@ -23,6 +23,7 @@ |
5 | Widgets/LanguageEntry.vala |
6 | Widgets/InstallEntry.vala |
7 | Widgets/InstallPopover.vala |
8 | + Widgets/InstallInfoBar.vala |
9 | ${CMAKE_CURRENT_BINARY_DIR}/config.vala |
10 | PACKAGES |
11 | gtk+-3.0 |
12 | @@ -42,4 +43,4 @@ |
13 | target_link_libraries(${PLUGNAME} ${DEPS_LIBRARIES}) |
14 | |
15 | # Installation |
16 | -install (TARGETS ${PLUGNAME} DESTINATION ${PKGDATADIR}) |
17 | \ No newline at end of file |
18 | +install (TARGETS ${PLUGNAME} DESTINATION ${PKGDATADIR}) |
19 | |
20 | === modified file 'src/Installer/UbuntuInstaller.vala' |
21 | --- src/Installer/UbuntuInstaller.vala 2014-05-01 19:51:14 +0000 |
22 | +++ src/Installer/UbuntuInstaller.vala 2014-12-14 05:12:27 +0000 |
23 | @@ -18,9 +18,22 @@ |
24 | static const string LOCALES_REMOVER = "/usr/share/locales/install-language-pack"; |
25 | |
26 | AptdProxy aptd; |
27 | + AptdTransactionProxy proxy; |
28 | + |
29 | + string []? missing_packages = null; |
30 | + public bool install_cancellable; |
31 | + public TransactionMode transaction_mode; |
32 | |
33 | public signal void install_finished (string langcode); |
34 | public signal void remove_finished (string langcode); |
35 | + public signal void check_missing_finished (string [] missing); |
36 | + public signal void progress_changed (int progress); |
37 | + |
38 | + public enum TransactionMode { |
39 | + INSTALL, |
40 | + REMOVE, |
41 | + INSTALL_MISSING, |
42 | + } |
43 | |
44 | Gee.HashMap<string, string> transactions; |
45 | |
46 | @@ -38,6 +51,7 @@ |
47 | } |
48 | |
49 | public void install (string language) { |
50 | + transaction_mode = TransactionMode.INSTALL; |
51 | var packages = get_remaining_packages_for_language (language); |
52 | |
53 | foreach (var packet in packages) { |
54 | @@ -53,14 +67,54 @@ |
55 | } catch (Error e) { |
56 | warning ("Could not queue downloads: %s", e.message); |
57 | } |
58 | - |
59 | - |
60 | - }); |
61 | - |
62 | + |
63 | + |
64 | + }); |
65 | + |
66 | + } |
67 | + |
68 | + public void install_packages (string [] packages) { |
69 | + foreach (var packet in packages) { |
70 | + message ("will install: %s", packet); |
71 | + } |
72 | + |
73 | + aptd.install_packages.begin (packages, (obj, res) => { |
74 | + |
75 | + try { |
76 | + var transaction_id = aptd.install_packages.end (res); |
77 | + transactions.@set (transaction_id, "install-missing"); |
78 | + run_transaction (transaction_id); |
79 | + } catch (Error e) { |
80 | + warning ("Could not queue downloads: %s", e.message); |
81 | + } |
82 | + }); |
83 | + |
84 | + } |
85 | + |
86 | + public void check_missing_languages () { |
87 | + Utils.get_missing_languages.begin ((obj, res) => { |
88 | + try { |
89 | + missing_packages = Utils.get_missing_languages.end (res); |
90 | + |
91 | + if (missing_packages != null) |
92 | + check_missing_finished (missing_packages); |
93 | + } catch (Error e) { |
94 | + warning ("cant parse missing language:%s", e.message); |
95 | + } |
96 | + }); |
97 | + |
98 | + } |
99 | + |
100 | + public void install_missing_languages () { |
101 | + if (missing_packages == null || missing_packages.length == 0) |
102 | + return; |
103 | + transaction_mode = TransactionMode.INSTALL_MISSING; |
104 | + |
105 | + install_packages (missing_packages); |
106 | } |
107 | |
108 | public void remove (string languagecode) { |
109 | - |
110 | + transaction_mode = TransactionMode.REMOVE; |
111 | |
112 | var installed = get_to_remove_packages_for_language (languagecode); |
113 | |
114 | @@ -79,13 +133,31 @@ |
115 | |
116 | } |
117 | |
118 | + public void cancel_install () { |
119 | + if (install_cancellable) { |
120 | + warning ("cancel_install"); |
121 | + try { |
122 | + proxy.cancel (); |
123 | + } catch (Error e) { |
124 | + warning ("cannot cancel installation:%s", e.message); |
125 | + } |
126 | + } |
127 | + } |
128 | + |
129 | void run_transaction (string transaction_id) { |
130 | |
131 | - var proxy = new AptdTransactionProxy (); |
132 | + proxy = new AptdTransactionProxy (); |
133 | proxy.finished.connect (() => { |
134 | on_apt_finshed (transaction_id, true); |
135 | }); |
136 | |
137 | + proxy.property_changed.connect ((prop, val) => { |
138 | + if (prop == "Progress") |
139 | + progress_changed ((int) val.get_int32 ()); |
140 | + if (prop == "Cancellable") |
141 | + install_cancellable = val.get_boolean (); |
142 | + }); |
143 | + |
144 | try { |
145 | proxy.connect_to_aptd (transaction_id); |
146 | proxy.simulate (); |
147 | @@ -110,6 +182,11 @@ |
148 | } |
149 | |
150 | var action = transactions.get (id); |
151 | + if (action == "install-missing") { |
152 | + install_finished (""); |
153 | + transactions.unset (id); |
154 | + return; |
155 | + } |
156 | var lang = action[2:action.length]; |
157 | |
158 | message ("ID %s -> %s", id, success ? "success" : "failed"); |
159 | @@ -188,4 +265,4 @@ |
160 | return output.strip ().split (" "); |
161 | |
162 | } |
163 | -} |
164 | \ No newline at end of file |
165 | +} |
166 | |
167 | === modified file 'src/Installer/aptd-client.vala' |
168 | --- src/Installer/aptd-client.vala 2014-04-09 17:30:07 +0000 |
169 | +++ src/Installer/aptd-client.vala 2014-12-14 05:12:27 +0000 |
170 | @@ -37,6 +37,7 @@ |
171 | public abstract void simulate () throws IOError; |
172 | public abstract void cancel () throws IOError; |
173 | public signal void finished (string exit_state); |
174 | + public signal void property_changed (string property, Variant val); |
175 | } |
176 | |
177 | public class AptdProxy: GLib.Object |
178 | @@ -69,6 +70,7 @@ |
179 | public class AptdTransactionProxy: GLib.Object |
180 | { |
181 | public signal void finished (string transaction_id); |
182 | + public signal void property_changed (string property, Variant variant); |
183 | |
184 | public void connect_to_aptd (string transaction_id) throws IOError |
185 | { |
186 | @@ -78,6 +80,9 @@ |
187 | debug ("aptd transaction finished: %s\n", exit_state); |
188 | finished (transaction_id); |
189 | }); |
190 | + _aptd_service.property_changed.connect ((prop, variant) => { |
191 | + property_changed (prop, variant); |
192 | + }); |
193 | } |
194 | |
195 | public void simulate () throws IOError |
196 | @@ -90,5 +95,10 @@ |
197 | _aptd_service.run (); |
198 | } |
199 | |
200 | + public void cancel () throws IOError |
201 | + { |
202 | + _aptd_service.cancel (); |
203 | + } |
204 | + |
205 | private AptdTransactionService _aptd_service; |
206 | } |
207 | |
208 | === modified file 'src/Plug.vala' |
209 | --- src/Plug.vala 2014-05-07 11:39:44 +0000 |
210 | +++ src/Plug.vala 2014-12-14 05:12:27 +0000 |
211 | @@ -32,6 +32,7 @@ |
212 | LocaleManager lm; |
213 | |
214 | Gtk.InfoBar infobar; |
215 | + Gtk.InfoBar missing_lang_infobar; |
216 | Gtk.Grid grid; |
217 | Gtk.Box top_box; |
218 | |
219 | @@ -149,6 +150,47 @@ |
220 | infobar.show_all (); |
221 | }); |
222 | |
223 | + var install_infobar = new InstallInfoBar (); |
224 | + install_infobar.hide (); |
225 | + install_infobar.cancel_clicked.connect (() => { |
226 | + language_list.cancel_install (); |
227 | + }); |
228 | + |
229 | + missing_lang_infobar = new Gtk.InfoBar (); |
230 | + missing_lang_infobar.message_type = Gtk.MessageType.INFO; |
231 | + |
232 | + var missing_content = missing_lang_infobar.get_content_area () as Gtk.Box; |
233 | + |
234 | + var missing_label = new Gtk.Label (_("Language support is not installed completely")); |
235 | + |
236 | + var install_missing = new Gtk.Button.with_label (_("Complete Installation")); |
237 | + install_missing.clicked.connect (() => { |
238 | + missing_lang_infobar.hide (); |
239 | + |
240 | + language_list.install_missing_languages (); |
241 | + }); |
242 | + language_list.check_missing_finished.connect ((missing) => { |
243 | + if (missing.length > 0) { |
244 | + missing_lang_infobar.show (); |
245 | + missing_lang_infobar.show_all (); |
246 | + } else { |
247 | + missing_lang_infobar.hide (); |
248 | + } |
249 | + }); |
250 | + |
251 | + missing_content.pack_start (missing_label, false); |
252 | + missing_content.pack_end (install_missing, false); |
253 | + |
254 | + language_list.settings_changed.connect (() => { |
255 | + infobar.no_show_all = false; |
256 | + infobar.show_all (); |
257 | + }); |
258 | + language_list.progress_changed.connect((progress) => { |
259 | + install_infobar.set_progress (progress); |
260 | + install_infobar.set_cancellable (language_list.install_cancellable); |
261 | + install_infobar.set_transaction_mode (language_list.get_transaction_mode ()); |
262 | + }); |
263 | + |
264 | try { |
265 | |
266 | var permission = new Polkit.Permission.sync ("org.freedesktop.locale1.set-locale", Polkit.UnixProcess.new (Posix.getpid ())); |
267 | @@ -157,7 +199,7 @@ |
268 | apply_button.label = _("Apply for login screen, guest account and new users"); |
269 | apply_button.halign = Gtk.Align.CENTER; |
270 | apply_button.margin = 12; |
271 | - grid.attach (apply_button, 0, 4, 4, 1); |
272 | + grid.attach (apply_button, 0, 6, 4, 1); |
273 | |
274 | permission.notify["allowed"].connect (() => { |
275 | if (permission.allowed) { |
276 | @@ -170,14 +212,16 @@ |
277 | critical (e.message); |
278 | } |
279 | |
280 | - |
281 | + |
282 | sw.show (); |
283 | header_entry.show_all (); |
284 | |
285 | grid.attach (infobar, 0, 0, 4, 1); |
286 | - grid.attach (header_entry, 0, 1, 4, 1); |
287 | - grid.attach (top_box, 0, 2, 4, 1); |
288 | - grid.attach (sw, 0, 3, 4, 1); |
289 | + grid.attach (missing_lang_infobar, 0, 1, 4, 1); |
290 | + grid.attach (install_infobar, 0, 2, 4, 1); |
291 | + grid.attach (header_entry, 0, 3, 4, 1); |
292 | + grid.attach (top_box, 0, 4, 4, 1); |
293 | + grid.attach (sw, 0, 5, 4, 1); |
294 | grid.show (); |
295 | |
296 | } |
297 | @@ -194,4 +238,4 @@ |
298 | debug ("Activating About plug"); |
299 | var plug = new Locale.Plug (); |
300 | return plug; |
301 | -} |
302 | \ No newline at end of file |
303 | +} |
304 | |
305 | === modified file 'src/Utils.vala' |
306 | --- src/Utils.vala 2014-06-09 19:07:35 +0000 |
307 | +++ src/Utils.vala 2014-12-14 05:12:27 +0000 |
308 | @@ -41,6 +41,41 @@ |
309 | |
310 | } |
311 | |
312 | + public static async string []? get_missing_languages () { |
313 | + |
314 | + /* string output; */ |
315 | + string final = null; |
316 | + Pid pid; |
317 | + int input; |
318 | + int output; |
319 | + int error; |
320 | + |
321 | + try { |
322 | + Process.spawn_async_with_pipes (null, |
323 | + {"check-language-support", null}, |
324 | + Environ.get (), |
325 | + SpawnFlags.SEARCH_PATH, |
326 | + null, |
327 | + out pid, |
328 | + out input, |
329 | + out output, |
330 | + out error); |
331 | + UnixInputStream read_stream = new UnixInputStream (output, true); |
332 | + DataInputStream out_channel = new DataInputStream (read_stream); |
333 | + string line = null; |
334 | + final = ""; |
335 | + while ((line = yield out_channel.read_line_async (Priority.DEFAULT)) != null) { |
336 | + final += line; |
337 | + } |
338 | + |
339 | + if (final != null) |
340 | + return final.strip ().split (" "); |
341 | + else |
342 | + return null; |
343 | + } catch (Error e) { |
344 | + return null; |
345 | + } |
346 | + } |
347 | public static Gee.ArrayList<string>? get_installed_locales () { |
348 | |
349 | string output; |
350 | @@ -71,6 +106,7 @@ |
351 | |
352 | } |
353 | |
354 | + |
355 | public static string translate_language (string lang) { |
356 | Intl.textdomain ("iso_639"); |
357 | var lang_name = dgettext ("iso_639", lang); |
358 | @@ -102,4 +138,4 @@ |
359 | } |
360 | return instance; |
361 | } |
362 | -} |
363 | \ No newline at end of file |
364 | +} |
365 | |
366 | === added file 'src/Widgets/InstallInfoBar.vala' |
367 | --- src/Widgets/InstallInfoBar.vala 1970-01-01 00:00:00 +0000 |
368 | +++ src/Widgets/InstallInfoBar.vala 2014-12-14 05:12:27 +0000 |
369 | @@ -0,0 +1,71 @@ |
370 | +/*** |
371 | + Copyright (C) 2011-2012 Switchboard Locale Plug Developers |
372 | + This program is free software: you can redistribute it and/or modify it |
373 | + under the terms of the GNU Lesser General Public License version 3, as published |
374 | + by the Free Software Foundation. |
375 | + This program is distributed in the hope that it will be useful, but |
376 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
377 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
378 | + PURPOSE. See the GNU General Public License for more details. |
379 | + You should have received a copy of the GNU General Public License along |
380 | + with this program. If not, see |
381 | +***/ |
382 | + |
383 | +public class InstallInfoBar : Gtk.InfoBar { |
384 | + protected Gtk.Box box; |
385 | + protected Gtk.Label label; |
386 | + protected Gtk.ProgressBar progress; |
387 | + protected Gtk.Button cancel_button; |
388 | + |
389 | + private bool _install_cancellable; |
390 | + public void set_cancellable (bool cancellable) { |
391 | + _install_cancellable = cancellable; |
392 | + cancel_button.set_sensitive (_install_cancellable); |
393 | + } |
394 | + |
395 | + public signal void cancel_clicked (); |
396 | + |
397 | + public InstallInfoBar () { |
398 | + this.message_type = Gtk.MessageType.INFO; |
399 | + |
400 | + box = get_content_area () as Gtk.Box; |
401 | + |
402 | + label = new Gtk.Label (null); |
403 | + |
404 | + progress = new Gtk.ProgressBar (); |
405 | + |
406 | + cancel_button = new Gtk.Button.with_label (_("Cancel")); |
407 | + cancel_button.clicked.connect (() => { |
408 | + hide (); |
409 | + cancel_clicked (); |
410 | + }); |
411 | + |
412 | + box.pack_start (label, false); |
413 | + box.pack_end (cancel_button, false); |
414 | + box.pack_end (progress, false); |
415 | + |
416 | + show_all (); |
417 | + } |
418 | + |
419 | + public void set_transaction_mode (UbuntuInstaller.TransactionMode transaction_mode) { |
420 | + switch (transaction_mode) { |
421 | + case UbuntuInstaller.TransactionMode.INSTALL: |
422 | + label.set_label (_("installing language")); |
423 | + break; |
424 | + case UbuntuInstaller.TransactionMode.REMOVE: |
425 | + label.set_label (_("removing language")); |
426 | + break; |
427 | + case UbuntuInstaller.TransactionMode.INSTALL_MISSING: |
428 | + label.set_label (_("installing missing language")); |
429 | + break; |
430 | + } |
431 | + } |
432 | + |
433 | + public void set_progress (int progress) { |
434 | + if (progress >= 100) |
435 | + hide (); |
436 | + else |
437 | + show (); |
438 | + this.progress.set_fraction(progress/100.0); |
439 | + } |
440 | +} |
441 | |
442 | === modified file 'src/Widgets/LanguageList.vala' |
443 | --- src/Widgets/LanguageList.vala 2014-05-07 12:25:29 +0000 |
444 | +++ src/Widgets/LanguageList.vala 2014-12-14 05:12:27 +0000 |
445 | @@ -14,12 +14,18 @@ |
446 | public class LanguageList : Gtk.ListBox { |
447 | |
448 | public signal void settings_changed (); |
449 | + public signal void check_missing_finished (string [] missing); |
450 | + public signal void progress_changed (int progress); |
451 | |
452 | InstallPopover language_popover; |
453 | InstallEntry install_entry; |
454 | |
455 | UbuntuInstaller li; |
456 | |
457 | + public bool install_cancellable { |
458 | + get {return li.install_cancellable;} |
459 | + } |
460 | + |
461 | public Gtk.RadioButton language_button = new Gtk.RadioButton (null); |
462 | public Gtk.RadioButton format_button = new Gtk.RadioButton (null); |
463 | |
464 | @@ -49,6 +55,11 @@ |
465 | li = new UbuntuInstaller (); |
466 | li.install_finished.connect (on_install_finished); |
467 | li.remove_finished.connect (on_remove_finished); |
468 | + li.check_missing_languages (); |
469 | + li.check_missing_finished.connect (on_check_missing_finished); |
470 | + li.progress_changed.connect ((progress) => { |
471 | + progress_changed (progress); |
472 | + }); |
473 | |
474 | lm = LocaleManager.get_default (); |
475 | |
476 | @@ -76,6 +87,8 @@ |
477 | add_locale (locale); |
478 | } |
479 | |
480 | + li.check_missing_languages (); |
481 | + |
482 | requery_display (); |
483 | |
484 | } |
485 | @@ -137,6 +150,8 @@ |
486 | reload_languages (); |
487 | install_entry.install_complete (); |
488 | |
489 | + li.check_missing_languages (); |
490 | + |
491 | } |
492 | |
493 | void on_deletion_requested (string locale) { |
494 | @@ -160,6 +175,20 @@ |
495 | |
496 | } |
497 | |
498 | + void on_check_missing_finished (string [] missing) { |
499 | + this.set_sensitive (true); |
500 | + check_missing_finished (missing); |
501 | + } |
502 | + |
503 | + public void cancel_install () { |
504 | + li.cancel_install (); |
505 | + check_missing_languages (); |
506 | + } |
507 | + |
508 | + public UbuntuInstaller.TransactionMode get_transaction_mode () { |
509 | + return li.transaction_mode; |
510 | + } |
511 | + |
512 | public void add_language(string locale) { |
513 | |
514 | var langcode = locale.substring (0, 2); |
515 | @@ -211,7 +240,14 @@ |
516 | } |
517 | } |
518 | |
519 | + public void check_missing_languages () { |
520 | + li.check_missing_languages (); |
521 | + } |
522 | |
523 | + public void install_missing_languages (){ |
524 | + this.set_sensitive (false); |
525 | + li.install_missing_languages (); |
526 | + } |
527 | |
528 | void on_language_changed (UpdateType type, string lang) { |
529 | if (update_lock) |
530 | @@ -295,4 +331,4 @@ |
531 | return true; |
532 | |
533 | } |
534 | -} |
535 | \ No newline at end of file |
536 | +} |
get_missing_ languages should be async not to block the UI if for any reason the command "/usr/bin/ check-language- support" takes time or hangs.