Merge lp:~mabkenar/ubuntu-keyboard/add-persian-layout into lp:ubuntu-keyboard

Proposed by Masoud Abkenar on 2017-01-11
Status: Merged
Approved by: Michael Sheldon on 2017-03-28
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
Reviewer Review Type Date Requested Status
Ken VanDine packaging Approve on 2017-03-28
Michael Sheldon (community) 2017-01-11 Approve on 2017-03-28
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/fa/qml/Keyboard_symbols_fa.qml' next to other Persian layouts.

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://forum.ubuntu.ir/index.php/topic,143281.msg1128226.html#msg1128226
[2] https://masoud.abkenar.net/blog/en/?p=63

To post a comment you must log in.
Masoud Abkenar (mabkenar) wrote :

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.

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.imgur.com/NiHFGZB.png), so I think there's a font package we'll need to add as an additional dependency to the ubuntu-keyboard-persian package. Do you know which font is likely to provide this character?

 * I noticed that key isn't present on the email layout (but is there on the URL layout), is that intentional?

Thanks!

review: Needs Fixing
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://goo.gl/vVPwXT and similar key in AOSP is here https://goo.gl/hYBdm6

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-impossible-to-catch errors when typing email addresses.

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 :)

review: Approve
Ken VanDine (ken-vandine) wrote :

Packaging changes are fine

review: Approve (packaging)

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 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'
572Binary 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");

Subscribers

People subscribed via source and target branches