kate: fix git widget integration via ChildAdded event filter
The previous approach using QMetaObject::invokeMethod on gitWidget() failed because that method isn't Q_INVOKABLE. The new approach: - Find git tool view by object name or 'git' in name - Install event filter to catch QEvent::ChildAdded - When a QMenu child is added, connect to aboutToShow - Add Ollie actions to the menu before it's shown Also add retry timer for setupProjectGitWidget since the plugin view may not exist at construction time.
This commit is contained in:
parent
a546b8721a
commit
c3782dd3b7
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QChildEvent>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
|
@ -465,22 +466,36 @@ void OllieKateView::setupGitPlusPlusDiffAction()
|
|||
|
||||
void OllieKateView::setupProjectGitWidget()
|
||||
{
|
||||
QObject *projectView = m_mainWindow->pluginView(QStringLiteral("kateprojectplugin"));
|
||||
if (!projectView) return;
|
||||
// Find the git tool view by name — it's created with ID "kateprojectgit"
|
||||
QWidget *gitToolView = m_mainWindow->window()->findChild<QWidget *>(QStringLiteral("kateprojectgit"));
|
||||
if (!gitToolView) {
|
||||
// Try alternate lookup via mainWindow
|
||||
for (auto *child : m_mainWindow->window()->findChildren<QWidget *>()) {
|
||||
if (child->objectName().contains(QStringLiteral("git"), Qt::CaseInsensitive)) {
|
||||
gitToolView = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!gitToolView) {
|
||||
// Schedule retry — plugin view might not be created yet
|
||||
QTimer::singleShot(1000, this, &OllieKateView::setupProjectGitWidget);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the GitWidget via the gitWidget() method
|
||||
QWidget *gitWidget = nullptr;
|
||||
QMetaObject::invokeMethod(projectView, "gitWidget",
|
||||
Qt::DirectConnection,
|
||||
Q_RETURN_ARG(QWidget *, gitWidget));
|
||||
if (!gitWidget) return;
|
||||
|
||||
// Find the tree view inside the git widget for context menu interception
|
||||
auto *treeView = gitWidget->findChild<QTreeView *>();
|
||||
if (treeView && treeView->viewport()) {
|
||||
treeView->viewport()->installEventFilter(this);
|
||||
// Find the tree view inside the git tool view and store for later use
|
||||
auto *treeView = gitToolView->findChild<QTreeView *>();
|
||||
if (treeView) {
|
||||
m_gitTreeView = treeView;
|
||||
}
|
||||
|
||||
// Install event filter on the git tool view to intercept menus
|
||||
gitToolView->installEventFilter(this);
|
||||
}
|
||||
|
||||
void OllieKateView::onGitTreeContextMenu(const QPoint &)
|
||||
{
|
||||
// Unused - left for API compatibility
|
||||
}
|
||||
|
||||
void OllieKateView::onWidgetAdded(QWidget *widget)
|
||||
|
|
@ -546,24 +561,6 @@ void OllieKateView::reviewDiffFromWidget(QWidget *diffWidget)
|
|||
m_9p->write(agentPath() + "/prompt", prompt.toUtf8());
|
||||
}
|
||||
|
||||
void OllieKateView::addOllieActionsToGitContextMenu(const QPoint &)
|
||||
{
|
||||
// Find the active popup menu (Kate's git widget context menu)
|
||||
QMenu *menu = qobject_cast<QMenu *>(QApplication::activePopupWidget());
|
||||
if (!menu) return;
|
||||
|
||||
// Add separator and Ollie actions
|
||||
menu->addSeparator();
|
||||
|
||||
auto *reviewAction = menu->addAction(QIcon::fromTheme(QStringLiteral("document-preview")),
|
||||
QStringLiteral("Ollie: Review Staged Changes"));
|
||||
connect(reviewAction, &QAction::triggered, this, &OllieKateView::reviewStagedChanges);
|
||||
|
||||
auto *askAction = menu->addAction(QIcon::fromTheme(QStringLiteral("help-about")),
|
||||
QStringLiteral("Ollie: Ask About Selection"));
|
||||
connect(askAction, &QAction::triggered, this, &OllieKateView::askAboutGitSelection);
|
||||
}
|
||||
|
||||
void OllieKateView::reviewStagedChanges()
|
||||
{
|
||||
QString baseDir = projectBaseDir();
|
||||
|
|
@ -782,14 +779,31 @@ void OllieKateView::setupGhostProvider()
|
|||
|
||||
bool OllieKateView::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
// Handle context menu for git widget's tree view
|
||||
if (event->type() == QEvent::ContextMenu && m_gitTreeView && obj == m_gitTreeView->viewport()) {
|
||||
auto *contextEvent = static_cast<QContextMenuEvent *>(event);
|
||||
// Don't block the event — let the original handler run first
|
||||
// We'll add our items via a delayed single-shot
|
||||
QTimer::singleShot(0, this, [this, pos = contextEvent->globalPos()]() {
|
||||
addOllieActionsToGitContextMenu(pos);
|
||||
});
|
||||
// Watch for menus being created in the git tool view area
|
||||
if (event->type() == QEvent::ChildAdded) {
|
||||
auto *childEvent = static_cast<QChildEvent *>(event);
|
||||
if (auto *menu = qobject_cast<QMenu *>(childEvent->child())) {
|
||||
// Connect to aboutToShow to add our items
|
||||
connect(menu, &QMenu::aboutToShow, this, [this, menu]() {
|
||||
// Only add if we haven't already
|
||||
bool hasOllieAction = false;
|
||||
for (auto *action : menu->actions()) {
|
||||
if (action->text().startsWith(QStringLiteral("Ollie:"))) {
|
||||
hasOllieAction = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasOllieAction && menu->actions().count() > 0) {
|
||||
menu->addSeparator();
|
||||
menu->addAction(QIcon::fromTheme(QStringLiteral("document-preview")),
|
||||
QStringLiteral("Ollie: Review Staged Changes"),
|
||||
this, &OllieKateView::reviewStagedChanges);
|
||||
menu->addAction(QIcon::fromTheme(QStringLiteral("help-about")),
|
||||
QStringLiteral("Ollie: Ask About Selection"),
|
||||
this, &OllieKateView::askAboutGitSelection);
|
||||
}
|
||||
}, Qt::UniqueConnection);
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::KeyPress && m_ghost) {
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ private slots:
|
|||
void onProjectChanged();
|
||||
void heartbeat();
|
||||
void onWidgetAdded(QWidget *widget);
|
||||
void onGitTreeContextMenu(const QPoint &pos);
|
||||
|
||||
private:
|
||||
// Actions
|
||||
|
|
@ -92,7 +93,6 @@ private:
|
|||
void setupGitPlusPlusDiffAction();
|
||||
void setupProjectGitWidget();
|
||||
void onDiffWidgetContextMenu(QWidget *diffWidget, const QPoint &pos);
|
||||
void addOllieActionsToGitContextMenu(const QPoint &globalPos);
|
||||
|
||||
// Ghost text
|
||||
void setupGhostProvider();
|
||||
|
|
|
|||
Loading…
Reference in New Issue