File indexing completed on 2024-04-28 03:53:10

0001 /*
0002     This file is part of the KDE libraries
0003 
0004     This class was originally inspired by Torben Weis'
0005     fileentry.cpp for KFM II.
0006 
0007     SPDX-FileCopyrightText: 1997 Sven Radej <sven.radej@iname.com>
0008     SPDX-FileCopyrightText: 1999 Patrick Ward <PAT_WARD@HP-USA-om5.om.hp.com>
0009     SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org>
0010 
0011     Completely re-designed:
0012     SPDX-FileCopyrightText: 2000, 2001 Dawit Alemayehu <adawit@kde.org>
0013 
0014     SPDX-License-Identifier: LGPL-2.0-or-later
0015 */
0016 
0017 #ifndef KLINEEDIT_H
0018 #define KLINEEDIT_H
0019 
0020 #include <kcompletion.h>
0021 #include <kcompletion_export.h>
0022 #include <kcompletionbase.h>
0023 
0024 #include <QLineEdit>
0025 #include <memory>
0026 
0027 class QAction;
0028 class QMenu;
0029 class KCompletionBox;
0030 class QUrl;
0031 class KLineEditPrivate;
0032 
0033 /**
0034  * @class KLineEdit klineedit.h KLineEdit
0035  *
0036  * An enhanced QLineEdit widget for inputting text.
0037  *
0038  * \b Detail \n
0039  *
0040  * This widget inherits from QLineEdit and implements the following
0041  * additional functionalities:
0042  * @li a completion object that provides both automatic and manual text
0043  * completion as well as multiple match iteration features
0044  * @li configurable key-bindings to activate these features
0045  * @li a popup-menu item that can be used to allow the user to set text
0046  * completion modes on the fly based on their preference
0047  *
0048  * To support these features KLineEdit also emits a few more additional
0049  * signals:
0050  * @li @c completion(const QString &): this signal can be connected to
0051  * a slot that will assist the user in filling out the remaining text
0052  * @li @c textRotation(KeyBindingType): this signal is intended to be
0053  * used to iterate through the list of all possible matches whenever
0054  * there is more than one match for the entered text
0055  * @li @c returnKeyPressed(const QString &): this signal provides the
0056  * current text in the widget as its argument whenever appropriate (this
0057  * is in addition to the @c QLineEdit::returnPressed() signal which KLineEdit
0058  * inherits from QLineEdit).
0059  *
0060  * This widget by default creates a completion object when you invoke
0061  * the @c completionObject(bool) member function for the first time or
0062  * use @c setCompletionObject(KCompletion *, bool) to assign your own
0063  * completion object. Additionally, to make this widget more functional,
0064  * KLineEdit will by default handle the text rotation and completion
0065  * events internally when a completion object is created through either one
0066  * of the methods mentioned above. If you do not need this functionality,
0067  * simply use @c KCompletionBase::setHandleSignals(bool) or set the boolean
0068  * parameter in the above functions to false.
0069  *
0070  * The default key-bindings for completion and rotation is determined
0071  * from the global settings in KStandardShortcut. These values, however,
0072  * can be overridden locally by invoking @c KCompletionBase::setKeyBinding().
0073  * The values can easily be reverted back to the default setting, by simply
0074  * calling @c useGlobalSettings(). An alternate method would be to default
0075  * individual key-bindings by using setKeyBinding() with the default
0076  * second argument.
0077  *
0078  * If @c EchoMode for this widget is set to something other than @c QLineEdit::Normal,
0079  * the completion mode will always be defaulted to CompletionNone.
0080  * This is done purposefully to guard against protected entries, such as
0081  * passwords, being cached in KCompletion's list. Hence, if the @c EchoMode
0082  * is not @c QLineEdit::Normal, the completion mode is automatically disabled.
0083  *
0084  * A read-only KLineEdit will have the same background color as a disabled
0085  * KLineEdit, but its foreground color will be the one used for the read-write
0086  * mode. This differs from QLineEdit's implementation and is done to give visual
0087  * distinction between the three different modes: disabled, read-only, and read-write.
0088  *
0089  * @b Usage
0090  *
0091  * To enable the basic completion feature:
0092  *
0093  * @code
0094  * KLineEdit *edit = new KLineEdit(this);
0095  * KCompletion *comp = edit->completionObject();
0096  * // Connect to the Return pressed signal - optional
0097  * connect(edit, &KLineEdit::returnKeyPressed, comp, [this](const QString &text) { addItem(text); });
0098  * @endcode
0099  *
0100  * To use a customized completion object or your own completion object:
0101  *
0102  * @code
0103  * KLineEdit *edit = new KLineEdit(this);
0104  * KUrlCompletion *comp = new KUrlCompletion();
0105  * edit->setCompletionObject(comp);
0106  * // Connect to the return pressed signal - optional
0107  * connect(edit, &KLineEdit::returnKeyPressed, comp, [this](const QString &text) { addItem(text); });
0108  * @endcode
0109  *
0110  * Note if you specify your own completion object you have to either delete
0111  * it when you don't need it anymore, or you can tell KLineEdit to delete it
0112  * for you:
0113  * @code
0114  * edit->setAutoDeleteCompletionObject(true);
0115  * @endcode
0116  *
0117  * <b>Miscellaneous function calls :</b>\n
0118  *
0119  * @code
0120  * // Tell the widget to not handle completion and iteration automatically
0121  * edit->setHandleSignals(false);
0122  *
0123  * // Set your own key-bindings for a text completion mode
0124  * edit->setKeyBinding(KCompletionBase::TextCompletion, Qt::End);
0125  *
0126  * // Hide the context (popup) menu
0127  * edit->setContextMenuPolicy(Qt::NoContextMenu);
0128  *
0129  * // Default the key-bindings back to the default system settings
0130  * edit->useGlobalKeyBindings();
0131  * @endcode
0132  *
0133  * @image html klineedit.png "KLineEdit widgets with clear-button"
0134  *
0135  * @author Dawit Alemayehu <adawit@kde.org>
0136  */
0137 
0138 class KCOMPLETION_EXPORT KLineEdit : public QLineEdit, public KCompletionBase // krazy:exclude=qclasses
0139 {
0140     friend class KComboBox;
0141     friend class KLineEditStyle;
0142 
0143     Q_OBJECT
0144     Q_DECLARE_PRIVATE(KLineEdit)
0145     Q_PROPERTY(bool trapEnterKeyEvent READ trapReturnKey WRITE setTrapReturnKey)
0146     Q_PROPERTY(bool squeezedTextEnabled READ isSqueezedTextEnabled WRITE setSqueezedTextEnabled)
0147 
0148 public:
0149     /**
0150      * Constructs a KLineEdit object with a default text, a parent,
0151      * and a name.
0152      *
0153      * @param string Text to be shown in the edit widget.
0154      * @param parent The parent widget of the line edit.
0155      */
0156     explicit KLineEdit(const QString &string, QWidget *parent = nullptr);
0157 
0158     /**
0159      * Constructs a line edit
0160      * @param parent The parent widget of the line edit.
0161      */
0162     explicit KLineEdit(QWidget *parent = nullptr);
0163 
0164     /**
0165      *  Destructor.
0166      */
0167     ~KLineEdit() override;
0168 
0169     /**
0170      * Sets @p url into the lineedit. It uses QUrl::toDisplayString() so
0171      * that the url is properly decoded for displaying.
0172      */
0173     void setUrl(const QUrl &url);
0174 
0175     /**
0176      * Reimplemented from KCompletionBase for internal reasons.
0177      *
0178      * This function is re-implemented in order to make sure that
0179      * the EchoMode is acceptable before we set the completion mode.
0180      *
0181      * See KCompletionBase::setCompletionMode
0182      */
0183     void setCompletionMode(KCompletion::CompletionMode mode) override;
0184 
0185     /**
0186      * Disables completion modes by making them non-checkable.
0187      *
0188      * The context menu allows to change the completion mode.
0189      * This method allows to disable some modes.
0190      */
0191     void setCompletionModeDisabled(KCompletion::CompletionMode mode, bool disable = true);
0192 
0193     /**
0194      * Enables/Disables handling of URL drops. If enabled and the user
0195      * drops an URL, the decoded URL will be inserted. Otherwise the default
0196      * behavior of QLineEdit is used, which inserts the encoded URL.
0197      * Call setUrlDropsEnabled(false) if you need dropEvent to be called in a KLineEdit subclass.
0198      *
0199      * @param enable If @c true, insert decoded URLs
0200      */
0201     void setUrlDropsEnabled(bool enable); // KF6: remove it and don't create LineEditUrlDropEventFilter by default.
0202 
0203     /**
0204      * Returns @c true when decoded URL drops are enabled
0205      */
0206     bool urlDropsEnabled() const;
0207 
0208     /**
0209      * By default, KLineEdit recognizes @c Key_Return and @c Key_Enter and emits
0210      * the returnPressed() signals, but it also lets the event pass,
0211      * for example causing a dialog's default-button to be called.
0212      *
0213      * Call this method with @p trap = @c true to make @c KLineEdit stop these
0214      * events. The signals will still be emitted of course.
0215      *
0216      * @see trapReturnKey()
0217      */
0218     void setTrapReturnKey(bool trap);
0219 
0220     /**
0221      * @returns @c true if keyevents of @c Key_Return or
0222      * @c Key_Enter will be stopped or if they will be propagated.
0223      *
0224      * @see setTrapReturnKey ()
0225      */
0226     bool trapReturnKey() const;
0227 
0228     /**
0229      * This method will create a completion-box if none is there, yet.
0230      *
0231      * @param create Set this to false if you don't want the box to be created
0232      *               i.e. to test if it is available.
0233      * @returns the completion-box, that is used in completion mode
0234      * CompletionPopup.
0235      */
0236     virtual KCompletionBox *completionBox(bool create = true);
0237 
0238     /**
0239      * Reimplemented for internal reasons, the API is not affected.
0240      */
0241     void setCompletionObject(KCompletion *, bool handle = true) override;
0242 
0243     /**
0244      * Reimplemented for internal reasons, the API is not affected.
0245      */
0246     virtual void copy() const;
0247 
0248     /**
0249      * Enable text squeezing whenever the supplied text is too long.
0250      * Only works for "read-only" mode.
0251      *
0252      * Note that once text squeezing is enabled, QLineEdit::text()
0253      * and QLineEdit::displayText() return the squeezed text. If
0254      * you want the original text, use @ref originalText.
0255      *
0256      * @see QLineEdit
0257      */
0258     void setSqueezedTextEnabled(bool enable);
0259 
0260     /**
0261      * Returns true if text squeezing is enabled.
0262      * This is only valid when the widget is in read-only mode.
0263      */
0264     bool isSqueezedTextEnabled() const;
0265 
0266     /**
0267      * Returns the original text if text squeezing is enabled.
0268      * If the widget is not in "read-only" mode, this function
0269      * returns the same thing as QLineEdit::text().
0270      *
0271      * @see QLineEdit
0272      */
0273     QString originalText() const;
0274 
0275     /**
0276      * Returns the text as given by the user (i.e. not autocompleted)
0277      * if the widget has autocompletion disabled, this function
0278      * returns the same as QLineEdit::text().
0279      * @since 4.2.2
0280      */
0281     QString userText() const;
0282 
0283     /**
0284      * Set the completion-box to be used in completion mode
0285      * CompletionPopup.
0286      * This will do nothing if a completion-box already exists.
0287      *
0288      * @param box The KCompletionBox to set
0289      */
0290     void setCompletionBox(KCompletionBox *box);
0291 
0292     /**
0293      * @return the size used by the clear button
0294      * @since 4.1
0295      */
0296     QSize clearButtonUsedSize() const;
0297 
0298     /**
0299      * Do completion now. This is called automatically when typing a key for instance.
0300      * Emits completion() and/or calls makeCompletion(), depending on
0301      * emitSignals and handleSignals.
0302      *
0303      * @since 4.2.1
0304      */
0305     void doCompletion(const QString &text);
0306 
0307 Q_SIGNALS:
0308     /**
0309      * Emitted whenever the completion box is activated.
0310      */
0311     void completionBoxActivated(const QString &);
0312 
0313     /**
0314      * Emitted when the user presses the Return or Enter key.
0315      *
0316      * The argument is the current text. Note that this signal is @em not emitted
0317      * if the widget's @c EchoMode is set to QLineEdit::EchoMode.
0318      *
0319      * @since 5.81
0320      */
0321     void returnKeyPressed(const QString &text);
0322 
0323     /**
0324      * Emitted when the completion key is pressed.
0325      *
0326      * Please note that this signal is @em not emitted if the
0327      * completion mode is set to @c CompletionNone or @c EchoMode is
0328      * @em normal.
0329      */
0330     void completion(const QString &);
0331 
0332     /**
0333      * Emitted when the shortcut for substring completion is pressed.
0334      */
0335     void substringCompletion(const QString &);
0336 
0337     /**
0338      * Emitted when the text rotation key-bindings are pressed.
0339      *
0340      * The argument indicates which key-binding was pressed.
0341      * In KLineEdit's case this can be either one of two values:
0342      * PrevCompletionMatch or NextCompletionMatch. See
0343      * KCompletionBase::setKeyBinding for details.
0344      *
0345      * Note that this signal is @em not emitted if the completion
0346      * mode is set to @c CompletionNone or @c echoMode() is @em not  normal.
0347      */
0348     void textRotation(KCompletionBase::KeyBindingType);
0349 
0350     /**
0351      * Emitted when the user changed the completion mode by using the
0352      * popupmenu.
0353      */
0354     void completionModeChanged(KCompletion::CompletionMode);
0355 
0356     /**
0357      * Emitted before the context menu is displayed.
0358      *
0359      * The signal allows you to add your own entries into the
0360      * the context menu that is created on demand.
0361      *
0362      * NOTE: Do not store the pointer to the QMenu
0363      * provided through since it is created and deleted
0364      * on demand.
0365      *
0366      * @param contextMenu the context menu about to be displayed
0367      */
0368     void aboutToShowContextMenu(QMenu *contextMenu);
0369 
0370     /**
0371      * Emitted when the user clicked on the clear button
0372      */
0373     void clearButtonClicked();
0374 
0375 public Q_SLOTS:
0376 
0377     /**
0378      * Sets the lineedit to read-only. Similar to QLineEdit::setReadOnly
0379      * but also takes care of the background color, and the clear button.
0380      */
0381     virtual void setReadOnly(bool);
0382 
0383     /**
0384      * Iterates through all possible matches of the completed text or
0385      * the history list.
0386      *
0387      * This function simply iterates over all possible matches in case
0388      * multiple matches are found as a result of a text completion request.
0389      * It will have no effect if only a single match is found.
0390      *
0391      * @param type The key-binding invoked.
0392      */
0393     void rotateText(KCompletionBase::KeyBindingType type);
0394 
0395     /**
0396      * See KCompletionBase::setCompletedText.
0397      */
0398     void setCompletedText(const QString &) override;
0399 
0400     /**
0401      * Same as the above function except it allows you to temporarily
0402      * turn off text completion in CompletionPopupAuto mode.
0403      *
0404      *
0405      * @param items list of completion matches to be shown in the completion box.
0406      * @param autoSuggest true if you want automatic text completion (suggestion) enabled.
0407      */
0408     void setCompletedItems(const QStringList &items, bool autoSuggest = true) override;
0409 
0410     /**
0411      * Squeezes @p text into the line edit.
0412      * This can only be used with read-only line-edits.
0413      */
0414     void setSqueezedText(const QString &text);
0415 
0416     /**
0417      * Reimplemented to enable text squeezing. API is not affected.
0418      */
0419     virtual void setText(const QString &);
0420 
0421 protected Q_SLOTS:
0422 
0423     /**
0424      * Completes the remaining text with a matching one from
0425      * a given list.
0426      */
0427     virtual void makeCompletion(const QString &);
0428 
0429     /**
0430      * Resets the current displayed text.
0431      * Call this function to revert a text completion if the user
0432      * cancels the request. Mostly applies to popup completions.
0433      */
0434     void userCancelled(const QString &cancelText);
0435 
0436 protected:
0437     /**
0438      * Reimplemented for internal reasons. API not affected.
0439      */
0440     bool event(QEvent *) override;
0441 
0442     /**
0443      * Reimplemented for internal reasons. API not affected.
0444      *
0445      * See QLineEdit::resizeEvent().
0446      */
0447     void resizeEvent(QResizeEvent *) override;
0448 
0449     /**
0450      * Reimplemented for internal reasons. API not affected.
0451      *
0452      * See QLineEdit::keyPressEvent().
0453      */
0454     void keyPressEvent(QKeyEvent *) override;
0455 
0456     /**
0457      * Reimplemented for internal reasons. API not affected.
0458      *
0459      * See QLineEdit::mousePressEvent().
0460      */
0461     void mousePressEvent(QMouseEvent *) override;
0462 
0463     /**
0464      * Reimplemented for internal reasons. API not affected.
0465      *
0466      * See QLineEdit::mouseReleaseEvent().
0467      */
0468     void mouseReleaseEvent(QMouseEvent *) override;
0469 
0470     /**
0471      * Reimplemented for internal reasons. API not affected.
0472      *
0473      * See QWidget::mouseDoubleClickEvent().
0474      */
0475     void mouseDoubleClickEvent(QMouseEvent *) override;
0476 
0477     /**
0478      * Reimplemented for internal reasons. API not affected.
0479      *
0480      * See QLineEdit::contextMenuEvent().
0481      */
0482     void contextMenuEvent(QContextMenuEvent *) override;
0483 
0484     /**
0485      * Reimplemented for internal reasons. API not affected.
0486      *
0487      * See QLineEdit::createStandardContextMenu().
0488      */
0489     QMenu *createStandardContextMenu();
0490 
0491     /**
0492      * This function simply sets the lineedit text and
0493      * highlights the text appropriately if the boolean
0494      * value is set to true.
0495      *
0496      * @param text
0497      * @param marked
0498      */
0499     virtual void setCompletedText(const QString & /*text*/, bool /*marked*/);
0500 
0501     /**
0502      * Sets the widget in userSelection mode or in automatic completion
0503      * selection mode. This changes the colors of selections.
0504      */
0505     void setUserSelection(bool userSelection);
0506 
0507     /**
0508      * Whether in current state text should be auto-suggested
0509      */
0510     bool autoSuggest() const;
0511 
0512     void paintEvent(QPaintEvent *ev) override;
0513 
0514 private:
0515     std::unique_ptr<KLineEditPrivate> const d_ptr;
0516 };
0517 
0518 #endif