1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLTextColumnsContext.cxx,v $
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
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
},
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
},
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
;
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
)
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
);
139 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName
,
141 const OUString
& rValue
= xAttrList
->getValueByIndex( i
);
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
;
158 case XML_TOK_COLUMN_MARGIN_LEFT
:
159 if( GetImport().GetMM100UnitConverter().
160 convertMeasure( nVal
, rValue
) )
161 aColumn
.LeftMargin
= nVal
;
163 case XML_TOK_COLUMN_MARGIN_RIGHT
:
165 if( GetImport().GetMM100UnitConverter().
166 convertMeasure( nVal
, rValue
) )
167 aColumn
.RightMargin
= nVal
;
175 XMLTextColumnContext_Impl::~XMLTextColumnContext_Impl()
179 // --------------------------------------------------------------------------
181 class XMLTextColumnSepContext_Impl
: public SvXMLImportContext
186 VerticalAlignment eVertAlign
;
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
),
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
);
227 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName
,
229 const OUString
& rValue
= xAttrList
->getValueByIndex( i
);
232 switch( rTokenMap
.Get( nPrefix
, aLocalName
) )
234 case XML_TOK_COLUMN_SEP_WIDTH
:
235 if( GetImport().GetMM100UnitConverter().
236 convertMeasure( nVal
, rValue
) )
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
;
245 case XML_TOK_COLUMN_SEP_COLOR
:
248 if( GetImport().GetMM100UnitConverter().
249 convertColor( aColor
, rValue
) )
250 nColor
= (sal_Int32
)aColor
.GetColor();
253 case XML_TOK_COLUMN_SEP_ALIGN
:
256 if( GetImport().GetMM100UnitConverter().
257 convertEnum( nAlign
, rValue
,
258 pXML_Sep_Align_Enum
) )
259 eVertAlign
= (VerticalAlignment
)nAlign
;
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
>&
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"))
294 , pColumnAttrTokenMap( new SvXMLTokenMap(aColAttrTokenMap
) )
295 , pColumnSepAttrTokenMap( new SvXMLTokenMap(aColSepAttrTokenMap
) )
297 , bAutomatic( sal_False
)
298 , nAutomaticDistance( 0 )
300 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
302 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
304 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
307 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName
,
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()
331 sal_uInt16 nColCount
= pColumns
->Count();
335 XMLTextColumnContext_Impl
*pColumn
= (*pColumns
)[nColCount
];
336 pColumns
->Remove( nColCount
, 1 );
337 pColumn
->ReleaseRef();
341 pColumnSep
->ReleaseRef();
344 delete pColumnAttrTokenMap
;
345 delete pColumnSepAttrTokenMap
;
348 SvXMLImportContext
*XMLTextColumnsContext::CreateChildContext(
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
364 pColumns
= new XMLTextColumnsArray_Impl
;
366 pColumns
->Insert( pColumn
, pColumns
->Count() );
371 else if( XML_NAMESPACE_STYLE
== nPrefix
&&
372 IsXMLToken( rLocalName
, XML_COLUMN_SEP
) )
375 new XMLTextColumnSepContext_Impl( GetImport(), nPrefix
, rLocalName
,
376 xAttrList
, *pColumnSepAttrTokenMap
);
377 pColumnSep
->AddRef();
379 pContext
= pColumnSep
;
383 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
389 void XMLTextColumnsContext::EndElement( )
391 Reference
<XMultiServiceFactory
> xFactory(GetImport().GetModel(),UNO_QUERY
);
395 Reference
<XInterface
> xIfc
= xFactory
->createInstance(
396 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextColumns")));
400 Reference
< XTextColumns
> xColumns( xIfc
, UNO_QUERY
);
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;
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
;
426 if( nColumnsWithWidth
< nCount
)
428 sal_Int32 nColWidth
= 0==nRelWidth
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
)
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
);
455 // only set column count (and let the columns be distributed
458 xColumns
->setColumnCount( nCount
);
461 Reference
< XPropertySet
> xPropSet( xColumns
, UNO_QUERY
);
465 sal_Bool bOn
= pColumnSep
!= 0;
467 aAny
.setValue( &bOn
, ::getBooleanCppuType() );
468 xPropSet
->setPropertyValue( sSeparatorLineIsOn
, aAny
);
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
,
485 aAny
<<= pColumnSep
->GetColor();
486 xPropSet
->setPropertyValue( sSeparatorLineColor
, aAny
);
489 aAny
<<= pColumnSep
->GetVertAlign();
490 xPropSet
->setPropertyValue( sSeparatorLineVerticalAlignment
, aAny
);
493 // handle 'automatic columns': column distance
496 aAny
<<= nAutomaticDistance
;
497 xPropSet
->setPropertyValue( sAutomaticDistance
, aAny
);
501 aProp
.maValue
<<= xColumns
;
503 SetInsert( sal_True
);
504 XMLElementPropertyContext::EndElement();