File indexing completed on 2024-12-08 03:40:27

0001 // -*- c++ -*-
0002 /*
0003     This file is part of the KDE libraries
0004     SPDX-FileCopyrightText: 1997, 1998 Richard Moore <rich@kde.org>
0005     SPDX-FileCopyrightText: 1998 Stephan Kulow <coolo@kde.org>
0006     SPDX-FileCopyrightText: 1998 Daniel Grana <grana@ie.iwi.unibe.ch>
0007     SPDX-FileCopyrightText: 2000, 2001 Carsten Pfeiffer <pfeiffer@kde.org>
0008     SPDX-FileCopyrightText: 2001 Frerich Raabe <raabe@kde.org>
0009     SPDX-FileCopyrightText: 2007 David Faure <faure@kde.org>
0010     SPDX-FileCopyrightText: 2008 Rafael Fernández López <ereslibre@kde.org>
0011 
0012     SPDX-License-Identifier: LGPL-2.0-or-later
0013 */
0014 
0015 #ifndef KFILEWIDGET_H
0016 #define KFILEWIDGET_H
0017 
0018 #include "kfile.h"
0019 #include "kiofilewidgets_export.h"
0020 #include <QWidget>
0021 
0022 #include <KFileFilter>
0023 
0024 #include <memory>
0025 
0026 class QUrl;
0027 class QPushButton;
0028 class KActionCollection;
0029 class KFileWidgetPrivate;
0030 class KUrlComboBox;
0031 class KFileFilterCombo;
0032 
0033 class KPreviewWidgetBase;
0034 class QMimeType;
0035 class KConfigGroup;
0036 class KJob;
0037 class KFileItem;
0038 class KDirOperator;
0039 
0040 /**
0041  * @class KFileWidget kfilewidget.h <KFileWidget>
0042  *
0043  * File selector widget.
0044  *
0045  * This is the contents of the KDE file dialog, without the actual QDialog around it.
0046  * It can be embedded directly into applications.
0047  */
0048 class KIOFILEWIDGETS_EXPORT KFileWidget : public QWidget
0049 {
0050     Q_OBJECT
0051 public:
0052     /**
0053      * Constructs a file selector widget.
0054      *
0055      * @param startDir This can either be:
0056      *         @li An empty URL (QUrl()) to start in the current working directory,
0057      *             or the last directory where a file has been selected.
0058      *         @li The path or URL of a starting directory.
0059      *         @li An initial file name to select, with the starting directory being
0060      *             the current working directory or the last directory where a file
0061      *             has been selected.
0062      *         @li The path or URL of a file, specifying both the starting directory and
0063      *             an initially selected file name.
0064      *         @li A URL of the form @c kfiledialog:///&lt;keyword&gt; to start in the
0065      *             directory last used by a filedialog in the same application that
0066      *             specified the same keyword.
0067      *         @li A URL of the form @c kfiledialog:///&lt;keyword&gt;/&lt;filename&gt;
0068      *             to start in the directory last used by a filedialog in the same
0069      *             application that specified the same keyword, and to initially
0070      *             select the specified filename.
0071      *         @li Deprecated: A URL of the form @c kfiledialog:///&lt;keyword&gt;?global to start
0072      *             in the directory last used by a filedialog in any application that
0073      *             specified the same keyword.
0074      *         @li Deprecated: A URL of the form @c kfiledialog:///&lt;keyword&gt;/&lt;filename&gt;?global
0075      *             to start in the directory last used by a filedialog in any
0076      *             application that specified the same keyword, and to initially
0077      *             select the specified filename.
0078      *
0079      * @note Since 5.96, the "?global" syntax is deprecated, for lack of usage.
0080      *
0081      * @param parent The parent widget of this widget
0082      *
0083      */
0084     explicit KFileWidget(const QUrl &startDir, QWidget *parent = nullptr);
0085 
0086     /**
0087      * Destructor
0088      */
0089     ~KFileWidget() override;
0090 
0091     /**
0092      * Defines some default behavior of the filedialog.
0093      * E.g. in mode @p Opening and @p Saving, the selected files/urls will
0094      * be added to the "recent documents" list. The Saving mode also implies
0095      * setKeepLocation() being set.
0096      *
0097      * @p Other means that no default actions are performed.
0098      *
0099      * @see setOperationMode
0100      * @see operationMode
0101      */
0102     enum OperationMode { Other = 0, Opening, Saving };
0103 
0104     /**
0105      * @returns The selected fully qualified filename.
0106      */
0107     QUrl selectedUrl() const;
0108 
0109     /**
0110      * @returns The list of selected URLs.
0111      */
0112     QList<QUrl> selectedUrls() const;
0113 
0114     /**
0115      * @returns the currently shown directory.
0116      */
0117     QUrl baseUrl() const;
0118 
0119     /**
0120      * Returns the full path of the selected file in the local filesystem.
0121      * (Local files only)
0122      */
0123     QString selectedFile() const;
0124 
0125     /**
0126      * Returns a list of all selected local files.
0127      */
0128     QStringList selectedFiles() const;
0129 
0130     /**
0131      * Sets the directory to view.
0132      *
0133      * @param url URL to show.
0134      * @param clearforward Indicates whether the forward queue
0135      * should be cleared.
0136      */
0137     void setUrl(const QUrl &url, bool clearforward = true);
0138 
0139     /**
0140      * Sets the URL to preselect to @p url
0141      *
0142      * This method handles absolute URLs (remember to use fromLocalFile for local paths).
0143      * It also handles relative URLs, which you should construct like this:
0144      * QUrl relativeUrl; relativeUrl.setPath(fileName);
0145      *
0146      * @since 5.33
0147      */
0148     void setSelectedUrl(const QUrl &url);
0149 
0150     /**
0151      * Sets a list of URLs as preselected
0152      *
0153      * @see setSelectedUrl
0154      * @since 5.75
0155      */
0156     void setSelectedUrls(const QList<QUrl> &urls);
0157 
0158     /**
0159      * Sets the operational mode of the filedialog to @p Saving, @p Opening
0160      * or @p Other. This will set some flags that are specific to loading
0161      * or saving files. E.g. setKeepLocation() makes mostly sense for
0162      * a save-as dialog. So setOperationMode( KFileWidget::Saving ); sets
0163      * setKeepLocation for example.
0164      *
0165      * The mode @p Saving, together with a default filter set via
0166      * setMimeFilter() will make the filter combobox read-only.
0167      *
0168      * The default mode is @p Opening.
0169      *
0170      * Call this method right after instantiating KFileWidget.
0171      *
0172      * @see operationMode
0173      * @see KFileWidget::OperationMode
0174      */
0175     void setOperationMode(OperationMode);
0176 
0177     /**
0178      * @returns the current operation mode, Opening, Saving or Other. Default
0179      * is Other.
0180      *
0181      * @see operationMode
0182      * @see KFileWidget::OperationMode
0183      */
0184     OperationMode operationMode() const;
0185 
0186     /**
0187      * Sets whether the filename/url should be kept when changing directories.
0188      * This is for example useful when having a predefined filename where
0189      * the full path for that file is searched.
0190      *
0191      * This is implicitly set when operationMode() is KFileWidget::Saving
0192      *
0193      * getSaveFileName() and getSaveUrl() set this to true by default, so that
0194      * you can type in the filename and change the directory without having
0195      * to type the name again.
0196      */
0197     void setKeepLocation(bool keep);
0198 
0199     /**
0200      * @returns whether the contents of the location edit are kept when
0201      * changing directories.
0202      */
0203     bool keepsLocation() const;
0204 
0205     /**
0206      * Set the filters to be used.
0207      *
0208      * Each item of the list corresponds to a selectable filter.
0209      *
0210      * Only one filter is active at a time.
0211      *
0212      * @param activeFilter the initially active filter
0213      *
0214      * @since 6.0
0215      *
0216      */
0217     void setFilters(const QList<KFileFilter> &filters, const KFileFilter &activeFilter = KFileFilter());
0218 
0219     /**
0220      * Returns the current filter as entered by the user or one of the
0221      * predefined set via setFilter().
0222      *
0223      * @see setFilter()
0224      * @see filterChanged()
0225      *
0226      * @since 6.0
0227      */
0228     KFileFilter currentFilter() const;
0229 
0230     /**
0231      *  Clears any MIME type or name filter. Does not reload the directory.
0232      */
0233     void clearFilter();
0234 
0235     /**
0236      * Adds a preview widget and enters the preview mode.
0237      *
0238      * In this mode the dialog is split and the right part contains your
0239      * preview widget.
0240      *
0241      * Ownership is transferred to KFileWidget. You need to create the
0242      * preview-widget with "new", i.e. on the heap.
0243      *
0244      * @param w The widget to be used for the preview.
0245      */
0246     void setPreviewWidget(KPreviewWidgetBase *w);
0247 
0248     /**
0249      * Sets the mode of the dialog.
0250      *
0251      * The mode is defined as (in kfile.h):
0252      * \code
0253      *    enum Mode {
0254      *         File         = 1,
0255      *         Directory    = 2,
0256      *         Files        = 4,
0257      *         ExistingOnly = 8,
0258      *         LocalOnly    = 16,
0259      *    };
0260      * \endcode
0261      * You can OR the values, e.g.
0262      * \code
0263      * KFile::Modes mode = KFile::Files |
0264      *                     KFile::ExistingOnly |
0265      *                     KFile::LocalOnly );
0266      * setMode( mode );
0267      * \endcode
0268      */
0269     void setMode(KFile::Modes m);
0270 
0271     /**
0272      * Returns the mode of the filedialog.
0273      * @see setMode()
0274      */
0275     KFile::Modes mode() const;
0276 
0277     /**
0278      * Sets the text to be displayed in front of the selection.
0279      *
0280      * The default is "Location".
0281      * Most useful if you want to make clear what
0282      * the location is used for.
0283      */
0284     void setLocationLabel(const QString &text);
0285 
0286     /**
0287      * @returns a pointer to the OK-Button in the filedialog.
0288      * Note that the button is hidden and unconnected when using KFileWidget alone;
0289      * KFileDialog shows it and connects to it.
0290      */
0291     QPushButton *okButton() const;
0292 
0293     /**
0294      * @returns a pointer to the Cancel-Button in the filedialog.
0295      * Note that the button is hidden and unconnected when using KFileWidget alone;
0296      * KFileDialog shows it and connects to it.
0297      */
0298     QPushButton *cancelButton() const;
0299 
0300     /**
0301      * @returns the combobox used to type the filename or full location of the file.
0302      */
0303     KUrlComboBox *locationEdit() const;
0304 
0305     /**
0306      * @returns the combobox that contains the filters
0307      */
0308     KFileFilterCombo *filterWidget() const;
0309 
0310     /**
0311      * This method implements the logic to determine the user's default directory
0312      * to be listed. E.g. the documents directory, home directory or a recently
0313      * used directory.
0314      * @param startDir A URL specifying the initial directory, or using the
0315      *                 @c kfiledialog:/// syntax to specify a last used
0316      *                 directory.  If this URL specifies a file name, it is
0317      *                 ignored.  Refer to the KFileWidget::KFileWidget()
0318      *                 documentation for the @c kfiledialog:/// URL syntax.
0319      * @param recentDirClass If the @c kfiledialog:/// syntax is used, this
0320      *        will return the string to be passed to KRecentDirs::dir() and
0321      *        KRecentDirs::add().
0322      * @return The URL that should be listed by default (e.g. by KFileDialog or
0323      *         KDirSelectDialog).
0324      * @see KFileWidget::KFileWidget()
0325      */
0326     static QUrl getStartUrl(const QUrl &startDir, QString &recentDirClass);
0327 
0328     /**
0329      * Similar to getStartUrl(const QUrl& startDir,QString& recentDirClass),
0330      * but allows both the recent start directory keyword and a suggested file name
0331      * to be returned.
0332      * @param startDir A URL specifying the initial directory and/or filename,
0333      *                 or using the @c kfiledialog:/// syntax to specify a
0334      *                 last used location.
0335      *                 Refer to the KFileWidget::KFileWidget()
0336      *                 documentation for the @c kfiledialog:/// URL syntax.
0337      * @param recentDirClass If the @c kfiledialog:/// syntax is used, this
0338      *        will return the string to be passed to KRecentDirs::dir() and
0339      *        KRecentDirs::add().
0340      * @param fileName The suggested file name, if specified as part of the
0341      *        @p StartDir URL.
0342      * @return The URL that should be listed by default (e.g. by KFileDialog or
0343      *         KDirSelectDialog).
0344      *
0345      * @see KFileWidget::KFileWidget()
0346      */
0347     static QUrl getStartUrl(const QUrl &startDir, QString &recentDirClass, QString &fileName);
0348 
0349     /**
0350      * @internal
0351      * Used by KDirSelectDialog to share the dialog's start directory.
0352      */
0353     static void setStartDir(const QUrl &directory);
0354 
0355     /**
0356      * Set a custom widget that should be added to the file dialog.
0357      * @param widget A widget, or a widget of widgets, for displaying custom
0358      *               data in the file widget. This can be used, for example, to
0359      *               display a check box with the title "Open as read-only".
0360      *               When creating this widget, you don't need to specify a parent,
0361      *               since the widget's parent will be set automatically by KFileWidget.
0362      */
0363     void setCustomWidget(QWidget *widget);
0364 
0365     /**
0366      * Sets a custom widget that should be added below the location and the filter
0367      * editors.
0368      * @param text     Label of the custom widget, which is displayed below the labels
0369      *                 "Location:" and "Filter:".
0370      * @param widget   Any kind of widget, but preferable a combo box or a line editor
0371      *                 to be compliant with the location and filter layout.
0372      *                 When creating this widget, you don't need to specify a parent,
0373      *                 since the widget's parent will be set automatically by KFileWidget.
0374      */
0375     void setCustomWidget(const QString &text, QWidget *widget);
0376 
0377     /**
0378      * Sets whether the user should be asked for confirmation
0379      * when an overwrite might occur.
0380      *
0381      * @param enable Set this to true to enable checking.
0382      */
0383     void setConfirmOverwrite(bool enable);
0384 
0385     /**
0386      * Forces the inline previews to be shown or hidden, depending on @p show.
0387      *
0388      * @param show Whether to show inline previews or not.
0389      */
0390     void setInlinePreviewShown(bool show);
0391 
0392     /**
0393      * Provides a size hint, useful for dialogs that embed the widget.
0394      *
0395      * @return a QSize, calculated to be optimal for a dialog.
0396      * @since 5.0
0397      */
0398     QSize dialogSizeHint() const;
0399 
0400     /**
0401      * Sets how the view should be displayed.
0402      *
0403      * @see KFile::FileView
0404      * @since 5.0
0405      */
0406     void setViewMode(KFile::FileView mode);
0407 
0408     /**
0409      * Reimplemented
0410      */
0411     QSize sizeHint() const override;
0412 
0413     /**
0414      * Set the URL schemes that the file widget should allow navigating to.
0415      *
0416      * If the returned list is empty, all schemes are supported.
0417      *
0418      * @sa QFileDialog::setSupportedSchemes
0419      * @since 5.43
0420      */
0421     void setSupportedSchemes(const QStringList &schemes);
0422 
0423     /**
0424      * Returns the URL schemes that the file widget should allow navigating to.
0425      *
0426      * If the returned list is empty, all schemes are supported. Examples for
0427      * schemes are @c "file" or @c "ftp".
0428      *
0429      * @sa QFileDialog::supportedSchemes
0430      * @since 5.43
0431      */
0432     QStringList supportedSchemes() const;
0433 
0434 public Q_SLOTS:
0435     /**
0436      * Called when clicking ok (when this widget is used in KFileDialog)
0437      * Might or might not call accept().
0438      */
0439     void slotOk();
0440     void accept();
0441     void slotCancel();
0442 
0443 protected:
0444     void resizeEvent(QResizeEvent *event) override;
0445     void showEvent(QShowEvent *event) override;
0446     bool eventFilter(QObject *watched, QEvent *event) override;
0447 
0448 Q_SIGNALS:
0449     /**
0450      * Emitted when the user selects a file. It is only emitted in single-
0451      * selection mode. The best way to get notified about selected file(s)
0452      * is to connect to the okClicked() signal inherited from KDialog
0453      * and call selectedFile(), selectedFiles(),
0454      * selectedUrl() or selectedUrls().
0455      *
0456      * \since 4.4
0457      */
0458     void fileSelected(const QUrl &);
0459 
0460     /**
0461      * Emitted when the user highlights a file.
0462      * \since 4.4
0463      */
0464     void fileHighlighted(const QUrl &);
0465 
0466     /**
0467      * Emitted when the user highlights one or more files in multiselection mode.
0468      *
0469      * Note: fileHighlighted() or fileSelected() are @em not
0470      * emitted in multiselection mode. You may use selectedItems() to
0471      * ask for the current highlighted items.
0472      * @see fileSelected
0473      */
0474     void selectionChanged();
0475 
0476     /**
0477      * Emitted when the filter changed, i.e.\ the user entered an own filter
0478      * or chose one of the predefined set via setFilter().
0479      *
0480      * @param filter contains the new filter (only the extension part,
0481      * not the explanation), i.e. "*.cpp" or "*.cpp *.cc".
0482      *
0483      * @see setFilter()
0484      * @see currentFilter()
0485      *
0486      * @since 6.0
0487      */
0488     void filterChanged(const KFileFilter &filter);
0489 
0490     /**
0491      * Emitted by slotOk() (directly or asynchronously) once everything has
0492      * been done. Should be used by the caller to call accept().
0493      */
0494     void accepted();
0495 
0496 public:
0497     /**
0498      * @returns the KDirOperator used to navigate the filesystem
0499      */
0500     KDirOperator *dirOperator();
0501 
0502     /**
0503      * reads the configuration for this widget from the given config group
0504      * @param group the KConfigGroup to read from
0505      */
0506     void readConfig(KConfigGroup &group);
0507 
0508 private:
0509     friend class KFileWidgetPrivate;
0510     std::unique_ptr<KFileWidgetPrivate> const d;
0511 };
0512 
0513 #endif