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