Update ooo320-m1
[ooovba.git] / xmloff / source / text / XMLTextColumnsContext.cxx
blob5bb67f69865994d07a99084395cc2c474e1b63d9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLTextColumnsContext.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
33 #include <com/sun/star/text/XTextColumns.hpp>
34 #include <com/sun/star/text/TextColumn.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/style/VerticalAlignment.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <xmloff/xmltkmap.hxx>
39 #include <xmloff/xmluconv.hxx>
40 #include <xmloff/nmspmap.hxx>
41 #include "xmlnmspe.hxx"
42 #include <xmloff/xmlimp.hxx>
43 #include <xmloff/xmltoken.hxx>
44 #include "XMLTextColumnsContext.hxx"
45 #define _SVSTDARR_USHORTS
46 #include <svtools/svstdarr.hxx>
48 using ::rtl::OUString;
49 using ::rtl::OUStringBuffer;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::text;
55 using namespace ::com::sun::star::style;
56 using namespace ::com::sun::star::beans;
57 using namespace ::xmloff::token;
59 enum SvXMLTokenMapAttrs
61 XML_TOK_COLUMN_WIDTH,
62 XML_TOK_COLUMN_MARGIN_LEFT,
63 XML_TOK_COLUMN_MARGIN_RIGHT,
64 XML_TOK_COLUMN_END=XML_TOK_UNKNOWN
67 enum SvXMLSepTokenMapAttrs
69 XML_TOK_COLUMN_SEP_WIDTH,
70 XML_TOK_COLUMN_SEP_HEIGHT,
71 XML_TOK_COLUMN_SEP_COLOR,
72 XML_TOK_COLUMN_SEP_ALIGN,
73 XML_TOK_COLUMN_SEP_END=XML_TOK_UNKNOWN
76 static __FAR_DATA SvXMLTokenMapEntry aColAttrTokenMap[] =
78 { XML_NAMESPACE_STYLE, XML_REL_WIDTH, XML_TOK_COLUMN_WIDTH },
79 { XML_NAMESPACE_FO, XML_START_INDENT, XML_TOK_COLUMN_MARGIN_LEFT },
80 { XML_NAMESPACE_FO, XML_END_INDENT, XML_TOK_COLUMN_MARGIN_RIGHT },
81 XML_TOKEN_MAP_END
84 static __FAR_DATA SvXMLTokenMapEntry aColSepAttrTokenMap[] =
86 { XML_NAMESPACE_STYLE, XML_WIDTH, XML_TOK_COLUMN_SEP_WIDTH },
87 { XML_NAMESPACE_STYLE, XML_COLOR, XML_TOK_COLUMN_SEP_COLOR },
88 { XML_NAMESPACE_STYLE, XML_HEIGHT, XML_TOK_COLUMN_SEP_HEIGHT },
89 { XML_NAMESPACE_STYLE, XML_VERTICAL_ALIGN, XML_TOK_COLUMN_SEP_ALIGN },
90 XML_TOKEN_MAP_END
93 SvXMLEnumMapEntry __READONLY_DATA pXML_Sep_Align_Enum[] =
95 { XML_TOP, VerticalAlignment_TOP },
96 { XML_MIDDLE, VerticalAlignment_MIDDLE },
97 { XML_BOTTOM, VerticalAlignment_BOTTOM },
98 { XML_TOKEN_INVALID, 0 }
101 class XMLTextColumnContext_Impl: public SvXMLImportContext
103 text::TextColumn aColumn;
105 public:
106 TYPEINFO();
108 XMLTextColumnContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
109 const OUString& rLName,
110 const uno::Reference<
111 xml::sax::XAttributeList > & xAttrList,
112 const SvXMLTokenMap& rTokenMap );
114 virtual ~XMLTextColumnContext_Impl();
116 text::TextColumn& getTextColumn() { return aColumn; }
119 TYPEINIT1( XMLTextColumnContext_Impl, SvXMLImportContext );
121 XMLTextColumnContext_Impl::XMLTextColumnContext_Impl(
122 SvXMLImport& rImport, sal_uInt16 nPrfx,
123 const OUString& rLName,
124 const uno::Reference<
125 xml::sax::XAttributeList > & xAttrList,
126 const SvXMLTokenMap& rTokenMap ) :
127 SvXMLImportContext( rImport, nPrfx, rLName )
129 aColumn.Width = 0;
130 aColumn.LeftMargin = 0;
131 aColumn.RightMargin = 0;
133 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
134 for( sal_Int16 i=0; i < nAttrCount; i++ )
136 const OUString& rAttrName = xAttrList->getNameByIndex( i );
137 OUString aLocalName;
138 sal_uInt16 nPrefix =
139 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
140 &aLocalName );
141 const OUString& rValue = xAttrList->getValueByIndex( i );
143 sal_Int32 nVal;
144 switch( rTokenMap.Get( nPrefix, aLocalName ) )
146 case XML_TOK_COLUMN_WIDTH:
148 sal_Int32 nPos = rValue.indexOf( (sal_Unicode)'*' );
149 if( nPos != -1 && nPos+1 == rValue.getLength() )
151 OUString sTmp( rValue.copy( 0, nPos ) );
152 if( GetImport().GetMM100UnitConverter().
153 convertNumber( nVal, sTmp, 0, USHRT_MAX ) )
154 aColumn.Width = nVal;
157 break;
158 case XML_TOK_COLUMN_MARGIN_LEFT:
159 if( GetImport().GetMM100UnitConverter().
160 convertMeasure( nVal, rValue ) )
161 aColumn.LeftMargin = nVal;
162 break;
163 case XML_TOK_COLUMN_MARGIN_RIGHT:
165 if( GetImport().GetMM100UnitConverter().
166 convertMeasure( nVal, rValue ) )
167 aColumn.RightMargin = nVal;
168 break;
169 default:
170 break;
175 XMLTextColumnContext_Impl::~XMLTextColumnContext_Impl()
179 // --------------------------------------------------------------------------
181 class XMLTextColumnSepContext_Impl: public SvXMLImportContext
183 sal_Int32 nWidth;
184 sal_Int32 nColor;
185 sal_Int8 nHeight;
186 VerticalAlignment eVertAlign;
189 public:
190 TYPEINFO();
192 XMLTextColumnSepContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
193 const OUString& rLName,
194 const uno::Reference<
195 xml::sax::XAttributeList > & xAttrList,
196 const SvXMLTokenMap& rTokenMap );
198 virtual ~XMLTextColumnSepContext_Impl();
200 sal_Int32 GetWidth() const { return nWidth; }
201 sal_Int32 GetColor() const { return nColor; }
202 sal_Int8 GetHeight() const { return nHeight; }
203 VerticalAlignment GetVertAlign() const { return eVertAlign; }
207 TYPEINIT1( XMLTextColumnSepContext_Impl, SvXMLImportContext );
209 XMLTextColumnSepContext_Impl::XMLTextColumnSepContext_Impl(
210 SvXMLImport& rImport, sal_uInt16 nPrfx,
211 const OUString& rLName,
212 const uno::Reference<
213 xml::sax::XAttributeList > & xAttrList,
214 const SvXMLTokenMap& rTokenMap ) :
215 SvXMLImportContext( rImport, nPrfx, rLName ),
216 nWidth( 2 ),
217 nColor( 0 ),
218 nHeight( 100 ),
219 eVertAlign( VerticalAlignment_TOP )
221 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
222 for( sal_Int16 i=0; i < nAttrCount; i++ )
224 const OUString& rAttrName = xAttrList->getNameByIndex( i );
225 OUString aLocalName;
226 sal_uInt16 nPrefix =
227 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
228 &aLocalName );
229 const OUString& rValue = xAttrList->getValueByIndex( i );
231 sal_Int32 nVal;
232 switch( rTokenMap.Get( nPrefix, aLocalName ) )
234 case XML_TOK_COLUMN_SEP_WIDTH:
235 if( GetImport().GetMM100UnitConverter().
236 convertMeasure( nVal, rValue ) )
237 nWidth = nVal;
238 break;
239 case XML_TOK_COLUMN_SEP_HEIGHT:
240 if( GetImport().GetMM100UnitConverter().
241 convertPercent( nVal, rValue ) &&
242 nVal >=1 && nVal <= 100 )
243 nHeight = (sal_Int8)nVal;
244 break;
245 case XML_TOK_COLUMN_SEP_COLOR:
247 Color aColor;
248 if( GetImport().GetMM100UnitConverter().
249 convertColor( aColor, rValue ) )
250 nColor = (sal_Int32)aColor.GetColor();
252 break;
253 case XML_TOK_COLUMN_SEP_ALIGN:
255 sal_uInt16 nAlign;
256 if( GetImport().GetMM100UnitConverter().
257 convertEnum( nAlign, rValue,
258 pXML_Sep_Align_Enum ) )
259 eVertAlign = (VerticalAlignment)nAlign;
261 break;
266 XMLTextColumnSepContext_Impl::~XMLTextColumnSepContext_Impl()
270 // --------------------------------------------------------------------------
272 typedef XMLTextColumnContext_Impl *XMLTextColumnContext_ImplPtr;
273 SV_DECL_PTRARR( XMLTextColumnsArray_Impl, XMLTextColumnContext_ImplPtr, 5, 5 )
275 TYPEINIT1( XMLTextColumnsContext, XMLElementPropertyContext );
277 XMLTextColumnsContext::XMLTextColumnsContext(
278 SvXMLImport& rImport, sal_uInt16 nPrfx,
279 const OUString& rLName,
280 const Reference< xml::sax::XAttributeList >&
281 xAttrList,
282 const XMLPropertyState& rProp,
283 ::std::vector< XMLPropertyState > &rProps )
284 : XMLElementPropertyContext( rImport, nPrfx, rLName, rProp, rProps )
285 , sSeparatorLineIsOn(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineIsOn"))
286 , sSeparatorLineWidth(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineWidth"))
287 , sSeparatorLineColor(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineColor"))
288 , sSeparatorLineRelativeHeight(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineRelativeHeight"))
289 , sSeparatorLineVerticalAlignment(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineVerticalAlignment"))
290 , sIsAutomatic(RTL_CONSTASCII_USTRINGPARAM("IsAutomatic"))
291 , sAutomaticDistance(RTL_CONSTASCII_USTRINGPARAM("AutomaticDistance"))
292 , pColumns( 0 )
293 , pColumnSep( 0 )
294 , pColumnAttrTokenMap( new SvXMLTokenMap(aColAttrTokenMap) )
295 , pColumnSepAttrTokenMap( new SvXMLTokenMap(aColSepAttrTokenMap) )
296 , nCount( 0 )
297 , bAutomatic( sal_False )
298 , nAutomaticDistance( 0 )
300 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
301 sal_Int32 nVal;
302 for( sal_Int16 i=0; i < nAttrCount; i++ )
304 const OUString& rAttrName = xAttrList->getNameByIndex( i );
305 OUString aLocalName;
306 sal_uInt16 nPrefix =
307 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
308 &aLocalName );
309 const OUString& rValue = xAttrList->getValueByIndex( i );
310 if( XML_NAMESPACE_FO == nPrefix )
312 if( IsXMLToken( aLocalName, XML_COLUMN_COUNT ) &&
313 GetImport().GetMM100UnitConverter().
314 convertNumber( nVal, rValue, 0, SHRT_MAX ) )
316 nCount = (sal_Int16)nVal;
318 else if( IsXMLToken( aLocalName, XML_COLUMN_GAP ) )
320 bAutomatic = GetImport().GetMM100UnitConverter().
321 convertMeasure( nAutomaticDistance, rValue );
327 XMLTextColumnsContext::~XMLTextColumnsContext()
329 if( pColumns )
331 sal_uInt16 nColCount = pColumns->Count();
332 while( nColCount )
334 nColCount--;
335 XMLTextColumnContext_Impl *pColumn = (*pColumns)[nColCount];
336 pColumns->Remove( nColCount, 1 );
337 pColumn->ReleaseRef();
340 if( pColumnSep )
341 pColumnSep->ReleaseRef();
343 delete pColumns;
344 delete pColumnAttrTokenMap;
345 delete pColumnSepAttrTokenMap;
348 SvXMLImportContext *XMLTextColumnsContext::CreateChildContext(
349 sal_uInt16 nPrefix,
350 const OUString& rLocalName,
351 const uno::Reference< xml::sax::XAttributeList > & xAttrList )
353 SvXMLImportContext *pContext = 0;
355 if( XML_NAMESPACE_STYLE == nPrefix &&
356 IsXMLToken( rLocalName, XML_COLUMN ) )
358 XMLTextColumnContext_Impl *pColumn =
359 new XMLTextColumnContext_Impl( GetImport(), nPrefix, rLocalName,
360 xAttrList, *pColumnAttrTokenMap );
362 // add new tabstop to array of tabstops
363 if( !pColumns )
364 pColumns = new XMLTextColumnsArray_Impl;
366 pColumns->Insert( pColumn, pColumns->Count() );
367 pColumn->AddRef();
369 pContext = pColumn;
371 else if( XML_NAMESPACE_STYLE == nPrefix &&
372 IsXMLToken( rLocalName, XML_COLUMN_SEP ) )
374 pColumnSep =
375 new XMLTextColumnSepContext_Impl( GetImport(), nPrefix, rLocalName,
376 xAttrList, *pColumnSepAttrTokenMap );
377 pColumnSep->AddRef();
379 pContext = pColumnSep;
381 else
383 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
386 return pContext;
389 void XMLTextColumnsContext::EndElement( )
391 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
392 if( !xFactory.is() )
393 return;
395 Reference<XInterface> xIfc = xFactory->createInstance(
396 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextColumns")));
397 if( !xIfc.is() )
398 return;
400 Reference< XTextColumns > xColumns( xIfc, UNO_QUERY );
401 if ( 0 == nCount )
403 // zero columns = no columns -> 1 column
404 xColumns->setColumnCount( 1 );
406 else if( !bAutomatic && pColumns &&
407 pColumns->Count() == (sal_uInt16)nCount )
409 // if we have column descriptions, one per column, and we don't use
410 // automatic width, then set the column widths
412 sal_Int32 nRelWidth = 0;
413 sal_uInt16 nColumnsWithWidth = 0;
414 sal_Int16 i;
416 for( i = 0; i < nCount; i++ )
418 const TextColumn& rColumn =
419 (*pColumns)[(sal_uInt16)i]->getTextColumn();
420 if( rColumn.Width > 0 )
422 nRelWidth += rColumn.Width;
423 nColumnsWithWidth++;
426 if( nColumnsWithWidth < nCount )
428 sal_Int32 nColWidth = 0==nRelWidth
429 ? USHRT_MAX / nCount
430 : nRelWidth / nColumnsWithWidth;
432 for( i=0; i < nCount; i++ )
434 TextColumn& rColumn =
435 (*pColumns)[(sal_uInt16)i]->getTextColumn();
436 if( rColumn.Width == 0 )
438 rColumn.Width = nColWidth;
439 nRelWidth += rColumn.Width;
440 if( 0 == --nColumnsWithWidth )
441 break;
446 Sequence< TextColumn > aColumns( (sal_Int32)nCount );
447 TextColumn *pTextColumns = aColumns.getArray();
448 for( i=0; i < nCount; i++ )
449 *pTextColumns++ = (*pColumns)[(sal_uInt16)i]->getTextColumn();
451 xColumns->setColumns( aColumns );
453 else
455 // only set column count (and let the columns be distributed
456 // automatically)
458 xColumns->setColumnCount( nCount );
461 Reference < XPropertySet > xPropSet( xColumns, UNO_QUERY );
462 if( xPropSet.is() )
464 Any aAny;
465 sal_Bool bOn = pColumnSep != 0;
467 aAny.setValue( &bOn, ::getBooleanCppuType() );
468 xPropSet->setPropertyValue( sSeparatorLineIsOn, aAny );
470 if( pColumnSep )
472 if( pColumnSep->GetWidth() )
474 aAny <<= pColumnSep->GetWidth();
475 xPropSet->setPropertyValue( sSeparatorLineWidth, aAny );
477 if( pColumnSep->GetHeight() )
479 aAny <<= pColumnSep->GetHeight();
480 xPropSet->setPropertyValue( sSeparatorLineRelativeHeight,
481 aAny );
485 aAny <<= pColumnSep->GetColor();
486 xPropSet->setPropertyValue( sSeparatorLineColor, aAny );
489 aAny <<= pColumnSep->GetVertAlign();
490 xPropSet->setPropertyValue( sSeparatorLineVerticalAlignment, aAny );
493 // handle 'automatic columns': column distance
494 if( bAutomatic )
496 aAny <<= nAutomaticDistance;
497 xPropSet->setPropertyValue( sAutomaticDistance, aAny );
501 aProp.maValue <<= xColumns;
503 SetInsert( sal_True );
504 XMLElementPropertyContext::EndElement();