LibreOffice Module sc (master)  1
vbaworkbook.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <tools/urlobj.hxx>
21 
22 #include <com/sun/star/util/XProtectable.hpp>
23 #include <com/sun/star/sheet/XNamedRanges.hpp>
24 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
25 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
26 #include <com/sun/star/frame/XStorable.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <ooo/vba/excel/XlFileFormat.hpp>
29 #include <ooo/vba/excel/XApplication.hpp>
30 
31 #include "vbaworksheet.hxx"
32 #include "vbaworksheets.hxx"
33 #include "vbaworkbook.hxx"
34 #include "vbawindows.hxx"
35 #include "vbastyles.hxx"
36 #include "excelvbahelper.hxx"
37 #include "vbapalette.hxx"
38 #include <osl/file.hxx>
39 #include "vbanames.hxx"
40 #include <docoptio.hxx>
41 #include <docsh.hxx>
42 
43 // Much of the impl. for the equivalent UNO module is
44 // sc/source/ui/unoobj/docuno.cxx, viewuno.cxx
45 
46 using namespace ::ooo::vba;
47 using namespace ::com::sun::star;
48 
49 uno::Sequence< sal_Int32 > ScVbaWorkbook::ColorData;
50 
51 void ScVbaWorkbook::initColorData( const uno::Sequence< sal_Int32 >& sColors )
52 {
53  std::copy(sColors.begin(), sColors.end(), ColorData.begin());
54 }
55 
56 void SAL_CALL
58 {
59  uno::Reference< container::XIndexAccess > xIndexAccess( ScVbaPalette::getDefaultPalette(), uno::UNO_SET_THROW );
60  sal_Int32 nLen = xIndexAccess->getCount();
61  ColorData.realloc( nLen );
62 
63  uno::Sequence< sal_Int32 > dDefaultColors( nLen );
64  sal_Int32* pDest = dDefaultColors.getArray();
65  for ( sal_Int32 index=0; index < nLen; ++pDest, ++index )
66  xIndexAccess->getByIndex( index ) >>= *pDest;
67  initColorData( dDefaultColors );
68 }
69 
70 ::uno::Any SAL_CALL
71 ScVbaWorkbook::Colors( const ::uno::Any& Index )
72 {
73  uno::Any aRet;
74  if ( Index.hasValue() )
75  {
76  sal_Int32 nIndex = 0;
77  Index >>= nIndex;
78  aRet <<= XLRGBToOORGB( ColorData[ --nIndex ] );
79  }
80  else
81  aRet <<= ColorData;
82  return aRet;
83 }
84 
85 bool ScVbaWorkbook::setFilterPropsFromFormat( sal_Int32 nFormat, uno::Sequence< beans::PropertyValue >& rProps )
86 {
87  auto pProp = std::find_if(rProps.begin(), rProps.end(),
88  [](const beans::PropertyValue& rProp) { return rProp.Name == "FilterName"; });
89  bool bRes = pProp != rProps.end();
90  if (bRes)
91  {
92  switch( nFormat )
93  {
94  case excel::XlFileFormat::xlCSV:
95  pProp->Value <<= OUString(SC_TEXT_CSV_FILTER_NAME);
96  break;
97  case excel::XlFileFormat::xlDBF4:
98  pProp->Value <<= OUString("DBF");
99  break;
100  case excel::XlFileFormat::xlDIF:
101  pProp->Value <<= OUString("DIF");
102  break;
103  case excel::XlFileFormat::xlWK3:
104  pProp->Value <<= OUString("Lotus");
105  break;
106  case excel::XlFileFormat::xlExcel4Workbook:
107  pProp->Value <<= OUString("MS Excel 4.0");
108  break;
109  case excel::XlFileFormat::xlExcel5:
110  pProp->Value <<= OUString("MS Excel 5.0/95");
111  break;
112  case excel::XlFileFormat::xlHtml:
113  pProp->Value <<= OUString("HTML (StarCalc)");
114  break;
115  case excel::XlFileFormat::xlExcel9795:
116  default:
117  pProp->Value <<= OUString("MS Excel 97");
118  break;
119  }
120  }
121  return bRes;
122 }
123 
124 ::sal_Int32 SAL_CALL
126 {
127  sal_Int32 aFileFormat = 0;
128  OUString aFilterName;
129  uno::Sequence< beans::PropertyValue > aArgs = getModel()->getArgs();
130 
131  // #FIXME - seems suspect should we not walk through the properties
132  // to find the FilterName
133  if ( aArgs[0].Name == "FilterName" ) {
134  aArgs[0].Value >>= aFilterName;
135  } else {
136  aArgs[1].Value >>= aFilterName;
137  }
138 
139  if (aFilterName == SC_TEXT_CSV_FILTER_NAME) {
140  aFileFormat = excel::XlFileFormat::xlCSV; //xlFileFormat.
141  }
142 
143  if ( aFilterName == "DBF" ) {
144  aFileFormat = excel::XlFileFormat::xlDBF4;
145  }
146 
147  if ( aFilterName == "DIF" ) {
148  aFileFormat = excel::XlFileFormat::xlDIF;
149  }
150 
151  if ( aFilterName == "Lotus" ) {
152  aFileFormat = excel::XlFileFormat::xlWK3;
153  }
154 
155  if ( aFilterName == "MS Excel 4.0" ) {
156  aFileFormat = excel::XlFileFormat::xlExcel4Workbook;
157  }
158 
159  if ( aFilterName == "MS Excel 5.0/95" ) {
160  aFileFormat = excel::XlFileFormat::xlExcel5;
161  }
162 
163  if ( aFilterName == "MS Excel 97" ) {
164  aFileFormat = excel::XlFileFormat::xlExcel9795;
165  }
166 
167  if (aFilterName == "HTML (StarCalc)") {
168  aFileFormat = excel::XlFileFormat::xlHtml;
169  }
170 
171  if ( aFilterName == "calc_StarOffice_XML_Calc_Template" ) {
172  aFileFormat = excel::XlFileFormat::xlTemplate;
173  }
174 
175  if (aFilterName == "StarOffice XML (Calc)") {
176  aFileFormat = excel::XlFileFormat::xlWorkbookNormal;
177  }
178  if ( aFilterName == "calc8" ) {
179  aFileFormat = excel::XlFileFormat::xlWorkbookNormal;
180  }
181 
182  return aFileFormat;
183 }
184 
185 void
187 {
188  if ( !ColorData.hasElements() )
189  ResetColors();
190  uno::Reference< frame::XModel > xModel = getModel();
191  if ( xModel.is() )
193 }
194 
195 ScVbaWorkbook::ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, css::uno::Reference< css::frame::XModel > const & xModel ) : ScVbaWorkbook_BASE( xParent, xContext, xModel )
196 {
197  init();
198 }
199 
200 ScVbaWorkbook::ScVbaWorkbook( uno::Sequence< uno::Any> const & args,
201  uno::Reference< uno::XComponentContext> const & xContext ) : ScVbaWorkbook_BASE( args, xContext )
202 {
203  init();
204 }
205 
206 uno::Reference< excel::XWorksheet >
208 {
209  uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
210  uno::Reference< sheet::XSpreadsheetView > xView( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
211  uno::Reference< sheet::XSpreadsheet > xSheet( xView->getActiveSheet(), uno::UNO_SET_THROW );
212  // #162503# return the original sheet module wrapper object, instead of a new instance
213  uno::Reference< excel::XWorksheet > xWorksheet( excel::getUnoSheetModuleObj( xSheet ), uno::UNO_QUERY );
214  if( xWorksheet.is() ) return xWorksheet;
215  // #i116936# excel::getUnoSheetModuleObj() may return null in documents without global VBA mode enabled
216  return new ScVbaWorksheet( this, mxContext, xSheet, xModel );
217 }
218 
219 uno::Any SAL_CALL
221 {
222  return Worksheets( aIndex );
223 }
224 
225 uno::Any SAL_CALL
227 {
228  uno::Reference< frame::XModel > xModel( getModel() );
229  uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW );
230  uno::Reference<container::XIndexAccess > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
231  uno::Reference< XCollection > xWorkSheets( new ScVbaWorksheets( this, mxContext, xSheets, xModel ) );
232  if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
233  {
234  return uno::Any( xWorkSheets );
235  }
236  // pass on to collection
237  return xWorkSheets->Item( aIndex, uno::Any() );
238 }
239 uno::Any SAL_CALL
241 {
242 
243  uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( getParent(), mxContext ) );
244  if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
245  return uno::Any( xWindows );
246  return xWindows->Item( aIndex, uno::Any() );
247 }
248 
249 void SAL_CALL
251 {
253 }
254 
255 void
256 ScVbaWorkbook::Protect( const uno::Any &aPassword )
257 {
258  VbaDocumentBase::Protect( aPassword );
259 }
260 
261 sal_Bool
263 {
264  uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW );
265  return xProt->isProtected();
266 }
267 
269 {
270  uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
271  ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
272  return rDoc.GetDocOptions().IsCalcAsShown();
273 }
274 
275 void SAL_CALL ScVbaWorkbook::setPrecisionAsDisplayed( sal_Bool _precisionAsDisplayed )
276 {
277  uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
278  ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
279  ScDocOptions aOpt = rDoc.GetDocOptions();
280  aOpt.SetCalcAsShown( _precisionAsDisplayed );
281  rDoc.SetDocOptions( aOpt );
282 }
283 
284 OUString SAL_CALL ScVbaWorkbook::getAuthor()
285 {
286  uno::Reference<document::XDocumentPropertiesSupplier> xDPS( getModel(), uno::UNO_QUERY );
287  if (!xDPS.is())
288  return "?";
289  uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
290  return xDocProps->getAuthor();
291 }
292 
293 void SAL_CALL ScVbaWorkbook::setAuthor( const OUString& _author )
294 {
295  uno::Reference<document::XDocumentPropertiesSupplier> xDPS( getModel(), uno::UNO_QUERY );
296  if (!xDPS.is())
297  return;
298  uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
299  xDocProps->setAuthor( _author );
300 }
301 
302 void
303 ScVbaWorkbook::SaveCopyAs( const OUString& sFileName )
304 {
305  OUString aURL;
306  osl::FileBase::getFileURLFromSystemPath( sFileName, aURL );
307  uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW );
308  uno::Sequence< beans::PropertyValue > storeProps(1);
309  storeProps[0].Name = "FilterName";
310  storeProps[0].Value <<= OUString( "MS Excel 97" );
311  xStor->storeToURL( aURL, storeProps );
312 }
313 
314 void SAL_CALL
315 ScVbaWorkbook::SaveAs( const uno::Any& FileName, const uno::Any& FileFormat, const uno::Any& /*Password*/, const uno::Any& /*WriteResPassword*/, const uno::Any& /*ReadOnlyRecommended*/, const uno::Any& /*CreateBackup*/, const uno::Any& /*AccessMode*/, const uno::Any& /*ConflictResolution*/, const uno::Any& /*AddToMru*/, const uno::Any& /*TextCodepage*/, const uno::Any& /*TextVisualLayout*/, const uno::Any& /*Local*/ )
316 {
317  OUString sFileName;
318  FileName >>= sFileName;
319  OUString sURL;
320  osl::FileBase::getFileURLFromSystemPath( sFileName, sURL );
321  // detect if there is no path then we need
322  // to use the current folder
323  INetURLObject aURL( sURL );
325  if( sURL.isEmpty() )
326  {
327  // need to add cur dir ( of this workbook ) or else the 'Work' dir
328  sURL = getModel()->getURL();
329 
330  if ( sURL.isEmpty() )
331  {
332  // not path available from 'this' document
333  // need to add the 'document'/work directory then
334  uno::Reference< excel::XApplication > xApplication ( Application(),uno::UNO_QUERY_THROW );
335  OUString sWorkPath = xApplication->getDefaultFilePath();
336  OUString sWorkURL;
337  osl::FileBase::getFileURLFromSystemPath( sWorkPath, sWorkURL );
338  aURL.SetURL( sWorkURL );
339  }
340  else
341  {
342  aURL.SetURL( sURL );
343  aURL.Append( sFileName );
344  }
346 
347  }
348 
349  sal_Int32 nFileFormat = excel::XlFileFormat::xlExcel9795;
350  FileFormat >>= nFileFormat;
351 
352  uno::Sequence< beans::PropertyValue > storeProps(1);
353  storeProps[0].Name = "FilterName" ;
354 
355  setFilterPropsFromFormat( nFileFormat, storeProps );
356 
357  uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW );
358  xStor->storeAsURL( sURL, storeProps );
359 }
360 
361 css::uno::Any SAL_CALL
363 {
364  // quick look and Styles object doesn't seem to have a valid parent
365  // or a least the object browser just shows an object that has no
366  // variables ( therefore... leave as NULL for now )
367  uno::Reference< XCollection > dStyles = new ScVbaStyles( uno::Reference< XHelperInterface >(), mxContext, getModel() );
368  if ( Item.hasValue() )
369  return dStyles->Item( Item, uno::Any() );
370  return uno::makeAny( dStyles );
371 }
372 
373 uno::Any SAL_CALL
375 {
376  uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
377  uno::Reference< beans::XPropertySet > xProps( xModel, uno::UNO_QUERY_THROW );
378  uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue("NamedRanges"), uno::UNO_QUERY_THROW );
379  uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, xModel ) );
380  if ( aIndex.hasValue() )
381  return xNames->Item( aIndex, uno::Any() );
382  return uno::Any( xNames );
383 }
384 
385 OUString
387 {
388  return "ScVbaWorkbook";
389 }
390 
391 uno::Sequence< OUString >
393 {
394  static uno::Sequence< OUString > const aServiceNames
395  {
396  "ooo.vba.excel.Workbook"
397  };
398  return aServiceNames;
399 }
400 
401 OUString SAL_CALL
403 {
404  uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW );
405  return xModelProp->getPropertyValue("CodeName").get< OUString >();
406 }
407 
408 sal_Int64
409 ScVbaWorkbook::getSomething(const uno::Sequence<sal_Int8 >& rId )
410 {
411  if (isUnoTunnelId<ScVbaWorksheet>(rId))
412  {
413  return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
414  }
415  return 0;
416 }
417 
418 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
420  css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
421 {
422  return cppu::acquire(new ScVbaWorkbook(args, context));
423 }
424 
425 
426 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
URL aURL
bool hasValue()
sal_Int32 nIndex
virtual css::uno::Any SAL_CALL Windows(const css::uno::Any &aIndex) override
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * Calc_ScVbaWorkbook_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &args)
void RegisterAutomationWorkbookObject(css::uno::Reference< ooo::vba::excel::XWorkbook > const &xWorkbook)
Definition: docsh.cxx:3266
virtual OUString SAL_CALL getAuthor() override
ScVbaWorkbook(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, css::uno::Reference< css::frame::XModel > const &xModel)
uno::Reference< uno::XComponentContext > mxContext
virtual css::uno::Sequence< OUString > getServiceNames() override
Sequence< OUString > aServiceNames
virtual void SAL_CALL ResetColors() override
Definition: vbaworkbook.cxx:57
OUString Name
sal_Int32 XLRGBToOORGB(sal_Int32 nCol)
virtual css::uno::Any SAL_CALL Sheets(const css::uno::Any &aIndex) override
virtual css::uno::Any SAL_CALL Worksheets(const css::uno::Any &aIndex) override
uno::Reference< XHelperInterface > getUnoSheetModuleObj(const uno::Reference< table::XCellRange > &xRange)
virtual void SAL_CALL setPrecisionAsDisplayed(sal_Bool _precisionAsDisplayed) override
virtual void SAL_CALL Activate() override
virtual void SAL_CALL SaveAs(const css::uno::Any &FileName, const css::uno::Any &FileFormat, const css::uno::Any &Password, const css::uno::Any &WriteResPassword, const css::uno::Any &ReadOnlyRecommended, const css::uno::Any &CreateBackup, const css::uno::Any &AccessMode, const css::uno::Any &ConflictResolution, const css::uno::Any &AddToMru, const css::uno::Any &TextCodepage, const css::uno::Any &TextVisualLayout, const css::uno::Any &Local) override
virtual ::sal_Int32 SAL_CALL getFileFormat() override
void SetCalcAsShown(bool bVal)
Definition: docoptio.hxx:83
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1923
virtual ::sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &rId) override
ScDocShell * getDocShell(const css::uno::Reference< css::frame::XModel > &xModel)
bool Append(OUString const &rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
cppu::ImplInheritanceHelper< VbaDocumentBase, ov::excel::XWorkbook > ScVbaWorkbook_BASE
Definition: vbaworkbook.hxx:27
virtual void SAL_CALL Protect(const css::uno::Any &aPassword) override
static css::uno::Sequence< sal_Int32 > ColorData
Definition: vbaworkbook.hxx:31
unsigned char sal_Bool
virtual css::uno::Any SAL_CALL Names(const css::uno::Any &aIndex) override
virtual void SAL_CALL Protect(const css::uno::Any &aPassword)
tuple index
virtual css::uno::Any SAL_CALL Styles(const css::uno::Any &Item) override
virtual void SAL_CALL Activate() override
virtual css::uno::Any SAL_CALL Colors(const css::uno::Any &Index) override
Definition: vbaworkbook.cxx:71
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static void initColorData(const css::uno::Sequence< sal_Int32 > &sColors)
Definition: vbaworkbook.cxx:51
SC_DLLPUBLIC void SetDocOptions(const ScDocOptions &rOpt)
Definition: documen3.cxx:1929
static bool setFilterPropsFromFormat(sal_Int32 nFormat, css::uno::Sequence< css::beans::PropertyValue > &rProps)
Definition: vbaworkbook.cxx:85
bool IsCalcAsShown() const
Definition: docoptio.hxx:82
virtual void SAL_CALL SaveCopyAs(const OUString &Filename) override
#define SC_TEXT_CSV_FILTER_NAME
Definition: global.hxx:59
const ScDocument & GetDocument() const
Definition: docsh.hxx:216
uno::Reference< frame::XModel > getCurrentExcelDoc(const uno::Reference< uno::XComponentContext > &xContext)
virtual void SAL_CALL setAuthor(const OUString &_author) override
virtual OUString getServiceImplName() override
bool SetURL(OUString const &rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
Reference< XModel > xModel
virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() override
virtual sal_Bool SAL_CALL getProtectStructure() override
virtual sal_Bool SAL_CALL getPrecisionAsDisplayed() override
struct _ADOIndex Index
static css::uno::Reference< css::container::XIndexAccess > getDefaultPalette()
Definition: vbapalette.cxx:94
virtual OUString SAL_CALL getCodeName() override