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