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
=== modified file 'plugins/pinyin/src/chineselanguagefeatures.cpp'
--- plugins/pinyin/src/chineselanguagefeatures.cpp 2014-10-22 15:56:37 +0000
+++ plugins/pinyin/src/chineselanguagefeatures.cpp 2014-11-12 14:55:15 +0000
@@ -83,3 +83,8 @@
8383
84 return false;84 return false;
85}85}
86
87bool ChineseLanguageFeatures::ignoreSimilarity() const
88{
89 return true;
90}
8691
=== modified file 'plugins/pinyin/src/chineselanguagefeatures.h'
--- plugins/pinyin/src/chineselanguagefeatures.h 2014-09-08 15:09:32 +0000
+++ plugins/pinyin/src/chineselanguagefeatures.h 2014-11-12 14:55:15 +0000
@@ -33,6 +33,7 @@
33 virtual QString appendixForReplacedPreedit(const QString &preedit) const;33 virtual QString appendixForReplacedPreedit(const QString &preedit) const;
34 virtual bool isSeparator(const QString &text) const;34 virtual bool isSeparator(const QString &text) const;
35 virtual bool isSymbol(const QString &text) const;35 virtual bool isSymbol(const QString &text) const;
36 virtual bool ignoreSimilarity() const;
36};37};
3738
38#endif // CHINESELANGUAGEFEATURES_H39#endif // CHINESELANGUAGEFEATURES_H
3940
=== modified file 'plugins/westernsupport/westernlanguagefeatures.cpp'
--- plugins/westernsupport/westernlanguagefeatures.cpp 2014-09-08 15:09:32 +0000
+++ plugins/westernsupport/westernlanguagefeatures.cpp 2014-11-12 14:55:15 +0000
@@ -104,3 +104,8 @@
104104
105 return false;105 return false;
106}106}
107
108bool WesternLanguageFeatures::ignoreSimilarity() const
109{
110 return false;
111}
107112
=== modified file 'plugins/westernsupport/westernlanguagefeatures.h'
--- plugins/westernsupport/westernlanguagefeatures.h 2014-09-08 15:09:32 +0000
+++ plugins/westernsupport/westernlanguagefeatures.h 2014-11-12 14:55:15 +0000
@@ -49,6 +49,7 @@
49 virtual bool isSeparator(const QString &text) const;49 virtual bool isSeparator(const QString &text) const;
50 virtual QString fullStopSequence() const { return QString("."); }50 virtual QString fullStopSequence() const { return QString("."); }
51 virtual bool isSymbol(const QString &text) const;51 virtual bool isSymbol(const QString &text) const;
52 virtual bool ignoreSimilarity() const;
52};53};
5354
54#endif // MALIITKEYBOARD_LANGUAGEFEATURES_H55#endif // MALIITKEYBOARD_LANGUAGEFEATURES_H
5556
=== modified file 'src/lib/logic/abstractlanguagefeatures.h'
--- src/lib/logic/abstractlanguagefeatures.h 2014-09-08 15:09:32 +0000
+++ src/lib/logic/abstractlanguagefeatures.h 2014-11-12 14:55:15 +0000
@@ -48,6 +48,10 @@
48 virtual bool isSeparator(const QString &text) const { Q_UNUSED(text); return false; }48 virtual bool isSeparator(const QString &text) const { Q_UNUSED(text); return false; }
49 virtual QString fullStopSequence() const { return QString(); }49 virtual QString fullStopSequence() const { return QString(); }
50 virtual bool isSymbol(const QString &text) const { Q_UNUSED(text); return false; }50 virtual bool isSymbol(const QString &text) const { Q_UNUSED(text); return false; }
51 // Typically we disable auto-correct if the predicted word isn't similar
52 // to the user's input. However for input methods such as pinyin this
53 // can be disabled by implementing this method to return true.
54 virtual bool ignoreSimilarity() const { return false; }
51};55};
5256
53#endif // MALIIT_KEYBOARD_ABSTRACTLANGUAGEFEATURES_H57#endif // MALIIT_KEYBOARD_ABSTRACTLANGUAGEFEATURES_H
5458
=== modified file 'src/lib/logic/wordengine.cpp'
--- src/lib/logic/wordengine.cpp 2014-11-07 11:31:10 +0000
+++ src/lib/logic/wordengine.cpp 2014-11-12 14:55:15 +0000
@@ -345,6 +345,14 @@
345 primary.setPrimary(true);345 primary.setPrimary(true);
346 d->candidates->replace(0, primary);346 d->candidates->replace(0, primary);
347 Q_EMIT primaryCandidateChanged(primary.word());347 Q_EMIT primaryCandidateChanged(primary.word());
348 } else if (!d->languagePlugin->languageFeature()->ignoreSimilarity()
349 && !similarWords(d->candidates->at(0).word(), d->candidates->at(1).word())) {
350 // The prediction is too different to the user input, so the user input
351 // becomes the primary candidate
352 WordCandidate primary = d->candidates->value(0);
353 primary.setPrimary(true);
354 d->candidates->replace(0, primary);
355 Q_EMIT primaryCandidateChanged(primary.word());
348 } else {356 } else {
349 // The first prediction is the primary candidate357 // The first prediction is the primary candidate
350 WordCandidate primary = d->candidates->value(1);358 WordCandidate primary = d->candidates->value(1);
@@ -420,6 +428,46 @@
420 return d->languagePlugin->languageFeature();428 return d->languagePlugin->languageFeature();
421}429}
422430
431bool WordEngine::similarWords(QString word1, QString word2) {
432 // Calculate the Levenshtein distance between the first word and the
433 // beginning of the second word. If the distance is too great then word2
434 // is not considered to be a suitable prediction for word1.
435 word2 = word2.left(word1.size());
436 if (word1 == word2) {
437 return true;
438 }
439
440 int *v0 = (int *) malloc(sizeof(int) * word1.size() + 1);
441 int *v1 = (int *) malloc(sizeof(int) * word1.size() + 1);
442
443 for (int i = 0; i < word2.size() + 1; i++) {
444 v0[i] = i;
445 v1[i] = 0;
446 }
447
448 for (int i = 0; i < word1.size(); i++) {
449 v1[0] = i + 1;
450
451 for (int j = 0; j < word2.size(); j++) {
452 int cost = (word1[i] == word2[i]) ? 0 : 1;
453 v1[j + 1] = std::min(v1[j] + 1, v0[j + 1] + 1);
454 v1[j + 1] = std::min(v1[j] + 1, v0[j] + cost);
455 }
456
457 for (int j = 0; j < word1.size() + 1; j++) {
458 v0[j] = v1[j];
459 }
460 }
461
462 double threshold = std::max(word1.size() / 3.0, 3.0);
463 int distance = v1[word2.size()];
464
465 free(v0);
466 free(v1);
467
468 return distance <= threshold;
469}
470
423void WordEngine::clearCandidates()471void WordEngine::clearCandidates()
424{472{
425 Q_D(WordEngine);473 Q_D(WordEngine);
426474
=== modified file 'src/lib/logic/wordengine.h'
--- src/lib/logic/wordengine.h 2014-10-29 13:57:51 +0000
+++ src/lib/logic/wordengine.h 2014-11-12 14:55:15 +0000
@@ -82,6 +82,7 @@
82 virtual void fetchCandidates(Model::Text *text);82 virtual void fetchCandidates(Model::Text *text);
83 //! \reimp_end83 //! \reimp_end
84 void calculatePrimaryCandidate();84 void calculatePrimaryCandidate();
85 bool similarWords(QString word1, QString word2);
8586
86 const QScopedPointer<WordEnginePrivate> d_ptr;87 const QScopedPointer<WordEnginePrivate> d_ptr;
8788

Subscribers

People subscribed via source and target branches