Changeset View
Changeset View
Standalone View
Standalone View
applets/kimpanel/package/contents/ui/main.qml
Show All 19 Lines | |||||
20 | import QtQuick.Layouts 1.1 | 20 | import QtQuick.Layouts 1.1 | ||
21 | import org.kde.plasma.plasmoid 2.0 | 21 | import org.kde.plasma.plasmoid 2.0 | ||
22 | import org.kde.plasma.core 2.0 as PlasmaCore | 22 | import org.kde.plasma.core 2.0 as PlasmaCore | ||
23 | import org.kde.plasma.components 2.0 as PlasmaComponents | 23 | import org.kde.plasma.components 2.0 as PlasmaComponents | ||
24 | import org.kde.kquickcontrolsaddons 2.0 | 24 | import org.kde.kquickcontrolsaddons 2.0 | ||
25 | 25 | | |||
26 | Item { | 26 | Item { | ||
27 | id: kimpanel | 27 | id: kimpanel | ||
28 | property int visibleButtons: 0 | | |||
29 | 28 | | |||
30 | property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical | 29 | property string imIcon: "input-keyboard" | ||
31 | 30 | property string imLabel: "" | |||
32 | LayoutMirroring.enabled: !vertical && Qt.application.layoutDirection === Qt.RightToLeft | 31 | property string imTip: "" | ||
33 | LayoutMirroring.childrenInherit: true | 32 | property string imHint: "" | ||
34 | 33 | | |||
35 | Layout.minimumWidth: vertical ? units.iconSizes.small : items.implicitWidth | 34 | Layout.minimumWidth: units.iconSizeHints.panel | ||
36 | Layout.minimumHeight: !vertical ? units.iconSizes.small : items.implicitHeight | 35 | Layout.minimumHeight: units.iconSizeHints.panel | ||
37 | Layout.preferredHeight: Layout.minimumHeight | 36 | | ||
38 | Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation | 37 | Plasmoid.icon: imIcon | ||
39 | 38 | Plasmoid.toolTipMainText: imTip | |||
40 | InputPanel { } | 39 | Plasmoid.toolTipSubText: imTip | ||
41 | 40 | | |||
42 | Flow { | 41 | Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation | ||
43 | id: items | 42 | | ||
43 | // Icon view in system tray or panel | ||||
44 | Plasmoid.compactRepresentation: PlasmaCore.IconItem { | ||||
45 | source: imIcon | ||||
44 | width: parent.width | 46 | width: parent.width | ||
45 | height: parent.height | 47 | height: parent.height | ||
46 | x: (parent.width - childrenRect.width) / 2 | | |||
47 | y: (parent.height - childrenRect.height) / 2 | | |||
48 | flow: kimpanel.vertical ? Flow.LeftToRight : Flow.TopToBottom | | |||
49 | 48 | | |||
50 | property int iconSize: Math.min(units.iconSizeHints.panel, units.roundToIconSize(Math.min(width, height))) | 49 | MouseArea { | ||
50 | anchors.fill: parent | ||||
51 | acceptedButtons: Qt.LeftButton | ||||
51 | 52 | | |||
52 | Repeater { | 53 | onClicked: { | ||
53 | model: ListModel { | 54 | plasmoid.expanded = !plasmoid.expanded | ||
54 | id: list | | |||
55 | dynamicRoles: true | | |||
56 | } | | |||
57 | | ||||
58 | delegate: Item { | | |||
59 | id: iconDelegate | | |||
60 | width: items.iconSize | | |||
61 | height: items.iconSize | | |||
62 | StatusIcon { | | |||
63 | id: statusIcon | | |||
64 | anchors.centerIn: parent | | |||
65 | width: items.iconSize | | |||
66 | height: items.iconSize | | |||
67 | label: model.label | | |||
68 | tip: model.tip | | |||
69 | icon: model.icon | | |||
70 | hint: model.hint | | |||
71 | onTriggered : { | | |||
72 | if (button === Qt.LeftButton) { | | |||
73 | clickHandler(model.key); | | |||
74 | // clickHandler will trigger the menu, but we have to wait for | | |||
75 | // the menu data. So we have to set the visual parent ahead. | | |||
76 | actionMenu.visualParent = statusIcon; | | |||
77 | } else { | | |||
78 | contextMenu.open(statusIcon, {key: model.key, label: model.label}); | | |||
79 | } | | |||
80 | } | | |||
81 | } | | |||
82 | } | 55 | } | ||
83 | } | 56 | } | ||
84 | } | 57 | } | ||
85 | 58 | | |||
86 | function clickHandler(key) { | 59 | // The expanded input status panel | ||
87 | var service = dataEngine.serviceForSource("statusbar"); | 60 | Plasmoid.fullRepresentation: StatusPanel { | ||
88 | var operation = service.operationDescription("TriggerProperty"); | 61 | anchors.fill: parent | ||
89 | operation.key = key; | 62 | Layout.minimumWidth: units.gridUnit * 9 | ||
90 | service.startOperationCall(operation); | 63 | Layout.minimumHeight: units.gridUnit * 9 | ||
91 | } | 64 | } | ||
92 | 65 | | |||
93 | function action(key) { | 66 | // The floating input candidate list following text cursor position | ||
94 | var service = dataEngine.serviceForSource("statusbar"); | 67 | InputPanel { } | ||
95 | var operation = service.operationDescription(key); | | |||
96 | service.startOperationCall(operation); | | |||
97 | } | | |||
98 | | ||||
99 | function hideAction(key) { | | |||
100 | // We must use assignment to change the configuration property, | | |||
101 | // otherwise it won't get notified. | | |||
102 | var hiddenList = plasmoid.configuration.hiddenList; | | |||
103 | if (hiddenList.indexOf(key) === -1) { | | |||
104 | hiddenList.push(key); | | |||
105 | plasmoid.configuration.hiddenList = hiddenList; | | |||
106 | } | | |||
107 | timer.restart(); | | |||
108 | } | | |||
109 | | ||||
110 | function showAction(key) { | | |||
111 | // We must use assignment to change the configuration property, | | |||
112 | // otherwise it won't get notified. | | |||
113 | var hiddenList = plasmoid.configuration.hiddenList; | | |||
114 | var index = hiddenList.indexOf(key); | | |||
115 | if (index !== -1) { | | |||
116 | hiddenList.splice(index, 1); | | |||
117 | plasmoid.configuration.hiddenList = hiddenList; | | |||
118 | } | | |||
119 | timer.restart(); | | |||
120 | } | | |||
121 | | ||||
122 | function showMenu(menu, menuData) { | | |||
123 | if (!menuData) { | | |||
124 | return; | | |||
125 | } | | |||
126 | | ||||
127 | if (menuData["timestamp"] > menu.timestamp) { | | |||
128 | menu.timestamp = menuData["timestamp"]; | | |||
129 | var actionList = []; | | |||
130 | for (var i = 0; i < menuData["props"].length; i++ ) { | | |||
131 | actionList.push({"actionId": menuData["props"][i].key, "icon": menuData["props"][i].icon, "text": menuData["props"][i].label, hint: menuData["props"][i].hint}); | | |||
132 | } | | |||
133 | if (actionList.length > 0) { | | |||
134 | menu.actionList = actionList; | | |||
135 | menu.open(); | | |||
136 | } | | |||
137 | } | | |||
138 | } | | |||
139 | | ||||
140 | ActionMenu { | | |||
141 | property var timestamp: 0; | | |||
142 | id: actionMenu | | |||
143 | onActionClicked: { | | |||
144 | clickHandler(actionId); | | |||
145 | } | | |||
146 | } | | |||
147 | | ||||
148 | ContextMenu { | | |||
149 | id: contextMenu | | |||
150 | } | | |||
151 | | ||||
152 | Timer { | | |||
153 | id: timer | | |||
154 | interval: 50 | | |||
155 | onTriggered: { | | |||
156 | var data = dataEngine.data["statusbar"]["Properties"]; | | |||
157 | if (!data) { | | |||
158 | return; | | |||
159 | } | | |||
160 | var count = list.count; | | |||
161 | var c = 0, i; | | |||
162 | var hiddenActions = []; | | |||
163 | for (i = 0; i < data.length; i ++) { | | |||
164 | if (plasmoid.configuration.hiddenList.indexOf(data[i].key) !== -1) { | | |||
165 | hiddenActions.push({'key': data[i].key, | | |||
166 | 'icon': data[i].icon, | | |||
167 | 'label': data[i].label}); | | |||
168 | } else { | | |||
169 | c = c + 1; | | |||
170 | } | | |||
171 | } | | |||
172 | if (c < count) { | | |||
173 | list.remove(c, count - c); | | |||
174 | } | | |||
175 | kimpanel.visibleButtons = c; | | |||
176 | 68 | | |||
177 | c = 0; | 69 | // Context menu of system tray or panel icon | ||
178 | for (i = 0; i < data.length; i ++) { | 70 | function action_fcitxkcm() { | ||
179 | if (plasmoid.configuration.hiddenList.indexOf(data[i].key) !== -1) { | 71 | KCMShell.open(["kcm_fcitx.desktop"]); | ||
180 | continue; | | |||
181 | } | | |||
182 | var itemData = {'key': data[i].key, | | |||
183 | 'icon': data[i].icon, | | |||
184 | 'label': data[i].label, | | |||
185 | 'tip': data[i].tip, | | |||
186 | 'hint': data[i].hint }; | | |||
187 | if (c < count) { | | |||
188 | list.set(c, itemData); | | |||
189 | } else { | | |||
190 | list.append(itemData); | | |||
191 | } | 72 | } | ||
192 | c = c + 1; | 73 | function action_keyboardkcm() { | ||
193 | } | 74 | KCMShell.open(["kcm_keyboard.desktop"]); | ||
194 | contextMenu.actionList = hiddenActions; | | |||
195 | } | 75 | } | ||
76 | Component.onCompleted: { | ||||
77 | plasmoid.setAction("keyboardkcm", i18n("Configure &Keyboard"), "input-keyboard"); | ||||
78 | plasmoid.setAction("fcitxkcm", i18n("Configure &Fcitx"), "fcitx"); | ||||
196 | } | 79 | } | ||
197 | 80 | | |||
81 | // Data engine to get IME status information | ||||
198 | PlasmaCore.DataSource { | 82 | PlasmaCore.DataSource { | ||
199 | id: dataEngine | 83 | id: dataEngine | ||
200 | engine: "kimpanel" | 84 | engine: "kimpanel" | ||
201 | connectedSources: ["statusbar"] | 85 | connectedSources: ["statusbar"] | ||
202 | onDataChanged: { | 86 | onDataChanged: { | ||
203 | showMenu(actionMenu, dataEngine.data["statusbar"]["Menu"]); | 87 | // Lock input method state when opening kimpanel so we can avoid state jumping | ||
204 | var data = dataEngine.data["statusbar"]["Properties"]; | 88 | if (!plasmoid.expanded) { | ||
205 | if (!data) { | 89 | var Properties = dataEngine.data["statusbar"]["Properties"]; | ||
206 | kimpanel.visibleButtons = 0; | 90 | for (var i = 0; i < Properties.length; i++) { | ||
207 | return; | 91 | var p = Properties[i]; | ||
92 | // Find data of current input method | ||||
93 | if (p.key === "/Fcitx/im" || p.key.indexOf("/IBus/Engine/") === 0 || p.key.indexOf("/Factory/") === 0) { | ||||
94 | imIcon = p.icon || "input-keyboard" | ||||
95 | imLabel = p.label | ||||
96 | imTip = p.tip | ||||
97 | imHint = p.hint | ||||
98 | } | ||||
99 | } | ||||
208 | } | 100 | } | ||
209 | | ||||
210 | timer.restart(); | | |||
211 | } | 101 | } | ||
212 | } | 102 | } | ||
213 | } | 103 | } | ||
214 | |