Warning, file /office/calligra/libs/text/KoSection.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright (c) 2011 Boudewijn Rempt <boud@valdyas.org> 0003 * Copyright (c) 2014-2015 Denis Kuplyakov <dener.kup@gmail.com> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoSection.h" 0022 0023 #include <KoXmlNS.h> 0024 #include <KoXmlReader.h> 0025 #include <KoTextSharedLoadingData.h> 0026 #include <KoShapeSavingContext.h> 0027 #include <KoXmlWriter.h> 0028 #include <KoSectionStyle.h> 0029 #include <KoSectionModel.h> 0030 #include <KoSectionEnd.h> 0031 #include <KoTextDocument.h> 0032 #include <KoTextInlineRdf.h> 0033 0034 #include <QTextBlock> 0035 0036 #include "TextDebug.h" 0037 0038 class KoSectionPrivate 0039 { 0040 public: 0041 explicit KoSectionPrivate(const QTextCursor &cursor, const QString &_name, KoSection *_parent) 0042 : document(cursor.block().document()) 0043 , name(_name) 0044 , sectionStyle(0) 0045 , boundingCursorStart(cursor) 0046 , boundingCursorEnd(cursor) 0047 , parent(_parent) 0048 , inlineRdf(0) 0049 { 0050 } 0051 0052 const QTextDocument *document; 0053 0054 QString condition; 0055 QString display; 0056 QString name; 0057 QString text_protected; 0058 QString protection_key; 0059 QString protection_key_digest_algorithm; 0060 QString style_name; 0061 KoSectionStyle *sectionStyle; 0062 0063 QScopedPointer<KoSectionEnd> sectionEnd; ///< pointer to the corresponding section end 0064 int level; ///< level of the section in document, root sections have 0 level 0065 QTextCursor boundingCursorStart; ///< This cursor points to the start of the section 0066 QTextCursor boundingCursorEnd; ///< This cursor points to the end of the section (excluding paragraph symbol) 0067 0068 // Boundings explanation: 0069 // 0070 // |S|e|c|t|i|o|n|...|t|e|x|t|P| 0071 // ^ ^ 0072 // |--- Start |-- End 0073 0074 QVector<KoSection *> children; ///< List of the section's childrens 0075 KoSection *parent; ///< Parent of the section 0076 0077 KoTextInlineRdf *inlineRdf; ///< Handling associated RDF 0078 }; 0079 0080 KoSection::KoSection(const QTextCursor &cursor, const QString &name, KoSection *parent) 0081 : d_ptr(new KoSectionPrivate(cursor, name, parent)) 0082 { 0083 Q_D(KoSection); 0084 0085 d->boundingCursorStart.setKeepPositionOnInsert(true); // Start cursor should stay on place 0086 d->boundingCursorEnd.setKeepPositionOnInsert(false); // and end one should move forward 0087 0088 if (parent) { 0089 d->level = parent->level() + 1; 0090 } else { 0091 d->level = 0; 0092 } 0093 } 0094 0095 KoSection::~KoSection() 0096 { 0097 // Here scoped pointer will delete sectionEnd 0098 } 0099 0100 QString KoSection::name() const 0101 { 0102 Q_D(const KoSection); 0103 return d->name; 0104 } 0105 0106 QPair<int, int> KoSection::bounds() const 0107 { 0108 Q_D(const KoSection); 0109 return QPair<int, int>( 0110 d->boundingCursorStart.position(), 0111 d->boundingCursorEnd.position() 0112 ); 0113 } 0114 0115 int KoSection::level() const 0116 { 0117 Q_D(const KoSection); 0118 return d->level; 0119 } 0120 0121 bool KoSection::loadOdf(const KoXmlElement &element, KoTextSharedLoadingData *sharedData, bool stylesDotXml) 0122 { 0123 Q_D(KoSection); 0124 // check whether we really are a section 0125 if (element.namespaceURI() == KoXmlNS::text && element.localName() == "section") { 0126 // get all the attributes 0127 d->condition = element.attributeNS(KoXmlNS::text, "condition"); 0128 d->display = element.attributeNS(KoXmlNS::text, "display"); 0129 0130 if (d->display == "condition" && d->condition.isEmpty()) { 0131 warnText << "Section display is set to \"condition\", but condition is empty."; 0132 } 0133 0134 QString newName = element.attributeNS(KoXmlNS::text, "name"); 0135 if (!KoTextDocument(d->document).sectionModel()->setName(this, newName)) { 0136 warnText << "Section name \"" << newName 0137 << "\" must be unique or is invalid. Resetting it to " << name(); 0138 } 0139 0140 d->text_protected = element.attributeNS(KoXmlNS::text, "text-protected"); 0141 d->protection_key = element.attributeNS(KoXmlNS::text, "protection-key"); 0142 d->protection_key_digest_algorithm = element.attributeNS(KoXmlNS::text, "protection-key-algorithm"); 0143 d->style_name = element.attributeNS(KoXmlNS::text, "style-name", ""); 0144 0145 if (!d->style_name.isEmpty()) { 0146 d->sectionStyle = sharedData->sectionStyle(d->style_name, stylesDotXml); 0147 } 0148 0149 // lets handle associated xml:id 0150 if (element.hasAttribute("id")) { 0151 KoTextInlineRdf* inlineRdf = new KoTextInlineRdf(const_cast<QTextDocument *>(d->document), this); 0152 if (inlineRdf->loadOdf(element)) { 0153 d->inlineRdf = inlineRdf; 0154 } else { 0155 delete inlineRdf; 0156 inlineRdf = 0; 0157 } 0158 } 0159 0160 return true; 0161 } 0162 return false; 0163 } 0164 0165 void KoSection::saveOdf(KoShapeSavingContext &context) const 0166 { 0167 Q_D(const KoSection); 0168 KoXmlWriter *writer = &context.xmlWriter(); 0169 Q_ASSERT(writer); 0170 writer->startElement("text:section", false); 0171 0172 if (!d->condition.isEmpty()) writer->addAttribute("text:condition", d->condition); 0173 if (!d->display.isEmpty()) writer->addAttribute("text:display", d->condition); 0174 if (!d->name.isEmpty()) writer->addAttribute("text:name", d->name); 0175 if (!d->text_protected.isEmpty()) writer->addAttribute("text:text-protected", d->text_protected); 0176 if (!d->protection_key.isEmpty()) writer->addAttribute("text:protection-key", d->protection_key); 0177 if (!d->protection_key_digest_algorithm.isEmpty()) { 0178 writer->addAttribute("text:protection-key-digest-algorithm", d->protection_key_digest_algorithm); 0179 } 0180 if (!d->style_name.isEmpty()) writer->addAttribute("text:style-name", d->style_name); 0181 0182 if (d->inlineRdf) { 0183 d->inlineRdf->saveOdf(context, writer); 0184 } 0185 } 0186 0187 void KoSection::setSectionEnd(KoSectionEnd* sectionEnd) 0188 { 0189 Q_D(KoSection); 0190 d->sectionEnd.reset(sectionEnd); 0191 } 0192 0193 void KoSection::setName(const QString &name) 0194 { 0195 Q_D(KoSection); 0196 d->name = name; 0197 } 0198 0199 void KoSection::setLevel(int level) 0200 { 0201 Q_D(KoSection); 0202 d->level = level; 0203 } 0204 0205 void KoSection::setKeepEndBound(bool state) 0206 { 0207 Q_D(KoSection); 0208 d->boundingCursorEnd.setKeepPositionOnInsert(state); 0209 } 0210 0211 KoSection *KoSection::parent() const 0212 { 0213 Q_D(const KoSection); 0214 return d->parent; 0215 } 0216 0217 QVector<KoSection *> KoSection::children() const 0218 { 0219 Q_D(const KoSection); 0220 return d->children; 0221 } 0222 0223 void KoSection::insertChild(int childIdx, KoSection *section) 0224 { 0225 Q_D(KoSection); 0226 d->children.insert(childIdx, section); 0227 } 0228 0229 void KoSection::removeChild(int childIdx) 0230 { 0231 Q_D(KoSection); 0232 d->children.remove(childIdx); 0233 } 0234 0235 KoTextInlineRdf *KoSection::inlineRdf() const 0236 { 0237 Q_D(const KoSection); 0238 return d->inlineRdf; 0239 } 0240 0241 void KoSection::setInlineRdf(KoTextInlineRdf *inlineRdf) 0242 { 0243 Q_D(KoSection); 0244 d->inlineRdf = inlineRdf; 0245 }