Warning, file /office/calligra/libs/odf/KoGenStyles.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2004-2006 David Faure <faure@kde.org> 0003 Copyright (C) 2007-2008 Thorsten Zachmann <zachmann@kde.org> 0004 Copyright (C) 2009 Thomas Zander <zander@kde.org> 0005 Copyright (C) 2008 Girish Ramakrishnan <girish@forwardbias.in> 0006 Copyright (C) 2009 Inge Wallin <inge@lysator.liu.se> 0007 Copyright (C) 2010 KO GmbH <jos.van.den.oever@kogmbh.com> 0008 Copyright (C) 2010 Jarosław Staniek <staniek@kde.org> 0009 0010 This library is free software; you can redistribute it and/or 0011 modify it under the terms of the GNU Library General Public 0012 License version 2 as published by the Free Software Foundation. 0013 0014 This library is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 Library General Public License for more details. 0018 0019 You should have received a copy of the GNU Library General Public License 0020 along with this library; see the file COPYING.LIB. If not, write to 0021 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0022 * Boston, MA 02110-1301, USA. 0023 */ 0024 0025 #include "KoGenStyles.h" 0026 0027 #include <KoStore.h> 0028 #include <KoStoreDevice.h> 0029 #include <KoXmlWriter.h> 0030 #include "KoOdfWriteStore.h" 0031 #include "KoFontFace.h" 0032 #include <float.h> 0033 #include <OdfDebug.h> 0034 0035 static const struct { 0036 KoGenStyle::Type m_type; 0037 const char * m_elementName; 0038 const char * m_propertiesElementName; 0039 bool m_drawElement; 0040 } styleData[] = { 0041 { KoGenStyle::TextStyle, "style:style", "style:text-properties", false }, 0042 { KoGenStyle::ParagraphStyle, "style:style", "style:paragraph-properties", false }, 0043 { KoGenStyle::SectionStyle, "style:style", "style:section-properties", false }, 0044 { KoGenStyle::RubyStyle, "style:style", "style:ruby-properties", false }, 0045 { KoGenStyle::TableStyle, "style:style", "style:table-properties", false }, 0046 { KoGenStyle::TableColumnStyle, "style:style", "style:table-column-properties", false }, 0047 { KoGenStyle::TableRowStyle, "style:style", "style:table-row-properties", false }, 0048 { KoGenStyle::TableCellStyle, "style:style", "style:table-cell-properties", false }, 0049 { KoGenStyle::GraphicStyle, "style:style", "style:graphic-properties", false }, 0050 { KoGenStyle::PresentationStyle, "style:style", "style:graphic-properties", false }, 0051 { KoGenStyle::DrawingPageStyle, "style:style", "style:drawing-page-properties", false }, 0052 { KoGenStyle::ChartStyle, "style:style", "style:chart-properties", false }, 0053 { KoGenStyle::ListStyle, "text:list-style", 0, false }, 0054 { KoGenStyle::LinearGradientStyle, "svg:linearGradient", 0, true }, 0055 { KoGenStyle::RadialGradientStyle, "svg:radialGradient", 0, true }, 0056 { KoGenStyle::ConicalGradientStyle, "calligra:conicalGradient", 0, true }, 0057 { KoGenStyle::StrokeDashStyle, "draw:stroke-dash", 0, true }, 0058 { KoGenStyle::FillImageStyle, "draw:fill-image", 0, true }, 0059 { KoGenStyle::HatchStyle, "draw:hatch", "style:graphic-properties", true }, 0060 { KoGenStyle::GradientStyle, "draw:gradient", "style:graphic-properties", true }, 0061 { KoGenStyle::MarkerStyle, "draw:marker", "style:graphic-properties", true }, 0062 { KoGenStyle::PresentationPageLayoutStyle, "style:presentation-page-layout", 0, false }, 0063 { KoGenStyle::OutlineLevelStyle, "text:outline-style", 0, false } 0064 }; 0065 0066 static const unsigned int numStyleData = sizeof(styleData) / sizeof(*styleData); 0067 0068 static const struct { 0069 KoGenStyle::Type m_type; 0070 const char * m_elementName; 0071 const char * m_propertiesElementName; 0072 bool m_drawElement; 0073 } autoStyleData[] = { 0074 { KoGenStyle::TextAutoStyle, "style:style", "style:text-properties", false }, 0075 { KoGenStyle::ParagraphAutoStyle, "style:style", "style:paragraph-properties", false }, 0076 { KoGenStyle::SectionAutoStyle, "style:style", "style:section-properties", false }, 0077 { KoGenStyle::RubyAutoStyle, "style:style", "style:ruby-properties", false }, 0078 { KoGenStyle::TableAutoStyle, "style:style", "style:table-properties", false }, 0079 { KoGenStyle::TableColumnAutoStyle, "style:style", "style:table-column-properties", false }, 0080 { KoGenStyle::TableRowAutoStyle, "style:style", "style:table-row-properties", false }, 0081 { KoGenStyle::TableCellAutoStyle, "style:style", "style:table-cell-properties", false }, 0082 { KoGenStyle::GraphicAutoStyle, "style:style", "style:graphic-properties", false }, 0083 { KoGenStyle::PresentationAutoStyle, "style:style", "style:graphic-properties", false }, 0084 { KoGenStyle::DrawingPageAutoStyle, "style:style", "style:drawing-page-properties", false }, 0085 { KoGenStyle::ChartAutoStyle, "style:style", "style:chart-properties", false }, 0086 { KoGenStyle::PageLayoutStyle, "style:page-layout", "style:page-layout-properties", false }, 0087 { KoGenStyle::ListAutoStyle, "text:list-style", 0, false }, 0088 { KoGenStyle::NumericNumberStyle, "number:number-style", 0, false }, 0089 { KoGenStyle::NumericFractionStyle, "number:number-style", 0, false }, 0090 { KoGenStyle::NumericScientificStyle, "number:number-style", 0, false }, 0091 { KoGenStyle::NumericDateStyle, "number:date-style", 0, false }, 0092 { KoGenStyle::NumericTimeStyle, "number:time-style", 0, false }, 0093 { KoGenStyle::NumericPercentageStyle, "number:percentage-style", 0, false }, 0094 { KoGenStyle::NumericCurrencyStyle, "number:currency-style", 0, false }, 0095 { KoGenStyle::NumericBooleanStyle, "number:boolean-style", 0, false }, 0096 { KoGenStyle::NumericTextStyle, "number:text-style", 0, false } 0097 }; 0098 0099 static const unsigned int numAutoStyleData = sizeof(autoStyleData) / sizeof(*autoStyleData); 0100 0101 static void insertRawOdfStyles(const QByteArray& xml, QByteArray& styles) 0102 { 0103 if (xml.isEmpty()) 0104 return; 0105 if (!styles.isEmpty() && !styles.endsWith('\n') && !xml.startsWith('\n')) { 0106 styles.append('\n'); 0107 } 0108 styles.append(xml); 0109 } 0110 0111 class Q_DECL_HIDDEN KoGenStyles::Private 0112 { 0113 public: 0114 Private(KoGenStyles *q) : q(q) 0115 { 0116 } 0117 0118 ~Private() 0119 { 0120 } 0121 0122 QVector<KoGenStyles::NamedStyle> styles(bool autoStylesInStylesDotXml, KoGenStyle::Type type) const; 0123 void saveOdfAutomaticStyles(KoXmlWriter* xmlWriter, bool autoStylesInStylesDotXml, 0124 const QByteArray& rawOdfAutomaticStyles) const; 0125 void saveOdfDocumentStyles(KoXmlWriter* xmlWriter) const; 0126 void saveOdfMasterStyles(KoXmlWriter* xmlWriter) const; 0127 QString makeUniqueName(const QString& base, const QByteArray &family, InsertionFlags flags) const; 0128 0129 /** 0130 * Save font face declarations 0131 * 0132 * This creates the office:font-face-decls tag containing all font face 0133 * declarations 0134 */ 0135 void saveOdfFontFaceDecls(KoXmlWriter* xmlWriter) const; 0136 0137 /// style definition -> name 0138 StyleMap styleMap; 0139 0140 /// Map with the style name as key. 0141 /// This map is mainly used to check for name uniqueness 0142 QMap<QByteArray, QSet<QString> > styleNames; 0143 QMap<QByteArray, QSet<QString> > autoStylesInStylesDotXml; 0144 0145 /// List of styles (used to preserve ordering) 0146 QVector<KoGenStyles::NamedStyle> styleList; 0147 0148 /// map for saving default styles 0149 QMap<int, KoGenStyle> defaultStyles; 0150 0151 /// font faces 0152 QMap<QString, KoFontFace> fontFaces; 0153 0154 StyleMap::iterator insertStyle(const KoGenStyle &style, const QString &name, InsertionFlags flags); 0155 0156 struct RelationTarget { 0157 QString target; // the style we point to 0158 QString attribute; // the attribute name used for the relation 0159 }; 0160 QHash<QString, RelationTarget> relations; // key is the name of the source style 0161 0162 QByteArray rawOdfDocumentStyles; 0163 QByteArray rawOdfAutomaticStyles_stylesDotXml; 0164 QByteArray rawOdfAutomaticStyles_contentDotXml; 0165 QByteArray rawOdfMasterStyles; 0166 QByteArray rawOdfFontFaceDecls; 0167 0168 KoGenStyles *q; 0169 }; 0170 0171 QVector<KoGenStyles::NamedStyle> KoGenStyles::Private::styles(bool autoStylesInStylesDotXml, KoGenStyle::Type type) const 0172 { 0173 QVector<KoGenStyles::NamedStyle> lst; 0174 QVector<KoGenStyles::NamedStyle>::const_iterator it = styleList.constBegin(); 0175 const QVector<KoGenStyles::NamedStyle>::const_iterator end = styleList.constEnd(); 0176 for (; it != end ; ++it) { 0177 if ((*it).style->type() == type && (*it).style->autoStyleInStylesDotXml() == autoStylesInStylesDotXml) { 0178 lst.append(*it); 0179 } 0180 } 0181 return lst; 0182 } 0183 0184 void KoGenStyles::Private::saveOdfAutomaticStyles(KoXmlWriter* xmlWriter, bool autoStylesInStylesDotXml, 0185 const QByteArray& rawOdfAutomaticStyles) const 0186 { 0187 xmlWriter->startElement("office:automatic-styles"); 0188 0189 for (uint i = 0; i < numAutoStyleData; ++i) { 0190 QVector<KoGenStyles::NamedStyle> stylesList = styles(autoStylesInStylesDotXml, autoStyleData[i].m_type); 0191 QVector<KoGenStyles::NamedStyle>::const_iterator it = stylesList.constBegin(); 0192 for (; it != stylesList.constEnd() ; ++it) { 0193 (*it).style->writeStyle(xmlWriter, *q, autoStyleData[i].m_elementName, (*it).name, 0194 autoStyleData[i].m_propertiesElementName, true, autoStyleData[i].m_drawElement); 0195 } 0196 } 0197 0198 if (!rawOdfAutomaticStyles.isEmpty()) { 0199 xmlWriter->addCompleteElement(rawOdfAutomaticStyles.constData()); 0200 } 0201 0202 xmlWriter->endElement(); // office:automatic-styles 0203 } 0204 0205 void KoGenStyles::Private::saveOdfDocumentStyles(KoXmlWriter* xmlWriter) const 0206 { 0207 xmlWriter->startElement("office:styles"); 0208 0209 for (uint i = 0; i < numStyleData; ++i) { 0210 const QMap<int, KoGenStyle>::const_iterator it(defaultStyles.constFind(styleData[i].m_type)); 0211 if (it != defaultStyles.constEnd()) { 0212 it.value().writeStyle(xmlWriter, *q, "style:default-style", "", 0213 styleData[i].m_propertiesElementName, true, styleData[i].m_drawElement); 0214 } 0215 } 0216 0217 for (uint i = 0; i < numStyleData; ++i) { 0218 QVector<KoGenStyles::NamedStyle> stylesList(styles(false, styleData[i].m_type)); 0219 QVector<KoGenStyles::NamedStyle>::const_iterator it = stylesList.constBegin(); 0220 for (; it != stylesList.constEnd() ; ++it) { 0221 if (relations.contains(it->name)) { 0222 KoGenStyles::Private::RelationTarget relation = relations.value(it->name); 0223 KoGenStyle styleCopy = *(*it).style; 0224 styleCopy.addAttribute(relation.attribute, relation.target); 0225 styleCopy.writeStyle(xmlWriter, *q, styleData[i].m_elementName, (*it).name, 0226 styleData[i].m_propertiesElementName, true, styleData[i].m_drawElement); 0227 } else { 0228 (*it).style->writeStyle(xmlWriter, *q, styleData[i].m_elementName, (*it).name, 0229 styleData[i].m_propertiesElementName, true, styleData[i].m_drawElement); 0230 } 0231 } 0232 } 0233 0234 if (!rawOdfDocumentStyles.isEmpty()) { 0235 xmlWriter->addCompleteElement(rawOdfDocumentStyles.constData()); 0236 } 0237 0238 xmlWriter->endElement(); // office:styles 0239 } 0240 0241 void KoGenStyles::Private::saveOdfMasterStyles(KoXmlWriter* xmlWriter) const 0242 { 0243 xmlWriter->startElement("office:master-styles"); 0244 0245 QVector<KoGenStyles::NamedStyle> stylesList = styles(false, KoGenStyle::MasterPageStyle); 0246 QVector<KoGenStyles::NamedStyle>::const_iterator it = stylesList.constBegin(); 0247 for (; it != stylesList.constEnd() ; ++it) { 0248 (*it).style->writeStyle(xmlWriter, *q, "style:master-page", (*it).name, 0); 0249 } 0250 0251 if (!rawOdfMasterStyles.isEmpty()) { 0252 xmlWriter->addCompleteElement(rawOdfMasterStyles.constData()); 0253 } 0254 0255 xmlWriter->endElement(); // office:master-styles 0256 } 0257 0258 void KoGenStyles::Private::saveOdfFontFaceDecls(KoXmlWriter* xmlWriter) const 0259 { 0260 if (fontFaces.isEmpty()) 0261 return; 0262 0263 xmlWriter->startElement("office:font-face-decls"); 0264 for (QMap<QString, KoFontFace>::ConstIterator it(fontFaces.constBegin()); 0265 it != fontFaces.constEnd(); ++it) 0266 { 0267 it.value().saveOdf(xmlWriter); 0268 } 0269 0270 if (!rawOdfFontFaceDecls.isEmpty()) { 0271 xmlWriter->addCompleteElement(rawOdfFontFaceDecls.constData()); 0272 } 0273 0274 xmlWriter->endElement(); // office:font-face-decls 0275 } 0276 0277 QString KoGenStyles::Private::makeUniqueName(const QString& base, const QByteArray &family, InsertionFlags flags) const 0278 { 0279 // If this name is not used yet, and numbering isn't forced, then the given name is ok. 0280 if ((flags & DontAddNumberToName) 0281 && !autoStylesInStylesDotXml[family].contains(base) 0282 && !styleNames[family].contains(base)) 0283 return base; 0284 int num = 1; 0285 QString name; 0286 do { 0287 name = base + QString::number(num++); 0288 } while (autoStylesInStylesDotXml[family].contains(name) 0289 || styleNames[family].contains(name)); 0290 return name; 0291 } 0292 0293 //------------------------ 0294 0295 KoGenStyles::KoGenStyles() 0296 : d(new Private(this)) 0297 { 0298 } 0299 0300 KoGenStyles::~KoGenStyles() 0301 { 0302 delete d; 0303 } 0304 0305 QString KoGenStyles::insert(const KoGenStyle& style, const QString& baseName, InsertionFlags flags) 0306 { 0307 // if it is a default style it has to be saved differently 0308 if (style.isDefaultStyle()) { 0309 // we can have only one default style per type 0310 Q_ASSERT(!d->defaultStyles.contains(style.type())); 0311 // default style is only possible for style:style in office:style types 0312 Q_ASSERT(style.type() == KoGenStyle::TextStyle || 0313 style.type() == KoGenStyle::ParagraphStyle || 0314 style.type() == KoGenStyle::SectionStyle || 0315 style.type() == KoGenStyle::RubyStyle || 0316 style.type() == KoGenStyle::TableStyle || 0317 style.type() == KoGenStyle::TableColumnStyle || 0318 style.type() == KoGenStyle::TableRowStyle || 0319 style.type() == KoGenStyle::TableCellStyle || 0320 style.type() == KoGenStyle::GraphicStyle || 0321 style.type() == KoGenStyle::PresentationStyle || 0322 style.type() == KoGenStyle::DrawingPageStyle || 0323 style.type() == KoGenStyle::ChartStyle); 0324 0325 d->defaultStyles.insert(style.type(), style); 0326 // default styles don't have a name 0327 return QString(); 0328 } 0329 0330 if (flags & AllowDuplicates) { 0331 StyleMap::iterator it = d->insertStyle(style, baseName, flags); 0332 return it.value(); 0333 } 0334 0335 StyleMap::iterator it = d->styleMap.find(style); 0336 if (it == d->styleMap.end()) { 0337 // Not found, try if this style is in fact equal to its parent (the find above 0338 // wouldn't have found it, due to m_parentName being set). 0339 if (!style.parentName().isEmpty()) { 0340 KoGenStyle testStyle(style); 0341 const KoGenStyle* parentStyle = this->style(style.parentName(), style.familyName()); // ## linear search 0342 if (!parentStyle) { 0343 debugOdf << "baseName=" << baseName << "parent style" << style.parentName() 0344 << "not found in collection"; 0345 } else { 0346 // TODO remove 0347 if (testStyle.m_familyName != parentStyle->m_familyName) { 0348 warnOdf << "baseName=" << baseName << "family=" << testStyle.m_familyName 0349 << "parent style" << style.parentName() << "has a different family:" 0350 << parentStyle->m_familyName; 0351 } 0352 0353 testStyle.m_parentName = parentStyle->m_parentName; 0354 // Exclude the type from the comparison. It's ok for an auto style 0355 // to have a user style as parent; they can still be identical 0356 testStyle.m_type = parentStyle->m_type; 0357 // Also it's ok to not have the display name of the parent style 0358 // in the auto style 0359 QMap<QString, QString>::const_iterator it = parentStyle->m_attributes.find("style:display-name"); 0360 if (it != parentStyle->m_attributes.end()) 0361 testStyle.addAttribute("style:display-name", *it); 0362 0363 if (*parentStyle == testStyle) 0364 return style.parentName(); 0365 } 0366 } 0367 0368 it = d->insertStyle(style, baseName, flags); 0369 } 0370 return it.value(); 0371 } 0372 0373 KoGenStyles::StyleMap::iterator KoGenStyles::Private::insertStyle(const KoGenStyle &style, 0374 const QString& baseName, InsertionFlags flags) 0375 { 0376 QString styleName(baseName); 0377 if (styleName.isEmpty()) { 0378 switch (style.type()) { 0379 case KoGenStyle::ParagraphAutoStyle: styleName = 'P'; break; 0380 case KoGenStyle::ListAutoStyle: styleName = 'L'; break; 0381 case KoGenStyle::TextAutoStyle: styleName = 'T'; break; 0382 default: 0383 styleName = 'A'; // for "auto". 0384 } 0385 flags &= ~DontAddNumberToName; // i.e. force numbering 0386 } 0387 styleName = makeUniqueName(styleName, style.m_familyName, flags); 0388 if (style.autoStyleInStylesDotXml()) 0389 autoStylesInStylesDotXml[style.m_familyName].insert(styleName); 0390 else 0391 styleNames[style.m_familyName].insert(styleName); 0392 KoGenStyles::StyleMap::iterator it = styleMap.insert(style, styleName); 0393 NamedStyle s; 0394 s.style = &it.key(); 0395 s.name = styleName; 0396 styleList.append(s); 0397 return it; 0398 } 0399 0400 KoGenStyles::StyleMap KoGenStyles::styles() const 0401 { 0402 return d->styleMap; 0403 } 0404 0405 QVector<KoGenStyles::NamedStyle> KoGenStyles::styles(KoGenStyle::Type type) const 0406 { 0407 return d->styles(false, type); 0408 } 0409 0410 const KoGenStyle* KoGenStyles::style(const QString &name, const QByteArray &family) const 0411 { 0412 QVector<KoGenStyles::NamedStyle>::const_iterator it = d->styleList.constBegin(); 0413 const QVector<KoGenStyles::NamedStyle>::const_iterator end = d->styleList.constEnd(); 0414 for (; it != end ; ++it) { 0415 if ((*it).name == name && (*it).style->familyName() == family) { 0416 return (*it).style; 0417 } 0418 } 0419 return 0; 0420 } 0421 0422 KoGenStyle* KoGenStyles::styleForModification(const QString &name, const QByteArray &family) 0423 { 0424 return const_cast<KoGenStyle *>(style(name, family)); 0425 } 0426 0427 void KoGenStyles::markStyleForStylesXml(const QString &name, const QByteArray &family) 0428 { 0429 Q_ASSERT(d->styleNames[family].contains(name)); 0430 d->styleNames[family].remove(name); 0431 d->autoStylesInStylesDotXml[family].insert(name); 0432 styleForModification(name, family)->setAutoStyleInStylesDotXml(true); 0433 } 0434 0435 void KoGenStyles::insertFontFace(const KoFontFace &face) 0436 { 0437 Q_ASSERT(!face.isNull()); 0438 if (face.isNull()) { 0439 warnOdf << "This font face is null and will not be added to styles: set at least the name"; 0440 return; 0441 } 0442 d->fontFaces.insert(face.name(), face); // replaces prev item 0443 } 0444 0445 KoFontFace KoGenStyles::fontFace(const QString& name) const 0446 { 0447 return d->fontFaces.value(name); 0448 } 0449 0450 bool KoGenStyles::saveOdfStylesDotXml(KoStore* store, KoXmlWriter* manifestWriter) const 0451 { 0452 if (!store->open("styles.xml")) 0453 return false; 0454 0455 manifestWriter->addManifestEntry("styles.xml", "text/xml"); 0456 0457 KoStoreDevice stylesDev(store); 0458 KoXmlWriter* stylesWriter = KoOdfWriteStore::createOasisXmlWriter(&stylesDev, "office:document-styles"); 0459 0460 d->saveOdfFontFaceDecls(stylesWriter); 0461 d->saveOdfDocumentStyles(stylesWriter); 0462 d->saveOdfAutomaticStyles(stylesWriter, true, d->rawOdfAutomaticStyles_stylesDotXml); 0463 d->saveOdfMasterStyles(stylesWriter); 0464 0465 stylesWriter->endElement(); // root element (office:document-styles) 0466 stylesWriter->endDocument(); 0467 delete stylesWriter; 0468 0469 if (!store->close()) // done with styles.xml 0470 return false; 0471 0472 return true; 0473 } 0474 0475 void KoGenStyles::saveOdfStyles(StylesPlacement placement, KoXmlWriter* xmlWriter) const 0476 { 0477 switch (placement) { 0478 case DocumentStyles: 0479 d->saveOdfDocumentStyles(xmlWriter); 0480 break; 0481 case MasterStyles: 0482 d->saveOdfMasterStyles(xmlWriter); 0483 break; 0484 case DocumentAutomaticStyles: 0485 d->saveOdfAutomaticStyles(xmlWriter, false, d->rawOdfAutomaticStyles_contentDotXml); 0486 break; 0487 case StylesXmlAutomaticStyles: 0488 d->saveOdfAutomaticStyles(xmlWriter, true, d->rawOdfAutomaticStyles_stylesDotXml); 0489 break; 0490 case FontFaceDecls: 0491 d->saveOdfFontFaceDecls(xmlWriter); 0492 break; 0493 } 0494 } 0495 0496 void KoGenStyles::insertRawOdfStyles(StylesPlacement placement, const QByteArray& xml) 0497 { 0498 switch (placement) { 0499 case DocumentStyles: 0500 ::insertRawOdfStyles(xml, d->rawOdfDocumentStyles); 0501 break; 0502 case MasterStyles: 0503 ::insertRawOdfStyles(xml, d->rawOdfMasterStyles); 0504 break; 0505 case DocumentAutomaticStyles: 0506 ::insertRawOdfStyles(xml, d->rawOdfAutomaticStyles_contentDotXml); 0507 break; 0508 case StylesXmlAutomaticStyles: 0509 ::insertRawOdfStyles(xml, d->rawOdfAutomaticStyles_stylesDotXml); 0510 break; 0511 case FontFaceDecls: 0512 ::insertRawOdfStyles(xml, d->rawOdfFontFaceDecls); 0513 break; 0514 } 0515 } 0516 0517 void KoGenStyles::insertStyleRelation(const QString &source, const QString &target, const char *tagName) 0518 { 0519 KoGenStyles::Private::RelationTarget relation; 0520 relation.target = target; 0521 relation.attribute = QString(tagName); 0522 d->relations.insert(source, relation); 0523 } 0524 0525 QDebug operator<<(QDebug dbg, const KoGenStyles& styles) 0526 { 0527 dbg.nospace() << "KoGenStyles:"; 0528 QVector<KoGenStyles::NamedStyle>::const_iterator it = styles.d->styleList.constBegin(); 0529 const QVector<KoGenStyles::NamedStyle>::const_iterator end = styles.d->styleList.constEnd(); 0530 for (; it != end ; ++it) { 0531 dbg.nospace() << (*it).name; 0532 } 0533 for (QMap<QByteArray, QSet<QString> >::const_iterator familyIt(styles.d->styleNames.constBegin()); familyIt != styles.d->styleNames.constEnd(); ++familyIt) { 0534 for (QSet<QString>::const_iterator it(familyIt.value().constBegin()); it != familyIt.value().constEnd(); ++it) { 0535 dbg.space() << "style:" << *it; 0536 } 0537 } 0538 #ifndef NDEBUG 0539 for (QMap<QByteArray, QSet<QString> >::const_iterator familyIt(styles.d->autoStylesInStylesDotXml.constBegin()); familyIt != styles.d->autoStylesInStylesDotXml.constEnd(); ++familyIt) { 0540 for (QSet<QString>::const_iterator it(familyIt.value().constBegin()); it != familyIt.value().constEnd(); ++it) { 0541 dbg.space() << "auto style for style.xml:" << *it; 0542 } 0543 } 0544 #endif 0545 return dbg.space(); 0546 }