F:/KPlato/koffice/libs/kofficecore/KoStyleStack.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (c) 2003 Lukas Tinkl <lukas@kde.org>
00003    Copyright (c) 2003 David Faure <faure@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "KoStyleStack.h"
00022 #include "KoUnit.h"
00023 #include "KoDom.h"
00024 #include "KoXmlNS.h"
00025 
00026 #include <kdebug.h>
00027 //Added by qt3to4:
00028 #include <Q3ValueList>
00029 
00030 //#define DEBUG_STYLESTACK
00031 
00032 KoStyleStack::KoStyleStack()
00033     : m_styleNSURI( KoXmlNS::style ), m_foNSURI( KoXmlNS::fo )
00034 {
00035     clear();
00036 }
00037 
00038 KoStyleStack::KoStyleStack( const char* styleNSURI, const char* foNSURI )
00039     : m_propertiesTagName( "properties" ), m_styleNSURI( styleNSURI ), m_foNSURI( foNSURI )
00040 {
00041     clear();
00042 }
00043 
00044 KoStyleStack::~KoStyleStack()
00045 {
00046 }
00047 
00048 void KoStyleStack::clear()
00049 {
00050     m_stack.clear();
00051 #ifdef DEBUG_STYLESTACK
00052     kDebug(30003) << "clear!" << endl;
00053 #endif
00054 }
00055 
00056 void KoStyleStack::save()
00057 {
00058     m_marks.push( m_stack.count() );
00059 #ifdef DEBUG_STYLESTACK
00060     kDebug(30003) << "save (level " << m_marks.count() << ") -> index " << m_stack.count() << endl;
00061 #endif
00062 }
00063 
00064 void KoStyleStack::restore()
00065 {
00066     Q_ASSERT( !m_marks.isEmpty() );
00067     int toIndex = m_marks.pop();
00068 #ifdef DEBUG_STYLESTACK
00069     kDebug(30003) << "restore (level " << m_marks.count()+1 << ") -> to index " << toIndex << endl;
00070 #endif
00071     Q_ASSERT( toIndex > -1 );
00072     Q_ASSERT( toIndex <= (int)m_stack.count() ); // If equal, nothing to remove. If greater, bug.
00073     for ( int index = (int)m_stack.count() - 1; index >= toIndex; --index )
00074         m_stack.pop_back();
00075 }
00076 
00077 void KoStyleStack::pop()
00078 {
00079     Q_ASSERT( !m_stack.isEmpty() );
00080     m_stack.pop_back();
00081 #ifdef DEBUG_STYLESTACK
00082     kDebug(30003) << "pop -> count=" << m_stack.count() << endl;
00083 #endif
00084 }
00085 
00086 void KoStyleStack::push( const KoXmlElement& style )
00087 {
00088     m_stack.append( style );
00089 #ifdef DEBUG_STYLESTACK
00090     kDebug(30003) << "pushed " << style.attributeNS( m_styleNSURI, "name", QString::null ) << " -> count=" << m_stack.count() << endl;
00091 #endif
00092 }
00093 
00094 bool KoStyleStack::hasAttribute( const QString& name, const QString& detail ) const
00095 {
00096     QString fullName( name );
00097     if ( !detail.isEmpty() )
00098     {
00099         fullName += '-';
00100         fullName += detail;
00101     }
00102     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00103     while ( it != m_stack.begin() )
00104     {
00105         --it;
00106         KoXmlElement properties = (*it).namedItem( "style:"+m_propertiesTagName ).toElement();
00107         if ( properties.hasAttribute( name ) ||
00108              ( !detail.isEmpty() && properties.hasAttribute( fullName ) ) )
00109             return true;
00110     }
00111     return false;
00112 }
00113 
00114 QString KoStyleStack::attribute( const QString& name, const QString& detail ) const
00115 {
00116     QString fullName( name );
00117     if ( !detail.isEmpty() )
00118     {
00119         fullName += '-';
00120         fullName += detail;
00121     }
00122     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00123     while ( it != m_stack.begin() )
00124     {
00125         --it;
00126         KoXmlElement properties = (*it).namedItem( "style:"+m_propertiesTagName ).toElement();
00127         if ( properties.hasAttribute( name ) )
00128             return properties.attribute( name );
00129         if ( !detail.isEmpty() && properties.hasAttribute( fullName ) )
00130             return properties.attribute( fullName );
00131     }
00132     return QString();
00133 }
00134 
00135 QString KoStyleStack::attributeNS( const char* nsURI, const char* name, const char* detail ) const
00136 {
00137     QString fullName( name );
00138     if ( detail )
00139     {
00140         fullName += '-';
00141         fullName += detail;
00142     }
00143     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00144     while ( it != m_stack.begin() )
00145     {
00146         --it;
00147         KoXmlElement properties = KoDom::namedItemNS( *it, m_styleNSURI, m_propertiesTagName );
00148         if ( properties.hasAttributeNS( nsURI, name ) )
00149             return properties.attributeNS( nsURI, name, QString::null );
00150         if ( detail && properties.hasAttributeNS( nsURI, fullName ) )
00151             return properties.attributeNS( nsURI, fullName, QString::null );
00152     }
00153     return QString();
00154 }
00155 
00156 bool KoStyleStack::hasAttributeNS( const char* nsURI, const char* name, const char* detail ) const
00157 {
00158     QString fullName( name );
00159     if ( detail )
00160     {
00161         fullName += '-';
00162         fullName += detail;
00163     }
00164     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00165     while ( it != m_stack.begin() )
00166     {
00167         --it;
00168         KoXmlElement properties = KoDom::namedItemNS( *it, m_styleNSURI, m_propertiesTagName );
00169         if ( properties.hasAttributeNS( nsURI, name ) ||
00170              ( detail && properties.hasAttributeNS( nsURI, fullName ) ) )
00171             return true;
00172     }
00173     return false;
00174 }
00175 
00176 // Font size is a bit special. "115%" applies to "the fontsize of the parent style".
00177 // This can be generalized though (hasAttributeThatCanBePercentOfParent() ? :)
00178 // Although, if we also add support for fo:font-size-rel here then it's not general anymore.
00179 double KoStyleStack::fontSize() const
00180 {
00181     const QString name = "font-size";
00182     double percent = 1;
00183     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end(); // reverse iterator
00184 
00185     while ( it != m_stack.begin() )
00186     {
00187         --it;
00188         KoXmlElement properties = KoDom::namedItemNS( *it, m_styleNSURI, m_propertiesTagName ).toElement();
00189         if ( properties.hasAttributeNS( m_foNSURI, name ) ) {
00190             const QString value = properties.attributeNS( m_foNSURI, name, QString::null );
00191             if ( value.endsWith( "%" ) )
00192                 percent *= value.left( value.length() - 1 ).toDouble() / 100.0;
00193             else
00194                 return percent * KoUnit::parseValue( value ); // e.g. 12pt
00195         }
00196     }
00197     return 0;
00198 }
00199 
00200 bool KoStyleStack::hasChildNode(const QString & name) const
00201 {
00202     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00203     while ( it != m_stack.begin() )
00204     {
00205         --it;
00206         KoXmlElement properties = (*it).namedItem( "style:"+m_propertiesTagName ).toElement();
00207         if ( !properties.namedItem( name ).isNull() )
00208             return true;
00209     }
00210 
00211     return false;
00212 }
00213 
00214 KoXmlElement KoStyleStack::childNode(const QString & name) const
00215 {
00216     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00217 
00218     while ( it != m_stack.begin() )
00219     {
00220         --it;
00221         KoXmlElement properties = (*it).namedItem( "style:"+m_propertiesTagName ).toElement();
00222         if ( !properties.namedItem( name ).isNull() )
00223             return properties.namedItem( name ).toElement();
00224     }
00225 
00226     return KoXmlElement();          // a null element
00227 }
00228 
00229 bool KoStyleStack::hasChildNodeNS( const char* nsURI, const char* localName ) const
00230 {
00231     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00232     while ( it != m_stack.begin() )
00233     {
00234         --it;
00235         KoXmlElement properties = KoDom::namedItemNS( *it, m_styleNSURI, m_propertiesTagName );
00236         if ( !KoDom::namedItemNS( properties, nsURI, localName ).isNull() )
00237             return true;
00238     }
00239 
00240     return false;
00241 }
00242 
00243 KoXmlElement KoStyleStack::childNodeNS( const char* nsURI, const char* localName) const
00244 {
00245     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00246 
00247     while ( it != m_stack.begin() )
00248     {
00249         --it;
00250         KoXmlElement properties = KoDom::namedItemNS( *it, m_styleNSURI, m_propertiesTagName );
00251         KoXmlElement e = KoDom::namedItemNS( properties, nsURI, localName );
00252         if ( !e.isNull() )
00253             return e;
00254     }
00255 
00256     return KoXmlElement();          // a null element
00257 }
00258 
00259 bool KoStyleStack::isUserStyle( const KoXmlElement& e, const QString& family ) const
00260 {
00261     if ( e.attributeNS( m_styleNSURI, "family", QString::null ) != family )
00262         return false;
00263     const KoXmlElement parent = e.parentNode().toElement();
00264     //kDebug(30003) << k_funcinfo << "tagName=" << e.tagName() << " parent-tagName=" << parent.tagName() << endl;
00265     return parent.localName() == "styles" /*&& parent.namespaceURI() == KoXmlNS::office*/;
00266 }
00267 
00268 QString KoStyleStack::userStyleName( const QString& family ) const
00269 {
00270     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00271     while ( it != m_stack.begin() )
00272     {
00273         --it;
00274         //kDebug(30003) << k_funcinfo << (*it).attributeNS( m_styleNSURI, "name", QString::null) << endl;
00275         if ( isUserStyle( *it, family ) )
00276             return (*it).attributeNS( m_styleNSURI, "name", QString::null );
00277     }
00278     // Can this ever happen?
00279     return "Standard";
00280 }
00281 
00282 QString KoStyleStack::userStyleDisplayName( const QString& family ) const
00283 {
00284     Q3ValueList<KoXmlElement>::ConstIterator it = m_stack.end();
00285     while ( it != m_stack.begin() )
00286     {
00287         --it;
00288         //kDebug(30003) << k_funcinfo << (*it).attributeNS( m_styleNSURI, "display-name") << endl;
00289         if ( isUserStyle( *it, family ) )
00290             return (*it).attributeNS( m_styleNSURI, "display-name", QString::null );
00291     }
00292     return QString(); // no display name, this can happen since it's optional
00293 }
00294 
00295 void KoStyleStack::setTypeProperties( const char* typeProperties )
00296 {
00297     m_propertiesTagName = typeProperties == 0 ? QByteArray( "properties" ) : ( QByteArray( typeProperties ) + "-properties" );
00298 }

Généré le Wed Nov 22 23:41:04 2006 pour KPlato par  doxygen 1.5.1-p1