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 <vbahelper/helperdecl.hxx> 28 #include <tools/urlobj.hxx> 29 #include <comphelper/unwrapargs.hxx> 30 31 #include <com/sun/star/util/XModifiable.hpp> 32 #include <com/sun/star/util/XProtectable.hpp> 33 #include <com/sun/star/sheet/XSpreadsheetView.hpp> 34 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 35 #include <com/sun/star/frame/XStorable.hpp> 36 #include <com/sun/star/frame/XFrame.hpp> 37 #include <com/sun/star/beans/XPropertySet.hpp> 38 #include <ooo/vba/excel/XlFileFormat.hpp> 39 40 #include "scextopt.hxx" 41 #include "vbaworksheet.hxx" 42 #include "vbaworksheets.hxx" 43 #include "vbaworkbook.hxx" 44 #include "vbawindows.hxx" 45 #include "vbastyles.hxx" 46 #include "excelvbahelper.hxx" 47 #include "vbapalette.hxx" 48 #include <osl/file.hxx> 49 #include <stdio.h> 50 #include "vbanames.hxx" // Amelia Wang 51 #include "nameuno.hxx" 52 #include "docoptio.hxx" 53 #include "unonames.hxx" 54 55 // Much of the impl. for the equivalend UNO module is 56 // sc/source/ui/unoobj/docuno.cxx, viewuno.cxx 57 58 using namespace ::ooo::vba; 59 using namespace ::com::sun::star; 60 61 class ActiveSheet : public ScVbaWorksheet 62 { 63 protected: 64 virtual uno::Reference< frame::XModel > getModel() 65 { 66 return getCurrentExcelDoc( mxContext ); 67 } 68 virtual uno::Reference< sheet::XSpreadsheet > getSheet() 69 { 70 uno::Reference< frame::XModel > xModel = getModel(); 71 uno::Reference< sheet::XSpreadsheet > xSheet; 72 if ( xModel.is() ) 73 { 74 uno::Reference< sheet::XSpreadsheetView > xSpreadsheet( 75 xModel->getCurrentController(), uno::UNO_QUERY ); 76 if ( xSpreadsheet.is() ) 77 xSheet = xSpreadsheet->getActiveSheet(); 78 } 79 return xSheet; 80 } 81 public: 82 ActiveSheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : ScVbaWorksheet( xParent, xContext ) {} 83 84 }; 85 86 uno::Sequence< sal_Int32 > ScVbaWorkbook::ColorData; 87 88 void ScVbaWorkbook::initColorData( const uno::Sequence< sal_Int32 >& sColors ) 89 { 90 const sal_Int32* pSource = sColors.getConstArray(); 91 sal_Int32* pDest = ColorData.getArray(); 92 const sal_Int32* pEnd = pSource + sColors.getLength(); 93 for ( ; pSource != pEnd; ++pSource, ++pDest ) 94 *pDest = *pSource; 95 } 96 97 98 void SAL_CALL 99 ScVbaWorkbook::ResetColors( ) throw (::script::BasicErrorException, ::uno::RuntimeException) 100 { 101 uno::Reference< container::XIndexAccess > xIndexAccess( ScVbaPalette::getDefaultPalette(), uno::UNO_QUERY_THROW ); 102 sal_Int32 nLen = xIndexAccess->getCount(); 103 ColorData.realloc( nLen ); 104 105 uno::Sequence< sal_Int32 > dDefaultColors( nLen ); 106 sal_Int32* pDest = dDefaultColors.getArray(); 107 for ( sal_Int32 index=0; index < nLen; ++pDest, ++index ) 108 xIndexAccess->getByIndex( index ) >>= (*pDest); 109 initColorData( dDefaultColors ); 110 } 111 112 ::uno::Any SAL_CALL 113 ScVbaWorkbook::Colors( const ::uno::Any& Index ) throw (::script::BasicErrorException, ::uno::RuntimeException) 114 { 115 uno::Any aRet; 116 if ( Index.getValue() ) 117 { 118 sal_Int32 nIndex = 0; 119 Index >>= nIndex; 120 aRet = uno::makeAny( XLRGBToOORGB( ColorData[ --nIndex ] ) ); 121 } 122 else 123 aRet = uno::makeAny( ColorData ); 124 return aRet; 125 } 126 127 ::sal_Int32 SAL_CALL 128 ScVbaWorkbook::FileFormat( ) throw (::script::BasicErrorException, ::uno::RuntimeException) 129 { 130 sal_Int32 aFileFormat = 0; 131 rtl::OUString aFilterName; 132 uno::Sequence< beans::PropertyValue > aArgs = getModel()->getArgs(); 133 134 // #FIXME - seems suspect should we not walk through the properties 135 // to find the FilterName 136 if (aArgs[0].Name.equalsAscii( "FilterName")) { 137 aArgs[0].Value >>= aFilterName; 138 } else { 139 aArgs[1].Value >>= aFilterName; 140 } 141 142 if (aFilterName.equalsAscii("Text - txt - csv (StarCalc)")) { 143 aFileFormat = excel::XlFileFormat::xlCSV; //xlFileFormat. 144 } 145 146 if (aFilterName.equalsAscii("DBF")) { 147 aFileFormat = excel::XlFileFormat::xlDBF4; 148 } 149 150 if (aFilterName.equalsAscii("DIF")) { 151 aFileFormat = excel::XlFileFormat::xlDIF; 152 } 153 154 if (aFilterName.equalsAscii("Lotus")) { 155 aFileFormat = excel::XlFileFormat::xlWK3; 156 } 157 158 if (aFilterName.equalsAscii("MS Excel 4.0")) { 159 aFileFormat = excel::XlFileFormat::xlExcel4Workbook; 160 } 161 162 if (aFilterName.equalsAscii("MS Excel 5.0/95")) { 163 aFileFormat = excel::XlFileFormat::xlExcel5; 164 } 165 166 if (aFilterName.equalsAscii("MS Excel 97")) { 167 aFileFormat = excel::XlFileFormat::xlExcel9795; 168 } 169 170 if (aFilterName.equalsAscii("HTML (StarCalc)")) { 171 aFileFormat = excel::XlFileFormat::xlHtml; 172 } 173 174 if (aFilterName.equalsAscii("calc_StarOffice_XML_Calc_Template")) { 175 aFileFormat = excel::XlFileFormat::xlTemplate; 176 } 177 178 if (aFilterName.equalsAscii("StarOffice XML (Calc)")) { 179 aFileFormat = excel::XlFileFormat::xlWorkbookNormal; 180 } 181 if (aFilterName.equalsAscii("calc8")) { 182 aFileFormat = excel::XlFileFormat::xlWorkbookNormal; 183 } 184 185 return aFileFormat; 186 } 187 188 void 189 ScVbaWorkbook::init() 190 { 191 if ( !ColorData.getLength() ) 192 ResetColors(); 193 } 194 ScVbaWorkbook::ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext) :ScVbaWorkbook_BASE( xParent, xContext ) 195 { 196 //#FIXME this persists the color data per office instance and 197 // not per workbook instance, need to hook the data into XModel 198 // ( e.g. we already store the imported palette in there ) 199 // so we should, 200 // a) make the class that does that a service 201 // b) make that service implement XIndexContainer 202 init(); 203 } 204 205 ScVbaWorkbook::ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, css::uno::Reference< css::frame::XModel > xModel ) : ScVbaWorkbook_BASE( xParent, xContext, xModel ) 206 { 207 init(); 208 } 209 210 ScVbaWorkbook::ScVbaWorkbook( uno::Sequence< uno::Any> const & args, 211 uno::Reference< uno::XComponentContext> const & xContext ) : ScVbaWorkbook_BASE( args, xContext ) 212 { 213 init(); 214 } 215 216 uno::Reference< excel::XWorksheet > 217 ScVbaWorkbook::getActiveSheet() throw (uno::RuntimeException) 218 { 219 uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW ); 220 uno::Reference< sheet::XSpreadsheetView > xView( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); 221 uno::Reference< sheet::XSpreadsheet > xSheet( xView->getActiveSheet(), uno::UNO_SET_THROW ); 222 // #162503# return the original sheet module wrapper object, instead of a new instance 223 uno::Reference< excel::XWorksheet > xWorksheet( excel::getUnoSheetModuleObj( xSheet ), uno::UNO_QUERY ); 224 if( xWorksheet.is() ) return xWorksheet; 225 // #i116936# excel::getUnoSheetModuleObj() may return null in documents without global VBA mode enabled 226 return new ScVbaWorksheet( this, mxContext, xSheet, xModel ); 227 } 228 229 uno::Any SAL_CALL 230 ScVbaWorkbook::Sheets( const uno::Any& aIndex ) throw (uno::RuntimeException) 231 { 232 return Worksheets( aIndex ); 233 } 234 235 uno::Any SAL_CALL 236 ScVbaWorkbook::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeException) 237 { 238 uno::Reference< frame::XModel > xModel( getModel() ); 239 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW ); 240 uno::Reference<container::XIndexAccess > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW ); 241 uno::Reference< XCollection > xWorkSheets( new ScVbaWorksheets( this, mxContext, xSheets, xModel ) ); 242 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) 243 { 244 return uno::Any( xWorkSheets ); 245 } 246 // pass on to collection 247 return uno::Any( xWorkSheets->Item( aIndex, uno::Any() ) ); 248 } 249 uno::Any SAL_CALL 250 ScVbaWorkbook::Windows( const uno::Any& aIndex ) throw (uno::RuntimeException) 251 { 252 253 uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( getParent(), mxContext ) ); 254 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) 255 return uno::Any( xWindows ); 256 return uno::Any( xWindows->Item( aIndex, uno::Any() ) ); 257 } 258 259 void SAL_CALL 260 ScVbaWorkbook::Activate() throw (uno::RuntimeException) 261 { 262 VbaDocumentBase::Activate(); 263 } 264 265 ::sal_Bool 266 ScVbaWorkbook::getProtectStructure() throw (uno::RuntimeException) 267 { 268 uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW ); 269 return xProt->isProtected(); 270 } 271 272 ::sal_Bool SAL_CALL ScVbaWorkbook::getPrecisionAsDisplayed() throw (uno::RuntimeException) 273 { 274 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); 275 ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); 276 return pDoc->GetDocOptions().IsCalcAsShown(); 277 } 278 279 void SAL_CALL ScVbaWorkbook::setPrecisionAsDisplayed( sal_Bool _precisionAsDisplayed ) throw (uno::RuntimeException) 280 { 281 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); 282 ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); 283 ScDocOptions aOpt = pDoc->GetDocOptions(); 284 aOpt.SetCalcAsShown( _precisionAsDisplayed ); 285 pDoc->SetDocOptions( aOpt ); 286 } 287 288 void 289 ScVbaWorkbook::SaveCopyAs( const rtl::OUString& sFileName ) throw ( uno::RuntimeException) 290 { 291 rtl::OUString aURL; 292 osl::FileBase::getFileURLFromSystemPath( sFileName, aURL ); 293 uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW ); 294 uno::Sequence< beans::PropertyValue > storeProps(1); 295 storeProps[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); 296 storeProps[0].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MS Excel 97" ) ); 297 xStor->storeToURL( aURL, storeProps ); 298 } 299 300 css::uno::Any SAL_CALL 301 ScVbaWorkbook::Styles( const uno::Any& Item ) throw (uno::RuntimeException) 302 { 303 // quick look and Styles object doesn't seem to have a valid parent 304 // or a least the object browser just shows an object that has no 305 // variables ( therefore... leave as NULL for now ) 306 uno::Reference< XCollection > dStyles = new ScVbaStyles( uno::Reference< XHelperInterface >(), mxContext, getModel() ); 307 if ( Item.hasValue() ) 308 return dStyles->Item( Item, uno::Any() ); 309 return uno::makeAny( dStyles ); 310 } 311 312 // Amelia Wang 313 uno::Any SAL_CALL 314 ScVbaWorkbook::Names( const uno::Any& aIndex ) throw (uno::RuntimeException) 315 { 316 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW ); 317 uno::Reference< beans::XPropertySet > xProps( xModel, uno::UNO_QUERY_THROW ); 318 uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NamedRanges") ) ), uno::UNO_QUERY_THROW ); 319 uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, xModel ) ); 320 if ( aIndex.hasValue() ) 321 return uno::Any( xNames->Item( aIndex, uno::Any() ) ); 322 return uno::Any( xNames ); 323 } 324 325 rtl::OUString& 326 ScVbaWorkbook::getServiceImplName() 327 { 328 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorkbook") ); 329 return sImplName; 330 } 331 332 uno::Sequence< rtl::OUString > 333 ScVbaWorkbook::getServiceNames() 334 { 335 static uno::Sequence< rtl::OUString > aServiceNames; 336 if ( aServiceNames.getLength() == 0 ) 337 { 338 aServiceNames.realloc( 1 ); 339 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Workbook" ) ); 340 } 341 return aServiceNames; 342 } 343 344 ::rtl::OUString SAL_CALL 345 ScVbaWorkbook::getCodeName() throw (css::uno::RuntimeException) 346 { 347 uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW ); 348 return xModelProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); 349 } 350 351 namespace workbook 352 { 353 namespace sdecl = comphelper::service_decl; 354 sdecl::vba_service_class_<ScVbaWorkbook, sdecl::with_args<true> > serviceImpl; 355 extern sdecl::ServiceDecl const serviceDecl( 356 serviceImpl, 357 "ScVbaWorkbook", 358 "ooo.vba.excel.Workbook" ); 359 } 360