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 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* 56 ScVbaFont::GetDataSet() 57 { 58 return mpRangeObj ? excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ) : 0; 59 } 60 61 ScVbaFont::~ScVbaFont() 62 { 63 } 64 65 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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& 481 ScVbaFont::getServiceImplName() 482 { 483 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFont") ); 484 return sImplName; 485 } 486 487 uno::Sequence< rtl::OUString > 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