From 0d76d078e22ff8d5f00a47eff5cdfae8c47f75c1 Mon Sep 17 00:00:00 2001 From: Scott Furry Date: Sun, 23 Jun 2019 11:04:53 -0600 Subject: [PATCH] Implement User Selectable Code Editor Style in cppcheck-gui (#1913) Building on #1874, commit adds user controls to choose or edit style in cppcheck-gui ONLY. Commit does not address CodeEditor style usage in triage app at this time. Code Editor style can be altered from the added "Code Editor" tab in the user preferences. The user has the option to select default light, default dark, or to customize. If user leaves the style set to light or dark defaults, this will be reflected in the choices shown in the preferences dialog. User choice for Code Editor Style is saved in the cppcheck-gui preferences under the heading "EditorStyle". --- gui/codeeditor.cpp | 120 +++++++++--- gui/codeeditor.h | 21 ++- gui/codeeditorstyle.cpp | 214 +++++++++++++++++++++ gui/codeeditorstyle.h | 89 ++++++--- gui/codeeditstylecontrols.cpp | 114 ++++++++++++ gui/codeeditstylecontrols.h | 73 ++++++++ gui/codeeditstyledialog.cpp | 342 ++++++++++++++++++++++++++++++++++ gui/codeeditstyledialog.h | 94 ++++++++++ gui/gui.pro | 7 +- gui/mainwindow.cpp | 2 + gui/resultsview.cpp | 10 + gui/resultsview.h | 10 + gui/settings.ui | 84 ++++++++- gui/settingsdialog.cpp | 41 ++++ gui/settingsdialog.h | 19 ++ tools/triage/CMakeLists.txt | 8 +- tools/triage/triage.pro | 2 + 17 files changed, 1195 insertions(+), 55 deletions(-) create mode 100644 gui/codeeditorstyle.cpp create mode 100644 gui/codeeditstylecontrols.cpp create mode 100644 gui/codeeditstylecontrols.h create mode 100644 gui/codeeditstyledialog.cpp create mode 100644 gui/codeeditstyledialog.h diff --git a/gui/codeeditor.cpp b/gui/codeeditor.cpp index aeaafa41c..da8bbe6c5 100644 --- a/gui/codeeditor.cpp +++ b/gui/codeeditor.cpp @@ -56,6 +56,7 @@ Highlighter::Highlighter(QTextDocument *parent, foreach (const QString &pattern, keywordPatterns) { rule.pattern = QRegularExpression("\\b" + pattern + "\\b"); rule.format = mKeywordFormat; + rule.ruleRole = RuleRole::Keyword; mHighlightingRules.append(rule); } @@ -63,18 +64,21 @@ Highlighter::Highlighter(QTextDocument *parent, mClassFormat.setFontWeight(mWidgetStyle->classWeight); rule.pattern = QRegularExpression("\\bQ[A-Za-z]+\\b"); rule.format = mClassFormat; + rule.ruleRole = RuleRole::Class; mHighlightingRules.append(rule); mQuotationFormat.setForeground(mWidgetStyle->quoteColor); mQuotationFormat.setFontWeight(mWidgetStyle->quoteWeight); rule.pattern = QRegularExpression("\".*\""); rule.format = mQuotationFormat; + rule.ruleRole = RuleRole::Quote; mHighlightingRules.append(rule); mSingleLineCommentFormat.setForeground(mWidgetStyle->commentColor); mSingleLineCommentFormat.setFontWeight(mWidgetStyle->commentWeight); rule.pattern = QRegularExpression("//[^\n]*"); rule.format = mSingleLineCommentFormat; + rule.ruleRole = RuleRole::Comment; mHighlightingRules.append(rule); mHighlightingRulesWithSymbols = mHighlightingRules; @@ -97,10 +101,35 @@ void Highlighter::setSymbols(const QStringList &symbols) HighlightingRule rule; rule.pattern = QRegularExpression("\\b" + sym + "\\b"); rule.format = mSymbolFormat; + rule.ruleRole = RuleRole::Symbol; mHighlightingRulesWithSymbols.append(rule); } } +void Highlighter::setStyle( const CodeEditorStyle &newStyle ) +{ + mKeywordFormat.setForeground( newStyle.keywordColor ); + mKeywordFormat.setFontWeight( newStyle.keywordWeight ); + mClassFormat.setForeground( newStyle.classColor ); + mClassFormat.setFontWeight( newStyle.classWeight ); + mSingleLineCommentFormat.setForeground( newStyle.commentColor ); + mSingleLineCommentFormat.setFontWeight( newStyle.commentWeight ); + mMultiLineCommentFormat.setForeground( newStyle.commentColor ); + mMultiLineCommentFormat.setFontWeight( newStyle.commentWeight ); + mQuotationFormat.setForeground( newStyle.quoteColor ); + mQuotationFormat.setFontWeight( newStyle.quoteWeight ); + mSymbolFormat.setForeground( newStyle.symbolFGColor ); + mSymbolFormat.setBackground( newStyle.symbolBGColor ); + mSymbolFormat.setFontWeight( newStyle.symbolWeight ); + for( HighlightingRule& rule : mHighlightingRules ) { + applyFormat( rule ); + } + + for( HighlightingRule& rule : mHighlightingRulesWithSymbols ) { + applyFormat( rule ); + } +} + void Highlighter::highlightBlock(const QString &text) { foreach (const HighlightingRule &rule, mHighlightingRulesWithSymbols) { @@ -133,34 +162,43 @@ void Highlighter::highlightBlock(const QString &text) } } - -CodeEditor::CodeEditor(QWidget *parent, - CodeEditorStyle *widgetStyle /*= nullptr*/) : - QPlainTextEdit(parent) +void Highlighter::applyFormat( HighlightingRule &rule ) { - if (widgetStyle) mWidgetStyle = widgetStyle; - else mWidgetStyle = new CodeEditorStyle(defaultStyle); + switch( rule.ruleRole ) + { + case RuleRole::Keyword: + rule.format = mKeywordFormat; + break; + case RuleRole::Class: + rule.format = mClassFormat; + break; + case RuleRole::Comment: + rule.format = mSingleLineCommentFormat; + break; + case RuleRole::Quote: + rule.format = mQuotationFormat; + break; + case RuleRole::Symbol: + rule.format = mSymbolFormat; + break; + } +} +CodeEditor::CodeEditor(QWidget *parent) : + QPlainTextEdit(parent), + mWidgetStyle( new CodeEditorStyle( defaultStyleLight )) +{ mLineNumberArea = new LineNumberArea(this); - mHighlighter = new Highlighter(this->document(), mWidgetStyle); + mHighlighter = new Highlighter( document(), mWidgetStyle ); mErrorPosition = -1; - // set widget coloring by overriding widget style sheet - QString bgcolor = QString("background:rgb(%1,%2,%3);") - .arg(mWidgetStyle->widgetBGColor.red()) - .arg(mWidgetStyle->widgetBGColor.green()) - .arg(mWidgetStyle->widgetBGColor.blue()); - QString fgcolor = QString("color:rgb(%1,%2,%3);") - .arg(mWidgetStyle->widgetFGColor.red()) - .arg(mWidgetStyle->widgetFGColor.green()) - .arg(mWidgetStyle->widgetFGColor.blue()); - QString style = QString("%1 %2") - .arg(bgcolor) - .arg(fgcolor); - setObjectName("CodeEditor"); - setStyleSheet(style); + QFont font( "Monospace" ); + font.setStyleHint( QFont::TypeWriter ); + setFont( font ); - setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + // set widget coloring by overriding widget style sheet + setObjectName("CodeEditor"); + setStyleSheet( generateStyleString() ); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); @@ -168,6 +206,12 @@ CodeEditor::CodeEditor(QWidget *parent, updateLineNumberAreaWidth(0); } +CodeEditor::~CodeEditor() +{ + // NOTE: not a Qt Object - delete manually + delete mWidgetStyle; +} + static int getPos(const QString &fileData, int lineNumber) { if (lineNumber <= 1) @@ -182,6 +226,16 @@ static int getPos(const QString &fileData, int lineNumber) return fileData.size(); } +void CodeEditor::setStyle(const CodeEditorStyle& newStyle) +{ + *mWidgetStyle = newStyle; + // apply new styling + setStyleSheet( generateStyleString() ); + mHighlighter->setStyle( newStyle ); + mHighlighter->rehighlight(); + highlightErrorLine(); +} + void CodeEditor::setError(const QString &code, int errorLine, const QStringList &symbols) { mHighlighter->setSymbols(symbols); @@ -242,7 +296,11 @@ void CodeEditor::highlightErrorLine() selection.format.setBackground(mWidgetStyle->highlightBGColor); selection.format.setProperty(QTextFormat::FullWidthSelection, true); selection.cursor = QTextCursor(document()); - selection.cursor.setPosition(mErrorPosition); + if( mErrorPosition >= 0 ) { + selection.cursor.setPosition(mErrorPosition); + } else { + selection.cursor.setPosition(0); + } selection.cursor.clearSelection(); extraSelections.append(selection); @@ -273,3 +331,19 @@ void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) ++blockNumber; } } + +QString CodeEditor::generateStyleString() +{ + QString bgcolor = QString("background:rgb(%1,%2,%3);") + .arg(mWidgetStyle->widgetBGColor.red()) + .arg(mWidgetStyle->widgetBGColor.green()) + .arg(mWidgetStyle->widgetBGColor.blue()); + QString fgcolor = QString("color:rgb(%1,%2,%3);") + .arg(mWidgetStyle->widgetFGColor.red()) + .arg(mWidgetStyle->widgetFGColor.green()) + .arg(mWidgetStyle->widgetFGColor.blue()); + QString style = QString("%1 %2") + .arg(bgcolor) + .arg(fgcolor); + return style; +} diff --git a/gui/codeeditor.h b/gui/codeeditor.h index 4edbef99d..a852e68ff 100644 --- a/gui/codeeditor.h +++ b/gui/codeeditor.h @@ -24,14 +24,27 @@ public: void setSymbols(const QStringList &symbols); + void setStyle( const CodeEditorStyle &newStyle ); + protected: void highlightBlock(const QString &text) override; private: + enum RuleRole { + Keyword = 1, + Class = 2, + Comment = 3, + Quote = 4, + Symbol = 5 + }; struct HighlightingRule { QRegularExpression pattern; QTextCharFormat format; + RuleRole ruleRole; }; + + void applyFormat( HighlightingRule &rule ); + QVector mHighlightingRules; QVector mHighlightingRulesWithSymbols; @@ -52,13 +65,14 @@ class CodeEditor : public QPlainTextEdit { Q_OBJECT public: - explicit CodeEditor(QWidget *parent, - CodeEditorStyle *widgetStyle = nullptr); + explicit CodeEditor(QWidget *parent); CodeEditor(const CodeEditor &) = delete; CodeEditor &operator=(const CodeEditor &) = delete; + ~CodeEditor(); void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); + void setStyle(const CodeEditorStyle& newStyle); /** * Set source code to show, goto error line and highlight that line. @@ -76,6 +90,9 @@ private slots: void highlightErrorLine(); void updateLineNumberArea(const QRect &, int); +private: + QString generateStyleString(); + private: QWidget *mLineNumberArea; Highlighter *mHighlighter; diff --git a/gui/codeeditorstyle.cpp b/gui/codeeditorstyle.cpp new file mode 100644 index 000000000..3f9859922 --- /dev/null +++ b/gui/codeeditorstyle.cpp @@ -0,0 +1,214 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2019 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "codeeditorstyle.h" +#include + +CodeEditorStyle::CodeEditorStyle( + const QColor& CtrlFGColor, const QColor& CtrlBGColor, + const QColor& HiLiBGColor, + const QColor& LnNumFGColor, const QColor& LnNumBGColor, + const QColor& KeyWdFGColor, const QFont::Weight& KeyWdWeight, + const QColor& ClsFGColor, const QFont::Weight& ClsWeight, + const QColor& QteFGColor, const QFont::Weight& QteWeight, + const QColor& CmtFGColor, const QFont::Weight& CmtWeight, + const QColor& SymbFGColor, const QColor& SymbBGColor, + const QFont::Weight& SymbWeight) : + widgetFGColor(CtrlFGColor), + widgetBGColor(CtrlBGColor), + highlightBGColor(HiLiBGColor), + lineNumFGColor(LnNumFGColor), + lineNumBGColor(LnNumBGColor), + keywordColor(KeyWdFGColor), + keywordWeight(KeyWdWeight), + classColor(ClsFGColor), + classWeight(ClsWeight), + quoteColor(QteFGColor), + quoteWeight(QteWeight), + commentColor(CmtFGColor), + commentWeight(CmtWeight), + symbolFGColor(SymbFGColor), + symbolBGColor(SymbBGColor), + symbolWeight(SymbWeight) +{} + +bool CodeEditorStyle::operator==( const CodeEditorStyle& rhs ) const +{ + if( widgetFGColor != rhs.widgetFGColor ) return false; + if( widgetBGColor != rhs.widgetBGColor ) return false; + if( highlightBGColor != rhs.highlightBGColor ) return false; + if( lineNumFGColor != rhs.lineNumFGColor ) return false; + if( lineNumBGColor != rhs.lineNumBGColor ) return false; + if( keywordColor != rhs.keywordColor ) return false; + if( keywordWeight != rhs.keywordWeight ) return false; + if( classColor != rhs.classColor ) return false; + if( classWeight != rhs.classWeight ) return false; + if( quoteColor != rhs.quoteColor ) return false; + if( quoteWeight != rhs.quoteWeight ) return false; + if( commentColor != rhs.commentColor ) return false; + if( commentWeight != rhs.commentWeight ) return false; + if( symbolFGColor != rhs.symbolFGColor ) return false; + if( symbolBGColor != rhs.symbolBGColor ) return false; + if( symbolWeight != rhs.symbolWeight ) return false; + return true; +} + +bool CodeEditorStyle::operator!=( const CodeEditorStyle& rhs ) const +{ + return !(*this == rhs); +} + +CodeEditorStyle CodeEditorStyle::loadSettings( QSettings *settings ) +{ + CodeEditorStyle theStyle( defaultStyleLight ); + if( !settings) return theStyle; + + if( !settings->childGroups().contains( SETTINGS_STYLE_GROUP )) + return theStyle; + + // style section exists - load values + settings->beginGroup( SETTINGS_STYLE_GROUP ); + QString type = settings->value( + SETTINGS_STYLE_TYPE, + QVariant( SETTINGS_STYLE_TYPE_LIGHT ) + ).toString(); + if( type == SETTINGS_STYLE_TYPE_LIGHT ) + { + settings->endGroup(); + return theStyle; + } + if( type == SETTINGS_STYLE_TYPE_DARK ) + { + theStyle = defaultStyleDark; + settings->endGroup(); + return theStyle; + } + if( type == SETTINGS_STYLE_TYPE_CUSTOM ) + { + theStyle.widgetFGColor = settings->value( + SETTINGS_STYLE_WIDGETFG, + QVariant(defaultStyleLight.widgetFGColor)).value(); + theStyle.widgetBGColor = settings->value( + SETTINGS_STYLE_WIDGETBG, + QVariant(defaultStyleLight.widgetBGColor)).value(); + theStyle.highlightBGColor = settings->value( + SETTINGS_STYLE_HILIFG, + QVariant(defaultStyleLight.highlightBGColor)).value(); + theStyle.lineNumFGColor = settings->value( + SETTINGS_STYLE_LINENUMFG, + QVariant(defaultStyleLight.lineNumFGColor)).value(); + theStyle.lineNumBGColor = settings->value( + SETTINGS_STYLE_LINENUMBG, + QVariant(defaultStyleLight.lineNumBGColor)).value(); + theStyle.keywordColor = settings->value( + SETTINGS_STYLE_KEYWORDFG, + QVariant(defaultStyleLight.keywordColor)).value(); + QVariant defKeyWWt(static_cast(defaultStyleLight.keywordWeight)); + theStyle.keywordWeight = static_cast( + settings->value( SETTINGS_STYLE_KEYWORDWT, defKeyWWt).toInt()); + theStyle.classColor = settings->value( + SETTINGS_STYLE_CLASSFG, + QVariant(defaultStyleLight.classColor)).value(); + QVariant defClsWt(static_cast(defaultStyleLight.classWeight)); + theStyle.classWeight = static_cast( + settings->value( SETTINGS_STYLE_CLASSWT, defClsWt).toInt()); + theStyle.quoteColor = settings->value( + SETTINGS_STYLE_QUOTEFG, + QVariant(defaultStyleLight.quoteColor)).value(); + QVariant defQteWt(static_cast(defaultStyleLight.quoteWeight)); + theStyle.quoteWeight = static_cast( + settings->value( SETTINGS_STYLE_QUOTEWT, defQteWt).toInt()); + theStyle.commentColor = settings->value( + SETTINGS_STYLE_COMMENTFG, + QVariant(defaultStyleLight.commentColor)).value(); + QVariant defCmtWt(static_cast(defaultStyleLight.commentWeight)); + theStyle.commentWeight = static_cast( + settings->value( SETTINGS_STYLE_COMMENTWT, defCmtWt).toInt()); + theStyle.symbolFGColor = settings->value( + SETTINGS_STYLE_SYMBOLFG, + QVariant(defaultStyleLight.symbolFGColor)).value(); + theStyle.symbolBGColor = settings->value( + SETTINGS_STYLE_SYMBOLBG, + QVariant(defaultStyleLight.symbolBGColor)).value(); + QVariant defSymWt(static_cast(defaultStyleLight.symbolWeight)); + theStyle.symbolWeight = static_cast( + settings->value( SETTINGS_STYLE_SYMBOLWT, defSymWt).toInt()); + } + settings->endGroup(); + return theStyle; +} + +void CodeEditorStyle::saveSettings( QSettings *settings, + const CodeEditorStyle& theStyle ) +{ + if( !settings ) return; + + if( settings->childGroups().contains( SETTINGS_STYLE_GROUP )) + { + settings->remove( SETTINGS_STYLE_GROUP ); + } + + settings->beginGroup( SETTINGS_STYLE_GROUP ); + bool isDefaultLight = ( defaultStyleLight == theStyle ); + bool isDefaultDark = ( defaultStyleDark == theStyle ); + if( isDefaultLight && !isDefaultDark ) { + settings->setValue( SETTINGS_STYLE_TYPE, + SETTINGS_STYLE_TYPE_LIGHT ); + } + else if( !isDefaultLight && isDefaultDark ) { + settings->setValue( SETTINGS_STYLE_TYPE, + SETTINGS_STYLE_TYPE_DARK ); + } + else { + settings->setValue( SETTINGS_STYLE_TYPE, + SETTINGS_STYLE_TYPE_CUSTOM ); + settings->setValue( SETTINGS_STYLE_WIDGETFG, + QVariant( theStyle.widgetFGColor )); + settings->setValue( SETTINGS_STYLE_WIDGETBG, + QVariant( theStyle.widgetBGColor )); + settings->setValue( SETTINGS_STYLE_HILIFG, + QVariant( theStyle.highlightBGColor )); + settings->setValue( SETTINGS_STYLE_LINENUMFG, + QVariant( theStyle.lineNumFGColor )); + settings->setValue( SETTINGS_STYLE_LINENUMBG, + QVariant( theStyle.lineNumBGColor )); + settings->setValue( SETTINGS_STYLE_KEYWORDFG, + QVariant( theStyle.keywordColor )); + settings->setValue( SETTINGS_STYLE_KEYWORDWT, + QVariant( static_cast( theStyle.keywordWeight ))); + settings->setValue( SETTINGS_STYLE_CLASSFG, + QVariant( theStyle.classColor )); + settings->setValue( SETTINGS_STYLE_CLASSWT, + QVariant( static_cast( theStyle.classWeight ))); + settings->setValue( SETTINGS_STYLE_QUOTEFG, + QVariant( theStyle.quoteColor )); + settings->setValue( SETTINGS_STYLE_QUOTEWT, + QVariant( static_cast( theStyle.quoteWeight ))); + settings->setValue( SETTINGS_STYLE_COMMENTFG, + QVariant( theStyle.commentColor )); + settings->setValue( SETTINGS_STYLE_COMMENTWT, + QVariant( static_cast( theStyle.commentWeight ))); + settings->setValue( SETTINGS_STYLE_SYMBOLFG, + QVariant( theStyle.symbolFGColor )); + settings->setValue( SETTINGS_STYLE_SYMBOLBG, + QVariant( theStyle.symbolBGColor )); + settings->setValue( SETTINGS_STYLE_SYMBOLWT, + QVariant( static_cast( theStyle.symbolWeight ))); + } + settings->endGroup(); +} diff --git a/gui/codeeditorstyle.h b/gui/codeeditorstyle.h index 0070e62a4..d9647250d 100644 --- a/gui/codeeditorstyle.h +++ b/gui/codeeditorstyle.h @@ -1,3 +1,21 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2019 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifndef CODEEDITORSTYLE_H #define CODEEDITORSTYLE_H @@ -5,11 +23,33 @@ #include #include +const QString SETTINGS_STYLE_GROUP( "EditorStyle" ); +const QString SETTINGS_STYLE_TYPE( "StyleType"); +const QString SETTINGS_STYLE_TYPE_LIGHT( "DefaultLight" ); +const QString SETTINGS_STYLE_TYPE_DARK( "DefaultDark" ); +const QString SETTINGS_STYLE_TYPE_CUSTOM( "Custom" ); +const QString SETTINGS_STYLE_WIDGETFG( "StyleWidgetFG" ); +const QString SETTINGS_STYLE_WIDGETBG( "StyleWidgetBG" ); +const QString SETTINGS_STYLE_HILIFG( "StyleHighlightFG" ); +const QString SETTINGS_STYLE_LINENUMFG( "StyleLineNumFG" ); +const QString SETTINGS_STYLE_LINENUMBG( "StyleLineNumBG" ); +const QString SETTINGS_STYLE_KEYWORDFG( "StyleKeywordFG" ); +const QString SETTINGS_STYLE_KEYWORDWT( "StyleKeywordWeight" ); +const QString SETTINGS_STYLE_CLASSFG( "StyleClassFG" ); +const QString SETTINGS_STYLE_CLASSWT( "StyleClassWeight" ); +const QString SETTINGS_STYLE_QUOTEFG( "StyleQuoteFG" ); +const QString SETTINGS_STYLE_QUOTEWT( "StyleQuoteWeight" ); +const QString SETTINGS_STYLE_COMMENTFG( "StyleCommentFG" ); +const QString SETTINGS_STYLE_COMMENTWT( "StyleCommentWeight" ); +const QString SETTINGS_STYLE_SYMBOLFG( "StyleSymbolFG" ); +const QString SETTINGS_STYLE_SYMBOLBG( "StyleSymbolBG" ); +const QString SETTINGS_STYLE_SYMBOLWT( "StyleSymbolWeight" ); + +class QSettings; + class CodeEditorStyle { -private: - CodeEditorStyle() {}; public: - CodeEditorStyle( + explicit CodeEditorStyle( const QColor& CtrlFGColor, const QColor& CtrlBGColor, const QColor& HiLiBGColor, const QColor& LnNumFGColor, const QColor& LnNumBGColor, @@ -18,24 +58,14 @@ public: const QColor& QteFGColor, const QFont::Weight& QteWeight, const QColor& CmtFGColor, const QFont::Weight& CmtWeight, const QColor& SymbFGColor, const QColor& SymbBGColor, - const QFont::Weight& SymbWeight) : - widgetFGColor(CtrlFGColor), - widgetBGColor(CtrlBGColor), - highlightBGColor(HiLiBGColor), - lineNumFGColor(LnNumFGColor), - lineNumBGColor(LnNumBGColor), - keywordColor(KeyWdFGColor), - keywordWeight(KeyWdWeight), - classColor(ClsFGColor), - classWeight(ClsWeight), - quoteColor(QteFGColor), - quoteWeight(QteWeight), - commentColor(CmtFGColor), - commentWeight(CmtWeight), - symbolFGColor(SymbFGColor), - symbolBGColor(SymbBGColor), - symbolWeight(SymbWeight) - {} + const QFont::Weight& SymbWeight); + ~CodeEditorStyle() {}; + + bool operator==( const CodeEditorStyle& rhs ) const; + bool operator!=( const CodeEditorStyle& rhs ) const; + + static CodeEditorStyle loadSettings( QSettings *settings ); + static void saveSettings( QSettings *settings, const CodeEditorStyle& theStyle ); public: QColor widgetFGColor; @@ -56,7 +86,7 @@ public: QFont::Weight symbolWeight; }; -static const CodeEditorStyle defaultStyle({ +static const CodeEditorStyle defaultStyleLight( /* editor FG/BG */ Qt::black, QColor(240, 240, 240), /* highlight BG */ QColor(255, 220, 220), /* line number FG/BG */ Qt::black, QColor(240, 240, 240), @@ -65,6 +95,19 @@ static const CodeEditorStyle defaultStyle({ /* quote FG/Weight */ Qt::darkGreen, QFont::Normal, /* comment FG/Weight */ Qt::gray, QFont::Normal, /* Symbol FG/BG/Weight */ Qt::red, QColor(220, 220, 255), QFont::Normal -}); +); + +// Styling derived from Eclipse Color Theme - 'RecognEyes' +// http://www.eclipsecolorthemes.org/?view=theme&id=30 +static const CodeEditorStyle defaultStyleDark( + /* editor FG/BG */ QColor(218, 218, 218), QColor(16, 16, 32), + /* highlight BG */ QColor(64, 64, 64), + /* line number FG/BG */ QColor(43, 145, 175), QColor(16, 16, 32), + /* keyword FG/Weight */ QColor(0, 204, 204), QFont::Bold, + /* class FG/Weight */ QColor(218, 0, 218), QFont::Bold, + /* quote FG/Weight */ QColor(0, 204, 0), QFont::Normal, + /* comment FG/Weight */ QColor(180, 180, 180), QFont::Normal, + /* Symbol FG/BG/Weight */ QColor(218, 32, 32), QColor(32, 32, 108), QFont::Normal +); #endif /* CODEEDITORSTYLE_H */ diff --git a/gui/codeeditstylecontrols.cpp b/gui/codeeditstylecontrols.cpp new file mode 100644 index 000000000..1e788d422 --- /dev/null +++ b/gui/codeeditstylecontrols.cpp @@ -0,0 +1,114 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2019 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "codeeditstylecontrols.h" +#include + +SelectColorButton::SelectColorButton( QWidget* parent ) : + QPushButton( parent ), + mColor( QColor( 255, 255, 255 )) +{ + updateColor(); + connect( this, SIGNAL( clicked() ), this, SLOT( changeColor() )); +} + +void SelectColorButton::updateColor() { + QString btnColorStyle = QString( + "background-color:rgb(%1,%2,%3);" + "border-style:outset;" + "border-width: 1px;") + .arg( mColor.red() ) + .arg( mColor.green() ) + .arg( mColor.blue() ); + setObjectName("SelectColorButton"); + setStyleSheet( btnColorStyle ); +} + +void SelectColorButton::changeColor() { + QColorDialog pDlg( mColor ); + pDlg.setModal( true ); + int nResult = pDlg.exec(); + if (nResult == QDialog::Accepted ) + { + setColor( pDlg.selectedColor() ); + emit colorChanged( mColor ); + } +} + +void SelectColorButton::setColor( const QColor& color ) { + mColor = color; + updateColor(); +} + +const QColor& SelectColorButton::getColor() { + return mColor; +} + +SelectFontWeightCombo::SelectFontWeightCombo( QWidget* parent ) : + QComboBox( parent ), + mWeight( QFont::Normal ) +{ + addItem( QObject::tr( "Thin" ), + QVariant( static_cast( QFont::Thin ))); + addItem( QObject::tr( "ExtraLight" ), + QVariant( static_cast( QFont::ExtraLight ))); + addItem( QObject::tr( "Light" ), + QVariant( static_cast( QFont::Light ))); + addItem( QObject::tr( "Normal" ), + QVariant( static_cast( QFont::Normal ))); + addItem( QObject::tr( "Medium" ), + QVariant( static_cast( QFont::Medium ))); + addItem( QObject::tr( "DemiBold" ), + QVariant( static_cast( QFont::DemiBold ))); + addItem( QObject::tr( "Bold" ), + QVariant( static_cast( QFont::Bold ))); + addItem( QObject::tr( "ExtraBold" ), + QVariant( static_cast( QFont::ExtraBold ))); + addItem( QObject::tr( "Black" ), + QVariant( static_cast( QFont::Black ))); + updateWeight(); + connect( this, SIGNAL( currentIndexChanged( int )), + this, SLOT( changeWeight( int ))); +} + +void SelectFontWeightCombo::updateWeight() { + int nResult = findData( QVariant( static_cast( mWeight ))); + + if( nResult != -1 ) { + setCurrentIndex( nResult ); + } + else { + setCurrentIndex( findData( static_cast( QFont::Normal ))); + } +} + +void SelectFontWeightCombo::changeWeight( int index ) { + if( index != -1 ) { + setWeight( static_cast( itemData( index ).toInt() )); + emit weightChanged( mWeight ); + } +} + +void SelectFontWeightCombo::setWeight( const QFont::Weight& weight ) { + mWeight = weight; + updateWeight(); +} + +const QFont::Weight& SelectFontWeightCombo::getWeight() { + return mWeight; +} diff --git a/gui/codeeditstylecontrols.h b/gui/codeeditstylecontrols.h new file mode 100644 index 000000000..7f778b9a2 --- /dev/null +++ b/gui/codeeditstylecontrols.h @@ -0,0 +1,73 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2019 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// widget subclass methodology derived from here: +// https://stackoverflow.com/questions/18257281/qt-color-picker-widget/43871405#43871405 + +#ifndef CODEEDITORSTYLECONTROLS_H +#define CODEEDITORSTYLECONTROLS_H + +#include +#include +#include +#include + +class SelectColorButton : public QPushButton +{ + Q_OBJECT +public: + explicit SelectColorButton( QWidget* parent ); + virtual ~SelectColorButton(){}; + + void setColor( const QColor& color ); + const QColor& getColor(); + +signals: + void colorChanged( QColor& newColor ); + +public slots: + void updateColor(); + void changeColor(); + +private: + QColor mColor; +}; + + +class SelectFontWeightCombo : public QComboBox +{ + Q_OBJECT +public: + explicit SelectFontWeightCombo( QWidget* parent ); + virtual ~SelectFontWeightCombo() {} + + void setWeight( const QFont::Weight& weight ); + const QFont::Weight& getWeight(); + +signals: + void weightChanged( QFont::Weight& newWeight ); + +public slots: + void updateWeight(); + void changeWeight( int index ); + +private: + QFont::Weight mWeight; +}; + +#endif //CODEEDITORSTYLECONTROLS_H \ No newline at end of file diff --git a/gui/codeeditstyledialog.cpp b/gui/codeeditstyledialog.cpp new file mode 100644 index 000000000..b29d68c07 --- /dev/null +++ b/gui/codeeditstyledialog.cpp @@ -0,0 +1,342 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2019 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "codeeditstyledialog.h" +#include +#include +#include +#include + +const QString StyleEditDialog::mSampleDocument( +"/*****\n" +"* Multiline Comment\n" +"*****/\n" +"#include \n" +"#include \n" +"\n" +"class fwdClass;\n" +"\n" +"int main(int argc, char *argv[])\n" +"{\n" +" QApplication a(argc, argv);\n" +" int nLife = 42;\n" +" w.show();\n" +" // single line comment\n" +" // line below is highlighted\n" +" fwdClass( nLife );\n" +" return a.exec();\n" +"}\n" +"\n" +"void class fwdClass( double dValue ) {\n" +" std::cout << \"Ipsum Lorem: \"\n" +" << nValue\n" +" << std::endl;\n" +"}\n"); + +const QStringList StyleEditDialog::mErrSymbolsList = ( + QStringList( QStringList() + << "nLife" + << "dValue" + << "nValue")); +const int StyleEditDialog::mErrLineNum = 16; + +StyleEditDialog::StyleEditDialog( const CodeEditorStyle& newStyle, + QWidget *parent /*= nullptr*/ ) : + QDialog( parent ), + mStyleIncoming( newStyle ), + mStyleOutgoing( newStyle ) +{ + QVBoxLayout *vboxMain = new QVBoxLayout(this); + QHBoxLayout *hboxEdit = new QHBoxLayout(); + // Color/Weight controls + QFormLayout *flEditControls = new QFormLayout(); + mBtnWidgetColorFG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Editor Foreground Color"), + mBtnWidgetColorFG ); + mBtnWidgetColorBG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Editor Background Color"), + mBtnWidgetColorBG ); + mBtnHighlightBG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Highlight Background Color"), + mBtnHighlightBG ); + mBtnLineNumFG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Line Number Foreground Color"), + mBtnLineNumFG ); + mBtnLineNumBG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Line Number Background Color"), + mBtnLineNumBG ); + mBtnKeywordFG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Keyword Foreground Color"), + mBtnKeywordFG ); + mCBKeywordWeight = new SelectFontWeightCombo( this ); + flEditControls->addRow( QObject::tr("Keyword Font Weight"), + mCBKeywordWeight ); + mBtnClassFG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Class ForegroundColor"), + mBtnClassFG ); + mCBClassWeight = new SelectFontWeightCombo( this ); + flEditControls->addRow( QObject::tr("Class Font Weight"), + mCBClassWeight ); + mBtnQuoteFG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Quote Foreground Color"), + mBtnQuoteFG ); + mCBQuoteWeight = new SelectFontWeightCombo( this ); + flEditControls->addRow( QObject::tr("Quote Font Weight"), + mCBQuoteWeight ); + mBtnCommentFG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Comment Foreground Color"), + mBtnCommentFG ); + mCBCommentWeight = new SelectFontWeightCombo( this ); + flEditControls->addRow( QObject::tr("Comment Font Weight"), + mCBCommentWeight ); + mBtnSymbolFG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Symbol Foreground Color"), + mBtnSymbolFG ); + mBtnSymbolBG = new SelectColorButton( this ); + flEditControls->addRow( QObject::tr("Symbol Background Color"), + mBtnSymbolBG ); + mCBSymbolWeight = new SelectFontWeightCombo( this ); + flEditControls->addRow( QObject::tr("Symbol Font Weight"), + mCBSymbolWeight ); + hboxEdit->addLayout( flEditControls ); + // CodeEditor to display Style + mSampleEditor = new CodeEditor( this ); + QFont sampleFont( "Monospace" ); + QFontMetrics fm(sampleFont); + mSampleEditor->setMinimumWidth( fm.width(QString( 40, 'W' ))); + // designate highlight, errors, and symbols + mSampleEditor->setError( mSampleDocument, mErrLineNum, mErrSymbolsList); + // End Controls + hboxEdit->addWidget( mSampleEditor ); + vboxMain->addLayout( hboxEdit ); + + // Default Controls + QHBoxLayout *hboxDefaultControls = new QHBoxLayout(); + mBtnDefaultLight = new QPushButton( QObject::tr("Set to Default Light"), + this ); + mBtnDefaultDark = new QPushButton( QObject::tr("Set to Default Dark"), + this ); + hboxDefaultControls->addStretch( 1 ); + hboxDefaultControls->addWidget( mBtnDefaultLight ); + hboxDefaultControls->addWidget( mBtnDefaultDark ); + hboxDefaultControls->addStretch( 1 ); + vboxMain->addLayout( hboxDefaultControls ); + vboxMain->addStretch( 2 ); + // dialog controls + QDialogButtonBox *dBtnBox = new QDialogButtonBox( + QDialogButtonBox::Cancel | + QDialogButtonBox::Ok | + QDialogButtonBox::Reset ); + vboxMain->addStretch( 1 ); + vboxMain->addWidget( dBtnBox ); + + // setup values for style controls + updateControls(); + updateStyle(); + + connect( dBtnBox, SIGNAL( accepted() ), this, SLOT( accept() )); + connect( dBtnBox, SIGNAL( rejected() ), this, SLOT( reject() )); + connect( dBtnBox->button( QDialogButtonBox::Reset ), SIGNAL(clicked()), + this, SLOT( resetStyle() )); + connect( mBtnDefaultLight, SIGNAL( clicked() ), + this, SLOT( setStyleDefaultLight() )); + connect( mBtnDefaultDark, SIGNAL( clicked() ), + this, SLOT( setStyleDefaultDark() )); + connect( mBtnWidgetColorFG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedWidgetFG( QColor& ))); + connect( mBtnWidgetColorBG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedWidgetBG( QColor& ))); + connect( mBtnHighlightBG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedHighlightBG( QColor& ))); + connect( mBtnLineNumFG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedLineNumFG( QColor& ))); + connect( mBtnLineNumBG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedLineNumBG( QColor& ))); + connect( mBtnKeywordFG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedKeywordFG( QColor& ))); + connect( mCBKeywordWeight, SIGNAL( weightChanged( QFont::Weight& )), + this, SLOT( weightChangedKeyword( QFont::Weight& ))); + connect( mBtnClassFG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedClassFG( QColor& ))); + connect( mCBClassWeight, SIGNAL( weightChanged( QFont::Weight& )), + this, SLOT( weightChangedClass( QFont::Weight& ))); + connect( mBtnQuoteFG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedQuoteFG( QColor& ))); + connect( mCBQuoteWeight, SIGNAL( weightChanged( QFont::Weight& )), + this, SLOT( weightChangedQuote( QFont::Weight& ))); + connect( mBtnCommentFG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedCommentFG( QColor& ))); + connect( mCBCommentWeight, SIGNAL( weightChanged( QFont::Weight& )), + this, SLOT( weightChangedComment( QFont::Weight& ))); + connect( mBtnSymbolFG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedSymbolFG( QColor& ))); + connect( mBtnSymbolBG, SIGNAL( colorChanged( QColor& )), + this, SLOT( colorChangedSymbolBG( QColor& ))); + connect( mCBSymbolWeight, SIGNAL( weightChanged( QFont::Weight& )), + this, SLOT( weightChangedSymbol( QFont::Weight& ))); +} + +void StyleEditDialog::updateControls() +{ + mBtnWidgetColorFG->setColor( mStyleOutgoing.widgetFGColor ); + mBtnWidgetColorBG->setColor( mStyleOutgoing.widgetBGColor ); + mBtnHighlightBG->setColor( mStyleOutgoing.highlightBGColor ); + mBtnLineNumFG->setColor( mStyleOutgoing.lineNumFGColor ); + mBtnLineNumBG->setColor( mStyleOutgoing.lineNumBGColor ); + mBtnKeywordFG->setColor( mStyleOutgoing.keywordColor ); + mCBKeywordWeight->setWeight( mStyleOutgoing.keywordWeight ); + mBtnClassFG->setColor( mStyleOutgoing.classColor ); + mCBClassWeight->setWeight( mStyleOutgoing.classWeight ); + mBtnQuoteFG->setColor( mStyleOutgoing.quoteColor ); + mCBQuoteWeight->setWeight( mStyleOutgoing.quoteWeight ); + mBtnCommentFG->setColor( mStyleOutgoing.commentColor ); + mCBCommentWeight->setWeight( mStyleOutgoing.commentWeight ); + mBtnSymbolFG->setColor( mStyleOutgoing.symbolFGColor ); + mBtnSymbolBG->setColor( mStyleOutgoing.symbolBGColor ); + mCBSymbolWeight->setWeight( mStyleOutgoing.symbolWeight ); +} + +void StyleEditDialog::updateStyle() +{ + mBtnDefaultLight->setEnabled( mStyleOutgoing != defaultStyleLight ); + mBtnDefaultDark->setEnabled( mStyleOutgoing != defaultStyleDark ); + // set Editor Styling + mSampleEditor->setStyle( mStyleOutgoing ); +} + +CodeEditorStyle StyleEditDialog::getStyle() +{ + return mStyleOutgoing; +} + +void StyleEditDialog::resetStyle() +{ + mStyleOutgoing = mStyleIncoming; + updateControls(); + updateStyle(); +} + +void StyleEditDialog::setStyleDefaultLight() +{ + mStyleOutgoing = defaultStyleLight; + updateControls(); + updateStyle(); +} + +void StyleEditDialog::setStyleDefaultDark() +{ + mStyleOutgoing = defaultStyleDark; + updateControls(); + updateStyle(); +} + +void StyleEditDialog::colorChangedWidgetFG( QColor& newColor ) +{ + mStyleOutgoing.widgetFGColor = newColor; + updateStyle(); +} + +void StyleEditDialog::colorChangedWidgetBG( QColor& newColor ) +{ + mStyleOutgoing.widgetBGColor = newColor; + updateStyle(); +} + +void StyleEditDialog::colorChangedHighlightBG( QColor& newColor ) +{ + mStyleOutgoing.highlightBGColor = newColor; + updateStyle(); +} + +void StyleEditDialog::colorChangedLineNumFG( QColor& newColor ) +{ + mStyleOutgoing.lineNumFGColor = newColor; + updateStyle(); +} + +void StyleEditDialog::colorChangedLineNumBG( QColor& newColor ) +{ + mStyleOutgoing.lineNumBGColor = newColor; + updateStyle(); +} + +void StyleEditDialog::colorChangedKeywordFG( QColor& newColor ) +{ + mStyleOutgoing.keywordColor = newColor; + updateStyle(); +} + +void StyleEditDialog::weightChangedKeyword( QFont::Weight& newWeight ) +{ + mStyleOutgoing.keywordWeight = newWeight; + updateStyle(); +} + +void StyleEditDialog::colorChangedClassFG( QColor& newColor ) +{ + mStyleOutgoing.classColor = newColor; + updateStyle(); +} + +void StyleEditDialog::weightChangedClass( QFont::Weight& newWeight ) +{ + mStyleOutgoing.classWeight = newWeight; + updateStyle(); +} + +void StyleEditDialog::colorChangedQuoteFG( QColor& newColor ) +{ + mStyleOutgoing.quoteColor = newColor; + updateStyle(); +} + +void StyleEditDialog::weightChangedQuote( QFont::Weight& newWeight ) +{ + mStyleOutgoing.quoteWeight = newWeight; + updateStyle(); +} + +void StyleEditDialog::colorChangedCommentFG( QColor& newColor ) +{ + mStyleOutgoing.commentColor = newColor; + updateStyle(); +} + +void StyleEditDialog::weightChangedComment( QFont::Weight& newWeight ) +{ + mStyleOutgoing.commentWeight = newWeight; + updateStyle(); +} + +void StyleEditDialog::colorChangedSymbolFG( QColor& newColor ) +{ + mStyleOutgoing.symbolFGColor = newColor; + updateStyle(); +} + +void StyleEditDialog::colorChangedSymbolBG( QColor& newColor ) +{ + mStyleOutgoing.symbolBGColor = newColor; + updateStyle(); +} + +void StyleEditDialog::weightChangedSymbol( QFont::Weight& newWeight ) +{ + mStyleOutgoing.symbolWeight = newWeight; + updateStyle(); +} diff --git a/gui/codeeditstyledialog.h b/gui/codeeditstyledialog.h new file mode 100644 index 000000000..aeead245a --- /dev/null +++ b/gui/codeeditstyledialog.h @@ -0,0 +1,94 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2019 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CODEEDITSTYLEDIALOG_H +#define CODEEDITSTYLEDIALOG_H + +#include +#include +#include "codeeditstylecontrols.h" +#include "codeeditor.h" +#include "codeeditorstyle.h" + +class StyleEditDialog : public QDialog +{ + Q_OBJECT +public: + explicit StyleEditDialog( const CodeEditorStyle& newStyle, + QWidget *parent = nullptr); + virtual ~StyleEditDialog() {}; + + CodeEditorStyle getStyle(); + +private: + void updateControls(); + void updateStyle(); + +public slots: + void resetStyle(); + void setStyleDefaultLight(); + void setStyleDefaultDark(); + void colorChangedWidgetFG( QColor& newColor ); + void colorChangedWidgetBG( QColor& newColor ); + void colorChangedHighlightBG( QColor& newColor ); + void colorChangedLineNumFG( QColor& newColor ); + void colorChangedLineNumBG( QColor& newColor ); + void colorChangedKeywordFG( QColor& newColor ); + void weightChangedKeyword( QFont::Weight& newWeight ); + void colorChangedClassFG( QColor& newColor ); + void weightChangedClass( QFont::Weight& newWeight ); + void colorChangedQuoteFG( QColor& newColor ); + void weightChangedQuote( QFont::Weight& newWeight ); + void colorChangedCommentFG( QColor& newColor ); + void weightChangedComment( QFont::Weight& newWeight ); + void colorChangedSymbolFG( QColor& newColor ); + void colorChangedSymbolBG( QColor& newColor ); + void weightChangedSymbol( QFont::Weight& newWeight ); + +private: + CodeEditorStyle mStyleIncoming; + CodeEditorStyle mStyleOutgoing; + + CodeEditor *mSampleEditor; + + SelectColorButton *mBtnWidgetColorFG; + SelectColorButton *mBtnWidgetColorBG; + SelectColorButton *mBtnHighlightBG; + SelectColorButton *mBtnLineNumFG; + SelectColorButton *mBtnLineNumBG; + SelectColorButton *mBtnKeywordFG; + SelectFontWeightCombo *mCBKeywordWeight; + SelectColorButton *mBtnClassFG; + SelectFontWeightCombo *mCBClassWeight; + SelectColorButton *mBtnQuoteFG; + SelectFontWeightCombo *mCBQuoteWeight; + SelectColorButton *mBtnCommentFG; + SelectFontWeightCombo *mCBCommentWeight; + SelectColorButton *mBtnSymbolFG; + SelectColorButton *mBtnSymbolBG; + SelectFontWeightCombo *mCBSymbolWeight; + + QPushButton *mBtnDefaultLight; + QPushButton *mBtnDefaultDark; + + static const QString mSampleDocument; + static const QStringList mErrSymbolsList; + static const int mErrLineNum; +}; + +#endif //CODEEDITSTYLEDIALOG_H \ No newline at end of file diff --git a/gui/gui.pro b/gui/gui.pro index 86b15cf17..0cbaebf16 100644 --- a/gui/gui.pro +++ b/gui/gui.pro @@ -90,7 +90,9 @@ HEADERS += aboutdialog.h \ applicationlist.h \ checkstatistics.h \ checkthread.h \ + codeeditstylecontrols.h \ codeeditorstyle.h \ + codeeditstyledialog.h \ codeeditor.h \ common.h \ csvreport.h \ @@ -127,6 +129,9 @@ SOURCES += aboutdialog.cpp \ applicationlist.cpp \ checkstatistics.cpp \ checkthread.cpp \ + codeeditorstyle.cpp \ + codeeditstylecontrols.cpp \ + codeeditstyledialog.cpp \ codeeditor.cpp \ common.cpp \ csvreport.cpp \ @@ -168,7 +173,7 @@ win32 { } contains(QMAKE_CC, gcc) { - QMAKE_CXXFLAGS += -std=c++0x -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare + QMAKE_CXXFLAGS += -std=c++11 -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare } contains(QMAKE_CXX, clang++) { diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 73ebeda54..34d34ca39 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -1000,12 +1000,14 @@ void MainWindow::programSettings() SettingsDialog dialog(mApplications, mTranslation, this); if (dialog.exec() == QDialog::Accepted) { dialog.saveSettingValues(); + mSettings->sync(); mUI.mResults->updateSettings(dialog.showFullPath(), dialog.saveFullPath(), dialog.saveAllErrors(), dialog.showNoErrorsMessage(), dialog.showErrorId(), dialog.showInconclusive()); + mUI.mResults->updateStyleSetting( mSettings ); const QString newLang = mSettings->value(SETTINGS_LANGUAGE, "en").toString(); setLanguage(newLang); } diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index 3238e0835..abb8b1e7b 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -41,6 +41,7 @@ #include "applicationlist.h" #include "checkstatistics.h" #include "path.h" +#include "codeeditorstyle.h" ResultsView::ResultsView(QWidget * parent) : QWidget(parent), @@ -69,6 +70,9 @@ void ResultsView::initialize(QSettings *settings, ApplicationList *list, ThreadH mUI.mProgress->setMinimum(0); mUI.mProgress->setVisible(false); + CodeEditorStyle theStyle( CodeEditorStyle::loadSettings( settings )); + mUI.mCode->setStyle( theStyle ); + QByteArray state = settings->value(SETTINGS_MAINWND_SPLITTER_STATE).toByteArray(); mUI.mVerticalSplitter->restoreState(state); mShowNoErrorsMessage = settings->value(SETTINGS_SHOW_NO_ERRORS, true).toBool(); @@ -236,6 +240,12 @@ void ResultsView::updateSettings(bool showFullPath, mShowNoErrorsMessage = showNoErrorsMessage; } +void ResultsView::updateStyleSetting( QSettings *settings ) +{ + CodeEditorStyle theStyle( CodeEditorStyle::loadSettings( settings )); + mUI.mCode->setStyle( theStyle ); +} + void ResultsView::setCheckDirectory(const QString &dir) { mUI.mTree->setCheckDirectory(dir); diff --git a/gui/resultsview.h b/gui/resultsview.h index 46e155ab3..f295a2646 100644 --- a/gui/resultsview.h +++ b/gui/resultsview.h @@ -107,6 +107,16 @@ public: bool showErrorId, bool showInconclusive); + /** + * @brief Update Code Editor Style + * + * Function will read updated Code Editor styling from + * stored program settings. + * + * @param settings Pointer to QSettings Object + */ + void updateStyleSetting( QSettings *settings ); + /** * @brief Set the directory we are checking * diff --git a/gui/settings.ui b/gui/settings.ui index aaa9fdd88..e6e9abcfa 100644 --- a/gui/settings.ui +++ b/gui/settings.ui @@ -7,7 +7,7 @@ 0 0 589 - 319 + 346 @@ -420,6 +420,80 @@ + + + Code Editor + + + + + + Code Editor Style + + + + + + Default Light Style + + + + + + + Default Dark Style + + + + + + + + + Custom + + + + + + + Edit... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + @@ -463,8 +537,8 @@ accept() - 248 - 254 + 257 + 336 157 @@ -479,8 +553,8 @@ reject() - 316 - 260 + 325 + 336 286 diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 1b45f0d5a..7b1aaaf9e 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -28,6 +28,8 @@ #include "applicationdialog.h" #include "applicationlist.h" #include "translationhandler.h" +#include "codeeditorstyle.h" +#include "codeeditstyledialog.h" #include "common.h" SettingsDialog::SettingsDialog(ApplicationList *list, @@ -64,6 +66,9 @@ SettingsDialog::SettingsDialog(ApplicationList *list, #else mUI.mTabClang->setVisible(false); #endif + mCurrentStyle = new CodeEditorStyle( CodeEditorStyle::loadSettings( &settings )); + manageStyleControls(); + connect(mUI.mButtons, &QDialogButtonBox::accepted, this, &SettingsDialog::ok); connect(mUI.mButtons, &QDialogButtonBox::rejected, this, &SettingsDialog::reject); connect(mUI.mBtnAddApplication, SIGNAL(clicked()), @@ -79,6 +84,10 @@ SettingsDialog::SettingsDialog(ApplicationList *list, connect(mUI.mBtnBrowsePythonPath, &QPushButton::clicked, this, &SettingsDialog::browsePythonPath); connect(mUI.mBtnBrowseMisraFile, &QPushButton::clicked, this, &SettingsDialog::browseMisraFile); + connect(mUI.btnEditCustom, SIGNAL( clicked() ), this, SLOT( editCodeEditorStyle() )); + connect(mUI.choiceLight, SIGNAL( released() ), this, SLOT( setCodeEditorStyleDefault() )); + connect(mUI.choiceDark, SIGNAL( released() ), this, SLOT( setCodeEditorStyleDefault() )); + connect(mUI.choiceCustom, SIGNAL( toggled( bool )), mUI.btnEditCustom, SLOT( setEnabled( bool ))); mUI.mListWidget->setSortingEnabled(false); populateApplicationList(); @@ -175,6 +184,8 @@ void SettingsDialog::saveSettingValues() const const QString langcode = currentLang->data(mLangCodeRole).toString(); settings.setValue(SETTINGS_LANGUAGE, langcode); } + CodeEditorStyle::saveSettings(&settings, *mCurrentStyle ); + } void SettingsDialog::saveCheckboxValue(QSettings *settings, QCheckBox *box, @@ -316,6 +327,26 @@ void SettingsDialog::browseMisraFile() mUI.mEditMisraFile->setText(fileName); } +// Slot to set default light style +void SettingsDialog::setCodeEditorStyleDefault() +{ + if( mUI.choiceLight->isChecked() ) *mCurrentStyle = defaultStyleLight; + if( mUI.choiceDark->isChecked() ) *mCurrentStyle = defaultStyleDark; + manageStyleControls(); +} + +// Slot to edit custom style +void SettingsDialog::editCodeEditorStyle() +{ + StyleEditDialog pDlg( *mCurrentStyle, this ); + int nResult = pDlg.exec(); + if( nResult == QDialog::Accepted ) + { + *mCurrentStyle = pDlg.getStyle(); + manageStyleControls(); + } +} + void SettingsDialog::browseClangPath() { QString selectedDir = QFileDialog::getExistingDirectory(this, @@ -326,3 +357,13 @@ void SettingsDialog::browseClangPath() mUI.mEditClangPath->setText(selectedDir); } } + +void SettingsDialog::manageStyleControls() +{ + bool isDefaultLight = *mCurrentStyle == defaultStyleLight; + bool isDefaultDark = *mCurrentStyle == defaultStyleDark; + mUI.choiceLight->setChecked( isDefaultLight && !isDefaultDark ); + mUI.choiceDark->setChecked( !isDefaultLight && isDefaultDark ); + mUI.choiceCustom->setChecked( !isDefaultLight && !isDefaultDark ); + mUI.btnEditCustom->setEnabled( !isDefaultLight && !isDefaultDark ); +} \ No newline at end of file diff --git a/gui/settingsdialog.h b/gui/settingsdialog.h index 9d794e0e2..3a5f200e3 100644 --- a/gui/settingsdialog.h +++ b/gui/settingsdialog.h @@ -27,6 +27,7 @@ class QSettings; class QWidget; class ApplicationList; class TranslationHandler; +class CodeEditorStyle; /// @addtogroup GUI /// @{ @@ -136,6 +137,17 @@ protected slots: * @brief Browse for MISRA file */ void browseMisraFile(); + + /** + * @brief Set Code Editor Style to Default + */ + void setCodeEditorStyleDefault(); + + /** + * @brief Edit Custom Code Editor Style + */ + void editCodeEditorStyle(); + protected: /** * @brief Clear all applications from the list and re insert them from mTempApplications @@ -186,6 +198,11 @@ protected: */ void initTranslationsList(); + /** + * @brief Current Code Editor Style + */ + CodeEditorStyle *mCurrentStyle; + /** * @brief List of applications user has specified * @@ -211,6 +228,8 @@ protected: */ Ui::Settings mUI; private: + void manageStyleControls(); + static const int mLangCodeRole = Qt::UserRole; }; /// @} diff --git a/tools/triage/CMakeLists.txt b/tools/triage/CMakeLists.txt index 834d76275..7721d03a7 100644 --- a/tools/triage/CMakeLists.txt +++ b/tools/triage/CMakeLists.txt @@ -13,7 +13,13 @@ if (BUILD_GUI AND BUILD_TESTS) file(GLOB uis "*.ui") qt5_wrap_ui(uis_hdrs ${uis}) - add_executable(triage ${hdrs} ${srcs} ${uis_hdrs} ${PROJECT_SOURCE_DIR}/gui/codeeditor.cpp) + add_executable( + triage + ${hdrs} + ${srcs} + ${uis_hdrs} + ${PROJECT_SOURCE_DIR}/gui/codeeditorstyle.cpp + ${PROJECT_SOURCE_DIR}/gui/codeeditor.cpp) target_include_directories(triage PUBLIC ${PROJECT_SOURCE_DIR}/gui/) target_link_libraries(triage Qt5::Core Qt5::Gui Qt5::Widgets) diff --git a/tools/triage/triage.pro b/tools/triage/triage.pro index f290f0a62..70425ee94 100644 --- a/tools/triage/triage.pro +++ b/tools/triage/triage.pro @@ -28,9 +28,11 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += main.cpp\ mainwindow.cpp \ + ../../gui/codeeditorstyle.cpp \ ../../gui/codeeditor.cpp HEADERS += mainwindow.h \ + ../../gui/codeeditorstyle.h \ ../../gui/codeeditor.h FORMS += mainwindow.ui