aboutsummaryrefslogtreecommitdiff
path: root/lib/indicator-menu.vala
blob: 2cfa52c6d7152f2d8a452145c9e2e5f675f300f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright 2014 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: William Hua <william.hua@canonical.com>
 */

public class Indicator.Keyboard.IndicatorMenu : MenuModel {

	public enum Options {
		NONE     = 0,
		DCONF    = 1 << 0,
		XKB      = 1 << 1,
		IBUS     = 1 << 2,
		SETTINGS = 1 << 3
	}

	private Options options;

	private Menu indicator_menu;
	private Menu sources_section;
	private IBusMenu properties_section;

	public IndicatorMenu (ActionMap? action_map = null, Options options = Options.NONE) {
		this.options = options;

		indicator_menu = new Menu ();
		sources_section = new Menu ();

		if ((options & ~Options.DCONF) != Options.NONE) {
			var submenu = new Menu ();

			submenu.append_section (null, sources_section);

			if (Options.IBUS in options) {
				properties_section = new IBusMenu (action_map);
				properties_section.activate.connect ((property, state) => { activate (property, state); });
				submenu.append_section (null, properties_section);
			}

			if (Options.SETTINGS in options) {
				var settings_section = new Menu ();
				settings_section.append (_ ("Character Map"), "indicator.map");
				settings_section.append (_ ("Keyboard Layout Chart"), "indicator.chart");
				settings_section.append (_ ("Text Entry Settings..."), "indicator.settings");
				submenu.append_section (null, settings_section);
			}

			var indicator = new MenuItem.submenu (null, submenu);
			indicator.set_detailed_action ("indicator.indicator");
			indicator.set_attribute ("x-canonical-type", "s", "org.ayatana.indicator.root");

			/* We need special mouse actions on the lock screen. */
			if (Options.DCONF in options) {
				indicator.set_attribute ("x-canonical-secondary-action", "s", "indicator.next");
				indicator.set_attribute ("x-canonical-scroll-action", "s", "indicator.scroll");
			} else {
				indicator.set_attribute ("x-canonical-secondary-action", "s", "indicator.locked_next");
				indicator.set_attribute ("x-canonical-scroll-action", "s", "indicator.locked_scroll");
			}

			indicator_menu.append_item (indicator);
		}
	}

	public signal void activate (IBus.Property property, IBus.PropState state);

	public void set_sources (Source[] sources) {
		sources_section.remove_all ();

		for (var i = 0; i < sources.length; i++) {
			var visible = (sources[i].is_xkb && Options.XKB in options) ||
			              (sources[i].is_ibus && Options.IBUS in options);

			if (visible) {
				string action;

				if (Options.DCONF in options) {
					action = "indicator.current";
				} else {
					action = "indicator.active";
				}

				var item = new MenuItem (sources[i].name, action);

				item.set_attribute (Menu.ATTRIBUTE_TARGET, "u", i);

				if (sources[i].icon != null) {
					item.set_icon ((!) sources[i].icon);
				}

				sources_section.append_item (item);
			}
		}
	}

	public void set_properties (IBus.PropList properties) {
		if (Options.IBUS in options) {
			properties_section.set_properties (properties);
		}
	}

	public void update_property (IBus.Property property) {
		if (Options.IBUS in options) {
			properties_section.update_property (property);
		}
	}

	public override bool is_mutable () {
		return indicator_menu.is_mutable ();
	}

	public override int get_n_items () {
		return indicator_menu.get_n_items ();
	}

	public override void get_item_attributes (int item_index, out HashTable<string, Variant>? attributes) {
		indicator_menu.get_item_attributes (item_index, out attributes);
	}

	public override void get_item_links (int item_index, out HashTable<string, MenuModel> links) {
		indicator_menu.get_item_links (item_index, out links);
	}

	public override Variant get_item_attribute_value (int item_index, string attribute, VariantType? expected_type) {
		return indicator_menu.get_item_attribute_value (item_index, attribute, expected_type);
	}

	public override MenuModel get_item_link (int item_index, string link) {
		return indicator_menu.get_item_link (item_index, link);
	}

	public override MenuAttributeIter iterate_item_attributes (int item_index) {
		return indicator_menu.iterate_item_attributes (item_index);
	}

	public override MenuLinkIter iterate_item_links (int item_index) {
		return indicator_menu.iterate_item_links (item_index);
	}
}