Merge lp:~vikoadi/switchboard-plug-locale/missing-locale into lp:~elementary-apps/switchboard-plug-locale/trunk

Proposed by Viko Adi Rahmawan
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
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-language-support" command to find missing packages

To post a comment you must log in.
55. By Viko Adi Rahmawan

clean code style

Revision history for this message
PerfectCarl (name-is-carl) wrote :

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.

56. By Viko Adi Rahmawan

asynchronously query missing language packages

Revision history for this message
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.

review: Approve (ux)
Revision history for this message
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.

Revision history for this message
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

Revision history for this message
Viko Adi Rahmawan (vikoadi) wrote :

show installation and removal progress
provide cancel button

60. By Viko Adi Rahmawan

oops, forget to bzr add

Revision history for this message
Viko Adi Rahmawan (vikoadi) wrote :

add InstallInfobar.vala

61. By Viko Adi Rahmawan

add copyright text

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

It does the job, needed feature.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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+}

Subscribers

People subscribed via source and target branches