Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Kamm <mail@ckamm.de>2019-04-16 11:17:21 +0300
committerChristian Kamm <mail@ckamm.de>2019-04-23 10:21:17 +0300
commit96831247e24118018b4ccfca70253cd47996e3e4 (patch)
tree746c6e3857a026ca736c95ab2414c5b6da4b02cd /src
parentac19fab71aaee448a3f588ba01f06b2f5dca26b8 (diff)
Vfs: "free space" only shows when it has an effect #7143
To do this, introduce AllDehydrated availability and rename SomeDehydrated to Mixed - it now guarantees there are also hydrated items.
Diffstat (limited to 'src')
-rw-r--r--src/common/pinstate.h16
-rw-r--r--src/common/syncjournaldb.cpp25
-rw-r--r--src/common/syncjournaldb.h9
-rw-r--r--src/common/vfs.cpp10
-rw-r--r--src/gui/accountsettings.cpp6
-rw-r--r--src/gui/guiutility.cpp12
-rw-r--r--src/gui/guiutility.h2
-rw-r--r--src/gui/socketapi.cpp27
8 files changed, 64 insertions, 43 deletions
diff --git a/src/common/pinstate.h b/src/common/pinstate.h
index 44ee12417..c86d11ae5 100644
--- a/src/common/pinstate.h
+++ b/src/common/pinstate.h
@@ -83,13 +83,15 @@ enum class PinState {
*
* Note that this is only about *intent*. The file could still be out of date,
* or not have been synced for other reasons, like errors.
+ *
+ * NOTE: The numerical values and ordering of this enum are relevant.
*/
enum class VfsItemAvailability {
/** The item and all its subitems are hydrated and pinned AlwaysLocal.
*
* This guarantees that all contents will be kept in sync.
*/
- AlwaysLocal,
+ AlwaysLocal = 0,
/** The item and all its subitems are hydrated.
*
@@ -98,20 +100,24 @@ enum class VfsItemAvailability {
*
* A folder with no file contents will have this availability.
*/
- AllHydrated,
+ AllHydrated = 1,
- /** There are dehydrated items but the pin state isn't all OnlineOnly.
+ /** There are dehydrated and hydrated items.
*
* This would happen if a dehydration happens to a Unspecified item that
* used to be hydrated.
*/
- SomeDehydrated,
+ Mixed = 2,
+
+ /** There are only dehydrated items but the pin state isn't all OnlineOnly.
+ */
+ AllDehydrated = 3,
/** The item and all its subitems are dehydrated and OnlineOnly.
*
* This guarantees that contents will not take up space.
*/
- OnlineOnly,
+ OnlineOnly = 4,
};
}
diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp
index 09b7471a8..1ff231641 100644
--- a/src/common/syncjournaldb.cpp
+++ b/src/common/syncjournaldb.cpp
@@ -1261,18 +1261,16 @@ bool SyncJournalDb::updateLocalMetadata(const QString &filename,
return _setFileRecordLocalMetadataQuery.exec();
}
-Optional<bool> SyncJournalDb::hasDehydratedFiles(const QByteArray &filename)
+Optional<SyncJournalDb::HasHydratedDehydrated> SyncJournalDb::hasHydratedOrDehydratedFiles(const QByteArray &filename)
{
QMutexLocker locker(&_mutex);
if (!checkConnect())
return {};
auto &query = _countDehydratedFilesQuery;
- static_assert(ItemTypeVirtualFile == 4 && ItemTypeVirtualFileDownload == 5, "");
if (!query.initOrReset(QByteArrayLiteral(
- "SELECT count(*) FROM metadata"
- " WHERE (" IS_PREFIX_PATH_OR_EQUAL("?1", "path") " OR ?1 == '')"
- " AND (type == 4 OR type == 5);"), _db)) {
+ "SELECT DISTINCT type FROM metadata"
+ " WHERE (" IS_PREFIX_PATH_OR_EQUAL("?1", "path") " OR ?1 == '');"), _db)) {
return {};
}
@@ -1280,10 +1278,21 @@ Optional<bool> SyncJournalDb::hasDehydratedFiles(const QByteArray &filename)
if (!query.exec())
return {};
- if (!query.next().hasData)
- return {};
+ HasHydratedDehydrated result;
+ forever {
+ auto next = query.next();
+ if (!next.ok)
+ return {};
+ if (!next.hasData)
+ break;
+ auto type = static_cast<ItemType>(query.intValue(0));
+ if (type == ItemTypeFile || type == ItemTypeVirtualFileDehydration)
+ result.hasHydrated = true;
+ if (type == ItemTypeVirtualFile || type == ItemTypeVirtualFileDownload)
+ result.hasDehydrated = true;
+ }
- return query.intValue(0) > 0;
+ return result;
}
static void toDownloadInfo(SqlQuery &query, SyncJournalDb::DownloadInfo *res)
diff --git a/src/common/syncjournaldb.h b/src/common/syncjournaldb.h
index 5aab475f1..d1daefb2a 100644
--- a/src/common/syncjournaldb.h
+++ b/src/common/syncjournaldb.h
@@ -72,8 +72,15 @@ public:
bool updateLocalMetadata(const QString &filename,
qint64 modtime, qint64 size, quint64 inode);
+ /// Return value for hasHydratedOrDehydratedFiles()
+ struct HasHydratedDehydrated
+ {
+ bool hasHydrated = false;
+ bool hasDehydrated = false;
+ };
+
/** Returns whether the item or any subitems are dehydrated */
- Optional<bool> hasDehydratedFiles(const QByteArray &filename);
+ Optional<HasHydratedDehydrated> hasHydratedOrDehydratedFiles(const QByteArray &filename);
bool exists();
void walCheckpoint();
diff --git a/src/common/vfs.cpp b/src/common/vfs.cpp
index 54f6cb6bd..c24c11cd6 100644
--- a/src/common/vfs.cpp
+++ b/src/common/vfs.cpp
@@ -83,15 +83,17 @@ Optional<VfsItemAvailability> Vfs::availabilityInDb(const QString &folderPath, c
{
auto pin = _setupParams.journal->internalPinStates().effectiveForPathRecursive(pinPath.toUtf8());
// not being able to retrieve the pin state isn't too bad
- Optional<bool> hasDehydrated = _setupParams.journal->hasDehydratedFiles(folderPath.toUtf8());
- if (!hasDehydrated)
+ auto hydrationStatus = _setupParams.journal->hasHydratedOrDehydratedFiles(folderPath.toUtf8());
+ if (!hydrationStatus)
return {};
- if (*hasDehydrated) {
+ if (hydrationStatus->hasDehydrated) {
+ if (hydrationStatus->hasHydrated)
+ return VfsItemAvailability::Mixed;
if (pin && *pin == PinState::OnlineOnly)
return VfsItemAvailability::OnlineOnly;
else
- return VfsItemAvailability::SomeDehydrated;
+ return VfsItemAvailability::AllDehydrated;
} else {
if (pin && *pin == PinState::AlwaysLocal)
return VfsItemAvailability::AlwaysLocal;
diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp
index 775b916ce..cd9274ea3 100644
--- a/src/gui/accountsettings.cpp
+++ b/src/gui/accountsettings.cpp
@@ -342,7 +342,7 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
auto availabilityMenu = menu->addMenu(tr("Availability"));
auto availability = folder->vfs().availability(QString());
if (availability) {
- ac = availabilityMenu->addAction(Utility::vfsCurrentAvailabilityText(*availability, true));
+ ac = availabilityMenu->addAction(Utility::vfsCurrentAvailabilityText(*availability));
ac->setEnabled(false);
}
@@ -351,7 +351,9 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
connect(ac, &QAction::triggered, this, [this]() { slotSetCurrentFolderAvailability(PinState::AlwaysLocal); });
ac = availabilityMenu->addAction(Utility::vfsFreeSpaceActionText());
- ac->setEnabled(!availability || *availability != VfsItemAvailability::OnlineOnly);
+ ac->setEnabled(!availability
+ || !(*availability == VfsItemAvailability::OnlineOnly
+ || *availability == VfsItemAvailability::AllDehydrated));
connect(ac, &QAction::triggered, this, [this]() { slotSetCurrentFolderAvailability(PinState::OnlineOnly); });
ac = menu->addAction(tr("Disable virtual file support..."));
diff --git a/src/gui/guiutility.cpp b/src/gui/guiutility.cpp
index 545f56bff..10e5bbf2c 100644
--- a/src/gui/guiutility.cpp
+++ b/src/gui/guiutility.cpp
@@ -69,19 +69,17 @@ bool Utility::openEmailComposer(const QString &subject, const QString &body, QWi
return true;
}
-QString Utility::vfsCurrentAvailabilityText(VfsItemAvailability availability, bool forFolder)
+QString Utility::vfsCurrentAvailabilityText(VfsItemAvailability availability)
{
switch(availability) {
case VfsItemAvailability::AlwaysLocal:
return QCoreApplication::translate("utility", "Currently always available locally");
case VfsItemAvailability::AllHydrated:
return QCoreApplication::translate("utility", "Currently available locally");
- case VfsItemAvailability::SomeDehydrated:
- if (forFolder) {
- return QCoreApplication::translate("utility", "Currently some available online only");
- } else {
- return QCoreApplication::translate("utility", "Currently available online only");
- }
+ case VfsItemAvailability::Mixed:
+ return QCoreApplication::translate("utility", "Currently some available online only");
+ case VfsItemAvailability::AllDehydrated:
+ return QCoreApplication::translate("utility", "Currently available online only");
case VfsItemAvailability::OnlineOnly:
return QCoreApplication::translate("utility", "Currently available online only");
}
diff --git a/src/gui/guiutility.h b/src/gui/guiutility.h
index b25ecc937..6e2c5f163 100644
--- a/src/gui/guiutility.h
+++ b/src/gui/guiutility.h
@@ -41,7 +41,7 @@ namespace Utility {
*
* This will be used in context menus to describe the current state.
*/
- QString vfsCurrentAvailabilityText(VfsItemAvailability availability, bool forFolder);
+ QString vfsCurrentAvailabilityText(VfsItemAvailability availability);
/** Translated text for "making items always available locally" */
QString vfsPinActionText();
diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp
index baf9473e9..69192f700 100644
--- a/src/gui/socketapi.cpp
+++ b/src/gui/socketapi.cpp
@@ -750,7 +750,7 @@ void SocketApi::emailPrivateLink(const QString &link)
Utility::openEmailComposer(
tr("I shared something with you"),
link,
- 0);
+ nullptr);
}
void OCC::SocketApi::openPrivateLink(const QString &link)
@@ -953,19 +953,19 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe
auto merge = [](VfsItemAvailability lhs, VfsItemAvailability rhs) {
if (lhs == rhs)
return lhs;
- if (lhs == VfsItemAvailability::SomeDehydrated || rhs == VfsItemAvailability::SomeDehydrated
- || lhs == VfsItemAvailability::OnlineOnly || rhs == VfsItemAvailability::OnlineOnly) {
- return VfsItemAvailability::SomeDehydrated;
- }
- return VfsItemAvailability::AllHydrated;
+ auto l = int(lhs) < int(rhs) ? lhs : rhs; // reduce cases by sorting
+ auto r = int(lhs) < int(rhs) ? rhs : lhs;
+ if (l == VfsItemAvailability::AlwaysLocal && r == VfsItemAvailability::AllHydrated)
+ return VfsItemAvailability::AllHydrated;
+ if (l == VfsItemAvailability::AllDehydrated && r == VfsItemAvailability::OnlineOnly)
+ return VfsItemAvailability::AllDehydrated;
+ return VfsItemAvailability::Mixed;
};
- bool isFolderOrMultiple = false;
for (const auto &file : files) {
auto fileData = FileData::get(file);
- isFolderOrMultiple = QFileInfo(fileData.localPath).isDir();
auto availability = folder->vfs().availability(fileData.folderRelativePath);
if (!availability)
- availability = VfsItemAvailability::SomeDehydrated; // db error
+ availability = VfsItemAvailability::Mixed; // db error
if (!combined) {
combined = availability;
} else {
@@ -973,13 +973,11 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe
}
}
ENFORCE(combined);
- if (files.size() > 1)
- isFolderOrMultiple = true;
// TODO: Should be a submenu, should use icons
auto makePinContextMenu = [&](bool makeAvailableLocally, bool freeSpace) {
listener->sendMessage(QLatin1String("MENU_ITEM:CURRENT_PIN:d:")
- + Utility::vfsCurrentAvailabilityText(*combined, isFolderOrMultiple));
+ + Utility::vfsCurrentAvailabilityText(*combined));
listener->sendMessage(QLatin1String("MENU_ITEM:MAKE_AVAILABLE_LOCALLY:")
+ (makeAvailableLocally ? QLatin1String(":") : QLatin1String("d:"))
+ Utility::vfsPinActionText());
@@ -993,11 +991,10 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe
makePinContextMenu(false, true);
break;
case VfsItemAvailability::AllHydrated:
+ case VfsItemAvailability::Mixed:
makePinContextMenu(true, true);
break;
- case VfsItemAvailability::SomeDehydrated:
- makePinContextMenu(true, true);
- break;
+ case VfsItemAvailability::AllDehydrated:
case VfsItemAvailability::OnlineOnly:
makePinContextMenu(true, false);
break;