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 "xmloff/dllapi.h" 31 32 #include "sal/config.h" 33 #include <osl/diagnose.h> 34 35 #include <rtl/ustring.hxx> 36 #include <rtl/ustrbuf.hxx> 37 38 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> 39 #include <com/sun/star/text/XText.hpp> 40 #include <com/sun/star/container/XNamed.hpp> 41 #include <com/sun/star/container/XEnumerationAccess.hpp> 42 #include <com/sun/star/table/XCellRange.hpp> 43 #include <com/sun/star/table/XColumnRowRange.hpp> 44 #include <com/sun/star/table/CellContentType.hpp> 45 #include <com/sun/star/table/XMergeableCell.hpp> 46 #include <com/sun/star/style/XStyle.hpp> 47 #include <com/sun/star/beans/XPropertySetInfo.hpp> 48 49 #include "xmloff/table/XMLTableExport.hxx" 50 #include "xmloff/xmlnmspe.hxx" 51 #include <xmloff/xmlprmap.hxx> 52 #include <xmloff/xmlexppr.hxx> 53 #include <xmloff/xmlexp.hxx> 54 #include "table.hxx" 55 56 using ::rtl::OUString; 57 using namespace ::xmloff::token; 58 using namespace ::com::sun::star::uno; 59 using namespace ::com::sun::star::lang; 60 using namespace ::com::sun::star::table; 61 using namespace ::com::sun::star::beans; 62 using namespace ::com::sun::star::container; 63 using namespace ::com::sun::star::text; 64 using namespace ::com::sun::star::style; 65 using namespace ::xmloff::token; 66 67 // -------------------------------------------------------------------- 68 69 #define _MAP(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010 } 70 #define CMAP(name,prefix,token,type,context) _MAP(name,prefix,token,type|XML_TYPE_PROP_TABLE_COLUMN,context) 71 #define RMAP(name,prefix,token,type,context) _MAP(name,prefix,token,type|XML_TYPE_PROP_TABLE_ROW,context) 72 #define MAP_END { 0L, 0, 0, XML_EMPTY, 0, 0, SvtSaveOptions::ODFVER_010 } 73 74 // -------------------------------------------------------------------- 75 76 const XMLPropertyMapEntry* getColumnPropertiesMap() 77 { 78 static const XMLPropertyMapEntry aXMLColumnProperties[] = 79 { 80 CMAP( "Width", XML_NAMESPACE_STYLE, XML_COLUMN_WIDTH, XML_TYPE_MEASURE, 0 ), 81 CMAP( "OptimalWidth", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_COLUMN_WIDTH, XML_TYPE_BOOL, 0 ), 82 MAP_END 83 }; 84 85 return &aXMLColumnProperties[0]; 86 } 87 88 // -------------------------------------------------------------------- 89 90 const XMLPropertyMapEntry* getRowPropertiesMap() 91 { 92 static const XMLPropertyMapEntry aXMLRowProperties[] = 93 { 94 RMAP( "Height", XML_NAMESPACE_STYLE, XML_ROW_HEIGHT, XML_TYPE_MEASURE, 0 ), 95 RMAP( "OptimalHeight", XML_NAMESPACE_STYLE, XML_MIN_ROW_HEIGHT, XML_TYPE_MEASURE, 0 ), 96 RMAP( "OptimalWidth", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT, XML_TYPE_BOOL, 0 ), 97 MAP_END 98 }; 99 100 return &aXMLRowProperties[0]; 101 } 102 103 // -------------------------------------------------------------------- 104 105 class StringStatisticHelper : public std::map< OUString, sal_Int32 > 106 { 107 public: 108 void add( const OUString& rStyleName ); 109 void clear() { std::map< OUString, sal_Int32 >::clear(); } 110 111 sal_Int32 getModeString( /* out */ OUString& rModeString ); 112 }; 113 114 // -------------------------------------------------------------------- 115 116 void StringStatisticHelper::add( const OUString& rStyleName ) 117 { 118 std::map< OUString, sal_Int32 >::iterator iter( find( rStyleName ) ); 119 if( iter == end() ) 120 { 121 (*this)[rStyleName] = 1; 122 } 123 else 124 { 125 (*iter).second += 1; 126 } 127 } 128 129 // -------------------------------------------------------------------- 130 131 sal_Int32 StringStatisticHelper::getModeString( OUString& rStyleName ) 132 { 133 sal_Int32 nMax = 0; 134 for( std::map< OUString, sal_Int32 >::iterator iter( begin() ); iter != end(); iter++ ) 135 { 136 if( (*iter).second > nMax ) 137 { 138 rStyleName = (*iter).first; 139 nMax = (*iter).second; 140 } 141 } 142 143 return nMax; 144 } 145 146 // -------------------------------------------------------------------- 147 // class XMLTableExport 148 // -------------------------------------------------------------------- 149 150 XMLTableExport::XMLTableExport(SvXMLExport& rExp, const rtl::Reference< SvXMLExportPropertyMapper >& xExportPropertyMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef ) 151 : mrExport( rExp ) 152 , mbExportTables( false ) 153 { 154 Reference< XMultiServiceFactory > xFac( rExp.GetModel(), UNO_QUERY ); 155 if( xFac.is() ) try 156 { 157 Sequence< OUString > sSNS( xFac->getAvailableServiceNames() ); 158 sal_Int32 n = sSNS.getLength(); 159 const OUString* pSNS( sSNS.getConstArray() ); 160 while( --n > 0 ) 161 { 162 if( (*pSNS++).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.TableShape") ) ) 163 { 164 mbExportTables = true; 165 break; 166 } 167 } 168 } 169 catch( Exception& e ) 170 { 171 (void)e; 172 } 173 174 mxCellExportPropertySetMapper = xExportPropertyMapper; 175 mxCellExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp)); 176 177 mxRowExportPropertySetMapper = new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get() ) ); 178 mxColumnExportPropertySetMapper = new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef.get() ) ); 179 180 mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, 181 OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME)), 182 mxColumnExportPropertySetMapper.get(), 183 OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX))); 184 mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, 185 OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME)), 186 mxRowExportPropertySetMapper.get(), 187 OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX))); 188 // mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE 189 // OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME)), 190 // xTableStylesExportPropertySetMapper, 191 // OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX))); 192 mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, 193 OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), 194 mxCellExportPropertySetMapper.get(), 195 OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX))); 196 } 197 198 // -------------------------------------------------------------------- 199 200 XMLTableExport::~XMLTableExport () 201 { 202 } 203 204 // -------------------------------------------------------------------- 205 206 static bool has_states( const std::vector< XMLPropertyState >& xPropStates ) 207 { 208 if( !xPropStates.empty() ) 209 { 210 std::vector< XMLPropertyState >::const_iterator aIter( xPropStates.begin() ); 211 std::vector< XMLPropertyState >::const_iterator aEnd( xPropStates.end() ); 212 while( aIter != aEnd ) 213 { 214 if( aIter->mnIndex != -1 ) 215 return true; 216 aIter++; 217 } 218 } 219 return false; 220 } 221 222 // -------------------------------------------------------------------- 223 224 void XMLTableExport::collectTableAutoStyles(const Reference < XColumnRowRange >& xColumnRowRange) 225 { 226 if( !mbExportTables ) 227 return; 228 229 boost::shared_ptr< XMLTableInfo > pTableInfo( new XMLTableInfo() ); 230 maTableInfoMap[xColumnRowRange] = pTableInfo; 231 232 try 233 { 234 Reference< XIndexAccess > xIndexAccessCols( xColumnRowRange->getColumns(), UNO_QUERY_THROW ); 235 const sal_Int32 nColumnCount = xIndexAccessCols->getCount(); 236 for( sal_Int32 nColumn = 0; nColumn < nColumnCount; ++nColumn ) try 237 { 238 Reference< XPropertySet > xPropSet( xIndexAccessCols->getByIndex(nColumn) , UNO_QUERY_THROW ); 239 std::vector< XMLPropertyState > xPropStates( mxColumnExportPropertySetMapper->Filter( xPropSet ) ); 240 241 if( has_states( xPropStates ) ) 242 { 243 const OUString sStyleName( mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_COLUMN, xPropStates) ); 244 Reference< XInterface > xKey( xPropSet, UNO_QUERY ); 245 pTableInfo->maColumnStyleMap[xKey] = sStyleName; 246 } 247 } 248 catch( Exception& ) 249 { 250 DBG_ERROR("xmloff::XMLTableExport::collectTableAutoStyles(), exception during column style collection!"); 251 } 252 253 Reference< XIndexAccess > xIndexAccessRows( xColumnRowRange->getRows(), UNO_QUERY_THROW ); 254 const sal_Int32 nRowCount = xIndexAccessRows->getCount(); 255 pTableInfo->maDefaultRowCellStyles.resize(nRowCount); 256 257 StringStatisticHelper aStringStatistic; 258 259 for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) try 260 { 261 Reference< XPropertySet > xPropSet( xIndexAccessRows->getByIndex(nRow) , UNO_QUERY_THROW ); 262 std::vector< XMLPropertyState > xRowPropStates( mxRowExportPropertySetMapper->Filter( xPropSet ) ); 263 264 if( has_states( xRowPropStates ) ) 265 { 266 const OUString sStyleName( mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_ROW, xRowPropStates) ); 267 Reference< XInterface > xKey( xPropSet, UNO_QUERY ); 268 pTableInfo->maRowStyleMap[xKey] = sStyleName; 269 } 270 271 // get the current row 272 Reference< XCellRange > xCellRange( xPropSet, UNO_QUERY_THROW ); 273 for ( sal_Int32 nColumn = 0; nColumn < nColumnCount; ++nColumn ) 274 { 275 // get current cell, remarks row index is 0, because we get the range for each row seperate 276 Reference< XPropertySet > xCellSet( xCellRange->getCellByPosition(nColumn, 0), UNO_QUERY_THROW ); 277 278 // get style 279 OUString sParentStyleName; 280 Reference< XPropertySetInfo > xPropertySetInfo( xCellSet->getPropertySetInfo() ); 281 if( xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName( OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))) ) 282 { 283 Reference< XStyle > xStyle( xCellSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))), UNO_QUERY ); 284 if( xStyle.is() ) 285 sParentStyleName = xStyle->getName(); 286 } 287 288 // create auto style, if needed 289 OUString sStyleName; 290 std::vector< XMLPropertyState > xCellPropStates( mxCellExportPropertySetMapper->Filter( xCellSet ) ); 291 if( has_states( xCellPropStates ) ) 292 sStyleName = mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_CELL, xCellPropStates); 293 else 294 sStyleName = sParentStyleName; 295 296 if( sStyleName.getLength() ) 297 { 298 Reference< XInterface > xKey( xCellSet, UNO_QUERY ); 299 pTableInfo->maCellStyleMap[xKey] = sStyleName; 300 } 301 302 // create auto style for text 303 Reference< XText > xText(xCellSet, UNO_QUERY); 304 if(xText.is() && xText->getString().getLength()) 305 GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText ); 306 307 aStringStatistic.add( sStyleName ); 308 } 309 310 OUString sDefaultCellStyle; 311 if( aStringStatistic.getModeString( sDefaultCellStyle ) > 1 ) 312 pTableInfo->maDefaultRowCellStyles[nRow] = sDefaultCellStyle; 313 314 aStringStatistic.clear(); 315 } 316 catch( Exception& ) 317 { 318 DBG_ERROR("xmloff::XMLTableExport::collectTableAutoStyles(), exception during column style collection!"); 319 } 320 } 321 catch( Exception& ) 322 { 323 DBG_ERROR("xmloff::XMLTableExport::collectTableAutoStyles(), exception caught!"); 324 } 325 } 326 327 // -------------------------------------------------------------------- 328 329 void XMLTableExport::exportTable( const Reference < XColumnRowRange >& xColumnRowRange ) 330 { 331 if( !mbExportTables ) 332 return; 333 334 try 335 { 336 boost::shared_ptr< XMLTableInfo > pTableInfo( maTableInfoMap[xColumnRowRange] ); 337 338 // get row and column count 339 Reference< XIndexAccess > xIndexAccess( xColumnRowRange->getRows(), UNO_QUERY_THROW ); 340 Reference< XIndexAccess > xIndexAccessCols( xColumnRowRange->getColumns(), UNO_QUERY_THROW ); 341 342 const sal_Int32 rowCount = xIndexAccess->getCount(); 343 const sal_Int32 columnCount = xIndexAccessCols->getCount(); 344 345 SvXMLElementExport tableElement( mrExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True ); 346 347 // export table columns 348 ExportTableColumns( xIndexAccessCols, pTableInfo ); 349 350 // start iterating rows and columns 351 for ( sal_Int32 rowIndex = 0; rowIndex < rowCount; rowIndex++ ) 352 { 353 // get the current row 354 Reference< XCellRange > xCellRange( xIndexAccess->getByIndex(rowIndex), UNO_QUERY_THROW ); 355 356 OUString sDefaultCellStyle; 357 358 // table:style-name 359 if( pTableInfo.get() ) 360 { 361 Reference< XInterface > xKey( xCellRange, UNO_QUERY ); 362 const OUString sStyleName( pTableInfo->maRowStyleMap[xKey] ); 363 if( sStyleName.getLength() ) 364 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sStyleName ); 365 366 sDefaultCellStyle = pTableInfo->maDefaultRowCellStyles[rowIndex]; 367 if( sDefaultCellStyle.getLength() ) 368 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, sDefaultCellStyle ); 369 } 370 371 // write row element 372 SvXMLElementExport tableRowElement( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True ); 373 374 for ( sal_Int32 columnIndex = 0; columnIndex < columnCount; columnIndex++ ) 375 { 376 // get current cell, remarks row index is 0, because we get the range for each row seperate 377 Reference< XCell > xCell( xCellRange->getCellByPosition(columnIndex, 0), UNO_QUERY_THROW ); 378 379 // use XMergeableCell interface from offapi 380 Reference< XMergeableCell > xMergeableCell( xCell, UNO_QUERY_THROW ); 381 382 // export cell 383 ExportCell( xCell, pTableInfo, sDefaultCellStyle ); 384 } 385 } 386 } 387 catch( Exception ) 388 { 389 DBG_ERROR( "XMLTableExport::exportTable(), exception cought!" ); 390 } 391 } 392 393 // -------------------------------------------------------------------- 394 // Export the table columns 395 // -------------------------------------------------------------------- 396 397 void XMLTableExport::ExportTableColumns( const Reference < XIndexAccess >& xtableColumnsIndexAccess, const boost::shared_ptr< XMLTableInfo >& pTableInfo ) 398 { 399 const sal_Int32 nColumnCount = xtableColumnsIndexAccess->getCount(); 400 for( sal_Int32 nColumn = 0; nColumn < nColumnCount; ++nColumn ) 401 { 402 Reference< XPropertySet > xColumnProperties( xtableColumnsIndexAccess->getByIndex(nColumn) , UNO_QUERY ); 403 if ( xColumnProperties.is() ) 404 { 405 // table:style-name 406 if( pTableInfo.get() ) 407 { 408 Reference< XInterface > xKey( xColumnProperties, UNO_QUERY ); 409 const OUString sStyleName( pTableInfo->maColumnStyleMap[xKey] ); 410 if( sStyleName.getLength() ) 411 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sStyleName ); 412 } 413 414 // TODO: All columns first have to be checked if some ones 415 // have identical properties. If yes, attr table:number-columns-repeated 416 // has to be written. 417 SvXMLElementExport tableColumnElement( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True ); 418 } 419 } 420 } 421 422 // -------------------------------------------------------------------- 423 // ODF export for a table cell. 424 // -------------------------------------------------------------------- 425 426 void XMLTableExport::ExportCell( const Reference < XCell >& xCell, const boost::shared_ptr< XMLTableInfo >& pTableInfo, const OUString& rDefaultCellStyle ) 427 { 428 bool bIsMerged = false; 429 sal_Int32 nRowSpan = 0; 430 sal_Int32 nColSpan = 0; 431 432 try 433 { 434 if( pTableInfo.get() ) 435 { 436 // table:style-name 437 Reference< XInterface > xKey( xCell, UNO_QUERY ); 438 const OUString sStyleName( pTableInfo->maCellStyleMap[xKey] ); 439 if( sStyleName.getLength() && (sStyleName != rDefaultCellStyle) ) 440 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sStyleName ); 441 } 442 443 Reference< XMergeableCell > xMerge( xCell, UNO_QUERY ); 444 if( xMerge.is() ) 445 { 446 bIsMerged = xMerge->isMerged(); 447 nRowSpan = xMerge->getRowSpan(); 448 nColSpan = xMerge->getColumnSpan(); 449 } 450 DBG_ASSERT( (nRowSpan >= 1) && (nColSpan >= 1), "xmloff::XMLTableExport::ExportCell(), illegal row or col span < 1?" ); 451 } 452 catch ( Exception ) 453 { 454 DBG_ERROR( "exception while exporting a table cell" ); 455 } 456 457 // table:number-columns-repeated 458 // todo 459 460 // table:number-columns-spanned 461 if( nColSpan > 1 ) 462 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, OUString::valueOf( nColSpan ) ); 463 464 // table:number-rows-spanned 465 if( nRowSpan > 1 ) 466 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, OUString::valueOf( nRowSpan ) ); 467 468 // <table:table-cell> or <table:covered-table-cell> 469 SvXMLElementExport tableCellElement( mrExport, XML_NAMESPACE_TABLE, bIsMerged ? XML_COVERED_TABLE_CELL : XML_TABLE_CELL, sal_True, sal_True ); 470 471 // export cells text content 472 ImpExportText( xCell ); 473 } 474 475 // -------------------------------------------------------------------- 476 // ODF export of the text contents of a table cell. 477 // Remarks: Up to now we only export text contents! 478 // TODO: Check against nested tables .... 479 // -------------------------------------------------------------------- 480 481 void XMLTableExport::ImpExportText( const Reference< XCell >& xCell ) 482 { 483 Reference< XText > xText( xCell, UNO_QUERY ); 484 if( xText.is() && xText->getString().getLength()) 485 mrExport.GetTextParagraphExport()->exportText( xText ); 486 } 487 488 // -------------------------------------------------------------------- 489 490 void XMLTableExport::exportTableStyles() 491 { 492 if( !mbExportTables ) 493 return; 494 495 XMLStyleExport aStEx(mrExport, OUString(), mrExport.GetAutoStylePool().get()); 496 497 // write graphic family styles 498 aStEx.exportStyleFamily("cell", OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), mxCellExportPropertySetMapper.get(), sal_True, XML_STYLE_FAMILY_TABLE_CELL); 499 500 exportTableTemplates(); 501 } 502 503 // -------------------------------------------------------------------- 504 // Export the collected automatic styles 505 // -------------------------------------------------------------------- 506 507 void XMLTableExport::exportAutoStyles() 508 { 509 if( !mbExportTables ) 510 return; 511 512 mrExport.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_COLUMN, mrExport.GetDocHandler(), mrExport.GetMM100UnitConverter(), mrExport.GetNamespaceMap() ); 513 mrExport.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_ROW, mrExport.GetDocHandler(), mrExport.GetMM100UnitConverter(), mrExport.GetNamespaceMap() ); 514 mrExport.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_CELL, mrExport.GetDocHandler(), mrExport.GetMM100UnitConverter(), mrExport.GetNamespaceMap() ); 515 } 516 517 // -------------------------------------------------------------------- 518 519 const TableStyleElement* getTableStyleMap() 520 { 521 static struct TableStyleElement gTableStyleElements[] = 522 { 523 { XML_FIRST_ROW, OUString( RTL_CONSTASCII_USTRINGPARAM( "first-row" ) ) }, 524 { XML_LAST_ROW, OUString( RTL_CONSTASCII_USTRINGPARAM( "last-row" ) ) }, 525 { XML_FIRST_COLUMN, OUString( RTL_CONSTASCII_USTRINGPARAM( "first-column" ) ) }, 526 { XML_LAST_COLUMN, OUString( RTL_CONSTASCII_USTRINGPARAM( "last-column" ) ) }, 527 { XML_EVEN_ROWS, OUString( RTL_CONSTASCII_USTRINGPARAM( "even-rows" ) ) }, 528 { XML_ODD_ROWS, OUString( RTL_CONSTASCII_USTRINGPARAM( "odd-rows" ) ) }, 529 { XML_EVEN_COLUMNS, OUString( RTL_CONSTASCII_USTRINGPARAM( "even-columns" ) ) }, 530 { XML_ODD_COLUMNS, OUString( RTL_CONSTASCII_USTRINGPARAM( "odd-columns" ) ) }, 531 { XML_BODY, OUString( RTL_CONSTASCII_USTRINGPARAM( "body" ) ) }, 532 { XML_TOKEN_END, OUString() } 533 }; 534 535 return &gTableStyleElements[0]; 536 } 537 538 // -------------------------------------------------------------------- 539 540 void XMLTableExport::exportTableTemplates() 541 { 542 if( !mbExportTables ) 543 return; 544 545 try 546 { 547 Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrExport.GetModel(), UNO_QUERY_THROW ); 548 Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() ); 549 const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM("table" ) ); 550 Reference< XIndexAccess > xTableFamily( xFamilies->getByName( sFamilyName ), UNO_QUERY_THROW ); 551 552 for( sal_Int32 nIndex = 0; nIndex < xTableFamily->getCount(); nIndex++ ) try 553 { 554 Reference< XStyle > xTableStyle( xTableFamily->getByIndex( nIndex ), UNO_QUERY_THROW ); 555 if( !xTableStyle->isInUse() ) 556 continue; 557 558 Reference< XNameAccess > xStyleNames( xTableStyle, UNO_QUERY_THROW ); 559 560 mrExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, GetExport().EncodeStyleName( xTableStyle->getName() ) ); 561 SvXMLElementExport tableTemplate( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_TEMPLATE, sal_True, sal_True ); 562 563 const TableStyleElement* pElements = getTableStyleMap(); 564 while( pElements->meElement != XML_TOKEN_END ) 565 { 566 try 567 { 568 Reference< XStyle > xStyle( xStyleNames->getByName( pElements->msStyleName ), UNO_QUERY ); 569 if( xStyle.is() ) 570 { 571 mrExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, GetExport().EncodeStyleName( xStyle->getName() ) ); 572 SvXMLElementExport element( mrExport, XML_NAMESPACE_TABLE, pElements->meElement, sal_True, sal_True ); 573 } 574 } 575 catch( Exception& ) 576 { 577 DBG_ERROR("xmloff::XMLTableExport::exportTableTemplates(), exception caught!"); 578 } 579 580 pElements++; 581 } 582 } 583 catch( Exception& ) 584 { 585 DBG_ERROR("xmloff::XMLTableExport::exportTableDesigns(), exception caught while exporting a table design!"); 586 } 587 } 588 catch( Exception& ) 589 { 590 DBG_ERROR("xmloff::XMLTableExport::exportTableDesigns(), exception caught!"); 591 } 592 } 593 594 // -------------------------------------------------------------------- 595 596