| 1 | #include <IssueItem.h> | 
| 2 |  | 
| 3 | #include <ButtonLink.hpp> | 
| 4 | #include <PullRequest.h> | 
| 5 |  | 
| 6 | #include <QDir> | 
| 7 | #include <QFile> | 
| 8 | #include <QUrl> | 
| 9 | #include <QGridLayout> | 
| 10 | #include <QDesktopServices> | 
| 11 | #include <QLocale> | 
| 12 |  | 
| 13 | using namespace GitServer; | 
| 14 |  | 
| 15 | IssueItem::IssueItem(const Issue &issueData, QWidget *parent) | 
| 16 |    : QFrame(parent) | 
| 17 |    , mComments(new QLabel()) | 
| 18 | { | 
| 19 |    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum); | 
| 20 |  | 
| 21 |    fillWidget(issueData); | 
| 22 |  | 
| 23 |    mComments->setText(QString::number(issueData.commentsCount)); | 
| 24 | } | 
| 25 |  | 
| 26 | IssueItem::IssueItem(const PullRequest &issueData, QWidget *parent) | 
| 27 |    : QFrame(parent) | 
| 28 |    , mComments(new QLabel()) | 
| 29 | { | 
| 30 |    fillWidget(issueData); | 
| 31 |  | 
| 32 |    mComments->setText(QString::number(issueData.commentsCount + issueData.reviewCommentsCount)); | 
| 33 | } | 
| 34 |  | 
| 35 | void IssueItem::fillWidget(const Issue &issueData) | 
| 36 | { | 
| 37 |    const auto title = new ButtonLink(QString("#%1 - %2" ).arg(issueData.number).arg(issueData.title)); | 
| 38 |    title->setWordWrap(true); | 
| 39 |    title->setObjectName("IssueTitle" ); | 
| 40 |    connect(title, &ButtonLink::clicked, this, [this, issueNum = issueData.number]() { emit selected(issueNum); }); | 
| 41 |  | 
| 42 |    const auto titleLayout = new QHBoxLayout(); | 
| 43 |    titleLayout->setContentsMargins(QMargins()); | 
| 44 |    titleLayout->setSpacing(0); | 
| 45 |    titleLayout->addWidget(title); | 
| 46 |  | 
| 47 |    const auto creationLayout = new QHBoxLayout(); | 
| 48 |    creationLayout->setContentsMargins(QMargins()); | 
| 49 |    creationLayout->setSpacing(0); | 
| 50 |    creationLayout->addWidget(new QLabel(tr("<i>Created by </i>" ))); | 
| 51 |    const auto creator = new ButtonLink(QString("<i><b>%1</b></i>" ).arg(issueData.creator.name)); | 
| 52 |    creator->setObjectName("CreatorLink" ); | 
| 53 |    connect(creator, &ButtonLink::clicked, [url = issueData.url]() { QDesktopServices::openUrl(url); }); | 
| 54 |  | 
| 55 |    creationLayout->addWidget(creator); | 
| 56 |  | 
| 57 |    const auto days = issueData.creation.daysTo(QDateTime::currentDateTime()); | 
| 58 |    const auto whenText = days <= 30 | 
| 59 |        ? tr("<i> %1 days ago</i>" ).arg(days) | 
| 60 |        : tr("<i> on %1</i>" ).arg(issueData.creation.date().toString(QLocale().dateFormat(QLocale::ShortFormat))); | 
| 61 |  | 
| 62 |    const auto whenLabel = new QLabel(whenText); | 
| 63 |    whenLabel->setToolTip(issueData.creation.toString(QLocale().dateFormat(QLocale::ShortFormat))); | 
| 64 |  | 
| 65 |    creationLayout->addWidget(whenLabel); | 
| 66 |    creationLayout->addStretch(); | 
| 67 |  | 
| 68 |    const auto layout = new QVBoxLayout(); | 
| 69 |    layout->setContentsMargins(QMargins()); | 
| 70 |    layout->setSpacing(5); | 
| 71 |    layout->addLayout(titleLayout); | 
| 72 |    layout->addLayout(creationLayout); | 
| 73 |  | 
| 74 |    if (!issueData.assignees.isEmpty()) | 
| 75 |    { | 
| 76 |       const auto assigneeLayout = new QHBoxLayout(); | 
| 77 |       assigneeLayout->setContentsMargins(QMargins()); | 
| 78 |       assigneeLayout->setSpacing(0); | 
| 79 |       assigneeLayout->addWidget(new QLabel(tr("Assigned to " ))); | 
| 80 |  | 
| 81 |       auto count = 0; | 
| 82 |       const auto totalAssignees = issueData.assignees.count(); | 
| 83 |       for (auto &assignee : issueData.assignees) | 
| 84 |       { | 
| 85 |          const auto assigneLabel = new ButtonLink(QString("<b>%1</b>" ).arg(assignee.name)); | 
| 86 |          assigneLabel->setObjectName("CreatorLink" ); | 
| 87 |          connect(assigneLabel, &ButtonLink::clicked, [url = assignee.url]() { QDesktopServices::openUrl(url); }); | 
| 88 |          assigneeLayout->addWidget(assigneLabel); | 
| 89 |  | 
| 90 |          if (count++ < totalAssignees - 1) | 
| 91 |             assigneeLayout->addWidget(new QLabel(", " )); | 
| 92 |       } | 
| 93 |       assigneeLayout->addStretch(); | 
| 94 |  | 
| 95 |       layout->addLayout(assigneeLayout); | 
| 96 |    } | 
| 97 |  | 
| 98 |    if (!issueData.labels.isEmpty()) | 
| 99 |    { | 
| 100 |       const auto labelsLayout = new QHBoxLayout(); | 
| 101 |       labelsLayout->setContentsMargins(QMargins()); | 
| 102 |       labelsLayout->setSpacing(10); | 
| 103 |  | 
| 104 |       QStringList labelsList; | 
| 105 |  | 
| 106 |       for (auto &label : issueData.labels) | 
| 107 |       { | 
| 108 |          auto labelWidget = new QLabel(); | 
| 109 |          labelWidget->setStyleSheet(QString("QLabel {"  | 
| 110 |                                             "background-color: #%1;"  | 
| 111 |                                             "border-radius: 7px;"  | 
| 112 |                                             "min-height: 15px;"  | 
| 113 |                                             "max-height: 15px;"  | 
| 114 |                                             "min-width: 15px;"  | 
| 115 |                                             "max-width: 15px;}" ) | 
| 116 |                                         .arg(label.colorHex)); | 
| 117 |          labelWidget->setToolTip(label.name); | 
| 118 |          labelsLayout->addWidget(labelWidget); | 
| 119 |       } | 
| 120 |  | 
| 121 |       const auto milestone = new QLabel(QString("%1" ).arg(issueData.milestone.title)); | 
| 122 |       milestone->setObjectName("IssueLabel" ); | 
| 123 |       labelsLayout->addWidget(milestone); | 
| 124 |       labelsLayout->addStretch(); | 
| 125 |       layout->addLayout(labelsLayout); | 
| 126 |    } | 
| 127 |  | 
| 128 |    QPixmap pic(":/icons/comment" ); | 
| 129 |    pic = pic.scaled(15, 15, Qt::KeepAspectRatio, Qt::SmoothTransformation); | 
| 130 |  | 
| 131 |    const auto icon = new QLabel(); | 
| 132 |    icon->setPixmap(pic); | 
| 133 |  | 
| 134 |    const auto  = new QGridLayout(); | 
| 135 |    commentsLayout->addWidget(mComments, 0, 0); | 
| 136 |    commentsLayout->addWidget(icon, 0, 1); | 
| 137 |    commentsLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), 1, 0, 1, 2); | 
| 138 |  | 
| 139 |    const auto mainLayout = new QHBoxLayout(this); | 
| 140 |    mainLayout->setContentsMargins(10, 10, 10, 10); | 
| 141 |    mainLayout->addLayout(layout); | 
| 142 |    mainLayout->addLayout(commentsLayout); | 
| 143 | } | 
| 144 |  |