Merge lp:~michael-sheldon/ubuntu-keyboard/word-ribbon-tidy-up into lp:ubuntu-keyboard

Proposed by Michael Sheldon
Status: Merged
Approved by: Łukasz Zemczak
Approved revision: 197
Merged at revision: 196
Proposed branch: lp:~michael-sheldon/ubuntu-keyboard/word-ribbon-tidy-up
Merge into: lp:ubuntu-keyboard
Diff against target: 522 lines (+139/-38)
19 files modified
plugins/pinyin/src/pinyinplugin.cpp (+1/-1)
plugins/pinyin/src/pinyinplugin.h (+1/-1)
plugins/westernsupport/predictivetextworker.cpp (+1/-1)
plugins/westernsupport/predictivetextworker.h (+1/-1)
plugins/westernsupport/spellcheckerworker.cpp (+1/-1)
plugins/westernsupport/spellcheckerworker.h (+1/-1)
plugins/westernsupport/westernlanguagesplugin.cpp (+2/-2)
plugins/westernsupport/westernlanguagesplugin.h (+2/-2)
qml/WordRibbon.qml (+1/-1)
src/lib/logic/abstractlanguageplugin.h (+2/-2)
src/lib/logic/abstractwordengine.cpp (+7/-0)
src/lib/logic/abstractwordengine.h (+1/-0)
src/lib/logic/wordengine.cpp (+84/-16)
src/lib/logic/wordengine.h (+7/-2)
src/lib/models/wordcandidate.cpp (+12/-0)
src/lib/models/wordcandidate.h (+4/-0)
src/lib/models/wordribbon.cpp (+4/-0)
src/lib/models/wordribbon.h (+2/-1)
src/view/abstracttexteditor.cpp (+5/-6)
To merge this branch: bzr merge lp:~michael-sheldon/ubuntu-keyboard/word-ribbon-tidy-up
Reviewer Review Type Date Requested Status
Łukasz Zemczak Approve
PS Jenkins bot continuous-integration Approve
Bill Filler (community) Needs Fixing
Review via email: mp+228488@code.launchpad.net

Commit message

Merge user input and primary prediction when they match, highlight auto-completion word instead of user input.

Description of the change

Merge user input and primary prediction when they match, highlight auto-completion word instead of user input.

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?

 * Yes, change to word ribbon UI requested at fit and finish sprint.

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)
Revision history for this message
Bill Filler (bfiller) wrote :

Seems to break a few cases that used to work, or possibly I don't understand the new changes. I have all the switches turned on.

- If I type the word "do", I'm presented with "do" and "don" both bold on the word ribbon. I expected pressing space would insert "do" but it inserts "don".

- Seeing the same thing with "that". It's showing "that" and "than" both highlighted and space selects "than".

It doesn't always do this. Seems to be related to the context of what I'm typing. But I think the bug is there should never be two highlighted words?

review: Needs Fixing
Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

It sounds like maybe there's a race condition with the spell checker and presage both claiming the first candidate, I'll have a look into this when I get back on Friday.

195. By Michael Sheldon

Merge from trunk

196. By Michael Sheldon

Use mutex when receiving new candidates asynchronously from spell checker and word predictor

197. By Michael Sheldon

Keep track of the word that suggestions have been generated for and don't report suggestions that no longer match the current pre-edit text

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Code-wise everything looks fine, all cases seem to be handled pretty nicely. From the testing side everything looks good as well. For a moment I thought pinyin is a bit crashy, but then I checked that the same happens with the old code-base as well (bug will follow). So in overall, a green light from me! A great improvement I must say. Just hope I didn't miss anything, I'm not a big user of auto-completion and preedit ;)

+1.

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/pinyinplugin.cpp'
2--- plugins/pinyin/src/pinyinplugin.cpp 2014-05-07 13:30:05 +0000
3+++ plugins/pinyin/src/pinyinplugin.cpp 2014-08-01 15:45:12 +0000
4@@ -18,7 +18,7 @@
5 {
6 Q_UNUSED(surroundingLeft);
7 pinyinAdapter->parse(preedit);
8- Q_EMIT newPredictionSuggestions(pinyinAdapter->getWordCandidates());
9+ Q_EMIT newPredictionSuggestions(preedit, pinyinAdapter->getWordCandidates());
10 }
11
12 void PinyinPlugin::wordCandidateSelected(QString word)
13
14=== modified file 'plugins/pinyin/src/pinyinplugin.h'
15--- plugins/pinyin/src/pinyinplugin.h 2014-05-07 13:30:05 +0000
16+++ plugins/pinyin/src/pinyinplugin.h 2014-08-01 15:45:12 +0000
17@@ -35,7 +35,7 @@
18 virtual bool setSpellCheckerLanguage(const QString& languageId) { Q_UNUSED(languageId); return false; }
19
20 signals:
21- void newPredictionSuggestions(QStringList suggestions);
22+ void newPredictionSuggestions(QString word, QStringList suggestions);
23
24 public slots:
25
26
27=== modified file 'plugins/westernsupport/predictivetextworker.cpp'
28--- plugins/westernsupport/predictivetextworker.cpp 2014-05-15 14:10:15 +0000
29+++ plugins/westernsupport/predictivetextworker.cpp 2014-08-01 15:45:12 +0000
30@@ -66,7 +66,7 @@
31 qWarning() << "An exception was thrown in libpresage when calling predict(), exception nr: " << error;
32 }
33
34- Q_EMIT newSuggestions(list);
35+ Q_EMIT newSuggestions(preedit, list);
36 }
37
38 void PredictiveTextWorker::setPredictionLanguage(QString locale)
39
40=== modified file 'plugins/westernsupport/predictivetextworker.h'
41--- plugins/westernsupport/predictivetextworker.h 2014-05-15 14:10:15 +0000
42+++ plugins/westernsupport/predictivetextworker.h 2014-08-01 15:45:12 +0000
43@@ -51,7 +51,7 @@
44 void updateSpellCheckWord(QString word);
45
46 signals:
47- void newSuggestions(QStringList suggestions);
48+ void newSuggestions(QString word, QStringList suggestions);
49
50 private:
51 std::string m_candidatesContext;
52
53=== modified file 'plugins/westernsupport/spellcheckerworker.cpp'
54--- plugins/westernsupport/spellcheckerworker.cpp 2014-05-15 14:10:15 +0000
55+++ plugins/westernsupport/spellcheckerworker.cpp 2014-08-01 15:45:12 +0000
56@@ -40,7 +40,7 @@
57 void SpellCheckerWorker::suggest(const QString& word, int limit)
58 {
59 QStringList suggestions = m_spellChecker.suggest(word, limit);
60- Q_EMIT newSuggestions(suggestions);
61+ Q_EMIT newSuggestions(word, suggestions);
62 }
63
64 void SpellCheckerWorker::newSpellCheckWord(QString word)
65
66=== modified file 'plugins/westernsupport/spellcheckerworker.h'
67--- plugins/westernsupport/spellcheckerworker.h 2014-05-15 14:10:15 +0000
68+++ plugins/westernsupport/spellcheckerworker.h 2014-08-01 15:45:12 +0000
69@@ -48,7 +48,7 @@
70 void updateSpellCheckWord(QString word);
71
72 signals:
73- void newSuggestions(QStringList suggestions);
74+ void newSuggestions(QString word, QStringList suggestions);
75
76 private:
77 SpellChecker m_spellChecker;
78
79=== modified file 'plugins/westernsupport/westernlanguagesplugin.cpp'
80--- plugins/westernsupport/westernlanguagesplugin.cpp 2014-05-19 11:53:27 +0000
81+++ plugins/westernsupport/westernlanguagesplugin.cpp 2014-08-01 15:45:12 +0000
82@@ -15,7 +15,7 @@
83 SpellCheckerWorker *spellWorker = new SpellCheckerWorker();
84 spellWorker->moveToThread(m_spellCheckThread);
85
86- connect(spellWorker, SIGNAL(newSuggestions(QStringList)), this, SIGNAL(newSpellingSuggestions(QStringList)));
87+ connect(spellWorker, SIGNAL(newSuggestions(QString, QStringList)), this, SIGNAL(newSpellingSuggestions(QString, QStringList)));
88 connect(this, SIGNAL(newSpellCheckWord(QString)), spellWorker, SLOT(newSpellCheckWord(QString)));
89 connect(this, SIGNAL(setSpellCheckLanguage(QString)), spellWorker, SLOT(setLanguage(QString)));
90 connect(this, SIGNAL(setSpellCheckLimit(int)), spellWorker, SLOT(setLimit(int)));
91@@ -27,7 +27,7 @@
92 PredictiveTextWorker *predictiveWorker = new PredictiveTextWorker();
93 predictiveWorker->moveToThread(m_predictiveTextThread);
94
95- connect(predictiveWorker, SIGNAL(newSuggestions(QStringList)), this, SIGNAL(newPredictionSuggestions(QStringList)));
96+ connect(predictiveWorker, SIGNAL(newSuggestions(QString, QStringList)), this, SIGNAL(newPredictionSuggestions(QString, QStringList)));
97 connect(this, SIGNAL(parsePredictionText(QString, QString)), predictiveWorker, SLOT(parsePredictionText(QString, QString)));
98 connect(this, SIGNAL(setPredictionLanguage(QString)), predictiveWorker, SLOT(setPredictionLanguage(QString)));
99 connect(this, SIGNAL(updateSpellCheckWord(QString)), predictiveWorker, SLOT(updateSpellCheckWord(QString)));
100
101=== modified file 'plugins/westernsupport/westernlanguagesplugin.h'
102--- plugins/westernsupport/westernlanguagesplugin.h 2014-05-19 11:53:27 +0000
103+++ plugins/westernsupport/westernlanguagesplugin.h 2014-08-01 15:45:12 +0000
104@@ -36,8 +36,8 @@
105 virtual bool setSpellCheckerLanguage(const QString& languageId);
106
107 signals:
108- void newSpellingSuggestions(QStringList suggestions);
109- void newPredictionSuggestions(QStringList suggestions);
110+ void newSpellingSuggestions(QString word, QStringList suggestions);
111+ void newPredictionSuggestions(QString word, QStringList suggestions);
112 void newSpellCheckWord(QString word);
113 void setSpellCheckLimit(int limit);
114 void setSpellCheckLanguage(QString language);
115
116=== modified file 'qml/WordRibbon.qml'
117--- qml/WordRibbon.qml 2014-05-20 06:49:39 +0000
118+++ qml/WordRibbon.qml 2014-08-01 15:45:12 +0000
119@@ -57,7 +57,7 @@
120 font.pixelSize: units.gu(2);
121 font.family: "Ubuntu Medium"
122 color: "#999999"
123- font.bold: isUserInput
124+ font.bold: isPrimaryCandidate
125 text: word;
126 }
127 }
128
129=== modified file 'src/lib/logic/abstractlanguageplugin.h'
130--- src/lib/logic/abstractlanguageplugin.h 2014-05-07 13:30:05 +0000
131+++ src/lib/logic/abstractlanguageplugin.h 2014-08-01 15:45:12 +0000
132@@ -54,8 +54,8 @@
133 virtual bool setSpellCheckerLanguage(const QString& languageId);
134
135 signals:
136- void newSpellingSuggestions(QStringList suggestions);
137- void newPredictionSuggestions(QStringList suggestions);
138+ void newSpellingSuggestions(QString word, QStringList suggestions);
139+ void newPredictionSuggestions(QString word, QStringList suggestions);
140 };
141
142 #endif // ABSTRACTLANGUAGEPLUGIN_H
143
144=== modified file 'src/lib/logic/abstractwordengine.cpp'
145--- src/lib/logic/abstractwordengine.cpp 2014-04-24 13:18:54 +0000
146+++ src/lib/logic/abstractwordengine.cpp 2014-08-01 15:45:12 +0000
147@@ -172,6 +172,13 @@
148 Q_UNUSED(on);
149 qDebug() << Q_FUNC_INFO << "should be implemented by inherited class";
150 }
151+
152+void AbstractWordEngine::setAutoCorrectEnabled(bool on)
153+{
154+ Q_UNUSED(on);
155+ qDebug() << Q_FUNC_INFO << "should be implemented by inherited class";
156+}
157+
158 /*
159 AbstractLanguageFeature* AbstractWordEngine::languageFeature()
160 {
161
162=== modified file 'src/lib/logic/abstractwordengine.h'
163--- src/lib/logic/abstractwordengine.h 2014-05-01 14:40:09 +0000
164+++ src/lib/logic/abstractwordengine.h 2014-08-01 15:45:12 +0000
165@@ -64,6 +64,7 @@
166
167 Q_SLOT virtual void setWordPredictionEnabled(bool on);
168 Q_SLOT virtual void setSpellcheckerEnabled(bool on);
169+ Q_SLOT virtual void setAutoCorrectEnabled(bool on);
170
171 void clearCandidates();
172 void computeCandidates(Model::Text *text);
173
174=== modified file 'src/lib/logic/wordengine.cpp'
175--- src/lib/logic/wordengine.cpp 2014-07-23 11:21:23 +0000
176+++ src/lib/logic/wordengine.cpp 2014-08-01 15:45:12 +0000
177@@ -56,12 +56,16 @@
178
179 bool correct_spelling;
180
181+ bool auto_correct_enabled;
182+
183 LanguagePluginInterface* languagePlugin;
184
185 QPluginLoader pluginLoader;
186
187 WordCandidateList* candidates;
188
189+ QString currentPreedit;
190+
191 explicit WordEnginePrivate();
192
193 QString currentPlugin;
194@@ -105,6 +109,7 @@
195 , use_spell_checker(false)
196 , is_preedit_capitalized(false)
197 , correct_spelling(false)
198+ , auto_correct_enabled(false)
199 , languagePlugin(0)
200 {
201 loadPlugin(DEFAULT_PLUGIN);
202@@ -200,6 +205,13 @@
203 Q_EMIT enabledChanged(isEnabled());
204 }
205
206+void WordEngine::setAutoCorrectEnabled(bool enabled)
207+{
208+ Q_D(WordEngine);
209+
210+ d->auto_correct_enabled = enabled;
211+}
212+
213 void WordEngine::onWordCandidateSelected(QString word)
214 {
215 Q_D(WordEngine);
216@@ -211,6 +223,8 @@
217 {
218 Q_D(WordEngine);
219
220+ d->currentPreedit = text->preedit();
221+
222 d->candidates = new WordCandidateList();
223 const QString &preedit(text->preedit());
224 d->is_preedit_capitalized = not preedit.isEmpty() && preedit.at(0).isUpper();
225@@ -240,10 +254,19 @@
226 }
227 }
228
229-void WordEngine::newSpellingSuggestions(QStringList suggestions)
230+void WordEngine::newSpellingSuggestions(QString word, QStringList suggestions)
231 {
232 Q_D(WordEngine);
233
234+ if (word != d->currentPreedit) {
235+ // Don't add suggestions coming in for a previous word
236+ return;
237+ }
238+
239+ // Spelling and prediction suggestions arrive asynchronously
240+ // So we need to ensure only one primary candidate is selected
241+ suggestionMutex.lock();
242+
243 // Only append candidates if we don't have the correct spelling, as these
244 // might be candidates from an earlier version of the word, before it was
245 // spelt correctly
246@@ -252,41 +275,86 @@
247 appendToCandidates(d->candidates, WordCandidate::SourceSpellChecking, correction);
248 }
249
250- Q_EMIT candidatesChanged(*d->candidates);
251-
252- // Candidates always has at least one entry from the user input candidate
253- Q_EMIT primaryCandidateChanged(d->candidates->size() == 1 ? QString()
254- : d->candidates->at(1).label());
255+ calculatePrimaryCandidate();
256 }
257
258 Q_EMIT preeditFaceChanged(d->candidates->size() == 1 ? (d->correct_spelling ? Model::Text::PreeditDefault
259 : Model::Text::PreeditNoCandidates)
260 : Model::Text::PreeditDefault);
261+
262+ suggestionMutex.unlock();
263 }
264
265-void WordEngine::newPredictionSuggestions(QStringList suggestions)
266+void WordEngine::newPredictionSuggestions(QString word, QStringList suggestions)
267 {
268 Q_D(WordEngine);
269
270+ if (word != d->currentPreedit) {
271+ // Don't add suggestions coming in for a previous word
272+ return;
273+ }
274+
275+ // Spelling and prediction suggestions arrive asynchronously
276+ // So we need to ensure only one primary candidate is selected
277+ suggestionMutex.lock();
278+
279 // If the current user entry is a valid word, add this as the first prediction
280 if(d->correct_spelling) {
281 appendToCandidates(d->candidates, WordCandidate::SourceSpellChecking, d->candidates->at(0).word());
282 }
283
284 Q_FOREACH(const QString &correction, suggestions) {
285- if(correction != d->candidates->at(0).word()) { // Don't repeat correctly spelt user word
286- appendToCandidates(d->candidates, WordCandidate::SourceSpellChecking, correction);
287- }
288+ appendToCandidates(d->candidates, WordCandidate::SourceSpellChecking, correction);
289 }
290
291- Q_EMIT candidatesChanged(*d->candidates);
292-
293- Q_EMIT primaryCandidateChanged(d->candidates->size() == 1 ? QString()
294- : d->candidates->at(1).label());
295+ calculatePrimaryCandidate();
296
297 Q_EMIT preeditFaceChanged(d->candidates->size() == 1 ? (d->correct_spelling ? Model::Text::PreeditDefault
298 : Model::Text::PreeditNoCandidates)
299 : Model::Text::PreeditDefault);
300+
301+ suggestionMutex.unlock();
302+}
303+
304+void WordEngine::calculatePrimaryCandidate()
305+{
306+ Q_D(WordEngine);
307+
308+ if (!d->auto_correct_enabled) {
309+ if (d->candidates->size() > 1 && d->candidates->at(0).word() == d->candidates->at(1).word()) {
310+ // Avoid duplicating the user input if the first prediction matches
311+ d->candidates->removeAt(1);
312+ }
313+ Q_EMIT candidatesChanged(*d->candidates);
314+ return;
315+ }
316+
317+ if (d->candidates->size() == 0) {
318+ // We should always have at least one entry due to the user input
319+ qWarning() << __PRETTY_FUNCTION__ << "User candidate missing";
320+ } else if (d->candidates->size() == 1) {
321+ // We don't have any predictions, so the user input is the primary candidate
322+ WordCandidate primary = d->candidates->value(0);
323+ Q_EMIT primaryCandidateChanged(primary.word());
324+ } else if (d->candidates->at(0).word() == d->candidates->at(1).word()) {
325+ // The user candidate matches the first prediction; remove the prediction
326+ // and make the user input the primary candidate so as not to duplicate
327+ // the word.
328+ d->candidates->removeAt(1);
329+ WordCandidate primary = d->candidates->value(0);
330+ primary.setPrimary(true);
331+ d->candidates->replace(0, primary);
332+ Q_EMIT primaryCandidateChanged(primary.word());
333+ } else {
334+ // The first prediction is the primary candidate
335+ WordCandidate primary = d->candidates->value(1);
336+ primary.setPrimary(true);
337+ d->candidates->replace(1, primary);
338+ Q_EMIT primaryCandidateChanged(primary.word());
339+ }
340+
341+ Q_EMIT candidatesChanged(*d->candidates);
342+
343 }
344
345 void WordEngine::addToUserDictionary(const QString &word)
346@@ -342,8 +410,8 @@
347 if (ok)
348 d->languagePlugin->setSpellCheckerEnabled(d->use_spell_checker);
349
350- connect((AbstractLanguagePlugin *) d->languagePlugin, SIGNAL(newSpellingSuggestions(QStringList)), this, SLOT(newSpellingSuggestions(QStringList)));
351- connect((AbstractLanguagePlugin *) d->languagePlugin, SIGNAL(newPredictionSuggestions(QStringList)), this, SLOT(newPredictionSuggestions(QStringList)));
352+ connect((AbstractLanguagePlugin *) d->languagePlugin, SIGNAL(newSpellingSuggestions(QString, QStringList)), this, SLOT(newSpellingSuggestions(QString, QStringList)));
353+ connect((AbstractLanguagePlugin *) d->languagePlugin, SIGNAL(newPredictionSuggestions(QString, QStringList)), this, SLOT(newPredictionSuggestions(QString, QStringList)));
354 }
355
356 AbstractLanguageFeatures* WordEngine::languageFeature()
357
358=== modified file 'src/lib/logic/wordengine.h'
359--- src/lib/logic/wordengine.h 2014-06-30 11:31:44 +0000
360+++ src/lib/logic/wordengine.h 2014-08-01 15:45:12 +0000
361@@ -38,6 +38,7 @@
362 #include "languageplugininterface.h"
363
364 #include <QtCore>
365+#include <QMutex>
366
367 namespace MaliitKeyboard {
368 namespace Logic {
369@@ -61,6 +62,7 @@
370
371 virtual void addToUserDictionary(const QString &word);
372 virtual void setSpellcheckerEnabled(bool enabled);
373+ virtual void setAutoCorrectEnabled(bool enabled);
374 //! \reimp_end
375
376 void appendToCandidates(WordCandidateList *candidates,
377@@ -69,8 +71,8 @@
378
379 Q_SLOT void onWordCandidateSelected(QString word);
380 Q_SLOT void onLanguageChanged(const QString& languageId);
381- Q_SLOT void newSpellingSuggestions(QStringList suggestions);
382- Q_SLOT void newPredictionSuggestions(QStringList suggestions);
383+ Q_SLOT void newSpellingSuggestions(QString word, QStringList suggestions);
384+ Q_SLOT void newPredictionSuggestions(QString word, QStringList suggestions);
385
386 virtual AbstractLanguageFeatures* languageFeature();
387
388@@ -78,8 +80,11 @@
389 //! \reimp
390 virtual void fetchCandidates(Model::Text *text);
391 //! \reimp_end
392+ void calculatePrimaryCandidate();
393
394 const QScopedPointer<WordEnginePrivate> d_ptr;
395+
396+ QMutex suggestionMutex;
397 };
398
399 }} // namespace Logic, MaliitKeyboard
400
401=== modified file 'src/lib/models/wordcandidate.cpp'
402--- src/lib/models/wordcandidate.cpp 2013-11-07 17:43:22 +0000
403+++ src/lib/models/wordcandidate.cpp 2014-08-01 15:45:12 +0000
404@@ -39,6 +39,7 @@
405 , m_label()
406 , m_source(SourceUnknown)
407 , m_word()
408+ , m_primary(false)
409 {}
410
411 WordCandidate::WordCandidate(Source source, const QString &word)
412@@ -47,6 +48,7 @@
413 , m_label()
414 , m_source(source)
415 , m_word(word)
416+ , m_primary(false)
417 {
418 if (source == WordCandidate::SourceUser) {
419 m_label = QString(QT_TR_NOOP("Add '%1' to user dictionary")).arg(word);
420@@ -126,6 +128,16 @@
421 m_word = word;
422 }
423
424+bool WordCandidate::primary() const
425+{
426+ return m_primary;
427+}
428+
429+void WordCandidate::setPrimary(const bool primary)
430+{
431+ m_primary = primary;
432+}
433+
434 bool operator==(const WordCandidate &lhs,
435 const WordCandidate &rhs)
436 {
437
438=== modified file 'src/lib/models/wordcandidate.h'
439--- src/lib/models/wordcandidate.h 2013-11-07 17:43:22 +0000
440+++ src/lib/models/wordcandidate.h 2014-08-01 15:45:12 +0000
441@@ -54,6 +54,7 @@
442 QString m_label;
443 Source m_source;
444 QString m_word;
445+ bool m_primary;
446
447 public:
448 explicit WordCandidate();
449@@ -79,6 +80,9 @@
450
451 QString word() const;
452 void setWord(const QString &word);
453+
454+ bool primary() const;
455+ void setPrimary(const bool primary);
456 };
457
458 typedef QList<WordCandidate> WordCandidateList;
459
460=== modified file 'src/lib/models/wordribbon.cpp'
461--- src/lib/models/wordribbon.cpp 2014-05-15 14:10:15 +0000
462+++ src/lib/models/wordribbon.cpp 2014-08-01 15:45:12 +0000
463@@ -42,6 +42,7 @@
464 {
465 m_roles.insert(WordRole, "word");
466 m_roles.insert(IsUserInputRole, "isUserInput");
467+ m_roles.insert(IsPrimaryCandidateRole, "isPrimaryCandidate");
468 }
469
470 bool WordRibbon::valid() const
471@@ -128,6 +129,9 @@
472 case WordRibbon::IsUserInputRole:
473 return m_candidates.at(index.row()).source() == WordCandidate::SourceUser;
474 break;
475+ case WordRibbon::IsPrimaryCandidateRole:
476+ return m_candidates.at(index.row()).primary();
477+ break;
478 default:
479 break;
480 }
481
482=== modified file 'src/lib/models/wordribbon.h'
483--- src/lib/models/wordribbon.h 2014-05-14 15:48:09 +0000
484+++ src/lib/models/wordribbon.h 2014-08-01 15:45:12 +0000
485@@ -58,7 +58,8 @@
486
487 enum WordRibbonRoles {
488 WordRole = Qt::UserRole + 1,
489- IsUserInputRole
490+ IsUserInputRole,
491+ IsPrimaryCandidateRole
492 };
493
494 virtual QVariant data(const QModelIndex &index, int role) const;
495
496=== modified file 'src/view/abstracttexteditor.cpp'
497--- src/view/abstracttexteditor.cpp 2014-07-25 10:15:16 +0000
498+++ src/view/abstracttexteditor.cpp 2014-08-01 15:45:12 +0000
499@@ -360,6 +360,9 @@
500
501 connect(word_engine, SIGNAL(primaryCandidateChanged(QString)),
502 this, SLOT(setPrimaryCandidate(QString)));
503+
504+ connect(this, SIGNAL(autoCorrectEnabledChanged(bool)),
505+ word_engine, SLOT(setAutoCorrectEnabled(bool)));
506
507 setPreeditEnabled(word_engine->isEnabled());
508 }
509@@ -899,12 +902,8 @@
510 d->text->removeFromPreedit(1);
511 textOnLeft += d->text->preedit();
512
513- // Don't find word candidates if the user is holding down backspace
514- if(!d->repeating_backspace) {
515- d->word_engine->computeCandidates(d->text.data());
516- } else {
517- Q_EMIT wordCandidatesChanged(WordCandidateList());
518- }
519+ // Clear previous word candidates
520+ Q_EMIT wordCandidatesChanged(WordCandidateList());
521 sendPreeditString(d->text->preedit(), d->text->preeditFace(),
522 Replacement());
523

Subscribers

People subscribed via source and target branches