From 567bb809192837ce64ca3f6f490e241b164485a3 2013-05-16 11:33:19 From: Miikka Heikkinen Date: 2013-05-16 11:33:19 Subject: [PATCH] Fix explicitly set default pen/brush/font getting overridden by theme Now we use default pen/brush/font that is unlikely to be ever explicitly set by user, so checks for default in theme initialization work more reliably. Task-number: QTRD-1926 Task-number: QTRD-2023 Task-number: QTRD-2039 Change-Id: Id46b978ee49132e486e06968af00ef60559ede0f Reviewed-by: Mika Salmela --- diff --git a/src/areachart/qareaseries.cpp b/src/areachart/qareaseries.cpp index e6feb36..13af5a1 100644 --- a/src/areachart/qareaseries.cpp +++ b/src/areachart/qareaseries.cpp @@ -331,6 +331,8 @@ bool QAreaSeries::pointsVisible() const QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries, QAreaSeries *q) : QAbstractSeriesPrivate(q), + m_brush(QChartPrivate::defaultBrush()), + m_pen(QChartPrivate::defaultPen()), m_upperSeries(upperSeries), m_lowerSeries(lowerSeries), m_pointsVisible(false) @@ -427,19 +429,18 @@ QAbstractAxis* QAreaSeriesPrivate::createDefaultAxis(Qt::Orientation orientation void QAreaSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced) { Q_Q(QAreaSeries); - QPen pen; - QBrush brush; const QList gradients = theme->seriesGradients(); const QList colors = theme->seriesColors(); - if (forced || pen == m_pen) { + if (forced || QChartPrivate::defaultPen() == m_pen) { + QPen pen; pen.setColor(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0)); pen.setWidthF(2); q->setPen(pen); } - if (forced || brush == m_brush) { + if (forced || QChartPrivate::defaultBrush() == m_brush) { QBrush brush(colors.at(index % colors.size())); q->setBrush(brush); } diff --git a/src/axis/qabstractaxis.cpp b/src/axis/qabstractaxis.cpp index 797aeb9..9afbe7e 100644 --- a/src/axis/qabstractaxis.cpp +++ b/src/axis/qabstractaxis.cpp @@ -22,6 +22,7 @@ #include "qabstractaxis_p.h" #include "chartdataset_p.h" #include "charttheme_p.h" +#include "qchart_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -876,16 +877,25 @@ QAbstractAxisPrivate::QAbstractAxisPrivate(QAbstractAxis *q) m_orientation(Qt::Orientation(0)), m_visible(true), m_arrowVisible(true), + m_axisPen(QChartPrivate::defaultPen()), + m_axisBrush(QChartPrivate::defaultBrush()), m_gridLineVisible(true), + m_gridLinePen(QChartPrivate::defaultPen()), m_labelsVisible(true), + m_labelsPen(QChartPrivate::defaultPen()), + m_labelsBrush(QChartPrivate::defaultBrush()), + m_labelsFont(QChartPrivate::defaultFont()), m_labelsAngle(0), m_titleVisible(true), + m_titlePen(QChartPrivate::defaultPen()), + m_titleBrush(QChartPrivate::defaultBrush()), + m_titleFont(QChartPrivate::defaultFont()), m_shadesVisible(false), - m_shadesBrush(Qt::SolidPattern), + m_shadesBrush(QChartPrivate::defaultBrush()), + m_shadesPen(QChartPrivate::defaultPen()), m_shadesOpacity(1.0), m_dirty(false) { - } QAbstractAxisPrivate::~QAbstractAxisPrivate() @@ -912,61 +922,42 @@ void QAbstractAxisPrivate::setAlignment( Qt::Alignment alignment) void QAbstractAxisPrivate::initializeTheme(ChartTheme* theme, bool forced) { - QPen pen; - QBrush brush; - QFont font; + //TODO: introduce axis brush + if (forced || QChartPrivate::defaultPen() == m_axisPen) + q_ptr->setLinePen(theme->axisLinePen()); + + if (forced || QChartPrivate::defaultPen() == m_gridLinePen) + q_ptr->setGridLinePen(theme->girdLinePen()); + + if (forced || QChartPrivate::defaultBrush() == m_labelsBrush) + q_ptr->setLabelsBrush(theme->labelBrush()); + if (forced || QChartPrivate::defaultPen() == m_labelsPen) + q_ptr->setLabelsPen(Qt::NoPen); // NoPen for performance reasons + if (forced || QChartPrivate::defaultFont() == m_labelsFont) + q_ptr->setLabelsFont(theme->labelFont()); + + if (forced || QChartPrivate::defaultBrush() == m_titleBrush) + q_ptr->setTitleBrush(theme->labelBrush()); + if (forced || QChartPrivate::defaultPen() == m_titlePen) + q_ptr->setTitlePen(Qt::NoPen); // NoPen for performance reasons + if (forced || QChartPrivate::defaultFont() == m_titleFont) { + QFont font(m_labelsFont); + font.setBold(true); + q_ptr->setTitleFont(font); + } - bool axisX = m_orientation == Qt::Horizontal; + if (forced || QChartPrivate::defaultBrush() == m_shadesBrush) + q_ptr->setShadesBrush(theme->backgroundShadesBrush()); + if (forced || QChartPrivate::defaultPen() == m_shadesPen) + q_ptr->setShadesPen(theme->backgroundShadesPen()); - //TODO: introduce axis brush - if (m_visible) { - if (m_arrowVisible) { - if (forced || pen == m_axisPen) { - q_ptr->setLinePen(theme->axisLinePen()); - } - } - if (m_gridLineVisible) { - if (forced || pen == m_gridLinePen) { - q_ptr->setGridLinePen(theme->girdLinePen()); - } - } - if (m_labelsVisible) { - if (forced || brush == m_labelsBrush){ - q_ptr->setLabelsBrush(theme->labelBrush()); - } - if (forced || pen == m_labelsPen){ - q_ptr->setLabelsPen(Qt::NoPen);// NoPen for performance reasons - } - if (forced || font == m_labelsFont){ - q_ptr->setLabelsFont(theme->labelFont()); - } - } - if (m_titleVisible) { - if (forced || brush == m_titleBrush){ - q_ptr->setTitleBrush(theme->labelBrush()); - } - if (forced || pen == m_titlePen){ - q_ptr->setTitlePen(Qt::NoPen);// Noen for performance reasons - } - if (forced || font == m_titleFont){ - QFont font(m_labelsFont); - font.setBold(true); - q_ptr->setTitleFont(font); - } - } - if (forced || m_shadesVisible) { - if (forced || brush == m_shadesBrush){ - q_ptr->setShadesBrush(theme->backgroundShadesBrush()); - } - if (forced || pen == m_shadesPen){ - q_ptr->setShadesPen(theme->backgroundShadesPen()); - } - if (forced && (theme->backgroundShades() == ChartTheme::BackgroundShadesBoth - || (theme->backgroundShades() == ChartTheme::BackgroundShadesVertical && axisX) - || (theme->backgroundShades() == ChartTheme::BackgroundShadesHorizontal && !axisX))) { - q_ptr->setShadesVisible(true); - } - } + bool axisX = m_orientation == Qt::Horizontal; + if (forced && (theme->backgroundShades() == ChartTheme::BackgroundShadesBoth + || (theme->backgroundShades() == ChartTheme::BackgroundShadesVertical && axisX) + || (theme->backgroundShades() == ChartTheme::BackgroundShadesHorizontal && !axisX))) { + q_ptr->setShadesVisible(true); + } else if (forced) { + q_ptr->setShadesVisible(false); } } diff --git a/src/axis/qabstractaxis_p.h b/src/axis/qabstractaxis_p.h index 9ab993d..20b8a73 100644 --- a/src/axis/qabstractaxis_p.h +++ b/src/axis/qabstractaxis_p.h @@ -85,6 +85,7 @@ protected: QAbstractAxis *q_ptr; QChart *m_chart; QScopedPointer m_item; + private: QList m_series; diff --git a/src/barchart/qabstractbarseries.cpp b/src/barchart/qabstractbarseries.cpp index 51be5de..b9b026e 100644 --- a/src/barchart/qabstractbarseries.cpp +++ b/src/barchart/qabstractbarseries.cpp @@ -30,6 +30,7 @@ #include "qbarlegendmarker.h" #include "baranimation_p.h" #include "abstractbarchartitem_p.h" +#include "qchart_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -842,9 +843,6 @@ void QAbstractBarSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bo { const QList gradients = theme->seriesGradients(); - QBrush brush; - QPen pen; - qreal takeAtPos = 0.5; qreal step = 0.2; if (m_barSets.count() > 1) { @@ -864,19 +862,19 @@ void QAbstractBarSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bo takeAtPos += step; takeAtPos -= (int) takeAtPos; } - if (forced || brush == m_barSets.at(i)->brush()) + if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->brush()) m_barSets.at(i)->setBrush(ChartThemeManager::colorAt(gradients.at(colorIndex), takeAtPos)); // Pick label color from the opposite end of the gradient. // 0.3 as a boundary seems to work well. - if (forced || brush == m_barSets.at(i)->labelBrush()) { + if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->labelBrush()) { if (takeAtPos < 0.3) m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 1)); else m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0)); } - if (forced || pen == m_barSets.at(i)->pen()) { + if (forced || QChartPrivate::defaultPen() == m_barSets.at(i)->pen()) { QColor c = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0); m_barSets.at(i)->setPen(c); } diff --git a/src/barchart/qbarset.cpp b/src/barchart/qbarset.cpp index ef5b337..1ddd889 100644 --- a/src/barchart/qbarset.cpp +++ b/src/barchart/qbarset.cpp @@ -21,6 +21,7 @@ #include "qbarset.h" #include "qbarset_p.h" #include "charthelpers_p.h" +#include "qchart_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -546,7 +547,10 @@ void QBarSet::setLabelColor(QColor color) QBarSetPrivate::QBarSetPrivate(const QString label, QBarSet *parent) : QObject(parent), q_ptr(parent), - m_label(label) + m_label(label), + m_pen(QChartPrivate::defaultPen()), + m_brush(QChartPrivate::defaultBrush()), + m_labelBrush(QChartPrivate::defaultBrush()) { } diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp index 83aa8f7..782df1d 100644 --- a/src/chartpresenter.cpp +++ b/src/chartpresenter.cpp @@ -152,7 +152,8 @@ void ChartPresenter::createBackgroundItem() { if (!m_background) { m_background = new ChartBackground(rootItem()); - m_background->setPen(Qt::NoPen); + m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default + m_background->setBrush(QChartPrivate::defaultBrush()); m_background->setZValue(ChartPresenter::BackgroundZValue); } } diff --git a/src/chartthememanager.cpp b/src/chartthememanager.cpp index 68ac0e0..4c62192 100644 --- a/src/chartthememanager.cpp +++ b/src/chartthememanager.cpp @@ -41,90 +41,71 @@ ChartThemeManager::ChartThemeManager(QChart* chart) : void ChartThemeManager::setTheme(QChart::ChartTheme theme) { - if(m_theme.isNull() || theme != m_theme->id()) - { + if (m_theme.isNull() || theme != m_theme->id()) { switch (theme) { - case QChart::ChartThemeLight: + case QChart::ChartThemeLight: m_theme.reset(new ChartThemeLight()); break; - case QChart::ChartThemeBlueCerulean: + case QChart::ChartThemeBlueCerulean: m_theme.reset(new ChartThemeBlueCerulean()); break; - case QChart::ChartThemeDark: + case QChart::ChartThemeDark: m_theme.reset(new ChartThemeDark()); break; - case QChart::ChartThemeBrownSand: + case QChart::ChartThemeBrownSand: m_theme.reset(new ChartThemeBrownSand()); break; - case QChart::ChartThemeBlueNcs: + case QChart::ChartThemeBlueNcs: m_theme.reset(new ChartThemeBlueNcs()); break; - case QChart::ChartThemeHighContrast: + case QChart::ChartThemeHighContrast: m_theme.reset(new ChartThemeHighContrast()); break; - case QChart::ChartThemeBlueIcy: + case QChart::ChartThemeBlueIcy: m_theme.reset(new ChartThemeBlueIcy()); break; - default: + default: m_theme.reset(new ChartThemeSystem()); break; } - if(!m_theme.isNull()) - { - decorateChart(m_chart,m_theme.data(),true); - decorateLegend(m_chart->legend(),m_theme.data(),true); - foreach(QAbstractAxis* axis, m_axisList) { - axis->d_ptr->initializeTheme(m_theme.data(),true); - } - foreach(QAbstractSeries* series, m_seriesMap.keys()) { - series->d_ptr->initializeTheme(m_seriesMap[series],m_theme.data(),true); - } - + if (!m_theme.isNull()) { + decorateChart(m_chart,m_theme.data()); + decorateLegend(m_chart->legend(),m_theme.data()); + foreach (QAbstractAxis* axis, m_axisList) + axis->d_ptr->initializeTheme(m_theme.data(), true); + foreach (QAbstractSeries* series, m_seriesMap.keys()) + series->d_ptr->initializeTheme(m_seriesMap[series], m_theme.data(), true); } } } -void ChartThemeManager::decorateChart(QChart *chart,ChartTheme* theme,bool force) const +// decorateChart is only called when theme is forcibly initialized +void ChartThemeManager::decorateChart(QChart *chart, ChartTheme *theme) const { - QBrush brush; - - if (force || brush == chart->backgroundBrush()) - chart->setBackgroundBrush(theme->chartBackgroundGradient()); + chart->setBackgroundBrush(theme->chartBackgroundGradient()); - if (force) { - // Always clear plotArea brush when forced update, do not touch otherwise - QPen pen(Qt::transparent); - chart->setPlotAreaBackgroundBrush(brush); - chart->setPlotAreaBackgroundPen(pen); - chart->setPlotAreaBackgroundVisible(false); - } + QPen pen(Qt::transparent); + QBrush brush; + chart->setPlotAreaBackgroundBrush(brush); + chart->setPlotAreaBackgroundPen(pen); + chart->setPlotAreaBackgroundVisible(false); chart->setTitleFont(theme->masterFont()); chart->setTitleBrush(theme->labelBrush()); chart->setDropShadowEnabled(theme->isBackgroundDropShadowEnabled()); } -void ChartThemeManager::decorateLegend(QLegend *legend, ChartTheme* theme, bool force) const +// decorateLegend is only called when theme is forcibly initialized +void ChartThemeManager::decorateLegend(QLegend *legend, ChartTheme *theme) const { - QPen pen; - QBrush brush; - QFont font; - - if (force || pen == legend->pen()) - legend->setPen(theme->axisLinePen()); - - if (force || brush == legend->brush()) - legend->setBrush(theme->chartBackgroundGradient()); - - if (force || font == legend->font()) - legend->setFont(theme->labelFont()); - - if (force || brush == legend->labelBrush()) - legend->setLabelBrush(theme->labelBrush()); + legend->setPen(theme->axisLinePen()); + legend->setBrush(theme->chartBackgroundGradient()); + legend->setFont(theme->labelFont()); + legend->setLabelBrush(theme->labelBrush()); } -int ChartThemeManager::createIndexKey(QList keys) const +int ChartThemeManager::createIndexKey(QList keys) const { qSort(keys); diff --git a/src/chartthememanager_p.h b/src/chartthememanager_p.h index ee947d5..349521e 100644 --- a/src/chartthememanager_p.h +++ b/src/chartthememanager_p.h @@ -53,8 +53,8 @@ public: explicit ChartThemeManager(QChart* chart); void setTheme(QChart::ChartTheme theme); ChartTheme* theme() const { return m_theme.data(); } - void decorateChart(QChart *chart, ChartTheme* theme, bool force = false) const; - void decorateLegend(QLegend *legend, ChartTheme* theme, bool force = false) const; + void decorateChart(QChart *chart, ChartTheme* theme) const; + void decorateLegend(QLegend *legend, ChartTheme* theme) const; void updateSeries(QAbstractSeries *series); public: diff --git a/src/linechart/qlineseries.cpp b/src/linechart/qlineseries.cpp index 76cedd4..faabffe 100644 --- a/src/linechart/qlineseries.cpp +++ b/src/linechart/qlineseries.cpp @@ -23,7 +23,7 @@ #include "linechartitem_p.h" #include "chartdataset_p.h" #include "charttheme_p.h" - +#include "qchart_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE /*! @@ -149,8 +149,8 @@ void QLineSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forc Q_Q(QLineSeries); const QList colors = theme->seriesColors(); - QPen pen; - if (forced || pen == m_pen) { + if (forced || QChartPrivate::defaultPen() == m_pen) { + QPen pen; pen.setColor(colors.at(index % colors.size())); pen.setWidthF(2); q->setPen(pen); diff --git a/src/qchart.cpp b/src/qchart.cpp index 0948054..4906cf1 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -687,6 +687,36 @@ QChartPrivate::~QChartPrivate() { } +// Hackish solution to the problem of explicitly assigning the default pen/brush/font +// to a series or axis and having theme override it: +// Initialize pens, brushes, and fonts to something nobody is likely to ever use, +// so that default theme initialization will always set these properly. +QPen &QChartPrivate::defaultPen() +{ + static QPen *defaultPen = 0; + if (!defaultPen) + defaultPen = new QPen(QColor(1, 2, 0), 0.93247536); + return *defaultPen; +} + +QBrush &QChartPrivate::defaultBrush() +{ + static QBrush *defaultBrush = 0; + if (!defaultBrush) + defaultBrush = new QBrush(QColor(1, 2, 0), Qt::Dense7Pattern); + return *defaultBrush; +} + +QFont &QChartPrivate::defaultFont() +{ + static QFont *defaultFont = 0; + if (!defaultFont) { + defaultFont = new QFont(); + defaultFont->setPointSizeF(8.34563465); + } + return *defaultFont; +} + void QChartPrivate::init() { m_legend = new LegendScroller(q_ptr); diff --git a/src/qchart_p.h b/src/qchart_p.h index e715bc6..e8a4be3 100644 --- a/src/qchart_p.h +++ b/src/qchart_p.h @@ -53,6 +53,10 @@ public: ChartThemeManager *m_themeManager; QChart::ChartType m_type; + static QPen &defaultPen(); + static QBrush &defaultBrush(); + static QFont &defaultFont(); + void init(); void zoomIn(qreal factor); void zoomOut(qreal factor); diff --git a/src/scatterchart/qscatterseries.cpp b/src/scatterchart/qscatterseries.cpp index e9605f4..2468529 100644 --- a/src/scatterchart/qscatterseries.cpp +++ b/src/scatterchart/qscatterseries.cpp @@ -24,6 +24,7 @@ #include "chartdataset_p.h" #include "charttheme_p.h" #include "scatteranimation_p.h" +#include "qchart_p.h" /*! \class QScatterSeries @@ -266,18 +267,17 @@ void QScatterSeriesPrivate::initializeGraphics(QGraphicsItem* parent) void QScatterSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced) { Q_Q(QScatterSeries); - QPen pen; - QBrush brush; const QList colors = theme->seriesColors(); const QList gradients = theme->seriesGradients(); - if (forced || pen == m_pen) { + if (forced || QChartPrivate::defaultPen() == m_pen) { + QPen pen; pen.setColor(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0)); pen.setWidthF(2); q->setPen(pen); } - if (forced || brush == m_brush) { + if (forced || QChartPrivate::defaultBrush() == m_brush) { QBrush brush(colors.at(index % colors.size())); q->setBrush(brush); } diff --git a/src/splinechart/qsplineseries.cpp b/src/splinechart/qsplineseries.cpp index bcf9507..7c55b10 100644 --- a/src/splinechart/qsplineseries.cpp +++ b/src/splinechart/qsplineseries.cpp @@ -24,6 +24,7 @@ #include "chartdataset_p.h" #include "charttheme_p.h" #include "splineanimation_p.h" +#include "qchart_p.h" /*! \class QSplineSeries @@ -126,8 +127,8 @@ void QSplineSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool fo Q_Q(QSplineSeries); const QList colors = theme->seriesColors(); - QPen pen; - if (forced || pen == m_pen) { + if (forced || QChartPrivate::defaultPen() == m_pen) { + QPen pen; pen.setColor(colors.at(index % colors.size())); pen.setWidthF(2); q->setPen(pen); diff --git a/src/themes/charttheme_p.h b/src/themes/charttheme_p.h index 71b8208..1f27d30 100644 --- a/src/themes/charttheme_p.h +++ b/src/themes/charttheme_p.h @@ -49,8 +49,10 @@ public: protected: explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeLight):m_id(id), - m_backgroundShades(BackgroundShadesNone), - m_backgroundDropShadowEnabled(false){}; + m_backgroundShades(BackgroundShadesNone), + m_backgroundShadesBrush(Qt::SolidPattern), + m_backgroundDropShadowEnabled(false) + {}; public: QChart::ChartTheme id() const { return m_id; } QList seriesGradients() const { return m_seriesGradients; } diff --git a/src/xychart/qxyseries.cpp b/src/xychart/qxyseries.cpp index 2ddb835..0eb4490 100644 --- a/src/xychart/qxyseries.cpp +++ b/src/xychart/qxyseries.cpp @@ -25,6 +25,7 @@ #include "xychart_p.h" #include "qxylegendmarker.h" #include "charthelpers_p.h" +#include "qchart_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -511,6 +512,8 @@ QXYSeries &QXYSeries::operator<< (const QList& points) QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q), + m_pen(QChartPrivate::defaultPen()), + m_brush(QChartPrivate::defaultBrush()), m_pointsVisible(false) { }