F:/KPlato/koffice/libs/kotext/KoParagStyle.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2001-2005 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 "KoParagStyle.h"
00020 #include "KoOasisContext.h"
00021 #include "KoParagCounter.h"
00022 
00023 #include <KoGenStyles.h>
00024 #include <KoXmlWriter.h>
00025 #include <KoXmlNS.h>
00026 
00027 #include <kdebug.h>
00028 #include <klocale.h>
00029 
00030 
00031 KoCharStyle::KoCharStyle( const QString & name )
00032     : KoUserStyle( name )
00033 {
00034 }
00035 
00036 const KoTextFormat & KoCharStyle::format() const
00037 {
00038     return m_format;
00039 }
00040 
00041 KoTextFormat & KoCharStyle::format()
00042 {
00043     return m_format;
00044 }
00045 
00047 
00048 KoParagStyle::KoParagStyle( const QString & name )
00049     : KoCharStyle( name )
00050 {
00051     m_followingStyle = this;
00052 
00053     // This way, KoTextParag::setParagLayout also sets the style pointer, to this style
00054     m_paragLayout.style = this;
00055     m_parentStyle = 0L;
00056     m_inheritedParagLayoutFlag = 0;
00057     m_inheritedFormatFlag = 0;
00058     m_bOutline = false;
00059 }
00060 
00061 KoParagStyle::KoParagStyle( const KoParagStyle & rhs )
00062     : KoCharStyle( rhs)
00063 {
00064     *this = rhs;
00065 }
00066 
00067 KoParagStyle::~KoParagStyle()
00068 {
00069 }
00070 
00071 void KoParagStyle::operator=( const KoParagStyle &rhs )
00072 {
00073     KoCharStyle::operator=( rhs );
00074     m_paragLayout = rhs.m_paragLayout;
00075     m_followingStyle = rhs.m_followingStyle;
00076     m_paragLayout.style = this; // must always be "this"
00077     m_parentStyle = rhs.m_parentStyle;
00078     m_inheritedParagLayoutFlag = rhs.m_inheritedParagLayoutFlag;
00079     m_inheritedFormatFlag = rhs.m_inheritedFormatFlag;
00080     m_bOutline = rhs.m_bOutline;
00081 }
00082 
00083 void KoParagStyle::setFollowingStyle( KoParagStyle *fst )
00084 {
00085   m_followingStyle = fst;
00086 }
00087 
00088 void KoParagStyle::saveStyle( QDomElement & parentElem )
00089 {
00090     m_paragLayout.saveParagLayout( parentElem, m_paragLayout.alignment );
00091 
00092     if ( followingStyle() )
00093     {
00094         QDomElement element = parentElem.ownerDocument().createElement( "FOLLOWING" );
00095         parentElem.appendChild( element );
00096         element.setAttribute( "name", followingStyle()->displayName() );
00097     }
00098     // TODO save parent style, and inherited flags.
00099 
00100     parentElem.setAttribute( "outline", m_bOutline ? "true" : "false" );
00101 }
00102 
00103 void KoParagStyle::loadStyle( QDomElement & parentElem, int docVersion )
00104 {
00105     KoParagLayout layout;
00106     KoParagLayout::loadParagLayout( layout, parentElem, docVersion );
00107 
00108     // This way, KoTextParag::setParagLayout also sets the style pointer, to this style
00109     layout.style = this;
00110     m_paragLayout = layout;
00111 
00112     // Load name
00113     QDomElement nameElem = parentElem.namedItem("NAME").toElement();
00114     if ( !nameElem.isNull() ) {
00115         m_name = nameElem.attribute("value");
00116         m_displayName = i18nc( "Style name", m_name.toUtf8() );
00117     } else
00118         kWarning() << "No NAME tag in LAYOUT -> no name for this style!" << endl;
00119 
00120     // The followingStyle stuff has to be done after loading all styles.
00121 
00122     m_bOutline = parentElem.attribute( "outline" ) == "true";
00123 }
00124 
00125 void KoParagStyle::loadStyle( QDomElement & styleElem, KoOasisContext& context )
00126 {
00127     // Load name
00128     m_name = styleElem.attributeNS( KoXmlNS::style, "name", QString::null );
00129     m_displayName = styleElem.attributeNS( KoXmlNS::style, "display-name", QString::null );
00130     if ( m_displayName.isEmpty() )
00131         m_displayName = m_name;
00132 
00133     // OOo hack
00134     //m_bOutline = m_name.startsWith( "Heading" );
00135     // real OASIS solution:
00136     m_bOutline = styleElem.hasAttributeNS( KoXmlNS::style, "default-outline-level" );
00137 
00138     context.styleStack().save();
00139     context.addStyles( &styleElem, "paragraph" ); // Load all parents - only because we don't support inheritance.
00140     KoParagLayout layout;
00141     KoParagLayout::loadOasisParagLayout( layout, context );
00142 
00143     // loadOasisParagLayout doesn't load the counter. It's modelled differently for parags and for styles.
00144     int level = 0;
00145     bool listOK = false;
00146     const QString listStyleName = styleElem.attributeNS( KoXmlNS::style, "list-style-name", QString::null );
00147     if ( m_bOutline ) {
00148         level = styleElem.attributeNS( KoXmlNS::style, "default-outline-level", QString::null ).toInt(); // 1-based
00149         listOK = context.pushOutlineListLevelStyle( level );
00150         // allow overriding the outline numbering, see http://lists.oasis-open.org/archives/office/200310/msg00033.html
00151         if ( !listStyleName.isEmpty() )
00152             context.pushListLevelStyle( listStyleName, level );
00153     }
00154     else {
00155         // ######## BIG difference here. In the OOo/OASIS format, one list style has infos for 10 list levels...
00156         // ###### so we can't know a level at this point...
00157 
00158         // The only solution I can think of, to preserve document content when importing OO but
00159         // not necessarily the styles used when editing, is:
00160         // 1) when importing from OOo, convert each non-heading style with numbering
00161         // into 10 kotext styles (at least those used by the document) [TODO]
00162         // 2) for KWord's own loading/saving, to add a hack into the file format, say
00163         // style:default-level.
00164         // Note that default-level defaults to "1", i.e. works for non-nested OOo lists too.
00165         level = styleElem.attributeNS( KoXmlNS::style, "default-level", "1" ).toInt(); // 1-based
00166         listOK = !listStyleName.isEmpty();
00167         if ( listOK )
00168             listOK = context.pushListLevelStyle( listStyleName, level );
00169     }
00170     if ( listOK ) {
00171         const QDomElement listStyle = context.listStyleStack().currentListStyle();
00172         // The tag is either text:list-level-style-number or text:list-level-style-bullet
00173         const bool ordered = listStyle.localName() == "list-level-style-number";
00174         Q_ASSERT( !layout.counter );
00175         layout.counter = new KoParagCounter;
00176         layout.counter->loadOasis( context, -1, ordered, m_bOutline, level, true );
00177         context.listStyleStack().pop();
00178     }
00179 
00180     // This way, KoTextParag::setParagLayout also sets the style pointer, to this style
00181     layout.style = this;
00182     m_paragLayout = layout;
00183 
00184     m_format.load( context );
00185 
00186     context.styleStack().restore();
00187 }
00188 
00189 QString KoParagStyle::saveStyle( KoGenStyles& genStyles, int styleType, const QString& parentStyleName, KoSavingContext& context ) const
00190 {
00191     KoGenStyle gs( styleType, "paragraph", parentStyleName );
00192 
00193     gs.addAttribute( "style:display-name", m_displayName );
00194     if ( m_paragLayout.counter ) {
00195         if ( m_bOutline )
00196             gs.addAttribute( "style:default-outline-level", (int)m_paragLayout.counter->depth() + 1 );
00197         else if ( m_paragLayout.counter->depth() )
00198             // ### kword-specific attribute, see loadOasis
00199             gs.addAttribute( "style:default-level", (int)m_paragLayout.counter->depth() + 1 );
00200 
00201         if ( m_paragLayout.counter->numbering() != KoParagCounter::NUM_NONE &&
00202              m_paragLayout.counter->style() != KoParagCounter::STYLE_NONE )
00203         {
00204             KoGenStyle listStyle( KoGenStyle::STYLE_LIST /*, no family*/ );
00205             m_paragLayout.counter->saveOasis( listStyle, true );
00206             // This display-name will probably look nicer in OO, but this also means
00207             // no re-use possible between list styles...
00208             listStyle.addAttribute( "style:display-name",
00209                                     i18n( "Numbering Style for %1" , m_displayName ) );
00210 
00211             QString autoListStyleName = genStyles.lookup( listStyle, "L", KoGenStyles::ForceNumbering );
00212             gs.addAttribute( "style:list-style-name", autoListStyleName );
00213         }
00214     }
00215 
00216     m_paragLayout.saveOasis( gs, context, true );
00217 
00218     m_format.save( gs, context );
00219 
00220     // try to preserve existing internal name, if it looks adequate (no spaces)
00221     // ## TODO: check XML-Schemacs NCName conformity
00222     bool nameIsConform = !m_name.isEmpty() && !m_name.contains( ' ' );
00223     QString newName;
00224     if ( nameIsConform )
00225         newName = genStyles.lookup( gs, m_name, KoGenStyles::DontForceNumbering );
00226     else
00227         newName = genStyles.lookup( gs, "U", KoGenStyles::ForceNumbering );
00228     const_cast<KoParagStyle*>( this )->m_name = newName;
00229     return m_name;
00230 }
00231 
00232 const KoParagLayout & KoParagStyle::paragLayout() const
00233 {
00234     return m_paragLayout;
00235 }
00236 
00237 KoParagLayout & KoParagStyle::paragLayout()
00238 {
00239     return m_paragLayout;
00240 }
00241 
00242 void KoParagStyle::propagateChanges( int paragLayoutFlag, int /*formatFlag*/ )
00243 {
00244     if ( !m_parentStyle )
00245         return;
00246     if ( !(paragLayoutFlag & KoParagLayout::Alignment) )
00247         m_paragLayout.alignment = m_parentStyle->paragLayout().alignment;
00248     if ( !(paragLayoutFlag & KoParagLayout::Margins) )
00249         for ( int i = 0 ; i < 5 ; ++i )
00250             m_paragLayout.margins[i] = m_parentStyle->paragLayout().margins[i];
00251     if ( !(paragLayoutFlag & KoParagLayout::LineSpacing) )
00252     {
00253         m_paragLayout.setLineSpacingValue(m_parentStyle->paragLayout().lineSpacingValue());
00254         m_paragLayout.lineSpacingType = m_parentStyle->paragLayout().lineSpacingType;
00255     }
00256     if ( !(paragLayoutFlag & KoParagLayout::Borders) )
00257     {
00258         m_paragLayout.leftBorder = m_parentStyle->paragLayout().leftBorder;
00259         m_paragLayout.rightBorder = m_parentStyle->paragLayout().rightBorder;
00260         m_paragLayout.topBorder = m_parentStyle->paragLayout().topBorder;
00261         m_paragLayout.bottomBorder = m_parentStyle->paragLayout().bottomBorder;
00262         m_paragLayout.joinBorder = m_parentStyle->paragLayout().joinBorder;
00263     }
00264     if ( !(paragLayoutFlag & KoParagLayout::BulletNumber) )
00265         m_paragLayout.counter = m_parentStyle->paragLayout().counter;
00266     if ( !(paragLayoutFlag & KoParagLayout::Tabulator) )
00267         m_paragLayout.setTabList(m_parentStyle->paragLayout().tabList());
00268 #if 0
00269     if ( paragLayoutFlag == KoParagLayout::All )
00270     {
00271         setDirection( static_cast<QChar::Direction>(layout.direction) );
00272         // Don't call applyStyle from here, it would overwrite any paragraph-specific settings
00273         setStyle( layout.style );
00274     }
00275 #endif
00276     // TODO a flag for the "is outline" bool? Otherwise we have no way to inherit
00277     // that property (and possibly reset it).
00278 }
00279 
00280 void KoParagStyle::setOutline( bool b )
00281 {
00282     m_bOutline = b;
00283 }

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