File indexing completed on 2025-01-19 04:22:44

0001 /*
0002 SPDX-FileCopyrightText: 2021 Hamed Masafi <hamed.masfi@gmail.com>
0003 
0004 SPDX-License-Identifier: GPL-3.0-or-later
0005 */
0006 
0007 #include "authorsmodel.h"
0008 #include <KLocalizedString>
0009 
0010 namespace Git
0011 {
0012 
0013 AuthorsModel::AuthorsModel(Manager *git, QObject *parent)
0014     : AbstractGitItemsModel{git, parent}
0015 {
0016 }
0017 
0018 int AuthorsModel::rowCount(const QModelIndex &parent) const
0019 {
0020     Q_UNUSED(parent)
0021     return mData.size();
0022 }
0023 
0024 int AuthorsModel::columnCount(const QModelIndex &parent) const
0025 {
0026     Q_UNUSED(parent)
0027     return static_cast<int>(AuthorsModelsRoles::LastColumn);
0028 }
0029 
0030 QVariant AuthorsModel::headerData(int section, Qt::Orientation orientation, int role) const
0031 {
0032     if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
0033         return {};
0034 
0035     switch (section) {
0036     case Name:
0037         return i18n("Name");
0038     case Email:
0039         return i18n("Email");
0040     case Commits:
0041         return i18n("Commits");
0042     }
0043     return {};
0044 }
0045 
0046 QVariant AuthorsModel::data(const QModelIndex &index, int role) const
0047 {
0048     if (role != Qt::DisplayRole || !index.isValid() || index.row() < 0 || index.row() >= mData.size())
0049         return {};
0050 
0051     switch (index.column()) {
0052     case Name:
0053         return mData.at(index.row())->name;
0054     case Email:
0055         return mData.at(index.row())->email;
0056     case Commits:
0057         return mData.at(index.row())->commits.count;
0058     }
0059 
0060     return {};
0061 }
0062 
0063 Author *AuthorsModel::findOrCreate(const QString &name, const QString &email)
0064 {
0065     QMutexLocker locker(&mDataMutex);
0066 
0067     auto authorIterator = std::find_if(mData.begin(), mData.end(), [&name, &email](Author *a) {
0068         return a->email == email && a->name == name;
0069     });
0070 
0071     if (authorIterator != mData.end())
0072         return *authorIterator;
0073 
0074     auto author = new Author;
0075     author->name = name;
0076     author->email = email;
0077 
0078     authorIterator = std::upper_bound(mData.begin(), mData.end(), qMakePair(name, email), [](const QPair<QString, QString> &data, const Author *a) {
0079         auto c = QString::compare(data.first, a->name, Qt::CaseInsensitive);
0080         if (!c)
0081             return QString::compare(data.second, a->email, Qt::CaseInsensitive) < 0;
0082         return c < 0;
0083     });
0084 
0085     const int idx = authorIterator - mData.begin();
0086     beginInsertRows(QModelIndex(), idx, idx);
0087     mData.insert(authorIterator, author);
0088     endInsertRows();
0089     return author;
0090 }
0091 
0092 Author *AuthorsModel::findOrCreate(const QString &name, const QString &email, const QDateTime &time, AuthorCreateReason reason)
0093 {
0094     QMutexLocker locker(&mDataMutex);
0095 
0096     auto authorIterator = std::find_if(mData.begin(), mData.end(), [&name, &email](Author *a) {
0097         return a->email == email && a->name == name;
0098     });
0099 
0100     if (authorIterator != mData.end()) {
0101         switch (reason) {
0102         case Commit:
0103             (*authorIterator)->commits.increase(time);
0104             break;
0105         case AuthoredCommit:
0106             (*authorIterator)->authoredCommits.increase(time);
0107             break;
0108         case Tag:
0109             (*authorIterator)->tags.increase(time);
0110             break;
0111         }
0112         return *authorIterator;
0113     }
0114 
0115     auto author = new Author;
0116     author->name = name;
0117     author->email = email;
0118 
0119     switch (reason) {
0120     case Commit:
0121         author->commits.begin(time);
0122         break;
0123     case AuthoredCommit:
0124         author->authoredCommits.begin(time);
0125         break;
0126     case Tag:
0127         author->tags.begin(time);
0128         break;
0129     }
0130 
0131     authorIterator = std::upper_bound(mData.begin(), mData.end(), author, [](Author *author, const Author *a) {
0132         auto c = QString::compare(author->name, a->name, Qt::CaseInsensitive);
0133         if (!c)
0134             return QString::compare(author->email, a->email, Qt::CaseInsensitive) < 0;
0135         return c < 0;
0136     });
0137 
0138     int idx = authorIterator - mData.begin();
0139     beginInsertRows(QModelIndex(), idx, idx);
0140     mData.insert(authorIterator, author);
0141     endInsertRows();
0142     return author;
0143 }
0144 
0145 void AuthorsModel::clear()
0146 {
0147     beginResetModel();
0148     qDeleteAll(mData);
0149     mData.clear();
0150     endResetModel();
0151 }
0152 
0153 void AuthorsModel::fill()
0154 {
0155 }
0156 
0157 void DatesRange::begin(const QDateTime &time)
0158 {
0159     count = 1;
0160     first = time;
0161 }
0162 
0163 void DatesRange::increase(const QDateTime &time)
0164 {
0165     last = time;
0166     count++;
0167 }
0168 
0169 } // namespace Git