FolderStatusModel: Different icon for external storages
authorOlivier Goffart <ogoffart@woboq.com>
Tue, 24 Jan 2017 14:39:08 +0000 (15:39 +0100)
committerMarkus Goetz <markus@woboq.com>
Fri, 27 Jan 2017 14:59:59 +0000 (15:59 +0100)
Issue: https://github.com/owncloud/client/pull/5340#issuecomment-274564441

src/gui/folderstatusmodel.cpp
src/gui/folderstatusmodel.h

index 42b787d146c8ece7b34e3763c50c19f99696c1c4..e3d24cafe6b5fb8662d2e2a41defa699631548be 100644 (file)
@@ -29,6 +29,14 @@ Q_DECLARE_METATYPE(QPersistentModelIndex)
 namespace OCC {
 
 static const char propertyParentIndexC[] = "oc_parentIndex";
+static const char propertyPermissionMap[] = "oc_permissionMap";
+
+static QString removeTrailingSlash(const QString &s) {
+    if (s.endsWith('/')) {
+        return s.left(s.size() - 1);
+    }
+    return s;
+}
 
 FolderStatusModel::FolderStatusModel(QObject *parent)
     :QAbstractItemModel(parent), _accountState(0), _dirty(false)
@@ -162,7 +170,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
         case Qt::CheckStateRole:
             return x._checked;
         case Qt::DecorationRole:
-            return QFileIconProvider().icon(QFileIconProvider::Folder);
+            return QFileIconProvider().icon(x._isExternal ? QFileIconProvider::Network : QFileIconProvider::Folder);
         case Qt::ForegroundRole:
             if (x._isUndecided) {
                 return QColor(Qt::red);
@@ -368,6 +376,9 @@ FolderStatusModel::SubFolderInfo* FolderStatusModel::infoForIndex(const QModelIn
         if (parentInfo->hasLabel()) {
             return 0;
         }
+        if (index.row() >= parentInfo->_subs.size()) {
+            return 0;
+        }
         return &parentInfo->_subs[index.row()];
     } else {
         if (index.row() >= _folders.count()) {
@@ -537,12 +548,15 @@ void FolderStatusModel::fetchMore(const QModelIndex& parent)
         path += info->_path;
     }
     LsColJob *job = new LsColJob(_accountState->account(), path, this);
-    job->setProperties(QList<QByteArray>() << "resourcetype" << "http://owncloud.org/ns:size");
+    job->setProperties(QList<QByteArray>() << "resourcetype" << "http://owncloud.org/ns:size" << "http://owncloud.org/ns:permissions");
     job->setTimeout(60 * 1000);
     connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
             SLOT(slotUpdateDirectories(QStringList)));
     connect(job, SIGNAL(finishedWithError(QNetworkReply*)),
             this, SLOT(slotLscolFinishedWithError(QNetworkReply*)));
+    connect(job, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
+            this, SLOT(slotGatherPermissions(const QString&, const QMap<QString,QString>&)));
+
     job->start();
 
     QPersistentModelIndex persistentIndex(parent);
@@ -553,6 +567,20 @@ void FolderStatusModel::fetchMore(const QModelIndex& parent)
     QTimer::singleShot(1000, this, SLOT(slotShowFetchProgress()));
 }
 
+void FolderStatusModel::slotGatherPermissions(const QString &href, const QMap<QString,QString> &map)
+{
+    auto it = map.find("permissions");
+    if (it == map.end())
+        return;
+
+    auto job = sender();
+    auto permissionMap = job->property(propertyPermissionMap).toMap();
+    job->setProperty(propertyPermissionMap, QVariant()); // avoid a detach of the map while it is modified
+    Q_ASSERT(!href.endsWith(QLatin1Char('/'))); // LsColXMLParser::parse removes the trailing slash before calling us.
+    permissionMap[href] = *it;
+    job->setProperty(propertyPermissionMap, permissionMap);
+}
+
 void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
 {
     auto job = qobject_cast<LsColJob *>(sender());
@@ -598,6 +626,7 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
             selectiveSyncUndecidedSet.insert(str);
         }
     }
+    const auto permissionMap = job->property(propertyPermissionMap).toMap();
 
     QStringList sortedSubfolders = list;
     // skip the parent item (first in the list)
@@ -618,8 +647,8 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
         newInfo._folder = parentInfo->_folder;
         newInfo._pathIdx = parentInfo->_pathIdx;
         newInfo._pathIdx << newSubs.size();
-        auto size = job ? job->_sizes.value(path) : 0;
-        newInfo._size = size;
+        newInfo._size = job->_sizes.value(path);
+        newInfo._isExternal = permissionMap.value(removeTrailingSlash(path)).toString().contains("M");
         newInfo._path = relativePath;
         newInfo._name = relativePath.split('/', QString::SkipEmptyParts).last();
 
index f1813ca1c944d8651939d58f52f92cccb6170f7e..5071e1e3091aefe3d876897ec2681ccd9131d8d8 100644 (file)
@@ -51,7 +51,7 @@ public:
 
     struct SubFolderInfo {
         SubFolderInfo()
-            : _folder(0), _size(0), _fetched(false), _fetching(false),
+            : _folder(0), _size(0), _isExternal(false), _fetched(false), _fetching(false),
             _hasError(false), _fetchingLabel(false), _isUndecided(false), _checked(Qt::Checked) {}
         Folder *_folder;
         QString _name;
@@ -59,6 +59,7 @@ public:
         QVector<int> _pathIdx;
         QVector<SubFolderInfo> _subs;
         qint64 _size;
+        bool _isExternal;
 
         bool _fetched; // If we did the LSCOL for this folder already
         bool _fetching; // Whether a LSCOL job is currently running
@@ -113,6 +114,7 @@ public slots:
 
 private slots:
     void slotUpdateDirectories(const QStringList &);
+    void slotGatherPermissions(const QString &name, const QMap<QString,QString> &properties);
     void slotLscolFinishedWithError(QNetworkReply *r);
     void slotFolderSyncStateChange(Folder* f);
     void slotFolderScheduleQueueChanged();