Merge lp:~mabkenar/ubuntu-keyboard/add-persian-layout into lp:ubuntu-keyboard
- add-persian-layout
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michael Sheldon |
Approved revision: | 526 |
Merged at revision: | 545 |
Proposed branch: | lp:~mabkenar/ubuntu-keyboard/add-persian-layout |
Merge into: | lp:ubuntu-keyboard |
Diff against target: |
690 lines (+589/-0) 14 files modified
debian/control (+10/-0) debian/ubuntu-keyboard-persian.install (+1/-0) plugins/fa/fa.pro (+9/-0) plugins/fa/qml/Keyboard_fa.qml (+93/-0) plugins/fa/qml/Keyboard_fa_email.qml (+93/-0) plugins/fa/qml/Keyboard_fa_url.qml (+92/-0) plugins/fa/qml/Keyboard_fa_url_search.qml (+94/-0) plugins/fa/qml/Keyboard_symbols_fa.qml (+96/-0) plugins/fa/qml/qml.pro (+21/-0) plugins/fa/src/persianplugin.h (+25/-0) plugins/fa/src/persianplugin.json (+7/-0) plugins/fa/src/src.pro (+46/-0) plugins/plugins.pro (+1/-0) qml/keys/languages.js (+1/-0) |
To merge this branch: | bzr merge lp:~mabkenar/ubuntu-keyboard/add-persian-layout |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ken VanDine | packaging | Approve | |
Michael Sheldon (community) | Approve | ||
Review via email: mp+314532@code.launchpad.net |
Commit message
Persian layout
Description of the change
This is a Persian layout (fa_IR) for ubuntu-keyboard. This layout is a bit more complicated than most existing layouts because it has a dedicated symbols keyboard that contains Persian-specific symbols, and is defined in 'plugins/
A dedicated symbols keyboard is essential for Persian since many of the punctuation and numeric characters are different from other Latin scripts. For example, Persian has different question mark, comma, decimal separator, and thousands separator (just to name a few) and all of these characters should be included in the symbols keyboard. Android (version 5 and later) also follows the same approach and have a special symbols keyboard for Persian. However, the proposed Persian layout here fixes some of the shortcomings of the Persian layout in Android [1].
Another specialty of this layout is the inclusion of invisible characters necessary for typesetting Persian text, ZWNJ (U+200C) and ZWJ (U+200D). These keys have a different label than what they actually insert into the text, thanks to the property 'valueToSubmit' of CharKey{} object.
For more information about the design process, please refer to my blog [2].
[1] http://
[2] https:/
Masoud Abkenar (mabkenar) wrote : | # |
Michael Sheldon (michael-sheldon) wrote : | # |
Just a quick message to say thanks for the branch and that it is still on my list to review, but is currently blocked by some issues with the keyboard and recent Mir versions, as soon as we have the fixes for those merged I'll get right on this :)
Michael Sheldon (michael-sheldon) wrote : | # |
Hi Masoud,
Overall this plugin looks great, just a couple of small things:
* On my desktop system there's a key that doesn't render correctly on the bottom row (see http://
* I noticed that key isn't present on the email layout (but is there on the URL layout), is that intentional?
Thanks!
Masoud Abkenar (mabkenar) wrote : | # |
Hi Michael,
Thanks for taking the time to review this plugin and thanks for the nice words :)
The key that is not rendered correctly on your (desktop?) machine is supposed to have "🢐⸽🢒" string on the label and insert U+200C (Zero-Width Non-Joiner) into the text.
A correct rendering on the device is shown here https:/
The rest of the letters on the keyboard are rendered using DejaVu font (it is NOT the Ubuntu font family). DejaVu is the default font for Persian scripts everywhere in the phone (and also in the desktop as of 16.10). Unless fontconfig/etc are at work here, I assume this "🢐⸽🢒" thingy is also rendered with DejaVu. Your screenshot is using FreeSerif for the Persian letters.
For your second point: This is intentional. AFAIK the ZWNJ character is forbidden in email addresses, but it is possible to have ZWNJ in URLs (not in the domain part, but in the page address). Since this character is invisible, I removed it to avoid almost-
Michael Sheldon (michael-sheldon) wrote : | # |
I've just retested this on a clean Zesty VM and that key is rendered without issues, so I think it's one of the extra fonts installed on my personal system incorrectly claiming it can render this key when it can't (and so not allowing it to fallback to something that can). As such I think this branch is good to go :)
Ken VanDine (ken-vandine) wrote : | # |
Packaging changes are fine
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2016-12-08 04:06:47 +0000 |
3 | +++ debian/control 2017-01-11 14:46:10 +0000 |
4 | @@ -107,6 +107,7 @@ |
5 | ubuntu-keyboard-dutch (>= ${source:Version}), |
6 | ubuntu-keyboard-emoji (>= ${source:Version}), |
7 | ubuntu-keyboard-english (>= ${source:Version}), |
8 | + ubuntu-keyboard-persian (>= ${source:Version}), |
9 | ubuntu-keyboard-finnish (>= ${source:Version}), |
10 | ubuntu-keyboard-french (>= ${source:Version}), |
11 | ubuntu-keyboard-german (>= ${source:Version}), |
12 | @@ -246,6 +247,15 @@ |
13 | Description: Ubuntu on-screen keyboard data files - Esperanto |
14 | Data files for the Ubuntu virtual keyboard - Esperanto |
15 | |
16 | +Package: ubuntu-keyboard-persian |
17 | +Architecture: any |
18 | +Depends: ubuntu-keyboard (= ${binary:Version}), |
19 | + myspell-fa, |
20 | + ${misc:Depends}, |
21 | + ${shlibs:Depends}, |
22 | +Description: Ubuntu on-screen keyboard data files - Persian |
23 | + Data files for the Ubuntu virtual keyboard - Persian |
24 | + |
25 | Package: ubuntu-keyboard-finnish |
26 | Architecture: any |
27 | Depends: ubuntu-keyboard (= ${binary:Version}), |
28 | |
29 | === added file 'debian/ubuntu-keyboard-persian.install' |
30 | --- debian/ubuntu-keyboard-persian.install 1970-01-01 00:00:00 +0000 |
31 | +++ debian/ubuntu-keyboard-persian.install 2017-01-11 14:46:10 +0000 |
32 | @@ -0,0 +1,1 @@ |
33 | +usr/share/maliit/plugins/com/ubuntu/lib/fa/ |
34 | |
35 | === added directory 'plugins/fa' |
36 | === added file 'plugins/fa/fa.pro' |
37 | --- plugins/fa/fa.pro 1970-01-01 00:00:00 +0000 |
38 | +++ plugins/fa/fa.pro 2017-01-11 14:46:10 +0000 |
39 | @@ -0,0 +1,9 @@ |
40 | +CONFIG += ordered |
41 | +TEMPLATE = subdirs |
42 | +SUBDIRS = \ |
43 | + src \ |
44 | + qml |
45 | + |
46 | +QMAKE_EXTRA_TARGETS += check |
47 | +check.target = check |
48 | +check.CONFIG = recursive |
49 | |
50 | === added directory 'plugins/fa/qml' |
51 | === added file 'plugins/fa/qml/Keyboard_fa.qml' |
52 | --- plugins/fa/qml/Keyboard_fa.qml 1970-01-01 00:00:00 +0000 |
53 | +++ plugins/fa/qml/Keyboard_fa.qml 2017-01-11 14:46:10 +0000 |
54 | @@ -0,0 +1,93 @@ |
55 | +/* |
56 | + * Copyright 2013 Canonical Ltd. |
57 | + * |
58 | + * This program is free software; you can redistribute it and/or modify |
59 | + * it under the terms of the GNU Lesser General Public License as published by |
60 | + * the Free Software Foundation; version 3. |
61 | + * |
62 | + * This program is distributed in the hope that it will be useful, |
63 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
64 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
65 | + * GNU Lesser General Public License for more details. |
66 | + * |
67 | + * You should have received a copy of the GNU Lesser General Public License |
68 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
69 | + */ |
70 | + |
71 | +import QtQuick 2.4 |
72 | +import keys 1.0 |
73 | + |
74 | +KeyPad { |
75 | + anchors.fill: parent |
76 | + |
77 | + content: c1 |
78 | + symbols: "lib/fa/Keyboard_symbols_fa.qml" |
79 | + |
80 | + Column { |
81 | + id: c1 |
82 | + anchors.fill: parent |
83 | + spacing: 0 |
84 | + |
85 | + Row { |
86 | + anchors.horizontalCenter: parent.horizontalCenter; |
87 | + spacing: 0 |
88 | + |
89 | + CharKey { label: "ض"; extended: ["۱","1"]; shifted: "ض"; extendedShifted: ["۱","1"]; leftSide: true; } |
90 | + CharKey { label: "ص"; extended: ["۲","2","٬"]; shifted: "ص"; extendedShifted: ["۲","2","٬"]; } |
91 | + CharKey { label: "ق"; extended: ["۳","3","٫"]; shifted: "ق"; extendedShifted: ["۳","3","٫"]; } |
92 | + CharKey { label: "ف"; extended: ["۴","4"]; shifted: "ف"; extendedShifted: ["۴","4"]; } |
93 | + CharKey { label: "غ"; extended: ["۵","5"]; shifted: "غ"; extendedShifted: ["۵","5"]; } |
94 | + CharKey { label: "ع"; extended: ["۶","6"]; shifted: "ع"; extendedShifted: ["۶","6"]; } |
95 | + CharKey { label: "ه"; extended: ["۷","7","ه","ة"]; shifted: "ه"; extendedShifted: ["۷","7","ه","ة"]; } |
96 | + CharKey { label: "خ"; extended: ["۸","8"]; shifted: "خ"; extendedShifted: ["۸","8"]; } |
97 | + CharKey { label: "ح"; extended: ["۹","9"]; shifted: "ح"; extendedShifted: ["۹","9"]; } |
98 | + CharKey { label: "ج"; extended: ["۰","0"]; shifted: "ج"; extendedShifted: ["۰","0"]; rightSide: true; } |
99 | + } |
100 | + |
101 | + Row { |
102 | + anchors.horizontalCenter: parent.horizontalCenter; |
103 | + spacing: 0 |
104 | + |
105 | + CharKey { label: "ش"; shifted: "ش"; leftSide: true; } |
106 | + CharKey { label: "س"; shifted: "س"; } |
107 | + CharKey { label: "ی"; extended: ["ٔ","ئ","ء","ي"]; shifted: "ی"; extendedShifted: ["ٔ","ئ","ء","ي"]; } |
108 | + CharKey { label: "ب"; shifted: "ب"; } |
109 | + CharKey { label: "ل"; shifted: "ل"; } |
110 | + CharKey { label: "ا"; extended: ["آ","أ","إ","ء"]; shifted: "ا"; extendedShifted: ["آ","أ","إ","ء"]; } |
111 | + CharKey { label: "ت"; extended: ["ث","ة"]; shifted: "ت"; extendedShifted: ["ث","ة"]; } |
112 | + CharKey { label: "ن"; shifted: "ن"; } |
113 | + CharKey { label: "م"; shifted: "م"; rightSide: true; } |
114 | + } |
115 | + |
116 | + Row { |
117 | + anchors.horizontalCenter: parent.horizontalCenter; |
118 | + spacing: 0 |
119 | + |
120 | + CharKey { label: "ط"; extended: ["ظ","ك"]; shifted: "ط"; extendedShifted: ["ظ","ك"]; } |
121 | + CharKey { label: "ز"; extended: ["ژ"]; shifted: "ز"; extendedShifted: ["ژ"]; } |
122 | + CharKey { label: "ر"; shifted: "ر"; } |
123 | + CharKey { label: "د"; extended: ["ذ"]; shifted: "د"; extendedShifted: ["ذ"]; } |
124 | + CharKey { label: "پ"; shifted: "پ"; } |
125 | + CharKey { label: "و"; extended: ["ؤ"]; shifted: "و"; extendedShifted: ["ؤ"]; } |
126 | + CharKey { label: "ک"; shifted: "ک"; } |
127 | + CharKey { label: "گ"; shifted: "گ"; } |
128 | + CharKey { label: "چ"; shifted: "چ"; } |
129 | + BackspaceKey { padding: 0 } |
130 | + } |
131 | + |
132 | + Item { |
133 | + anchors.left: parent.left |
134 | + anchors.right: parent.right |
135 | + |
136 | + height: panel.keyHeight + units.gu(UI.row_margin); |
137 | + |
138 | + SymbolShiftKey { id: symShiftKey; label: "۱۲۳؟"; shifted: "۱۲۳؟"; anchors.left: parent.left; height: parent.height; } |
139 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; } |
140 | + CharKey { id: commaKey; label: "،"; extended: ["«", "ْ", "ّ", ")", "(", "»", "ُ", "ِ", "َ", "ٌ", "ٍ", "ً"]; shifted: "،"; extendedShifted: ["«", "ْ", "ّ", ")", "(", "»", "ُ", "ِ", "َ", "ٌ", "ٍ", "ً"]; anchors.left: languageMenuButton.right; height: parent.height; } |
141 | + SpaceKey { id: spaceKey; anchors.left: commaKey.right; anchors.right: zwnj.left; noMagnifier: true; height: parent.height; } |
142 | + CharKey { id: zwnj; label: "🢐⸽🢒"; shifted: "🢐⸽🢒"; valueToSubmit: ""; anchors.right: dotKey.left; height: parent.height; } |
143 | + CharKey { id: dotKey; label: "."; extended: ["؟", "٪", ":", "؛", "!","/","ـ"]; shifted: "."; extendedShifted: ["؟", "٪", ":", "؛", "!","/","ـ"]; anchors.right: enterKey.left; height: parent.height; } |
144 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
145 | + } |
146 | + } // column |
147 | +} |
148 | |
149 | === added file 'plugins/fa/qml/Keyboard_fa_email.qml' |
150 | --- plugins/fa/qml/Keyboard_fa_email.qml 1970-01-01 00:00:00 +0000 |
151 | +++ plugins/fa/qml/Keyboard_fa_email.qml 2017-01-11 14:46:10 +0000 |
152 | @@ -0,0 +1,93 @@ |
153 | +/* |
154 | + * Copyright 2013 Canonical Ltd. |
155 | + * |
156 | + * This program is free software; you can redistribute it and/or modify |
157 | + * it under the terms of the GNU Lesser General Public License as published by |
158 | + * the Free Software Foundation; version 3. |
159 | + * |
160 | + * This program is distributed in the hope that it will be useful, |
161 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
162 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
163 | + * GNU Lesser General Public License for more details. |
164 | + * |
165 | + * You should have received a copy of the GNU Lesser General Public License |
166 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
167 | + */ |
168 | + |
169 | +import QtQuick 2.4 |
170 | +import keys 1.0 |
171 | + |
172 | +KeyPad { |
173 | + anchors.fill: parent |
174 | + |
175 | + content: c1 |
176 | + symbols: "lib/fa/Keyboard_symbols_fa.qml" |
177 | + |
178 | + Column { |
179 | + id: c1 |
180 | + anchors.fill: parent |
181 | + spacing: 0 |
182 | + |
183 | + Row { |
184 | + anchors.horizontalCenter: parent.horizontalCenter; |
185 | + spacing: 0 |
186 | + |
187 | + CharKey { label: "ض"; extended: ["۱","1"]; shifted: "ض"; extendedShifted: ["۱","1"]; leftSide: true; } |
188 | + CharKey { label: "ص"; extended: ["۲","2","٬"]; shifted: "ص"; extendedShifted: ["۲","2","٬"]; } |
189 | + CharKey { label: "ق"; extended: ["۳","3","٫"]; shifted: "ق"; extendedShifted: ["۳","3","٫"]; } |
190 | + CharKey { label: "ف"; extended: ["۴","4"]; shifted: "ف"; extendedShifted: ["۴","4"]; } |
191 | + CharKey { label: "غ"; extended: ["۵","5"]; shifted: "غ"; extendedShifted: ["۵","5"]; } |
192 | + CharKey { label: "ع"; extended: ["۶","6"]; shifted: "ع"; extendedShifted: ["۶","6"]; } |
193 | + CharKey { label: "ه"; extended: ["۷","7","ه","ة"]; shifted: "ه"; extendedShifted: ["۷","7","ه","ة"]; } |
194 | + CharKey { label: "خ"; extended: ["۸","8"]; shifted: "خ"; extendedShifted: ["۸","8"]; } |
195 | + CharKey { label: "ح"; extended: ["۹","9"]; shifted: "ح"; extendedShifted: ["۹","9"]; } |
196 | + CharKey { label: "ج"; extended: ["۰","0"]; shifted: "ج"; extendedShifted: ["۰","0"]; rightSide: true; } |
197 | + } |
198 | + |
199 | + Row { |
200 | + anchors.horizontalCenter: parent.horizontalCenter; |
201 | + spacing: 0 |
202 | + |
203 | + CharKey { label: "ش"; shifted: "ش"; leftSide: true; } |
204 | + CharKey { label: "س"; shifted: "س"; } |
205 | + CharKey { label: "ی"; extended: ["ٔ","ئ","ء","ي"]; shifted: "ی"; extendedShifted: ["ٔ","ئ","ء","ي"]; } |
206 | + CharKey { label: "ب"; shifted: "ب"; } |
207 | + CharKey { label: "ل"; shifted: "ل"; } |
208 | + CharKey { label: "ا"; extended: ["آ","أ","إ","ء"]; shifted: "ا"; extendedShifted: ["آ","أ","إ","ء"]; } |
209 | + CharKey { label: "ت"; extended: ["ث","ة"]; shifted: "ت"; extendedShifted: ["ث","ة"]; } |
210 | + CharKey { label: "ن"; shifted: "ن"; } |
211 | + CharKey { label: "م"; shifted: "م"; rightSide: true; } |
212 | + } |
213 | + |
214 | + Row { |
215 | + anchors.horizontalCenter: parent.horizontalCenter; |
216 | + spacing: 0 |
217 | + |
218 | + CharKey { label: "ط"; extended: ["ظ","ك"]; shifted: "ط"; extendedShifted: ["ظ","ك"]; } |
219 | + CharKey { label: "ز"; extended: ["ژ"]; shifted: "ز"; extendedShifted: ["ژ"]; } |
220 | + CharKey { label: "ر"; shifted: "ر"; } |
221 | + CharKey { label: "د"; extended: ["ذ"]; shifted: "د"; extendedShifted: ["ذ"]; } |
222 | + CharKey { label: "پ"; shifted: "پ"; } |
223 | + CharKey { label: "و"; extended: ["ؤ"]; shifted: "و"; extendedShifted: ["ؤ"]; } |
224 | + CharKey { label: "ک"; shifted: "ک"; } |
225 | + CharKey { label: "گ"; shifted: "گ"; } |
226 | + CharKey { label: "چ"; shifted: "چ"; } |
227 | + BackspaceKey { padding: 0 } |
228 | + } |
229 | + |
230 | + Item { |
231 | + anchors.left: parent.left |
232 | + anchors.right: parent.right |
233 | + |
234 | + height: panel.keyHeight + units.gu(UI.row_margin); |
235 | + |
236 | + SymbolShiftKey { id: symShiftKey; label: "۱۲۳؟"; shifted: "۱۲۳؟"; anchors.left: parent.left; height: parent.height; } |
237 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; } |
238 | + CharKey { id: atKey; label: "@"; shifted: "@"; anchors.left: languageMenuButton.right; height: parent.height; } |
239 | + SpaceKey { id: spaceKey; anchors.left: atKey.right; anchors.right: urlKey.left; noMagnifier: true; height: parent.height; } |
240 | + UrlKey { id: urlKey; label: ".com"; extended: [".ir", ".net", ".org", ".edu", ".gov.ir", ".ac.ir"]; anchors.right: dotKey.left; height: parent.height; } |
241 | + CharKey { id: dotKey; label: "."; extended: ["؟", "٪", ":", "؛", "!","/","ـ"]; shifted: "."; extendedShifted: ["؟", "٪", ":", "؛", "!","/","ـ"]; anchors.right: enterKey.left; height: parent.height; } |
242 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
243 | + } |
244 | + } // column |
245 | +} |
246 | |
247 | === added file 'plugins/fa/qml/Keyboard_fa_url.qml' |
248 | --- plugins/fa/qml/Keyboard_fa_url.qml 1970-01-01 00:00:00 +0000 |
249 | +++ plugins/fa/qml/Keyboard_fa_url.qml 2017-01-11 14:46:10 +0000 |
250 | @@ -0,0 +1,92 @@ |
251 | +/* |
252 | + * Copyright 2013 Canonical Ltd. |
253 | + * |
254 | + * This program is free software; you can redistribute it and/or modify |
255 | + * it under the terms of the GNU Lesser General Public License as published by |
256 | + * the Free Software Foundation; version 3. |
257 | + * |
258 | + * This program is distributed in the hope that it will be useful, |
259 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
260 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
261 | + * GNU Lesser General Public License for more details. |
262 | + * |
263 | + * You should have received a copy of the GNU Lesser General Public License |
264 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
265 | + */ |
266 | + |
267 | +import QtQuick 2.4 |
268 | +import keys 1.0 |
269 | + |
270 | +KeyPad { |
271 | + anchors.fill: parent |
272 | + |
273 | + content: c1 |
274 | + symbols: "lib/fa/Keyboard_symbols_fa.qml" |
275 | + |
276 | + Column { |
277 | + id: c1 |
278 | + anchors.fill: parent |
279 | + spacing: 0 |
280 | + |
281 | + Row { |
282 | + anchors.horizontalCenter: parent.horizontalCenter; |
283 | + spacing: 0 |
284 | + |
285 | + CharKey { label: "ض"; extended: ["۱","1"]; shifted: "ض"; extendedShifted: ["۱","1"]; leftSide: true; } |
286 | + CharKey { label: "ص"; extended: ["۲","2","٬"]; shifted: "ص"; extendedShifted: ["۲","2","٬"]; } |
287 | + CharKey { label: "ق"; extended: ["۳","3","٫"]; shifted: "ق"; extendedShifted: ["۳","3","٫"]; } |
288 | + CharKey { label: "ف"; extended: ["۴","4"]; shifted: "ف"; extendedShifted: ["۴","4"]; } |
289 | + CharKey { label: "غ"; extended: ["۵","5"]; shifted: "غ"; extendedShifted: ["۵","5"]; } |
290 | + CharKey { label: "ع"; extended: ["۶","6"]; shifted: "ع"; extendedShifted: ["۶","6"]; } |
291 | + CharKey { label: "ه"; extended: ["۷","7","ه","ة"]; shifted: "ه"; extendedShifted: ["۷","7","ه","ة"]; } |
292 | + CharKey { label: "خ"; extended: ["۸","8"]; shifted: "خ"; extendedShifted: ["۸","8"]; } |
293 | + CharKey { label: "ح"; extended: ["۹","9"]; shifted: "ح"; extendedShifted: ["۹","9"]; } |
294 | + CharKey { label: "ج"; extended: ["۰","0"]; shifted: "ج"; extendedShifted: ["۰","0"]; rightSide: true; } |
295 | + } |
296 | + |
297 | + Row { |
298 | + anchors.horizontalCenter: parent.horizontalCenter; |
299 | + spacing: 0 |
300 | + |
301 | + CharKey { label: "ش"; shifted: "ش"; leftSide: true; } |
302 | + CharKey { label: "س"; shifted: "س"; } |
303 | + CharKey { label: "ی"; extended: ["ٔ","ئ","ء","ي"]; shifted: "ی"; extendedShifted: ["ٔ","ئ","ء","ي"]; } |
304 | + CharKey { label: "ب"; shifted: "ب"; } |
305 | + CharKey { label: "ل"; shifted: "ل"; } |
306 | + CharKey { label: "ا"; extended: ["آ","أ","إ","ء"]; shifted: "ا"; extendedShifted: ["آ","أ","إ","ء"]; } |
307 | + CharKey { label: "ت"; extended: ["ث","ة"]; shifted: "ت"; extendedShifted: ["ث","ة"]; } |
308 | + CharKey { label: "ن"; shifted: "ن"; } |
309 | + CharKey { label: "م"; shifted: "م"; rightSide: true; } |
310 | + } |
311 | + |
312 | + Row { |
313 | + anchors.horizontalCenter: parent.horizontalCenter; |
314 | + spacing: 0 |
315 | + |
316 | + CharKey { label: "ط"; extended: ["ظ","ك"]; shifted: "ط"; extendedShifted: ["ظ","ك"]; } |
317 | + CharKey { label: "ز"; extended: ["ژ"]; shifted: "ز"; extendedShifted: ["ژ"]; } |
318 | + CharKey { label: "ر"; shifted: "ر"; } |
319 | + CharKey { label: "د"; extended: ["ذ"]; shifted: "د"; extendedShifted: ["ذ"]; } |
320 | + CharKey { label: "پ"; shifted: "پ"; } |
321 | + CharKey { label: "و"; extended: ["ؤ"]; shifted: "و"; extendedShifted: ["ؤ"]; } |
322 | + CharKey { label: "ک"; shifted: "ک"; } |
323 | + CharKey { label: "گ"; shifted: "گ"; } |
324 | + CharKey { label: "چ"; shifted: "چ"; } |
325 | + BackspaceKey { padding: 0 } |
326 | + } |
327 | + |
328 | + Item { |
329 | + anchors.left: parent.left |
330 | + anchors.right: parent.right |
331 | + |
332 | + height: panel.keyHeight + units.gu(UI.row_margin); |
333 | + |
334 | + SymbolShiftKey { id: symShiftKey; label: "۱۲۳؟"; shifted: "۱۲۳؟"; anchors.left: parent.left; height: parent.height; } |
335 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; } |
336 | + CharKey { id: slashKey; label: "/"; shifted: "/"; anchors.left: languageMenuButton.right; height: parent.height; } |
337 | + UrlKey { id: urlKey; label: ".com"; extended: [".ir", ".net", ".org", ".edu", ".gov.ir", ".ac.ir"]; anchors.right: dotKey.left; height: parent.height; } |
338 | + CharKey { id: dotKey; label: "."; extended: ["؟", "٪", ":", "؛", "!","/","ـ"]; shifted: "."; extendedShifted: ["؟", "٪", ":", "؛", "!","/","ـ"]; anchors.right: enterKey.left; height: parent.height; } |
339 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
340 | + } |
341 | + } // column |
342 | +} |
343 | |
344 | === added file 'plugins/fa/qml/Keyboard_fa_url_search.qml' |
345 | --- plugins/fa/qml/Keyboard_fa_url_search.qml 1970-01-01 00:00:00 +0000 |
346 | +++ plugins/fa/qml/Keyboard_fa_url_search.qml 2017-01-11 14:46:10 +0000 |
347 | @@ -0,0 +1,94 @@ |
348 | +/* |
349 | + * Copyright 2013 Canonical Ltd. |
350 | + * |
351 | + * This program is free software; you can redistribute it and/or modify |
352 | + * it under the terms of the GNU Lesser General Public License as published by |
353 | + * the Free Software Foundation; version 3. |
354 | + * |
355 | + * This program is distributed in the hope that it will be useful, |
356 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
357 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
358 | + * GNU Lesser General Public License for more details. |
359 | + * |
360 | + * You should have received a copy of the GNU Lesser General Public License |
361 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
362 | + */ |
363 | + |
364 | +import QtQuick 2.4 |
365 | +import keys 1.0 |
366 | + |
367 | +KeyPad { |
368 | + anchors.fill: parent |
369 | + |
370 | + content: c1 |
371 | + symbols: "lib/fa/Keyboard_symbols_fa.qml" |
372 | + |
373 | + Column { |
374 | + id: c1 |
375 | + anchors.fill: parent |
376 | + spacing: 0 |
377 | + |
378 | + Row { |
379 | + anchors.horizontalCenter: parent.horizontalCenter; |
380 | + spacing: 0 |
381 | + |
382 | + CharKey { label: "ض"; extended: ["۱","1"]; shifted: "ض"; extendedShifted: ["۱","1"]; leftSide: true; } |
383 | + CharKey { label: "ص"; extended: ["۲","2","٬"]; shifted: "ص"; extendedShifted: ["۲","2","٬"]; } |
384 | + CharKey { label: "ق"; extended: ["۳","3","٫"]; shifted: "ق"; extendedShifted: ["۳","3","٫"]; } |
385 | + CharKey { label: "ف"; extended: ["۴","4"]; shifted: "ف"; extendedShifted: ["۴","4"]; } |
386 | + CharKey { label: "غ"; extended: ["۵","5"]; shifted: "غ"; extendedShifted: ["۵","5"]; } |
387 | + CharKey { label: "ع"; extended: ["۶","6"]; shifted: "ع"; extendedShifted: ["۶","6"]; } |
388 | + CharKey { label: "ه"; extended: ["۷","7","ه","ة"]; shifted: "ه"; extendedShifted: ["۷","7","ه","ة"]; } |
389 | + CharKey { label: "خ"; extended: ["۸","8"]; shifted: "خ"; extendedShifted: ["۸","8"]; } |
390 | + CharKey { label: "ح"; extended: ["۹","9"]; shifted: "ح"; extendedShifted: ["۹","9"]; } |
391 | + CharKey { label: "ج"; extended: ["۰","0"]; shifted: "ج"; extendedShifted: ["۰","0"]; rightSide: true; } |
392 | + } |
393 | + |
394 | + Row { |
395 | + anchors.horizontalCenter: parent.horizontalCenter; |
396 | + spacing: 0 |
397 | + |
398 | + CharKey { label: "ش"; shifted: "ش"; leftSide: true; } |
399 | + CharKey { label: "س"; shifted: "س"; } |
400 | + CharKey { label: "ی"; extended: ["ٔ","ئ","ء","ي"]; shifted: "ی"; extendedShifted: ["ٔ","ئ","ء","ي"]; } |
401 | + CharKey { label: "ب"; shifted: "ب"; } |
402 | + CharKey { label: "ل"; shifted: "ل"; } |
403 | + CharKey { label: "ا"; extended: ["آ","أ","إ","ء"]; shifted: "ا"; extendedShifted: ["آ","أ","إ","ء"]; } |
404 | + CharKey { label: "ت"; extended: ["ث","ة"]; shifted: "ت"; extendedShifted: ["ث","ة"]; } |
405 | + CharKey { label: "ن"; shifted: "ن"; } |
406 | + CharKey { label: "م"; shifted: "م"; rightSide: true; } |
407 | + } |
408 | + |
409 | + Row { |
410 | + anchors.horizontalCenter: parent.horizontalCenter; |
411 | + spacing: 0 |
412 | + |
413 | + CharKey { label: "ط"; extended: ["ظ","ك"]; shifted: "ط"; extendedShifted: ["ظ","ك"]; } |
414 | + CharKey { label: "ز"; extended: ["ژ"]; shifted: "ز"; extendedShifted: ["ژ"]; } |
415 | + CharKey { label: "ر"; shifted: "ر"; } |
416 | + CharKey { label: "د"; extended: ["ذ"]; shifted: "د"; extendedShifted: ["ذ"]; } |
417 | + CharKey { label: "پ"; shifted: "پ"; } |
418 | + CharKey { label: "و"; extended: ["ؤ"]; shifted: "و"; extendedShifted: ["ؤ"]; } |
419 | + CharKey { label: "ک"; shifted: "ک"; } |
420 | + CharKey { label: "گ"; shifted: "گ"; } |
421 | + CharKey { label: "چ"; shifted: "چ"; } |
422 | + BackspaceKey { padding: 0 } |
423 | + } |
424 | + |
425 | + Item { |
426 | + anchors.left: parent.left |
427 | + anchors.right: parent.right |
428 | + |
429 | + height: panel.keyHeight + units.gu(UI.row_margin); |
430 | + |
431 | + SymbolShiftKey { id: symShiftKey; label: "۱۲۳؟"; shifted: "۱۲۳؟"; anchors.left: parent.left; height: parent.height; } |
432 | + LanguageKey { id: languageMenuButton; anchors.left: symShiftKey.right; height: parent.height; } |
433 | + CharKey { id: slashKey; label: "/"; shifted: "/"; anchors.left: languageMenuButton.right; height: parent.height; } |
434 | + SpaceKey { id: spaceKey; anchors.left: slashKey.right; anchors.right: zwnj.left; noMagnifier: true; height: parent.height; } |
435 | + CharKey { id: zwnj; label: "🢐⸽🢒"; shifted: "🢐⸽🢒"; valueToSubmit: ""; anchors.right: urlKey.left; height: parent.height; } |
436 | + UrlKey { id: urlKey; label: ".com"; extended: [".ir", ".net", ".org", ".edu", ".gov.ir", ".ac.ir"]; anchors.right: dotKey.left; height: parent.height; } |
437 | + CharKey { id: dotKey; label: "."; extended: ["؟", "٪", ":", "؛", "!","/","ـ"]; shifted: "."; extendedShifted: ["؟", "٪", ":", "؛", "!","/","ـ"]; anchors.right: enterKey.left; height: parent.height; } |
438 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
439 | + } |
440 | + } // column |
441 | +} |
442 | |
443 | === added file 'plugins/fa/qml/Keyboard_symbols_fa.qml' |
444 | --- plugins/fa/qml/Keyboard_symbols_fa.qml 1970-01-01 00:00:00 +0000 |
445 | +++ plugins/fa/qml/Keyboard_symbols_fa.qml 2017-01-11 14:46:10 +0000 |
446 | @@ -0,0 +1,96 @@ |
447 | +/* |
448 | + * Copyright 2013 Canonical Ltd. |
449 | + * |
450 | + * This program is free software; you can redistribute it and/or modify |
451 | + * it under the terms of the GNU Lesser General Public License as published by |
452 | + * the Free Software Foundation; version 3. |
453 | + * |
454 | + * This program is distributed in the hope that it will be useful, |
455 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
456 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
457 | + * GNU Lesser General Public License for more details. |
458 | + * |
459 | + * You should have received a copy of the GNU Lesser General Public License |
460 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
461 | + */ |
462 | + |
463 | +import QtQuick 2.4 |
464 | +import "../../keys" |
465 | +import "../../keys/key_constants.js" as UI |
466 | + |
467 | +KeyPad { |
468 | + anchors.fill: parent |
469 | + |
470 | + content: c1 |
471 | + |
472 | + Column { |
473 | + id: c1 |
474 | + anchors.fill: parent |
475 | + anchors.margins: 0; |
476 | + |
477 | + spacing: 0 |
478 | + |
479 | + Row { |
480 | + anchors.horizontalCenter: parent.horizontalCenter; |
481 | + anchors.margins: 50; |
482 | + spacing: 0 |
483 | + |
484 | + CharKey { label: "۱"; extended: ["1"]; shifted: "~"; leftSide: true; } |
485 | + CharKey { label: "۲"; extended: ["2"]; shifted: "`"; } |
486 | + CharKey { label: "۳"; extended: ["3"]; shifted: "|"; } |
487 | + CharKey { label: "۴"; extended: ["4"]; shifted: "•"; } |
488 | + CharKey { label: "۵"; extended: ["5"]; shifted: "√"; } |
489 | + CharKey { label: "۶"; extended: ["6"]; shifted: "π"; } |
490 | + CharKey { label: "۷"; extended: ["7"]; shifted: "÷"; } |
491 | + CharKey { label: "۸"; extended: ["8"]; shifted: "×"; } |
492 | + CharKey { label: "۹"; extended: ["9"]; shifted: "¶"; } |
493 | + CharKey { label: "۰"; extended: ["0","∅","ⁿ"]; shifted: "∆"; rightSide: true; } |
494 | + } |
495 | + |
496 | + Row { |
497 | + anchors.horizontalCenter: parent.horizontalCenter; |
498 | + anchors.margins: 50; |
499 | + spacing: 0 |
500 | + |
501 | + CharKey { label: "٫"; shifted: "@"; leftSide: true; } |
502 | + CharKey { label: "٬"; shifted: "#"; } |
503 | + CharKey { label: "﷼"; shifted: ">"; extended: ["$","€","¢","₱","£","¥"]; } |
504 | + CharKey { label: "٪"; shifted: "<"; extended: ["%", "‰"]; } |
505 | + CharKey { label: "*"; extended: ["٭", "★"]; shifted: "^"; } |
506 | + CharKey { label: "-"; shifted: "°"; extended: ["_", "ـ", "—", "–", "·"]; } |
507 | + CharKey { label: "+"; shifted: "="; extended: ["±"]; } |
508 | + CharKey { label: ")"; shifted: "}"; extended: ["}", "﴾", ">", "]"]; switchBackFromSymbols: true; } |
509 | + CharKey { label: "("; shifted: "{"; extended: ["{", "﴿", "<", "["]; switchBackFromSymbols: true; rightSide: true; } |
510 | + } |
511 | + |
512 | + Row { |
513 | + anchors.horizontalCenter: parent.horizontalCenter; |
514 | + anchors.margins: 50; |
515 | + spacing: 0 |
516 | + |
517 | + OneTwoKey { label: "=\\×"; shifted: "۱۲۳؟"; } |
518 | + CharKey { label: "»"; shifted: "©"; switchBackFromSymbols: true; } |
519 | + CharKey { label: "«"; shifted: "®"; switchBackFromSymbols: true; } |
520 | + CharKey { label: "/"; shifted: "\\"; } |
521 | + CharKey { label: ":"; shifted: "™"; } |
522 | + CharKey { label: "؛"; shifted: "℅"; } |
523 | + CharKey { label: "!"; shifted: "]"; extended: ["¡"]; } |
524 | + CharKey { label: "؟"; shifted: "["; extended: ["?", "¿"]; } |
525 | + BackspaceKey {} |
526 | + } |
527 | + |
528 | + Item { |
529 | + anchors.left: parent.left |
530 | + anchors.right: parent.right |
531 | + |
532 | + height: panel.keyHeight + units.gu(UI.bottom_margin*2); |
533 | + |
534 | + SymbolShiftKey { id: symShiftKey; label: "ابپ"; shifted: "ابپ"; anchors.left: parent.left; height: parent.height; } |
535 | + CharKey { id: commaKey; label: "،"; shifted: "،"; anchors.left: symShiftKey.right; height: parent.height; } |
536 | + SpaceKey { id: spaceKey; anchors.left: commaKey.right; anchors.right: zwj.left; noMagnifier: true; height: parent.height } |
537 | + CharKey { id: zwj; label: "🢒⸽🢐"; shifted: "🢒⸽🢐"; valueToSubmit: ""; anchors.right: dotKey.left; height: parent.height; } |
538 | + CharKey { id: dotKey; label: "."; shifted: "."; anchors.right: enterKey.left; height: parent.height; } |
539 | + ReturnKey { id: enterKey; anchors.right: parent.right; height: parent.height; } |
540 | + } |
541 | + } // column |
542 | +} |
543 | |
544 | === added file 'plugins/fa/qml/qml.pro' |
545 | --- plugins/fa/qml/qml.pro 1970-01-01 00:00:00 +0000 |
546 | +++ plugins/fa/qml/qml.pro 2017-01-11 14:46:10 +0000 |
547 | @@ -0,0 +1,21 @@ |
548 | +TOP_BUILDDIR = $$OUT_PWD/../../.. |
549 | +TOP_SRCDIR = $$PWD/../../.. |
550 | + |
551 | +include($${TOP_SRCDIR}/config.pri) |
552 | + |
553 | +TARGET = dummy |
554 | +TEMPLATE = lib |
555 | + |
556 | +lang_fa.path = "$${UBUNTU_KEYBOARD_LIB_DIR}/fa/" |
557 | +lang_fa.files = *.qml *.js |
558 | + |
559 | +INSTALLS += lang_fa |
560 | + |
561 | +# for QtCreator |
562 | +OTHER_FILES += \ |
563 | + Keyboard_fa.qml \ |
564 | + Keyboard_fa_email.qml \ |
565 | + Keyboard_fa_url.qml \ |
566 | + Keyboard_fa_url_search.qml \ |
567 | + Keyboard_symbols_fa.qml |
568 | + |
569 | |
570 | === added directory 'plugins/fa/src' |
571 | === added file 'plugins/fa/src/database_fa.db' |
572 | Binary files plugins/fa/src/database_fa.db 1970-01-01 00:00:00 +0000 and plugins/fa/src/database_fa.db 2017-01-11 14:46:10 +0000 differ |
573 | === added file 'plugins/fa/src/free_ebook.txt' |
574 | === added file 'plugins/fa/src/persianplugin.h' |
575 | --- plugins/fa/src/persianplugin.h 1970-01-01 00:00:00 +0000 |
576 | +++ plugins/fa/src/persianplugin.h 2017-01-11 14:46:10 +0000 |
577 | @@ -0,0 +1,25 @@ |
578 | +#ifndef PERSIANPLUGIN_H |
579 | +#define PERSIANPLUGIN_H |
580 | + |
581 | +#include <QObject> |
582 | +#include "languageplugininterface.h" |
583 | +#include "westernlanguagesplugin.h" |
584 | + |
585 | +class PersianPlugin : public WesternLanguagesPlugin |
586 | +{ |
587 | + Q_OBJECT |
588 | + Q_INTERFACES(LanguagePluginInterface) |
589 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PersianPlugin" FILE "persianplugin.json") |
590 | + |
591 | +public: |
592 | + explicit PersianPlugin(QObject* parent = 0) |
593 | + : WesternLanguagesPlugin(parent) |
594 | + { |
595 | + } |
596 | + |
597 | + virtual ~PersianPlugin() |
598 | + { |
599 | + } |
600 | +}; |
601 | + |
602 | +#endif // PERSIANPLUGIN_H |
603 | |
604 | === added file 'plugins/fa/src/persianplugin.json' |
605 | --- plugins/fa/src/persianplugin.json 1970-01-01 00:00:00 +0000 |
606 | +++ plugins/fa/src/persianplugin.json 2017-01-11 14:46:10 +0000 |
607 | @@ -0,0 +1,7 @@ |
608 | +{ |
609 | + "IID": "org.qt-project.Qt.Examples.PersianPlugin", |
610 | + "MetaData": { |
611 | + }, |
612 | + "className": "PersianPlugin", |
613 | + "debug": true |
614 | +} |
615 | |
616 | === added file 'plugins/fa/src/src.pro' |
617 | --- plugins/fa/src/src.pro 1970-01-01 00:00:00 +0000 |
618 | +++ plugins/fa/src/src.pro 2017-01-11 14:46:10 +0000 |
619 | @@ -0,0 +1,46 @@ |
620 | +TOP_BUILDDIR = $$OUT_PWD/../../.. |
621 | +TOP_SRCDIR = $$PWD/../../.. |
622 | + |
623 | +include($${TOP_SRCDIR}/config.pri) |
624 | + |
625 | +TEMPLATE = lib |
626 | +CONFIG += plugin |
627 | +QT += widgets |
628 | +INCLUDEPATH += \ |
629 | + $${TOP_SRCDIR}/src/ \ |
630 | + $${TOP_SRCDIR}/src/lib/ \ |
631 | + $${TOP_SRCDIR}/src/lib/logic/ |
632 | + $${TOP_SRCDIR}/plugins/westernsupport |
633 | + |
634 | +HEADERS = \ |
635 | + persianplugin.h |
636 | + |
637 | +TARGET = $$qtLibraryTarget(faplugin) |
638 | + |
639 | +EXAMPLE_FILES = persianplugin.json |
640 | + |
641 | +# generate database for presage: |
642 | +PLUGIN_INSTALL_PATH = $${UBUNTU_KEYBOARD_LIB_DIR}/fa/ |
643 | + |
644 | +lang_db_fa.commands += \ |
645 | + rm -f $$PWD/database_fa.db && \ |
646 | + text2ngram -n 1 -l -f sqlite -o $$PWD/database_fa.db $$PWD/free_ebook.txt && \ |
647 | + text2ngram -n 2 -l -f sqlite -o $$PWD/database_fa.db $$PWD/free_ebook.txt && \ |
648 | + text2ngram -n 3 -l -f sqlite -o $$PWD/database_fa.db $$PWD/free_ebook.txt |
649 | +lang_db_fa.files += $$PWD/database_fa.db |
650 | +lang_db_fa_install.path = $$PLUGIN_INSTALL_PATH |
651 | +lang_db_fa_install.files += $$PWD/database_fa.db |
652 | + |
653 | +QMAKE_EXTRA_TARGETS += lang_db_fa lang_db_fa_install |
654 | + |
655 | +target.path = $$PLUGIN_INSTALL_PATH |
656 | +INSTALLS += target lang_db_fa_install |
657 | + |
658 | +OTHER_FILES += \ |
659 | + persianplugin.json \ |
660 | + free_ebook.txt |
661 | + |
662 | +LIBS += $${TOP_BUILDDIR}/plugins/plugins/libwesternsupport.a -lpresage -lhunspell |
663 | + |
664 | +INCLUDEPATH += $$PWD/../../westernsupport |
665 | +DEPENDPATH += $$PWD/../../westernsupport |
666 | |
667 | === added directory 'plugins/fa/tests' |
668 | === modified file 'plugins/plugins.pro' |
669 | --- plugins/plugins.pro 2016-12-08 04:06:47 +0000 |
670 | +++ plugins/plugins.pro 2017-01-11 14:46:10 +0000 |
671 | @@ -14,6 +14,7 @@ |
672 | en \ |
673 | eo \ |
674 | es \ |
675 | + fa \ |
676 | fi \ |
677 | fr \ |
678 | gd \ |
679 | |
680 | === modified file 'qml/keys/languages.js' |
681 | --- qml/keys/languages.js 2016-12-08 04:06:47 +0000 |
682 | +++ qml/keys/languages.js 2017-01-11 14:46:10 +0000 |
683 | @@ -28,6 +28,7 @@ |
684 | if (languageId == "en") return i18n.tr("English"); |
685 | if (languageId == "eo") return i18n.tr("Esperanto"); |
686 | if (languageId == "es") return i18n.tr("Spanish"); |
687 | + if (languageId == "fa") return i18n.tr("Persian"); |
688 | if (languageId == "fi") return i18n.tr("Finnish"); |
689 | if (languageId == "fr") return i18n.tr("French"); |
690 | if (languageId == "gd") return i18n.tr("Scottish Gaelic"); |
I should probably also mention that this is a perfectly working patch. I can successfully compile this branch and use it on my own Nexus 4.