summaryrefslogtreecommitdiff
path: root/inputmethods/handwriting
Unidiff
Diffstat (limited to 'inputmethods/handwriting') (more/less context) (show whitespace changes)
-rw-r--r--inputmethods/handwriting/qimpenchar.cpp9
-rw-r--r--inputmethods/handwriting/qimpeninput.cpp24
-rw-r--r--inputmethods/handwriting/qimpenmatch.cpp35
-rw-r--r--inputmethods/handwriting/qimpenstroke.cpp15
-rw-r--r--inputmethods/handwriting/qimpenwordpick.cpp2
5 files changed, 45 insertions, 40 deletions
diff --git a/inputmethods/handwriting/qimpenchar.cpp b/inputmethods/handwriting/qimpenchar.cpp
index 929f370..db5d135 100644
--- a/inputmethods/handwriting/qimpenchar.cpp
+++ b/inputmethods/handwriting/qimpenchar.cpp
@@ -17,24 +17,25 @@
17 ** not clear to you. 17 ** not clear to you.
18 ** 18 **
19 **********************************************************************/ 19 **********************************************************************/
20 20
21#include <qfile.h> 21#include <qfile.h>
22#include <qtl.h> 22#include <qtl.h>
23#include <math.h> 23#include <math.h>
24#include <limits.h> 24#include <limits.h>
25#include <errno.h> 25#include <errno.h>
26#include <qdatastream.h> 26#include <qdatastream.h>
27#include "qimpencombining.h" 27#include "qimpencombining.h"
28#include "qimpenchar.h" 28#include "qimpenchar.h"
29#include "opie2/odebug.h"
29 30
30 #define QIMPEN_MATCH_THRESHOLD 200000 31 #define QIMPEN_MATCH_THRESHOLD 200000
31 32
32const QIMPenSpecialKeys qimpen_specialKeys[] = { 33const QIMPenSpecialKeys qimpen_specialKeys[] = {
33 { Qt::Key_Escape, "[Esc]" }, 34 { Qt::Key_Escape, "[Esc]" },
34 { Qt::Key_Tab, "[Tab]" }, 35 { Qt::Key_Tab, "[Tab]" },
35 { Qt::Key_Backspace,"[BackSpace]" }, 36 { Qt::Key_Backspace,"[BackSpace]" },
36 { Qt::Key_Return, "[Return]" }, 37 { Qt::Key_Return, "[Return]" },
37 { QIMPenChar::Caps, "[Uppercase]" }, 38 { QIMPenChar::Caps, "[Uppercase]" },
38 { QIMPenChar::CapsLock,"[Caps Lock]" }, 39 { QIMPenChar::CapsLock,"[Caps Lock]" },
39 { QIMPenChar::Shortcut,"[Shortcut]" }, 40 { QIMPenChar::Shortcut,"[Shortcut]" },
40 { QIMPenChar::Punctuation, "[Punctuation]" }, 41 { QIMPenChar::Punctuation, "[Punctuation]" },
@@ -158,40 +159,40 @@ int QIMPenChar::match( QIMPenChar *pen )
158 QPoint p1 = it1.current()->boundingRect().center() - 159 QPoint p1 = it1.current()->boundingRect().center() -
159 strokes.getFirst()->boundingRect().center(); 160 strokes.getFirst()->boundingRect().center();
160 QPoint p2 = it2.current()->boundingRect().center() - 161 QPoint p2 = it2.current()->boundingRect().center() -
161 pen->strokes.getFirst()->boundingRect().center(); 162 pen->strokes.getFirst()->boundingRect().center();
162 int xdiff = QABS( p1.x() - p2.x() ) - 6; 163 int xdiff = QABS( p1.x() - p2.x() ) - 6;
163 int ydiff = QABS( p1.y() - p2.y() ) - 5; 164 int ydiff = QABS( p1.y() - p2.y() ) - 5;
164 if ( xdiff < 0 ) 165 if ( xdiff < 0 )
165 xdiff = 0; 166 xdiff = 0;
166 if ( ydiff < 0 ) 167 if ( ydiff < 0 )
167 ydiff = 0; 168 ydiff = 0;
168 if ( xdiff > 10 || ydiff > 10 ) { // not a chance 169 if ( xdiff > 10 || ydiff > 10 ) { // not a chance
169#ifdef DEBUG_QIMPEN 170#ifdef DEBUG_QIMPEN
170 qDebug( "char %c, stroke starting pt diff excessive", pen->ch ); 171 odebug << "char " << pen->ch <<", stroke starting pt diff excessive" << oendl;
171#endif 172#endif
172 return INT_MAX; 173 return INT_MAX;
173 } 174 }
174 diff += xdiff*xdiff + ydiff*ydiff; 175 diff += xdiff*xdiff + ydiff*ydiff;
175 err = it1.current()->match( it2.current() ); 176 err = it1.current()->match( it2.current() );
176 if ( err > maxErr ) 177 if ( err > maxErr )
177 maxErr = err; 178 maxErr = err;
178 ++it1; 179 ++it1;
179 ++it2; 180 ++it2;
180 } 181 }
181 182
182 maxErr += diff * diff * 6; // magic weighting :) 183 maxErr += diff * diff * 6; // magic weighting :)
183 184
184#ifdef DEBUG_QIMPEN 185#ifdef DEBUG_QIMPEN
185 qDebug( "char: %c, maxErr %d, diff %d, (%d)", pen->ch, maxErr, diff, strokes.count() ); 186 odebug << "char: " << pen->ch << ", maxErr " << maxErr << ", diff " << diff << ", " << strokes.count() << oendl;
186#endif 187#endif
187 return maxErr; 188 return maxErr;
188} 189}
189 190
190/*! 191/*!
191 Return the bounding rect of this character. It may have sides with 192 Return the bounding rect of this character. It may have sides with
192 negative coords since its origin is where the user started drawing 193 negative coords since its origin is where the user started drawing
193 the character. 194 the character.
194 */ 195 */
195QRect QIMPenChar::boundingRect() 196QRect QIMPenChar::boundingRect()
196{ 197{
197 QRect br; 198 QRect br;
@@ -449,26 +450,26 @@ QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch )
449 QIMPenCharMatch m; 450 QIMPenCharMatch m;
450 m.error = err; 451 m.error = err;
451 m.penChar = tmplChar; 452 m.penChar = tmplChar;
452 matches.append( m ); 453 matches.append( m );
453 } 454 }
454 } 455 }
455 } 456 }
456 } 457 }
457 qHeapSort( matches ); 458 qHeapSort( matches );
458 /* 459 /*
459 QIMPenCharMatchList::Iterator it; 460 QIMPenCharMatchList::Iterator it;
460 for ( it = matches.begin(); it != matches.end(); ++it ) { 461 for ( it = matches.begin(); it != matches.end(); ++it ) {
461 qDebug( "Match: \'%c\', error %d, strokes %d", (*it).penChar->character(), 462
462 (*it).error, (*it).penChar->penStrokes().count() ); 463 odebug << "Match: \'" << (*it).penChar->character() "\', error " << (*it).error ", strokes " <<(*it).penChar->penStrokes().count() << oendl;
463 } 464 }
464 */ 465 */
465 return matches; 466 return matches;
466} 467}
467 468
468/*! 469/*!
469 Add a character \a ch to this set. 470 Add a character \a ch to this set.
470 QIMPenCharSet will delete this character when it is no longer needed. 471 QIMPenCharSet will delete this character when it is no longer needed.
471 */ 472 */
472void QIMPenCharSet::addChar( QIMPenChar *ch ) 473void QIMPenCharSet::addChar( QIMPenChar *ch )
473{ 474{
474 if ( ch->penStrokes().count() > maxStrokes ) 475 if ( ch->penStrokes().count() > maxStrokes )
diff --git a/inputmethods/handwriting/qimpeninput.cpp b/inputmethods/handwriting/qimpeninput.cpp
index d073cdf..6ea1bb4 100644
--- a/inputmethods/handwriting/qimpeninput.cpp
+++ b/inputmethods/handwriting/qimpeninput.cpp
@@ -27,24 +27,25 @@
27#include "qimpenhelp.h" 27#include "qimpenhelp.h"
28 28
29#include <qpe/qpeapplication.h> 29#include <qpe/qpeapplication.h>
30#include <qpe/qdawg.h> 30#include <qpe/qdawg.h>
31#include <qpe/config.h> 31#include <qpe/config.h>
32#include <qpe/global.h> 32#include <qpe/global.h>
33 33
34#include <qlayout.h> 34#include <qlayout.h>
35#include <qpushbutton.h> 35#include <qpushbutton.h>
36#include <qlabel.h> 36#include <qlabel.h>
37#include <qtimer.h> 37#include <qtimer.h>
38#include <qdir.h> 38#include <qdir.h>
39#include <opie2/odebug.h>
39 40
40#include <limits.h> 41#include <limits.h>
41 42
42// We'll use little pixmaps for the buttons to save screen space. 43// We'll use little pixmaps for the buttons to save screen space.
43 44
44/* XPM */ 45/* XPM */
45static const char * const pen_xpm[] = { 46static const char * const pen_xpm[] = {
46"12 12 4 1", 47"12 12 4 1",
47 " c None", 48 " c None",
48 ".c #000000", 49 ".c #000000",
49 "+c #FFFFFF", 50 "+c #FFFFFF",
50 "@c #808080", 51 "@c #808080",
@@ -310,25 +311,25 @@ void QIMPenInput::wordPicked( const QString &w )
310 keypress( Qt::Key_Backspace << 16 ); 311 keypress( Qt::Key_Backspace << 16 );
311 312
312 for ( unsigned int i = 0; i < w.length(); i++ ) 313 for ( unsigned int i = 0; i < w.length(); i++ )
313 keypress( w[i].unicode() ); 314 keypress( w[i].unicode() );
314 315
315 matcher->resetState(); 316 matcher->resetState();
316 wordPicker->clear(); 317 wordPicker->clear();
317} 318}
318 319
319void QIMPenInput::selectCharSet( int idx ) 320void QIMPenInput::selectCharSet( int idx )
320{ 321{
321 if ( mode == Switch ) { 322 if ( mode == Switch ) {
322 //qDebug( "Switch back to normal" ); 323 //odebug << "Switch back to normal" << oendl;
323 pw->changeCharSet( baseSets.at(currCharSet), currCharSet ); 324 pw->changeCharSet( baseSets.at(currCharSet), currCharSet );
324 mode = Normal; 325 mode = Normal;
325 } 326 }
326 currCharSet = idx; 327 currCharSet = idx;
327} 328}
328 329
329void QIMPenInput::beginStroke() 330void QIMPenInput::beginStroke()
330{ 331{
331} 332}
332 333
333void QIMPenInput::strokeEntered( QIMPenStroke * ) 334void QIMPenInput::strokeEntered( QIMPenStroke * )
334{ 335{
@@ -344,67 +345,68 @@ void QIMPenInput::matchedCharacters( const QIMPenCharMatchList &cl )
344{ 345{
345 const QIMPenChar *ch = cl.first().penChar; 346 const QIMPenChar *ch = cl.first().penChar;
346 int scan = ch->character() >> 16; 347 int scan = ch->character() >> 16;
347 348
348 if ( scan < QIMPenChar::ModeBase ) 349 if ( scan < QIMPenChar::ModeBase )
349 return; 350 return;
350 351
351 // We matched a special character... 352 // We matched a special character...
352 353
353 switch ( scan ) { 354 switch ( scan ) {
354 case QIMPenChar::Caps: 355 case QIMPenChar::Caps:
355 if ( profile->style() == QIMPenProfile::ToggleCases ) { 356 if ( profile->style() == QIMPenProfile::ToggleCases ) {
356 // qDebug( "Caps" ); 357 // odebug << "Caps" << oendl;
358 //
357 if ( mode == SwitchLock ) { 359 if ( mode == SwitchLock ) {
358 // qDebug( "Switch to normal" ); 360 // odebug << "Switch to normal" << oendl;
359 pw->changeCharSet( profile->lowercase(), currCharSet ); 361 pw->changeCharSet( profile->lowercase(), currCharSet );
360 mode = Switch; 362 mode = Switch;
361 } else { 363 } else {
362 // qDebug( "Switch to upper" ); 364 // odebug << "Switch to upper" << oendl;
363 pw->changeCharSet( profile->uppercase(), currCharSet ); 365 pw->changeCharSet( profile->uppercase(), currCharSet );
364 mode = Switch; 366 mode = Switch;
365 } 367 }
366 } 368 }
367 break; 369 break;
368 case QIMPenChar::CapsLock: 370 case QIMPenChar::CapsLock:
369 if ( profile->style() == QIMPenProfile::ToggleCases ) { 371 if ( profile->style() == QIMPenProfile::ToggleCases ) {
370 // qDebug( "CapsLock" ); 372 // odebug << "CapsLock" << oendl;
371 if ( mode == Switch && 373 if ( mode == Switch &&
372 baseSets.at(currCharSet) == profile->uppercase() ) { 374 baseSets.at(currCharSet) == profile->uppercase() ) {
373 // qDebug( "Switch to normal" ); 375 // odebug << "Switch to normal" << oendl;
374 pw->changeCharSet( profile->lowercase(), currCharSet ); 376 pw->changeCharSet( profile->lowercase(), currCharSet );
375 // change our base set back to lower. 377 // change our base set back to lower.
376 baseSets.remove( currCharSet ); 378 baseSets.remove( currCharSet );
377 baseSets.insert( currCharSet, profile->lowercase() ); 379 baseSets.insert( currCharSet, profile->lowercase() );
378 mode = Normal; 380 mode = Normal;
379 } else { 381 } else {
380 // qDebug( "Switch to caps lock" ); 382 // odebug << "Switch to caps lock" << oendl;
381 pw->changeCharSet( profile->uppercase(), currCharSet ); 383 pw->changeCharSet( profile->uppercase(), currCharSet );
382 // change our base set to upper. 384 // change our base set to upper.
383 baseSets.remove( currCharSet ); 385 baseSets.remove( currCharSet );
384 baseSets.insert( currCharSet, profile->uppercase() ); 386 baseSets.insert( currCharSet, profile->uppercase() );
385 mode = SwitchLock; 387 mode = SwitchLock;
386 } 388 }
387 } 389 }
388 break; 390 break;
389 case QIMPenChar::Punctuation: 391 case QIMPenChar::Punctuation:
390 if ( profile->punctuation() ) { 392 if ( profile->punctuation() ) {
391 //qDebug( "Switch to punctuation" ); 393 //odebug << "Switch to punctuation" << oendl;
392 pw->changeCharSet( profile->punctuation(), currCharSet ); 394 pw->changeCharSet( profile->punctuation(), currCharSet );
393 mode = Switch; 395 mode = Switch;
394 } 396 }
395 break; 397 break;
396 case QIMPenChar::Symbol: 398 case QIMPenChar::Symbol:
397 if ( profile->symbol() ) { 399 if ( profile->symbol() ) {
398 //qDebug( "Switch to symbol" ); 400 //odebug << "Switch to symbol" << oendl ;
399 pw->changeCharSet( profile->symbol(), currCharSet ); 401 pw->changeCharSet( profile->symbol(), currCharSet );
400 mode = Switch; 402 mode = Switch;
401 } 403 }
402 break; 404 break;
403 case QIMPenChar::Shortcut: 405 case QIMPenChar::Shortcut:
404 if ( shortcutCharSet ) { 406 if ( shortcutCharSet ) {
405 pw->changeCharSet( shortcutCharSet, currCharSet ); 407 pw->changeCharSet( shortcutCharSet, currCharSet );
406 mode = Switch; 408 mode = Switch;
407 } 409 }
408 break; 410 break;
409 case QIMPenChar::Extended: 411 case QIMPenChar::Extended:
410 handleExtended( ch->data() ); 412 handleExtended( ch->data() );
@@ -434,41 +436,41 @@ void QIMPenInput::keypress( uint scan_uni )
434 break; 436 break;
435 case Key_Backspace: 437 case Key_Backspace:
436 scan_uni = 8; 438 scan_uni = 8;
437 break; 439 break;
438 case Key_Escape: 440 case Key_Escape:
439 scan_uni = 27; 441 scan_uni = 27;
440 break; 442 break;
441 default: 443 default:
442 break; 444 break;
443 } 445 }
444 446
445 if ( mode == Switch ) { 447 if ( mode == Switch ) {
446 //qDebug( "Switch back to normal" ); 448 //odebug << "Switch back to normal" << oendl ;
447 pw->changeCharSet( baseSets.at(currCharSet), currCharSet ); 449 pw->changeCharSet( baseSets.at(currCharSet), currCharSet );
448 if ( baseSets.at(currCharSet) == profile->uppercase() ) 450 if ( baseSets.at(currCharSet) == profile->uppercase() )
449 mode = SwitchLock; 451 mode = SwitchLock;
450 else 452 else
451 mode = Normal; 453 mode = Normal;
452 } 454 }
453 455
454 emit key( scan_uni&0xffff, scan, 0, true, false ); 456 emit key( scan_uni&0xffff, scan, 0, true, false );
455 emit key( scan_uni&0xffff, scan, 0, false, false ); 457 emit key( scan_uni&0xffff, scan, 0, false, false );
456} 458}
457 459
458void QIMPenInput::handleExtended( const QString &ex ) 460void QIMPenInput::handleExtended( const QString &ex )
459{ 461{
460 if ( ex.find( "Select" ) == 0 ) { 462 if ( ex.find( "Select" ) == 0 ) {
461 QString set = ex.mid( 7 ); 463 QString set = ex.mid( 7 );
462 qDebug( "Select new profile: %s", set.latin1() ); 464 odebug << "Select new profile: " << set.latin1() << oendl;
463 selectProfile( set ); 465 selectProfile( set );
464 } 466 }
465} 467}
466 468
467void QIMPenInput::help() 469void QIMPenInput::help()
468{ 470{
469 if ( helpDlg ) 471 if ( helpDlg )
470 delete (HandwritingHelp*) helpDlg; 472 delete (HandwritingHelp*) helpDlg;
471 helpDlg = new HandwritingHelp( profile, 0, 0, WDestructiveClose ); 473 helpDlg = new HandwritingHelp( profile, 0, 0, WDestructiveClose );
472 helpDlg->showMaximized(); 474 helpDlg->showMaximized();
473 helpDlg->show(); 475 helpDlg->show();
474 helpDlg->raise(); 476 helpDlg->raise();
diff --git a/inputmethods/handwriting/qimpenmatch.cpp b/inputmethods/handwriting/qimpenmatch.cpp
index 0d3e25a..a0448b6 100644
--- a/inputmethods/handwriting/qimpenmatch.cpp
+++ b/inputmethods/handwriting/qimpenmatch.cpp
@@ -16,24 +16,25 @@
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include "qimpenmatch.h" 21#include "qimpenmatch.h"
22 22
23#include <qpe/qdawg.h> 23#include <qpe/qdawg.h>
24#include <qpe/global.h> 24#include <qpe/global.h>
25 25
26#include <qapplication.h> 26#include <qapplication.h>
27#include <qtimer.h> 27#include <qtimer.h>
28#include <opie2/odebug.h>
28 29
29#include <limits.h> 30#include <limits.h>
30 31
31 #define ERROR_THRESHOLD 200000 32 #define ERROR_THRESHOLD 200000
32 #define LOOKAHEAD_ERROR 2500 33 #define LOOKAHEAD_ERROR 2500
33//#define DEBUG_QIMPEN 34//#define DEBUG_QIMPEN
34 35
35QIMPenMatch::QIMPenMatch( QObject *parent, const char *name ) 36QIMPenMatch::QIMPenMatch( QObject *parent, const char *name )
36 : QObject( parent, name ) 37 : QObject( parent, name )
37{ 38{
38 strokes.setAutoDelete( TRUE ); 39 strokes.setAutoDelete( TRUE );
39 wordChars.setAutoDelete( TRUE ); 40 wordChars.setAutoDelete( TRUE );
@@ -59,154 +60,154 @@ void QIMPenMatch::setCharSet( QIMPenCharSet *cs )
59{ 60{
60 charSet = cs; 61 charSet = cs;
61} 62}
62 63
63void QIMPenMatch::beginStroke() 64void QIMPenMatch::beginStroke()
64{ 65{
65 multiTimer->stop(); 66 multiTimer->stop();
66} 67}
67 68
68void QIMPenMatch::strokeEntered( QIMPenStroke *st ) 69void QIMPenMatch::strokeEntered( QIMPenStroke *st )
69{ 70{
70#ifdef DEBUG_QIMPEN 71#ifdef DEBUG_QIMPEN
71 qDebug( "---------- new stroke -------------" ); 72 odebug << "---------- new stroke -------------" << oendl;
72#endif 73#endif
73 strokes.append( new QIMPenStroke( *st ) ); 74 strokes.append( new QIMPenStroke( *st ) );
74 75
75 QIMPenChar testChar; 76 QIMPenChar testChar;
76 QIMPenStrokeIterator it(strokes); 77 QIMPenStrokeIterator it(strokes);
77 for ( ; it.current(); ++it ) { 78 for ( ; it.current(); ++it ) {
78 testChar.addStroke( it.current() ); 79 testChar.addStroke( it.current() );
79 } 80 }
80 81
81 QIMPenCharMatchList ml; 82 QIMPenCharMatchList ml;
82 if ( strokes.count() > 1 && multiCharSet ) { 83 if ( strokes.count() > 1 && multiCharSet ) {
83#ifdef DEBUG_QIMPEN 84#ifdef DEBUG_QIMPEN
84 qDebug( "Matching against multi set" ); 85 odebug << "Matching against multi set" << oendl;
85#endif 86#endif
86 ml = multiCharSet->match( &testChar ); 87 ml = multiCharSet->match( &testChar );
87 } else { 88 } else {
88#ifdef DEBUG_QIMPEN 89#ifdef DEBUG_QIMPEN
89 qDebug( "Matching against single set" ); 90 odebug << "Matching against single set" << oendl;
90#endif 91#endif
91 ml = charSet->match( &testChar ); 92 ml = charSet->match( &testChar );
92 } 93 }
93 94
94 processMatches( ml ); 95 processMatches( ml );
95} 96}
96 97
97void QIMPenMatch::processMatches( QIMPenCharMatchList &ml ) 98void QIMPenMatch::processMatches( QIMPenCharMatchList &ml )
98{ 99{
99#ifdef DEBUG_QIMPEN 100#ifdef DEBUG_QIMPEN
100 qDebug( "Entering strokes.count() = %d", strokes.count() ); 101 odebug << "Entering strokes.count() = " << strokes.count() << oendl;
101#endif 102#endif
102 QIMPenCharMatch candidate1 = { INT_MAX, 0 }; 103 QIMPenCharMatch candidate1 = { INT_MAX, 0 };
103 QIMPenCharMatch candidate2 = { INT_MAX, 0 }; 104 QIMPenCharMatch candidate2 = { INT_MAX, 0 };
104 QIMPenCharMatchList ml2; 105 QIMPenCharMatchList ml2;
105 106
106 if ( ml.count() ) {//&& 107 if ( ml.count() ) {//&&
107 // ml.first().penChar->penStrokes().count() == strokes.count() ) { 108 // ml.first().penChar->penStrokes().count() == strokes.count() ) {
108 candidate1 = ml.first(); 109 candidate1 = ml.first();
109#ifdef DEBUG_QIMPEN 110#ifdef DEBUG_QIMPEN
110 qDebug( QString("Candidate1 = %1").arg(QChar(candidate1.penChar->character())) ); 111 odebug << "Candidate1 = " << candidate1.penChar->character() << oendl;
111#endif 112#endif
112 } 113 }
113 114
114 if ( strokes.count() > 1 ) { 115 if ( strokes.count() > 1 ) {
115 // See if the last stroke can match a new character 116 // See if the last stroke can match a new character
116 QIMPenChar testChar; 117 QIMPenChar testChar;
117 QIMPenStroke *st = strokes.at(strokes.count()-1); 118 QIMPenStroke *st = strokes.at(strokes.count()-1);
118 testChar.addStroke( st ); 119 testChar.addStroke( st );
119 ml2 = charSet->match( &testChar ); 120 ml2 = charSet->match( &testChar );
120 if ( ml2.count() ) { 121 if ( ml2.count() ) {
121 candidate2 = ml2.first(); 122 candidate2 = ml2.first();
122#ifdef DEBUG_QIMPEN 123#ifdef DEBUG_QIMPEN
123 qDebug( QString("Candidate2 = %1").arg(QChar(candidate2.penChar->character())) ); 124 odebug << "Candidate2 = " << candidate2.penChar->character() << oendl;
124#endif 125#endif
125 } 126 }
126 } 127 }
127 128
128 bool eraseLast = FALSE; 129 bool eraseLast = FALSE;
129 bool output = TRUE; 130 bool output = TRUE;
130 131
131 if ( candidate1.penChar && candidate2.penChar ) { 132 if ( candidate1.penChar && candidate2.penChar ) {
132 // Hmmm, a multi-stroke or a new character are both possible. 133 // Hmmm, a multi-stroke or a new character are both possible.
133 // Bias the multi-stroke case. 134 // Bias the multi-stroke case.
134 if ( QMAX(candidate2.error, prevMatchError)*3 < candidate1.error ) { 135 if ( QMAX(candidate2.error, prevMatchError)*3 < candidate1.error ) {
135 int i = strokes.count()-1; 136 int i = strokes.count()-1;
136 while ( i-- ) { 137 while ( i-- ) {
137 strokes.removeFirst(); 138 strokes.removeFirst();
138 emit removeStroke(); 139 emit removeStroke();
139 } 140 }
140 prevMatchChar = candidate2.penChar; 141 prevMatchChar = candidate2.penChar;
141 prevMatchError = candidate2.error; 142 prevMatchError = candidate2.error;
142 multiCharSet = charSet; 143 multiCharSet = charSet;
143 ml = ml2; 144 ml = ml2;
144#ifdef DEBUG_QIMPEN 145#ifdef DEBUG_QIMPEN
145 qDebug( "** Using Candidate2" ); 146 odebug << "** Using Candidate2" << oendl;
146#endif 147#endif
147 } else { 148 } else {
148 if ( (prevMatchChar->character() >> 16) != Qt::Key_Backspace && 149 if ( (prevMatchChar->character() >> 16) != Qt::Key_Backspace &&
149 (prevMatchChar->character() >> 16) < QIMPenChar::ModeBase ) 150 (prevMatchChar->character() >> 16) < QIMPenChar::ModeBase )
150 eraseLast = TRUE; 151 eraseLast = TRUE;
151 prevMatchChar = candidate1.penChar; 152 prevMatchChar = candidate1.penChar;
152 prevMatchError = candidate1.error; 153 prevMatchError = candidate1.error;
153#ifdef DEBUG_QIMPEN 154#ifdef DEBUG_QIMPEN
154 qDebug( "** Using Candidate1, with erase" ); 155 odebug << "** Using Candidate1, with erase" << oendl;
155#endif 156#endif
156 } 157 }
157 } else if ( candidate1.penChar ) { 158 } else if ( candidate1.penChar ) {
158 if ( strokes.count() != 1 ) 159 if ( strokes.count() != 1 )
159 eraseLast = TRUE; 160 eraseLast = TRUE;
160 else 161 else
161 multiCharSet = charSet; 162 multiCharSet = charSet;
162 prevMatchChar = candidate1.penChar; 163 prevMatchChar = candidate1.penChar;
163 prevMatchError = candidate1.error; 164 prevMatchError = candidate1.error;
164#ifdef DEBUG_QIMPEN 165#ifdef DEBUG_QIMPEN
165 qDebug( "** Using Candidate1" ); 166 odebug << "** Using Candidate1" << oendl;
166#endif 167#endif
167 } else if ( candidate2.penChar ) { 168 } else if ( candidate2.penChar ) {
168 int i = strokes.count()-1; 169 int i = strokes.count()-1;
169 while ( i-- ) { 170 while ( i-- ) {
170 strokes.removeFirst(); 171 strokes.removeFirst();
171 emit removeStroke(); 172 emit removeStroke();
172 } 173 }
173 prevMatchChar = candidate2.penChar; 174 prevMatchChar = candidate2.penChar;
174 prevMatchError = candidate2.error; 175 prevMatchError = candidate2.error;
175 multiCharSet = charSet; 176 multiCharSet = charSet;
176 ml = ml2; 177 ml = ml2;
177#ifdef DEBUG_QIMPEN 178#ifdef DEBUG_QIMPEN
178 qDebug( "** Using Candidate2" ); 179 odebug << "** Using Candidate2" << oendl;
179#endif 180#endif
180 } else { 181 } else {
181 if ( !ml.count() ) { 182 if ( !ml.count() ) {
182#ifdef DEBUG_QIMPEN 183#ifdef DEBUG_QIMPEN
183 qDebug( "** Failed" ); 184 odebug << "** Failed" << oendl;
184#endif 185#endif
185 canErase = FALSE; 186 canErase = FALSE;
186 } else { 187 } else {
187#ifdef DEBUG_QIMPEN 188#ifdef DEBUG_QIMPEN
188 qDebug( "Need more strokes" ); 189 odebug << "Need more strokes" << oendl;
189#endif 190#endif
190 if ( strokes.count() == 1 ) 191 if ( strokes.count() == 1 )
191 canErase = FALSE; 192 canErase = FALSE;
192 multiCharSet = charSet; 193 multiCharSet = charSet;
193 } 194 }
194 output = FALSE; 195 output = FALSE;
195 emit noMatch(); 196 emit noMatch();
196 } 197 }
197 198
198 if ( eraseLast && canErase ) { 199 if ( eraseLast && canErase ) {
199#ifdef DEBUG_QIMPEN 200#ifdef DEBUG_QIMPEN
200 qDebug( "deleting last" ); 201 odebug << "deleting last" << oendl;
201#endif 202#endif
202 emit erase(); 203 emit erase();
203 wordChars.removeLast(); 204 wordChars.removeLast();
204 wordEntered.truncate( wordEntered.length() - 1 ); 205 wordEntered.truncate( wordEntered.length() - 1 );
205 } 206 }
206 207
207 if ( output ) { 208 if ( output ) {
208 emit matchedCharacters( ml ); 209 emit matchedCharacters( ml );
209 uint code = prevMatchChar->character() >> 16; 210 uint code = prevMatchChar->character() >> 16;
210 if ( code < QIMPenChar::ModeBase ) { 211 if ( code < QIMPenChar::ModeBase ) {
211 updateWordMatch( ml ); 212 updateWordMatch( ml );
212 emit keypress( prevMatchChar->character() ); 213 emit keypress( prevMatchChar->character() );
@@ -219,30 +220,30 @@ void QIMPenMatch::processMatches( QIMPenCharMatchList &ml )
219} 220}
220 221
221void QIMPenMatch::updateWordMatch( QIMPenCharMatchList &ml ) 222void QIMPenMatch::updateWordMatch( QIMPenCharMatchList &ml )
222{ 223{
223 if ( !ml.count() || !doWordMatching ) 224 if ( !ml.count() || !doWordMatching )
224 return; 225 return;
225 int ch = ml.first().penChar->character(); 226 int ch = ml.first().penChar->character();
226 QChar qch( ch ); 227 QChar qch( ch );
227 int code = ch >> 16; 228 int code = ch >> 16;
228 if ( qch.isPunct() || qch.isSpace() || 229 if ( qch.isPunct() || qch.isSpace() ||
229 code == Qt::Key_Enter || code == Qt::Key_Return || 230 code == Qt::Key_Enter || code == Qt::Key_Return ||
230 code == Qt::Key_Tab || code == Qt::Key_Escape ) { 231 code == Qt::Key_Tab || code == Qt::Key_Escape ) {
231 //qDebug( "Word Matching: Clearing word" ); 232 //odebug << "Word Matching: Clearing word" << oendl;
232 wordChars.clear(); 233 wordChars.clear();
233 wordMatches.clear(); 234 wordMatches.clear();
234 wordEntered = QString(); 235 wordEntered = QString();
235 } else if ( code == Qt::Key_Backspace ) { 236 } else if ( code == Qt::Key_Backspace ) {
236 //qDebug( "Word Matching: Handle backspace" ); 237 //odebug << "Word Matching: Handle backspace" << oendl;
237 wordChars.removeLast(); 238 wordChars.removeLast();
238 wordEntered.truncate( wordEntered.length() - 1 ); 239 wordEntered.truncate( wordEntered.length() - 1 );
239 matchWords(); 240 matchWords();
240 } else { 241 } else {
241 QIMPenChar *matchCh; 242 QIMPenChar *matchCh;
242 243
243 wordChars.append( new QIMPenCharMatchList() ); 244 wordChars.append( new QIMPenCharMatchList() );
244 wordEntered += ml.first().penChar->character(); 245 wordEntered += ml.first().penChar->character();
245 246
246 QIMPenCharMatchList::Iterator it; 247 QIMPenCharMatchList::Iterator it;
247 for ( it = ml.begin(); it != ml.end(); ++it ) { 248 for ( it = ml.begin(); it != ml.end(); ++it ) {
248 matchCh = (*it).penChar; 249 matchCh = (*it).penChar;
@@ -272,29 +273,29 @@ void QIMPenMatch::matchWords()
272 wordMatches.clear(); 273 wordMatches.clear();
273 goodMatches = 0; 274 goodMatches = 0;
274 badMatches = 0; 275 badMatches = 0;
275 if ( wordChars.count() > 0 ) { 276 if ( wordChars.count() > 0 ) {
276 maxGuess = (int)wordChars.count() * 2; 277 maxGuess = (int)wordChars.count() * 2;
277 if ( maxGuess < 3 ) 278 if ( maxGuess < 3 )
278 maxGuess = 3; 279 maxGuess = 3;
279 QString str; 280 QString str;
280 scanDict( Global::fixedDawg().root(), 0, str, 0 ); 281 scanDict( Global::fixedDawg().root(), 0, str, 0 );
281/* 282/*
282 QListIterator<MatchWord> it( wordMatches); 283 QListIterator<MatchWord> it( wordMatches);
283 for ( ; it.current(); ++it ) { 284 for ( ; it.current(); ++it ) {
284 qDebug( QString("Match word: %1").arg(it.current()->word) ); 285 odebug << "Match word: " << it.current()->word << oendl;
285 } 286 }
286*/ 287*/
287 } 288 }
288 //qDebug( "Possibles: Good %d, total %d", goodMatches, wordMatches.count() ); 289 //odebug << "Possibles: Good " << goodMatches << ", total " << wordMatches.count() << oendl;
289 wordMatches.sort(); 290 wordMatches.sort();
290} 291}
291 292
292void QIMPenMatch::scanDict( const QDawg::Node* n, int ipos, const QString& str, int error ) 293void QIMPenMatch::scanDict( const QDawg::Node* n, int ipos, const QString& str, int error )
293{ 294{
294 if ( !n ) 295 if ( !n )
295 return; 296 return;
296 if ( error / (ipos+1) > errorThreshold ) 297 if ( error / (ipos+1) > errorThreshold )
297 return; 298 return;
298 299
299 while (n) { 300 while (n) {
300 if ( goodMatches > 20 ) 301 if ( goodMatches > 20 )
diff --git a/inputmethods/handwriting/qimpenstroke.cpp b/inputmethods/handwriting/qimpenstroke.cpp
index 3567d6d..14e435a 100644
--- a/inputmethods/handwriting/qimpenstroke.cpp
+++ b/inputmethods/handwriting/qimpenstroke.cpp
@@ -15,24 +15,25 @@
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include <qfile.h> 21#include <qfile.h>
22#include <qtl.h> 22#include <qtl.h>
23#include <math.h> 23#include <math.h>
24#include <limits.h> 24#include <limits.h>
25#include <qdatastream.h> 25#include <qdatastream.h>
26#include "qimpenstroke.h" 26#include "qimpenstroke.h"
27#include "opie2/odebug.h"
27 28
28#define QIMPEN_CORRELATION_POINTS 25 29#define QIMPEN_CORRELATION_POINTS 25
29//#define DEBUG_QIMPEN 30//#define DEBUG_QIMPEN
30 31
31/*! 32/*!
32 \class QIMPenStroke qimpenstroke.h 33 \class QIMPenStroke qimpenstroke.h
33 34
34 Handles a single stroke. Can calculate closeness of match to 35 Handles a single stroke. Can calculate closeness of match to
35 another stroke. 36 another stroke.
36*/ 37*/
37 38
38QIMPenStroke::QIMPenStroke() 39QIMPenStroke::QIMPenStroke()
@@ -40,25 +41,25 @@ QIMPenStroke::QIMPenStroke()
40} 41}
41 42
42QIMPenStroke::QIMPenStroke( const QIMPenStroke &st ) 43QIMPenStroke::QIMPenStroke( const QIMPenStroke &st )
43{ 44{
44 startPoint = st.startPoint; 45 startPoint = st.startPoint;
45 lastPoint = st.lastPoint; 46 lastPoint = st.lastPoint;
46 links = st.links.copy(); 47 links = st.links.copy();
47} 48}
48 49
49QIMPenStroke &QIMPenStroke::operator=( const QIMPenStroke &s ) 50QIMPenStroke &QIMPenStroke::operator=( const QIMPenStroke &s )
50{ 51{
51 clear(); 52 clear();
52 //qDebug( "copy strokes %d", s.links.count() ); 53 //odebug << "copy strokes " << s.links.count() << oendl;
53 startPoint = s.startPoint; 54 startPoint = s.startPoint;
54 lastPoint = s.lastPoint; 55 lastPoint = s.lastPoint;
55 links = s.links.copy(); 56 links = s.links.copy();
56 57
57 return *this; 58 return *this;
58} 59}
59 60
60void QIMPenStroke::clear() 61void QIMPenStroke::clear()
61{ 62{
62 startPoint = QPoint(0,0); 63 startPoint = QPoint(0,0);
63 lastPoint = QPoint( 0, 0 ); 64 lastPoint = QPoint( 0, 0 );
64 links.resize( 0 ); 65 links.resize( 0 );
@@ -140,45 +141,45 @@ bool QIMPenStroke::addPoint( QPoint p )
140 Finish inputting a stroke. 141 Finish inputting a stroke.
141*/ 142*/
142void QIMPenStroke::endInput() 143void QIMPenStroke::endInput()
143{ 144{
144 if ( links.count() < 3 ) { 145 if ( links.count() < 3 ) {
145 QIMPenGlyphLink gl; 146 QIMPenGlyphLink gl;
146 links.resize(1); 147 links.resize(1);
147 gl.dx = 1; 148 gl.dx = 1;
148 gl.dy = 0; 149 gl.dy = 0;
149 links[0] = gl; 150 links[0] = gl;
150 } 151 }
151 152
152 //qDebug("Points: %d", links.count() ); 153 //odebug << "Points: " << links.count() << oendl;
153} 154}
154 155
155/*! 156/*!
156 Return an indicator of the closeness of this stroke to \a pen. 157 Return an indicator of the closeness of this stroke to \a pen.
157 Lower value is better. 158 Lower value is better.
158*/ 159*/
159unsigned int QIMPenStroke::match( QIMPenStroke *pen ) 160unsigned int QIMPenStroke::match( QIMPenStroke *pen )
160{ 161{
161 double lratio; 162 double lratio;
162 163
163 if ( links.count() > pen->links.count() ) 164 if ( links.count() > pen->links.count() )
164 lratio = (links.count()+2) / (pen->links.count()+2); 165 lratio = (links.count()+2) / (pen->links.count()+2);
165 else 166 else
166 lratio = (pen->links.count()+2) / (links.count()+2); 167 lratio = (pen->links.count()+2) / (links.count()+2);
167 168
168 lratio -= 1.0; 169 lratio -= 1.0;
169 170
170 if ( lratio > 2.0 ) { 171 if ( lratio > 2.0 ) {
171#ifdef DEBUG_QIMPEN 172#ifdef DEBUG_QIMPEN
172 qDebug( "stroke length too different" ); 173 odebug << "stroke length too different" << oendl;
173#endif 174#endif
174 return 400000; 175 return 400000;
175 } 176 }
176 177
177 createSignatures(); 178 createSignatures();
178 pen->createSignatures(); 179 pen->createSignatures();
179 180
180 // Starting point offset 181 // Starting point offset
181 int vdiff = QABS(startPoint.y() - pen->startPoint.y()); 182 int vdiff = QABS(startPoint.y() - pen->startPoint.y());
182 183
183 // Insanely offset? 184 // Insanely offset?
184 if ( vdiff > 18 ) { 185 if ( vdiff > 18 ) {
@@ -206,57 +207,57 @@ unsigned int QIMPenStroke::match( QIMPenStroke *pen )
206 int err3 = INT_MAX; 207 int err3 = INT_MAX;
207 208
208 // base has extra points at the start and end to enable 209 // base has extra points at the start and end to enable
209 // correlation of a sliding window with the pen supplied. 210 // correlation of a sliding window with the pen supplied.
210 QArray<int> base = createBase( tsig, 2 ); 211 QArray<int> base = createBase( tsig, 2 );
211 for ( int i = 0; i < 4; i++ ) { 212 for ( int i = 0; i < 4; i++ ) {
212 int e = calcError( base, pen->tsig, i, TRUE ); 213 int e = calcError( base, pen->tsig, i, TRUE );
213 if ( e < err1 ) 214 if ( e < err1 )
214 err1 = e; 215 err1 = e;
215 } 216 }
216 if ( err1 > 40 ) { // no need for more matching 217 if ( err1 > 40 ) { // no need for more matching
217#ifdef DEBUG_QIMPEN 218#ifdef DEBUG_QIMPEN
218 qDebug( "tsig too great: %d", err1 ); 219 odebug << "tsig too great: " << err1 << oendl;
219#endif 220#endif
220 return 400000; 221 return 400000;
221 } 222 }
222 223
223 // maybe a sliding window is worthwhile for these too. 224 // maybe a sliding window is worthwhile for these too.
224 err2 = calcError( dsig, pen->dsig, 0, FALSE ); 225 err2 = calcError( dsig, pen->dsig, 0, FALSE );
225 if ( err2 > 100 ) { 226 if ( err2 > 100 ) {
226#ifdef DEBUG_QIMPEN 227#ifdef DEBUG_QIMPEN
227 qDebug( "dsig too great: %d", err2 ); 228 odebug << "dsig too great: " << err2 << oendl;
228#endif 229#endif
229 return 400000; 230 return 400000;
230 } 231 }
231 232
232 err3 = calcError( asig, pen->asig, 0, TRUE ); 233 err3 = calcError( asig, pen->asig, 0, TRUE );
233 if ( err3 > 60 ) { 234 if ( err3 > 60 ) {
234#ifdef DEBUG_QIMPEN 235#ifdef DEBUG_QIMPEN
235 qDebug( "asig too great: %d", err3 ); 236 odebug << "asig too great: " << err3 << oendl;
236#endif 237#endif
237 return 400000; 238 return 400000;
238 } 239 }
239 240
240 // Some magic numbers here - the addition reduces the weighting of 241 // Some magic numbers here - the addition reduces the weighting of
241 // the error and compensates for the different error scales. I 242 // the error and compensates for the different error scales. I
242 // consider the tangent signature to be the best indicator, so it 243 // consider the tangent signature to be the best indicator, so it
243 // has the most weight. This ain't rocket science. 244 // has the most weight. This ain't rocket science.
244 // Basically, these numbers are the tuning factors. 245 // Basically, these numbers are the tuning factors.
245 unsigned int err = (err1+1) * ( err2 + 60 ) * ( err3 + 20 ) + 246 unsigned int err = (err1+1) * ( err2 + 60 ) * ( err3 + 20 ) +
246 vdiff * 1000 + evdiff * 500 + 247 vdiff * 1000 + evdiff * 500 +
247 (unsigned int)(lratio * 5000.0); 248 (unsigned int)(lratio * 5000.0);
248 249
249#ifdef DEBUG_QIMPEN 250#ifdef DEBUG_QIMPEN
250 qDebug( "err %d ( %d, %d, %d, %d)", err, err1, err2, err3, vdiff ); 251 odebug << "err " << err << "( " << err1 << ", " << err2 << ", " << err3 << ", " << vdiff << oendl;
251#endif 252#endif
252 253
253 return err; 254 return err;
254} 255}
255 256
256/*! 257/*!
257 Return the bounding rect of this stroke. 258 Return the bounding rect of this stroke.
258*/ 259*/
259QRect QIMPenStroke::boundingRect() 260QRect QIMPenStroke::boundingRect()
260{ 261{
261 if ( !bounding.isValid() ) { 262 if ( !bounding.isValid() ) {
262 int x = startPoint.x(); 263 int x = startPoint.x();
diff --git a/inputmethods/handwriting/qimpenwordpick.cpp b/inputmethods/handwriting/qimpenwordpick.cpp
index 8ee103d..39745c6 100644
--- a/inputmethods/handwriting/qimpenwordpick.cpp
+++ b/inputmethods/handwriting/qimpenwordpick.cpp
@@ -95,19 +95,19 @@ void QIMPenWordPick::paintEvent( QPaintEvent * )
95} 95}
96 96
97void QIMPenWordPick::mousePressEvent( QMouseEvent *e ) 97void QIMPenWordPick::mousePressEvent( QMouseEvent *e )
98{ 98{
99 clickWord = onWord( e->pos() ); 99 clickWord = onWord( e->pos() );
100 repaint(); 100 repaint();
101} 101}
102 102
103void QIMPenWordPick::mouseReleaseEvent( QMouseEvent *e ) 103void QIMPenWordPick::mouseReleaseEvent( QMouseEvent *e )
104{ 104{
105 int wordIdx = onWord( e->pos() ); 105 int wordIdx = onWord( e->pos() );
106 if ( wordIdx >= 0 && wordIdx == clickWord ) { 106 if ( wordIdx >= 0 && wordIdx == clickWord ) {
107 //qDebug( "Clicked %s", words[wordIdx].latin1() ); 107 //odebug << "Clicked " << words[wordIdx].latin1() << oendl;
108 emit wordClicked( words[wordIdx] ); 108 emit wordClicked( words[wordIdx] );
109 } 109 }
110 clickWord = -1; 110 clickWord = -1;
111 repaint(); 111 repaint();
112} 112}
113 113