xref: /aoo41x/main/sc/source/ui/vba/vbafont.cxx (revision cdf0e10c)
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 #include <com/sun/star/beans/XProperty.hpp>
28 #include <com/sun/star/awt/FontWeight.hpp>
29 #include <com/sun/star/awt/FontUnderline.hpp>
30 #include <com/sun/star/awt/FontStrikeout.hpp>
31 #include <com/sun/star/awt/FontSlant.hpp>
32 #include <com/sun/star/text/XSimpleText.hpp>
33 #include <com/sun/star/table/XCellRange.hpp>
34 #include <com/sun/star/table/XCell.hpp>
35 #include <com/sun/star/table/XColumnRowRange.hpp>
36 #include <ooo/vba/excel/XlColorIndex.hpp>
37 #include <ooo/vba/excel/XlUnderlineStyle.hpp>
38 #include <svl/itemset.hxx>
39 #include "excelvbahelper.hxx"
40 #include "vbafont.hxx"
41 #include "scitems.hxx"
42 #include "cellsuno.hxx"
43 
44 using namespace ::ooo::vba;
45 using namespace ::com::sun::star;
46 
47 ScVbaFont::ScVbaFont(
48         const uno::Reference< XHelperInterface >& xParent,
49         const uno::Reference< uno::XComponentContext >& xContext,
50         const ScVbaPalette& dPalette,
51         const uno::Reference< beans::XPropertySet >& xPropertySet,
52         ScCellRangeObj* pRangeObj, bool bFormControl ) throw ( uno::RuntimeException ) :
53     ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet, bFormControl ),
54     mPalette( dPalette ),
55     mpRangeObj( pRangeObj )
56 {
57 }
58 
59 SfxItemSet*
60 ScVbaFont::GetDataSet()
61 {
62     return mpRangeObj ? excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ) : 0;
63 }
64 
65 ScVbaFont::~ScVbaFont()
66 {
67 }
68 
69 
70 uno::Reference< beans::XPropertySet > lcl_TextProperties( uno::Reference< table::XCell >& xIf ) throw ( uno::RuntimeException )
71 {
72 	uno::Reference< text::XTextRange > xTxtRange( xIf, uno::UNO_QUERY_THROW );
73 	uno::Reference< text::XSimpleText > xTxt( xTxtRange->getText(), uno::UNO_QUERY_THROW ) ;
74 	uno::Reference< beans::XPropertySet > xProps( xTxt->createTextCursor(), uno::UNO_QUERY_THROW );
75 	return xProps;
76 }
77 void SAL_CALL
78 ScVbaFont::setSuperscript( const uno::Any& aValue ) throw ( uno::RuntimeException )
79 {
80 	// #FIXEME create some sort of generic get/set code where
81 	// you can pass a functor
82 	// get/set - Super/sub script code is exactly the same
83 	// except for the call applied at each cell position
84         uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
85         uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
86 	if ( !xCell.is() )
87 	{
88 		uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
89 		sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
90 		sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
91 		for ( sal_Int32 col = 0; col < nCols; ++col )
92 		{
93 			for ( sal_Int32 row = 0; row < nRows; ++row )
94 			{
95 				uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ) , uno::UNO_QUERY_THROW );
96 				ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
97 				aFont.setSuperscript( aValue );
98 			}
99 		}
100 		return;
101 
102 	}
103         xCell.set( xCellRange->getCellByPosition( 0,0 ) );
104 
105 	uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
106 	sal_Bool bValue = sal_False;
107 	aValue >>= bValue;
108 	sal_Int16 nValue = NORMAL;
109 	sal_Int8 nValue2 = NORMALHEIGHT;
110 
111         if( bValue )
112 	{
113 		nValue = SUPERSCRIPT;
114 	        nValue2 = SUPERSCRIPTHEIGHT;
115 	}
116 	xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ), ( uno::Any )nValue );
117  	xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapementHeight" ) ), ( uno::Any )nValue2 );
118 }
119 
120 uno::Any SAL_CALL
121 ScVbaFont::getSuperscript() throw ( uno::RuntimeException )
122 {
123         uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
124         uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
125 	if ( !xCell.is() )
126 	{
127 		uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
128 		sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
129 		sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
130 		uno::Any aRes;
131 		for ( sal_Int32 col = 0; col < nCols; ++col )
132 		{
133 			for ( sal_Int32 row = 0; row < nRows; ++row )
134 			{
135 				uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ), uno::UNO_QUERY_THROW );
136 				ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
137 				if ( !col && !row )
138 					aRes = aFont.getSuperscript();
139 				else if ( aRes != aFont.getSuperscript() )
140 					return aNULL();
141 			}
142 		}
143 		return aRes;
144 
145 	}
146         xCell.set( xCellRange->getCellByPosition( 0,0 ) );
147 	uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
148 	short nValue = 0;
149 	xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue;
150 	return uno::makeAny( ( nValue == SUPERSCRIPT ) );
151 }
152 
153 void SAL_CALL
154 ScVbaFont::setSubscript( const uno::Any& aValue ) throw ( uno::RuntimeException )
155 {
156         uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
157         uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
158 	if ( !xCell.is() )
159 	{
160 		uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
161 		sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
162 		sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
163 		for ( sal_Int32 col = 0; col < nCols; ++col )
164 		{
165 			for ( sal_Int32 row = 0; row < nRows; ++row )
166 			{
167 				uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ) , uno::UNO_QUERY_THROW );
168 				ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
169 				aFont.setSubscript( aValue );
170 			}
171 		}
172 		return;
173 
174 	}
175         xCell.set( xCellRange->getCellByPosition( 0,0 ) );
176 	uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
177 
178 	sal_Bool bValue = sal_False;
179 	aValue >>= bValue;
180 	sal_Int16 nValue = NORMAL;
181 	sal_Int8 nValue2 = NORMALHEIGHT;
182 
183         if( bValue )
184 	{
185 		nValue= SUBSCRIPT;
186 	        nValue2 = SUBSCRIPTHEIGHT;
187 	}
188 
189  	xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapementHeight" ) ), ( uno::Any )nValue2 );
190 	xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ), ( uno::Any )nValue );
191 
192 }
193 
194 uno::Any SAL_CALL
195 ScVbaFont::getSubscript() throw ( uno::RuntimeException )
196 {
197         uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
198         uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
199 	if ( !xCell.is() )
200 	{
201 		uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
202 		sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
203 		sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
204 		uno::Any aRes;
205 		for ( sal_Int32 col = 0; col < nCols; ++col )
206 		{
207 			for ( sal_Int32 row = 0; row < nRows; ++row )
208 			{
209 				uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ), uno::UNO_QUERY_THROW );
210 				ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
211 				if ( !col && !row )
212 					aRes = aFont.getSubscript();
213 				else if ( aRes != aFont.getSubscript() )
214 					return aNULL();
215 			}
216 		}
217 		return aRes;
218 
219 	}
220         xCell.set( xCellRange->getCellByPosition( 0,0 ) );
221 	uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
222 
223 	short nValue = NORMAL;
224 	xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue;
225 	return uno::makeAny( ( nValue == SUBSCRIPT ) );
226 }
227 
228 uno::Any SAL_CALL
229 ScVbaFont::getSize() throw ( uno::RuntimeException )
230 {
231 	if ( GetDataSet() )
232 		if (  GetDataSet()->GetItemState( ATTR_FONT_HEIGHT, sal_True, NULL) == SFX_ITEM_DONTCARE )
233 			return aNULL();
234         return ScVbaFont_BASE::getSize();
235 }
236 
237 void SAL_CALL
238 ScVbaFont::setColorIndex( const uno::Any& _colorindex ) throw( uno::RuntimeException )
239 {
240 	sal_Int32 nIndex = 0;
241 	_colorindex >>= nIndex;
242 	// #FIXME  xlColorIndexAutomatic & xlColorIndexNone are not really
243 	// handled properly here
244 
245 	if ( !nIndex || ( nIndex == excel::XlColorIndex::xlColorIndexAutomatic ) )
246         {
247 		nIndex = 1;  // check defualt ( assume black )
248                 ScVbaFont_BASE::setColorIndex( uno::makeAny( nIndex ) );
249         }
250         else
251             ScVbaFont_BASE::setColorIndex( _colorindex );
252 }
253 
254 
255 uno::Any SAL_CALL
256 ScVbaFont::getColorIndex() throw ( uno::RuntimeException )
257 {
258 	if ( GetDataSet() )
259 		if (  GetDataSet()->GetItemState( ATTR_FONT_COLOR, sal_True, NULL) == SFX_ITEM_DONTCARE )
260 			return aNULL();
261 	return ScVbaFont_BASE::getColorIndex();
262 }
263 
264 //////////////////////////////////////////////////////////////////////////////////////////
265 void  SAL_CALL
266 ScVbaFont::setStandardFontSize( const uno::Any& /*aValue*/ ) throw( uno::RuntimeException )
267 {
268 //XXX #TODO# #FIXME#
269 	//mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharSize" ) ), ( uno::Any )fValue );
270 	throw uno::RuntimeException(
271 		rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("setStandardFontSize not supported") ), uno::Reference< uno::XInterface >() );
272 }
273 
274 
275 uno::Any SAL_CALL
276 ScVbaFont::getStandardFontSize() throw ( uno::RuntimeException )
277 {
278 //XXX #TODO# #FIXME#
279 	throw uno::RuntimeException(
280 		rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("getStandardFontSize not supported") ), uno::Reference< uno::XInterface >() );
281 	// return uno::Any();
282 }
283 
284 
285 void  SAL_CALL
286 ScVbaFont::setStandardFont( const uno::Any& /*aValue*/ ) throw( uno::RuntimeException )
287 {
288 //XXX #TODO# #FIXME#
289 	throw uno::RuntimeException(
290 		rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("setStandardFont not supported") ), uno::Reference< uno::XInterface >() );
291 }
292 
293 
294 uno::Any SAL_CALL
295 ScVbaFont::getStandardFont() throw ( uno::RuntimeException )
296 {
297 //XXX #TODO# #FIXME#
298 	throw uno::RuntimeException(
299 		rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("getStandardFont not supported") ), uno::Reference< uno::XInterface >() );
300 	// return uno::Any();
301 }
302 
303 void SAL_CALL
304 ScVbaFont::setFontStyle( const uno::Any& aValue ) throw( uno::RuntimeException )
305 {
306     sal_Bool bBold = sal_False;
307     sal_Bool bItalic = sal_False;
308 
309     rtl::OUString aStyles;
310     aValue >>= aStyles;
311 
312     std::vector< rtl::OUString > aTokens;
313     sal_Int32 nIndex = 0;
314     do
315     {
316         rtl::OUString aToken = aStyles.getToken( 0, ' ', nIndex );
317         aTokens.push_back( aToken );
318     }while( nIndex >= 0 );
319 
320     std::vector< rtl::OUString >::iterator it;
321     for( it = aTokens.begin(); it != aTokens.end(); ++it )
322     {
323         if( (*it).equalsIgnoreAsciiCaseAscii( "Bold" ) )
324             bBold = sal_True;
325 
326         if( (*it).equalsIgnoreAsciiCaseAscii( "Italic" ) )
327             bItalic = sal_True;
328     }
329 
330     setBold( uno::makeAny( bBold ) );
331     setItalic( uno::makeAny( bItalic ) );
332 }
333 
334 
335 uno::Any SAL_CALL
336 ScVbaFont::getFontStyle() throw ( uno::RuntimeException )
337 {
338     rtl::OUStringBuffer aStyles;
339     sal_Bool bValue = sal_False;
340     getBold() >>= bValue;
341     if( bValue )
342         aStyles.appendAscii("Bold");
343 
344     getItalic() >>= bValue;
345     if( bValue )
346     {
347         if( aStyles.getLength() )
348             aStyles.appendAscii(" ");
349         aStyles.appendAscii("Italic");
350     }
351     return uno::makeAny( aStyles.makeStringAndClear() );
352 }
353 
354 uno::Any SAL_CALL
355 ScVbaFont::getBold() throw ( uno::RuntimeException )
356 {
357 	if ( GetDataSet() )
358 		if (  GetDataSet()->GetItemState( ATTR_FONT_WEIGHT, sal_True, NULL) == SFX_ITEM_DONTCARE )
359 			return aNULL();
360 	return ScVbaFont_BASE::getBold();
361 }
362 
363 void SAL_CALL
364 ScVbaFont::setUnderline( const uno::Any& aValue ) throw ( uno::RuntimeException )
365 {
366 	// default
367 	sal_Int32 nValue = excel::XlUnderlineStyle::xlUnderlineStyleNone;
368 	aValue >>= nValue;
369 	switch ( nValue )
370 	{
371 // NOTE:: #TODO #FIMXE
372 // xlUnderlineStyleDoubleAccounting & xlUnderlineStyleSingleAccounting
373 // don't seem to be supported in Openoffice.
374 // The import filter converts them to single or double underlines as appropriate
375 // So, here at the moment we are similarly silently converting
376 // xlUnderlineStyleSingleAccounting to xlUnderlineStyleSingle.
377 
378 		case excel::XlUnderlineStyle::xlUnderlineStyleNone:
379 			nValue = awt::FontUnderline::NONE;
380 			break;
381 		case excel::XlUnderlineStyle::xlUnderlineStyleSingle:
382 		case excel::XlUnderlineStyle::xlUnderlineStyleSingleAccounting:
383 			nValue = awt::FontUnderline::SINGLE;
384 			break;
385 		case excel::XlUnderlineStyle::xlUnderlineStyleDouble:
386 		case excel::XlUnderlineStyle::xlUnderlineStyleDoubleAccounting:
387 			nValue = awt::FontUnderline::DOUBLE;
388 			break;
389 		default:
390 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown value for Underline")), uno::Reference< uno::XInterface >() );
391 	}
392 
393 	mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ), ( uno::Any )nValue );
394 
395 }
396 
397 uno::Any SAL_CALL
398 ScVbaFont::getUnderline() throw ( uno::RuntimeException )
399 {
400 	if ( GetDataSet() )
401 		if (  GetDataSet()->GetItemState( ATTR_FONT_UNDERLINE, sal_True, NULL) == SFX_ITEM_DONTCARE )
402 			return aNULL();
403 
404 	sal_Int32 nValue = awt::FontUnderline::NONE;
405 	mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ) ) >>= nValue;
406 	switch ( nValue )
407 	{
408 		case  awt::FontUnderline::DOUBLE:
409 			nValue = excel::XlUnderlineStyle::xlUnderlineStyleDouble;
410 			break;
411 		case  awt::FontUnderline::SINGLE:
412 			nValue = excel::XlUnderlineStyle::xlUnderlineStyleSingle;
413 			break;
414 		case  awt::FontUnderline::NONE:
415 			nValue = excel::XlUnderlineStyle::xlUnderlineStyleNone;
416 			break;
417 		default:
418 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown value retrieved for Underline") ), uno::Reference< uno::XInterface >() );
419 
420 	}
421 	return uno::makeAny( nValue );
422 }
423 
424 uno::Any SAL_CALL
425 ScVbaFont::getStrikethrough() throw ( uno::RuntimeException )
426 {
427 	if ( GetDataSet() )
428 		if (  GetDataSet()->GetItemState( ATTR_FONT_CROSSEDOUT, sal_True, NULL) == SFX_ITEM_DONTCARE )
429 			return aNULL();
430 	return ScVbaFont_BASE::getStrikethrough();
431 }
432 
433 uno::Any SAL_CALL
434 ScVbaFont::getShadow() throw (uno::RuntimeException)
435 {
436 	if ( GetDataSet() )
437 		if (  GetDataSet()->GetItemState( ATTR_FONT_SHADOWED, sal_True, NULL) == SFX_ITEM_DONTCARE )
438 			return aNULL();
439 	return ScVbaFont_BASE::getShadow();
440 }
441 
442 uno::Any SAL_CALL
443 ScVbaFont::getItalic() throw ( uno::RuntimeException )
444 {
445 	if ( GetDataSet() )
446 		if (  GetDataSet()->GetItemState( ATTR_FONT_POSTURE, sal_True, NULL) == SFX_ITEM_DONTCARE )
447 			return aNULL();
448 
449 	return ScVbaFont_BASE::getItalic();
450 }
451 
452 uno::Any SAL_CALL
453 ScVbaFont::getName() throw ( uno::RuntimeException )
454 {
455 	if ( GetDataSet() )
456 		if (  GetDataSet()->GetItemState( ATTR_FONT, sal_True, NULL) == SFX_ITEM_DONTCARE )
457 			return aNULL();
458 	return ScVbaFont_BASE::getName();
459 }
460 uno::Any
461 ScVbaFont::getColor() throw (uno::RuntimeException)
462 {
463 	// #TODO #FIXME - behave like getXXX above ( wrt. GetDataSet )
464 	uno::Any aAny;
465 	aAny = OORGBToXLRGB( mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ) ) );
466 	return aAny;
467 }
468 
469 void  SAL_CALL
470 ScVbaFont::setOutlineFont( const uno::Any& aValue ) throw ( uno::RuntimeException )
471 {
472 	mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharContoured" ) ), aValue );
473 }
474 
475 uno::Any SAL_CALL
476 ScVbaFont::getOutlineFont() throw (uno::RuntimeException)
477 {
478 	if ( GetDataSet() )
479 		if (  GetDataSet()->GetItemState( ATTR_FONT_CONTOUR, sal_True, NULL) == SFX_ITEM_DONTCARE )
480 			return aNULL();
481 	return mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharContoured" ) ) );
482 }
483 
484 rtl::OUString&
485 ScVbaFont::getServiceImplName()
486 {
487 	static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFont") );
488 	return sImplName;
489 }
490 
491 uno::Sequence< rtl::OUString >
492 ScVbaFont::getServiceNames()
493 {
494 	static uno::Sequence< rtl::OUString > aServiceNames;
495 	if ( aServiceNames.getLength() == 0 )
496 	{
497 		aServiceNames.realloc( 1 );
498 		aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Font" ) );
499 	}
500 	return aServiceNames;
501 }
502