File indexing completed on 2024-04-28 05:49:05
0001 /* 0002 SPDX-FileCopyrightText: 2021 Waqar Ahmed <waqar.17a@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "gitcommitdialog.h" 0007 #include "git/gitutils.h" 0008 #include "gitwidget.h" 0009 0010 #include <QCoreApplication> 0011 #include <QInputMethodEvent> 0012 #include <QSyntaxHighlighter> 0013 #include <QVBoxLayout> 0014 0015 #include <KColorScheme> 0016 #include <KLocalizedString> 0017 0018 #include <ktexteditor_utils.h> 0019 0020 class BadLengthHighlighter : public QSyntaxHighlighter 0021 { 0022 public: 0023 explicit BadLengthHighlighter(QTextDocument *doc, int badLen) 0024 : QSyntaxHighlighter(doc) 0025 , badLength(badLen) 0026 { 0027 } 0028 0029 void highlightBlock(const QString &text) override 0030 { 0031 if (text.length() < badLength) { 0032 return; 0033 } 0034 setFormat(badLength, text.length() - badLength, red); 0035 } 0036 0037 private: 0038 int badLength = 0; 0039 const QColor red = KColorScheme().foreground(KColorScheme::NegativeText).color(); 0040 }; 0041 0042 static void changeTextColorToRed(QLineEdit *lineEdit, const QColor &red) 0043 { 0044 if (!lineEdit) 0045 return; 0046 0047 // Everything > 52 = red color 0048 QList<QInputMethodEvent::Attribute> attributes; 0049 if (lineEdit->text().length() > 52) { 0050 int start = 52 - lineEdit->cursorPosition(); 0051 int len = lineEdit->text().length() - start; 0052 QInputMethodEvent::AttributeType type = QInputMethodEvent::TextFormat; 0053 0054 QTextCharFormat fmt; 0055 fmt.setForeground(red); 0056 QVariant format = fmt; 0057 0058 attributes.append(QInputMethodEvent::Attribute(type, start, len, format)); 0059 } 0060 QInputMethodEvent event(QString(), attributes); 0061 QCoreApplication::sendEvent(lineEdit, &event); 0062 } 0063 0064 GitCommitDialog::GitCommitDialog(const QString &lastCommit, QWidget *parent, Qt::WindowFlags f) 0065 : QDialog(parent, f) 0066 { 0067 Q_ASSERT(parent); 0068 0069 setWindowTitle(i18n("Commit Changes")); 0070 0071 QFont font = Utils::editorFont(); 0072 0073 ok.setText(i18n("Commit")); 0074 cancel.setText(i18n("Cancel")); 0075 0076 m_le.setPlaceholderText(i18n("Write commit message...")); 0077 m_le.setFont(font); 0078 0079 QFontMetrics fm(font); 0080 0081 m_leLen.setText(QStringLiteral("0 / 52")); 0082 0083 m_pe.setPlaceholderText(i18n("Extended commit description...")); 0084 m_pe.setFont(font); 0085 0086 /** Dialog's main layout **/ 0087 QVBoxLayout *vlayout = new QVBoxLayout(this); 0088 vlayout->setContentsMargins(4, 4, 4, 4); 0089 setLayout(vlayout); 0090 0091 /** Setup the label at the top **/ 0092 QHBoxLayout *hLayoutLine = new QHBoxLayout; 0093 hLayoutLine->addStretch(); 0094 hLayoutLine->addWidget(&m_leLen); 0095 0096 /** Setup plaintextedit and line edit **/ 0097 vlayout->addLayout(hLayoutLine); 0098 vlayout->addWidget(&m_le); 0099 vlayout->addWidget(&m_pe); 0100 0101 loadCommitMessage(lastCommit); 0102 0103 auto bottomLayout = new QHBoxLayout; 0104 0105 /** Setup checkboxes at the bottom **/ 0106 m_cbSignOff.setChecked(false); 0107 m_cbSignOff.setText(i18n("Sign off")); 0108 bottomLayout->addWidget(&m_cbSignOff); 0109 0110 m_cbAmend.setChecked(false); 0111 m_cbAmend.setText(i18n("Amend")); 0112 m_cbAmend.setToolTip(i18n("Amend Last Commit")); 0113 connect(&m_cbAmend, &QCheckBox::stateChanged, this, [this](int state) { 0114 if (state != Qt::Checked) { 0115 ok.setText(i18n("Commit")); 0116 setWindowTitle(i18n("Commit Changes")); 0117 return; 0118 } 0119 setWindowTitle(i18n("Amending Commit")); 0120 ok.setText(i18n("Amend")); 0121 const auto [msg, desc] = GitUtils::getLastCommitMessage(static_cast<GitWidget *>(this->parent())->dotGitPath()); 0122 m_le.setText(msg); 0123 m_pe.setPlainText(desc); 0124 }); 0125 0126 bottomLayout->addWidget(&m_cbAmend); 0127 bottomLayout->addStretch(); 0128 0129 vlayout->addLayout(bottomLayout); 0130 0131 /** Setup Ok / Cancel Button **/ 0132 QHBoxLayout *hLayout = new QHBoxLayout; 0133 hLayout->addStretch(); 0134 hLayout->addWidget(&ok); 0135 hLayout->addWidget(&cancel); 0136 0137 connect(&ok, &QPushButton::clicked, this, &QDialog::accept); 0138 connect(&cancel, &QPushButton::clicked, this, &QDialog::reject); 0139 connect(&m_le, &QLineEdit::textChanged, this, &GitCommitDialog::updateLineSizeLabel); 0140 0141 updateLineSizeLabel(); 0142 0143 vlayout->addLayout(hLayout); 0144 0145 /** 0146 * Setup highlighting which changes text color to red if 0147 * it crosses the 72 char threshold 0148 */ 0149 auto hl = new BadLengthHighlighter(m_pe.document(), 72); 0150 Q_UNUSED(hl) 0151 0152 // set 72 chars wide plain text edit 0153 const int avgCharWidth = fm.averageCharWidth(); 0154 const int width = (avgCharWidth * 72); 0155 const int fw = width + vlayout->contentsMargins().left() * 2 + m_pe.frameWidth() * 2 + m_pe.contentsMargins().left() + vlayout->spacing(); 0156 resize(fw, avgCharWidth * 52); 0157 } 0158 0159 void GitCommitDialog::loadCommitMessage(const QString &lastCommit) 0160 { 0161 if (lastCommit.isEmpty()) { 0162 return; 0163 } 0164 // restore last message ? 0165 auto msgs = lastCommit.split(QStringLiteral("[[\n\n]]")); 0166 if (!msgs.isEmpty()) { 0167 m_le.setText(msgs.at(0)); 0168 if (msgs.length() > 1) { 0169 m_pe.setPlainText(msgs.at(1)); 0170 } 0171 } 0172 } 0173 0174 QString GitCommitDialog::subject() const 0175 { 0176 return m_le.text(); 0177 } 0178 0179 QString GitCommitDialog::description() const 0180 { 0181 return m_pe.toPlainText(); 0182 } 0183 0184 bool GitCommitDialog::signoff() const 0185 { 0186 return m_cbSignOff.isChecked(); 0187 } 0188 0189 bool GitCommitDialog::amendingLastCommit() const 0190 { 0191 return m_cbAmend.isChecked(); 0192 } 0193 0194 void GitCommitDialog::setAmendingCommit() 0195 { 0196 m_cbAmend.setChecked(true); 0197 } 0198 0199 void GitCommitDialog::updateLineSizeLabel() 0200 { 0201 int len = m_le.text().length(); 0202 if (len <= 52) { 0203 m_leLen.setText(i18nc("Number of characters", "%1 / 52", QString::number(len))); 0204 } else { 0205 const QColor red = KColorScheme().foreground(KColorScheme::NegativeText).color(); 0206 changeTextColorToRed(&m_le, red); 0207 m_leLen.setText(i18nc("Number of characters", "<span style=\"color:%1;\">%2</span> / 52", red.name(), QString::number(len))); 0208 } 0209 } 0210 0211 #include "moc_gitcommitdialog.cpp"