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/controlpropertyhdl.hxx>
31 #include <com/sun/star/awt/TextAlign.hpp>
32 #include <com/sun/star/awt/FontWidth.hpp>
33 #include <com/sun/star/awt/FontEmphasisMark.hpp>
34 #include <xmloff/xmltypes.hxx>
35 #include "xmloff/NamedBoolPropertyHdl.hxx"
36 #include "formenums.hxx"
37 #include <xmloff/xmluconv.hxx>
38 #include <xmloff/xmltoken.hxx>
39 #include <rtl/ustrbuf.hxx>
40 #include <osl/diagnose.h>
41 #include "callbacks.hxx"
42 #include <xmloff/XMLConstantsPropertyHandler.hxx>
43 
44 //.........................................................................
45 namespace xmloff
46 {
47 //.........................................................................
48 
49 	using namespace ::com::sun::star::uno;
50 	using namespace ::com::sun::star::awt;
51 	using namespace ::com::sun::star::beans;
52 	using namespace ::xmloff::token;
53 
54 	//=====================================================================
55 	//= OControlPropertyHandlerFactory
56 	//=====================================================================
57 	//---------------------------------------------------------------------
58 	OControlPropertyHandlerFactory::OControlPropertyHandlerFactory()
59 		:m_pTextAlignHandler(NULL)
60 		,m_pControlBorderStyleHandler(NULL)
61         ,m_pControlBorderColorHandler(NULL)
62 		,m_pRotationAngleHandler(NULL)
63 		,m_pFontWidthHandler(NULL)
64 		,m_pFontEmphasisHandler(NULL)
65 		,m_pFontReliefHandler(NULL)
66 	{
67 	}
68 
69 	//---------------------------------------------------------------------
70 	OControlPropertyHandlerFactory::~OControlPropertyHandlerFactory()
71 	{
72 		delete m_pTextAlignHandler;
73 		delete m_pControlBorderStyleHandler;
74         delete m_pControlBorderColorHandler;
75 		delete m_pRotationAngleHandler;
76 		delete m_pFontWidthHandler;
77 		delete m_pFontEmphasisHandler;
78 		delete m_pFontReliefHandler;
79 	}
80 
81 	//---------------------------------------------------------------------
82 	const XMLPropertyHandler* OControlPropertyHandlerFactory::GetPropertyHandler(sal_Int32 _nType) const
83 	{
84 		const XMLPropertyHandler* pHandler = NULL;
85 
86 		switch (_nType)
87 		{
88 			case XML_TYPE_TEXT_ALIGN:
89 				if (!m_pTextAlignHandler)
90 					m_pTextAlignHandler = new XMLConstantsPropertyHandler(OEnumMapper::getEnumMap(OEnumMapper::epTextAlign), XML_TOKEN_INVALID );
91 				pHandler = m_pTextAlignHandler;
92 				break;
93 
94 			case XML_TYPE_CONTROL_BORDER:
95 				if (!m_pControlBorderStyleHandler)
96                     m_pControlBorderStyleHandler = new OControlBorderHandler( OControlBorderHandler::STYLE );
97 				pHandler = m_pControlBorderStyleHandler;
98 				break;
99 
100 			case XML_TYPE_CONTROL_BORDER_COLOR:
101 				if ( !m_pControlBorderColorHandler )
102 					m_pControlBorderColorHandler = new OControlBorderHandler( OControlBorderHandler::COLOR );
103 				pHandler = m_pControlBorderColorHandler;
104 				break;
105 
106 			case XML_TYPE_ROTATION_ANGLE:
107 				if (!m_pRotationAngleHandler)
108 					m_pRotationAngleHandler = new ORotationAngleHandler;
109 				pHandler = m_pRotationAngleHandler;
110 				break;
111 
112 			case XML_TYPE_FONT_WIDTH:
113 				if (!m_pFontWidthHandler)
114 					m_pFontWidthHandler = new OFontWidthHandler;
115 				pHandler = m_pFontWidthHandler;
116 				break;
117 
118 			case XML_TYPE_CONTROL_TEXT_EMPHASIZE:
119 				if (!m_pFontEmphasisHandler)
120 					m_pFontEmphasisHandler = new XMLConstantsPropertyHandler( OEnumMapper::getEnumMap(OEnumMapper::epFontEmphasis), XML_NONE );
121 				pHandler = m_pFontEmphasisHandler;
122 				break;
123 
124 			case XML_TYPE_TEXT_FONT_RELIEF:
125 				if (!m_pFontReliefHandler)
126 					m_pFontReliefHandler = new XMLConstantsPropertyHandler( OEnumMapper::getEnumMap(OEnumMapper::epFontRelief), XML_NONE );
127 				pHandler = m_pFontReliefHandler;
128 				break;
129             case XML_TYPE_TEXT_LINE_MODE:
130 		        pHandler = new XMLNamedBoolPropertyHdl(
131 									        ::xmloff::token::XML_SKIP_WHITE_SPACE,
132                                             ::xmloff::token::XML_CONTINUOUS);
133 		        break;
134 		}
135 
136 		if (!pHandler)
137 			pHandler = XMLPropertyHandlerFactory::GetPropertyHandler(_nType);
138 		return pHandler;
139 	}
140 
141 	//=====================================================================
142 	//= OControlTextEmphasisHandler
143 	//=====================================================================
144 	OControlTextEmphasisHandler::OControlTextEmphasisHandler()
145 	{
146 	}
147 
148 	//---------------------------------------------------------------------
149 	sal_Bool OControlTextEmphasisHandler::exportXML( ::rtl::OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
150 	{
151 		::rtl::OUStringBuffer aReturn;
152 		sal_Bool bSuccess = sal_False;
153 		sal_Int16 nFontEmphasis = sal_Int16();
154 		if (_rValue >>= nFontEmphasis)
155 		{
156 			// the type
157 			sal_Int16 nType = nFontEmphasis & ~(FontEmphasisMark::ABOVE | FontEmphasisMark::BELOW);
158 			// the position of the mark
159 			sal_Bool bBelow = 0 != (nFontEmphasis & FontEmphasisMark::BELOW);
160 
161 			// convert
162             bSuccess = SvXMLUnitConverter::convertEnum(aReturn, nType, OEnumMapper::getEnumMap(OEnumMapper::epFontEmphasis), XML_NONE);
163 			if (bSuccess)
164 			{
165 				aReturn.append( (sal_Unicode)' ' );
166 				aReturn.append( GetXMLToken(bBelow ? XML_BELOW : XML_ABOVE) );
167 
168 				_rStrExpValue = aReturn.makeStringAndClear();
169 			}
170 		}
171 
172 		return bSuccess;
173 	}
174 
175 	//---------------------------------------------------------------------
176 	sal_Bool OControlTextEmphasisHandler::importXML( const ::rtl::OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
177 	{
178 		sal_Bool bSuccess = sal_True;
179 		sal_uInt16 nEmphasis = FontEmphasisMark::NONE;
180 
181 		sal_Bool bBelow = sal_False;
182 		sal_Bool bHasPos = sal_False, bHasType = sal_False;
183 
184 		::rtl::OUString sToken;
185 		SvXMLTokenEnumerator aTokenEnum(_rStrImpValue);
186 		while (aTokenEnum.getNextToken(sToken))
187 		{
188 			if (!bHasPos)
189 			{
190 				if (IsXMLToken(sToken, XML_ABOVE))
191 				{
192 					bBelow = sal_False;
193 					bHasPos = sal_True;
194 				}
195 				else if (IsXMLToken(sToken, XML_BELOW))
196 				{
197 					bBelow = sal_True;
198 					bHasPos = sal_True;
199 				}
200 			}
201 			if (!bHasType)
202 			{
203 				if (SvXMLUnitConverter::convertEnum(nEmphasis, sToken, OEnumMapper::getEnumMap(OEnumMapper::epFontEmphasis)))
204 				{
205 					bHasType = sal_True;
206 				}
207 				else
208 				{
209 					bSuccess = sal_False;
210 					break;
211 				}
212 			}
213 		}
214 
215 		if (bSuccess)
216 		{
217 			nEmphasis |= bBelow ? FontEmphasisMark::BELOW : FontEmphasisMark::ABOVE;
218 			_rValue <<= (sal_Int16)nEmphasis;
219 		}
220 
221 		return bSuccess;
222 	}
223 
224 	//=====================================================================
225 	//= OControlBorderHandlerBase
226 	//=====================================================================
227 	//---------------------------------------------------------------------
228 	OControlBorderHandler::OControlBorderHandler( const OControlBorderHandler::BorderFacet _eFacet )
229         :m_eFacet( _eFacet )
230 	{
231 	}
232 
233 	//---------------------------------------------------------------------
234 	sal_Bool OControlBorderHandler::importXML( const ::rtl::OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
235 	{
236 		::rtl::OUString sToken;
237 		SvXMLTokenEnumerator aTokens(_rStrImpValue);
238 
239 		sal_uInt16 nStyle = 1;
240         Color aColor;
241 
242 		while	(	aTokens.getNextToken(sToken)	// have a new token
243 				&&	(0 != sToken.getLength())		// really have a new token
244 				)
245 		{
246             // try interpreting the token as border style
247             if ( m_eFacet == STYLE )
248             {
249                 // is it a valid enum value?
250 			    if ( SvXMLUnitConverter::convertEnum( nStyle, sToken, OEnumMapper::getEnumMap( OEnumMapper::epBorderWidth ) ) )
251                 {
252                     _rValue <<= nStyle;
253                     return sal_True;
254                 }
255             }
256 
257             // try interpreting it as color value
258             if ( m_eFacet == COLOR )
259             {
260                 if ( SvXMLUnitConverter::convertColor( aColor, sToken ) )
261                 {
262                     _rValue <<= (sal_Int32)aColor.GetColor();
263                     return sal_True;
264                 }
265             }
266 		}
267 
268 		return sal_False;
269 	}
270 
271 	//---------------------------------------------------------------------
272 	sal_Bool OControlBorderHandler::exportXML( ::rtl::OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
273 	{
274 		sal_Bool bSuccess = sal_False;
275 
276 	    ::rtl::OUStringBuffer aOut;
277         switch ( m_eFacet )
278         {
279         case STYLE:
280         {
281 		    sal_Int16 nBorder = 0;
282 		    bSuccess =	(_rValue >>= nBorder)
283 			    	&&	SvXMLUnitConverter::convertEnum( aOut, nBorder, OEnumMapper::getEnumMap( OEnumMapper::epBorderWidth ) );
284         }
285         break;
286         case COLOR:
287         {
288 		    sal_Int32 nBorderColor = 0;
289 		    if ( _rValue >>= nBorderColor )
290             {
291                 SvXMLUnitConverter::convertColor( aOut, Color( nBorderColor ) );
292                 bSuccess = sal_True;
293             }
294         }
295         break;
296         }   // switch ( m_eFacet )
297 
298         if ( !bSuccess )
299             return sal_False;
300 
301         if ( _rStrExpValue.getLength() )
302             _rStrExpValue += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) );
303 		_rStrExpValue += aOut.makeStringAndClear();
304 
305 		return sal_True;
306     }
307 
308 	//=====================================================================
309 	//= OFontWidthHandler
310 	//=====================================================================
311 	//---------------------------------------------------------------------
312 	OFontWidthHandler::OFontWidthHandler()
313 	{
314 	}
315 
316 	//---------------------------------------------------------------------
317 	sal_Bool OFontWidthHandler::importXML( const ::rtl::OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
318 	{
319 		sal_Int32 nWidth = 0;
320 		sal_Bool bSuccess = SvXMLUnitConverter::convertMeasure(nWidth, _rStrImpValue, MAP_POINT);
321 		if (bSuccess)
322 			_rValue <<= (sal_Int16)nWidth;
323 
324 		return bSuccess;
325 	}
326 
327 	//---------------------------------------------------------------------
328 	sal_Bool OFontWidthHandler::exportXML( ::rtl::OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
329 	{
330 		sal_Int16 nWidth = 0;
331 		::rtl::OUStringBuffer aResult;
332 		if (_rValue >>= nWidth)
333 			SvXMLUnitConverter::convertMeasure(aResult, nWidth, MAP_POINT, MAP_POINT);
334 		_rStrExpValue = aResult.makeStringAndClear();
335 
336 		return _rStrExpValue.getLength() != 0;
337 	}
338 
339 	//=====================================================================
340 	//= ORotationAngleHandler
341 	//=====================================================================
342 	//---------------------------------------------------------------------
343 	ORotationAngleHandler::ORotationAngleHandler()
344 	{
345 	}
346 
347 	//---------------------------------------------------------------------
348 	sal_Bool ORotationAngleHandler::importXML( const ::rtl::OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
349 	{
350 		double fValue;
351 		sal_Bool bSucces =
352             SvXMLUnitConverter::convertDouble(fValue, _rStrImpValue);
353 		if (bSucces)
354 		{
355 			fValue *= 10;
356 			_rValue <<= (float)fValue;
357 		}
358 
359 		return bSucces;
360 	}
361 
362 	//---------------------------------------------------------------------
363 	sal_Bool ORotationAngleHandler::exportXML( ::rtl::OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
364 	{
365 		float fAngle = 0;
366 		sal_Bool bSuccess = (_rValue >>= fAngle);
367 
368 		if (bSuccess)
369 		{
370 			rtl::OUStringBuffer sValue;
371 			SvXMLUnitConverter::convertDouble(sValue, ((double)fAngle) / 10);
372 			_rStrExpValue = sValue.makeStringAndClear();
373 		}
374 
375 		return bSuccess;
376 	}
377 
378 	//=====================================================================
379 	//= ImageScaleModeHandler
380 	//=====================================================================
381 	//---------------------------------------------------------------------
382     ImageScaleModeHandler::ImageScaleModeHandler()
383         :XMLConstantsPropertyHandler( OEnumMapper::getEnumMap( OEnumMapper::epImageScaleMode ), XML_STRETCH )
384     {
385     }
386 
387 //.........................................................................
388 }	// namespace xmloff
389 //.........................................................................
390 
391