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

Proposed by Michael Sheldon
Status: Merged
Approved by: Bill Filler
Approved revision: 236
Merged at revision: 245
Proposed branch: lp:~michael-sheldon/ubuntu-keyboard/fix-1347796
Merge into: lp:ubuntu-keyboard
Diff against target: 141 lines (+65/-0)
7 files modified
plugins/pinyin/src/chineselanguagefeatures.cpp (+5/-0)
plugins/pinyin/src/chineselanguagefeatures.h (+1/-0)
plugins/westernsupport/westernlanguagefeatures.cpp (+5/-0)
plugins/westernsupport/westernlanguagefeatures.h (+1/-0)
src/lib/logic/abstractlanguagefeatures.h (+4/-0)
src/lib/logic/wordengine.cpp (+48/-0)
src/lib/logic/wordengine.h (+1/-0)
To merge this branch: bzr merge lp:~michael-sheldon/ubuntu-keyboard/fix-1347796
Reviewer Review Type Date Requested Status
Bill Filler (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+239124@code.launchpad.net

Commit message

Calculate the similarity between the current user's input and the prediction candidate, if they differ too much make the user input the primary candidate for auto-completion.

Description of the change

Calculate the similarity between the current user's input and the prediction candidate, if they differ too much make the user input the primary candidate for auto-completion.

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?

 * 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)
236. By Michael Sheldon

Merge from trunk

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

aprpoved

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-10-22 15:56:37 +0000
3+++ plugins/pinyin/src/chineselanguagefeatures.cpp 2014-11-12 14:55:15 +0000
4@@ -83,3 +83,8 @@
5
6 return false;
7 }
8+
9+bool ChineseLanguageFeatures::ignoreSimilarity() const
10+{
11+ return true;
12+}
13
14=== modified file 'plugins/pinyin/src/chineselanguagefeatures.h'
15--- plugins/pinyin/src/chineselanguagefeatures.h 2014-09-08 15:09:32 +0000
16+++ plugins/pinyin/src/chineselanguagefeatures.h 2014-11-12 14:55:15 +0000
17@@ -33,6 +33,7 @@
18 virtual QString appendixForReplacedPreedit(const QString &preedit) const;
19 virtual bool isSeparator(const QString &text) const;
20 virtual bool isSymbol(const QString &text) const;
21+ virtual bool ignoreSimilarity() const;
22 };
23
24 #endif // CHINESELANGUAGEFEATURES_H
25
26=== modified file 'plugins/westernsupport/westernlanguagefeatures.cpp'
27--- plugins/westernsupport/westernlanguagefeatures.cpp 2014-09-08 15:09:32 +0000
28+++ plugins/westernsupport/westernlanguagefeatures.cpp 2014-11-12 14:55:15 +0000
29@@ -104,3 +104,8 @@
30
31 return false;
32 }
33+
34+bool WesternLanguageFeatures::ignoreSimilarity() const
35+{
36+ return false;
37+}
38
39=== modified file 'plugins/westernsupport/westernlanguagefeatures.h'
40--- plugins/westernsupport/westernlanguagefeatures.h 2014-09-08 15:09:32 +0000
41+++ plugins/westernsupport/westernlanguagefeatures.h 2014-11-12 14:55:15 +0000
42@@ -49,6 +49,7 @@
43 virtual bool isSeparator(const QString &text) const;
44 virtual QString fullStopSequence() const { return QString("."); }
45 virtual bool isSymbol(const QString &text) const;
46+ virtual bool ignoreSimilarity() const;
47 };
48
49 #endif // MALIITKEYBOARD_LANGUAGEFEATURES_H
50
51=== modified file 'src/lib/logic/abstractlanguagefeatures.h'
52--- src/lib/logic/abstractlanguagefeatures.h 2014-09-08 15:09:32 +0000
53+++ src/lib/logic/abstractlanguagefeatures.h 2014-11-12 14:55:15 +0000
54@@ -48,6 +48,10 @@
55 virtual bool isSeparator(const QString &text) const { Q_UNUSED(text); return false; }
56 virtual QString fullStopSequence() const { return QString(); }
57 virtual bool isSymbol(const QString &text) const { Q_UNUSED(text); return false; }
58+ // Typically we disable auto-correct if the predicted word isn't similar
59+ // to the user's input. However for input methods such as pinyin this
60+ // can be disabled by implementing this method to return true.
61+ virtual bool ignoreSimilarity() const { return false; }
62 };
63
64 #endif // MALIIT_KEYBOARD_ABSTRACTLANGUAGEFEATURES_H
65
66=== modified file 'src/lib/logic/wordengine.cpp'
67--- src/lib/logic/wordengine.cpp 2014-11-07 11:31:10 +0000
68+++ src/lib/logic/wordengine.cpp 2014-11-12 14:55:15 +0000
69@@ -345,6 +345,14 @@
70 primary.setPrimary(true);
71 d->candidates->replace(0, primary);
72 Q_EMIT primaryCandidateChanged(primary.word());
73+ } else if (!d->languagePlugin->languageFeature()->ignoreSimilarity()
74+ && !similarWords(d->candidates->at(0).word(), d->candidates->at(1).word())) {
75+ // The prediction is too different to the user input, so the user input
76+ // becomes the primary candidate
77+ WordCandidate primary = d->candidates->value(0);
78+ primary.setPrimary(true);
79+ d->candidates->replace(0, primary);
80+ Q_EMIT primaryCandidateChanged(primary.word());
81 } else {
82 // The first prediction is the primary candidate
83 WordCandidate primary = d->candidates->value(1);
84@@ -420,6 +428,46 @@
85 return d->languagePlugin->languageFeature();
86 }
87
88+bool WordEngine::similarWords(QString word1, QString word2) {
89+ // Calculate the Levenshtein distance between the first word and the
90+ // beginning of the second word. If the distance is too great then word2
91+ // is not considered to be a suitable prediction for word1.
92+ word2 = word2.left(word1.size());
93+ if (word1 == word2) {
94+ return true;
95+ }
96+
97+ int *v0 = (int *) malloc(sizeof(int) * word1.size() + 1);
98+ int *v1 = (int *) malloc(sizeof(int) * word1.size() + 1);
99+
100+ for (int i = 0; i < word2.size() + 1; i++) {
101+ v0[i] = i;
102+ v1[i] = 0;
103+ }
104+
105+ for (int i = 0; i < word1.size(); i++) {
106+ v1[0] = i + 1;
107+
108+ for (int j = 0; j < word2.size(); j++) {
109+ int cost = (word1[i] == word2[i]) ? 0 : 1;
110+ v1[j + 1] = std::min(v1[j] + 1, v0[j + 1] + 1);
111+ v1[j + 1] = std::min(v1[j] + 1, v0[j] + cost);
112+ }
113+
114+ for (int j = 0; j < word1.size() + 1; j++) {
115+ v0[j] = v1[j];
116+ }
117+ }
118+
119+ double threshold = std::max(word1.size() / 3.0, 3.0);
120+ int distance = v1[word2.size()];
121+
122+ free(v0);
123+ free(v1);
124+
125+ return distance <= threshold;
126+}
127+
128 void WordEngine::clearCandidates()
129 {
130 Q_D(WordEngine);
131
132=== modified file 'src/lib/logic/wordengine.h'
133--- src/lib/logic/wordengine.h 2014-10-29 13:57:51 +0000
134+++ src/lib/logic/wordengine.h 2014-11-12 14:55:15 +0000
135@@ -82,6 +82,7 @@
136 virtual void fetchCandidates(Model::Text *text);
137 //! \reimp_end
138 void calculatePrimaryCandidate();
139+ bool similarWords(QString word1, QString word2);
140
141 const QScopedPointer<WordEnginePrivate> d_ptr;
142

Subscribers

People subscribed via source and target branches