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 <xmloff/xmlaustp.hxx> 28 #include <xmloff/xmltoken.hxx> 29 #include <xmloff/nmspmap.hxx> 30 #include "xmloff/xmlnmspe.hxx" 31 #include <xmloff/attrlist.hxx> 32 #include "impastpl.hxx" 33 #include <xmloff/xmlexppr.hxx> 34 #include <xmloff/xmlexp.hxx> 35 #include <xmloff/families.hxx> 36 #ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX 37 #include <xmloff/PageMasterStyleMap.hxx> 38 #endif 39 40 using namespace ::std; 41 using ::rtl::OUString; 42 using ::rtl::OUStringBuffer; 43 44 using namespace ::com::sun::star; 45 using namespace ::xmloff::token; 46 47 //############################################################################# 48 // 49 // Class SvXMLAutoStylePool_Impl 50 // 51 52 /////////////////////////////////////////////////////////////////////////////// 53 // 54 // ctor/dtor class SvXMLAutoStylePool_Impl 55 // 56 57 SvXMLAutoStylePoolP_Impl::SvXMLAutoStylePoolP_Impl( SvXMLExport& rExp) 58 : rExport( rExp ), 59 maFamilyList( 5, 5 ) 60 { 61 } 62 63 SvXMLAutoStylePoolP_Impl::~SvXMLAutoStylePoolP_Impl() 64 { 65 for (;;) { 66 XMLFamilyData_Impl* pData = maFamilyList.Remove( sal_uLong(0) ); 67 if (pData == NULL) { 68 break; 69 } 70 delete pData; 71 } 72 } 73 74 /////////////////////////////////////////////////////////////////////////////// 75 // 76 // Adds stylefamily-informations to sorted list 77 // 78 79 void SvXMLAutoStylePoolP_Impl::AddFamily( 80 sal_Int32 nFamily, 81 const OUString& rStrName, 82 const UniReference < SvXMLExportPropertyMapper > & rMapper, 83 const OUString& rStrPrefix, 84 sal_Bool bAsFamily ) 85 { 86 // store family in a list if not already stored 87 sal_uLong nPos; 88 89 sal_uInt16 nExportFlags = GetExport().getExportFlags(); 90 sal_Bool bStylesOnly = (nExportFlags & EXPORT_STYLES) != 0 && (nExportFlags & EXPORT_CONTENT) == 0; 91 92 OUString aPrefix( rStrPrefix ); 93 if( bStylesOnly ) 94 { 95 aPrefix = OUString( 'M' ); 96 aPrefix += rStrPrefix; 97 } 98 99 XMLFamilyData_Impl *pFamily = new XMLFamilyData_Impl( nFamily, rStrName, rMapper, aPrefix, bAsFamily ); 100 if( !maFamilyList.Seek_Entry( pFamily, &nPos ) ) 101 maFamilyList.Insert( pFamily ); 102 else 103 delete pFamily; 104 } 105 106 /////////////////////////////////////////////////////////////////////////////// 107 // 108 // Adds a name to list 109 // 110 111 void SvXMLAutoStylePoolP_Impl::RegisterName( sal_Int32 nFamily, const OUString& rName ) 112 { 113 SvXMLAutoStylePoolNamesP_Impl *pNames = 0; 114 115 sal_uLong nPos; 116 XMLFamilyData_Impl aTmp( nFamily ); 117 if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) 118 pNames = maFamilyList.GetObject( nPos )->mpNameList; 119 120 DBG_ASSERT( pNames, 121 "SvXMLAutoStylePool_Impl::RegisterName: unknown family" ); 122 if( pNames ) 123 { 124 OUString *pName = new OUString( rName ); 125 if( !pNames->Insert( pName ) ) 126 delete pName; 127 } 128 } 129 130 /////////////////////////////////////////////////////////////////////////////// 131 // 132 // Retrieve the list of registered names 133 // 134 135 void SvXMLAutoStylePoolP_Impl::GetRegisteredNames( 136 uno::Sequence<sal_Int32>& rFamilies, 137 uno::Sequence<OUString>& rNames ) 138 { 139 // collect registered names + families 140 vector<sal_Int32> aFamilies; 141 vector<OUString> aNames; 142 143 // iterate over families 144 sal_uInt32 nCount = maFamilyList.Count(); 145 for( sal_uInt32 i = 0; i < nCount; i++ ) 146 { 147 XMLFamilyData_Impl* pFamily = maFamilyList.GetObject( i ); 148 149 // iterate over names 150 SvXMLAutoStylePoolNamesP_Impl* pNames = pFamily->mpNameList; 151 sal_uInt32 nNames = ( pNames != NULL ) ? pNames->Count() : 0; 152 for( sal_uInt32 j = 0; j < nNames; j++ ) 153 { 154 aFamilies.push_back( pFamily->mnFamily ); 155 aNames.push_back( *pNames->GetObject( j ) ); 156 } 157 } 158 159 // copy the families + names into the sequence types 160 DBG_ASSERT( aFamilies.size() == aNames.size(), "families != names" ); 161 162 rFamilies.realloc( aFamilies.size() ); 163 std::copy( aFamilies.begin(), aFamilies.end(), rFamilies.getArray() ); 164 165 rNames.realloc( aNames.size() ); 166 std::copy( aNames.begin(), aNames.end(), rNames.getArray() ); 167 } 168 169 /////////////////////////////////////////////////////////////////////////////// 170 // 171 // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list 172 // if not added, yet. 173 // 174 175 /*OUString SvXMLAutoStylePoolP_Impl::Add( sal_Int32 nFamily, 176 const OUString& rParent, 177 const vector< XMLPropertyState >& rProperties, 178 sal_Bool bCache )*/ 179 sal_Bool SvXMLAutoStylePoolP_Impl::Add(OUString& rName, sal_Int32 nFamily, 180 const OUString& rParent, 181 const ::std::vector< XMLPropertyState >& rProperties, 182 sal_Bool bCache, 183 bool bDontSeek ) 184 { 185 sal_Bool bRet(sal_False); 186 sal_uLong nPos; 187 188 XMLFamilyData_Impl *pFamily = 0; 189 XMLFamilyData_Impl aTemporary( nFamily ); 190 if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) ) 191 { 192 pFamily = maFamilyList.GetObject( nPos ); 193 } 194 195 DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" ); 196 if( pFamily ) 197 { 198 SvXMLAutoStylePoolParentP_Impl aTmp( rParent ); 199 SvXMLAutoStylePoolParentP_Impl *pParent = 0; 200 201 SvXMLAutoStylePoolParentsP_Impl *pParents = pFamily->mpParentList; 202 if( pParents->Seek_Entry( &aTmp, &nPos ) ) 203 { 204 pParent = pParents->GetObject( nPos ); 205 } 206 else 207 { 208 pParent = new SvXMLAutoStylePoolParentP_Impl( rParent ); 209 pParents->Insert( pParent ); 210 } 211 212 if( pParent->Add( pFamily, rProperties, rName, bDontSeek ) ) 213 { 214 pFamily->mnCount++; 215 bRet = sal_True; 216 } 217 218 if( bCache ) 219 { 220 if( !pFamily->pCache ) 221 pFamily->pCache = new SvXMLAutoStylePoolCache_Impl( 256, 256 ); 222 if( pFamily->pCache->Count() < MAX_CACHE_SIZE ) 223 pFamily->pCache->Insert( new OUString( rName ), 224 pFamily->pCache->Count() ); 225 } 226 } 227 228 return bRet; 229 } 230 231 sal_Bool SvXMLAutoStylePoolP_Impl::AddNamed(const OUString& rName, sal_Int32 nFamily, 232 const OUString& rParent, const ::std::vector< XMLPropertyState >& rProperties ) 233 { 234 // get family and parent the same way as in Add() 235 sal_Bool bRet(sal_False); 236 sal_uLong nPos; 237 238 XMLFamilyData_Impl *pFamily = 0; 239 XMLFamilyData_Impl aTemporary( nFamily ); 240 if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) ) 241 { 242 pFamily = maFamilyList.GetObject( nPos ); 243 } 244 245 DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" ); 246 if( pFamily ) 247 { 248 SvXMLAutoStylePoolParentP_Impl aTmp( rParent ); 249 SvXMLAutoStylePoolParentP_Impl *pParent = 0; 250 251 SvXMLAutoStylePoolParentsP_Impl *pParents = pFamily->mpParentList; 252 if( pParents->Seek_Entry( &aTmp, &nPos ) ) 253 { 254 pParent = pParents->GetObject( nPos ); 255 } 256 else 257 { 258 pParent = new SvXMLAutoStylePoolParentP_Impl( rParent ); 259 pParents->Insert( pParent ); 260 } 261 262 if( pParent->AddNamed( pFamily, rProperties, rName ) ) 263 { 264 pFamily->mnCount++; 265 bRet = sal_True; 266 } 267 } 268 269 return bRet; 270 } 271 272 OUString SvXMLAutoStylePoolP_Impl::AddToCache( sal_Int32 nFamily, 273 const OUString& rParent ) 274 { 275 sal_uLong nPos; 276 277 XMLFamilyData_Impl *pFamily = 0; 278 XMLFamilyData_Impl aTmp( nFamily ); 279 if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) 280 { 281 pFamily = maFamilyList.GetObject( nPos ); 282 } 283 284 DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" ); 285 if( pFamily ) 286 { 287 if( !pFamily->pCache ) 288 pFamily->pCache = new SvXMLAutoStylePoolCache_Impl( 256, 256 ); 289 if( pFamily->pCache->Count() < MAX_CACHE_SIZE ) 290 pFamily->pCache->Insert( new OUString( rParent ), 291 pFamily->pCache->Count() ); 292 } 293 294 return rParent; 295 } 296 /////////////////////////////////////////////////////////////////////////////// 297 // 298 // Search for a array of XMLPropertyState ( vector< XMLPropertyState > ) in list 299 // 300 301 OUString SvXMLAutoStylePoolP_Impl::Find( sal_Int32 nFamily, 302 const OUString& rParent, 303 const vector< XMLPropertyState >& rProperties ) const 304 { 305 OUString sName; 306 307 sal_uLong nPos; 308 XMLFamilyData_Impl aTemporary( nFamily ); 309 XMLFamilyData_Impl *pFamily = 0; 310 if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) ) 311 { 312 pFamily = maFamilyList.GetObject( nPos ); 313 } 314 315 DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Find: unknown family" ); 316 317 if( pFamily ) 318 { 319 SvXMLAutoStylePoolParentP_Impl aTmp( rParent ); 320 321 const SvXMLAutoStylePoolParentsP_Impl* pParents = 322 pFamily->mpParentList; 323 if( pParents->Seek_Entry( &aTmp, &nPos ) ) 324 sName = pParents->GetObject( nPos )->Find( pFamily, rProperties ); 325 } 326 327 return sName; 328 } 329 330 OUString SvXMLAutoStylePoolP_Impl::FindAndRemoveCached( sal_Int32 nFamily ) const 331 { 332 OUString sName; 333 334 sal_uLong nPos; 335 XMLFamilyData_Impl aTmp( nFamily ); 336 XMLFamilyData_Impl *pFamily = 0; 337 if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) 338 { 339 pFamily = maFamilyList.GetObject( nPos ); 340 } 341 342 DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Find: unknown family" ); 343 344 if( pFamily ) 345 { 346 DBG_ASSERT( pFamily->pCache, "family doesn't have a cache" ); 347 348 // The cache may be empty already. This happens if it was filled 349 // completly. 350 if( pFamily->pCache && pFamily->pCache->Count() ) 351 { 352 OUString *pName = pFamily->pCache->Remove( 0UL ); 353 sName = *pName; 354 delete pName; 355 } 356 } 357 358 return sName; 359 } 360 361 /////////////////////////////////////////////////////////////////////////////// 362 // 363 // export 364 // 365 366 void SvXMLAutoStylePoolP_Impl::exportXML( 367 sal_Int32 nFamily, 368 const uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > &, 369 const SvXMLUnitConverter&, 370 const SvXMLNamespaceMap&, 371 const SvXMLAutoStylePoolP *pAntiImpl) const 372 { 373 sal_uInt32 nCount = 0; 374 375 // Get list of parents for current family (nFamily) 376 sal_uLong nPos; 377 XMLFamilyData_Impl aTmp( nFamily ); 378 XMLFamilyData_Impl *pFamily = 0; 379 if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) 380 { 381 pFamily = maFamilyList.GetObject( nPos ); 382 nCount = pFamily->mnCount; 383 } 384 385 DBG_ASSERT( pFamily, 386 "SvXMLAutoStylePool_Impl::exportXML: unknown family" ); 387 if( pFamily && nCount > 0 ) 388 { 389 ///////////////////////////////////////////////////////////////////////////////////// 390 // create, initialize and fill helper-structure (SvXMLAutoStylePoolProperties_Impl) 391 // wich contains a parent-name and a SvXMLAutoStylePoolProperties_Impl 392 // 393 const SvXMLAutoStylePoolParentsP_Impl *pParents = 394 pFamily->mpParentList; 395 396 SvXMLAutoStylePoolPExport_Impl* aExpStyles = 397 new SvXMLAutoStylePoolPExport_Impl[nCount]; 398 399 sal_uInt32 i; 400 for( i=0; i < nCount; i++ ) 401 { 402 aExpStyles[i].mpParent = 0; 403 aExpStyles[i].mpProperties = 0; 404 } 405 406 sal_uInt32 nParents = pParents->Count(); 407 for( i=0; i < nParents; i++ ) 408 { 409 const SvXMLAutoStylePoolParentP_Impl* pParent = 410 pParents->GetObject( i ); 411 sal_uInt32 nProperties = pParent->GetPropertiesList().Count(); 412 for( sal_uInt32 j=0; j < nProperties; j++ ) 413 { 414 const SvXMLAutoStylePoolPropertiesP_Impl *pProperties = 415 pParent->GetPropertiesList().GetObject( j ); 416 nPos = pProperties->GetPos(); 417 DBG_ASSERT( nPos < nCount, 418 "SvXMLAutoStylePool_Impl::exportXML: wrong position" ); 419 if( nPos < nCount ) 420 { 421 DBG_ASSERT( !aExpStyles[nPos].mpProperties, 422 "SvXMLAutoStylePool_Impl::exportXML: double position" ); 423 aExpStyles[nPos].mpProperties = pProperties; 424 aExpStyles[nPos].mpParent = &pParent->GetParent(); 425 } 426 } 427 } 428 429 ///////////////////////////////////////////////////////////////////////////////////// 430 // 431 // create string to export for each XML-style. That means for each property-list 432 // 433 OUString aStrFamilyName = pFamily->maStrFamilyName; 434 435 for( i=0; i<nCount; i++ ) 436 { 437 DBG_ASSERT( aExpStyles[i].mpProperties, 438 "SvXMLAutoStylePool_Impl::exportXML: empty position" ); 439 440 if( aExpStyles[i].mpProperties ) 441 { 442 GetExport().AddAttribute( 443 XML_NAMESPACE_STYLE, XML_NAME, 444 aExpStyles[i].mpProperties->GetName() ); 445 446 if( pFamily->bAsFamily ) 447 { 448 GetExport().AddAttribute( 449 XML_NAMESPACE_STYLE, XML_FAMILY, aStrFamilyName ); 450 } 451 452 if( aExpStyles[i].mpParent->getLength() ) 453 { 454 GetExport().AddAttribute( 455 XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME, 456 GetExport().EncodeStyleName( 457 *aExpStyles[i].mpParent ) ); 458 } 459 460 OUString sName; 461 if( pFamily->bAsFamily ) 462 sName = GetXMLToken(XML_STYLE); 463 else 464 sName = pFamily->maStrFamilyName; 465 466 pAntiImpl->exportStyleAttributes( 467 GetExport().GetAttrList(), 468 nFamily, 469 aExpStyles[i].mpProperties->GetProperties(), 470 *pFamily->mxMapper.get() 471 , GetExport().GetMM100UnitConverter(), 472 GetExport().GetNamespaceMap() 473 ); 474 475 SvXMLElementExport aElem( GetExport(), 476 XML_NAMESPACE_STYLE, sName, 477 sal_True, sal_True ); 478 479 sal_Int32 nStart(-1); 480 sal_Int32 nEnd(-1); 481 if (nFamily == XML_STYLE_FAMILY_PAGE_MASTER) 482 { 483 nStart = 0; 484 sal_Int32 nIndex = 0; 485 UniReference< XMLPropertySetMapper > aPropMapper = 486 pFamily->mxMapper->getPropertySetMapper(); 487 sal_Int16 nContextID; 488 while(nIndex < aPropMapper->GetEntryCount() && nEnd == -1) 489 { 490 nContextID = aPropMapper->GetEntryContextId( nIndex ); 491 if (nContextID && ((nContextID & CTF_PM_FLAGMASK) != XML_PM_CTF_START)) 492 nEnd = nIndex; 493 nIndex++; 494 } 495 if (nEnd == -1) 496 nEnd = nIndex; 497 } 498 499 pFamily->mxMapper->exportXML( 500 GetExport(), 501 aExpStyles[i].mpProperties->GetProperties(), 502 nStart, nEnd, XML_EXPORT_FLAG_IGN_WS ); 503 504 pAntiImpl->exportStyleContent( 505 GetExport().GetDocHandler(), 506 nFamily, 507 aExpStyles[i].mpProperties->GetProperties(), 508 *pFamily->mxMapper.get(), 509 GetExport().GetMM100UnitConverter(), 510 GetExport().GetNamespaceMap() 511 ); 512 } 513 } 514 515 delete[] aExpStyles; 516 } 517 } 518 519 void SvXMLAutoStylePoolP_Impl::ClearEntries() 520 { 521 for(sal_uInt32 a = 0L; a < maFamilyList.Count(); a++) 522 maFamilyList[a]->ClearEntries(); 523 } 524