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 | |