1 /*
2  * Copyright (C) 2012 - 2015  Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19 
20 
21 #ifndef FM_FOLDERMODEL_H
22 #define FM_FOLDERMODEL_H
23 
24 #include "libfmqtglobals.h"
25 #include <QAbstractListModel>
26 #include <QItemSelection>
27 #include <QIcon>
28 #include <QImage>
29 #include <QList>
30 #include <vector>
31 #include <utility>
32 #include <forward_list>
33 #include "foldermodelitem.h"
34 
35 #include "core/folder.h"
36 #include "core/thumbnailjob.h"
37 
38 namespace Fm {
39 
40 class LIBFM_QT_API FolderModel : public QAbstractListModel {
41     Q_OBJECT
42 public:
43 
44     enum Role {
45         FileInfoRole = Qt::UserRole,
46         FileIsDirRole,
47         FileIsCutRole
48     };
49 
50     enum ColumnId {
51         ColumnFileName,
52         ColumnFileType,
53         ColumnFileSize,
54         ColumnFileMTime,
55         ColumnFileCrTime,
56         ColumnFileDTime,
57         ColumnFileOwner,
58         ColumnFileGroup,
59         NumOfColumns
60     };
61 
62 public:
63     explicit FolderModel();
64     ~FolderModel() override;
65 
folder()66     const std::shared_ptr<Fm::Folder>& folder() const {
67         return folder_;
68     }
69 
70     void setFolder(const std::shared_ptr<Fm::Folder>& new_folder);
71 
path()72     Fm::FilePath path() {
73         return folder_ ? folder_->path() : Fm::FilePath();
74     }
75 
76     int rowCount(const QModelIndex& parent = QModelIndex()) const override;
77     int columnCount(const QModelIndex& parent) const override;
78     QVariant data(const QModelIndex& index, int role) const override;
79     QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
80     QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
81     QModelIndex parent(const QModelIndex& index) const override;
82     // void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
83 
84     Qt::ItemFlags flags(const QModelIndex& index) const override;
85 
86     QStringList mimeTypes() const override;
87     QMimeData* mimeData(const QModelIndexList& indexes) const override;
88     Qt::DropActions supportedDropActions() const override;
89     bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override;
90 
91     std::shared_ptr<const Fm::FileInfo> fileInfoFromIndex(const QModelIndex& index) const;
92     std::shared_ptr<const Fm::FileInfo> fileInfoFromPath(const Fm::FilePath& path) const;
93     FolderModelItem* itemFromIndex(const QModelIndex& index) const;
94     QImage thumbnailFromIndex(const QModelIndex& index, int size);
95 
96     void cacheThumbnails(int size);
97     void releaseThumbnails(int size);
98 
setShowFullName(bool fullName)99     void setShowFullName(bool fullName) {
100         showFullNames_ = fullName;
101     }
102 
103 Q_SIGNALS:
104     void thumbnailLoaded(const QModelIndex& index, int size);
105     void fileSizeChanged(const QModelIndex& index);
106     void filesAdded(FileInfoList infoList);
107 
108 protected Q_SLOTS:
109 
110     void onStartLoading();
111     void onFinishLoading();
112     void onFilesAdded(const Fm::FileInfoList& files);
113     void onFilesChanged(std::vector<Fm::FileInfoPair>& files);
114     void onFilesRemoved(const Fm::FileInfoList& files);
115 
116     void onThumbnailLoaded(const std::shared_ptr<const Fm::FileInfo>& file, int size, const QImage& image);
117     void onThumbnailJobFinished();
118     void loadPendingThumbnails();
119 
120     void onClipboardDataChange();
121 
122 protected:
123     void queueLoadThumbnail(const std::shared_ptr<const Fm::FileInfo>& file, int size);
124     void insertFiles(int row, const Fm::FileInfoList& files);
125     void removeAll();
126     QList<FolderModelItem>::iterator findItemByName(const char* name, int* row);
127     QList<FolderModelItem>::iterator findItemByFileInfo(const Fm::FileInfo* info, int* row);
128 
129 private:
130     QString makeTooltip(FolderModelItem* item) const;
131     void updateCutFilesSet();
132 
133 private:
134 
135     struct ThumbnailData {
ThumbnailDataThumbnailData136         ThumbnailData(int size):
137             size_{size},
138             refCount_{1} {
139         }
140 
141         int size_;
142         int refCount_;
143         Fm::FileInfoList pendingThumbnails_;
144     };
145 
146     std::shared_ptr<Fm::Folder> folder_;
147     QList<FolderModelItem> items;
148 
149     bool hasPendingThumbnailHandler_;
150     std::vector<Fm::ThumbnailJob*> pendingThumbnailJobs_;
151     std::forward_list<ThumbnailData> thumbnailData_;
152 
153     bool showFullNames_;
154 
155     bool isLoaded_;
156 
157     bool hasCutfile_;
158     HashSet cutFilesHashSet_;
159 };
160 
161 }
162 
163 #endif // FM_FOLDERMODEL_H
164