1 /*
2 SPDX-FileCopyrightText: 2020 Jonathan L. Verner <jonathan.verner@matfyz.cz>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "simplecommitform.h"
8
9 #include <KColorScheme>
10 #include <KLocalizedString>
11 #include <KMessageWidget>
12
13 #include <QAction>
14 #include <QFontDatabase>
15 #include <QGuiApplication>
16 #include <QHBoxLayout>
17 #include <QLabel>
18 #include <QLineEdit>
19 #include <QPainter>
20 #include <QPushButton>
21 #include <QTextEdit>
22 #include <QToolButton>
23 #include <QVBoxLayout>
24
textIcon(const QString & str,const QColor & fg=Qt::black,const QColor & bg=Qt::white)25 QPixmap textIcon(const QString& str, const QColor& fg = Qt::black, const QColor& bg = Qt::white)
26 {
27 QPixmap ret(40, 40);
28 QPainter p(&ret);
29 QFont font = p.font();
30 font.setPixelSize(0.625 * 40);
31 p.setFont(font);
32 ret.fill(bg);
33 p.setPen(fg);
34 p.drawText(ret.rect(), Qt::AlignCenter, str);
35 return ret;
36 }
37
SimpleCommitForm(QWidget * parent)38 SimpleCommitForm::SimpleCommitForm(QWidget* parent)
39 : QWidget(parent)
40 , m_commitBtn(new QPushButton(i18n("Commit")))
41 , m_summaryEdit(new QLineEdit)
42 , m_messageEdit(new QTextEdit)
43 , m_inlineError(new KMessageWidget)
44 , m_disabled(false)
45 {
46 QHBoxLayout* _hlayout = new QHBoxLayout();
47 _hlayout->setSpacing(0);
48 _hlayout->addWidget(m_summaryEdit);
49 _hlayout->addWidget(m_commitBtn);
50
51 QVBoxLayout* _vlayout = new QVBoxLayout(this);
52 _vlayout->setSpacing(2);
53 _vlayout->setMargin(0);
54 _vlayout->addWidget(m_inlineError);
55 _vlayout->addLayout(_hlayout);
56 _vlayout->addWidget(m_messageEdit);
57
58 m_inlineError->setHidden(true);
59 m_inlineError->setMessageType(KMessageWidget::Error);
60 m_inlineError->setCloseButtonVisible(true);
61 m_inlineError->setWordWrap(true);
62
63 auto monospace = QFontDatabase::systemFont(QFontDatabase::FixedFont);
64 monospace.setStyleHint(QFont::TypeWriter);
65 m_messageEdit->setPlaceholderText(i18n("Extended commit description"));
66 m_messageEdit->setMinimumHeight(30);
67 m_messageEdit->setFont(monospace);
68 m_messageEdit->setWordWrapMode(QTextOption::WordWrap);
69 m_messageEdit->setLineWrapMode(QTextEdit::FixedColumnWidth);
70 m_messageEdit->setLineWrapColumnOrWidth(80);
71
72 QAction* summaryLen = new QAction(this);
73 m_summaryEdit->setPlaceholderText(i18n("Commit summary"));
74 m_summaryEdit->addAction(summaryLen, QLineEdit::TrailingPosition);
75 m_summaryEdit->setFont(monospace);
76
77 auto colors = KColorScheme();
78
79 summaryLen->setIcon(textIcon(QString::number(0), colors.foreground(KColorScheme::NormalText).color(),
80 colors.background(KColorScheme::NormalBackground).color()));
81 connect(m_summaryEdit, &QLineEdit::textChanged, this, [=] {
82 int sz = m_summaryEdit->text().size();
83
84 // Disable the commit button if the message is empty
85 if (sz == 0) {
86 m_commitBtn->setDisabled(true);
87 if (!m_disabled)
88 m_commitBtn->setToolTip(i18n("To commit changes, please write a commit message first"));
89 } else if (!m_disabled) {
90 m_commitBtn->setToolTip(
91 i18n("Commit changes to <b>%1</b> on branch <b>%2</b>", m_projectName, m_branchName));
92 m_commitBtn->setDisabled(false);
93 }
94
95 // Determine the summary background color based on the length
96 QBrush fg, bg;
97
98 if (sz < 65) {
99 bg = colors.background(KColorScheme::NormalBackground);
100 fg = colors.foreground(KColorScheme::NormalText);
101 } else if (sz < 73) {
102 bg = colors.background(KColorScheme::NormalBackground);
103 fg = colors.foreground(KColorScheme::NormalText);
104 } else if (sz < 79) {
105 bg = colors.background(KColorScheme::NeutralBackground);
106 fg = colors.foreground(KColorScheme::NeutralText);
107 } else {
108 bg = colors.background(KColorScheme::NegativeBackground);
109 fg = colors.foreground(KColorScheme::NegativeText);
110 }
111
112 QPalette palette = QGuiApplication::palette();
113 palette.setBrush(QPalette::Base, bg);
114 palette.setBrush(QPalette::Text, fg);
115 m_summaryEdit->setPalette(palette);
116 summaryLen->setIcon(textIcon(QString::number(sz), fg.color(), bg.color()));
117 });
118
119 connect(m_commitBtn, &QPushButton::clicked, this, &SimpleCommitForm::committed);
120 setLayout(_vlayout);
121
122 m_commitBtn->setToolTip(i18n("To commit changes, please select a project first"));
123 disable();
124 }
125
extendedDescription(int wrapAtColumn) const126 QString SimpleCommitForm::extendedDescription(int wrapAtColumn) const
127 {
128 if (wrapAtColumn <= 0)
129 return m_messageEdit->toPlainText();
130 int currentLineLen = 0;
131 QString ret;
132 for(const auto c: m_messageEdit->toPlainText()) {
133 if (c == QLatin1Char('\n')) {
134 ret += QLatin1Char('\n');
135 currentLineLen = 0;
136 } else if (currentLineLen > wrapAtColumn && c.isSpace()) {
137 ret += QLatin1Char('\n');
138 currentLineLen = 0;
139 } else {
140 ret += c;
141 currentLineLen++;
142 }
143 }
144 return ret;
145 }
146
setExtendedDescription(const QString & txt)147 void SimpleCommitForm::setExtendedDescription(const QString& txt)
148 {
149 m_messageEdit->setText(txt);
150 }
summary() const151 QString SimpleCommitForm::summary() const
152 {
153 return m_summaryEdit->text();
154 }
setSummary(const QString & txt)155 void SimpleCommitForm::setSummary(const QString& txt)
156 {
157 m_summaryEdit->setText(txt);
158 }
disableCommitButton()159 void SimpleCommitForm::disableCommitButton()
160 {
161 m_disabled = true;
162 m_commitBtn->setDisabled(true);
163 m_commitBtn->setToolTip(i18n("Please stage some changes before committing."));
164 }
enableCommitButton()165 void SimpleCommitForm::enableCommitButton()
166 {
167 m_disabled = false;
168 if (m_summaryEdit->text().size() > 0) {
169 m_commitBtn->setToolTip(i18n("Commit changes to <b>%1</b> on branch <b>%2</b>", m_projectName, m_branchName));
170 m_commitBtn->setDisabled(false);
171 } else {
172 m_commitBtn->setToolTip(i18n("To commit changes, please write a commit message first"));
173 }
174 }
175
disable()176 void SimpleCommitForm::disable()
177 {
178 m_commitBtn->setDisabled(true);
179 m_summaryEdit->setDisabled(true);
180 m_messageEdit->setDisabled(true);
181 }
182
enable()183 void SimpleCommitForm::enable()
184 {
185 if (! m_disabled)
186 enableCommitButton();
187 m_summaryEdit->setDisabled(false);
188 m_messageEdit->setDisabled(false);
189 }
190
191
192
clear()193 void SimpleCommitForm::clear()
194 {
195 m_summaryEdit->clear();
196 m_messageEdit->clear();
197 clearError();
198 }
199
200
setBranchName(const QString & branchName)201 void SimpleCommitForm::setBranchName(const QString& branchName)
202 {
203 m_branchName = branchName;
204 }
205
setProjectName(const QString & projName)206 void SimpleCommitForm::setProjectName(const QString& projName)
207 {
208 m_projectName = projName;
209 }
210
showError(const QString & error)211 void SimpleCommitForm::showError(const QString& error)
212 {
213 m_inlineError->setText(error);
214 m_inlineError->animatedShow();
215 }
216
clearError()217 void SimpleCommitForm::clearError()
218 {
219 if (!m_inlineError->isHidden() && !m_inlineError->isHideAnimationRunning()) {
220 m_inlineError->animatedHide();
221 }
222 }
223