LibreOffice Module sc (master)  1
vbanames.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 <com/sun/star/table/XCellRange.hpp>
21 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
22 #include <com/sun/star/sheet/XNamedRange.hpp>
23 #include <com/sun/star/sheet/XNamedRanges.hpp>
24 
25 #include "excelvbahelper.hxx"
26 #include "vbanames.hxx"
27 #include "vbaname.hxx"
28 #include "vbarange.hxx"
29 #include <tabvwsh.hxx>
30 #include <viewdata.hxx>
31 #include <compiler.hxx>
32 #include <tokenarray.hxx>
33 #include <cellsuno.hxx>
34 
35 #include <memory>
36 
37 using namespace ::ooo::vba;
38 using namespace ::com::sun::star;
39 
40 namespace {
41 
42 class NamesEnumeration : public EnumerationHelperImpl
43 {
44  uno::Reference< frame::XModel > m_xModel;
45  uno::Reference< sheet::XNamedRanges > m_xNames;
46 public:
48  NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ), m_xNames( xNames ) {}
49 
50  virtual uno::Any SAL_CALL nextElement( ) override
51  {
52  uno::Reference< sheet::XNamedRange > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
53  return uno::makeAny( uno::Reference< excel::XName > ( new ScVbaName( m_xParent, m_xContext, xNamed ,m_xNames , m_xModel ) ) );
54  }
55 
56 };
57 
58 }
59 
60 ScVbaNames::ScVbaNames(const css::uno::Reference< ov::XHelperInterface >& xParent,
61  const css::uno::Reference< css::uno::XComponentContext >& xContext,
62  const css::uno::Reference< css::sheet::XNamedRanges >& xNames,
63  const css::uno::Reference< css::frame::XModel >& xModel ):
64  ScVbaNames_BASE( xParent , xContext , uno::Reference< container::XIndexAccess >( xNames, uno::UNO_QUERY ) ),
65  mxModel( xModel ),
66  mxNames( xNames )
67 {
68  m_xNameAccess.set( xNames, uno::UNO_QUERY_THROW );
69 }
70 
72 {
73 }
74 
77 {
78  uno::Reference< frame::XModel > xModel( getModel() , uno::UNO_SET_THROW );
79  ScTabViewShell * pTabViewShell = excel::getBestViewShell( xModel );
80  if ( !pTabViewShell )
81  throw uno::RuntimeException( "No ViewShell available" );
82  ScViewData& rViewData = pTabViewShell->GetViewData();
83  return rViewData.GetDocument();
84 }
85 
86 css::uno::Any
87 ScVbaNames::Add( const css::uno::Any& Name ,
88  const css::uno::Any& RefersTo,
89  const css::uno::Any& /*Visible*/,
90  const css::uno::Any& /*MacroType*/,
91  const css::uno::Any& /*ShoutcutKey*/,
92  const css::uno::Any& /*Category*/,
93  const css::uno::Any& NameLocal,
94  const css::uno::Any& /*RefersToLocal*/,
95  const css::uno::Any& /*CategoryLocal*/,
96  const css::uno::Any& RefersToR1C1,
97  const css::uno::Any& RefersToR1C1Local )
98 {
99  OUString sName;
100  uno::Reference< excel::XRange > xRange;
101  if ( Name.hasValue() )
102  Name >>= sName;
103  else if ( NameLocal.hasValue() )
104  NameLocal >>= sName;
105  if ( !sName.isEmpty() )
106  {
108  {
109  const sal_Int32 nIndex{ sName.indexOf('!') };
110  if (nIndex>=0)
111  sName = sName.copy(nIndex+1);
113  throw uno::RuntimeException( "This Name is not valid ." );
114  }
115  }
116  uno::Reference< table::XCellRange > xUnoRange;
117  if ( RefersTo.hasValue() || RefersToR1C1.hasValue() || RefersToR1C1Local.hasValue() )
118  {
119  OUString sFormula;
120 
122  if ( RefersTo.hasValue() )
123  {
124  if ( RefersTo.getValueTypeClass() == uno::TypeClass_STRING )
125  RefersTo >>= sFormula;
126  else
127  RefersTo >>= xRange;
128  }
129  if ( RefersToR1C1.hasValue() )
130  {
131  if ( RefersToR1C1.getValueTypeClass() == uno::TypeClass_STRING )
132  {
133  RefersToR1C1 >>= sFormula;
135  }
136  else
137  RefersToR1C1 >>= xRange;
138  }
139  if ( RefersToR1C1Local.hasValue() )
140  {
141  if ( RefersToR1C1Local.getValueTypeClass() == uno::TypeClass_STRING )
142  {
143  RefersToR1C1Local >>= sFormula;
145  }
146  else
147  RefersToR1C1Local >>= xRange;
148  }
149  if ( !xRange.is() && !sFormula.isEmpty() )
150  {
151  ScAddress aBlank;
152  ScCompiler aComp( getScDocument(), aBlank, eGram );
153  std::unique_ptr<ScTokenArray> pTokens(aComp.CompileString(sFormula));
154  if ( pTokens )
155  {
156  ScRange aRange;
158  if (pTokens->IsValidReference(aRange, aBlank))
159  xUnoRange = new ScCellRangeObj( pDocSh, aRange );
160  else
161  {
162  // assume it's an address try strip the '=' if it's there
163  // and try and create a range ( must be a better way )
164  if ( sFormula.startsWith("=") )
165  sFormula = sFormula.copy(1);
166  ScRangeList aCellRanges;
167  ScRefFlags nFlags = ScRefFlags::ZERO;
169  if ( ScVbaRange::getCellRangesForAddress( nFlags, sFormula, pDocSh, aCellRanges, eConv , ',' ) )
170  {
171  if ( aCellRanges.size() == 1 )
172  xUnoRange = new ScCellRangeObj( pDocSh, aCellRanges.front() );
173  else
174  {
175  uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
176  xRange = new ScVbaRange( mxParent, mxContext, xRanges );
177  }
178  }
179 
180  }
181  }
182  }
183  }
184 
185  if ( xRange.is() || xUnoRange.is() )
186  {
187  if ( !xRange.is() )
188  xRange = new ScVbaRange( mxParent, mxContext, xUnoRange );
189 
190  uno::Reference< excel::XRange > xArea( xRange->Areas( uno::makeAny( sal_Int32(1) ) ), uno::UNO_QUERY );
191 
192  uno::Any aAny = xArea->getCellRange() ;
193 
194  uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( aAny, ::uno::UNO_QUERY_THROW);
195 
196  table::CellRangeAddress aAddr = thisRangeAdd->getRangeAddress();
197  uno::Any aAny2;
198  if ( mxNames.is() )
199  {
200  table::CellAddress aCellAddr( aAddr.Sheet , aAddr.StartColumn , aAddr.StartRow );
201  if ( mxNames->hasByName( sName ) )
202  mxNames->removeByName(sName);
203  OUStringBuffer sTmp = "$";
204  uno::Reference< ov::XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY );
205  for ( sal_Int32 nArea = 1; nArea <= xCol->getCount(); ++nArea )
206  {
207  xArea.set( xRange->Areas( uno::makeAny( nArea ) ), uno::UNO_QUERY_THROW );
208 
209  OUString sRangeAdd = xArea->Address( aAny2, aAny2 , aAny2 , aAny2, aAny2 );
210  if ( nArea > 1 )
211  sTmp.append(",");
212  sTmp.append("'").append(xRange->getWorksheet()->getName()).append("'.").append(sRangeAdd);
213  }
214  mxNames->addNewByName( sName, sTmp.makeStringAndClear(), aCellAddr, 0/*nUnoType*/);
215  return Item( uno::makeAny( sName ), uno::Any() );
216  }
217  }
218  return css::uno::Any();
219 }
220 
221 // XEnumerationAccess
222 css::uno::Type
224 {
226 }
227 
228 uno::Reference< container::XEnumeration >
230 {
231  uno::Reference< container::XEnumerationAccess > xEnumAccess( mxNames, uno::UNO_QUERY_THROW );
232  return new NamesEnumeration( getParent(), mxContext, xEnumAccess->createEnumeration(), mxModel , mxNames );
233 }
234 
235 uno::Any
237 {
238  uno::Reference< sheet::XNamedRange > xName( aSource, uno::UNO_QUERY );
239  return uno::makeAny( uno::Reference< excel::XName > ( new ScVbaName( getParent(), mxContext, xName, mxNames , mxModel ) ) );
240 }
241 
242 OUString
244 {
245  return "ScVbaNames";
246 }
247 
248 css::uno::Sequence<OUString>
250 {
251  static uno::Sequence< OUString > const aServiceNames
252  {
253  "ooo.vba.excel.NamedRanges"
254  };
255  return aServiceNames;
256 }
257 
258 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< frame::XModel > m_xModel
sal_Int32 nIndex
css::uno::Reference< css::frame::XModel > mxModel
Definition: vbanames.hxx:33
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4535
virtual css::uno::Sequence< OUString > getServiceNames() override
Definition: vbanames.cxx:249
Reference
const css::uno::Reference< css::frame::XModel > & getModel() const
Definition: vbanames.hxx:36
css::uno::Reference< css::frame::XModel2 > mxModel
Sequence< OUString > aServiceNames
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
exports com.sun.star. container
const char * sName
ScViewData & GetViewData()
Definition: tabview.hxx:332
ScVbaNames(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::sheet::XNamedRanges > &xNames, const css::uno::Reference< css::frame::XModel > &xModel)
Definition: vbanames.cxx:60
virtual OUString getServiceImplName() override
Definition: vbanames.cxx:243
ScDocShell * getDocShell(const css::uno::Reference< css::frame::XModel > &xModel)
static SC_DLLPUBLIC IsNameValidType IsNameValid(const OUString &rName, const ScDocument &rDoc)
Definition: rangenam.cxx:467
css::uno::Reference< css::container::XNameAccess > m_xNameAccess
size_t size() const
Definition: rangelst.hxx:90
css::uno::WeakReference< ov::XHelperInterface > mxParent
css::uno::Type const & get()
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
Definition: vbanames.cxx:229
ScTabViewShell * getBestViewShell(const css::uno::Reference< css::frame::XModel > &xModel)
css::uno::Reference< css::uno::XComponentContext > mxContext
virtual css::uno::Reference< ov::XHelperInterface > SAL_CALL getParent() override
ScDocument & getScDocument()
Definition: vbanames.cxx:76
virtual css::uno::Any createCollectionObject(const css::uno::Any &aSource) override
Definition: vbanames.cxx:236
ScRange & front()
Definition: rangelst.hxx:93
Reference< XModel > xModel
virtual css::uno::Type SAL_CALL getElementType() override
Definition: vbanames.cxx:223
virtual css::uno::Any SAL_CALL Item(const css::uno::Any &Index1, const css::uno::Any &) override
ScRefFlags
Definition: address.hxx:145
css::uno::Reference< css::sheet::XNamedRanges > mxNames
Definition: vbanames.hxx:34
static bool getCellRangesForAddress(ScRefFlags &rResFlags, const OUString &sAddress, ScDocShell *pDocSh, ScRangeList &rCellRanges, formula::FormulaGrammar::AddressConvention eConv, char cDelimiter)
Definition: vbarange.cxx:1146
virtual ~ScVbaNames() override
Definition: vbanames.cxx:71
virtual css::uno::Any SAL_CALL Add(const css::uno::Any &aName, const css::uno::Any &aRefersTo, const css::uno::Any &aVisible, const css::uno::Any &aMacroType, const css::uno::Any &aShoutcutKey, const css::uno::Any &aCategory, const css::uno::Any &aNameLocal, const css::uno::Any &aRefersToLocal, const css::uno::Any &aCategoryLocal, const css::uno::Any &aRefersToR1C1, const css::uno::Any &aRefersToR1C1Local) override
Definition: vbanames.cxx:87