File indexing completed on 2024-04-28 15:27:29

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 1999, 2000, 2001 Carsten Pfeiffer <pfeiffer@kde.org>
0004     SPDX-FileCopyrightText: 2013 Teo Mrnjavac <teo@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #ifndef KURLREQUESTER_H
0010 #define KURLREQUESTER_H
0011 
0012 #include "kiowidgets_export.h"
0013 
0014 #include <KEditListWidget>
0015 #include <kfile.h>
0016 
0017 #include <QFileDialog>
0018 #include <QPushButton>
0019 #include <QUrl>
0020 
0021 #include <memory>
0022 
0023 class KComboBox;
0024 class KLineEdit;
0025 class KUrlCompletion;
0026 
0027 class QEvent;
0028 class QString;
0029 
0030 /**
0031  * @class KUrlRequester kurlrequester.h <KUrlRequester>
0032  *
0033  * This class is a widget showing a lineedit and a button, which invokes a
0034  * filedialog. File name completion is available in the lineedit.
0035  *
0036  * The default for the filedialog is to ask for one existing local file, i.e.
0037  * the default mode is 'KFile::File | KFile::ExistingOnly | KFile::LocalOnly',
0038  * which you can change by using setMode().
0039  *
0040  * The default filter is "*", i.e. show all files, which you can change by
0041  * using setNameFilters() or setMimeTypeFilters().
0042  *
0043  * By default the start directory is the current working directory, or the
0044  * last directory where a file has been selected previously, you can change
0045  * this behavior by calling setStartDir().
0046  *
0047  * The default window modality for the file dialog is Qt::ApplicationModal
0048  *
0049  * \image html kurlrequester.png "KUrlRequester"
0050  *
0051  * @short A widget to request a filename/url from the user
0052  * @author Carsten Pfeiffer <pfeiffer@kde.org>
0053  */
0054 class KIOWIDGETS_EXPORT KUrlRequester : public QWidget
0055 {
0056     Q_OBJECT
0057     Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY textChanged USER true)
0058 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 108)
0059     /// @deprecated Since 5.108, use nameFilters
0060     Q_PROPERTY(QString filter READ filter WRITE setFilter)
0061 #endif
0062     /// @since 5.108
0063     Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
0064     Q_PROPERTY(KFile::Modes mode READ mode WRITE setMode)
0065     Q_PROPERTY(QFileDialog::AcceptMode acceptMode READ acceptMode WRITE setAcceptMode)
0066 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 0)
0067     /// @deprecated Since 5.0, use placeholderText
0068     Q_PROPERTY(QString clickMessage READ clickMessage WRITE setClickMessage)
0069 #endif
0070     Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
0071     Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
0072     Q_PROPERTY(Qt::WindowModality fileDialogModality READ fileDialogModality WRITE setFileDialogModality)
0073 
0074 public:
0075     /**
0076      * Constructs a KUrlRequester widget.
0077      */
0078     explicit KUrlRequester(QWidget *parent = nullptr);
0079 
0080     /**
0081      * Constructs a KUrlRequester widget with the initial URL @p url.
0082      */
0083     explicit KUrlRequester(const QUrl &url, QWidget *parent = nullptr);
0084 
0085     /**
0086      * Special constructor, which creates a KUrlRequester widget with a custom
0087      * edit-widget. The edit-widget can be either a KComboBox or a KLineEdit
0088      * (or inherited thereof). Note: for geometry management reasons, the
0089      * edit-widget is reparented to have the KUrlRequester as parent.
0090      */
0091     KUrlRequester(QWidget *editWidget, QWidget *parent);
0092     /**
0093      * Destructs the KUrlRequester.
0094      */
0095     ~KUrlRequester() override;
0096 
0097     /**
0098      * @returns the current url in the lineedit. May be malformed, if the user
0099      * entered something weird. For local files, ~user or environment variables
0100      * are substituted, relative paths will be resolved against startDir()
0101      */
0102     QUrl url() const;
0103 
0104     /**
0105      * @returns the current start dir
0106      * @since 4.3
0107      */
0108     QUrl startDir() const;
0109 
0110     /**
0111      * @returns the current text in the lineedit or combobox.
0112      * This does not do the URL expansion that url() does, it's only provided
0113      * for cases where KUrlRequester is used to enter URL-or-something-else,
0114      * like KOpenWithDialog where you can type a full command with arguments.
0115      *
0116      * @since 4.2
0117      */
0118     QString text() const;
0119 
0120     /**
0121      * Sets the mode of the file dialog.
0122      *
0123      * The default mode of the file dialog is 'KFile::File | KFile::ExistingOnly | KFile::LocalOnly',
0124      * which you can change using this method.
0125      *
0126      * @note You can only select one file from the file dialog invoked
0127      * by KUrlRequester, hence setting KFile::Files doesn't make
0128      * much sense here.
0129      *
0130      * @param mode an OR'ed combination of KFile::Modes flags
0131      *
0132      * @see QFileDialog::setFileMode()
0133      */
0134     void setMode(KFile::Modes mode);
0135 
0136     /**
0137      * Returns the current mode
0138      * @see QFileDialog::fileMode()
0139      */
0140     KFile::Modes mode() const;
0141 
0142     /**
0143      * Sets the open / save mode of the file dialog.
0144      *
0145      * The default is QFileDialog::AcceptOpen.
0146      *
0147      * @see QFileDialog::setAcceptMode()
0148      * @since 5.33
0149      */
0150     void setAcceptMode(QFileDialog::AcceptMode m);
0151 
0152     /**
0153      * Returns the current open / save mode
0154      * @see QFileDialog::acceptMode()
0155      * @since 5.33
0156      */
0157     QFileDialog::AcceptMode acceptMode() const;
0158 
0159 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 108)
0160     /**
0161      * Sets the filters for the file dialog, separated by \\n.
0162      * Use "*.foo *.bar|Comment" syntax for each named filter.
0163      * "*.foo *.bar" for name-less filters also is supported.
0164      * @note This filter syntax is different from the one used in
0165      * QFileDialog::nameFilters() and converted internally.
0166      * @see filter()
0167      * @deprecated Since 5.108, use setNameFilters(const QStringList &) or setNameFilter(const QString &).
0168      *              Note: the filter argument might need adaption, due to the different filter syntax.
0169      */
0170     KIOWIDGETS_DEPRECATED_VERSION(
0171         5,
0172         108,
0173         "Use KUrlRequester::setNameFilters(const QStringList &) or KUrlRequester::setNameFilter(const QString &). NOTE: different filter syntax.")
0174     void setFilter(const QString &filter);
0175 #endif
0176 
0177 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 108)
0178     /**
0179      * Returns the filters for the file dialog, separated by \\n.
0180      * @note This filter syntax is different from the one used in
0181      * QFileDialog::nameFilters() and converted internally.
0182      * @see setFilter()
0183      * @deprecated Since 5.108, use nameFilters() const.
0184      */
0185     KIOWIDGETS_DEPRECATED_VERSION(5, 108, "Use KUrlRequester::nameFilters() const")
0186     QString filter() const;
0187 #endif
0188 
0189     /**
0190      * Sets the filters for the file dialog.
0191      * @see QFileDialog::setNameFilters()
0192      * @since 5.108
0193      */
0194     void setNameFilters(const QStringList &filters);
0195 
0196     /**
0197      * Sets the filters for the file dialog.
0198      * @see QFileDialog::setNameFilter()
0199      * @since 5.108
0200      */
0201     void setNameFilter(const QString &filter);
0202 
0203     /**
0204      * Returns the filters for the file dialog.
0205      * @see QFileDialog::nameFilters()
0206      * @since 5.108
0207      */
0208     QStringList nameFilters() const;
0209 
0210     /**
0211      * Sets the MIME type filters for the file dialog.
0212      * @see QFileDialog::setMimeTypeFilters()
0213      * @since 5.31
0214      */
0215     void setMimeTypeFilters(const QStringList &mimeTypes);
0216     /**
0217      * Returns the MIME type filters for the file dialog.
0218      * @see QFileDialog::mimeTypeFilters()
0219      * @since 5.31
0220      */
0221     QStringList mimeTypeFilters() const;
0222 
0223     /**
0224      * @returns a pointer to the filedialog.
0225      * You can use this to customize the dialog, e.g. to call setLocationLabel
0226      * or other things which are not accessible in the KUrlRequester API.
0227      *
0228      * Never returns 0. This method creates the file dialog on demand.
0229      *
0230      * @deprecated since 5.0. The dialog will be created anyway when the user
0231      * requests it, and will behave according to the properties of KUrlRequester.
0232      */
0233     KIOWIDGETS_DEPRECATED_VERSION(5, 0, "See API docs")
0234     virtual QFileDialog *fileDialog() const;
0235 
0236     /**
0237      * @returns a pointer to the lineedit, either the default one, or the
0238      * special one, if you used the special constructor.
0239      *
0240      * It is provided so that you can e.g. set an own completion object
0241      * (e.g. KShellCompletion) into it.
0242      */
0243     KLineEdit *lineEdit() const;
0244 
0245     /**
0246      * @returns a pointer to the combobox, in case you have set one using the
0247      * special constructor. Returns 0L otherwise.
0248      */
0249     KComboBox *comboBox() const;
0250 
0251     /**
0252      * @returns a pointer to the pushbutton. It is provided so that you can
0253      * specify an own pixmap or a text, if you really need to.
0254      */
0255     QPushButton *button() const;
0256 
0257     /**
0258      * @returns the KUrlCompletion object used in the lineedit/combobox.
0259      */
0260     KUrlCompletion *completionObject() const;
0261 
0262     /**
0263      * @returns an object, suitable for use with KEditListWidget. It allows you
0264      * to put this KUrlRequester into a KEditListWidget.
0265      * Basically, do it like this:
0266      * \code
0267      * KUrlRequester *req = new KUrlRequester( someWidget );
0268      * [...]
0269      * KEditListWidget *editListWidget = new KEditListWidget( req->customEditor(), someWidget );
0270      * \endcode
0271      */
0272     const KEditListWidget::CustomEditor &customEditor();
0273 
0274 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 0)
0275     /**
0276      * @returns the message set with setClickMessage
0277      * @since 4.2
0278      * @deprecated Since 5.0, use KUrlRequester::placeholderText instead.
0279      */
0280     KIOWIDGETS_DEPRECATED_VERSION(5, 0, "Use KUrlRequester::placeholderText()")
0281     QString clickMessage() const;
0282 #endif
0283 
0284 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 0)
0285     /**
0286      * Set a click message @p msg
0287      * @since 4.2
0288      * @deprecated Since 5.0, use KUrlRequester::setPlaceholderText instead.
0289      */
0290     KIOWIDGETS_DEPRECATED_VERSION(5, 0, "Use KUrlRequester::setPlaceholderText(const QString&)")
0291     void setClickMessage(const QString &msg);
0292 #endif
0293 
0294     /**
0295      * @return the message set with setPlaceholderText
0296      * @since 5.0
0297      */
0298     QString placeholderText() const;
0299 
0300     /**
0301      * This makes the KUrlRequester line edit display a grayed-out hinting text as long as
0302      * the user didn't enter any text. It is often used as indication about
0303      * the purpose of the line edit.
0304      * @since 5.0
0305      */
0306     void setPlaceholderText(const QString &msg);
0307 
0308     /**
0309      * @returns the window modality of the file dialog set with setFileDialogModality
0310      * @since 4.4
0311      */
0312     Qt::WindowModality fileDialogModality() const;
0313 
0314     /**
0315      * Set the window modality for the file dialog to @p modality
0316      * Directory selection dialogs are always modal
0317      *
0318      * The default is Qt::ApplicationModal.
0319      *
0320      * @since 4.4
0321      */
0322     void setFileDialogModality(Qt::WindowModality modality);
0323 
0324 public Q_SLOTS:
0325     /**
0326      * Sets the url in the lineedit to @p url.
0327      */
0328     void setUrl(const QUrl &url);
0329 
0330     /**
0331      * Sets the start dir @p startDir.
0332      * The start dir is only used when the URL isn't set.
0333      * @since 4.3
0334      */
0335     void setStartDir(const QUrl &startDir);
0336 
0337 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(4, 3)
0338     /**
0339      * Sets the url in the lineedit to @p QUrl::fromLocalFile(path).
0340      * This is only for local paths; do not pass a url here.
0341      * This method is mostly for "local paths only" url requesters,
0342      * for instance those set up with setMode(KFile::File|KFile::ExistingOnly|KFile::LocalOnly)
0343      *
0344      * @deprecated Since 4.3. Use setUrl(QUrl::fromLocalFile(path)) instead.
0345      */
0346     KIOWIDGETS_DEPRECATED_VERSION(4, 3, "Use KUrlRequester::setUrl(QUrl::fromLocalFile(path))")
0347     void setPath(const QString &path);
0348 #endif
0349 
0350     /**
0351      * Sets the current text in the lineedit or combobox.
0352      * This is used for cases where KUrlRequester is used to
0353      * enter URL-or-something-else, like KOpenWithDialog where you
0354      * can type a full command with arguments.
0355      *
0356      * @see text
0357      * @since 4.3
0358      */
0359     void setText(const QString &text);
0360 
0361     /**
0362      * Clears the lineedit/combobox.
0363      */
0364     void clear();
0365 
0366 Q_SIGNALS:
0367     // forwards from LineEdit
0368     /**
0369      * Emitted when the text in the lineedit changes.
0370      * The parameter contains the contents of the lineedit.
0371      */
0372     void textChanged(const QString &);
0373 
0374     /**
0375      * Emitted when the text in the lineedit was modified by the user.
0376      * Unlike textChanged(), this signal is not emitted when the text is changed programmatically, for example, by calling setText().
0377      * @since 5.21
0378      */
0379     void textEdited(const QString &);
0380 
0381 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 80)
0382     /**
0383      * Emitted when return or enter was pressed in the lineedit.
0384      *
0385      * @deprecated since 5.80, use KUrlRequester::returnPressed(const QString &) signal
0386      */
0387     KIOWIDGETS_DEPRECATED_VERSION(5, 80, "Use KUrlRequester::returnPressed(const QString &) signal")
0388     void returnPressed(); // clazy:exclude=overloaded-signal
0389 #endif
0390 
0391     /**
0392      * Emitted when return or enter was pressed in the lineedit.
0393      * The parameter contains the contents of the lineedit.
0394      */
0395     void returnPressed(const QString &text); // clazy:exclude=overloaded-signal
0396 
0397     /**
0398      * Emitted before the filedialog is going to open. Connect
0399      * to this signal to "configure" the filedialog, e.g. set the
0400      * filefilter, the mode, a preview-widget, etc. It's usually
0401      * not necessary to set a URL for the filedialog, as it will
0402      * get set properly from the editfield contents.
0403      *
0404      * If you use multiple KUrlRequesters, you can connect all of them
0405      * to the same slot and use the given KUrlRequester pointer to know
0406      * which one is going to open.
0407      */
0408     void openFileDialog(KUrlRequester *);
0409 
0410     /**
0411      * Emitted when the user changed the URL via the file dialog.
0412      * The parameter contains the contents of the lineedit.
0413      */
0414     void urlSelected(const QUrl &);
0415 
0416 protected:
0417     void changeEvent(QEvent *e) override;
0418     bool eventFilter(QObject *obj, QEvent *ev) override;
0419 
0420 private:
0421     class KUrlRequesterPrivate;
0422     std::unique_ptr<KUrlRequesterPrivate> const d;
0423 
0424     Q_DISABLE_COPY(KUrlRequester)
0425 };
0426 
0427 class KIOWIDGETS_EXPORT KUrlComboRequester : public KUrlRequester // krazy:exclude=dpointer (For use in Qt Designer)
0428 {
0429     Q_OBJECT
0430 public:
0431     /**
0432      * Constructs a KUrlRequester widget with a combobox.
0433      */
0434     explicit KUrlComboRequester(QWidget *parent = nullptr);
0435 
0436 private:
0437     class Private;
0438     Private *const d;
0439 };
0440 
0441 #endif // KURLREQUESTER_H