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