Skip to content

Commit

Permalink
Merge pull request #6467 from nextcloud/feature/file-provide-file-evi…
Browse files Browse the repository at this point in the history
…ction
  • Loading branch information
claucambra committed Mar 7, 2024
2 parents 2e5aa59 + fe53933 commit 0e301e7
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -49,6 +61,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
.allowsDeleting,
.allowsRenaming,
.allowsReparenting,
.allowsEvicting
]
}

Expand Down Expand Up @@ -133,6 +146,11 @@ class FileProviderItem: NSObject, NSFileProviderItem {
}
}

@available(macOSApplicationExtension 13.0, *)
var contentPolicy: NSFileProviderContentPolicy {
.downloadLazily
}

required init(
metadata: NextcloudItemMetadataTable,
parentItemIdentifier: NSFileProviderItemIdentifier,
Expand Down
1 change: 1 addition & 0 deletions src/gui/macOS/fileprovidersettingscontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
100 changes: 58 additions & 42 deletions src/gui/macOS/fileprovidersettingscontroller_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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<NSFileProviderEnumerator> 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<FileProviderItemMetadata> qMaterialisedItems;
qMaterialisedItems.reserve(items.count);
for (const id<NSFileProviderItem> 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()
{
Expand Down Expand Up @@ -237,47 +284,7 @@ void fetchMaterialisedFilesStorageUsage()
return;
}

const id<NSFileProviderEnumerator> 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<FileProviderItemMetadata> qMaterialisedItems;
qMaterialisedItems.reserve(items.count);
for (const id<NSFileProviderItem> 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);
}
}];
}
Expand Down Expand Up @@ -435,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;
}
Expand All @@ -457,10 +465,18 @@ void initialCheck()
{fpMaterialisedItemsModelProp, QVariant::fromValue(model)},
});
const auto dialog = qobject_cast<QQuickWindow *>(genericDialog);
QObject::connect(dialog, SIGNAL(reloadMaterialisedItems(QString)),
this, SLOT(refreshMaterialisedItemsForAccount(QString)));
Q_ASSERT(dialog);
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);
Expand Down
49 changes: 43 additions & 6 deletions src/gui/macOS/ui/FileProviderEvictionDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,58 @@ import com.nextcloud.desktopclient 1.0
ApplicationWindow {
id: root

signal reloadMaterialisedItems(string accountUserIdAtHost)

property var materialisedItemsModel: null
property string accountUserIdAtHost: ""

title: qsTr("Evict materialised files")
color: Style.backgroundColor
flags: Qt.Dialog | Qt.WindowStaysOnTopHint
width: 640
height: 480

ListView {
Component.onCompleted: reloadMaterialisedItems(accountUserIdAtHost)

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")
onClicked: reloadMaterialisedItems(accountUserIdAtHost)
}
}

ListView {
Layout.fillWidth: true
Layout.fillHeight: true

Layout.leftMargin: Style.standardSpacing
Layout.rightMargin: Style.standardSpacing

clip: true
model: root.materialisedItemsModel
delegate: FileProviderFileDelegate {
width: parent.width
height: 60
onEvictItem: root.materialisedItemsModel.evictItem(identifier, domainIdentifier)
}
}
}
}
3 changes: 2 additions & 1 deletion src/gui/macOS/ui/FileProviderFileDelegate.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/gui/macOS/ui/FileProviderStorageInfo.qml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ GridLayout {
required property real remoteUsedStorage

Layout.fillWidth: true
columns: 2
columns: 3

EnforcedPlainTextLabel {
Layout.row: 0
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions theme/Style/Style.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 0e301e7

Please sign in to comment.