File indexing completed on 2024-04-28 05:49:06
0001 /* 0002 SPDX-FileCopyrightText: 2021 Waqar Ahmed <waqar.17a@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #pragma once 0007 0008 #include <QFutureWatcher> 0009 #include <QPointer> 0010 #include <QProcess> 0011 #include <QTimer> 0012 #include <QWidget> 0013 0014 #include "git/gitstatus.h" 0015 0016 class QTreeView; 0017 class QStringListModel; 0018 class GitStatusModel; 0019 class KateProject; 0020 class QItemSelection; 0021 class QMenu; 0022 class QToolButton; 0023 class QTemporaryFile; 0024 class KateProjectPluginView; 0025 class GitWidgetTreeView; 0026 class QStackedWidget; 0027 class QLineEdit; 0028 class KActionCollection; 0029 0030 namespace KTextEditor 0031 { 0032 class MainWindow; 0033 class View; 0034 class Document; 0035 } 0036 0037 enum class ClickAction : uint8_t; 0038 enum class StashMode : uint8_t; 0039 0040 class GitWidget : public QWidget 0041 { 0042 Q_OBJECT 0043 public: 0044 explicit GitWidget(KateProject *project, KTextEditor::MainWindow *mainWindow = nullptr, KateProjectPluginView *pluginView = nullptr); 0045 ~GitWidget() override; 0046 0047 void init(); 0048 0049 bool eventFilter(QObject *o, QEvent *e) override; 0050 0051 void showEvent(QShowEvent *e) override; 0052 0053 /** 0054 * Trigger the GitWidget to update itself. 0055 * It is safe to call it repeatedly in a short time, due to delayed update after the last call. 0056 */ 0057 void updateStatus(); 0058 0059 KTextEditor::MainWindow *mainWindow(); 0060 0061 // will just proxy the message to the plugin view 0062 void sendMessage(const QString &message, bool warn); 0063 0064 QString dotGitPath() const 0065 { 0066 return m_activeGitDirPath; 0067 } 0068 0069 QString indexPath() const 0070 { 0071 if (m_activeGitDirPath == m_topLevelGitPath) { 0072 return m_activeGitDirPath + QStringLiteral(".git/index"); 0073 } 0074 // Should we support submodules? 0075 return QString(); 0076 } 0077 0078 private: 0079 /** These ends with "/", always remember this */ 0080 0081 // This variable contains the current active git path 0082 // being tracked by this widget 0083 QString m_activeGitDirPath; 0084 // This variable contains the topLevel git path 0085 QString m_topLevelGitPath; 0086 // This variable contains all submodule paths 0087 QStringList m_submodulePaths; 0088 0089 /** 0090 * Helper to avoid multiple reloads at a time 0091 * @see slotUpdateStatus 0092 */ 0093 QTimer m_updateTrigger; 0094 0095 QToolButton *m_menuBtn; 0096 QToolButton *m_commitBtn; 0097 QToolButton *m_pushBtn; 0098 QToolButton *m_pullBtn; 0099 QToolButton *m_cancelBtn; 0100 KateProject *m_project; 0101 GitWidgetTreeView *m_treeView; 0102 GitStatusModel *m_model; 0103 QLineEdit *m_filterLineEdit; 0104 QFutureWatcher<GitUtils::GitParsedStatus> m_gitStatusWatcher; 0105 QString m_commitMessage; 0106 KTextEditor::MainWindow *m_mainWin; 0107 QMenu *m_gitMenu; 0108 KateProjectPluginView *m_pluginView; 0109 bool m_initialized = false; 0110 0111 QWidget *m_mainView; 0112 QStackedWidget *m_stackWidget; 0113 0114 using CancelHandle = QPointer<QProcess>; 0115 CancelHandle m_cancelHandle; 0116 0117 void setDotGitPath(); 0118 void setSubmodulesPaths(); 0119 void setActiveGitDir(); 0120 void selectActiveFileInStatus(); 0121 0122 QProcess *gitp(const QStringList &arguments); 0123 0124 void buildMenu(KActionCollection *ac); 0125 void runGitCmd(const QStringList &args, const QString &i18error); 0126 void runPushPullCmd(const QStringList &args); 0127 void stage(const QStringList &files, bool = false); 0128 void unstage(const QStringList &files); 0129 void discard(const QStringList &files); 0130 void clean(const QStringList &files); 0131 void openAtHEAD(const QString &file); 0132 void showDiff(const QString &file, bool staged); 0133 void launchExternalDiffTool(const QString &file, bool staged); 0134 void commitChanges(const QString &msg, const QString &desc, bool signOff, bool amend = false); 0135 void branchCompareFiles(const QString &from, const QString &to); 0136 0137 QMenu *stashMenu(KActionCollection *pCollection); 0138 QAction *stashMenuAction(KActionCollection *ac, const QString &name, const QString &text, StashMode m); 0139 0140 void treeViewContextMenuEvent(QContextMenuEvent *e); 0141 void selectedContextMenu(QContextMenuEvent *e); 0142 0143 void createStashDialog(StashMode m, const QString &gitPath); 0144 0145 void enableCancel(QProcess *git); 0146 void hideCancel(); 0147 0148 private Q_SLOTS: 0149 /** 0150 * Does the real update 0151 */ 0152 void slotUpdateStatus(); 0153 0154 void parseStatusReady(); 0155 void openCommitChangesDialog(bool amend = false); 0156 void handleClick(const QModelIndex &idx, ClickAction clickAction); 0157 void treeViewSingleClicked(const QModelIndex &idx); 0158 void treeViewDoubleClicked(const QModelIndex &idx); 0159 0160 // signals 0161 public: 0162 Q_SIGNAL void checkoutBranch(); 0163 };