diff --git a/ChatView/ChatModel.cpp b/ChatView/ChatModel.cpp index 3f8a700..e097f98 100644 --- a/ChatView/ChatModel.cpp +++ b/ChatView/ChatModel.cpp @@ -117,8 +117,10 @@ QVariant ChatModel::data(const QModelIndex &index, int role) const QString contentFolder = QDir(dirPath).filePath(baseName + "_content"); QString fullPath = QDir(contentFolder).filePath(image.storedPath); imageMap["imageUrl"] = QUrl::fromLocalFile(fullPath).toString(); + imageMap["filePath"] = fullPath; } else { imageMap["imageUrl"] = QString(); + imageMap["filePath"] = QString(); } imagesList.append(imageMap); diff --git a/ChatView/qml/chatparts/ChatItem.qml b/ChatView/qml/chatparts/ChatItem.qml index 0b20453..e48be80 100644 --- a/ChatView/qml/chatparts/ChatItem.qml +++ b/ChatView/qml/chatparts/ChatItem.qml @@ -181,9 +181,12 @@ Rectangle { onClicked: function() { root.resetChatToMessage(root.messageIndex) } - ToolTip.visible: hovered - ToolTip.text: qsTr("Reset chat to this message and edit") - ToolTip.delay: 500 + + QoAToolTip { + visible: stopButtonId.hovered + text: qsTr("Reset chat to this message and edit") + delay: 500 + } } component TextComponent : TextBlock { @@ -267,33 +270,21 @@ Rectangle { anchors.fill: parent hoverEnabled: true - acceptedButtons: Qt.LeftButton | Qt.RightButton + acceptedButtons: Qt.LeftButton cursorShape: Qt.PointingHandCursor onClicked: (mouse) => { - if (mouse.button === Qt.LeftButton) { + if (mouse.modifiers & Qt.ShiftModifier) { + fileItem.openFileInExternalEditor() + } else { fileItem.openFileInEditor() - } else if (mouse.button === Qt.RightButton) { - attachmentContextMenu.popup() } } - ToolTip.visible: containsMouse - ToolTip.text: qsTr("Left click: Open in Qt Creator\nRight click: More options") - ToolTip.delay: 500 - } - - Menu { - id: attachmentContextMenu - - MenuItem { - text: qsTr("Open in Qt Creator") - onTriggered: fileItem.openFileInEditor() - } - - MenuItem { - text: qsTr("Open in System Editor") - onTriggered: fileItem.openFileInExternalEditor() + QoAToolTip { + visible: attachFileMouseArea.containsMouse + text: qsTr("Click: Open in Qt Creator\nShift+Click: Open in System Editor") + delay: 500 } } } @@ -315,7 +306,7 @@ Rectangle { FileItem { id: imageFileItem - filePath: itemData.imageUrl ? itemData.imageUrl.toString().replace("file://", "") : "" + filePath: itemData.filePath || "" } ColumnLayout { @@ -371,33 +362,21 @@ Rectangle { anchors.fill: parent hoverEnabled: true - acceptedButtons: Qt.LeftButton | Qt.RightButton + acceptedButtons: Qt.LeftButton cursorShape: Qt.PointingHandCursor onClicked: (mouse) => { - if (mouse.button === Qt.LeftButton) { + if (mouse.modifiers & Qt.ShiftModifier) { + imageFileItem.openFileInExternalEditor() + } else { imageFileItem.openFileInEditor() - } else if (mouse.button === Qt.RightButton) { - imageContextMenu.popup() } } - ToolTip.visible: containsMouse - ToolTip.text: qsTr("Left click: Open in System\nRight click: More options") - ToolTip.delay: 500 - } - - Menu { - id: imageContextMenu - - MenuItem { - text: qsTr("Open in Qt Creator") - onTriggered: imageFileItem.openFileInEditor() - } - - MenuItem { - text: qsTr("Open in System Viewer") - onTriggered: imageFileItem.openFileInExternalEditor() + QoAToolTip { + visible: imageMouseArea.containsMouse + text: qsTr("Click: Open in Qt Creator\nShift+Click: Open in System Editor") + delay: 500 } } } diff --git a/ChatView/qml/controls/AttachedFilesPlace.qml b/ChatView/qml/controls/AttachedFilesPlace.qml index 739d3f5..ab554ba 100644 --- a/ChatView/qml/controls/AttachedFilesPlace.qml +++ b/ChatView/qml/controls/AttachedFilesPlace.qml @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024-2025 Petr Mironychev + * Copyright (C) 2024-2026 Petr Mironychev * * This file is part of QodeAssist. * @@ -21,6 +21,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import ChatView +import UIControls Flow { id: root @@ -78,9 +79,11 @@ Flow { } } - ToolTip.visible: containsMouse - ToolTip.delay: 500 - ToolTip.text: "Click: Open in Qt Creator\nShift+Click: Open in external editor\nCtrl+Click / Middle Click: Remove" + QoAToolTip { + visible: mouse.containsMouse + delay: 500 + text: "Click: Open in Qt Creator\nShift+Click: Open in external editor\nCtrl+Click / Middle Click: Remove" + } } Menu { diff --git a/UIControls/CMakeLists.txt b/UIControls/CMakeLists.txt index 7d38401..c22c9ab 100644 --- a/UIControls/CMakeLists.txt +++ b/UIControls/CMakeLists.txt @@ -13,11 +13,12 @@ qt_add_qml_module(QodeAssistUIControls qml/QoATextSlider.qml qml/QoAComboBox.qml qml/FadeListItemAnimation.qml + qml/QoASeparator.qml + qml/QoAToolTip.qml RESOURCES icons/dropdown-arrow-light.svg icons/dropdown-arrow-dark.svg - QML_FILES qml/QoASeparator.qml ) target_link_libraries(QodeAssistUIControls diff --git a/UIControls/qml/QoAToolTip.qml b/UIControls/qml/QoAToolTip.qml new file mode 100644 index 0000000..698e405 --- /dev/null +++ b/UIControls/qml/QoAToolTip.qml @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2026 Petr Mironychev + * + * This file is part of QodeAssist. + * + * QodeAssist is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QodeAssist is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QodeAssist. If not, see . + */ + +import QtQuick +import QtQuick.Controls + +ToolTip { + id: root + + padding: 8 + + contentItem: Text { + text: root.text + font: root.font + color: palette.toolTipText + wrapMode: Text.Wrap + } + + background: Item { + implicitWidth: bg.implicitWidth + implicitHeight: bg.implicitHeight + + Rectangle { + anchors.fill: bg + anchors.margins: -2 + color: Qt.rgba(palette.shadow.r, palette.shadow.g, palette.shadow.b, 0.12) + radius: 8 + z: -2 + } + + Rectangle { + anchors.fill: bg + anchors.margins: -1 + color: Qt.rgba(palette.shadow.r, palette.shadow.g, palette.shadow.b, 0.08) + radius: 7 + z: -1 + } + + Rectangle { + id: bg + anchors.fill: parent + color: palette.toolTipBase + border.color: Qt.darker(palette.toolTipBase, 1.2) + border.width: 1 + radius: 6 + } + } + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0.0 + to: 1.0 + duration: 150 + easing.type: Easing.OutQuad + } + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1.0 + to: 0.0 + duration: 100 + easing.type: Easing.InQuad + } + } +}