File indexing completed on 2024-04-28 16:21:32
0001 /* This file is part of the KDE project 0002 Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org> 0003 Copyright 2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net> 0004 Copyright 2003 Norbert Andres <nandres@web.de> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 Boston, MA 02110-1301, USA. 0020 */ 0021 0022 // Local 0023 #include "Style.h" 0024 0025 #include <QBrush> 0026 #include <QHash> 0027 #include <QPen> 0028 #include <QFontDatabase> 0029 0030 #include <KoGlobal.h> 0031 0032 #include "SheetsDebug.h" 0033 #include "Currency.h" 0034 #include "Global.h" 0035 #include "StyleManager.h" 0036 #include "Util.h" 0037 0038 using namespace Calligra::Sheets; 0039 0040 ///////////////////////////////////////////////////////////////////////////// 0041 // 0042 // SubStyles 0043 // 0044 ///////////////////////////////////////////////////////////////////////////// 0045 0046 namespace Calligra 0047 { 0048 namespace Sheets 0049 { 0050 0051 static uint calculateValue(QPen const & pen) 0052 { 0053 uint n = pen.color().red() + pen.color().green() + pen.color().blue(); 0054 n += 1000 * pen.width(); 0055 n += 10000 * (uint) pen.style(); 0056 return n; 0057 } 0058 0059 // specialized debug method 0060 template<> 0061 QString SubStyleOne<Style::CurrencyFormat, Currency>::debugData(bool withName) const 0062 { 0063 QString out; if (withName) out = name(Style::CurrencyFormat) + ' '; QDebug qdbg(&out); qdbg << value1.symbol(); return out; 0064 } 0065 0066 template<Style::Key key> 0067 class PenStyle : public SubStyleOne<key, QPen> 0068 { 0069 public: 0070 PenStyle(const QPen& p = Qt::NoPen) : SubStyleOne<key, QPen>(p) {} 0071 }; 0072 0073 template<Style::Key key> 0074 class BorderPenStyle : public PenStyle<key> 0075 { 0076 public: 0077 BorderPenStyle(const QPen& p = Qt::NoPen) : PenStyle<key>(p), value(calculateValue(p)) {} 0078 int value; 0079 }; 0080 0081 QString SubStyle::name(Style::Key key) 0082 { 0083 QString name; 0084 switch (key) { 0085 case Style::DefaultStyleKey: name = "Default style"; break; 0086 case Style::NamedStyleKey: name = "Named style"; break; 0087 case Style::LeftPen: name = "Left pen"; break; 0088 case Style::RightPen: name = "Right pen"; break; 0089 case Style::TopPen: name = "Top pen"; break; 0090 case Style::BottomPen: name = "Bottom pen"; break; 0091 case Style::FallDiagonalPen: name = "Fall diagonal pen"; break; 0092 case Style::GoUpDiagonalPen: name = "Go up diagonal pen"; break; 0093 case Style::HorizontalAlignment: name = "Horz. alignment"; break; 0094 case Style::VerticalAlignment: name = "Vert. alignment"; break; 0095 case Style::MultiRow: name = "Wrap text"; break; 0096 case Style::VerticalText: name = "Vertical text"; break; 0097 case Style::Angle: name = "Angle"; break; 0098 case Style::Indentation: name = "Indentation"; break; 0099 case Style::ShrinkToFit: name = "Shrink to Fit"; break; 0100 case Style::Prefix: name = "Prefix"; break; 0101 case Style::Postfix: name = "Postfix"; break; 0102 case Style::Precision: name = "Precision"; break; 0103 case Style::ThousandsSep: name = "Thousands separator"; break; 0104 case Style::FormatTypeKey: name = "Format type"; break; 0105 case Style::FloatFormatKey: name = "Float format"; break; 0106 case Style::FloatColorKey: name = "Float color"; break; 0107 case Style::CurrencyFormat: name = "Currency"; break; 0108 case Style::CustomFormat: name = "Custom format"; break; 0109 case Style::BackgroundBrush: name = "Background brush"; break; 0110 case Style::BackgroundColor: name = "Background color"; break; 0111 case Style::FontColor: name = "Font color"; break; 0112 case Style::FontFamily: name = "Font family"; break; 0113 case Style::FontSize: name = "Font size"; break; 0114 case Style::FontBold: name = "Font bold"; break; 0115 case Style::FontItalic: name = "Font italic"; break; 0116 case Style::FontStrike: name = "Font strikeout"; break; 0117 case Style::FontUnderline: name = "Font underline"; break; 0118 case Style::DontPrintText: name = "Do not print text"; break; 0119 case Style::NotProtected: name = "Not protected"; break; 0120 case Style::HideAll: name = "Hide all"; break; 0121 case Style::HideFormula: name = "Hide formula"; break; 0122 } 0123 return name; 0124 } 0125 0126 SharedSubStyle SharedSubStyle::s_defaultStyle(new SubStyle()); 0127 0128 } // namespace Sheets 0129 } // namespace Calligra 0130 0131 ///////////////////////////////////////////////////////////////////////////// 0132 // 0133 // Style::Private 0134 // 0135 ///////////////////////////////////////////////////////////////////////////// 0136 0137 class Q_DECL_HIDDEN Style::Private : public QSharedData 0138 { 0139 public: 0140 QHash<Key, SharedSubStyle> subStyles; 0141 }; 0142 0143 0144 ///////////////////////////////////////////////////////////////////////////// 0145 // 0146 // Style 0147 // 0148 ///////////////////////////////////////////////////////////////////////////// 0149 0150 Style::Style() 0151 : d(new Private) 0152 { 0153 } 0154 0155 Style::Style(const Style& style) 0156 : d(style.d) 0157 { 0158 } 0159 0160 Style::~Style() 0161 { 0162 } 0163 0164 Style::StyleType Style::type() const 0165 { 0166 return AUTO; 0167 } 0168 0169 QString Style::parentName() const 0170 { 0171 if (!d->subStyles.contains(NamedStyleKey)) 0172 return QString(); 0173 return static_cast<const NamedStyle*>(d->subStyles[NamedStyleKey].data())->name; 0174 } 0175 0176 void Style::setParentName(const QString& name) 0177 { 0178 d->subStyles.insert(NamedStyleKey, SharedSubStyle(new NamedStyle(name))); 0179 } 0180 0181 void Style::clearAttribute(Key key) 0182 { 0183 d->subStyles.remove(key); 0184 } 0185 0186 bool Style::hasAttribute(Key key) const 0187 { 0188 return d->subStyles.contains(key); 0189 } 0190 0191 0192 void Style::saveXML(QDomDocument& doc, QDomElement& format, const StyleManager* styleManager) const 0193 { 0194 // list of substyles to store 0195 QSet<Key> keysToStore; 0196 0197 if (d->subStyles.contains(NamedStyleKey)) { 0198 const CustomStyle* namedStyle = styleManager->style(parentName()); 0199 // check, if it's an unmodified named style 0200 keysToStore = difference(*namedStyle); 0201 if (type() == AUTO) { 0202 const QList<Key> keys = keysToStore.toList(); 0203 if ((keysToStore.count() == 0) || 0204 (keysToStore.count() == 1 && keysToStore.toList().first() == NamedStyleKey)) { 0205 // just save the name and we are done. 0206 format.setAttribute("style-name", parentName()); 0207 return; 0208 } else 0209 format.setAttribute("parent", parentName()); 0210 } else { // custom style 0211 if (d->subStyles.contains(NamedStyleKey)) 0212 format.setAttribute("parent", parentName()); 0213 } 0214 } else 0215 keysToStore = QSet<Key>::fromList(d->subStyles.keys()); 0216 0217 if (keysToStore.contains(HorizontalAlignment) && halign() != HAlignUndefined) 0218 format.setAttribute(type() == AUTO ? "align" : "alignX", (int) halign()); 0219 0220 if (keysToStore.contains(VerticalAlignment) && valign() != VAlignUndefined) 0221 format.setAttribute("alignY", QString::number((int) valign())); 0222 0223 if (keysToStore.contains(BackgroundColor) && backgroundColor().isValid()) 0224 format.setAttribute("bgcolor", backgroundColor().name()); 0225 0226 if (keysToStore.contains(MultiRow) && wrapText()) 0227 format.setAttribute("multirow", "yes"); 0228 0229 if (keysToStore.contains(VerticalText) && verticalText()) 0230 format.setAttribute("verticaltext", "yes"); 0231 0232 if (keysToStore.contains(ShrinkToFit) && shrinkToFit()) 0233 format.setAttribute("shrinktofit", "yes"); 0234 0235 if (keysToStore.contains(Precision)) 0236 format.setAttribute("precision", QString::number(precision())); 0237 0238 if (keysToStore.contains(Prefix) && !prefix().isEmpty()) 0239 format.setAttribute("prefix", prefix()); 0240 0241 if (keysToStore.contains(Postfix) && !postfix().isEmpty()) 0242 format.setAttribute("postfix", postfix()); 0243 0244 if (keysToStore.contains(FloatFormatKey)) 0245 format.setAttribute("float", QString::number((int) floatFormat())); 0246 0247 if (keysToStore.contains(FloatColorKey)) 0248 format.setAttribute("floatcolor", QString::number((int)floatColor())); 0249 0250 if (keysToStore.contains(FormatTypeKey)) 0251 format.setAttribute("format", QString::number((int) formatType())); 0252 0253 if (keysToStore.contains(CustomFormat) && !customFormat().isEmpty()) 0254 format.setAttribute("custom", customFormat()); 0255 0256 if (keysToStore.contains(FormatTypeKey) && formatType() == Format::Money) { 0257 format.setAttribute("type", (int) currency().index()); 0258 format.setAttribute("symbol", currency().symbol()); 0259 } 0260 0261 if (keysToStore.contains(Angle)) 0262 format.setAttribute("angle", QString::number(angle())); 0263 0264 if (keysToStore.contains(Indentation)) 0265 format.setAttribute("indent", QString::number(indentation())); 0266 0267 if (keysToStore.contains(DontPrintText)) 0268 format.setAttribute("dontprinttext", printText() ? "no" : "yes"); 0269 0270 if (keysToStore.contains(NotProtected)) 0271 format.setAttribute("noprotection", notProtected() ? "yes" : "no"); 0272 0273 if (keysToStore.contains(HideAll)) 0274 format.setAttribute("hideall", hideAll() ? "yes" : "no"); 0275 0276 if (keysToStore.contains(HideFormula)) 0277 format.setAttribute("hideformula", hideFormula() ? "yes" : "no"); 0278 0279 if (type() == AUTO) { 0280 if (keysToStore.contains(FontFamily) || 0281 keysToStore.contains(FontSize) || 0282 keysToStore.contains(FontBold) || 0283 keysToStore.contains(FontItalic) || 0284 keysToStore.contains(FontStrike) || 0285 keysToStore.contains(FontUnderline)) { 0286 format.appendChild(NativeFormat::createElement("font", font(), doc)); 0287 } 0288 } else { // custom style 0289 if (keysToStore.contains(FontFamily)) 0290 format.setAttribute("font-family", fontFamily()); 0291 if (keysToStore.contains(FontSize)) 0292 format.setAttribute("font-size", QString::number(fontSize())); 0293 if (keysToStore.contains(FontBold) || keysToStore.contains(FontItalic) || 0294 keysToStore.contains(FontUnderline) || keysToStore.contains(FontStrike)) { 0295 enum FontFlags { 0296 FBold = 0x01, 0297 FUnderline = 0x02, 0298 FItalic = 0x04, 0299 FStrike = 0x08 0300 }; 0301 int fontFlags = 0; 0302 fontFlags |= bold() ? FBold : 0; 0303 fontFlags |= italic() ? FItalic : 0; 0304 fontFlags |= underline() ? FUnderline : 0; 0305 fontFlags |= strikeOut() ? FStrike : 0; 0306 format.setAttribute("font-flags", QString::number(fontFlags)); 0307 } 0308 } 0309 0310 if (keysToStore.contains(FontColor) && fontColor().isValid()) 0311 format.appendChild(NativeFormat::createElement("pen", fontColor(), doc)); 0312 0313 if (keysToStore.contains(BackgroundBrush)) { 0314 format.setAttribute("brushcolor", backgroundBrush().color().name()); 0315 format.setAttribute("brushstyle", QString::number((int) backgroundBrush().style())); 0316 } 0317 0318 if (keysToStore.contains(LeftPen)) { 0319 QDomElement left = doc.createElement("left-border"); 0320 left.appendChild(NativeFormat::createElement("pen", leftBorderPen(), doc)); 0321 format.appendChild(left); 0322 } 0323 0324 if (keysToStore.contains(TopPen)) { 0325 QDomElement top = doc.createElement("top-border"); 0326 top.appendChild(NativeFormat::createElement("pen", topBorderPen(), doc)); 0327 format.appendChild(top); 0328 } 0329 0330 if (keysToStore.contains(RightPen)) { 0331 QDomElement right = doc.createElement("right-border"); 0332 right.appendChild(NativeFormat::createElement("pen", rightBorderPen(), doc)); 0333 format.appendChild(right); 0334 } 0335 0336 if (keysToStore.contains(BottomPen)) { 0337 QDomElement bottom = doc.createElement("bottom-border"); 0338 bottom.appendChild(NativeFormat::createElement("pen", bottomBorderPen(), doc)); 0339 format.appendChild(bottom); 0340 } 0341 0342 if (keysToStore.contains(FallDiagonalPen)) { 0343 QDomElement fallDiagonal = doc.createElement("fall-diagonal"); 0344 fallDiagonal.appendChild(NativeFormat::createElement("pen", fallDiagonalPen(), doc)); 0345 format.appendChild(fallDiagonal); 0346 } 0347 0348 if (keysToStore.contains(GoUpDiagonalPen)) { 0349 QDomElement goUpDiagonal = doc.createElement("up-diagonal"); 0350 goUpDiagonal.appendChild(NativeFormat::createElement("pen", goUpDiagonalPen(), doc)); 0351 format.appendChild(goUpDiagonal); 0352 } 0353 } 0354 0355 bool Style::loadXML(KoXmlElement& format, Paste::Mode mode) 0356 { 0357 if (format.hasAttribute("style-name")) { 0358 // Simply set the style name and we are done. 0359 insertSubStyle(NamedStyleKey, format.attribute("style-name")); 0360 return true; 0361 } else if (format.hasAttribute("parent")) 0362 insertSubStyle(NamedStyleKey, format.attribute("parent")); 0363 0364 bool ok; 0365 if (format.hasAttribute(type() == AUTO ? "align" : "alignX")) { 0366 HAlign a = (HAlign) format.attribute(type() == AUTO ? "align" : "alignX").toInt(&ok); 0367 if (!ok) 0368 return false; 0369 if ((unsigned int) a >= 1 && (unsigned int) a <= 4) { 0370 setHAlign(a); 0371 } 0372 } 0373 if (format.hasAttribute("alignY")) { 0374 VAlign a = (VAlign) format.attribute("alignY").toInt(&ok); 0375 if (!ok) 0376 return false; 0377 if ((unsigned int) a >= 1 && (unsigned int) a < 4) { 0378 setVAlign(a); 0379 } 0380 } 0381 0382 if (format.hasAttribute("bgcolor")) { 0383 QColor color(format.attribute("bgcolor")); 0384 if (color.isValid()) 0385 setBackgroundColor(color); 0386 } 0387 0388 if (format.hasAttribute("multirow")) { 0389 setWrapText(true); 0390 } 0391 0392 if (format.hasAttribute("shrinktofit")) { 0393 setShrinkToFit(true); 0394 } 0395 0396 if (format.hasAttribute("precision")) { 0397 int i = format.attribute("precision").toInt(&ok); 0398 if (i < -1) { 0399 debugSheetsODF << "Value out of range Cell::precision=" << i; 0400 return false; 0401 } 0402 // special handling for precision 0403 // The Style default (-1) and the storage default (0) differ. 0404 if (type() == AUTO && i == -1) 0405 i = 0; 0406 // The maximum is 10. Replace the Style value 0 with -11, which always results 0407 // in a storage value < 0 and is interpreted as Style value 0. 0408 else if (type() == AUTO && i == 0) 0409 i = -11; 0410 setPrecision(i); 0411 } 0412 0413 if (format.hasAttribute("float")) { 0414 FloatFormat a = (FloatFormat)format.attribute("float").toInt(&ok); 0415 if (!ok) 0416 return false; 0417 if ((unsigned int) a >= 1 && (unsigned int) a <= 3) { 0418 setFloatFormat(a); 0419 } 0420 } 0421 0422 if (format.hasAttribute("floatcolor")) { 0423 FloatColor a = (FloatColor) format.attribute("floatcolor").toInt(&ok); 0424 if (!ok) return false; 0425 if ((unsigned int) a >= 1 && (unsigned int) a <= 2) { 0426 setFloatColor(a); 0427 } 0428 } 0429 0430 if (format.hasAttribute("format")) { 0431 int fo = format.attribute("format").toInt(&ok); 0432 if (! ok) 0433 return false; 0434 setFormatType(static_cast<Format::Type>(fo)); 0435 } 0436 if (format.hasAttribute("custom")) { 0437 setCustomFormat(format.attribute("custom")); 0438 } 0439 if (formatType() == Format::Money) { 0440 ok = true; 0441 Currency currency; 0442 if (format.hasAttribute("type")) { 0443 currency = Currency(format.attribute("type").toInt(&ok)); 0444 if (!ok) { 0445 if (format.hasAttribute("symbol")) 0446 currency = Currency(format.attribute("symbol")); 0447 } 0448 } else if (format.hasAttribute("symbol")) 0449 currency = Currency(format.attribute("symbol")); 0450 setCurrency(currency); 0451 } 0452 if (format.hasAttribute("angle")) { 0453 setAngle(format.attribute("angle").toInt(&ok)); 0454 if (!ok) 0455 return false; 0456 } 0457 if (format.hasAttribute("indent")) { 0458 setIndentation(format.attribute("indent").toDouble(&ok)); 0459 if (!ok) 0460 return false; 0461 } 0462 if (format.hasAttribute("dontprinttext")) { 0463 setDontPrintText(true); 0464 } 0465 0466 if (format.hasAttribute("noprotection")) { 0467 setNotProtected(true); 0468 } 0469 0470 if (format.hasAttribute("hideall")) { 0471 setHideAll(true); 0472 } 0473 0474 if (format.hasAttribute("hideformula")) { 0475 setHideFormula(true); 0476 } 0477 0478 if (type() == AUTO) { 0479 KoXmlElement fontElement = format.namedItem("font").toElement(); 0480 if (!fontElement.isNull()) { 0481 QFont font(NativeFormat::toFont(fontElement)); 0482 setFontFamily(font.family()); 0483 setFontSize(font.pointSize()); 0484 if (font.italic()) 0485 setFontItalic(true); 0486 if (font.bold()) 0487 setFontBold(true); 0488 if (font.underline()) 0489 setFontUnderline(true); 0490 if (font.strikeOut()) 0491 setFontStrikeOut(true); 0492 } 0493 } else { // custom style 0494 if (format.hasAttribute("font-family")) 0495 setFontFamily(format.attribute("font-family")); 0496 if (format.hasAttribute("font-size")) { 0497 setFontSize(format.attribute("font-size").toInt(&ok)); 0498 if (!ok) 0499 return false; 0500 } 0501 if (format.hasAttribute("font-flags")) { 0502 int fontFlags = format.attribute("font-flags").toInt(&ok); 0503 if (!ok) 0504 return false; 0505 0506 enum FontFlags { 0507 FBold = 0x01, 0508 FUnderline = 0x02, 0509 FItalic = 0x04, 0510 FStrike = 0x08 0511 }; 0512 setFontBold(fontFlags & FBold); 0513 setFontItalic(fontFlags & FItalic); 0514 setFontUnderline(fontFlags & FUnderline); 0515 setFontStrikeOut(fontFlags & FStrike); 0516 } 0517 } 0518 0519 if (format.hasAttribute("brushcolor")) { 0520 QColor color(format.attribute("brushcolor")); 0521 if (color.isValid()) { 0522 QBrush brush = backgroundBrush(); 0523 brush.setColor(color); 0524 setBackgroundBrush(brush); 0525 } 0526 } 0527 0528 if (format.hasAttribute("brushstyle")) { 0529 QBrush brush = backgroundBrush(); 0530 brush.setStyle((Qt::BrushStyle) format.attribute("brushstyle").toInt(&ok)); 0531 if (!ok) 0532 return false; 0533 setBackgroundBrush(brush); 0534 } 0535 0536 KoXmlElement pen = format.namedItem("pen").toElement(); 0537 if (!pen.isNull()) { 0538 setFontColor(NativeFormat::toPen(pen).color()); 0539 } 0540 0541 if (mode != Paste::NoBorder) { 0542 KoXmlElement left = format.namedItem("left-border").toElement(); 0543 if (!left.isNull()) { 0544 KoXmlElement pen = left.namedItem("pen").toElement(); 0545 if (!pen.isNull()) 0546 setLeftBorderPen(NativeFormat::toPen(pen)); 0547 } 0548 0549 KoXmlElement top = format.namedItem("top-border").toElement(); 0550 if (!top.isNull()) { 0551 KoXmlElement pen = top.namedItem("pen").toElement(); 0552 if (!pen.isNull()) 0553 setTopBorderPen(NativeFormat::toPen(pen)); 0554 } 0555 0556 KoXmlElement right = format.namedItem("right-border").toElement(); 0557 if (!right.isNull()) { 0558 KoXmlElement pen = right.namedItem("pen").toElement(); 0559 if (!pen.isNull()) 0560 setRightBorderPen(NativeFormat::toPen(pen)); 0561 } 0562 0563 KoXmlElement bottom = format.namedItem("bottom-border").toElement(); 0564 if (!bottom.isNull()) { 0565 KoXmlElement pen = bottom.namedItem("pen").toElement(); 0566 if (!pen.isNull()) 0567 setBottomBorderPen(NativeFormat::toPen(pen)); 0568 } 0569 0570 KoXmlElement fallDiagonal = format.namedItem("fall-diagonal").toElement(); 0571 if (!fallDiagonal.isNull()) { 0572 KoXmlElement pen = fallDiagonal.namedItem("pen").toElement(); 0573 if (!pen.isNull()) 0574 setFallDiagonalPen(NativeFormat::toPen(pen)); 0575 } 0576 0577 KoXmlElement goUpDiagonal = format.namedItem("up-diagonal").toElement(); 0578 if (!goUpDiagonal.isNull()) { 0579 KoXmlElement pen = goUpDiagonal.namedItem("pen").toElement(); 0580 if (!pen.isNull()) 0581 setGoUpDiagonalPen(NativeFormat::toPen(pen)); 0582 } 0583 } 0584 0585 if (format.hasAttribute("prefix")) { 0586 setPrefix(format.attribute("prefix")); 0587 } 0588 if (format.hasAttribute("postfix")) { 0589 setPostfix(format.attribute("postfix")); 0590 } 0591 0592 return true; 0593 } 0594 0595 uint Style::bottomPenValue() const 0596 { 0597 if (!d->subStyles.contains(BottomPen)) 0598 return BorderPenStyle<BottomPen>().value; 0599 return static_cast<const BorderPenStyle<BottomPen>*>(d->subStyles[BottomPen].data())->value; 0600 } 0601 0602 uint Style::rightPenValue() const 0603 { 0604 if (!d->subStyles.contains(RightPen)) 0605 return BorderPenStyle<RightPen>().value; 0606 return static_cast<const BorderPenStyle<RightPen>*>(d->subStyles[RightPen].data())->value; 0607 } 0608 0609 uint Style::leftPenValue() const 0610 { 0611 if (!d->subStyles.contains(LeftPen)) 0612 return BorderPenStyle<LeftPen>().value; 0613 return static_cast<const BorderPenStyle<LeftPen>*>(d->subStyles[LeftPen].data())->value; 0614 } 0615 0616 uint Style::topPenValue() const 0617 { 0618 if (!d->subStyles.contains(TopPen)) 0619 return BorderPenStyle<TopPen>().value; 0620 return static_cast<const BorderPenStyle<TopPen>*>(d->subStyles[TopPen].data())->value; 0621 } 0622 0623 QColor Style::fontColor() const 0624 { 0625 if (!d->subStyles.contains(FontColor)) 0626 return SubStyleOne<FontColor, QColor>(Qt::black).value1; 0627 return static_cast<const SubStyleOne<FontColor, QColor>*>(d->subStyles[FontColor].data())->value1; 0628 } 0629 0630 QColor Style::backgroundColor() const 0631 { 0632 if (!d->subStyles.contains(BackgroundColor)) 0633 return SubStyleOne<BackgroundColor, QColor>().value1; 0634 return static_cast<const SubStyleOne<BackgroundColor, QColor>*>(d->subStyles[BackgroundColor].data())->value1; 0635 } 0636 0637 QPen Style::rightBorderPen() const 0638 { 0639 if (!d->subStyles.contains(RightPen)) 0640 return BorderPenStyle<RightPen>().value1; 0641 return static_cast<const BorderPenStyle<RightPen>*>(d->subStyles[RightPen].data())->value1; 0642 } 0643 0644 QPen Style::bottomBorderPen() const 0645 { 0646 if (!d->subStyles.contains(BottomPen)) 0647 return BorderPenStyle<BottomPen>().value1; 0648 return static_cast<const BorderPenStyle<BottomPen>*>(d->subStyles[BottomPen].data())->value1; 0649 } 0650 0651 QPen Style::leftBorderPen() const 0652 { 0653 if (!d->subStyles.contains(LeftPen)) 0654 return BorderPenStyle<LeftPen>().value1; 0655 return static_cast<const BorderPenStyle<LeftPen>*>(d->subStyles[LeftPen].data())->value1; 0656 } 0657 0658 QPen Style::topBorderPen() const 0659 { 0660 if (!d->subStyles.contains(TopPen)) 0661 return BorderPenStyle<TopPen>().value1; 0662 return static_cast<const BorderPenStyle<TopPen>*>(d->subStyles[TopPen].data())->value1; 0663 } 0664 0665 QPen Style::fallDiagonalPen() const 0666 { 0667 if (!d->subStyles.contains(FallDiagonalPen)) 0668 return PenStyle<FallDiagonalPen>().value1; 0669 return static_cast<const PenStyle<FallDiagonalPen>*>(d->subStyles[FallDiagonalPen].data())->value1; 0670 } 0671 0672 QPen Style::goUpDiagonalPen() const 0673 { 0674 if (!d->subStyles.contains(GoUpDiagonalPen)) 0675 return PenStyle<GoUpDiagonalPen>().value1; 0676 return static_cast<const PenStyle<GoUpDiagonalPen>*>(d->subStyles[GoUpDiagonalPen].data())->value1; 0677 } 0678 0679 QBrush Style::backgroundBrush() const 0680 { 0681 if (!d->subStyles.contains(BackgroundBrush)) 0682 return SubStyleOne<BackgroundBrush, QBrush>(Qt::white).value1; 0683 return static_cast<const SubStyleOne<BackgroundBrush, QBrush>*>(d->subStyles[BackgroundBrush].data())->value1; 0684 } 0685 0686 QString Style::customFormat() const 0687 { 0688 if (!d->subStyles.contains(CustomFormat)) 0689 return SubStyleOne<CustomFormat, QString>().value1; 0690 return static_cast<const SubStyleOne<CustomFormat, QString>*>(d->subStyles[CustomFormat].data())->value1; 0691 } 0692 0693 QString Style::prefix() const 0694 { 0695 if (!d->subStyles.contains(Prefix)) 0696 return SubStyleOne<Prefix, QString>().value1; 0697 return static_cast<const SubStyleOne<Prefix, QString>*>(d->subStyles[Prefix].data())->value1; 0698 } 0699 0700 QString Style::postfix() const 0701 { 0702 if (!d->subStyles.contains(Postfix)) 0703 return SubStyleOne<Postfix, QString>().value1; 0704 return static_cast<const SubStyleOne<Postfix, QString>*>(d->subStyles[Postfix].data())->value1; 0705 } 0706 0707 QString Style::fontFamily() const 0708 { 0709 if (!d->subStyles.contains(FontFamily)) 0710 return KoGlobal::defaultFont().family(); // SubStyleOne<FontFamily, QString>().value1; 0711 return static_cast<const SubStyleOne<FontFamily, QString>*>(d->subStyles[FontFamily].data())->value1; 0712 } 0713 0714 Style::HAlign Style::halign() const 0715 { 0716 if (!d->subStyles.contains(HorizontalAlignment)) 0717 return SubStyleOne<HorizontalAlignment, Style::HAlign>().value1; 0718 return static_cast<const SubStyleOne<HorizontalAlignment, Style::HAlign>*>(d->subStyles[HorizontalAlignment].data())->value1; 0719 } 0720 0721 Style::VAlign Style::valign() const 0722 { 0723 if (!d->subStyles.contains(VerticalAlignment)) 0724 return SubStyleOne<VerticalAlignment, Style::VAlign>().value1; 0725 return static_cast<const SubStyleOne<VerticalAlignment, Style::VAlign>*>(d->subStyles[VerticalAlignment].data())->value1; 0726 } 0727 0728 Style::FloatFormat Style::floatFormat() const 0729 { 0730 if (!d->subStyles.contains(FloatFormatKey)) 0731 return SubStyleOne<FloatFormatKey, FloatFormat>().value1; 0732 return static_cast<const SubStyleOne<FloatFormatKey, FloatFormat>*>(d->subStyles[FloatFormatKey].data())->value1; 0733 } 0734 0735 Style::FloatColor Style::floatColor() const 0736 { 0737 if (!d->subStyles.contains(FloatColorKey)) 0738 return SubStyleOne<FloatColorKey, FloatColor>().value1; 0739 return static_cast<const SubStyleOne<FloatColorKey, FloatColor>*>(d->subStyles[FloatColorKey].data())->value1; 0740 } 0741 0742 Format::Type Style::formatType() const 0743 { 0744 if (!d->subStyles.contains(FormatTypeKey)) 0745 return SubStyleOne<FormatTypeKey, Format::Type>().value1; 0746 return static_cast<const SubStyleOne<FormatTypeKey, Format::Type>*>(d->subStyles[FormatTypeKey].data())->value1; 0747 } 0748 0749 Currency Style::currency() const 0750 { 0751 if (!d->subStyles.contains(CurrencyFormat)) 0752 return Currency(); 0753 return static_cast<const SubStyleOne<CurrencyFormat, Currency>*>(d->subStyles[CurrencyFormat].data())->value1; 0754 } 0755 0756 QFont Style::font() const 0757 { 0758 QFont font; 0759 font.setFamily(fontFamily()); 0760 font.setPointSize(fontSize()); 0761 font.setBold(bold()); 0762 font.setItalic(italic()); 0763 font.setUnderline(underline()); 0764 font.setStrikeOut(strikeOut()); 0765 return font; 0766 } 0767 0768 bool Style::bold() const 0769 { 0770 if (!d->subStyles.contains(FontBold)) 0771 return SubStyleOne<FontBold, bool>().value1; 0772 return static_cast<const SubStyleOne<FontBold, bool>*>(d->subStyles[FontBold].data())->value1; 0773 } 0774 0775 bool Style::italic() const 0776 { 0777 if (!d->subStyles.contains(FontItalic)) 0778 return SubStyleOne<FontItalic, bool>().value1; 0779 return static_cast<const SubStyleOne<FontItalic, bool>*>(d->subStyles[FontItalic].data())->value1; 0780 } 0781 0782 bool Style::underline() const 0783 { 0784 if (!d->subStyles.contains(FontUnderline)) 0785 return SubStyleOne<FontUnderline, bool>().value1; 0786 return static_cast<const SubStyleOne<FontUnderline, bool>*>(d->subStyles[FontUnderline].data())->value1; 0787 } 0788 0789 bool Style::strikeOut() const 0790 { 0791 if (!d->subStyles.contains(FontStrike)) 0792 return SubStyleOne<FontStrike, bool>().value1; 0793 return static_cast<const SubStyleOne<FontStrike, bool>*>(d->subStyles[FontStrike].data())->value1; 0794 } 0795 0796 int Style::fontSize() const 0797 { 0798 if (!d->subStyles.contains(FontSize)) 0799 return KoGlobal::defaultFont().pointSize(); //SubStyleOne<FontSize, int>().value1; 0800 return static_cast<const SubStyleOne<FontSize, int>*>(d->subStyles[FontSize].data())->value1; 0801 } 0802 0803 int Style::precision() const 0804 { 0805 if (!d->subStyles.contains(Precision)) 0806 return -1; //SubStyleOne<Precision, int>().value1; 0807 return static_cast<const SubStyleOne<Precision, int>*>(d->subStyles[Precision].data())->value1; 0808 } 0809 0810 bool Style::thousandsSep() const 0811 { 0812 if (!d->subStyles.contains(ThousandsSep)) 0813 return false; 0814 return static_cast<const SubStyleOne<ThousandsSep, bool>*>(d->subStyles[ThousandsSep].data())->value1; 0815 } 0816 0817 int Style::angle() const 0818 { 0819 if (!d->subStyles.contains(Angle)) 0820 return SubStyleOne<Angle, int>().value1; 0821 return static_cast<const SubStyleOne<Angle, int>*>(d->subStyles[Angle].data())->value1; 0822 } 0823 0824 double Style::indentation() const 0825 { 0826 if (!d->subStyles.contains(Indentation)) 0827 return SubStyleOne<Indentation, int>().value1; 0828 return static_cast<const SubStyleOne<Indentation, int>*>(d->subStyles[Indentation].data())->value1; 0829 } 0830 0831 bool Style::shrinkToFit() const 0832 { 0833 if (!d->subStyles.contains(ShrinkToFit)) 0834 return SubStyleOne<ShrinkToFit, bool>().value1; 0835 return static_cast<const SubStyleOne<ShrinkToFit, bool>*>(d->subStyles[ShrinkToFit].data())->value1; 0836 } 0837 0838 bool Style::verticalText() const 0839 { 0840 if (!d->subStyles.contains(VerticalText)) 0841 return SubStyleOne<VerticalText, bool>().value1; 0842 return static_cast<const SubStyleOne<VerticalText, bool>*>(d->subStyles[VerticalText].data())->value1; 0843 } 0844 0845 bool Style::wrapText() const 0846 { 0847 if (!d->subStyles.contains(MultiRow)) 0848 return SubStyleOne<MultiRow, bool>().value1; 0849 return static_cast<const SubStyleOne<MultiRow, bool>*>(d->subStyles[MultiRow].data())->value1; 0850 } 0851 0852 bool Style::printText() const 0853 { 0854 if (!d->subStyles.contains(DontPrintText)) 0855 return !SubStyleOne<DontPrintText, bool>().value1; 0856 return !static_cast<const SubStyleOne<DontPrintText, bool>*>(d->subStyles[DontPrintText].data())->value1; 0857 } 0858 0859 bool Style::hideAll() const 0860 { 0861 if (!d->subStyles.contains(HideAll)) 0862 return SubStyleOne<HideAll, bool>().value1; 0863 return static_cast<const SubStyleOne<HideAll, bool>*>(d->subStyles[HideAll].data())->value1; 0864 } 0865 0866 bool Style::hideFormula() const 0867 { 0868 if (!d->subStyles.contains(HideFormula)) 0869 return SubStyleOne<HideFormula, bool>().value1; 0870 return static_cast<const SubStyleOne<HideFormula, bool>*>(d->subStyles[HideFormula].data())->value1; 0871 } 0872 0873 bool Style::notProtected() const 0874 { 0875 if (!d->subStyles.contains(NotProtected)) 0876 return SubStyleOne<NotProtected, bool>().value1; 0877 return static_cast<const SubStyleOne<NotProtected, bool>*>(d->subStyles[NotProtected].data())->value1; 0878 } 0879 0880 bool Style::isDefault() const 0881 { 0882 return isEmpty() || d->subStyles.contains(DefaultStyleKey); 0883 } 0884 0885 bool Style::isEmpty() const 0886 { 0887 return d->subStyles.isEmpty(); 0888 } 0889 0890 void Style::setHAlign(HAlign align) 0891 { 0892 insertSubStyle(HorizontalAlignment, align); 0893 } 0894 0895 void Style::setVAlign(VAlign align) 0896 { 0897 insertSubStyle(VerticalAlignment, align); 0898 } 0899 0900 void Style::setFont(QFont const & font) 0901 { 0902 insertSubStyle(FontFamily, font.family()); 0903 insertSubStyle(FontSize, font.pointSize()); 0904 insertSubStyle(FontBold, font.bold()); 0905 insertSubStyle(FontItalic, font.italic()); 0906 insertSubStyle(FontStrike, font.strikeOut()); 0907 insertSubStyle(FontUnderline, font.underline()); 0908 } 0909 0910 void Style::setFontFamily(QString const & family) 0911 { 0912 QString font = family; 0913 // use the KDE default for sans serif, not Qt's default - this is because Qt doesn't return the default system font here 0914 if (font.toLower() == "sans serif") { 0915 QFont f = QFontDatabase::systemFont(QFontDatabase::GeneralFont); 0916 font = f.family(); 0917 } 0918 0919 insertSubStyle(FontFamily, font); 0920 } 0921 0922 void Style::setFontBold(bool enabled) 0923 { 0924 insertSubStyle(FontBold, enabled); 0925 } 0926 0927 void Style::setFontItalic(bool enabled) 0928 { 0929 insertSubStyle(FontItalic, enabled); 0930 } 0931 0932 void Style::setFontUnderline(bool enabled) 0933 { 0934 insertSubStyle(FontUnderline, enabled); 0935 } 0936 0937 void Style::setFontStrikeOut(bool enabled) 0938 { 0939 insertSubStyle(FontStrike, enabled); 0940 } 0941 0942 void Style::setFontSize(int size) 0943 { 0944 insertSubStyle(FontSize, size); 0945 } 0946 0947 void Style::setFontColor(QColor const & color) 0948 { 0949 insertSubStyle(FontColor, color); 0950 } 0951 0952 void Style::setBackgroundColor(QColor const & color) 0953 { 0954 insertSubStyle(BackgroundColor, color); 0955 } 0956 0957 void Style::setRightBorderPen(QPen const & pen) 0958 { 0959 insertSubStyle(RightPen, pen); 0960 } 0961 0962 void Style::setBottomBorderPen(QPen const & pen) 0963 { 0964 insertSubStyle(BottomPen, pen); 0965 } 0966 0967 void Style::setLeftBorderPen(QPen const & pen) 0968 { 0969 insertSubStyle(LeftPen, pen); 0970 } 0971 0972 void Style::setTopBorderPen(QPen const & pen) 0973 { 0974 insertSubStyle(TopPen, pen); 0975 } 0976 0977 void Style::setFallDiagonalPen(QPen const & pen) 0978 { 0979 insertSubStyle(FallDiagonalPen, pen); 0980 } 0981 0982 void Style::setGoUpDiagonalPen(QPen const & pen) 0983 { 0984 insertSubStyle(GoUpDiagonalPen, pen); 0985 } 0986 0987 void Style::setAngle(int angle) 0988 { 0989 insertSubStyle(Angle, angle); 0990 } 0991 0992 void Style::setIndentation(double indent) 0993 { 0994 insertSubStyle(Indentation, indent); 0995 } 0996 0997 void Style::setBackgroundBrush(QBrush const & brush) 0998 { 0999 insertSubStyle(BackgroundBrush, brush); 1000 } 1001 1002 void Style::setFloatFormat(FloatFormat format) 1003 { 1004 insertSubStyle(FloatFormatKey, format); 1005 } 1006 1007 void Style::setFloatColor(FloatColor color) 1008 { 1009 insertSubStyle(FloatColorKey, color); 1010 } 1011 1012 void Style::setFormatType(Format::Type format) 1013 { 1014 insertSubStyle(FormatTypeKey, format); 1015 } 1016 1017 void Style::setCustomFormat(QString const & strFormat) 1018 { 1019 insertSubStyle(CustomFormat, strFormat); 1020 } 1021 1022 void Style::setPrecision(int precision) 1023 { 1024 insertSubStyle(Precision, precision); 1025 } 1026 1027 void Style::setThousandsSep(bool thousandsSep) 1028 { 1029 insertSubStyle(ThousandsSep, thousandsSep); 1030 } 1031 1032 void Style::setPrefix(QString const & prefix) 1033 { 1034 insertSubStyle(Prefix, prefix); 1035 } 1036 1037 void Style::setPostfix(QString const & postfix) 1038 { 1039 insertSubStyle(Postfix, postfix); 1040 } 1041 1042 void Style::setCurrency(Currency const & currency) 1043 { 1044 QVariant variant; 1045 variant.setValue(currency); 1046 insertSubStyle(CurrencyFormat, variant); 1047 } 1048 1049 void Style::setWrapText(bool enable) 1050 { 1051 insertSubStyle(MultiRow, enable); 1052 } 1053 1054 void Style::setHideAll(bool enable) 1055 { 1056 insertSubStyle(HideAll, enable); 1057 } 1058 1059 void Style::setHideFormula(bool enable) 1060 { 1061 insertSubStyle(HideFormula, enable); 1062 } 1063 1064 void Style::setNotProtected(bool enable) 1065 { 1066 insertSubStyle(NotProtected, enable); 1067 } 1068 1069 void Style::setDontPrintText(bool enable) 1070 { 1071 insertSubStyle(DontPrintText, enable); 1072 } 1073 1074 void Style::setVerticalText(bool enable) 1075 { 1076 insertSubStyle(VerticalText, enable); 1077 } 1078 1079 void Style::setShrinkToFit(bool enable) 1080 { 1081 insertSubStyle(ShrinkToFit, enable); 1082 } 1083 1084 void Style::setDefault() 1085 { 1086 insertSubStyle(DefaultStyleKey, true); 1087 } 1088 1089 void Style::clear() 1090 { 1091 d->subStyles.clear(); 1092 } 1093 1094 bool Style::compare(const SubStyle* one, const SubStyle* two) 1095 { 1096 if (!one || !two) 1097 return one == two; 1098 if (one->type() != two->type()) 1099 return false; 1100 switch (one->type()) { 1101 case DefaultStyleKey: 1102 return true; 1103 case NamedStyleKey: 1104 return static_cast<const NamedStyle*>(one)->name == static_cast<const NamedStyle*>(two)->name; 1105 // borders 1106 case LeftPen: 1107 return static_cast<const SubStyleOne<LeftPen, QPen>*>(one)->value1 == static_cast<const SubStyleOne<LeftPen, QPen>*>(two)->value1; 1108 case RightPen: 1109 return static_cast<const SubStyleOne<RightPen, QPen>*>(one)->value1 == static_cast<const SubStyleOne<RightPen, QPen>*>(two)->value1; 1110 case TopPen: 1111 return static_cast<const SubStyleOne<TopPen, QPen>*>(one)->value1 == static_cast<const SubStyleOne<TopPen, QPen>*>(two)->value1; 1112 case BottomPen: 1113 return static_cast<const SubStyleOne<BottomPen, QPen>*>(one)->value1 == static_cast<const SubStyleOne<BottomPen, QPen>*>(two)->value1; 1114 case FallDiagonalPen: 1115 return static_cast<const SubStyleOne<FallDiagonalPen, QPen>*>(one)->value1 == static_cast<const SubStyleOne<FallDiagonalPen, QPen>*>(two)->value1; 1116 case GoUpDiagonalPen: 1117 return static_cast<const SubStyleOne<GoUpDiagonalPen, QPen>*>(one)->value1 == static_cast<const SubStyleOne<GoUpDiagonalPen, QPen>*>(two)->value1; 1118 // layout 1119 case HorizontalAlignment: 1120 return static_cast<const SubStyleOne<HorizontalAlignment, HAlign>*>(one)->value1 == static_cast<const SubStyleOne<HorizontalAlignment, HAlign>*>(two)->value1; 1121 case VerticalAlignment: 1122 return static_cast<const SubStyleOne<VerticalAlignment, VAlign>*>(one)->value1 == static_cast<const SubStyleOne<VerticalAlignment, VAlign>*>(two)->value1; 1123 case MultiRow: 1124 return static_cast<const SubStyleOne<MultiRow, bool>*>(one)->value1 == static_cast<const SubStyleOne<MultiRow, bool>*>(two)->value1; 1125 case VerticalText: 1126 return static_cast<const SubStyleOne<VerticalText, bool>*>(one)->value1 == static_cast<const SubStyleOne<VerticalText, bool>*>(two)->value1; 1127 case ShrinkToFit: 1128 return static_cast<const SubStyleOne<ShrinkToFit, bool>*>(one)->value1 == static_cast<const SubStyleOne<ShrinkToFit, bool>*>(two)->value1; 1129 case Angle: 1130 return static_cast<const SubStyleOne<Angle, int>*>(one)->value1 == static_cast<const SubStyleOne<Angle, int>*>(two)->value1; 1131 case Indentation: 1132 return static_cast<const SubStyleOne<Indentation, int>*>(one)->value1 == static_cast<const SubStyleOne<Indentation, int>*>(two)->value1; 1133 // content format 1134 case Prefix: 1135 return static_cast<const SubStyleOne<Prefix, QString>*>(one)->value1 == static_cast<const SubStyleOne<Prefix, QString>*>(two)->value1; 1136 case Postfix: 1137 return static_cast<const SubStyleOne<Postfix, QString>*>(one)->value1 == static_cast<const SubStyleOne<Postfix, QString>*>(two)->value1; 1138 case Precision: 1139 return static_cast<const SubStyleOne<Precision, int>*>(one)->value1 == static_cast<const SubStyleOne<Precision, int>*>(two)->value1; 1140 case ThousandsSep: 1141 return static_cast<const SubStyleOne<ThousandsSep, bool>*>(one)->value1 == static_cast<const SubStyleOne<ThousandsSep, bool>*>(two)->value1; 1142 case FormatTypeKey: 1143 return static_cast<const SubStyleOne<FormatTypeKey, Format::Type>*>(one)->value1 == static_cast<const SubStyleOne<FormatTypeKey, Format::Type>*>(two)->value1; 1144 case FloatFormatKey: 1145 return static_cast<const SubStyleOne<FloatFormatKey, FloatFormat>*>(one)->value1 == static_cast<const SubStyleOne<FloatFormatKey, FloatFormat>*>(two)->value1; 1146 case FloatColorKey: 1147 return static_cast<const SubStyleOne<FloatColorKey, FloatColor>*>(one)->value1 == static_cast<const SubStyleOne<FloatColorKey, FloatColor>*>(two)->value1; 1148 case CurrencyFormat: { 1149 Currency currencyOne = static_cast<const SubStyleOne<CurrencyFormat, Currency>*>(one)->value1; 1150 Currency currencyTwo = static_cast<const SubStyleOne<CurrencyFormat, Currency>*>(two)->value1; 1151 if (currencyOne != currencyTwo) 1152 return false; 1153 return true; 1154 } 1155 case CustomFormat: 1156 return static_cast<const SubStyleOne<CustomFormat, QString>*>(one)->value1 == static_cast<const SubStyleOne<CustomFormat, QString>*>(two)->value1; 1157 // background 1158 case BackgroundBrush: 1159 return static_cast<const SubStyleOne<BackgroundBrush, QBrush>*>(one)->value1 == static_cast<const SubStyleOne<BackgroundBrush, QBrush>*>(two)->value1; 1160 case BackgroundColor: 1161 return static_cast<const SubStyleOne<BackgroundColor, QColor>*>(one)->value1 == static_cast<const SubStyleOne<BackgroundColor, QColor>*>(two)->value1; 1162 // font 1163 case FontColor: 1164 return static_cast<const SubStyleOne<FontColor, QColor>*>(one)->value1 == static_cast<const SubStyleOne<FontColor, QColor>*>(two)->value1; 1165 case FontFamily: 1166 return static_cast<const SubStyleOne<FontFamily, QString>*>(one)->value1 == static_cast<const SubStyleOne<FontFamily, QString>*>(two)->value1; 1167 case FontSize: 1168 return static_cast<const SubStyleOne<FontSize, int>*>(one)->value1 == static_cast<const SubStyleOne<FontSize, int>*>(two)->value1; 1169 case FontBold: 1170 return static_cast<const SubStyleOne<FontBold, bool>*>(one)->value1 == static_cast<const SubStyleOne<FontBold, bool>*>(two)->value1; 1171 case FontItalic: 1172 return static_cast<const SubStyleOne<FontItalic, bool>*>(one)->value1 == static_cast<const SubStyleOne<FontItalic, bool>*>(two)->value1; 1173 case FontStrike: 1174 return static_cast<const SubStyleOne<FontStrike, bool>*>(one)->value1 == static_cast<const SubStyleOne<FontStrike, bool>*>(two)->value1; 1175 case FontUnderline: 1176 return static_cast<const SubStyleOne<FontUnderline, bool>*>(one)->value1 == static_cast<const SubStyleOne<FontUnderline, bool>*>(two)->value1; 1177 //misc 1178 case DontPrintText: 1179 return static_cast<const SubStyleOne<DontPrintText, bool>*>(one)->value1 == static_cast<const SubStyleOne<DontPrintText, bool>*>(two)->value1; 1180 case NotProtected: 1181 return static_cast<const SubStyleOne<NotProtected, bool>*>(one)->value1 == static_cast<const SubStyleOne<NotProtected, bool>*>(two)->value1; 1182 case HideAll: 1183 return static_cast<const SubStyleOne<HideAll, bool>*>(one)->value1 == static_cast<const SubStyleOne<HideAll, bool>*>(two)->value1; 1184 case HideFormula: 1185 return static_cast<const SubStyleOne<HideFormula, bool>*>(one)->value1 == static_cast<const SubStyleOne<HideFormula, bool>*>(two)->value1; 1186 default: 1187 return false; 1188 } 1189 } 1190 1191 bool Style::operator==(const Style& other) const 1192 { 1193 if (other.isEmpty()) 1194 return isEmpty() ? true : false; 1195 const QSet<Key> keys = QSet<Key>::fromList(d->subStyles.keys() + other.d->subStyles.keys()); 1196 const QSet<Key>::ConstIterator end = keys.constEnd(); 1197 for (QSet<Key>::ConstIterator it = keys.constBegin(); it != end; ++it) { 1198 if (!compare(d->subStyles.value(*it).data(), other.d->subStyles.value(*it).data())) 1199 return false; 1200 } 1201 return true; 1202 } 1203 1204 uint Calligra::Sheets::qHash(const Style& style) 1205 { 1206 uint hash = 0; 1207 foreach (const SharedSubStyle& ss, style.subStyles()) { 1208 hash ^= ss->koHash(); 1209 } 1210 return hash; 1211 } 1212 1213 void Style::operator=(const Style & other) 1214 { 1215 d = other.d; 1216 } 1217 1218 Style Style::operator-(const Style& other) const 1219 { 1220 Style style; 1221 const QSet<Key> keys = difference(other); 1222 const QSet<Key>::ConstIterator end = keys.constEnd(); 1223 for (QSet<Key>::ConstIterator it = keys.constBegin(); it != end; ++it) 1224 style.insertSubStyle(d->subStyles[*it]); 1225 return style; 1226 } 1227 1228 void Style::merge(const Style& style) 1229 { 1230 const QList<SharedSubStyle> subStyles(style.subStyles()); 1231 // debugSheetsStyle <<"merging" << subStyles.count() <<" attributes."; 1232 for (int i = 0; i < subStyles.count(); ++i) { 1233 // debugSheetsStyle << subStyles[i]->debugData(); 1234 insertSubStyle(subStyles[i]); 1235 } 1236 } 1237 1238 QSet<Style::Key> Style::difference(const Style& other) const 1239 { 1240 QSet<Key> result; 1241 const QSet<Key> keys = QSet<Key>::fromList(d->subStyles.keys() + other.d->subStyles.keys()); 1242 const QSet<Key>::ConstIterator end = keys.constEnd(); 1243 for (QSet<Key>::ConstIterator it = keys.constBegin(); it != end; ++it) { 1244 if (!other.d->subStyles.contains(*it)) 1245 result.insert(*it); 1246 else if (d->subStyles.contains(*it)) { // both contain this key 1247 if (!compare(d->subStyles.value(*it).data(), other.d->subStyles.value(*it).data())) 1248 result.insert(*it); 1249 } 1250 } 1251 return result; 1252 } 1253 1254 void Style::dump() const 1255 { 1256 for (int i = 0; i < subStyles().count(); ++i) 1257 subStyles()[i]->dump(); 1258 } 1259 1260 QTextCharFormat Style::asCharFormat() const 1261 { 1262 QTextCharFormat format; 1263 format.setFont(font()); 1264 format.setFontWeight(bold() ? QFont::Bold : QFont::Normal); 1265 format.setFontItalic(italic()); 1266 format.setFontUnderline(underline()); 1267 format.setFontStrikeOut(strikeOut()); 1268 return format; 1269 } 1270 1271 QSet<Style::Key> Style::definedKeys(const StyleManager *styles) const 1272 { 1273 QSet<Style::Key> keys; 1274 1275 if (isDefault()) return keys; 1276 1277 if (hasAttribute(Style::NamedStyleKey)) 1278 { 1279 // it's not really the parent name in this case 1280 CustomStyle* namedStyle = styles->style(parentName()); 1281 // remove substyles already present in named style 1282 if (namedStyle) keys = difference(*namedStyle); 1283 } 1284 else 1285 keys = QSet<Style::Key>::fromList(d->subStyles.keys()); 1286 1287 return keys; 1288 } 1289 1290 QList<SharedSubStyle> Style::subStyles() const 1291 { 1292 return d->subStyles.values(); 1293 } 1294 1295 SharedSubStyle Style::createSubStyle(Key key, const QVariant& value) 1296 { 1297 SharedSubStyle newSubStyle; 1298 switch (key) { 1299 // special cases 1300 case DefaultStyleKey: 1301 newSubStyle = new SubStyle(); 1302 break; 1303 case NamedStyleKey: 1304 newSubStyle = new NamedStyle(value.value<QString>()); 1305 break; 1306 case LeftPen: 1307 newSubStyle = new BorderPenStyle<LeftPen>(value.value<QPen>()); 1308 break; 1309 case RightPen: 1310 newSubStyle = new BorderPenStyle<RightPen>(value.value<QPen>()); 1311 break; 1312 case TopPen: 1313 newSubStyle = new BorderPenStyle<TopPen>(value.value<QPen>()); 1314 break; 1315 case BottomPen: 1316 newSubStyle = new BorderPenStyle<BottomPen>(value.value<QPen>()); 1317 break; 1318 case FallDiagonalPen: 1319 newSubStyle = new BorderPenStyle<FallDiagonalPen>(value.value<QPen>()); 1320 break; 1321 case GoUpDiagonalPen: 1322 newSubStyle = new BorderPenStyle<GoUpDiagonalPen>(value.value<QPen>()); 1323 break; 1324 // layout 1325 case HorizontalAlignment: 1326 newSubStyle = new SubStyleOne<HorizontalAlignment, HAlign>((HAlign)value.value<int>()); 1327 break; 1328 case VerticalAlignment: 1329 newSubStyle = new SubStyleOne<VerticalAlignment, VAlign>((VAlign)value.value<int>()); 1330 break; 1331 case MultiRow: 1332 newSubStyle = new SubStyleOne<MultiRow, bool>(value.value<bool>()); 1333 break; 1334 case VerticalText: 1335 newSubStyle = new SubStyleOne<VerticalText, bool>(value.value<bool>()); 1336 break; 1337 case Angle: 1338 newSubStyle = new SubStyleOne<Angle, int>(value.value<int>()); 1339 break; 1340 case Indentation: 1341 newSubStyle = new SubStyleOne<Indentation, int>(value.value<int>()); 1342 break; 1343 case ShrinkToFit: 1344 newSubStyle = new SubStyleOne<ShrinkToFit,bool>(value.value<bool>()); 1345 break; 1346 // content format 1347 case Prefix: 1348 newSubStyle = new SubStyleOne<Prefix, QString>(value.value<QString>()); 1349 break; 1350 case Postfix: 1351 newSubStyle = new SubStyleOne<Postfix, QString>(value.value<QString>()); 1352 break; 1353 case Precision: 1354 newSubStyle = new SubStyleOne<Precision, int>(value.value<int>()); 1355 break; 1356 case ThousandsSep: 1357 newSubStyle = new SubStyleOne<ThousandsSep, bool>(value.value<bool>()); 1358 break; 1359 case FormatTypeKey: 1360 newSubStyle = new SubStyleOne<FormatTypeKey, Format::Type>((Format::Type)value.value<int>()); 1361 break; 1362 case FloatFormatKey: 1363 newSubStyle = new SubStyleOne<FloatFormatKey, FloatFormat>((FloatFormat)value.value<int>()); 1364 break; 1365 case FloatColorKey: 1366 newSubStyle = new SubStyleOne<FloatColorKey, FloatColor>((FloatColor)value.value<int>()); 1367 break; 1368 case CurrencyFormat: 1369 newSubStyle = new SubStyleOne<CurrencyFormat, Currency>(value.value<Currency>()); 1370 break; 1371 case CustomFormat: 1372 newSubStyle = new SubStyleOne<CustomFormat, QString>(value.value<QString>()); 1373 break; 1374 // background 1375 case BackgroundBrush: 1376 newSubStyle = new SubStyleOne<BackgroundBrush, QBrush>(value.value<QBrush>()); 1377 break; 1378 case BackgroundColor: 1379 newSubStyle = new SubStyleOne<BackgroundColor, QColor>(value.value<QColor>()); 1380 break; 1381 // font 1382 case FontColor: 1383 newSubStyle = new SubStyleOne<FontColor, QColor>(value.value<QColor>()); 1384 break; 1385 case FontFamily: 1386 newSubStyle = new SubStyleOne<FontFamily, QString>(value.value<QString>()); 1387 break; 1388 case FontSize: 1389 newSubStyle = new SubStyleOne<FontSize, int>(value.value<int>()); 1390 break; 1391 case FontBold: 1392 newSubStyle = new SubStyleOne<FontBold, bool>(value.value<bool>()); 1393 break; 1394 case FontItalic: 1395 newSubStyle = new SubStyleOne<FontItalic, bool>(value.value<bool>()); 1396 break; 1397 case FontStrike: 1398 newSubStyle = new SubStyleOne<FontStrike, bool>(value.value<bool>()); 1399 break; 1400 case FontUnderline: 1401 newSubStyle = new SubStyleOne<FontUnderline, bool>(value.value<bool>()); 1402 break; 1403 //misc 1404 case DontPrintText: 1405 newSubStyle = new SubStyleOne<DontPrintText, bool>(value.value<bool>()); 1406 break; 1407 case NotProtected: 1408 newSubStyle = new SubStyleOne<NotProtected, bool>(value.value<bool>()); 1409 break; 1410 case HideAll: 1411 newSubStyle = new SubStyleOne<HideAll, bool>(value.value<bool>()); 1412 break; 1413 case HideFormula: 1414 newSubStyle = new SubStyleOne<HideFormula, bool>(value.value<bool>()); 1415 break; 1416 } 1417 return newSubStyle; 1418 } 1419 1420 void Style::insertSubStyle(Key key, const QVariant& value) 1421 { 1422 const SharedSubStyle subStyle = createSubStyle(key, value); 1423 Q_ASSERT(!!subStyle); 1424 insertSubStyle(subStyle); 1425 } 1426 1427 void Style::insertSubStyle(const SharedSubStyle& subStyle) 1428 { 1429 if (!subStyle) 1430 return; 1431 releaseSubStyle(subStyle->type()); 1432 d->subStyles.insert(subStyle->type(), subStyle); 1433 } 1434 1435 bool Style::releaseSubStyle(Key key) 1436 { 1437 if (!d->subStyles.contains(key)) 1438 return false; 1439 1440 d->subStyles.remove(key); 1441 return true; 1442 } 1443 1444 ///////////////////////////////////////////////////////////////////////////// 1445 // 1446 // CustomStyle::Private 1447 // 1448 ///////////////////////////////////////////////////////////////////////////// 1449 1450 class Q_DECL_HIDDEN CustomStyle::Private : public QSharedData 1451 { 1452 public: 1453 QString name; 1454 StyleType type; 1455 }; 1456 1457 1458 ///////////////////////////////////////////////////////////////////////////// 1459 // 1460 // CustomStyle 1461 // 1462 ///////////////////////////////////////////////////////////////////////////// 1463 1464 CustomStyle::CustomStyle() 1465 : Style() 1466 , d(new Private) 1467 { 1468 d->name = "Default"; 1469 d->type = BUILTIN; 1470 setDefault(); 1471 } 1472 1473 CustomStyle::CustomStyle(QString const & name, CustomStyle * parent) 1474 : Style() 1475 , d(new Private) 1476 { 1477 d->name = name; 1478 d->type = CUSTOM; 1479 if (parent) 1480 setParentName(parent->name()); 1481 } 1482 1483 CustomStyle::CustomStyle(const CustomStyle& style) 1484 : Style(style), d(style.d) 1485 { 1486 } 1487 1488 CustomStyle::~CustomStyle() 1489 { 1490 } 1491 1492 CustomStyle& CustomStyle::operator=(const CustomStyle& style) 1493 { 1494 Style::operator=(style); 1495 d = style.d; 1496 return *this; 1497 } 1498 1499 Style::StyleType CustomStyle::type() const 1500 { 1501 return d->type; 1502 } 1503 1504 void CustomStyle::setType(StyleType type) 1505 { 1506 Q_ASSERT(type != AUTO); 1507 d->type = type; 1508 } 1509 1510 const QString& CustomStyle::name() const 1511 { 1512 return d->name; 1513 } 1514 1515 void CustomStyle::setName(QString const & name) 1516 { 1517 d->name = name; 1518 } 1519 1520 void CustomStyle::save(QDomDocument& doc, QDomElement& styles, const StyleManager* styleManager) 1521 { 1522 if (name().isEmpty()) 1523 return; 1524 1525 QDomElement style(doc.createElement("style")); 1526 style.setAttribute("type", QString::number((int) type())); 1527 if (!parentName().isNull()) 1528 style.setAttribute("parent", parentName()); 1529 style.setAttribute("name", name()); 1530 1531 QDomElement format(doc.createElement("format")); 1532 saveXML(doc, format, styleManager); 1533 style.appendChild(format); 1534 1535 styles.appendChild(style); 1536 } 1537 1538 bool CustomStyle::loadXML(KoXmlElement const & style, QString const & name) 1539 { 1540 setName(name); 1541 1542 if (style.hasAttribute("parent")) 1543 setParentName(style.attribute("parent")); 1544 1545 if (!style.hasAttribute("type")) 1546 return false; 1547 1548 bool ok = true; 1549 setType((StyleType) style.attribute("type").toInt(&ok)); 1550 if (!ok) 1551 return false; 1552 1553 KoXmlElement f(style.namedItem("format").toElement()); 1554 if (!f.isNull()) 1555 if (!Style::loadXML(f)) 1556 return false; 1557 1558 return true; 1559 } 1560 1561 int CustomStyle::usage() const 1562 { 1563 return d->ref; 1564 } 1565 1566 QSet<Style::Key> CustomStyle::definedKeys(const StyleManager *) const 1567 { 1568 QList<SharedSubStyle> subs = subStyles(); 1569 QSet<Style::Key> keys; 1570 for (int i = 0; i < subs.count(); ++i) 1571 keys.insert(subs[i].data()->type()); 1572 return keys; 1573 } 1574 1575 QDebug operator<<(QDebug dbg, const Calligra::Sheets::Style *s) 1576 { 1577 if (s) { 1578 dbg << (*s); 1579 } else { 1580 dbg << "Style[0x0]"; 1581 } 1582 return dbg; 1583 } 1584 1585 QDebug operator<<(QDebug dbg, const Calligra::Sheets::Style &s) 1586 { 1587 static const char *types[] = {"Builtin", "Custom", "Auto", "Tentative"}; 1588 dbg << "Style["<<types[s.type()]<<"]"; 1589 return dbg; 1590 }