1 /* This file is part of the KDE project
2    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3    Copyright 2002, 2003 David Faure <faure@kde.org>
4    Copyright 2003 Nicolas GOUTTE <goutte@kde.org>
5    Copyright 2007, 2010 Thomas Zander <zander@kde.org>
6    Copyright 2009 Inge Wallin <inge@lysator.liu.se>
7 
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Library General Public
10    License as published by the Free Software Foundation; either
11    version 2 of the License, or (at your option) any later version.
12 
13    This library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Library General Public License for more details.
17 
18    You should have received a copy of the GNU Library General Public License
19    along with this library; see the file COPYING.LIB.  If not, write to
20    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22 */
23 
24 #include "KoPageLayout.h"
25 
26 #include <OdfDebug.h>
27 
28 #include "KoXmlNS.h"
29 #include "KoUnit.h"
30 #include "KoXmlReader.h"
31 
saveOdf() const32 KoGenStyle KoPageLayout::saveOdf() const
33 {
34     KoGenStyle style(KoGenStyle::PageLayoutStyle);
35 
36     // Save page dimension.
37     style.addPropertyPt("fo:page-width", width);
38     style.addPropertyPt("fo:page-height", height);
39 
40     // Save margins. If all margins are the same, only one value needs to be saved.
41     if (leftMargin == topMargin && leftMargin == rightMargin && leftMargin == bottomMargin) {
42         style.addPropertyPt("fo:margin", leftMargin);
43     }
44     else {
45         style.addPropertyPt("fo:margin-left", leftMargin);
46         style.addPropertyPt("fo:margin-right", rightMargin);
47         style.addPropertyPt("fo:margin-top", topMargin);
48         style.addPropertyPt("fo:margin-bottom", bottomMargin);
49     }
50 
51     // Save padding. If all paddings are the same, only one value needs to be saved.
52     if (leftPadding == topPadding && leftPadding == rightPadding && leftPadding == bottomPadding) {
53         style.addPropertyPt("fo:padding", leftPadding);
54     }
55     else {
56         style.addPropertyPt("fo:padding-left", leftPadding);
57         style.addPropertyPt("fo:padding-right", rightPadding);
58         style.addPropertyPt("fo:padding-top", topPadding);
59         style.addPropertyPt("fo:padding-bottom", bottomPadding);
60     }
61 
62     // If there are any page borders, add them to the style.
63     border.saveOdf(style);
64 
65     style.addProperty("style:print-orientation",
66                       (orientation == KoPageFormat::Landscape
67                        ? "landscape" : "portrait"));
68     return style;
69 }
70 
loadOdf(const KoXmlElement & style)71 void KoPageLayout::loadOdf(const KoXmlElement &style)
72 {
73     KoXmlElement  properties(KoXml::namedItemNS(style, KoXmlNS::style,
74                                                 "page-layout-properties"));
75 
76     if (!properties.isNull()) {
77         KoPageLayout standard;
78 
79         // Page dimension -- width / height
80         width = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "page-width"),
81                                    standard.width);
82         height = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "page-height"),
83                                     standard.height);
84 
85         // Page orientation
86         if (properties.attributeNS(KoXmlNS::style, "print-orientation", QString()) == "portrait")
87             orientation = KoPageFormat::Portrait;
88         else
89             orientation = KoPageFormat::Landscape;
90 
91         // Margins.  Check if there is one "margin" attribute and use it for all
92         // margins if there is.  Otherwise load the individual margins.
93         if (properties.hasAttributeNS(KoXmlNS::fo, "margin")) {
94             leftMargin  = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "margin"));
95             topMargin = leftMargin;
96             rightMargin = leftMargin;
97             bottomMargin = leftMargin;
98         } else {
99             /*
100                 If one of the individual margins is specified then the default for the others is zero.
101                 Otherwise all of them are set to 20mm.
102             */
103             qreal defaultValue = 0;
104             if (!(properties.hasAttributeNS(KoXmlNS::fo, "margin-left")
105                     || properties.hasAttributeNS(KoXmlNS::fo, "margin-top")
106                     || properties.hasAttributeNS(KoXmlNS::fo, "margin-right")
107                     || properties.hasAttributeNS(KoXmlNS::fo, "margin-bottom")))
108                 defaultValue = MM_TO_POINT(20.0); // no margin specified at all, lets make it 20mm
109 
110             leftMargin   = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "margin-left"), defaultValue);
111             topMargin    = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "margin-top"), defaultValue);
112             rightMargin  = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "margin-right"), defaultValue);
113             bottomMargin = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "margin-bottom"), defaultValue);
114         }
115 
116         // Padding.  Same reasoning as for margins
117         if (properties.hasAttributeNS(KoXmlNS::fo, "padding")) {
118             leftPadding  = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "padding"));
119             topPadding = leftPadding;
120             rightPadding = leftPadding;
121             bottomPadding = leftPadding;
122         }
123         else {
124             leftPadding   = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "padding-left"));
125             topPadding    = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "padding-top"));
126             rightPadding  = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "padding-right"));
127             bottomPadding = KoUnit::parseValue(properties.attributeNS(KoXmlNS::fo, "padding-bottom"));
128         }
129 
130         // Parse border properties if there are any.
131         border.loadOdf(properties);
132 
133         // guessFormat takes millimeters
134         if (orientation == KoPageFormat::Landscape)
135             format = KoPageFormat::guessFormat(POINT_TO_MM(height), POINT_TO_MM(width));
136         else
137             format = KoPageFormat::guessFormat(POINT_TO_MM(width), POINT_TO_MM(height));
138     }
139 }
140 
operator ==(const KoPageLayout & l) const141 bool KoPageLayout::operator==(const KoPageLayout &l) const
142 {
143     return qFuzzyCompare(width,l.width)
144         && qFuzzyCompare(height,l.height)
145         && qFuzzyCompare(leftMargin,l.leftMargin)
146         && qFuzzyCompare(rightMargin,l.rightMargin)
147         && qFuzzyCompare(topMargin,l.topMargin)
148         && qFuzzyCompare(bottomMargin,l.bottomMargin)
149         && qFuzzyCompare(pageEdge,l.pageEdge)
150         && qFuzzyCompare(bindingSide,l.bindingSide)
151         && border == l.border;
152 }
153 
operator !=(const KoPageLayout & l) const154 bool KoPageLayout::operator!=(const KoPageLayout& l) const
155 {
156     return !((*this) == l);
157 }
158 
KoPageLayout()159 KoPageLayout::KoPageLayout()
160   : format(KoPageFormat::defaultFormat())
161   , orientation(KoPageFormat::Portrait)
162   , width(MM_TO_POINT(KoPageFormat::width(format, orientation)))
163   , height(MM_TO_POINT(KoPageFormat::height(format, orientation)))
164   , leftMargin(MM_TO_POINT(20.0))
165   , rightMargin(MM_TO_POINT(20.0))
166   , topMargin(MM_TO_POINT(20.0))
167   , bottomMargin(MM_TO_POINT(20.0))
168   , pageEdge(-1)
169   , bindingSide(-1)
170   , leftPadding(0)
171   , rightPadding(0)
172   , topPadding(0)
173   , bottomPadding(0)
174   , border()
175 {
176 }
177