diff --git a/ChatView/qml/RootItem.qml b/ChatView/qml/RootItem.qml index 4f79079..14290e5 100644 --- a/ChatView/qml/RootItem.qml +++ b/ChatView/qml/RootItem.qml @@ -124,9 +124,6 @@ ChatRootView { icon.source: (typeof _chatview !== 'undefined') ? "qrc:/qt/qml/ChatView/icons/open-in-editor.svg" : "qrc:/qt/qml/ChatView/icons/open-in-window.svg" - ToolTip.text: (typeof _chatview !== 'undefined') - ? qsTr("Move this chat to an editor tab") - : qsTr("Move this chat to a separate window") onClicked: { if (typeof _chatview !== 'undefined') root.relocateToSplit() @@ -134,6 +131,9 @@ ChatRootView { root.relocateToWindow() } } + relocateTooltip.text: (typeof _chatview !== 'undefined') + ? qsTr("Move this chat to an editor tab") + : qsTr("Move this chat to a separate window") toolsButton { checked: root.useTools onCheckedChanged: { @@ -156,19 +156,19 @@ ChatRootView { root.applyConfiguration(root.availableConfigurations[index]) } } - + popup.onAboutToShow: { root.loadAvailableConfigurations() } } - + roleSelector { model: root.availableAgentRoles displayText: root.currentAgentRole onActivated: function(index) { root.applyAgentRole(root.availableAgentRoles[index]) } - + popup.onAboutToShow: { root.loadAvailableAgentRoles() } @@ -561,8 +561,8 @@ ChatRootView { sendButton.icon.source: !root.isRequestInProgress ? "qrc:/qt/qml/ChatView/icons/chat-icon.svg" : "qrc:/qt/qml/ChatView/icons/chat-pause-icon.svg" sendButton.text: !root.isRequestInProgress ? qsTr("Send") : qsTr("Stop") - sendButton.ToolTip.text: !root.isRequestInProgress ? qsTr("Send message to LLM %1").arg(Qt.platform.os === "osx" ? "Cmd+Return" : "Ctrl+Return") - : qsTr("Stop") + sendButtonTooltip.text: !root.isRequestInProgress ? qsTr("Send message to LLM %1").arg(Qt.platform.os === "osx" ? "Cmd+Return" : "Ctrl+Return") + : qsTr("Stop") compressButton.onClicked: compressConfirmDialog.open() cancelCompressButton.onClicked: root.cancelCompression() syncOpenFiles { diff --git a/ChatView/qml/chatparts/FileEditBlock.qml b/ChatView/qml/chatparts/FileEditBlock.qml index fb447a6..1167c2a 100644 --- a/ChatView/qml/chatparts/FileEditBlock.qml +++ b/ChatView/qml/chatparts/FileEditBlock.qml @@ -259,10 +259,12 @@ Rectangle { } hoverEnabled: true onClicked: root.openInEditor(editData.edit_id) - - ToolTip.visible: hovered - ToolTip.text: qsTr("Open file in editor and navigate to changes") - ToolTip.delay: 500 + + QoAToolTip { + visible: parent.hovered + delay: 500 + text: qsTr("Open file in editor and navigate to changes") + } } QoAButton { diff --git a/ChatView/qml/controls/BottomBar.qml b/ChatView/qml/controls/BottomBar.qml index cc8a1a9..583077d 100644 --- a/ChatView/qml/controls/BottomBar.qml +++ b/ChatView/qml/controls/BottomBar.qml @@ -19,6 +19,7 @@ Rectangle { property alias cancelCompressButton: cancelCompressButtonId property bool isCompressing: false + property alias sendButtonTooltip: sendButtonTooltipId color: palette.window.hslLightness > 0.5 ? Qt.darker(palette.window, 1.1) : @@ -45,9 +46,12 @@ Rectangle { height: 15 width: 8 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Attach file to message") + + QoAToolTip { + visible: attachFilesId.hovered + delay: 250 + text: qsTr("Attach file to message") + } } QoAButton { @@ -58,9 +62,12 @@ Rectangle { height: 15 width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Attach image to message") + + QoAToolTip { + visible: attachImagesId.hovered + delay: 250 + text: qsTr("Attach image to message") + } } QoAButton { @@ -71,9 +78,12 @@ Rectangle { height: 15 width: 8 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Link file to context") + + QoAToolTip { + visible: linkFilesId.hovered + delay: 250 + text: qsTr("Link file to context") + } } CheckBox { @@ -81,8 +91,10 @@ Rectangle { text: qsTr("Sync open files") - ToolTip.visible: syncOpenFilesId.hovered - ToolTip.text: qsTr("Automatically synchronize currently opened files with the model context") + QoAToolTip { + visible: syncOpenFilesId.hovered + text: qsTr("Automatically synchronize currently opened files with the model context") + } } Item { @@ -117,9 +129,11 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter text: qsTr("Cancel") - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Cancel compression") + QoAToolTip { + visible: cancelCompressButtonId.hovered + delay: 250 + text: qsTr("Cancel compression") + } } } @@ -134,9 +148,12 @@ Rectangle { height: 15 width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Compress chat (create summarized copy using LLM)") + + QoAToolTip { + visible: compressButtonId.hovered + delay: 250 + text: qsTr("Compress chat (create summarized copy using LLM)") + } } QoAButton { @@ -146,8 +163,13 @@ Rectangle { height: 15 width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 + + QoAToolTip { + id: sendButtonTooltipId + + visible: sendButtonId.hovered + delay: 250 + } } } } diff --git a/ChatView/qml/controls/FileEditsActionBar.qml b/ChatView/qml/controls/FileEditsActionBar.qml index bfe8de7..3a416f9 100644 --- a/ChatView/qml/controls/FileEditsActionBar.qml +++ b/ChatView/qml/controls/FileEditsActionBar.qml @@ -117,12 +117,14 @@ Rectangle { text: root.hasPendingEdits ? qsTr("Apply All (%1)").arg(root.pendingEdits + root.rejectedEdits) : qsTr("Reapply All (%1)").arg(root.rejectedEdits) - - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: root.hasPendingEdits - ? qsTr("Apply all pending and rejected edits in this message") - : qsTr("Reapply all rejected edits in this message") + + QoAToolTip { + visible: applyAllButton.hovered + delay: 250 + text: root.hasPendingEdits + ? qsTr("Apply all pending and rejected edits in this message") + : qsTr("Reapply all rejected edits in this message") + } onClicked: root.applyAllClicked() } @@ -133,10 +135,12 @@ Rectangle { visible: root.hasAppliedEdits enabled: root.hasAppliedEdits text: qsTr("Undo All (%1)").arg(root.appliedEdits) - - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Undo all applied edits in this message") + + QoAToolTip { + visible: undoAllButton.hovered + delay: 250 + text: qsTr("Undo all applied edits in this message") + } onClicked: root.undoAllClicked() } diff --git a/ChatView/qml/controls/TopBar.qml b/ChatView/qml/controls/TopBar.qml index 780f2f7..523537f 100644 --- a/ChatView/qml/controls/TopBar.qml +++ b/ChatView/qml/controls/TopBar.qml @@ -27,6 +27,7 @@ Rectangle { property alias settingsButton: settingsButtonId property alias configSelector: configSelectorId property alias roleSelector: roleSelector + property alias relocateTooltip: relocateTooltipId color: palette.window.hslLightness > 0.5 ? Qt.darker(palette.window, 1.1) : @@ -59,10 +60,13 @@ Rectangle { height: 15 width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: checked ? qsTr("Unpin chat window") - : qsTr("Pin chat window to the top") + + QoAToolTip { + visible: pinButtonId.hovered + delay: 250 + text: pinButtonId.checked ? qsTr("Unpin chat window") + : qsTr("Pin chat window to the top") + } } QoAButton { @@ -76,8 +80,13 @@ Rectangle { height: 15 width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 + + QoAToolTip { + id: relocateTooltipId + + visible: relocateButtonId.hovered + delay: 250 + } } QoASeparator { @@ -92,9 +101,12 @@ Rectangle { height: 15 width: 8 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Clean chat") + + QoAToolTip { + visible: clearButtonId.hovered + delay: 250 + text: qsTr("Clean chat") + } } QoASeparator { @@ -112,9 +124,12 @@ Rectangle { height: 15 width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Open new chat in a new tab") + + QoAToolTip { + visible: newChatButtonId.hovered + delay: 250 + text: qsTr("Open new chat in a new tab") + } } QoAComboBox { @@ -125,9 +140,11 @@ Rectangle { model: [] currentIndex: 0 - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Switch saved AI configuration") + QoAToolTip { + visible: configSelectorId.hovered + delay: 250 + text: qsTr("Switch saved AI configuration") + } } QoAComboBox { @@ -138,9 +155,11 @@ Rectangle { model: [] currentIndex: 0 - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Switch agent role (different system prompts)") + QoAToolTip { + visible: roleSelector.hovered + delay: 250 + text: qsTr("Switch agent role (different system prompts)") + } } } @@ -163,15 +182,17 @@ Rectangle { width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: { - if (!toolsButtonId.enabled) { - return qsTr("Tools are disabled in General Settings") + QoAToolTip { + visible: toolsButtonId.hovered + delay: 250 + text: { + if (!toolsButtonId.enabled) { + return qsTr("Tools are disabled in General Settings") + } + return toolsButtonId.checked + ? qsTr("Tools enabled: AI can use tools to read files, search project, and build code") + : qsTr("Tools disabled: Simple conversation without tool access") } - return checked - ? qsTr("Tools enabled: AI can use tools to read files, search project, and build code") - : qsTr("Tools disabled: Simple conversation without tool access") } } @@ -191,11 +212,14 @@ Rectangle { width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: enabled ? (checked ? qsTr("Thinking Mode enabled (Check model list support it)") - : qsTr("Thinking Mode disabled")) - : qsTr("Thinking Mode is not available for this provider") + QoAToolTip { + visible: thinkingModeId.hovered + delay: 250 + text: thinkingModeId.enabled + ? (thinkingModeId.checked ? qsTr("Thinking Mode enabled (Check model list support it)") + : qsTr("Thinking Mode disabled")) + : qsTr("Thinking Mode is not available for this provider") + } } QoAButton { @@ -210,9 +234,11 @@ Rectangle { width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Open Chat Assistant Settings") + QoAToolTip { + visible: settingsButtonId.hovered + delay: 250 + text: qsTr("Open Chat Assistant Settings") + } } QoASeparator { @@ -238,9 +264,11 @@ Rectangle { anchors.fill: parent hoverEnabled: true - ToolTip.visible: containsMouse - ToolTip.delay: 500 - ToolTip.text: recentPathId.text + QoAToolTip { + visible: parent.containsMouse && recentPathId.text.length > 0 + text: recentPathId.text + delay: 500 + } } } } @@ -261,9 +289,12 @@ Rectangle { height: 15 width: 8 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Save chat to *.json file") + + QoAToolTip { + visible: saveButtonId.hovered + delay: 250 + text: qsTr("Save chat to *.json file") + } } QoAButton { @@ -274,9 +305,12 @@ Rectangle { height: 15 width: 8 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Load chat from *.json file") + + QoAToolTip { + visible: loadButtonId.hovered + delay: 250 + text: qsTr("Load chat from *.json file") + } } QoAButton { @@ -287,9 +321,12 @@ Rectangle { height: 15 width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("Show in system") + + QoAToolTip { + visible: openChatHistoryId.hovered + delay: 250 + text: qsTr("Show in system") + } } QoASeparator {} @@ -304,9 +341,11 @@ Rectangle { width: 15 } - ToolTip.visible: hovered - ToolTip.delay: 250 - ToolTip.text: qsTr("View chat context (system prompt, role, rules)") + QoAToolTip { + visible: contextButtonId.hovered + delay: 250 + text: qsTr("View chat context (system prompt, role, rules)") + } } Badge { diff --git a/UIControls/qml/Badge.qml b/UIControls/qml/Badge.qml index 5e28540..410cab6 100644 --- a/UIControls/qml/Badge.qml +++ b/UIControls/qml/Badge.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later import QtQuick +import QtQuick.Controls Rectangle { id: root @@ -9,6 +10,12 @@ Rectangle { property alias text: badgeText.text property alias hovered: mouse.hovered + QoAToolTip { + visible: root.hovered && root.ToolTip.text.length > 0 + text: root.ToolTip.text + delay: root.ToolTip.delay + } + implicitWidth: badgeText.implicitWidth + root.radius implicitHeight: badgeText.implicitHeight + 6 color: palette.button