diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.cpp b/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.cpp index 43c9b275ac..261c031553 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.cpp +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.cpp @@ -98,3 +98,16 @@ ViewMode TitleBarEventCaller::sendGetDefualtViewMode(const QString &scheme) int defaultViewMode = dpfSlotChannel->push("dfmplugin_workspace", "slot_View_GetDefaultViewMode", scheme).toInt(); return static_cast(defaultViewMode); } + +void TitleBarEventCaller::sendCd(dfmgui::Applet *applet, const QUrl &url) +{ + DFMBASE_USE_NAMESPACE + quint64 id = TitleBarHelper::windowId(applet); + Q_ASSERT(id > 0); + if (!url.isValid()) { + fmWarning() << "Invalid url: " << url; + return; + } + + dpfSignalDispatcher->publish(DFMBASE_NAMESPACE::GlobalEventType::kChangeCurrentUrl, id, url); +} diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.h b/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.h index 58490e4001..d184bf9164 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.h +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/events/titlebareventcaller.h @@ -9,6 +9,8 @@ #include +#include + #include namespace dfmplugin_titlebar { @@ -30,6 +32,8 @@ class TitleBarEventCaller static void sendCheckAddressInputStr(QWidget *sender, QString *str); static bool sendCheckTabAddable(quint64 windowId); static DFMGLOBAL_NAMESPACE::ViewMode sendGetDefualtViewMode(const QString &scheme); + + static void sendCd(dfmgui::Applet *applet, const QUrl &url); }; } diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/models/quickcrumbmodel.cpp b/src/plugins/filemanager/core/dfmplugin-titlebar/models/quickcrumbmodel.cpp new file mode 100644 index 0000000000..808d526e45 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/models/quickcrumbmodel.cpp @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "quickcrumbmodel.h" + +namespace dfmplugin_titlebar { + +QuickCrumbModel::QuickCrumbModel(QObject *parent) + : QAbstractListModel { parent } +{ +} + +void QuickCrumbModel::setCurrentUrl(const QUrl &url, const QList &crumbDataList) +{ + beginResetModel(); + fileUrl = url; + crumbData = crumbDataList; + endResetModel(); +} + +int QuickCrumbModel::rowCount(const QModelIndex &) const +{ + return crumbData.size(); +} + +QVariant QuickCrumbModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < 0 || index.row() >= crumbData.size()) { + return {}; + } + + const CrumbData &data = crumbData.at(index.row()); + switch (role) { + case FileUrlRole: + return data.url; + case FullUrlRole: + return fileUrl; + case TextRole: + return data.displayText; + case IconRole: + return data.iconName; + case UseIconRole: + return !data.iconName.isEmpty(); + } + + return {}; +} + +QHash QuickCrumbModel::roleNames() const +{ + QHash roles; + roles[FileUrlRole] = "fileUrl"; + roles[FullUrlRole] = "fullUrl"; + roles[TextRole] = "text"; + roles[IconRole] = "icon"; + roles[UseIconRole] = "useIcon"; + return roles; +} + +} diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/models/quickcrumbmodel.h b/src/plugins/filemanager/core/dfmplugin-titlebar/models/quickcrumbmodel.h new file mode 100644 index 0000000000..22539767e9 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/models/quickcrumbmodel.h @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef QUICKCRUMBMODEL_H +#define QUICKCRUMBMODEL_H + +#include "dfmplugin_titlebar_global.h" + +#include +#include + +namespace dfmplugin_titlebar { + +class QuickCrumbModel : public QAbstractListModel +{ + Q_OBJECT +public: + enum Roles { + FileUrlRole = Qt::UserRole + 1, + FullUrlRole, + TextRole, + IconRole, + UseIconRole, + }; + Q_ENUM(Roles) + + explicit QuickCrumbModel(QObject *parent = nullptr); + + void setCurrentUrl(const QUrl &url, const QList &crumbDataList); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; + +private: + QUrl fileUrl; + QList crumbData; +}; + +} + +#endif // QUICKCRUMBMODEL_H diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/qml/CrumbBar.qml b/src/plugins/filemanager/core/dfmplugin-titlebar/qml/CrumbBar.qml new file mode 100644 index 0000000000..9262d36708 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/qml/CrumbBar.qml @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Controls +import org.dfm.base +import org.deepin.dtk +import org.deepin.dtk.private 1.0 as P + +///! 面包屑导航栏 +Item { + id: breadcrumbs + + // 请求弹出同级文件夹列表 + signal requsetQuickJumpMenu(var url, real x, real y) + + ListView { + id: addressline + + anchors.fill: parent + model: Containment.crumbModel + orientation: ListView.Horizontal + + delegate: Button { + id: addressBtn + + enabled: index !== (ListView.view.count - 1) + icon.name: model.useIcon ? model.icon : undefined + leftInset: 0 + padding: 0 + rightInset: 0 + spacing: 0 + text: model.useIcon ? undefined : model.text + + background: P.ButtonPanel { + id: bkgPanel + + button: addressBtn + implicitWidth: addressBtn.contentItem.implicitWidth + visible: addressBtn.enabled && addressBtn.hovered + } + indicator: Item { + implicitHeight: 20 + implicitWidth: 10 + + Text { + anchors.centerIn: parent + font.bold: false + font.family: "Noto Sans CJK TC" + text: "/" + visible: !bkgPanel.visible + } + + Loader { + enabled: bkgPanel.visible + + sourceComponent: Button { + id: popupBtn + + height: 16 + icon.height: 10 + icon.name: "combobox_arrow" + icon.width: 10 + visible: bkgPanel.visible + width: 16 + + onClicked: { + breadcrumbs.requsetQuickJumpMenu(model.fileUrl, popupBtn.x, popupBtn.y + 20); + } + + anchors { + right: parent.right + rightMargin: 10 + verticalCenter: parent.verticalCenter + } + } + } + } + + onClicked: { + Containment.currentUrl = model.fileUrl; + } + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml b/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml index 231aed454e..39ceee519c 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml @@ -10,7 +10,7 @@ import org.dfm.base import org.deepin.dtk import org.deepin.dtk.style 1.0 as DS -AppletItem { +ContainmentItem { id: titlebar property int breadcrumbsHeight: 30 @@ -30,7 +30,6 @@ AppletItem { RowLayout { Layout.fillHeight: true - Layout.fillWidth: true layoutDirection: Qt.LeftToRight CheckBox { @@ -67,16 +66,20 @@ AppletItem { IconButton { icon.name: "button_add" + + onClicked: { + console.warn("--- test", Containment.applets); + Applet.currentUrl = "file:///home/uos/Downloads/GammaRay/build/bin"; + } } } Loader { - Layout.preferredWidth: item ? item.implicitWidth : 0 + Layout.fillWidth: true active: Window.window height: DS.Style.titleBar.height sourceComponent: TitleBar { - // replace Window.window.width width: parent.width } } @@ -89,12 +92,11 @@ AppletItem { implicitHeight: breadcrumbsHeight spacing: 0 - Rectangle { + CrumbBar { id: breadcrumbs Layout.fillHeight: true Layout.fillWidth: true - color: "blue" } Rectangle { diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.cpp b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.cpp index e6284763f4..e90be25947 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.cpp +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "titlebar.h" +#include "titlebarcontainment.h" #include "utils/titlebarhelper.h" #include "utils/crumbinterface.h" #include "utils/crumbmanager.h" @@ -16,11 +17,29 @@ #include #include +#include +#include + #include namespace dfmplugin_titlebar { DFM_LOG_REISGER_CATEGORY(DPTITLEBAR_NAMESPACE) +static constexpr char kAppletUrl[] { "org.dfm.titlebar" }; + +static dfmgui::Applet *createTitlebarApplet(const QString &url, dfmgui::Containment *parent, QString *errorString) +{ + if (kAppletUrl == url) { + Q_ASSERT_X(parent && parent->flags().testFlag(dfmgui::Applet::kPanel), + "Create titlebar applet", "Parent must based on panel"); + + auto titlebar = new TitlebarContainment(parent); + QObject::connect(parent, &dfmgui::Applet::currentUrlChanged, titlebar, &TitlebarContainment::setCurrentUrl); + return titlebar; + } + return nullptr; +} + void TitleBar::initialize() { DFMBASE_USE_NAMESPACE @@ -31,6 +50,14 @@ void TitleBar::initialize() // event has been sended before the Window showed bindEvents(); + + // register qml component + QString errorString; + bool regSuccess = dfmgui::AppletFactory::instance()->regCreator( + kAppletUrl, &createTitlebarApplet, &errorString); + if (!regSuccess) { + fmWarning() << QString("Register applet %1 failed.").arg(kAppletUrl) << errorString; + } } bool TitleBar::start() diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.json b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.json index e54b06f8e0..d66d144e48 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.json +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebar.json @@ -16,7 +16,8 @@ { "Url" : "qml/Titlebar.qml", "Id" : "titlebar", - "Parent" : "dfmplugin-core.filewindow" + "Parent" : "dfmplugin-core.filewindow", + "Applet" : "org.dfm.titlebar" } ] } diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.cpp b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.cpp new file mode 100644 index 0000000000..b5eeb967d8 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.cpp @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "titlebarcontainment.h" +#include "models/quickcrumbmodel.h" +#include "utils/crumbinterface.h" +#include "utils/crumbmanager.h" +#include "events/titlebareventcaller.h" + +#include + +namespace dfmplugin_titlebar { + +TitlebarContainment::TitlebarContainment(QObject *parent) + : dfmgui::Containment(parent), model(new QuickCrumbModel) +{ + connect(this, &Applet::currentUrlChanged, this, &TitlebarContainment::onUrlChanged); +} + +QuickCrumbModel *TitlebarContainment::crumbModel() const +{ + return model; +} + +void TitlebarContainment::onUrlChanged(const QUrl &url) +{ + TitleBarEventCaller::sendCd(this, url); + + updateController(url); + + if (crumbController) { + crumbController->crumbUrlChangedBehavior(url); + } + + +} + +void TitlebarContainment::updateController(const QUrl &url) +{ + if (!crumbController || !crumbController->isSupportedScheme(url.scheme())) { + if (crumbController) { + crumbController->deleteLater(); + } + crumbController = CrumbManager::instance()->createControllerByUrl(url); + // Not found? Then nothing here... + if (!crumbController) { + fmWarning() << "Unsupported url / scheme: " << url; + // always has default controller + crumbController = new CrumbInterface; + } + crumbController->setParent(this); + // QObject::connect(crumbController, &CrumbInterface::hideAddressBar, q, &CrumbBar::hideAddressBar); + // QObject::connect(crumbController, &CrumbInterface::keepAddressBar, q, &CrumbBar::onKeepAddressBar); + QObject::connect(crumbController, &CrumbInterface::hideAddrAndUpdateCrumbs, this, &TitlebarContainment::onHideAddrAndUpdateCrumbs); + } +} + +void TitlebarContainment::onHideAddrAndUpdateCrumbs(const QUrl &url) +{ + if (!crumbController) { + fmWarning("No controller found when trying to call DFMCrumbBar::updateCrumbs() !!!"); + fmDebug() << "updateCrumbs (no controller) : " << url; + return; + } + + setCurrentUrl(url); + + QList &&crumbDataList = crumbController->seprateUrl(url); + model->setCurrentUrl(url, crumbDataList); +} + +} diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.h b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.h new file mode 100644 index 0000000000..cdd2d716ad --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.h @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TITLEBARCONTAINMENT_H +#define TITLEBARCONTAINMENT_H + +#include + +#include + +namespace dfmplugin_titlebar { + +class CrumbInterface; +class QuickCrumbModel; + +class TitlebarContainment : public dfmgui::Containment +{ + Q_OBJECT + Q_PROPERTY(QuickCrumbModel *crumbModel READ crumbModel CONSTANT) + +public: + explicit TitlebarContainment(QObject *parent = nullptr); + + QuickCrumbModel *crumbModel() const; + Q_SLOT void onUrlChanged(const QUrl &url); + +private: + void updateController(const QUrl &url); + Q_SLOT void onHideAddrAndUpdateCrumbs(const QUrl &url); + +private: + CrumbInterface *crumbController = nullptr; + QuickCrumbModel *model = nullptr; +}; + +} + +#endif // TITLEBARCONTAINMENT_H diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.cpp b/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.cpp index 62ba8aaf2c..e287e5b310 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.cpp +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.cpp @@ -19,6 +19,8 @@ #include #include +#include + #include #include @@ -61,6 +63,11 @@ quint64 TitleBarHelper::windowId(QWidget *sender) return FMWindowsIns.findWindowId(sender); } +quint64 TitleBarHelper::windowId(dfmgui::Applet *applet) +{ + return FMQuickWindowIns->findWindowIdFromApplet(applet); +} + void TitleBarHelper::createSettingsMenu(quint64 id) { QMenu *menu = new QMenu(); diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.h b/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.h index ade692bd15..49cda521a2 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.h +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/utils/titlebarhelper.h @@ -7,6 +7,8 @@ #include "dfmplugin_titlebar_global.h" +#include + #include #include #include @@ -23,6 +25,8 @@ class TitleBarHelper static void removeTitleBar(quint64 windowId); static quint64 windowId(QWidget *sender); + static quint64 windowId(dfmgui::Applet *applet); + static void createSettingsMenu(quint64 id); static QList crumbSeprateUrl(const QUrl &url); static QList tansToCrumbDataList(const QList &mapGroup);