2
* Copyright (C) 2012 Robin Burchell <robin+nemo@viroteck.net>
4
* You may use this file under the terms of the BSD license as follows:
6
* "Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions are
9
* * Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* * Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in
13
* the documentation and/or other materials provided with the
15
* * Neither the name of Nemo Mobile nor the names of its contributors
16
* may be used to endorse or promote products derived from this
17
* software without specific prior written permission.
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36
#include <QStringList>
40
#include "iorequest.h"
41
#include "filecompare.h"
42
#include "diritemabstractlistmodel.h"
43
#include "diriteminfo.h"
45
class FileSystemAction;
48
class LocationsFactory;
50
class ExternalFSWatcher;
51
class NetAuthenticationDataList;
53
class DirModel : public DirItemAbstractListModel
58
FileNameRole = Qt::UserRole,
66
IsHostRole, //!< it can also be used for other protocols than smb/cifs
69
NeedsAuthenticationRole,
72
IsSharedDirRole, //!< it can also be used for other protocols than smb/cifs
73
IsSharingAllowedRole,//!< true for local directories (not in Trash) and not IsSharedDirRole
74
IsBrowsableRole, //!< any Dir, Host, WorkGroup or Share
91
explicit DirModel(QObject *parent = 0);
94
static void registerMetaTypes();
96
//DirItemAbstractListModel
97
virtual int getIndex(const QString& name);
98
virtual void notifyItemChanged(int row);
100
int rowCount(const QModelIndex &index = QModelIndex()) const
102
if (index.parent() != QModelIndex())
104
return mDirectoryContents.count();
107
// TODO: this won't be safe if the model can change under the holder of the row
108
Q_INVOKABLE QVariant data(int row, const QByteArray &stringRole) const;
110
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
112
Q_INVOKABLE void refresh()
114
// just some syntactical sugar really
118
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
119
inline QString path() const { return mCurrentDir; }
120
void setPath(const QString &pathName, const QString& user = QString(), const QString& password = QString(), bool savePassword = false);
122
Q_INVOKABLE QDateTime curPathAccessedDate() const;
123
Q_INVOKABLE QDateTime curPathCreatedDate() const;
124
Q_INVOKABLE QDateTime curPathModifiedDate() const;
125
Q_INVOKABLE QString curPathAccessedDateLocaleShort() const;
126
Q_INVOKABLE QString curPathCreatedDateLocaleShort() const;
127
Q_INVOKABLE QString curPathModifiedDateLocaleShort() const;
128
Q_INVOKABLE bool curPathIsWritable() const;
130
Q_PROPERTY(bool awaitingResults READ awaitingResults NOTIFY awaitingResultsChanged)
131
bool awaitingResults() const;
133
Q_INVOKABLE void rm(const QStringList &paths);
135
Q_INVOKABLE bool rename(const QString& oldName, const QString& newName);
136
Q_INVOKABLE bool rename(int row, const QString &newName);
138
Q_INVOKABLE bool mkdir(const QString &newdir);
140
Q_PROPERTY(bool filterDirectories READ filterDirectories WRITE setFilterDirectories NOTIFY filterDirectoriesChanged)
141
bool filterDirectories() const;
143
Q_PROPERTY(bool isRecursive READ isRecursive WRITE setIsRecursive NOTIFY isRecursiveChanged)
144
bool isRecursive() const;
146
Q_PROPERTY(bool readsMediaMetadata READ readsMediaMetadata WRITE setReadsMediaMetadata NOTIFY readsMediaMetadataChanged)
147
bool readsMediaMetadata() const;
149
Q_PROPERTY(bool showDirectories READ showDirectories WRITE setShowDirectories NOTIFY showDirectoriesChanged)
150
bool showDirectories() const;
152
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged)
153
QStringList nameFilters() const;
154
void setNameFilters(const QStringList &nameFilters);
157
void onItemsAdded(const DirItemInfoList &newFiles);
158
void onItemsFetched();
161
void awaitingResultsChanged();
162
void nameFiltersChanged();
163
void filterDirectoriesChanged();
164
void isRecursiveChanged();
165
void readsMediaMetadataChanged();
166
void showDirectoriesChanged();
167
void pathChanged(const QString& newPath);
168
void error(const QString &errorTitle, const QString &errorMessage);
171
QHash<int, QByteArray> buildRoleNames() const;
172
QHash<int, QByteArray> roleNames() const;
173
QStringList mNameFilters;
174
bool mFilterDirectories;
175
bool mShowDirectories;
176
bool mAwaitingResults;
178
bool mReadsMediaMetadata;
180
DirItemInfoList mDirectoryContents;
184
Q_INVOKABLE DirSelection * selectionObject() const ;
186
//[0] new stuff Ubuntu File Manager
187
Q_PROPERTY(QString parentPath READ parentPath NOTIFY pathChanged)
188
QString parentPath() const;
190
Q_PROPERTY(bool showHiddenFiles READ getShowHiddenFiles WRITE setShowHiddenFiles NOTIFY showHiddenFilesChanged)
191
bool getShowHiddenFiles() const;
193
Q_PROPERTY(bool onlyAllowedPaths READ getOnlyAllowedPaths WRITE setOnlyAllowedPaths NOTIFY onlyAllowedPathsChanged)
194
bool getOnlyAllowedPaths() const;
202
Q_PROPERTY(SortBy sortBy READ getSortBy WRITE setSortBy NOTIFY sortByChanged)
203
SortBy getSortBy() const;
208
SortAscending = Qt::AscendingOrder,
209
SortDescending = Qt::DescendingOrder
211
Q_PROPERTY(SortOrder sortOrder READ getSortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
212
SortOrder getSortOrder() const;
214
Q_PROPERTY(int clipboardUrlsCounter READ getClipboardUrlsCounter NOTIFY clipboardChanged)
215
int getClipboardUrlsCounter() const;
217
Q_PROPERTY(bool enableExternalFSWatcher READ getEnabledExternalFSWatcher WRITE setEnabledExternalFSWatcher NOTIFY enabledExternalFSWatcherChanged)
218
bool getEnabledExternalFSWatcher() const;
220
Q_INVOKABLE QString homePath() const;
222
Q_INVOKABLE QString lastFolderVisited() const;
226
* \brief Tries to make the directory pointed by row as the current to be browsed
227
* \return true if row points to a directory and the directory is readble, false otherwise
229
Q_INVOKABLE bool cdIntoIndex(int row);
230
Q_INVOKABLE bool cdIntoPath(const QString& filename);
233
* \brief copyIndex() puts the item pointed by \a row (dir or file) into the clipboard
234
* \param row points to the item file or directory
236
Q_INVOKABLE void copyIndex(int row);
239
* \brief copyPaths(const QStringList& urls) several items (dirs or files) into the clipboard
240
* \param items fullpathnames or names only
242
Q_INVOKABLE void copyPaths(const QStringList& items);
245
* \brief cutIndex() puts the item into the clipboard as \ref copy(),
246
* mark the item to be removed after \ref paste()
247
* \param row points to the item file or directory
249
Q_INVOKABLE void cutIndex(int row);
252
* \brief cut() puts several items (dirs or files) into the clipboard as \ref copy(),
253
* mark the item to be removed after \ref paste()
254
* \param items fullpathnames or names only
256
Q_INVOKABLE void cutPaths(const QStringList& items);
259
* \brief removeIndex(); remove a item file or directory
261
* I gets the item indicated by \row and calls \ref rm()
263
* \param row points to the item to b e removed
264
* \return true if it was possible to remove the item
266
Q_INVOKABLE void removeIndex(int row);
269
* Just calls \ref rm()
271
Q_INVOKABLE void removePaths(const QStringList& items);
274
* Tries to open a file using a suitable application, if the index points to a directory
275
* it goes into it using \ref cdIntoIndex() or \ref cdIntoPath()
277
* \note Qt uses Qt QDesktopServices::openUrl()
279
Q_INVOKABLE bool openIndex(int row);
282
* Same as \ref openIndex() but using a file name instead of index
284
* It allows to open directories and files using absoulte paths
286
* \sa \ref cdIntoPath()
288
Q_INVOKABLE bool openPath(const QString& filename);
291
* \brief getProgressCounter() returns the number of \ref progress() notifications an Action will perform
293
* It may be useful to decide about showing or not a progress dialog for Remove/Copy/Cut/Paste Actions
295
* This function can be called just after receiving first \ref progress() notification
297
* \note In the future this \ref getProgressCounter() and \ref progress() will merge to single signal that
298
* will send the Action full information, it will allow to have multi thread Actions.
299
* Also \ref cancelAction() needs to change
301
Q_INVOKABLE int getProgressCounter() const;
303
// some helper functions that can be useful to other QML applications than File Manager
304
Q_INVOKABLE bool existsDir(const QString& folderName) const;
305
Q_INVOKABLE bool canReadDir(const QString& folderName) const;
306
Q_INVOKABLE bool existsFile(const QString& fileName) const;
307
Q_INVOKABLE bool canReadFile(const QString& fileName) const;
310
Q_INVOKABLE void moveIndexToTrash(int index);
311
void moveIndexesToTrash(const QList<int>&);
312
Q_INVOKABLE void restoreIndexFromTrash(int index);
313
void restoreIndexesFromTrash(const QList<int>&);
315
Q_INVOKABLE void setPathWithAuthentication(const QString& path,
317
const QString& password,
322
/*! \brief download(int index) download file pointed by \a index into standard Download location
324
* \return true if the download could be started, othewise false
326
Q_INVOKABLE bool download(int index);
328
/*! \brief downloadAndSaveAs(int index, const QString& filename) download file pointed by \a index and save it as \a filename
330
* \return true if the download could be started, othewise false
333
Q_INVOKABLE bool downloadAndSaveAs(int index, const QString& filename);
335
/*! \brief downloadAsTemporaryFile(int index) save download as temporary, useful to open remote files
337
* At the end if download is OK the signal downloadTemporaryComplete(const QString& fullpathname) is emitted
339
* \return true if the download could be started, othewise false
342
Q_INVOKABLE bool downloadAsTemporaryFile(int index);
347
* \brief copySelection() copy selected items to the clipboard
349
void copySelection();
352
* \brief cutSelection() cut selected items to the clipboard
357
* \brief removeSelection() remove selected items, it handles Trash items
359
void removeSelection();
362
* \brief moveSelectionToTrash() move selected items from Local Disk (only) to Local Trash
364
void moveSelectionToTrash();
367
* \brief restoreSelectionFromTrash() restore selected trash items to their orginal location
369
void restoreSelectionFromTrash();
372
* \brief restoreTrash() restore all items being actually browsed in the Trash
378
* \brief emptyTrash() remove definitely all items being actually browsed in the Trash
380
* \sa \ref removeSelection() and \ref rm()
386
* \brief goHome() goes to user home dir
387
* Go to user home dir, we may have a tab for places or something like that
392
* \brief goTrash() goes to logical folder trash:///
397
* \brief goBack() goes to the previous folder if available
403
* \brief cdUp() sets the parent directory as current directory
405
* It can work as a back function if there is no user input path
406
* \return true if it was possible to change to parent dir, otherwise false
411
* \brief paste() copy item(s) from \ref copy() and \ref paste() into the current directory
413
* If the operation was \ref cut(), then remove the original item
418
* \brief clears clipboard entries
420
void clearClipboard();
423
* \brief cancelAction() any copy/cut/remove can be cancelled
427
void setIsRecursive(bool isRecursive);
428
void setReadsMediaMetadata(bool readsMediaMetadata);
429
void setFilterDirectories(bool filterDirectories);
430
void setShowDirectories(bool showDirectories);
431
void setShowHiddenFiles(bool show);
433
* \brief if set to true then only Allowed paths are shown or be modified
435
void setOnlyAllowedPaths(bool onlyAllowedPaths);
436
void setSortBy(SortBy field);
437
void setSortOrder(SortOrder order);
438
void setEnabledExternalFSWatcher(bool enable);
441
void toggleShowDirectories();
442
void toggleShowHiddenFiles();
443
void toggleSortOrder();
447
* \brief Adds a directory to the set of directories that are accessible when "onlyAllowedPaths" property is set.
449
inline void addAllowedDirectory(const QString &allowedDirAbsolutePath) {
450
m_allowedDirs << allowedDirAbsolutePath;
453
inline void removeAllowedDirectory(const QString &allowedDirAbsolutePath) {
454
m_allowedDirs.remove(allowedDirAbsolutePath);
456
bool isAllowedPath(const QString &absolutePath) const;
460
* \brief needsAuthentication()
461
* This notifies the UI that the current URL being browsed needs to set
462
* user/password to perform an authentication
464
* The UI must ask for "user" and "password" for the current URL and then call
465
* \ref setAuthentication()
467
* \param user current user being used
468
* \param urlPath the current URL asked to be browsed
470
void needsAuthentication(const QString& user, const QString& urlPath);
473
* \brief insertedRow()
475
* It happens when a new file is inserted in an existent view,
476
* for example from \ref mkdir() or \ref paste()
478
* It can be used to make the new row visible to the user doing a scroll to
480
void insertedRow(int row);
484
* Sends status about recursive and multi-items remove/move/copy
486
* \param curItem current item being handled
487
* \param totalItems total of items including recursive directories content
488
* \param percent a percent done
490
void progress(int curItem, int totalItems, int percent);
492
void showHiddenFilesChanged();
493
void onlyAllowedPathsChanged();
494
void sortByChanged();
495
void sortOrderChanged();
496
void clipboardChanged();
497
void enabledExternalFSWatcherChanged(bool);
500
* \brief downloadTemporaryComplete() says that download has been completed and
501
* the \a filename is ready to be used, filename is a full pathname
503
void downloadTemporaryComplete(const QString& filename);
506
void onItemRemoved(const DirItemInfo&);
507
void onItemAdded(const DirItemInfo&);
508
void onItemChanged(const DirItemInfo&);
511
int addItem(const DirItemInfo& fi);
512
void setCompareAndReorder();
513
int rowOfItem(const DirItemInfo& fi);
514
QDir::Filters currentDirFilter() const;
515
QString dirItems(const DirItemInfo& fi) const;
516
bool cdIntoItem(const DirItemInfo& fi);
517
bool openItem(const DirItemInfo& fi);
518
DirItemInfo setParentIfRelative(const QString &fileOrDir) const;
519
void setPathFromCurrentLocation();
522
void startExternalFsWatcher();
523
void stoptExternalFsWatcher();
527
void onItemAddedOutsideFm(const DirItemInfo&fi);
528
void onItemRemovedOutSideFm(const DirItemInfo&);
529
void onItemChangedOutSideFm(const DirItemInfo&fi);
530
void onThereAreExternalChanges(const QString &);
531
void onExternalFsWorkerFinished(int);
535
bool mShowHiddenFiles;
536
bool mOnlyAllowedPaths;
538
SortOrder mSortOrder;
539
CompareFunction mCompareFunction;
541
Clipboard * mClipboard;
542
DirSelection * mSelection;
543
NetAuthenticationDataList *mAuthData;
544
LocationsFactory * mLocationFactory;
545
Location * mCurLocation;
546
QStringList mPathList; //!< it will be used for goBack()
549
FileSystemAction * m_fsAction; //!< it does file system recursive remove/copy/move
550
QString fileSize(qint64 size) const;
551
#ifndef DO_NOT_USE_TAG_LIB
552
QVariant getAudioMetaData(const QFileInfo& fi, int role) const;
554
QSet<QString> m_allowedDirs;
558
#if defined(REGRESSION_TEST_FOLDERLISTMODEL)
559
ExternalFSWatcher * getExternalFSWatcher() const;
560
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
561
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
562
friend class TestDirModel;
565
bool allowAccess(const DirItemInfo &fi) const;
566
bool allowCurrentPathAccess() const;