File indexing completed on 2024-05-26 16:01:01
0001 /* 0002 * <one line to give the program's name and a brief idea of what it does.> 0003 * Copyright (C) 2018 Camilo Higuita <email> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 #pragma once 0020 0021 #include <QObject> 0022 #include <QImage> 0023 0024 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0025 #include <MauiKit3/Core/mauilist.h> 0026 #else 0027 #include <MauiKit4/Core/mauilist.h> 0028 #endif 0029 0030 #include "filebrowsing_export.h" 0031 0032 #include "fmstatic.h" 0033 0034 class FM; 0035 0036 /** 0037 * @brief Represents the status of a directory listing, be it non existence location, loading or empty. 0038 * 0039 * The status object is divided into different properties for convenience, such as error label, message, icon, code, etc. 0040 */ 0041 struct PathStatus 0042 { 0043 Q_GADGET 0044 0045 /** 0046 * The status code. More details are exposed with the other properties. 0047 */ 0048 Q_PROPERTY(PathStatus::STATUS_CODE code MEMBER m_code) 0049 0050 /** 0051 * The status title. 0052 */ 0053 Q_PROPERTY(QString title MEMBER m_title) 0054 0055 /** 0056 * The message details of the status. 0057 */ 0058 Q_PROPERTY(QString message MEMBER m_message) 0059 0060 /** 0061 * An associated icon name for the status. 0062 */ 0063 Q_PROPERTY(QString icon MEMBER m_icon) 0064 0065 /** 0066 * Whether the location is empty and there is nothing for listing. 0067 */ 0068 Q_PROPERTY(bool empty MEMBER m_empty) 0069 0070 /** 0071 * Whether the location can be accessed and exists. 0072 */ 0073 Q_PROPERTY(bool exists MEMBER m_exists) 0074 0075 public: 0076 /** 0077 * @brief The different status that can occur. 0078 */ 0079 enum STATUS_CODE : int 0080 { 0081 /** 0082 * The content is still loading its contents 0083 */ 0084 LOADING, 0085 0086 /** 0087 * The listing of the contents has failed. For knowing the reason check the other properties, such as `title`, `exists`, etc. 0088 */ 0089 ERROR, 0090 0091 /** 0092 * The listing has finished successfully 0093 */ 0094 READY 0095 0096 }; Q_ENUM(STATUS_CODE) 0097 0098 STATUS_CODE m_code; 0099 QString m_title; 0100 QString m_message; 0101 QString m_icon; 0102 bool m_empty = false; 0103 bool m_exists = false; 0104 }; 0105 Q_DECLARE_METATYPE(PathStatus) 0106 0107 /** 0108 * @private 0109 */ 0110 struct NavHistory { 0111 void appendPath(const QUrl &path) 0112 { 0113 this->prev_history.append(path); 0114 } 0115 0116 QUrl getPosteriorPath() 0117 { 0118 if (this->post_history.isEmpty()) 0119 return QUrl(); 0120 0121 return this->post_history.takeLast(); 0122 } 0123 0124 QUrl getPreviousPath() 0125 { 0126 if (this->prev_history.isEmpty()) 0127 return QUrl(); 0128 0129 if (this->prev_history.length() < 2) 0130 return this->prev_history.at(0); 0131 0132 this->post_history.append(this->prev_history.takeLast()); 0133 return this->prev_history.takeLast(); 0134 } 0135 0136 private: 0137 QVector<QUrl> prev_history; 0138 QVector<QUrl> post_history; 0139 }; 0140 0141 /** 0142 * @brief The FMList class 0143 * Model for listing the file system files and directories and perform relevant actions upon it 0144 */ 0145 class FILEBROWSING_EXPORT FMList : public MauiList 0146 { 0147 Q_OBJECT 0148 Q_DISABLE_COPY(FMList) 0149 0150 // writable 0151 0152 /** 0153 * Whether to auto load the content entries when the path property is modified. Otherwise explicitly call the load method. 0154 * @see search 0155 * @see fill 0156 */ 0157 Q_PROPERTY(bool autoLoad READ getAutoLoad WRITE setAutoLoad NOTIFY autoLoadChanged) 0158 0159 /** 0160 * The URL to location path to proceed listing all of its file entries. 0161 * There is support for multiple type of location depending on the scheme, for example local file system uses `file://`, while you can browser networks using `ftp://` or `fish://`. Support for those locations depends on KIO and its slaves - to know more about it read the KIO slaves documentation. 0162 */ 0163 Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged) 0164 0165 /** 0166 * Whether to list the hidden entries. 0167 * By default this is set to `false`. 0168 */ 0169 Q_PROPERTY(bool hidden READ getHidden WRITE setHidden NOTIFY hiddenChanged) 0170 0171 /** 0172 * Whether only directories should be listed. 0173 * By default this is set to `false`. 0174 */ 0175 Q_PROPERTY(bool onlyDirs READ getOnlyDirs WRITE setOnlyDirs NOTIFY onlyDirsChanged) 0176 0177 /** 0178 * Whether the folders should be sorted first and then the files. 0179 * By default this is set to `true`. 0180 */ 0181 Q_PROPERTY(bool foldersFirst READ getFoldersFirst WRITE setFoldersFirst NOTIFY foldersFirstChanged) 0182 0183 /** 0184 * When the location if a remote cloud directory, this allows to define the depth of the levels for listing the contents. 0185 * By default this is set to `1`, which will only lists the entries in the current location, a bigger depth will start listing sub-directories too. 0186 * @deprecated 0187 */ 0188 Q_PROPERTY(int cloudDepth READ getCloudDepth WRITE setCloudDepth NOTIFY cloudDepthChanged) 0189 0190 /** 0191 * The list of string values to filter the listing. For example to only list PNG and JPG images: `filters: ["*.png", "*.jpg"]`. 0192 * To reset or clear the filters you can set the property to `undefined` 0193 */ 0194 Q_PROPERTY(QStringList filters READ getFilters WRITE setFilters NOTIFY filtersChanged RESET resetFilters) 0195 0196 /** 0197 * A convenient way to filter the location contents by a file type (mimetype). 0198 * By default this is set to `FILTER_TYPE::NONE`. 0199 */ 0200 Q_PROPERTY(FMList::FILTER filterType READ getFilterType WRITE setFilterType NOTIFY filterTypeChanged RESET resetFilterType) 0201 0202 /** 0203 * The sorting value. 0204 * By default this is set to `SORTBY::MODIFIED`. 0205 */ 0206 Q_PROPERTY(FMList::SORTBY sortBy READ getSortBy WRITE setSortBy NOTIFY sortByChanged) 0207 0208 /** 0209 * Whether destructive actions or modifications can be done to the current location contents, such as deleting, renaming, pasting, adding, etc. 0210 * This only protects the location contents if using this API action methods. 0211 */ 0212 Q_PROPERTY(bool readOnly READ readOnly WRITE setReadOnly NOTIFY readOnlyChanged) 0213 0214 // readonly 0215 /** 0216 * The title name of the current location. 0217 */ 0218 Q_PROPERTY(QString pathName READ getPathName NOTIFY pathNameChanged FINAL) 0219 0220 /** 0221 * The known type of the current location. 0222 */ 0223 Q_PROPERTY(FMList::PATHTYPE pathType READ getPathType NOTIFY pathTypeChanged FINAL) 0224 0225 /** 0226 * The current status of the location contents listing. This is a group of properties. 0227 */ 0228 Q_PROPERTY(PathStatus status READ getStatus NOTIFY statusChanged) 0229 0230 /** 0231 * The location of the parent directory of this current location. 0232 */ 0233 Q_PROPERTY(QUrl parentPath READ getParentPath NOTIFY pathChanged) 0234 0235 public: 0236 /** 0237 * @brief The possible values to sort the location contents 0238 */ 0239 enum SORTBY : uint_fast8_t { 0240 /** 0241 * The size of the file entry 0242 */ 0243 SIZE = FMH::MODEL_KEY::SIZE, 0244 0245 /** 0246 * The last modified date of the entry file 0247 */ 0248 MODIFIED = FMH::MODEL_KEY::MODIFIED, 0249 0250 /** 0251 * The creation date of the file entry 0252 */ 0253 DATE = FMH::MODEL_KEY::DATE, 0254 0255 /** 0256 * The name or title of the file entry 0257 */ 0258 LABEL = FMH::MODEL_KEY::LABEL, 0259 0260 /** 0261 * The file type of the entry. Deduced from its file suffix name 0262 */ 0263 MIME = FMH::MODEL_KEY::MIME, 0264 0265 /** 0266 * The date when the file entry was added 0267 */ 0268 ADDDATE = FMH::MODEL_KEY::ADDDATE 0269 }; 0270 Q_ENUM(SORTBY) 0271 0272 /** 0273 * @brief The possible values to filter the a location content by a mime-type. 0274 */ 0275 enum FILTER : uint_fast8_t { 0276 /** 0277 * Audio file types. Such as MP3, WAV, FLAC, MP4, etc. 0278 */ 0279 AUDIO = FMStatic::FILTER_TYPE::AUDIO, 0280 0281 /** 0282 * Video file types 0283 */ 0284 VIDEO = FMStatic::FILTER_TYPE::VIDEO, 0285 0286 /** 0287 * Plain text file types 0288 */ 0289 TEXT = FMStatic::FILTER_TYPE::TEXT, 0290 0291 /** 0292 * Image file types 0293 */ 0294 IMAGE = FMStatic::FILTER_TYPE::IMAGE, 0295 0296 /** 0297 * PDF, EBooks and comic books file types 0298 */ 0299 DOCUMENT = FMStatic::FILTER_TYPE::DOCUMENT, 0300 0301 /** 0302 * Compressed archives 0303 */ 0304 COMPRESSED = FMStatic::FILTER_TYPE::COMPRESSED, 0305 0306 /** 0307 * Font file types 0308 */ 0309 FONT = FMStatic::FILTER_TYPE::FONT, 0310 0311 /** 0312 * Any file type 0313 */ 0314 NONE = FMStatic::FILTER_TYPE::NONE 0315 }; 0316 Q_ENUM(FILTER) 0317 0318 /** 0319 * @brief The different location or places types. 0320 */ 0321 enum PATHTYPE : uint_fast8_t { 0322 PLACES_PATH = FMStatic::PATHTYPE_KEY::PLACES_PATH, 0323 FISH_PATH = FMStatic::PATHTYPE_KEY::FISH_PATH, 0324 MTP_PATH = FMStatic::PATHTYPE_KEY::MTP_PATH, 0325 REMOTE_PATH = FMStatic::PATHTYPE_KEY::REMOTE_PATH, 0326 DRIVES_PATH = FMStatic::PATHTYPE_KEY::DRIVES_PATH, 0327 REMOVABLE_PATH = FMStatic::PATHTYPE_KEY::REMOVABLE_PATH, 0328 TAGS_PATH = FMStatic::PATHTYPE_KEY::TAGS_PATH, 0329 BOOKMARKS_PATH = FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH, 0330 APPS_PATH = FMStatic::PATHTYPE_KEY::APPS_PATH, 0331 TRASH_PATH = FMStatic::PATHTYPE_KEY::TRASH_PATH, 0332 CLOUD_PATH = FMStatic::PATHTYPE_KEY::CLOUD_PATH, 0333 QUICK_PATH = FMStatic::PATHTYPE_KEY::QUICK_PATH, 0334 OTHER_PATH = FMStatic::PATHTYPE_KEY::OTHER_PATH 0335 0336 }; 0337 Q_ENUM(PATHTYPE) 0338 0339 /** 0340 * @brief The possible view types for listing the entries in the FileBrowser visual control. 0341 */ 0342 enum VIEW_TYPE : uint_fast8_t { 0343 /** 0344 * Display the file system entries in a grid view. 0345 */ 0346 ICON_VIEW, 0347 0348 /** 0349 * Display the file system entries in a list, with more information details visible. 0350 */ 0351 LIST_VIEW 0352 }; 0353 Q_ENUM(VIEW_TYPE) 0354 0355 /** 0356 * @brief FMList 0357 * @param parent 0358 */ 0359 FMList(QObject *parent = nullptr); 0360 0361 /** 0362 * @brief items 0363 * @return 0364 */ 0365 const FMH::MODEL_LIST &items() const final override; 0366 0367 FMList::SORTBY getSortBy() const; 0368 void setSortBy(const FMList::SORTBY &key); 0369 0370 /** 0371 * @private 0372 */ 0373 void componentComplete() override final; 0374 0375 bool getAutoLoad() const; 0376 void setAutoLoad(bool value); 0377 0378 QString getPath() const; 0379 void setPath(const QString &path); 0380 0381 QString getPathName() const; 0382 0383 FMList::PATHTYPE getPathType() const; 0384 0385 QStringList getFilters() const; 0386 void setFilters(const QStringList &filters); 0387 void resetFilters(); 0388 0389 FMList::FILTER getFilterType() const; 0390 void setFilterType(const FMList::FILTER &type); 0391 void resetFilterType(); 0392 0393 bool getHidden() const; 0394 void setHidden(const bool &state); 0395 0396 bool getOnlyDirs() const; 0397 void setOnlyDirs(const bool &state); 0398 0399 const QUrl getParentPath(); 0400 0401 bool getFoldersFirst() const; 0402 void setFoldersFirst(const bool &value); 0403 0404 int getCloudDepth() const; 0405 void setCloudDepth(const int &value); 0406 0407 PathStatus getStatus() const; 0408 0409 void setReadOnly(bool value); 0410 bool readOnly() const; 0411 0412 private: 0413 FM *fm; 0414 void clear(); 0415 void reset(); 0416 void setList(); 0417 void assignList(const FMH::MODEL_LIST &list); 0418 void appendToList(const FMH::MODEL_LIST &list); 0419 void sortList(); 0420 void filterContent(const QString &query, const QUrl &path); 0421 void setStatus(const PathStatus &status); 0422 0423 bool saveImageFile(const QImage &image); 0424 bool saveTextFile(const QString &data, const QString &format); 0425 /** 0426 * @brief Gets a model of the files associated with a tag 0427 * @param tag The lookup tag 0428 * @param filters Filters as regular expression 0429 * @return Model of files associated 0430 */ 0431 FMH::MODEL_LIST getTagContent(const QString &tag, const QStringList &filters = {}); 0432 0433 FMH::MODEL_LIST list = {{}}; 0434 0435 bool m_autoLoad = true; 0436 QUrl path; 0437 QString pathName = QString(); 0438 QStringList filters = {}; 0439 0440 bool onlyDirs = false; 0441 bool hidden = false; 0442 0443 bool foldersFirst = false; 0444 int cloudDepth = 1; 0445 0446 PathStatus m_status; 0447 0448 FMList::SORTBY sort = FMList::SORTBY::MODIFIED; 0449 FMList::FILTER filterType = FMList::FILTER::NONE; 0450 FMList::PATHTYPE pathType = FMList::PATHTYPE::PLACES_PATH; 0451 0452 NavHistory m_navHistory; 0453 0454 bool m_readOnly = false; 0455 0456 public Q_SLOTS: 0457 0458 /** 0459 * @brief Refresh the model for new changes. h content listing ill be regenerated. 0460 */ 0461 void refresh(); 0462 0463 /** 0464 * @brief Create a new directory within the current directory. 0465 * @param name the name of the directory 0466 */ 0467 void createDir(const QString &name); 0468 0469 /** 0470 * @brief Create a new file. 0471 * @note To create a custom file, please supply with the correct suffix. 0472 * @param name the name of the new file, for example `new.txt` 0473 */ 0474 void createFile(const QString &name); 0475 0476 /** 0477 * @brief Rename a file with from a given URL to the a new name provided 0478 * @param url the file URL to be renamed 0479 * @param newName the new name for the file 0480 */ 0481 void renameFile(const QString &url, const QString &newName); 0482 0483 /** 0484 * @brief Create a symbolic link to the given URL in the current location. 0485 * @param url the file URL to create the link from 0486 */ 0487 void createSymlink(const QString &url); 0488 0489 /** 0490 * @brief Completely remove the set of file URLs provided. This action can not be undone 0491 * @param urls the list of file URLS to be removed 0492 */ 0493 void removeFiles(const QStringList &urls); 0494 0495 /** 0496 * @brief Remove and move to the trash the provided set of file URLs 0497 * @param urls the list of file URLS to be removed 0498 */ 0499 void moveToTrash(const QStringList &urls); 0500 0501 /** 0502 * @brief Whether the clipboard has a supported type of content. 0503 * @return whether the clipboard content is a supported file URL or a text or image raw data. 0504 */ 0505 bool clipboardHasContent() const; 0506 0507 /** 0508 * @brief Copy a list of file URLs into the current directory 0509 * @param urls list of files 0510 */ 0511 void copyInto(const QStringList &urls); 0512 0513 /** 0514 * @brief Cut/move a list of file URLs to the current directory 0515 * @param urls list of files 0516 */ 0517 void cutInto(const QStringList &urls); 0518 0519 /** 0520 * @brief Handle the paste action. 0521 * This allows to quickly paste into the current location any file URL in the clipboard, and raw image data and text snippets into a new file. 0522 */ 0523 void paste(); 0524 0525 /** 0526 * @brief Changes the icon of a directory by making use of the directory config file 0527 * @param index the index position of the directory in the model 0528 * @param iconName then name of the new icon 0529 */ 0530 void setDirIcon(const int &index, const QString &iconName); 0531 0532 /** 0533 * @brief Remove an item from the model, this does not remove the file from the file system 0534 * @param index the index position of the file entry 0535 */ 0536 void remove(const int &index); 0537 0538 /** 0539 * @brief Start a search - starting from the current location - for a given name query. 0540 * @param query the search query name 0541 * @param recursive whether the search should be recursive and look into the subsequent sub-directories structure. By default this is set to `false`. 0542 */ 0543 void search(const QString &query, bool recursive = true); 0544 0545 /** 0546 * @brief The immediate previous path location that was navigated 0547 * @return the path URL location 0548 */ 0549 const QUrl previousPath(); 0550 0551 /** 0552 * @brief The immediate posterior path location that was navigated 0553 * @return the path URL location 0554 */ 0555 const QUrl posteriorPath(); 0556 0557 /** 0558 * @brief Given a file name query find if it exists in the current location 0559 * @param index the index of the found file entry otherwise `-1` 0560 */ 0561 int indexOfName(const QString &query); 0562 int indexOfFile(const QString &url); 0563 0564 Q_SIGNALS: 0565 void pathChanged(); 0566 void pathNameChanged(); 0567 void pathTypeChanged(); 0568 void filtersChanged(); 0569 void filterTypeChanged(); 0570 void hiddenChanged(); 0571 void onlyDirsChanged(); 0572 void sortByChanged(); 0573 void foldersFirstChanged(); 0574 void statusChanged(); 0575 void cloudDepthChanged(); 0576 void autoLoadChanged(); 0577 void readOnlyChanged(); 0578 0579 /** 0580 * @brief Emitted when the listing process has any error message that needs to be notified. 0581 * @param message the warning message text 0582 */ 0583 void warning(QString message); 0584 0585 /** 0586 * @brief Emitted while the file listing is still in progress. 0587 * @param percent the loading progress - it goes from 0 to 100. 0588 */ 0589 void progress(int percent); 0590 }; 0591