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