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

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2004-2006 David Faure <faure@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016  * Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include <float.h>
00020 
00021 #include <Q3ValueList>
00022 
00023 #include <kdebug.h>
00024 
00025 #include <KoXmlWriter.h>
00026 #include "KoGenStyles.h"
00027 
00028 #include "KoGenStyle.h"
00029 
00030 
00031 // Returns -1, 0 (equal) or 1
00032 static int compareMap( const QMap<QString, QString>& map1, const QMap<QString, QString>& map2 )
00033 {
00034   QMap<QString, QString>::const_iterator it = map1.begin();
00035   QMap<QString, QString>::const_iterator oit = map2.begin();
00036   for ( ; it != map1.end(); ++it, ++oit ) { // both maps have been checked for size already
00037     if ( it.key() != oit.key() )
00038       return it.key() < oit.key() ? -1 : +1;
00039     if ( it.value() != oit.value() )
00040       return it.value() < oit.value() ? -1 : +1;
00041   }
00042   return 0; // equal
00043 }
00044 
00045 
00046 KoGenStyle::KoGenStyle( int type, const char* familyName,
00047                         const QString& parentName )
00048     : m_type( type ), m_familyName( familyName ), m_parentName( parentName ),
00049       m_autoStyleInStylesDotXml( false ), m_defaultStyle( false )
00050 {
00051 }
00052 
00053 KoGenStyle::~KoGenStyle()
00054 {
00055 }
00056 
00057 void KoGenStyle::writeStyleProperties( KoXmlWriter* writer, PropertyType i,
00058                                        const char* elementName, const KoGenStyle* parentStyle ) const
00059 {
00060     if ( !m_properties[i].isEmpty() ) {
00061         writer->startElement( elementName );
00062         QMap<QString, QString>::const_iterator it = m_properties[i].begin();
00063         const QMap<QString, QString>::const_iterator end = m_properties[i].end();
00064         for ( ; it != end; ++it ) {
00065             if ( !parentStyle || parentStyle->property( it.key(), i ) != it.value() )
00066                 writer->addAttribute( it.key().toUtf8(), it.value().toUtf8() );
00067         }
00068         writer->endElement();
00069     }
00070 }
00071 
00072 void KoGenStyle::writeStyle( KoXmlWriter* writer, KoGenStyles& styles, const char* elementName, const QString& name, const char* propertiesElementName, bool closeElement, bool drawElement ) const
00073 {
00074     //kDebug(30003) << "writing out style " << name << " display-name=" << m_attributes["style:display-name"] << " family=" << m_familyName << endl;
00075     writer->startElement( elementName );
00076     const KoGenStyle* parentStyle = 0;
00077     if ( !m_defaultStyle ) {
00078         if ( !drawElement )
00079             writer->addAttribute( "style:name", name );
00080         else
00081             writer->addAttribute( "draw:name", name );
00082         if ( !m_parentName.isEmpty() ) {
00083             parentStyle = styles.style( m_parentName );
00084             if ( parentStyle && m_familyName.isEmpty() ) {
00085                 // get family from parent style, just in case
00086                 // Note: this is saving code, don't convert to attributeNS!
00087                 const_cast<KoGenStyle *>( this )->
00088                     m_familyName = parentStyle->attribute( "style:family" ).toLatin1();
00089                 //kDebug(30003) << "Got familyname " << m_familyName << " from parent" << endl;
00090             }
00091             writer->addAttribute( "style:parent-style-name", m_parentName );
00092         }
00093     } else { // default-style
00094         Q_ASSERT( qstrcmp( elementName, "style:default-style" ) == 0 );
00095         Q_ASSERT( m_parentName.isEmpty() );
00096     }
00097     if ( !m_familyName.isEmpty() )
00098         const_cast<KoGenStyle *>( this )->
00099             addAttribute( "style:family", QString::fromLatin1( m_familyName ) );
00100     else {
00101         if ( qstrcmp( elementName, "style:style" ) == 0 )
00102             kWarning(30003) << "User style " << name << " is without family - invalid. m_type=" << m_type << endl;
00103     }
00104 
00105 #if 0 // #ifndef NDEBUG
00106     kDebug() << "style: " << name << endl;
00107     printDebug();
00108     if ( parentStyle ) {
00109         kDebug() << " parent: " << m_parentName << endl;
00110         parentStyle->printDebug();
00111     }
00112 #endif
00113 
00114     // Write attributes [which differ from the parent style]
00115     // We only look at the direct parent style because we assume
00116     // that styles are fully specified, i.e. the inheritance is
00117     // only in the final file, not in the caller's code.
00118     QMap<QString, QString>::const_iterator it = m_attributes.begin();
00119     for ( ; it != m_attributes.end(); ++it ) {
00120         bool writeit = true;
00121         if ( parentStyle && it.key() != "style:family" // always write the family out
00122              && parentStyle->attribute( it.key() ) == it.value() )
00123             writeit = false;
00124         if ( writeit )
00125             writer->addAttribute( it.key().toUtf8(), it.value().toUtf8() );
00126     }
00127     bool createPropertiesTag = propertiesElementName && propertiesElementName[0] != '\0';
00128     KoGenStyle::PropertyType i = KoGenStyle::DefaultType;
00129     if ( !m_properties[i].isEmpty() ||
00130          !m_properties[KoGenStyle::ChildElement].isEmpty() ) {
00131         if ( createPropertiesTag )
00132             writer->startElement( propertiesElementName ); // e.g. paragraph-properties
00133         it = m_properties[i].begin();
00134         for ( ; it != m_properties[i].end(); ++it ) {
00135             if ( !parentStyle || parentStyle->property( it.key(), i ) != it.value() )
00136                 writer->addAttribute( it.key().toUtf8(), it.value().toUtf8() );
00137         }
00138         i = KoGenStyle::ChildElement;
00139         it = m_properties[i].begin();
00140         for ( ; it != m_properties[i].end(); ++it ) {
00141             if ( !parentStyle || parentStyle->property( it.key(), i ) != it.value() ) {
00142                 writer->addCompleteElement( it.value().toUtf8() );
00143             }
00144         }
00145         if ( createPropertiesTag )
00146             writer->endElement();
00147     }
00148     writeStyleProperties( writer, KoGenStyle::GraphicType, "style:graphic-properties", parentStyle );
00149     writeStyleProperties( writer, KoGenStyle::ParagraphType, "style:paragraph-properties", parentStyle );
00150     writeStyleProperties( writer, KoGenStyle::TextType, "style:text-properties", parentStyle );
00151 
00152     // And now the style maps
00153     for ( int i = 0; i < m_maps.count(); ++i ) {
00154         bool writeit = true;
00155         if ( parentStyle && compareMap( m_maps[i], parentStyle->m_maps[i] ) == 0 )
00156             writeit = false;
00157         if ( writeit ) {
00158             writer->startElement( "style:map" );
00159             QMap<QString, QString>::const_iterator it = m_maps[i].begin();
00160             for ( ; it != m_maps[i].end(); ++it ) {
00161                 writer->addAttribute( it.key().toUtf8(), it.value().toUtf8() );
00162             }
00163             writer->endElement(); // style:map
00164         }
00165     }
00166     if ( closeElement )
00167         writer->endElement();
00168 }
00169 
00170 void KoGenStyle::addPropertyPt( const QString& propName, double propValue, PropertyType type )
00171 {
00172     QString str;
00173     str.setNum( propValue, 'g', DBL_DIG );
00174     str += "pt";
00175     m_properties[type].insert( propName, str );
00176 }
00177 
00178 void KoGenStyle::addAttributePt( const QString& attrName, double attrValue )
00179 {
00180     QString str;
00181     str.setNum( attrValue, 'g', DBL_DIG );
00182     str += "pt";
00183     m_attributes.insert( attrName, str );
00184 }
00185 
00186 #ifndef NDEBUG
00187 void KoGenStyle::printDebug() const
00188 {
00189     int i = DefaultType;
00190     kDebug() << m_properties[i].count() << " properties." << endl;
00191     for( QMap<QString,QString>::ConstIterator it = m_properties[i].begin(); it != m_properties[i].end(); ++it ) {
00192         kDebug() << "     " << it.key() << " = " << it.value() << endl;
00193     }
00194     i = TextType;
00195     kDebug() << m_properties[i].count() << " text properties." << endl;
00196     for( QMap<QString,QString>::ConstIterator it = m_properties[i].begin(); it != m_properties[i].end(); ++it ) {
00197         kDebug() << "     " << it.key() << " = " << it.value() << endl;
00198     }
00199     i = ParagraphType;
00200     kDebug() << m_properties[i].count() << " paragraph properties." << endl;
00201     for( QMap<QString,QString>::ConstIterator it = m_properties[i].begin(); it != m_properties[i].end(); ++it ) {
00202         kDebug() << "     " << it.key() << " = " << it.value() << endl;
00203     }
00204     i = ChildElement;
00205     kDebug() << m_properties[i].count() << " child elements." << endl;
00206     for( QMap<QString,QString>::ConstIterator it = m_properties[i].begin(); it != m_properties[i].end(); ++it ) {
00207         kDebug() << "     " << it.key() << " = " << it.value() << endl;
00208     }
00209     kDebug() << m_attributes.count() << " attributes." << endl;
00210     for( QMap<QString,QString>::ConstIterator it = m_attributes.begin(); it != m_attributes.end(); ++it ) {
00211         kDebug() << "     " << it.key() << " = " << it.value() << endl;
00212     }
00213     kDebug() << m_maps.count() << " maps." << endl;
00214     for ( int i = 0; i < m_maps.count(); ++i ) {
00215         kDebug() << "map " << i << ":" << endl;
00216         for( QMap<QString,QString>::ConstIterator it = m_maps[i].begin(); it != m_maps[i].end(); ++it ) {
00217             kDebug() << "     " << it.key() << " = " << it.value() << endl;
00218         }
00219     }
00220     kDebug() << endl;
00221 }
00222 #endif
00223 
00224 bool KoGenStyle::operator<( const KoGenStyle &other ) const
00225 {
00226     if ( m_type != other.m_type ) return m_type < other.m_type;
00227     if ( m_parentName != other.m_parentName ) return m_parentName < other.m_parentName;
00228     if ( m_autoStyleInStylesDotXml != other.m_autoStyleInStylesDotXml ) return m_autoStyleInStylesDotXml;
00229     for ( uint i = 0 ; i < N_NumTypes ; ++i )
00230         if ( m_properties[i].count() != other.m_properties[i].count() )
00231             return m_properties[i].count() < other.m_properties[i].count();
00232     if ( m_attributes.count() != other.m_attributes.count() ) return m_attributes.count() < other.m_attributes.count();
00233     if ( m_maps.count() != other.m_maps.count() ) return m_maps.count() < other.m_maps.count();
00234     // Same number of properties and attributes, no other choice than iterating
00235     for ( uint i = 0 ; i < N_NumTypes ; ++i ) {
00236         int comp = compareMap( m_properties[i], other.m_properties[i] );
00237         if ( comp != 0 )
00238             return comp < 0;
00239     }
00240     int comp = compareMap( m_attributes, other.m_attributes );
00241     if ( comp != 0 )
00242         return comp < 0;
00243     for ( int i = 0 ; i < m_maps.count() ; ++i ) {
00244         int comp = compareMap( m_maps[i], other.m_maps[i] );
00245         if ( comp != 0 )
00246             return comp < 0;
00247     }
00248     return false;
00249 }
00250 
00251 bool KoGenStyle::operator==( const KoGenStyle &other ) const
00252 {
00253     if ( m_type != other.m_type ) return false;
00254     if ( m_parentName != other.m_parentName ) return false;
00255     if ( m_autoStyleInStylesDotXml != other.m_autoStyleInStylesDotXml ) return false;
00256     for ( uint i = 0 ; i < N_NumTypes ; ++i )
00257         if ( m_properties[i].count() != other.m_properties[i].count() )
00258             return false;
00259     if ( m_attributes.count() != other.m_attributes.count() ) return false;
00260     if ( m_maps.count() != other.m_maps.count() ) return false;
00261     // Same number of properties and attributes, no other choice than iterating
00262     for ( uint i = 0 ; i < N_NumTypes ; ++i ) {
00263         int comp = compareMap( m_properties[i], other.m_properties[i] );
00264         if ( comp != 0 )
00265             return false;
00266     }
00267     int comp = compareMap( m_attributes, other.m_attributes );
00268     if ( comp != 0 )
00269         return false;
00270     for ( int i = 0 ; i < m_maps.count() ; ++i ) {
00271         int comp = compareMap( m_maps[i], other.m_maps[i] );
00272         if ( comp != 0 )
00273             return false;
00274     }
00275     return true;
00276 }

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