Merge lp:~michael-sheldon/ubuntu-keyboard/fix-1335007 into lp:ubuntu-keyboard

Proposed by Michael Sheldon
Status: Merged
Approved by: Bill Filler
Approved revision: 260
Merged at revision: 254
Proposed branch: lp:~michael-sheldon/ubuntu-keyboard/fix-1335007
Merge into: lp:ubuntu-keyboard
Prerequisite: lp:~michael-sheldon/ubuntu-keyboard/fix-autopilot
Diff against target: 346 lines (+175/-6)
8 files modified
plugins/pinyin/src/chineselanguagefeatures.cpp (+1/-1)
src/lib/logic/abstractlanguagefeatures.h (+7/-0)
src/plugin/inputmethod.cpp (+20/-2)
src/plugin/inputmethod.h (+4/-0)
src/plugin/inputmethod_p.h (+2/-0)
src/view/abstracttexteditor.cpp (+5/-3)
src/view/abstracttexteditor.h (+3/-0)
tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py (+133/-0)
To merge this branch: bzr merge lp:~michael-sheldon/ubuntu-keyboard/fix-1335007
Reviewer Review Type Date Requested Status
Bill Filler (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+243037@code.launchpad.net

Commit message

Allow Pinyin to be used in URL and email fields and fix text selection issues.

Description of the change

Allow Pinyin to be used in URL and email fields and fix text selection issues.

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 (besides pre-requisite)

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?

 * No change

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?

 * No change

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
259. By Michael Sheldon

Update comment to reflect actual test actions

260. By Michael Sheldon

Remove unnecessary import

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote :

tested, works

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/pinyin/src/chineselanguagefeatures.cpp'
2--- plugins/pinyin/src/chineselanguagefeatures.cpp 2014-11-12 14:54:54 +0000
3+++ plugins/pinyin/src/chineselanguagefeatures.cpp 2014-11-27 23:24:06 +0000
4@@ -47,7 +47,7 @@
5
6 QString ChineseLanguageFeatures::appendixForReplacedPreedit(const QString &preedit) const
7 {
8- if (isSeparator(preedit.right(1))) {
9+ if (isSeparator(preedit.right(1)) && contentType() != Maliit::EmailContentType && contentType() != Maliit::UrlContentType) {
10 return QString(" ");
11 }
12
13
14=== modified file 'src/lib/logic/abstractlanguagefeatures.h'
15--- src/lib/logic/abstractlanguagefeatures.h 2014-10-21 18:54:25 +0000
16+++ src/lib/logic/abstractlanguagefeatures.h 2014-11-27 23:24:06 +0000
17@@ -33,6 +33,7 @@
18 #define MALIIT_KEYBOARD_ABSTRACTLANGUAGEFEATURES_H
19
20 #include <QObject>
21+#include <maliit/plugins/abstractinputmethod.h>
22
23 class QObject;
24 class AbstractLanguageFeatures
25@@ -52,6 +53,12 @@
26 // to the user's input. However for input methods such as pinyin this
27 // can be disabled by implementing this method to return true.
28 virtual bool ignoreSimilarity() const { return false; }
29+
30+ Maliit::TextContentType contentType() const { return m_contentType; }
31+ void setContentType(Maliit::TextContentType contentType) { m_contentType = contentType; }
32+
33+private:
34+ Maliit::TextContentType m_contentType;
35 };
36
37 #endif // MALIIT_KEYBOARD_ABSTRACTLANGUAGEFEATURES_H
38
39=== modified file 'src/plugin/inputmethod.cpp'
40--- src/plugin/inputmethod.cpp 2014-11-19 15:39:41 +0000
41+++ src/plugin/inputmethod.cpp 2014-11-27 23:24:06 +0000
42@@ -103,6 +103,7 @@
43
44 connect(this, SIGNAL(contentTypeChanged(TextContentType)), this, SLOT(setContentType(TextContentType)));
45 connect(this, SIGNAL(activeLanguageChanged(QString)), d->editor.wordEngine(), SLOT(onLanguageChanged(QString)));
46+ connect(this, SIGNAL(hasSelectionChanged(bool)), &d->editor, SLOT(onHasSelectionChanged(bool)));
47 connect(d->editor.wordEngine(), SIGNAL(pluginChanged()), this, SLOT(onWordEnginePluginChanged()));
48 connect(this, SIGNAL(keyboardStateChanged(QString)), &d->editor, SLOT(onKeyboardStateChanged(QString)));
49 connect(d->m_geometry, SIGNAL(visibleRectChanged()), this, SLOT(onVisibleRectChanged()));
50@@ -137,7 +138,6 @@
51 d->m_geometry->setShown(true);
52 update();
53 d->view->setVisible(true);
54- d->editor.checkPreeditReentry(false);
55 }
56
57 //! \brief InputMethod::hide
58@@ -345,6 +345,13 @@
59 }
60
61 bool valid;
62+
63+ bool hasSelection = d->host->hasSelection(valid);
64+
65+ if (valid && hasSelection != d->hasSelection) {
66+ d->hasSelection = hasSelection;
67+ Q_EMIT hasSelectionChanged(d->hasSelection);
68+ }
69
70 bool emitPredictionEnabled = false;
71
72@@ -387,8 +394,11 @@
73 {
74 Q_D(InputMethod);
75
76- if (d->contentType != FreeTextContentType)
77+ if (d->contentType != FreeTextContentType
78+ && !(d->editor.wordEngine()->languageFeature()->alwaysShowSuggestions()
79+ && (d->contentType == UrlContentType || d->contentType == EmailContentType))) {
80 d->wordEngineEnabled = false;
81+ }
82
83 d->editor.clearPreedit();
84 d->editor.wordEngine()->setEnabled( d->wordEngineEnabled );
85@@ -413,6 +423,8 @@
86
87 setActiveLanguage(d->activeLanguage);
88
89+ d->editor.wordEngine()->languageFeature()->setContentType(static_cast<Maliit::TextContentType>(contentType));
90+
91 d->contentType = contentType;
92 Q_EMIT contentTypeChanged(contentType);
93
94@@ -542,6 +554,12 @@
95 Q_EMIT keyboardStateChanged(d->keyboardState);
96 }
97
98+bool InputMethod::hasSelection() const
99+{
100+ Q_D(const InputMethod);
101+ return d->hasSelection;
102+}
103+
104 void InputMethod::onVisibleRectChanged()
105 {
106 Q_D(InputMethod);
107
108=== modified file 'src/plugin/inputmethod.h'
109--- src/plugin/inputmethod.h 2014-11-17 14:53:36 +0000
110+++ src/plugin/inputmethod.h 2014-11-27 23:24:06 +0000
111@@ -56,6 +56,7 @@
112 Q_PROPERTY(QObject* actionKeyOverride READ actionKeyOverride NOTIFY actionKeyOverrideChanged)
113 Q_PROPERTY(bool useHapticFeedback READ useHapticFeedback NOTIFY useHapticFeedbackChanged)
114 Q_PROPERTY(QString keyboardState READ keyboardState WRITE setKeyboardState NOTIFY keyboardStateChanged)
115+ Q_PROPERTY(bool hasSelection READ hasSelection NOTIFY hasSelectionChanged)
116
117 Q_ENUMS(TextContentType)
118
119@@ -116,6 +117,8 @@
120 const QString keyboardState() const;
121 Q_SLOT void setKeyboardState(const QString& state);
122
123+ bool hasSelection() const;
124+
125 QObject* actionKeyOverride() const;
126
127 Q_SLOT void close();
128@@ -135,6 +138,7 @@
129 void actionKeyOverrideChanged();
130 void keyboardStateChanged(QString state);
131 void keyboardReset();
132+ void hasSelectionChanged(bool hasSelection);
133
134 private:
135 Q_SLOT void onAutoCorrectSettingChanged();
136
137=== modified file 'src/plugin/inputmethod_p.h'
138--- src/plugin/inputmethod_p.h 2014-09-15 09:39:19 +0000
139+++ src/plugin/inputmethod_p.h 2014-11-27 23:24:06 +0000
140@@ -58,6 +58,7 @@
141 QStringList enabledLanguages;
142 Qt::ScreenOrientation appsCurrentOrientation;
143 QString keyboardState;
144+ bool hasSelection;
145
146 KeyboardGeometry *m_geometry;
147 KeyboardSettings m_settings;
148@@ -82,6 +83,7 @@
149 , enabledLanguages(activeLanguage)
150 , appsCurrentOrientation(qGuiApp->primaryScreen()->orientation())
151 , keyboardState("CHARACTERS")
152+ , hasSelection(false)
153 , m_geometry(new KeyboardGeometry(q))
154 , m_settings()
155 , m_greeterStatus(new GreeterStatus())
156
157=== modified file 'src/view/abstracttexteditor.cpp'
158--- src/view/abstracttexteditor.cpp 2014-11-04 20:17:35 +0000
159+++ src/view/abstracttexteditor.cpp 2014-11-27 23:24:06 +0000
160@@ -1060,13 +1060,12 @@
161 }
162
163 //! \brief AbstractTextEditor::checkPreeditReentry Checks to see whether we should
164-//! place a word back in to pre-edit after a character has been deleted or focus
165-//! has changed
166+//! place a word back in to pre-edit after a character has been deleted
167 void AbstractTextEditor::checkPreeditReentry(bool uncommittedDelete)
168 {
169 Q_D(AbstractTextEditor);
170
171- if(!isPreeditEnabled()) {
172+ if(!isPreeditEnabled() || m_hasSelection) {
173 return;
174 }
175
176@@ -1115,5 +1114,8 @@
177 d->word_engine->computeCandidates(d->text.data());
178 }
179
180+void AbstractTextEditor::onHasSelectionChanged(bool hasSelection) {
181+ m_hasSelection = hasSelection;
182+}
183
184 } // namespace MaliitKeyboard
185
186=== modified file 'src/view/abstracttexteditor.h'
187--- src/view/abstracttexteditor.h 2014-09-10 14:57:52 +0000
188+++ src/view/abstracttexteditor.h 2014-11-27 23:24:06 +0000
189@@ -118,6 +118,7 @@
190 Q_SLOT void onCursorPositionChanged(int cursor_position,
191 const QString &surrounding_text);
192 Q_SLOT void onKeyboardStateChanged(QString state);
193+ Q_SLOT void onHasSelectionChanged(bool hasSelection);
194 Q_SLOT void replacePreedit(const QString &replacement);
195 Q_SLOT void replaceTextWithPreedit(const QString &replacement, int start, int len, int pos);
196 Q_SLOT void replaceAndCommitPreedit(const QString &replacement);
197@@ -174,6 +175,8 @@
198
199 void sendKeyPressAndReleaseEvents(int key, Qt::KeyboardModifiers modifiers,
200 const QString& text = QString());
201+
202+ bool m_hasSelection;
203 };
204
205 } // namespace MaliitKeyboard
206
207=== modified file 'tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py'
208--- tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py 2014-11-27 23:24:05 +0000
209+++ tests/autopilot/ubuntu_keyboard/tests/test_keyboard.py 2014-11-27 23:24:06 +0000
210@@ -458,3 +458,136 @@
211 Eventually(Equals(expected))
212 )
213
214+
215+class UbuntuKeyboardPinyin(UbuntuKeyboardTests):
216+
217+ scenarios = [
218+ (
219+ "Url",
220+ dict(
221+ label="Url",
222+ hints=['Qt.ImhUrlCharactersOnly'],
223+ expected_activeview="url"
224+ )
225+ ),
226+ (
227+ "Email",
228+ dict(
229+ label="Email",
230+ hints=['Qt.ImhEmailCharactersOnly'],
231+ expected_activeview="email"
232+ )
233+ ),
234+ (
235+ "FreeText",
236+ dict(
237+ label="FreeText",
238+ hints=None,
239+ expected_activeview="freetext"
240+ )
241+ ),
242+ (
243+ "NoPredictiveText",
244+ dict(
245+ label="NoPredictiveText",
246+ hints=['Qt.ImhNoPredictveText'],
247+ expected_activeview="freetext"
248+ )
249+ ),
250+ ]
251+
252+ def set_test_settings(self):
253+ gsettings = Gio.Settings.new("com.canonical.keyboard.maliit")
254+ gsettings.set_string("active-language", "zh")
255+ gsettings.set_boolean("auto-capitalization", True)
256+ gsettings.set_boolean("auto-completion", True)
257+ gsettings.set_boolean("predictive-text", True)
258+ gsettings.set_boolean("spell-checking", True)
259+ gsettings.set_boolean("double-space-full-stop", True)
260+
261+ def test_pinyin(self):
262+ """Switching to Chinese should result in pinyin characters being entered
263+ via autocomplete regardless of layout or prediction being disabled.
264+
265+ """
266+ text_area = self.launch_test_input_area(self.label, self.hints)
267+ self.ensure_focus_on_input(text_area)
268+ keyboard = Keyboard()
269+ self.addCleanup(keyboard.dismiss)
270+
271+ keyboard.type('pinyin ')
272+
273+ expected = "品以"
274+ self.assertThat(
275+ text_area.text,
276+ Eventually(Equals(expected))
277+ )
278+
279+ def test_fullstop(self):
280+ """Full stop shouldn't have space added after it in pinyin mode.
281+
282+ """
283+ text_area = self.launch_test_input_area(self.label, self.hints)
284+ self.ensure_focus_on_input(text_area)
285+ keyboard = Keyboard()
286+ self.addCleanup(keyboard.dismiss)
287+
288+ keyboard.type('pinyin.cn ')
289+
290+ expected = "品以.cn"
291+ self.assertThat(
292+ text_area.text,
293+ Eventually(Equals(expected))
294+ )
295+
296+
297+class UbuntuKeyboardSelection(UbuntuKeyboardTests):
298+
299+ def test_delete_selection(self):
300+ """Selecting a word and then pressing backspace should delete the world.
301+
302+ """
303+ text_area = self.launch_test_input_area()
304+ self.ensure_focus_on_input(text_area)
305+ keyboard = Keyboard()
306+ self.addCleanup(keyboard.dismiss)
307+
308+ keyboard.type('Testing selection deletion')
309+
310+ # Double tap to select a word
311+ self.pointer.click_object(text_area)
312+ self.pointer.click_object(text_area)
313+
314+ keyboard.type('\b')
315+
316+ expected = 'Testing deletion'
317+ self.assertThat(
318+ text_area.text,
319+ Eventually(Equals(expected))
320+ )
321+
322+ def test_selection_focus(self):
323+ """Focusing on a field with selected text should leave the text unchanged.
324+
325+ """
326+ text_area = self.launch_test_input_area()
327+ self.ensure_focus_on_input(text_area)
328+ keyboard = Keyboard()
329+ self.addCleanup(keyboard.dismiss)
330+
331+ keyboard.type('This is a test')
332+
333+ # Double tap to select a word
334+ self.pointer.click_object(text_area)
335+ self.pointer.click_object(text_area)
336+
337+ keyboard.dismiss()
338+
339+ self.ensure_focus_on_input(text_area)
340+
341+ expected = 'This is a test'
342+ self.assertThat(
343+ text_area.text,
344+ Eventually(Equals(expected))
345+ )
346+

Subscribers

People subscribed via source and target branches