From 3e5766be47e7b30e07f4bb77f43a66e4d875bc28 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 15:57:26 +0800 Subject: [PATCH 1/9] Reintegrate eviction dialog button Signed-off-by: Claudio Cambra --- src/gui/macOS/ui/FileProviderStorageInfo.qml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/macOS/ui/FileProviderStorageInfo.qml b/src/gui/macOS/ui/FileProviderStorageInfo.qml index 9189507239273..2830309b30982 100644 --- a/src/gui/macOS/ui/FileProviderStorageInfo.qml +++ b/src/gui/macOS/ui/FileProviderStorageInfo.qml @@ -31,7 +31,7 @@ GridLayout { required property real remoteUsedStorage Layout.fillWidth: true - columns: 2 + columns: 3 EnforcedPlainTextLabel { Layout.row: 0 @@ -51,6 +51,14 @@ GridLayout { horizontalAlignment: Text.AlignRight } + CustomButton { + Layout.row: 0 + Layout.column: 2 + Layout.alignment: Layout.AlignRight | Layout.AlignVCenter + text: qsTr("Evict local copies...") + onPressed: root.evictDialogRequested() + } + ProgressBar { Layout.row: 1 Layout.columnSpan: root.columns From 60f116cdd43b369de741d101fa2b6609b2e0e6e9 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 15:58:19 +0800 Subject: [PATCH 2/9] Implement eviction capabilities in FileProviderItem Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderItem.swift | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderItem.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderItem.swift index 9dc4dbbb5f35b..eea2b950c572b 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderItem.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderItem.swift @@ -32,13 +32,25 @@ class FileProviderItem: NSObject, NSFileProviderItem { var capabilities: NSFileProviderItemCapabilities { guard !metadata.directory else { - return [ - .allowsAddingSubItems, - .allowsContentEnumerating, - .allowsReading, - .allowsDeleting, - .allowsRenaming, - ] + if #available(macOS 13.0, *) { + // .allowsEvicting deprecated on macOS 13.0+, use contentPolicy instead + return [ + .allowsAddingSubItems, + .allowsContentEnumerating, + .allowsReading, + .allowsDeleting, + .allowsRenaming + ] + } else { + return [ + .allowsAddingSubItems, + .allowsContentEnumerating, + .allowsReading, + .allowsDeleting, + .allowsRenaming, + .allowsEvicting + ] + } } guard !metadata.lock else { return [.allowsReading] @@ -49,6 +61,7 @@ class FileProviderItem: NSObject, NSFileProviderItem { .allowsDeleting, .allowsRenaming, .allowsReparenting, + .allowsEvicting ] } @@ -133,6 +146,11 @@ class FileProviderItem: NSObject, NSFileProviderItem { } } + @available(macOSApplicationExtension 13.0, *) + var contentPolicy: NSFileProviderContentPolicy { + .downloadLazily + } + required init( metadata: NextcloudItemMetadataTable, parentItemIdentifier: NSFileProviderItemIdentifier, From 9f4e87dc1f86d6b2b7dca5c0340b1f9ce3b09638 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 16:50:53 +0800 Subject: [PATCH 3/9] Fix header text color property Signed-off-by: Claudio Cambra --- theme/Style/Style.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml index 7410faa60a2a9..8fd90e0a0f6ed 100644 --- a/theme/Style/Style.qml +++ b/theme/Style/Style.qml @@ -10,6 +10,7 @@ QtObject { // Colors readonly property color ncBlue: Theme.wizardHeaderBackgroundColor + readonly property color ncHeaderTextColor: Theme.wizardHeaderTitleColor readonly property color ncTextColor: Theme.systemPalette.windowText readonly property color ncTextBrightColor: "white" readonly property color ncSecondaryTextColor: "#808080" From bf4fc01b39e0d0e8c7b68dcadf55a0d8995a27ef Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 16:51:58 +0800 Subject: [PATCH 4/9] Extract enumeration of materialised files for each domain manager into a separate slot Signed-off-by: Claudio Cambra --- .../fileprovidersettingscontroller_mac.mm | 89 ++++++++++--------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index cd3749df5d1d3..b18a25d7a85db 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -185,6 +185,53 @@ void signalFileProviderDomain(const QString &userIdAtHost) const return _fileProviderDomainSyncStatuses.value(userIdAtHost); } +public slots: + void enumerateMaterialisedFilesForDomainManager(NSFileProviderManager * const managerForDomain, + NSFileProviderDomain * const domain) + { + const id enumerator = [managerForDomain enumeratorForMaterializedItems]; + Q_ASSERT(enumerator != nil); + [enumerator retain]; + + FileProviderStorageUseEnumerationObserver *const storageUseObserver = [[FileProviderStorageUseEnumerationObserver alloc] init]; + [storageUseObserver retain]; + storageUseObserver.enumerationFinishedHandler = ^(NSError *const error) { + qCInfo(lcFileProviderSettingsController) << "Enumeration finished for" << domain.identifier; + if (error != nil) { + qCWarning(lcFileProviderSettingsController) << "Error while enumerating storage use" << error.localizedDescription; + [storageUseObserver release]; + [enumerator release]; + return; + } + + const auto items = storageUseObserver.materialisedItems; + Q_ASSERT(items != nil); + + // Remember that OCC::Account::userIdAtHost == domain.identifier for us + const auto qDomainIdentifier = QString::fromNSString(domain.identifier); + QVector qMaterialisedItems; + qMaterialisedItems.reserve(items.count); + for (const id item in items) { + const auto itemMetadata = FileProviderItemMetadata::fromNSFileProviderItem(item, qDomainIdentifier); + const auto storageUsage = _storageUsage.value(qDomainIdentifier) + itemMetadata.documentSize(); + qCDebug(lcFileProviderSettingsController) << "Adding item" << itemMetadata.identifier() + << "with size" << itemMetadata.documentSize() + << "to storage usage for account" << qDomainIdentifier + << "with total size" << storageUsage; + qMaterialisedItems.append(itemMetadata); + _storageUsage.insert(qDomainIdentifier, storageUsage); + } + _materialisedFiles.insert(qDomainIdentifier, qMaterialisedItems); + + emit q->localStorageUsageForAccountChanged(qDomainIdentifier); + emit q->materialisedItemsForAccountChanged(qDomainIdentifier); + + [storageUseObserver release]; + [enumerator release]; + }; + [enumerator enumerateItemsForObserver:storageUseObserver startingAtPage:NSFileProviderInitialPageSortedByName]; + } + private slots: void updateDomainSyncStatuses() { @@ -237,47 +284,7 @@ void fetchMaterialisedFilesStorageUsage() return; } - const id enumerator = [managerForDomain enumeratorForMaterializedItems]; - Q_ASSERT(enumerator != nil); - [enumerator retain]; - - FileProviderStorageUseEnumerationObserver *const storageUseObserver = [[FileProviderStorageUseEnumerationObserver alloc] init]; - [storageUseObserver retain]; - storageUseObserver.enumerationFinishedHandler = ^(NSError *const error) { - qCInfo(lcFileProviderSettingsController) << "Enumeration finished for" << domain.identifier; - if (error != nil) { - qCWarning(lcFileProviderSettingsController) << "Error while enumerating storage use" << error.localizedDescription; - [storageUseObserver release]; - [enumerator release]; - return; - } - - const auto items = storageUseObserver.materialisedItems; - Q_ASSERT(items != nil); - - // Remember that OCC::Account::userIdAtHost == domain.identifier for us - const auto qDomainIdentifier = QString::fromNSString(domain.identifier); - QVector qMaterialisedItems; - qMaterialisedItems.reserve(items.count); - for (const id item in items) { - const auto itemMetadata = FileProviderItemMetadata::fromNSFileProviderItem(item, qDomainIdentifier); - const auto storageUsage = _storageUsage.value(qDomainIdentifier) + itemMetadata.documentSize(); - qCDebug(lcFileProviderSettingsController) << "Adding item" << itemMetadata.identifier() - << "with size" << itemMetadata.documentSize() - << "to storage usage for account" << qDomainIdentifier - << "with total size" << storageUsage; - qMaterialisedItems.append(itemMetadata); - _storageUsage.insert(qDomainIdentifier, storageUsage); - } - _materialisedFiles.insert(qDomainIdentifier, qMaterialisedItems); - - emit q->localStorageUsageForAccountChanged(qDomainIdentifier); - emit q->materialisedItemsForAccountChanged(qDomainIdentifier); - - [storageUseObserver release]; - [enumerator release]; - }; - [enumerator enumerateItemsForObserver:storageUseObserver startingAtPage:NSFileProviderInitialPageSortedByName]; + enumerateMaterialisedFilesForDomainManager(managerForDomain, domain); } }]; } From 69a3f286c0b83157be4cf131d8e7a2847bfcb11f Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 16:52:33 +0800 Subject: [PATCH 5/9] Add slot to file provider settings controller to refresh materialised items for account Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersettingscontroller.h | 1 + src/gui/macOS/fileprovidersettingscontroller_mac.mm | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/gui/macOS/fileprovidersettingscontroller.h b/src/gui/macOS/fileprovidersettingscontroller.h index 43d17c04361a2..2cb37aa1ba54a 100644 --- a/src/gui/macOS/fileprovidersettingscontroller.h +++ b/src/gui/macOS/fileprovidersettingscontroller.h @@ -55,6 +55,7 @@ public slots: void setFastEnumerationEnabledForAccount(const QString &userIdAtHost, const bool setEnabled); void createEvictionWindowForAccount(const QString &userIdAtHost); + void refreshMaterialisedItemsForAccount(const QString &userIdAtHost); void signalFileProviderDomain(const QString &userIdAtHost); void createDebugArchive(const QString &userIdAtHost); diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index b18a25d7a85db..87be8bd039347 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -468,6 +468,12 @@ void initialCheck() dialog->show(); } +void FileProviderSettingsController::refreshMaterialisedItemsForAccount(const QString &userIdAtHost) +{ + d->enumerateMaterialisedFilesForDomainManager(FileProviderUtils::managerForDomainIdentifier(userIdAtHost), + FileProviderUtils::domainForIdentifier(userIdAtHost)); +} + void FileProviderSettingsController::signalFileProviderDomain(const QString &userIdAtHost) { d->signalFileProviderDomain(userIdAtHost); From 1e96c0f1f9c11e5cf0603ab6a71dceeae93a3fc0 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 16:55:51 +0800 Subject: [PATCH 6/9] Add title and reload button to file provider eviction dialog Signed-off-by: Claudio Cambra --- .../macOS/ui/FileProviderEvictionDialog.qml | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/gui/macOS/ui/FileProviderEvictionDialog.qml b/src/gui/macOS/ui/FileProviderEvictionDialog.qml index 5884b63770a9b..b1d1d5dece4ed 100644 --- a/src/gui/macOS/ui/FileProviderEvictionDialog.qml +++ b/src/gui/macOS/ui/FileProviderEvictionDialog.qml @@ -33,13 +33,41 @@ ApplicationWindow { width: 640 height: 480 - ListView { + ColumnLayout { anchors.fill: parent - model: root.materialisedItemsModel - delegate: FileProviderFileDelegate { - width: parent.width - height: 60 - onEvictItem: root.materialisedItemsModel.evictItem(identifier, domainIdentifier) + + RowLayout { + Layout.fillWidth: true + Layout.margins: Style.standardSpacing + + EnforcedPlainTextLabel { + text: qsTr("Materialised items") + font.bold: true + font.pointSize: Style.headerFontPtSize + Layout.fillWidth: true + } + + CustomButton { + padding: Style.smallSpacing + textColor: Style.ncTextColor + textColorHovered: Style.ncHeaderTextColor + contentsFont.bold: true + bgColor: Style.ncBlue + text: qsTr("Reload") + } + } + + ListView { + Layout.fillWidth: true + Layout.fillHeight: true + + clip: true + model: root.materialisedItemsModel + delegate: FileProviderFileDelegate { + width: parent.width + height: 60 + onEvictItem: root.materialisedItemsModel.evictItem(identifier, domainIdentifier) + } } } } From 19d1971612252b9fb6cd628225427a800a1fe3c5 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 16:56:14 +0800 Subject: [PATCH 7/9] Enable reloading of materialised items model from within file provider eviction dialog Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersettingscontroller_mac.mm | 5 ++++- src/gui/macOS/ui/FileProviderEvictionDialog.qml | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index 87be8bd039347..5e6f89241f5a8 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -442,7 +442,8 @@ void initialCheck() const auto model = new FileProviderMaterialisedItemsModel(this); model->setItems(items); - connect(this, &FileProviderSettingsController::materialisedItemsForAccountChanged, model, [this, model, userIdAtHost](const QString &accountUserIdAtHost) { + connect(this, &FileProviderSettingsController::materialisedItemsForAccountChanged, + model, [this, model, userIdAtHost](const QString &accountUserIdAtHost) { if (accountUserIdAtHost != userIdAtHost) { return; } @@ -464,6 +465,8 @@ void initialCheck() {fpMaterialisedItemsModelProp, QVariant::fromValue(model)}, }); const auto dialog = qobject_cast(genericDialog); + QObject::connect(dialog, SIGNAL(reloadMaterialisedItems(QString)), + this, SLOT(refreshMaterialisedItemsForAccount(QString))); Q_ASSERT(dialog); dialog->show(); } diff --git a/src/gui/macOS/ui/FileProviderEvictionDialog.qml b/src/gui/macOS/ui/FileProviderEvictionDialog.qml index b1d1d5dece4ed..15e2b2056114d 100644 --- a/src/gui/macOS/ui/FileProviderEvictionDialog.qml +++ b/src/gui/macOS/ui/FileProviderEvictionDialog.qml @@ -25,6 +25,8 @@ import com.nextcloud.desktopclient 1.0 ApplicationWindow { id: root + signal reloadMaterialisedItems(string accountUserIdAtHost) + property var materialisedItemsModel: null property string accountUserIdAtHost: "" @@ -33,6 +35,8 @@ ApplicationWindow { width: 640 height: 480 + Component.onCompleted: reloadMaterialisedItems(accountUserIdAtHost) + ColumnLayout { anchors.fill: parent @@ -54,6 +58,7 @@ ApplicationWindow { contentsFont.bold: true bgColor: Style.ncBlue text: qsTr("Reload") + onClicked: reloadMaterialisedItems(accountUserIdAtHost) } } From 5f243a86d467f8d2f44b94c31f58076fcf1117a0 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 16:59:07 +0800 Subject: [PATCH 8/9] Use palette background color for file provider eviction dialog Signed-off-by: Claudio Cambra --- src/gui/macOS/ui/FileProviderEvictionDialog.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/macOS/ui/FileProviderEvictionDialog.qml b/src/gui/macOS/ui/FileProviderEvictionDialog.qml index 15e2b2056114d..674d6b94d5ef9 100644 --- a/src/gui/macOS/ui/FileProviderEvictionDialog.qml +++ b/src/gui/macOS/ui/FileProviderEvictionDialog.qml @@ -31,6 +31,7 @@ ApplicationWindow { property string accountUserIdAtHost: "" title: qsTr("Evict materialised files") + color: Style.backgroundColor flags: Qt.Dialog | Qt.WindowStaysOnTopHint width: 640 height: 480 From fe53933b044fc9fbc9063026ffdc5d2efe608716 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 20 Feb 2024 17:09:10 +0800 Subject: [PATCH 9/9] Improve design of materialised file delegates Signed-off-by: Claudio Cambra --- src/gui/macOS/ui/FileProviderEvictionDialog.qml | 3 +++ src/gui/macOS/ui/FileProviderFileDelegate.qml | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/macOS/ui/FileProviderEvictionDialog.qml b/src/gui/macOS/ui/FileProviderEvictionDialog.qml index 674d6b94d5ef9..01db805c8bb53 100644 --- a/src/gui/macOS/ui/FileProviderEvictionDialog.qml +++ b/src/gui/macOS/ui/FileProviderEvictionDialog.qml @@ -67,6 +67,9 @@ ApplicationWindow { Layout.fillWidth: true Layout.fillHeight: true + Layout.leftMargin: Style.standardSpacing + Layout.rightMargin: Style.standardSpacing + clip: true model: root.materialisedItemsModel delegate: FileProviderFileDelegate { diff --git a/src/gui/macOS/ui/FileProviderFileDelegate.qml b/src/gui/macOS/ui/FileProviderFileDelegate.qml index 25d812f6623e0..d364a364c3744 100644 --- a/src/gui/macOS/ui/FileProviderFileDelegate.qml +++ b/src/gui/macOS/ui/FileProviderFileDelegate.qml @@ -90,11 +90,12 @@ Item { id: deleteButton Layout.minimumWidth: implicitWidth - Layout.fillHeight: true Layout.alignment: Qt.AlignRight | Qt.AlignVCenter text: qsTr("Delete") + textColorHovered: Style.ncHeaderTextColor bgColor: Style.errorBoxBackgroundColor + contentsFont.bold: true onClicked: root.evictItem(root.identifier, root.domainIdentifier) } }