LibreOffice Module sc (master)  1
addruno.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/CellAddress.hpp>
21 #include <com/sun/star/table/CellRangeAddress.hpp>
23 
24 #include <svl/itemprop.hxx>
25 #include <vcl/svapp.hxx>
26 
27 #include <docsh.hxx>
28 #include <unonames.hxx>
29 #include <miscuno.hxx>
30 #include <convuno.hxx>
31 #include <addruno.hxx>
32 
33 using namespace com::sun::star;
34 
36  pDocShell( pDocSh ),
37  nRefSheet( 0 ),
38  bIsRange( _bIsRange )
39 {
41 }
42 
44 {
46 
47  if (pDocShell)
49 }
50 
52 {
53  if ( rHint.GetId() == SfxHintId::Dying )
54  {
55  pDocShell = nullptr; // invalid
56  }
57 }
58 
60 {
61  if (!pDocShell)
62  return false;
63 
64  ScDocument& rDoc = pDocShell->GetDocument();
65  bool bSuccess = false;
66  if ( bIsRange )
67  {
68  ScRefFlags nResult = aRange.ParseAny( rUIString, &rDoc, eConv );
69  if ( nResult & ScRefFlags::VALID )
70  {
71  if ( ( nResult & ScRefFlags::TAB_3D ) == ScRefFlags::ZERO )
72  aRange.aStart.SetTab( static_cast<SCTAB>(nRefSheet) );
73  if ( ( nResult & ScRefFlags::TAB2_3D ) == ScRefFlags::ZERO )
75  // different sheets are not supported in CellRangeAddress
76  if ( aRange.aStart.Tab() == aRange.aEnd.Tab() )
77  bSuccess = true;
78  }
79  }
80  else
81  {
82  ScRefFlags nResult = aRange.aStart.Parse( rUIString, &rDoc, eConv );
83  if ( nResult & ScRefFlags::VALID )
84  {
85  if ( ( nResult & ScRefFlags::TAB_3D ) == ScRefFlags::ZERO )
86  aRange.aStart.SetTab( static_cast<SCTAB>(nRefSheet) );
87  bSuccess = true;
88  }
89  }
90  return bSuccess;
91 }
92 
93 // XPropertySet
94 
95 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAddressConversionObj::getPropertySetInfo()
96 {
97  SolarMutexGuard aGuard;
98 
99  if ( bIsRange )
100  {
101  static const SfxItemPropertyMapEntry aPropertyMap[] =
102  {
104  { OUString(SC_UNONAME_PERSREPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
105  { OUString(SC_UNONAME_XLA1REPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
106  { OUString(SC_UNONAME_REFSHEET), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
107  { OUString(SC_UNONAME_UIREPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
108  { OUString(SC_UNONAME_XLA1REPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
109  { OUString(), 0, css::uno::Type(), 0, 0 }
110  };
111  static uno::Reference<beans::XPropertySetInfo> aRef(new SfxItemPropertySetInfo( aPropertyMap ));
112  return aRef;
113  }
114  else
115  {
116  static const SfxItemPropertyMapEntry aPropertyMap[] =
117  {
119  { OUString(SC_UNONAME_PERSREPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
120  { OUString(SC_UNONAME_XLA1REPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
121  { OUString(SC_UNONAME_REFSHEET), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
122  { OUString(SC_UNONAME_UIREPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
123  { OUString(SC_UNONAME_XLA1REPR), 0, cppu::UnoType<OUString>::get(), 0, 0 },
124  { OUString(), 0, css::uno::Type(), 0, 0 }
125  };
126  static uno::Reference<beans::XPropertySetInfo> aRef(new SfxItemPropertySetInfo( aPropertyMap ));
127  return aRef;
128  }
129 }
130 
131 void SAL_CALL ScAddressConversionObj::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
132 {
133  if ( !pDocShell )
134  throw uno::RuntimeException();
135 
136  bool bSuccess = false;
137  if ( aPropertyName == SC_UNONAME_ADDRESS )
138  {
139  // read the cell/range address from API struct
140  if ( bIsRange )
141  {
142  table::CellRangeAddress aRangeAddress;
143  if ( aValue >>= aRangeAddress )
144  {
145  ScUnoConversion::FillScRange( aRange, aRangeAddress );
146  bSuccess = true;
147  }
148  }
149  else
150  {
151  table::CellAddress aCellAddress;
152  if ( aValue >>= aCellAddress )
153  {
155  bSuccess = true;
156  }
157  }
158  }
159  else if ( aPropertyName == SC_UNONAME_REFSHEET )
160  {
161  // set the reference sheet
162  sal_Int32 nIntVal = 0;
163  if ( aValue >>= nIntVal )
164  {
165  nRefSheet = nIntVal;
166  bSuccess = true;
167  }
168  }
169  else if ( aPropertyName == SC_UNONAME_UIREPR )
170  {
171  // parse the UI representation string
172  OUString sRepresentation;
173  if (aValue >>= sRepresentation)
174  {
175  bSuccess = ParseUIString( sRepresentation );
176  }
177  }
178  else if ( aPropertyName == SC_UNONAME_PERSREPR || aPropertyName == SC_UNONAME_XLA1REPR )
179  {
182 
183  // parse the file format string
184  OUString sRepresentation;
185  if (aValue >>= sRepresentation)
186  {
187  OUString aUIString(sRepresentation);
188 
189  // cell or range: strip a single "." at the start
190  if ( aUIString[0]== '.' )
191  aUIString = aUIString.copy( 1 );
192 
193  if ( bIsRange )
194  {
195  // range: also strip a "." after the last colon
196  sal_Int32 nColon = aUIString.lastIndexOf( ':' );
197  if ( nColon >= 0 && nColon < aUIString.getLength() - 1 &&
198  aUIString[nColon+1] == '.' )
199  aUIString = aUIString.replaceAt( nColon+1, 1, "" );
200  }
201 
202  // parse the rest like a UI string
203  bSuccess = ParseUIString( aUIString, eConv );
204  }
205  }
206  else
207  throw beans::UnknownPropertyException(aPropertyName);
208 
209  if ( !bSuccess )
210  throw lang::IllegalArgumentException();
211 }
212 
213 uno::Any SAL_CALL ScAddressConversionObj::getPropertyValue( const OUString& aPropertyName )
214 {
215  if ( !pDocShell )
216  throw uno::RuntimeException();
217 
218  ScDocument& rDoc = pDocShell->GetDocument();
219  uno::Any aRet;
220 
221  if ( aPropertyName == SC_UNONAME_ADDRESS )
222  {
223  if ( bIsRange )
224  {
225  table::CellRangeAddress aRangeAddress;
226  ScUnoConversion::FillApiRange( aRangeAddress, aRange );
227  aRet <<= aRangeAddress;
228  }
229  else
230  {
231  table::CellAddress aCellAddress;
233  aRet <<= aCellAddress;
234  }
235  }
236  else if ( aPropertyName == SC_UNONAME_REFSHEET )
237  {
238  aRet <<= nRefSheet;
239  }
240  else if ( aPropertyName == SC_UNONAME_UIREPR )
241  {
242  // generate UI representation string - include sheet only if different from ref sheet
243  OUString aFormatStr;
244  ScRefFlags nFlags = ScRefFlags::VALID;
245  if ( aRange.aStart.Tab() != nRefSheet )
246  nFlags |= ScRefFlags::TAB_3D;
247  if ( bIsRange )
248  aFormatStr = aRange.Format(rDoc, nFlags);
249  else
250  aFormatStr = aRange.aStart.Format(nFlags, &rDoc);
251  aRet <<= aFormatStr;
252  }
253  else if ( aPropertyName == SC_UNONAME_PERSREPR || aPropertyName == SC_UNONAME_XLA1REPR )
254  {
257 
258  // generate file format string - always include sheet
259  OUString aFormatStr(aRange.aStart.Format(ScRefFlags::VALID | ScRefFlags::TAB_3D, &rDoc, eConv));
260  if ( bIsRange )
261  {
262  // manually concatenate range so both parts always have the sheet name
263  aFormatStr += ":";
264  ScRefFlags nFlags = ScRefFlags::VALID;
265  if( eConv != ::formula::FormulaGrammar::CONV_XL_A1 )
266  nFlags |= ScRefFlags::TAB_3D;
267  OUString aSecond(aRange.aEnd.Format(nFlags, &rDoc, eConv));
268  aFormatStr += aSecond ;
269  }
270  aRet <<= aFormatStr;
271  }
272  else
273  throw beans::UnknownPropertyException(aPropertyName);
274 
275  return aRet;
276 }
277 
279 
280 // lang::XServiceInfo
281 
282 OUString SAL_CALL ScAddressConversionObj::getImplementationName()
283 {
284  return "ScAddressConversionObj";
285 }
286 
287 sal_Bool SAL_CALL ScAddressConversionObj::supportsService( const OUString& rServiceName )
288 {
289  return cppu::supportsService(this, rServiceName);
290 }
291 
292 uno::Sequence<OUString> SAL_CALL ScAddressConversionObj::getSupportedServiceNames()
293 {
294  if (bIsRange)
296  else
298 }
299 
300 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2111
SC_DLLPUBLIC ScRefFlags ParseAny(const OUString &, const ScDocument *, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
Definition: address.cxx:1770
ScAddress aStart
Definition: address.hxx:500
ScDocShell * pDocShell
Definition: addruno.hxx:37
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: addruno.cxx:287
#define SC_UNONAME_XLA1REPR
Definition: unonames.hxx:660
ScAddress aEnd
Definition: address.hxx:501
SfxHintId GetId() const
ScAddressConversionObj(ScDocShell *pDocSh, bool bIsRange)
Definition: addruno.cxx:35
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: addruno.cxx:292
static void FillApiAddress(css::table::CellAddress &rApiAddress, const ScAddress &rScAddress)
Definition: convuno.hxx:71
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: addruno.cxx:131
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
SCTAB Tab() const
Definition: address.hxx:271
#define SC_UNONAME_PERSREPR
Definition: unonames.hxx:659
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
#define SC_UNONAME_REFSHEET
Definition: unonames.hxx:661
SC_DLLPUBLIC OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2207
#define SC_UNONAME_UIREPR
Definition: unonames.hxx:658
unsigned char sal_Bool
css::uno::Type const & get()
static void FillScAddress(ScAddress &rScAddress, const css::table::CellAddress &rApiAddress)
Definition: convuno.hxx:64
#define SC_IMPL_DUMMY_PROPERTY_LISTENER(ClassName)
Definition: miscuno.hxx:73
void AddUnoObject(SfxListener &rObject)
Definition: documen3.cxx:879
void RemoveUnoObject(SfxListener &rObject)
Definition: documen3.cxx:887
const ScDocument & GetDocument() const
Definition: docsh.hxx:216
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: addruno.cxx:51
virtual ~ScAddressConversionObj() override
Definition: addruno.cxx:43
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: addruno.cxx:213
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: addruno.cxx:95
static void FillApiRange(css::table::CellRangeAddress &rApiRange, const ScRange &rScRange)
Definition: convuno.hxx:88
#define SC_SERVICENAME_RANGEADDRESS
Definition: unonames.hxx:28
#define SC_SERVICENAME_CELLADDRESS
Definition: unonames.hxx:27
bool ParseUIString(const OUString &rUIString,::formula::FormulaGrammar::AddressConvention eConv=::formula::FormulaGrammar::CONV_OOO)
Definition: addruno.cxx:59
ScRefFlags
Definition: address.hxx:145
static void FillScRange(ScRange &rScRange, const css::table::CellRangeAddress &rApiRange)
Definition: convuno.hxx:80
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument *=nullptr, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1543
#define SC_UNONAME_ADDRESS
Definition: unonames.hxx:657