File indexing completed on 2025-01-05 05:14:51

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 "commitdetails.h"
0008 #include "avatarview.h"
0009 
0010 #include <entities/commit.h>
0011 #include <gitmanager.h>
0012 #include <models/logsmodel.h>
0013 
0014 #include <KLocalizedString>
0015 #include <QDesktopServices>
0016 
0017 namespace
0018 {
0019 
0020 void showSignature(QSharedPointer<Git::Signature> sign, AvatarView *avatarView, QLabel *nameLabel, QLabel *timeLabel, bool createLink)
0021 {
0022     if (!sign)
0023         return;
0024 
0025     avatarView->setUserEmail(sign->email());
0026 
0027     QString label;
0028     if (createLink)
0029         label = QStringLiteral("<a href=\"mailto:%2\">%1 &lt;%2&gt;</a>");
0030     else
0031         label = QStringLiteral("%1 <%2>");
0032 
0033     nameLabel->setText(label.arg(sign->name(), sign->email()));
0034     timeLabel->setText(sign->time().toString());
0035 }
0036 }
0037 CommitDetails::CommitDetails(QWidget *parent)
0038     : QWidget(parent)
0039 {
0040     setupUi(this);
0041 
0042     connect(labelChangedFiles, &QLabel::linkActivated, this, &CommitDetails::fileClicked);
0043     connect(labelParent, &QLabel::linkActivated, this, &CommitDetails::hashClicked);
0044     connect(labelChildren, &QLabel::linkActivated, this, &CommitDetails::hashClicked);
0045 
0046     connect(labelAuthor, &QLabel::linkActivated, this, &CommitDetails::mSlotEmailLinkClicked);
0047     connect(labelCommitter, &QLabel::linkActivated, this, &CommitDetails::mSlotEmailLinkClicked);
0048 
0049     stackedWidget->setCurrentIndex(0);
0050 }
0051 
0052 Git::Commit *CommitDetails::commit() const
0053 {
0054     return mCommit;
0055 }
0056 
0057 void CommitDetails::setCommit(Git::Commit *commit)
0058 {
0059     mCommit = commit;
0060 
0061     stackedWidget->setCurrentIndex(commit ? 1 : 0);
0062     if (!commit)
0063         return;
0064 
0065     labelCommitHash->setText(commit->commitHash());
0066     labelCommitSubject->setText(commit->subject());
0067 
0068     showSignature(commit->author(), labelAuthorAvatar, labelAuthor, labelAuthTime, mEnableEmailsLinks);
0069     showSignature(commit->committer(), labelCommiterAvatar, labelCommitter, labelCommitTime, mEnableEmailsLinks);
0070 
0071     widgetCommitterInfo->setVisible(commit && commit->author()->email() != commit->committer()->email());
0072     labelCommitterText->setVisible(widgetCommitterInfo->isVisible());
0073 
0074     labelChangedFiles->setText(createChangedFiles());
0075 
0076     auto ref = commit->reference();
0077     if (!ref.isNull()) {
0078         if (ref->isBranch())
0079             labelRefType->setText(i18n("Branch: "));
0080         else if (ref->isNote())
0081             labelRefType->setText(i18n("Note: "));
0082         else if (ref->isRemote())
0083             labelRefType->setText(i18n("Remote: "));
0084         else if (ref->isTag())
0085             labelRefType->setText(i18n("Tag: "));
0086 
0087         labelRefName->setText(ref->shorthand());
0088 
0089         labelRefType->setVisible(true);
0090         labelRefName->setVisible(true);
0091     } else {
0092         labelRefType->setVisible(false);
0093         labelRefName->setVisible(false);
0094     }
0095 
0096     auto parents = generateCommitsLink(commit->parents());
0097     auto children = generateCommitsLink(commit->children());
0098 
0099     labelParentsText->setVisible(!parents.isEmpty());
0100     labelParent->setVisible(!parents.isEmpty());
0101     labelParentsText->setText(commit->parents().size() > 1 ? QStringLiteral("Parents:") : QStringLiteral("Parent:"));
0102     labelParent->setText(parents);
0103 
0104     labelChildrenText->setVisible(!children.isEmpty());
0105     labelChildren->setVisible(!children.isEmpty());
0106     labelChildrenText->setText(commit->children().size() > 1 ? QStringLiteral("Children:") : QStringLiteral("Child:"));
0107     labelChildren->setText(children);
0108 }
0109 
0110 bool CommitDetails::enableCommitsLinks() const
0111 {
0112     return mEnableCommitsLinks;
0113 }
0114 
0115 void CommitDetails::setEnableCommitsLinks(bool enableCommitsLinks)
0116 {
0117     if (mEnableCommitsLinks == enableCommitsLinks)
0118         return;
0119     mEnableCommitsLinks = enableCommitsLinks;
0120     emit enableCommitsLinksChanged();
0121 }
0122 
0123 bool CommitDetails::enableEmailsLinks() const
0124 {
0125     return mEnableEmailsLinks;
0126 }
0127 
0128 void CommitDetails::setEnableEmailsLinks(bool enableEmailsLinks)
0129 {
0130     if (mEnableEmailsLinks == enableEmailsLinks)
0131         return;
0132     mEnableEmailsLinks = enableEmailsLinks;
0133     emit enableEmailsLinksChanged();
0134 }
0135 
0136 bool CommitDetails::enableFilesLinks() const
0137 {
0138     return mEnableFilesLinks;
0139 }
0140 
0141 void CommitDetails::setEnableFilesLinks(bool enableFilesLinks)
0142 {
0143     if (mEnableFilesLinks == enableFilesLinks)
0144         return;
0145     mEnableFilesLinks = enableFilesLinks;
0146     emit enableFilesLinksChanged();
0147 }
0148 
0149 void CommitDetails::mSlotEmailLinkClicked(const QString &link)
0150 {
0151     QDesktopServices::openUrl(QUrl{link});
0152 }
0153 
0154 QString CommitDetails::createChangedFiles()
0155 {
0156     const auto files = Git::Manager::instance()->changedFiles(mCommit->commitHash());
0157     QStringList filesHtml;
0158 
0159     for (auto i = files.constBegin(); i != files.constEnd(); ++i) {
0160         QString color;
0161         // switch (i.value()) {
0162         // case Git::ChangeStatus::Modified:
0163         //     color = mChangedFilesColor.name();
0164         //     break;
0165         // case Git::ChangeStatus::Added:
0166         //     color = mAddedFilesColor.name();
0167         //     break;
0168         // case Git::ChangeStatus::Removed:
0169         //     color = mRemovedFilesColor.name();
0170         //     break;
0171 
0172         // default:
0173         //     break;
0174         // }
0175         if (mEnableFilesLinks)
0176             filesHtml.append(QStringLiteral("<font color=%1><a href=\"%2\">%2</a></a>").arg(color, i.key()));
0177         else
0178             filesHtml.append(QStringLiteral("<font color=%1>%2</a>").arg(color, i.key()));
0179     }
0180 
0181     return filesHtml.join(QStringLiteral("<br />"));
0182 }
0183 
0184 QString CommitDetails::generateCommitLink(const QString &hash)
0185 {
0186     QString subject = hash;
0187     if (mLogsModel) {
0188         auto commit = mLogsModel->findLogByHash(hash);
0189         if (commit)
0190             subject = commit->subject();
0191     }
0192     if (mEnableCommitsLinks)
0193         return QStringLiteral(R"(<a href="%1">%2</a> )").arg(hash, subject);
0194 
0195     return subject;
0196 }
0197 
0198 QString CommitDetails::generateCommitsLink(const QStringList &hashes)
0199 {
0200     QStringList ret;
0201     for (auto const &hash : hashes)
0202         ret << generateCommitLink(hash);
0203 
0204     return ret.join(QStringLiteral(", "));
0205 }