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 return uno::Reference< excel::XWorksheet >( excel::getUnoSheetModuleObj( xSheet ), uno::UNO_QUERY_THROW ); 224 } 225 226 uno::Any SAL_CALL 227 ScVbaWorkbook::Sheets( const uno::Any& aIndex ) throw (uno::RuntimeException) 228 { 229 return Worksheets( aIndex ); 230 } 231 232 uno::Any SAL_CALL 233 ScVbaWorkbook::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeException) 234 { 235 uno::Reference< frame::XModel > xModel( getModel() ); 236 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW ); 237 uno::Reference<container::XIndexAccess > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW ); 238 uno::Reference< XCollection > xWorkSheets( new ScVbaWorksheets( this, mxContext, xSheets, xModel ) ); 239 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) 240 { 241 return uno::Any( xWorkSheets ); 242 } 243 // pass on to collection 244 return uno::Any( xWorkSheets->Item( aIndex, uno::Any() ) ); 245 } 246 uno::Any SAL_CALL 247 ScVbaWorkbook::Windows( const uno::Any& aIndex ) throw (uno::RuntimeException) 248 { 249 250 uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( getParent(), mxContext ) ); 251 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) 252 return uno::Any( xWindows ); 253 return uno::Any( xWindows->Item( aIndex, uno::Any() ) ); 254 } 255 256 void SAL_CALL 257 ScVbaWorkbook::Activate() throw (uno::RuntimeException) 258 { 259 VbaDocumentBase::Activate(); 260 } 261 262 ::sal_Bool 263 ScVbaWorkbook::getProtectStructure() throw (uno::RuntimeException) 264 { 265 uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW ); 266 return xProt->isProtected(); 267 } 268 269 ::sal_Bool SAL_CALL ScVbaWorkbook::getPrecisionAsDisplayed() throw (uno::RuntimeException) 270 { 271 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); 272 ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); 273 return pDoc->GetDocOptions().IsCalcAsShown(); 274 } 275 276 void SAL_CALL ScVbaWorkbook::setPrecisionAsDisplayed( sal_Bool _precisionAsDisplayed ) throw (uno::RuntimeException) 277 { 278 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); 279 ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); 280 ScDocOptions aOpt = pDoc->GetDocOptions(); 281 aOpt.SetCalcAsShown( _precisionAsDisplayed ); 282 pDoc->SetDocOptions( aOpt ); 283 } 284 285 void 286 ScVbaWorkbook::SaveCopyAs( const rtl::OUString& sFileName ) throw ( uno::RuntimeException) 287 { 288 rtl::OUString aURL; 289 osl::FileBase::getFileURLFromSystemPath( sFileName, aURL ); 290 uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW ); 291 uno::Sequence< beans::PropertyValue > storeProps(1); 292 storeProps[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); 293 storeProps[0].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MS Excel 97" ) ); 294 xStor->storeToURL( aURL, storeProps ); 295 } 296 297 css::uno::Any SAL_CALL 298 ScVbaWorkbook::Styles( const uno::Any& Item ) throw (uno::RuntimeException) 299 { 300 // quick look and Styles object doesn't seem to have a valid parent 301 // or a least the object browser just shows an object that has no 302 // variables ( therefore... leave as NULL for now ) 303 uno::Reference< XCollection > dStyles = new ScVbaStyles( uno::Reference< XHelperInterface >(), mxContext, getModel() ); 304 if ( Item.hasValue() ) 305 return dStyles->Item( Item, uno::Any() ); 306 return uno::makeAny( dStyles ); 307 } 308 309 // Amelia Wang 310 uno::Any SAL_CALL 311 ScVbaWorkbook::Names( const uno::Any& aIndex ) throw (uno::RuntimeException) 312 { 313 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW ); 314 uno::Reference< beans::XPropertySet > xProps( xModel, uno::UNO_QUERY_THROW ); 315 uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NamedRanges") ) ), uno::UNO_QUERY_THROW ); 316 uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, xModel ) ); 317 if ( aIndex.hasValue() ) 318 return uno::Any( xNames->Item( aIndex, uno::Any() ) ); 319 return uno::Any( xNames ); 320 } 321 322 rtl::OUString& 323 ScVbaWorkbook::getServiceImplName() 324 { 325 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorkbook") ); 326 return sImplName; 327 } 328 329 uno::Sequence< rtl::OUString > 330 ScVbaWorkbook::getServiceNames() 331 { 332 static uno::Sequence< rtl::OUString > aServiceNames; 333 if ( aServiceNames.getLength() == 0 ) 334 { 335 aServiceNames.realloc( 1 ); 336 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Workbook" ) ); 337 } 338 return aServiceNames; 339 } 340 341 ::rtl::OUString SAL_CALL 342 ScVbaWorkbook::getCodeName() throw (css::uno::RuntimeException) 343 { 344 uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW ); 345 return xModelProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); 346 } 347 348 namespace workbook 349 { 350 namespace sdecl = comphelper::service_decl; 351 sdecl::vba_service_class_<ScVbaWorkbook, sdecl::with_args<true> > serviceImpl; 352 extern sdecl::ServiceDecl const serviceDecl( 353 serviceImpl, 354 "ScVbaWorkbook", 355 "ooo.vba.excel.Workbook" ); 356 } 357