diff --git a/resources.qrc b/resources.qrc index 8771c776a0..2681104929 100644 --- a/resources.qrc +++ b/resources.qrc @@ -61,8 +61,5 @@ src/gui/ConflictItemFileInfo.qml src/gui/macOS/ui/FileProviderSettings.qml src/gui/macOS/ui/FileProviderFileDelegate.qml - src/gui/macOS/ui/FileProviderEvictionDialog.qml - src/gui/macOS/ui/FileProviderSyncStatus.qml - src/gui/macOS/ui/FileProviderStorageInfo.qml diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 9ce24e95a0..ba94c3bd92 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -302,17 +302,12 @@ IF( APPLE ) macOS/fileprovider_mac.mm macOS/fileproviderdomainmanager.h macOS/fileproviderdomainmanager_mac.mm - macOS/fileproviderdomainsyncstatus.h - macOS/fileproviderdomainsyncstatus_mac.mm macOS/fileprovidereditlocallyjob.h macOS/fileprovidereditlocallyjob.cpp macOS/fileprovidereditlocallyjob_mac.mm macOS/fileprovideritemmetadata.h macOS/fileprovideritemmetadata.cpp macOS/fileprovideritemmetadata_mac.mm - macOS/fileprovidermaterialiseditemsmodel.h - macOS/fileprovidermaterialiseditemsmodel.cpp - macOS/fileprovidermaterialiseditemsmodel_mac.mm macOS/fileprovidersettingscontroller.h macOS/fileprovidersettingscontroller_mac.mm macOS/fileprovidersocketcontroller.h @@ -320,8 +315,6 @@ IF( APPLE ) macOS/fileprovidersocketserver.h macOS/fileprovidersocketserver.cpp macOS/fileprovidersocketserver_mac.mm - macOS/fileproviderstorageuseenumerationobserver.h - macOS/fileproviderstorageuseenumerationobserver.m macOS/fileproviderutils.h macOS/fileproviderutils_mac.mm macOS/fileproviderxpc.h diff --git a/src/gui/macOS/fileproviderdomainsyncstatus.h b/src/gui/macOS/fileproviderdomainsyncstatus.h deleted file mode 100644 index d036d16eb7..0000000000 --- a/src/gui/macOS/fileproviderdomainsyncstatus.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include -#include - -#pragma once - -namespace OCC::Mac -{ - -class FileProviderDomainSyncStatus : public QObject -{ - Q_OBJECT - QML_ELEMENT - QML_UNCREATABLE("FileProviderDomainSyncStatus cannot be instantiated from QML") - Q_PROPERTY(bool syncing READ syncing NOTIFY syncingChanged) - Q_PROPERTY(bool downloading READ downloading NOTIFY downloadingChanged) - Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged) - Q_PROPERTY(double fractionCompleted READ fractionCompleted NOTIFY fractionCompletedChanged) - Q_PROPERTY(double downloadFractionCompleted READ downloadFractionCompleted NOTIFY downloadFractionCompletedChanged) - Q_PROPERTY(double uploadFractionCompleted READ uploadFractionCompleted NOTIFY uploadFractionCompletedChanged) - Q_PROPERTY(int downloadFileTotalCount READ downloadFileTotalCount NOTIFY downloadFileTotalCountChanged) - Q_PROPERTY(int downloadFileCompletedCount READ downloadFileCompletedCount NOTIFY downloadFileCompletedCountChanged) - Q_PROPERTY(int uploadFileTotalCount READ uploadFileTotalCount NOTIFY uploadFileTotalCountChanged) - Q_PROPERTY(int uploadFileCompletedCount READ uploadFileCompletedCount NOTIFY uploadFileCompletedCountChanged) - // TODO: more detailed reporting (time remaining, megabytes, etc.) - Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged) - -public: - explicit FileProviderDomainSyncStatus(const QString &domainIdentifier, QObject *parent = nullptr); - ~FileProviderDomainSyncStatus() override; - - [[nodiscard]] bool syncing() const; - [[nodiscard]] bool downloading() const; - [[nodiscard]] bool uploading() const; - [[nodiscard]] double fractionCompleted() const; - [[nodiscard]] double downloadFractionCompleted() const; - [[nodiscard]] double uploadFractionCompleted() const; - [[nodiscard]] int downloadFileTotalCount() const; - [[nodiscard]] int downloadFileCompletedCount() const; - [[nodiscard]] int uploadFileTotalCount() const; - [[nodiscard]] int uploadFileCompletedCount() const; - [[nodiscard]] QUrl icon() const; - -signals: - void syncingChanged(bool syncing); - void downloadingChanged(bool downloading); - void uploadingChanged(bool uploading); - void fractionCompletedChanged(double fractionCompleted); - void downloadFractionCompletedChanged(double downloadFractionCompleted); - void uploadFractionCompletedChanged(double uploadFractionCompleted); - void downloadFileTotalCountChanged(int downloadFileTotalCount); - void downloadFileCompletedCountChanged(int downloadFileCompletedCount); - void uploadFileTotalCountChanged(int uploadFileTotalCount); - void uploadFileCompletedCountChanged(int uploadFileCompletedCount); - void iconChanged(const QUrl &icon); - -private: - void setDownloading(const bool syncing); - void setUploading(const bool syncing); - void setDownloadFractionCompleted(const double fractionCompleted); - void setUploadFractionCompleted(const double fractionCompleted); - void setDownloadFileTotalCount(const int fileTotalCount); - void setDownloadFileCompletedCount(const int fileCompletedCount); - void setUploadFileTotalCount(const int fileTotalCount); - void setUploadFileCompletedCount(const int fileCompletedCount); - void setIcon(const QUrl &icon); - void updateIcon(); - - bool _downloading = false; - bool _uploading = false; - double _downloadFractionCompleted = 0.0; - double _uploadFractionCompleted = 0.0; - int _downloadFileTotalCount = 0; - int _downloadFileCompletedCount = 0; - int _uploadFileTotalCount = 0; - int _uploadFileCompletedCount = 0; - QUrl _icon; - - class MacImplementation; - std::unique_ptr d; -}; - -} // OCC::Mac - -Q_DECLARE_METATYPE(OCC::Mac::FileProviderDomainSyncStatus*) diff --git a/src/gui/macOS/fileproviderdomainsyncstatus_mac.mm b/src/gui/macOS/fileproviderdomainsyncstatus_mac.mm deleted file mode 100644 index affd83f397..0000000000 --- a/src/gui/macOS/fileproviderdomainsyncstatus_mac.mm +++ /dev/null @@ -1,261 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "fileproviderdomainsyncstatus.h" - -#include - -#include "gui/macOS/fileproviderutils.h" -#include "libsync/theme.h" - -#import - -#import "gui/macOS/progressobserver.h" - -namespace OCC::Mac -{ - -Q_LOGGING_CATEGORY(lcMacFileProviderDomainSyncStatus, "nextcloud.gui.macfileproviderdomainsyncstatus", QtInfoMsg) - -class FileProviderDomainSyncStatus::MacImplementation -{ -public: - explicit MacImplementation(const QString &domainIdentifier, FileProviderDomainSyncStatus *parent) - : q(parent) - { - _domain = FileProviderUtils::domainForIdentifier(domainIdentifier); - _manager = [NSFileProviderManager managerForDomain:_domain]; - - if (_manager == nil) { - qCWarning(lcMacFileProviderDomainSyncStatus) << "Could not get manager for domain" << domainIdentifier; - return; - } - [_manager retain]; - - if (@available(macOS 11.3, *)) { - NSProgress *const downloadProgress = [_manager globalProgressForKind:NSProgressFileOperationKindDownloading]; - NSProgress *const uploadProgress = [_manager globalProgressForKind:NSProgressFileOperationKindUploading]; - _downloadProgressObserver = [[ProgressObserver alloc] initWithProgress:downloadProgress]; - _uploadProgressObserver = [[ProgressObserver alloc] initWithProgress:uploadProgress]; - - _downloadProgressObserver.progressKVOChangeHandler = ^(NSProgress *const progress){ - updateDownload(progress); - }; - _uploadProgressObserver.progressKVOChangeHandler = ^(NSProgress *const progress){ - updateUpload(progress); - }; - } - } - - ~MacImplementation() - { - [_downloadProgressObserver release]; - [_uploadProgressObserver release]; - [_domain release]; - [_manager release]; - } - - void updateDownload(NSProgress *const progress) const - { - qCInfo(lcMacFileProviderDomainSyncStatus) << "Download progress changed" << progress.localizedDescription; - if (progress == nil || q == nullptr) { - return; - } - - q->setDownloading(!progress.paused && !progress.cancelled && !progress.finished); - q->setDownloadFractionCompleted(progress.fractionCompleted); - q->setDownloadFileTotalCount(progress.fileTotalCount.intValue); - q->setDownloadFileCompletedCount(progress.fileCompletedCount.intValue); - q->updateIcon(); - } - - void updateUpload(NSProgress *const progress) const - { - qCInfo(lcMacFileProviderDomainSyncStatus) << "Upload progress changed" << progress.localizedDescription; - if (progress == nil || q == nullptr) { - return; - } - - q->setUploading(!progress.paused && !progress.cancelled && !progress.finished); - q->setUploadFractionCompleted(progress.fractionCompleted); - q->setUploadFileTotalCount(progress.fileTotalCount.intValue); - q->setUploadFileCompletedCount(progress.fileCompletedCount.intValue); - q->updateIcon(); - } - -private: - NSFileProviderDomain *_domain = nil; - NSFileProviderManager *_manager = nil; - ProgressObserver *_downloadProgressObserver = nullptr; - ProgressObserver *_uploadProgressObserver = nullptr; - FileProviderDomainSyncStatus *q = nullptr; -}; - -FileProviderDomainSyncStatus::FileProviderDomainSyncStatus(const QString &domainIdentifier, QObject *parent) - : QObject(parent) - , d(std::make_unique(domainIdentifier, this)) -{ - qRegisterMetaType("FileProviderDomainSyncStatus*"); - updateIcon(); -} - -FileProviderDomainSyncStatus::~FileProviderDomainSyncStatus() = default; - -bool FileProviderDomainSyncStatus::syncing() const -{ - return downloading() || uploading(); -} - -bool FileProviderDomainSyncStatus::downloading() const -{ - return _downloading; -} - -bool FileProviderDomainSyncStatus::uploading() const -{ - return _uploading; -} - -double FileProviderDomainSyncStatus::fractionCompleted() const -{ - return (downloadFractionCompleted() + uploadFractionCompleted()) / 2; -} - -double FileProviderDomainSyncStatus::downloadFractionCompleted() const -{ - return _downloadFractionCompleted; -} - -double FileProviderDomainSyncStatus::uploadFractionCompleted() const -{ - return _uploadFractionCompleted; -} - -int FileProviderDomainSyncStatus::downloadFileTotalCount() const -{ - return _downloadFileTotalCount; -} - -int FileProviderDomainSyncStatus::downloadFileCompletedCount() const -{ - return _downloadFileCompletedCount; -} - -int FileProviderDomainSyncStatus::uploadFileTotalCount() const -{ - return _uploadFileTotalCount; -} - -int FileProviderDomainSyncStatus::uploadFileCompletedCount() const -{ - return _uploadFileCompletedCount; -} - -QUrl FileProviderDomainSyncStatus::icon() const -{ - return _icon; -} - -void FileProviderDomainSyncStatus::setDownloading(const bool downloading) -{ - if (_downloading == downloading) { - return; - } - - _downloading = downloading; - emit downloadingChanged(_downloading); - emit syncingChanged(syncing()); -} - -void FileProviderDomainSyncStatus::setUploading(const bool uploading) -{ - if (_uploading == uploading) { - return; - } - - _uploading = uploading; - emit uploadingChanged(_uploading); - emit syncingChanged(syncing()); -} - -void FileProviderDomainSyncStatus::setDownloadFractionCompleted(const double downloadFractionCompleted) -{ - if (_downloadFractionCompleted == downloadFractionCompleted) { - return; - } - - _downloadFractionCompleted = downloadFractionCompleted; - emit downloadFractionCompletedChanged(_downloadFractionCompleted); - emit fractionCompletedChanged(fractionCompleted()); -} - -void FileProviderDomainSyncStatus::setUploadFractionCompleted(const double uploadFractionCompleted) -{ - if (_uploadFractionCompleted == uploadFractionCompleted) { - return; - } - - _uploadFractionCompleted = uploadFractionCompleted; - emit uploadFractionCompletedChanged(_uploadFractionCompleted); - emit fractionCompletedChanged(fractionCompleted()); -} - -void FileProviderDomainSyncStatus::setDownloadFileTotalCount(const int fileTotalCount) -{ - if (_downloadFileTotalCount == fileTotalCount) { - return; - } - - _downloadFileTotalCount = fileTotalCount; - emit downloadFileTotalCountChanged(_downloadFileTotalCount); -} - -void FileProviderDomainSyncStatus::setDownloadFileCompletedCount(const int fileCompletedCount) -{ - if (_downloadFileCompletedCount == fileCompletedCount) { - return; - } - - _downloadFileCompletedCount = fileCompletedCount; - emit downloadFileCompletedCountChanged(_downloadFileCompletedCount); -} - -void FileProviderDomainSyncStatus::setUploadFileTotalCount(const int fileTotalCount) -{ - if (_uploadFileTotalCount == fileTotalCount) { - return; - } - - _uploadFileTotalCount = fileTotalCount; - emit uploadFileTotalCountChanged(_uploadFileTotalCount); -} - -void FileProviderDomainSyncStatus::setUploadFileCompletedCount(const int fileCompletedCount) -{ - if (_uploadFileCompletedCount == fileCompletedCount) { - return; - } - - _uploadFileCompletedCount = fileCompletedCount; - emit uploadFileCompletedCountChanged(_uploadFileCompletedCount); -} - -void FileProviderDomainSyncStatus::setIcon(const QUrl &icon) -{ - if (_icon == icon) { - return; - } - - _icon = icon; - emit iconChanged(_icon); -} - -void FileProviderDomainSyncStatus::updateIcon() -{ - const auto iconUrl = syncing() ? Theme::instance()->sync() : Theme::instance()->ok(); - setIcon(iconUrl); -} - -} // OCC::Mac diff --git a/src/gui/macOS/fileprovidermaterialiseditemsmodel.cpp b/src/gui/macOS/fileprovidermaterialiseditemsmodel.cpp deleted file mode 100644 index ce3e038de2..0000000000 --- a/src/gui/macOS/fileprovidermaterialiseditemsmodel.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "fileprovidermaterialiseditemsmodel.h" - -#include - -namespace OCC { - -namespace Mac { - -FileProviderMaterialisedItemsModel::FileProviderMaterialisedItemsModel(QObject * const parent) - : QAbstractListModel(parent) -{ -} - -int FileProviderMaterialisedItemsModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) { - return 0; - } - - return _items.count(); -} - -QVariant FileProviderMaterialisedItemsModel::data(const QModelIndex &index, int role) const -{ - const auto item = _items.at(index.row()); - - switch (role) { - case Qt::DisplayRole: - case FilenameRole: - return item.filename(); - case IdentifierRole: - return item.identifier(); - case ParentItemIdentifierRole: - return item.parentItemIdentifier(); - case DomainIdentifierRole: - return item.domainIdentifier(); - case TypeIdentifierRole: - return item.typeIdentifier(); - case SymlinkTargetPathRole: - return item.symlinkTargetPath(); - case UploadingErrorRole: - return item.uploadingError(); - case DownloadingErrorRole: - return item.downloadingError(); - case MostRecentEditorNameRole: - return item.mostRecentEditorName(); - case OwnerNameRole: - return item.ownerName(); - case ContentModificationDateRole: - return item.contentModificationDate(); - case CreationDateRole: - return item.creationDate(); - case LastUsedDateRole: - return item.lastUsedDate(); - case ContentVersionRole: - return item.contentVersion(); - case MetadataVersionRole: - return item.metadataVersion(); - case TagDataRole: - return item.tagData(); - case CapabilitiesRole: - return item.capabilities(); - case FileSystemFlagsRole: - return item.fileSystemFlags(); - case ChildItemCountRole: - return item.childItemCount(); - case TypeOsCodeRole: - return item.typeOsCode(); - case CreatorOsCodeRole: - return item.creatorOsCode(); - case DocumentSizeRole: - return item.documentSize(); - case MostRecentVersionDownloadedRole: - return item.mostRecentVersionDownloaded(); - case UploadingRole: - return item.uploading(); - case UploadedRole: - return item.uploaded(); - case DownloadingRole: - return item.downloading(); - case DownloadedRole: - return item.downloaded(); - case SharedRole: - return item.shared(); - case SharedByCurrentUserRole: - return item.sharedByCurrentUser(); - case UserVisiblePathRole: - return item.userVisiblePath(); - case FileTypeStringRole: - return item.fileTypeString(); - case FileSizeStringRole: - return _locale.formattedDataSize(item.documentSize()); - } - return {}; -} - -QHash FileProviderMaterialisedItemsModel::roleNames() const -{ - auto roleNames = QAbstractListModel::roleNames(); - roleNames.insert({ - { IdentifierRole, "identifier" }, - { ParentItemIdentifierRole, "parentItemIdentifier" }, - { DomainIdentifierRole, "domainIdentifier" }, - { FilenameRole, "fileName" }, - { TypeIdentifierRole, "typeIdentifier" }, - { SymlinkTargetPathRole, "symlinkTargetPath" }, - { UploadingErrorRole, "uploadingError" }, - { DownloadingErrorRole, "downloadingError" }, - { MostRecentEditorNameRole, "mostRecentEditorName" }, - { OwnerNameRole, "ownerName" }, - { ContentModificationDateRole, "contentModificationDate" }, - { CreationDateRole, "creationDate" }, - { LastUsedDateRole, "lastUsedDate" }, - { ContentVersionRole, "contentVersion" }, - { MetadataVersionRole, "metadataVersion" }, - { TagDataRole, "tagData" }, - { CapabilitiesRole, "capabilities" }, - { FileSystemFlagsRole, "fileSystemFlags" }, - { ChildItemCountRole, "childItemCount" }, - { TypeOsCodeRole, "typeOsCode" }, - { CreatorOsCodeRole, "creatorOsCode" }, - { DocumentSizeRole, "documentSize" }, - { MostRecentVersionDownloadedRole, "mostRecentVersionDownloaded" }, - { UploadingRole, "uploading" }, - { UploadedRole, "uploaded" }, - { DownloadingRole, "downloading" }, - { DownloadedRole, "downloaded" }, - { SharedRole, "shared" }, - { SharedByCurrentUserRole, "sharedByCurrentUser" }, - { UserVisiblePathRole, "userVisiblePath" }, - { FileTypeStringRole, "fileTypeString" }, - { FileSizeStringRole, "fileSizeString" }, - }); - return roleNames; -} - -QVector FileProviderMaterialisedItemsModel::items() const -{ - return _items; -} - -void FileProviderMaterialisedItemsModel::setItems(const QVector &items) -{ - if (items == _items) { - return; - } - - beginResetModel(); - // We are using this in the "Free up space" dialog so, sort by size. - _items = items; - std::ranges::sort(_items, [](const auto &a, const auto &b) { - return a.documentSize() > b.documentSize(); - }); - endResetModel(); - - Q_EMIT itemsChanged(); -} - -} // namespace Mac - -} // namespace OCC diff --git a/src/gui/macOS/fileprovidermaterialiseditemsmodel.h b/src/gui/macOS/fileprovidermaterialiseditemsmodel.h deleted file mode 100644 index 62f12ab753..0000000000 --- a/src/gui/macOS/fileprovidermaterialiseditemsmodel.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#pragma once - -#include -#include - -#include "gui/macOS/fileprovideritemmetadata.h" - -namespace OCC { - -namespace Mac { - -class FileProviderMaterialisedItemsModel : public QAbstractListModel -{ - Q_OBJECT - - Q_PROPERTY(QVector items READ items WRITE setItems NOTIFY itemsChanged) - -public: - enum Roles { - IdentifierRole = Qt::UserRole + 1, - ParentItemIdentifierRole, - DomainIdentifierRole, - FilenameRole, - TypeIdentifierRole, - SymlinkTargetPathRole, - UploadingErrorRole, - DownloadingErrorRole, - MostRecentEditorNameRole, - OwnerNameRole, - ContentModificationDateRole, - CreationDateRole, - LastUsedDateRole, - ContentVersionRole, - MetadataVersionRole, - TagDataRole, - CapabilitiesRole, - FileSystemFlagsRole, - ChildItemCountRole, - TypeOsCodeRole, - CreatorOsCodeRole, - DocumentSizeRole, - MostRecentVersionDownloadedRole, - UploadingRole, - UploadedRole, - DownloadingRole, - DownloadedRole, - SharedRole, - SharedByCurrentUserRole, - UserVisiblePathRole, - FileTypeStringRole, - FileSizeStringRole, - }; - Q_ENUM(Roles) - - explicit FileProviderMaterialisedItemsModel(QObject *parent = nullptr); - [[nodiscard]] int rowCount(const QModelIndex &parent = {}) const override; - [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - [[nodiscard]] QHash roleNames() const override; - - [[nodiscard]] QVector items() const; - -signals: - void itemsChanged(); - -public slots: - void setItems(const QVector &items); - void evictItem(const QString &identifier, const QString &domainIdentifier); - -private: - QVector _items; - QLocale _locale; -}; - -} // namespace Mac - -} // namespace OCC diff --git a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm b/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm deleted file mode 100644 index 624b61b6bf..0000000000 --- a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "fileprovidermaterialiseditemsmodel.h" - -#include - -#import - -#include "fileproviderutils.h" - -#include "gui/systray.h" - -namespace OCC { - -namespace Mac { - -Q_LOGGING_CATEGORY(lcMacImplFileProviderMaterialisedItemsModelMac, "nextcloud.gui.macfileprovidermaterialiseditemsmodelmac", QtInfoMsg) - -void FileProviderMaterialisedItemsModel::evictItem(const QString &identifier, const QString &domainIdentifier) -{ - NSFileProviderManager *const manager = FileProviderUtils::managerForDomainIdentifier(domainIdentifier); - if (manager == nil) { - qCWarning(lcMacImplFileProviderMaterialisedItemsModelMac) << "Received null manager for domain" - << domainIdentifier - << "cannot evict item" - << identifier; - Systray::instance()->showMessage(tr("Error"), - tr("An internal error occurred. Please try again later."), - QSystemTrayIcon::Warning); - return; - } - - __block BOOL successfullyDeleted = NO; - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - - [manager evictItemWithIdentifier:identifier.toNSString() completionHandler:^(NSError *error) { - if (error != nil) { - const auto errorDesc = QString::fromNSString(error.localizedDescription); - qCWarning(lcMacImplFileProviderMaterialisedItemsModelMac) << "Error evicting item:" << errorDesc; - Systray::instance()->showMessage(tr("Error"), - tr("An error occurred while trying to delete the local copy of this item: %1").arg(errorDesc), - QSystemTrayIcon::Warning); - } else { - successfullyDeleted = YES; - } - dispatch_semaphore_signal(semaphore); - }]; - - dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC)); - [manager release]; - - if (successfullyDeleted == NO) { - return; - } - - const auto deletedItemIt = std::find_if(_items.cbegin(), - _items.cend(), - [identifier, domainIdentifier](const FileProviderItemMetadata &item) { - return item.identifier() == identifier && item.domainIdentifier() == domainIdentifier; - }); - - if (deletedItemIt == _items.cend()) { - qCWarning(lcMacImplFileProviderMaterialisedItemsModelMac) << "Could not find item" - << identifier - << "in model items."; - return; - } - - const auto deletedItemRow = std::distance(_items.cbegin(), deletedItemIt); - beginRemoveRows({}, deletedItemRow, deletedItemRow); - _items.remove(deletedItemRow); - endRemoveRows(); -} - - -} // namespace OCC - -} // namespace Mac diff --git a/src/gui/macOS/fileprovidersettingscontroller.h b/src/gui/macOS/fileprovidersettingscontroller.h index 0633978dad..081a28c784 100644 --- a/src/gui/macOS/fileprovidersettingscontroller.h +++ b/src/gui/macOS/fileprovidersettingscontroller.h @@ -8,8 +8,6 @@ #include #include -#include "gui/macOS/fileproviderdomainsyncstatus.h" - class QAbstractListModel; namespace OCC { @@ -31,30 +29,15 @@ public: [[nodiscard]] QStringList vfsEnabledAccounts() const; [[nodiscard]] Q_INVOKABLE bool vfsEnabledForAccount(const QString &userIdAtHost) const; - [[nodiscard]] unsigned long long localStorageUsageForAccount(const QString &userIdAtHost) const; - [[nodiscard]] Q_INVOKABLE float localStorageUsageGbForAccount(const QString &userIdAtHost) const; - [[nodiscard]] unsigned long long remoteStorageUsageForAccount(const QString &userIdAtHost) const; - [[nodiscard]] Q_INVOKABLE float remoteStorageUsageGbForAccount(const QString &userIdAtHost) const; [[nodiscard]] Q_INVOKABLE bool trashDeletionEnabledForAccount(const QString &userIdAtHost) const; [[nodiscard]] Q_INVOKABLE bool trashDeletionSetForAccount(const QString &userIdAtHost) const; - [[nodiscard]] Q_INVOKABLE QAbstractListModel *materialisedItemsModelForAccount(const QString &userIdAtHost); - [[nodiscard]] Q_INVOKABLE FileProviderDomainSyncStatus *domainSyncStatusForAccount(const QString &userIdAtHost) const; - public slots: void setVfsEnabledForAccount(const QString &userIdAtHost, const bool setEnabled, const bool showInformationDialog = true); void setTrashDeletionEnabledForAccount(const QString &userIdAtHost, const bool setEnabled); - void resetVfsForAccount(const QString &userIdAtHost); - - void createEvictionWindowForAccount(const QString &userIdAtHost); - void refreshMaterialisedItemsForAccount(const QString &userIdAtHost); - void signalFileProviderDomain(const QString &userIdAtHost); signals: void vfsEnabledAccountsChanged(); - void localStorageUsageForAccountChanged(const QString &userIdAtHost); - void remoteStorageUsageForAccountChanged(const QString &userIdAtHost); - void materialisedItemsForAccountChanged(const QString &userIdAtHost); void trashDeletionEnabledForAccountChanged(const QString &userIdAtHost); void trashDeletionSetForAccountChanged(const QString &userIdAtHost); diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index 8a19ba10f3..1b7abf3858 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -12,31 +12,21 @@ #include "gui/userinfo.h" #include "gui/macOS/fileprovider.h" #include "gui/macOS/fileprovideritemmetadata.h" -#include "gui/macOS/fileprovidermaterialiseditemsmodel.h" #include "gui/macOS/fileproviderutils.h" // Objective-C imports #import - -#import "fileproviderstorageuseenumerationobserver.h" // End of Objective-C imports namespace { constexpr auto fpSettingsQmlPath = "qrc:/qml/src/gui/macOS/ui/FileProviderSettings.qml"; -constexpr auto fpEvictionDialogQmlPath = "qrc:/qml/src/gui/macOS/ui/FileProviderEvictionDialog.qml"; // QML properties -- make sure they match up in QML file! constexpr auto fpAccountUserIdAtHostProp = "accountUserIdAtHost"; -constexpr auto fpMaterialisedItemsModelProp = "materialisedItemsModel"; // NSUserDefaults entries constexpr auto enabledAccountsSettingsKey = "enabledAccounts"; -float gbFromBytesWithOneDecimal(const unsigned long long bytes) -{ - constexpr auto bytesIn100Mb = 1ULL * 1000ULL * 1000ULL * 100ULL; - return ((bytes * 1.0) / bytesIn100Mb) / 10.0; -} } // namespace namespace OCC { @@ -57,7 +47,6 @@ public: { q = parent; initialCheck(); - fetchMaterialisedFilesStorageUsage(); }; ~MacImplementation() override = default; @@ -146,161 +135,18 @@ public: return overallActResult; } - [[nodiscard]] unsigned long long localStorageUsageForAccount(const QString &userIdAtHost) const - { - // Return cached value as we fetch asynchronously on initialisation of this class. - // We will then emit a signal when the new value is found. - return _storageUsage.value(userIdAtHost); - } - - [[nodiscard]] QVector materialisedItemsForAccount(const QString &userIdAtHost) const - { - return _materialisedFiles.value(userIdAtHost); - } - - void signalFileProviderDomain(const QString &userIdAtHost) const - { - qCInfo(lcFileProviderSettingsController) << "Signalling file provider domain" << userIdAtHost; - NSFileProviderDomain * const domain = FileProviderUtils::domainForIdentifier(userIdAtHost); - NSFileProviderManager * const manager = [NSFileProviderManager managerForDomain:domain]; - [domain release]; - [manager signalEnumeratorForContainerItemIdentifier:NSFileProviderRootContainerItemIdentifier - completionHandler:^(NSError *const error) { - if (error != nil) { - qCWarning(lcFileProviderSettingsController) << "Could not signal file provider domain, error" - << error.localizedDescription; - return; - } - - qCInfo(lcFileProviderSettingsController) << "Successfully signalled file provider domain"; - // TODO: Provide some feedback in the UI - }]; - } - - [[nodiscard]] FileProviderDomainSyncStatus *domainSyncStatusForAccount(const QString &userIdAtHost) const - { - return _fileProviderDomainSyncStatuses.value(userIdAtHost); - } - -public slots: - // NOTE: This method will release the provided args so make sure to retain them beforehand - 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.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); - unsigned long long storageUsage = 0; - for (const id item in items) { - const auto itemMetadata = FileProviderItemMetadata::fromNSFileProviderItem(item, qDomainIdentifier); - storageUsage += 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]; - - [managerForDomain release]; - [domain release]; - }; - [enumerator enumerateItemsForObserver:storageUseObserver startingAtPage:NSFileProviderInitialPageSortedByName]; - } - -private slots: - void updateDomainSyncStatuses() - { - qCInfo(lcFileProviderSettingsController) << "Updating file provider domain sync statuses."; - _fileProviderDomainSyncStatuses.clear(); - const auto enabledAccounts = nsEnabledAccounts(); - - for (NSString *const accountIdentifier in enabledAccounts) { - const auto qAccountIdentifier = QString::fromNSString(accountIdentifier); - const auto domainIdentifier = FileProviderUtils::domainIdentifierForAccountIdentifier(accountIdentifier); - const auto syncStatus = new FileProviderDomainSyncStatus(domainIdentifier, q); - _fileProviderDomainSyncStatuses.insert(qAccountIdentifier, syncStatus); - } - } - private: [[nodiscard]] NSArray *nsEnabledAccounts() const { return (NSArray *)[_userDefaults objectForKey:_accountsKey]; } - void fetchMaterialisedFilesStorageUsage() - { - qCInfo(lcFileProviderSettingsController) << "Fetching used storage space of materialized items."; - - [NSFileProviderManager getDomainsWithCompletionHandler: ^(NSArray *const domains, NSError *const error) { - if (error != nil) { - qCWarning(lcFileProviderSettingsController) << "Could not get file provider domains:" - << error.localizedDescription - << "Will try again in 2 secs"; - - // HACK: Sometimes the system is not in a state where it wants to give us access to - // the file provider domains. We will try again in 2 seconds and hope it works - const auto thisQobject = (QObject*)this; - dispatch_async(dispatch_get_main_queue(), ^{ - [NSTimer scheduledTimerWithTimeInterval:2 repeats:NO block:^(NSTimer *const timer) { - Q_UNUSED(timer) - QMetaObject::invokeMethod(thisQobject, [this] { fetchMaterialisedFilesStorageUsage(); }); - }]; - }); - return; - } - - for (NSFileProviderDomain *const domain in domains) { - qCInfo(lcFileProviderSettingsController) << "Checking storage use for domain:" << domain.identifier; - - NSFileProviderManager *const managerForDomain = [NSFileProviderManager managerForDomain:domain]; - if (managerForDomain == nil) { - qCWarning(lcFileProviderSettingsController) << "Got a nil file provider manager for domain" - << domain.identifier - << ", returning early."; - return; - } - [managerForDomain retain]; - [domain retain]; - enumerateMaterialisedFilesForDomainManager(managerForDomain, domain); - } - }]; - } - void initialCheck() { qCInfo(lcFileProviderSettingsController) << "Running initial checks for file provider settings controller."; NSArray *const vfsEnabledAccounts = nsEnabledAccounts(); if (vfsEnabledAccounts != nil) { - updateDomainSyncStatuses(); - connect(q, &FileProviderSettingsController::vfsEnabledAccountsChanged, this, &MacImplementation::updateDomainSyncStatuses); return; } @@ -313,9 +159,7 @@ private: FileProviderSettingsController *q = nullptr; NSUserDefaults *_userDefaults = NSUserDefaults.standardUserDefaults; NSString *_accountsKey = [NSString stringWithUTF8String:enabledAccountsSettingsKey]; - QHash> _materialisedFiles; QHash _storageUsage; - QHash _fileProviderDomainSyncStatuses; }; FileProviderSettingsController *FileProviderSettingsController::instance() @@ -337,9 +181,6 @@ FileProviderSettingsController::FileProviderSettingsController(QObject *parent) const auto accountUserIdAtHost = account->userIdAtHostWithPort(); _userInfos.insert(accountUserIdAtHost, userInfo); - connect(userInfo, &UserInfo::fetchedLastInfo, this, [this, accountUserIdAtHost] { - emit remoteStorageUsageForAccountChanged(accountUserIdAtHost); - }); userInfo->setActive(true); } } @@ -383,6 +224,10 @@ void FileProviderSettingsController::setVfsEnabledForAccount(const QString &user bool FileProviderSettingsController::trashDeletionEnabledForAccount(const QString &userIdAtHost) const { + if (userIdAtHost.isEmpty()) { + return false; + } + const auto xpc = FileProvider::instance()->xpc(); if (!xpc) { @@ -434,140 +279,6 @@ void FileProviderSettingsController::setTrashDeletionEnabledForAccount(const QSt emit trashDeletionSetForAccountChanged(userIdAtHost); } -unsigned long long FileProviderSettingsController::localStorageUsageForAccount(const QString &userIdAtHost) const -{ - return d->localStorageUsageForAccount(userIdAtHost); -} - -float FileProviderSettingsController::localStorageUsageGbForAccount(const QString &userIdAtHost) const -{ - return gbFromBytesWithOneDecimal(localStorageUsageForAccount(userIdAtHost)); -} - -unsigned long long FileProviderSettingsController::remoteStorageUsageForAccount(const QString &userIdAtHost) const -{ - const auto userInfoForAccount = _userInfos.value(userIdAtHost); - if (!userInfoForAccount) { - return 0; - } - - return userInfoForAccount->lastQuotaUsedBytes(); -} - -float FileProviderSettingsController::remoteStorageUsageGbForAccount(const QString &userIdAtHost) const -{ - return gbFromBytesWithOneDecimal(remoteStorageUsageForAccount(userIdAtHost)); -} - -QAbstractListModel *FileProviderSettingsController::materialisedItemsModelForAccount(const QString &userIdAtHost) -{ - const auto items = d->materialisedItemsForAccount(userIdAtHost); - if (items.isEmpty()) { - return nullptr; - } - - const auto model = new FileProviderMaterialisedItemsModel(this); - model->setItems(items); - - connect(this, &FileProviderSettingsController::materialisedItemsForAccountChanged, - model, [this, model, userIdAtHost](const QString &accountUserIdAtHost) { - if (accountUserIdAtHost != userIdAtHost) { - return; - } - - const auto items = d->materialisedItemsForAccount(userIdAtHost); - model->setItems(items); - }); - - return model; -} - -void FileProviderSettingsController::createEvictionWindowForAccount(const QString &userIdAtHost) -{ - const auto engine = Systray::instance()->trayEngine(); - QQmlComponent component(engine, QUrl(fpEvictionDialogQmlPath)); - const auto model = materialisedItemsModelForAccount(userIdAtHost); - const auto genericDialog = component.createWithInitialProperties({ - {fpAccountUserIdAtHostProp, userIdAtHost}, - {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(); -} - -void FileProviderSettingsController::refreshMaterialisedItemsForAccount(const QString &userIdAtHost) -{ - d->enumerateMaterialisedFilesForDomainManager(FileProviderUtils::managerForDomainIdentifier(userIdAtHost), - FileProviderUtils::domainForIdentifier(userIdAtHost)); -} - -void FileProviderSettingsController::signalFileProviderDomain(const QString &userIdAtHost) -{ - d->signalFileProviderDomain(userIdAtHost); -} - -FileProviderDomainSyncStatus *FileProviderSettingsController::domainSyncStatusForAccount(const QString &userIdAtHost) const -{ - return d->domainSyncStatusForAccount(userIdAtHost); -} - -void FileProviderSettingsController::resetVfsForAccount(const QString &userIdAtHost) -{ - qCInfo(lcFileProviderSettingsController) << "Resetting virtual files environment for account" << userIdAtHost; - setVfsEnabledForAccount(userIdAtHost, false); - - const auto accountState = AccountManager::instance()->accountFromUserId(userIdAtHost); - if (!accountState) { - qCWarning(lcFileProviderSettingsController) << "Could not find account for userIdAtHost" << userIdAtHost - << "to reset VFS environment."; - return; - } - const auto splitUserId = userIdAtHost.split('@'); - if (splitUserId.size() != 2) { - qCWarning(lcFileProviderSettingsController) << "Invalid userIdAtHost format" << userIdAtHost - << "Expected format: userId@host"; - return; - } - const auto accUserId = splitUserId.at(0); - const auto accHost = splitUserId.at(1); - - // Delete the database in the group container - const auto groupContainerPath = FileProviderUtils::groupContainerPath(); - if (groupContainerPath.isEmpty()) { - qCWarning(lcFileProviderSettingsController) << "Could not determine group container path, cannot reset VFS."; - return; - } - const auto dbsPath = QDir::cleanPath(groupContainerPath + "/FileProviderExt/Database"); - qCInfo(lcFileProviderSettingsController) << "Resetting VFS for account" << userIdAtHost - << "by deleting database files in" << dbsPath; - const auto databases = QDir(dbsPath).entryList(QDir::Files); - for (const auto &dbFile : databases) { - // Format of db file names is "userId_cloud_nc_com-fileproviderextdatabase.realm" - const auto splitDbName = dbFile.split('-'); - const auto address = splitDbName.at(0).split('_').mid(1).join('.'); - const auto userId = splitDbName.at(0).split('_').first(); - - if (userId != accUserId || address != accHost) { - qCInfo(lcFileProviderSettingsController) << "Skipping database file" << dbFile - << "for userId" << userId - << "and host" << address - << "as it does not match the account we are resetting."; - continue; // Not the database we are looking for - } - - const auto dbPath = QDir(dbsPath).filePath(dbFile); - qCInfo(lcFileProviderSettingsController) << "Deleting database file" << dbPath; - if (QFile::exists(dbPath)) { - QFile::remove(dbPath); - } - } - - setVfsEnabledForAccount(userIdAtHost, true); -} - } // namespace Mac } // namespace OCC diff --git a/src/gui/macOS/fileproviderstorageuseenumerationobserver.h b/src/gui/macOS/fileproviderstorageuseenumerationobserver.h deleted file mode 100644 index 4d483ce565..0000000000 --- a/src/gui/macOS/fileproviderstorageuseenumerationobserver.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#import -#import - -typedef void(^UsageEnumerationFinishedHandler)(NSError *const error); - -@interface FileProviderStorageUseEnumerationObserver : NSObject - -@property (readwrite, strong) UsageEnumerationFinishedHandler enumerationFinishedHandler; -@property (readonly) NSSet> *materialisedItems; - -@end diff --git a/src/gui/macOS/fileproviderstorageuseenumerationobserver.m b/src/gui/macOS/fileproviderstorageuseenumerationobserver.m deleted file mode 100644 index c275367073..0000000000 --- a/src/gui/macOS/fileproviderstorageuseenumerationobserver.m +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#import "fileproviderstorageuseenumerationobserver.h" - -@implementation FileProviderStorageUseEnumerationObserver - -- (instancetype)init -{ - self = [super init]; - if (self) { - _materialisedItems = [NSSet set]; - } - return self; -} - -// NSFileProviderEnumerationObserver protocol methods -- (void)didEnumerateItems:(NSArray> *)updatedItems -{ - NSMutableSet> * const existingItems = self.materialisedItems.mutableCopy; - - for (const id item in updatedItems) { - NSLog(@"StorageUseEnumerationObserver: Enumerating %@ with size %llu", - item.filename, item.documentSize.unsignedLongLongValue); - [existingItems addObject:item]; - } - - _materialisedItems = existingItems.copy; -} - -- (void)finishEnumeratingWithError:(NSError *)error -{ - dispatch_async(dispatch_get_main_queue(), ^{ - self.enumerationFinishedHandler(error); - }); -} - -- (void)finishEnumeratingUpToPage:(NSFileProviderPage)nextPage -{ - dispatch_async(dispatch_get_main_queue(), ^{ - self.enumerationFinishedHandler(nil); - }); -} - -@end diff --git a/src/gui/macOS/ui/FileProviderEvictionDialog.qml b/src/gui/macOS/ui/FileProviderEvictionDialog.qml deleted file mode 100644 index 1becc03016..0000000000 --- a/src/gui/macOS/ui/FileProviderEvictionDialog.qml +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 - -import Style 1.0 -import "../../filedetails" -import "../../tray" - -import com.nextcloud.desktopclient 1.0 - -ApplicationWindow { - id: root - - signal reloadMaterialisedItems(string accountUserIdAtHost) - - property var materialisedItemsModel: null - property string accountUserIdAtHost: "" - - LayoutMirroring.enabled: Application.layoutDirection === Qt.RightToLeft - LayoutMirroring.childrenInherit: true - - title: qsTr("Remove local copies") - color: palette.base - flags: Qt.Dialog | Qt.WindowStaysOnTopHint - width: 640 - height: 480 - - Component.onCompleted: reloadMaterialisedItems(accountUserIdAtHost) - - ColumnLayout { - anchors.fill: parent - - RowLayout { - Layout.fillWidth: true - Layout.margins: Style.standardSpacing - - EnforcedPlainTextLabel { - text: qsTr("Local copies") - font.bold: true - font.pointSize: Style.headerFontPtSize - Layout.fillWidth: true - } - - Button { - padding: Style.smallSpacing - 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) - } - } - } -} diff --git a/src/gui/macOS/ui/FileProviderSettings.qml b/src/gui/macOS/ui/FileProviderSettings.qml index ef78665bbe..e15b3ec63e 100644 --- a/src/gui/macOS/ui/FileProviderSettings.qml +++ b/src/gui/macOS/ui/FileProviderSettings.qml @@ -53,63 +53,11 @@ Page { checked: root.controller.vfsEnabledForAccount(root.accountUserIdAtHost) onClicked: root.controller.setVfsEnabledForAccount(root.accountUserIdAtHost, checked) } - - Loader { - id: vfsSettingsLoader - - Layout.fillWidth: true - Layout.fillHeight: true - - active: vfsEnabledCheckBox.checked - sourceComponent: ColumnLayout { - Rectangle { - Layout.fillWidth: true - height: Style.normalBorderWidth - color: palette.dark - } - - FileProviderSyncStatus { - syncStatus: root.controller.domainSyncStatusForAccount(root.accountUserIdAtHost) - onDomainSignalRequested: root.controller.signalFileProviderDomain(root.accountUserIdAtHost) - } - - FileProviderStorageInfo { - id: storageInfo - localUsedStorage: root.controller.localStorageUsageGbForAccount(root.accountUserIdAtHost) - remoteUsedStorage: root.controller.remoteStorageUsageGbForAccount(root.accountUserIdAtHost) - - onEvictDialogRequested: root.controller.createEvictionWindowForAccount(root.accountUserIdAtHost) - - Connections { - target: root.controller - - function onLocalStorageUsageForAccountChanged(accountUserIdAtHost) { - if (root.accountUserIdAtHost !== accountUserIdAtHost) { - return; - } - storageInfo.localUsedStorage = root.controller.localStorageUsageGbForAccount(root.accountUserIdAtHost); - } - - function onRemoteStorageUsageForAccountChanged(accountUserIdAtHost) { - if (root.accountUserIdAtHost !== accountUserIdAtHost) { - return; - } - storageInfo.remoteUsedStorage = root.controller.remoteStorageUsageGbForAccount(root.accountUserIdAtHost); - } - } - } - - CheckBox { - text: qsTr("Allow deletion of items in Trash") - checked: root.controller.trashDeletionEnabledForAccount(root.accountUserIdAtHost) - onClicked: root.controller.setTrashDeletionEnabledForAccount(root.accountUserIdAtHost, checked) - } - - Button { - text: qsTr("Reset virtual files environment") - onPressed: root.controller.resetVfsForAccount(root.accountUserIdAtHost); - } - } + + CheckBox { + text: qsTr("Allow deletion of items in Trash") + checked: root.controller.trashDeletionEnabledForAccount(root.accountUserIdAtHost) + onClicked: root.controller.setTrashDeletionEnabledForAccount(root.accountUserIdAtHost, checked) } } } diff --git a/src/gui/macOS/ui/FileProviderStorageInfo.qml b/src/gui/macOS/ui/FileProviderStorageInfo.qml deleted file mode 100644 index 3c316d78f0..0000000000 --- a/src/gui/macOS/ui/FileProviderStorageInfo.qml +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 - -import Style 1.0 -import "../../filedetails" -import "../../tray" - -import com.nextcloud.desktopclient 1.0 - -GridLayout { - id: root - - signal evictDialogRequested() - - required property real localUsedStorage - required property real remoteUsedStorage - - Layout.fillWidth: true - columns: 3 - - EnforcedPlainTextLabel { - Layout.row: 0 - Layout.column: 0 - Layout.alignment: Layout.AlignLeft | Layout.AlignVCenter - text: qsTr("Local storage use") - font.bold: true - } - - EnforcedPlainTextLabel { - Layout.row: 0 - Layout.column: 1 - Layout.alignment: Layout.AlignRight | Layout.AlignVCenter - Layout.fillWidth: true - text: qsTr("%1 GB of %2 GB remote files synced").arg(root.localUsedStorage.toFixed(2)).arg(root.remoteUsedStorage.toFixed(2)); - elide: Text.ElideRight - color: palette.dark - horizontalAlignment: Text.AlignRight - } - - Button { - Layout.row: 0 - Layout.column: 2 - Layout.alignment: Layout.AlignRight | Layout.AlignVCenter - text: qsTr("Free up space …") - onPressed: root.evictDialogRequested() - } - - ProgressBar { - Layout.row: 1 - Layout.columnSpan: root.columns - Layout.fillWidth: true - value: root.localUsedStorage / root.remoteUsedStorage - } -} diff --git a/src/gui/macOS/ui/FileProviderSyncStatus.qml b/src/gui/macOS/ui/FileProviderSyncStatus.qml deleted file mode 100644 index 523e7275ed..0000000000 --- a/src/gui/macOS/ui/FileProviderSyncStatus.qml +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 - -import Style 1.0 -import "../../filedetails" -import "../../tray" - -import com.nextcloud.desktopclient 1.0 - -GridLayout { - id: root - - signal domainSignalRequested - required property var syncStatus - - rows: syncStatus.syncing ? 2 : 1 - - NCBusyIndicator { - id: syncIcon - - property int size: Style.trayListItemIconSize * 0.8 - - Layout.row: 0 - Layout.rowSpan: root.syncStatus.syncing ? 2 : 1 - Layout.column: 0 - Layout.preferredWidth: size - Layout.preferredHeight: size - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - - padding: 0 - spacing: 0 - imageSource: root.syncStatus.icon - running: false // avoid rotating the icon when syncing - } - - EnforcedPlainTextLabel { - Layout.row: 0 - Layout.column: 1 - Layout.columnSpan: root.syncStatus.syncing ? 2 : 1 - Layout.fillWidth: true - font.bold: true - font.pointSize: Style.headerFontPtSize - text: root.syncStatus.syncing ? qsTr("Syncing") : qsTr("All synced!") - } - - NCProgressBar { - Layout.row: 1 - Layout.column: 1 - Layout.fillWidth: true - value: root.syncStatus.fractionCompleted - visible: root.syncStatus.syncing - } - - Button { - id: requestSyncButton - text: qsTr("Request sync") - visible: !root.syncStatus.syncing - hoverEnabled: true - onClicked: root.domainSignalRequested() - - ToolTip.visible: hovered - ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval - ToolTip.text: qsTr("Request a sync of changes for the VFS environment.\nmacOS may ignore or delay this request.") - } -} diff --git a/translations/client_en.ts b/translations/client_en.ts index 44b760a8b6..b1e5600285 100644 --- a/translations/client_en.ts +++ b/translations/client_en.ts @@ -332,53 +332,6 @@ Allow deletion of items in Trash - - - Reset virtual files environment - - - - - FileProviderStorageInfo - - - Local storage use - - - - - %1 GB of %2 GB remote files synced - - - - - Free up space … - - - - - FileProviderSyncStatus - - - Syncing - - - - - All synced! - - - - - Request sync - - - - - Request a sync of changes for the VFS environment. -macOS may ignore or delay this request. - - FileSystem