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 *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));
|
||||
if (chosen == diffAction) {
|
||||
diffSelected();
|
||||
|
|
@ -552,6 +562,10 @@ GitPlusPlusView::GitPlusPlusView(GitPlusPlusPlugin *plugin, KTextEditor::MainWin
|
|||
QString absPath = m_gitDir + QLatin1Char('/') + file;
|
||||
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;"));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_lastDiff = diff;
|
||||
Q_EMIT diffShown(diff, title);
|
||||
|
||||
#ifdef HAVE_KATE_DIFF
|
||||
DiffParams params;
|
||||
params.tabTitle = title;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class QLabel;
|
|||
class QComboBox;
|
||||
class QCheckBox;
|
||||
class QTabWidget;
|
||||
class QAction;
|
||||
class QSortFilterProxyModel;
|
||||
class QStringListModel;
|
||||
class QFileSystemWatcher;
|
||||
|
|
@ -55,11 +56,23 @@ public:
|
|||
class GitPlusPlusView : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QByteArray lastDiff READ lastDiff NOTIFY diffShown)
|
||||
|
||||
public:
|
||||
explicit GitPlusPlusView(GitPlusPlusPlugin *plugin, KTextEditor::MainWindow *mainWindow);
|
||||
~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:
|
||||
// Status
|
||||
void updateStatus();
|
||||
|
|
@ -128,6 +141,7 @@ private:
|
|||
void runSimpleGit(const QStringList &args, const QString &successMsg, const QString &errorMsg);
|
||||
void runRemoteGit(const QStringList &args, const QString &opName);
|
||||
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 updateIndicators();
|
||||
void setRemoteBusy(bool busy, const QString &opName = {});
|
||||
|
|
@ -223,6 +237,10 @@ private:
|
|||
QString m_workspaceDir; // this workspace's directory
|
||||
QString m_workspaceSourceDir; // resolved source workspace path
|
||||
QStringList m_workspaceRepos; // repo subdirs in source workspace
|
||||
|
||||
// Diff extension mechanism
|
||||
QByteArray m_lastDiff;
|
||||
QList<QAction *> m_diffActions;
|
||||
};
|
||||
|
||||
#endif // GITPLUSPLUS_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue