File indexing completed on 2024-05-12 03:48:18
0001 /* 0002 File : Background.cpp 0003 Project : LabPlot 0004 Description : Background 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2022 Alexander Semke <alexander.semke@web.de> 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 /*! 0011 \class Background 0012 \brief This class contains the background properties of worksheet elements like worksheet background, 0013 plot background, the area filling in XYCurve, Histogram, etc. 0014 0015 \ingroup worksheet 0016 */ 0017 0018 #include "Background.h" 0019 #include "BackgroundPrivate.h" 0020 #include "backend/lib/XmlStreamReader.h" 0021 #include "backend/lib/commandtemplates.h" 0022 0023 #include <KConfigGroup> 0024 #include <KLocalizedString> 0025 0026 Background::Background(const QString& name) 0027 : AbstractAspect(name, AspectType::AbstractAspect) 0028 , d_ptr(new BackgroundPrivate(this)) { 0029 } 0030 0031 Background::~Background() { 0032 delete d_ptr; 0033 } 0034 0035 void Background::setPrefix(const QString& prefix) { 0036 Q_D(Background); 0037 d->prefix = prefix; 0038 } 0039 0040 const QString& Background::prefix() const { 0041 Q_D(const Background); 0042 return d->prefix; 0043 } 0044 0045 void Background::init(const KConfigGroup& group) { 0046 Q_D(Background); 0047 0048 d->type = (Type)group.readEntry(d->prefix + QStringLiteral("Type"), static_cast<int>(Type::Color)); 0049 d->colorStyle = (ColorStyle)group.readEntry(d->prefix + QStringLiteral("ColorStyle"), static_cast<int>(ColorStyle::SingleColor)); 0050 d->imageStyle = (ImageStyle)group.readEntry(d->prefix + QStringLiteral("ImageStyle"), static_cast<int>(ImageStyle::Scaled)); 0051 d->brushStyle = (Qt::BrushStyle)group.readEntry(d->prefix + QStringLiteral("BrushStyle"), static_cast<int>(Qt::SolidPattern)); 0052 d->fileName = group.readEntry(d->prefix + QStringLiteral("FileName"), QString()); 0053 d->firstColor = group.readEntry(d->prefix + QStringLiteral("FirstColor"), QColor(Qt::white)); 0054 d->secondColor = group.readEntry(d->prefix + QStringLiteral("SecondColor"), QColor(Qt::black)); 0055 0056 double defaultOpacity = 1.0; 0057 auto type = parentAspect()->type(); 0058 if (type == AspectType::Histogram || type == AspectType::BoxPlot) 0059 defaultOpacity = 0.5; 0060 d->opacity = group.readEntry(d->prefix + QStringLiteral("Opacity"), defaultOpacity); 0061 0062 // optional parameters 0063 if (d->enabledAvailable) 0064 d->enabled = group.readEntry(d->prefix + QStringLiteral("Enabled"), true); 0065 0066 if (d->positionAvailable) 0067 d->position = (Position)group.readEntry(d->prefix + QStringLiteral("Position"), static_cast<int>(Position::No)); 0068 } 0069 0070 // ############################################################################## 0071 // ########################## getter methods ################################## 0072 // ############################################################################## 0073 BASIC_SHARED_D_READER_IMPL(Background, bool, enabledAvailable, enabledAvailable) 0074 BASIC_SHARED_D_READER_IMPL(Background, bool, positionAvailable, positionAvailable) 0075 0076 BASIC_SHARED_D_READER_IMPL(Background, bool, enabled, enabled) 0077 BASIC_SHARED_D_READER_IMPL(Background, Background::Position, position, position) 0078 BASIC_SHARED_D_READER_IMPL(Background, Background::Type, type, type) 0079 BASIC_SHARED_D_READER_IMPL(Background, Background::ColorStyle, colorStyle, colorStyle) 0080 BASIC_SHARED_D_READER_IMPL(Background, Background::ImageStyle, imageStyle, imageStyle) 0081 BASIC_SHARED_D_READER_IMPL(Background, Qt::BrushStyle, brushStyle, brushStyle) 0082 BASIC_SHARED_D_READER_IMPL(Background, QColor, firstColor, firstColor) 0083 BASIC_SHARED_D_READER_IMPL(Background, QColor, secondColor, secondColor) 0084 BASIC_SHARED_D_READER_IMPL(Background, QString, fileName, fileName) 0085 BASIC_SHARED_D_READER_IMPL(Background, double, opacity, opacity) 0086 0087 // ############################################################################## 0088 // ################# setter methods and undo commands ########################## 0089 // ############################################################################## 0090 void Background::setEnabledAvailable(bool available) { 0091 Q_D(Background); 0092 d->enabledAvailable = available; 0093 } 0094 0095 void Background::setPositionAvailable(bool available) { 0096 Q_D(Background); 0097 d->positionAvailable = available; 0098 } 0099 0100 STD_SETTER_CMD_IMPL_F_S(Background, SetEnabled, bool, enabled, update) 0101 void Background::setEnabled(bool enabled) { 0102 Q_D(Background); 0103 if (enabled != d->enabled) 0104 exec(new BackgroundSetEnabledCmd(d, enabled, ki18n("%1: filling changed"))); 0105 } 0106 0107 STD_SETTER_CMD_IMPL_F_S(Background, SetPosition, Background::Position, position, updatePosition) 0108 void Background::setPosition(Position position) { 0109 Q_D(Background); 0110 if (position != d->position) 0111 exec(new BackgroundSetPositionCmd(d, position, ki18n("%1: filling position changed"))); 0112 } 0113 0114 STD_SETTER_CMD_IMPL_F_S(Background, SetType, Background::Type, type, update) 0115 void Background::setType(Background::Type type) { 0116 Q_D(Background); 0117 if (type != d->type) 0118 exec(new BackgroundSetTypeCmd(d, type, ki18n("%1: background type changed"))); 0119 } 0120 0121 STD_SETTER_CMD_IMPL_F_S(Background, SetColorStyle, Background::ColorStyle, colorStyle, update) 0122 void Background::setColorStyle(Background::ColorStyle style) { 0123 Q_D(Background); 0124 if (style != d->colorStyle) 0125 exec(new BackgroundSetColorStyleCmd(d, style, ki18n("%1: background color style changed"))); 0126 } 0127 0128 STD_SETTER_CMD_IMPL_F_S(Background, SetImageStyle, Background::ImageStyle, imageStyle, update) 0129 void Background::setImageStyle(Background::ImageStyle style) { 0130 Q_D(Background); 0131 if (style != d->imageStyle) 0132 exec(new BackgroundSetImageStyleCmd(d, style, ki18n("%1: background image style changed"))); 0133 } 0134 0135 STD_SETTER_CMD_IMPL_F_S(Background, SetBrushStyle, Qt::BrushStyle, brushStyle, update) 0136 void Background::setBrushStyle(Qt::BrushStyle style) { 0137 Q_D(Background); 0138 if (style != d->brushStyle) 0139 exec(new BackgroundSetBrushStyleCmd(d, style, ki18n("%1: background brush style changed"))); 0140 } 0141 0142 STD_SETTER_CMD_IMPL_F_S(Background, SetFirstColor, QColor, firstColor, update) 0143 void Background::setFirstColor(const QColor& color) { 0144 Q_D(Background); 0145 if (color != d->firstColor) 0146 exec(new BackgroundSetFirstColorCmd(d, color, ki18n("%1: set background first color"))); 0147 } 0148 0149 STD_SETTER_CMD_IMPL_F_S(Background, SetSecondColor, QColor, secondColor, update) 0150 void Background::setSecondColor(const QColor& color) { 0151 Q_D(Background); 0152 if (color != d->secondColor) 0153 exec(new BackgroundSetSecondColorCmd(d, color, ki18n("%1: set background second color"))); 0154 } 0155 0156 STD_SETTER_CMD_IMPL_F_S(Background, SetFileName, QString, fileName, update) 0157 void Background::setFileName(const QString& fileName) { 0158 Q_D(Background); 0159 if (fileName != d->fileName) 0160 exec(new BackgroundSetFileNameCmd(d, fileName, ki18n("%1: set background image"))); 0161 } 0162 0163 STD_SETTER_CMD_IMPL_F_S(Background, SetOpacity, double, opacity, update) 0164 void Background::setOpacity(double opacity) { 0165 Q_D(Background); 0166 if (opacity != d->opacity) 0167 exec(new BackgroundSetOpacityCmd(d, opacity, ki18n("%1: set background opacity"))); 0168 } 0169 0170 // ############################################################################## 0171 // ####################### Private implementation ############################### 0172 // ############################################################################## 0173 BackgroundPrivate::BackgroundPrivate(Background* owner) 0174 : q(owner) { 0175 } 0176 0177 QString BackgroundPrivate::name() const { 0178 return q->parentAspect()->name(); 0179 } 0180 0181 void BackgroundPrivate::update() { 0182 Q_EMIT q->updateRequested(); 0183 } 0184 0185 void BackgroundPrivate::updatePosition() { 0186 Q_EMIT q->updatePositionRequested(); 0187 } 0188 0189 // ############################################################################## 0190 // ################## Serialization/Deserialization ########################### 0191 // ############################################################################## 0192 //! Save as XML 0193 void Background::save(QXmlStreamWriter* writer) const { 0194 Q_D(const Background); 0195 0196 writer->writeStartElement(d->prefix.toLower()); 0197 if (d->enabledAvailable) 0198 writer->writeAttribute(QStringLiteral("enabled"), QString::number(d->enabled)); 0199 0200 if (d->positionAvailable) 0201 writer->writeAttribute(QStringLiteral("position"), QString::number(static_cast<int>(d->position))); 0202 0203 writer->writeAttribute(QStringLiteral("type"), QString::number(static_cast<int>(d->type))); 0204 writer->writeAttribute(QStringLiteral("colorStyle"), QString::number(static_cast<int>(d->colorStyle))); 0205 writer->writeAttribute(QStringLiteral("imageStyle"), QString::number(static_cast<int>(d->imageStyle))); 0206 writer->writeAttribute(QStringLiteral("brushStyle"), QString::number(d->brushStyle)); 0207 writer->writeAttribute(QStringLiteral("firstColor_r"), QString::number(d->firstColor.red())); 0208 writer->writeAttribute(QStringLiteral("firstColor_g"), QString::number(d->firstColor.green())); 0209 writer->writeAttribute(QStringLiteral("firstColor_b"), QString::number(d->firstColor.blue())); 0210 writer->writeAttribute(QStringLiteral("secondColor_r"), QString::number(d->secondColor.red())); 0211 writer->writeAttribute(QStringLiteral("secondColor_g"), QString::number(d->secondColor.green())); 0212 writer->writeAttribute(QStringLiteral("secondColor_b"), QString::number(d->secondColor.blue())); 0213 writer->writeAttribute(QStringLiteral("fileName"), d->fileName); 0214 writer->writeAttribute(QStringLiteral("opacity"), QString::number(d->opacity)); 0215 writer->writeEndElement(); 0216 } 0217 0218 //! Load from XML 0219 bool Background::load(XmlStreamReader* reader, bool preview) { 0220 if (preview) 0221 return true; 0222 0223 Q_D(Background); 0224 QString str; 0225 0226 auto attribs = reader->attributes(); 0227 0228 if (d->enabledAvailable) 0229 READ_INT_VALUE("enabled", enabled, bool); 0230 0231 if (d->positionAvailable) 0232 READ_INT_VALUE("position", position, Position); 0233 0234 READ_INT_VALUE("type", type, Background::Type); 0235 READ_INT_VALUE("colorStyle", colorStyle, Background::ColorStyle); 0236 READ_INT_VALUE("imageStyle", imageStyle, Background::ImageStyle); 0237 READ_INT_VALUE("brushStyle", brushStyle, Qt::BrushStyle); 0238 0239 str = attribs.value(QStringLiteral("firstColor_r")).toString(); 0240 if (str.isEmpty()) 0241 reader->raiseMissingAttributeWarning(QStringLiteral("firstColor_r")); 0242 else 0243 d->firstColor.setRed(str.toInt()); 0244 0245 str = attribs.value(QStringLiteral("firstColor_g")).toString(); 0246 if (str.isEmpty()) 0247 reader->raiseMissingAttributeWarning(QStringLiteral("firstColor_g")); 0248 else 0249 d->firstColor.setGreen(str.toInt()); 0250 0251 str = attribs.value(QStringLiteral("firstColor_b")).toString(); 0252 if (str.isEmpty()) 0253 reader->raiseMissingAttributeWarning(QStringLiteral("firstColor_b")); 0254 else 0255 d->firstColor.setBlue(str.toInt()); 0256 0257 str = attribs.value(QStringLiteral("secondColor_r")).toString(); 0258 if (str.isEmpty()) 0259 reader->raiseMissingAttributeWarning(QStringLiteral("secondColor_r")); 0260 else 0261 d->secondColor.setRed(str.toInt()); 0262 0263 str = attribs.value(QStringLiteral("secondColor_g")).toString(); 0264 if (str.isEmpty()) 0265 reader->raiseMissingAttributeWarning(QStringLiteral("secondColor_g")); 0266 else 0267 d->secondColor.setGreen(str.toInt()); 0268 0269 str = attribs.value(QStringLiteral("secondColor_b")).toString(); 0270 if (str.isEmpty()) 0271 reader->raiseMissingAttributeWarning(QStringLiteral("secondColor_b")); 0272 else 0273 d->secondColor.setBlue(str.toInt()); 0274 0275 str = attribs.value(QStringLiteral("fileName")).toString(); 0276 d->fileName = str; 0277 0278 READ_DOUBLE_VALUE("opacity", opacity); 0279 0280 return true; 0281 } 0282 0283 // ############################################################################## 0284 // ######################### Theme management ################################## 0285 // ############################################################################## 0286 void Background::loadThemeConfig(const KConfigGroup& group) { 0287 Q_D(const Background); 0288 const QColor themeColor = group.readEntry(d->prefix + QStringLiteral("FirstColor"), QColor(Qt::white)); 0289 loadThemeConfig(group, themeColor); 0290 } 0291 0292 void Background::loadThemeConfig(const KConfigGroup& group, const QColor& themeColor) { 0293 Q_D(const Background); 0294 0295 if (d->positionAvailable) 0296 setPosition((Position)group.readEntry(d->prefix + QStringLiteral("Position"), static_cast<int>(Position::No))); 0297 0298 setType((Type)group.readEntry(d->prefix + QStringLiteral("Type"), static_cast<int>(Type::Color))); 0299 setColorStyle((ColorStyle)group.readEntry(d->prefix + QStringLiteral("ColorStyle"), static_cast<int>(ColorStyle::SingleColor))); 0300 setImageStyle((ImageStyle)group.readEntry(d->prefix + QStringLiteral("ImageStyle"), static_cast<int>(ImageStyle::Scaled))); 0301 setBrushStyle((Qt::BrushStyle)group.readEntry(d->prefix + QStringLiteral("BrushStyle"), static_cast<int>(Qt::SolidPattern))); 0302 setFirstColor(themeColor); 0303 setSecondColor(group.readEntry(d->prefix + QStringLiteral("SecondColor"), QColor(Qt::black))); 0304 0305 double defaultOpacity = 1.0; 0306 auto type = parentAspect()->type(); 0307 if (type == AspectType::Histogram || type == AspectType::BoxPlot || type == AspectType::BarPlot) 0308 defaultOpacity = 0.8; 0309 setOpacity(group.readEntry(d->prefix + QStringLiteral("Opacity"), defaultOpacity)); 0310 } 0311 0312 void Background::saveThemeConfig(KConfigGroup& group) const { 0313 Q_D(const Background); 0314 0315 if (d->positionAvailable) 0316 group.writeEntry(d->prefix + QStringLiteral("Position"), static_cast<int>(d->position)); 0317 0318 group.writeEntry(d->prefix + QStringLiteral("Type"), static_cast<int>(d->type)); 0319 group.writeEntry(d->prefix + QStringLiteral("ColorStyle"), static_cast<int>(d->colorStyle)); 0320 group.writeEntry(d->prefix + QStringLiteral("BrushStyle"), static_cast<int>(d->brushStyle)); 0321 group.writeEntry(d->prefix + QStringLiteral("ImageStyle"), static_cast<int>(d->imageStyle)); 0322 group.writeEntry(d->prefix + QStringLiteral("FirstColor"), d->firstColor); 0323 group.writeEntry(d->prefix + QStringLiteral("SecondColor"), d->secondColor); 0324 group.writeEntry(d->prefix + QStringLiteral("Opacity"), d->opacity); 0325 }