subtraction of already painted area: be fool and
[kdelibs.git] / kdeui / keditcl2.cpp
blob7242d0eaf3c304a260cce9377c90f54c2e18c132
1 /* This file is part of the KDE libraries
3 Copyright (C) 1997 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
4 Copyright (C) 2000 Waldo Bastian <bastian@kde.org>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
19 Boston, MA 02110-1301, USA.
22 #include <limits.h> // INT_MAX
24 #include <qframe.h>
25 #include <qlabel.h>
26 #include <qlineedit.h>
27 #include <qvbuttongroup.h>
28 #include <qcheckbox.h>
29 #include <qlayout.h>
30 #include <qpushbutton.h>
31 #include <qhbox.h>
32 #include <qpopupmenu.h>
34 #include <kapplication.h>
35 #include <kcombobox.h>
36 #include <knuminput.h>
37 #include <kmessagebox.h>
38 #include <knotifyclient.h>
39 #include <klocale.h>
40 #include <kdebug.h>
41 #include <kiconloader.h>
43 #include "keditcl.h"
46 //////////////////////////////////////////////////////////////////////////
48 // Find Methods
51 void KEdit::search(){
53 if( replace_dialog && replace_dialog->isVisible() )
55 replace_dialog->hide();
58 if( !srchdialog )
60 srchdialog = new KEdFind( this, "searchdialog", false);
61 connect(srchdialog,SIGNAL(search()),this,SLOT(search_slot()));
62 connect(srchdialog,SIGNAL(done()),this,SLOT(searchdone_slot()));
65 // If we already searched / replaced something before make sure it shows
66 // up in the find dialog line-edit.
68 QString string;
69 string = srchdialog->getText();
70 srchdialog->setText(string.isEmpty() ? pattern : string);
72 deselect();
73 last_search = NONE;
75 srchdialog->show();
76 srchdialog->result();
80 void KEdit::search_slot(){
82 int line, col;
84 if (!srchdialog)
85 return;
87 QString to_find_string = srchdialog->getText();
88 getCursorPosition(&line,&col);
90 // srchdialog->get_direction() is true if searching backward
92 if (last_search != NONE && srchdialog->get_direction()){
93 col = col - pattern.length() - 1 ;
96 again:
97 int result = doSearch(to_find_string, srchdialog->case_sensitive(),
98 false, (!srchdialog->get_direction()),line,col);
100 if(!result){
101 if(!srchdialog->get_direction()){ // forward search
103 int query = KMessageBox::questionYesNo(
104 srchdialog,
105 i18n("End of document reached.\n"\
106 "Continue from the beginning?"),
107 i18n("Find"),KStdGuiItem::cont(),i18n("Stop"));
108 if (query == KMessageBox::Yes){
109 line = 0;
110 col = 0;
111 goto again;
114 else{ //backward search
116 int query = KMessageBox::questionYesNo(
117 srchdialog,
118 i18n("Beginning of document reached.\n"\
119 "Continue from the end?"),
120 i18n("Find"),KStdGuiItem::cont(),i18n("Stop"));
121 if (query == KMessageBox::Yes){
122 QString string = textLine( numLines() - 1 );
123 line = numLines() - 1;
124 col = string.length();
125 last_search = BACKWARD;
126 goto again;
130 else{
131 emit CursorPositionChanged();
137 void KEdit::searchdone_slot(){
139 if (!srchdialog)
140 return;
142 srchdialog->hide();
143 setFocus();
144 last_search = NONE;
147 /* antlarr: KDE 4: make it const QString & */
148 int KEdit::doSearch(QString s_pattern, bool case_sensitive,
149 bool wildcard, bool forward, int line, int col){
151 (void) wildcard; // reserved for possible extension to regex
154 int i, length;
155 int pos = -1;
157 if(forward){
159 QString string;
161 for(i = line; i < numLines(); i++) {
163 string = textLine(i);
165 pos = string.find(s_pattern, i == line ? col : 0, case_sensitive);
167 if( pos != -1){
169 length = s_pattern.length();
171 setCursorPosition(i,pos,false);
173 for(int l = 0 ; l < length; l++){
174 cursorRight(true);
177 setCursorPosition( i , pos + length, true );
178 pattern = s_pattern;
179 last_search = FORWARD;
181 return 1;
185 else{ // searching backwards
187 QString string;
189 for(i = line; i >= 0; i--) {
191 string = textLine(i);
192 int line_length = string.length();
194 pos = string.findRev(s_pattern, line == i ? col : line_length , case_sensitive);
196 if (pos != -1){
198 length = s_pattern.length();
200 if( ! (line == i && pos > col ) ){
202 setCursorPosition(i ,pos ,false );
204 for(int l = 0 ; l < length; l++){
205 cursorRight(true);
208 setCursorPosition(i ,pos + length ,true );
209 pattern = s_pattern;
210 last_search = BACKWARD;
211 return 1;
219 return 0;
225 bool KEdit::repeatSearch() {
227 if(!srchdialog || pattern.isEmpty())
229 search();
230 return true;
233 search_slot();
235 setFocus();
236 return true;
241 //////////////////////////////////////////////////////////////////////////
243 // Replace Methods
247 void KEdit::replace()
249 if( srchdialog && srchdialog->isVisible() )
251 srchdialog->hide();
254 if( !replace_dialog )
256 replace_dialog = new KEdReplace( this, "replace_dialog", false );
257 connect(replace_dialog,SIGNAL(find()),this,SLOT(replace_search_slot()));
258 connect(replace_dialog,SIGNAL(replace()),this,SLOT(replace_slot()));
259 connect(replace_dialog,SIGNAL(replaceAll()),this,SLOT(replace_all_slot()));
260 connect(replace_dialog,SIGNAL(done()),this,SLOT(replacedone_slot()));
263 QString string = replace_dialog->getText();
264 replace_dialog->setText(string.isEmpty() ? pattern : string);
267 deselect();
268 last_replace = NONE;
270 replace_dialog->show();
271 replace_dialog->result();
275 void KEdit::replace_slot(){
277 if (!replace_dialog)
278 return;
280 if(!can_replace){
281 KNotifyClient::beep();
282 return;
285 int line,col, length;
287 QString string = replace_dialog->getReplaceText();
288 length = string.length();
290 this->cut();
292 getCursorPosition(&line,&col);
294 insertAt(string,line,col);
295 setModified(true);
296 can_replace = false;
298 if (replace_dialog->get_direction())
300 // Backward
301 setCursorPosition(line,col+length);
302 for( int k = 0; k < length; k++){
303 cursorLeft(true);
306 else
308 // Forward
309 setCursorPosition(line,col);
310 for( int k = 0; k < length; k++){
311 cursorRight(true);
316 void KEdit::replace_all_slot(){
318 if (!replace_dialog)
319 return;
321 QString to_find_string = replace_dialog->getText();
323 int lineFrom, lineTo, colFrom, colTo;
324 getSelection(&lineFrom, &colFrom, &lineTo, &colTo);
326 // replace_dialog->get_direction() is true if searching backward
327 if (replace_dialog->get_direction())
329 if (colTo != -1)
331 replace_all_col = colTo - to_find_string.length();
332 replace_all_line = lineTo;
334 else
336 getCursorPosition(&replace_all_line,&replace_all_col);
337 replace_all_col--;
340 else
342 if (colFrom != -1)
344 replace_all_col = colFrom;
345 replace_all_line = lineFrom;
347 else
349 getCursorPosition(&replace_all_line,&replace_all_col);
353 deselect();
355 again:
357 setAutoUpdate(false);
358 int result = 1;
360 while(result){
362 result = doReplace(to_find_string, replace_dialog->case_sensitive(),
363 false, (!replace_dialog->get_direction()),
364 replace_all_line,replace_all_col,true);
368 setAutoUpdate(true);
369 update();
371 if(!replace_dialog->get_direction()){ // forward search
373 int query = KMessageBox::questionYesNo(
374 srchdialog,
375 i18n("End of document reached.\n"\
376 "Continue from the beginning?"),
377 i18n("Find"),KStdGuiItem::cont(),i18n("Stop"));
378 if (query == KMessageBox::Yes){
379 replace_all_line = 0;
380 replace_all_col = 0;
381 goto again;
384 else{ //backward search
386 int query = KMessageBox::questionYesNo(
387 srchdialog,
388 i18n("Beginning of document reached.\n"\
389 "Continue from the end?"),
390 i18n("Find"),KStdGuiItem::cont(),i18n("Stop"));
391 if (query == KMessageBox::Yes){
392 QString string = textLine( numLines() - 1 );
393 replace_all_line = numLines() - 1;
394 replace_all_col = string.length();
395 last_replace = BACKWARD;
396 goto again;
400 emit CursorPositionChanged();
405 void KEdit::replace_search_slot(){
407 int line, col;
409 if (!replace_dialog)
410 return;
412 QString to_find_string = replace_dialog->getText();
414 int lineFrom, lineTo, colFrom, colTo;
415 getSelection(&lineFrom, &colFrom, &lineTo, &colTo);
417 // replace_dialog->get_direction() is true if searching backward
418 if (replace_dialog->get_direction())
420 if (colFrom != -1)
422 col = colFrom - to_find_string.length();
423 line = lineFrom;
425 else
427 getCursorPosition(&line,&col);
428 col--;
431 else
433 if (colTo != -1)
435 col = colTo;
436 line = lineTo;
438 else
440 getCursorPosition(&line,&col);
444 again:
446 int result = doReplace(to_find_string, replace_dialog->case_sensitive(),
447 false, (!replace_dialog->get_direction()), line, col, false );
449 if(!result){
450 if(!replace_dialog->get_direction()){ // forward search
452 int query = KMessageBox::questionYesNo(
453 replace_dialog,
454 i18n("End of document reached.\n"\
455 "Continue from the beginning?"),
456 i18n("Replace"),KStdGuiItem::cont(),i18n("Stop"));
457 if (query == KMessageBox::Yes){
458 line = 0;
459 col = 0;
460 goto again;
463 else{ //backward search
465 int query = KMessageBox::questionYesNo(
466 replace_dialog,
467 i18n("Beginning of document reached.\n"\
468 "Continue from the end?"),
469 i18n("Replace"),KStdGuiItem::cont(),i18n("Stop"));
470 if (query == KMessageBox::Yes){
471 QString string = textLine( numLines() - 1 );
472 line = numLines() - 1;
473 col = string.length();
474 last_replace = BACKWARD;
475 goto again;
479 else{
481 emit CursorPositionChanged();
487 void KEdit::replacedone_slot(){
489 if (!replace_dialog)
490 return;
492 replace_dialog->hide();
493 // replace_dialog->clearFocus();
495 setFocus();
497 last_replace = NONE;
498 can_replace = false;
504 /* antlarr: KDE 4: make it const QString & */
505 int KEdit::doReplace(QString s_pattern, bool case_sensitive,
506 bool wildcard, bool forward, int line, int col, bool replace_all){
509 (void) wildcard; // reserved for possible extension to regex
511 int line_counter, length;
512 int pos = -1;
514 QString string;
515 QString stringnew;
516 QString replacement;
518 replacement = replace_dialog->getReplaceText();
519 line_counter = line;
520 replace_all_col = col;
522 if(forward){
524 int num_lines = numLines();
526 while (line_counter < num_lines){
528 string = textLine(line_counter);
530 if (replace_all){
531 pos = string.find(s_pattern, replace_all_col, case_sensitive);
533 else{
534 pos = string.find(s_pattern, line_counter == line ? col : 0, case_sensitive);
537 if (pos == -1 ){
538 line_counter++;
539 replace_all_col = 0;
540 replace_all_line = line_counter;
543 if( pos != -1){
545 length = s_pattern.length();
547 if(replace_all){ // automatic
549 stringnew = string.copy();
552 stringnew.replace(pos,length,replacement);
554 replace_all_col = pos + replacement.length();
555 replace_all_line = line_counter;
557 pos = stringnew.find(s_pattern, replace_all_col, case_sensitive);
559 while( pos != -1);
561 removeLine(line_counter);
562 insertLine(stringnew,line_counter);
564 setModified(true);
566 else{ // interactive
568 setCursorPosition( line_counter , pos, false );
570 for(int l = 0 ; l < length; l++){
571 cursorRight(true);
574 setCursorPosition( line_counter , pos + length, true );
575 pattern = s_pattern;
576 last_replace = FORWARD;
577 can_replace = true;
579 return 1;
586 else{ // searching backwards
588 while(line_counter >= 0){
590 string = textLine(line_counter);
592 int line_length = string.length();
594 if( replace_all ){
595 if (replace_all_col < 0)
596 pos = -1;
597 else
598 pos = string.findRev(s_pattern, replace_all_col , case_sensitive);
600 else{
601 if ((line == line_counter) && (col < 0))
602 pos = -1;
603 else
604 pos = string.findRev(s_pattern,
605 line == line_counter ? col : line_length , case_sensitive);
608 if (pos == -1 ){
609 line_counter--;
611 replace_all_col = 0;
612 if(line_counter >= 0){
613 string = textLine(line_counter);
614 replace_all_col = string.length();
617 replace_all_line = line_counter;
621 if (pos != -1){
622 length = s_pattern.length();
624 if(replace_all){ // automatic
626 stringnew = string.copy();
627 stringnew.replace(pos,length,replacement);
629 removeLine(line_counter);
630 insertLine(stringnew,line_counter);
632 replace_all_col = pos-length;
633 replace_all_line = line_counter;
634 if (replace_all_col < 0)
636 line_counter--;
638 if(line_counter >= 0){
639 string = textLine(line_counter);
640 replace_all_col = string.length();
642 replace_all_line = line_counter;
645 setModified(true);
647 else{ // interactive
649 // printf("line_counter %d pos %d col %d\n",line_counter, pos,col);
650 if( ! (line == line_counter && pos > col ) ){
652 setCursorPosition(line_counter, pos + length ,false );
654 for(int l = 0 ; l < length; l++){
655 cursorLeft(true);
658 setCursorPosition(line_counter, pos ,true );
659 pattern = s_pattern;
661 last_replace = BACKWARD;
662 can_replace = true;
664 return 1;
671 return 0;
679 ////////////////////////////////////////////////////////////////////
681 // Find Dialog
684 class KEdFind::KEdFindPrivate
686 public:
687 KEdFindPrivate( QWidget *parent ) {
688 combo = new KHistoryCombo( parent, "value" );
689 combo->setMaxCount( 20 ); // just some default
691 ~KEdFindPrivate() {
692 delete combo;
695 KHistoryCombo *combo;
699 KEdFind::KEdFind( QWidget *parent, const char *name, bool modal )
700 :KDialogBase( parent, name, modal, i18n("Find"),
701 modal ? User1|Cancel : User1|Close, User1, false, KGuiItem( i18n("&Find"), "find") )
703 setWFlags( WType_TopLevel );
705 QWidget *page = new QWidget( this );
706 setMainWidget(page);
707 QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
709 d = new KEdFindPrivate( page );
711 QString text = i18n("Find:");
712 QLabel *label = new QLabel( text, page , "find" );
713 topLayout->addWidget( label );
715 d->combo->setMinimumWidth(fontMetrics().maxWidth()*20);
716 d->combo->setFocus();
718 connect(d->combo, SIGNAL(textChanged ( const QString & )),
719 this,SLOT(textSearchChanged ( const QString & )));
721 topLayout->addWidget(d->combo);
723 group = new QVButtonGroup( i18n("Options"), page );
724 topLayout->addWidget( group );
726 QHBox* row1 = new QHBox( group );
728 text = i18n("Case &sensitive");
729 sensitive = new QCheckBox( text, row1, "case");
730 text = i18n("Find &backwards");
731 direction = new QCheckBox( text, row1, "direction" );
734 enableButton( KDialogBase::User1, !d->combo->currentText().isEmpty() );
736 if ( !modal )
737 connect( this, SIGNAL( closeClicked() ), this, SLOT( slotCancel() ) );
740 KEdFind::~KEdFind()
742 delete d;
745 void KEdFind::textSearchChanged ( const QString &text )
747 enableButton( KDialogBase::User1, !text.isEmpty() );
750 void KEdFind::slotCancel( void )
752 emit done();
753 KDialogBase::slotCancel();
756 void KEdFind::slotUser1( void )
758 if( !d->combo->currentText().isEmpty() )
760 d->combo->addToHistory( d->combo->currentText() );
761 emit search();
766 QString KEdFind::getText() const
768 return d->combo->currentText();
772 /* antlarr: KDE 4: make it const QString & */
773 void KEdFind::setText(QString string)
775 d->combo->setEditText(string);
776 d->combo->lineEdit()->selectAll();
779 void KEdFind::setCaseSensitive( bool b )
781 sensitive->setChecked( b );
784 bool KEdFind::case_sensitive() const
786 return sensitive->isChecked();
789 void KEdFind::setDirection( bool b )
791 direction->setChecked( b );
794 bool KEdFind::get_direction() const
796 return direction->isChecked();
799 KHistoryCombo * KEdFind::searchCombo() const
801 return d->combo;
806 ////////////////////////////////////////////////////////////////////
808 // Replace Dialog
811 class KEdReplace::KEdReplacePrivate
813 public:
814 KEdReplacePrivate( QWidget *parent ) {
815 searchCombo = new KHistoryCombo( parent, "value" );
816 replaceCombo = new KHistoryCombo( parent, "replace_value" );
818 searchCombo->setMaxCount( 20 ); // just some defaults
819 replaceCombo->setMaxCount( 20 );
821 ~KEdReplacePrivate() {
822 delete searchCombo;
823 delete replaceCombo;
826 KHistoryCombo *searchCombo, *replaceCombo;
829 KEdReplace::KEdReplace( QWidget *parent, const char *name, bool modal )
830 :KDialogBase( parent, name, modal, i18n("Replace"),
831 modal ? User3|User2|User1|Cancel : User3|User2|User1|Close,
832 User3, false,
833 i18n("Replace &All"), i18n("&Replace"), KGuiItem( i18n("&Find"), "find") )
835 setWFlags( WType_TopLevel );
837 setButtonBoxOrientation( Vertical );
839 QFrame *page = makeMainWidget();
840 QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
842 d = new KEdReplacePrivate( page );
844 QString text = i18n("Find:");
845 QLabel *label = new QLabel( text, page, "find" );
846 topLayout->addWidget( label );
848 d->searchCombo->setMinimumWidth(fontMetrics().maxWidth()*20);
849 d->searchCombo->setFocus();
850 topLayout->addWidget(d->searchCombo);
852 text = i18n("Replace with:");
853 label = new QLabel( text, page, "replace" );
854 topLayout->addWidget( label );
856 d->replaceCombo->setMinimumWidth(fontMetrics().maxWidth()*20);
857 topLayout->addWidget(d->replaceCombo);
859 connect(d->searchCombo, SIGNAL(textChanged ( const QString & )),
860 this,SLOT(textSearchChanged ( const QString & )));
862 QButtonGroup *group = new QButtonGroup( i18n("Options"), page );
863 topLayout->addWidget( group );
865 QGridLayout *gbox = new QGridLayout( group, 3, 2, spacingHint() );
866 gbox->addRowSpacing( 0, fontMetrics().lineSpacing() );
868 text = i18n("Case &sensitive");
869 sensitive = new QCheckBox( text, group, "case");
870 text = i18n("Find &backwards");
871 direction = new QCheckBox( text, group, "direction" );
872 gbox->addWidget( sensitive, 1, 0 );
873 gbox->addWidget( direction, 1, 1 );
874 gbox->setRowStretch( 2, 10 );
878 KEdReplace::~KEdReplace()
880 delete d;
883 void KEdReplace::textSearchChanged ( const QString &text )
885 bool state=text.isEmpty();
886 enableButton( KDialogBase::User1, !state );
887 enableButton( KDialogBase::User2, !state );
888 enableButton( KDialogBase::User3, !state );
891 void KEdReplace::slotCancel( void )
893 emit done();
894 d->searchCombo->clearEdit();
895 d->replaceCombo->clearEdit();
896 KDialogBase::slotCancel();
899 void KEdReplace::slotClose( void )
901 slotCancel();
904 void KEdReplace::slotUser1( void )
906 if( !d->searchCombo->currentText().isEmpty() )
908 d->replaceCombo->addToHistory( d->replaceCombo->currentText() );
909 emit replaceAll();
914 void KEdReplace::slotUser2( void )
916 if( !d->searchCombo->currentText().isEmpty() )
918 d->replaceCombo->addToHistory( d->replaceCombo->currentText() );
919 emit replace();
923 void KEdReplace::slotUser3( void )
925 if( !d->searchCombo->currentText().isEmpty() )
927 d->searchCombo->addToHistory( d->searchCombo->currentText() );
928 emit find();
933 QString KEdReplace::getText()
935 return d->searchCombo->currentText();
939 QString KEdReplace::getReplaceText()
941 return d->replaceCombo->currentText();
945 /* antlarr: KDE 4: make it const QString & */
946 void KEdReplace::setText(QString string)
948 d->searchCombo->setEditText(string);
949 d->searchCombo->lineEdit()->selectAll();
953 bool KEdReplace::case_sensitive()
955 return sensitive->isChecked();
959 bool KEdReplace::get_direction()
961 return direction->isChecked();
964 KHistoryCombo * KEdReplace::searchCombo() const
966 return d->searchCombo;
969 KHistoryCombo * KEdReplace::replaceCombo() const
971 return d->replaceCombo;
975 KEdGotoLine::KEdGotoLine( QWidget *parent, const char *name, bool modal )
976 :KDialogBase( parent, name, modal, i18n("Go to Line"), modal ? Ok|Cancel : Ok|Close, Ok, false )
978 QWidget *page = new QWidget( this );
979 setMainWidget(page);
980 QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
982 lineNum = new KIntNumInput( 1, page);
983 lineNum->setRange(1, 1000000, 1, false);
984 lineNum->setLabel(i18n("Go to line:"), AlignVCenter | AlignLeft);
985 // lineNum->setMinimumWidth(fontMetrics().maxWidth()*20);
986 topLayout->addWidget( lineNum );
988 topLayout->addStretch(10);
989 lineNum->setFocus();
993 void KEdGotoLine::selected(int)
995 accept();
999 int KEdGotoLine::getLineNumber()
1001 return lineNum->value();
1005 //////////////////////////////////////////////////////////////////////////////
1007 // Spell Checking
1010 void KEdit::spellcheck_start()
1012 saved_readonlystate = isReadOnly();
1013 setReadOnly(true);
1016 void KEdit::misspelling (const QString &word, const QStringList &, unsigned int pos)
1019 unsigned int l = 0;
1020 unsigned int cnt = 0;
1021 posToRowCol (pos, l, cnt);
1022 setSelection(l, cnt, l, cnt+word.length());
1025 if (cursorPoint().y()>height()/2)
1026 kspell->moveDlg (10, height()/2-kspell->heightDlg()-15);
1027 else
1028 kspell->moveDlg (10, height()/2 + 15);
1033 //need to use pos for insert, not cur, so forget cur altogether
1034 void KEdit::corrected (const QString &originalword, const QString &newword, unsigned int pos)
1036 //we'll reselect the original word in case the user has played with
1037 //the selection in eframe or the word was auto-replaced
1039 unsigned int l = 0;
1040 unsigned int cnt = 0;
1042 if( newword != originalword )
1044 posToRowCol (pos, l, cnt);
1045 setSelection(l, cnt, l, cnt+originalword.length());
1047 setReadOnly ( false );
1048 removeSelectedText();
1049 insert(newword);
1050 setReadOnly ( true );
1052 else
1054 deselect();
1058 void KEdit::posToRowCol(unsigned int pos, unsigned int &line, unsigned int &col)
1060 for (line = 0; line < static_cast<uint>(numLines()) && col <= pos; line++)
1062 col += lineLength(line)+1;
1064 line--;
1065 col = pos - col + lineLength(line) + 1;
1068 void KEdit::spellcheck_stop()
1070 deselect();
1072 setReadOnly ( saved_readonlystate);
1075 QString KEdit::selectWordUnderCursor( )
1077 int parag;
1078 int pos;
1080 getCursorPosition(&parag, &pos);
1082 QString txt = text(parag);
1084 // Find start
1085 int start = pos;
1086 while( start > 0 )
1088 const QChar &ch = txt[start-1];
1089 if (ch.isSpace() || ch.isPunct())
1090 break;
1091 start--;
1094 // Find end
1095 int end = pos;
1096 int len = txt.length();
1097 while( end < len )
1099 const QChar &ch = txt[end];
1100 if (ch.isSpace() || ch.isPunct())
1101 break;
1102 end++;
1104 setSelection(parag, start, parag, end);
1105 return txt.mid(start, end-start);
1108 QPopupMenu *KEdit::createPopupMenu( const QPoint& pos )
1110 enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll };
1112 QPopupMenu *menu = QMultiLineEdit::createPopupMenu( pos );
1114 if ( isReadOnly() )
1115 menu->changeItem( menu->idAt(0), SmallIconSet("editcopy"), menu->text( menu->idAt(0) ) );
1116 else {
1117 int id = menu->idAt(0);
1118 menu->changeItem( id - IdUndo, SmallIconSet("undo"), menu->text( id - IdUndo) );
1119 menu->changeItem( id - IdRedo, SmallIconSet("redo"), menu->text( id - IdRedo) );
1120 menu->changeItem( id - IdCut, SmallIconSet("editcut"), menu->text( id - IdCut) );
1121 menu->changeItem( id - IdCopy, SmallIconSet("editcopy"), menu->text( id - IdCopy) );
1122 menu->changeItem( id - IdPaste, SmallIconSet("editpaste"), menu->text( id - IdPaste) );
1123 menu->changeItem( id - IdClear, SmallIconSet("editclear"), menu->text( id - IdClear) );
1126 return menu;