00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#include <qclipboard.h>
00029
#include <qtimer.h>
00030
00031
#include <kconfig.h>
00032
#include <qtooltip.h>
00033
#include <kcursor.h>
00034
#include <klocale.h>
00035
#include <kstdaccel.h>
00036
#include <kpopupmenu.h>
00037
#include <kdebug.h>
00038
#include <kcompletionbox.h>
00039
#include <kurl.h>
00040
#include <kurldrag.h>
00041
#include <kiconloader.h>
00042
#include <kapplication.h>
00043
00044
#include "klineedit.h"
00045
#include "klineedit.moc"
00046
00047
00048
class KLineEdit::KLineEditPrivate
00049 {
00050
public:
00051 KLineEditPrivate()
00052 {
00053 completionBox = 0L;
00054 handleURLDrops =
true;
00055 grabReturnKeyEvents =
false;
00056
00057 userSelection =
true;
00058 autoSuggest =
false;
00059 disableRestoreSelection =
false;
00060 enableSqueezedText =
false;
00061
00062
if ( !initialized )
00063 {
00064
KConfigGroup config( KGlobal::config(),
"General" );
00065 backspacePerformsCompletion = config.
readBoolEntry(
"Backspace performs completion",
false );
00066
00067 initialized =
true;
00068 }
00069
00070 }
00071
00072 ~KLineEditPrivate()
00073 {
00074
00075
00076 }
00077
00078
static bool initialized;
00079
static bool backspacePerformsCompletion;
00080
00081
QColor previousHighlightColor;
00082
QColor previousHighlightedTextColor;
00083
00084
bool userSelection: 1;
00085
bool autoSuggest : 1;
00086
bool disableRestoreSelection: 1;
00087
bool handleURLDrops:1;
00088
bool grabReturnKeyEvents:1;
00089
bool enableSqueezedText:1;
00090
00091
int squeezedEnd;
00092
int squeezedStart;
00093 BackgroundMode bgMode;
00094
QString squeezedText;
00095
KCompletionBox *completionBox;
00096 };
00097
00098
bool KLineEdit::KLineEditPrivate::backspacePerformsCompletion =
false;
00099
bool KLineEdit::KLineEditPrivate::initialized =
false;
00100
00101
00102 KLineEdit::KLineEdit(
const QString &string,
QWidget *parent,
const char *name )
00103 :
QLineEdit( string, parent, name )
00104 {
00105 init();
00106 }
00107
00108 KLineEdit::KLineEdit(
QWidget *parent,
const char *name )
00109 :
QLineEdit( parent, name )
00110 {
00111 init();
00112 }
00113
00114 KLineEdit::~KLineEdit ()
00115 {
00116
delete d;
00117 d = 0;
00118 }
00119
00120
void KLineEdit::init()
00121 {
00122 d =
new KLineEditPrivate;
00123 possibleTripleClick =
false;
00124 d->bgMode = backgroundMode ();
00125
00126
00127 setContextMenuEnabled(
true );
00128 KCursor::setAutoHideCursor(
this,
true,
true );
00129 installEventFilter(
this );
00130
00131 KGlobalSettings::Completion mode =
completionMode();
00132 d->autoSuggest = (mode == KGlobalSettings::CompletionMan ||
00133 mode == KGlobalSettings::CompletionPopupAuto ||
00134 mode == KGlobalSettings::CompletionAuto);
00135 connect(
this, SIGNAL(
selectionChanged()),
this, SLOT(slotRestoreSelectionColors()));
00136
00137
QPalette p = palette();
00138
if ( !d->previousHighlightedTextColor.isValid() )
00139 d->previousHighlightedTextColor=p.
color(QPalette::Normal,QColorGroup::HighlightedText);
00140
if ( !d->previousHighlightColor.isValid() )
00141 d->previousHighlightColor=p.
color(QPalette::Normal,QColorGroup::Highlight);
00142 }
00143
00144 void KLineEdit::setCompletionMode( KGlobalSettings::Completion mode )
00145 {
00146 KGlobalSettings::Completion oldMode =
completionMode();
00147
00148
if ( oldMode != mode && (oldMode == KGlobalSettings::CompletionPopup ||
00149 oldMode == KGlobalSettings::CompletionPopupAuto ) &&
00150 d->completionBox && d->completionBox->isVisible() )
00151 d->completionBox->hide();
00152
00153
00154
00155
if (
echoMode() != QLineEdit::Normal )
00156 mode = KGlobalSettings::CompletionNone;
00157
00158
if ( kapp && !kapp->authorize(
"lineedit_text_completion") )
00159 mode = KGlobalSettings::CompletionNone;
00160
00161
if ( mode == KGlobalSettings::CompletionPopupAuto ||
00162 mode == KGlobalSettings::CompletionAuto ||
00163 mode == KGlobalSettings::CompletionMan )
00164 d->autoSuggest =
true;
00165
else
00166 d->autoSuggest =
false;
00167
00168 KCompletionBase::setCompletionMode( mode );
00169 }
00170
00171
void KLineEdit::setCompletedText(
const QString& t,
bool marked )
00172 {
00173
if ( !d->autoSuggest )
00174
return;
00175
00176
QString txt =
text();
00177
00178
if ( t != txt )
00179 {
00180
int start = marked ? txt.
length() : t.length();
00181 validateAndSet( t,
cursorPosition(), start, t.
length() );
00182 setUserSelection(
false);
00183 }
00184
else
00185
setUserSelection(
true);
00186
00187 }
00188
00189 void KLineEdit::setCompletedText(
const QString& text )
00190 {
00191 KGlobalSettings::Completion mode =
completionMode();
00192
bool marked = ( mode == KGlobalSettings::CompletionAuto ||
00193 mode == KGlobalSettings::CompletionMan ||
00194 mode == KGlobalSettings::CompletionPopup ||
00195 mode == KGlobalSettings::CompletionPopupAuto );
00196
setCompletedText( text, marked );
00197 }
00198
00199 void KLineEdit::rotateText( KCompletionBase::KeyBindingType type )
00200 {
00201
KCompletion* comp =
compObj();
00202
if ( comp &&
00203 (type == KCompletionBase::PrevCompletionMatch ||
00204 type == KCompletionBase::NextCompletionMatch ) )
00205 {
00206
QString input;
00207
00208
if (type == KCompletionBase::PrevCompletionMatch)
00209 comp->
previousMatch();
00210
else
00211 comp->
nextMatch();
00212
00213
00214
if ( input.
isNull() || input ==
displayText() )
00215
return;
00216
setCompletedText( input,
hasSelectedText() );
00217 }
00218 }
00219
00220 void KLineEdit::makeCompletion(
const QString& text )
00221 {
00222
KCompletion *comp =
compObj();
00223 KGlobalSettings::Completion mode =
completionMode();
00224
00225
if ( !comp || mode == KGlobalSettings::CompletionNone )
00226
return;
00227
00228
QString match = comp->
makeCompletion( text );
00229
00230
if ( mode == KGlobalSettings::CompletionPopup ||
00231 mode == KGlobalSettings::CompletionPopupAuto )
00232 {
00233
if ( match.
isNull() )
00234 {
00235
if ( d->completionBox )
00236 {
00237 d->completionBox->hide();
00238 d->completionBox->clear();
00239 }
00240 }
00241
else
00242
setCompletedItems( comp->
allMatches() );
00243 }
00244
else
00245 {
00246
00247
00248
if ( match.
isNull() || match == text )
00249
return;
00250
00251
if ( mode != KGlobalSettings::CompletionShell )
00252
setUserSelection(
false);
00253
00254
if ( d->autoSuggest )
00255
setCompletedText( match );
00256 }
00257 }
00258
00259 void KLineEdit::setReadOnly(
bool readOnly)
00260 {
00261
00262
if (readOnly ==
isReadOnly ())
00263
return;
00264
00265 QLineEdit::setReadOnly (readOnly);
00266
00267
if (readOnly)
00268 {
00269 d->bgMode = backgroundMode ();
00270 setBackgroundMode (Qt::PaletteBackground);
00271
if (d->enableSqueezedText && d->squeezedText.isEmpty())
00272 {
00273 d->squeezedText =
text();
00274
setSqueezedText();
00275 }
00276 }
00277
else
00278 {
00279
if (!d->squeezedText.isEmpty())
00280 {
00281
setText(d->squeezedText);
00282 d->squeezedText = QString::null;
00283 }
00284 setBackgroundMode (d->bgMode);
00285 }
00286 }
00287
00288 void KLineEdit::setSqueezedText(
const QString &text)
00289 {
00290
setEnableSqueezedText(
true);
00291
setText(text);
00292 }
00293
00294 void KLineEdit::setEnableSqueezedText(
bool enable )
00295 {
00296 d->enableSqueezedText = enable;
00297 }
00298
00299 bool KLineEdit::isSqueezedTextEnabled()
const
00300
{
00301
return d->enableSqueezedText;
00302 }
00303
00304 void KLineEdit::setText(
const QString& text )
00305 {
00306
if( d->enableSqueezedText &&
isReadOnly() )
00307 {
00308 d->squeezedText = text;
00309
setSqueezedText();
00310
return;
00311 }
00312
00313 QLineEdit::setText( text );
00314 }
00315
00316
void KLineEdit::setSqueezedText()
00317 {
00318 d->squeezedStart = 0;
00319 d->squeezedEnd = 0;
00320
QString fullText = d->squeezedText;
00321
QFontMetrics fm(fontMetrics());
00322
int labelWidth = size().width() - 2*frameWidth() - 2;
00323
int textWidth = fm.
width(fullText);
00324
00325
if (textWidth > labelWidth)
00326 {
00327
00328
QString squeezedText =
"...";
00329
int squeezedWidth = fm.
width(squeezedText);
00330
00331
00332
int letters = fullText.
length() * (labelWidth - squeezedWidth) / textWidth / 2;
00333 squeezedText = fullText.
left(letters) +
"..." + fullText.
right(letters);
00334 squeezedWidth = fm.
width(squeezedText);
00335
00336
if (squeezedWidth < labelWidth)
00337 {
00338
00339
00340
do
00341 {
00342 letters++;
00343 squeezedText = fullText.
left(letters) +
"..." + fullText.
right(letters);
00344 squeezedWidth = fm.
width(squeezedText);
00345 }
while (squeezedWidth < labelWidth);
00346 letters--;
00347 squeezedText = fullText.
left(letters) +
"..." + fullText.
right(letters);
00348 }
00349
else if (squeezedWidth > labelWidth)
00350 {
00351
00352
00353
do
00354 {
00355 letters--;
00356 squeezedText = fullText.
left(letters) +
"..." + fullText.
right(letters);
00357 squeezedWidth = fm.
width(squeezedText);
00358 }
while (squeezedWidth > labelWidth);
00359 }
00360
00361
if (letters < 5)
00362 {
00363
00364
QLineEdit::setText(fullText);
00365 }
00366
else
00367 {
00368
QLineEdit::setText(squeezedText);
00369 d->squeezedStart = letters;
00370 d->squeezedEnd = fullText.
length() - letters;
00371 }
00372
00373
QToolTip::remove(
this );
00374
QToolTip::add(
this, fullText );
00375
00376 }
00377
else
00378 {
00379
QLineEdit::setText(fullText);
00380
00381
QToolTip::remove(
this );
00382
QToolTip::hide();
00383 }
00384
00385
setCursorPosition(0);
00386 }
00387
00388 void KLineEdit::copy()
const
00389
{
00390
if (!d->squeezedText.isEmpty() && d->squeezedStart)
00391 {
00392
int start, end;
00393
KLineEdit *that = const_cast<KLineEdit *>(
this);
00394
if (!that->getSelection(&start, &end))
00395
return;
00396
if (start >= d->squeezedStart+3)
00397 start = start - 3 - d->squeezedStart + d->squeezedEnd;
00398
else if (start > d->squeezedStart)
00399 start = d->squeezedStart;
00400
if (end >= d->squeezedStart+3)
00401 end = end - 3 - d->squeezedStart + d->squeezedEnd;
00402
else if (end > d->squeezedStart)
00403 end = d->squeezedEnd;
00404
if (start == end)
00405
return;
00406
QString t = d->squeezedText;
00407 t = t.
mid(start, end - start);
00408 disconnect( QApplication::clipboard(), SIGNAL(
selectionChanged()),
this, 0);
00409
QApplication::clipboard()->setText( t );
00410 connect( QApplication::clipboard(), SIGNAL(
selectionChanged()),
this,
00411 SLOT(clipboardChanged()) );
00412
return;
00413 }
00414
00415
QLineEdit::copy();
00416 }
00417
00418 void KLineEdit::resizeEvent(
QResizeEvent * ev )
00419 {
00420
if (!d->squeezedText.isEmpty())
00421
setSqueezedText();
00422
00423 QLineEdit::resizeEvent(ev);
00424 }
00425
00426 void KLineEdit::keyPressEvent(
QKeyEvent *e )
00427 {
00428
KKey key( e );
00429
00430
if (
KStdAccel::copy().
contains( key ) )
00431 {
00432
copy();
00433
return;
00434 }
00435
else if (
KStdAccel::paste().
contains( key ) )
00436 {
00437
paste();
00438
return;
00439 }
00440
00441
00442
else if ( e->
key() == Key_Insert &&
00443 (e->
state() == (ShiftButton | ControlButton)) )
00444 {
00445
#if QT_VERSION >= 0x030100
00446
QString text =
QApplication::clipboard()->text( QClipboard::Selection);
00447
#else
00448
QClipboard *clip =
QApplication::clipboard();
00449
bool oldMode = clip->selectionModeEnabled();
00450 clip->setSelectionMode(
true );
00451
QString text =
QApplication::clipboard()->text();
00452 clip->setSelectionMode( oldMode );
00453
#endif
00454
00455 insert( text );
00456
deselect();
00457
return;
00458 }
00459
00460
else if (
KStdAccel::cut().
contains( key ) )
00461 {
00462
cut();
00463
return;
00464 }
00465
else if (
KStdAccel::undo().
contains( key ) )
00466 {
00467
undo();
00468
return;
00469 }
00470
else if (
KStdAccel::redo().
contains( key ) )
00471 {
00472
redo();
00473
return;
00474 }
00475
else if (
KStdAccel::deleteWordBack().
contains( key ) )
00476 {
00477 cursorWordBackward(
true);
00478
if (
hasSelectedText() )
00479
del();
00480
00481 e->
accept();
00482
return;
00483 }
00484
else if (
KStdAccel::deleteWordForward().
contains( key ) )
00485 {
00486
00487 cursorWordForward(
true);
00488
if (
hasSelectedText() )
00489
del();
00490
00491 e->
accept();
00492
return;
00493 }
00494
00495
00496
00497
00498
if (
echoMode() == QLineEdit::Normal &&
00499
completionMode() != KGlobalSettings::CompletionNone )
00500 {
00501 KeyBindingMap keys =
getKeyBindings();
00502 KGlobalSettings::Completion mode =
completionMode();
00503
bool noModifier = (e->
state() == NoButton ||
00504 e->
state() == ShiftButton ||
00505 e->
state() == Keypad);
00506
00507
if ( (mode == KGlobalSettings::CompletionAuto ||
00508 mode == KGlobalSettings::CompletionPopupAuto ||
00509 mode == KGlobalSettings::CompletionMan) && noModifier )
00510 {
00511
if ( !d->userSelection &&
hasSelectedText() &&
00512 ( e->
key() == Key_Right || e->
key() == Key_Left ) &&
00513 e->
state()==NoButton )
00514 {
00515
QString old_txt =
text();
00516 d->disableRestoreSelection =
true;
00517
int start,end;
00518 getSelection(&start, &end);
00519
00520
deselect();
00521 QLineEdit::keyPressEvent ( e );
00522
int cPosition=
cursorPosition();
00523
if (e->
key() ==Key_Right && cPosition > start )
00524 validateAndSet(old_txt, cPosition, cPosition, old_txt.
length());
00525
else
00526 validateAndSet(old_txt, cPosition, start, old_txt.
length());
00527
00528 d->disableRestoreSelection =
false;
00529
return;
00530 }
00531
00532
if ( e->
key() == Key_Escape )
00533 {
00534
if (
hasSelectedText() && !d->userSelection )
00535 {
00536
del();
00537
setUserSelection(
true);
00538 }
00539
00540
00541
00542 e->
ignore();
00543
return;
00544 }
00545
00546 }
00547
00548
if ( (mode == KGlobalSettings::CompletionAuto ||
00549 mode == KGlobalSettings::CompletionMan) && noModifier )
00550 {
00551
QString keycode = e->
text();
00552
if ( !keycode.
isEmpty() && (keycode.
unicode()->isPrint() ||
00553 e->
key() == Key_Backspace || e->
key() == Key_Delete ) )
00554 {
00555
bool hasUserSelection=d->userSelection;
00556
bool hadSelection=
hasSelectedText();
00557
00558
bool cursorNotAtEnd=
false;
00559
00560
int start,end;
00561 getSelection(&start, &end);
00562
int cPos =
cursorPosition();
00563
00564
00565
00566
00567
00568
if ( hadSelection && !hasUserSelection && start>cPos )
00569 {
00570
del();
00571 setCursorPosition(cPos);
00572 cursorNotAtEnd=
true;
00573 }
00574
00575 d->disableRestoreSelection =
true;
00576 QLineEdit::keyPressEvent ( e );
00577 d->disableRestoreSelection =
false;
00578
00579
QString txt =
text();
00580
int len = txt.
length();
00581
if ( !
hasSelectedText() && len )
00582 {
00583
if ( e->
key() == Key_Backspace )
00584 {
00585
if ( hadSelection && !hasUserSelection && !cursorNotAtEnd )
00586 {
00587
backspace();
00588 txt =
text();
00589 len = txt.
length();
00590 }
00591
00592
if ( !d->backspacePerformsCompletion || !len )
00593 d->autoSuggest =
false;
00594 }
00595
00596
if (e->
key() == Key_Delete )
00597 d->autoSuggest=
false;
00598
00599
if (
emitSignals() )
00600 emit
completion( txt );
00601
00602
if (
handleSignals() )
00603
makeCompletion( txt );
00604
00605
if( (e->
key() == Key_Backspace || e->
key() == Key_Delete) )
00606 d->autoSuggest=
true;
00607
00608 e->
accept();
00609 }
00610
00611
return;
00612 }
00613
00614 }
00615
00616
else if (( mode == KGlobalSettings::CompletionPopup ||
00617 mode == KGlobalSettings::CompletionPopupAuto ) &&
00618 noModifier && !e->
text().isEmpty() )
00619 {
00620
QString old_txt =
text();
00621
00622
bool hasUserSelection=d->userSelection;
00623
bool hadSelection=
hasSelectedText();
00624
bool cursorNotAtEnd=
false;
00625
00626
int start,end;
00627 getSelection(&start, &end);
00628
int cPos =
cursorPosition();
00629
QString keycode = e->
text();
00630
00631
00632
00633
00634
00635
if (hadSelection && !hasUserSelection && start>cPos &&
00636 ( (!keycode.
isEmpty() && keycode.
unicode()->isPrint()) ||
00637 e->
key() == Key_Backspace || e->
key() == Key_Delete ) )
00638 {
00639
del();
00640 setCursorPosition(cPos);
00641 cursorNotAtEnd=
true;
00642 }
00643
00644 uint selectedLength=
selectedText().length();
00645
00646 d->disableRestoreSelection =
true;
00647 QLineEdit::keyPressEvent ( e );
00648 d->disableRestoreSelection =
false;
00649
00650
if (( selectedLength !=
selectedText().length() ) && !hasUserSelection )
00651 slotRestoreSelectionColors();
00652
00653
QString txt =
text();
00654
int len = txt.
length();
00655
00656
if ( txt != old_txt && len &&
00657 ( (!keycode.
isEmpty() && keycode.
unicode()->isPrint()) ||
00658 e->
key() == Key_Backspace || e->
key() == Key_Delete) )
00659 {
00660
if ( e->
key() == Key_Backspace )
00661 {
00662
if ( hadSelection && !hasUserSelection && !cursorNotAtEnd )
00663 {
00664
backspace();
00665 txt =
text();
00666 len = txt.
length();
00667 }
00668
00669
if ( !d->backspacePerformsCompletion )
00670 d->autoSuggest =
false;
00671 }
00672
00673
if (e->
key() == Key_Delete )
00674 d->autoSuggest=
false;
00675
00676
if (
emitSignals() )
00677 emit
completion( txt );
00678
00679
if (
handleSignals() )
00680
makeCompletion( txt );
00681
00682
if ( (e->
key() == Key_Backspace || e->
key() == Key_Delete ) &&
00683 mode == KGlobalSettings::CompletionPopupAuto )
00684 d->autoSuggest=
true;
00685
00686 e->
accept();
00687 }
00688
else if (!len && d->completionBox && d->completionBox->isVisible())
00689 d->completionBox->hide();
00690
00691
return;
00692 }
00693
00694
else if ( mode == KGlobalSettings::CompletionShell )
00695 {
00696
00697
KShortcut cut;
00698
if ( keys[TextCompletion].isNull() )
00699 cut =
KStdAccel::shortcut(KStdAccel::TextCompletion);
00700
else
00701 cut = keys[TextCompletion];
00702
00703
if ( cut.
contains( key ) )
00704 {
00705
00706
00707
QString txt =
text();
00708
int len = txt.
length();
00709
if (
cursorPosition() == len && len != 0 )
00710 {
00711
if (
emitSignals() )
00712 emit
completion( txt );
00713
if (
handleSignals() )
00714
makeCompletion( txt );
00715
return;
00716 }
00717 }
00718
else if ( d->completionBox )
00719 d->completionBox->hide();
00720 }
00721
00722
00723
if ( mode != KGlobalSettings::CompletionNone )
00724 {
00725
00726
KShortcut cut;
00727
if ( keys[PrevCompletionMatch].isNull() )
00728 cut =
KStdAccel::shortcut(KStdAccel::PrevCompletion);
00729
else
00730 cut = keys[PrevCompletionMatch];
00731
00732
if ( cut.
contains( key ) )
00733 {
00734
if (
emitSignals() )
00735 emit
textRotation( KCompletionBase::PrevCompletionMatch );
00736
if (
handleSignals() )
00737
rotateText( KCompletionBase::PrevCompletionMatch );
00738
return;
00739 }
00740
00741
00742
if ( keys[NextCompletionMatch].isNull() )
00743 cut =
KStdAccel::shortcut(KStdAccel::NextCompletion);
00744
else
00745 cut = keys[NextCompletionMatch];
00746
00747
if ( cut.
contains( key ) )
00748 {
00749
if (
emitSignals() )
00750 emit
textRotation( KCompletionBase::NextCompletionMatch );
00751
if (
handleSignals() )
00752
rotateText( KCompletionBase::NextCompletionMatch );
00753
return;
00754 }
00755 }
00756
00757
00758
if (
compObj() )
00759 {
00760
KShortcut cut;
00761
if ( keys[SubstringCompletion].isNull() )
00762 cut =
KStdAccel::shortcut(KStdAccel::SubstringCompletion);
00763
else
00764 cut = keys[SubstringCompletion];
00765
00766
if ( cut.
contains( key ) )
00767 {
00768
if (
emitSignals() )
00769 emit
substringCompletion(
text() );
00770
if (
handleSignals() )
00771 {
00772
setCompletedItems(
compObj()->substringCompletion(
text()));
00773 e->
accept();
00774 }
00775
return;
00776 }
00777 }
00778 }
00779
00780 uint selectedLength =
selectedText().length();
00781
00782
00783 QLineEdit::keyPressEvent ( e );
00784
00785
if ( selectedLength !=
selectedText().length() )
00786 slotRestoreSelectionColors();
00787 }
00788
00789 void KLineEdit::mouseDoubleClickEvent(
QMouseEvent* e )
00790 {
00791
if ( e->
button() == Qt::LeftButton )
00792 {
00793 possibleTripleClick=
true;
00794 QTimer::singleShot( QApplication::doubleClickInterval(),
this,
00795 SLOT(tripleClickTimeout()) );
00796 }
00797 QLineEdit::mouseDoubleClickEvent( e );
00798 }
00799
00800 void KLineEdit::mousePressEvent(
QMouseEvent* e )
00801 {
00802
if ( possibleTripleClick && e->
button() == Qt::LeftButton )
00803 {
00804
selectAll();
00805 e->
accept();
00806
return;
00807 }
00808 QLineEdit::mousePressEvent( e );
00809 }
00810
00811
void KLineEdit::tripleClickTimeout()
00812 {
00813 possibleTripleClick=
false;
00814 }
00815
00816 QPopupMenu *
KLineEdit::createPopupMenu()
00817 {
00818
enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll };
00819
00820
00821
if ( !m_bEnableMenu )
00822
return 0;
00823
00824
QPopupMenu *popup =
QLineEdit::createPopupMenu();
00825
00826
int id = popup->
idAt(0);
00827 popup->
changeItem(
id - IdUndo, SmallIcon(
"undo"), popup->
text(
id - IdUndo) );
00828 popup->
changeItem(
id - IdRedo, SmallIcon(
"redo"), popup->
text(
id - IdRedo) );
00829 popup->
changeItem(
id - IdCut, SmallIcon(
"editcut"), popup->
text(
id - IdCut) );
00830 popup->
changeItem(
id - IdCopy, SmallIcon(
"editcopy"), popup->
text(
id - IdCopy) );
00831 popup->
changeItem(
id - IdPaste, SmallIcon(
"editpaste"), popup->
text(
id - IdPaste) );
00832 popup->
changeItem(
id - IdClear, SmallIcon(
"editclear"), popup->
text(
id - IdClear) );
00833
00834
00835
00836
00837
if (
compObj() && !
isReadOnly() && kapp->authorize(
"lineedit_text_completion") )
00838 {
00839
QPopupMenu *subMenu =
new QPopupMenu( popup );
00840 connect( subMenu, SIGNAL( activated(
int ) ),
00841
this, SLOT( completionMenuActivated(
int ) ) );
00842
00843 popup->
insertSeparator();
00844 popup->
insertItem( SmallIconSet(
"completion"), i18n(
"Text Completion"),
00845 subMenu );
00846
00847 subMenu->
insertItem( i18n(
"None"), NoCompletion );
00848 subMenu->
insertItem( i18n(
"Manual"), ShellCompletion );
00849 subMenu->
insertItem( i18n(
"Automatic"), AutoCompletion );
00850 subMenu->
insertItem( i18n(
"Dropdown List"), PopupCompletion );
00851 subMenu->
insertItem( i18n(
"Short Automatic"), ShortAutoCompletion );
00852 subMenu->
insertItem( i18n(
"Dropdown List && Automatic"), PopupAutoCompletion );
00853
00854 subMenu->
setAccel( KStdAccel::completion(), ShellCompletion );
00855
00856 KGlobalSettings::Completion mode =
completionMode();
00857 subMenu->
setItemChecked( NoCompletion,
00858 mode == KGlobalSettings::CompletionNone );
00859 subMenu->
setItemChecked( ShellCompletion,
00860 mode == KGlobalSettings::CompletionShell );
00861 subMenu->
setItemChecked( PopupCompletion,
00862 mode == KGlobalSettings::CompletionPopup );
00863 subMenu->
setItemChecked( AutoCompletion,
00864 mode == KGlobalSettings::CompletionAuto );
00865 subMenu->
setItemChecked( ShortAutoCompletion,
00866 mode == KGlobalSettings::CompletionMan );
00867 subMenu->
setItemChecked( PopupAutoCompletion,
00868 mode == KGlobalSettings::CompletionPopupAuto );
00869
if ( mode !=
KGlobalSettings::completionMode() )
00870 {
00871 subMenu->
insertSeparator();
00872 subMenu->
insertItem( i18n(
"Default"), Default );
00873 }
00874 }
00875
00876
00877
00878
00879 emit
aboutToShowContextMenu( popup );
00880
00881
return popup;
00882 }
00883
00884
void KLineEdit::completionMenuActivated(
int id )
00885 {
00886 KGlobalSettings::Completion oldMode =
completionMode();
00887
00888
switch (
id )
00889 {
00890
case Default:
00891 setCompletionMode( KGlobalSettings::completionMode() );
00892
break;
00893
case NoCompletion:
00894 setCompletionMode( KGlobalSettings::CompletionNone );
00895
break;
00896
case AutoCompletion:
00897 setCompletionMode( KGlobalSettings::CompletionAuto );
00898
break;
00899
case ShortAutoCompletion:
00900 setCompletionMode( KGlobalSettings::CompletionMan );
00901
break;
00902
case ShellCompletion:
00903 setCompletionMode( KGlobalSettings::CompletionShell );
00904
break;
00905
case PopupCompletion:
00906 setCompletionMode( KGlobalSettings::CompletionPopup );
00907
break;
00908
case PopupAutoCompletion:
00909 setCompletionMode( KGlobalSettings::CompletionPopupAuto );
00910
break;
00911
default:
00912
return;
00913 }
00914
00915
if ( oldMode !=
completionMode() )
00916 {
00917
if ( (oldMode ==
KGlobalSettings::CompletionPopup ||
00918 oldMode ==
KGlobalSettings::CompletionPopupAuto ) &&
00919 d->completionBox && d->completionBox->isVisible() )
00920 d->completionBox->hide();
00921 emit
completionModeChanged(
completionMode() );
00922 }
00923 }
00924
00925 void KLineEdit::dropEvent(
QDropEvent *e)
00926 {
00927
KURL::List urlList;
00928
if( d->handleURLDrops && KURLDrag::decode( e, urlList ) )
00929 {
00930
QString dropText =
text();
00931 KURL::List::ConstIterator it;
00932
for( it = urlList.
begin() ; it != urlList.
end() ; ++it )
00933 {
00934
if(!dropText.
isEmpty())
00935 dropText+=
' ';
00936
00937 dropText += (*it).prettyURL();
00938 }
00939
00940 validateAndSet( dropText, dropText.
length(), 0, 0);
00941
00942 e->
accept();
00943 }
00944
else
00945 QLineEdit::dropEvent(e);
00946 }
00947
00948 bool KLineEdit::eventFilter(
QObject* o,
QEvent* ev )
00949 {
00950
if( o ==
this )
00951 {
00952 KCursor::autoHideEventFilter(
this, ev );
00953
if ( ev->
type() == QEvent::AccelOverride )
00954 {
00955
QKeyEvent *e = static_cast<QKeyEvent *>( ev );
00956
if (overrideAccel (e))
00957 {
00958 e->
accept();
00959
return true;
00960 }
00961 }
00962
else if( ev->
type() == QEvent::KeyPress )
00963 {
00964
QKeyEvent *e = static_cast<QKeyEvent *>( ev );
00965
00966
if( e->
key() == Qt::Key_Return || e->
key() == Qt::Key_Enter )
00967 {
00968
bool trap = d->completionBox && d->completionBox->isVisible();
00969
00970
bool stopEvent = trap || (d->grabReturnKeyEvents &&
00971 (e->
state() == NoButton ||
00972 e->
state() == Keypad));
00973
00974
00975
if ( stopEvent )
00976 {
00977 emit
QLineEdit::returnPressed();
00978 e->
accept ();
00979 }
00980
00981 emit
returnPressed(
displayText() );
00982
00983
if ( trap )
00984 {
00985 d->completionBox->hide();
00986
deselect();
00987 setCursorPosition(
text().length());
00988 }
00989
00990
00991
return stopEvent;
00992 }
00993 }
00994 }
00995
return QLineEdit::eventFilter( o, ev );
00996 }
00997
00998
00999 void KLineEdit::setURLDropsEnabled(
bool enable)
01000 {
01001 d->handleURLDrops=enable;
01002 }
01003
01004 bool KLineEdit::isURLDropsEnabled()
const
01005
{
01006
return d->handleURLDrops;
01007 }
01008
01009 void KLineEdit::setTrapReturnKey(
bool grab )
01010 {
01011 d->grabReturnKeyEvents = grab;
01012 }
01013
01014 bool KLineEdit::trapReturnKey()
const
01015
{
01016
return d->grabReturnKeyEvents;
01017 }
01018
01019 void KLineEdit::setURL(
const KURL& url )
01020 {
01021 QLineEdit::setText( url.
prettyURL() );
01022 }
01023
01024
void KLineEdit::makeCompletionBox()
01025 {
01026
if ( d->completionBox )
01027
return;
01028
01029 d->completionBox =
new KCompletionBox(
this,
"completion box" );
01030
if (
handleSignals() )
01031 {
01032 connect( d->completionBox, SIGNAL(highlighted(
const QString& )),
01033 SLOT(setTextWorkaround(
const QString& )) );
01034 connect( d->completionBox, SIGNAL(userCancelled(
const QString& )),
01035 SLOT(userCancelled(
const QString& )) );
01036
01037 connect( d->completionBox, SIGNAL( activated(
const QString& )),
01038 SIGNAL(completionBoxActivated(
const QString& )) );
01039 }
01040 }
01041
01042 void KLineEdit::userCancelled(
const QString & cancelText)
01043 {
01044
if (
completionMode() != KGlobalSettings::CompletionPopupAuto )
01045 {
01046
setText(cancelText);
01047 }
01048
else if (
hasSelectedText() )
01049 {
01050
if (d->userSelection)
01051
deselect();
01052
else
01053 {
01054 d->autoSuggest=
false;
01055
int start,end;
01056 getSelection(&start, &end);
01057
QString s=
text().remove(start, end-start+1);
01058 validateAndSet(s,start,s.
length(),s.
length());
01059 d->autoSuggest=
true;
01060 }
01061 }
01062 }
01063
01064
bool KLineEdit::overrideAccel (
const QKeyEvent* e)
01065 {
01066
KShortcut scKey;
01067
01068
KKey key( e );
01069 KeyBindingMap keys =
getKeyBindings();
01070
01071
if (keys[TextCompletion].isNull())
01072 scKey =
KStdAccel::shortcut(KStdAccel::TextCompletion);
01073
else
01074 scKey = keys[TextCompletion];
01075
01076
if (scKey.
contains( key ))
01077
return true;
01078
01079
if (keys[NextCompletionMatch].isNull())
01080 scKey =
KStdAccel::shortcut(KStdAccel::NextCompletion);
01081
else
01082 scKey = keys[NextCompletionMatch];
01083
01084
if (scKey.
contains( key ))
01085
return true;
01086
01087
if (keys[PrevCompletionMatch].isNull())
01088 scKey =
KStdAccel::shortcut(KStdAccel::PrevCompletion);
01089
else
01090 scKey = keys[PrevCompletionMatch];
01091
01092
if (scKey.
contains( key ))
01093
return true;
01094
01095
01096
if (
KStdAccel::copy().
contains( key ) )
01097
return true;
01098
else if (
KStdAccel::paste().
contains( key ) )
01099
return true;
01100
else if (
KStdAccel::cut().
contains( key ) )
01101
return true;
01102
else if (
KStdAccel::undo().
contains( key ) )
01103
return true;
01104
else if (
KStdAccel::redo().
contains( key ) )
01105
return true;
01106
else if (
KStdAccel::deleteWordBack().
contains( key ))
01107
return true;
01108
else if (
KStdAccel::deleteWordForward().
contains( key ))
01109
return true;
01110
01111
if (d->completionBox && d->completionBox->isVisible ())
01112 {
01113
int key = e->
key();
01114 ButtonState state = e->
state();
01115
if ((key == Key_Backtab || key == Key_Tab) &&
01116 (state == NoButton || (state & ShiftButton)))
01117 {
01118
return true;
01119 }
01120 }
01121
01122
01123
return false;
01124 }
01125
01126 void KLineEdit::setCompletedItems(
const QStringList& items )
01127 {
01128
QString txt =
text();
01129
01130
if ( !items.isEmpty() &&
01131 !(items.count() == 1 && txt == items.first()) )
01132 {
01133
if ( !d->completionBox )
01134 makeCompletionBox();
01135
01136
if ( !txt.
isEmpty() )
01137 d->completionBox->setCancelledText( txt );
01138
01139 d->completionBox->setItems( items );
01140 d->completionBox->popup();
01141
01142
if ( d->autoSuggest )
01143 {
01144
int index = items.first().find( txt );
01145
QString newText = items.first().mid( index );
01146
setUserSelection(
false);
01147
setCompletedText(newText,
true);
01148 }
01149 }
01150
else
01151 {
01152
if ( d->completionBox && d->completionBox->isVisible() )
01153 d->completionBox->hide();
01154 }
01155 }
01156
01157 KCompletionBox *
KLineEdit::completionBox(
bool create )
01158 {
01159
if ( create )
01160 makeCompletionBox();
01161
01162
return d->completionBox;
01163 }
01164
01165 void KLineEdit::setCompletionObject(
KCompletion* comp,
bool hsig )
01166 {
01167
KCompletion *oldComp =
compObj();
01168
if ( oldComp &&
handleSignals() )
01169 disconnect( oldComp, SIGNAL( matches(
const QStringList& )),
01170
this, SLOT(
setCompletedItems(
const QStringList& )));
01171
01172
if ( comp && hsig )
01173 connect( comp, SIGNAL( matches(
const QStringList& )),
01174
this, SLOT(
setCompletedItems(
const QStringList& )));
01175
01176 KCompletionBase::setCompletionObject( comp, hsig );
01177 }
01178
01179
01180 void KLineEdit::create( WId
id,
bool initializeWindow,
bool destroyOldWindow )
01181 {
01182 QLineEdit::create(
id, initializeWindow, destroyOldWindow );
01183 KCursor::setAutoHideCursor(
this,
true,
true );
01184 }
01185
01186 void KLineEdit::setUserSelection(
bool userSelection)
01187 {
01188
QPalette p = palette();
01189
01190
if (userSelection)
01191 {
01192 p.
setColor(QColorGroup::Highlight, d->previousHighlightColor);
01193 p.
setColor(QColorGroup::HighlightedText, d->previousHighlightedTextColor);
01194 }
01195
else
01196 {
01197
QColor color=p.
color(QPalette::Disabled, QColorGroup::Text);
01198 p.
setColor(QColorGroup::HighlightedText, color);
01199 color=p.
color(QPalette::Active, QColorGroup::Base);
01200 p.
setColor(QColorGroup::Highlight, color);
01201 }
01202
01203 d->userSelection=userSelection;
01204 setPalette(p);
01205 }
01206
01207
void KLineEdit::slotRestoreSelectionColors()
01208 {
01209
if (d->disableRestoreSelection)
01210
return;
01211
01212 setUserSelection(
true);
01213 }
01214
01215 void KLineEdit::clear()
01216 {
01217
setText( QString::null );
01218 }
01219
01220
void KLineEdit::setTextWorkaround(
const QString& text )
01221 {
01222 setText( text );
01223 end(
false );
01224 }
01225
01226 QString KLineEdit::originalText()
const
01227
{
01228
if ( d->enableSqueezedText &&
isReadOnly() )
01229
return d->squeezedText;
01230
01231
return text();
01232 }
01233
01234
void KLineEdit::virtual_hook(
int id,
void* data )
01235 { KCompletionBase::virtual_hook(
id, data ); }