File indexing completed on 2024-12-01 03:40:53
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2007 Kevin Ottens <ervin@kde.org> 0004 SPDX-FileCopyrightText: 2007 David Faure <faure@kde.org> 0005 SPDX-FileCopyrightText: 2023 Harald Sitter <sitter@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only 0008 */ 0009 0010 #ifndef KFILEPLACESMODEL_H 0011 #define KFILEPLACESMODEL_H 0012 0013 #include "kiofilewidgets_export.h" 0014 0015 #include <KBookmark> 0016 #include <QAbstractItemModel> 0017 #include <QUrl> 0018 0019 #include <solid/device.h> 0020 #include <solid/solidnamespace.h> 0021 0022 #include <memory> 0023 0024 class KFilePlacesModelPrivate; 0025 class KBookmarkManager; 0026 0027 class QMimeData; 0028 class QAction; 0029 0030 /** 0031 * @class KFilePlacesModel kfileplacesmodel.h <KFilePlacesModel> 0032 * 0033 * This class is a list view model. Each entry represents a "place" 0034 * where user can access files. Only relevant when 0035 * used with QListView or QTableView. 0036 * @note This class is since 6.0 re-entrant 0037 */ 0038 class KIOFILEWIDGETS_EXPORT KFilePlacesModel : public QAbstractItemModel 0039 { 0040 Q_OBJECT 0041 0042 Q_PROPERTY(QStringList supportedSchemes READ supportedSchemes WRITE setSupportedSchemes NOTIFY supportedSchemesChanged) 0043 0044 public: 0045 // Note: run printf "0x%08X\n" $(($RANDOM*$RANDOM)) 0046 // to define additional roles. 0047 enum AdditionalRoles { 0048 /** roleName is "url". @see url() */ 0049 UrlRole = 0x069CD12B, 0050 0051 /** roleName is "isHidden". @see isHidden() */ 0052 HiddenRole = 0x0741CAAC, 0053 0054 /** roleName is "isSetupNeeded". @see setupNeeded() */ 0055 SetupNeededRole = 0x059A935D, 0056 0057 /** 0058 * Whether the place is a fixed device (neither hotpluggable nor removable). 0059 * roleName is "isFixedDevice". 0060 */ 0061 FixedDeviceRole = 0x332896C1, 0062 0063 /** 0064 * Whether the place should have its free space displayed in a capacity bar. 0065 * roleName is "isCapacityBarRecommended". 0066 */ 0067 CapacityBarRecommendedRole = 0x1548C5C4, 0068 0069 /** 0070 * The name of the group, for example "Remote" or "Devices". roleName is "group". 0071 * @since 5.40 0072 */ 0073 GroupRole = 0x0a5b64ee, 0074 0075 /** 0076 * roleName is "iconName". 0077 * @see icon() 0078 * @since 5.41 0079 */ 0080 IconNameRole = 0x00a45c00, 0081 0082 /** roleName is "isGroupHidden". 0083 * @see isGroupHidden() 0084 * @since 5.42 0085 */ 0086 GroupHiddenRole = 0x21a4b936, 0087 0088 /** roleName is "isTeardownAllowed". 0089 * @see isTeardownAllowed(). 0090 * @since 5.91 0091 */ 0092 TeardownAllowedRole = 0x02533364, 0093 0094 /** roleName is "isEjectAllowed". 0095 * @since 5.94. 0096 */ 0097 EjectAllowedRole = 0x0A16AC5B, 0098 0099 /** 0100 * roleName is "isTeardownOverlayRecommended". 0101 * @see isTeardownOverlayRecommended() 0102 * @since 5.95 0103 */ 0104 TeardownOverlayRecommendedRole = 0x032EDCCE, 0105 0106 /** 0107 * roleName is "deviceAccessibility". 0108 * @see deviceAccessibility() 0109 * @since 5.99 0110 */ 0111 DeviceAccessibilityRole = 0x023FFD93, 0112 }; 0113 0114 /** 0115 * Describes the available group types used in this model. 0116 * @since 5.42 0117 */ 0118 enum GroupType { 0119 PlacesType, ///< "Places" section 0120 RemoteType, ///< "Remote" section 0121 RecentlySavedType, ///< "Recent" section 0122 SearchForType, ///< "Search for" section 0123 DevicesType, ///< "Devices" section 0124 RemovableDevicesType, ///< "Removable Devices" section 0125 UnknownType, ///< Unknown GroupType 0126 TagsType, ///< "Tags" section. @since 5.54 0127 }; 0128 Q_ENUM(GroupType) 0129 0130 enum DeviceAccessibility { SetupNeeded, SetupInProgress, Accessible, TeardownInProgress }; 0131 Q_ENUM(DeviceAccessibility) 0132 0133 explicit KFilePlacesModel(QObject *parent = nullptr); 0134 ~KFilePlacesModel() override; 0135 0136 /** 0137 * @return The URL of the place at index @p index. 0138 */ 0139 Q_INVOKABLE QUrl url(const QModelIndex &index) const; 0140 0141 /** 0142 * @return Whether the place at index @p index needs to be mounted before it can be used. 0143 */ 0144 Q_INVOKABLE bool setupNeeded(const QModelIndex &index) const; 0145 0146 /** 0147 * @return Whether the place is a device that can be unmounted, e.g. it is 0148 * mounted but does not point at system Root or the user's Home directory. 0149 * 0150 * It does not indicate whether the teardown can succeed. 0151 * @since 5.91 0152 */ 0153 Q_INVOKABLE bool isTeardownAllowed(const QModelIndex &index) const; 0154 0155 /** 0156 * @return Whether the place is a device that can be ejected, e.g. it is 0157 * a CD, DVD, etc. 0158 * 0159 * It does not indicate whether the eject can succeed. 0160 * @since 5.94 0161 */ 0162 Q_INVOKABLE bool isEjectAllowed(const QModelIndex &index) const; 0163 0164 /** 0165 * @return Whether showing an inline teardown button is recommended, 0166 * e.g. when it is a removable drive. 0167 * 0168 * @since 5.95 0169 **/ 0170 Q_INVOKABLE bool isTeardownOverlayRecommended(const QModelIndex &index) const; 0171 0172 /** 0173 * @return Whether this device is currently accessible or being (un)mounted. 0174 * 0175 * @since 5.99 0176 */ 0177 Q_INVOKABLE KFilePlacesModel::DeviceAccessibility deviceAccessibility(const QModelIndex &index) const; 0178 0179 /** 0180 * @return The icon of the place at index @p index. 0181 */ 0182 Q_INVOKABLE QIcon icon(const QModelIndex &index) const; 0183 0184 /** 0185 * @return The user-visible text of the place at index @p index. 0186 */ 0187 Q_INVOKABLE QString text(const QModelIndex &index) const; 0188 0189 /** 0190 * @return Whether the place at index @p index is hidden or is inside an hidden group. 0191 */ 0192 Q_INVOKABLE bool isHidden(const QModelIndex &index) const; 0193 0194 /** 0195 * @return Whether the group type @p type is hidden. 0196 * @since 5.42 0197 */ 0198 Q_INVOKABLE bool isGroupHidden(const GroupType type) const; 0199 0200 /** 0201 * @return Whether the group of the place at index @p index is hidden. 0202 * @since 5.42 0203 */ 0204 Q_INVOKABLE bool isGroupHidden(const QModelIndex &index) const; 0205 0206 /** 0207 * @return Whether the place at index @p index is a device handled by Solid. 0208 * @see deviceForIndex() 0209 */ 0210 Q_INVOKABLE bool isDevice(const QModelIndex &index) const; 0211 0212 /** 0213 * @return The solid device of the place at index @p index, if it is a device. Otherwise a default Solid::Device() instance is returned. 0214 * @see isDevice() 0215 */ 0216 Solid::Device deviceForIndex(const QModelIndex &index) const; 0217 0218 /** 0219 * @return The KBookmark instance of the place at index @p index. 0220 * If the index is not valid, a default KBookmark instance is returned. 0221 */ 0222 KBookmark bookmarkForIndex(const QModelIndex &index) const; 0223 0224 /** 0225 * @return The KBookmark instance of the place with url @p searchUrl. 0226 * If the bookmark corresponding to searchUrl is not found, a default KBookmark instance is returned. 0227 * @since 5.63 0228 */ 0229 KBookmark bookmarkForUrl(const QUrl &searchUrl) const; 0230 0231 /** 0232 * @return The group type of the place at index @p index. 0233 * @since 5.42 0234 */ 0235 Q_INVOKABLE GroupType groupType(const QModelIndex &index) const; 0236 0237 /** 0238 * @return The list of model indexes that have @ type as their group type. 0239 * @see groupType() 0240 * @since 5.42 0241 */ 0242 Q_INVOKABLE QModelIndexList groupIndexes(const GroupType type) const; 0243 0244 /** 0245 * @return A QAction with a proper translated label that can be used to trigger the requestTeardown() 0246 * method for the place at index @p index. 0247 * @see requestTeardown() 0248 */ 0249 Q_INVOKABLE QAction *teardownActionForIndex(const QModelIndex &index) const; 0250 0251 /** 0252 * @return A QAction with a proper translated label that can be used to trigger the requestEject() 0253 * method for the place at index @p index. 0254 * @see requestEject() 0255 */ 0256 Q_INVOKABLE QAction *ejectActionForIndex(const QModelIndex &index) const; 0257 0258 /** 0259 * @return A QAction with a proper translated label that can be used to open a partitioning menu for the device. nullptr if not a device. 0260 */ 0261 Q_INVOKABLE QAction *partitionActionForIndex(const QModelIndex &index) const; 0262 0263 /** 0264 * Unmounts the place at index @p index by triggering the teardown functionality of its Solid device. 0265 * @see deviceForIndex() 0266 */ 0267 Q_INVOKABLE void requestTeardown(const QModelIndex &index); 0268 0269 /** 0270 * Ejects the place at index @p index by triggering the eject functionality of its Solid device. 0271 * @see deviceForIndex() 0272 */ 0273 Q_INVOKABLE void requestEject(const QModelIndex &index); 0274 0275 /** 0276 * Mounts the place at index @p index by triggering the setup functionality of its Solid device. 0277 * @see deviceForIndex() 0278 */ 0279 Q_INVOKABLE void requestSetup(const QModelIndex &index); 0280 0281 /** 0282 * Adds a new place to the model. 0283 * @param text The user-visible text for the place 0284 * @param url The URL of the place. It will be stored in its QUrl::FullyEncoded string format. 0285 * @param iconName The icon of the place 0286 * @param appName If set as the value of QCoreApplication::applicationName(), will make the place visible only in this application. 0287 */ 0288 Q_INVOKABLE void addPlace(const QString &text, const QUrl &url, const QString &iconName = QString(), const QString &appName = QString()); 0289 0290 /** 0291 * Adds a new place to the model. 0292 * @param text The user-visible text for the place 0293 * @param url The URL of the place. It will be stored in its QUrl::FullyEncoded string format. 0294 * @param iconName The icon of the place 0295 * @param appName If set as the value of QCoreApplication::applicationName(), will make the place visible only in this application. 0296 * @param after The index after which the new place will be added. 0297 */ 0298 Q_INVOKABLE void addPlace(const QString &text, const QUrl &url, const QString &iconName, const QString &appName, const QModelIndex &after); 0299 0300 /** 0301 * Edits the place with index @p index. 0302 * @param text The new user-visible text for the place 0303 * @param url The new URL of the place 0304 * @param iconName The new icon of the place 0305 * @param appName The new application-local filter for the place (@see addPlace()). 0306 */ 0307 Q_INVOKABLE void 0308 editPlace(const QModelIndex &index, const QString &text, const QUrl &url, const QString &iconName = QString(), const QString &appName = QString()); 0309 0310 /** 0311 * Deletes the place with index @p index from the model. 0312 */ 0313 Q_INVOKABLE void removePlace(const QModelIndex &index) const; 0314 0315 /** 0316 * Changes the visibility of the place with index @p index, but only if the place is not inside an hidden group. 0317 * @param hidden Whether the place should be hidden or visible. 0318 * @see isGroupHidden() 0319 */ 0320 Q_INVOKABLE void setPlaceHidden(const QModelIndex &index, bool hidden); 0321 0322 /** 0323 * Changes the visibility of the group with type @p type. 0324 * @param hidden Whether the group should be hidden or visible. 0325 * @see isGroupHidden() 0326 * @since 5.42 0327 */ 0328 Q_INVOKABLE void setGroupHidden(const GroupType type, bool hidden); 0329 0330 /** 0331 * @brief Move place at @p itemRow to a position before @p row 0332 * @return Whether the place has been moved. 0333 * @since 5.41 0334 */ 0335 Q_INVOKABLE bool movePlace(int itemRow, int row); 0336 0337 /** 0338 * @return The number of hidden places in the model. 0339 * @see isHidden() 0340 */ 0341 Q_INVOKABLE int hiddenCount() const; 0342 0343 /** 0344 * @brief Get a visible data based on Qt role for the given index. 0345 * Return the device information for the give index. 0346 * 0347 * @param index The QModelIndex which contains the row, column to fetch the data. 0348 * @param role The Interview data role(ex: Qt::DisplayRole). 0349 * 0350 * @return the data for the given index and role. 0351 */ 0352 QVariant data(const QModelIndex &index, int role) const override; 0353 0354 /** 0355 * @brief Get the children model index for the given row and column. 0356 */ 0357 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; 0358 0359 /** 0360 * @brief Get the parent QModelIndex for the given model child. 0361 */ 0362 QModelIndex parent(const QModelIndex &child) const override; 0363 0364 /// Reimplemented from QAbstractItemModel. 0365 /// @see AdditionalRoles 0366 QHash<int, QByteArray> roleNames() const override; 0367 0368 /** 0369 * @brief Get the number of rows for a model index. 0370 */ 0371 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0372 0373 /** 0374 * @brief Get the number of columns for a model index. 0375 */ 0376 int columnCount(const QModelIndex &parent = QModelIndex()) const override; 0377 0378 /** 0379 * Returns the closest item for the URL \a url. 0380 * The closest item is defined as item which is equal to 0381 * the URL or at least is a parent URL. If there are more than 0382 * one possible parent URL candidates, the item which covers 0383 * the bigger range of the URL is returned. 0384 * 0385 * Example: the url is '/home/peter/Documents/Music'. 0386 * Available items are: 0387 * - /home/peter 0388 * - /home/peter/Documents 0389 * 0390 * The returned item will the one for '/home/peter/Documents'. 0391 */ 0392 QModelIndex closestItem(const QUrl &url) const; 0393 0394 Qt::DropActions supportedDropActions() const override; 0395 Qt::ItemFlags flags(const QModelIndex &index) const override; 0396 QStringList mimeTypes() const override; 0397 QMimeData *mimeData(const QModelIndexList &indexes) const override; 0398 bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; 0399 0400 /** 0401 * @brief Reload bookmark information 0402 * @since 5.41 0403 */ 0404 Q_INVOKABLE void refresh() const; 0405 0406 /** 0407 * @brief Converts the URL, which contains "virtual" URLs for system-items like 0408 * "timeline:/lastmonth" into a Query-URL "timeline:/2017-10" 0409 * that will be handled by the corresponding KIO worker. 0410 * Virtual URLs for bookmarks are used to be independent from 0411 * internal format changes. 0412 * @param an url 0413 * @return the converted URL, which can be handled by a KIO worker 0414 * @since 5.41 0415 */ 0416 static QUrl convertedUrl(const QUrl &url); 0417 0418 /** 0419 * Set the URL schemes that the file widget should allow navigating to. 0420 * 0421 * If the returned list is empty, all schemes are supported. Examples for 0422 * schemes are @c "file" or @c "ftp". 0423 * 0424 * @sa QFileDialog::setSupportedSchemes 0425 * @since 5.43 0426 */ 0427 void setSupportedSchemes(const QStringList &schemes); 0428 0429 /** 0430 * Returns the URL schemes that the file widget should allow navigating to. 0431 * 0432 * If the returned list is empty, all schemes are supported. 0433 * 0434 * @sa QFileDialog::supportedSchemes 0435 * @since 5.43 0436 */ 0437 QStringList supportedSchemes() const; 0438 0439 Q_SIGNALS: 0440 /** 0441 * @p message An error message explaining what went wrong. 0442 */ 0443 void errorMessage(const QString &message); 0444 0445 /** 0446 * Emitted after the Solid setup ends. 0447 * @param success Whether the Solid setup has been successful. 0448 * @see requestSetup() 0449 */ 0450 void setupDone(const QModelIndex &index, bool success); 0451 0452 /** 0453 * Emitted after the teardown of a device ends. 0454 * 0455 * @note In case of an error, the @p errorMessage signal 0456 * will also be emitted with a message describing the error. 0457 * 0458 * @param error Type of error that occurred, if any. 0459 * @param errorData More information about the error, if any. 0460 * @since 5.100 0461 */ 0462 void teardownDone(const QModelIndex &index, Solid::ErrorType error, const QVariant &errorData); 0463 0464 /** 0465 * Emitted whenever the visibility of the group @p group changes. 0466 * @param hidden The new visibility of the group. 0467 * @see setGroupHidden() 0468 * @since 5.42 0469 */ 0470 void groupHiddenChanged(KFilePlacesModel::GroupType group, bool hidden); 0471 0472 /** 0473 * Called once the model has been reloaded 0474 * 0475 * @since 5.71 0476 */ 0477 void reloaded(); 0478 0479 /** 0480 * Emitted whenever the list of supported schemes has been changed 0481 * 0482 * @since 5.94 0483 */ 0484 void supportedSchemesChanged(); 0485 0486 private: 0487 friend class KFilePlacesModelPrivate; 0488 std::unique_ptr<KFilePlacesModelPrivate> d; 0489 }; 0490 0491 #endif