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  {
109  {
110  const sal_Int32 nIndex{ sName.indexOf('!') };
111  if (nIndex>=0)
112  sName = sName.copy(nIndex+1);
115  throw uno::RuntimeException( "This Name is not valid ." );
116  }
117  }
118  uno::Reference< table::XCellRange > xUnoRange;
119  if ( RefersTo.hasValue() || RefersToR1C1.hasValue() || RefersToR1C1Local.hasValue() )
120  {
121  OUString sFormula;
122 
124  if ( RefersTo.hasValue() )
125  {
126  if ( RefersTo.getValueTypeClass() == uno::TypeClass_STRING )
127  RefersTo >>= sFormula;
128  else
129  RefersTo >>= xRange;
130  }
131  if ( RefersToR1C1.hasValue() )
132  {
133  if ( RefersToR1C1.getValueTypeClass() == uno::TypeClass_STRING )
134  {
135  RefersToR1C1 >>= sFormula;
137  }
138  else
139  RefersToR1C1 >>= xRange;
140  }
141  if ( RefersToR1C1Local.hasValue() )
142  {
143  if ( RefersToR1C1Local.getValueTypeClass() == uno::TypeClass_STRING )
144  {
145  RefersToR1C1Local >>= sFormula;
147  }
148  else
149  RefersToR1C1Local >>= xRange;
150  }
151  if ( !xRange.is() && !sFormula.isEmpty() )
152  {
153  ScAddress aBlank;
154  ScCompiler aComp( getScDocument(), aBlank, eGram );
155  std::unique_ptr<ScTokenArray> pTokens(aComp.CompileString(sFormula));
156  if ( pTokens )
157  {
158  ScRange aRange;
160  if (pTokens->IsValidReference(aRange, aBlank))
161  xUnoRange = new ScCellRangeObj( pDocSh, aRange );
162  else
163  {
164  // assume it's an address try strip the '=' if it's there
165  // and try and create a range ( must be a better way )
166  if ( sFormula.startsWith("=") )
167  sFormula = sFormula.copy(1);
168  ScRangeList aCellRanges;
169  ScRefFlags nFlags = ScRefFlags::ZERO;
171  if ( ScVbaRange::getCellRangesForAddress( nFlags, sFormula, pDocSh, aCellRanges, eConv , ',' ) )
172  {
173  if ( aCellRanges.size() == 1 )
174  xUnoRange = new ScCellRangeObj( pDocSh, aCellRanges.front() );
175  else
176  {
177  uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
178  xRange = new ScVbaRange( mxParent, mxContext, xRanges );
179  }
180  }
181 
182  }
183  }
184  }
185  }
186 
187  if ( xRange.is() || xUnoRange.is() )
188  {
189  if ( !xRange.is() )
190  xRange = new ScVbaRange( mxParent, mxContext, xUnoRange );
191 
192  uno::Reference< excel::XRange > xArea( xRange->Areas( uno::makeAny( sal_Int32(1) ) ), uno::UNO_QUERY );
193 
194  uno::Any aAny = xArea->getCellRange() ;
195 
196  uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( aAny, ::uno::UNO_QUERY_THROW);
197 
198  table::CellRangeAddress aAddr = thisRangeAdd->getRangeAddress();
199  uno::Any aAny2;
200  if ( mxNames.is() )
201  {
202  table::CellAddress aCellAddr( aAddr.Sheet , aAddr.StartColumn , aAddr.StartRow );
203  if ( mxNames->hasByName( sName ) )
204  mxNames->removeByName(sName);
205  OUStringBuffer sTmp = "$";
206  uno::Reference< ov::XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY );
207  for ( sal_Int32 nArea = 1; nArea <= xCol->getCount(); ++nArea )
208  {
209  xArea.set( xRange->Areas( uno::makeAny( nArea ) ), uno::UNO_QUERY_THROW );
210 
211  OUString sRangeAdd = xArea->Address( aAny2, aAny2 , aAny2 , aAny2, aAny2 );
212  if ( nArea > 1 )
213  sTmp.append(",");
214  sTmp.append("'" + xRange->getWorksheet()->getName() + "'." + sRangeAdd);
215  }
216  mxNames->addNewByName( sName, sTmp.makeStringAndClear(), aCellAddr, 0/*nUnoType*/);
217  return Item( uno::makeAny( sName ), uno::Any() );
218  }
219  }
220  return css::uno::Any();
221 }
222 
223 // XEnumerationAccess
224 css::uno::Type
226 {
228 }
229 
230 uno::Reference< container::XEnumeration >
232 {
233  uno::Reference< container::XEnumerationAccess > xEnumAccess( mxNames, uno::UNO_QUERY_THROW );
234  return new NamesEnumeration( getParent(), mxContext, xEnumAccess->createEnumeration(), mxModel , mxNames );
235 }
236 
237 uno::Any
239 {
240  uno::Reference< sheet::XNamedRange > xName( aSource, uno::UNO_QUERY );
241  return uno::makeAny( uno::Reference< excel::XName > ( new ScVbaName( getParent(), mxContext, xName, mxNames , mxModel ) ) );
242 }
243 
244 OUString
246 {
247  return "ScVbaNames";
248 }
249 
250 css::uno::Sequence<OUString>
252 {
253  static uno::Sequence< OUString > const aServiceNames
254  {
255  "ooo.vba.excel.NamedRanges"
256  };
257  return aServiceNames;
258 }
259 
260 /* 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:32
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4584
virtual css::uno::Sequence< OUString > getServiceNames() override
Definition: vbanames.cxx:251
Reference
const css::uno::Reference< css::frame::XModel > & getModel() const
Definition: vbanames.hxx:35
css::uno::Reference< css::frame::XModel2 > mxModel
Sequence< OUString > aServiceNames
ScDocument & GetDocument() const
Definition: viewdata.hxx:379
exports com.sun.star. container
const char * sName
ScViewData & GetViewData()
Definition: tabview.hxx:333
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:245
ScDocShell * getDocShell(const css::uno::Reference< css::frame::XModel > &xModel)
static SC_DLLPUBLIC IsNameValidType IsNameValid(const OUString &rName, const ScDocument &rDoc)
Definition: rangenam.cxx:466
css::uno::Reference< css::container::XNameAccess > m_xNameAccess
size_t size() const
Definition: rangelst.hxx:89
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:231
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:238
ScRange & front()
Definition: rangelst.hxx:92
Reference< XModel > xModel
virtual css::uno::Type SAL_CALL getElementType() override
Definition: vbanames.cxx:225
virtual css::uno::Any SAL_CALL Item(const css::uno::Any &Index1, const css::uno::Any &) override
ScRefFlags
Definition: address.hxx:144
css::uno::Reference< css::sheet::XNamedRanges > mxNames
Definition: vbanames.hxx:33
static bool getCellRangesForAddress(ScRefFlags &rResFlags, const OUString &sAddress, ScDocShell *pDocSh, ScRangeList &rCellRanges, formula::FormulaGrammar::AddressConvention eConv, char cDelimiter)
Definition: vbarange.cxx:1147
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