mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-05-30 10:59:30 -04:00
fix: Throwing focus and hotkeys to QtCreator
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
# list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.app/Contents/Resources")
|
||||||
|
list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.sdk/lib/cmake/QtCreator")
|
||||||
|
# list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.sdk")
|
||||||
|
# list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.app/Contents/Resources")
|
||||||
|
|
||||||
project(QodeAssist)
|
project(QodeAssist)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|||||||
@@ -94,5 +94,5 @@ target_link_libraries(QodeAssistChatView
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(QodeAssistChatView
|
target_include_directories(QodeAssistChatView
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,12 +6,16 @@
|
|||||||
#include <QQmlComponent>
|
#include <QQmlComponent>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
#include <QQuickItem>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
|
#include <coreplugin/actionmanager/command.h>
|
||||||
#include <logger/Logger.hpp>
|
#include <logger/Logger.hpp>
|
||||||
|
|
||||||
|
#include "QodeAssistConstants.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr Qt::WindowFlags baseFlags = Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
|
constexpr Qt::WindowFlags baseFlags = Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
|
||||||
| Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint
|
| Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint
|
||||||
@@ -39,20 +43,31 @@ ChatView::ChatView(QQmlEngine* engine)
|
|||||||
setMinimumSize({400, 300});
|
setMinimumSize({400, 300});
|
||||||
setFlags(baseFlags);
|
setFlags(baseFlags);
|
||||||
|
|
||||||
if (auto action = Core::ActionManager::command("QodeAssist.CloseChatView")) {
|
bindCommandShortcut("QodeAssist.CloseChatView", [this] { close(); });
|
||||||
m_closeShortcut = new QShortcut(action->keySequence(), this);
|
bindCommandShortcut(Constants::QODE_ASSIST_CHAT_SEND_MESSAGE, [this] {
|
||||||
connect(m_closeShortcut, &QShortcut::activated, this, &QQuickView::close);
|
QMetaObject::invokeMethod(rootObject(), "sendChatMessage");
|
||||||
|
});
|
||||||
connect(action, &Core::Command::keySequenceChanged, this, [action, this]() {
|
bindCommandShortcut(Constants::QODE_ASSIST_CHAT_CLEAR_SESSION, [this] {
|
||||||
if (m_closeShortcut) {
|
QMetaObject::invokeMethod(rootObject(), "clearChat");
|
||||||
m_closeShortcut->setKey(action->keySequence());
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
restoreSettings();
|
restoreSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatView::bindCommandShortcut(Utils::Id commandId,
|
||||||
|
const std::function<void()> &onActivated)
|
||||||
|
{
|
||||||
|
auto command = Core::ActionManager::command(commandId);
|
||||||
|
if (!command)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto shortcut = new QShortcut(command->keySequence(), this);
|
||||||
|
connect(shortcut, &QShortcut::activated, this, onActivated);
|
||||||
|
connect(command, &Core::Command::keySequenceChanged, shortcut, [command, shortcut]() {
|
||||||
|
shortcut->setKey(command->keySequence());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ChatView::closeEvent(QCloseEvent *event)
|
void ChatView::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <utils/id.h>
|
||||||
|
|
||||||
#include <QQuickView>
|
#include <QQuickView>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
|
|
||||||
@@ -27,9 +31,9 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
void restoreSettings();
|
void restoreSettings();
|
||||||
|
void bindCommandShortcut(Utils::Id commandId, const std::function<void()> &onActivated);
|
||||||
|
|
||||||
bool m_isPin;
|
bool m_isPin;
|
||||||
QShortcut *m_closeShortcut;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::Chat
|
} // namespace QodeAssist::Chat
|
||||||
|
|||||||
@@ -3,8 +3,15 @@
|
|||||||
|
|
||||||
#include "ChatWidget.hpp"
|
#include "ChatWidget.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
#include <coreplugin/icontext.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include "QodeAssistConstants.hpp"
|
||||||
|
|
||||||
namespace QodeAssist::Chat {
|
namespace QodeAssist::Chat {
|
||||||
|
|
||||||
@@ -20,6 +27,12 @@ ChatWidget::ChatWidget(QQmlEngine* engine, QWidget *parent)
|
|||||||
setContent(component->url(), component, rootItem);
|
setContent(component->url(), component, rootItem);
|
||||||
}
|
}
|
||||||
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
|
|
||||||
|
auto ideContext = new Core::IContext{this};
|
||||||
|
ideContext->setWidget(this);
|
||||||
|
ideContext->setContext(Core::Context{Constants::QODE_ASSIST_CHAT_CONTEXT});
|
||||||
|
Core::ICore::addContextObject(ideContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWidget::clear()
|
void ChatWidget::clear()
|
||||||
@@ -31,4 +44,35 @@ void ChatWidget::scrollToBottom()
|
|||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(rootObject(), "scrollToBottom");
|
QMetaObject::invokeMethod(rootObject(), "scrollToBottom");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatWidget::focusInput()
|
||||||
|
{
|
||||||
|
setFocus(Qt::OtherFocusReason);
|
||||||
|
QMetaObject::invokeMethod(rootObject(), "focusInput");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatWidget::isChatFocused() const
|
||||||
|
{
|
||||||
|
return hasFocus() || (rootObject() && rootObject()->hasActiveFocus());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWidget::sendMessage()
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(rootObject(), "sendChatMessage");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWidget::clearSession()
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(rootObject(), "clearChat");
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatWidget *ChatWidget::focusedInstance()
|
||||||
|
{
|
||||||
|
for (QWidget *widget = QApplication::focusWidget(); widget;
|
||||||
|
widget = widget->parentWidget()) {
|
||||||
|
if (auto chatWidget = qobject_cast<ChatWidget *>(widget))
|
||||||
|
return chatWidget;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
} // namespace QodeAssist::Chat
|
} // namespace QodeAssist::Chat
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ public:
|
|||||||
|
|
||||||
Q_INVOKABLE void clear();
|
Q_INVOKABLE void clear();
|
||||||
Q_INVOKABLE void scrollToBottom();
|
Q_INVOKABLE void scrollToBottom();
|
||||||
|
Q_INVOKABLE void focusInput();
|
||||||
|
|
||||||
|
void sendMessage();
|
||||||
|
void clearSession();
|
||||||
|
|
||||||
|
bool isChatFocused() const;
|
||||||
|
|
||||||
|
static ChatWidget *focusedInstance();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void clearPressed();
|
void clearPressed();
|
||||||
|
|||||||
@@ -526,15 +526,6 @@ ChatRootView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shortcut {
|
|
||||||
id: sendMessageShortcut
|
|
||||||
|
|
||||||
sequences: ["Ctrl+Return", "Ctrl+Enter"]
|
|
||||||
context: Qt.WindowShortcut
|
|
||||||
enabled: messageInput.activeFocus && !Qt.inputMethod.visible && !fileMentionPopup.visible
|
|
||||||
onActivated: root.sendChatMessage()
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearChat() {
|
function clearChat() {
|
||||||
root.clearMessages()
|
root.clearMessages()
|
||||||
root.clearAttachmentFiles()
|
root.clearAttachmentFiles()
|
||||||
@@ -545,6 +536,10 @@ ChatRootView {
|
|||||||
Qt.callLater(chatListView.positionViewAtEnd)
|
Qt.callLater(chatListView.positionViewAtEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function focusInput() {
|
||||||
|
messageInput.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
function applyMentionSelection() {
|
function applyMentionSelection() {
|
||||||
var result = fileMentionPopup.applyCurrentSelection(
|
var result = fileMentionPopup.applyCurrentSelection(
|
||||||
messageInput.text, messageInput.cursorPosition, root.useTools)
|
messageInput.text, messageInput.cursorPosition, root.useTools)
|
||||||
@@ -654,6 +649,6 @@ ChatRootView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
messageInput.forceActiveFocus()
|
focusInput()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,4 +10,11 @@ const char MENU_ID[] = "QodeAssist.Menu";
|
|||||||
|
|
||||||
const char QODE_ASSIST_REQUEST_SUGGESTION[] = "QodeAssist.RequestSuggestion";
|
const char QODE_ASSIST_REQUEST_SUGGESTION[] = "QodeAssist.RequestSuggestion";
|
||||||
|
|
||||||
|
const char QODE_ASSIST_CHAT_CONTEXT[] = "QodeAssist.ChatContext";
|
||||||
|
const char QODE_ASSIST_CHAT_NAV_ID[] = "QodeAssistChat";
|
||||||
|
|
||||||
|
const char QODE_ASSIST_CHAT_SEND_MESSAGE[] = "QodeAssist.Chat.SendMessage";
|
||||||
|
const char QODE_ASSIST_CHAT_CLEAR_SESSION[] = "QodeAssist.Chat.ClearSession";
|
||||||
|
const char QODE_ASSIST_CHAT_SHOW_IN_RIGHT[] = "QodeAssist.Chat.ShowInRightSidebar";
|
||||||
|
|
||||||
} // namespace QodeAssist::Constants
|
} // namespace QodeAssist::Constants
|
||||||
|
|||||||
@@ -38,18 +38,20 @@ void ChatOutputPane::clearContents()
|
|||||||
|
|
||||||
void ChatOutputPane::visibilityChanged(bool visible)
|
void ChatOutputPane::visibilityChanged(bool visible)
|
||||||
{
|
{
|
||||||
if (visible)
|
if (visible) {
|
||||||
m_chatWidget->scrollToBottom();
|
m_chatWidget->scrollToBottom();
|
||||||
|
m_chatWidget->focusInput();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatOutputPane::setFocus()
|
void ChatOutputPane::setFocus()
|
||||||
{
|
{
|
||||||
m_chatWidget->setFocus();
|
m_chatWidget->focusInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatOutputPane::hasFocus() const
|
bool ChatOutputPane::hasFocus() const
|
||||||
{
|
{
|
||||||
return m_chatWidget->hasFocus();
|
return m_chatWidget->isChatFocused();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatOutputPane::canFocus() const
|
bool ChatOutputPane::canFocus() const
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "NavigationPanel.hpp"
|
#include "NavigationPanel.hpp"
|
||||||
|
|
||||||
#include "ChatView/ChatWidget.hpp"
|
#include "ChatView/ChatWidget.hpp"
|
||||||
|
#include "QodeAssistConstants.hpp"
|
||||||
|
|
||||||
namespace QodeAssist::Chat {
|
namespace QodeAssist::Chat {
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ NavigationPanel::NavigationPanel(QQmlEngine* engine)
|
|||||||
{
|
{
|
||||||
setDisplayName(tr("QodeAssist Chat"));
|
setDisplayName(tr("QodeAssist Chat"));
|
||||||
setPriority(500);
|
setPriority(500);
|
||||||
setId("QodeAssistChat");
|
setId(Constants::QODE_ASSIST_CHAT_NAV_ID);
|
||||||
setActivationSequence(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_C));
|
setActivationSequence(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_C));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
#include <coreplugin/modemanager.h>
|
#include <coreplugin/modemanager.h>
|
||||||
|
#include <coreplugin/navigationwidget.h>
|
||||||
#include <coreplugin/statusbarmanager.h>
|
#include <coreplugin/statusbarmanager.h>
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
#include <languageclient/languageclientmanager.h>
|
#include <languageclient/languageclientmanager.h>
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
#include "widgets/QuickRefactorDialog.hpp"
|
#include "widgets/QuickRefactorDialog.hpp"
|
||||||
#include <ChatView/ChatView.hpp>
|
#include <ChatView/ChatView.hpp>
|
||||||
#include <ChatView/ChatFileManager.hpp>
|
#include <ChatView/ChatFileManager.hpp>
|
||||||
|
#include <ChatView/ChatWidget.hpp>
|
||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
@@ -230,6 +232,26 @@ public:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ActionBuilder sendMessageAction(this, Constants::QODE_ASSIST_CHAT_SEND_MESSAGE);
|
||||||
|
sendMessageAction.setContext(Core::Context(Constants::QODE_ASSIST_CHAT_CONTEXT));
|
||||||
|
sendMessageAction.setText(Tr::tr("Send QodeAssist Chat Message"));
|
||||||
|
sendMessageAction.setToolTip(Tr::tr("Send the current message to the LLM"));
|
||||||
|
sendMessageAction.setDefaultKeySequence(QKeySequence(Qt::CTRL | Qt::Key_Return));
|
||||||
|
sendMessageAction.addOnTriggered(this, [] {
|
||||||
|
if (auto chatWidget = Chat::ChatWidget::focusedInstance())
|
||||||
|
chatWidget->sendMessage();
|
||||||
|
});
|
||||||
|
|
||||||
|
ActionBuilder clearSessionAction(this, Constants::QODE_ASSIST_CHAT_CLEAR_SESSION);
|
||||||
|
clearSessionAction.setContext(Core::Context(Constants::QODE_ASSIST_CHAT_CONTEXT));
|
||||||
|
clearSessionAction.setText(Tr::tr("Clear QodeAssist Chat Session"));
|
||||||
|
clearSessionAction.setToolTip(Tr::tr("Clear the current chat session"));
|
||||||
|
clearSessionAction.setDefaultKeySequence(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_L));
|
||||||
|
clearSessionAction.addOnTriggered(this, [] {
|
||||||
|
if (auto chatWidget = Chat::ChatWidget::focusedInstance())
|
||||||
|
chatWidget->clearSession();
|
||||||
|
});
|
||||||
|
|
||||||
Core::ActionContainer *editorContextMenu = Core::ActionManager::actionContainer(
|
Core::ActionContainer *editorContextMenu = Core::ActionManager::actionContainer(
|
||||||
TextEditor::Constants::M_STANDARDCONTEXTMENU);
|
TextEditor::Constants::M_STANDARDCONTEXTMENU);
|
||||||
if (editorContextMenu) {
|
if (editorContextMenu) {
|
||||||
|
|||||||
Reference in New Issue
Block a user