From fcb43fe34feb69169b9c030d13e866f6fb21aace Mon Sep 17 00:00:00 2001 From: Jokul Date: Sun, 19 Jul 2026 19:13:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20About=20=E7=AA=97=E5=8F=A3=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E6=94=B9=E4=B8=BA=E9=A1=B9=E7=9B=AE=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E7=89=88=E6=9C=AC=EF=BC=8C=E4=BB=93=E5=BA=93=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E5=A2=9E=E5=8A=A0=E4=B8=80=E9=94=AE=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package/components/AboutWindow.qml | 96 +++++++++++++++++++++++++++++- package/networkview.qml | 3 +- src/networkmonitorapplet.cpp | 9 +++ src/networkmonitorapplet.h | 4 ++ 4 files changed, 110 insertions(+), 2 deletions(-) diff --git a/package/components/AboutWindow.qml b/package/components/AboutWindow.qml index 58b6b14..fd4da21 100644 --- a/package/components/AboutWindow.qml +++ b/package/components/AboutWindow.qml @@ -17,6 +17,14 @@ Window { // 默认值与 networkview.qml 中 root.accentRed 一致,确保独立可用 property color accentColor: Qt.rgba(220 / 255, 38 / 255, 38 / 255, 1) + // 插件版本号,由父组件从 C++ 后端 applet.version 传入 + // 默认值保证组件独立可用(如 qmlscene 预览时未传入) + property string version: "1.0" + + // 复制成功状态标记:true 时复制图标变绿并显示"已复制"提示, + // 2 秒后由 copyResetTimer 复位 + property bool copied: false + width: 320 height: 260 visible: false @@ -163,7 +171,7 @@ Window { } Text { - text: "1.0" + text: version font.pixelSize: 12 color: "#333333" Layout.fillWidth: true @@ -233,6 +241,76 @@ Window { Layout.fillWidth: true wrapMode: Text.WrapAnywhere } + + // 复制按钮:点击复制仓库地址到剪贴板,成功后图标变绿并显示"已复制"提示 2 秒 + Item { + Layout.preferredWidth: 24 + Layout.preferredHeight: 24 + Layout.alignment: Qt.AlignTop + + // "已复制"提示:白底绿字小标签,显示在按钮左侧, + // 覆盖于 URL 文字上方,避免与值文本混排 + Rectangle { + anchors.right: parent.left + anchors.rightMargin: 4 + anchors.verticalCenter: parent.verticalCenter + visible: copied + width: copiedHintText.implicitWidth + 10 + height: 18 + radius: 4 + color: "#FFFFFF" + border.width: 1 + border.color: "#22A34A" + + Text { + id: copiedHintText + anchors.centerIn: parent + text: qsTr("已复制") + font.pixelSize: 10 + color: "#22A34A" + } + } + + MouseArea { + id: copyRepoMouse + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + clipboardHelper.text = "git.jokul.space/Jokul/JNetApplet" + clipboardHelper.selectAll() + clipboardHelper.copy() + copied = true + copyResetTimer.restart() + } + } + + // 复制图标:两个重叠的小圆角矩形 + // 前层矩形白底压住后层边框重叠区,形成"堆叠纸张"的视觉效果 + // 后层矩形(向右下偏移 2px) + Rectangle { + x: 8 + y: 8 + width: 10 + height: 10 + radius: 2 + color: "#FFFFFF" + border.width: 1 + border.color: copyRepoMouse.containsMouse ? "#333333" : "#999999" + } + + // 前层矩形(左上),复制成功时边框短暂变绿 + Rectangle { + x: 6 + y: 6 + width: 10 + height: 10 + radius: 2 + color: "#FFFFFF" + border.width: 1 + border.color: copied ? "#22A34A" : (copyRepoMouse.containsMouse ? "#333333" : "#999999") + } + } } } @@ -247,4 +325,20 @@ Window { } } } + + // 隐藏的 TextEdit 用于复制仓库地址到剪贴板 + // QML 没有直接剪贴板 API,用 TextEdit.selectAll()+copy() 实现 + //(与 networkview.qml 中 clipboardHelper 同模式) + TextEdit { + id: clipboardHelper + visible: false + text: "" + } + + // 复制状态还原定时器:2 秒后将 copied 复位,图标与"已复制"提示恢复原状 + Timer { + id: copyResetTimer + interval: 2000 + onTriggered: root.copied = false + } } diff --git a/package/networkview.qml b/package/networkview.qml index 891adef..8d39c81 100644 --- a/package/networkview.qml +++ b/package/networkview.qml @@ -675,10 +675,11 @@ AppletItem { } // 关于窗口:抽取为独立组件 package/components/AboutWindow.qml - // 依赖通过属性传入:accentColor = root.accentRed + // 依赖通过属性传入:accentColor = root.accentRed,version 取自 C++ 后端 applet.version AboutWindow { id: aboutWindow accentColor: root.accentRed + version: root.applet ? root.applet.version : "1.0" } // 设置窗口:独立顶层窗口,在桌面中间弹出 diff --git a/src/networkmonitorapplet.cpp b/src/networkmonitorapplet.cpp index 3d7d3f1..420ec07 100644 --- a/src/networkmonitorapplet.cpp +++ b/src/networkmonitorapplet.cpp @@ -116,6 +116,15 @@ QString NetworkMonitorApplet::ipv6Address() const return m_ipv6Address; } +// 返回插件版本号,从 dde-shell 插件元数据(metadata.json)读取 +// 版本唯一源为 CMakeLists.txt 的 project(VERSION),经 configure_file 写入 metadata.json, +// dde-shell 加载时存入 DPluginMetaData,此处通过继承自 DApplet 的 pluginMetaData() 读取 +QString NetworkMonitorApplet::version() const +{ + // metadata.json 结构:{ "Plugin": { "Version": "x.y.z", ... } } + return pluginMetaData().value("Plugin").toMap().value("Version").toString(); +} + void NetworkMonitorApplet::refresh() { readNetworkStats(); diff --git a/src/networkmonitorapplet.h b/src/networkmonitorapplet.h index f7d095d..593eca9 100644 --- a/src/networkmonitorapplet.h +++ b/src/networkmonitorapplet.h @@ -42,6 +42,8 @@ class NetworkMonitorApplet : public DApplet Q_PROPERTY(QString ipAddress READ ipAddress NOTIFY ipAddressChanged) // 活动接口的 IPv6 全球地址(已过滤 link-local 和 loopback),供 QML 显示 Q_PROPERTY(QString ipv6Address READ ipv6Address NOTIFY ipv6AddressChanged) + // 插件版本号,从 dde-shell 元数据读取,版本唯一源为 CMakeLists.txt project(VERSION) + Q_PROPERTY(QString version READ version CONSTANT) public: explicit NetworkMonitorApplet(QObject *parent = nullptr); @@ -60,6 +62,8 @@ public: QString activeInterface() const; QString ipAddress() const; QString ipv6Address() const; + // 返回插件版本号,从 dde-shell 插件元数据(metadata.json)读取 + QString version() const; Q_INVOKABLE void refresh(); Q_INVOKABLE void setActiveInterface(const QString &interface);