From b3c34995bfdcf98afc90cddd85944357e8c394f9 Mon Sep 17 00:00:00 2001 From: Ofek Itscovits Date: Fri, 15 Mar 2024 14:36:25 +0200 Subject: [PATCH 1/2] qt6 --- package/contents/config/config.qml | 4 +- package/contents/ui/CompactRepresentation.qml | 24 +- package/contents/ui/configAdvanced.qml | 109 +++---- package/contents/ui/configGeneral.qml | 112 ++++---- package/contents/ui/main.qml | 271 +++++++++--------- package/metadata.desktop | 16 -- package/metadata.json | 9 +- 7 files changed, 269 insertions(+), 276 deletions(-) delete mode 100644 package/metadata.desktop diff --git a/package/contents/config/config.qml b/package/contents/config/config.qml index 490e8e6..5c5ad5e 100644 --- a/package/contents/config/config.qml +++ b/package/contents/config/config.qml @@ -1,5 +1,5 @@ -import QtQuick 2.3 -import org.kde.plasma.configuration 2.0 +import QtQuick +import org.kde.plasma.configuration ConfigModel { ConfigCategory { diff --git a/package/contents/ui/CompactRepresentation.qml b/package/contents/ui/CompactRepresentation.qml index 86d3119..aa9c200 100644 --- a/package/contents/ui/CompactRepresentation.qml +++ b/package/contents/ui/CompactRepresentation.qml @@ -1,27 +1,25 @@ -import QtQuick 2.3 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.plasmoid 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.plasmoid +import org.kde.ksvg as KSvg Item { anchors.fill: parent - - PlasmaCore.SvgItem { + + KSvg.SvgItem { anchors.centerIn: parent width: parent.width < parent.height ? parent.width : parent.height height: width - - svg: PlasmaCore.Svg { - imagePath: Qt.resolvedUrl("assets/logo.svg"); - } + imagePath: Qt.resolvedUrl("assets/logo.svg"); MouseArea { anchors.fill: parent onClicked: { - plasmoid.expanded = !plasmoid.expanded + expanded = !expanded } } } -} \ No newline at end of file +} diff --git a/package/contents/ui/configAdvanced.qml b/package/contents/ui/configAdvanced.qml index 931ee68..0b01c86 100644 --- a/package/contents/ui/configAdvanced.qml +++ b/package/contents/ui/configAdvanced.qml @@ -1,54 +1,59 @@ -import QtQuick 2.3 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.5 as QQC2 -import org.kde.kirigami 2.4 as Kirigami - -Kirigami.FormLayout { - id: page - property alias cfg_focusInterval: focusInterval.value - property alias cfg_maxReloadTime: maxReloadTime.value - property alias cfg_debugConsole: debugConsole.checked - - Layout.fillHeight:true - - QQC2.Slider { - Kirigami.FormData.label:i18n("Focus input after : %1ms",focusInterval.value ); - id: focusInterval - from:0 - stepSize:10 - value:0 - to:1000 - live:true +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 +import org.kde.kirigami as Kirigami +import org.kde.kcmutils as KCM + +KCM.SimpleKCM { + id:root + + property int cfg_focusInterval: focusInterval.value + property int cfg_maxReloadTime: maxReloadTime.value + property bool cfg_debugConsole: debugConsole.checked + + Kirigami.FormLayout { + id: page + + Layout.fillHeight:true + + QQC2.Slider { + Kirigami.FormData.label:i18n("Focus input after : %1ms",focusInterval.value ); + id: focusInterval + from:0 + stepSize:10 + value:0 + to:1000 + live:true + } + + QQC2.Label { + font.pixelSize: 8 + font.italic: true + text:i18n("This is a workaround to allow input field to be fcoused when using the widget shortcut.") + + "\n" + + i18n("incrase the timeout if theres issues with focusing on the input when using the shortcut."); + } + + QQC2.CheckBox { + id: debugConsole + Layout.alignment: Qt.AlignBottom + Kirigami.FormData.label: i18n("Show debug console") + } + + + QQC2.Slider { + Kirigami.FormData.label:i18n("Max realod is set to : %1 second ",maxReloadTime.value ); + id: maxReloadTime + from:0 + stepSize:10 + value:30 + to:3600 + live:true + } + QQC2.Label { + font.pixelSize: 8 + font.italic: true + text:i18n("This is a limit on how often the widget will try to auto reload the page (when hidden) if the page failed to load."); + } } - - QQC2.Label { - font.pixelSize: 8 - font.italic: true - text:i18n("This is a workaround to allow input field to be fcoused when using the widget shortcut.") + - "\n" + - i18n("incrase the timeout if theres issues with focusing on the input when using the shortcut."); - } - - QQC2.CheckBox { - id: debugConsole - Layout.alignment: Qt.AlignBottom - Kirigami.FormData.label: i18n("Show debug console") - } - - - QQC2.Slider { - Kirigami.FormData.label:i18n("Max realod is set to : %1 second ",maxReloadTime.value ); - id: maxReloadTime - from:0 - stepSize:10 - value:30 - to:3600 - live:true - } - QQC2.Label { - font.pixelSize: 8 - font.italic: true - text:i18n("This is a limit on how often the widget will try to auto reload the page (when hidden) if the page failed to load."); - } - } diff --git a/package/contents/ui/configGeneral.qml b/package/contents/ui/configGeneral.qml index a4d7ca4..6b9196c 100644 --- a/package/contents/ui/configGeneral.qml +++ b/package/contents/ui/configGeneral.qml @@ -1,64 +1,68 @@ -import QtQuick 2.3 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.3 -import QtQuick.Controls 2.5 as QQC2 -import org.kde.kirigami 2.4 as Kirigami +import QtQuick +import QtQuick.Layouts +import QtQuick.Dialogs +import QtQuick.Controls as QQC2 +import org.kde.kirigami as Kirigami +import org.kde.kcmutils as KCM -Kirigami.FormLayout { - id: page - property alias cfg_downloadLocation: fileDialog.folder - property alias cfg_sendOnEnter: sendOnEnter.checked - property alias cfg_matchTheme: matchTheme.checked - property alias cfg_allowClipboardAccess: allowClipboardAccess.checked +KCM.SimpleKCM { + id:root - Layout.fillHeight:true + property string cfg_downloadLocation: folderDialog.folder + property bool cfg_sendOnEnter: sendOnEnter.checked + property bool cfg_matchTheme: matchTheme.checked + property bool cfg_allowClipboardAccess: allowClipboardAccess.checked - QQC2.CheckBox { - id: sendOnEnter - text: i18n("Send On Enter") - } - QQC2.Label { - font.pixelSize: 12 - text:i18n("When checked pressing Enter will send the query to ChatGPT."); - } - QQC2.Label { - font.pixelSize: 8 - font.italic: true - text:i18n("For now please reload the page with the 'Reload' Button after changing this configuration."); - } - - QQC2.CheckBox { - id: matchTheme - text: i18n("Match OS theme") - } + Kirigami.FormLayout { + id: page - QQC2.CheckBox { - id: allowClipboardAccess - text: i18n("Allow ChatGPT system clipboard access") - } - QQC2.Label { - font.pixelSize: 8 - font.italic: true - text:i18n("This is enabled by default to allow for quick code/recipe/etc but can be disabled if you are worried about ChatCGPT examining your system clipboard"); - } + Layout.fillHeight:true - QQC2.Button { - id: downloadLocation - text: i18n("Select Download Path : %1 ", fileDialog.folder ) - onClicked:{ - fileDialog.open(); + QQC2.CheckBox { + id: sendOnEnter + text: i18n("Send On Enter") + } + QQC2.Label { + font.pixelSize: 12 + text:i18n("When checked pressing Enter will send the query to ChatGPT."); + } + QQC2.Label { + font.pixelSize: 8 + font.italic: true + text:i18n("For now please reload the page with the 'Reload' Button after changing this configuration."); } - } - QQC2.Label { - font.pixelSize: 8 - font.italic: true - text:i18n("Select the directory to download files to."); - } - FileDialog { - id:fileDialog - selectFolder:true; - } + QQC2.CheckBox { + id: matchTheme + text: i18n("Match OS theme") + } + QQC2.CheckBox { + id: allowClipboardAccess + text: i18n("Allow ChatGPT system clipboard access") + } + QQC2.Label { + font.pixelSize: 8 + font.italic: true + text:i18n("This is enabled by default to allow for quick code/recipe/etc but can be disabled if you are worried about ChatCGPT examining your system clipboard"); + } + + QQC2.Button { + id: downloadLocation + text: i18n("Select Download Path : %1 ", folderDialog.folder ) + onClicked:{ + folderDialog.open(); + } + } + QQC2.Label { + font.pixelSize: 8 + font.italic: true + text:i18n("Select the directory to download files to."); + } + + FolderDialog { + id:folderDialog + } + } } diff --git a/package/contents/ui/main.qml b/package/contents/ui/main.qml index d487839..f54ee63 100644 --- a/package/contents/ui/main.qml +++ b/package/contents/ui/main.qml @@ -3,19 +3,19 @@ * SPDX-License-Identifier: LGPL-2.1-or-later */ -import QtQuick 2.3 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Dialogs 1.3 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 3.0 as PlasmaComponents -import org.kde.plasma.plasmoid 2.0 -import org.kde.plasma.extras 2.0 as PlasmaExtras -import org.kde.kirigami 2.19 as Kirigami - -import QtWebEngine 1.9 - -Item { +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Dialogs +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.plasmoid +import org.kde.plasma.extras as PlasmaExtras +import org.kde.kirigami as Kirigami + +import QtWebEngine + +PlasmoidItem { id: root property bool themeMismatch: false; property int nextReloadTime: 0; @@ -23,19 +23,19 @@ Item { property int maxReloadRetiries: 25; property bool loadedsuccessfully:false; - Plasmoid.compactRepresentation: CompactRepresentation {} + compactRepresentation: CompactRepresentation {} - Plasmoid.fullRepresentation: ColumnLayout { + fullRepresentation: ColumnLayout { anchors.fill: parent - Layout.minimumWidth: 256 * PlasmaCore.Units.devicePixelRatio - Layout.minimumHeight: 512 * PlasmaCore.Units.devicePixelRatio - Layout.preferredWidth: 520 * PlasmaCore.Units.devicePixelRatio - Layout.preferredHeight: 840 * PlasmaCore.Units.devicePixelRatio + Layout.minimumWidth: 256 * 1 + Layout.minimumHeight: 512 * 1 + Layout.preferredWidth: 520 * 1 + Layout.preferredHeight: 840 * 1 //----------------------------- Helpers -------------------------------------------- // Added workaround by @zontafil thank you! - + Timer { id: exposeTimer @@ -68,7 +68,7 @@ Item { //-------------------------------------- Connections && handlers ------------------------------------ - Keys.onPressed: { + Keys.onPressed: { if (event.key === Qt.Key_F5 && gptWebView) { gptWebView.reload(); } @@ -113,10 +113,10 @@ Item { ColumnLayout { spacing: Kirigami.Units.mediumSpacing - PlasmaExtras.PlasmoidHeading { + Kirigami.Heading { Layout.fillWidth: true - ColumnLayout { + ColumnLayout { anchors.fill: parent Layout.fillWidth: true @@ -244,135 +244,140 @@ Item { //------------------------- Actual ChatGPT View -------------------------- WebEngineView { - // anchors.fill: parent - Layout.fillHeight: true - Layout.fillWidth: true - - id: gptWebView - focus: true - url: "https://chat.openai.com/chat" - - profile: WebEngineProfile { - id: chatGptProfile - storageName: "chat-gpt" - offTheRecord: false - httpCacheType: WebEngineProfile.DiskHttpCache - persistentCookiesPolicy: WebEngineProfile.ForcePersistentCookies - downloadPath: (plasmoid.configuration.downloadLocation ? - Qt.resolveUrl(plasmoid.configuration.downloadLocation) : - chatGptProfile.downloadPath) + "/" - userScripts: [ - WebEngineScript { - injectionPoint: WebEngineScript.DocumentCreation - name: "helperFunctions" - worldId: WebEngineScript.MainWorld - sourceUrl: "./js/helper_functions.js" - } - ] - onDownloadFinished: { - console.log("onDownloadFinished : " +download.downloadDirectory + download.downloadFileName); - } - onDownloadRequested : { - console.log("onDownloadRequested : " + download.downloadFileName); - if( plasmoid.configuration.downloadLocation ) { - download.downloadDirectory = chatGptProfile.downloadPath; - download.accept(); - console.log("onDownloadRequested : downloaded to "+download.downloadDirectory); - console.log("onDownloadRequested : downloaded to "+plasmoid.configuration.downloadLocation ); - } else { - console.log("onDownloadRequested : please configure a download location"); - } - } + // anchors.fill: parent + Layout.fillHeight: true + Layout.fillWidth: true + + id: gptWebView + focus: true + url: "https://chat.openai.com/chat" + + profile: WebEngineProfile { + id: chatGptProfile + storageName: "chat-gpt" + offTheRecord: false + httpCacheType: WebEngineProfile.DiskHttpCache + persistentCookiesPolicy: WebEngineProfile.ForcePersistentCookies + downloadPath: (plasmoid.configuration.downloadLocation ? + Qt.resolveUrl(plasmoid.configuration.downloadLocation) : + chatGptProfile.downloadPath) + "/" + + onDownloadFinished: { + console.log("onDownloadFinished : " +download.downloadDirectory + download.downloadFileName); } - - settings.javascriptCanAccessClipboard: plasmoid.configuration.allowClipboardAccess - - onLoadingChanged: { - if(WebEngineView.LoadSucceededStatus === loadRequest.status) { - root.reloadRetries = 0; - let themeLightness = (isDark(theme.backgroundColor) ? 'dark' : 'light') ; - - gptWebView.runJavaScript("document.userScripts.setConfig("+JSON.stringify(plasmoid.configuration)+");"); - gptWebView.runJavaScript("document.userScripts.setSendOnEnter();"); - gptWebView.runJavaScript("document.userScripts.getTheme();",function(theme) { - if( !plasmoid.expanded && plasmoid.configuration.matchTheme && (!theme || theme !== themeLightness)) { - gptWebView.runJavaScript("document.userScripts.setTheme('"+themeLightness+"');"); - gptWebView.relreloadAndBypassCacheoad(); - } else if(plasmoid.configuration.matchTheme && theme !== themeLightness) { - root.themeMismatch = true; - } - }); - gptWebView.runJavaScript("document.userScripts.setTheme('"+themeLightness+"');"); + onDownloadRequested : { + console.log("onDownloadRequested : " + download.downloadFileName); + if( plasmoid.configuration.downloadLocation ) { + download.downloadDirectory = chatGptProfile.downloadPath; + download.accept(); + console.log("onDownloadRequested : downloaded to "+download.downloadDirectory); + console.log("onDownloadRequested : downloaded to "+plasmoid.configuration.downloadLocation ); + } else { + console.log("onDownloadRequested : please configure a download location"); } + } + } + settings.javascriptCanAccessClipboard: plasmoid.configuration.allowClipboardAccess - loadedsuccessfully = ( loadRequest.status == WebEngineLoadRequest.LoadSucceededStatus && (gptWebView.loadProgress == 100 || gptWebView.loadProgress == 0)) - && - ( !gptWebView.loading ) - + Component.onCompleted: { + var helperScript = { + name: "helperFunctions", + injectionPoint: WebEngineScript.DocumentCreation, + sourceUrl: Qt.resolvedUrl("./js/helper_functions.js"), + worldId: WebEngineScript.MainWorld } - onFileDialogRequested: { - console.log("onFileDialogRequested"); - //console.log(JSON.stringify(request)); - fileDialog.title = "Choose File"; - fileDialog.accept.connect(function (request){ - request.dialogAccept(fileDialog.selectedFiles); - }); - fileDialog.reject.connect(function(request) { - request.dialogReject() + userScripts.collection = [ helperScript ] + } + + onLoadingChanged: { + if(WebEngineView.LoadSucceededStatus === loadRequest.status) { + root.reloadRetries = 0; + let themeLightness = (isDark(theme.backgroundColor) ? 'dark' : 'light') ; + + gptWebView.runJavaScript("document.userScripts.setConfig("+JSON.stringify(plasmoid.configuration)+");"); + gptWebView.runJavaScript("document.userScripts.setSendOnEnter();"); + gptWebView.runJavaScript("document.userScripts.getTheme();",function(theme) { + if( !plasmoid.expanded && plasmoid.configuration.matchTheme && (!theme || theme !== themeLightness)) { + gptWebView.runJavaScript("document.userScripts.setTheme('"+themeLightness+"');"); + gptWebView.relreloadAndBypassCacheoad(); + } else if(plasmoid.configuration.matchTheme && theme !== themeLightness) { + root.themeMismatch = true; + } }); - fileDialog.open(); - request.accepted = true + gptWebView.runJavaScript("document.userScripts.setTheme('"+themeLightness+"');"); } - onJavaScriptDialogRequested : { - console.log("onJavaScriptDialogRequested"); + + loadedsuccessfully = ( loadRequest.status == WebEngineLoadRequest.LoadSucceededStatus && (gptWebView.loadProgress == 100 || gptWebView.loadProgress == 0)) + && + ( !gptWebView.loading ) + + } + + onFileDialogRequested: { + console.log("onFileDialogRequested"); + //console.log(JSON.stringify(request)); + fileDialog.title = "Choose File"; + fileDialog.accept.connect(function (request){ + request.dialogAccept(fileDialog.selectedFiles); + }); + fileDialog.reject.connect(function(request) { + request.dialogReject() + }); + fileDialog.open(); + request.accepted = true + } + + onJavaScriptDialogRequested : { + console.log("onJavaScriptDialogRequested"); + } + + onNewWindowRequested : { + console.log("onNewViewRequested"); + if(request.requestedUrl.toString().match(/https?\:\/\/chat\.openai\.com/)) { + gptWebView.url = request.requestedUrl; + console.log(request.url); + } else { + Qt.openUrlExternally(request.url); + request.action = WebEngineNavigationRequest.IgnoreRequest; } + } - onNewViewRequested : { - console.log("onNewViewRequested"); - if(request.requestedUrl.toString().match(/https?\:\/\/chat\.openai\.com/)) { - gptWebView.url = request.requestedUrl; + onJavaScriptConsoleMessage: if( Qt.application.arguments[0].match(/plasmoidviewer/) ) { + console.log("Chat-GPT: " + message); + } + + onNavigationRequested: { + if(request.navigationType == WebEngineNavigationRequest.LinkClickedNavigation) { + if(request.url.toString().match(/https?\:\/\/chat\.openai\.com/)) { + gptWebView.url = request.url; console.log(request.url); } else { Qt.openUrlExternally(request.url); request.action = WebEngineNavigationRequest.IgnoreRequest; } } - - onJavaScriptConsoleMessage: if( Qt.application.arguments[0].match(/plasmoidviewer/) ) { - console.log("Chat-GPT: " + message); - } - - onNavigationRequested: { - if(request.navigationType == WebEngineNavigationRequest.LinkClickedNavigation) { - if(request.url.toString().match(/https?\:\/\/chat\.openai\.com/)) { - gptWebView.url = request.url; - console.log(request.url); - } else { - Qt.openUrlExternally(request.url); - request.action = WebEngineNavigationRequest.IgnoreRequest; - } - } - } - - function isDark(color) { - let luminance = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; - return (luminance < 0.5); - } } - WebEngineView { - id:gptWebViewInspector - enabled: false - visible: false - z:100 - height:parent.height /2 - - Layout.fillWidth:true - Layout.alignment:Qt.AlignBottom - inspectedView:enabled ? gptWebView : null + + function isDark(color) { + let luminance = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; + return (luminance < 0.5); } + } + + WebEngineView { + id:gptWebViewInspector + enabled: false + visible: false + z:100 + height:parent.height /2 + + Layout.fillWidth:true + Layout.alignment:Qt.AlignBottom + inspectedView:enabled ? gptWebView : null + } } } diff --git a/package/metadata.desktop b/package/metadata.desktop deleted file mode 100644 index 3e55c22..0000000 --- a/package/metadata.desktop +++ /dev/null @@ -1,16 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Name=ChatGPT plasmoid for Plasma -Keywords=ChatGPT -Icon=search-symbolic -X-Plasma-API=declarativeappletscript -Type=Service -X-Plasma-Provides=com.darkeye.chatGPT -X-KDE-ServiceTypes=Plasma/Applet -X-KDE-PluginInfo-Category=Windows and Tasks -X-KDE-PluginInfo-Name=com.darkeye.chatGPT -X-KDE-PluginInfo-EnabledByDefault=true -X-KDE-PluginInfo-Version=0.9 -X-KDE-PluginInfo-Website=https://github.com/dark-eye/com.darkeye.chatGPT -KDE-PluginInfo-License=BSD 3.0 -X-Plasma-MainScript=ui/main.qml diff --git a/package/metadata.json b/package/metadata.json index 67260f2..724b3ec 100644 --- a/package/metadata.json +++ b/package/metadata.json @@ -1,4 +1,5 @@ { + "KPackageStructure": "Plasma/Applet", "KPlugin": { "Authors": [ { @@ -11,13 +12,9 @@ "Id": "com.darkeye.chatGPT", "License": "BSD 3.0", "Name": "ChatGPT Plasmoid", - "ServiceTypes": [ - "Plasma/Applet" - ], "Version": "0.8", "Website": "https://github.com/dark-eye/com.darkeye.chatGPT" }, - "X-Plasma-API": "declarativeappletscript", - "X-Plasma-MainScript": "ui/main.qml", - "X-Plasma-StandAloneApp": true + "X-Plasma-StandAloneApp": true, + "X-Plasma-API-Minimum-Version": "6.0" } From 71edddec2f7dbaed0910296a4ff59e1267f147c4 Mon Sep 17 00:00:00 2001 From: Ofek Itscovits Date: Fri, 15 Mar 2024 15:02:51 +0200 Subject: [PATCH 2/2] Improve settings ui a tad bit --- package/contents/ui/configAdvanced.qml | 4 ++-- package/contents/ui/configGeneral.qml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package/contents/ui/configAdvanced.qml b/package/contents/ui/configAdvanced.qml index 0b01c86..13b3279 100644 --- a/package/contents/ui/configAdvanced.qml +++ b/package/contents/ui/configAdvanced.qml @@ -27,7 +27,7 @@ KCM.SimpleKCM { } QQC2.Label { - font.pixelSize: 8 + opacity: 0.7 font.italic: true text:i18n("This is a workaround to allow input field to be fcoused when using the widget shortcut.") + "\n" + @@ -51,7 +51,7 @@ KCM.SimpleKCM { live:true } QQC2.Label { - font.pixelSize: 8 + opacity: 0.7 font.italic: true text:i18n("This is a limit on how often the widget will try to auto reload the page (when hidden) if the page failed to load."); } diff --git a/package/contents/ui/configGeneral.qml b/package/contents/ui/configGeneral.qml index 6b9196c..f89506b 100644 --- a/package/contents/ui/configGeneral.qml +++ b/package/contents/ui/configGeneral.qml @@ -24,11 +24,11 @@ KCM.SimpleKCM { text: i18n("Send On Enter") } QQC2.Label { - font.pixelSize: 12 + opacity: 0.7 text:i18n("When checked pressing Enter will send the query to ChatGPT."); } QQC2.Label { - font.pixelSize: 8 + opacity: 0.7 font.italic: true text:i18n("For now please reload the page with the 'Reload' Button after changing this configuration."); } @@ -43,7 +43,7 @@ KCM.SimpleKCM { text: i18n("Allow ChatGPT system clipboard access") } QQC2.Label { - font.pixelSize: 8 + opacity: 0.7 font.italic: true text:i18n("This is enabled by default to allow for quick code/recipe/etc but can be disabled if you are worried about ChatCGPT examining your system clipboard"); } @@ -56,7 +56,7 @@ KCM.SimpleKCM { } } QQC2.Label { - font.pixelSize: 8 + opacity: 0.7 font.italic: true text:i18n("Select the directory to download files to."); }