1 /* This file is part of the KDE project
2 * Copyright 2014 Dan Leinir Turthra Jensen <admin@leinir.dk>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License or (at your option) version 3 or any later version
8 * accepted by the membership of KDE e.V. (or its successor approved
9 * by the membership of KDE e.V.), which shall act as a proxy
10 * defined in Section 14 of version 3 of the license.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include "gitlogmodel.h"
23
24 // #include <qgit2.h>
25 // #include <qgit2/qgitglobal.h>
26
27 #include <git2.h>
28 #include <git2/repository.h>
29
30 #include <QDateTime>
31 #include <QDebug>
32
33 struct LogEntry {
34 public:
LogEntryLogEntry35 LogEntry() {}
36 QString authorName;
37 QString authorEmail;
38 QDateTime time;
39 QString oid;
40 QString shortMessage;
41 QString message;
42 };
43
44 class GitLogModel::Private
45 {
46 public:
Private()47 Private() {}
~Private()48 ~Private()
49 {
50 qDeleteAll(entries);
51 }
52 QString repoDir;
53 QList<LogEntry*> entries;
54 };
55
GitLogModel(QObject * parent)56 GitLogModel::GitLogModel(QObject* parent)
57 : QAbstractListModel(parent)
58 , d(new Private)
59 {
60 QHash<int, QByteArray> roleNames;
61 roleNames[AuthorNameRole] = "authorName";
62 roleNames[AuthorEmailRole] = "authorEmail";
63 roleNames[TimeRole] = "time";
64 roleNames[OIDRole] = "oid";
65 roleNames[ShortMessageRole] = "shortMessage";
66 roleNames[MessageRole] = "message";
67 setRoleNames(roleNames);
68 }
69
~GitLogModel()70 GitLogModel::~GitLogModel()
71 {
72 delete d;
73 }
74
rowCount(const QModelIndex & parent) const75 int GitLogModel::rowCount(const QModelIndex &parent) const
76 {
77 if ( parent.isValid() )
78 return 0;
79 return d->entries.count();
80 }
81
data(const QModelIndex & index,int role) const82 QVariant GitLogModel::data(const QModelIndex &index, int role) const
83 {
84 QVariant data;
85 if(index.isValid() && index.row() < d->entries.count()) {
86 LogEntry * entry = d->entries.at(index.row());
87 switch(role)
88 {
89 case AuthorNameRole:
90 data = entry->authorName;
91 break;
92 case AuthorEmailRole:
93 data = entry->authorEmail;
94 break;
95 case TimeRole:
96 data = entry->time;
97 break;
98 case OIDRole:
99 data = entry->oid;
100 break;
101 case ShortMessageRole:
102 data = entry->shortMessage;
103 break;
104 case MessageRole:
105 data = entry->message;
106 break;
107 default:
108 data = "Unknown Role";
109 break;
110 }
111 }
112 return data;
113 }
114
repoDir() const115 QString GitLogModel::repoDir() const
116 {
117 return d->repoDir;
118 }
119
setRepoDir(const QString & repoDir)120 void GitLogModel::setRepoDir(const QString& repoDir)
121 {
122 if(d->repoDir != repoDir) {
123 d->repoDir = repoDir;
124 refreshLog();
125 emit repoDirChanged();
126 }
127 }
128
refreshLog()129 void GitLogModel::refreshLog()
130 {
131 beginResetModel();
132 qDeleteAll(d->entries);
133 d->entries.clear();
134
135 git_repository* repository;
136 int error = git_repository_open(&repository, QString("%1/.git").arg(d->repoDir).toLatin1());
137 if(error != 0) { const git_error* err = giterr_last(); qDebug() << "Kapow, error code from git2 was" << error << "which is described as" << err->message; return; }
138
139 git_revwalk *walker;
140 error = git_revwalk_new(&walker, repository);
141 if(error != 0) { const git_error* err = giterr_last(); qDebug() << "Kapow, error code from git2 was" << error << "which is described as" << err->message; return; }
142 error = git_revwalk_push_range(walker, "HEAD~100..HEAD");
143 if(error != 0) { const git_error* err = giterr_last(); qDebug() << "Kapow, error code from git2 was" << error << "which is described as" << err->message; return; }
144
145 git_oid oid;
146 git_commit *commit = NULL;
147 while (git_revwalk_next(&oid, walker) == 0) {
148 error = git_commit_lookup(&commit, repository, &oid);
149 if(error != 0) { const git_error* err = giterr_last(); qDebug() << "Kapow, error code from git2 was" << error << "which is described as" << err->message; return; }
150
151 const git_signature *author = git_commit_author(commit);
152
153 LogEntry* entry = new LogEntry();
154 entry->authorName = author->name;
155 if(entry->authorName.isEmpty())
156 entry->authorName = "Unknown";
157 entry->authorEmail = author->email;
158
159 git_time_t time = git_commit_time(commit);
160 entry->time = QDateTime::fromMSecsSinceEpoch(time * 1000);
161
162 entry->oid = QString::fromAscii(git_oid_tostr_s(git_commit_id(commit)));
163 entry->message = QString::fromAscii(git_commit_message(commit));
164 entry->shortMessage = entry->message.left(120).split(QRegExp("(\\r|\\n)")).first();
165
166 d->entries.append(entry);
167
168 git_commit_free(commit);
169 }
170 git_repository_free(repository);
171 endResetModel();
172 }
173