Merge lp:~attente/indicator-keyboard/1291962-2 into lp:indicator-keyboard

Proposed by William Hua
Status: Merged
Merged at revision: 337
Proposed branch: lp:~attente/indicator-keyboard/1291962-2
Merge into: lp:indicator-keyboard
Diff against target: 591 lines (+205/-127)
9 files modified
.bzrignore (+3/-1)
data/Makefile.am (+2/-2)
lib/Makefile.am (+7/-6)
lib/ibus-menu.vala (+22/-23)
lib/indicator-menu.vala (+128/-0)
lib/main.vala (+36/-90)
po/POTFILES.in (+1/-0)
po/POTFILES.skip (+1/-0)
po/indicator-keyboard.pot (+5/-5)
To merge this branch: bzr merge lp:~attente/indicator-keyboard/1291962-2
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Sebastien Bacher Needs Fixing
Ted Gould (community) Approve
Review via email: mp+213346@code.launchpad.net

Commit message

Export separate menus for desktop and greeter.

Description of the change

Export separate menus for desktop and greeter.

(Re-submission of https://code.launchpad.net/~attente/indicator-keyboard/1291962/+merge/212967)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ted Gould (ted) wrote :

Small thing, need to change the "..." to a "…" in "Text Entry Settings..." Marking approved on the review but not top-approving.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sebastien Bacher (seb128) wrote :

While Ted's comment makes sense, could you revert it? That's a string change which would invalidate the translations, the i18n team said that would be better be done next cycle to avoid regression on some locales for the release.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sebastien Bacher (seb128) wrote :

trying to put that under CI train the build failed with

" VALAC indicator_keyboard_service_vala.stamp
main.vala:134.9-134.20: error: The name `sources_menu' does not exist in the context of `Indicator.Keyboard.Service.get_ibus._lambda12_'
    if (sources_menu != null) {
        ^^^^^^^^^^^^
main.vala:135.6-135.24: error: The name `update_sources_menu' does not exist in the context of `Indicator.Keyboard.Service.get_ibus._lambda12_'
     update_sources_menu ();"

review: Needs Fixing
324. By William Hua

Merge trunk fixing conflicts.

Revision history for this message
William Hua (attente) wrote :

Sorry... it's the same bad merge.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2013-08-08 22:15:00 +0000
3+++ .bzrignore 2014-04-08 19:41:04 +0000
4@@ -29,6 +29,8 @@
5 po/POTFILES
6 po/stamp-it
7 tests/config.vala
8+tests/dconf-service
9+tests/gvfs
10 tests/indicator-keyboard-test
11 tests/indicator-keyboard-test.trs
12 tests/indicator-keyboard-tests
13@@ -39,4 +41,4 @@
14 m4/lt~obsolete.m4
15 m4/ltoptions.m4
16 m4/ltsugar.m4
17-m4/ltversion.m4
18\ No newline at end of file
19+m4/ltversion.m4
20
21=== modified file 'data/Makefile.am'
22--- data/Makefile.am 2014-03-11 13:25:54 +0000
23+++ data/Makefile.am 2014-04-08 19:41:04 +0000
24@@ -54,10 +54,10 @@
25 echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop'; \
26 echo ''; \
27 echo '[desktop_greeter]'; \
28- echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop'; \
29+ echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop_greeter'; \
30 echo ''; \
31 echo '[desktop_lockscreen]'; \
32- echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop'; \
33+ echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop_greeter'; \
34 echo ''; \
35 echo '[ubiquity]'; \
36 echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop') > $@.tmp && \
37
38=== modified file 'lib/Makefile.am'
39--- lib/Makefile.am 2014-03-19 03:32:18 +0000
40+++ lib/Makefile.am 2014-04-08 19:41:04 +0000
41@@ -6,12 +6,13 @@
42 --metadatadir $(top_srcdir)/deps \
43 --vapidir $(top_srcdir)/deps
44
45-indicator_keyboard_service_SOURCES = main.vala \
46- source.vala \
47- common.vala \
48- ibus-menu.vala \
49- ibus-panel.vala \
50- window-stack.vala \
51+indicator_keyboard_service_SOURCES = main.vala \
52+ source.vala \
53+ common.vala \
54+ ibus-menu.vala \
55+ ibus-panel.vala \
56+ indicator-menu.vala \
57+ window-stack.vala \
58 unity-greeter.vala
59 indicator_keyboard_service_VALAFLAGS = $(AM_VALAFLAGS) \
60 --pkg gee-1.0 \
61
62=== modified file 'lib/ibus-menu.vala'
63--- lib/ibus-menu.vala 2014-02-20 03:59:24 +0000
64+++ lib/ibus-menu.vala 2014-04-08 19:41:04 +0000
65@@ -23,16 +23,16 @@
66 private IBus.PropList? properties;
67
68 private Menu menu;
69- private SimpleActionGroup? action_group;
70+ private ActionMap? action_map;
71
72 private string? radio_name;
73 private SimpleAction? radio_action;
74 private Gee.HashMap<string, IBus.Property> radio_properties;
75
76- // A list of the action names this menu registers
77+ /* A list of the action names this menu registers. */
78 private Gee.LinkedList<string> names;
79
80- public IBusMenu (SimpleActionGroup? action_group = null, IBus.PropList? properties = null) {
81+ public IBusMenu (ActionMap? action_map = null, IBus.PropList? properties = null) {
82 menu = new Menu ();
83
84 menu.items_changed.connect ((position, removed, added) => {
85@@ -40,7 +40,7 @@
86 });
87
88 names = new Gee.LinkedList<string> ();
89- set_action_group (action_group);
90+ set_action_map (action_map);
91 set_properties (properties);
92 }
93
94@@ -72,12 +72,12 @@
95 name = @"ibus-$key";
96 }
97
98- // Find an unused action name using a counter
99- if (action_group != null && (Action?) ((!) action_group).lookup_action (name) != null) {
100+ /* Find an unused action name using a counter. */
101+ if (action_map != null && (Action?) ((!) action_map).lookup_action (name) != null) {
102 var i = 0;
103 var unique_name = @"$name-$i";
104
105- while ((Action?) ((!) action_group).lookup_action (unique_name) != null) {
106+ while ((Action?) ((!) action_map).lookup_action (unique_name) != null) {
107 i++;
108 unique_name = @"$name-$i";
109 }
110@@ -107,10 +107,10 @@
111 if ((string?) property.key != null) {
112 var name = get_action_name (property.key);
113
114- if (action_group != null) {
115+ if (action_map != null) {
116 var action = new SimpleAction (name, null);
117 action.activate.connect ((parameter) => { activate (property, property.state); });
118- ((!) action_group).add_action (action);
119+ ((!) action_map).add_action (action);
120 names.add (name);
121 }
122
123@@ -124,7 +124,7 @@
124 if ((string?) property.key != null) {
125 var name = get_action_name (property.key);
126
127- if (action_group != null) {
128+ if (action_map != null) {
129 var state = new Variant.boolean (property.state == IBus.PropState.CHECKED);
130 var action = new SimpleAction.stateful (name, null, state);
131
132@@ -139,7 +139,7 @@
133 }
134 });
135
136- ((!) action_group).add_action (action);
137+ ((!) action_map).add_action (action);
138 names.add (name);
139 }
140
141@@ -151,8 +151,8 @@
142 private void append_radio_property (IBus.Property property) {
143 if (property.prop_type == IBus.PropType.RADIO) {
144 if ((string?) property.key != null) {
145- // Create a single action for all radio properties.
146- if (action_group != null && radio_name == null) {
147+ /* Create a single action for all radio properties. */
148+ if (action_map != null && radio_name == null) {
149 radio_counter++;
150 radio_name = @"-private-radio-$radio_counter";
151 radio_action = new SimpleAction.stateful ((!) radio_name, VariantType.STRING, new Variant.string (""));
152@@ -172,7 +172,7 @@
153 }
154 });
155
156- ((!) action_group).add_action ((!) radio_action);
157+ ((!) action_map).add_action ((!) radio_action);
158 names.add ((!) radio_name);
159 }
160
161@@ -195,7 +195,7 @@
162
163 private void append_menu_property (IBus.Property property) {
164 if (property.prop_type == IBus.PropType.MENU) {
165- var submenu = new IBusMenu (action_group, ((!) property).sub_props);
166+ var submenu = new IBusMenu (action_map, ((!) property).sub_props);
167 submenu.activate.connect ((property, state) => { activate (property, state); });
168 menu.append_submenu (get_label (property), submenu);
169 }
170@@ -227,8 +227,7 @@
171 }
172
173 private void update_menu () {
174- // There's a reference cycle between the action group and the submenus.
175- // We need to break it here so that those submenus aren't hanging around.
176+ /* Break reference cycle between action map and submenus. */
177 for (var i = 0; i < menu.get_n_items (); i++) {
178 var submenu = menu.get_item_link (i, Menu.LINK_SUBMENU) as IBusMenu;
179
180@@ -250,19 +249,19 @@
181 radio_action = null;
182 radio_name = null;
183
184- if (action_group != null) {
185+ if (action_map != null) {
186 foreach (var name in names) {
187- ((!) action_group).remove_action (name);
188+ ((!) action_map).remove_action (name);
189 }
190 }
191
192 names.clear ();
193 }
194
195- public void set_action_group (SimpleActionGroup? action_group) {
196- if (action_group != this.action_group) {
197+ public void set_action_map (ActionMap? action_map) {
198+ if (action_map != this.action_map) {
199 remove_actions ();
200- this.action_group = action_group;
201+ this.action_map = action_map;
202 update_menu ();
203 }
204 }
205@@ -282,7 +281,7 @@
206 update_menu ();
207 }
208
209- // Forward all menu model calls to our internal menu
210+ /* Forward all menu model calls to our internal menu. */
211
212 public override Variant get_item_attribute_value (int item_index, string attribute, VariantType? expected_type) {
213 return menu.get_item_attribute_value (item_index, attribute, expected_type);
214
215=== added file 'lib/indicator-menu.vala'
216--- lib/indicator-menu.vala 1970-01-01 00:00:00 +0000
217+++ lib/indicator-menu.vala 2014-04-08 19:41:04 +0000
218@@ -0,0 +1,128 @@
219+/*
220+ * Copyright 2014 Canonical Ltd.
221+ *
222+ * This program is free software: you can redistribute it and/or modify
223+ * it under the terms of the GNU General Public License as published by
224+ * the Free Software Foundation, version 3 of the License.
225+ *
226+ * This program is distributed in the hope that it will be useful,
227+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
228+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
229+ * GNU General Public License for more details.
230+ *
231+ * You should have received a copy of the GNU General Public License
232+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
233+ *
234+ * Authors: William Hua <william.hua@canonical.com>
235+ */
236+
237+public class Indicator.Keyboard.IndicatorMenu : MenuModel {
238+
239+ public enum Options {
240+ NONE = 0x0,
241+ IBUS = 0x1,
242+ SETTINGS = 0x2
243+ }
244+
245+ private Options options;
246+
247+ private Menu indicator_menu;
248+ private Menu sources_section;
249+ private IBusMenu properties_section;
250+
251+ public IndicatorMenu (ActionMap? action_map = null, Options options = Options.IBUS | Options.SETTINGS) {
252+ var submenu = new Menu ();
253+
254+ sources_section = new Menu ();
255+ submenu.append_section (null, sources_section);
256+
257+ if ((options & Options.IBUS) != Options.NONE) {
258+ properties_section = new IBusMenu (action_map);
259+ properties_section.activate.connect ((property, state) => { activate (property, state); });
260+ submenu.append_section (null, properties_section);
261+ }
262+
263+ if ((options & Options.SETTINGS) != Options.NONE) {
264+ var settings_section = new Menu ();
265+ settings_section.append (_ ("Character Map"), "indicator.map");
266+ settings_section.append (_ ("Keyboard Layout Chart"), "indicator.chart");
267+ settings_section.append (_ ("Text Entry Settings..."), "indicator.settings");
268+ submenu.append_section (null, settings_section);
269+ }
270+
271+ var indicator = new MenuItem.submenu (null, submenu);
272+ indicator.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.root");
273+ indicator.set_attribute ("x-canonical-secondary-action", "s", "indicator.next");
274+ indicator.set_attribute ("x-canonical-scroll-action", "s", "indicator.scroll");
275+ indicator.set_detailed_action ("indicator.indicator");
276+
277+ indicator_menu = new Menu ();
278+ indicator_menu.append_item (indicator);
279+
280+ this.options = options;
281+ }
282+
283+ public signal void activate (IBus.Property property, IBus.PropState state);
284+
285+ public void set_sources (Source[] sources) {
286+ sources_section.remove_all ();
287+
288+ for (var i = 0; i < sources.length; i++) {
289+ if (!sources[i].is_ibus || (options & Options.IBUS) != Options.NONE) {
290+ var item = new MenuItem (sources[i].name, "indicator.current");
291+
292+ item.set_attribute (Menu.ATTRIBUTE_TARGET, "u", i);
293+
294+ if (sources[i].icon != null) {
295+ item.set_icon ((!) sources[i].icon);
296+ }
297+
298+ sources_section.append_item (item);
299+ }
300+ }
301+ }
302+
303+ public void set_properties (IBus.PropList properties) {
304+ if ((options & Options.IBUS) != Options.NONE) {
305+ properties_section.set_properties (properties);
306+ }
307+ }
308+
309+ public void update_property (IBus.Property property) {
310+ if ((options & Options.IBUS) != Options.NONE) {
311+ properties_section.update_property (property);
312+ }
313+ }
314+
315+ public override bool is_mutable () {
316+ return indicator_menu.is_mutable ();
317+ }
318+
319+ public override int get_n_items () {
320+ return indicator_menu.get_n_items ();
321+ }
322+
323+ public override void get_item_attributes (int item_index, out HashTable<string, Variant>? attributes) {
324+ indicator_menu.get_item_attributes (item_index, out attributes);
325+ }
326+
327+ public override void get_item_links (int item_index, out HashTable<string, MenuModel>? links) {
328+ indicator_menu.get_item_links (item_index, out links);
329+ }
330+
331+ public override Variant get_item_attribute_value (int item_index, string attribute, VariantType? expected_type) {
332+ return indicator_menu.get_item_attribute_value (item_index, attribute, expected_type);
333+ }
334+
335+ public override MenuModel get_item_link (int item_index, string link) {
336+ return indicator_menu.get_item_link (item_index, link);
337+ }
338+
339+ public override MenuAttributeIter iterate_item_attributes (int item_index) {
340+ return indicator_menu.iterate_item_attributes (item_index);
341+ }
342+
343+ public override MenuLinkIter iterate_item_links (int item_index) {
344+ return indicator_menu.iterate_item_links (item_index);
345+ }
346+}
347
348=== modified file 'lib/main.vala'
349--- lib/main.vala 2014-04-01 21:42:22 +0000
350+++ lib/main.vala 2014-04-08 19:41:04 +0000
351@@ -45,9 +45,8 @@
352
353 private SimpleActionGroup? action_group;
354 private SimpleAction? indicator_action;
355- private MenuModel? menu_model;
356- private Menu? sources_menu;
357- private IBusMenu? ibus_menu;
358+ private IndicatorMenu? desktop_menu;
359+ private IndicatorMenu? desktop_greeter_menu;
360
361 private UnityGreeter? unity_greeter;
362 private string? greeter_user;
363@@ -71,8 +70,12 @@
364 }
365 }
366
367- if (sources_menu != null) {
368- update_sources_menu ();
369+ if (desktop_menu != null) {
370+ get_desktop_menu ().set_sources (get_sources ());
371+ }
372+
373+ if (desktop_greeter_menu != null) {
374+ get_desktop_greeter_menu ().set_sources (get_sources ());
375 }
376
377 if (indicator_action != null) {
378@@ -128,8 +131,12 @@
379 IBus.init ();
380 ibus = new IBus.Bus ();
381 ((!) ibus).connected.connect (() => {
382- if (sources_menu != null) {
383- update_sources_menu ();
384+ if (desktop_menu != null) {
385+ get_desktop_menu ().set_sources (get_sources ());
386+ }
387+
388+ if (desktop_greeter_menu != null) {
389+ get_desktop_greeter_menu ().set_sources (get_sources ());
390 }
391
392 if (indicator_action != null) {
393@@ -645,7 +652,7 @@
394 }
395
396 panel_timeout = Timeout.add (PROPERTIES_DELAY, () => {
397- update_ibus_menu (list);
398+ get_desktop_menu ().set_properties (list);
399 panel_timeout = 0;
400 return false;
401 });
402@@ -653,7 +660,7 @@
403
404 [DBus (visible = false)]
405 private void handle_property_updated (IBus.Property property) {
406- get_ibus_menu ().update_property (property);
407+ get_desktop_menu ().update_property (property);
408 }
409
410 [DBus (visible = false)]
411@@ -753,48 +760,11 @@
412 }
413
414 [DBus (visible = false)]
415- private void update_sources_menu () {
416- if (sources_menu != null) {
417- var menu = get_sources_menu ();
418- menu.remove_all ();
419-
420- var sources = get_sources ();
421- for (var i = 0; i < sources.length; i++) {
422- var item = new MenuItem (sources[i].name, "indicator.current");
423- item.set_attribute (Menu.ATTRIBUTE_TARGET, "u", i);
424-
425- var icon = sources[i].icon;
426- if (icon != null) {
427- item.set_icon ((!) icon);
428- }
429-
430- menu.append_item (item);
431- }
432- } else {
433- get_sources_menu ();
434- }
435- }
436-
437- [DBus (visible = false)]
438- private Menu get_sources_menu () {
439- if (sources_menu == null) {
440- sources_menu = new Menu ();
441- update_sources_menu ();
442- }
443-
444- return (!) sources_menu;
445- }
446-
447- [DBus (visible = false)]
448- private void update_ibus_menu (IBus.PropList list) {
449- get_ibus_menu ().set_properties (list);
450- }
451-
452- [DBus (visible = false)]
453- private IBusMenu get_ibus_menu () {
454- if (ibus_menu == null) {
455- ibus_menu = new IBusMenu (get_action_group ());
456- ((!) ibus_menu).activate.connect ((property, state) => {
457+ public IndicatorMenu get_desktop_menu () {
458+ if (desktop_menu == null) {
459+ desktop_menu = new IndicatorMenu (get_action_group ());
460+ ((!) desktop_menu).set_sources (get_sources ());
461+ ((!) desktop_menu).activate.connect ((property, state) => {
462 var panel = get_ibus_panel ();
463
464 if (panel != null) {
465@@ -807,43 +777,17 @@
466 });
467 }
468
469- return (!) ibus_menu;
470- }
471-
472- [DBus (visible = false)]
473- protected virtual MenuModel create_menu_model (MenuModel sources_menu, MenuModel ibus_menu) {
474- var menu = new Menu ();
475-
476- var submenu = new Menu ();
477-
478- submenu.append_section (null, sources_menu);
479- submenu.append_section (null, ibus_menu);
480-
481- if (!is_login_user ()) {
482- var section = new Menu ();
483- section.append (_ ("Character Map"), "indicator.map");
484- section.append (_ ("Keyboard Layout Chart"), "indicator.chart");
485- section.append (_ ("Text Entry Settings..."), "indicator.settings");
486- submenu.append_section (null, section);
487- }
488-
489- var indicator = new MenuItem.submenu ("x", submenu);
490- indicator.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.root");
491- indicator.set_attribute ("x-canonical-secondary-action", "s", "indicator.next");
492- indicator.set_attribute ("x-canonical-scroll-action", "s", "indicator.scroll");
493- indicator.set_detailed_action ("indicator.indicator");
494- menu.append_item (indicator);
495-
496- return menu;
497- }
498-
499- [DBus (visible = false)]
500- public MenuModel get_menu_model () {
501- if (menu_model == null) {
502- menu_model = create_menu_model (get_sources_menu (), get_ibus_menu ());
503- }
504-
505- return (!) menu_model;
506+ return (!) desktop_menu;
507+ }
508+
509+ [DBus (visible = false)]
510+ public IndicatorMenu get_desktop_greeter_menu () {
511+ if (desktop_greeter_menu == null) {
512+ desktop_greeter_menu = new IndicatorMenu (get_action_group (), IndicatorMenu.Options.NONE);
513+ ((!) desktop_greeter_menu).set_sources (get_sources ());
514+ }
515+
516+ return (!) desktop_greeter_menu;
517 }
518
519 [DBus (visible = false)]
520@@ -861,7 +805,8 @@
521 private void handle_changed_sources (string key) {
522 sources = null;
523
524- update_sources_menu ();
525+ get_desktop_menu ().set_sources (get_sources ());
526+ get_desktop_greeter_menu ().set_sources (get_sources ());
527 update_indicator_action ();
528 update_login_layout ();
529 }
530@@ -951,7 +896,8 @@
531 private void handle_bus_acquired (DBusConnection connection, string name) {
532 try {
533 connection.export_action_group ("/com/canonical/indicator/keyboard", get_action_group ());
534- connection.export_menu_model ("/com/canonical/indicator/keyboard/desktop", get_menu_model ());
535+ connection.export_menu_model ("/com/canonical/indicator/keyboard/desktop", get_desktop_menu ());
536+ connection.export_menu_model ("/com/canonical/indicator/keyboard/desktop_greeter", get_desktop_greeter_menu ());
537 } catch (Error error) {
538 warning ("error: %s", error.message);
539 }
540
541=== modified file 'po/POTFILES.in'
542--- po/POTFILES.in 2013-09-27 15:10:19 +0000
543+++ po/POTFILES.in 2014-04-08 19:41:04 +0000
544@@ -1,2 +1,3 @@
545 # List of source files which contain translatable strings.
546 lib/main.vala
547+lib/indicator-menu.vala
548
549=== modified file 'po/POTFILES.skip'
550--- po/POTFILES.skip 2013-09-27 15:10:19 +0000
551+++ po/POTFILES.skip 2014-04-08 19:41:04 +0000
552@@ -1,1 +1,2 @@
553 lib/main.c
554+lib/indicator-menu.c
555
556=== modified file 'po/indicator-keyboard.pot'
557--- po/indicator-keyboard.pot 2014-03-19 23:25:34 +0000
558+++ po/indicator-keyboard.pot 2014-04-08 19:41:04 +0000
559@@ -8,7 +8,7 @@
560 msgstr ""
561 "Project-Id-Version: PACKAGE VERSION\n"
562 "Report-Msgid-Bugs-To: \n"
563-"POT-Creation-Date: 2014-03-20 12:25+1300\n"
564+"POT-Creation-Date: 2014-03-27 23:39+1300\n"
565 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
566 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
567 "Language-Team: LANGUAGE <LL@li.org>\n"
568@@ -17,19 +17,19 @@
569 "Content-Type: text/plain; charset=CHARSET\n"
570 "Content-Transfer-Encoding: 8bit\n"
571
572-#: ../lib/main.vala:667
573+#: ../lib/main.vala:670
574 #, c-format
575 msgid "%s input source"
576 msgstr ""
577
578-#: ../lib/main.vala:815
579+#: ../lib/indicator-menu.vala:47
580 msgid "Character Map"
581 msgstr ""
582
583-#: ../lib/main.vala:816
584+#: ../lib/indicator-menu.vala:48
585 msgid "Keyboard Layout Chart"
586 msgstr ""
587
588-#: ../lib/main.vala:817
589+#: ../lib/indicator-menu.vala:49
590 msgid "Text Entry Settings..."
591 msgstr ""

Subscribers

People subscribed via source and target branches

to all changes: