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 "klineedit.h"
00029 #include "klineedit_p.h"
00030 #include "kdeuiwidgetsproxystyle_p.h"
00031
00032 #include <kaction.h>
00033 #include <kapplication.h>
00034 #include <kauthorized.h>
00035 #include <kconfig.h>
00036 #include <kconfiggroup.h>
00037 #include <kcursor.h>
00038 #include <kdebug.h>
00039 #include <kcompletionbox.h>
00040 #include <kicontheme.h>
00041 #include <kicon.h>
00042 #include <klocale.h>
00043 #include <kmenu.h>
00044 #include <kstandardaction.h>
00045 #include <kstandardshortcut.h>
00046
00047 #include <QtCore/QTimer>
00048 #include <QtGui/QClipboard>
00049 #include <QtGui/QStyleOption>
00050 #include <QtGui/QToolTip>
00051
00052 class KLineEditPrivate
00053 {
00054 public:
00055 KLineEditPrivate(KLineEdit* qq)
00056 : q(qq)
00057 {
00058 completionBox = 0L;
00059 handleURLDrops = true;
00060 grabReturnKeyEvents = false;
00061
00062 userSelection = true;
00063 autoSuggest = false;
00064 disableRestoreSelection = false;
00065 enableSqueezedText = false;
00066
00067 drawClickMsg = false;
00068 enableClickMsg = false;
00069 threeStars = false;
00070 completionRunning = false;
00071 if ( !initialized )
00072 {
00073 KConfigGroup config( KGlobal::config(), "General" );
00074 backspacePerformsCompletion = config.readEntry("Backspace performs completion", false);
00075
00076 initialized = true;
00077 }
00078
00079 clearButton = 0;
00080 clickInClear = false;
00081 wideEnoughForClear = true;
00082 overlap = 0;
00083
00084
00085
00086
00087
00088
00089 QString metaMsg = i18nc("Italic placeholder text in line edits: 0 no, 1 yes", "1");
00090 italicizePlaceholder = (metaMsg.trimmed() != QString('0'));
00091 }
00092
00093 ~KLineEditPrivate()
00094 {
00095
00096
00097 }
00098
00099 void _k_slotSettingsChanged(int category)
00100 {
00101 Q_UNUSED(category);
00102
00103 if (clearButton) {
00104 clearButton->setAnimationsEnabled(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects);
00105 }
00106 }
00107
00108 void _k_updateUserText( const QString &txt)
00109 {
00110 if ((!completionRunning) && (txt != userText))
00111 {
00112 userText = txt;
00113 emit q->userTextChanged(txt);
00114 }
00115 }
00116
00122 bool overrideShortcut(const QKeyEvent* e);
00123
00124 static bool initialized;
00125 static bool backspacePerformsCompletion;
00126
00127 QColor previousHighlightColor;
00128 QColor previousHighlightedTextColor;
00129
00130 bool userSelection: 1;
00131 bool autoSuggest : 1;
00132 bool disableRestoreSelection: 1;
00133 bool handleURLDrops:1;
00134 bool grabReturnKeyEvents:1;
00135 bool enableSqueezedText:1;
00136 bool completionRunning:1;
00137
00138 int squeezedEnd;
00139 int squeezedStart;
00140 QPalette::ColorRole bgRole;
00141 QString squeezedText;
00142 QString userText;
00143
00144 QString clickMessage;
00145 bool enableClickMsg:1;
00146 bool drawClickMsg:1;
00147 bool threeStars:1;
00148
00149 bool possibleTripleClick :1;
00150
00151 bool clickInClear:1;
00152 bool wideEnoughForClear:1;
00153 KLineEditButton *clearButton;
00154
00155 KCompletionBox *completionBox;
00156
00157 int overlap;
00158
00159 bool italicizePlaceholder:1;
00160
00161 QAction *noCompletionAction, *shellCompletionAction, *autoCompletionAction, *popupCompletionAction, *shortAutoCompletionAction, *popupAutoCompletionAction, *defaultAction;
00162
00163 QMap<KGlobalSettings::Completion, bool> disableCompletionMap;
00164 KLineEdit* q;
00165 };
00166
00167
00168
00169
00170 class KLineEditStyle : public KdeUiProxyStyle
00171 {
00172 public:
00173 KLineEditStyle(KLineEdit *parent, KLineEditPrivate *lineEditPrivate)
00174 : KdeUiProxyStyle(parent), lineEditPrivate(lineEditPrivate) {}
00175
00176 QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
00177
00178 KLineEditPrivate* lineEditPrivate;
00179 };
00180
00181 QRect KLineEditStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
00182 {
00183 if (element == SE_LineEditContents)
00184 {
00185 QRect rect = style()->subElementRect(SE_LineEditContents, option, widget);
00186
00187 const int overlap = lineEditPrivate->overlap;
00188 if (option->direction == Qt::LeftToRight) return rect.adjusted(0, 0, -overlap, 0);
00189 else return rect.adjusted(overlap, 0, 0, 0);
00190 }
00191
00192 return KdeUiProxyStyle::subElementRect(element, option, widget);
00193 }
00194
00195 bool KLineEditPrivate::backspacePerformsCompletion = false;
00196 bool KLineEditPrivate::initialized = false;
00197
00198
00199 KLineEdit::KLineEdit( const QString &string, QWidget *parent )
00200 : QLineEdit( string, parent ), d(new KLineEditPrivate(this))
00201 {
00202 init();
00203 }
00204
00205 KLineEdit::KLineEdit( QWidget *parent )
00206 : QLineEdit( parent ), d(new KLineEditPrivate(this))
00207 {
00208 init();
00209 }
00210
00211
00212 KLineEdit::~KLineEdit ()
00213 {
00214 delete d;
00215 }
00216
00217 void KLineEdit::init()
00218 {
00219 d->possibleTripleClick = false;
00220 d->bgRole = backgroundRole();
00221
00222
00223 QLineEdit::setContextMenuPolicy( Qt::DefaultContextMenu );
00224 KCursor::setAutoHideCursor( this, true, true );
00225
00226 KGlobalSettings::Completion mode = completionMode();
00227 d->autoSuggest = (mode == KGlobalSettings::CompletionMan ||
00228 mode == KGlobalSettings::CompletionPopupAuto ||
00229 mode == KGlobalSettings::CompletionAuto);
00230 connect( this, SIGNAL(selectionChanged()), this, SLOT(slotRestoreSelectionColors()));
00231
00232 connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), this, SLOT(_k_slotSettingsChanged(int)));
00233
00234 const QPalette p = palette();
00235 if ( !d->previousHighlightedTextColor.isValid() )
00236 d->previousHighlightedTextColor=p.color(QPalette::Normal,QPalette::HighlightedText);
00237 if ( !d->previousHighlightColor.isValid() )
00238 d->previousHighlightColor=p.color(QPalette::Normal,QPalette::Highlight);
00239
00240 QStyle *lineEditStyle = new KLineEditStyle(this, d);
00241 lineEditStyle->setParent(this);
00242 setStyle(lineEditStyle);
00243
00244 connect( this, SIGNAL(textChanged( const QString&)), this, SLOT(_k_updateUserText( const QString&)));
00245
00246 }
00247
00248 QString KLineEdit::clickMessage() const
00249 {
00250 return d->clickMessage;
00251 }
00252
00253 void KLineEdit::setClearButtonShown(bool show)
00254 {
00255 if (show) {
00256 if (d->clearButton) {
00257 return;
00258 }
00259
00260 d->clearButton = new KLineEditButton(this);
00261 d->clearButton->setCursor( Qt::ArrowCursor );
00262 d->clearButton->setToolTip( i18nc( "@action:button Clear current text in the line edit", "Clear text" ) );
00263
00264 updateClearButtonIcon(text());
00265 updateClearButton();
00266 connect(this, SIGNAL(textChanged(QString)), this, SLOT(updateClearButtonIcon(QString)));
00267 } else {
00268 disconnect(this, SIGNAL(textChanged(QString)), this, SLOT(updateClearButtonIcon(QString)));
00269 delete d->clearButton;
00270 d->clearButton = 0;
00271 d->clickInClear = false;
00272 d->overlap = 0;
00273 }
00274 }
00275
00276 bool KLineEdit::isClearButtonShown() const
00277 {
00278 return d->clearButton != 0;
00279 }
00280
00281 QSize KLineEdit::clearButtonUsedSize() const
00282 {
00283 QSize s;
00284 if (d->clearButton) {
00285 const int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this);
00286 s = d->clearButton->sizeHint();
00287 s.rwidth() += frameWidth;
00288 }
00289 return s;
00290 }
00291
00292 void KLineEdit::updateClearButtonIcon(const QString& text)
00293 {
00294 if (!d->clearButton || isReadOnly()) {
00295 return;
00296 }
00297
00298 int clearButtonState = KIconLoader::DefaultState;
00299
00300 if (d->wideEnoughForClear && text.length() > 0) {
00301 d->clearButton->animateVisible(true);
00302 } else {
00303 d->clearButton->animateVisible(false);
00304 }
00305
00306 if (!d->clearButton->pixmap().isNull()) {
00307 return;
00308 }
00309
00310 if (layoutDirection() == Qt::LeftToRight) {
00311 d->clearButton->setPixmap(SmallIcon("edit-clear-locationbar-rtl", 0, clearButtonState));
00312 } else {
00313 d->clearButton->setPixmap(SmallIcon("edit-clear-locationbar-ltr", 0, clearButtonState));
00314 }
00315
00316 d->clearButton->setVisible(text.length());
00317 }
00318
00319 void KLineEdit::updateClearButton()
00320 {
00321 if (!d->clearButton || isReadOnly()) {
00322 return;
00323 }
00324
00325 const QSize geom = size();
00326 const int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth,0,this);
00327 const int buttonWidth = d->clearButton->sizeHint().width();
00328 const QSize newButtonSize(buttonWidth, geom.height());
00329 const QFontMetrics fm(font());
00330 const int em = fm.width("m");
00331
00332
00333
00334 const bool wideEnough = geom.width() > 4 * em + buttonWidth + frameWidth;
00335
00336 if (newButtonSize != d->clearButton->size()) {
00337 d->clearButton->resize(newButtonSize);
00338 d->overlap = wideEnough ? buttonWidth + frameWidth : 0;
00339 }
00340
00341 if (layoutDirection() == Qt::LeftToRight ) {
00342 d->clearButton->move(geom.width() - frameWidth - buttonWidth - 1, 0);
00343 } else {
00344 d->clearButton->move(frameWidth + 1, 0);
00345 }
00346
00347 if (wideEnough != d->wideEnoughForClear) {
00348
00349
00350
00351 d->wideEnoughForClear = wideEnough;
00352 updateClearButtonIcon(text());
00353 }
00354 }
00355
00356 void KLineEdit::setCompletionMode( KGlobalSettings::Completion mode )
00357 {
00358 KGlobalSettings::Completion oldMode = completionMode();
00359
00360 if ( oldMode != mode && (oldMode == KGlobalSettings::CompletionPopup ||
00361 oldMode == KGlobalSettings::CompletionPopupAuto ) &&
00362 d->completionBox && d->completionBox->isVisible() )
00363 d->completionBox->hide();
00364
00365
00366
00367 if ( echoMode() != QLineEdit::Normal )
00368 mode = KGlobalSettings::CompletionNone;
00369
00370 if ( kapp && !KAuthorized::authorize("lineedit_text_completion") )
00371 mode = KGlobalSettings::CompletionNone;
00372
00373 if ( mode == KGlobalSettings::CompletionPopupAuto ||
00374 mode == KGlobalSettings::CompletionAuto ||
00375 mode == KGlobalSettings::CompletionMan )
00376 d->autoSuggest = true;
00377 else
00378 d->autoSuggest = false;
00379
00380 KCompletionBase::setCompletionMode( mode );
00381 }
00382
00383 void KLineEdit::setCompletionModeDisabled( KGlobalSettings::Completion mode, bool disable )
00384 {
00385 d->disableCompletionMap[ mode ] = disable;
00386 }
00387
00388 void KLineEdit::setCompletedText( const QString& t, bool marked )
00389 {
00390 if ( !d->autoSuggest )
00391 return;
00392
00393 const QString txt = text();
00394
00395 if ( t != txt )
00396 {
00397 const int start = marked ? txt.length() : t.length();
00398 setText(t);
00399 setSelection(start, t.length());
00400 setUserSelection(false);
00401 }
00402 else
00403 setUserSelection(true);
00404
00405 }
00406
00407 void KLineEdit::setCompletedText( const QString& text )
00408 {
00409 KGlobalSettings::Completion mode = completionMode();
00410 const bool marked = ( mode == KGlobalSettings::CompletionAuto ||
00411 mode == KGlobalSettings::CompletionMan ||
00412 mode == KGlobalSettings::CompletionPopup ||
00413 mode == KGlobalSettings::CompletionPopupAuto );
00414 setCompletedText( text, marked );
00415 }
00416
00417 void KLineEdit::rotateText( KCompletionBase::KeyBindingType type )
00418 {
00419 KCompletion* comp = compObj();
00420 if ( comp &&
00421 (type == KCompletionBase::PrevCompletionMatch ||
00422 type == KCompletionBase::NextCompletionMatch ) )
00423 {
00424 QString input;
00425
00426 if (type == KCompletionBase::PrevCompletionMatch)
00427 input = comp->previousMatch();
00428 else
00429 input = comp->nextMatch();
00430
00431
00432 if ( input.isEmpty() || input == displayText() )
00433 return;
00434 setCompletedText( input, hasSelectedText() );
00435 }
00436 }
00437
00438 void KLineEdit::makeCompletion( const QString& text )
00439 {
00440 KCompletion *comp = compObj();
00441 KGlobalSettings::Completion mode = completionMode();
00442
00443 if ( !comp || mode == KGlobalSettings::CompletionNone )
00444 return;
00445
00446 const QString match = comp->makeCompletion( text );
00447
00448 if ( mode == KGlobalSettings::CompletionPopup ||
00449 mode == KGlobalSettings::CompletionPopupAuto )
00450 {
00451 if ( match.isEmpty() )
00452 {
00453 if ( d->completionBox )
00454 {
00455 d->completionBox->hide();
00456 d->completionBox->clear();
00457 }
00458 }
00459 else
00460 setCompletedItems( comp->allMatches() );
00461 }
00462 else
00463 {
00464
00465
00466 if ( match.isEmpty() || match == text )
00467 return;
00468
00469 if ( mode != KGlobalSettings::CompletionShell )
00470 setUserSelection(false);
00471
00472 if ( d->autoSuggest )
00473 setCompletedText( match );
00474 }
00475 }
00476
00477 void KLineEdit::setReadOnly(bool readOnly)
00478 {
00479
00480 if (readOnly == isReadOnly ()) {
00481 return;
00482 }
00483
00484 QLineEdit::setReadOnly(readOnly);
00485
00486 if (readOnly) {
00487 d->bgRole = backgroundRole();
00488 setBackgroundRole(QPalette::Window);
00489 if (d->enableSqueezedText && d->squeezedText.isEmpty()) {
00490 d->squeezedText = text();
00491 setSqueezedText();
00492 }
00493
00494 if (d->clearButton) {
00495 d->clearButton->animateVisible(false);
00496 d->overlap = 0;
00497 }
00498 } else {
00499 if (!d->squeezedText.isEmpty()) {
00500 setText(d->squeezedText);
00501 d->squeezedText.clear();
00502 }
00503
00504 setBackgroundRole(d->bgRole);
00505 updateClearButton();
00506 }
00507 }
00508
00509 void KLineEdit::setSqueezedText( const QString &text)
00510 {
00511 setSqueezedTextEnabled(true);
00512 setText(text);
00513 }
00514
00515 void KLineEdit::setSqueezedTextEnabled( bool enable )
00516 {
00517 d->enableSqueezedText = enable;
00518 }
00519
00520 bool KLineEdit::isSqueezedTextEnabled() const
00521 {
00522 return d->enableSqueezedText;
00523 }
00524
00525 void KLineEdit::setText( const QString& text )
00526 {
00527 if( d->enableClickMsg )
00528 {
00529 d->drawClickMsg = text.isEmpty();
00530 update();
00531 }
00532 if( d->enableSqueezedText && isReadOnly() )
00533 {
00534 d->squeezedText = text;
00535 setSqueezedText();
00536 return;
00537 }
00538
00539 QLineEdit::setText( text );
00540 }
00541
00542 void KLineEdit::setSqueezedText()
00543 {
00544 d->squeezedStart = 0;
00545 d->squeezedEnd = 0;
00546 const QString fullText = d->squeezedText;
00547 const QFontMetrics fm(fontMetrics());
00548 const int labelWidth = size().width() - 2*style()->pixelMetric(QStyle::PM_DefaultFrameWidth) - 2;
00549 const int textWidth = fm.width(fullText);
00550
00551 if (textWidth > labelWidth)
00552 {
00553
00554 QString squeezedText = "...";
00555 int squeezedWidth = fm.width(squeezedText);
00556
00557
00558 int letters = fullText.length() * (labelWidth - squeezedWidth) / textWidth / 2;
00559 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
00560 squeezedWidth = fm.width(squeezedText);
00561
00562 if (squeezedWidth < labelWidth)
00563 {
00564
00565
00566 do
00567 {
00568 letters++;
00569 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
00570 squeezedWidth = fm.width(squeezedText);
00571 } while (squeezedWidth < labelWidth);
00572 letters--;
00573 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
00574 }
00575 else if (squeezedWidth > labelWidth)
00576 {
00577
00578
00579 do
00580 {
00581 letters--;
00582 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
00583 squeezedWidth = fm.width(squeezedText);
00584 } while (squeezedWidth > labelWidth);
00585 }
00586
00587 if (letters < 5)
00588 {
00589
00590 QLineEdit::setText(fullText);
00591 }
00592 else
00593 {
00594 QLineEdit::setText(squeezedText);
00595 d->squeezedStart = letters;
00596 d->squeezedEnd = fullText.length() - letters;
00597 }
00598
00599 setToolTip( fullText );
00600
00601 }
00602 else
00603 {
00604 QLineEdit::setText(fullText);
00605
00606 this->setToolTip( "" );
00607 QToolTip::showText(pos(), QString());
00608 }
00609
00610 setCursorPosition(0);
00611 }
00612
00613 void KLineEdit::copy() const
00614 {
00615 if( !copySqueezedText(true))
00616 QLineEdit::copy();
00617 }
00618
00619 bool KLineEdit::copySqueezedText(bool clipboard) const
00620 {
00621 if (!d->squeezedText.isEmpty() && d->squeezedStart)
00622 {
00623 KLineEdit *that = const_cast<KLineEdit *>(this);
00624 if (!that->hasSelectedText())
00625 return false;
00626 int start = selectionStart(), end = start + selectedText().length();
00627 if (start >= d->squeezedStart+3)
00628 start = start - 3 - d->squeezedStart + d->squeezedEnd;
00629 else if (start > d->squeezedStart)
00630 start = d->squeezedStart;
00631 if (end >= d->squeezedStart+3)
00632 end = end - 3 - d->squeezedStart + d->squeezedEnd;
00633 else if (end > d->squeezedStart)
00634 end = d->squeezedEnd;
00635 if (start == end)
00636 return false;
00637 QString t = d->squeezedText;
00638 t = t.mid(start, end - start);
00639 disconnect( QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
00640 QApplication::clipboard()->setText( t, clipboard ? QClipboard::Clipboard : QClipboard::Selection );
00641 connect( QApplication::clipboard(), SIGNAL(selectionChanged()), this,
00642 SLOT(_q_clipboardChanged()) );
00643 return true;
00644 }
00645 return false;
00646 }
00647
00648 void KLineEdit::resizeEvent( QResizeEvent * ev )
00649 {
00650 if (!d->squeezedText.isEmpty())
00651 setSqueezedText();
00652
00653 updateClearButton();
00654 QLineEdit::resizeEvent(ev);
00655 }
00656
00657
00658 void KLineEdit::keyPressEvent( QKeyEvent *e )
00659 {
00660 const int key = e->key() | e->modifiers();
00661
00662 if ( KStandardShortcut::copy().contains( key ) )
00663 {
00664 copy();
00665 return;
00666 }
00667 else if ( KStandardShortcut::paste().contains( key ) )
00668 {
00669
00670
00671
00672 if( !isReadOnly() )
00673 paste();
00674 return;
00675 }
00676 else if ( KStandardShortcut::pasteSelection().contains( key ) )
00677 {
00678 QString text = QApplication::clipboard()->text( QClipboard::Selection);
00679 insert( text );
00680 deselect();
00681 return;
00682 }
00683
00684 else if ( KStandardShortcut::cut().contains( key ) )
00685 {
00686 if( !isReadOnly() )
00687 cut();
00688 return;
00689 }
00690 else if ( KStandardShortcut::undo().contains( key ) )
00691 {
00692 if( !isReadOnly() )
00693 undo();
00694 return;
00695 }
00696 else if ( KStandardShortcut::redo().contains( key ) )
00697 {
00698 if( !isReadOnly() )
00699 redo();
00700 return;
00701 }
00702 else if ( KStandardShortcut::deleteWordBack().contains( key ) )
00703 {
00704 cursorWordBackward(true);
00705 if ( hasSelectedText() )
00706 del();
00707
00708 e->accept();
00709 return;
00710 }
00711 else if ( KStandardShortcut::deleteWordForward().contains( key ) )
00712 {
00713
00714 cursorWordForward(true);
00715 if ( hasSelectedText() )
00716 del();
00717
00718 e->accept();
00719 return;
00720 }
00721 else if ( KStandardShortcut::backwardWord().contains( key ) )
00722 {
00723 cursorWordBackward(false);
00724 e->accept();
00725 return;
00726 }
00727 else if ( KStandardShortcut::forwardWord().contains( key ) )
00728 {
00729 cursorWordForward(false);
00730 e->accept();
00731 return;
00732 }
00733 else if ( KStandardShortcut::beginningOfLine().contains( key ) )
00734 {
00735 home(false);
00736 e->accept();
00737 return;
00738 }
00739 else if ( KStandardShortcut::endOfLine().contains( key ) )
00740 {
00741 end(false);
00742 e->accept();
00743 return;
00744 }
00745
00746
00747
00748
00749 if ( echoMode() == QLineEdit::Normal &&
00750 completionMode() != KGlobalSettings::CompletionNone )
00751 {
00752 const KeyBindingMap keys = getKeyBindings();
00753 const KGlobalSettings::Completion mode = completionMode();
00754 const bool noModifier = (e->modifiers() == Qt::NoButton ||
00755 e->modifiers() == Qt::ShiftModifier ||
00756 e->modifiers() == Qt::KeypadModifier);
00757
00758 if ( (mode == KGlobalSettings::CompletionAuto ||
00759 mode == KGlobalSettings::CompletionPopupAuto ||
00760 mode == KGlobalSettings::CompletionMan) && noModifier )
00761 {
00762 if ( !d->userSelection && hasSelectedText() &&
00763 ( e->key() == Qt::Key_Right || e->key() == Qt::Key_Left ) &&
00764 e->modifiers()==Qt::NoButton )
00765 {
00766 const QString old_txt = text();
00767 d->disableRestoreSelection = true;
00768 const int start = selectionStart();
00769
00770 deselect();
00771 QLineEdit::keyPressEvent ( e );
00772 const int cPosition=cursorPosition();
00773 setText(old_txt);
00774 setCursorPosition(cPosition);
00775 if (e->key() ==Qt::Key_Right && cPosition > start )
00776 {
00777 setSelection(cPosition, old_txt.length());
00778
00779 d->_k_updateUserText(text());
00780 }
00781 else
00782 setSelection(start, old_txt.length());
00783
00784 d->disableRestoreSelection = false;
00785 return;
00786 }
00787
00788 if ( e->key() == Qt::Key_Escape )
00789 {
00790 if (hasSelectedText() && !d->userSelection )
00791 {
00792 del();
00793 setUserSelection(true);
00794 }
00795
00796
00797
00798 e->ignore();
00799 return;
00800 }
00801
00802 }
00803
00804 if ( (mode == KGlobalSettings::CompletionAuto ||
00805 mode == KGlobalSettings::CompletionMan) && noModifier )
00806 {
00807 const QString keycode = e->text();
00808 if ( !keycode.isEmpty() && (keycode.unicode()->isPrint() ||
00809 e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) )
00810 {
00811 const bool hasUserSelection=d->userSelection;
00812 const bool hadSelection=hasSelectedText();
00813
00814 bool cursorNotAtEnd=false;
00815
00816 const int start = selectionStart();
00817 const int cPos = cursorPosition();
00818
00819
00820
00821
00822
00823 if ( hadSelection && !hasUserSelection && start>cPos )
00824 {
00825 del();
00826 setCursorPosition(cPos);
00827 cursorNotAtEnd=true;
00828 }
00829
00830 d->disableRestoreSelection = true;
00831 QLineEdit::keyPressEvent ( e );
00832 d->disableRestoreSelection = false;
00833
00834 QString txt = text();
00835 int len = txt.length();
00836 if ( !hasSelectedText() && len )
00837 {
00838 if ( e->key() == Qt::Key_Backspace )
00839 {
00840 if ( hadSelection && !hasUserSelection && !cursorNotAtEnd )
00841 {
00842 backspace();
00843 txt = text();
00844 len = txt.length();
00845 }
00846
00847 if ( !d->backspacePerformsCompletion || !len )
00848 d->autoSuggest = false;
00849 }
00850
00851 if (e->key() == Qt::Key_Delete )
00852 d->autoSuggest=false;
00853
00854 doCompletion(txt);
00855
00856 if( (e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete) )
00857 d->autoSuggest=true;
00858
00859 e->accept();
00860 }
00861
00862 return;
00863 }
00864
00865 }
00866
00867 else if (( mode == KGlobalSettings::CompletionPopup ||
00868 mode == KGlobalSettings::CompletionPopupAuto ) &&
00869 noModifier && !e->text().isEmpty() )
00870 {
00871 const QString old_txt = text();
00872 const bool hasUserSelection=d->userSelection;
00873 const bool hadSelection=hasSelectedText();
00874 bool cursorNotAtEnd=false;
00875
00876 const int start = selectionStart();
00877 const int cPos = cursorPosition();
00878 const QString keycode = e->text();
00879
00880
00881
00882
00883
00884 if (hadSelection && !hasUserSelection && start>cPos &&
00885 ( (!keycode.isEmpty() && keycode.unicode()->isPrint()) ||
00886 e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) )
00887 {
00888 del();
00889 setCursorPosition(cPos);
00890 cursorNotAtEnd=true;
00891 }
00892
00893 const int selectedLength=selectedText().length();
00894
00895 d->disableRestoreSelection = true;
00896 QLineEdit::keyPressEvent ( e );
00897 d->disableRestoreSelection = false;
00898
00899 if (( selectedLength != selectedText().length() ) && !hasUserSelection )
00900 slotRestoreSelectionColors();
00901
00902 QString txt = text();
00903 int len = txt.length();
00904 if ( ( txt != old_txt || txt != e->text() ) && len &&
00905 ( (!keycode.isEmpty() && keycode.unicode()->isPrint()) ||
00906 e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete) )
00907 {
00908 if ( e->key() == Qt::Key_Backspace )
00909 {
00910 if ( hadSelection && !hasUserSelection && !cursorNotAtEnd )
00911 {
00912 backspace();
00913 txt = text();
00914 len = txt.length();
00915 }
00916
00917 if ( !d->backspacePerformsCompletion )
00918 d->autoSuggest = false;
00919 }
00920
00921 if (e->key() == Qt::Key_Delete )
00922 d->autoSuggest=false;
00923
00924 if ( d->completionBox )
00925 d->completionBox->setCancelledText( txt );
00926
00927 doCompletion(txt);
00928
00929 if ( (e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) &&
00930 mode == KGlobalSettings::CompletionPopupAuto )
00931 d->autoSuggest=true;
00932
00933 e->accept();
00934 }
00935 else if (!len && d->completionBox && d->completionBox->isVisible())
00936 d->completionBox->hide();
00937
00938 return;
00939 }
00940
00941 else if ( mode == KGlobalSettings::CompletionShell )
00942 {
00943
00944 KShortcut cut;
00945 if ( keys[TextCompletion].isEmpty() )
00946 cut = KStandardShortcut::shortcut(KStandardShortcut::TextCompletion);
00947 else
00948 cut = keys[TextCompletion];
00949
00950 if ( cut.contains( key ) )
00951 {
00952
00953
00954 const QString txt = text();
00955 const int len = txt.length();
00956 if ( cursorPosition() == len && len != 0 )
00957 {
00958 doCompletion(txt);
00959 return;
00960 }
00961 }
00962 else if ( d->completionBox )
00963 d->completionBox->hide();
00964 }
00965
00966
00967 if ( mode != KGlobalSettings::CompletionNone )
00968 {
00969
00970 KShortcut cut;
00971 if ( keys[PrevCompletionMatch].isEmpty() )
00972 cut = KStandardShortcut::shortcut(KStandardShortcut::PrevCompletion);
00973 else
00974 cut = keys[PrevCompletionMatch];
00975
00976 if ( cut.contains( key ) )
00977 {
00978 if ( emitSignals() )
00979 emit textRotation( KCompletionBase::PrevCompletionMatch );
00980 if ( handleSignals() )
00981 rotateText( KCompletionBase::PrevCompletionMatch );
00982 return;
00983 }
00984
00985
00986 if ( keys[NextCompletionMatch].isEmpty() )
00987 cut = KStandardShortcut::shortcut(KStandardShortcut::NextCompletion);
00988 else
00989 cut = keys[NextCompletionMatch];
00990
00991 if ( cut.contains( key ) )
00992 {
00993 if ( emitSignals() )
00994 emit textRotation( KCompletionBase::NextCompletionMatch );
00995 if ( handleSignals() )
00996 rotateText( KCompletionBase::NextCompletionMatch );
00997 return;
00998 }
00999 }
01000
01001
01002 if ( compObj() )
01003 {
01004 KShortcut cut;
01005 if ( keys[SubstringCompletion].isEmpty() )
01006 cut = KStandardShortcut::shortcut(KStandardShortcut::SubstringCompletion);
01007 else
01008 cut = keys[SubstringCompletion];
01009
01010 if ( cut.contains( key ) )
01011 {
01012 if ( emitSignals() )
01013 emit substringCompletion( text() );
01014 if ( handleSignals() )
01015 {
01016 setCompletedItems( compObj()->substringCompletion(text()));
01017 e->accept();
01018 }
01019 return;
01020 }
01021 }
01022 }
01023 const int selectedLength = selectedText().length();
01024
01025
01026 QLineEdit::keyPressEvent ( e );
01027
01028 if ( selectedLength != selectedText().length() )
01029 slotRestoreSelectionColors();
01030 }
01031
01032 void KLineEdit::mouseDoubleClickEvent( QMouseEvent* e )
01033 {
01034 if ( e->button() == Qt::LeftButton )
01035 {
01036 d->possibleTripleClick=true;
01037 QTimer::singleShot( QApplication::doubleClickInterval(),this,
01038 SLOT(tripleClickTimeout()) );
01039 }
01040 QLineEdit::mouseDoubleClickEvent( e );
01041 }
01042
01043 void KLineEdit::mousePressEvent( QMouseEvent* e )
01044 {
01045 if ( (e->button() == Qt::LeftButton ||
01046 e->button() == Qt::MidButton ) &&
01047 d->clearButton ) {
01048 d->clickInClear = d->clearButton->underMouse();
01049
01050 if ( d->clickInClear ) {
01051 d->possibleTripleClick = false;
01052 }
01053 }
01054
01055 if ( e->button() == Qt::LeftButton && d->possibleTripleClick ) {
01056 selectAll();
01057 e->accept();
01058 return;
01059 }
01060
01061 QLineEdit::mousePressEvent( e );
01062 }
01063
01064 void KLineEdit::mouseReleaseEvent( QMouseEvent* e )
01065 {
01066 if ( d->clickInClear ) {
01067 if ( d->clearButton->underMouse() ) {
01068 QString newText;
01069 if ( e->button() == Qt::MidButton ) {
01070 newText = QApplication::clipboard()->text( QClipboard::Selection );
01071 setText( newText );
01072 } else {
01073 setSelection(0, text().size());
01074 del();
01075 emit clearButtonClicked();
01076 }
01077 emit textChanged( newText );
01078 }
01079
01080 d->clickInClear = false;
01081 e->accept();
01082 return;
01083 }
01084
01085 QLineEdit::mouseReleaseEvent( e );
01086
01087 if (QApplication::clipboard()->supportsSelection() ) {
01088 if ( e->button() == Qt::LeftButton ) {
01089
01090 copySqueezedText( false );
01091 }
01092 }
01093 }
01094
01095 void KLineEdit::tripleClickTimeout()
01096 {
01097 d->possibleTripleClick=false;
01098 }
01099
01100 QMenu* KLineEdit::createStandardContextMenu()
01101 {
01102 QMenu *popup = QLineEdit::createStandardContextMenu();
01103
01104 if( !isReadOnly() )
01105 {
01106
01107 const QList<QAction *> actionList = popup->actions();
01108 enum { UndoAct, RedoAct, Separator1, CutAct, CopyAct, PasteAct, DeleteAct, ClearAct,
01109 Separator2, SelectAllAct, NCountActs };
01110 QAction *separatorAction = 0L;
01111
01112 const int idx = actionList.indexOf( actionList[DeleteAct] ) + 1;
01113 if ( idx < actionList.count() )
01114 separatorAction = actionList.at( idx );
01115 if ( separatorAction )
01116 {
01117 KAction *clearAllAction = KStandardAction::clear( this, SLOT( clear() ), this) ;
01118 if ( text().isEmpty() )
01119 clearAllAction->setEnabled( false );
01120 popup->insertAction( separatorAction, clearAllAction );
01121 }
01122 }
01123
01124 KIconTheme::assignIconsToContextMenu( KIconTheme::TextEditor, popup->actions () );
01125
01126
01127
01128
01129 if ( compObj() && !isReadOnly() && KAuthorized::authorize("lineedit_text_completion") )
01130 {
01131 QMenu *subMenu = popup->addMenu( KIcon("text-completion"), i18nc("@title:menu", "Text Completion") );
01132 connect( subMenu, SIGNAL( triggered ( QAction* ) ),
01133 this, SLOT( completionMenuActivated( QAction* ) ) );
01134
01135 popup->addSeparator();
01136
01137 QActionGroup* ag = new QActionGroup( this );
01138 d->noCompletionAction = ag->addAction( i18nc("@item:inmenu Text Completion", "None"));
01139 d->shellCompletionAction = ag->addAction( i18nc("@item:inmenu Text Completion", "Manual") );
01140 d->autoCompletionAction = ag->addAction( i18nc("@item:inmenu Text Completion", "Automatic") );
01141 d->popupCompletionAction = ag->addAction( i18nc("@item:inmenu Text Completion", "Dropdown List") );
01142 d->shortAutoCompletionAction = ag->addAction( i18nc("@item:inmenu Text Completion", "Short Automatic") );
01143 d->popupAutoCompletionAction = ag->addAction( i18nc("@item:inmenu Text Completion", "Dropdown List && Automatic"));
01144 subMenu->addActions( ag->actions() );
01145
01146
01147
01148 d->shellCompletionAction->setCheckable( true );
01149 d->noCompletionAction->setCheckable( true );
01150 d->popupCompletionAction->setCheckable( true );
01151 d->autoCompletionAction->setCheckable( true );
01152 d->shortAutoCompletionAction->setCheckable( true );
01153 d->popupAutoCompletionAction->setCheckable( true );
01154
01155 d->shellCompletionAction->setEnabled( !d->disableCompletionMap[ KGlobalSettings::CompletionShell ] );
01156 d->noCompletionAction->setEnabled( !d->disableCompletionMap[ KGlobalSettings::CompletionNone ] );
01157 d->popupCompletionAction->setEnabled( !d->disableCompletionMap[ KGlobalSettings::CompletionPopup ] );
01158 d->autoCompletionAction->setEnabled( !d->disableCompletionMap[ KGlobalSettings::CompletionAuto ] );
01159 d->shortAutoCompletionAction->setEnabled( !d->disableCompletionMap[ KGlobalSettings::CompletionMan ] );
01160 d->popupAutoCompletionAction->setEnabled( !d->disableCompletionMap[ KGlobalSettings::CompletionPopupAuto ] );
01161
01162 const KGlobalSettings::Completion mode = completionMode();
01163 d->noCompletionAction->setChecked( mode == KGlobalSettings::CompletionNone );
01164 d->shellCompletionAction->setChecked( mode == KGlobalSettings::CompletionShell );
01165 d->popupCompletionAction->setChecked( mode == KGlobalSettings::CompletionPopup );
01166 d->autoCompletionAction->setChecked( mode == KGlobalSettings::CompletionAuto );
01167 d->shortAutoCompletionAction->setChecked( mode == KGlobalSettings::CompletionMan );
01168 d->popupAutoCompletionAction->setChecked( mode == KGlobalSettings::CompletionPopupAuto );
01169
01170 const KGlobalSettings::Completion defaultMode = KGlobalSettings::completionMode();
01171 if ( mode != defaultMode && !d->disableCompletionMap[ defaultMode ] )
01172 {
01173 subMenu->addSeparator();
01174 d->defaultAction = subMenu->addAction( i18nc("@item:inmenu Text Completion", "Default") );
01175 }
01176 }
01177
01178 return popup;
01179 }
01180
01181 void KLineEdit::contextMenuEvent( QContextMenuEvent *e )
01182 {
01183 if ( QLineEdit::contextMenuPolicy() != Qt::DefaultContextMenu )
01184 return;
01185 QMenu *popup = createStandardContextMenu();
01186
01187
01188
01189
01190 emit aboutToShowContextMenu( popup );
01191
01192 popup->exec(e->globalPos());
01193 delete popup;
01194 }
01195
01196 void KLineEdit::completionMenuActivated( QAction *act)
01197 {
01198 KGlobalSettings::Completion oldMode = completionMode();
01199
01200 if( act == d->noCompletionAction )
01201 {
01202 setCompletionMode( KGlobalSettings::CompletionNone );
01203 }
01204 else if( act == d->shellCompletionAction)
01205 {
01206 setCompletionMode( KGlobalSettings::CompletionShell );
01207 }
01208 else if( act == d->autoCompletionAction)
01209 {
01210 setCompletionMode( KGlobalSettings::CompletionAuto );
01211 }
01212 else if( act == d->popupCompletionAction)
01213 {
01214 setCompletionMode( KGlobalSettings::CompletionPopup );
01215 }
01216 else if( act == d->shortAutoCompletionAction)
01217 {
01218 setCompletionMode( KGlobalSettings::CompletionMan );
01219 }
01220 else if( act == d->popupAutoCompletionAction)
01221 {
01222 setCompletionMode( KGlobalSettings::CompletionPopupAuto );
01223 }
01224 else if( act == d->defaultAction )
01225 {
01226 setCompletionMode( KGlobalSettings::completionMode() );
01227 }
01228 else
01229 return;
01230
01231 if ( oldMode != completionMode() )
01232 {
01233 if ( (oldMode == KGlobalSettings::CompletionPopup ||
01234 oldMode == KGlobalSettings::CompletionPopupAuto ) &&
01235 d->completionBox && d->completionBox->isVisible() )
01236 d->completionBox->hide();
01237 emit completionModeChanged( completionMode() );
01238 }
01239 }
01240
01241 void KLineEdit::dropEvent(QDropEvent *e)
01242 {
01243 if( d->handleURLDrops )
01244 {
01245 const KUrl::List urlList = KUrl::List::fromMimeData( e->mimeData() );
01246 if ( !urlList.isEmpty() )
01247 {
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 QString dropText;
01258
01259 KUrl::List::ConstIterator it;
01260 for( it = urlList.begin() ; it != urlList.end() ; ++it )
01261 {
01262 if(!dropText.isEmpty())
01263 dropText+=' ';
01264
01265 dropText += (*it).prettyUrl();
01266 }
01267
01268 setText(dropText);
01269 setCursorPosition(dropText.length());
01270
01271 e->accept();
01272 return;
01273 }
01274 }
01275 QLineEdit::dropEvent(e);
01276 }
01277
01278 bool KLineEdit::event( QEvent* ev )
01279 {
01280 KCursor::autoHideEventFilter( this, ev );
01281 if ( ev->type() == QEvent::ShortcutOverride )
01282 {
01283 QKeyEvent *e = static_cast<QKeyEvent *>( ev );
01284 if (d->overrideShortcut(e)) {
01285 ev->accept();
01286 }
01287 }
01288 else if( ev->type() == QEvent::KeyPress )
01289 {
01290
01291
01292 QKeyEvent *e = static_cast<QKeyEvent *>( ev );
01293
01294 if( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
01295 {
01296 const bool trap = d->completionBox && d->completionBox->isVisible();
01297
01298 const bool stopEvent = trap || (d->grabReturnKeyEvents &&
01299 (e->modifiers() == Qt::NoButton ||
01300 e->modifiers() == Qt::KeypadModifier));
01301
01302
01303 if ( stopEvent )
01304 {
01305 emit QLineEdit::returnPressed();
01306 e->accept();
01307 }
01308
01309 emit returnPressed( displayText() );
01310
01311 if ( trap )
01312 {
01313 d->completionBox->hide();
01314 deselect();
01315 setCursorPosition(text().length());
01316 }
01317
01318
01319 if (stopEvent)
01320 return true;
01321 }
01322 }
01323 return QLineEdit::event( ev );
01324 }
01325
01326
01327 void KLineEdit::setUrlDropsEnabled(bool enable)
01328 {
01329 d->handleURLDrops=enable;
01330 }
01331
01332 bool KLineEdit::urlDropsEnabled() const
01333 {
01334 return d->handleURLDrops;
01335 }
01336
01337 void KLineEdit::setTrapReturnKey( bool grab )
01338 {
01339 d->grabReturnKeyEvents = grab;
01340 }
01341
01342 bool KLineEdit::trapReturnKey() const
01343 {
01344 return d->grabReturnKeyEvents;
01345 }
01346
01347 void KLineEdit::setUrl( const KUrl& url )
01348 {
01349 setText( url.prettyUrl() );
01350 }
01351
01352 void KLineEdit::setCompletionBox( KCompletionBox *box )
01353 {
01354 if ( d->completionBox )
01355 return;
01356
01357 d->completionBox = box;
01358 if ( handleSignals() )
01359 {
01360 connect( d->completionBox, SIGNAL(currentTextChanged( const QString& )),
01361 SLOT(setTextWorkaround( const QString& )) );
01362 connect( d->completionBox, SIGNAL(userCancelled( const QString& )),
01363 SLOT(userCancelled( const QString& )) );
01364
01365
01366 connect( d->completionBox, SIGNAL( activated( const QString& )),
01367 SIGNAL(completionBoxActivated( const QString& )) );
01368 }
01369 }
01370
01371 void KLineEdit::userCancelled(const QString & cancelText)
01372 {
01373 if ( completionMode() != KGlobalSettings::CompletionPopupAuto )
01374 {
01375
01376 setText(cancelText);
01377 }
01378 else if (hasSelectedText() )
01379 {
01380 if (d->userSelection)
01381 deselect();
01382 else
01383 {
01384 d->autoSuggest=false;
01385 const int start = selectionStart() ;
01386 const QString s=text().remove(selectionStart(), selectedText().length());
01387 setText(s);
01388 setCursorPosition(start);
01389 d->autoSuggest=true;
01390 }
01391 }
01392 }
01393
01394 bool KLineEditPrivate::overrideShortcut(const QKeyEvent* e)
01395 {
01396 KShortcut scKey;
01397
01398 const int key = e->key() | e->modifiers();
01399 const KLineEdit::KeyBindingMap keys = q->getKeyBindings();
01400
01401 if (keys[KLineEdit::TextCompletion].isEmpty())
01402 scKey = KStandardShortcut::shortcut(KStandardShortcut::TextCompletion);
01403 else
01404 scKey = keys[KLineEdit::TextCompletion];
01405
01406 if (scKey.contains( key ))
01407 return true;
01408
01409 if (keys[KLineEdit::NextCompletionMatch].isEmpty())
01410 scKey = KStandardShortcut::shortcut(KStandardShortcut::NextCompletion);
01411 else
01412 scKey = keys[KLineEdit::NextCompletionMatch];
01413
01414 if (scKey.contains( key ))
01415 return true;
01416
01417 if (keys[KLineEdit::PrevCompletionMatch].isEmpty())
01418 scKey = KStandardShortcut::shortcut(KStandardShortcut::PrevCompletion);
01419 else
01420 scKey = keys[KLineEdit::PrevCompletionMatch];
01421
01422 if (scKey.contains( key ))
01423 return true;
01424
01425
01426 if ( KStandardShortcut::copy().contains( key ) )
01427 return true;
01428 else if ( KStandardShortcut::paste().contains( key ) )
01429 return true;
01430 else if ( KStandardShortcut::cut().contains( key ) )
01431 return true;
01432 else if ( KStandardShortcut::undo().contains( key ) )
01433 return true;
01434 else if ( KStandardShortcut::redo().contains( key ) )
01435 return true;
01436 else if (KStandardShortcut::deleteWordBack().contains( key ))
01437 return true;
01438 else if (KStandardShortcut::deleteWordForward().contains( key ))
01439 return true;
01440 else if (KStandardShortcut::forwardWord().contains( key ))
01441 return true;
01442 else if (KStandardShortcut::backwardWord().contains( key ))
01443 return true;
01444 else if (KStandardShortcut::beginningOfLine().contains( key ))
01445 return true;
01446 else if (KStandardShortcut::endOfLine().contains( key ))
01447 return true;
01448
01449
01450
01451 else if (e->matches(QKeySequence::SelectAll)) {
01452 return true;
01453 }
01454 #ifdef Q_WS_X11
01455 else if (key == Qt::CTRL + Qt::Key_E || key == Qt::CTRL + Qt::Key_U)
01456 return true;
01457 #endif
01458
01459 if (completionBox && completionBox->isVisible ())
01460 {
01461 const int key = e->key();
01462 const Qt::KeyboardModifiers modifiers = e->modifiers();
01463 if ((key == Qt::Key_Backtab || key == Qt::Key_Tab) &&
01464 (modifiers == Qt::NoModifier || (modifiers & Qt::ShiftModifier)))
01465 {
01466 return true;
01467 }
01468 }
01469
01470
01471 return false;
01472 }
01473
01474 void KLineEdit::setCompletedItems( const QStringList& items, bool autoSuggest )
01475 {
01476 QString txt;
01477 if ( d->completionBox && d->completionBox->isVisible() ) {
01478
01479
01480 txt = completionBox()->cancelledText();
01481 } else {
01482 txt = text();
01483 }
01484
01485 if ( !items.isEmpty() &&
01486 !(items.count() == 1 && txt == items.first()) )
01487 {
01488
01489 completionBox();
01490
01491 if ( d->completionBox->isVisible() )
01492 {
01493 QListWidgetItem* currentItem = d->completionBox->currentItem();
01494
01495 bool wasSelected = false;
01496 QString currentSelection;
01497
01498 if ( currentItem != 0 ) {
01499 wasSelected = currentItem->isSelected();
01500 currentSelection = currentItem->text();
01501 }
01502
01503 d->completionBox->setItems( items );
01504
01505 const QList<QListWidgetItem*> matchedItems = d->completionBox->findItems( currentSelection , Qt::MatchExactly);
01506 QListWidgetItem* matchedItem = matchedItems.isEmpty() ? 0 : matchedItems.first();
01507
01508
01509
01510
01511 if( !matchedItem || !wasSelected )
01512 {
01513 wasSelected = false;
01514 matchedItem = d->completionBox->item( 0 );
01515 }
01516 if ( matchedItem )
01517 {
01518 const bool blocked = d->completionBox->blockSignals( true );
01519 d->completionBox->setCurrentItem( matchedItem );
01520 matchedItem->setSelected(wasSelected);
01521 d->completionBox->blockSignals( blocked );
01522 }
01523 }
01524 else
01525 {
01526 if ( !txt.isEmpty() )
01527 d->completionBox->setCancelledText( txt );
01528 d->completionBox->setItems( items );
01529 d->completionBox->popup();
01530 }
01531
01532 if ( d->autoSuggest && autoSuggest )
01533 {
01534 const int index = items.first().indexOf( txt );
01535 const QString newText = items.first().mid( index );
01536 setUserSelection(false);
01537 setCompletedText(newText,true);
01538 }
01539 }
01540 else
01541 {
01542 if ( d->completionBox && d->completionBox->isVisible() )
01543 d->completionBox->hide();
01544 }
01545 }
01546
01547 KCompletionBox * KLineEdit::completionBox( bool create )
01548 {
01549 if ( create && !d->completionBox ) {
01550 setCompletionBox( new KCompletionBox( this ) );
01551 d->completionBox->setObjectName("completion box");
01552 d->completionBox->setFont(font());
01553 }
01554
01555 return d->completionBox;
01556 }
01557
01558 void KLineEdit::setCompletionObject( KCompletion* comp, bool hsig )
01559 {
01560 KCompletion *oldComp = compObj();
01561 if ( oldComp && handleSignals() )
01562 disconnect( oldComp, SIGNAL( matches( const QStringList& )),
01563 this, SLOT( setCompletedItems( const QStringList& )));
01564
01565 if ( comp && hsig )
01566 connect( comp, SIGNAL( matches( const QStringList& )),
01567 this, SLOT( setCompletedItems( const QStringList& )));
01568
01569 KCompletionBase::setCompletionObject( comp, hsig );
01570 }
01571
01572
01573 void KLineEdit::create( WId id, bool initializeWindow, bool destroyOldWindow )
01574 {
01575 QLineEdit::create( id, initializeWindow, destroyOldWindow );
01576 KCursor::setAutoHideCursor( this, true, true );
01577 }
01578
01579 void KLineEdit::setUserSelection(bool userSelection)
01580 {
01581
01582
01583
01584 if (!d->userSelection && userSelection)
01585 {
01586 d->_k_updateUserText(text());
01587 }
01588
01589 QPalette p = palette();
01590
01591 if (userSelection)
01592 {
01593 p.setColor(QPalette::Highlight, d->previousHighlightColor);
01594 p.setColor(QPalette::HighlightedText, d->previousHighlightedTextColor);
01595 }
01596 else
01597 {
01598 QColor color=p.color(QPalette::Disabled, QPalette::Text);
01599 p.setColor(QPalette::HighlightedText, color);
01600 color=p.color(QPalette::Active, QPalette::Base);
01601 p.setColor(QPalette::Highlight, color);
01602 }
01603
01604 d->userSelection=userSelection;
01605 setPalette(p);
01606 }
01607
01608 void KLineEdit::slotRestoreSelectionColors()
01609 {
01610 if (d->disableRestoreSelection)
01611 return;
01612
01613 setUserSelection(true);
01614 }
01615
01616 void KLineEdit::clear()
01617 {
01618 setText( QString() );
01619 }
01620
01621 void KLineEdit::setTextWorkaround( const QString& text )
01622 {
01623 if (!text.isEmpty())
01624 {
01625 setText( text );
01626 end( false );
01627 }
01628 }
01629
01630 QString KLineEdit::originalText() const
01631 {
01632 if ( d->enableSqueezedText && isReadOnly() )
01633 return d->squeezedText;
01634
01635 return text();
01636 }
01637
01638 QString KLineEdit::userText() const
01639 {
01640 return d->userText;
01641 }
01642
01643 bool KLineEdit::autoSuggest() const
01644 {
01645 return d->autoSuggest;
01646 }
01647
01648 void KLineEdit::paintEvent( QPaintEvent *ev )
01649 {
01650 if (echoMode() == Password && d->threeStars) {
01651 blockSignals(true);
01652 const QString oldText = text();
01653 const bool isModifiedState = isModified();
01654 setText(oldText + oldText + oldText);
01655 QLineEdit::paintEvent(ev);
01656 setText(oldText);
01657 setModified(isModifiedState);
01658 blockSignals(false);
01659 } else {
01660 QLineEdit::paintEvent( ev );
01661 }
01662
01663 if (d->enableClickMsg && d->drawClickMsg && !hasFocus() && text().isEmpty()) {
01664 QPainter p(this);
01665 QFont f = font();
01666 f.setItalic(d->italicizePlaceholder);
01667 p.setFont(f);
01668
01669 QColor color(palette().color(foregroundRole()));
01670 color.setAlphaF(0.5);
01671 p.setPen(color);
01672
01673
01674
01675
01676
01677
01678 QStyleOptionFrame opt;
01679 initStyleOption(&opt);
01680 QRect cr = style()->subElementRect(QStyle::SE_LineEditContents, &opt, this);
01681 cr.setLeft(cr.left() + 2);
01682 cr.setRight(cr.right() - 2);
01683
01684 p.drawText(cr, Qt::AlignLeft|Qt::AlignVCenter, d->clickMessage);
01685 }
01686 }
01687
01688 void KLineEdit::focusInEvent( QFocusEvent *ev )
01689 {
01690 if ( d->enableClickMsg && d->drawClickMsg )
01691 {
01692 d->drawClickMsg = false;
01693 update();
01694 }
01695 QLineEdit::focusInEvent( ev );
01696 }
01697
01698 void KLineEdit::focusOutEvent( QFocusEvent *ev )
01699 {
01700 if ( d->enableClickMsg && text().isEmpty() )
01701 {
01702 d->drawClickMsg = true;
01703 update();
01704 }
01705 QLineEdit::focusOutEvent( ev );
01706 }
01707
01708 void KLineEdit::setClickMessage( const QString &msg )
01709 {
01710 d->enableClickMsg = !msg.isEmpty();
01711 d->clickMessage = msg;
01712 d->drawClickMsg = text().isEmpty();
01713 update();
01714 }
01715
01716 void KLineEdit::setContextMenuEnabled( bool showMenu )
01717 {
01718 QLineEdit::setContextMenuPolicy( showMenu ? Qt::DefaultContextMenu : Qt::NoContextMenu );
01719 }
01720
01721 bool KLineEdit::isContextMenuEnabled() const
01722 {
01723 return ( contextMenuPolicy() == Qt::DefaultContextMenu );
01724 }
01725
01726 void KLineEdit::setPasswordMode(bool b)
01727 {
01728 if(b)
01729 {
01730 KConfigGroup cg(KGlobal::config(), "Passwords");
01731 const QString val = cg.readEntry("EchoMode", "OneStar");
01732 if (val == "NoEcho")
01733 setEchoMode(NoEcho);
01734 else {
01735 d->threeStars = (val == "ThreeStars");
01736 setEchoMode(Password);
01737 }
01738 }
01739 else
01740 {
01741 setEchoMode( Normal );
01742 }
01743 }
01744
01745 bool KLineEdit::passwordMode() const
01746 {
01747 return echoMode() == NoEcho || echoMode() == Password;
01748 }
01749
01750 void KLineEdit::doCompletion(const QString& txt)
01751 {
01752 if (emitSignals()) {
01753 emit completion(txt);
01754 }
01755 d->completionRunning = true;
01756 if (handleSignals()) {
01757 makeCompletion(txt);
01758 }
01759 d->completionRunning = false;
01760 }
01761
01762 #include "klineedit.moc"
01763 #include "klineedit_p.moc"
01764