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