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