From 1ec70aee6f3ab76601cb6c9c7302bd49bbea0a4c Mon Sep 17 00:00:00 2001 From: Lighto-Ku Date: Mon, 1 Jul 2024 17:13:27 +0800 Subject: [PATCH] refactor: [workspace] show workspace file list reimpl workspace in qml, and set base workspace into mainwindow. Log: refactor workspace --- include/dfm-gui/appletfactory.h | 2 + src/dfm-gui/appletfactory.cpp | 54 +++--- src/dfm-gui/windowmanager.cpp | 2 +- .../core/dfmplugin-core/FileWindow.qml | 11 +- .../core/dfmplugin-sidebar/Sidebar.qml | 10 +- .../core/dfmplugin-workspace/CMakeLists.txt | 1 + .../core/dfmplugin-workspace/Workspace.qml | 41 ---- .../dfmplugin_workspace_global.h | 4 +- .../fileviewcontainment.cpp | 26 +++ .../dfmplugin-workspace/fileviewcontainment.h | 29 +++ .../models/fileitemdata.cpp | 8 +- .../models/fileviewmodel.cpp | 175 +++++++++++------- .../models/fileviewmodel.h | 17 +- .../dfmplugin-workspace/models/rootinfo.cpp | 13 +- .../core/dfmplugin-workspace/qml/FileView.qml | 36 ++++ .../qml/ListItemDelegate.qml | 46 +++++ .../dfmplugin-workspace/qml/ViewContainer.qml | 42 +++++ .../dfmplugin-workspace/qml/Workspace.qml | 33 ++++ .../dfmplugin-workspace/qml/WorkspacePage.qml | 40 ++++ .../utils/fileoperatorhelper.cpp | 84 +++++++-- .../utils/fileoperatorhelper.h | 1 + .../utils/filesortworker.cpp | 26 ++- .../utils/workspacehelper.cpp | 3 + .../utils/workspacemanager.cpp | 87 +++++++++ .../utils/workspacemanager.h | 43 +++++ .../core/dfmplugin-workspace/workspace.cpp | 21 ++- .../core/dfmplugin-workspace/workspace.h | 3 + .../core/dfmplugin-workspace/workspace.json | 5 +- .../workspacecontainment.cpp | 57 ++++++ .../workspacecontainment.h | 38 ++++ .../dfmplugin-workspace/workspacepage.cpp | 47 +++++ .../core/dfmplugin-workspace/workspacepage.h | 37 ++++ 32 files changed, 856 insertions(+), 186 deletions(-) delete mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/Workspace.qml create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.cpp create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.h create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/qml/FileView.qml create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/qml/ListItemDelegate.qml create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/qml/ViewContainer.qml create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/qml/Workspace.qml create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/qml/WorkspacePage.qml create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.cpp create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.h create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.cpp create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.h create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.cpp create mode 100644 src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.h diff --git a/include/dfm-gui/appletfactory.h b/include/dfm-gui/appletfactory.h index 4162013341..11b3223657 100644 --- a/include/dfm-gui/appletfactory.h +++ b/include/dfm-gui/appletfactory.h @@ -24,6 +24,8 @@ class AppletFactory bool regCreator(const QString &id, CreateFunc creator, QString *errorString = nullptr); Applet *create(const QString &id, Containment *parent = nullptr, QString *errorString = nullptr); + QUrl pluginComponent(const QString &plugin, const QString &qmlFile, QString *errorString = nullptr) const; + private: explicit AppletFactory(); QScopedPointer d; diff --git a/src/dfm-gui/appletfactory.cpp b/src/dfm-gui/appletfactory.cpp index ad214be661..60e54d5d44 100644 --- a/src/dfm-gui/appletfactory.cpp +++ b/src/dfm-gui/appletfactory.cpp @@ -86,6 +86,32 @@ Applet *AppletFactory::create(const QString &id, Containment *parent, QString *e return info; } +QUrl AppletFactory::pluginComponent(const QString &plugin, const QString &qmlFile, QString *errorString) const +{ + QString error; + dfmbase::FinallyUtil finally([&]() { + if (errorString) + *errorString = error; + }); + + // 根据插件路径 + 文件名查找 + dpf::PluginMetaObjectPointer info = dpf::LifeCycle::pluginMetaObj(plugin); + if (!info) { + error = QStringLiteral("Plugin not found"); + return QUrl(); + } + + QString pluginPath = QFileInfo(info->fileName()).absolutePath(); + QString fullPath = pluginPath + QDir::separator() + info->name() + QDir::separator() + qmlFile; + if (!QFile::exists(fullPath)) { + error = QStringLiteral("Qml file not exists"); + return QUrl(); + } + + finally.dismiss(); + return QUrl::fromLocalFile(fullPath); +} + class ViewAppletFacotryData { public: @@ -125,36 +151,18 @@ ViewAppletFactory *ViewAppletFactory::instance() bool ViewAppletFactory::regCreator(const QString &plugin, const QString &qmlFile, const QString &scheme, CreateFunc creator, QString *errorString) { - QString error; - dfmbase::FinallyUtil finally([&]() { - if (errorString) - *errorString = error; - }); - - // 根据插件路径 + 文件名查找 - dpf::PluginMetaObjectPointer info = dpf::LifeCycle::pluginMetaObj(plugin); - if (!info) { - error = QStringLiteral("Plugin not found"); - return false; - } - - QString pluginPath = QFileInfo(info->fileName()).absolutePath(); - QString fullPath = pluginPath + QDir::separator() + info->name() + QDir::separator() + qmlFile; - if (!QFile::exists(fullPath)) { - error = QStringLiteral("Qml file not exists"); + QUrl qmlUrl = AppletFactory::instance()->pluginComponent(plugin, qmlFile, errorString); + if (!qmlUrl.isValid()) return false; - } - - QUrl qmlUrl = QUrl::fromLocalFile(fullPath); if (d->constructList.contains(scheme)) { - error = "The current url has registered " - "the associated construction class"; + if (errorString) + *errorString = "The current url has registered " + "the associated construction class"; return false; } d->constructList.insert(scheme, { qmlUrl, creator }); - finally.dismiss(); return true; } diff --git a/src/dfm-gui/windowmanager.cpp b/src/dfm-gui/windowmanager.cpp index 8691329bab..33017e4aaa 100644 --- a/src/dfm-gui/windowmanager.cpp +++ b/src/dfm-gui/windowmanager.cpp @@ -355,7 +355,7 @@ WindowManager::Handle WindowManager::createWindow(const QUrl &url, const QString Handle handle = d->createQuickWindow(pluginName, quickId, var); if (handle) { handle->loadState(); - handle->setCurrentUrl(url); + handle->setCurrentUrl(showedUrl); d->connectWindowHandle(handle); if (1 == d->windows.size()) { diff --git a/src/plugins/filemanager/core/dfmplugin-core/FileWindow.qml b/src/plugins/filemanager/core/dfmplugin-core/FileWindow.qml index 4c583d5d6d..28a1a30705 100644 --- a/src/plugins/filemanager/core/dfmplugin-core/FileWindow.qml +++ b/src/plugins/filemanager/core/dfmplugin-core/FileWindow.qml @@ -16,8 +16,8 @@ ApplicationWindow { DWindow.enabled: true flags: Qt.Window | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint height: 600 - minimumHeight: 380 - minimumWidth: 600 + minimumHeight: 600 + minimumWidth: 800 width: 800 // TODO: 待评估方案 @@ -51,7 +51,6 @@ ApplicationWindow { // For local module test ActionMenu { } - Connections { function onWidthChanged(width) { } @@ -59,7 +58,6 @@ ApplicationWindow { enabled: Window.window !== null target: Window.window } - RowLayout { anchors.fill: parent @@ -81,14 +79,12 @@ ApplicationWindow { Layout.preferredWidth: parent.width color: "lightyellow" } - LayoutItemProxy { id: sidebar Layout.fillHeight: true } } - AnimationHSpliter { id: spliter @@ -107,7 +103,6 @@ ApplicationWindow { } } } - ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true @@ -117,7 +112,6 @@ ApplicationWindow { onTargetChanged: target => {} } - RowLayout { Layout.fillHeight: true Layout.fillWidth: true @@ -127,7 +121,6 @@ ApplicationWindow { id: workspace } - LayoutItemProxy { id: detailspace diff --git a/src/plugins/filemanager/core/dfmplugin-sidebar/Sidebar.qml b/src/plugins/filemanager/core/dfmplugin-sidebar/Sidebar.qml index b9f447e805..c54107800e 100644 --- a/src/plugins/filemanager/core/dfmplugin-sidebar/Sidebar.qml +++ b/src/plugins/filemanager/core/dfmplugin-sidebar/Sidebar.qml @@ -37,9 +37,9 @@ AppletItem { showDirsFirst: true } } - Text { - color: "lightgray" - font.pointSize: 36 - text: "sidebar" - } + // Text { + // color: "lightgray" + // font.pointSize: 36 + // text: "sidebar" + // } } diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/CMakeLists.txt b/src/plugins/filemanager/core/dfmplugin-workspace/CMakeLists.txt index 08e56a43f8..22cdf34814 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/CMakeLists.txt +++ b/src/plugins/filemanager/core/dfmplugin-workspace/CMakeLists.txt @@ -27,6 +27,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} DFM::base + DFM::gui DFM::framework ${DtkWidget_LIBRARIES} ) diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/Workspace.qml b/src/plugins/filemanager/core/dfmplugin-workspace/Workspace.qml deleted file mode 100644 index 98073bb2e8..0000000000 --- a/src/plugins/filemanager/core/dfmplugin-workspace/Workspace.qml +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts -import org.deepin.filemanager.gui - -ContainmentItem { - property int widgetType: QuickUtils.WorkSpace - - Layout.fillHeight: true - Layout.fillWidth: true - - Component.onCompleted: - // do init Workspace - { - } - - SplitView { - id: workspaceMainSpliteContainer - - anchors.fill: parent - - Rectangle { - id: tempViewRect - - SplitView.fillWidth: true - SplitView.minimumWidth: 200 - color: "lightblue" - - Text { - anchors.centerIn: parent - color: "black" - font.pointSize: 36 - text: "Workspace" - } - } - } -} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/dfmplugin_workspace_global.h b/src/plugins/filemanager/core/dfmplugin-workspace/dfmplugin_workspace_global.h index ba0c2c1a78..4a5f6fd617 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/dfmplugin_workspace_global.h +++ b/src/plugins/filemanager/core/dfmplugin-workspace/dfmplugin_workspace_global.h @@ -31,7 +31,7 @@ enum class DirOpenMode : uint8_t { kOpenInCurrentWindow, kOpenNewWindow, kAwaysInCurrentWindow, - //kForceOpenNewWindow // Todo(yanghao): ??? + // kForceOpenNewWindow // Todo(yanghao): ??? }; // view defines @@ -89,6 +89,8 @@ inline constexpr int kMaxTabCount { 8 }; // view select box inline constexpr int kSelectBoxLineWidth { 2 }; +inline char kWorkspaceUri[] { "org.deepin.filemanager.workspace" }; + namespace PropertyKey { inline constexpr char kScheme[] { "Property_Key_Scheme" }; inline constexpr char kKeepShow[] { "Property_Key_KeepShow" }; diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.cpp new file mode 100644 index 0000000000..3e619f3cf1 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.cpp @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "fileviewcontainment.h" + +#include +#include +#include +#include + +#include +#include + +using namespace dfmgui; +using namespace dfmplugin_workspace; + +FileViewContainment::FileViewContainment(QObject *parent) + : Containment(parent) +{ +} + +quint64 FileViewContainment::getWinId() +{ + return this->panel()->windId(); +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.h b/src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.h new file mode 100644 index 0000000000..375da4557b --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/fileviewcontainment.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef FILEVIEWCONTAINMENT_H +#define FILEVIEWCONTAINMENT_H + +#include + +#include + +DFMGUI_BEGIN_NAMESPACE +class AppletItem; +DFMGUI_END_NAMESPACE + +namespace dfmplugin_workspace { + +class FileViewContainment : public dfmgui::Containment +{ + Q_OBJECT +public: + explicit FileViewContainment(QObject *parent = nullptr); + + Q_INVOKABLE quint64 getWinId(); +}; + +} // namespace dfmplugin_workspace + +#endif // FILEVIEWCONTAINMENT_H diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.cpp index 6ee4df0115..4e0f4b4786 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.cpp @@ -29,6 +29,7 @@ FileItemData::FileItemData(const SortInfoPointer &info, FileItemData *parent) url(info->fileUrl()), sortInfo(info) { + const_cast(this)->info = InfoFactory::create(url); } void FileItemData::setParentData(FileItemData *p) @@ -111,7 +112,12 @@ QVariant FileItemData::data(int role) const return "-"; } case kItemIconRole: - return fileIcon(); + // return fileIcon(); + if (info->isFile()) + // return "file:///usr/share/icons/bloom/mimetypes/32/application-json.svg"; + return "application-json"; + // return "file:///usr/share/icons/bloom/places/32/folder.svg"; + return "folder"; case kItemFileSizeRole: if (info) return info->displayOf(DisPlayInfoType::kSizeDisplayName); diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp index 08a84c41c5..ed85d7687d 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp @@ -43,6 +43,8 @@ FileViewModel::FileViewModel(QAbstractItemView *parent) : QAbstractItemModel(parent) { + initRoleNamesMap(); + currentKey = QString::number(quintptr(this), 16); itemRootData = new FileItemData(dirRootUrl); connect(ThumbnailFactory::instance(), &ThumbnailFactory::produceFinished, this, &FileViewModel::onFileThumbUpdated); @@ -67,24 +69,24 @@ FileViewModel::~FileViewModel() QModelIndex FileViewModel::index(int row, int column, const QModelIndex &parent) const { - auto isParentValid = parent.isValid(); + // auto isParentValid = parent.isValid(); - if ((!isParentValid && (row != 0 || column != 0)) - || (row < 0 || column < 0)) - return QModelIndex(); + // if ((!isParentValid && (row != 0 || column != 0)) + // || (row < 0 || column < 0)) + // return QModelIndex(); - if (!isParentValid && filterSortWorker.isNull()) - return createIndex(row, column, itemRootData); + // if (!isParentValid && filterSortWorker.isNull()) + // return createIndex(row, column, itemRootData); if (!filterSortWorker) return QModelIndex(); FileItemDataPointer itemData = nullptr; - if (!isParentValid) { - itemData = filterSortWorker->rootData(); - } else { - itemData = filterSortWorker->childData(row); - } + // if (!isParentValid) { + // itemData = filterSortWorker->rootData(); + // } else { + itemData = filterSortWorker->childData(row); + // } return createIndex(row, column, itemData.data()); } @@ -96,15 +98,16 @@ QUrl FileViewModel::rootUrl() const QModelIndex FileViewModel::rootIndex() const { - if (!filterSortWorker) - return QModelIndex(); + return QModelIndex(); + // if (!filterSortWorker) + // return QModelIndex(); - auto data = filterSortWorker->rootData(); - if (data) { - return createIndex(0, 0, data.data()); - } else { - return QModelIndex(); - } + // auto data = filterSortWorker->rootData(); + // if (data) { + // return createIndex(0, 0, data.data()); + // } else { + // return QModelIndex(); + // } } QModelIndex FileViewModel::setRootUrl(const QUrl &url) @@ -117,14 +120,15 @@ QModelIndex FileViewModel::setRootUrl(const QUrl &url) WorkspaceEventCaller::sendEnterDirReportLog(data); // insert root index - beginResetModel(); closeCursorTimer(); // create root by url dirRootUrl = url; RootInfo *root = FileDataManager::instance()->fetchRoot(dirRootUrl); - endResetModel(); + // endResetModel(); + beginResetModel(); initFilterSortWork(); + endResetModel(); // connect signals connectRootAndFilterSortWork(root); @@ -150,6 +154,28 @@ QModelIndex FileViewModel::setRootUrl(const QUrl &url) return index; } +void FileViewModel::openIndex(quint64 winId, int index) +{ + if (index >= rowCount(rootIndex())) + return; + + auto curIndex = this->index(index, 0, rootIndex()); + if (!curIndex.isValid()) + return; + + const FileInfoPointer &info = fileInfo(curIndex); + + if (!info) + return; + // if (NetworkUtils::instance()->checkFtpOrSmbBusy(info->urlOf(UrlInfoType::kUrl))) { + // DialogManager::instance()->showUnableToVistDir(info->urlOf(UrlInfoType::kUrl).path()); + // return; + // } + + qWarning() << "open index url: " << info->urlOf(FileInfo::FileUrlInfoType::kUrl); + FileOperatorHelper::instance()->openFiles(winId, { info->urlOf(UrlInfoType::kUrl) }); +} + void FileViewModel::doExpand(const QModelIndex &index) { if (!index.isValid()) @@ -163,7 +189,8 @@ void FileViewModel::doExpand(const QModelIndex &index) const QUrl &url = index.data(kItemUrlRole).toUrl(); RootInfo *expandRoot = FileDataManager::instance()->fetchRoot(url); - connect(expandRoot, &RootInfo::requestCloseTab, this, [](const QUrl &url) { WorkspaceHelper::instance()->closeTab(url); }, Qt::QueuedConnection); + connect( + expandRoot, &RootInfo::requestCloseTab, this, [](const QUrl &url) { WorkspaceHelper::instance()->closeTab(url); }, Qt::QueuedConnection); connect(filterSortWorker.data(), &FileSortWorker::getSourceData, expandRoot, &RootInfo::handleGetSourceData, Qt::QueuedConnection); connect(expandRoot, &RootInfo::sourceDatas, filterSortWorker.data(), &FileSortWorker::handleSourceChildren, Qt::QueuedConnection); connect(expandRoot, &RootInfo::iteratorLocalFiles, filterSortWorker.data(), &FileSortWorker::handleIteratorLocalChildren, Qt::QueuedConnection); @@ -206,24 +233,24 @@ FileInfoPointer FileViewModel::fileInfo(const QModelIndex &index) const if (!index.isValid() || index.row() < 0 || filterSortWorker.isNull()) return nullptr; - const QModelIndex &parentIndex = index.parent(); - FileItemDataPointer item{ nullptr }; - if (!parentIndex.isValid()) { - item = filterSortWorker->rootData(); - } else { - item = filterSortWorker->childData(index.row()); - } + // const QModelIndex &parentIndex = index.parent(); + FileItemDataPointer item { nullptr }; + // if (!parentIndex.isValid()) { + // item = filterSortWorker->rootData(); + // } else { + item = filterSortWorker->childData(index.row()); + // } if (!item) return nullptr; - if (item == filterSortWorker->rootData()) { - if (!item->fileInfo()) - item->data(Global::ItemRoles::kItemCreateFileInfoRole); + // if (item == filterSortWorker->rootData()) { + // if (!item->fileInfo()) + // item->data(Global::ItemRoles::kItemCreateFileInfoRole); - if (!item->fileInfo()) - return InfoFactory::create(item->data(Global::ItemRoles::kItemUrlRole).value()); - } + // if (!item->fileInfo()) + // return InfoFactory::create(item->data(Global::ItemRoles::kItemUrlRole).value()); + // } return item->fileInfo(); } @@ -281,10 +308,10 @@ int FileViewModel::getColumnByRole(ItemRoles role) const QModelIndex FileViewModel::parent(const QModelIndex &child) const { - const FileItemData *childData = static_cast(child.internalPointer()); + // const FileItemData *childData = static_cast(child.internalPointer()); - if (childData && childData->parentData()) - return index(0, 0, QModelIndex()); + // if (childData && childData->parentData()) + // return index(0, 0, QModelIndex()); return QModelIndex(); } @@ -316,28 +343,31 @@ int FileViewModel::columnCount(const QModelIndex &parent) const QVariant FileViewModel::data(const QModelIndex &index, int role) const { - const QModelIndex &parentIndex = index.parent(); + // const QModelIndex &parentIndex = index.parent(); if (filterSortWorker.isNull()) return QVariant(); + if (!index.isValid()) + return QVariant(); + FileItemDataPointer itemData = nullptr; int columnRole = role; - if (!parentIndex.isValid()) { - itemData = filterSortWorker->rootData(); - } else { - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - ItemRoles temRole = columnToRole(index.column()); - if (temRole != ItemRoles::kItemUnknowRole) - columnRole = temRole; - } break; - default: - break; - } - itemData = filterSortWorker->childData(index.row()); + // if (!parentIndex.isValid()) { + // itemData = filterSortWorker->rootData(); + // } else { + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: { + ItemRoles temRole = columnToRole(index.column()); + if (temRole != ItemRoles::kItemUnknowRole) + columnRole = temRole; + } break; + default: + break; } + itemData = filterSortWorker->childData(index.row()); + // } if (itemData) { return itemData->data(columnRole); @@ -753,12 +783,12 @@ void FileViewModel::onFileUpdated(int show) void FileViewModel::onInsert(int firstIndex, int count) { - beginInsertRows(rootIndex(), firstIndex, firstIndex + count - 1); + Q_EMIT beginInsertRows(rootIndex(), firstIndex, firstIndex + count - 1); } void FileViewModel::onInsertFinish() { - endInsertRows(); + Q_EMIT endInsertRows(); } void FileViewModel::onRemove(int firstIndex, int count) @@ -849,6 +879,11 @@ void FileViewModel::onDataChanged(int first, int last) Q_EMIT dataChanged(firstIndex, lastIndex); } +QHash FileViewModel::roleNames() const +{ + return roleNamesMap; +} + void FileViewModel::connectRootAndFilterSortWork(RootInfo *root, const bool refresh) { if (filterSortWorker.isNull()) @@ -859,7 +894,8 @@ void FileViewModel::connectRootAndFilterSortWork(RootInfo *root, const bool refr return; root->addConnectToken(token); } - connect(root, &RootInfo::requestCloseTab, this, [](const QUrl &url) { WorkspaceHelper::instance()->closeTab(url); }, Qt::QueuedConnection); + connect( + root, &RootInfo::requestCloseTab, this, [](const QUrl &url) { WorkspaceHelper::instance()->closeTab(url); }, Qt::QueuedConnection); connect(filterSortWorker.data(), &FileSortWorker::getSourceData, root, &RootInfo::handleGetSourceData, Qt::QueuedConnection); connect(root, &RootInfo::sourceDatas, filterSortWorker.data(), &FileSortWorker::handleSourceChildren, Qt::QueuedConnection); connect(root, &RootInfo::iteratorLocalFiles, filterSortWorker.data(), &FileSortWorker::handleIteratorLocalChildren, Qt::QueuedConnection); @@ -900,12 +936,12 @@ void FileViewModel::initFilterSortWork() filterSortWorker->disconnect(); filterSortWorker.reset(new FileSortWorker(dirRootUrl, currentKey, filterCallback, nameFilters, currentFilters)); - beginInsertRows(QModelIndex(), 0, 0); + // beginInsertRows(QModelIndex(), 0, 0); auto rootInfo = InfoFactory::create(dirRootUrl); if (!rootInfo.isNull()) rootInfo->updateAttributes(); filterSortWorker->setRootData(FileItemDataPointer(new FileItemData(dirRootUrl, rootInfo))); - endInsertRows(); + // endInsertRows(); filterSortWorker->setSortAgruments(order, role, Application::instance()->appAttribute(Application::kFileAndDirMixedSort).toBool()); filterSortWorker->setTreeView(DConfigManager::instance()->value(kViewDConfName, kTreeViewEnable, true).toBool() && WorkspaceHelper::instance()->supportTreeView(rootUrl().scheme())); @@ -917,7 +953,8 @@ void FileViewModel::initFilterSortWork() connect(filterSortWorker.data(), &FileSortWorker::removeRows, this, &FileViewModel::onRemove, Qt::QueuedConnection); connect(filterSortWorker.data(), &FileSortWorker::removeFinish, this, &FileViewModel::onRemoveFinish, Qt::QueuedConnection); connect(filterSortWorker.data(), &FileSortWorker::dataChanged, this, &FileViewModel::onDataChanged, Qt::QueuedConnection); - connect(filterSortWorker.data(), &FileSortWorker::requestFetchMore, this, [this]() { + connect( + filterSortWorker.data(), &FileSortWorker::requestFetchMore, this, [this]() { canFetchFiles = true; fetchingUrl = rootUrl(); RootInfo *root = FileDataManager::instance()->fetchRoot(dirRootUrl); @@ -970,11 +1007,12 @@ void FileViewModel::discardFilterSortObjects() discardedObjects.append(discardedThread); filterSortThread.reset(); - connect(discardedThread.data(), &QThread::finished, this, [this, discardedWorker, discardedThread] { - discardedObjects.removeAll(discardedWorker); - discardedObjects.removeAll(discardedThread); - discardedThread->disconnect(); - }, + connect( + discardedThread.data(), &QThread::finished, this, [this, discardedWorker, discardedThread] { + discardedObjects.removeAll(discardedWorker); + discardedObjects.removeAll(discardedThread); + discardedThread->disconnect(); + }, Qt::QueuedConnection); discardedThread->quit(); @@ -1005,3 +1043,12 @@ void FileViewModel::startCursorTimer() onSetCursorWait(); } + +void FileViewModel::initRoleNamesMap() +{ + roleNamesMap[kItemFileDisplayNameRole] = "fileDisplayName"; + roleNamesMap[kItemIconRole] = "fileIcon"; + roleNamesMap[kItemFileMimeTypeRole] = "fileMimeType"; + roleNamesMap[kItemFileLastModifiedRole] = "fileLastModifiedTime"; + roleNamesMap[kItemFileSizeRole] = "fileSize"; +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.h b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.h index e2a6a3d01b..a58c4fe088 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.h +++ b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.h @@ -6,6 +6,7 @@ #define FILEVIEWMODEL_H #include "dfmplugin_workspace_global.h" +// #include "views/fileview.h" #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include @@ -25,14 +27,13 @@ class QAbstractItemView; namespace dfmplugin_workspace { -class FileView; class FileItemData; class FileSortWorker; class RootInfo; class FileViewModel : public QAbstractItemModel { Q_OBJECT - + QML_ELEMENT public: explicit FileViewModel(QAbstractItemView *parent = nullptr); virtual ~FileViewModel() override; @@ -56,7 +57,8 @@ class FileViewModel : public QAbstractItemModel QUrl rootUrl() const; QModelIndex rootIndex() const; - QModelIndex setRootUrl(const QUrl &url); + Q_INVOKABLE QModelIndex setRootUrl(const QUrl &url); + Q_INVOKABLE void openIndex(quint64 winId, int index); void refresh(); void doExpand(const QModelIndex &index); @@ -99,7 +101,7 @@ class FileViewModel : public QAbstractItemModel void stateChanged(); void renameFileProcessStarted(); void selectAndEditFile(const QUrl &url); - void traverPrehandle(const QUrl &url, const QModelIndex &index, FileView *view); + // void traverPrehandle(const QUrl &url, const QModelIndex &index, FileView *view); void hiddenFileChanged(); void filtersChanged(QStringList nameFilters, QDir::Filters filters); @@ -135,6 +137,9 @@ public Q_SLOTS: void onWorkFinish(int visiableCount, int totalCount); void onDataChanged(int first, int last); +protected: + virtual QHash roleNames() const override; + private: void connectRootAndFilterSortWork(RootInfo *root, const bool refresh = false); void initFilterSortWork(); @@ -145,6 +150,8 @@ public Q_SLOTS: void closeCursorTimer(); void startCursorTimer(); + void initRoleNamesMap(); + QUrl dirRootUrl; QUrl fetchingUrl; @@ -163,6 +170,8 @@ public Q_SLOTS: QList> discardedObjects {}; QDir::Filters currentFilters { QDir::NoFilter }; QStringList nameFilters {}; + + QHash roleNamesMap {}; }; } diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/models/rootinfo.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/models/rootinfo.cpp index 77fc79b723..7bdc4853e2 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/models/rootinfo.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/models/rootinfo.cpp @@ -144,10 +144,11 @@ int RootInfo::clearTraversalThread(const QString &key, const bool isRefresh) traversalThread->disconnect(this); if (traversalThread->isRunning()) { discardedThread.append(traversalThread); - connect(thread->traversalThread.data(), &TraversalDirThread::finished, this, [this, traversalThread] { - discardedThread.removeAll(traversalThread); - traversalThread->disconnect(); - }, + connect( + thread->traversalThread.data(), &TraversalDirThread::finished, this, [this, traversalThread] { + discardedThread.removeAll(traversalThread); + traversalThread->disconnect(); + }, Qt::QueuedConnection); traversaling = false; } @@ -223,13 +224,13 @@ void RootInfo::doWatcherEvent() qint64 oldtime = 0; int emptyLoopCount = 0; while (checkFileEventQueue() || timer.elapsed() < 200) { - //检查超时,重新设置起始时间 + // 检查超时,重新设置起始时间 if (timer.elapsed() - oldtime >= 200) { // 处理添加文件 if (!adds.isEmpty()) addChildren(adds); if (!updates.isEmpty()) - updateChildren(updates); + updateChildren(updates); if (!removes.isEmpty()) removeChildren(removes); diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/qml/FileView.qml b/src/plugins/filemanager/core/dfmplugin-workspace/qml/FileView.qml new file mode 100644 index 0000000000..e7ab31d428 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/qml/FileView.qml @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import org.deepin.filemanager.gui +import org.deepin.filemanager.workspace + +AppletItem { + Layout.fillHeight: true + Layout.fillWidth: true + + Connections { + function onCurrentUrlChanged(url) { + listview.model.setRootUrl(url); + } + + target: Containment + } + ScrollView { + anchors.fill: parent + clip: true + + ListView { + id: listview + + delegate: ListItemDelegate { + autoExclusive: false + } + model: FileItemModel { + } + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/qml/ListItemDelegate.qml b/src/plugins/filemanager/core/dfmplugin-workspace/qml/ListItemDelegate.qml new file mode 100644 index 0000000000..c91282a019 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/qml/ListItemDelegate.qml @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import org.deepin.dtk +import org.deepin.filemanager.gui + +ItemDelegate { + id: listItemDelegate + + backgroundVisible: index % 2 === 0 + hoverEnabled: true + icon.name: fileIcon + text: fileDisplayName + width: ListView.view.width + + content: RowLayout { + Label { + text: fileLastModifiedTime + } + Label { + text: fileSize + } + Label { + text: fileMimeType + } + } + + MouseArea { + acceptedButtons: Qt.LeftButton + anchors.fill: parent + + // onClicked: { + // console.warn(index, " item clicked."); + // listview.model.openIndex(index); + // console.warn(Containment.getWinId()); + // } + + onDoubleClicked: { + listview.model.openIndex(Containment.getWinId(), index); + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/qml/ViewContainer.qml b/src/plugins/filemanager/core/dfmplugin-workspace/qml/ViewContainer.qml new file mode 100644 index 0000000000..90faaab1ea --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/qml/ViewContainer.qml @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import org.deepin.filemanager.gui + +AppletItem { + Layout.fillHeight: true + Layout.fillWidth: true + + Connections { + function onSetViewItem(appletItem) { + centerItem.target = appletItem; + } + + target: Containment + } + Rectangle { + anchors.fill: parent + color: palette.base + + ColumnLayout { + anchors.fill: parent + + LayoutItemProxy { + id: topItem + + } + LayoutItemProxy { + id: centerItem + + } + LayoutItemProxy { + id: bottomItem + + } + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/qml/Workspace.qml b/src/plugins/filemanager/core/dfmplugin-workspace/qml/Workspace.qml new file mode 100644 index 0000000000..e69b7db614 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/qml/Workspace.qml @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import org.deepin.filemanager.gui + +ContainmentItem { + property int widgetType: QuickUtils.WorkSpace + + Layout.fillHeight: true + Layout.fillWidth: true + + Connections { + function onPushNewPage(appletItem) { + workspacePageStack.push(appletItem); + } + + target: Containment + } + Rectangle { + anchors.fill: parent + color: palette.base + + StackView { + id: workspacePageStack + + anchors.fill: parent + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/qml/WorkspacePage.qml b/src/plugins/filemanager/core/dfmplugin-workspace/qml/WorkspacePage.qml new file mode 100644 index 0000000000..e67419a594 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/qml/WorkspacePage.qml @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import org.deepin.filemanager.gui + +AppletItem { + Layout.fillHeight: true + Layout.fillWidth: true + + SplitView { + id: mainSplitView + + anchors.fill: parent + + handle: Rectangle { + // color: SplitHandle.pressed ? "#81e889" : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6") + implicitHeight: 1 + implicitWidth: 1 + } + + Control { + id: leftContainer + + SplitView.fillHeight: true + SplitView.fillWidth: true + + contentItem: ViewContainer { + } + } + Control { + id: rightContainer + + visible: false + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.cpp index 5462a284c6..d1b054cadb 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.cpp @@ -73,6 +73,55 @@ void FileOperatorHelper::openFiles(const FileView *view) openFiles(view, view->selectedUrlList()); } +void FileOperatorHelper::openFiles(quint64 winId, const QList &urls) +{ + DirOpenMode openMode; + if (Application::instance()->appAttribute(Application::kAllwayOpenOnNewWindow).toBool()) { + openMode = DirOpenMode::kOpenNewWindow; + } else { + openMode = DirOpenMode::kOpenInCurrentWindow; + } + + for (const QUrl &url : urls) { + const FileInfoPointer &fileInfoPtr = InfoFactory::create(url); + if (fileInfoPtr) { + if (!fileInfoPtr->exists()) { + // show alert + QString fileName = fileInfoPtr->nameOf(NameInfoType::kFileName); + QFont f; + f.setPixelSize(16); + QFontMetrics fm(f); + fileName = fm.elidedText(fileName, Qt::ElideMiddle, 200); + + UniversalUtils::notifyMessage(QObject::tr("dde-file-manager"), + tr("Failed to open %1, which may be moved or renamed").arg(fileName)); + continue; + } + + if (fileInfoPtr->isAttributes(OptInfoType::kIsDir)) { + QUrl dirUrl = url; + if (fileInfoPtr->isAttributes(OptInfoType::kIsSymLink)) + dirUrl = QUrl::fromLocalFile(fileInfoPtr->pathOf(PathInfoType::kSymLinkTarget)); + + auto flag = DConfigManager::instance()->value(kViewDConfName, + kOpenFolderWindowsInASeparateProcess, false) + .toBool(); + if (openMode == DirOpenMode::kOpenNewWindow /*|| (flag && FileManagerWindowsManager::instance().containsCurrentUrl(dirUrl, view->window()))*/) { + WorkspaceEventCaller::sendOpenWindow({ dirUrl }, !flag); + } else { + WorkspaceEventCaller::sendChangeCurrentUrl(winId, dirUrl); + } + continue; + } + } + + const QList &openUrls = { url }; + dpfSignalDispatcher->publish(GlobalEventType::kOpenFiles, + winId, + openUrls); + } +} + void FileOperatorHelper::openFiles(const FileView *view, const QList &urls) { DirOpenMode openMode = view->currentDirOpenMode(); @@ -105,11 +154,10 @@ void FileOperatorHelper::openFilesByMode(const FileView *view, const QList if (fileInfoPtr->isAttributes(OptInfoType::kIsSymLink)) dirUrl = QUrl::fromLocalFile(fileInfoPtr->pathOf(PathInfoType::kSymLinkTarget)); - auto flag = DConfigManager::instance()-> - value(kViewDConfName, - kOpenFolderWindowsInASeparateProcess, false).toBool(); - if (mode == DirOpenMode::kOpenNewWindow || - (flag && FileManagerWindowsManager::instance().containsCurrentUrl(dirUrl, view->window()))) { + auto flag = DConfigManager::instance()->value(kViewDConfName, + kOpenFolderWindowsInASeparateProcess, false) + .toBool(); + if (mode == DirOpenMode::kOpenNewWindow || (flag && FileManagerWindowsManager::instance().containsCurrentUrl(dirUrl, view->window()))) { WorkspaceEventCaller::sendOpenWindow({ dirUrl }, !flag); } else { WorkspaceEventCaller::sendChangeCurrentUrl(windowId, dirUrl); @@ -163,8 +211,8 @@ void FileOperatorHelper::copyFiles(const FileView *view) return; fmInfo() << "Copy shortcut key to clipboard, selected urls: " << selectedUrls.first() - << ", selected count: " << selectedUrls.size() - << ", current dir: " << view->rootUrl(); + << ", selected count: " << selectedUrls.size() + << ", current dir: " << view->rootUrl(); auto windowId = WorkspaceHelper::instance()->windowId(view); @@ -189,8 +237,8 @@ void FileOperatorHelper::cutFiles(const FileView *view) return; fmInfo() << "Cut shortcut key to clipboard, selected urls: " << selectedUrls.first() - << ", selected count: " << selectedUrls.size() - << ", current dir: " << view->rootUrl(); + << ", selected count: " << selectedUrls.size() + << ", current dir: " << view->rootUrl(); auto windowId = WorkspaceHelper::instance()->windowId(view); dpfSignalDispatcher->publish(GlobalEventType::kWriteUrlsToClipboard, @@ -257,7 +305,7 @@ void FileOperatorHelper::moveToTrash(const FileView *view) return; fmInfo() << "Move files to trash, selected urls: " << selectedUrls - << ", current dir: " << view->rootUrl(); + << ", current dir: " << view->rootUrl(); auto windowId = WorkspaceHelper::instance()->windowId(view); @@ -273,7 +321,7 @@ void FileOperatorHelper::moveToTrash(const FileView *view, const QList &ur return; fmInfo() << "Move files to trash, files urls: " << urls - << ", current dir: " << view->rootUrl(); + << ", current dir: " << view->rootUrl(); auto windowId = WorkspaceHelper::instance()->windowId(view); dpfSignalDispatcher->publish(GlobalEventType::kMoveToTrash, @@ -289,7 +337,7 @@ void FileOperatorHelper::deleteFiles(const FileView *view) return; fmInfo() << "Delete files, selected urls: " << selectedUrls - << ", current dir: " << view->rootUrl(); + << ", current dir: " << view->rootUrl(); auto windowId = WorkspaceHelper::instance()->windowId(view); dpfSignalDispatcher->publish(GlobalEventType::kDeleteFiles, @@ -346,7 +394,7 @@ void FileOperatorHelper::sendBluetoothFiles(const FileView *view) return; fmInfo() << "Send to bluetooth, selected urls: " << urls - << ", current dir: " << view->rootUrl(); + << ", current dir: " << view->rootUrl(); QStringList paths; for (const auto &u : urls) @@ -382,7 +430,7 @@ void FileOperatorHelper::dropFiles(const FileView *view, const Qt::DropAction &a void FileOperatorHelper::renameFilesByReplace(const QWidget *sender, const QList &urlList, const QPair &replacePair) { fmInfo() << "Rename files with replace string: " << replacePair - << ", files urls: " << urlList; + << ", files urls: " << urlList; auto windowId = WorkspaceHelper::instance()->windowId(sender); dpfSignalDispatcher->publish(GlobalEventType::kRenameFiles, @@ -395,7 +443,7 @@ void FileOperatorHelper::renameFilesByReplace(const QWidget *sender, const QList void FileOperatorHelper::renameFilesByAdd(const QWidget *sender, const QList &urlList, const QPair &addPair) { fmInfo() << "Rename files with add string: " << addPair - << ", files urls: " << urlList; + << ", files urls: " << urlList; auto windowId = WorkspaceHelper::instance()->windowId(sender); dpfSignalDispatcher->publish(GlobalEventType::kRenameFiles, @@ -407,7 +455,7 @@ void FileOperatorHelper::renameFilesByAdd(const QWidget *sender, const QList &urlList, const QPair &customPair) { fmInfo() << "Rename files with custom string: " << customPair - << ", files urls: " << urlList; + << ", files urls: " << urlList; auto windowId = WorkspaceHelper::instance()->windowId(sender); dpfSignalDispatcher->publish(GlobalEventType::kRenameFiles, @@ -476,7 +524,7 @@ void FileOperatorHelper::callBackFunction(const AbstractJobHandler::CallbackArgu void FileOperatorHelper::undoCallBackFunction(QSharedPointer handler) { - connect(handler.data(), &AbstractJobHandler::finishedNotify, this, [ = ](const JobInfoPointer jobInfo){ + connect(handler.data(), &AbstractJobHandler::finishedNotify, this, [=](const JobInfoPointer jobInfo) { AbstractJobHandler::JobType type = static_cast(jobInfo->value(AbstractJobHandler::kJobtypeKey).toInt()); if (type == AbstractJobHandler::JobType::kCutType) { QList targetUrls(jobInfo->value(AbstractJobHandler::kCompleteTargetFilesKey).value>()); @@ -484,7 +532,7 @@ void FileOperatorHelper::undoCallBackFunction(QSharedPointer } }); - connect(handler.data(), &AbstractJobHandler::workerFinish, this, [ = ](){ + connect(handler.data(), &AbstractJobHandler::workerFinish, this, [=]() { WorkspaceHelper::instance()->setUndoFiles({}); }); } diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.h b/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.h index c6f8f7b074..c7486224a4 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.h +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/fileoperatorhelper.h @@ -25,6 +25,7 @@ class FileOperatorHelper : public QObject void touchFiles(const FileView *view, const DFMGLOBAL_NAMESPACE::CreateFileType type, QString suffix = ""); void touchFiles(const FileView *view, const QUrl &source); void openFiles(const FileView *view); + void openFiles(quint64 winId, const QList &urls); void openFiles(const FileView *view, const QList &urls); void openFilesByMode(const FileView *view, const QList &urls, const DirOpenMode mode = DirOpenMode::kOpenInCurrentWindow); void openFilesByApp(const FileView *view, const QList &urls, const QList &apps); diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp index 5bbe7affdf..5ee291c1dc 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp @@ -294,8 +294,10 @@ void FileSortWorker::handleWatcherAddChildren(const QList &chil added = suc; } - if (added) + if (added) { + qWarning() << "insert 111111111"; Q_EMIT insertFinish(); + } } void FileSortWorker::handleWatcherRemoveChildren(const QList &children) @@ -387,7 +389,7 @@ bool FileSortWorker::handleWatcherUpdateFile(const SortInfoPointer child) void FileSortWorker::handleWatcherUpdateFiles(const QList &children) { bool added = false; - for(auto sort : children) { + for (auto sort : children) { if (isCanceled) return; auto suc = handleWatcherUpdateFile(sort); @@ -395,8 +397,10 @@ void FileSortWorker::handleWatcherUpdateFiles(const QList &chil added = suc; } - if (added) + if (added) { + qWarning() << "insert 2222222222"; Q_EMIT insertFinish(); + } } void FileSortWorker::handleWatcherUpdateHideFile(const QUrl &hidUrl) @@ -550,8 +554,10 @@ void FileSortWorker::handleUpdateFiles(const QList &urls) if (!added) added = suc; } - if (added) + if (added) { + qWarning() << "insert 33333333333"; emit insertFinish(); + } } void FileSortWorker::handleRefresh() @@ -744,12 +750,12 @@ bool FileSortWorker::handleAddChildren(const QString &key, childUrls.append(newChildren); visibleTreeChildren.insert(parentUrl, childUrls); depthMap.remove(depth - 1, parentUrl); - depthMap.insertMulti(depth - 1, parentUrl); + depthMap.insert(depth - 1, parentUrl); if (newChildren.isEmpty()) return true; insertVisibleChildren(startPos + posOffset, newChildren); - return true; + return false; } void FileSortWorker::setSourceHandleState(const bool isFinished) @@ -816,7 +822,7 @@ void FileSortWorker::filterAndSortFiles(const QUrl &dir, const bool fileter, con if (istree) visibleList = sortAllTreeFilesByParent(dir, reverse); else { - visibleList = sortTreeFiles(visibleTreeChildren.contains(current)? visibleTreeChildren[current] : visibleChildren, reverse); + visibleList = sortTreeFiles(visibleTreeChildren.contains(current) ? visibleTreeChildren[current] : visibleChildren, reverse); } // 执行界面刷新 设置过滤,当前的目录是当前树的根目录,反序。所有的显示url都要改变 @@ -845,7 +851,7 @@ void FileSortWorker::resortCurrent(const bool reverse) if (istree) visibleList = sortAllTreeFilesByParent(current, reverse); else { - visibleList = sortTreeFiles(visibleTreeChildren.contains(current)? visibleTreeChildren[current] : visibleChildren, reverse); + visibleList = sortTreeFiles(visibleTreeChildren.contains(current) ? visibleTreeChildren[current] : visibleChildren, reverse); } resortVisibleChildren(visibleList); @@ -936,7 +942,7 @@ bool FileSortWorker::addChild(const SortInfoPointer &sortInfo, } depthMap.remove(depth - 1, parentUrl); - depthMap.insertMulti(depth - 1, parentUrl); + depthMap.insert(depth - 1, parentUrl); if (!checkFilters(sortInfo, true)) return false; @@ -1033,7 +1039,7 @@ void FileSortWorker::switchListView() auto allShowList = visibleTreeChildren.value(current); visibleTreeChildren.clear(); depthMap.clear(); - depthMap.insertMulti(-1, current); + depthMap.insert(-1, current); auto oldMix = isMixDirAndFile; isMixDirAndFile = Application::instance()->appAttribute(Application::kFileAndDirMixedSort).toBool(); // 排序 diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacehelper.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacehelper.cpp index 9b14da370c..dee6573bd7 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacehelper.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacehelper.cpp @@ -15,12 +15,15 @@ #include #include +#include + #include #include #include using namespace dfmplugin_workspace; +DFMGUI_USE_NAMESPACE DFMBASE_USE_NAMESPACE DFMGLOBAL_USE_NAMESPACE diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.cpp new file mode 100644 index 0000000000..ac7bcc42d2 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.cpp @@ -0,0 +1,87 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "workspacemanager.h" +#include "fileviewcontainment.h" +#include "workspacecontainment.h" +#include "dfmplugin_workspace_global.h" + +#include +#include +#include + +using namespace dfmgui; +using namespace dfmplugin_workspace; + +WorkspaceManager *WorkspaceManager::instance() +{ + static WorkspaceManager ins; + return &ins; +} + +Applet *WorkspaceManager::createViewApplet(const QUrl &url, Containment *parent, QString *errorString) +{ + Q_UNUSED(url) + + auto view = new FileViewContainment(parent); + return view; +} + +Applet *WorkspaceManager::createWorkspaceApplet(const QString &id, dfmgui::Containment *parent, QString *errorString) +{ + if (kWorkspaceUri == id) { + Q_ASSERT_X(parent && parent->flags().testFlag(dfmgui::Applet::kPanel), + "Create workspace applet", "Parent must based on panel"); + + auto containment = new WorkspaceContainment(parent); + return containment; + } + return nullptr; +} + +void WorkspaceManager::registerViewItem(const QString &scheme) +{ + QString errStr {}; + bool ret = ViewAppletFactory::instance()->regCreator("dfmplugin-workspace", "qml/FileView.qml", + scheme, &WorkspaceManager::createViewApplet, &errStr); + + if (!ret && !errStr.isEmpty()) { + qWarning() << "register view item creator error. Error msg: " << errStr; + } +} + +void WorkspaceManager::registerWorkspaceCreator() +{ + // register qml component + QString errorString; + bool regSuccess = dfmgui::AppletFactory::instance()->regCreator( + kWorkspaceUri, &createWorkspaceApplet, &errorString); + if (!regSuccess) { + fmWarning() << QString("Register applet %1 failed.").arg(kWorkspaceUri) << errorString; + } +} + +void WorkspaceManager::onAddNewTab(quint64 windowId, const QUrl &url) +{ + auto workspace = findWorkspace(windowId); + if (!workspace) + return; + + workspace->createPageItem(); + workspace->setCurrentUrl(url); +} + +WorkspaceManager::WorkspaceManager(QObject *parent) + : QObject(parent) +{ +} + +// QTC_TEMP +WorkspaceContainment *WorkspaceManager::findWorkspace(quint64 winId) +{ + if (workspaceMap.contains(winId)) + return workspaceMap.value(winId); + + return nullptr; +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.h b/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.h new file mode 100644 index 0000000000..ffdd4702ca --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/workspacemanager.h @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef WORKSPACEMANAGER_H +#define WORKSPACEMANAGER_H + +#include + +#include + +namespace dfmplugin_workspace { + +inline constexpr char kViewItemApplet[] { "org.dfm.workspace.view" }; +inline constexpr char kAppletUrl[] { "org.dfm.workspace" }; + +class WorkspaceContainment; +class WorkspaceManager : public QObject +{ + Q_OBJECT +public: + static WorkspaceManager *instance(); + + static dfmgui::Applet *createViewApplet(const QUrl &url, dfmgui::Containment *parent, QString *errorString); + static dfmgui::Applet *createWorkspaceApplet(const QString &id, dfmgui::Containment *parent, QString *errorString); + + void registerViewItem(const QString &scheme); + void registerWorkspaceCreator(); + + Q_SLOT void onAddNewTab(quint64 windowId, const QUrl &url); + +private: + explicit WorkspaceManager(QObject *parent = nullptr); + WorkspaceContainment *findWorkspace(quint64 winId); + + inline QString viewAppletWithScheme(const QString &scheme) { return QString(kViewItemApplet).append(".") + scheme; }; + + QMap workspaceMap {}; +}; + +} // namespace dfmplugin_workspace + +#endif // WORKSPACEMANAGER_H diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/workspace.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/workspace.cpp index a81af7b99b..922fcc23d5 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/workspace.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/workspace.cpp @@ -7,11 +7,13 @@ #include "views/fileview.h" #include "views/renamebar.h" #include "utils/workspacehelper.h" +#include "utils/workspacemanager.h" #include "utils/customtopwidgetinterface.h" #include "events/workspaceeventreceiver.h" #include "menus/workspacemenuscene.h" #include "menus/sortanddisplaymenuscene.h" #include "menus/basesortmenuscene.h" +#include "models/fileviewmodel.h" #include "plugins/common/core/dfmplugin-menu/menu_eventinterface_helper.h" @@ -20,8 +22,15 @@ #include #include +#include +#include +#include +#include + #include +#include + namespace dfmplugin_workspace { DFM_LOG_REISGER_CATEGORY(DPWORKSPACE_NAMESPACE) @@ -29,7 +38,10 @@ void Workspace::initialize() { DFMBASE_USE_NAMESPACE - WorkspaceHelper::instance()->registerFileView(Global::Scheme::kFile); + registerQmlType(); + + WorkspaceManager::instance()->registerViewItem(Global::Scheme::kFile); + WorkspaceManager::instance()->registerWorkspaceCreator(); connect(&FMWindowsIns, &FileManagerWindowsManager::windowOpened, this, &Workspace::onWindowOpened, Qt::DirectConnection); connect(&FMWindowsIns, &FileManagerWindowsManager::windowClosed, this, &Workspace::onWindowClosed, Qt::DirectConnection); @@ -84,4 +96,11 @@ void Workspace::onWindowClosed(quint64 windId) { WorkspaceHelper::instance()->removeWorkspace(windId); } + +void Workspace::registerQmlType() +{ + // @uri org.deepin.filemanager.workspace + const char *uri { kWorkspaceUri }; + qmlRegisterType(uri, 1, 0, "FileItemModel"); +} } // namespace dfmplugin_workspace diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/workspace.h b/src/plugins/filemanager/core/dfmplugin-workspace/workspace.h index 7ef7a6277b..fc1d04ea39 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/workspace.h +++ b/src/plugins/filemanager/core/dfmplugin-workspace/workspace.h @@ -121,6 +121,9 @@ class Workspace : public dpf::Plugin private slots: void onWindowOpened(quint64 windId); void onWindowClosed(quint64 winId); + +private: + void registerQmlType(); }; } diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/workspace.json b/src/plugins/filemanager/core/dfmplugin-workspace/workspace.json index 81a27d14e3..f3ada9f6e6 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/workspace.json +++ b/src/plugins/filemanager/core/dfmplugin-workspace/workspace.json @@ -14,10 +14,11 @@ ], "Quick": [ { - "Url" : "Workspace.qml", + "Url" : "qml/Workspace.qml", "Id" : "workspace", "Type" : "Containment", - "Parent" : "dfmplugin-core.filewindow" + "Parent" : "dfmplugin-core.filewindow", + "Applet" : "org.deepin.filemanager.workspace" } ] } diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.cpp new file mode 100644 index 0000000000..9d6d832113 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.cpp @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "workspacecontainment.h" +#include "workspacepage.h" + +#include +#include +#include +#include + +#include +#include + +using namespace dfmgui; +using namespace dfmplugin_workspace; + +WorkspaceContainment::WorkspaceContainment(QObject *parent) + : Containment(parent) +{ + connect(this, &Applet::currentUrlChanged, this, &WorkspaceContainment::onCurrentUrlChanged); +} + +void WorkspaceContainment::onCurrentUrlChanged(const QUrl &url) +{ + if (pageMap.isEmpty()) { + createPageItem(); + currentPage = pageMap.first(); + currentPage->setCurrentUrl(url); + currentPage->initPage(); + return; + } + + if (!currentPage) + return; + + currentPage->setCurrentUrl(url); +} + +Applet *WorkspaceContainment::createPageItem() +{ + QUrl componentUrl = AppletFactory::instance()->pluginComponent("dfmplugin-workspace", "qml/WorkspacePage.qml"); + if (!componentUrl.isValid()) + return nullptr; + + auto pageStack = new WorkspacePage(this); + + pageStack->setComponentUrl(componentUrl); + this->appendApplet(pageStack); + + pageMap.insert(pageMap.count(), pageStack); + + AppletItem *item = AppletItem::itemForApplet(pageStack); + Q_EMIT pushNewPage(item); + return pageStack; +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.h b/src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.h new file mode 100644 index 0000000000..9563fe0bdb --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/workspacecontainment.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef WORKSPACECONTAINMENT_H +#define WORKSPACECONTAINMENT_H + +#include + +#include + +DFMGUI_BEGIN_NAMESPACE +class AppletItem; +DFMGUI_END_NAMESPACE + +namespace dfmplugin_workspace { +class WorkspacePage; +class WorkspaceContainment : public dfmgui::Containment +{ + Q_OBJECT +public: + explicit WorkspaceContainment(QObject *parent = nullptr); + + // slots + Q_SLOT void onCurrentUrlChanged(const QUrl &url); + Q_SLOT dfmgui::Applet *createPageItem(); + + // signals + Q_SIGNAL void pushNewPage(DFMGUI_NAMESPACE::AppletItem *); + +private: + QMap pageMap {}; + WorkspacePage *currentPage { nullptr }; + quint8 currentPageIndex { 0 }; +}; +} // namespace dfmplugin_workspace + +#endif // WORKSPACECONTAINMENT_H diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.cpp new file mode 100644 index 0000000000..9ffc68bc1b --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.cpp @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "workspacepage.h" +#include "fileviewcontainment.h" + +#include +#include +#include + +using namespace dfmgui; +using namespace dfmplugin_workspace; + +WorkspacePage::WorkspacePage(QObject *parent) + : Containment(parent) +{ +} + +quint64 WorkspacePage::getWinId() +{ + return this->panel()->windId(); +} + +void WorkspacePage::initPage() +{ + createViewItem(); +} + +void WorkspacePage::createViewItem() +{ + QString errStr {}; + + auto viewItem = ViewAppletFactory::instance()->create(currentUrl(), this, &errStr); + connect(this, &WorkspacePage::currentUrlChanged, viewItem, [viewItem](const QUrl &url) { + viewItem->setCurrentUrl(url); + }); + + this->appendApplet(viewItem); + + AppletItem *item = AppletItem::itemForApplet(viewItem); + Q_EMIT setViewItem(item); + + viewItem->setCurrentUrl(currentUrl()); + + viewContainmentsMap.insert(0, viewItem); +} diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.h b/src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.h new file mode 100644 index 0000000000..79069be035 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-workspace/workspacepage.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef WORKSPACEPAGE_H +#define WORKSPACEPAGE_H + +#include + +#include + +DFMGUI_BEGIN_NAMESPACE +class AppletItem; +DFMGUI_END_NAMESPACE + +namespace dfmplugin_workspace { +class WorkspacePage : public dfmgui::Containment +{ + Q_OBJECT +public: + explicit WorkspacePage(QObject *parent = nullptr); + + // signals + Q_SIGNAL void setViewItem(dfmgui::AppletItem *); + + Q_INVOKABLE quint64 getWinId(); + + void initPage(); + +private: + void createViewItem(); + + QMap viewContainmentsMap {}; +}; +} // namespace dfmplugin_workspace + +#endif // WORKSPACEPAGE_H