1 /*
2
3 Copyright (c) 2006-2013 uim Project https://github.com/uim/uim
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 3. Neither the name of authors nor the names of its contributors
17 may be used to endorse or promote products derived from this software
18 without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 SUCH DAMAGE.
31
32 */
33
34 #include "qtextutil.h"
35
36 #include <cstdlib>
37
38 #include <QtGui/QClipboard>
39 #if QT_VERSION < 0x050000
40 # include <QtGui/QApplication>
41 # include <QtGui/QLineEdit>
42 # include <QtGui/QTextEdit>
43 # ifdef ENABLE_QT4_QT3SUPPORT
44 # include <Qt3Support/Q3TextEdit>
45 # endif
46 #else
47 # include <QtWidgets/QApplication>
48 # include <QtWidgets/QLineEdit>
49 # include <QtWidgets/QTextEdit>
50 #endif
51
52 #if QT_VERSION < 0x050000
53 # include "quiminputcontext.h"
54 #else
55 # include <quimplatforminputcontext.h>
56 #endif
57
QUimTextUtil(QObject * parent)58 QUimTextUtil::QUimTextUtil( QObject *parent )
59 : QObject( parent )
60 {
61 #if QT_VERSION < 0x050000
62 mIc = static_cast<QUimInputContext *>( parent );
63 #else
64 mIc = static_cast<QUimPlatformInputContext *>( parent );
65 #endif
66 mPreeditSaved = false;
67 }
68
~QUimTextUtil()69 QUimTextUtil::~QUimTextUtil()
70 {
71 }
72
73 int
acquire_text_cb(void * ptr,enum UTextArea text_id,enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)74 QUimTextUtil::acquire_text_cb( void *ptr, enum UTextArea text_id,
75 enum UTextOrigin origin,
76 int former_req_len, int latter_req_len,
77 char **former, char **latter )
78 {
79 int err;
80 #if QT_VERSION < 0x050000
81 QUimInputContext *ic = static_cast<QUimInputContext *>( ptr );
82 #else
83 QUimPlatformInputContext *ic
84 = static_cast<QUimPlatformInputContext *>( ptr );
85 #endif
86 QUimTextUtil *tu = ic->textUtil();
87
88 switch ( text_id ) {
89 case UTextArea_Primary:
90 err = tu->acquirePrimaryText( origin, former_req_len, latter_req_len,
91 former, latter );
92 break;
93 case UTextArea_Selection:
94 err = tu->acquireSelectionText( origin, former_req_len, latter_req_len,
95 former, latter );
96 break;
97 case UTextArea_Clipboard:
98 err = tu->acquireClipboardText( origin, former_req_len, latter_req_len,
99 former, latter );
100 break;
101 case UTextArea_Unspecified:
102 default:
103 err = -1;
104 }
105
106 return err;
107 }
108
109 int
delete_text_cb(void * ptr,enum UTextArea text_id,enum UTextOrigin origin,int former_req_len,int latter_req_len)110 QUimTextUtil::delete_text_cb( void *ptr, enum UTextArea text_id,
111 enum UTextOrigin origin,
112 int former_req_len, int latter_req_len )
113 {
114 int err;
115 #if QT_VERSION < 0x050000
116 QUimInputContext *ic = static_cast<QUimInputContext *>( ptr );
117 #else
118 QUimPlatformInputContext *ic
119 = static_cast<QUimPlatformInputContext *>( ptr );
120 #endif
121 QUimTextUtil *tu = ic->textUtil();
122
123 switch ( text_id ) {
124 case UTextArea_Primary:
125 err = tu->deletePrimaryText( origin, former_req_len, latter_req_len );
126 break;
127 case UTextArea_Selection:
128 err = tu->deleteSelectionText( origin, former_req_len, latter_req_len );
129 break;
130 case UTextArea_Clipboard:
131 case UTextArea_Unspecified:
132 default:
133 err = -1;
134 break;
135 }
136
137 return err;
138 }
139
140 int
acquirePrimaryText(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)141 QUimTextUtil::acquirePrimaryText( enum UTextOrigin origin,
142 int former_req_len, int latter_req_len,
143 char **former, char **latter )
144 {
145 int err;
146 #if defined(Q_WS_X11) || defined(Q_OS_UNIX)
147 mWidget = QApplication::focusWidget();
148 #else
149 return -1;
150 #endif
151
152 if ( qobject_cast<QLineEdit *>( mWidget ) )
153 err = acquirePrimaryTextInQLineEdit( origin, former_req_len,
154 latter_req_len, former, latter );
155 else if ( qobject_cast<QTextEdit *>( mWidget ) )
156 err = acquirePrimaryTextInQTextEdit( origin, former_req_len,
157 latter_req_len, former, latter );
158 #ifdef ENABLE_QT4_QT3SUPPORT
159 else if ( qobject_cast<Q3TextEdit *>( mWidget ) )
160 err = acquirePrimaryTextInQ3TextEdit( origin, former_req_len,
161 latter_req_len, former, latter );
162 #endif
163 else
164 // FIXME other widgets?
165 err = -1;
166
167 return err;
168 }
169
170 int
acquirePrimaryTextInQLineEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)171 QUimTextUtil::acquirePrimaryTextInQLineEdit( enum UTextOrigin origin,
172 int former_req_len,
173 int latter_req_len,
174 char **former, char **latter )
175 {
176 QLineEdit *edit = static_cast<QLineEdit *>( mWidget );
177 QString text, former_text, latter_text;
178 int cursor_index, len, precedence_len, following_len, offset;
179 int preedit_len, preedit_cursor_pos;
180
181 preedit_len = mIc->getPreeditString().length();
182 preedit_cursor_pos = mIc->getPreeditCursorPosition();
183
184 text = edit->text(); // excluding preedit string
185 len = text.length();
186 cursor_index = edit->cursorPosition() + preedit_len;
187
188 precedence_len = cursor_index - preedit_cursor_pos;
189 following_len = len - precedence_len;
190
191 switch ( origin ) {
192 case UTextOrigin_Cursor:
193 offset = 0;
194 if ( former_req_len >= 0 ) {
195 if ( precedence_len > former_req_len )
196 offset = precedence_len - former_req_len;
197 } else {
198 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
199 return -1;
200 }
201 *former = strdup(
202 text.mid( offset, precedence_len - offset ).toUtf8().data() );
203
204 offset = 0;
205 if ( latter_req_len >= 0 ) {
206 if ( following_len > latter_req_len )
207 offset = following_len - latter_req_len;
208 } else {
209 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) ) {
210 free( *former );
211 return -1;
212 }
213 }
214 *latter = strdup( text.mid( precedence_len + preedit_len,
215 following_len - offset ).toUtf8().data() );
216 break;
217
218 case UTextOrigin_Beginning:
219 *former = 0;
220 if ( latter_req_len >= 0 ) {
221 if ( precedence_len >= latter_req_len )
222 text = text.left( latter_req_len );
223 else {
224 former_text = text.left( precedence_len );
225 if ( following_len >= ( latter_req_len - precedence_len ) )
226 latter_text = text.mid( precedence_len + preedit_len, ( latter_req_len - precedence_len ) );
227 else
228 latter_text = text.mid( precedence_len + preedit_len, following_len );
229 text = former_text + latter_text;
230 }
231 } else {
232 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
233 return -1;
234
235 former_text = text.left( precedence_len );
236 latter_text = text.mid( precedence_len + preedit_len, following_len );
237 text = former_text + latter_text;
238 }
239 *latter = strdup( text.toUtf8().data() );
240 break;
241
242 case UTextOrigin_End:
243 if ( former_req_len >= 0 ) {
244 if ( following_len >= former_req_len )
245 text = text.right( former_req_len );
246 else {
247 latter_text = text.right( following_len );
248 if ( precedence_len >= ( former_req_len - following_len ) )
249 former_text = text.mid( precedence_len - ( former_req_len - following_len ), former_req_len - following_len );
250 else
251 former_text = text.left( precedence_len );
252 text = former_text + latter_text;
253 }
254 } else {
255 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
256 return -1;
257
258 former_text = text.left( precedence_len );
259 latter_text = text.right( following_len );
260 text = former_text + latter_text;
261 }
262 *former = strdup( text.toUtf8().data() );
263 *latter = 0;
264 break;
265
266 case UTextOrigin_Unspecified:
267 default:
268 return -1;
269 }
270
271 return 0;
272 }
273
274 int
acquirePrimaryTextInQTextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)275 QUimTextUtil::acquirePrimaryTextInQTextEdit( enum UTextOrigin origin,
276 int former_req_len,
277 int latter_req_len,
278 char **former, char **latter )
279 {
280 QTextEdit *edit = static_cast<QTextEdit *>( mWidget );
281 QString text = edit->toPlainText(); // excluding preedit string
282 int len = text.length();
283
284 int preedit_len = mIc->getPreeditString().length();
285 int preedit_cursor_pos = mIc->getPreeditCursorPosition();
286
287 int cursor_index = edit->textCursor().position() + preedit_len;
288 int precedence_len = cursor_index - preedit_cursor_pos;
289 int following_len = len - precedence_len;
290
291 QString former_text;
292 QString latter_text;
293 switch ( origin ) {
294 case UTextOrigin_Cursor:
295 {
296 int offset = 0;
297 if ( former_req_len >= 0 ) {
298 if ( precedence_len > former_req_len )
299 offset = precedence_len - former_req_len;
300 } else {
301 if (! ( ~former_req_len
302 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
303 return -1;
304 }
305 *former = strdup(
306 text.mid( offset, precedence_len - offset ).toUtf8().data() );
307
308 offset = 0;
309 if ( latter_req_len >= 0 ) {
310 if ( following_len > latter_req_len )
311 offset = following_len - latter_req_len;
312 } else {
313 if (! ( ~latter_req_len
314 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) ) {
315 free( *former );
316 return -1;
317 }
318 }
319 *latter = strdup( text.mid( precedence_len + preedit_len,
320 following_len - offset ).toUtf8().data() );
321 break;
322 }
323
324 case UTextOrigin_Beginning:
325 *former = 0;
326 if ( latter_req_len >= 0 ) {
327 if ( precedence_len >= latter_req_len )
328 text = text.left( latter_req_len );
329 else {
330 former_text = text.left( precedence_len );
331 if ( following_len >= ( latter_req_len - precedence_len ) )
332 latter_text = text.mid( precedence_len + preedit_len,
333 ( latter_req_len - precedence_len ) );
334 else
335 latter_text = text.mid( precedence_len + preedit_len,
336 following_len );
337 text = former_text + latter_text;
338 }
339 } else {
340 if (! ( ~latter_req_len
341 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
342 return -1;
343
344 former_text = text.left( precedence_len );
345 latter_text = text.mid( precedence_len + preedit_len,
346 following_len );
347 text = former_text + latter_text;
348 }
349 *latter = strdup( text.toUtf8().data() );
350 break;
351
352 case UTextOrigin_End:
353 if ( former_req_len >= 0 ) {
354 if ( following_len >= former_req_len )
355 text = text.right( former_req_len );
356 else {
357 latter_text = text.right( following_len );
358 if ( precedence_len >= ( former_req_len - following_len ) )
359 former_text = text.mid( precedence_len
360 - ( former_req_len - following_len ),
361 former_req_len - following_len );
362 else
363 former_text = text.left( precedence_len );
364 text = former_text + latter_text;
365 }
366 } else {
367 if (! ( ~former_req_len
368 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
369 return -1;
370
371 former_text = text.left( precedence_len );
372 latter_text = text.right( following_len );
373 text = former_text + latter_text;
374 }
375 *former = strdup( text.toUtf8().data() );
376 *latter = 0;
377 break;
378
379 case UTextOrigin_Unspecified:
380 default:
381 return -1;
382 }
383
384 return 0;
385 }
386
387 #ifdef ENABLE_QT4_QT3SUPPORT
388 int
acquirePrimaryTextInQ3TextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)389 QUimTextUtil::acquirePrimaryTextInQ3TextEdit( enum UTextOrigin origin,
390 int former_req_len,
391 int latter_req_len,
392 char **former, char **latter )
393 {
394 Q3TextEdit *edit = static_cast<Q3TextEdit *>( mWidget );
395 QString text;
396
397 int start_para, start_index, end_para, end_index, para, index;
398 int n_para;
399 int preedit_len, preedit_cursor_pos;
400 int sel_start_para, sel_start_index, sel_end_para, sel_end_index;
401 Qt::TextFormat format;
402
403 format = edit->textFormat();
404 edit->setTextFormat( Qt::PlainText );
405
406 edit->getCursorPosition( ¶, &index ); // including preedit string
407
408 // keep current selection
409 edit->getSelection( &sel_start_para, &sel_start_index, &sel_end_para,
410 &sel_end_index, 0 );
411
412 preedit_len = mIc->getPreeditString().length();
413 preedit_cursor_pos = mIc->getPreeditCursorPosition();
414 n_para = edit->paragraphs();
415
416 switch ( origin ) {
417 case UTextOrigin_Cursor:
418 start_index = index - preedit_cursor_pos;
419 start_para = para;
420 end_index = start_index + preedit_len;
421 end_para = para;
422
423 if ( former_req_len >= 0 ) {
424 for ( int i = 0; i < former_req_len; i++ )
425 Q3TextEditPositionBackward( &start_para, &start_index );
426 } else {
427 if ( former_req_len == UTextExtent_Line )
428 start_index = 0;
429 else if ( former_req_len == UTextExtent_Full ) {
430 start_para = 0;
431 start_index = 0;
432 } else {
433 edit->setTextFormat( format );
434 return -1;
435 }
436 }
437 edit->setSelection( start_para, start_index, para, index - preedit_cursor_pos, 0 );
438 *former = strdup( edit->selectedText().toUtf8().data() );
439
440 if ( latter_req_len >= 0 ) {
441 for ( int i = 0; i < latter_req_len; i++ )
442 Q3TextEditPositionForward( &end_para, &end_index );
443 } else {
444 if ( latter_req_len == UTextExtent_Line ) {
445 end_index = edit->paragraphLength( end_para );
446 } else if ( latter_req_len == UTextExtent_Full ) {
447 end_para = n_para - 1;
448 end_index = edit->paragraphLength( end_para );
449 } else {
450 edit->setTextFormat( format );
451 return -1;
452 }
453 }
454 edit->setSelection( para, index - preedit_cursor_pos + preedit_len,
455 end_para, end_index, 0 );
456 *latter = strdup( edit->selectedText().toUtf8().data() );
457 break;
458
459 case UTextOrigin_Beginning:
460 *former = 0;
461
462 start_para = 0;
463 start_index = 0;
464 end_para = start_para;
465 end_index = start_index;
466
467 if ( latter_req_len >= 0 ) {
468 for ( int i = 0; i < latter_req_len; i++ )
469 Q3TextEditPositionForward( &end_para, &end_index );
470 } else {
471 if ( latter_req_len == UTextExtent_Line )
472 end_index = edit->paragraphLength( end_para );
473 else if ( latter_req_len == UTextExtent_Full ) {
474 end_para = n_para - 1;
475 end_index = edit->paragraphLength( end_para );
476 } else {
477 edit->setTextFormat( format );
478 return -1;
479 }
480 }
481 if ( end_para < para || ( end_para == para && end_index <= ( index - preedit_cursor_pos ) ) ) {
482 edit->setSelection( start_para, start_index, end_para, end_index, 0 );
483 text = edit->selectedText();
484 } else {
485 edit->setSelection( start_para, start_index, para, index - preedit_cursor_pos, 0 );
486 text = edit->selectedText();
487 edit->setSelection( para, index - preedit_cursor_pos + preedit_len, end_para, end_index, 0 );
488 text += edit->selectedText();
489 }
490 *latter = strdup( text.toUtf8().data() );
491 break;
492
493 case UTextOrigin_End:
494
495 end_para = n_para - 1;
496 end_index = edit->paragraphLength( end_para );
497 start_para = end_para;
498 start_index = end_index;
499
500 if ( former_req_len >= 0 ) {
501 for ( int i = 0; i < former_req_len; i++ )
502 Q3TextEditPositionBackward( &start_para, &start_index );
503 } else {
504 if ( former_req_len == UTextExtent_Line )
505 start_index = 0;
506 else if ( former_req_len == UTextExtent_Full ) {
507 start_para = 0;
508 start_index = 0;
509 } else {
510 edit->setTextFormat( format );
511 return -1;
512 }
513 }
514 if ( start_para > para || ( start_para == para && start_index >= ( index - preedit_cursor_pos + preedit_len ) ) ) {
515 edit->setSelection( start_para, start_index, end_para, end_index, 0 );
516 text = edit->selectedText();
517 } else {
518
519 edit->setSelection( start_para, start_index, para, index - preedit_cursor_pos, 0 );
520 text = edit->selectedText();
521
522 edit->setSelection( para, index - preedit_cursor_pos + preedit_len, end_para, end_index, 0 );
523 text += edit->selectedText();
524 }
525 *former = strdup( text.toUtf8().data() );
526 *latter = 0;
527 break;
528
529 case UTextOrigin_Unspecified:
530 default:
531 edit->setTextFormat( format );
532 return -1;
533 }
534
535 if ( sel_start_para != -1 && sel_start_index != -1 && sel_end_para != -1 &&
536 sel_end_index != -1 )
537 edit->setSelection( sel_start_index, sel_start_index, sel_end_para, sel_end_index, 0 );
538 else
539 edit->removeSelection( 0 );
540
541 edit->setCursorPosition( para, index );
542
543 edit->setTextFormat( format );
544 return 0;
545 }
546 #endif
547
548 int
acquireSelectionText(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)549 QUimTextUtil::acquireSelectionText( enum UTextOrigin origin,
550 int former_req_len, int latter_req_len,
551 char **former, char **latter )
552 {
553 int err;
554 #if defined(Q_WS_X11) || defined(Q_OS_UNIX)
555 mWidget = QApplication::focusWidget();
556 #else
557 return -1;
558 #endif
559
560 if ( qobject_cast<QLineEdit *>( mWidget ) )
561 err = acquireSelectionTextInQLineEdit( origin, former_req_len,
562 latter_req_len, former, latter );
563 else if ( qobject_cast<QTextEdit *>( mWidget ) )
564 err = acquireSelectionTextInQTextEdit( origin, former_req_len,
565 latter_req_len, former, latter );
566 #ifdef ENABLE_QT4_QT3SUPPORT
567 else if ( qobject_cast<Q3TextEdit *>( mWidget ) )
568 err = acquireSelectionTextInQ3TextEdit( origin, former_req_len,
569 latter_req_len, former,
570 latter );
571 #endif
572 else
573 // FIXME other widgets?
574 err = -1;
575
576 return err;
577 }
578
579 int
acquireSelectionTextInQLineEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)580 QUimTextUtil::acquireSelectionTextInQLineEdit( enum UTextOrigin origin,
581 int former_req_len,
582 int latter_req_len,
583 char **former, char **latter )
584 {
585 QLineEdit *edit = static_cast<QLineEdit *>( mWidget );
586 QString text;
587 int len, offset, start, current;
588 bool cursor_at_beginning = false;
589
590 if ( ! edit->hasSelectedText() )
591 return -1;
592
593 current = edit->cursorPosition();
594 start = edit->selectionStart();
595
596 if ( current == start )
597 cursor_at_beginning = true;
598
599 text = edit->selectedText();
600 len = text.length();
601
602 if ( origin == UTextOrigin_Beginning ||
603 ( origin == UTextOrigin_Cursor && cursor_at_beginning ) ) {
604 *former = 0;
605 offset = 0;
606 if ( latter_req_len >= 0 ) {
607 if ( len > latter_req_len )
608 offset = len - latter_req_len;
609 } else {
610 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
611 return -1;
612 }
613 *latter = strdup( text.left( len - offset ).toUtf8().data() );
614 } else if ( origin == UTextOrigin_End ||
615 ( origin == UTextOrigin_Cursor && !cursor_at_beginning ) ) {
616 offset = 0;
617 if ( former_req_len >= 0 ) {
618 if ( len > former_req_len )
619 offset = len - former_req_len;
620 } else {
621 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
622 return -1;
623 }
624 *former = strdup( text.mid( offset, len - offset ).toUtf8().data() );
625 *latter = 0;
626 } else {
627 return -1;
628 }
629
630 return 0;
631 }
632
633 int
acquireSelectionTextInQTextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)634 QUimTextUtil::acquireSelectionTextInQTextEdit( enum UTextOrigin origin,
635 int former_req_len,
636 int latter_req_len,
637 char **former, char **latter )
638 {
639 QTextEdit *edit = static_cast<QTextEdit *>( mWidget );
640 QTextCursor cursor = edit->textCursor();
641 if ( ! cursor.hasSelection() )
642 return -1;
643
644 bool cursor_at_beginning = false;
645 int current = cursor.position();
646 int start = cursor.selectionStart();
647 if ( current == start )
648 cursor_at_beginning = true;
649
650 QString text = cursor.selectedText();
651 int len = text.length();
652 int offset;
653 if ( origin == UTextOrigin_Beginning ||
654 ( origin == UTextOrigin_Cursor && cursor_at_beginning ) ) {
655 *former = 0;
656 offset = 0;
657 if ( latter_req_len >= 0 ) {
658 if ( len > latter_req_len )
659 offset = len - latter_req_len;
660 } else {
661 if (! ( ~latter_req_len
662 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
663 return -1;
664 }
665 *latter = strdup( text.left( len - offset ).toUtf8().data() );
666 } else if ( origin == UTextOrigin_End ||
667 ( origin == UTextOrigin_Cursor && !cursor_at_beginning ) ) {
668 offset = 0;
669 if ( former_req_len >= 0 ) {
670 if ( len > former_req_len )
671 offset = len - former_req_len;
672 } else {
673 if (! ( ~former_req_len
674 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
675 return -1;
676 }
677 *former = strdup( text.mid( offset, len - offset ).toUtf8().data() );
678 *latter = 0;
679 } else {
680 return -1;
681 }
682
683 return 0;
684 }
685
686 #ifdef ENABLE_QT4_QT3SUPPORT
687 int
acquireSelectionTextInQ3TextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)688 QUimTextUtil::acquireSelectionTextInQ3TextEdit( enum UTextOrigin origin,
689 int former_req_len,
690 int latter_req_len,
691 char **former, char **latter )
692 {
693 Q3TextEdit *edit = static_cast<Q3TextEdit *>( mWidget );
694 QString text;
695 int len, offset, newline;
696 int start_para, start_index, end_para, end_index;
697 int para, index;
698 bool cursor_at_beginning = false;
699 Qt::TextFormat format;
700
701 if ( ! edit->hasSelectedText() )
702 return -1;
703
704 format = edit->textFormat();
705 edit->setTextFormat( Qt::PlainText );
706
707 edit->getCursorPosition( ¶, &index );
708 edit->getSelection(&start_para, &start_index, &end_para, &end_index, 0 );
709
710 if ( para == start_para && index == start_index )
711 cursor_at_beginning = true;
712
713 text = edit->selectedText();
714 len = text.length();
715
716 if ( origin == UTextOrigin_Beginning ||
717 ( origin == UTextOrigin_Cursor && cursor_at_beginning ) ) {
718 *former = 0;
719 offset = 0;
720 if ( latter_req_len >= 0 ) {
721 if ( len > latter_req_len )
722 offset = len - latter_req_len;
723 } else {
724 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) ) {
725 edit->setTextFormat( format );
726 return -1;
727 }
728
729 if ( latter_req_len == UTextExtent_Line && ( ( newline = text.indexOf( '\n' ) ) != -1 ) )
730 offset = len - newline;
731 }
732 *latter = strdup( text.left( len - offset ).toUtf8().data() );
733 } else if ( origin == UTextOrigin_End ||
734 ( origin == UTextOrigin_Cursor && !cursor_at_beginning ) ) {
735 offset = 0;
736 if ( former_req_len >= 0 ) {
737 if ( len > former_req_len )
738 offset = len - former_req_len;
739 } else {
740 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) ) {
741 edit->setTextFormat( format );
742 return -1;
743 }
744
745 if ( former_req_len == UTextExtent_Line && ( ( newline = text.lastIndexOf( '\n' ) ) != -1 ) )
746 offset = newline + 1;
747 }
748 *former = strdup( text.mid( offset, len - offset ).toUtf8().data() );
749 *latter = 0;
750 } else {
751 edit->setTextFormat( format );
752 return -1;
753 }
754
755 edit->setTextFormat( format );
756 return 0;
757 }
758 #endif
759
760 int
acquireClipboardText(enum UTextOrigin origin,int former_req_len,int latter_req_len,char ** former,char ** latter)761 QUimTextUtil::acquireClipboardText( enum UTextOrigin origin,
762 int former_req_len, int latter_req_len,
763 char **former, char **latter )
764 {
765 QClipboard *cb = QApplication::clipboard();
766 QString text = cb->text( QClipboard::Clipboard );
767 int len, offset, newline;
768
769 if ( text.isNull() )
770 return -1;
771
772 len = text.length();
773
774 /* Cursor position is assumed to be at the end */
775 switch ( origin ) {
776 case UTextOrigin_Cursor:
777 case UTextOrigin_End:
778 offset = 0;
779 if ( former_req_len >= 0 ) {
780 if ( former_req_len < len )
781 offset = len - former_req_len;
782 } else {
783 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
784 return -1;
785
786 if ( former_req_len == UTextExtent_Line
787 && ( ( newline = text.lastIndexOf( '\n' ) ) != -1 ) )
788 offset = newline + 1;
789 }
790 *former = strdup( text.mid( offset, len - offset ).toUtf8().data() );
791 *latter = 0;
792 break;
793
794 case UTextOrigin_Beginning:
795 *former = 0;
796 offset = 0;
797 if ( latter_req_len >= 0 ) {
798 if ( latter_req_len < len )
799 offset = len - latter_req_len;
800 } else {
801 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
802 return -1;
803
804 if ( latter_req_len == UTextExtent_Line
805 && ( ( newline = text.indexOf( '\n' ) ) != -1 ) )
806 offset = len - newline;
807 }
808 *latter = strdup( text.left( len - offset ).toUtf8().data() );
809 break;
810
811 case UTextOrigin_Unspecified:
812 default:
813 return -1;
814 }
815
816 return 0;
817 }
818
819 int
deletePrimaryText(enum UTextOrigin origin,int former_req_len,int latter_req_len)820 QUimTextUtil::deletePrimaryText( enum UTextOrigin origin, int former_req_len,
821 int latter_req_len )
822 {
823 int err;
824 #if defined(Q_WS_X11) || defined(Q_OS_UNIX)
825 mWidget = QApplication::focusWidget();
826 #else
827 return -1;
828 #endif
829
830 if ( qobject_cast<QLineEdit *>( mWidget ) )
831 err = deletePrimaryTextInQLineEdit( origin, former_req_len,
832 latter_req_len );
833 else if ( qobject_cast<QTextEdit *>( mWidget ) )
834 err = deletePrimaryTextInQTextEdit( origin, former_req_len,
835 latter_req_len );
836 #ifdef ENABLE_QT4_QT3SUPPORT
837 else if ( qobject_cast<Q3TextEdit *>( mWidget ) )
838 err = deletePrimaryTextInQ3TextEdit( origin, former_req_len,
839 latter_req_len );
840 #endif
841 else
842 // FIXME other widgets?
843 err = -1;
844
845 return err;
846 }
847
848 int
deletePrimaryTextInQLineEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len)849 QUimTextUtil::deletePrimaryTextInQLineEdit( enum UTextOrigin origin,
850 int former_req_len,
851 int latter_req_len )
852 {
853 QLineEdit *edit = static_cast<QLineEdit *>( mWidget );
854 QString text;
855 int len, precedence_len, following_len;
856 int preedit_len;
857 int former_del_start;
858 int latter_del_end;
859
860 preedit_len = mIc->getPreeditString().length();
861
862 text = edit->text(); // excluding preedit string
863 len = text.length();
864 precedence_len = edit->cursorPosition();
865 following_len = len - precedence_len;
866
867 switch ( origin ) {
868 case UTextOrigin_Cursor:
869 former_del_start = 0;
870 if ( former_req_len >= 0 ) {
871 if ( precedence_len > former_req_len )
872 former_del_start = precedence_len - former_req_len;
873 } else {
874 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
875 return -1;
876 }
877 latter_del_end = len + preedit_len;
878 if ( latter_req_len >= 0 ) {
879 if ( following_len > latter_req_len )
880 latter_del_end = precedence_len + preedit_len + latter_req_len;
881 } else {
882 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
883 return -1;
884 }
885 break;
886
887 case UTextOrigin_Beginning:
888 former_del_start = 0;
889 latter_del_end = precedence_len + preedit_len;
890 if ( latter_req_len >= 0 ) {
891 if ( precedence_len < latter_req_len ) {
892 if ( following_len >= ( latter_req_len - precedence_len ) )
893 latter_del_end = preedit_len + latter_req_len;
894 else
895 latter_del_end = len + preedit_len;
896 }
897 } else {
898 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
899 return -1;
900 latter_del_end = len + preedit_len;
901 }
902 break;
903
904 case UTextOrigin_End:
905 former_del_start = precedence_len;
906 latter_del_end = len + preedit_len;
907 if ( former_req_len < 0 ) {
908 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
909 return -1;
910
911 former_del_start = 0;
912 }
913 break;
914
915 case UTextOrigin_Unspecified:
916 default:
917 return -1;
918 }
919
920 edit->setText( text.left( former_del_start ) + text.right( len - latter_del_end + preedit_len ) );
921 edit->setCursorPosition( former_del_start );
922
923 return 0;
924 }
925
926 int
deletePrimaryTextInQTextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len)927 QUimTextUtil::deletePrimaryTextInQTextEdit( enum UTextOrigin origin,
928 int former_req_len,
929 int latter_req_len )
930 {
931 QTextEdit *edit = static_cast<QTextEdit *>( mWidget );
932 QString text = edit->toPlainText(); // excluding preedit string
933 int len = text.length();
934
935 int preedit_len = mIc->getPreeditString().length();
936
937 QTextCursor cursor = edit->textCursor();
938 int precedence_len = cursor.position();
939 int following_len = len - precedence_len;
940
941 int former_del_start;
942 int latter_del_end;
943 switch ( origin ) {
944 case UTextOrigin_Cursor:
945 former_del_start = 0;
946 if ( former_req_len >= 0 ) {
947 if ( precedence_len > former_req_len )
948 former_del_start = precedence_len - former_req_len;
949 } else {
950 if (! ( ~former_req_len
951 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
952 return -1;
953 }
954 latter_del_end = len + preedit_len;
955 if ( latter_req_len >= 0 ) {
956 if ( following_len > latter_req_len )
957 latter_del_end = precedence_len + preedit_len + latter_req_len;
958 } else {
959 if (! ( ~latter_req_len
960 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
961 return -1;
962 }
963 break;
964
965 case UTextOrigin_Beginning:
966 former_del_start = 0;
967 latter_del_end = precedence_len + preedit_len;
968 if ( latter_req_len >= 0 ) {
969 if ( precedence_len < latter_req_len ) {
970 if ( following_len >= ( latter_req_len - precedence_len ) )
971 latter_del_end = preedit_len + latter_req_len;
972 else
973 latter_del_end = len + preedit_len;
974 }
975 } else {
976 if (! ( ~latter_req_len
977 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
978 return -1;
979 latter_del_end = len + preedit_len;
980 }
981 break;
982
983 case UTextOrigin_End:
984 former_del_start = precedence_len;
985 latter_del_end = len + preedit_len;
986 if ( former_req_len < 0 ) {
987 if (! ( ~former_req_len
988 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
989 return -1;
990
991 former_del_start = 0;
992 }
993 break;
994
995 case UTextOrigin_Unspecified:
996 default:
997 return -1;
998 }
999
1000 // don't call setText() to avoid flicker unlike QLineEdit
1001 int end_index = latter_del_end - preedit_len;
1002 if ( precedence_len != end_index ) {
1003 cursor.setPosition( precedence_len );
1004 cursor.setPosition( end_index, QTextCursor::KeepAnchor );
1005 edit->setTextCursor( cursor );
1006 cursor.deleteChar();
1007 }
1008 if ( precedence_len != former_del_start ) {
1009 cursor.setPosition( precedence_len );
1010 cursor.setPosition( former_del_start, QTextCursor::KeepAnchor );
1011 edit->setTextCursor( cursor );
1012 cursor.deleteChar();
1013 }
1014
1015 return 0;
1016 }
1017
1018 #ifdef ENABLE_QT4_QT3SUPPORT
1019 int
deletePrimaryTextInQ3TextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len)1020 QUimTextUtil::deletePrimaryTextInQ3TextEdit( enum UTextOrigin origin,
1021 int former_req_len,
1022 int latter_req_len )
1023 {
1024 Q3TextEdit *edit = static_cast<Q3TextEdit *>( mWidget );
1025 int start_para, start_index, end_para, end_index, para, index;
1026 int n_para;
1027
1028 savePreedit();
1029
1030 edit->getCursorPosition( ¶, &index );
1031 n_para = edit->paragraphs();
1032
1033 switch ( origin ) {
1034 case UTextOrigin_Cursor:
1035 start_index = index;
1036 start_para = para;
1037 end_index = start_index;
1038 end_para = para;
1039
1040 if ( former_req_len >= 0 ) {
1041 for ( int i = 0; i < former_req_len; i++ )
1042 Q3TextEditPositionBackward( &start_para, &start_index );
1043 } else {
1044 if ( former_req_len == UTextExtent_Line ) {
1045 start_index = 0;
1046 } else if ( former_req_len == UTextExtent_Full ) {
1047 start_para = 0;
1048 start_index = 0;
1049 } else {
1050 restorePreedit();
1051 return -1;
1052 }
1053 }
1054 if ( latter_req_len >= 0 ) {
1055 for ( int i = 0; i < latter_req_len; i++ )
1056 Q3TextEditPositionForward( &end_para, &end_index );
1057 } else {
1058 if ( latter_req_len == UTextExtent_Line ) {
1059 end_index = edit->paragraphLength( end_para );
1060 } else if ( latter_req_len == UTextExtent_Full ) {
1061 end_para = n_para - 1;
1062 end_index = edit->paragraphLength( end_para );
1063 } else {
1064 restorePreedit();
1065 return -1;
1066 }
1067 }
1068 break;
1069
1070 case UTextOrigin_Beginning:
1071 start_para = 0;
1072 start_index = 0;
1073 end_para = start_para;
1074 end_index = start_index;
1075
1076 if ( latter_req_len >= 0 ) {
1077 for ( int i = 0; i < latter_req_len; i++ )
1078 Q3TextEditPositionForward( &end_para, &end_index );
1079 } else {
1080 if ( latter_req_len == UTextExtent_Line ) {
1081 end_index = edit->paragraphLength( end_para );
1082 } else if ( latter_req_len == UTextExtent_Full ) {
1083 end_para = n_para - 1;
1084 end_index = edit->paragraphLength( end_para );
1085 } else {
1086 restorePreedit();
1087 return -1;
1088 }
1089 }
1090 break;
1091
1092 case UTextOrigin_End:
1093 end_para = n_para - 1;
1094 end_index = edit->paragraphLength( end_para );
1095 start_para = end_para;
1096 start_index = end_index;
1097
1098 if ( former_req_len >= 0 ) {
1099 for ( int i = 0; i < former_req_len; i++ )
1100 Q3TextEditPositionBackward( &start_para, &start_index );
1101 } else {
1102 if ( former_req_len == UTextExtent_Line )
1103 start_index = 0;
1104 else if ( former_req_len == UTextExtent_Full ) {
1105 start_para = 0;
1106 start_index = 0;
1107 } else {
1108 restorePreedit();
1109 return -1;
1110 }
1111 }
1112 break;
1113
1114 case UTextOrigin_Unspecified:
1115 default:
1116 restorePreedit();
1117 return -1;
1118 }
1119 edit->setSelection( start_para, start_index, end_para, end_index, 1 );
1120 edit->removeSelectedText( 1 );
1121 edit->setCursorPosition( start_para, start_index );
1122 restorePreedit();
1123
1124 return 0;
1125 }
1126 #endif
1127
1128 int
deleteSelectionText(enum UTextOrigin origin,int former_req_len,int latter_req_len)1129 QUimTextUtil::deleteSelectionText( enum UTextOrigin origin,
1130 int former_req_len, int latter_req_len )
1131 {
1132 int err;
1133 #if defined(Q_WS_X11) || defined(Q_OS_UNIX)
1134 mWidget = QApplication::focusWidget();
1135 #else
1136 return -1;
1137 #endif
1138
1139 if ( qobject_cast<QLineEdit *>( mWidget ) )
1140 err = deleteSelectionTextInQLineEdit( origin, former_req_len,
1141 latter_req_len );
1142 else if ( qobject_cast<QTextEdit *>( mWidget ) )
1143 err = deleteSelectionTextInQTextEdit( origin, former_req_len,
1144 latter_req_len );
1145 #ifdef ENABLE_QT4_QT3SUPPORT
1146 else if ( qobject_cast<Q3TextEdit *>( mWidget ) )
1147 err = deleteSelectionTextInQ3TextEdit( origin, former_req_len,
1148 latter_req_len );
1149 #endif
1150 else
1151 // FIXME other widgets?
1152 err = -1;
1153
1154 return err;
1155 }
1156
1157 int
deleteSelectionTextInQLineEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len)1158 QUimTextUtil::deleteSelectionTextInQLineEdit( enum UTextOrigin origin,
1159 int former_req_len,
1160 int latter_req_len )
1161 {
1162 QLineEdit *edit = static_cast<QLineEdit *>( mWidget );
1163 QString text;
1164 int len, start, end, current;
1165 bool cursor_at_beginning = false;
1166
1167 if ( ! edit->hasSelectedText() )
1168 return -1;
1169
1170 current = edit->cursorPosition();
1171 start = edit->selectionStart();
1172 if ( current == start )
1173 cursor_at_beginning = true;
1174
1175 text = edit->selectedText();
1176 len = text.length();
1177 end = start + len;
1178
1179 if ( origin == UTextOrigin_Beginning ||
1180 ( origin == UTextOrigin_Cursor && cursor_at_beginning ) ) {
1181 if ( latter_req_len >= 0 ) {
1182 if ( len > latter_req_len )
1183 end = start + latter_req_len;
1184 } else {
1185 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
1186 return -1;
1187 }
1188 } else if ( origin == UTextOrigin_End ||
1189 ( origin == UTextOrigin_Cursor && !cursor_at_beginning ) ) {
1190 if ( former_req_len >= 0 ) {
1191 if ( len > former_req_len )
1192 start = end - former_req_len;
1193 } else {
1194 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
1195 return -1;
1196 }
1197 } else {
1198 return -1;
1199 }
1200 edit->setSelection( start, end - start );
1201 edit->del();
1202
1203 return 0;
1204 }
1205
1206 int
deleteSelectionTextInQTextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len)1207 QUimTextUtil::deleteSelectionTextInQTextEdit( enum UTextOrigin origin,
1208 int former_req_len,
1209 int latter_req_len )
1210 {
1211 QTextEdit *edit = static_cast<QTextEdit *>( mWidget );
1212 QTextCursor cursor = edit->textCursor();
1213 if ( ! cursor.hasSelection() )
1214 return -1;
1215
1216 bool cursor_at_beginning = false;
1217 int current = cursor.position();
1218 int start = cursor.selectionStart();
1219 if ( current == start )
1220 cursor_at_beginning = true;
1221
1222 QString text = cursor.selectedText();
1223 int len = text.length();
1224 int end = start + len;
1225 if ( origin == UTextOrigin_Beginning ||
1226 ( origin == UTextOrigin_Cursor && cursor_at_beginning ) ) {
1227 if ( latter_req_len >= 0 ) {
1228 if ( len > latter_req_len )
1229 end = start + latter_req_len;
1230 } else {
1231 if (! ( ~latter_req_len
1232 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
1233 return -1;
1234 }
1235 } else if ( origin == UTextOrigin_End ||
1236 ( origin == UTextOrigin_Cursor && !cursor_at_beginning ) ) {
1237 if ( former_req_len >= 0 ) {
1238 if ( len > former_req_len )
1239 start = end - former_req_len;
1240 } else {
1241 if (! ( ~former_req_len
1242 & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
1243 return -1;
1244 }
1245 } else {
1246 return -1;
1247 }
1248 cursor.setPosition( start );
1249 cursor.setPosition( end, QTextCursor::KeepAnchor );
1250 edit->setTextCursor( cursor );
1251 cursor.deleteChar();
1252
1253 return 0;
1254 }
1255
1256 #ifdef ENABLE_QT4_QT3SUPPORT
1257 int
deleteSelectionTextInQ3TextEdit(enum UTextOrigin origin,int former_req_len,int latter_req_len)1258 QUimTextUtil::deleteSelectionTextInQ3TextEdit( enum UTextOrigin origin,
1259 int former_req_len,
1260 int latter_req_len )
1261 {
1262 Q3TextEdit *edit = static_cast<Q3TextEdit *>( mWidget );
1263 QString text;
1264 int len, newline;
1265 int para, index;
1266 int sel_para_from, sel_index_from, sel_para_to, sel_index_to;
1267 int start_para, start_index, end_para, end_index;
1268 bool cursor_at_beginning = false;
1269
1270 if ( ! edit->hasSelectedText() )
1271 return -1;
1272
1273 edit->getCursorPosition( ¶, &index );
1274 edit->getSelection( &sel_para_from, &sel_index_from, &sel_para_to, &sel_index_to, 0 );
1275
1276 if ( para == sel_para_from && index == sel_index_from )
1277 cursor_at_beginning = true;
1278
1279 text = edit->selectedText();
1280 len = text.length();
1281
1282 start_para = sel_para_from;
1283 start_index = sel_index_from;
1284 end_para = sel_para_to;
1285 end_index = sel_index_to;
1286
1287 if ( origin == UTextOrigin_Beginning ||
1288 ( origin == UTextOrigin_Cursor && cursor_at_beginning ) ) {
1289 edit->setCursorPosition( sel_para_from, sel_index_from );
1290 if ( latter_req_len >= 0 ) {
1291 if ( len > latter_req_len ) {
1292 end_para = sel_para_from;
1293 end_index = sel_index_from;
1294 for ( int i = 0; i < latter_req_len; i++)
1295 Q3TextEditPositionForward( &end_para, &end_index );
1296 }
1297 } else {
1298 if (! ( ~latter_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
1299 return -1;
1300
1301 if ( latter_req_len == UTextExtent_Line && ( ( newline = text.indexOf('\n') ) != -1 ) ) {
1302 end_para = sel_para_from;
1303 end_index = sel_index_from + newline;
1304 }
1305 }
1306 } else if ( origin == UTextOrigin_End ||
1307 ( origin == UTextOrigin_Cursor && !cursor_at_beginning ) ) {
1308 if ( former_req_len >= 0 ) {
1309 if ( len > former_req_len ) {
1310 start_para = sel_para_to;
1311 start_index = sel_index_to;
1312 for ( int i = 0; i < former_req_len; i++)
1313 Q3TextEditPositionBackward( &start_para, &start_index );
1314 }
1315 } else {
1316 if (! ( ~former_req_len & ( ~UTextExtent_Line | ~UTextExtent_Full ) ) )
1317 return -1;
1318
1319 if ( former_req_len == UTextExtent_Line && ( ( newline = text.lastIndexOf( '\n' ) ) != -1 ) ) {
1320 start_para = sel_para_to;
1321 start_index = 0;
1322 }
1323 }
1324 } else {
1325 return -1;
1326 }
1327 edit->setSelection( start_para, start_index, end_para, end_index, 1 );
1328 edit->removeSelectedText( 1 );
1329
1330 return 0;
1331 }
1332
1333 void
Q3TextEditPositionBackward(int * cursor_para,int * cursor_index)1334 QUimTextUtil::Q3TextEditPositionBackward( int *cursor_para, int *cursor_index )
1335 {
1336 Q3TextEdit *edit = static_cast<Q3TextEdit *>( mWidget );
1337 int preedit_len, preedit_cursor_pos;
1338 int para, index;
1339 int current_para, current_index;
1340
1341 current_para = *cursor_para;
1342 current_index = *cursor_index;
1343
1344 if ( ! mPreeditSaved ) {
1345 preedit_len = mIc->getPreeditString().length();
1346 preedit_cursor_pos = mIc->getPreeditCursorPosition();
1347 } else {
1348 preedit_len = 0;
1349 preedit_cursor_pos = 0;
1350 }
1351 edit->getCursorPosition( ¶, &index );
1352
1353 if ( current_para == para && current_index > ( index - preedit_cursor_pos ) && ( current_index <= ( index - preedit_cursor_pos + preedit_len ) ) )
1354 current_index = index - preedit_cursor_pos;
1355
1356 if ( current_index > 0 )
1357 current_index--;
1358 else {
1359 if ( current_para > 0 ) {
1360 current_para--;
1361 current_index = edit->paragraphLength( current_para );
1362 }
1363 }
1364
1365 *cursor_para = current_para;
1366 *cursor_index = current_index;
1367 }
1368
1369 void
Q3TextEditPositionForward(int * cursor_para,int * cursor_index)1370 QUimTextUtil::Q3TextEditPositionForward( int *cursor_para, int *cursor_index )
1371 {
1372 Q3TextEdit *edit = static_cast<Q3TextEdit *>( mWidget );
1373 int n_para = edit->paragraphs();
1374 int preedit_len, preedit_cursor_pos;
1375 int current_para_len;
1376 int para, index;
1377 int current_para, current_index;
1378
1379 current_para = *cursor_para;
1380 current_index = *cursor_index;
1381
1382 current_para_len = edit->paragraphLength( current_para );
1383 if ( ! mPreeditSaved ) {
1384 preedit_len = mIc->getPreeditString().length();
1385 preedit_cursor_pos = mIc->getPreeditCursorPosition();
1386 } else {
1387 preedit_len = 0;
1388 preedit_cursor_pos = 0;
1389 }
1390 edit->getCursorPosition( ¶, &index );
1391
1392 if ( current_para == para && current_index >= ( index - preedit_cursor_pos ) && current_index < ( index - preedit_cursor_pos + preedit_len ) )
1393 current_index = index - preedit_cursor_pos + preedit_len;
1394
1395 if ( current_para == n_para - 1 ) {
1396 if ( current_index < current_para_len )
1397 current_index++;
1398 } else {
1399 if ( current_index < current_para_len )
1400 current_index++;
1401 else {
1402 current_para++;
1403 current_index = 0;
1404 }
1405 }
1406
1407 *cursor_para = current_para;
1408 *cursor_index = current_index;
1409 }
1410 #endif
1411
savePreedit()1412 void QUimTextUtil::savePreedit()
1413 {
1414 mIc->saveContext();
1415 mPreeditSaved = true;
1416 }
1417
restorePreedit()1418 void QUimTextUtil::restorePreedit()
1419 {
1420 mIc->restoreContext();
1421 mPreeditSaved = false;
1422 }
1423