1#pragma once
2
3/****************************************************************************************
4 ** GitQlient is an application to manage and operate one or several Git repositories. With
5 ** GitQlient you will be able to add commits, branches and manage all the options Git provides.
6 ** Copyright (C) 2021 Francesc Martinez
7 **
8 ** LinkedIn: www.linkedin.com/in/cescmm/
9 ** Web: www.francescmm.com
10 **
11 ** This program is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU Lesser General Public
13 ** License as published by the Free Software Foundation; either
14 ** version 2 of the License, or (at your option) any later version.
15 **
16 ** This program is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** Lesser General Public License for more details.
20 **
21 ** You should have received a copy of the GNU Lesser General Public
22 ** License along with this library; if not, write to the Free Software
23 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 ***************************************************************************************/
25
26#include <QFrame>
27#include <QMap>
28
29class GitCache;
30class GitBase;
31class QFileSystemModel;
32class FileBlameWidget;
33class QTreeView;
34class CommitHistoryModel;
35class CommitHistoryView;
36class QTabWidget;
37class QModelIndex;
38class RepositoryViewDelegate;
39class GitQlientSettings;
40
41/**
42 * @brief The BlameWidget class creates the layout that contains all the widgets that are part of the blame and history
43 * view. The blame&history view is formed by a view that shows the history view of a given file, another view that shows
44 * the files in the repository folder, and finally a central widget in the form of a QTabWidget that openes as many file
45 * blames as the user wants.
46 *
47 * After the widget is instantiated and before its first use, it needs to be initialized by calling the @ref init
48 * method. Once it's done, it can open files requested by other widgets by using the @p showFileHistory method, that
49 * takes the file path.
50 *
51 * Internally the class also opens files but by taking the index from the QFileSystemModel.
52 *
53 */
54class BlameWidget : public QFrame
55{
56 Q_OBJECT
57
58signals:
59 /**
60 * @brief Signal triggered when the user wants to show the diff of file between two commits.
61 *
62 * @param sha The current sha
63 * @param parentSha The previous sha
64 * @param file The full path of the file to diff
65 */
66 void showFileDiff(const QString &sha, const QString &parentSha, const QString &file, bool isCached);
67
68 /**
69 * @brief Signal triggered when the user wants to see the diff of the selected SHA compared to its previous one.
70 * @param shas The selected commit SHA and its previous one.
71 */
72 void signalOpenDiff(const QStringList &shas);
73
74public:
75 /**
76 * @brief Constructor.
77 *
78 * @param cache The GitQlient cache for the current repository.
79 * @param git The Git object to execute git commands.
80 * @param parent The parent widget if needed.
81 */
82 explicit BlameWidget(const QSharedPointer<GitCache> &cache, const QSharedPointer<GitBase> &git,
83 const QSharedPointer<GitQlientSettings> &settings, QWidget *parent = nullptr);
84 /**
85 * @brief Destructor.
86 *
87 */
88 ~BlameWidget();
89
90 /**
91 * @brief The init method configures the file system view and sets the current working directory.
92 *
93 * @param workingDirectory The current working directory.
94 */
95 void init(const QString &workingDirectory);
96
97 /**
98 * @brief Opens the blame for a given file. This method configures both the history view, where the user can check
99 * all the commits where this file has been modified and also adds a tab in the central QTabWidget.
100 *
101 * @param filePath The full file path.
102 */
103 void showFileHistory(const QString &filePath);
104 /**
105 * @brief Configures the repository model once git finished to load the repository.
106 *
107 * @param totalCommits The total of commits loaded.
108 */
109 void onNewRevisions(int totalCommits);
110
111private:
112 QSharedPointer<GitCache> mCache;
113 QSharedPointer<GitBase> mGit;
114 QSharedPointer<GitQlientSettings> mSettings;
115 QFileSystemModel *fileSystemModel = nullptr;
116 CommitHistoryModel *mRepoModel = nullptr;
117 CommitHistoryView *mRepoView = nullptr;
118 QTreeView *fileSystemView = nullptr;
119 QTabWidget *mTabWidget = nullptr;
120 QString mWorkingDirectory;
121 QMap<QString, FileBlameWidget *> mTabsMap;
122 RepositoryViewDelegate *mItemDelegate = nullptr;
123 int mSelectedRow = -1;
124 int mLastTabIndex = 0;
125
126 /**
127 * @brief Opens the blame for a given index from the file system model. This method configures both the history view,
128 * where the user can check all the commits where this file has been modified and also adds a tab in the central
129 * QTabWidget.
130 *
131 * @param index The index from the file system model.
132 */
133 void showFileHistoryByIndex(const QModelIndex &index);
134 /**
135 * @brief Shows the context menu for the history view.
136 *
137 * @param pos The position where the menu should be shown.
138 */
139 void showRepoViewMenu(const QPoint &pos);
140 /**
141 * @brief This method reloads a blame when the user selects a different commit from the history view. In the history
142 * view the user can select newer or older commits where the file was modified. When it selects a different commit,
143 * both the selected SHA and its previous SHA are sent to reload the blame view.
144 *
145 * @param index The index from the history view.
146 */
147 void reloadBlame(const QModelIndex &index);
148 /**
149 * @brief When the user changes the blame view, the history view is notified to reload its history to accommodate the
150 * new information from the new selected file.
151 *
152 * @param tabIndex The new tab index selected.
153 */
154 void reloadHistory(int tabIndex);
155
156 /*!
157 \brief Retrieves the SHA from the QModelIndex and triggers the \ref signalOpenDiff signal.
158
159 \param index The index from the model.
160 */
161 void openDiff(const QModelIndex &index);
162};
163