diff --git a/src/dfm-gui/windowmanager.cpp b/src/dfm-gui/windowmanager.cpp index de7bba7a27..ff5b50dfef 100644 --- a/src/dfm-gui/windowmanager.cpp +++ b/src/dfm-gui/windowmanager.cpp @@ -322,6 +322,9 @@ QSharedPointer WindowManager::engine() const * \brief 根据传入的插件 \a pluginName 和组件 \a quickId 信息查找并创建对应的主窗体,\a var 为初始化时传递给主窗体组件的参数, * 创建的窗口会被当前管理类保留管理. * \return 创建的 QQuickWindow 和 Panel,无法创建返回空的 Handle + * + * \warning 主窗口对应的 Qml 组件会立即加载,子 Applet 是异步加载的,所以在默认初始化的流程中,不使用旧版框架中 findWindowId() 这类 + * 接口 */ WindowManager::Handle WindowManager::createWindow(const QUrl &url, const QString &pluginName, const QString &quickId, const QVariantMap &var) diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/CMakeLists.txt b/src/plugins/filemanager/core/dfmplugin-detailspace/CMakeLists.txt index 1e26c01388..9ace736e27 100644 --- a/src/plugins/filemanager/core/dfmplugin-detailspace/CMakeLists.txt +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/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-detailspace/DetailSpace.qml b/src/plugins/filemanager/core/dfmplugin-detailspace/DetailSpace.qml deleted file mode 100644 index 3fe715f9f0..0000000000 --- a/src/plugins/filemanager/core/dfmplugin-detailspace/DetailSpace.qml +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -import QtQuick -import QtQuick.Layouts -import org.dfm.base - -ContainmentItem { - property int widgetType: QuickUtils.DetailSpace - - Layout.fillHeight: true - implicitWidth: 200 - - ColumnLayout { - anchors.fill: parent - - Rectangle { - Layout.fillHeight: true - color: "lightyellow" - width: 200 - } - } - - Text { - color: "lightgray" - font.pointSize: 36 - text: "Detail Space" - } -} diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.cpp b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.cpp index 10ee1071c9..c76de898e2 100644 --- a/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.cpp +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.cpp @@ -5,17 +5,51 @@ #include "detailspace.h" #include "utils/detailspacehelper.h" #include "events/detailspaceeventreceiver.h" +#include "detailspacecontainment.h" +#include "model/quickfilebaseinfomodel.h" #include +#include +#include + +#include + namespace dfmplugin_detailspace { DFM_LOG_REISGER_CATEGORY(DPDETAILSPACE_NAMESPACE) DFMBASE_USE_NAMESPACE +static constexpr char kAppletUrl[] { "org.dfm.detailspace" }; + +static dfmgui::Applet *createDetailSpaceApplet(const QString &url, dfmgui::Containment *parent, QString *errorString) +{ + if (kAppletUrl == url) { + Q_ASSERT_X(parent && parent->flags().testFlag(dfmgui::Applet::kPanel), + "Create detailspace applet", "Parent must based on panel"); + + auto detailSpace = new DetailSpaceContainment(parent); + QObject::connect(parent, &dfmgui::Applet::currentUrlChanged, detailSpace, &DetailSpaceContainment::setCurrentUrl); + return detailSpace; + } + return nullptr; +} + void DetailSpace::initialize() { connect(&FMWindowsIns, &FileManagerWindowsManager::windowClosed, this, &DetailSpace::onWindowClosed, Qt::DirectConnection); DetailSpaceEventReceiver::instance().connectService(); + + // 注册插件使用模块组件 + // @uri org.dfm.detailspace + const char *uri = "org.dfm.detailspace"; + qmlRegisterType(uri, 1, 0, "BaseFileInfoModel"); + + QString errorString; + bool ret = dfmgui::AppletFactory::instance()->regCreator( + kAppletUrl, &createDetailSpaceApplet, &errorString); + if (!ret) { + fmWarning() << QString("Register applet %1 failed.").arg(kAppletUrl) << errorString; + } } bool DetailSpace::start() diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.json b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.json index 0dfb48681d..df9bf6d29a 100644 --- a/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.json +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspace.json @@ -14,9 +14,10 @@ ], "Quick": [ { - "Url" : "DetailSpace.qml", + "Url" : "qml/DetailSpace.qml", "Id" : "detailspace", - "Parent" : "dfmplugin-core.filewindow" + "Parent" : "dfmplugin-core.filewindow", + "Applet" : "org.dfm.detailspace" } ] } diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/detailspacecontainment.cpp b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspacecontainment.cpp new file mode 100644 index 0000000000..cc84c68b8d --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspacecontainment.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "detailspacecontainment.h" + +#include +#include +#include + +#include + +DFMBASE_USE_NAMESPACE + +namespace dfmplugin_detailspace { + +DetailSpaceContainment::DetailSpaceContainment(QObject *parent) + : dfmgui::Containment(parent) +{ +} + +bool DetailSpaceContainment::detailVisible() const +{ + return visibleFlag; +} + +void DetailSpaceContainment::setDetailVisible(bool b) +{ + if (visibleFlag != b) { + visibleFlag = b; + Q_EMIT detailVisibleChanged(b); + } +} + +} diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/detailspacecontainment.h b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspacecontainment.h new file mode 100644 index 0000000000..b9952f9479 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/detailspacecontainment.h @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef DETAILSPACECONTAINMENT_H +#define DETAILSPACECONTAINMENT_H + +#include + +#include + +namespace dfmplugin_detailspace { + +class DetailSpaceContainment : public dfmgui::Containment +{ + Q_OBJECT + + Q_PROPERTY(bool detailVisible READ detailVisible WRITE setDetailVisible NOTIFY detailVisibleChanged FINAL) + +public: + explicit DetailSpaceContainment(QObject *parent = nullptr); + + bool detailVisible() const; + void setDetailVisible(bool b); + Q_SIGNAL void detailVisibleChanged(bool b); + +private: + bool visibleFlag { false }; + QString curIconName; +}; + +} + +#endif // DETAILSPACECONTAINMENT_H diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/dfmplugin_detailspace_global.h b/src/plugins/filemanager/core/dfmplugin-detailspace/dfmplugin_detailspace_global.h index 8460eda05b..385eae6236 100644 --- a/src/plugins/filemanager/core/dfmplugin-detailspace/dfmplugin_detailspace_global.h +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/dfmplugin_detailspace_global.h @@ -32,8 +32,9 @@ enum DetailFilterType { kFileInterviewTimeField = 1 << 7, kFileChangeTimeField = 1 << 8 }; -Q_ENUM_NS(DetailFilterType) +Q_FLAG_NS(DetailFilterType) +// TODO: try remove it enum BasicFieldExpandEnum : int { kNotAll, kFileName, diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/model/quickfilebaseinfomodel.cpp b/src/plugins/filemanager/core/dfmplugin-detailspace/model/quickfilebaseinfomodel.cpp new file mode 100644 index 0000000000..45b6d51bdb --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/model/quickfilebaseinfomodel.cpp @@ -0,0 +1,358 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "quickfilebaseinfomodel.h" +#include "utils/detailmanager.h" + +#include +#include +#include +#include +#include + +USING_IO_NAMESPACE +DFMBASE_USE_NAMESPACE + +namespace dfmplugin_detailspace { + +// TODO: remove it 后续 BasicFieldExpandEnum 和 DetailFilterType 并为单个枚举 +static DetailFilterType enumConvert(BasicFieldExpandEnum value) +{ + switch (value) { + case BasicFieldExpandEnum::kFileName: + return DetailFilterType::kFileNameField; + case BasicFieldExpandEnum::kFileSize: + return DetailFilterType::kFileSizeField; + case BasicFieldExpandEnum::kFileViewSize: + return DetailFilterType::kFileViewSizeField; + case BasicFieldExpandEnum::kFileDuration: + return DetailFilterType::kFileDurationField; + case BasicFieldExpandEnum::kFileType: + return DetailFilterType::kFileTypeField; + case BasicFieldExpandEnum::kFileInterviewTime: + return DetailFilterType::kFileInterviewTimeField; + case BasicFieldExpandEnum::kFileChangeTIme: + return DetailFilterType::kFileChangeTimeField; + default: + return DetailFilterType::kNotFilter; + } +} + +/*! + * \class QuickFileBaseInfoModel + * \brief 基础文件信息模型 + * \details 根据传入的文件信息获取基础文件名/大小/修改时间等信息,对音视频文件提供文件大小和时长信息 + */ +QuickFileBaseInfoModel::QuickFileBaseInfoModel(QObject *parent) + : QAbstractListModel { parent } +{ + connect(this, &QuickFileBaseInfoModel::sigExtenInfo, + this, &QuickFileBaseInfoModel::receiveExtenInfo, Qt::QueuedConnection); +} + +QUrl QuickFileBaseInfoModel::url() const +{ + return modelUrl; +} + +void QuickFileBaseInfoModel::setUrl(const QUrl &url) +{ + if (url != modelUrl) { + modelUrl = url; + resetFieldValue(modelUrl); + + Q_EMIT urlChanged(url); + } +} + +int QuickFileBaseInfoModel::rowCount(const QModelIndex &parent) const +{ + return keyValueList.size(); +} + +QVariant QuickFileBaseInfoModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < 0 || index.row() >= keyValueList.size()) { + return {}; + } + + const KeyValue &keyValue = keyValueList.at(index.row()); + switch (role) { + case kKeyRole: + return keyValue.key; + case kValueRole: + return keyValue.value; + } + + return {}; +} + +QHash QuickFileBaseInfoModel::roleNames() const +{ + QHash roles; + roles[kKeyRole] = "key"; + roles[kValueRole] = "value"; + return roles; +} + +void QuickFileBaseInfoModel::imageExtenInfo(const QUrl &url, QMap properties) +{ + if ((url == modelUrl) && !properties.isEmpty()) { + QString viewSize = parseViewSize(properties); + Q_EMIT sigExtenInfo(DetailFilterType::kFileViewSizeField, viewSize); + } +} + +void QuickFileBaseInfoModel::videoExtenInfo(const QUrl &url, QMap properties) +{ + if ((url == modelUrl) && !properties.isEmpty()) { + QString viewSize = parseViewSize(properties); + Q_EMIT sigExtenInfo(DetailFilterType::kFileViewSizeField, viewSize); + QString durationStr = parseDuration(properties); + Q_EMIT sigExtenInfo(DetailFilterType::kFileDurationField, durationStr); + } +} + +void QuickFileBaseInfoModel::audioExtenInfo(const QUrl &url, QMap properties) +{ + if ((url == modelUrl) && !properties.isEmpty()) { + QString durationStr = parseViewSize(properties); + Q_EMIT sigExtenInfo(DetailFilterType::kFileDurationField, durationStr); + } +} + +void QuickFileBaseInfoModel::receiveExtenInfo(DetailFilterType field, const QString &value) +{ + appendKeyValue(field, value); +} + +void QuickFileBaseInfoModel::clearKeyValue() +{ + markedType = DetailFilterType::kNotFilter; + keyValueList.clear(); +} + +void QuickFileBaseInfoModel::resetFieldValue(const QUrl &url) +{ + reseting = true; + beginResetModel(); + + clearKeyValue(); + + markFilter(url); + // 优先执行拓展,以执行替换操作 + basicExpand(url); + basicFill(url); + + sortKeyValue(); + + endResetModel(); + reseting = false; +} + +/*! + * \brief 获取路径 \a url 当前过滤的字段类型,通过标记 Flag 已写入进行过滤 + */ +void QuickFileBaseInfoModel::markFilter(const QUrl &url) +{ + QUrl filterUrl = url; + QList urls {}; + bool ok = UniversalUtils::urlsTransformToLocal({ filterUrl }, &urls); + + if (ok && !urls.isEmpty()) + filterUrl = urls.first(); + + DetailFilterType fieldFilters = DetailManager::instance().basicFiledFiltes(filterUrl); + + // 设置过滤标识 & 已被写入的数据(拓展模块替换) 不需要二次写入 + markedType &= fieldFilters; +} + +/*! + * \brief 填充 \a url 拓展信息,插入的数据不会标记写入标识,相同字段后续也可插入;替换的数据后续不会重复更新 + */ +void QuickFileBaseInfoModel::basicExpand(const QUrl &url) +{ + QMap fieldCondition = DetailManager::instance().createBasicViewExtensionField(url); + + QMapIterator exIter(fieldCondition); + while (exIter.hasNext()) { + QMultiMapIterator valueItr(exIter.value()); + + while (valueItr.hasNext()) { + switch (exIter.key()) { + case BasicExpandType::kFieldInsert: + appendKeyValue(enumConvert(valueItr.key()), valueItr.value().second, valueItr.value().first, true); + break; + case BasicExpandType::kFieldReplace: + appendKeyValue(enumConvert(valueItr.key()), valueItr.value().second, valueItr.value().first); + break; + } + + valueItr.next(); + } + + exIter.next(); + } +} + +/*! + * \brief 填充 \a url 基础信息,名称/大小/修改时间,音视频文件会请求拓展插件提取文件大小和长度。 + */ +void QuickFileBaseInfoModel::basicFill(const QUrl &url) +{ + FileInfoPointer info = InfoFactory::create(url); + if (info.isNull()) + return; + + if (!(markedType & DetailFilterType::kFileNameField)) { + appendKeyValue(DetailFilterType::kFileNameField, info->displayOf(DisPlayInfoType::kFileDisplayName)); + } + + if (!(markedType & DetailFilterType::kFileSizeField)) { + if (!info->isAttributes(OptInfoType::kIsDir)) { + appendKeyValue(DetailFilterType::kFileSizeField, FileUtils::formatSize(info->size())); + } + } + + QUrl localUrl = url; + QList urls {}; + bool ok = UniversalUtils::urlsTransformToLocal({ localUrl }, &urls); + if (ok && !urls.isEmpty()) + localUrl = urls.first(); + FileInfoPointer localinfo = InfoFactory::create(localUrl); + if (!localinfo) { + return; + } + + if (!(markedType & kFileTypeField)) { + const QString &mimeName { localinfo->nameOf(NameInfoType::kMimeTypeName) }; + const FileInfo::FileType type = MimeTypeDisplayManager::instance()->displayNameToEnum(mimeName); + appendKeyValue(DetailFilterType::kFileTypeField, localinfo->displayOf(DisPlayInfoType::kMimeTypeDisplayName)); + QList extenList; + + if (type == FileInfo::FileType::kVideos) { + extenList << DFileInfo::AttributeExtendID::kExtendMediaWidth << DFileInfo::AttributeExtendID::kExtendMediaHeight << DFileInfo::AttributeExtendID::kExtendMediaDuration; + connect(&FileInfoHelper::instance(), &FileInfoHelper::mediaDataFinished, this, &QuickFileBaseInfoModel::videoExtenInfo, Qt::UniqueConnection); + const QMap &mediaAttributes = localinfo->mediaInfoAttributes(DFileInfo::MediaType::kVideo, extenList); + if (!mediaAttributes.isEmpty()) + videoExtenInfo(url, mediaAttributes); + + } else if (type == FileInfo::FileType::kImages) { + extenList << DFileInfo::AttributeExtendID::kExtendMediaWidth << DFileInfo::AttributeExtendID::kExtendMediaHeight; + connect(&FileInfoHelper::instance(), &FileInfoHelper::mediaDataFinished, this, &QuickFileBaseInfoModel::imageExtenInfo, Qt::UniqueConnection); + const QMap &mediaAttributes = localinfo->mediaInfoAttributes(DFileInfo::MediaType::kImage, extenList); + if (!mediaAttributes.isEmpty()) + imageExtenInfo(url, mediaAttributes); + + } else if (type == FileInfo::FileType::kAudios) { + extenList << DFileInfo::AttributeExtendID::kExtendMediaDuration; + connect(&FileInfoHelper::instance(), &FileInfoHelper::mediaDataFinished, this, &QuickFileBaseInfoModel::audioExtenInfo, Qt::UniqueConnection); + const QMap &mediaAttributes = localinfo->mediaInfoAttributes(DFileInfo::MediaType::kAudio, extenList); + if (!mediaAttributes.isEmpty()) + audioExtenInfo(url, mediaAttributes); + } + } + + if (!(markedType & kFileInterviewTimeField)) { + auto lastRead = localinfo->timeOf(TimeInfoType::kLastRead).value(); + if (lastRead.isValid()) { + appendKeyValue(DetailFilterType::kFileInterviewTimeField, lastRead.toString(FileUtils::dateTimeFormat())); + } + } + + if (!(markedType & kFileChangeTimeField)) { + auto lastModified = localinfo->timeOf(TimeInfoType::kLastModified).value(); + if (lastModified.isValid()) { + appendKeyValue(DetailFilterType::kFileChangeTimeField, lastModified.toString(FileUtils::dateTimeFormat())); + } + } +} + +void QuickFileBaseInfoModel::sortKeyValue() +{ + std::sort(keyValueList.begin(), keyValueList.end(), [](const KeyValue &first, const KeyValue &second) { + return first.type < second.type; + }); +} + +QString QuickFileBaseInfoModel::parseViewSize(const QMap &properties) const +{ + int width = properties[DFileInfo::AttributeExtendID::kExtendMediaWidth].toInt(); + int height = properties[DFileInfo::AttributeExtendID::kExtendMediaHeight].toInt(); + const QString &viewSize = QString::number(width) + "x" + QString::number(height); + + return viewSize; +} + +QString QuickFileBaseInfoModel::parseDuration(const QMap &properties) const +{ + QVariant duration = properties[DFileInfo::AttributeExtendID::kExtendMediaDuration]; + int s = duration.toInt(); + QTime t(0, 0, 0); + t = t.addMSecs(s); + const QString &durationStr = t.toString("hh:mm:ss"); + + return durationStr; +} + +QString QuickFileBaseInfoModel::displayFieldName(DetailFilterType field) +{ + switch (field) { + case DetailFilterType::kFileNameField: + return tr("Name"); + case DetailFilterType::kFileSizeField: + return tr("Size"); + case DetailFilterType::kFileViewSizeField: + return tr("Dimension"); + case DetailFilterType::kFileDurationField: + return tr("Duration"); + case DetailFilterType::kFileTypeField: + return tr("Type"); + case DetailFilterType::kFileInterviewTimeField: + return tr("Accessed"); + case DetailFilterType::kFileChangeTimeField: + return tr("Modified"); + default: + return tr("Unknown"); + } +} + +/*! + * \brief 追加文件信息键值对,\a field 是当前字段标识,存储时通过 displayFieldName() 转换为键名,\a value 为展示的值信息, + * \a specialKey 用于拓展信息显示特殊的字段名称,\a insert 用于标记字段数据是被插入的,不会记录对应字段已被写入。 + * 更新数据后,对应字段(非插入)会标记已写入,后续不会重复更新。 + */ +void QuickFileBaseInfoModel::appendKeyValue(DetailFilterType field, const QString &value, const QString &specialKey, bool insert) +{ + // 除拓展数据,已有的数据不允许二次插入 + if (markedType.testFlags(field) && !insert) { + return; + } + + // 非插入数据会标记字段已被填充 + if (!insert) { + markedType |= field; + } + + // 拓展的数据使用特殊键值 + QString key = specialKey.isEmpty() ? displayFieldName(field) : specialKey; + + if (!reseting) { + // 非复位模型状态,按顺序插入 + auto findItr = std::lower_bound(keyValueList.begin(), keyValueList.end(), field, [](const KeyValue &val, DetailFilterType cmpType) { + return val.type < cmpType; + }); + int index = std::distance(keyValueList.begin(), findItr); + + beginInsertRows(QModelIndex(), index, index); + keyValueList.insert(index, { field, key, value }); + endInsertRows(); + + } else { + keyValueList.append({ field, key, value }); + } +} + +} diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/model/quickfilebaseinfomodel.h b/src/plugins/filemanager/core/dfmplugin-detailspace/model/quickfilebaseinfomodel.h new file mode 100644 index 0000000000..83669c6730 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/model/quickfilebaseinfomodel.h @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef QUICKFILEBASEINFOMODEL_H +#define QUICKFILEBASEINFOMODEL_H + +#include "dfmplugin_detailspace_global.h" + +#include + +#include +#include + +namespace dfmplugin_detailspace { + +class QuickFileBaseInfoModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged FINAL) + +public: + enum Field { + kKeyRole = Qt::UserRole + 1, + kValueRole, + }; + + explicit QuickFileBaseInfoModel(QObject *parent = nullptr); + + QUrl url() const; + Q_SLOT void setUrl(const QUrl &url); + Q_SIGNAL void urlChanged(const QUrl &url); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; + +public Q_SLOTS: + void imageExtenInfo(const QUrl &url, QMap properties); + void videoExtenInfo(const QUrl &url, QMap properties); + void audioExtenInfo(const QUrl &url, QMap properties); + void receiveExtenInfo(DetailFilterType field, const QString &value); + +private: + void clearKeyValue(); + void resetFieldValue(const QUrl &url); + void markFilter(const QUrl &url); + void basicExpand(const QUrl &url); + void basicFill(const QUrl &url); + void sortKeyValue(); + void appendKeyValue(DetailFilterType field, const QString &value, const QString &specialKey = {}, bool insert = false); + + QString parseViewSize(const QMap &properties) const; + QString parseDuration(const QMap &properties) const; + QString displayFieldName(DetailFilterType field); + +Q_SIGNALS: + void sigExtenInfo(DetailFilterType field, const QString &value); + +private: + QUrl modelUrl; + bool reseting = false; + QFlags markedType; // 标记类型已被写入,非插入字段将跳过 + + struct KeyValue + { + DetailFilterType type = DetailFilterType::kNotFilter; + QString key; + QString value; + }; + QList keyValueList; +}; + +} + +#endif // QUICKFILEBASEINFOMODEL_H diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/qml/DetailSpace.qml b/src/plugins/filemanager/core/dfmplugin-detailspace/qml/DetailSpace.qml new file mode 100644 index 0000000000..c555d67bdd --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/qml/DetailSpace.qml @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Layouts +import org.deepin.dtk +import org.dfm.base + +ContainmentItem { + id: detailspace + + property int widgetType: QuickUtils.DetailSpace + + Layout.fillHeight: true + implicitWidth: 250 + + Containment.onAppletRootObjectChanged: appletItem => { + itemModel.append(appletItem); + } + + Rectangle { + anchors.fill: parent + border.color: "blue" + border.width: 1 + color: "transparent" + } + + ColumnLayout { + anchors.fill: parent + + Text { + color: "lightgray" + font.pointSize: 36 + text: "Detail Space" + } + + Loader { + Layout.fillHeight: true + Layout.fillWidth: true + active: detailspace.visible + + sourceComponent: FileBaseInfoView { + id: infoView + + anchors.fill: parent + } + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-detailspace/qml/FileBaseInfoView.qml b/src/plugins/filemanager/core/dfmplugin-detailspace/qml/FileBaseInfoView.qml new file mode 100644 index 0000000000..7b0449bcd7 --- /dev/null +++ b/src/plugins/filemanager/core/dfmplugin-detailspace/qml/FileBaseInfoView.qml @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Layouts +import org.deepin.dtk +import org.dfm.base +import org.dfm.detailspace + +Item { + property int fieldWidth: 100 + property int valueWidth: 150 + + BaseFileInfoModel { + id: baseModel + + url: Containment.currentUrl + } + + ListView { + anchors.fill: parent + interactive: false + model: baseModel + + delegate: Row { + Text { + id: field + + elide: Text.ElideMiddle + font.bold: true + horizontalAlignment: Text.AlignLeft + text: model.key + width: fieldWidth + } + + Text { + id: value + + elide: Text.ElideMiddle + horizontalAlignment: Text.AlignLeft + text: model.value + width: valueWidth + } + } + } +} diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml b/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml index 39ceee519c..72b5107357 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/qml/Titlebar.qml @@ -69,7 +69,7 @@ ContainmentItem { onClicked: { console.warn("--- test", Containment.applets); - Applet.currentUrl = "file:///home/uos/Downloads/GammaRay/build/bin"; + Applet.currentUrl = "file:///home/uos/Videos/dde-introduction.mp4"; } } } diff --git a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.cpp b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.cpp index b5eeb967d8..5586a1b4bd 100644 --- a/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.cpp +++ b/src/plugins/filemanager/core/dfmplugin-titlebar/titlebarcontainment.cpp @@ -25,15 +25,15 @@ QuickCrumbModel *TitlebarContainment::crumbModel() const void TitlebarContainment::onUrlChanged(const QUrl &url) { - TitleBarEventCaller::sendCd(this, url); + if (rootObject()) { + TitleBarEventCaller::sendCd(this, url); + } updateController(url); if (crumbController) { crumbController->crumbUrlChangedBehavior(url); } - - } void TitlebarContainment::updateController(const QUrl &url)