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