[Pkg-owncloud-commits] [owncloud-client] 65/484: SelectiveSync: Show in-progress label #3524
Sandro Knauß
hefee-guest at moszumanska.debian.org
Wed Dec 16 00:37:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
hefee-guest pushed a commit to branch master
in repository owncloud-client.
commit 05eee16959ab7cc485bee9c273392b84ba57eae8
Author: Christian Kamm <mail at ckamm.de>
Date: Tue Oct 13 14:10:52 2015 +0200
SelectiveSync: Show in-progress label #3524
We now show 'Fetching data...' after a second.
This also increased the timeout to 60s, making the error
condition much less likely.
---
src/gui/folderstatusmodel.cpp | 131 ++++++++++++++++++++++++++++++------------
src/gui/folderstatusmodel.h | 37 ++++++++++--
2 files changed, 124 insertions(+), 44 deletions(-)
diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp
index bcbbdcd..1e15e84 100644
--- a/src/gui/folderstatusmodel.cpp
+++ b/src/gui/folderstatusmodel.cpp
@@ -90,7 +90,7 @@ Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex &index ) const
}
return Qt::ItemIsEnabled | ret;
}
- case ErrorLabel:
+ case FetchLabel:
return Qt::ItemIsEnabled
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
| Qt::ItemNeverHasChildren
@@ -151,11 +151,20 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
}
}
return QVariant();
- case ErrorLabel:
+ case FetchLabel:
+ {
+ const auto x = static_cast<SubFolderInfo *>(index.internalPointer());
switch(role) {
- case Qt::DisplayRole: return tr("Error while loading the list of folders from the server.");
+ case Qt::DisplayRole:
+ if (x->_hasError) {
+ return tr("Error while loading the list of folders from the server.");
+ } else {
+ return tr("Fetching folder list from server...");
+ }
+ break;
default: return QVariant();
}
+ }
case RootFolder:
break;
}
@@ -302,7 +311,7 @@ int FolderStatusModel::rowCount(const QModelIndex& parent) const
auto info = infoForIndex(parent);
if (!info)
return 0;
- if (info->_hasError)
+ if (info->hasLabel())
return 1;
return info->_subs.count();
}
@@ -310,7 +319,11 @@ int FolderStatusModel::rowCount(const QModelIndex& parent) const
FolderStatusModel::ItemType FolderStatusModel::classify(const QModelIndex& index) const
{
if (auto sub = static_cast<SubFolderInfo*>(index.internalPointer())) {
- return sub->_hasError ? ErrorLabel : SubFolder;
+ if (sub->hasLabel()) {
+ return FetchLabel;
+ } else {
+ return SubFolder;
+ }
}
if (index.row() < _folders.count()) {
return RootFolder;
@@ -323,8 +336,7 @@ FolderStatusModel::SubFolderInfo* FolderStatusModel::infoForIndex(const QModelIn
if (!index.isValid())
return 0;
if (auto parentInfo = static_cast<SubFolderInfo*>(index.internalPointer())) {
- if (parentInfo->_hasError) {
- // Error label
+ if (parentInfo->hasLabel()) {
return 0;
}
return &parentInfo->_subs[index.row()];
@@ -384,20 +396,21 @@ QModelIndex FolderStatusModel::index(int row, int column, const QModelIndex& par
}
switch(classify(parent)) {
case AddButton:
- case ErrorLabel:
+ case FetchLabel:
return QModelIndex();
case RootFolder:
if (_folders.count() <= parent.row())
return QModelIndex(); // should not happen
return createIndex(row, column, const_cast<SubFolderInfo *>(&_folders[parent.row()]));
case SubFolder: {
- auto info = static_cast<SubFolderInfo*>(parent.internalPointer());
- if (info->_subs.count() <= parent.row())
+ auto pinfo = static_cast<SubFolderInfo*>(parent.internalPointer());
+ if (pinfo->_subs.count() <= parent.row())
return QModelIndex(); // should not happen
- if (!info->_subs.at(parent.row())._hasError
- && info->_subs.at(parent.row())._subs.count() <= row)
+ auto & info = pinfo->_subs[parent.row()];
+ if (!info.hasLabel()
+ && info._subs.count() <= row)
return QModelIndex(); // should not happen
- return createIndex(row, column, &info->_subs[parent.row()]);
+ return createIndex(row, column, &info);
}
}
return QModelIndex();
@@ -413,7 +426,7 @@ QModelIndex FolderStatusModel::parent(const QModelIndex& child) const
case AddButton:
return QModelIndex();
case SubFolder:
- case ErrorLabel:
+ case FetchLabel:
break;
}
auto pathIdx = static_cast<SubFolderInfo*>(child.internalPointer())->_pathIdx;
@@ -467,7 +480,9 @@ void FolderStatusModel::fetchMore(const QModelIndex& parent)
if (!info || info->_fetched || info->_fetching)
return;
+ info->_hasError = false;
info->_fetching = true;
+ info->_fetchingLabel = false;
QString path = info->_folder->remotePath();
if (info->_path != QLatin1String("/")) {
if (!path.endsWith(QLatin1Char('/'))) {
@@ -477,13 +492,18 @@ void FolderStatusModel::fetchMore(const QModelIndex& parent)
}
LsColJob *job = new LsColJob(_accountState->account(), path, this);
job->setProperties(QList<QByteArray>() << "resourcetype" << "quota-used-bytes");
- job->setTimeout(5 * 1000);
+ job->setTimeout(60 * 1000);
connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
SLOT(slotUpdateDirectories(QStringList)));
connect(job, SIGNAL(finishedWithError(QNetworkReply*)),
this, SLOT(slotLscolFinishedWithError(QNetworkReply*)));
job->start();
- job->setProperty(propertyParentIndexC , QVariant::fromValue<QPersistentModelIndex>(parent));
+ QPersistentModelIndex persistentIndex(parent);
+ job->setProperty(propertyParentIndexC , QVariant::fromValue(persistentIndex));
+
+ // Show 'fetching data...' hint after a while.
+ _fetchingItems[persistentIndex].start();
+ QTimer::singleShot(1000, this, SLOT(slotShowFetchProgress()));
}
void FolderStatusModel::slotUpdateDirectories(const QStringList &list_)
@@ -496,12 +516,16 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list_)
return;
}
- if (parentInfo->_hasError) {
+ if (parentInfo->hasLabel()) {
beginRemoveRows(idx, 0 ,0);
parentInfo->_hasError = false;
+ parentInfo->_fetchingLabel = false;
endRemoveRows();
}
+ parentInfo->_fetching = false;
+ parentInfo->_fetched = true;
+
auto list = list_;
list.removeFirst(); // remove the parent item
@@ -522,9 +546,6 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list_)
beginInsertRows(idx, 0, list.count() - 1);
- parentInfo->_fetched = true;
- parentInfo->_fetching = false;
-
QStringList selectiveSyncBlackList;
if (parentInfo->_checked == Qt::PartiallyChecked) {
selectiveSyncBlackList = parentInfo->_folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList);
@@ -589,14 +610,17 @@ void FolderStatusModel::slotLscolFinishedWithError(QNetworkReply* r)
}
auto parentInfo = infoForIndex(idx);
if (parentInfo) {
- parentInfo->_fetching = false;
if (r->error() == QNetworkReply::ContentNotFoundError) {
parentInfo->_fetched = true;
- } else if (!parentInfo->_hasError) {
- beginInsertRows(idx, 0, 0);
+ } else {
+ if (!parentInfo->hasLabel()) {
+ beginInsertRows(idx, 0, 0);
+ endInsertRows();
+ }
parentInfo->_hasError = true;
- endInsertRows();
}
+ parentInfo->_fetching = false;
+ parentInfo->_fetchingLabel = false;
}
}
@@ -900,13 +924,8 @@ void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
if (i->_isDirectory && (i->_instruction == CSYNC_INSTRUCTION_NEW
|| i->_instruction == CSYNC_INSTRUCTION_REMOVE)) {
// There is a new or a removed folder. reset all data
- _folders[folderIndex]._fetched = false;
- _folders[folderIndex]._fetching = false;
- if (!_folders.at(folderIndex)._subs.isEmpty()) {
- beginRemoveRows(index(folderIndex), 0, _folders.at(folderIndex)._subs.count() - 1);
- _folders[folderIndex]._subs.clear();
- endRemoveRows();
- }
+ auto & info = _folders[folderIndex];
+ info.resetSubs(this, index(folderIndex));
return;
}
}
@@ -942,17 +961,53 @@ void FolderStatusModel::slotNewBigFolder()
}
if (folderIndex < 0) { return; }
- _folders[folderIndex]._fetched = false;
- _folders[folderIndex]._fetching = false;
- if (!_folders.at(folderIndex)._subs.isEmpty()) {
- beginRemoveRows(index(folderIndex), 0, _folders.at(folderIndex)._subs.count() - 1);
- _folders[folderIndex]._subs.clear();
- endRemoveRows();
- }
+ _folders[folderIndex].resetSubs(this, index(folderIndex));
emit suggestExpand(index(folderIndex));
emit dirtyChanged();
}
+void FolderStatusModel::slotShowFetchProgress()
+{
+ QMutableMapIterator<QPersistentModelIndex, QElapsedTimer> it(_fetchingItems);
+ while (it.hasNext()) {
+ it.next();
+ if (it.value().elapsed() > 800)
+ {
+ auto idx = it.key();
+ auto* info = infoForIndex(idx);
+ if (info && info->_fetching) {
+ if (!info->hasLabel()) {
+ beginInsertRows(idx, 0, 0);
+ endInsertRows();
+ }
+ info->_fetchingLabel = true;
+ }
+ it.remove();
+ }
+ }
+}
+
+bool FolderStatusModel::SubFolderInfo::hasLabel() const
+{
+ return _hasError || _fetchingLabel;
+}
+
+void FolderStatusModel::SubFolderInfo::resetSubs(FolderStatusModel* model, QModelIndex index)
+{
+ _fetched = false;
+ _fetching = false;
+ if (hasLabel()) {
+ model->beginRemoveRows(index, 0 ,0);
+ _fetchingLabel = false;
+ _hasError = false;
+ model->endRemoveRows();
+ } else if (!_subs.isEmpty()) {
+ model->beginRemoveRows(index, 0, _subs.count() - 1);
+ _subs.clear();
+ model->endRemoveRows();
+ }
+}
+
} // namespace OCC
diff --git a/src/gui/folderstatusmodel.h b/src/gui/folderstatusmodel.h
index 9324080..b5f3de1 100644
--- a/src/gui/folderstatusmodel.h
+++ b/src/gui/folderstatusmodel.h
@@ -18,7 +18,7 @@
#include <accountfwd.h>
#include <QAbstractItemModel>
#include <QVector>
-
+#include <QElapsedTimer>
class QNetworkReply;
namespace OCC {
@@ -51,20 +51,30 @@ public:
struct SubFolderInfo {
SubFolderInfo()
- : _folder(0), _size(0), _fetched(false), _fetching(false), _isUndecided(false),
- _hasError(false), _checked(Qt::Checked) {}
+ : _folder(0), _size(0), _fetched(false), _fetching(false),
+ _hasError(false), _fetchingLabel(false), _isUndecided(false), _checked(Qt::Checked) {}
Folder *_folder;
QString _name;
QString _path;
QVector<int> _pathIdx;
QVector<SubFolderInfo> _subs;
qint64 _size;
+
bool _fetched; // If we did the LSCOL for this folder already
- bool _fetching;
- bool _isUndecided; // undecided folders are the big folders that the user has not accepted yet
+ bool _fetching; // Whether a LSCOL job is currently running
bool _hasError; // If the last fetching job ended in an error
+ bool _fetchingLabel; // Whether a 'fetching in progress' label is shown.
+
+ bool _isUndecided; // undecided folders are the big folders that the user has not accepted yet
+
Qt::CheckState _checked;
+ // Whether this has a FetchLabel subrow
+ bool hasLabel() const;
+
+ // Reset all subfolders and fetch status
+ void resetSubs(FolderStatusModel* model, QModelIndex index);
+
struct Progress {
Progress() : _warningCount(0), _overallPercent(0) {}
bool isNull() const
@@ -79,7 +89,7 @@ public:
QVector<SubFolderInfo> _folders;
- enum ItemType { RootFolder, SubFolder, AddButton, ErrorLabel };
+ enum ItemType { RootFolder, SubFolder, AddButton, FetchLabel };
ItemType classify(const QModelIndex &index) const;
SubFolderInfo *infoForIndex(const QModelIndex &index) const;
@@ -105,12 +115,25 @@ private slots:
void slotFolderScheduleQueueChanged();
void slotNewBigFolder();
+ /**
+ * "In progress" labels for fetching data from the server are only
+ * added after some time to avoid popping.
+ */
+ void slotShowFetchProgress();
+
private:
QStringList createBlackList(OCC::FolderStatusModel::SubFolderInfo* root,
const QStringList& oldBlackList) const;
const AccountState* _accountState;
bool _dirty; // If the selective sync checkboxes were changed
+ /**
+ * Keeps track of items that are fetching data from the server.
+ *
+ * See slotShowPendingFetchProgress()
+ */
+ QMap<QPersistentModelIndex, QElapsedTimer> _fetchingItems;
+
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
//the roles argument was added in Qt5
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>())
@@ -120,6 +143,8 @@ private:
signals:
void dirtyChanged();
void suggestExpand(const QModelIndex &); // Tell the view that this item should be expanded because it has an undecided item
+
+ friend class SubFolderInfo;
};
} // namespace OCC
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git
More information about the Pkg-owncloud-commits
mailing list