xref: /trunk/main/sc/source/ui/vba/vbafont.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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