1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmloff.hxx" 30 #include <tools/debug.hxx> 31 #include <com/sun/star/container/XNameContainer.hpp> 32 #include <com/sun/star/container/XIndexReplace.hpp> 33 #include <com/sun/star/style/XStyle.hpp> 34 #include <com/sun/star/beans/XPropertySet.hpp> 35 #include <xmloff/xmlimp.hxx> 36 #include <xmloff/xmlnumi.hxx> 37 #include <xmloff/nmspmap.hxx> 38 #include "xmloff/xmlnmspe.hxx" 39 #include <xmloff/xmltoken.hxx> 40 #include "XMLTextListItemContext.hxx" 41 #include "XMLTextListBlockContext.hxx" 42 #include "txtlists.hxx" 43 44 using ::rtl::OUString; 45 using ::rtl::OUStringBuffer; 46 47 using namespace ::com::sun::star; 48 using namespace ::com::sun::star::uno; 49 using namespace ::com::sun::star::container; 50 using namespace ::com::sun::star::style; 51 using namespace ::com::sun::star::beans; 52 using namespace ::xmloff::token; 53 54 TYPEINIT1( XMLTextListBlockContext, SvXMLImportContext ); 55 56 // OD 2008-05-07 #refactorlists# 57 // add optional parameter <bRestartNumberingAtSubList> and its handling 58 XMLTextListBlockContext::XMLTextListBlockContext( 59 SvXMLImport& rImport, 60 XMLTextImportHelper& rTxtImp, 61 sal_uInt16 nPrfx, 62 const OUString& rLName, 63 const Reference< xml::sax::XAttributeList > & xAttrList, 64 const sal_Bool bRestartNumberingAtSubList ) 65 : SvXMLImportContext( rImport, nPrfx, rLName ) 66 , mrTxtImport( rTxtImp ) 67 // --> OD 2008-04-22 #refactorlists# 68 , msListStyleName() 69 // <-- 70 , mxParentListBlock( ) 71 , mnLevel( 0 ) 72 // --> OD 2008-05-07 #refactorlists# 73 //, mbRestartNumbering( sal_True ) 74 , mbRestartNumbering( sal_False ) 75 // <-- 76 , mbSetDefaults( sal_False ) 77 // --> OD 2008-04-22 #refactorlists# 78 , msListId() 79 , msContinueListId() 80 // <-- 81 { 82 static ::rtl::OUString s_PropNameDefaultListId( 83 RTL_CONSTASCII_USTRINGPARAM("DefaultListId")); 84 { 85 // get the parent list block context (if any); this is a bit ugly... 86 XMLTextListBlockContext * pLB(0); 87 XMLTextListItemContext * pLI(0); 88 XMLNumberedParaContext * pNP(0); 89 rTxtImp.GetTextListHelper().ListContextTop(pLB, pLI, pNP); 90 mxParentListBlock = pLB; 91 } 92 // Inherit style name from parent list, as well as the flags whether 93 // numbering must be restarted and formats have to be created. 94 OUString sParentListStyleName; 95 // --> OD 2008-11-27 #158694# 96 sal_Bool bParentRestartNumbering( sal_False ); 97 // <-- 98 if( mxParentListBlock.Is() ) 99 { 100 XMLTextListBlockContext *pParent = 101 (XMLTextListBlockContext *)&mxParentListBlock; 102 msListStyleName = pParent->GetListStyleName(); 103 sParentListStyleName = msListStyleName; 104 mxNumRules = pParent->GetNumRules(); 105 mnLevel = pParent->GetLevel() + 1; 106 // --> OD 2008-05-07 #refactorlists# 107 // mbRestartNumbering = pParent->IsRestartNumbering(); 108 mbRestartNumbering = pParent->IsRestartNumbering() || 109 bRestartNumberingAtSubList; 110 // <-- 111 // --> OD 2008-11-27 #158694# 112 bParentRestartNumbering = pParent->IsRestartNumbering(); 113 // <-- 114 mbSetDefaults = pParent->mbSetDefaults; 115 // --> OD 2008-04-22 #refactorlists# 116 msListId = pParent->GetListId(); 117 msContinueListId = pParent->GetContinueListId(); 118 // <-- 119 } 120 121 const SvXMLTokenMap& rTokenMap = mrTxtImport.GetTextListBlockAttrTokenMap(); 122 123 // --> OD 2008-05-07 #refactorlists# 124 bool bIsContinueNumberingAttributePresent( false ); 125 // <-- 126 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 127 for( sal_Int16 i=0; i < nAttrCount; i++ ) 128 { 129 const OUString& rAttrName = xAttrList->getNameByIndex( i ); 130 const OUString& rValue = xAttrList->getValueByIndex( i ); 131 132 OUString aLocalName; 133 sal_uInt16 nPrefix = 134 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, 135 &aLocalName ); 136 switch( rTokenMap.Get( nPrefix, aLocalName ) ) 137 { 138 case XML_TOK_TEXT_LIST_BLOCK_XMLID: 139 sXmlId = rValue; 140 //FIXME: there is no UNO API for lists 141 // --> OD 2008-07-31 #i92221# - xml:id is also the list ID 142 if ( mnLevel == 0 ) // root <list> element 143 { 144 msListId = rValue; 145 } 146 // <-- 147 break; 148 case XML_TOK_TEXT_LIST_BLOCK_CONTINUE_NUMBERING: 149 mbRestartNumbering = !IsXMLToken(rValue, XML_TRUE); 150 // --> OD 2008-05-07 #refactorlists# 151 bIsContinueNumberingAttributePresent = true; 152 // <-- 153 break; 154 case XML_TOK_TEXT_LIST_BLOCK_STYLE_NAME: 155 msListStyleName = rValue; 156 break; 157 // --> OD 2008-04-22 #refactorlists# 158 case XML_TOK_TEXT_LIST_BLOCK_CONTINUE_LIST: 159 if ( mnLevel == 0 ) // root <list> element 160 { 161 msContinueListId = rValue; 162 } 163 break; 164 } 165 } 166 167 mxNumRules = XMLTextListsHelper::MakeNumRule(GetImport(), mxNumRules, 168 sParentListStyleName, msListStyleName, 169 mnLevel, &mbRestartNumbering, &mbSetDefaults ); 170 if( !mxNumRules.is() ) 171 return; 172 173 // --> OD 2008-04-23 #refactorlists# 174 if ( mnLevel == 0 ) // root <list> element 175 { 176 XMLTextListsHelper& rTextListsHelper( mrTxtImport.GetTextListHelper() ); 177 // --> OD 2008-08-15 #i92811# 178 ::rtl::OUString sListStyleDefaultListId; 179 { 180 uno::Reference< beans::XPropertySet > xNumRuleProps( mxNumRules, UNO_QUERY ); 181 if ( xNumRuleProps.is() ) 182 { 183 uno::Reference< beans::XPropertySetInfo > xNumRulePropSetInfo( 184 xNumRuleProps->getPropertySetInfo()); 185 if (xNumRulePropSetInfo.is() && 186 xNumRulePropSetInfo->hasPropertyByName( 187 s_PropNameDefaultListId)) 188 { 189 xNumRuleProps->getPropertyValue(s_PropNameDefaultListId) 190 >>= sListStyleDefaultListId; 191 DBG_ASSERT( sListStyleDefaultListId.getLength() != 0, 192 "no default list id found at numbering rules instance. Serious defect -> please inform OD." ); 193 } 194 } 195 } 196 // <-- 197 if ( msListId.getLength() == 0 ) // no text:id property found 198 { 199 sal_Int32 nUPD( 0 ); 200 sal_Int32 nBuild( 0 ); 201 const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild ); 202 if ( rImport.IsTextDocInOOoFileFormat() || 203 ( bBuildIdFound && nUPD == 680 ) ) 204 { 205 // handling former documents written by OpenOffice.org: 206 // use default list id of numbering rules instance, if existing 207 // --> OD 2008-08-15 #i92811# 208 if ( sListStyleDefaultListId.getLength() != 0 ) 209 { 210 msListId = sListStyleDefaultListId; 211 if ( !bIsContinueNumberingAttributePresent && 212 !mbRestartNumbering && 213 rTextListsHelper.IsListProcessed( msListId ) ) 214 { 215 mbRestartNumbering = sal_True; 216 } 217 } 218 // <-- 219 } 220 if ( msListId.getLength() == 0 ) 221 { 222 // generate a new list id for the list 223 msListId = rTextListsHelper.GenerateNewListId(); 224 } 225 } 226 227 if ( bIsContinueNumberingAttributePresent && !mbRestartNumbering && 228 msContinueListId.getLength() == 0 ) 229 { 230 ::rtl::OUString Last( rTextListsHelper.GetLastProcessedListId() ); 231 if ( rTextListsHelper.GetListStyleOfLastProcessedList() == msListStyleName 232 && Last != msListId ) 233 { 234 msContinueListId = Last; 235 } 236 } 237 238 if ( msContinueListId.getLength() > 0 ) 239 { 240 if ( !rTextListsHelper.IsListProcessed( msContinueListId ) ) 241 { 242 msContinueListId = ::rtl::OUString(); 243 } 244 else 245 { 246 // search continue list chain for master list and 247 // continue the master list. 248 ::rtl::OUString sTmpStr = 249 rTextListsHelper.GetContinueListIdOfProcessedList( msContinueListId ); 250 while ( sTmpStr.getLength() > 0 ) 251 { 252 msContinueListId = sTmpStr; 253 254 sTmpStr = 255 rTextListsHelper.GetContinueListIdOfProcessedList( msContinueListId ); 256 } 257 } 258 } 259 260 if ( !rTextListsHelper.IsListProcessed( msListId ) ) 261 { 262 // --> OD 2008-08-15 #i92811# 263 rTextListsHelper.KeepListAsProcessed( 264 msListId, msListStyleName, msContinueListId, 265 sListStyleDefaultListId ); 266 // <-- 267 } 268 } 269 // <-- 270 271 // Remember this list block. 272 mrTxtImport.GetTextListHelper().PushListContext( this ); 273 } 274 275 XMLTextListBlockContext::~XMLTextListBlockContext() 276 { 277 } 278 279 void XMLTextListBlockContext::EndElement() 280 { 281 // Numbering has not to be restarted if it has been restarted within 282 // a child list. 283 XMLTextListBlockContext *pParent = 284 (XMLTextListBlockContext *)&mxParentListBlock; 285 if( pParent ) 286 { 287 pParent->mbRestartNumbering = mbRestartNumbering; 288 } 289 290 // Restore current list block. 291 mrTxtImport.GetTextListHelper().PopListContext(); 292 293 // Any paragraph following the list within the same list item must not 294 // be numbered. 295 mrTxtImport.GetTextListHelper().SetListItem( 0 ); 296 } 297 298 SvXMLImportContext *XMLTextListBlockContext::CreateChildContext( 299 sal_uInt16 nPrefix, 300 const OUString& rLocalName, 301 const Reference< xml::sax::XAttributeList > & xAttrList ) 302 { 303 SvXMLImportContext *pContext = 0; 304 305 const SvXMLTokenMap& rTokenMap = 306 mrTxtImport.GetTextListBlockElemTokenMap(); 307 sal_Bool bHeader = sal_False; 308 switch( rTokenMap.Get( nPrefix, rLocalName ) ) 309 { 310 case XML_TOK_TEXT_LIST_HEADER: 311 bHeader = sal_True; 312 case XML_TOK_TEXT_LIST_ITEM: 313 pContext = new XMLTextListItemContext( GetImport(), mrTxtImport, 314 nPrefix, rLocalName, 315 xAttrList, bHeader ); 316 break; 317 } 318 319 if( !pContext ) 320 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); 321 322 return pContext; 323 } 324 325 // --> OD 2008-04-22 #refactorlists# 326 const ::rtl::OUString& XMLTextListBlockContext::GetListId() const 327 { 328 return msListId; 329 } 330 331 const ::rtl::OUString& XMLTextListBlockContext::GetContinueListId() const 332 { 333 return msContinueListId; 334 } 335 // <-- 336 337