File indexing completed on 2024-04-28 04:38:49

0001 /*
0002     SPDX-FileCopyrightText: 2011 Sergey Vidyuk <sir.vestnik@gmail.com>
0003     SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #include "gitmessagehighlighter.h"
0009 
0010 #include <QString>
0011 #include <QTextCharFormat>
0012 #include <QTextEdit>
0013 #include <KLocalizedString>
0014 
0015 /// Recommended summary limit from http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
0016 static const int summarySoftLimit = 50;
0017 /// Summary length limit causing warning messages from 'git push'
0018 static const int summaryHardLimit = 65;
0019 /// Recommended line length from http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
0020 static const int lineLenLimit = 72;
0021 
0022 void GitMessageHighlighter::applyErrorFormat(GitMessageHighlighter* text, bool warning, const QString& tooltip, int startPos, int endPos)
0023 {
0024     QTextCharFormat format;
0025     format.setFontUnderline(true);
0026     format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
0027     format.setUnderlineColor(warning ? Qt::yellow : Qt::red);
0028     format.setToolTip(tooltip);
0029     text->setFormat(startPos, endPos, format);
0030 }
0031 
0032 GitMessageHighlighter::GitMessageHighlighter(QTextEdit* parent): Sonnet::Highlighter(parent)
0033 {
0034 }
0035 
0036 GitMessageHighlighter::~GitMessageHighlighter()
0037 {
0038 }
0039 
0040 void GitMessageHighlighter::highlightBlock(const QString& text)
0041 {
0042     int blockState = previousBlockState();
0043     if (blockState < DetailedMessage)
0044         ++blockState;
0045     const int textLength = text.length();
0046     int startPos = 0;
0047     int endPos = 0;
0048     while (startPos < textLength)
0049     {
0050         // Switch block state for multiline blocks
0051         if (startPos != 0 && blockState < DetailedMessage)
0052             ++blockState;
0053         endPos = text.indexOf(QLatin1Char('\n'), startPos);
0054         if (endPos < 0)
0055             endPos = textLength;
0056         const int lineLength = endPos - startPos;
0057         
0058         Highlighter::highlightBlock( text );
0059         switch (blockState)
0060         {
0061             case Summary:
0062                 if (lineLength > summarySoftLimit)
0063                 {
0064                     applyErrorFormat(this,
0065                         lineLength <= summaryHardLimit,
0066                         i18n("Try to keep summary length below %1 characters.", summarySoftLimit),
0067                         startPos, endPos
0068                     );
0069                 } else {
0070                     for(int i=startPos; i<endPos; i++) {
0071                         QTextCharFormat f = format(i);
0072                         f.setFontWeight(QFont::Bold);
0073                         setFormat(i, 1, f);
0074                     }
0075                 }
0076                 break;
0077             case SummarySeparator:
0078                 if (lineLength != 0)
0079                 {
0080                     applyErrorFormat(this,
0081                         false,
0082                         i18n("Separate summary from details with one empty line."),
0083                         startPos, endPos
0084                     );
0085                 }
0086                 break;
0087             default:
0088                 if (lineLength > lineLenLimit)
0089                 {
0090                     applyErrorFormat(this,
0091                         false,
0092                         i18n("Try to keep line length below %1 characters.", lineLenLimit),
0093                         startPos+lineLenLimit, endPos
0094                     );
0095                 }
0096                 break;
0097         }
0098         startPos = endPos;
0099     }
0100     setCurrentBlockState(blockState);
0101 }
0102 
0103 #include "moc_gitmessagehighlighter.cpp"