1 /* 2 For general Scribus (>=1.3.2) copyright and licensing information please refer 3 to the COPYING file provided with the program. Following this notice may exist 4 a copyright and/or license notice that predates the release of Scribus 1.3.2 5 for which a new license (GPL+exception) is in place. 6 */ 7 /* This file is part of the KDE project 8 Copyright (c) 2003 Lukas Tinkl <lukas@kde.org> 9 Copyright (c) 2003 David Faure <faure@kde.org> 10 11 This library is free software; you can redistribute it and/or 12 modify it under the terms of the GNU Library General Public 13 License as published by the Free Software Foundation; either 14 version 2 of the License, or (at your option) any later version. 15 16 This library is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Library General Public License for more details. 20 21 You should have received a copy of the GNU Library General Public License 22 along with this library; see the file COPYING.LIB. If not, write to 23 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24 Boston, MA 02110-1301, USA. 25 */ 26 27 #ifndef STYLESTACK_H 28 #define STYLESTACK_H 29 30 #include <QDomElement> 31 #include <QStringList> 32 #include <QList> 33 #include <QStack> 34 35 36 /** 37 * This class implements a stack for the different styles of an object. 38 * 39 * There can be several styles that are valid for one object. For example 40 * a textobject on a page has styles 'pr3' and 'P7' and a paragraph in 41 * that textobject has styles 'P1' and 'T3'. And some styles even have 42 * parent-styles... 43 * 44 * If you want to know if there is, for example, the attribute 'fo:font-family' 45 * for this paragraph, you have to look into style 'T3', 'P1', 'P7' and 'pr3'. 46 * When you find this attribute in one style you have to stop processing the list 47 * and take the found attribute for this object. 48 * 49 * This is what this class does. You can push styles on the stack while walking 50 * through the xml-tree to your object and then ask the stack if any of the styles 51 * provides a certain attribute. The stack will search from top to bottom, i.e. 52 * in our example from 'T3' to 'pr3' and return the first occurrence of the wanted 53 * attribute. 54 * 55 * So this is some sort of inheritance where the styles on top of the stack overwrite 56 * the same attribute of a lower style on the stack. 57 */ 58 class StyleStack 59 { 60 public: 61 StyleStack(); 62 virtual ~StyleStack(); 63 64 enum Mode 65 { 66 OODraw1x = 1, 67 OODraw2x = 2 68 }; 69 70 /** 71 * Set attribute analysis mode. 72 */ 73 void setMode( const StyleStack::Mode mode ); 74 75 /** 76 * Clears the complete stack. 77 */ 78 void clear(); 79 80 /** 81 * Save the current state of the stack. Any items added between 82 * this call and its corresponding restore() will be removed when calling restore(). 83 */ 84 void save(); 85 86 /** 87 * Restore the stack to the state it was at the corresponding save() call. 88 */ 89 void restore(); 90 91 /** 92 * Removes the style on top of the stack. 93 */ 94 void pop(); 95 96 /** 97 * Pushes the new style onto the stack. 98 */ 99 void push( const QDomElement& style ); 100 101 /** 102 * Check if any of the styles on the stack has an attribute called 'name'. 103 */ 104 bool hasAttribute( const QString& name ) const; 105 106 /** 107 * Search for the attribute called 'name', starting on top of the stack, 108 * and return it. 109 */ 110 QString attribute( const QString& name ) const; 111 112 /** 113 * Check if any of the styles on the stack has an attribute called 'name'-'detail' 114 * where detail is e.g. left, right, top or bottom. 115 * This allows to also find 'name' alone (e.g. padding implies padding-left, padding-right etc.) 116 */ 117 bool hasAttribute( const QString& name, const QString& detail ) const; 118 119 /** 120 * Search for the attribute called 'name', starting on top of the stack, 121 * and return it. 122 */ 123 QString attribute( const QString& name, const QString& detail ) const; 124 125 /** 126 * Check if any of the styles on the stack has a child node called 'name'. 127 */ 128 bool hasChildNode(const QString & name) const; 129 130 /** 131 * Search for a child node called 'name', starting on top of the stack, 132 * and return it. 133 */ 134 QDomNode childNode(const QString & name) const; 135 136 /** 137 * Special case for the current font size, due to special handling of fo:font-size="115%". 138 */ 139 double fontSize() const; 140 141 /** 142 * Return the name of the style specified by the user, 143 * i.e. not an auto style 144 */ 145 QString userStyleName() const; 146 147 private: 148 149 // Node names to look for style properties 150 QStringList m_nodeNames; 151 152 // For save/restore: stack of "marks". Each mark is an index in m_stack. 153 QStack<int> m_marks; 154 155 // We use QValueList instead of QValueStack because we need access to all styles 156 // not only the top one. 157 QList<QDomElement> m_stack; 158 159 // Get node name to look for according to property type 160 void fillNodeNameList( QStringList& names, const StyleStack::Mode mode ); 161 162 // Search a specific attribute amongst childs of an element 163 QDomElement searchAttribute( const QDomElement& element, const QStringList& names,const QString& name ) const; 164 165 // Search a specific attribute amongst childs of an element 166 QDomElement searchAttribute( const QDomElement& element, const QStringList& names, const QString& name, const QString& fullName ) const; 167 }; 168 169 170 #endif /* STYLESTACK_H */ 171