feat: Add llm config to quick refactor dialog

This commit is contained in:
Petr Mironychev
2025-12-01 12:56:13 +01:00
parent b19c4c0c0c
commit 7a97d0aba5
4 changed files with 166 additions and 1 deletions

View File

@ -11,7 +11,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
find_package(QtCreator REQUIRED COMPONENTS Core)
find_package(Qt6 COMPONENTS Core Gui Quick Widgets Network Test LinguistTools REQUIRED)
find_package(Qt6 COMPONENTS Core Gui Quick Widgets Network Svg Test LinguistTools REQUIRED)
find_package(GTest)
qt_standard_project_setup(I18N_TRANSLATED_LANGUAGES en)
@ -57,6 +57,7 @@ add_qtc_plugin(QodeAssist
Qt::Quick
Qt::Widgets
Qt::Network
Qt::Svg
QtCreator::ExtensionSystem
QtCreator::Utils
QtCreator::CPlusPlus

View File

@ -57,6 +57,7 @@
#include "settings/ChatAssistantSettings.hpp"
#include "settings/GeneralSettings.hpp"
#include "settings/ProjectSettingsPanel.hpp"
#include "settings/QuickRefactorSettings.hpp"
#include "settings/SettingsConstants.hpp"
#include "templates/Templates.hpp"
#include "widgets/CustomInstructionsManager.hpp"

View File

@ -22,6 +22,10 @@
#include "CustomInstructionsManager.hpp"
#include "QodeAssisttr.h"
#include "settings/ConfigurationManager.hpp"
#include "settings/GeneralSettings.hpp"
#include "settings/QuickRefactorSettings.hpp"
#include <QApplication>
#include <QComboBox>
#include <QCompleter>
@ -30,12 +34,15 @@
#include <QDir>
#include <QFontMetrics>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QPainter>
#include <QPlainTextEdit>
#include <QScreen>
#include <QStringListModel>
#include <QSvgRenderer>
#include <QTimer>
#include <QToolButton>
#include <QUrl>
@ -48,6 +55,43 @@
namespace QodeAssist {
static QIcon createThemedIcon(const QString &svgPath, const QColor &color)
{
QSvgRenderer renderer(svgPath);
if (!renderer.isValid()) {
return QIcon();
}
QSize iconSize(16, 16);
QPixmap pixmap(iconSize);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
renderer.render(&painter);
painter.end();
QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
uchar *bits = image.bits();
const int bytesPerPixel = 4;
const int totalBytes = image.width() * image.height() * bytesPerPixel;
const int newR = color.red();
const int newG = color.green();
const int newB = color.blue();
for (int i = 0; i < totalBytes; i += bytesPerPixel) {
int alpha = bits[i + 3];
if (alpha > 0) {
bits[i] = newB;
bits[i + 1] = newG;
bits[i + 2] = newR;
}
}
return QIcon(QPixmap::fromImage(image));
}
QuickRefactorDialog::QuickRefactorDialog(QWidget *parent, const QString &lastInstructions)
: QDialog(parent)
, m_lastInstructions(lastInstructions)
@ -75,6 +119,49 @@ void QuickRefactorDialog::setupUi()
actionsLayout->addWidget(m_improveButton);
actionsLayout->addWidget(m_alternativeButton);
actionsLayout->addStretch();
m_configComboBox = new QComboBox(this);
m_configComboBox->setMinimumWidth(200);
m_configComboBox->setToolTip(Tr::tr("Switch AI configuration"));
actionsLayout->addWidget(m_configComboBox);
Utils::Theme *theme = Utils::creatorTheme();
QColor iconColor = theme ? theme->color(Utils::Theme::TextColorNormal) : QColor(Qt::white);
m_toolsIconOn = createThemedIcon(":/qt/qml/ChatView/icons/tools-icon-on.svg", iconColor);
m_toolsIconOff = createThemedIcon(":/qt/qml/ChatView/icons/tools-icon-off.svg", iconColor);
m_toolsButton = new QToolButton(this);
m_toolsButton->setCheckable(true);
m_toolsButton->setChecked(Settings::quickRefactorSettings().useTools());
m_toolsButton->setIcon(m_toolsButton->isChecked() ? m_toolsIconOn : m_toolsIconOff);
m_toolsButton->setToolTip(Tr::tr("Enable/Disable AI Tools"));
m_toolsButton->setIconSize(QSize(16, 16));
actionsLayout->addWidget(m_toolsButton);
connect(m_toolsButton, &QToolButton::toggled, this, [this](bool checked) {
m_toolsButton->setIcon(checked ? m_toolsIconOn : m_toolsIconOff);
Settings::quickRefactorSettings().useTools.setValue(checked);
Settings::quickRefactorSettings().writeSettings();
});
m_thinkingIconOn = createThemedIcon(":/qt/qml/ChatView/icons/thinking-icon-on.svg", iconColor);
m_thinkingIconOff = createThemedIcon(":/qt/qml/ChatView/icons/thinking-icon-off.svg", iconColor);
m_thinkingButton = new QToolButton(this);
m_thinkingButton->setCheckable(true);
m_thinkingButton->setChecked(Settings::quickRefactorSettings().useThinking());
m_thinkingButton->setIcon(m_thinkingButton->isChecked() ? m_thinkingIconOn : m_thinkingIconOff);
m_thinkingButton->setToolTip(Tr::tr("Enable/Disable Thinking Mode"));
m_thinkingButton->setIconSize(QSize(16, 16));
actionsLayout->addWidget(m_thinkingButton);
connect(m_thinkingButton, &QToolButton::toggled, this, [this](bool checked) {
m_thinkingButton->setIcon(checked ? m_thinkingIconOn : m_thinkingIconOff);
Settings::quickRefactorSettings().useThinking.setValue(checked);
Settings::quickRefactorSettings().writeSettings();
});
mainLayout->addLayout(actionsLayout);
QHBoxLayout *instructionsLayout = new QHBoxLayout();
@ -149,6 +236,13 @@ void QuickRefactorDialog::setupUi()
mainLayout->addWidget(m_textEdit);
loadCustomCommands();
loadAvailableConfigurations();
connect(
m_configComboBox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
&QuickRefactorDialog::onConfigurationChanged);
QDialogButtonBox *buttonBox
= new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
@ -476,4 +570,60 @@ void QuickRefactorDialog::onOpenInstructionsFolder()
QDesktopServices::openUrl(url);
}
QString QuickRefactorDialog::selectedConfiguration() const
{
return m_selectedConfiguration;
}
void QuickRefactorDialog::loadAvailableConfigurations()
{
auto &manager = Settings::ConfigurationManager::instance();
manager.loadConfigurations(Settings::ConfigurationType::QuickRefactor);
QVector<Settings::AIConfiguration> configs
= manager.configurations(Settings::ConfigurationType::QuickRefactor);
m_configComboBox->clear();
m_configComboBox->addItem(Tr::tr("Current"), QString());
for (const Settings::AIConfiguration &config : configs) {
m_configComboBox->addItem(config.name, config.id);
}
auto &settings = Settings::generalSettings();
QString currentProvider = settings.qrProvider.value();
QString currentModel = settings.qrModel.value();
QString currentConfigText = QString("%1/%2").arg(currentProvider, currentModel);
m_configComboBox->setItemText(0, Tr::tr("Current (%1)").arg(currentConfigText));
}
void QuickRefactorDialog::onConfigurationChanged(int index)
{
if (index == 0) {
m_selectedConfiguration.clear();
return;
}
QString configId = m_configComboBox->itemData(index).toString();
m_selectedConfiguration = m_configComboBox->itemText(index);
auto &manager = Settings::ConfigurationManager::instance();
Settings::AIConfiguration config
= manager.getConfigurationById(configId, Settings::ConfigurationType::QuickRefactor);
if (!config.id.isEmpty()) {
auto &settings = Settings::generalSettings();
settings.qrProvider.setValue(config.provider);
settings.qrModel.setValue(config.model);
settings.qrTemplate.setValue(config.templateName);
settings.qrUrl.setValue(config.url);
settings.qrEndpointMode.setValue(
settings.qrEndpointMode.indexForDisplay(config.endpointMode));
settings.qrCustomEndpoint.setValue(config.customEndpoint);
settings.writeSettings();
}
}
} // namespace QodeAssist

View File

@ -46,6 +46,8 @@ public:
Action selectedAction() const;
QString selectedConfiguration() const;
bool eventFilter(QObject *watched, QEvent *event) override;
private slots:
@ -59,6 +61,8 @@ private slots:
void onDeleteCustomCommand();
void onOpenInstructionsFolder();
void loadCustomCommands();
void loadAvailableConfigurations();
void onConfigurationChanged(int index);
private:
void setupUi();
@ -73,11 +77,20 @@ private:
QToolButton *m_editCommandButton;
QToolButton *m_deleteCommandButton;
QToolButton *m_openFolderButton;
QToolButton *m_toolsButton;
QToolButton *m_thinkingButton;
QComboBox *m_commandsComboBox;
QComboBox *m_configComboBox;
QLabel *m_instructionsLabel;
Action m_selectedAction = Action::Custom;
QString m_lastInstructions;
QString m_selectedConfiguration;
QIcon m_toolsIconOn;
QIcon m_toolsIconOff;
QIcon m_thinkingIconOn;
QIcon m_thinkingIconOff;
};
} // namespace QodeAssist