summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--inputmethods/handwriting/qimpenchar.cpp5
-rw-r--r--inputmethods/handwriting/qimpenchar.h3
-rw-r--r--inputmethods/handwriting/qimpenprofile.cpp25
-rw-r--r--inputmethods/handwriting/qimpenprofile.h2
-rw-r--r--inputmethods/handwriting/qimpensetup.cpp3
5 files changed, 35 insertions, 3 deletions
diff --git a/inputmethods/handwriting/qimpenchar.cpp b/inputmethods/handwriting/qimpenchar.cpp
index 0c37e5c..929f370 100644
--- a/inputmethods/handwriting/qimpenchar.cpp
+++ b/inputmethods/handwriting/qimpenchar.cpp
@@ -1,508 +1,511 @@
1/********************************************************************** 1/**********************************************************************
2 ** Copyright (C) 2000 Trolltech AS. All rights reserved. 2 ** Copyright (C) 2000 Trolltech AS. All rights reserved.
3 ** 3 **
4 ** This file is part of Qtopia Environment. 4 ** This file is part of Qtopia Environment.
5 ** 5 **
6 ** This file may be distributed and/or modified under the terms of the 6 ** This file may be distributed and/or modified under the terms of the
7 ** GNU General Public License version 2 as published by the Free Software 7 ** GNU General Public License version 2 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.GPL included in the 8 ** Foundation and appearing in the file LICENSE.GPL included in the
9 ** packaging of this file. 9 ** packaging of this file.
10 ** 10 **
11 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 ** 13 **
14 ** See http://www.trolltech.com/gpl/ for GPL licensing information. 14 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
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 <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 29
30 #define QIMPEN_MATCH_THRESHOLD 200000 30 #define QIMPEN_MATCH_THRESHOLD 200000
31 31
32const QIMPenSpecialKeys qimpen_specialKeys[] = { 32const QIMPenSpecialKeys qimpen_specialKeys[] = {
33 { Qt::Key_Escape, "[Esc]" }, 33 { Qt::Key_Escape, "[Esc]" },
34 { Qt::Key_Tab, "[Tab]" }, 34 { Qt::Key_Tab, "[Tab]" },
35 { Qt::Key_Backspace,"[BackSpace]" }, 35 { Qt::Key_Backspace,"[BackSpace]" },
36 { Qt::Key_Return, "[Return]" }, 36 { Qt::Key_Return, "[Return]" },
37 { QIMPenChar::Caps, "[Uppercase]" }, 37 { QIMPenChar::Caps, "[Uppercase]" },
38 { QIMPenChar::CapsLock,"[Caps Lock]" }, 38 { QIMPenChar::CapsLock,"[Caps Lock]" },
39 { QIMPenChar::Shortcut,"[Shortcut]" }, 39 { QIMPenChar::Shortcut,"[Shortcut]" },
40 { QIMPenChar::Punctuation, "[Punctuation]" }, 40 { QIMPenChar::Punctuation, "[Punctuation]" },
41 { QIMPenChar::Symbol,"[Symbol]" }, 41 { QIMPenChar::Symbol,"[Symbol]" },
42 { QIMPenChar::Extended,"[Extended]" }, 42 { QIMPenChar::Extended,"[Extended]" },
43 { Qt::Key_unknown, 0 } }; 43 { Qt::Key_unknown, 0 } };
44 44
45 45
46/*! 46/*!
47 \class QIMPenChar qimpenchar.h 47 \class QIMPenChar qimpenchar.h
48 48
49 Handles a single character. Can calculate closeness of match to 49 Handles a single character. Can calculate closeness of match to
50 another character. 50 another character.
51 */ 51 */
52 52
53QIMPenChar::QIMPenChar() 53QIMPenChar::QIMPenChar()
54{ 54{
55 flags = 0; 55 flags = 0;
56 strokes.setAutoDelete( TRUE ); 56 strokes.setAutoDelete( TRUE );
57} 57}
58 58
59QIMPenChar::QIMPenChar( const QIMPenChar &chr ) 59QIMPenChar::QIMPenChar( const QIMPenChar &chr )
60{ 60{
61 strokes.setAutoDelete( TRUE ); 61 strokes.setAutoDelete( TRUE );
62 ch = chr.ch; 62 ch = chr.ch;
63 flags = chr.flags; 63 flags = chr.flags;
64 d = chr.d; 64 d = chr.d;
65 QIMPenStrokeIterator it( chr.strokes ); 65 QIMPenStrokeIterator it( chr.strokes );
66 while ( it.current() ) { 66 while ( it.current() ) {
67 strokes.append( new QIMPenStroke( *it.current() ) ); 67 strokes.append( new QIMPenStroke( *it.current() ) );
68 ++it; 68 ++it;
69 } 69 }
70} 70}
71 71
72QIMPenChar &QIMPenChar::operator=( const QIMPenChar &chr ) 72QIMPenChar &QIMPenChar::operator=( const QIMPenChar &chr )
73{ 73{
74 strokes.clear(); 74 strokes.clear();
75 ch = chr.ch; 75 ch = chr.ch;
76 flags = chr.flags; 76 flags = chr.flags;
77 d = chr.d; 77 d = chr.d;
78 QIMPenStrokeIterator it( chr.strokes ); 78 QIMPenStrokeIterator it( chr.strokes );
79 while ( it.current() ) { 79 while ( it.current() ) {
80 strokes.append( new QIMPenStroke( *it.current() ) ); 80 strokes.append( new QIMPenStroke( *it.current() ) );
81 ++it; 81 ++it;
82 } 82 }
83 83
84 return *this; 84 return *this;
85} 85}
86 86
87QString QIMPenChar::name() const 87QString QIMPenChar::name() const
88{ 88{
89 QString n; 89 QString n;
90 90
91 if ( (ch & 0x0000FFFF) == 0 ) { 91 if ( (ch & 0x0000FFFF) == 0 ) {
92 int code = ch >> 16; 92 int code = ch >> 16;
93 for ( int i = 0; qimpen_specialKeys[i].code != Qt::Key_unknown; i++ ) { 93 for ( int i = 0; qimpen_specialKeys[i].code != Qt::Key_unknown; i++ ) {
94 if ( qimpen_specialKeys[i].code == code ) { 94 if ( qimpen_specialKeys[i].code == code ) {
95 n = qimpen_specialKeys[i].name; 95 n = qimpen_specialKeys[i].name;
96 break; 96 break;
97 } 97 }
98 } 98 }
99 } else { 99 } else {
100 n = QChar( ch & 0x0000FFFF ); 100 n = QChar( ch & 0x0000FFFF );
101 } 101 }
102 102
103 return n; 103 return n;
104} 104}
105 105
106void QIMPenChar::clear() 106void QIMPenChar::clear()
107{ 107{
108 ch = 0; 108 ch = 0;
109 flags = 0; 109 flags = 0;
110 d = QString::null; 110 d = QString::null;
111 strokes.clear(); 111 strokes.clear();
112} 112}
113 113
114unsigned int QIMPenChar::strokeLength( int s ) const 114unsigned int QIMPenChar::strokeLength( int s ) const
115{ 115{
116 QIMPenStrokeIterator it( strokes ); 116 QIMPenStrokeIterator it( strokes );
117 while ( it.current() && s ) { 117 while ( it.current() && s ) {
118 ++it; 118 ++it;
119 --s; 119 --s;
120 } 120 }
121 121
122 if ( it.current() ) 122 if ( it.current() )
123 return it.current()->length(); 123 return it.current()->length();
124 124
125 return 0; 125 return 0;
126} 126}
127 127
128/*! 128/*!
129 Add a stroke to the character 129 Add a stroke to the character
130 */ 130 */
131void QIMPenChar::addStroke( QIMPenStroke *st ) 131void QIMPenChar::addStroke( QIMPenStroke *st )
132{ 132{
133 QIMPenStroke *stroke = new QIMPenStroke( *st ); 133 QIMPenStroke *stroke = new QIMPenStroke( *st );
134 strokes.append( stroke ); 134 strokes.append( stroke );
135} 135}
136 136
137/*! 137/*!
138 Return an indicator of the closeness of this character to \a pen. 138 Return an indicator of the closeness of this character to \a pen.
139 Lower value is better. 139 Lower value is better.
140 */ 140 */
141int QIMPenChar::match( QIMPenChar *pen ) 141int QIMPenChar::match( QIMPenChar *pen )
142{ 142{
143 /* 143 /*
144 if ( strokes.count() > pen->strokes.count() ) 144 if ( strokes.count() > pen->strokes.count() )
145 return INT_MAX; 145 return INT_MAX;
146 */ 146 */
147 int err = 0; 147 int err = 0;
148 int maxErr = 0; 148 int maxErr = 0;
149 int diff = 0; 149 int diff = 0;
150 QIMPenStrokeIterator it1( strokes ); 150 QIMPenStrokeIterator it1( strokes );
151 QIMPenStrokeIterator it2( pen->strokes ); 151 QIMPenStrokeIterator it2( pen->strokes );
152 err = it1.current()->match( it2.current() ); 152 err = it1.current()->match( it2.current() );
153 if ( err > maxErr ) 153 if ( err > maxErr )
154 maxErr = err; 154 maxErr = err;
155 ++it1; 155 ++it1;
156 ++it2; 156 ++it2;
157 while ( err < 400000 && it1.current() && it2.current() ) { 157 while ( err < 400000 && it1.current() && it2.current() ) {
158 QPoint p1 = it1.current()->boundingRect().center() - 158 QPoint p1 = it1.current()->boundingRect().center() -
159 strokes.getFirst()->boundingRect().center(); 159 strokes.getFirst()->boundingRect().center();
160 QPoint p2 = it2.current()->boundingRect().center() - 160 QPoint p2 = it2.current()->boundingRect().center() -
161 pen->strokes.getFirst()->boundingRect().center(); 161 pen->strokes.getFirst()->boundingRect().center();
162 int xdiff = QABS( p1.x() - p2.x() ) - 6; 162 int xdiff = QABS( p1.x() - p2.x() ) - 6;
163 int ydiff = QABS( p1.y() - p2.y() ) - 5; 163 int ydiff = QABS( p1.y() - p2.y() ) - 5;
164 if ( xdiff < 0 ) 164 if ( xdiff < 0 )
165 xdiff = 0; 165 xdiff = 0;
166 if ( ydiff < 0 ) 166 if ( ydiff < 0 )
167 ydiff = 0; 167 ydiff = 0;
168 if ( xdiff > 10 || ydiff > 10 ) { // not a chance 168 if ( xdiff > 10 || ydiff > 10 ) { // not a chance
169#ifdef DEBUG_QIMPEN 169#ifdef DEBUG_QIMPEN
170 qDebug( "char %c, stroke starting pt diff excessive", pen->ch ); 170 qDebug( "char %c, stroke starting pt diff excessive", pen->ch );
171#endif 171#endif
172 return INT_MAX; 172 return INT_MAX;
173 } 173 }
174 diff += xdiff*xdiff + ydiff*ydiff; 174 diff += xdiff*xdiff + ydiff*ydiff;
175 err = it1.current()->match( it2.current() ); 175 err = it1.current()->match( it2.current() );
176 if ( err > maxErr ) 176 if ( err > maxErr )
177 maxErr = err; 177 maxErr = err;
178 ++it1; 178 ++it1;
179 ++it2; 179 ++it2;
180 } 180 }
181 181
182 maxErr += diff * diff * 6; // magic weighting :) 182 maxErr += diff * diff * 6; // magic weighting :)
183 183
184#ifdef DEBUG_QIMPEN 184#ifdef DEBUG_QIMPEN
185 qDebug( "char: %c, maxErr %d, diff %d, (%d)", pen->ch, maxErr, diff, strokes.count() ); 185 qDebug( "char: %c, maxErr %d, diff %d, (%d)", pen->ch, maxErr, diff, strokes.count() );
186#endif 186#endif
187 return maxErr; 187 return maxErr;
188} 188}
189 189
190/*! 190/*!
191 Return the bounding rect of this character. It may have sides with 191 Return the bounding rect of this character. It may have sides with
192 negative coords since its origin is where the user started drawing 192 negative coords since its origin is where the user started drawing
193 the character. 193 the character.
194 */ 194 */
195QRect QIMPenChar::boundingRect() 195QRect QIMPenChar::boundingRect()
196{ 196{
197 QRect br; 197 QRect br;
198 QIMPenStroke *st = strokes.first(); 198 QIMPenStroke *st = strokes.first();
199 while ( st ) { 199 while ( st ) {
200 br |= st->boundingRect(); 200 br |= st->boundingRect();
201 st = strokes.next(); 201 st = strokes.next();
202 } 202 }
203 203
204 return br; 204 return br;
205} 205}
206 206
207 207
208/*! 208/*!
209 Write the character's data to the stream. 209 Write the character's data to the stream.
210 */ 210 */
211QDataStream &operator<< (QDataStream &s, const QIMPenChar &ws) 211QDataStream &operator<< (QDataStream &s, const QIMPenChar &ws)
212{ 212{
213 s << ws.ch; 213 s << ws.ch;
214 s << ws.flags; 214 s << ws.flags;
215 if ( ws.flags & QIMPenChar::Data ) 215 if ( ws.flags & QIMPenChar::Data )
216 s << ws.d; 216 s << ws.d;
217 s << ws.strokes.count(); 217 s << ws.strokes.count();
218 QIMPenStrokeIterator it( ws.strokes ); 218 QIMPenStrokeIterator it( ws.strokes );
219 while ( it.current() ) { 219 while ( it.current() ) {
220 s << *it.current(); 220 s << *it.current();
221 ++it; 221 ++it;
222 } 222 }
223 223
224 return s; 224 return s;
225} 225}
226 226
227/*! 227/*!
228 Read the character's data from the stream. 228 Read the character's data from the stream.
229 */ 229 */
230QDataStream &operator>> (QDataStream &s, QIMPenChar &ws) 230QDataStream &operator>> (QDataStream &s, QIMPenChar &ws)
231{ 231{
232 s >> ws.ch; 232 s >> ws.ch;
233 s >> ws.flags; 233 s >> ws.flags;
234 if ( ws.flags & QIMPenChar::Data ) 234 if ( ws.flags & QIMPenChar::Data )
235 s >> ws.d; 235 s >> ws.d;
236 unsigned size; 236 unsigned size;
237 s >> size; 237 s >> size;
238 for ( unsigned i = 0; i < size; i++ ) { 238 for ( unsigned i = 0; i < size; i++ ) {
239 QIMPenStroke *st = new QIMPenStroke(); 239 QIMPenStroke *st = new QIMPenStroke();
240 s >> *st; 240 s >> *st;
241 ws.strokes.append( st ); 241 ws.strokes.append( st );
242 } 242 }
243 243
244 return s; 244 return s;
245} 245}
246 246
247//=========================================================================== 247//===========================================================================
248 248
249bool QIMPenCharMatch::operator>( const QIMPenCharMatch &m ) 249bool QIMPenCharMatch::operator>( const QIMPenCharMatch &m )
250{ 250{
251 return error > m.error; 251 return error > m.error;
252} 252}
253 253
254bool QIMPenCharMatch::operator<( const QIMPenCharMatch &m ) 254bool QIMPenCharMatch::operator<( const QIMPenCharMatch &m )
255{ 255{
256 return error < m.error; 256 return error < m.error;
257} 257}
258 258
259bool QIMPenCharMatch::operator<=( const QIMPenCharMatch &m ) 259bool QIMPenCharMatch::operator<=( const QIMPenCharMatch &m )
260{ 260{
261 return error <= m.error; 261 return error <= m.error;
262} 262}
263 263
264//=========================================================================== 264//===========================================================================
265 265
266/*! 266/*!
267 \class QIMPenCharSet qimpenchar.h 267 \class QIMPenCharSet qimpenchar.h
268 268
269 Maintains a set of related characters. 269 Maintains a set of related characters.
270 */ 270 */
271 271
272QIMPenCharSet::QIMPenCharSet() 272QIMPenCharSet::QIMPenCharSet()
273{ 273{
274 chars.setAutoDelete( TRUE ); 274 chars.setAutoDelete( TRUE );
275 desc = "Unnamed"; 275 desc = "Unnamed";
276 csTitle = "abc"; 276 csTitle = "abc";
277 csType = Unknown; 277 csType = Unknown;
278 maxStrokes = 0; 278 maxStrokes = 0;
279} 279}
280 280
281/*! 281/*!
282 Construct and load a characters set from file \a fn. 282 Construct and load a characters set from file \a fn.
283 */ 283 */
284QIMPenCharSet::QIMPenCharSet( const QString &fn ) 284QIMPenCharSet::QIMPenCharSet( const QString &fn )
285{ 285{
286 chars.setAutoDelete( TRUE ); 286 chars.setAutoDelete( TRUE );
287 desc = "Unnamed"; 287 desc = "Unnamed";
288 csTitle = "abc"; 288 csTitle = "abc";
289 csType = Unknown; 289 csType = Unknown;
290 maxStrokes = 0; 290 maxStrokes = 0;
291 load( fn, System ); 291 load( fn, System );
292} 292}
293 293
294const QString &QIMPenCharSet::filename( Domain d ) const 294const QString &QIMPenCharSet::filename( Domain d ) const
295{ 295{
296 if ( d == System ) 296 if ( d == System )
297 return sysFilename; 297 return sysFilename;
298 else 298 else
299 return userFilename; 299 return userFilename;
300} 300}
301 301
302void QIMPenCharSet::setFilename( const QString &fn, Domain d ) 302void QIMPenCharSet::setFilename( const QString &fn, Domain d )
303{ 303{
304 if ( d == System ) 304 if ( d == System )
305 sysFilename = fn; 305 sysFilename = fn;
306 else if ( d == User ) 306 else if ( d == User )
307 userFilename = fn; 307 userFilename = fn;
308} 308}
309 309
310/*! 310/*!
311 Load a character set from file \a fn. 311 Load a character set from file \a fn.
312 */ 312 */
313bool QIMPenCharSet::load( const QString &fn, Domain d ) 313bool QIMPenCharSet::load( const QString &fn, Domain d )
314{ 314{
315 setFilename( fn, d ); 315 setFilename( fn, d );
316 316
317 bool ok = FALSE; 317 bool ok = FALSE;
318 QFile file( fn ); 318 QFile file( fn );
319 if ( file.open( IO_ReadOnly ) ) { 319 if ( file.open( IO_ReadOnly ) ) {
320 QDataStream ds( &file ); 320 QDataStream ds( &file );
321 QString version; 321 QString version;
322 ds >> version; 322 ds >> version;
323 ds >> csTitle; 323 ds >> csTitle;
324 ds >> desc; 324 ds >> desc;
325 int major = version.mid( 4, 1 ).toInt(); 325 int major = version.mid( 4, 1 ).toInt();
326 int minor = version.mid( 6 ).toInt(); 326 int minor = version.mid( 6 ).toInt();
327 if ( major >= 1 && minor > 0 ) { 327 if ( major >= 1 && minor > 0 ) {
328 ds >> (Q_INT8 &)csType; 328 ds >> (Q_INT8 &)csType;
329 } else { 329 } else {
330 if ( csTitle == "abc" ) 330 if ( csTitle == "abc" )
331 csType = Lower; 331 csType = Lower;
332 else if ( csTitle == "ABC" ) 332 else if ( csTitle == "ABC" )
333 csType = Upper; 333 csType = Upper;
334 else if ( csTitle == "123" ) 334 else if ( csTitle == "123" )
335 csType = Numeric; 335 csType = Numeric;
336 else if ( fn == "Combining" ) 336 else if ( fn == "Combining" )
337 csType = Combining; 337 csType = Combining;
338 } 338 }
339 while ( !ds.atEnd() ) { 339 while ( !ds.atEnd() ) {
340 QIMPenChar *pc = new QIMPenChar; 340 QIMPenChar *pc = new QIMPenChar;
341 ds >> *pc; 341 ds >> *pc;
342 if ( d == User ) 342 if ( d == User )
343 markDeleted( pc->character() ); // override system 343 markDeleted( pc->character() ); // override system
344 addChar( pc ); 344 addChar( pc );
345 } 345 }
346 if ( file.status() == IO_Ok ) 346 if ( file.status() == IO_Ok )
347 ok = TRUE; 347 ok = TRUE;
348 } 348 }
349 349 setHidden ( false );
350 return ok; 350 return ok;
351} 351}
352 352
353/*! 353/*!
354 Save this character set. 354 Save this character set.
355 */ 355 */
356bool QIMPenCharSet::save( Domain d ) 356bool QIMPenCharSet::save( Domain d )
357{ 357{
358 if ( filename( d ).isEmpty() ) 358 if ( filename( d ).isEmpty() )
359 return FALSE; 359 return FALSE;
360 360
361 if ( hidden() )
362 return TRUE;
363
361 bool ok = FALSE; 364 bool ok = FALSE;
362 365
363 QString fn = filename( d ); 366 QString fn = filename( d );
364 QString tmpFn = fn + ".new"; 367 QString tmpFn = fn + ".new";
365 QFile file( tmpFn ); 368 QFile file( tmpFn );
366 if ( file.open( IO_WriteOnly|IO_Raw ) ) { 369 if ( file.open( IO_WriteOnly|IO_Raw ) ) {
367 QByteArray buf; 370 QByteArray buf;
368 QDataStream ds( buf, IO_WriteOnly ); 371 QDataStream ds( buf, IO_WriteOnly );
369 ds << QString( "QPT 1.1" ); 372 ds << QString( "QPT 1.1" );
370 ds << csTitle; 373 ds << csTitle;
371 ds << desc; 374 ds << desc;
372 ds << (Q_INT8)csType; 375 ds << (Q_INT8)csType;
373 QIMPenCharIterator ci( chars ); 376 QIMPenCharIterator ci( chars );
374 for ( ; ci.current(); ++ci ) { 377 for ( ; ci.current(); ++ci ) {
375 QIMPenChar *pc = ci.current(); 378 QIMPenChar *pc = ci.current();
376 if ( ( ( (d == System) && pc->testFlag( QIMPenChar::System ) ) || 379 if ( ( ( (d == System) && pc->testFlag( QIMPenChar::System ) ) ||
377 ( (d == User) && !pc->testFlag( QIMPenChar::System ) ) ) && 380 ( (d == User) && !pc->testFlag( QIMPenChar::System ) ) ) &&
378 ( !pc->testFlag (QIMPenChar::Combined ) ) ) { 381 ( !pc->testFlag (QIMPenChar::Combined ) ) ) {
379 ds << *pc; 382 ds << *pc;
380 } 383 }
381 } 384 }
382 385
383 file.writeBlock( buf ); 386 file.writeBlock( buf );
384 file.close(); 387 file.close();
385 if ( file.status() == IO_Ok ) 388 if ( file.status() == IO_Ok )
386 ok = TRUE; 389 ok = TRUE;
387 } 390 }
388 391
389 if ( ok ) { 392 if ( ok ) {
390 if ( ::rename( tmpFn.latin1(), fn.latin1() ) < 0 ) { 393 if ( ::rename( tmpFn.latin1(), fn.latin1() ) < 0 ) {
391 qWarning( "problem renaming file %s to %s, errno: %d", 394 qWarning( "problem renaming file %s to %s, errno: %d",
392 tmpFn.latin1(), fn.latin1(), errno ); 395 tmpFn.latin1(), fn.latin1(), errno );
393 // remove the tmp file, otherwise, it will just lay around... 396 // remove the tmp file, otherwise, it will just lay around...
394 QFile::remove( tmpFn.latin1() ); 397 QFile::remove( tmpFn.latin1() );
395 ok = FALSE; 398 ok = FALSE;
396 } 399 }
397 } 400 }
398 401
399 return ok; 402 return ok;
400} 403}
401 404
402QIMPenChar *QIMPenCharSet::at( int i ) 405QIMPenChar *QIMPenCharSet::at( int i )
403{ 406{
404 return chars.at(i); 407 return chars.at(i);
405} 408}
406 409
407void QIMPenCharSet::markDeleted( uint ch ) 410void QIMPenCharSet::markDeleted( uint ch )
408{ 411{
409 QIMPenCharIterator ci( chars ); 412 QIMPenCharIterator ci( chars );
410 for ( ; ci.current(); ++ci ) { 413 for ( ; ci.current(); ++ci ) {
411 QIMPenChar *pc = ci.current(); 414 QIMPenChar *pc = ci.current();
412 if ( pc->character() == ch && pc->testFlag( QIMPenChar::System ) ) 415 if ( pc->character() == ch && pc->testFlag( QIMPenChar::System ) )
413 pc->setFlag( QIMPenChar::Deleted ); 416 pc->setFlag( QIMPenChar::Deleted );
414 } 417 }
415} 418}
416 419
417/*! 420/*!
418 Find the best matches for \a ch in this character set. 421 Find the best matches for \a ch in this character set.
419 */ 422 */
420QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch ) 423QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch )
421{ 424{
422 QIMPenCharMatchList matches; 425 QIMPenCharMatchList matches;
423 426
424 QIMPenCharIterator ci( chars ); 427 QIMPenCharIterator ci( chars );
425 for ( ; ci.current(); ++ci ) { 428 for ( ; ci.current(); ++ci ) {
426 QIMPenChar *tmplChar = ci.current(); 429 QIMPenChar *tmplChar = ci.current();
427 if ( tmplChar->testFlag( QIMPenChar::Deleted ) ) { 430 if ( tmplChar->testFlag( QIMPenChar::Deleted ) ) {
428 continue; 431 continue;
429 } 432 }
430 int err; 433 int err;
431 if ( ch->penStrokes().count() <= tmplChar->penStrokes().count() ) { 434 if ( ch->penStrokes().count() <= tmplChar->penStrokes().count() ) {
432 err = ch->match( tmplChar ); 435 err = ch->match( tmplChar );
433 if ( err <= QIMPEN_MATCH_THRESHOLD ) { 436 if ( err <= QIMPEN_MATCH_THRESHOLD ) {
434 if (tmplChar->penStrokes().count() != ch->penStrokes().count()) 437 if (tmplChar->penStrokes().count() != ch->penStrokes().count())
435 err = QMIN(err*3, QIMPEN_MATCH_THRESHOLD); 438 err = QMIN(err*3, QIMPEN_MATCH_THRESHOLD);
436 QIMPenCharMatchList::Iterator it; 439 QIMPenCharMatchList::Iterator it;
437 for ( it = matches.begin(); it != matches.end(); ++it ) { 440 for ( it = matches.begin(); it != matches.end(); ++it ) {
438 if ( (*it).penChar->character() == tmplChar->character() && 441 if ( (*it).penChar->character() == tmplChar->character() &&
439 (*it).penChar->penStrokes().count() == tmplChar->penStrokes().count() ) { 442 (*it).penChar->penStrokes().count() == tmplChar->penStrokes().count() ) {
440 if ( (*it).error > err ) 443 if ( (*it).error > err )
441 (*it).error = err; 444 (*it).error = err;
442 break; 445 break;
443 } 446 }
444 } 447 }
445 if ( it == matches.end() ) { 448 if ( it == matches.end() ) {
446 QIMPenCharMatch m; 449 QIMPenCharMatch m;
447 m.error = err; 450 m.error = err;
448 m.penChar = tmplChar; 451 m.penChar = tmplChar;
449 matches.append( m ); 452 matches.append( m );
450 } 453 }
451 } 454 }
452 } 455 }
453 } 456 }
454 qHeapSort( matches ); 457 qHeapSort( matches );
455 /* 458 /*
456 QIMPenCharMatchList::Iterator it; 459 QIMPenCharMatchList::Iterator it;
457 for ( it = matches.begin(); it != matches.end(); ++it ) { 460 for ( it = matches.begin(); it != matches.end(); ++it ) {
458 qDebug( "Match: \'%c\', error %d, strokes %d", (*it).penChar->character(), 461 qDebug( "Match: \'%c\', error %d, strokes %d", (*it).penChar->character(),
459 (*it).error, (*it).penChar->penStrokes().count() ); 462 (*it).error, (*it).penChar->penStrokes().count() );
460 } 463 }
461 */ 464 */
462 return matches; 465 return matches;
463} 466}
464 467
465/*! 468/*!
466 Add a character \a ch to this set. 469 Add a character \a ch to this set.
467 QIMPenCharSet will delete this character when it is no longer needed. 470 QIMPenCharSet will delete this character when it is no longer needed.
468 */ 471 */
469void QIMPenCharSet::addChar( QIMPenChar *ch ) 472void QIMPenCharSet::addChar( QIMPenChar *ch )
470{ 473{
471 if ( ch->penStrokes().count() > maxStrokes ) 474 if ( ch->penStrokes().count() > maxStrokes )
472 maxStrokes = ch->penStrokes().count(); 475 maxStrokes = ch->penStrokes().count();
473 chars.append( ch ); 476 chars.append( ch );
474} 477}
475 478
476/*! 479/*!
477 Remove a character by reference \a ch from this set. 480 Remove a character by reference \a ch from this set.
478 QIMPenCharSet will delete this character. 481 QIMPenCharSet will delete this character.
479 */ 482 */
480void QIMPenCharSet::removeChar( QIMPenChar *ch ) 483void QIMPenCharSet::removeChar( QIMPenChar *ch )
481{ 484{
482 chars.remove( ch ); 485 chars.remove( ch );
483} 486}
484 487
485/*! 488/*!
486 Move the character up the list of characters. 489 Move the character up the list of characters.
487 */ 490 */
488void QIMPenCharSet::up( QIMPenChar *ch ) 491void QIMPenCharSet::up( QIMPenChar *ch )
489{ 492{
490 int idx = chars.findRef( ch ); 493 int idx = chars.findRef( ch );
491 if ( idx > 0 ) { 494 if ( idx > 0 ) {
492 chars.take(); 495 chars.take();
493 chars.insert( idx - 1, ch ); 496 chars.insert( idx - 1, ch );
494 } 497 }
495} 498}
496 499
497/*! 500/*!
498 Move the character down the list of characters. 501 Move the character down the list of characters.
499 */ 502 */
500void QIMPenCharSet::down( QIMPenChar *ch ) 503void QIMPenCharSet::down( QIMPenChar *ch )
501{ 504{
502 int idx = chars.findRef( ch ); 505 int idx = chars.findRef( ch );
503 if ( idx >= 0 && idx < (int)chars.count() - 1 ) { 506 if ( idx >= 0 && idx < (int)chars.count() - 1 ) {
504 chars.take(); 507 chars.take();
505 chars.insert( idx + 1, ch ); 508 chars.insert( idx + 1, ch );
506 } 509 }
507} 510}
508 511
diff --git a/inputmethods/handwriting/qimpenchar.h b/inputmethods/handwriting/qimpenchar.h
index efd6f16..e4e7645 100644
--- a/inputmethods/handwriting/qimpenchar.h
+++ b/inputmethods/handwriting/qimpenchar.h
@@ -1,157 +1,160 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
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#ifndef QIMPENCHAR_H_ 21#ifndef QIMPENCHAR_H_
22#define QIMPENCHAR_H_ 22#define QIMPENCHAR_H_
23 23
24#include <qlist.h> 24#include <qlist.h>
25#include <qvaluelist.h> 25#include <qvaluelist.h>
26#include <qcstring.h> 26#include <qcstring.h>
27#include "qimpenstroke.h" 27#include "qimpenstroke.h"
28 28
29struct QIMPenSpecialKeys { 29struct QIMPenSpecialKeys {
30 int code; 30 int code;
31 char *name; 31 char *name;
32}; 32};
33 33
34extern const QIMPenSpecialKeys qimpen_specialKeys[]; 34extern const QIMPenSpecialKeys qimpen_specialKeys[];
35 35
36 36
37class QIMPenChar 37class QIMPenChar
38{ 38{
39public: 39public:
40 QIMPenChar(); 40 QIMPenChar();
41 QIMPenChar( const QIMPenChar & ); 41 QIMPenChar( const QIMPenChar & );
42 42
43 unsigned int character() const { return ch; } 43 unsigned int character() const { return ch; }
44 void setCharacter( unsigned int c ) { ch = c; } 44 void setCharacter( unsigned int c ) { ch = c; }
45 45
46 const QString &data() const { return d; } 46 const QString &data() const { return d; }
47 void setData( const QString &ba ) { d = ba; } 47 void setData( const QString &ba ) { d = ba; }
48 48
49 QString name() const; 49 QString name() const;
50 bool isEmpty() const { return strokes.isEmpty(); } 50 bool isEmpty() const { return strokes.isEmpty(); }
51 unsigned int strokeCount() const { return strokes.count(); } 51 unsigned int strokeCount() const { return strokes.count(); }
52 unsigned int strokeLength( int s ) const; 52 unsigned int strokeLength( int s ) const;
53 void clear(); 53 void clear();
54 int match( QIMPenChar *ch ); 54 int match( QIMPenChar *ch );
55 const QIMPenStrokeList &penStrokes() { return strokes; } 55 const QIMPenStrokeList &penStrokes() { return strokes; }
56 QPoint startingPoint() const { return strokes.getFirst()->startingPoint(); } 56 QPoint startingPoint() const { return strokes.getFirst()->startingPoint(); }
57 QRect boundingRect(); 57 QRect boundingRect();
58 58
59 void setFlag( int f ) { flags |= f; } 59 void setFlag( int f ) { flags |= f; }
60 void clearFlag( int f ) { flags &= ~f; } 60 void clearFlag( int f ) { flags &= ~f; }
61 bool testFlag( int f ) { return flags & f; } 61 bool testFlag( int f ) { return flags & f; }
62 62
63 enum Flags { System=0x01, Deleted=0x02, CombineRight=0x04, Data=0x08, Combined=0x10 }; 63 enum Flags { System=0x01, Deleted=0x02, CombineRight=0x04, Data=0x08, Combined=0x10 };
64 // Correspond to codes in template files. Do not change values. 64 // Correspond to codes in template files. Do not change values.
65 enum Mode { ModeBase=0x4000, Caps=0x4001, Shortcut=0x4002, CapsLock=0x4003, 65 enum Mode { ModeBase=0x4000, Caps=0x4001, Shortcut=0x4002, CapsLock=0x4003,
66 Punctuation=0x4004, Symbol=0x4005, Extended=0x4006 }; 66 Punctuation=0x4004, Symbol=0x4005, Extended=0x4006 };
67 67
68 QIMPenChar &operator=( const QIMPenChar &s ); 68 QIMPenChar &operator=( const QIMPenChar &s );
69 69
70 void addStroke( QIMPenStroke * ); 70 void addStroke( QIMPenStroke * );
71 71
72protected: 72protected:
73 unsigned int ch; 73 unsigned int ch;
74 QString d; 74 QString d;
75 Q_UINT8 flags; 75 Q_UINT8 flags;
76 QIMPenStrokeList strokes; 76 QIMPenStrokeList strokes;
77 77
78 friend QDataStream &operator<< (QDataStream &, const QIMPenChar &); 78 friend QDataStream &operator<< (QDataStream &, const QIMPenChar &);
79 friend QDataStream &operator>> (QDataStream &, QIMPenChar &); 79 friend QDataStream &operator>> (QDataStream &, QIMPenChar &);
80}; 80};
81 81
82typedef QList<QIMPenChar> QIMPenCharList; 82typedef QList<QIMPenChar> QIMPenCharList;
83typedef QListIterator<QIMPenChar> QIMPenCharIterator; 83typedef QListIterator<QIMPenChar> QIMPenCharIterator;
84 84
85QDataStream & operator<< (QDataStream & s, const QIMPenChar &ws); 85QDataStream & operator<< (QDataStream & s, const QIMPenChar &ws);
86QDataStream & operator>> (QDataStream & s, QIMPenChar &ws); 86QDataStream & operator>> (QDataStream & s, QIMPenChar &ws);
87 87
88struct QIMPenCharMatch 88struct QIMPenCharMatch
89{ 89{
90 int error; 90 int error;
91 QIMPenChar *penChar; 91 QIMPenChar *penChar;
92 92
93 bool operator>( const QIMPenCharMatch &m ); 93 bool operator>( const QIMPenCharMatch &m );
94 bool operator<( const QIMPenCharMatch &m ); 94 bool operator<( const QIMPenCharMatch &m );
95 bool operator<=( const QIMPenCharMatch &m ); 95 bool operator<=( const QIMPenCharMatch &m );
96}; 96};
97 97
98typedef QValueList<QIMPenCharMatch> QIMPenCharMatchList; 98typedef QValueList<QIMPenCharMatch> QIMPenCharMatchList;
99 99
100 100
101class QIMPenCharSet 101class QIMPenCharSet
102{ 102{
103public: 103public:
104 QIMPenCharSet(); 104 QIMPenCharSet();
105 QIMPenCharSet( const QString &fn ); 105 QIMPenCharSet( const QString &fn );
106 106
107 bool isEmpty() const { return chars.isEmpty(); } 107 bool isEmpty() const { return chars.isEmpty(); }
108 unsigned int count() const { return chars.count(); } 108 unsigned int count() const { return chars.count(); }
109 void clear() { chars.clear(); } 109 void clear() { chars.clear(); }
110 110
111 void setDescription( const QString &d ) { desc = d; } 111 void setDescription( const QString &d ) { desc = d; }
112 QString description() const { return desc; } 112 QString description() const { return desc; }
113 void setTitle( const QString &t ) { csTitle = t; } 113 void setTitle( const QString &t ) { csTitle = t; }
114 QString title() const { return csTitle; } 114 QString title() const { return csTitle; }
115 115
116 QIMPenCharMatchList match( QIMPenChar *ch ); 116 QIMPenCharMatchList match( QIMPenChar *ch );
117 void addChar( QIMPenChar *ch ); 117 void addChar( QIMPenChar *ch );
118 void removeChar( QIMPenChar *ch ); 118 void removeChar( QIMPenChar *ch );
119 QIMPenChar *at( int i ); 119 QIMPenChar *at( int i );
120 void setHidden ( const bool &b ) { phidden = &b; }
121 bool hidden() const { return phidden; }
120 122
121 unsigned maximumStrokes() const { return maxStrokes; } 123 unsigned maximumStrokes() const { return maxStrokes; }
122 124
123 void up( QIMPenChar *ch ); 125 void up( QIMPenChar *ch );
124 void down( QIMPenChar *ch ); 126 void down( QIMPenChar *ch );
125 127
126 enum Domain { System, User }; 128 enum Domain { System, User };
127 enum Type { Unknown=0x00, Lower=0x01, Upper=0x02, Combining=0x04, 129 enum Type { Unknown=0x00, Lower=0x01, Upper=0x02, Combining=0x04,
128 Numeric=0x08, Punctuation=0x10, Symbol=0x20, Shortcut=0x40 }; 130 Numeric=0x08, Punctuation=0x10, Symbol=0x20, Shortcut=0x40 };
129 131
130 const QIMPenCharList &characters() const { return chars; } 132 const QIMPenCharList &characters() const { return chars; }
131 133
132 void setType( Type t ) { csType = t; } 134 void setType( Type t ) { csType = t; }
133 Type type() const { return csType; } 135 Type type() const { return csType; }
134 136
135 const QString &filename( Domain d ) const; 137 const QString &filename( Domain d ) const;
136 void setFilename( const QString &fn, Domain d=System ); 138 void setFilename( const QString &fn, Domain d=System );
137 bool load( const QString &fn, Domain d=System ); 139 bool load( const QString &fn, Domain d=System );
138 bool save( Domain d=System ); 140 bool save( Domain d=System );
139 141
140protected: 142protected:
141 void markDeleted( uint ch ); 143 void markDeleted( uint ch );
142 144
143protected: 145protected:
144 QString csTitle; 146 QString csTitle;
145 QString desc; 147 QString desc;
146 QString sysFilename; 148 QString sysFilename;
147 QString userFilename; 149 QString userFilename;
148 Type csType; 150 Type csType;
149 unsigned maxStrokes; 151 unsigned maxStrokes;
150 QIMPenCharList chars; 152 QIMPenCharList chars;
151 QIMPenCharMatchList matches; 153 QIMPenCharMatchList matches;
154 bool phidden : 1;
152}; 155};
153 156
154typedef QList<QIMPenCharSet> QIMPenCharSetList; 157typedef QList<QIMPenCharSet> QIMPenCharSetList;
155typedef QListIterator<QIMPenCharSet> QIMPenCharSetIterator; 158typedef QListIterator<QIMPenCharSet> QIMPenCharSetIterator;
156 159
157#endif 160#endif
diff --git a/inputmethods/handwriting/qimpenprofile.cpp b/inputmethods/handwriting/qimpenprofile.cpp
index 3b1b5e9..b1a6592 100644
--- a/inputmethods/handwriting/qimpenprofile.cpp
+++ b/inputmethods/handwriting/qimpenprofile.cpp
@@ -1,245 +1,268 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
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 "qimpencombining.h" 21#include "qimpencombining.h"
22#include "qimpenprofile.h" 22#include "qimpenprofile.h"
23 23
24#include <qpe/qpeapplication.h> 24#include <qpe/qpeapplication.h>
25#include <qpe/config.h> 25#include <qpe/config.h>
26#include <qpe/global.h> 26#include <qpe/global.h>
27 27
28 28
29QIMPenProfile::QIMPenProfile( const QString &fn ) 29QIMPenProfile::QIMPenProfile( const QString &fn )
30 : filename( fn ) 30 : filename( fn )
31{ 31{
32 sets.setAutoDelete( true ); 32 sets.setAutoDelete( true );
33 33
34 Config config( filename, Config::File ); 34 Config config( filename, Config::File );
35 config.setGroup( "Handwriting" ); 35 config.setGroup( "Handwriting" );
36 36
37 pname = config.readEntry( "Name" ); 37 pname = config.readEntry( "Name" );
38 pdesc = config.readEntry( "Description" ); 38 pdesc = config.readEntry( "Description" );
39 39
40 tstyle = config.readBoolEntry( "CanSelectStyle", false ); 40 tstyle = config.readBoolEntry( "CanSelectStyle", false );
41 41
42 wordMatch = config.readBoolEntry( "MatchWords", true ); 42 wordMatch = config.readBoolEntry( "MatchWords", true );
43 43
44 config.setGroup( "Settings" ); 44 config.setGroup( "Settings" );
45 45
46 pstyle = BothCases; 46 pstyle = BothCases;
47 QString s = config.readEntry( "Style", "BothCases" ); 47 QString s = config.readEntry( "Style", "BothCases" );
48 if ( s == "ToggleCases" ) 48 if ( s == "ToggleCases" )
49 pstyle = ToggleCases; 49 pstyle = ToggleCases;
50 50
51 QString t = config.readEntry( "Mono", "Dual" );
52 pmono = (QString::fromLatin1("Mono") == t );
53
51 msTimeout = config.readNumEntry( "MultiTimeout", 500 ); 54 msTimeout = config.readNumEntry( "MultiTimeout", 500 );
52 55
53 // Read user configuration 56 // Read user configuration
54 Config usrConfig( userConfig() ); 57 Config usrConfig( userConfig() );
55 usrConfig.setGroup( "Settings" ); 58 usrConfig.setGroup( "Settings" );
56 msTimeout = usrConfig.readNumEntry( "MultiTimeout", msTimeout ); 59 msTimeout = usrConfig.readNumEntry( "MultiTimeout", msTimeout );
57 60
58 if ( tstyle && usrConfig.hasKey( "Style" ) ) { 61 if ( tstyle && usrConfig.hasKey( "Style" ) ) {
59 pstyle = BothCases; 62 pstyle = BothCases;
60 QString s = usrConfig.readEntry( "Style", "BothCases" ); 63 QString s = usrConfig.readEntry( "Style", "BothCases" );
61 if ( s == "ToggleCases" ) 64 if ( s == "ToggleCases" )
62 pstyle = ToggleCases; 65 pstyle = ToggleCases;
63 } 66 }
64} 67}
65 68
66void QIMPenProfile::setStyle( Style s ) 69void QIMPenProfile::setStyle( Style s )
67{ 70{
68 if ( tstyle && s != pstyle ) { 71 if ( tstyle && s != pstyle ) {
69 pstyle = s; 72 pstyle = s;
70 Config config( userConfig() ); 73 Config config( userConfig() );
71 config.setGroup( "Settings" ); 74 config.setGroup( "Settings" );
72 QString s = pstyle == ToggleCases ? "ToggleCases" : "BothCases"; 75 QString s = pstyle == ToggleCases ? "ToggleCases" : "BothCases";
73 config.writeEntry( "Style", s ); 76 config.writeEntry( "Style", s );
74 } 77 }
75} 78}
76 79
77void QIMPenProfile::setMultiStrokeTimeout( int t ) 80void QIMPenProfile::setMultiStrokeTimeout( int t )
78{ 81{
79 if ( t != msTimeout ) { 82 if ( t != msTimeout ) {
80 msTimeout = t; 83 msTimeout = t;
81 Config config( userConfig() ); 84 Config config( userConfig() );
82 config.setGroup( "Settings" ); 85 config.setGroup( "Settings" );
83 config.writeEntry( "MultiTimeout", msTimeout ); 86 config.writeEntry( "MultiTimeout", msTimeout );
84 } 87 }
85} 88}
86 89
87QString QIMPenProfile::userConfig() 90QString QIMPenProfile::userConfig()
88{ 91{
89 QString un = filename; 92 QString un = filename;
90 int pos = un.findRev( '/' ); 93 int pos = un.findRev( '/' );
91 if ( pos >= 0 ) 94 if ( pos >= 0 )
92 un = un.mid( pos + 1 ); 95 un = un.mid( pos + 1 );
93 pos = un.find( '.' ); 96 pos = un.find( '.' );
94 if ( pos > 0 ) 97 if ( pos > 0 )
95 un.truncate( pos ); 98 un.truncate( pos );
96 99
97 un = "handwriting-" + un; // No tr 100 un = "handwriting-" + un; // No tr
98 101
99 return un; 102 return un;
100} 103}
101 104
102void QIMPenProfile::loadData() 105void QIMPenProfile::loadData()
103{ 106{
104 Config config( filename, Config::File ); 107 Config config( filename, Config::File );
105 config.setGroup( "CharSets" ); 108 config.setGroup( "CharSets" );
106 109
107 QString baseDir = QPEApplication::qpeDir(); 110 QString baseDir = QPEApplication::qpeDir();
108 baseDir += "/etc/"; 111 baseDir += "/etc/";
109 // accents 112 // accents
110 QIMPenCombining *combining = 0; 113 QIMPenCombining *combining = 0;
111 QString s = config.readEntry( "Combining" ); 114 QString s = config.readEntry( "Combining" );
112 if ( !s.isEmpty() ) { 115 if ( !s.isEmpty() ) {
113 combining = new QIMPenCombining( baseDir + "qimpen/" + s ); 116 combining = new QIMPenCombining( baseDir + "qimpen/" + s );
114 if ( combining->isEmpty() ) { 117 if ( combining->isEmpty() ) {
115 delete combining; 118 delete combining;
116 combining = 0; 119 combining = 0;
117 } 120 }
118 } 121 }
119 // uppercase latin1 122 // uppercase latin1
120 QIMPenCharSet *cs = 0; 123 QIMPenCharSet *cs = 0;
121 s = config.readEntry( "Uppercase" ); 124 s = config.readEntry( "Uppercase" );
122 if ( !s.isEmpty() ) { 125 if ( !s.isEmpty() && !mono() ) {
123 cs = new QIMPenCharSet( baseDir + "qimpen/" + s ); 126 cs = new QIMPenCharSet( baseDir + "qimpen/" + s );
124 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User ); 127 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User );
125 if ( !cs->isEmpty() ) { 128 if ( !cs->isEmpty() ) {
126 if ( combining ) 129 if ( combining )
127 combining->addCombined( cs ); 130 combining->addCombined( cs );
128 sets.append( cs ); 131 sets.append( cs );
129 } else { 132 } else {
130 delete cs; 133 delete cs;
131 } 134 }
132 } 135 }
133 // lowercase latin1 136 // lowercase latin1
134 s = config.readEntry( "Lowercase" ); 137 s = config.readEntry( "Lowercase" );
135 if ( !s.isEmpty() ) { 138 if ( !s.isEmpty() ) {
139 if ( mono() ) {
140 cs = new QIMPenCharSet ( baseDir + "qimpen/" + s );
141 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User );
142 if ( !cs->isEmpty() ) {
143 cs->setTitle( cs->title().upper() );
144 cs->setType( QIMPenCharSet::Upper );
145 cs->setHidden ( true );
146 QIMPenCharIterator it( cs->characters() );
147 for ( ; it.current(); ++it ) {
148 uint ch = it.current()->character();
149 if ( ch >= 'a' && ch <= 'z' )
150 it.current()->setCharacter( QChar(ch).upper() );
151 }
152 if ( combining )
153 combining->addCombined( cs );
154 sets.append( cs );
155 } else {
156 delete cs;
157 }
158 }
136 cs = new QIMPenCharSet( baseDir + "qimpen/" + s ); 159 cs = new QIMPenCharSet( baseDir + "qimpen/" + s );
137 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User ); 160 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User );
138 if ( !cs->isEmpty() ) { 161 if ( !cs->isEmpty() ) {
139 if ( combining ) 162 if ( combining )
140 combining->addCombined( cs ); 163 combining->addCombined( cs );
141 sets.append( cs ); 164 sets.append( cs );
142 } else { 165 } else {
143 delete cs; 166 delete cs;
144 } 167 }
145 } 168 }
146 // numeric (may comtain punctuation and symbols) 169 // numeric (may comtain punctuation and symbols)
147 s = config.readEntry( "Numeric" ); 170 s = config.readEntry( "Numeric" );
148 if ( !s.isEmpty() ) { 171 if ( !s.isEmpty() ) {
149 cs = new QIMPenCharSet( baseDir + "qimpen/" + s ); 172 cs = new QIMPenCharSet( baseDir + "qimpen/" + s );
150 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User ); 173 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User );
151 if ( !cs->isEmpty() ) { 174 if ( !cs->isEmpty() ) {
152 sets.append( cs ); 175 sets.append( cs );
153 } else { 176 } else {
154 delete cs; 177 delete cs;
155 } 178 }
156 } 179 }
157 // punctuation 180 // punctuation
158 s = config.readEntry( "Punctuation" ); 181 s = config.readEntry( "Punctuation" );
159 if ( !s.isEmpty() ) { 182 if ( !s.isEmpty() ) {
160 cs = new QIMPenCharSet( baseDir + "qimpen/" + s ); 183 cs = new QIMPenCharSet( baseDir + "qimpen/" + s );
161 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User ); 184 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User );
162 if ( !cs->isEmpty() ) { 185 if ( !cs->isEmpty() ) {
163 sets.append( cs ); 186 sets.append( cs );
164 } else { 187 } else {
165 delete cs; 188 delete cs;
166 } 189 }
167 } 190 }
168 // symbol 191 // symbol
169 s = config.readEntry( "Symbol" ); 192 s = config.readEntry( "Symbol" );
170 if ( !s.isEmpty() ) { 193 if ( !s.isEmpty() ) {
171 cs = new QIMPenCharSet( baseDir + "qimpen/" + s ); 194 cs = new QIMPenCharSet( baseDir + "qimpen/" + s );
172 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User ); 195 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User );
173 if ( !cs->isEmpty() ) { 196 if ( !cs->isEmpty() ) {
174 sets.append( cs ); 197 sets.append( cs );
175 } else { 198 } else {
176 delete cs; 199 delete cs;
177 } 200 }
178 } 201 }
179 // shortcut 202 // shortcut
180 s = config.readEntry( "Shortcut" ); 203 s = config.readEntry( "Shortcut" );
181 if ( !s.isEmpty() ) { 204 if ( !s.isEmpty() ) {
182 cs = new QIMPenCharSet( baseDir + "qimpen/" + s ); 205 cs = new QIMPenCharSet( baseDir + "qimpen/" + s );
183 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User ); 206 cs->load( Global::applicationFileName("qimpen",s), QIMPenCharSet::User );
184 if ( !cs->isEmpty() ) { 207 if ( !cs->isEmpty() ) {
185 sets.append( cs ); 208 sets.append( cs );
186 } else { 209 } else {
187 delete cs; 210 delete cs;
188 } 211 }
189 } 212 }
190 213
191 if ( combining ) 214 if ( combining )
192 delete combining; 215 delete combining;
193} 216}
194 217
195QIMPenCharSet *QIMPenProfile::uppercase() 218QIMPenCharSet *QIMPenProfile::uppercase()
196{ 219{
197 return find( QIMPenCharSet::Upper ); 220 return find( QIMPenCharSet::Upper );
198} 221}
199 222
200QIMPenCharSet *QIMPenProfile::lowercase() 223QIMPenCharSet *QIMPenProfile::lowercase()
201{ 224{
202 return find( QIMPenCharSet::Lower ); 225 return find( QIMPenCharSet::Lower );
203} 226}
204 227
205QIMPenCharSet *QIMPenProfile::numeric() 228QIMPenCharSet *QIMPenProfile::numeric()
206{ 229{
207 return find( QIMPenCharSet::Numeric ); 230 return find( QIMPenCharSet::Numeric );
208} 231}
209 232
210QIMPenCharSet *QIMPenProfile::punctuation() 233QIMPenCharSet *QIMPenProfile::punctuation()
211{ 234{
212 return find( QIMPenCharSet::Punctuation ); 235 return find( QIMPenCharSet::Punctuation );
213} 236}
214 237
215QIMPenCharSet *QIMPenProfile::symbol() 238QIMPenCharSet *QIMPenProfile::symbol()
216{ 239{
217 return find( QIMPenCharSet::Symbol ); 240 return find( QIMPenCharSet::Symbol );
218} 241}
219 242
220QIMPenCharSet *QIMPenProfile::shortcut() 243QIMPenCharSet *QIMPenProfile::shortcut()
221{ 244{
222 return find( QIMPenCharSet::Shortcut ); 245 return find( QIMPenCharSet::Shortcut );
223} 246}
224 247
225QIMPenCharSetList &QIMPenProfile::charSets() 248QIMPenCharSetList &QIMPenProfile::charSets()
226{ 249{
227 if ( sets.isEmpty() ) 250 if ( sets.isEmpty() )
228 loadData(); 251 loadData();
229 return sets; 252 return sets;
230} 253}
231 254
232QIMPenCharSet *QIMPenProfile::find( QIMPenCharSet::Type t ) 255QIMPenCharSet *QIMPenProfile::find( QIMPenCharSet::Type t )
233{ 256{
234 if ( sets.isEmpty() ) 257 if ( sets.isEmpty() )
235 loadData(); 258 loadData();
236 QIMPenCharSetIterator it( sets ); 259 QIMPenCharSetIterator it( sets );
237 for ( ; it.current(); ++it ) { 260 for ( ; it.current(); ++it ) {
238 if ( it.current()->type() == t ) 261 if ( it.current()->type() == t )
239 return it.current(); 262 return it.current();
240 } 263 }
241 264
242 return 0; 265 return 0;
243} 266}
244 267
245 268
diff --git a/inputmethods/handwriting/qimpenprofile.h b/inputmethods/handwriting/qimpenprofile.h
index 4ce4367..adfa866 100644
--- a/inputmethods/handwriting/qimpenprofile.h
+++ b/inputmethods/handwriting/qimpenprofile.h
@@ -1,70 +1,72 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
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#ifndef QIMPENPROFILE_H_ 21#ifndef QIMPENPROFILE_H_
22#define QIMPENPROFILE_H_ 22#define QIMPENPROFILE_H_
23 23
24#include "qimpenchar.h" 24#include "qimpenchar.h"
25 25
26class QIMPenProfile 26class QIMPenProfile
27{ 27{
28public: 28public:
29 QIMPenProfile( const QString &fn ); 29 QIMPenProfile( const QString &fn );
30 30
31 const QString &name() const { return pname; } 31 const QString &name() const { return pname; }
32 const QString &description() const { return pdesc; } 32 const QString &description() const { return pdesc; }
33 33
34 enum Style { ToggleCases, BothCases }; 34 enum Style { ToggleCases, BothCases };
35 Style style() const { return pstyle; } 35 Style style() const { return pstyle; }
36 bool mono() const { return pmono; }
36 void setStyle( Style s ); 37 void setStyle( Style s );
37 38
38 bool canSelectStyle() const { return tstyle; } 39 bool canSelectStyle() const { return tstyle; }
39 40
40 int multiStrokeTimeout() const { return msTimeout; } 41 int multiStrokeTimeout() const { return msTimeout; }
41 void setMultiStrokeTimeout( int t ); 42 void setMultiStrokeTimeout( int t );
42 43
43 bool matchWords() const { return wordMatch; } 44 bool matchWords() const { return wordMatch; }
44 45
45 QIMPenCharSet *uppercase(); 46 QIMPenCharSet *uppercase();
46 QIMPenCharSet *lowercase(); 47 QIMPenCharSet *lowercase();
47 QIMPenCharSet *numeric(); 48 QIMPenCharSet *numeric();
48 QIMPenCharSet *punctuation(); 49 QIMPenCharSet *punctuation();
49 QIMPenCharSet *symbol(); 50 QIMPenCharSet *symbol();
50 QIMPenCharSet *shortcut(); 51 QIMPenCharSet *shortcut();
51 QIMPenCharSet *find( QIMPenCharSet::Type t ); 52 QIMPenCharSet *find( QIMPenCharSet::Type t );
52 53
53 QIMPenCharSetList &charSets(); 54 QIMPenCharSetList &charSets();
54 55
55private: 56private:
56 QString userConfig(); 57 QString userConfig();
57 void loadData(); 58 void loadData();
58 59
59private: 60private:
60 QIMPenCharSetList sets; 61 QIMPenCharSetList sets;
61 QString filename; 62 QString filename;
62 QString pname; 63 QString pname;
63 QString pdesc; 64 QString pdesc;
64 Style pstyle; 65 Style pstyle;
65 bool tstyle; 66 bool tstyle;
66 int msTimeout; 67 int msTimeout;
67 bool wordMatch; 68 bool wordMatch;
69 bool pmono;
68}; 70};
69 71
70#endif 72#endif
diff --git a/inputmethods/handwriting/qimpensetup.cpp b/inputmethods/handwriting/qimpensetup.cpp
index 2441102..d0f9ffd 100644
--- a/inputmethods/handwriting/qimpensetup.cpp
+++ b/inputmethods/handwriting/qimpensetup.cpp
@@ -20,645 +20,646 @@
20 20
21#include "qimpenwidget.h" 21#include "qimpenwidget.h"
22#include "qimpenprefbase.h" 22#include "qimpenprefbase.h"
23#include "qimpensetup.h" 23#include "qimpensetup.h"
24 24
25#include <qpe/qpeapplication.h> 25#include <qpe/qpeapplication.h>
26#include <qpe/config.h> 26#include <qpe/config.h>
27 27
28#include <qcombobox.h> 28#include <qcombobox.h>
29#include <qlistbox.h> 29#include <qlistbox.h>
30#include <qlabel.h> 30#include <qlabel.h>
31#include <qpushbutton.h> 31#include <qpushbutton.h>
32#include <qlayout.h> 32#include <qlayout.h>
33#include <qpixmap.h> 33#include <qpixmap.h>
34#include <qbuttongroup.h> 34#include <qbuttongroup.h>
35#include <qslider.h> 35#include <qslider.h>
36#include <qtabwidget.h> 36#include <qtabwidget.h>
37#include <qdir.h> 37#include <qdir.h>
38#include <qmessagebox.h> 38#include <qmessagebox.h>
39 39
40 40
41/* XPM */ 41/* XPM */
42static const char * const left_xpm[] = { 42static const char * const left_xpm[] = {
43"16 16 2 1", 43"16 16 2 1",
44 " c None", 44 " c None",
45 ".c #000000", 45 ".c #000000",
46" ", 46" ",
47" ", 47" ",
48" ", 48" ",
49" . ", 49" . ",
50" .. ", 50" .. ",
51" ... ", 51" ... ",
52" .... ", 52" .... ",
53" ..... ", 53" ..... ",
54" ...... ", 54" ...... ",
55" ..... ", 55" ..... ",
56" .... ", 56" .... ",
57" ... ", 57" ... ",
58" .. ", 58" .. ",
59" . ", 59" . ",
60" ", 60" ",
61" "}; 61" "};
62 62
63 63
64/* XPM */ 64/* XPM */
65static const char * const right_xpm[] = { 65static const char * const right_xpm[] = {
66"16 16 2 1", 66"16 16 2 1",
67 " c None", 67 " c None",
68 ".c #000000", 68 ".c #000000",
69" ", 69" ",
70" ", 70" ",
71" ", 71" ",
72" . ", 72" . ",
73" .. ", 73" .. ",
74" ... ", 74" ... ",
75" .... ", 75" .... ",
76" ..... ", 76" ..... ",
77" ...... ", 77" ...... ",
78" ..... ", 78" ..... ",
79" .... ", 79" .... ",
80" ... ", 80" ... ",
81" .. ", 81" .. ",
82" . ", 82" . ",
83" ", 83" ",
84" "}; 84" "};
85 85
86 86
87 87
88QIMPenSetup::QIMPenSetup( QIMPenProfile *p, QWidget *parent, 88QIMPenSetup::QIMPenSetup( QIMPenProfile *p, QWidget *parent,
89 const char *name, bool modal, int WFlags ) 89 const char *name, bool modal, int WFlags )
90 : QDialog( parent, name, modal, WFlags ), profileCombo(0), profile(p) 90 : QDialog( parent, name, modal, WFlags ), profileCombo(0), profile(p)
91{ 91{
92 setCaption( tr("Setup Handwriting Input") ); 92 setCaption( tr("Setup Handwriting Input") );
93 93
94 QVBoxLayout *vb = new QVBoxLayout( this ); 94 QVBoxLayout *vb = new QVBoxLayout( this );
95 95
96#define MULTIPROFILE 96#define MULTIPROFILE
97#ifdef MULTIPROFILE 97#ifdef MULTIPROFILE
98 profileList.setAutoDelete( true ); 98 profileList.setAutoDelete( true );
99 QHBoxLayout *hb = new QHBoxLayout( vb ); 99 QHBoxLayout *hb = new QHBoxLayout( vb );
100 hb->setMargin( 6 ); 100 hb->setMargin( 6 );
101 QLabel *l = new QLabel( tr("Character Profile:"), this ); 101 QLabel *l = new QLabel( tr("Character Profile:"), this );
102 hb->addWidget( l ); 102 hb->addWidget( l );
103 profileCombo = new QComboBox( this ); 103 profileCombo = new QComboBox( this );
104 connect( profileCombo, SIGNAL(activated(const QString &)), 104 connect( profileCombo, SIGNAL(activated(const QString &)),
105 this, SLOT(selectProfile(const QString &)) ); 105 this, SLOT(selectProfile(const QString &)) );
106 hb->addWidget( profileCombo ); 106 hb->addWidget( profileCombo );
107#else 107#else
108 profileList.append( profile ); 108 profileList.append( profile );
109#endif 109#endif
110 110
111 qWarning("profiles: %d", profileList.count()); 111 qWarning("profiles: %d", profileList.count());
112 112
113 QTabWidget *tw = new QTabWidget( this ); 113 QTabWidget *tw = new QTabWidget( this );
114 vb->addWidget( tw ); 114 vb->addWidget( tw );
115 115
116 pref = new QIMPenPrefBase( this ); 116 pref = new QIMPenPrefBase( this );
117 tw->addTab( pref, tr("Preferences") ); 117 tw->addTab( pref, tr("Preferences") );
118 118
119 pref->inputStyle->setExclusive( TRUE ); 119 pref->inputStyle->setExclusive( TRUE );
120 120
121 style = profile->style() == QIMPenProfile::ToggleCases ? 1 : 0; 121 style = profile->style() == QIMPenProfile::ToggleCases ? 1 : 0;
122 pref->inputStyle->setButton( style ); 122 pref->inputStyle->setButton( style );
123 connect( pref->inputStyle, SIGNAL(clicked(int)), 123 connect( pref->inputStyle, SIGNAL(clicked(int)),
124 this, SLOT(styleClicked(int)) ); 124 this, SLOT(styleClicked(int)) );
125 pref->inputStyle->setEnabled( profile->canSelectStyle() ); 125 pref->inputStyle->setEnabled( profile->canSelectStyle() );
126 126
127 multiTimeout = profile->multiStrokeTimeout(); 127 multiTimeout = profile->multiStrokeTimeout();
128 pref->multiStrokeSlider->setValue( multiTimeout ); 128 pref->multiStrokeSlider->setValue( multiTimeout );
129 multiTimeoutChanged( multiTimeout ); 129 multiTimeoutChanged( multiTimeout );
130 connect( pref->multiStrokeSlider, SIGNAL(valueChanged(int)), 130 connect( pref->multiStrokeSlider, SIGNAL(valueChanged(int)),
131 this, SLOT(multiTimeoutChanged(int)) ); 131 this, SLOT(multiTimeoutChanged(int)) );
132 132
133 edit = new QIMPenEdit( p, tw ); 133 edit = new QIMPenEdit( p, tw );
134 tw->addTab( edit, tr("Customize") ); 134 tw->addTab( edit, tr("Customize") );
135#ifdef MULTIPROFILE 135#ifdef MULTIPROFILE
136 loadProfiles(); 136 loadProfiles();
137#endif 137#endif
138 138
139} 139}
140 140
141void QIMPenSetup::loadProfiles() 141void QIMPenSetup::loadProfiles()
142{ 142{
143 QString path = QPEApplication::qpeDir() + "etc/qimpen"; 143 QString path = QPEApplication::qpeDir() + "etc/qimpen";
144 QDir dir( path, "*.conf" ); 144 QDir dir( path, "*.conf" );
145 QStringList list = dir.entryList(); 145 QStringList list = dir.entryList();
146 QStringList::Iterator it; 146 QStringList::Iterator it;
147 for ( it = list.begin(); it != list.end(); ++it ) { 147 for ( it = list.begin(); it != list.end(); ++it ) {
148 QIMPenProfile *p = new QIMPenProfile( path + "/" + *it ); 148 QIMPenProfile *p = new QIMPenProfile( path + "/" + *it );
149 profileList.append( p ); 149 profileList.append( p );
150 profileCombo->insertItem( p->name() ); 150 profileCombo->insertItem( p->name() );
151 if ( p->name() == profile->name() ) { 151 if ( p->name() == profile->name() ) {
152 profileCombo->setCurrentItem( profileCombo->count()-1 ); 152 profileCombo->setCurrentItem( profileCombo->count()-1 );
153 profile = p; 153 profile = p;
154 edit->setProfile( profile ); 154 edit->setProfile( profile );
155 } 155 }
156 } 156 }
157} 157}
158 158
159void QIMPenSetup::styleClicked( int id ) 159void QIMPenSetup::styleClicked( int id )
160{ 160{
161 style = id; 161 style = id;
162} 162}
163 163
164void QIMPenSetup::multiTimeoutChanged( int v ) 164void QIMPenSetup::multiTimeoutChanged( int v )
165{ 165{
166 multiTimeout = v; 166 multiTimeout = v;
167 pref->multiStrokeLabel->setText( tr("%1 ms").arg(v) ); 167 pref->multiStrokeLabel->setText( tr("%1 ms").arg(v) );
168} 168}
169 169
170void QIMPenSetup::selectProfile( const QString &p ) 170void QIMPenSetup::selectProfile( const QString &p )
171{ 171{
172 if ( p == profile->name() ) 172 if ( p == profile->name() )
173 return; 173 return;
174 174
175 profile->setStyle( style ? QIMPenProfile::ToggleCases : QIMPenProfile::BothCases ); 175 profile->setStyle( style ? QIMPenProfile::ToggleCases : QIMPenProfile::BothCases );
176 profile->setMultiStrokeTimeout( multiTimeout ); 176 profile->setMultiStrokeTimeout( multiTimeout );
177 177
178 for ( int i = 0; i < (int)profileList.count(); i++ ) { 178 for ( int i = 0; i < (int)profileList.count(); i++ ) {
179 if ( profileList.at(i)->name() == p ) { 179 if ( profileList.at(i)->name() == p ) {
180 profile = profileList.at(i); 180 profile = profileList.at(i);
181 style = profile->style() == QIMPenProfile::ToggleCases ? 1 : 0; 181 style = profile->style() == QIMPenProfile::ToggleCases ? 1 : 0;
182 pref->inputStyle->setButton( style ); 182 pref->inputStyle->setButton( style );
183 pref->inputStyle->setEnabled( profile->canSelectStyle() ); 183 pref->inputStyle->setEnabled( profile->canSelectStyle() );
184 multiTimeout = profile->multiStrokeTimeout(); 184 multiTimeout = profile->multiStrokeTimeout();
185 pref->multiStrokeSlider->setValue( multiTimeout ); 185 pref->multiStrokeSlider->setValue( multiTimeout );
186 multiTimeoutChanged( multiTimeout ); 186 multiTimeoutChanged( multiTimeout );
187 edit->setProfile( profile ); 187 edit->setProfile( profile );
188 break; 188 break;
189 } 189 }
190 } 190 }
191} 191}
192 192
193void QIMPenSetup::accept() 193void QIMPenSetup::accept()
194{ 194{
195 profile->setStyle( style ? QIMPenProfile::ToggleCases : QIMPenProfile::BothCases ); 195 profile->setStyle( style ? QIMPenProfile::ToggleCases : QIMPenProfile::BothCases );
196 profile->setMultiStrokeTimeout( multiTimeout ); 196 profile->setMultiStrokeTimeout( multiTimeout );
197 // Save current profile 197 // Save current profile
198 if ( profileCombo ) { 198 if ( profileCombo ) {
199 Config config( "handwriting" ); 199 Config config( "handwriting" );
200 config.setGroup( "Settings" ); 200 config.setGroup( "Settings" );
201 config.writeEntry( "Profile", profileCombo->currentText() ); 201 config.writeEntry( "Profile", profileCombo->currentText() );
202 } 202 }
203 // Save charsets 203 // Save charsets
204 bool ok = TRUE; 204 bool ok = TRUE;
205 for ( int i = 0; i < (int)profileList.count(); i++ ) { 205 for ( int i = 0; i < (int)profileList.count(); i++ ) {
206 QIMPenProfile *prof = profileList.at(i); 206 QIMPenProfile *prof = profileList.at(i);
207 QIMPenCharSetIterator it(prof->charSets()); 207 QIMPenCharSetIterator it(prof->charSets());
208 for ( ; it.current(); ++it ) { 208 for ( ; it.current(); ++it ) {
209 if ( !(it.current()->save( QIMPenCharSet::User )) ) { 209 if ( !(it.current()->save( QIMPenCharSet::User )) ) {
210 ok = FALSE; 210 ok = FALSE;
211 break; 211 break;
212 } 212 }
213 } 213 }
214 } 214 }
215 if ( !ok ) { 215 if ( !ok ) {
216 if ( QMessageBox::critical( 0, tr( "Out of space" ), 216 if ( QMessageBox::critical( 0, tr( "Out of space" ),
217 tr("Unable to save information.\n" 217 tr("Unable to save information.\n"
218 "Free up some space\n" 218 "Free up some space\n"
219 "and try again.\n" 219 "and try again.\n"
220 "\nQuit anyway?"), 220 "\nQuit anyway?"),
221 QMessageBox::Yes|QMessageBox::Escape, 221 QMessageBox::Yes|QMessageBox::Escape,
222 QMessageBox::No|QMessageBox::Default ) 222 QMessageBox::No|QMessageBox::Default )
223 != QMessageBox::No ) { 223 != QMessageBox::No ) {
224 QDialog::accept(); 224 QDialog::accept();
225 } 225 }
226 } else { 226 } else {
227 QDialog::accept(); 227 QDialog::accept();
228 } 228 }
229} 229}
230 230
231//--------------------------------------------------------------------------- 231//---------------------------------------------------------------------------
232 232
233QIMPenInputCharDlg::QIMPenInputCharDlg( QWidget *parent, const char *name, 233QIMPenInputCharDlg::QIMPenInputCharDlg( QWidget *parent, const char *name,
234 bool modal, int WFlags) 234 bool modal, int WFlags)
235 : QDialog( parent, name, modal, WFlags ) 235 : QDialog( parent, name, modal, WFlags )
236{ 236{
237 setCaption( tr("Enter new character") ); 237 setCaption( tr("Enter new character") );
238 uni = 0; 238 uni = 0;
239 239
240 QVBoxLayout *vb = new QVBoxLayout( this, 10 ); 240 QVBoxLayout *vb = new QVBoxLayout( this, 10 );
241 241
242 QHBoxLayout *hb = new QHBoxLayout(); 242 QHBoxLayout *hb = new QHBoxLayout();
243 vb->addLayout( hb ); 243 vb->addLayout( hb );
244 244
245 QLabel *label = new QLabel( tr("Character:"), this ); 245 QLabel *label = new QLabel( tr("Character:"), this );
246 hb->addWidget( label ); 246 hb->addWidget( label );
247 247
248 QComboBox *cb = new QComboBox( TRUE, this ); 248 QComboBox *cb = new QComboBox( TRUE, this );
249 connect( cb, SIGNAL(activated(int)), SLOT(setSpecial(int)) ); 249 connect( cb, SIGNAL(activated(int)), SLOT(setSpecial(int)) );
250 connect( cb, SIGNAL(textChanged(const QString &)), 250 connect( cb, SIGNAL(textChanged(const QString &)),
251 SLOT(setCharacter(const QString &)) ); 251 SLOT(setCharacter(const QString &)) );
252 addSpecial( cb ); 252 addSpecial( cb );
253 cb->setEditText( "" ); 253 cb->setEditText( "" );
254 hb->addWidget( cb ); 254 hb->addWidget( cb );
255 255
256 hb = new QHBoxLayout(); 256 hb = new QHBoxLayout();
257 vb->addLayout( hb ); 257 vb->addLayout( hb );
258 258
259 QPushButton *pb = new QPushButton( "OK", this ); 259 QPushButton *pb = new QPushButton( "OK", this );
260 connect( pb, SIGNAL(clicked()), SLOT(accept())); 260 connect( pb, SIGNAL(clicked()), SLOT(accept()));
261 hb->addWidget( pb ); 261 hb->addWidget( pb );
262 pb = new QPushButton( "Cancel", this ); 262 pb = new QPushButton( "Cancel", this );
263 connect( pb, SIGNAL(clicked()), SLOT(reject())); 263 connect( pb, SIGNAL(clicked()), SLOT(reject()));
264 hb->addWidget( pb ); 264 hb->addWidget( pb );
265 265
266 cb->setFocus(); 266 cb->setFocus();
267} 267}
268 268
269void QIMPenInputCharDlg::addSpecial( QComboBox *cb ) 269void QIMPenInputCharDlg::addSpecial( QComboBox *cb )
270{ 270{
271 int i = 0; 271 int i = 0;
272 while ( qimpen_specialKeys[i].code != Key_unknown ) { 272 while ( qimpen_specialKeys[i].code != Key_unknown ) {
273 cb->insertItem( qimpen_specialKeys[i].name ); 273 cb->insertItem( qimpen_specialKeys[i].name );
274 i++; 274 i++;
275 } 275 }
276} 276}
277 277
278void QIMPenInputCharDlg::setSpecial( int sp ) 278void QIMPenInputCharDlg::setSpecial( int sp )
279{ 279{
280 uni = qimpen_specialKeys[sp].code << 16; 280 uni = qimpen_specialKeys[sp].code << 16;
281} 281}
282 282
283void QIMPenInputCharDlg::setCharacter( const QString &string ) 283void QIMPenInputCharDlg::setCharacter( const QString &string )
284{ 284{
285 uni = string[0].unicode(); 285 uni = string[0].unicode();
286} 286}
287 287
288//--------------------------------------------------------------------------- 288//---------------------------------------------------------------------------
289 289
290class CharListItem : public QListBoxText 290class CharListItem : public QListBoxText
291{ 291{
292public: 292public:
293 CharListItem( const QString &text, uint c ) 293 CharListItem( const QString &text, uint c )
294 : QListBoxText( text ) 294 : QListBoxText( text )
295 { 295 {
296 _code = c; 296 _code = c;
297 } 297 }
298 298
299 uint code() const { return _code; } 299 uint code() const { return _code; }
300 300
301protected: 301protected:
302 uint _code; 302 uint _code;
303}; 303};
304 304
305/*! 305/*!
306 \class QIMPenEdit qimpensetup.h 306 \class QIMPenEdit qimpensetup.h
307 307
308 Class to allow users to input totally useless character definitions 308 Class to allow users to input totally useless character definitions
309 which could match any number of the default set. 309 which could match any number of the default set.
310*/ 310*/
311 311
312QIMPenEdit::QIMPenEdit( QIMPenProfile *p, QWidget *parent, 312QIMPenEdit::QIMPenEdit( QIMPenProfile *p, QWidget *parent,
313 const char *name ) 313 const char *name )
314 : QWidget( parent, name ), profile(p) 314 : QWidget( parent, name ), profile(p)
315{ 315{
316 currentChar = 0; 316 currentChar = 0;
317 currentCode = 0; 317 currentCode = 0;
318 inputChar = new QIMPenChar(); 318 inputChar = new QIMPenChar();
319 319
320 QVBoxLayout *tvb = new QVBoxLayout( this, 5 ); 320 QVBoxLayout *tvb = new QVBoxLayout( this, 5 );
321 321
322 QGridLayout *gl = new QGridLayout( tvb, 4, 2 ); 322 QGridLayout *gl = new QGridLayout( tvb, 4, 2 );
323 gl->setRowStretch( 1, 1 ); 323 gl->setRowStretch( 1, 1 );
324 gl->addRowSpacing( 2, 35 ); 324 gl->addRowSpacing( 2, 35 );
325 gl->addRowSpacing( 3, 35 ); 325 gl->addRowSpacing( 3, 35 );
326 326
327 charSetCombo = new QComboBox( this ); 327 charSetCombo = new QComboBox( this );
328 gl->addMultiCellWidget( charSetCombo, 0, 0, 0, 1 ); 328 gl->addMultiCellWidget( charSetCombo, 0, 0, 0, 1 );
329 connect( charSetCombo, SIGNAL(activated(int)), SLOT(selectCharSet(int))); 329 connect( charSetCombo, SIGNAL(activated(int)), SLOT(selectCharSet(int)));
330 QIMPenCharSetIterator it( profile->charSets() ); 330 QIMPenCharSetIterator it( profile->charSets() );
331 for ( ; it.current(); ++it ) { 331 for ( ; it.current(); ++it ) {
332 charSetCombo->insertItem( it.current()->description() ); 332 charSetCombo->insertItem( it.current()->description() );
333 } 333 }
334 334
335 charList = new QListBox( this ); 335 charList = new QListBox( this );
336 charList->setMinimumHeight( charList->sizeHint().height() ); 336 charList->setMinimumHeight( charList->sizeHint().height() );
337 connect( charList, SIGNAL(highlighted(int)), SLOT(selectChar(int)) ); 337 connect( charList, SIGNAL(highlighted(int)), SLOT(selectChar(int)) );
338 gl->addWidget( charList, 1, 0 ); 338 gl->addWidget( charList, 1, 0 );
339 339
340 pw = new QIMPenWidget( this ); 340 pw = new QIMPenWidget( this );
341 pw->setFixedHeight( 75 ); 341 pw->setFixedHeight( 75 );
342 gl->addMultiCellWidget( pw, 2, 3, 0, 0 ); 342 gl->addMultiCellWidget( pw, 2, 3, 0, 0 );
343 connect( pw, SIGNAL(stroke(QIMPenStroke *)), 343 connect( pw, SIGNAL(stroke(QIMPenStroke *)),
344 SLOT(newStroke(QIMPenStroke *)) ); 344 SLOT(newStroke(QIMPenStroke *)) );
345 345
346 QVBoxLayout *vb = new QVBoxLayout(); 346 QVBoxLayout *vb = new QVBoxLayout();
347 gl->addLayout( vb, 1, 1 ); 347 gl->addLayout( vb, 1, 1 );
348 newBtn = new QPushButton( tr("New..."), this ); 348 newBtn = new QPushButton( tr("New..."), this );
349 connect( newBtn, SIGNAL(clicked()), SLOT(addNewChar()) ); 349 connect( newBtn, SIGNAL(clicked()), SLOT(addNewChar()) );
350 vb->addWidget( newBtn ); 350 vb->addWidget( newBtn );
351 351
352 addBtn = new QPushButton( tr("Add"), this ); 352 addBtn = new QPushButton( tr("Add"), this );
353 connect( addBtn, SIGNAL(clicked()), SLOT(addChar()) ); 353 connect( addBtn, SIGNAL(clicked()), SLOT(addChar()) );
354 vb->addWidget( addBtn ); 354 vb->addWidget( addBtn );
355 355
356 removeBtn = new QPushButton( tr("Remove"), this ); 356 removeBtn = new QPushButton( tr("Remove"), this );
357 connect( removeBtn, SIGNAL(clicked()), SLOT(removeChar()) ); 357 connect( removeBtn, SIGNAL(clicked()), SLOT(removeChar()) );
358 vb->addWidget( removeBtn ); 358 vb->addWidget( removeBtn );
359 359
360 QPushButton *pb = new QPushButton( tr("Default"), this ); 360 QPushButton *pb = new QPushButton( tr("Default"), this );
361 connect( pb, SIGNAL(clicked()), SLOT(defaultChars()) ); 361 connect( pb, SIGNAL(clicked()), SLOT(defaultChars()) );
362 vb->addWidget( pb ); 362 vb->addWidget( pb );
363 363
364 QHBoxLayout *hb = new QHBoxLayout(); 364 QHBoxLayout *hb = new QHBoxLayout();
365 gl->addLayout( hb, 2, 1 ); 365 gl->addLayout( hb, 2, 1 );
366 prevBtn = new QPushButton( this ); 366 prevBtn = new QPushButton( this );
367 prevBtn->setPixmap( QPixmap( (const char **)left_xpm ) ); 367 prevBtn->setPixmap( QPixmap( (const char **)left_xpm ) );
368 connect( prevBtn, SIGNAL(clicked()), SLOT(prevChar())); 368 connect( prevBtn, SIGNAL(clicked()), SLOT(prevChar()));
369 hb->addWidget( prevBtn ); 369 hb->addWidget( prevBtn );
370 370
371 nextBtn = new QPushButton( this ); 371 nextBtn = new QPushButton( this );
372 nextBtn->setPixmap( QPixmap( (const char **)right_xpm ) ); 372 nextBtn->setPixmap( QPixmap( (const char **)right_xpm ) );
373 connect( nextBtn, SIGNAL(clicked()), SLOT(nextChar())); 373 connect( nextBtn, SIGNAL(clicked()), SLOT(nextChar()));
374 hb->addWidget( nextBtn ); 374 hb->addWidget( nextBtn );
375 375
376 pb = new QPushButton( tr("Clear"), this ); 376 pb = new QPushButton( tr("Clear"), this );
377 connect( pb, SIGNAL(clicked()), SLOT(clearChar()) ); 377 connect( pb, SIGNAL(clicked()), SLOT(clearChar()) );
378 gl->addWidget( pb, 3, 1 ); 378 gl->addWidget( pb, 3, 1 );
379 379
380 //-- 380 //--
381#if !defined(Q_WS_QWS) 381#if !defined(Q_WS_QWS)
382 hb = new QHBoxLayout( tvb ); 382 hb = new QHBoxLayout( tvb );
383 pb = new QPushButton( tr("OK"), this ); 383 pb = new QPushButton( tr("OK"), this );
384 connect( pb, SIGNAL(clicked()), SLOT(accept()) ); 384 connect( pb, SIGNAL(clicked()), SLOT(accept()) );
385 hb->addWidget( pb ); 385 hb->addWidget( pb );
386 386
387 pb = new QPushButton( tr("Cancel"), this ); 387 pb = new QPushButton( tr("Cancel"), this );
388 connect( pb, SIGNAL(clicked()), SLOT(reject()) ); 388 connect( pb, SIGNAL(clicked()), SLOT(reject()) );
389 hb->addWidget( pb ); 389 hb->addWidget( pb );
390#endif 390#endif
391 selectCharSet( 0 ); 391 selectCharSet( 0 );
392 charList->setFocus(); 392 charList->setFocus();
393 393
394 resize( minimumSize() ); 394 resize( minimumSize() );
395 enableButtons(); 395 enableButtons();
396} 396}
397 397
398void QIMPenEdit::setProfile( QIMPenProfile *p ) 398void QIMPenEdit::setProfile( QIMPenProfile *p )
399{ 399{
400 profile = p; 400 profile = p;
401 charSetCombo->clear(); 401 charSetCombo->clear();
402 QIMPenCharSetIterator it( profile->charSets() ); 402 QIMPenCharSetIterator it( profile->charSets() );
403 for ( ; it.current(); ++it ) { 403 for ( ; it.current(); ++it ) {
404 charSetCombo->insertItem( it.current()->description() ); 404 if ( ! it.current()->hidden() )
405 charSetCombo->insertItem( it.current()->description() );
405 } 406 }
406 selectCharSet( 0 ); 407 selectCharSet( 0 );
407 charList->setFocus(); 408 charList->setFocus();
408 enableButtons(); 409 enableButtons();
409} 410}
410 411
411void QIMPenEdit::selectCharSet( QIMPenCharSet *c ) 412void QIMPenEdit::selectCharSet( QIMPenCharSet *c )
412{ 413{
413 int i = 0; 414 int i = 0;
414 QIMPenCharSetIterator it( profile->charSets() ); 415 QIMPenCharSetIterator it( profile->charSets() );
415 for ( ; it.current(); ++it, i++ ) { 416 for ( ; it.current(); ++it, i++ ) {
416 if ( it.current() == c ) { 417 if ( it.current() == c ) {
417 charSetCombo->setCurrentItem( i ); 418 charSetCombo->setCurrentItem( i );
418 selectCharSet( i ); 419 selectCharSet( i );
419 } 420 }
420 } 421 }
421} 422}
422 423
423 424
424/*! 425/*!
425 Fill the character list box with the characters. Duplicates are not 426 Fill the character list box with the characters. Duplicates are not
426 inserted. 427 inserted.
427*/ 428*/
428void QIMPenEdit::fillCharList() 429void QIMPenEdit::fillCharList()
429{ 430{
430 charList->clear(); 431 charList->clear();
431 QIMPenCharIterator it( currentSet->characters() ); 432 QIMPenCharIterator it( currentSet->characters() );
432 CharListItem *li = 0; 433 CharListItem *li = 0;
433 for ( ; it.current(); ++it ) { 434 for ( ; it.current(); ++it ) {
434 uint ch = it.current()->character(); 435 uint ch = it.current()->character();
435 QString n = it.current()->name(); 436 QString n = it.current()->name();
436 if ( !n.isEmpty() ) 437 if ( !n.isEmpty() )
437 li = new CharListItem( n, ch ); 438 li = new CharListItem( n, ch );
438 if ( li ) { 439 if ( li ) {
439 CharListItem *i = (CharListItem *)charList->findItem( li->text() ); 440 CharListItem *i = (CharListItem *)charList->findItem( li->text() );
440 if ( !i || i->code() != ch ) { 441 if ( !i || i->code() != ch ) {
441 charList->insertItem( li ); 442 charList->insertItem( li );
442 } else { 443 } else {
443 delete li; 444 delete li;
444 li = 0; 445 li = 0;
445 } 446 }
446 } 447 }
447 } 448 }
448 currentChar = 0; 449 currentChar = 0;
449} 450}
450 451
451void QIMPenEdit::enableButtons() 452void QIMPenEdit::enableButtons()
452{ 453{
453 bool add = !inputChar->isEmpty(); 454 bool add = !inputChar->isEmpty();
454 newBtn->setEnabled( add ); 455 newBtn->setEnabled( add );
455 addBtn->setEnabled( add ); 456 addBtn->setEnabled( add );
456 removeBtn->setEnabled( currentChar ); 457 removeBtn->setEnabled( currentChar );
457} 458}
458 459
459/*! 460/*!
460 Find the previous character with the same code as the current one. 461 Find the previous character with the same code as the current one.
461 returns 0 if there is no previous character. 462 returns 0 if there is no previous character.
462*/ 463*/
463QIMPenChar *QIMPenEdit::findPrev() 464QIMPenChar *QIMPenEdit::findPrev()
464{ 465{
465 if ( !currentChar ) 466 if ( !currentChar )
466 return 0; 467 return 0;
467 QIMPenCharIterator it( currentSet->characters() ); 468 QIMPenCharIterator it( currentSet->characters() );
468 bool found = FALSE; 469 bool found = FALSE;
469 for ( it.toLast(); it.current(); --it ) { 470 for ( it.toLast(); it.current(); --it ) {
470 if ( !found && it.current() == currentChar ) 471 if ( !found && it.current() == currentChar )
471 found = TRUE; 472 found = TRUE;
472 else if ( found && it.current()->character() == currentCode && 473 else if ( found && it.current()->character() == currentCode &&
473 !it.current()->testFlag( QIMPenChar::Deleted ) ) { 474 !it.current()->testFlag( QIMPenChar::Deleted ) ) {
474 return it.current(); 475 return it.current();
475 } 476 }
476 } 477 }
477 478
478 return 0; 479 return 0;
479} 480}
480 481
481/*! 482/*!
482 Find the next character with the same code as the current one. 483 Find the next character with the same code as the current one.
483 returns 0 if there is no next character. 484 returns 0 if there is no next character.
484*/ 485*/
485QIMPenChar *QIMPenEdit::findNext() 486QIMPenChar *QIMPenEdit::findNext()
486{ 487{
487 if ( !currentChar ) 488 if ( !currentChar )
488 return 0; 489 return 0;
489 QIMPenCharIterator it( currentSet->characters() ); 490 QIMPenCharIterator it( currentSet->characters() );
490 bool found = FALSE; 491 bool found = FALSE;
491 for ( ; it.current(); ++it ) { 492 for ( ; it.current(); ++it ) {
492 if ( !found && it.current() == currentChar ) 493 if ( !found && it.current() == currentChar )
493 found = TRUE; 494 found = TRUE;
494 else if ( found && it.current()->character() == currentCode && 495 else if ( found && it.current()->character() == currentCode &&
495 !it.current()->testFlag( QIMPenChar::Deleted ) ) { 496 !it.current()->testFlag( QIMPenChar::Deleted ) ) {
496 return it.current(); 497 return it.current();
497 } 498 }
498 } 499 }
499 500
500 return 0; 501 return 0;
501} 502}
502 503
503void QIMPenEdit::setCurrentChar( QIMPenChar *pc ) 504void QIMPenEdit::setCurrentChar( QIMPenChar *pc )
504{ 505{
505 currentChar = pc; 506 currentChar = pc;
506 pw->showCharacter( currentChar ); 507 pw->showCharacter( currentChar );
507 if ( currentChar ) { 508 if ( currentChar ) {
508 prevBtn->setEnabled( findPrev() != 0 ); 509 prevBtn->setEnabled( findPrev() != 0 );
509 nextBtn->setEnabled( findNext() != 0 ); 510 nextBtn->setEnabled( findNext() != 0 );
510 } 511 }
511} 512}
512 513
513void QIMPenEdit::prevChar() 514void QIMPenEdit::prevChar()
514{ 515{
515 QIMPenChar *pc = findPrev(); 516 QIMPenChar *pc = findPrev();
516 if ( pc ) 517 if ( pc )
517 setCurrentChar( pc ); 518 setCurrentChar( pc );
518} 519}
519 520
520void QIMPenEdit::nextChar() 521void QIMPenEdit::nextChar()
521{ 522{
522 QIMPenChar *pc = findNext(); 523 QIMPenChar *pc = findNext();
523 if ( pc ) 524 if ( pc )
524 setCurrentChar( pc ); 525 setCurrentChar( pc );
525} 526}
526 527
527void QIMPenEdit::clearChar() 528void QIMPenEdit::clearChar()
528{ 529{
529 inputChar->clear(); 530 inputChar->clear();
530 pw->clear(); 531 pw->clear();
531 enableButtons(); 532 enableButtons();
532} 533}
533 534
534void QIMPenEdit::selectChar( int i ) 535void QIMPenEdit::selectChar( int i )
535{ 536{
536 currentChar = 0; 537 currentChar = 0;
537 currentCode = ((CharListItem *)charList->item(i))->code(); 538 currentCode = ((CharListItem *)charList->item(i))->code();
538 QIMPenCharIterator it(currentSet->characters() ); 539 QIMPenCharIterator it(currentSet->characters() );
539 for ( ; it.current(); ++it ) { 540 for ( ; it.current(); ++it ) {
540 if ( it.current()->character() == currentCode && 541 if ( it.current()->character() == currentCode &&
541 !it.current()->testFlag( QIMPenChar::Deleted ) ) { 542 !it.current()->testFlag( QIMPenChar::Deleted ) ) {
542 setCurrentChar( it.current() ); 543 setCurrentChar( it.current() );
543 break; 544 break;
544 } 545 }
545 } 546 }
546 if ( !it.current() ) 547 if ( !it.current() )
547 setCurrentChar( 0 ); 548 setCurrentChar( 0 );
548 inputChar->clear(); 549 inputChar->clear();
549} 550}
550 551
551void QIMPenEdit::selectCharSet( int i ) 552void QIMPenEdit::selectCharSet( int i )
552{ 553{
553 if ( currentSet ) 554 if ( currentSet )
554 pw->removeCharSet( 0 ); 555 pw->removeCharSet( 0 );
555 currentSet = profile->charSets().at( i ); 556 currentSet = profile->charSets().at( i );
556 fillCharList(); 557 fillCharList();
557 pw->insertCharSet( currentSet ); 558 pw->insertCharSet( currentSet );
558 inputChar->clear(); 559 inputChar->clear();
559 if ( charList->count() ) { 560 if ( charList->count() ) {
560 charList->setSelected( 0, TRUE ); 561 charList->setSelected( 0, TRUE );
561 selectChar(0); 562 selectChar(0);
562 } 563 }
563} 564}
564 565
565void QIMPenEdit::addChar() 566void QIMPenEdit::addChar()
566{ 567{
567 if ( !inputChar->isEmpty() ) { 568 if ( !inputChar->isEmpty() ) {
568 QIMPenChar *pc = new QIMPenChar( *inputChar ); 569 QIMPenChar *pc = new QIMPenChar( *inputChar );
569 pc->setCharacter( currentCode ); 570 pc->setCharacter( currentCode );
570 571
571 // User characters override all matching system characters. 572 // User characters override all matching system characters.
572 // Copy and mark deleted identical system characters. 573 // Copy and mark deleted identical system characters.
573 574
574 QIMPenCharIterator it(currentSet->characters() ); 575 QIMPenCharIterator it(currentSet->characters() );
575 QIMPenChar *sc = 0; 576 QIMPenChar *sc = 0;
576 while ( (sc = it.current()) != 0 ) { 577 while ( (sc = it.current()) != 0 ) {
577 ++it; 578 ++it;
578 if ( sc->character() == currentCode && 579 if ( sc->character() == currentCode &&
579 sc->testFlag( QIMPenChar::System ) && 580 sc->testFlag( QIMPenChar::System ) &&
580 !sc->testFlag( QIMPenChar::Deleted ) ) { 581 !sc->testFlag( QIMPenChar::Deleted ) ) {
581 QIMPenChar *cc = new QIMPenChar( *sc ); 582 QIMPenChar *cc = new QIMPenChar( *sc );
582 cc->clearFlag( QIMPenChar::System ); 583 cc->clearFlag( QIMPenChar::System );
583 currentSet->addChar( cc ); 584 currentSet->addChar( cc );
584 sc->setFlag( QIMPenChar::Deleted ); 585 sc->setFlag( QIMPenChar::Deleted );
585 } 586 }
586 } 587 }
587 588
588 currentSet->addChar( pc ); 589 currentSet->addChar( pc );
589 setCurrentChar( pc ); 590 setCurrentChar( pc );
590 inputChar->clear(); 591 inputChar->clear();
591 } 592 }
592} 593}
593 594
594void QIMPenEdit::addNewChar() 595void QIMPenEdit::addNewChar()
595{ 596{
596 if ( !inputChar->isEmpty() ) { 597 if ( !inputChar->isEmpty() ) {
597 QIMPenInputCharDlg dlg( 0, 0, TRUE ); 598 QIMPenInputCharDlg dlg( 0, 0, TRUE );
598 if ( dlg.exec() ) { 599 if ( dlg.exec() ) {
599 currentCode = dlg.unicode(); 600 currentCode = dlg.unicode();
600 addChar(); 601 addChar();
601 fillCharList(); 602 fillCharList();
602 for ( unsigned int i = 0; i < charList->count(); i++ ) { 603 for ( unsigned int i = 0; i < charList->count(); i++ ) {
603 CharListItem *li = (CharListItem *)charList->item(i); 604 CharListItem *li = (CharListItem *)charList->item(i);
604 if ( li->code() == dlg.unicode() ) { 605 if ( li->code() == dlg.unicode() ) {
605 charList->setSelected( i, TRUE ); 606 charList->setSelected( i, TRUE );
606 break; 607 break;
607 } 608 }
608 } 609 }
609 } 610 }
610 } 611 }
611} 612}
612 613
613void QIMPenEdit::removeChar() 614void QIMPenEdit::removeChar()
614{ 615{
615 if ( currentChar ) { 616 if ( currentChar ) {
616 QIMPenChar *pc = findPrev(); 617 QIMPenChar *pc = findPrev();
617 if ( !pc ) pc = findNext(); 618 if ( !pc ) pc = findNext();
618 if ( currentChar->testFlag( QIMPenChar::System ) ) 619 if ( currentChar->testFlag( QIMPenChar::System ) )
619 currentChar->setFlag( QIMPenChar::Deleted ); 620 currentChar->setFlag( QIMPenChar::Deleted );
620 else 621 else
621 currentSet->removeChar( currentChar ); 622 currentSet->removeChar( currentChar );
622 setCurrentChar( pc ); 623 setCurrentChar( pc );
623 } 624 }
624} 625}
625 626
626void QIMPenEdit::defaultChars() 627void QIMPenEdit::defaultChars()
627{ 628{
628 if ( currentCode ) { 629 if ( currentCode ) {
629 currentChar = 0; 630 currentChar = 0;
630 bool haveSystem = FALSE; 631 bool haveSystem = FALSE;
631 QIMPenCharIterator it(currentSet->characters() ); 632 QIMPenCharIterator it(currentSet->characters() );
632 for ( ; it.current(); ++it ) { 633 for ( ; it.current(); ++it ) {
633 if ( it.current()->character() == currentCode && 634 if ( it.current()->character() == currentCode &&
634 it.current()->testFlag( QIMPenChar::System ) ) { 635 it.current()->testFlag( QIMPenChar::System ) ) {
635 haveSystem = TRUE; 636 haveSystem = TRUE;
636 break; 637 break;
637 } 638 }
638 } 639 }
639 if ( haveSystem ) { 640 if ( haveSystem ) {
640 it.toFirst(); 641 it.toFirst();
641 while ( it.current() ) { 642 while ( it.current() ) {
642 QIMPenChar *pc = it.current(); 643 QIMPenChar *pc = it.current();
643 ++it; 644 ++it;
644 if ( pc->character() == currentCode ) { 645 if ( pc->character() == currentCode ) {
645 if ( pc->testFlag( QIMPenChar::System ) ) { 646 if ( pc->testFlag( QIMPenChar::System ) ) {
646 pc->clearFlag( QIMPenChar::Deleted ); 647 pc->clearFlag( QIMPenChar::Deleted );
647 if ( !currentChar ) 648 if ( !currentChar )
648 currentChar = pc; 649 currentChar = pc;
649 } else { 650 } else {
650 currentSet->removeChar( pc ); 651 currentSet->removeChar( pc );
651 } 652 }
652 } 653 }
653 } 654 }
654 setCurrentChar( currentChar ); 655 setCurrentChar( currentChar );
655 } 656 }
656 } 657 }
657} 658}
658 659
659void QIMPenEdit::newStroke( QIMPenStroke *st ) 660void QIMPenEdit::newStroke( QIMPenStroke *st )
660{ 661{
661 inputChar->addStroke( st ); 662 inputChar->addStroke( st );
662 enableButtons(); 663 enableButtons();
663} 664}
664 665