Merge lp:~michael-sheldon/ubuntu-keyboard/emoji into lp:ubuntu-keyboard

Proposed by Michael Sheldon
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
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

To post a comment you must log in.
Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

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

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

review: Needs Information
Revision history for this message
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.

review: Approve
Revision history for this message
Bill Filler (bfiller) wrote :

works great, nice job!

review: Approve
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 '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+

Subscribers

People subscribed via source and target branches