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