Merge lp:~michael-sheldon/ubuntu-keyboard/emoji into lp:ubuntu-keyboard
- emoji
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Bill Filler | ||||
Approved revision: | 247 | ||||
Merged at revision: | 261 | ||||
Proposed branch: | lp:~michael-sheldon/ubuntu-keyboard/emoji | ||||
Merge into: | lp:ubuntu-keyboard | ||||
Diff against target: |
1131 lines (+822/-20) 29 files modified
debian/control (+8/-0) debian/ubuntu-keyboard-emoji.install (+1/-0) plugins/emoji/emoji.pro (+9/-0) plugins/emoji/qml/Keyboard_emoji.qml (+188/-0) plugins/emoji/qml/Keyboard_emoji_email.qml (+93/-0) plugins/emoji/qml/Keyboard_emoji_url.qml (+92/-0) plugins/emoji/qml/Keyboard_emoji_url_search.qml (+94/-0) plugins/emoji/qml/emoji.js (+14/-0) plugins/emoji/qml/qml.pro (+20/-0) plugins/emoji/src/emojilanguagefeatures.cpp (+83/-0) plugins/emoji/src/emojilanguagefeatures.h (+39/-0) plugins/emoji/src/emojiplugin.cpp (+19/-0) plugins/emoji/src/emojiplugin.h (+29/-0) plugins/emoji/src/emojiplugin.json (+7/-0) plugins/emoji/src/src.pro (+32/-0) plugins/pinyin/src/chineselanguagefeatures.cpp (+5/-0) plugins/pinyin/src/chineselanguagefeatures.h (+1/-0) plugins/plugins.pro (+1/-0) plugins/westernsupport/westernlanguagefeatures.cpp (+5/-0) plugins/westernsupport/westernlanguagefeatures.h (+1/-0) qml/KeyboardContainer.qml (+14/-2) qml/keys/LanguageKey.qml (+8/-1) qml/keys/LanguageMenu.qml (+1/-0) src/lib/logic/abstractlanguagefeatures.h (+1/-0) src/lib/logic/wordengine.cpp (+6/-1) src/plugin/inputmethod.cpp (+1/-6) src/plugin/inputmethod_p.h (+0/-9) tests/autopilot/ubuntu_keyboard/emulators/keyboard.py (+5/-0) tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py (+45/-1) |
||||
To merge this branch: | bzr merge lp:~michael-sheldon/ubuntu-keyboard/emoji | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Bill Filler (community) | Approve | ||
Ken VanDine | Approve | ||
Review via email: mp+244008@code.launchpad.net |
Commit message
Add emoji layout
Description of the change
Add emoji layout
Michael Sheldon (michael-sheldon) wrote : | # |
Ken VanDine (ken-vandine) wrote : | # |
The package description says it provides data files for the emoji keyboard. It looks like this builds a plugin as well. So that makes arch: any appropriate, however could this cause any multi-arch issues? Perhaps the data files should go in a -data package as arch: all?
Ken VanDine (ken-vandine) wrote : | # |
My multi-arch question above was answered on IRC, this plugin is packaged the same as the others. So if that's an issue, it's been there for the other plugins. Packaging changes look fine to me.
Bill Filler (bfiller) wrote : | # |
works great, nice job!
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:247
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2014-12-01 16:32:25 +0000 |
3 | +++ debian/control 2014-12-08 15:48:42 +0000 |
4 | @@ -162,6 +162,14 @@ |
5 | Description: Ubuntu on-screen keyboard data files - Dutch |
6 | Data files for the Ubuntu virtual keyboard - Dutch |
7 | |
8 | +Package: ubuntu-keyboard-emoji |
9 | +Architecture: any |
10 | +Depends: ubuntu-keyboard (= ${binary:Version}), |
11 | + ${misc:Depends}, |
12 | + ${shlibs:Depends}, |
13 | +Description: Ubuntu on-screen keyboard data files - Emoji |
14 | + Data files for the Ubuntu virtual keyboard - Emoji |
15 | + |
16 | Package: ubuntu-keyboard-english |
17 | Architecture: any |
18 | Depends: ubuntu-keyboard (= ${binary:Version}), |
19 | |
20 | === added file 'debian/ubuntu-keyboard-emoji.install' |
21 | --- debian/ubuntu-keyboard-emoji.install 1970-01-01 00:00:00 +0000 |
22 | +++ debian/ubuntu-keyboard-emoji.install 2014-12-08 15:48:42 +0000 |
23 | @@ -0,0 +1,1 @@ |
24 | +usr/share/maliit/plugins/com/ubuntu/lib/emoji/ |
25 | |
26 | === added directory 'plugins/emoji' |
27 | === added file 'plugins/emoji/emoji.pro' |
28 | --- plugins/emoji/emoji.pro 1970-01-01 00:00:00 +0000 |
29 | +++ plugins/emoji/emoji.pro 2014-12-08 15:48:42 +0000 |
30 | @@ -0,0 +1,9 @@ |
31 | +CONFIG += ordered |
32 | +TEMPLATE = subdirs |
33 | +SUBDIRS = \ |
34 | + src \ |
35 | + qml |
36 | + |
37 | +QMAKE_EXTRA_TARGETS += check |
38 | +check.target = check |
39 | +check.CONFIG = recursive |
40 | |
41 | === added directory 'plugins/emoji/qml' |
42 | === added file 'plugins/emoji/qml/Keyboard_emoji.qml' |
43 | --- plugins/emoji/qml/Keyboard_emoji.qml 1970-01-01 00:00:00 +0000 |
44 | +++ plugins/emoji/qml/Keyboard_emoji.qml 2014-12-08 15:48:42 +0000 |
45 | @@ -0,0 +1,188 @@ |
46 | +/* |
47 | + * Copyright 2013 Canonical Ltd. |
48 | + * |
49 | + * This program is free software; you can redistribute it and/or modify |
50 | + * it under the terms of the GNU Lesser General Public License as published by |
51 | + * the Free Software Foundation; version 3. |
52 | + * |
53 | + * This program is distributed in the hope that it will be useful, |
54 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
55 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
56 | + * GNU Lesser General Public License for more details. |
57 | + * |
58 | + * You should have received a copy of the GNU Lesser General Public License |
59 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
60 | + */ |
61 | + |
62 | +import QtQuick 2.0 |
63 | +import "../../keys" |
64 | +import "../../keys/key_constants.js" as UI |
65 | +import "emoji.js" as Emoji |
66 | + |
67 | +KeyPad { |
68 | + anchors.fill: parent |
69 | + |
70 | + content: c1 |
71 | + symbols: "languages/Keyboard_symbols.qml" |
72 | + |
73 | + QtObject { |
74 | + id: internal |
75 | + property int offset: 740 |
76 | + property var chars: calculateChars() |
77 | + |
78 | + function calculateChars() { |
79 | + var totalSkips = 0; |
80 | + var c = []; |
81 | + for (var block = 0; block < Emoji.start.length; block++) { |
82 | + for (var i = Emoji.start[block][1]; i < Emoji.end[block][1]; i++) { |
83 | + while (Emoji.skip[block].indexOf(i) != -1) { |
84 | + i++; |
85 | + } |
86 | + c.push(String.fromCharCode(Emoji.start[block][0], i)); |
87 | + } |
88 | + } |
89 | + return c; |
90 | + } |
91 | + } |
92 | + |
93 | + Column { |
94 | + id: c1 |
95 | + anchors.fill: parent |
96 | + spacing: 0 |
97 | + |
98 | + Row { |
99 | + anchors.horizontalCenter: parent.horizontalCenter |
100 | + spacing: 0 |
101 | + |
102 | + Repeater { |
103 | + model: 10 |
104 | + CharKey { |
105 | + label: internal.chars[internal.offset + index] |
106 | + shifted: label |
107 | + leftSide: index == 0 |
108 | + rightSide: index == 9 |
109 | + } |
110 | + } |
111 | + } |
112 | + |
113 | + Row { |
114 | + anchors.horizontalCenter: parent.horizontalCenter |
115 | + spacing: 0 |
116 | + |
117 | + ActionKey { |
118 | + iconNormal: "go-previous" |
119 | + iconShifted: "go-previous" |
120 | + iconCapsLock: "go-previous" |
121 | + overridePressArea: true |
122 | + onPressed: { |
123 | + if (internal.offset == 0) { |
124 | + // Wrap around |
125 | + internal.offset = internal.chars.length - 18 |
126 | + } else if (internal.offset - 18 < 0) { |
127 | + internal.offset = 0 |
128 | + } else { |
129 | + internal.offset -= 18; |
130 | + } |
131 | + } |
132 | + } |
133 | + |
134 | + Repeater { |
135 | + model: 8 |
136 | + CharKey { |
137 | + label: internal.chars[10 + internal.offset + index] |
138 | + shifted: label |
139 | + } |
140 | + } |
141 | + |
142 | + ActionKey { |
143 | + iconNormal: "go-next" |
144 | + iconShifted: "go-next" |
145 | + iconCapsLock: "go-next" |
146 | + overridePressArea: true |
147 | + onPressed: { |
148 | + if (internal.offset + 18 == internal.chars.length) { |
149 | + // Wrap around |
150 | + internal.offset = 0 |
151 | + } else if (internal.offset + 36 >= internal.chars.length) { |
152 | + internal.offset = internal.chars.length - 18 |
153 | + } else { |
154 | + internal.offset += 18 |
155 | + } |
156 | + } |
157 | + } |
158 | + } |
159 | + |
160 | + Row { |
161 | + anchors.horizontalCenter: parent.horizontalCenter |
162 | + spacing: 0 |
163 | + |
164 | + ActionKey { |
165 | + label: "😀" |
166 | + shifted: label |
167 | + overridePressArea: true |
168 | + onPressed: { |
169 | + internal.offset = 740 |
170 | + } |
171 | + } |
172 | + |
173 | + ActionKey { |
174 | + label: "🚀" |
175 | + shifted: label |
176 | + overridePressArea: true |
177 | + onPressed: { |
178 | + internal.offset = 865 |
179 | + } |
180 | + } |
181 | + |
182 | + ActionKey { |
183 | + label: "🕜" |
184 | + shifted: label |
185 | + overridePressArea: true |
186 | + onPressed: { |
187 | + internal.offset = 569 |
188 | + } |
189 | + } |
190 | + |
191 | + ActionKey { |
192 | + label: "🐀" |
193 | + shifted: label |
194 | + overridePressArea: true |
195 | + onPressed: { |
196 | + internal.offset = 237 |
197 | + } |
198 | + } |
199 | + |
200 | + ActionKey { |
201 | + label: "🏠" |
202 | + shifted: label |
203 | + overridePressArea: true |
204 | + onPressed: { |
205 | + internal.offset = 214 |
206 | + } |
207 | + } |
208 | + |
209 | + ActionKey { |
210 | + label: "🌍" |
211 | + shifted: label |
212 | + overridePressArea: true |
213 | + onPressed: { |
214 | + internal.offset = 14 |
215 | + } |
216 | + } |
217 | + |
218 | + BackspaceKey { padding: 0; width: enterKey.width } |
219 | + } |
220 | + |
221 | + Item { |
222 | + anchors.left: parent.left |
223 | + anchors.right: parent.right |
224 | + |
225 | + height: panel.keyHeight + units.gu(UI.row_margin); |
226 | + |
227 | + SymbolShiftKey { id: symShiftKey; anchors.left: parent.left; height: parent.height; } |
228 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; switchBack: true } |
229 | + SpaceKey { id: spaceKey; anchors.left: languageMenuButton.right; anchors.right: enterKey.left; noMagnifier: true; height: parent.height; } |
230 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
231 | + } |
232 | + } // column |
233 | +} |
234 | |
235 | === added file 'plugins/emoji/qml/Keyboard_emoji_email.qml' |
236 | --- plugins/emoji/qml/Keyboard_emoji_email.qml 1970-01-01 00:00:00 +0000 |
237 | +++ plugins/emoji/qml/Keyboard_emoji_email.qml 2014-12-08 15:48:42 +0000 |
238 | @@ -0,0 +1,93 @@ |
239 | +/* |
240 | + * Copyright 2013 Canonical Ltd. |
241 | + * |
242 | + * This program is free software; you can redistribute it and/or modify |
243 | + * it under the terms of the GNU Lesser General Public License as published by |
244 | + * the Free Software Foundation; version 3. |
245 | + * |
246 | + * This program is distributed in the hope that it will be useful, |
247 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
248 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
249 | + * GNU Lesser General Public License for more details. |
250 | + * |
251 | + * You should have received a copy of the GNU Lesser General Public License |
252 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
253 | + */ |
254 | + |
255 | +import QtQuick 2.0 |
256 | +import "../../keys" |
257 | +import "../../keys/key_constants.js" as UI |
258 | + |
259 | +KeyPad { |
260 | + anchors.fill: parent |
261 | + |
262 | + content: c1 |
263 | + symbols: "languages/Keyboard_symbols.qml" |
264 | + |
265 | + Column { |
266 | + id: c1 |
267 | + anchors.fill: parent |
268 | + spacing: 0 |
269 | + |
270 | + Row { |
271 | + anchors.horizontalCenter: parent.horizontalCenter; |
272 | + spacing: 0 |
273 | + |
274 | + CharKey { label: "q"; shifted: "Q"; extended: ["1"]; extendedShifted: ["1"]; leftSide: true; } |
275 | + CharKey { label: "w"; shifted: "W"; extended: ["2"]; extendedShifted: ["2"] } |
276 | + CharKey { label: "e"; shifted: "E"; extended: ["3", "è", "é", "ê", "ë", "€"]; extendedShifted: ["3", "È","É", "Ê", "Ë", "€"] } |
277 | + CharKey { label: "r"; shifted: "R"; extended: ["4"]; extendedShifted: ["4"] } |
278 | + CharKey { label: "t"; shifted: "T"; extended: ["5", "þ"]; extendedShifted: ["5", "Þ"] } |
279 | + CharKey { label: "y"; shifted: "Y"; extended: ["6", "ý", "¥"]; extendedShifted: ["6", "Ý", "¥"] } |
280 | + CharKey { label: "u"; shifted: "U"; extended: ["7", "û","ù","ú","ü"]; extendedShifted: ["7", "Û","Ù","Ú","Ü"] } |
281 | + CharKey { label: "i"; shifted: "I"; extended: ["8", "î","ï","ì","í"]; extendedShifted: ["8", "Î","Ï","Ì","Í"] } |
282 | + CharKey { label: "o"; shifted: "O"; extended: ["9", "ö","ô","ò","ó"]; extendedShifted: ["9", "Ö","Ô","Ò","Ó"] } |
283 | + CharKey { label: "p"; shifted: "P"; extended: ["0"]; extendedShifted: ["0"]; rightSide: true; } |
284 | + } |
285 | + |
286 | + Row { |
287 | + anchors.horizontalCenter: parent.horizontalCenter; |
288 | + spacing: 0 |
289 | + |
290 | + CharKey { label: "a"; shifted: "A"; extended: ["ä","à","â","á","ã","å"]; extendedShifted: ["Ä","À","Â","Á","Ã","Å"]; leftSide: true; } |
291 | + CharKey { label: "s"; shifted: "S"; extended: ["ß","$"]; extendedShifted: ["$"] } |
292 | + CharKey { label: "d"; shifted: "D"; extended: ["ð"]; extendedShifted: ["Ð"] } |
293 | + CharKey { label: "f"; shifted: "F"; } |
294 | + CharKey { label: "g"; shifted: "G"; } |
295 | + CharKey { label: "h"; shifted: "H"; } |
296 | + CharKey { label: "j"; shifted: "J"; } |
297 | + CharKey { label: "k"; shifted: "K"; } |
298 | + CharKey { label: "l"; shifted: "L"; rightSide: true; } |
299 | + } |
300 | + |
301 | + Row { |
302 | + anchors.horizontalCenter: parent.horizontalCenter; |
303 | + spacing: 0 |
304 | + |
305 | + ShiftKey {} |
306 | + CharKey { label: "z"; shifted: "Z"; } |
307 | + CharKey { label: "x"; shifted: "X"; } |
308 | + CharKey { label: "c"; shifted: "C"; extended: ["ç"]; extendedShifted: ["Ç"] } |
309 | + CharKey { label: "v"; shifted: "V"; } |
310 | + CharKey { label: "b"; shifted: "B"; } |
311 | + CharKey { label: "n"; shifted: "N"; extended: ["ñ"]; extendedShifted: ["Ñ"] } |
312 | + CharKey { label: "m"; shifted: "M"; } |
313 | + BackspaceKey {} |
314 | + } |
315 | + |
316 | + Item { |
317 | + anchors.left: parent.left |
318 | + anchors.right: parent.right |
319 | + |
320 | + height: panel.keyHeight + units.gu(UI.row_margin); |
321 | + |
322 | + SymbolShiftKey { id: symShiftKey; anchors.left: parent.left; height: parent.height; } |
323 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; } |
324 | + CharKey { id: atKey; label: "@"; shifted: "@"; anchors.left: languageMenuButton.right; height: parent.height; } |
325 | + SpaceKey { id: spaceKey; anchors.left: atKey.right; anchors.right: urlKey.left; noMagnifier: true; height: parent.height; } |
326 | + UrlKey { id: urlKey; label: ".com"; extended: [".co.uk", ".net", ".org", ".edu", ".gov", ".ac.uk"]; anchors.right: dotKey.left; height: parent.height; } |
327 | + CharKey { id: dotKey; label: "."; shifted: "."; extended: ["?", "!"]; extendedShifted: ["?", "!"]; anchors.right: enterKey.left; height: parent.height; } |
328 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
329 | + } |
330 | + } // column |
331 | +} |
332 | |
333 | === added file 'plugins/emoji/qml/Keyboard_emoji_url.qml' |
334 | --- plugins/emoji/qml/Keyboard_emoji_url.qml 1970-01-01 00:00:00 +0000 |
335 | +++ plugins/emoji/qml/Keyboard_emoji_url.qml 2014-12-08 15:48:42 +0000 |
336 | @@ -0,0 +1,92 @@ |
337 | +/* |
338 | + * Copyright 2013 Canonical Ltd. |
339 | + * |
340 | + * This program is free software; you can redistribute it and/or modify |
341 | + * it under the terms of the GNU Lesser General Public License as published by |
342 | + * the Free Software Foundation; version 3. |
343 | + * |
344 | + * This program is distributed in the hope that it will be useful, |
345 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
346 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
347 | + * GNU Lesser General Public License for more details. |
348 | + * |
349 | + * You should have received a copy of the GNU Lesser General Public License |
350 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
351 | + */ |
352 | + |
353 | +import QtQuick 2.0 |
354 | +import "../../keys" |
355 | +import "../../keys/key_constants.js" as UI |
356 | + |
357 | +KeyPad { |
358 | + anchors.fill: parent |
359 | + |
360 | + content: c1 |
361 | + symbols: "languages/Keyboard_symbols.qml" |
362 | + |
363 | + Column { |
364 | + id: c1 |
365 | + anchors.fill: parent |
366 | + spacing: 0 |
367 | + |
368 | + Row { |
369 | + anchors.horizontalCenter: parent.horizontalCenter; |
370 | + spacing: 0 |
371 | + |
372 | + CharKey { label: "q"; shifted: "Q"; extended: ["1"]; extendedShifted: ["1"]; leftSide: true; } |
373 | + CharKey { label: "w"; shifted: "W"; extended: ["2"]; extendedShifted: ["2"] } |
374 | + CharKey { label: "e"; shifted: "E"; extended: ["3", "è", "é", "ê", "ë", "€"]; extendedShifted: ["3", "È","É", "Ê", "Ë", "€"] } |
375 | + CharKey { label: "r"; shifted: "R"; extended: ["4"]; extendedShifted: ["4"] } |
376 | + CharKey { label: "t"; shifted: "T"; extended: ["5", "þ"]; extendedShifted: ["5", "Þ"] } |
377 | + CharKey { label: "y"; shifted: "Y"; extended: ["6", "ý", "¥"]; extendedShifted: ["6", "Ý", "¥"] } |
378 | + CharKey { label: "u"; shifted: "U"; extended: ["7", "û","ù","ú","ü"]; extendedShifted: ["7", "Û","Ù","Ú","Ü"] } |
379 | + CharKey { label: "i"; shifted: "I"; extended: ["8", "î","ï","ì","í"]; extendedShifted: ["8", "Î","Ï","Ì","Í"] } |
380 | + CharKey { label: "o"; shifted: "O"; extended: ["9", "ö","ô","ò","ó"]; extendedShifted: ["9", "Ö","Ô","Ò","Ó"] } |
381 | + CharKey { label: "p"; shifted: "P"; extended: ["0"]; extendedShifted: ["0"]; rightSide: true; } |
382 | + } |
383 | + |
384 | + Row { |
385 | + anchors.horizontalCenter: parent.horizontalCenter; |
386 | + spacing: 0 |
387 | + |
388 | + CharKey { label: "a"; shifted: "A"; extended: ["ä","à","â","á","ã","å"]; extendedShifted: ["Ä","À","Â","Á","Ã","Å"]; leftSide: true; } |
389 | + CharKey { label: "s"; shifted: "S"; extended: ["ß","$"]; extendedShifted: ["$"] } |
390 | + CharKey { label: "d"; shifted: "D"; extended: ["ð"]; extendedShifted: ["Ð"] } |
391 | + CharKey { label: "f"; shifted: "F"; } |
392 | + CharKey { label: "g"; shifted: "G"; } |
393 | + CharKey { label: "h"; shifted: "H"; } |
394 | + CharKey { label: "j"; shifted: "J"; } |
395 | + CharKey { label: "k"; shifted: "K"; } |
396 | + CharKey { label: "l"; shifted: "L"; rightSide: true; } |
397 | + } |
398 | + |
399 | + Row { |
400 | + anchors.horizontalCenter: parent.horizontalCenter; |
401 | + spacing: 0 |
402 | + |
403 | + ShiftKey {} |
404 | + CharKey { label: "z"; shifted: "Z"; } |
405 | + CharKey { label: "x"; shifted: "X"; } |
406 | + CharKey { label: "c"; shifted: "C"; extended: ["ç"]; extendedShifted: ["Ç"] } |
407 | + CharKey { label: "v"; shifted: "V"; } |
408 | + CharKey { label: "b"; shifted: "B"; } |
409 | + CharKey { label: "n"; shifted: "N"; extended: ["ñ"]; extendedShifted: ["Ñ"] } |
410 | + CharKey { label: "m"; shifted: "M"; } |
411 | + BackspaceKey {} |
412 | + } |
413 | + |
414 | + Item { |
415 | + anchors.left: parent.left |
416 | + anchors.right: parent.right |
417 | + |
418 | + height: panel.keyHeight + units.gu(UI.row_margin); |
419 | + |
420 | + SymbolShiftKey { id: symShiftKey; anchors.left: parent.left; height: parent.height; } |
421 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; } |
422 | + CharKey { id: slashKey; label: "/"; shifted: "/"; anchors.left: languageMenuButton.right; height: parent.height; } |
423 | + UrlKey { id: urlKey; label: ".com"; extended: [".co.uk", ".net", ".org", ".edu", ".gov", ".ac.uk"]; anchors.right: dotKey.left; height: parent.height; } |
424 | + CharKey { id: dotKey; label: "."; shifted: "."; extended: ["?", "!"]; extendedShifted: ["?", "!"]; anchors.right: enterKey.left; height: parent.height; } |
425 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
426 | + } |
427 | + } // column |
428 | +} |
429 | |
430 | === added file 'plugins/emoji/qml/Keyboard_emoji_url_search.qml' |
431 | --- plugins/emoji/qml/Keyboard_emoji_url_search.qml 1970-01-01 00:00:00 +0000 |
432 | +++ plugins/emoji/qml/Keyboard_emoji_url_search.qml 2014-12-08 15:48:42 +0000 |
433 | @@ -0,0 +1,94 @@ |
434 | +/* |
435 | + * Copyright 2013 Canonical Ltd. |
436 | + * |
437 | + * This program is free software; you can redistribute it and/or modify |
438 | + * it under the terms of the GNU Lesser General Public License as published by |
439 | + * the Free Software Foundation; version 3. |
440 | + * |
441 | + * This program is distributed in the hope that it will be useful, |
442 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
443 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
444 | + * GNU Lesser General Public License for more details. |
445 | + * |
446 | + * You should have received a copy of the GNU Lesser General Public License |
447 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
448 | + */ |
449 | + |
450 | +import QtQuick 2.0 |
451 | +import "../../keys" |
452 | +import "../../keys/key_constants.js" as UI |
453 | + |
454 | +KeyPad { |
455 | + anchors.fill: parent |
456 | + |
457 | + content: c1 |
458 | + symbols: "languages/Keyboard_symbols.qml" |
459 | + |
460 | + Column { |
461 | + id: c1 |
462 | + anchors.fill: parent |
463 | + |
464 | + spacing: 0 |
465 | + |
466 | + Row { |
467 | + anchors.horizontalCenter: parent.horizontalCenter; |
468 | + spacing: 0 |
469 | + |
470 | + CharKey { label: "q"; shifted: "Q"; extended: ["1"]; extendedShifted: ["1"]; leftSide: true; } |
471 | + CharKey { label: "w"; shifted: "W"; extended: ["2"]; extendedShifted: ["2"] } |
472 | + CharKey { label: "e"; shifted: "E"; extended: ["3", "è", "é", "ê", "ë", "€"]; extendedShifted: ["3", "È","É", "Ê", "Ë", "€"] } |
473 | + CharKey { label: "r"; shifted: "R"; extended: ["4"]; extendedShifted: ["4"] } |
474 | + CharKey { label: "t"; shifted: "T"; extended: ["5", "þ"]; extendedShifted: ["5", "Þ"] } |
475 | + CharKey { label: "y"; shifted: "Y"; extended: ["6", "ý", "¥"]; extendedShifted: ["6", "Ý", "¥"] } |
476 | + CharKey { label: "u"; shifted: "U"; extended: ["7", "û","ù","ú","ü"]; extendedShifted: ["7", "Û","Ù","Ú","Ü"] } |
477 | + CharKey { label: "i"; shifted: "I"; extended: ["8", "î","ï","ì","í"]; extendedShifted: ["8", "Î","Ï","Ì","Í"] } |
478 | + CharKey { label: "o"; shifted: "O"; extended: ["9", "ö","ô","ò","ó"]; extendedShifted: ["9", "Ö","Ô","Ò","Ó"] } |
479 | + CharKey { label: "p"; shifted: "P"; extended: ["0"]; extendedShifted: ["0"]; rightSide: true; } |
480 | + } |
481 | + |
482 | + Row { |
483 | + anchors.horizontalCenter: parent.horizontalCenter; |
484 | + spacing: 0 |
485 | + |
486 | + CharKey { label: "a"; shifted: "A"; extended: ["ä","à","â","á","ã","å"]; extendedShifted: ["Ä","À","Â","Á","Ã","Å"]; leftSide: true; } |
487 | + CharKey { label: "s"; shifted: "S"; extended: ["ß","$"]; extendedShifted: ["$"] } |
488 | + CharKey { label: "d"; shifted: "D"; extended: ["ð"]; extendedShifted: ["Ð"] } |
489 | + CharKey { label: "f"; shifted: "F"; } |
490 | + CharKey { label: "g"; shifted: "G"; } |
491 | + CharKey { label: "h"; shifted: "H"; } |
492 | + CharKey { label: "j"; shifted: "J"; } |
493 | + CharKey { label: "k"; shifted: "K"; } |
494 | + CharKey { label: "l"; shifted: "L"; rightSide: true; } |
495 | + } |
496 | + |
497 | + Row { |
498 | + anchors.horizontalCenter: parent.horizontalCenter; |
499 | + spacing: 0 |
500 | + |
501 | + ShiftKey {} |
502 | + CharKey { label: "z"; shifted: "Z"; } |
503 | + CharKey { label: "x"; shifted: "X"; } |
504 | + CharKey { label: "c"; shifted: "C"; extended: ["ç"]; extendedShifted: ["Ç"] } |
505 | + CharKey { label: "v"; shifted: "V"; } |
506 | + CharKey { label: "b"; shifted: "B"; } |
507 | + CharKey { label: "n"; shifted: "N"; extended: ["ñ"]; extendedShifted: ["Ñ"] } |
508 | + CharKey { label: "m"; shifted: "M"; } |
509 | + BackspaceKey {} |
510 | + } |
511 | + |
512 | + Item { |
513 | + anchors.left: parent.left |
514 | + anchors.right: parent.right |
515 | + |
516 | + height: panel.keyHeight + units.gu(UI.row_margin); |
517 | + |
518 | + SymbolShiftKey { id: symShiftKey; anchors.left: parent.left; height: parent.height; } |
519 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; } |
520 | + CharKey { id: slashKey; label: "/"; shifted: "/"; anchors.left: languageMenuButton.right; height: parent.height; } |
521 | + SpaceKey { id: spaceKey; anchors.left: slashKey.right; anchors.right: urlKey.left; noMagnifier: true; height: parent.height; } |
522 | + UrlKey { id: urlKey; label: ".com"; extended: [".co.uk", ".net", ".org", ".edu", ".gov", ".ac.uk"]; anchors.right: dotKey.left; height: parent.height; } |
523 | + CharKey { id: dotKey; label: "."; shifted: "."; extended: ["?", "!"]; extendedShifted: ["?", "!"]; anchors.right: enterKey.left; height: parent.height; } |
524 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
525 | + } |
526 | + } // column |
527 | +} |
528 | |
529 | === added file 'plugins/emoji/qml/emoji.js' |
530 | --- plugins/emoji/qml/emoji.js 1970-01-01 00:00:00 +0000 |
531 | +++ plugins/emoji/qml/emoji.js 2014-12-08 15:48:42 +0000 |
532 | @@ -0,0 +1,14 @@ |
533 | +// We have two blocks of utf-16 characters that can be used as emoji |
534 | +var start = [[55356, 57088], [55357, 56320]]; |
535 | +var end = [[55356, 57335], [55357, 57301]]; |
536 | + |
537 | +// Not supported by any of the installed fonts |
538 | +var skip = [[57133, 57134, 57135, 57214, 57215, 57295, 57296, 57297, 57298, 57299], |
539 | + [56575, 56651, 56652, 56653, 56654, 56655, 56675, 56826, 56884, 56899, |
540 | + 56900, 56698, 57040, 57041, 57042, 57043, 57044, 57045, 57046, 57047, |
541 | + 57048, 57049, 57050, 57051, 57052, 57053, 57054, 57055, 57069, 57070, |
542 | + 57071, 57076, 57077, 57078, 57079, 57080, 57081, 57082, 57083, 57084, |
543 | + 57085, 57086, 57087, 57204, 57205, 57206, 57207, 57208, 57209, 57210, |
544 | + 57211, 57212, 57213, 57214, 57215 |
545 | + ] |
546 | + ]; |
547 | |
548 | === added file 'plugins/emoji/qml/qml.pro' |
549 | --- plugins/emoji/qml/qml.pro 1970-01-01 00:00:00 +0000 |
550 | +++ plugins/emoji/qml/qml.pro 2014-12-08 15:48:42 +0000 |
551 | @@ -0,0 +1,20 @@ |
552 | +TOP_BUILDDIR = $$OUT_PWD/../../.. |
553 | +TOP_SRCDIR = $$PWD/../../.. |
554 | + |
555 | +include($${TOP_SRCDIR}/config.pri) |
556 | + |
557 | +TARGET = dummy |
558 | +TEMPLATE = lib |
559 | + |
560 | +lang_emoji.path = "$${UBUNTU_KEYBOARD_LIB_DIR}/emoji/" |
561 | +lang_emoji.files = *.qml *.js |
562 | + |
563 | +INSTALLS += lang_emoji |
564 | + |
565 | +# for QtCreator |
566 | +OTHER_FILES += \ |
567 | + Keyboard_emoji.qml \ |
568 | + Keyboard_emoji_email.qml \ |
569 | + Keyboard_emoji_url.qml \ |
570 | + Keyboard_emoji_url_search.qml |
571 | + |
572 | |
573 | === added directory 'plugins/emoji/src' |
574 | === added file 'plugins/emoji/src/emojilanguagefeatures.cpp' |
575 | --- plugins/emoji/src/emojilanguagefeatures.cpp 1970-01-01 00:00:00 +0000 |
576 | +++ plugins/emoji/src/emojilanguagefeatures.cpp 2014-12-08 15:48:42 +0000 |
577 | @@ -0,0 +1,83 @@ |
578 | +/* |
579 | + * Copyright 2014 Canonical Ltd. |
580 | + * |
581 | + * This program is free software; you can redistribute it and/or modify |
582 | + * it under the terms of the GNU Lesser General Public License as published by |
583 | + * the Free Software Foundation; version 3. |
584 | + * |
585 | + * This program is distributed in the hope that it will be useful, |
586 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
587 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
588 | + * GNU Lesser General Public License for more details. |
589 | + * |
590 | + * You should have received a copy of the GNU Lesser General Public License |
591 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
592 | + */ |
593 | + |
594 | +#include "emojilanguagefeatures.h" |
595 | + |
596 | +EmojiLanguageFeatures::EmojiLanguageFeatures(QObject *parent) : |
597 | + QObject(parent) |
598 | +{ |
599 | +} |
600 | + |
601 | +EmojiLanguageFeatures::~EmojiLanguageFeatures() |
602 | +{ |
603 | +} |
604 | + |
605 | +bool EmojiLanguageFeatures::alwaysShowSuggestions() const |
606 | +{ |
607 | + return false; |
608 | +} |
609 | + |
610 | +bool EmojiLanguageFeatures::autoCapsAvailable() const |
611 | +{ |
612 | + return false; |
613 | +} |
614 | + |
615 | +bool EmojiLanguageFeatures::activateAutoCaps(const QString &preedit) const |
616 | +{ |
617 | + Q_UNUSED(preedit) |
618 | + return false; |
619 | +} |
620 | + |
621 | +QString EmojiLanguageFeatures::appendixForReplacedPreedit(const QString &preedit) const |
622 | +{ |
623 | + Q_UNUSED(preedit) |
624 | + return QString(""); |
625 | +} |
626 | + |
627 | +bool EmojiLanguageFeatures::isSeparator(const QString &text) const |
628 | +{ |
629 | + static const QString separators = QString::fromUtf8("。、,!?:;.\r\n"); |
630 | + |
631 | + if (text.isEmpty()) { |
632 | + return false; |
633 | + } |
634 | + |
635 | + if (separators.contains(text.right(1))) { |
636 | + return true; |
637 | + } |
638 | + |
639 | + return false; |
640 | +} |
641 | + |
642 | +bool EmojiLanguageFeatures::isSymbol(const QString &text) const |
643 | +{ |
644 | + static const QString symbols = QString::fromUtf8("*#+=()@~/\\€£$¥₹%<>[]`^|_§{}¡¿«»\"“”„&0123456789"); |
645 | + |
646 | + if (text.isEmpty()) { |
647 | + return false; |
648 | + } |
649 | + |
650 | + if (symbols.contains(text.right(1))) { |
651 | + return true; |
652 | + } |
653 | + |
654 | + return false; |
655 | +} |
656 | + |
657 | +bool EmojiLanguageFeatures::ignoreSimilarity() const |
658 | +{ |
659 | + return true; |
660 | +} |
661 | |
662 | === added file 'plugins/emoji/src/emojilanguagefeatures.h' |
663 | --- plugins/emoji/src/emojilanguagefeatures.h 1970-01-01 00:00:00 +0000 |
664 | +++ plugins/emoji/src/emojilanguagefeatures.h 2014-12-08 15:48:42 +0000 |
665 | @@ -0,0 +1,39 @@ |
666 | +/* |
667 | + * Copyright 2014 Canonical Ltd. |
668 | + * |
669 | + * This program is free software; you can redistribute it and/or modify |
670 | + * it under the terms of the GNU Lesser General Public License as published by |
671 | + * the Free Software Foundation; version 3. |
672 | + * |
673 | + * This program is distributed in the hope that it will be useful, |
674 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
675 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
676 | + * GNU Lesser General Public License for more details. |
677 | + * |
678 | + * You should have received a copy of the GNU Lesser General Public License |
679 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
680 | + */ |
681 | + |
682 | +#ifndef EMOJILANGUAGEFEATURES_H |
683 | +#define EMOJILANGUAGEFEATURES_H |
684 | + |
685 | +#include "abstractlanguagefeatures.h" |
686 | +#include <QObject> |
687 | + |
688 | +class EmojiLanguageFeatures : public QObject, public AbstractLanguageFeatures |
689 | +{ |
690 | + Q_OBJECT |
691 | +public: |
692 | + explicit EmojiLanguageFeatures(QObject *parent = 0); |
693 | + virtual ~EmojiLanguageFeatures(); |
694 | + |
695 | + virtual bool alwaysShowSuggestions() const; |
696 | + virtual bool autoCapsAvailable() const; |
697 | + virtual bool activateAutoCaps(const QString &preedit) const; |
698 | + virtual QString appendixForReplacedPreedit(const QString &preedit) const; |
699 | + virtual bool isSeparator(const QString &text) const; |
700 | + virtual bool isSymbol(const QString &text) const; |
701 | + virtual bool ignoreSimilarity() const; |
702 | +}; |
703 | + |
704 | +#endif // EMOJILANGUAGEFEATURES_H |
705 | |
706 | === added file 'plugins/emoji/src/emojiplugin.cpp' |
707 | --- plugins/emoji/src/emojiplugin.cpp 1970-01-01 00:00:00 +0000 |
708 | +++ plugins/emoji/src/emojiplugin.cpp 2014-12-08 15:48:42 +0000 |
709 | @@ -0,0 +1,19 @@ |
710 | +#include "emojiplugin.h" |
711 | +#include "emojilanguagefeatures.h" |
712 | + |
713 | +#include <QDebug> |
714 | + |
715 | +EmojiPlugin::EmojiPlugin(QObject *parent) : |
716 | + AbstractLanguagePlugin(parent) |
717 | + , m_emojiLanguageFeatures(new EmojiLanguageFeatures) |
718 | +{ |
719 | +} |
720 | + |
721 | +EmojiPlugin::~EmojiPlugin() |
722 | +{ |
723 | +} |
724 | + |
725 | +AbstractLanguageFeatures* EmojiPlugin::languageFeature() |
726 | +{ |
727 | + return m_emojiLanguageFeatures; |
728 | +} |
729 | |
730 | === added file 'plugins/emoji/src/emojiplugin.h' |
731 | --- plugins/emoji/src/emojiplugin.h 1970-01-01 00:00:00 +0000 |
732 | +++ plugins/emoji/src/emojiplugin.h 2014-12-08 15:48:42 +0000 |
733 | @@ -0,0 +1,29 @@ |
734 | +#ifndef EMOJIPLUGIN_H |
735 | +#define EMOJIPLUGIN_H |
736 | + |
737 | +#include <QObject> |
738 | +#include <QStringList> |
739 | +#include "languageplugininterface.h" |
740 | +#include "abstractlanguageplugin.h" |
741 | + |
742 | +#include <iostream> |
743 | + |
744 | +class EmojiLanguageFeatures; |
745 | + |
746 | +class EmojiPlugin : public AbstractLanguagePlugin |
747 | +{ |
748 | + Q_OBJECT |
749 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EmojiPlugin" FILE "emojiplugin.json") |
750 | + Q_INTERFACES(LanguagePluginInterface) |
751 | + |
752 | +public: |
753 | + explicit EmojiPlugin(QObject *parent = 0); |
754 | + virtual ~EmojiPlugin(); |
755 | + |
756 | + virtual AbstractLanguageFeatures* languageFeature(); |
757 | + |
758 | +private: |
759 | + EmojiLanguageFeatures* m_emojiLanguageFeatures; |
760 | +}; |
761 | + |
762 | +#endif // EMOJIPLUGIN_H |
763 | |
764 | === added file 'plugins/emoji/src/emojiplugin.json' |
765 | --- plugins/emoji/src/emojiplugin.json 1970-01-01 00:00:00 +0000 |
766 | +++ plugins/emoji/src/emojiplugin.json 2014-12-08 15:48:42 +0000 |
767 | @@ -0,0 +1,7 @@ |
768 | +{ |
769 | + "IID": "org.qt-project.Qt.Examples.EmojiPlugin", |
770 | + "MetaData": { |
771 | + }, |
772 | + "className": "EmojiPlugin", |
773 | + "debug": true |
774 | +} |
775 | |
776 | === added file 'plugins/emoji/src/src.pro' |
777 | --- plugins/emoji/src/src.pro 1970-01-01 00:00:00 +0000 |
778 | +++ plugins/emoji/src/src.pro 2014-12-08 15:48:42 +0000 |
779 | @@ -0,0 +1,32 @@ |
780 | +TOP_BUILDDIR = $$OUT_PWD/../../.. |
781 | +TOP_SRCDIR = $$PWD/../../.. |
782 | + |
783 | +include($${TOP_SRCDIR}/config.pri) |
784 | + |
785 | +TEMPLATE = lib |
786 | +CONFIG += plugin |
787 | +QT += widgets |
788 | +INCLUDEPATH += \ |
789 | + $${TOP_SRCDIR}/src/ \ |
790 | + $${TOP_SRCDIR}/src/lib/logic |
791 | + |
792 | +HEADERS = \ |
793 | + emojiplugin.h \ |
794 | + emojilanguagefeatures.h \ |
795 | + $${TOP_SRCDIR}/src/lib/logic/abstractlanguageplugin.h |
796 | + |
797 | +SOURCES = \ |
798 | + emojiplugin.cpp \ |
799 | + emojilanguagefeatures.cpp \ |
800 | + $${TOP_SRCDIR}/src/lib/logic/abstractlanguageplugin.cpp |
801 | + |
802 | +TARGET = $$qtLibraryTarget(emojiplugin) |
803 | + |
804 | +EXAMPLE_FILES = emojiplugin.json |
805 | + |
806 | +# install |
807 | +target.path = $${UBUNTU_KEYBOARD_LIB_DIR}/emoji/ |
808 | +INSTALLS += target |
809 | + |
810 | +OTHER_FILES += \ |
811 | + emojiplugin.json |
812 | |
813 | === added directory 'plugins/emoji/tests' |
814 | === modified file 'plugins/pinyin/src/chineselanguagefeatures.cpp' |
815 | --- plugins/pinyin/src/chineselanguagefeatures.cpp 2014-11-25 13:28:55 +0000 |
816 | +++ plugins/pinyin/src/chineselanguagefeatures.cpp 2014-12-08 15:48:42 +0000 |
817 | @@ -88,3 +88,8 @@ |
818 | { |
819 | return true; |
820 | } |
821 | + |
822 | +bool ChineseLanguageFeatures::wordEngineAvailable() const |
823 | +{ |
824 | + return true; |
825 | +} |
826 | |
827 | === modified file 'plugins/pinyin/src/chineselanguagefeatures.h' |
828 | --- plugins/pinyin/src/chineselanguagefeatures.h 2014-10-21 18:54:25 +0000 |
829 | +++ plugins/pinyin/src/chineselanguagefeatures.h 2014-12-08 15:48:42 +0000 |
830 | @@ -34,6 +34,7 @@ |
831 | virtual bool isSeparator(const QString &text) const; |
832 | virtual bool isSymbol(const QString &text) const; |
833 | virtual bool ignoreSimilarity() const; |
834 | + virtual bool wordEngineAvailable() const; |
835 | }; |
836 | |
837 | #endif // CHINESELANGUAGEFEATURES_H |
838 | |
839 | === modified file 'plugins/plugins.pro' |
840 | --- plugins/plugins.pro 2014-11-12 15:19:36 +0000 |
841 | +++ plugins/plugins.pro 2014-12-08 15:48:42 +0000 |
842 | @@ -9,6 +9,7 @@ |
843 | cs \ |
844 | da \ |
845 | de \ |
846 | + emoji \ |
847 | en \ |
848 | es \ |
849 | fi \ |
850 | |
851 | === modified file 'plugins/westernsupport/westernlanguagefeatures.cpp' |
852 | --- plugins/westernsupport/westernlanguagefeatures.cpp 2014-10-21 18:54:25 +0000 |
853 | +++ plugins/westernsupport/westernlanguagefeatures.cpp 2014-12-08 15:48:42 +0000 |
854 | @@ -109,3 +109,8 @@ |
855 | { |
856 | return false; |
857 | } |
858 | + |
859 | +bool WesternLanguageFeatures::wordEngineAvailable() const |
860 | +{ |
861 | + return true; |
862 | +} |
863 | |
864 | === modified file 'plugins/westernsupport/westernlanguagefeatures.h' |
865 | --- plugins/westernsupport/westernlanguagefeatures.h 2014-10-21 18:54:25 +0000 |
866 | +++ plugins/westernsupport/westernlanguagefeatures.h 2014-12-08 15:48:42 +0000 |
867 | @@ -50,6 +50,7 @@ |
868 | virtual QString fullStopSequence() const { return QString("."); } |
869 | virtual bool isSymbol(const QString &text) const; |
870 | virtual bool ignoreSimilarity() const; |
871 | + virtual bool wordEngineAvailable() const; |
872 | }; |
873 | |
874 | #endif // MALIITKEYBOARD_LANGUAGEFEATURES_H |
875 | |
876 | === modified file 'qml/KeyboardContainer.qml' |
877 | --- qml/KeyboardContainer.qml 2014-11-20 17:06:32 +0000 |
878 | +++ qml/KeyboardContainer.qml 2014-12-08 15:48:42 +0000 |
879 | @@ -33,6 +33,7 @@ |
880 | |
881 | property string activeKeypadState: "NORMAL" |
882 | property alias popoverEnabled: extendedKeysSelector.enabled |
883 | + property string previousLanguage |
884 | |
885 | state: "CHARACTERS" |
886 | |
887 | @@ -125,6 +126,7 @@ |
888 | "cs", |
889 | "da", |
890 | "de", |
891 | + "emoji", |
892 | "en", |
893 | "es", |
894 | "fi", |
895 | @@ -147,7 +149,12 @@ |
896 | /// Returns the relative path to the keyboard QML file for a given language for free text |
897 | function freeTextLanguageKeyboard(language) |
898 | { |
899 | - language = language .slice(0,2).toLowerCase(); |
900 | + language = language.toLowerCase(); |
901 | + if (!languageIsSupported(language)) { |
902 | + // If we don't have a layout for this specific locale |
903 | + // check more generic locale |
904 | + language = language.slice(0,2); |
905 | + } |
906 | |
907 | if (!languageIsSupported(language)) { |
908 | console.log("Language '"+language+"' not supported - using 'en' instead"); |
909 | @@ -168,6 +175,8 @@ |
910 | return "lib/da/Keyboard_da.qml"; |
911 | if (language === "de") |
912 | return "lib/de/Keyboard_de.qml"; |
913 | + if (language === "emoji") |
914 | + return "lib/emoji/Keyboard_emoji.qml"; |
915 | if (language === "en") |
916 | return "lib/en/Keyboard_en.qml"; |
917 | if (language === "es") |
918 | @@ -214,7 +223,10 @@ |
919 | return "languages/Keyboard_telephone.qml"; |
920 | } |
921 | |
922 | - var locale = activeLanguage.slice(0,2).toLowerCase(); |
923 | + var locale = activeLanguage.toLowerCase(); |
924 | + if (!languageIsSupported(locale)) { |
925 | + locale = locale.slice(0,2); |
926 | + } |
927 | if (!languageIsSupported(locale)) { |
928 | console.log("System language '"+locale+"' can't be used in OSK - using 'en' instead") |
929 | locale = "en" |
930 | |
931 | === modified file 'qml/keys/LanguageKey.qml' |
932 | --- qml/keys/LanguageKey.qml 2014-08-22 15:45:03 +0000 |
933 | +++ qml/keys/LanguageKey.qml 2014-12-08 15:48:42 +0000 |
934 | @@ -17,6 +17,8 @@ |
935 | import QtQuick 2.0 |
936 | |
937 | ActionKey { |
938 | + property bool switchBack: false // Switch back to previous layout without showing menu |
939 | + |
940 | iconNormal: "language-chooser"; |
941 | iconShifted: "language-chooser"; |
942 | iconCapsLock: "language-chooser"; |
943 | @@ -34,6 +36,11 @@ |
944 | if (maliit_input_method.useHapticFeedback) |
945 | pressEffect.start(); |
946 | |
947 | - canvas.languageMenuShown = true |
948 | + if (switchBack && panel.previousLanguage) { |
949 | + maliit_input_method.activeLanguage = panel.previousLanguage |
950 | + } else { |
951 | + panel.previousLanguage = maliit_input_method.activeLanguage |
952 | + canvas.languageMenuShown = true |
953 | + } |
954 | } |
955 | } |
956 | |
957 | === modified file 'qml/keys/LanguageMenu.qml' |
958 | --- qml/keys/LanguageMenu.qml 2014-11-12 15:19:36 +0000 |
959 | +++ qml/keys/LanguageMenu.qml 2014-12-08 15:48:42 +0000 |
960 | @@ -78,6 +78,7 @@ |
961 | if (languageId == "cs") return i18n.tr("Czech"); |
962 | if (languageId == "da") return i18n.tr("Danish"); |
963 | if (languageId == "de") return i18n.tr("German"); |
964 | + if (languageId == "emoji") return i18n.tr("Emoji"); |
965 | if (languageId == "en") return i18n.tr("English"); |
966 | if (languageId == "es") return i18n.tr("Spanish"); |
967 | if (languageId == "fi") return i18n.tr("Finnish"); |
968 | |
969 | === modified file 'src/lib/logic/abstractlanguagefeatures.h' |
970 | --- src/lib/logic/abstractlanguagefeatures.h 2014-11-25 13:28:55 +0000 |
971 | +++ src/lib/logic/abstractlanguagefeatures.h 2014-12-08 15:48:42 +0000 |
972 | @@ -53,6 +53,7 @@ |
973 | // to the user's input. However for input methods such as pinyin this |
974 | // can be disabled by implementing this method to return true. |
975 | virtual bool ignoreSimilarity() const { return false; } |
976 | + virtual bool wordEngineAvailable() const { return false; } |
977 | |
978 | Maliit::TextContentType contentType() const { return m_contentType; } |
979 | void setContentType(Maliit::TextContentType contentType) { m_contentType = contentType; } |
980 | |
981 | === modified file 'src/lib/logic/wordengine.cpp' |
982 | --- src/lib/logic/wordengine.cpp 2014-11-19 15:39:41 +0000 |
983 | +++ src/lib/logic/wordengine.cpp 2014-12-08 15:48:42 +0000 |
984 | @@ -141,7 +141,8 @@ |
985 | { |
986 | Q_D(const WordEngine); |
987 | return (AbstractWordEngine::isEnabled() && |
988 | - (d->use_predictive_text || d->use_spell_checker)); |
989 | + (d->use_predictive_text || d->use_spell_checker) && |
990 | + d->languagePlugin->languageFeature()->wordEngineAvailable()); |
991 | } |
992 | |
993 | void WordEngine::appendToCandidates(WordCandidateList *candidates, |
994 | @@ -391,6 +392,8 @@ |
995 | d->loadPlugin("libdanishplugin.so", "da"); |
996 | else if (languageId == "de") |
997 | d->loadPlugin("libgermanplugin.so", "de"); |
998 | + else if (languageId == "emoji") |
999 | + d->loadPlugin("libemojiplugin.so", "emoji"); |
1000 | else if (languageId == "en") |
1001 | d->loadPlugin("libenglishplugin.so", "en"); |
1002 | else if (languageId == "es") |
1003 | @@ -426,6 +429,8 @@ |
1004 | |
1005 | d->languagePlugin->setLanguage(languageId); |
1006 | |
1007 | + Q_EMIT enabledChanged(isEnabled()); |
1008 | + |
1009 | connect((AbstractLanguagePlugin *) d->languagePlugin, SIGNAL(newSpellingSuggestions(QString, QStringList)), this, SLOT(newSpellingSuggestions(QString, QStringList))); |
1010 | connect((AbstractLanguagePlugin *) d->languagePlugin, SIGNAL(newPredictionSuggestions(QString, QStringList)), this, SLOT(newPredictionSuggestions(QString, QStringList))); |
1011 | Q_EMIT pluginChanged(); |
1012 | |
1013 | === modified file 'src/plugin/inputmethod.cpp' |
1014 | --- src/plugin/inputmethod.cpp 2014-11-26 15:02:05 +0000 |
1015 | +++ src/plugin/inputmethod.cpp 2014-12-08 15:48:42 +0000 |
1016 | @@ -276,7 +276,7 @@ |
1017 | void InputMethod::onEnabledLanguageSettingsChanged() |
1018 | { |
1019 | Q_D(InputMethod); |
1020 | - d->truncateEnabledLanguageLocales(d->m_settings.enabledLanguages()); |
1021 | + d->enabledLanguages = d->m_settings.enabledLanguages(); |
1022 | Q_EMIT enabledLanguagesChanged(d->enabledLanguages); |
1023 | } |
1024 | |
1025 | @@ -517,11 +517,6 @@ |
1026 | { |
1027 | Q_D(InputMethod); |
1028 | |
1029 | - if (newLanguage.length() != 2) { |
1030 | - qWarning() << Q_FUNC_INFO << "newLanguage is not valid:" << newLanguage; |
1031 | - return; |
1032 | - } |
1033 | - |
1034 | qDebug() << "in inputMethod.cpp setActiveLanguage() activeLanguage is:" << newLanguage; |
1035 | |
1036 | if (d->activeLanguage == newLanguage) |
1037 | |
1038 | === modified file 'src/plugin/inputmethod_p.h' |
1039 | --- src/plugin/inputmethod_p.h 2014-11-26 15:02:05 +0000 |
1040 | +++ src/plugin/inputmethod_p.h 2014-12-08 15:48:42 +0000 |
1041 | @@ -270,13 +270,4 @@ |
1042 | |
1043 | applicationApiWrapper->reportOSKInvisible(); |
1044 | } |
1045 | - |
1046 | - void truncateEnabledLanguageLocales(QStringList locales) |
1047 | - { |
1048 | - enabledLanguages.clear(); |
1049 | - foreach (QString locale, locales) { |
1050 | - locale.truncate(2); |
1051 | - enabledLanguages << locale; |
1052 | - } |
1053 | - } |
1054 | }; |
1055 | |
1056 | === modified file 'tests/autopilot/ubuntu_keyboard/emulators/keyboard.py' |
1057 | --- tests/autopilot/ubuntu_keyboard/emulators/keyboard.py 2014-11-21 00:04:17 +0000 |
1058 | +++ tests/autopilot/ubuntu_keyboard/emulators/keyboard.py 2014-12-08 15:48:42 +0000 |
1059 | @@ -297,6 +297,11 @@ |
1060 | self._current_keypad_name, |
1061 | "shift" |
1062 | ) |
1063 | + |
1064 | + if key_pos == None: |
1065 | + # Not all layouts have a shift key |
1066 | + return |
1067 | + |
1068 | self._tap_key(key_pos) |
1069 | self._keyboard_container.activeKeypadState.wait_for(state) |
1070 | self.active_keypad.opacity.wait_for(1.0) |
1071 | |
1072 | === modified file 'tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py' |
1073 | --- tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py 2014-12-02 19:24:45 +0000 |
1074 | +++ tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py 2014-12-08 15:48:42 +0000 |
1075 | @@ -83,7 +83,7 @@ |
1076 | def set_test_settings(self): |
1077 | gsettings = Gio.Settings.new("com.canonical.keyboard.maliit") |
1078 | gsettings.set_string("active-language", "en") |
1079 | - gsettings.set_strv("enabled-languages", ["en", "es", "de", "zh"]) |
1080 | + gsettings.set_strv("enabled-languages", ["en", "es", "de", "zh", "emoji"]) |
1081 | gsettings.set_boolean("auto-capitalization", True) |
1082 | gsettings.set_boolean("auto-completion", True) |
1083 | gsettings.set_boolean("predictive-text", True) |
1084 | @@ -603,3 +603,47 @@ |
1085 | Eventually(Equals(expected)) |
1086 | ) |
1087 | |
1088 | + |
1089 | +class UbuntuKeyboardEmoji(UbuntuKeyboardTests): |
1090 | + |
1091 | + def set_test_settings(self): |
1092 | + gsettings = Gio.Settings.new("com.canonical.keyboard.maliit") |
1093 | + gsettings.set_string("active-language", "emoji") |
1094 | + gsettings.set_boolean("auto-capitalization", True) |
1095 | + gsettings.set_boolean("auto-completion", True) |
1096 | + gsettings.set_boolean("predictive-text", True) |
1097 | + gsettings.set_boolean("spell-checking", True) |
1098 | + gsettings.set_boolean("double-space-full-stop", True) |
1099 | + |
1100 | + def test_emoji_input(self): |
1101 | + text_area = self.launch_test_input_area() |
1102 | + self.ensure_focus_on_input(text_area) |
1103 | + keyboard = Keyboard() |
1104 | + self.addCleanup(keyboard.dismiss) |
1105 | + |
1106 | + keyboard.type('😁😆😃😏') |
1107 | + |
1108 | + expected = "😁😆😃😏" |
1109 | + self.assertThat( |
1110 | + text_area.text, |
1111 | + Eventually(Equals(expected)) |
1112 | + ) |
1113 | + |
1114 | + def test_emoji_deletion(self): |
1115 | + """Emoji characters should be deleted completely, despite being made up |
1116 | + of multiple bytes. |
1117 | + |
1118 | + """ |
1119 | + text_area = self.launch_test_input_area() |
1120 | + self.ensure_focus_on_input(text_area) |
1121 | + keyboard = Keyboard() |
1122 | + self.addCleanup(keyboard.dismiss) |
1123 | + |
1124 | + keyboard.type('😁😆😃😏\b') |
1125 | + |
1126 | + expected = "😁😆😃" |
1127 | + self.assertThat( |
1128 | + text_area.text, |
1129 | + Eventually(Equals(expected)) |
1130 | + ) |
1131 | + |
Are there any related MPs required for this MP to build/function as expected? Please list.
* No
Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
* Yes
Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator?
* Yes
Did you successfully run all tests found in your component's Test Plan (https:/ /wiki.ubuntu. com/Process/ Merges/ TestPlan/ ubuntu- keyboard) on device or emulator?
* Yes
If you changed the UI, was the change specified/approved by design?
* Emoji layout not yet specified by design (waiting for colour emoji support before full design is specified)
If you changed UI labels, did you update the pot file?
* No change
If you changed the packaging (debian), did you add a core-dev as a reviewer to this MP?
* Yes