add diff action extension mechanism for external plugins
Expose Q_PROPERTY lastDiff, signal diffShown(), and Q_INVOKABLE registerDiffAction() so other KTextEditor plugins (e.g. ollie) can register actions that appear in the tree view context menu. When a registered action is picked, computeDiffForFiles() runs git diff synchronously for the selected files before triggering the action, ensuring the consumer always gets a fresh diff regardless of whether the user previously viewed it.
This commit is contained in:
parent
dcc5218ad7
commit
b8218878c5
|
|
@ -544,6 +544,16 @@ GitPlusPlusView::GitPlusPlusView(GitPlusPlusPlugin *plugin, KTextEditor::MainWin
|
||||||
auto *diffAction = menu.addAction(QIcon::fromTheme(QStringLiteral("vcs-diff")), diffLabel);
|
auto *diffAction = menu.addAction(QIcon::fromTheme(QStringLiteral("vcs-diff")), diffLabel);
|
||||||
auto *openAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-open")), openLabel);
|
auto *openAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-open")), openLabel);
|
||||||
|
|
||||||
|
// Registered diff actions (e.g. "Ollie: Review Diff") — always available
|
||||||
|
QList<QAction *> proxyActions;
|
||||||
|
if (!m_diffActions.isEmpty()) {
|
||||||
|
menu.addSeparator();
|
||||||
|
for (auto *a : m_diffActions) {
|
||||||
|
auto *proxy = menu.addAction(a->icon(), a->text());
|
||||||
|
proxyActions.append(proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto *chosen = menu.exec(m_treeView->viewport()->mapToGlobal(pos));
|
auto *chosen = menu.exec(m_treeView->viewport()->mapToGlobal(pos));
|
||||||
if (chosen == diffAction) {
|
if (chosen == diffAction) {
|
||||||
diffSelected();
|
diffSelected();
|
||||||
|
|
@ -552,6 +562,10 @@ GitPlusPlusView::GitPlusPlusView(GitPlusPlusPlugin *plugin, KTextEditor::MainWin
|
||||||
QString absPath = m_gitDir + QLatin1Char('/') + file;
|
QString absPath = m_gitDir + QLatin1Char('/') + file;
|
||||||
m_mainWindow->openUrl(QUrl::fromLocalFile(absPath));
|
m_mainWindow->openUrl(QUrl::fromLocalFile(absPath));
|
||||||
}
|
}
|
||||||
|
} else if (int idx = proxyActions.indexOf(chosen); idx >= 0) {
|
||||||
|
// Compute diff for selected files, then trigger the registered action
|
||||||
|
computeDiffForFiles(files);
|
||||||
|
m_diffActions[idx]->trigger();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -694,8 +708,40 @@ void GitPlusPlusView::setMessage(const QString &text, bool isError)
|
||||||
m_statusLabel->setStyleSheet(isError ? QStringLiteral("color: red;") : QStringLiteral("color: green;"));
|
m_statusLabel->setStyleSheet(isError ? QStringLiteral("color: red;") : QStringLiteral("color: green;"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GitPlusPlusView::registerDiffAction(QAction *action)
|
||||||
|
{
|
||||||
|
if (action && !m_diffActions.contains(action)) {
|
||||||
|
m_diffActions.append(action);
|
||||||
|
connect(action, &QObject::destroyed, this, [this, action]() {
|
||||||
|
m_diffActions.removeOne(action);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitPlusPlusView::computeDiffForFiles(const QStringList &files)
|
||||||
|
{
|
||||||
|
if (m_gitDir.isEmpty() || files.isEmpty()) return;
|
||||||
|
|
||||||
|
// Compute unstaged diff
|
||||||
|
QStringList args = {QStringLiteral("diff"), QStringLiteral("--")};
|
||||||
|
args.append(files);
|
||||||
|
QByteArray unstaged = GitProcess::run(m_gitDir, args);
|
||||||
|
|
||||||
|
// Compute staged diff
|
||||||
|
QStringList cachedArgs = {QStringLiteral("diff"), QStringLiteral("--cached"), QStringLiteral("--")};
|
||||||
|
cachedArgs.append(files);
|
||||||
|
QByteArray staged = GitProcess::run(m_gitDir, cachedArgs);
|
||||||
|
|
||||||
|
m_lastDiff = staged + unstaged;
|
||||||
|
if (!m_lastDiff.isEmpty())
|
||||||
|
Q_EMIT diffShown(m_lastDiff, QStringLiteral("Review: %1").arg(files.join(QStringLiteral(", "))));
|
||||||
|
}
|
||||||
|
|
||||||
void GitPlusPlusView::showDiffOutput(const QByteArray &diff, const QString &title, const QStringList &gitArgs, int extraFlags)
|
void GitPlusPlusView::showDiffOutput(const QByteArray &diff, const QString &title, const QStringList &gitArgs, int extraFlags)
|
||||||
{
|
{
|
||||||
|
m_lastDiff = diff;
|
||||||
|
Q_EMIT diffShown(diff, title);
|
||||||
|
|
||||||
#ifdef HAVE_KATE_DIFF
|
#ifdef HAVE_KATE_DIFF
|
||||||
DiffParams params;
|
DiffParams params;
|
||||||
params.tabTitle = title;
|
params.tabTitle = title;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ class QLabel;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
|
class QAction;
|
||||||
class QSortFilterProxyModel;
|
class QSortFilterProxyModel;
|
||||||
class QStringListModel;
|
class QStringListModel;
|
||||||
class QFileSystemWatcher;
|
class QFileSystemWatcher;
|
||||||
|
|
@ -55,11 +56,23 @@ public:
|
||||||
class GitPlusPlusView : public QObject
|
class GitPlusPlusView : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QByteArray lastDiff READ lastDiff NOTIFY diffShown)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GitPlusPlusView(GitPlusPlusPlugin *plugin, KTextEditor::MainWindow *mainWindow);
|
explicit GitPlusPlusView(GitPlusPlusPlugin *plugin, KTextEditor::MainWindow *mainWindow);
|
||||||
~GitPlusPlusView() override;
|
~GitPlusPlusView() override;
|
||||||
|
|
||||||
|
QByteArray lastDiff() const { return m_lastDiff; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an external action to appear in the diff context menu.
|
||||||
|
* Ownership stays with the caller.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void registerDiffAction(QAction *action);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void diffShown(const QByteArray &diff, const QString &title);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
// Status
|
// Status
|
||||||
void updateStatus();
|
void updateStatus();
|
||||||
|
|
@ -128,6 +141,7 @@ private:
|
||||||
void runSimpleGit(const QStringList &args, const QString &successMsg, const QString &errorMsg);
|
void runSimpleGit(const QStringList &args, const QString &successMsg, const QString &errorMsg);
|
||||||
void runRemoteGit(const QStringList &args, const QString &opName);
|
void runRemoteGit(const QStringList &args, const QString &opName);
|
||||||
void setMessage(const QString &text, bool isError = false);
|
void setMessage(const QString &text, bool isError = false);
|
||||||
|
void computeDiffForFiles(const QStringList &files);
|
||||||
void showDiffOutput(const QByteArray &diff, const QString &title, const QStringList &gitArgs = {}, int extraFlags = 0);
|
void showDiffOutput(const QByteArray &diff, const QString &title, const QStringList &gitArgs = {}, int extraFlags = 0);
|
||||||
void updateIndicators();
|
void updateIndicators();
|
||||||
void setRemoteBusy(bool busy, const QString &opName = {});
|
void setRemoteBusy(bool busy, const QString &opName = {});
|
||||||
|
|
@ -223,6 +237,10 @@ private:
|
||||||
QString m_workspaceDir; // this workspace's directory
|
QString m_workspaceDir; // this workspace's directory
|
||||||
QString m_workspaceSourceDir; // resolved source workspace path
|
QString m_workspaceSourceDir; // resolved source workspace path
|
||||||
QStringList m_workspaceRepos; // repo subdirs in source workspace
|
QStringList m_workspaceRepos; // repo subdirs in source workspace
|
||||||
|
|
||||||
|
// Diff extension mechanism
|
||||||
|
QByteArray m_lastDiff;
|
||||||
|
QList<QAction *> m_diffActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GITPLUSPLUS_H
|
#endif // GITPLUSPLUS_H
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue