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