From 8886d1b9253452f9fa5ec8a27852ee813a160b37 Mon Sep 17 00:00:00 2001 From: Zhang Sheng Date: Sat, 7 Dec 2024 13:40:41 +0800 Subject: [PATCH 1/7] fix: cannot append file to deepin-comprssor deepin-compressor is no longer a linglong app! Log: fix bug Bug: https://pms.uniontech.com/bug-view-286519.html --- .../appendcompress/appendcompresshelper.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/plugins/common/dfmplugin-utils/appendcompress/appendcompresshelper.cpp b/src/plugins/common/dfmplugin-utils/appendcompress/appendcompresshelper.cpp index 5a63a78aa9..e3e6dd2298 100644 --- a/src/plugins/common/dfmplugin-utils/appendcompress/appendcompresshelper.cpp +++ b/src/plugins/common/dfmplugin-utils/appendcompress/appendcompresshelper.cpp @@ -63,19 +63,11 @@ bool AppendCompressHelper::dragDropCompress(const QUrl &toUrl, const QList bool AppendCompressHelper::appendCompress(const QString &toFilePath, const QStringList &fromFilePaths) { - QStringList arguments; - QString cmd = "deepin-compressor"; -#ifdef COMPILE_ON_V2X - cmd = "ll-cli"; - arguments << "run"; - arguments << "org.deepin.compressor"; - arguments << "--exec"; - arguments << "deepin-compressor"; -#endif - arguments << toFilePath; + QStringList arguments { toFilePath }; arguments << fromFilePaths; arguments << "dragdropadd"; - return QProcess::startDetached(cmd, arguments); + + return QProcess::startDetached("deepin-compressor", arguments); } bool AppendCompressHelper::canAppendCompress(const QList &fromUrls, const QUrl &toUrl) From 853ace35c3b3eea8543363b6819eb4fa930f521d Mon Sep 17 00:00:00 2001 From: Zhang Sheng Date: Sat, 7 Dec 2024 14:29:15 +0800 Subject: [PATCH 2/7] fix: optimize property dialog height and scrolling behavior - Add proper scroll bar policy for vertical scrolling - Fix dialog height calculation to respect screen boundaries - Add size policies to maintain proper widget dimensions - Set maximum width for dialog content - Improve height adjustment logic for both Wayland and X11 - Fix content widget resizing and geometry updates Log: fix ui bug Bug: https://pms.uniontech.com/bug-view-287197.html --- .../views/filepropertydialog.cpp | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp b/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp index 2a0302de6a..cd9acd7b5f 100644 --- a/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp +++ b/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp @@ -68,9 +68,13 @@ void FilePropertyDialog::initInfoUI() scrollArea->viewport()->setPalette(palette); scrollArea->setFrameShape(QFrame::Shape::NoFrame); scrollArea->setWidgetResizable(true); - scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); + scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); QFrame *mainWidget = new QFrame(this); + mainWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + mainWidget->setMaximumWidth(kDialogWidth); + QVBoxLayout *scrollWidgetLayout = new QVBoxLayout; scrollWidgetLayout->setContentsMargins(10, 0, 10, 10); scrollWidgetLayout->setSpacing(kArrowExpandSpacing); @@ -78,6 +82,9 @@ void FilePropertyDialog::initInfoUI() scrollArea->setWidget(mainWidget); + scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + scrollArea->setMaximumWidth(kDialogWidth); + QVBoxLayout *vlayout1 = new QVBoxLayout; vlayout1->addWidget(scrollArea); vlayout1->setContentsMargins(0, 0, 0, 0); @@ -232,16 +239,23 @@ void FilePropertyDialog::processHeight(int height) Q_UNUSED(height) QRect rect = geometry(); - if (WindowUtils::isWayLand()) { - int logicHeight = contentHeight() + kArrowExpandSpacing; - int screenHeight = WindowUtils::cursorScreen()->availableSize().height(); - int realHeight = logicHeight > screenHeight ? screenHeight : logicHeight; - rect.setHeight(realHeight); - } else { - rect.setHeight(contentHeight() + kArrowExpandSpacing); - } + int screenHeight = WindowUtils::cursorScreen()->availableSize().height(); + screenHeight -= 100; + int contentH = contentHeight() + kArrowExpandSpacing; + int maxHeight = qMin(contentH, screenHeight); + rect.setHeight(maxHeight); setGeometry(rect); + + if (scrollArea) { + QWidget *content = scrollArea->widget(); + if (content) { + content->setMinimumHeight(0); + content->adjustSize(); + content->updateGeometry(); + } + scrollArea->updateGeometry(); + } } void FilePropertyDialog::insertExtendedControl(int index, QWidget *widget) From 6428d2f87e2b8b6f1cf42b33749b1cddaa819376 Mon Sep 17 00:00:00 2001 From: Zhang Sheng Date: Sat, 7 Dec 2024 17:02:55 +0800 Subject: [PATCH 3/7] fix: update dlnfs mount dbus interface name - Update dbus interface name from com.deepin.filemanager.daemon to org.deepin.Filemanager.MountControl - Update dbus object path accordingly - Add dlnfs package dependency in debian/control This change fixes compatibility issues with the new dlnfs dbus interface naming convention. Log: Bug: https://pms.uniontech.com/bug-view-273567.html --- assets/scripts/dfm-dlnfs-automount | 6 +++--- debian/control | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/assets/scripts/dfm-dlnfs-automount b/assets/scripts/dfm-dlnfs-automount index ab883cc27b..93192036e9 100755 --- a/assets/scripts/dfm-dlnfs-automount +++ b/assets/scripts/dfm-dlnfs-automount @@ -46,9 +46,9 @@ if [ "$dlnfs_enable" == "true" ]; then # do dlnfs mount for $abs_path. gdbus call -y \ - -d com.deepin.filemanager.daemon \ - -o /com/deepin/filemanager/daemon/MountControl \ - -m com.deepin.filemanager.daemon.MountControl.Mount \ + -d org.deepin.Filemanager.MountControl \ + -o /org/deepin/Filemanager/MountControl \ + -m org.deepin.Filemanager.MountControl.Mount \ "${abs_path}" \ "{'fsType': <'dlnfs'>}" \ -t 1 diff --git a/debian/control b/debian/control index 3f371017a9..b40dcecd37 100644 --- a/debian/control +++ b/debian/control @@ -126,7 +126,8 @@ Depends: libpoppler-cpp0v5 (>= 0.48.0), gvfs-backends (>=1.27.3), cryptsetup, - libdfm-extension (=${binary:Version}) + libdfm-extension (=${binary:Version}), + dlnfs | hello Multi-Arch: same Description: DDE File Manager core librarys This package contains the shared libraries. From 738a1f4f8254b92d835476f044779276753ec923 Mon Sep 17 00:00:00 2001 From: Zhang Sheng Date: Mon, 9 Dec 2024 10:23:40 +0800 Subject: [PATCH 4/7] fix: optimize property dialog layout stretch handling - Move stretch item management to showEvent - Remove redundant stretch item before adding new one - Fix potential memory leak by properly deleting old stretch item This change ensures proper layout spacing in the property dialog and prevents multiple stretch items from being added unintentionally. Log: --- .../views/filepropertydialog.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp b/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp index cd9acd7b5f..e6f063870b 100644 --- a/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp +++ b/src/plugins/common/dfmplugin-propertydialog/views/filepropertydialog.cpp @@ -28,6 +28,7 @@ #include #include #include +#include DWIDGET_USE_NAMESPACE DFMBASE_USE_NAMESPACE @@ -130,7 +131,6 @@ void FilePropertyDialog::createPermissionManagerWidget(const QUrl &url) QVBoxLayout *vlayout = qobject_cast(scrollArea->widget()->layout()); if (vlayout) { insertExtendedControl(vlayout->count(), permissionManagerWidget); - vlayout->addStretch(); } } @@ -314,6 +314,22 @@ void FilePropertyDialog::resizeEvent(QResizeEvent *event) void FilePropertyDialog::showEvent(QShowEvent *event) { DDialog::showEvent(event); + + QVBoxLayout *vlayout = qobject_cast(scrollArea->widget()->layout()); + if (vlayout) { + if (vlayout->count() > 0) { + QLayoutItem *item = vlayout->itemAt(vlayout->count() - 1); + if (item && item->spacerItem()) { + vlayout->removeItem(item); + delete item; + } + } + vlayout->addStretch(); + } + + QTimer::singleShot(0, this, [this]() { + processHeight(contentHeight()); + }); } void FilePropertyDialog::closeEvent(QCloseEvent *event) From d33c52db92e423c20466f16130a531b595bbadc6 Mon Sep 17 00:00:00 2001 From: Zhang Sheng Date: Mon, 9 Dec 2024 16:02:06 +0800 Subject: [PATCH 5/7] refactor: improve trash operation permission check - Replace manual symlink and home path check with proper canTrash attribute check - Simplify trash permission validation logic by removing redundant conditions - Use FileInfo's canAttributes API instead of manual path checks - Remove unnecessary supportTrash validation since it's handled by canTrash check This change makes the code more maintainable and follows the proper attribute checking pattern defined in the FileInfo interface. Log: --- src/dfm-base/utils/fileutils.cpp | 6 +++--- .../fileoperationsevent/trashfileeventreceiver.cpp | 10 ++-------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/dfm-base/utils/fileutils.cpp b/src/dfm-base/utils/fileutils.cpp index ac810aa33b..8bf1066fbf 100644 --- a/src/dfm-base/utils/fileutils.cpp +++ b/src/dfm-base/utils/fileutils.cpp @@ -363,7 +363,7 @@ bool FileUtils::isSameFile(const QUrl &url1, const QUrl &url2, const Global::Cre return isSameFile(path1, path2); } -bool FileUtils::isSameFile(const QString &path1, const QString &path2) +bool FileUtils::isSameFile(const QString &path1, const QString &path2) { struct stat stat1; struct stat stat2; @@ -372,7 +372,7 @@ bool FileUtils::isSameFile(const QString &path1, const QString &path2) if (0 == ret1 && 0 == ret2) { // 通过inode判断是否是同一个文件 return (stat1.st_ino == stat2.st_ino - && stat1.st_dev == stat2.st_dev); //! 需要判断设备号 + && stat1.st_dev == stat2.st_dev); //! 需要判断设备号 } return false; @@ -1333,7 +1333,7 @@ bool FileUtils::fileCanTrash(const QUrl &url) // 获取当前配置 bool alltotrash = DConfigManager::instance()->value(kDefaultCfgPath, kFileAllTrash).toBool(); if (!alltotrash) - return info ? info->extendAttributes(ExtInfoType::kFileLocalDevice).toBool() : isLocalDevice(url); + return info ? info->canAttributes(CanableInfoType::kCanTrash) : false; if (!url.isValid()) return false; diff --git a/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp b/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp index 645f23257a..582a0fc851 100644 --- a/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp +++ b/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp @@ -81,14 +81,8 @@ JobHandlePointer TrashFileEventReceiver::doMoveToTrash(const quint64 windowId, c && !info->isAttributes(OptInfoType::kIsSymLink) && !info->isAttributes(OptInfoType::kIsWritable); } - const auto &sourceInfo = InfoFactory::create(sourceFirst); - bool canTrash = false; - auto filesource = FileUtils::bindUrlTransform(sourceFirst); - if (sourceInfo) - canTrash = sourceInfo->isAttributes(OptInfoType::kIsSymLink) - && filesource.path().startsWith(StandardPaths::location(StandardPaths::StandardLocation::kHomePath)); - if (nullDirDelete || !FileUtils::fileCanTrash(sourceFirst) || - (!dfmio::DFMUtils::supportTrash(sourceFirst) && !canTrash)) { + + if (nullDirDelete || !FileUtils::fileCanTrash(sourceFirst)) { if (DialogManagerInstance->showDeleteFilesDialog(sources, true) != QDialog::Accepted) return nullptr; handle = copyMoveJob->deletes(sources, flags, isInit); From 1f50549ceb0a0a163f800cfeaad4bef1429a7e95 Mon Sep 17 00:00:00 2001 From: Zhang Sheng Date: Mon, 9 Dec 2024 17:09:26 +0800 Subject: [PATCH 6/7] fix: correct path handling for symlinks in trash operations - Add canonicalUrlList utility to properly handle symlink paths - Preserve symlink's original path while resolving parent directory - Process source URLs before trash operations to ensure correct paths - Handle symlinks in directories that are themselves symlinks This fixes an issue where symlinks would be incorrectly resolved when moving to trash, especially when the symlink is located in a directory that is also a symlink. The new implementation maintains the symlink's identity while ensuring its parent path is properly resolved. Log: fix bug Bug: https://pms.uniontech.com/bug-view-287739.html --- src/dfm-base/utils/systempathutil.cpp | 41 ++++++++++++++++++- src/dfm-base/utils/systempathutil.h | 3 ++ .../trashfileeventreceiver.cpp | 12 +++--- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/dfm-base/utils/systempathutil.cpp b/src/dfm-base/utils/systempathutil.cpp index 38db10ae06..9eb67a8506 100644 --- a/src/dfm-base/utils/systempathutil.cpp +++ b/src/dfm-base/utils/systempathutil.cpp @@ -144,7 +144,7 @@ bool SystemPathUtil::checkContainsSystemPathByFileInfo(const QList &urlLis bool SystemPathUtil::checkContainsSystemPathByFileUrl(const QList &urlList) { - return std::any_of(urlList.begin(), urlList.end(),[this](const QUrl &url){ + return std::any_of(urlList.begin(), urlList.end(), [this](const QUrl &url) { return isSystemPath(url.path()); }); } @@ -169,7 +169,7 @@ QString SystemPathUtil::findSystemPathKey(const QString &path) const if (targetPath.endsWith(sysPath)) return FileUtils::isSameFile(targetPath, sysPath); - + return false; }); @@ -202,3 +202,40 @@ void SystemPathUtil::loadSystemPaths() mkPath(path); } } + +QList SystemPathUtil::canonicalUrlList(const QList &urls) +{ + QList processedUrls; + processedUrls.reserve(urls.size()); + + for (const QUrl &url : urls) { + if (!url.isLocalFile()) { + processedUrls << url; + continue; + } + + auto info = InfoFactory::create(url); + if (!info) { + processedUrls << url; + continue; + } + + // 如果是符号链接文件 + if (info->isAttributes(OptInfoType::kIsSymLink)) { + // 获取链接文件所在目录的真实路径 + QString parentPath = QFileInfo(url.path()).dir().canonicalPath(); + // 获取链接文件的名称 + QString fileName = QFileInfo(url.path()).fileName(); + // 组合出正确的路径 + QString realLinkPath = parentPath + "/" + fileName; + processedUrls << QUrl::fromLocalFile(realLinkPath); + continue; + } + + // 非符号链接使用canonicalFilePath + const QString canonicalPath = QFileInfo(url.path()).canonicalFilePath(); + processedUrls << (canonicalPath.isEmpty() ? url : QUrl::fromLocalFile(canonicalPath)); + } + + return processedUrls; +} diff --git a/src/dfm-base/utils/systempathutil.h b/src/dfm-base/utils/systempathutil.h index fa8265eecc..ecf2a6cb88 100644 --- a/src/dfm-base/utils/systempathutil.h +++ b/src/dfm-base/utils/systempathutil.h @@ -30,6 +30,9 @@ class SystemPathUtil final : public QObject bool isSystemPath(QString path) const; bool checkContainsSystemPath(const QList &urlList); + // 将URL列表转换为规范路径,保持符号链接的原始路径 + static QList canonicalUrlList(const QList &urls); + private: explicit SystemPathUtil(QObject *parent = nullptr); ~SystemPathUtil(); diff --git a/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp b/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp index 582a0fc851..cc81b40cab 100644 --- a/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp +++ b/src/plugins/common/dfmplugin-fileoperations/fileoperationsevent/trashfileeventreceiver.cpp @@ -72,10 +72,12 @@ JobHandlePointer TrashFileEventReceiver::doMoveToTrash(const quint64 windowId, c return nullptr; } - const QUrl &sourceFirst = sources.first(); + // gio can only handle canonical file paths + QList processedSources = SystemPathUtil::canonicalUrlList(sources); + const QUrl &sourceFirst = processedSources.first(); JobHandlePointer handle = nullptr; bool nullDirDelete = false; - if (sources.count() == 1) { + if (processedSources.count() == 1) { auto info = InfoFactory::create(sourceFirst); nullDirDelete = info && info->isAttributes(OptInfoType::kIsDir) && !info->isAttributes(OptInfoType::kIsSymLink) @@ -83,14 +85,14 @@ JobHandlePointer TrashFileEventReceiver::doMoveToTrash(const quint64 windowId, c } if (nullDirDelete || !FileUtils::fileCanTrash(sourceFirst)) { - if (DialogManagerInstance->showDeleteFilesDialog(sources, true) != QDialog::Accepted) + if (DialogManagerInstance->showDeleteFilesDialog(processedSources, true) != QDialog::Accepted) return nullptr; - handle = copyMoveJob->deletes(sources, flags, isInit); + handle = copyMoveJob->deletes(processedSources, flags, isInit); if (!isInit) return handle; } else { // check url permission - QList urlsCanTrash = sources; + QList urlsCanTrash = processedSources; if (!flags.testFlag(AbstractJobHandler::JobFlag::kRevocation) && Application::instance()->genericAttribute(Application::kShowDeleteConfirmDialog).toBool()) { if (DialogManagerInstance->showNormalDeleteConfirmDialog(urlsCanTrash) != QDialog::Accepted) return nullptr; From 950ee736de44a87d4d1327fe435644ece6da3f1d Mon Sep 17 00:00:00 2001 From: Zhang Sheng Date: Mon, 9 Dec 2024 17:17:57 +0800 Subject: [PATCH 7/7] chore: remove redundant Conflicts fields in debian/control - Remove unnecessary Conflicts fields since Replaces is sufficient - Remove Conflicts with dde-desktop-plugins as it's already covered by Replaces - Remove duplicate package conflicts that are handled by Replaces - Remove redundant Conflicts with dfmplugin-disk-encrypt The Replaces field already handles package replacement properly, making the Conflicts declarations redundant in these cases. This simplifies the package relationships while maintaining the same functionality. Log: --- debian/control | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/debian/control b/debian/control index b40dcecd37..b5942e4bfc 100644 --- a/debian/control +++ b/debian/control @@ -76,7 +76,7 @@ Depends: libqt6sql6-sqlite, qt6-translations-l10n, libimageeditor6 | hello -Conflicts: dde-workspace (<< 2.90.5), dde-file-manager-oem, dde-desktop-plugins +Conflicts: dde-workspace (<< 2.90.5), dde-file-manager-oem Replaces: dde-file-manager-oem, dde-file-manager (<< 6.0.1), dde-desktop-plugins Recommends: qt5dxcb-plugin, deepin-screensaver, dcc-wallpapersetting-plugin Description: deepin desktop-environment - desktop module @@ -109,11 +109,6 @@ Replaces: dde-file-manager-oem, dde-desktop (<< 6.0.1), dde-file-manager-plugins, dde-file-manager-daemon-plugins, dde-file-manager-common-plugins -Conflicts: dde-file-manager-preview, - dde-file-manager-preview-plugins, - dde-file-manager-plugins, - dde-file-manager-daemon-plugins, - dde-file-manager-common-plugins Recommends: dde-qt5integration, avfs, samba, deepin-anything-server Description: File manager front end File manager front-end of Deepin OS @@ -132,7 +127,6 @@ Multi-Arch: same Description: DDE File Manager core librarys This package contains the shared libraries. Replaces: dfmplugin-disk-encrypt -Conflicts: dfmplugin-disk-encrypt Package: dde-disk-mount-plugin Architecture: any