File indexing completed on 2024-05-12 16:35:03
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2007 Pierre Ducroquet <pinaraf@gmail.com> 0003 * Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org> 0004 * Copyright (C) 2008 Sebastian Sauer <mail@dipe.org> 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 #include "PageVariable.h" 0023 0024 #include "VariablesDebug.h" 0025 0026 #include <KoXmlReader.h> 0027 #include <KoXmlWriter.h> 0028 #include <KoProperties.h> 0029 #include <KoShape.h> 0030 #include <KoShapeSavingContext.h> 0031 #include <KoShapeLoadingContext.h> 0032 #include <KoXmlNS.h> 0033 #include <KoTextLayoutRootArea.h> 0034 #include <KoTextDocumentLayout.h> 0035 #include <KoTextDocument.h> 0036 0037 #include <QFontMetricsF> 0038 #include <QTextDocument> 0039 #include <QAbstractTextDocumentLayout> 0040 #include <QTextInlineObject> 0041 0042 PageVariable::PageVariable() 0043 : KoVariable(true), 0044 m_type(PageNumber), 0045 m_pageselect(KoTextPage::CurrentPage), 0046 m_pageadjust(0), 0047 m_fixed(false) 0048 { 0049 } 0050 0051 void PageVariable::readProperties(const KoProperties *props) 0052 { 0053 switch (props->intProperty("vartype")) { 0054 case 1: 0055 m_type = PageCount; 0056 break; 0057 case 2: 0058 m_type = PageNumber; 0059 break; 0060 case 3: 0061 m_type = PageContinuation; 0062 break; 0063 default: 0064 Q_ASSERT(false); 0065 break; 0066 } 0067 } 0068 0069 void PageVariable::propertyChanged(Property property, const QVariant &value) 0070 { 0071 switch (m_type) { 0072 case PageCount: 0073 if (property == KoInlineObject::PageCount) { 0074 KoOdfNumberDefinition defaultDefinition; // FIXME Should fetch from pagestyle 0075 QString newValue = value.toInt() >= 0 ? m_numberFormat.formattedNumber(value.toInt(), &defaultDefinition) : QString(); 0076 setValue(newValue); 0077 } 0078 break; 0079 case PageNumber: 0080 break; 0081 case PageContinuation: 0082 break; 0083 } 0084 } 0085 0086 void PageVariable::resize(const QTextDocument *document, QTextInlineObject &object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd) 0087 { 0088 KoTextPage *page = 0; 0089 if (m_type != PageCount) { 0090 #if 0 // the code is left here to do some testing 0091 KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(document->documentLayout()); 0092 KoTextLayoutRootArea *rootArea = 0; 0093 KoTextPage *page2 = 0; 0094 if (lay) { 0095 rootArea = lay->rootAreaForPosition(posInDocument); 0096 if (rootArea) { 0097 page2 = rootArea->page(); 0098 } 0099 } 0100 #endif 0101 page = document->resource(KoTextDocument::LayoutTextPage, KoTextDocument::LayoutTextPageUrl).value<KoTextPage*>(); 0102 } 0103 int pagenumber = 0; 0104 0105 switch (m_type) { 0106 case PageCount: 0107 break; 0108 case PageNumber: 0109 if (page) { 0110 // the text is not yet layouted therefore we don't get the rootArea 0111 // if we don't do that we get an endless change of the variable. 0112 QString currentValue = value(); 0113 if (currentValue.isEmpty() || ! m_fixed) { 0114 pagenumber = page->visiblePageNumber(m_pageselect, m_pageadjust); 0115 KoOdfNumberDefinition defaultDefinition; // FIXME Should fetch from pagestyle 0116 QString newValue = pagenumber >= 0 ? m_numberFormat.formattedNumber(pagenumber, &defaultDefinition) : QString(); 0117 // only update value when changed 0118 if (currentValue != newValue) { 0119 setValue(newValue); 0120 } 0121 } 0122 } 0123 break; 0124 case PageContinuation: 0125 if (page) { 0126 // the text is not yet layouted therefore we don't get the rootArea 0127 // if we don't do that we get an endless change of the variable. 0128 pagenumber = page->visiblePageNumber(m_pageselect); 0129 setValue(pagenumber >= 0 ? m_continuation : QString()); 0130 } 0131 break; 0132 } 0133 KoVariable::resize(document, object, posInDocument, format, pd); 0134 } 0135 0136 void PageVariable::saveOdf(KoShapeSavingContext & context) 0137 { 0138 KoXmlWriter *writer = &context.xmlWriter(); 0139 switch (m_type) { 0140 case PageCount: 0141 // <text:page-count>3</text:page-count> 0142 writer->startElement("text:page-count", false); 0143 writer->addTextNode(value()); 0144 writer->endElement(); 0145 break; 0146 case PageNumber: 0147 // <text:page-number text:select-page="current" text:page-adjust="2" text:fixed="true">3</text:page-number> 0148 writer->startElement("text:page-number", false); 0149 0150 if (m_pageselect == KoTextPage::CurrentPage) 0151 writer->addAttribute("text:select-page", "current"); 0152 else if (m_pageselect == KoTextPage::PreviousPage) 0153 writer->addAttribute("text:select-page", "previous"); 0154 else if (m_pageselect == KoTextPage::NextPage) 0155 writer->addAttribute("text:select-page", "next"); 0156 0157 if (m_pageadjust != 0) 0158 writer->addAttribute("text:page-adjust", QString::number(m_pageadjust)); 0159 0160 m_numberFormat.saveOdf(writer); 0161 0162 if (m_fixed) 0163 writer->addAttribute("text:fixed", "true"); 0164 0165 writer->addTextNode(value()); 0166 writer->endElement(); 0167 break; 0168 case PageContinuation: 0169 // <text:page-continuation-string text:select-page="previous">The Text</text:page-continuation-string> 0170 writer->startElement("page-continuation-string", false); 0171 0172 if (m_pageselect == KoTextPage::PreviousPage) 0173 writer->addAttribute("text:select-page", "previous"); 0174 else if (m_pageselect == KoTextPage::NextPage) 0175 writer->addAttribute("text:select-page", "next"); 0176 0177 writer->addTextNode(m_continuation); 0178 writer->endElement(); 0179 break; 0180 } 0181 } 0182 0183 bool PageVariable::loadOdf(const KoXmlElement & element, KoShapeLoadingContext & context) 0184 { 0185 Q_UNUSED(context); 0186 const QString localName(element.localName()); 0187 if (localName == "page-count") { 0188 m_type = PageCount; 0189 0190 m_numberFormat.loadOdf(element); 0191 } else if (localName == "page-number") { 0192 m_type = PageNumber; 0193 0194 // The text:select-page attribute is used to display the number of the previous or the following 0195 // page rather than the number of the current page. 0196 QString pageselect = element.attributeNS(KoXmlNS::text, "select-page", QString()); 0197 if (pageselect == "previous") 0198 m_pageselect = KoTextPage::PreviousPage; 0199 else if (pageselect == "next") 0200 m_pageselect = KoTextPage::NextPage; 0201 else // "current" 0202 m_pageselect = KoTextPage::CurrentPage; 0203 0204 // The value of a page number field can be adjusted by a specified number, allowing the display 0205 // of page numbers of following or preceding pages. The adjustment amount is specified using 0206 // the text:page-adjust attribute. 0207 m_pageadjust = element.attributeNS(KoXmlNS::text, "page-adjust", QString()).toInt(); 0208 0209 m_numberFormat.loadOdf(element); 0210 0211 // The text:fixed attribute specifies whether or not the value of a field element is fixed. If 0212 // the value of a field is fixed, the value of the field element to which this attribute is 0213 // attached is preserved in all future edits of the document. If the value of the field is not 0214 // fixed, the value of the field may be replaced by a new value when the document is edited. 0215 m_fixed = element.attributeNS(KoXmlNS::text, "fixed", QString()) == "true"; 0216 } else if (localName == "page-continuation-string") { 0217 m_type = PageContinuation; 0218 0219 // This attribute specifies whether to check for a previous or next page and if the page exists, the 0220 // continuation text is printed. 0221 QString pageselect = element.attributeNS(KoXmlNS::text, "select-page", QString()); 0222 if (pageselect == "previous") 0223 m_pageselect = KoTextPage::PreviousPage; 0224 else if (pageselect == "next") 0225 m_pageselect = KoTextPage::NextPage; 0226 else 0227 m_pageselect = KoTextPage::CurrentPage; 0228 0229 // The text to display 0230 m_continuation = element.text(); 0231 } 0232 return true; 0233 }