File indexing completed on 2024-04-28 15:26:46

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 <memory>
0023 
0024 class QUrl;
0025 class QPushButton;
0026 class KActionCollection;
0027 class KToolBar;
0028 class KFileWidgetPrivate;
0029 class KUrlComboBox;
0030 class KFileFilterCombo;
0031 
0032 class KPreviewWidgetBase;
0033 class QMimeType;
0034 class KConfigGroup;
0035 class KJob;
0036 class KFileItem;
0037 class KDirOperator;
0038 
0039 /**
0040  * @class KFileWidget kfilewidget.h <KFileWidget>
0041  *
0042  * File selector widget.
0043  *
0044  * This is the contents of the KDE file dialog, without the actual QDialog around it.
0045  * It can be embedded directly into applications.
0046  */
0047 class KIOFILEWIDGETS_EXPORT KFileWidget : public QWidget
0048 {
0049     Q_OBJECT
0050 public:
0051     /**
0052      * Constructs a file selector widget.
0053      *
0054      * @param startDir This can either be:
0055      *         @li An empty URL (QUrl()) to start in the current working directory,
0056      *             or the last directory where a file has been selected.
0057      *         @li The path or URL of a starting directory.
0058      *         @li An initial file name to select, with the starting directory being
0059      *             the current working directory or the last directory where a file
0060      *             has been selected.
0061      *         @li The path or URL of a file, specifying both the starting directory and
0062      *             an initially selected file name.
0063      *         @li A URL of the form @c kfiledialog:///&lt;keyword&gt; to start in the
0064      *             directory last used by a filedialog in the same application that
0065      *             specified the same keyword.
0066      *         @li A URL of the form @c kfiledialog:///&lt;keyword&gt;/&lt;filename&gt;
0067      *             to start in the directory last used by a filedialog in the same
0068      *             application that specified the same keyword, and to initially
0069      *             select the specified filename.
0070      *         @li Deprecated: A URL of the form @c kfiledialog:///&lt;keyword&gt;?global to start
0071      *             in the directory last used by a filedialog in any application that
0072      *             specified the same keyword.
0073      *         @li Deprecated: A URL of the form @c kfiledialog:///&lt;keyword&gt;/&lt;filename&gt;?global
0074      *             to start in the directory last used by a filedialog in any
0075      *             application that specified the same keyword, and to initially
0076      *             select the specified filename.
0077      *
0078      * @note Since 5.96, the "?global" syntax is deprecated, for lack of usage.
0079      *
0080      * @param parent The parent widget of this widget
0081      *
0082      */
0083     explicit KFileWidget(const QUrl &startDir, QWidget *parent = nullptr);
0084 
0085     /**
0086      * Destructor
0087      */
0088     ~KFileWidget() override;
0089 
0090     /**
0091      * Defines some default behavior of the filedialog.
0092      * E.g. in mode @p Opening and @p Saving, the selected files/urls will
0093      * be added to the "recent documents" list. The Saving mode also implies
0094      * setKeepLocation() being set.
0095      *
0096      * @p Other means that no default actions are performed.
0097      *
0098      * @see setOperationMode
0099      * @see operationMode
0100      */
0101     enum OperationMode { Other = 0, Opening, Saving };
0102 
0103     /**
0104      * @returns The selected fully qualified filename.
0105      */
0106     QUrl selectedUrl() const;
0107 
0108     /**
0109      * @returns The list of selected URLs.
0110      */
0111     QList<QUrl> selectedUrls() const;
0112 
0113     /**
0114      * @returns the currently shown directory.
0115      */
0116     QUrl baseUrl() const;
0117 
0118     /**
0119      * Returns the full path of the selected file in the local filesystem.
0120      * (Local files only)
0121      */
0122     QString selectedFile() const;
0123 
0124     /**
0125      * Returns a list of all selected local files.
0126      */
0127     QStringList selectedFiles() const;
0128 
0129     /**
0130      * Sets the directory to view.
0131      *
0132      * @param url URL to show.
0133      * @param clearforward Indicates whether the forward queue
0134      * should be cleared.
0135      */
0136     void setUrl(const QUrl &url, bool clearforward = true);
0137 
0138 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(5, 33)
0139     /**
0140      * Sets the file to preselect to @p pathOrUrl
0141      *
0142      * This method handles absolute paths (on Unix, but probably not correctly on Windows)
0143      * and absolute URLs as strings (but for those you should use setSelectedUrl instead).
0144      *
0145      * This method does not work with relative paths (filenames)
0146      * (it would misinterpret a ':' or a '#' in the filename).
0147      *
0148      * @deprecated since 5.33, use setSelectedUrl instead, after ensuring that
0149      * construct the QUrl correctly (e.g. use fromLocalFile for local paths).
0150      */
0151     KIOFILEWIDGETS_DEPRECATED_VERSION(5, 33, "Use KFileWidget::setSelectedUrl(const QUrl &)")
0152     void setSelection(const QString &pathOrUrl);
0153 #endif
0154 
0155     /**
0156      * Sets the URL to preselect to @p url
0157      *
0158      * This method handles absolute URLs (remember to use fromLocalFile for local paths).
0159      * It also handles relative URLs, which you should construct like this:
0160      * QUrl relativeUrl; relativeUrl.setPath(fileName);
0161      *
0162      * @since 5.33
0163      */
0164     void setSelectedUrl(const QUrl &url);
0165 
0166     /**
0167      * Sets a list of URLs as preselected
0168      *
0169      * @see setSelectedUrl
0170      * @since 5.75
0171      */
0172     void setSelectedUrls(const QList<QUrl> &urls);
0173 
0174     /**
0175      * Sets the operational mode of the filedialog to @p Saving, @p Opening
0176      * or @p Other. This will set some flags that are specific to loading
0177      * or saving files. E.g. setKeepLocation() makes mostly sense for
0178      * a save-as dialog. So setOperationMode( KFileWidget::Saving ); sets
0179      * setKeepLocation for example.
0180      *
0181      * The mode @p Saving, together with a default filter set via
0182      * setMimeFilter() will make the filter combobox read-only.
0183      *
0184      * The default mode is @p Opening.
0185      *
0186      * Call this method right after instantiating KFileWidget.
0187      *
0188      * @see operationMode
0189      * @see KFileWidget::OperationMode
0190      */
0191     void setOperationMode(OperationMode);
0192 
0193     /**
0194      * @returns the current operation mode, Opening, Saving or Other. Default
0195      * is Other.
0196      *
0197      * @see operationMode
0198      * @see KFileWidget::OperationMode
0199      */
0200     OperationMode operationMode() const;
0201 
0202     /**
0203      * Sets whether the filename/url should be kept when changing directories.
0204      * This is for example useful when having a predefined filename where
0205      * the full path for that file is searched.
0206      *
0207      * This is implicitly set when operationMode() is KFileWidget::Saving
0208      *
0209      * getSaveFileName() and getSaveUrl() set this to true by default, so that
0210      * you can type in the filename and change the directory without having
0211      * to type the name again.
0212      */
0213     void setKeepLocation(bool keep);
0214 
0215     /**
0216      * @returns whether the contents of the location edit are kept when
0217      * changing directories.
0218      */
0219     bool keepsLocation() const;
0220 
0221     /**
0222      * Sets the filter to be used to @p filter.
0223      *
0224      * You can set more
0225      * filters for the user to select separated by '\n'. Every
0226      * filter entry is defined through namefilter|text to display.
0227      * If no | is found in the expression, just the namefilter is
0228      * shown. Examples:
0229      *
0230      * \code
0231      * kfile->setFilter("*.cpp|C++ Source Files\n*.h|Header files");
0232      * kfile->setFilter("*.cpp");
0233      * kfile->setFilter("*.cpp|Sources (*.cpp)");
0234      * kfile->setFilter("*.cpp|" + i18n("Sources (*.cpp)"));
0235      * kfile->setFilter("*.cpp *.cc *.C|C++ Source Files\n*.h *.H|Header files");
0236      * \endcode
0237      *
0238      * Note: The text to display is not parsed in any way. So, if you
0239      * want to show the suffix to select by a specific filter, you must
0240      * repeat it.
0241      *
0242      * If the filter contains an unescaped '/', a MIME type filter is assumed.
0243      * If you would like a '/' visible in your filter it can be escaped with
0244      * a '\'. You can specify multiple MIME types like this (separated with
0245      * space):
0246      *
0247      * \code
0248      * kfile->setFilter( "image/png text/html text/plain" );
0249      * kfile->setFilter( "*.cue|CUE\\/BIN Files (*.cue)" );
0250      * \endcode
0251      *
0252      * @see filterChanged
0253      * @see setMimeFilter
0254      */
0255     void setFilter(const QString &filter);
0256 
0257     /**
0258      * Returns the current filter as entered by the user or one of the
0259      * predefined set via setFilter().
0260      *
0261      * @see setFilter()
0262      * @see filterChanged()
0263      */
0264     QString currentFilter() const;
0265 
0266     /**
0267      * Returns the MIME type for the desired output format.
0268      *
0269      * This is only valid if setFilterMimeType() has been called
0270      * previously.
0271      *
0272      * @see setFilterMimeType()
0273      */
0274     QMimeType currentFilterMimeType();
0275 
0276     /**
0277      * Sets the filter up to specify the output type.
0278      *
0279      * @param types a list of MIME types that can be used as output format
0280      * @param defaultType the default MIME type to use as output format, if any.
0281      * If @p defaultType is set, it will be set as the current item.
0282      * Otherwise, a first item showing all the MIME types will be created.
0283      * Typically, @p defaultType should be empty for loading and set for saving.
0284      *
0285      * Do not use in conjunction with setFilter()
0286      */
0287     void setMimeFilter(const QStringList &types, const QString &defaultType = QString());
0288 
0289     /**
0290      * The MIME type for the desired output format.
0291      *
0292      * This is only valid if setMimeFilter() has been called
0293      * previously.
0294      *
0295      * @see setMimeFilter()
0296      */
0297     QString currentMimeFilter() const;
0298 
0299     /**
0300      *  Clears any MIME type or name filter. Does not reload the directory.
0301      */
0302     void clearFilter();
0303 
0304     /**
0305      * Adds a preview widget and enters the preview mode.
0306      *
0307      * In this mode the dialog is split and the right part contains your
0308      * preview widget.
0309      *
0310      * Ownership is transferred to KFileWidget. You need to create the
0311      * preview-widget with "new", i.e. on the heap.
0312      *
0313      * @param w The widget to be used for the preview.
0314      */
0315     void setPreviewWidget(KPreviewWidgetBase *w);
0316 
0317     /**
0318      * Sets the mode of the dialog.
0319      *
0320      * The mode is defined as (in kfile.h):
0321      * \code
0322      *    enum Mode {
0323      *         File         = 1,
0324      *         Directory    = 2,
0325      *         Files        = 4,
0326      *         ExistingOnly = 8,
0327      *         LocalOnly    = 16,
0328      *    };
0329      * \endcode
0330      * You can OR the values, e.g.
0331      * \code
0332      * KFile::Modes mode = KFile::Files |
0333      *                     KFile::ExistingOnly |
0334      *                     KFile::LocalOnly );
0335      * setMode( mode );
0336      * \endcode
0337      */
0338     void setMode(KFile::Modes m);
0339 
0340     /**
0341      * Returns the mode of the filedialog.
0342      * @see setMode()
0343      */
0344     KFile::Modes mode() const;
0345 
0346     /**
0347      * Sets the text to be displayed in front of the selection.
0348      *
0349      * The default is "Location".
0350      * Most useful if you want to make clear what
0351      * the location is used for.
0352      */
0353     void setLocationLabel(const QString &text);
0354 
0355 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(5, 66)
0356     /**
0357      * Returns a pointer to the toolbar.
0358      * @deprecated since 5.66 due to no known users and leaking KXMLGui into the API.
0359      *
0360      */
0361     KIOFILEWIDGETS_DEPRECATED_VERSION(5, 66, "No known user")
0362     KToolBar *toolBar() const;
0363 #endif
0364 
0365     /**
0366      * @returns a pointer to the OK-Button in the filedialog.
0367      * Note that the button is hidden and unconnected when using KFileWidget alone;
0368      * KFileDialog shows it and connects to it.
0369      */
0370     QPushButton *okButton() const;
0371 
0372     /**
0373      * @returns a pointer to the Cancel-Button in the filedialog.
0374      * Note that the button is hidden and unconnected when using KFileWidget alone;
0375      * KFileDialog shows it and connects to it.
0376      */
0377     QPushButton *cancelButton() const;
0378 
0379     /**
0380      * @returns the combobox used to type the filename or full location of the file.
0381      */
0382     KUrlComboBox *locationEdit() const;
0383 
0384     /**
0385      * @returns the combobox that contains the filters
0386      */
0387     KFileFilterCombo *filterWidget() const;
0388 
0389 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(5, 100)
0390     /**
0391      * @returns a pointer to the action collection, holding all the used
0392      * KActions.
0393      * @deprecated since 5.100, no known users.
0394      */
0395     KIOFILEWIDGETS_DEPRECATED_VERSION(5, 100, "No known users")
0396     KActionCollection *actionCollection() const;
0397 #endif
0398 
0399     /**
0400      * This method implements the logic to determine the user's default directory
0401      * to be listed. E.g. the documents directory, home directory or a recently
0402      * used directory.
0403      * @param startDir A URL specifying the initial directory, or using the
0404      *                 @c kfiledialog:/// syntax to specify a last used
0405      *                 directory.  If this URL specifies a file name, it is
0406      *                 ignored.  Refer to the KFileWidget::KFileWidget()
0407      *                 documentation for the @c kfiledialog:/// URL syntax.
0408      * @param recentDirClass If the @c kfiledialog:/// syntax is used, this
0409      *        will return the string to be passed to KRecentDirs::dir() and
0410      *        KRecentDirs::add().
0411      * @return The URL that should be listed by default (e.g. by KFileDialog or
0412      *         KDirSelectDialog).
0413      * @see KFileWidget::KFileWidget()
0414      */
0415     static QUrl getStartUrl(const QUrl &startDir, QString &recentDirClass);
0416 
0417     /**
0418      * Similar to getStartUrl(const QUrl& startDir,QString& recentDirClass),
0419      * but allows both the recent start directory keyword and a suggested file name
0420      * to be returned.
0421      * @param startDir A URL specifying the initial directory and/or filename,
0422      *                 or using the @c kfiledialog:/// syntax to specify a
0423      *                 last used location.
0424      *                 Refer to the KFileWidget::KFileWidget()
0425      *                 documentation for the @c kfiledialog:/// URL syntax.
0426      * @param recentDirClass If the @c kfiledialog:/// syntax is used, this
0427      *        will return the string to be passed to KRecentDirs::dir() and
0428      *        KRecentDirs::add().
0429      * @param fileName The suggested file name, if specified as part of the
0430      *        @p StartDir URL.
0431      * @return The URL that should be listed by default (e.g. by KFileDialog or
0432      *         KDirSelectDialog).
0433      *
0434      * @see KFileWidget::KFileWidget()
0435      * @since 4.3
0436      */
0437     static QUrl getStartUrl(const QUrl &startDir, QString &recentDirClass, QString &fileName);
0438 
0439     /**
0440      * @internal
0441      * Used by KDirSelectDialog to share the dialog's start directory.
0442      */
0443     static void setStartDir(const QUrl &directory);
0444 
0445     /**
0446      * Set a custom widget that should be added to the file dialog.
0447      * @param widget A widget, or a widget of widgets, for displaying custom
0448      *               data in the file widget. This can be used, for example, to
0449      *               display a check box with the title "Open as read-only".
0450      *               When creating this widget, you don't need to specify a parent,
0451      *               since the widget's parent will be set automatically by KFileWidget.
0452      */
0453     void setCustomWidget(QWidget *widget);
0454 
0455     /**
0456      * Sets a custom widget that should be added below the location and the filter
0457      * editors.
0458      * @param text     Label of the custom widget, which is displayed below the labels
0459      *                 "Location:" and "Filter:".
0460      * @param widget   Any kind of widget, but preferable a combo box or a line editor
0461      *                 to be compliant with the location and filter layout.
0462      *                 When creating this widget, you don't need to specify a parent,
0463      *                 since the widget's parent will be set automatically by KFileWidget.
0464      */
0465     void setCustomWidget(const QString &text, QWidget *widget);
0466 
0467     /**
0468      * Sets whether the user should be asked for confirmation
0469      * when an overwrite might occur.
0470      *
0471      * @param enable Set this to true to enable checking.
0472      * @since 4.2
0473      */
0474     void setConfirmOverwrite(bool enable);
0475 
0476     /**
0477      * Forces the inline previews to be shown or hidden, depending on @p show.
0478      *
0479      * @param show Whether to show inline previews or not.
0480      * @since 4.2
0481      */
0482     void setInlinePreviewShown(bool show);
0483 
0484     /**
0485      * Provides a size hint, useful for dialogs that embed the widget.
0486      *
0487      * @return a QSize, calculated to be optimal for a dialog.
0488      * @since 5.0
0489      */
0490     QSize dialogSizeHint() const;
0491 
0492     /**
0493      * Sets how the view should be displayed.
0494      *
0495      * @see KFile::FileView
0496      * @since 5.0
0497      */
0498     void setViewMode(KFile::FileView mode);
0499 
0500     /**
0501      * Reimplemented
0502      */
0503     QSize sizeHint() const override;
0504 
0505     /**
0506      * Set the URL schemes that the file widget should allow navigating to.
0507      *
0508      * If the returned list is empty, all schemes are supported.
0509      *
0510      * @sa QFileDialog::setSupportedSchemes
0511      * @since 5.43
0512      */
0513     void setSupportedSchemes(const QStringList &schemes);
0514 
0515     /**
0516      * Returns the URL schemes that the file widget should allow navigating to.
0517      *
0518      * If the returned list is empty, all schemes are supported. Examples for
0519      * schemes are @c "file" or @c "ftp".
0520      *
0521      * @sa QFileDialog::supportedSchemes
0522      * @since 5.43
0523      */
0524     QStringList supportedSchemes() const;
0525 
0526 public Q_SLOTS:
0527     /**
0528      * Called when clicking ok (when this widget is used in KFileDialog)
0529      * Might or might not call accept().
0530      */
0531     void slotOk();
0532     void accept();
0533     void slotCancel();
0534 
0535 protected:
0536     void resizeEvent(QResizeEvent *event) override;
0537     void showEvent(QShowEvent *event) override;
0538     bool eventFilter(QObject *watched, QEvent *event) override;
0539 
0540 Q_SIGNALS:
0541     /**
0542      * Emitted when the user selects a file. It is only emitted in single-
0543      * selection mode. The best way to get notified about selected file(s)
0544      * is to connect to the okClicked() signal inherited from KDialog
0545      * and call selectedFile(), selectedFiles(),
0546      * selectedUrl() or selectedUrls().
0547      *
0548      * \since 4.4
0549      */
0550     void fileSelected(const QUrl &);
0551 
0552     /**
0553      * Emitted when the user highlights a file.
0554      * \since 4.4
0555      */
0556     void fileHighlighted(const QUrl &);
0557 
0558     /**
0559      * Emitted when the user highlights one or more files in multiselection mode.
0560      *
0561      * Note: fileHighlighted() or fileSelected() are @em not
0562      * emitted in multiselection mode. You may use selectedItems() to
0563      * ask for the current highlighted items.
0564      * @see fileSelected
0565      */
0566     void selectionChanged();
0567 
0568     /**
0569      * Emitted when the filter changed, i.e.\ the user entered an own filter
0570      * or chose one of the predefined set via setFilter().
0571      *
0572      * @param filter contains the new filter (only the extension part,
0573      * not the explanation), i.e. "*.cpp" or "*.cpp *.cc".
0574      *
0575      * @see setFilter()
0576      * @see currentFilter()
0577      */
0578     void filterChanged(const QString &filter);
0579 
0580     /**
0581      * Emitted by slotOk() (directly or asynchronously) once everything has
0582      * been done. Should be used by the caller to call accept().
0583      */
0584     void accepted();
0585 
0586 public:
0587     /**
0588      * @returns the KDirOperator used to navigate the filesystem
0589      * @since 4.3
0590      */
0591     KDirOperator *dirOperator();
0592 
0593     /**
0594      * reads the configuration for this widget from the given config group
0595      * @param group the KConfigGroup to read from
0596      * @since 4.4
0597      */
0598     void readConfig(KConfigGroup &group);
0599 
0600 private:
0601     friend class KFileWidgetPrivate;
0602     std::unique_ptr<KFileWidgetPrivate> const d;
0603 };
0604 
0605 #endif