1 /******************************************************************************
2 
3   This source file is part of the Avogadro project.
4 
5   Copyright 2013 Kitware, Inc.
6 
7   This source code is released under the New BSD License, (the "License").
8 
9   Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14 
15 ******************************************************************************/
16 
17 #ifndef AVOGADRO_QTPLUGINS_FILEDIALOGMODEL_H
18 #define AVOGADRO_QTPLUGINS_FILEDIALOGMODEL_H
19 
20 #include <QAbstractItemModel>
21 #include <QFileIconProvider>
22 #include <QObject>
23 
24 class vtkProcessModule;
25 class QModelIndex;
26 
27 namespace ProtoCall {
28 namespace Runtime {
29 class RpcChannel;
30 class vtkCommunicatorChannel;
31 }
32 }
33 
34 class Listing;
35 class Path;
36 
37 /**
38  * @class FileDialogModel filedialogmodel.h
39  * <avogadro/qtplugins/clientserver/filedialogmodel.h>
40  * @brief Remote file dialog model
41  */
42 class FileDialogModel : public QAbstractItemModel
43 {
44   typedef QAbstractItemModel base;
45 
46   Q_OBJECT
47 
48 public:
49   enum FileType
50   {
51     INVALID = 0,
52     SINGLE_FILE,
53     SINGLE_FILE_LINK,
54     DIRECTORY,
55     DIRECTORY_LINK,
56     FILE_GROUP,
57     DRIVE,
58     NETWORK_ROOT,
59     NETWORK_DOMAIN,
60     NETWORK_SERVER,
61     NETWORK_SHARE
62   };
63 
64   FileDialogModel(ProtoCall::Runtime::vtkCommunicatorChannel* server,
65                   QObject* Parent = nullptr);
66   ~FileDialogModel();
67 
68   /// Sets the path that the file dialog will display
69   void setCurrentPath(const QString&);
70 
71   /// Returns the path to the file dialog will display
72   QString getCurrentPath();
73 
74   /// Return true if the file at the index is hidden
75   bool isHidden(const QModelIndex&);
76 
77   /// Return true if the given row is a directory
78   bool isDir(const QModelIndex&);
79 
80   // Creates a directory. "dirName" can be relative or absolute path
81   bool mkdir(const QString& dirname);
82 
83   // Removes a directory. "dirName" can be relative or absolute path
84   bool rmdir(const QString& dirname);
85 
86   // Renames a directory or file.
87   bool rename(const QString& oldname, const QString& newname);
88 
89   /// Returns whether the file exists
90   /// also returns the full path, which could be a resolved shortcut
91   void fileExists(const QString& file, const QObject* requestor,
92                   const char* resultSlot);
93 
94   /// Returns whether a directory exists
95   /// also returns the full path, which could be a resolved shortcut
96   void dirExists(const QString& dir, const QObject* requestor,
97                  const char* resultSlot);
98 
99   /// returns the path delimiter, could be \ or / depending on the platform
100   /// this model is browsing
101   QChar separator() const;
102 
103   /// return the absolute path for this file
104   void absoluteFilePath(const QString& path, const QObject* requester,
105                         const char* resultSlot);
106 
107   /// Returns the set of file paths associated with the given row
108   /// (a row may represent one-to-many paths if grouping is implemented)
109   /// this also resolved symlinks if necessary
110   QStringList getFilePaths(const QModelIndex&);
111 
112   /// Returns the server that this model is browsing
113   ProtoCall::Runtime::vtkCommunicatorChannel* server() const;
114 
115   // overloads for QAbstractItemModel
116 
117   /// return the number of columns in the model
118   int columnCount(const QModelIndex&) const;
119   /// return the data for an item
120   QVariant data(const QModelIndex& idx, int role) const;
121   /// return an index from another index
122   QModelIndex index(int row, int column, const QModelIndex&) const;
123   /// return the parent index of an index
124   QModelIndex parent(const QModelIndex&) const;
125   /// return the number of rows under a given index
126   int rowCount(const QModelIndex&) const;
127   /// return whether a given index has children
128   bool hasChildren(const QModelIndex& p) const;
129   /// returns header data
130   QVariant headerData(int section, Qt::Orientation, int role) const;
131   /// returns flags for item
132   Qt::ItemFlags flags(const QModelIndex& idx) const;
133 
134   static bool isDirectory(FileDialogModel::FileType type);
135   static bool isFile(FileDialogModel::FileType type);
136 
137 signals:
138   void fileExistsComplete(const QString& path, bool exists);
139   void dirExistsComplete(const QString& path, bool exits);
140   void absoluteFilePathComplete(const QString& path);
141 
142 private:
143   class Private;
144   Private* const m_implementation;
145 
146   void handleFileExists(Listing* listing);
147   void handleDirExists(Listing* listing);
148   void handleAbsolutePathResponse(Path* response);
149 
150 private slots:
151   void cleanup();
152 };
153 
154 class FileDialogModelIconProvider : protected QFileIconProvider
155 {
156 public:
157   enum IconType
158   {
159     Computer,
160     Drive,
161     Folder,
162     File,
163     FolderLink,
164     FileLink,
165     NetworkFolder
166   };
167   FileDialogModelIconProvider();
168   QIcon icon(IconType t) const;
169   QIcon icon(FileDialogModel::FileType f) const;
170 
171 protected:
172   QIcon icon(const QFileInfo& info) const;
173   QIcon icon(QFileIconProvider::IconType ico) const;
174 
175   QIcon m_folderLinkIcon;
176   QIcon m_fileLinkIcon;
177 };
178 
179 #endif
180