xref: /trunk/main/sc/source/ui/unoobj/addruno.cxx (revision b3f79822)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <com/sun/star/table/CellAddress.hpp>
30cdf0e10cSrcweir #include <com/sun/star/table/CellRangeAddress.hpp>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <svl/itemprop.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "docsh.hxx"
35cdf0e10cSrcweir #include "unonames.hxx"
36cdf0e10cSrcweir #include "unoguard.hxx"
37cdf0e10cSrcweir #include "miscuno.hxx"
38cdf0e10cSrcweir #include "convuno.hxx"
39cdf0e10cSrcweir #include "addruno.hxx"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir using namespace com::sun::star;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir //------------------------------------------------------------------------
44cdf0e10cSrcweir 
ScAddressConversionObj(ScDocShell * pDocSh,sal_Bool bForRange)45cdf0e10cSrcweir ScAddressConversionObj::ScAddressConversionObj(ScDocShell* pDocSh, sal_Bool bForRange) :
46cdf0e10cSrcweir     pDocShell( pDocSh ),
47cdf0e10cSrcweir     nRefSheet( 0 ),
48cdf0e10cSrcweir     bIsRange( bForRange )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir     pDocShell->GetDocument()->AddUnoObject(*this);
51cdf0e10cSrcweir }
52cdf0e10cSrcweir 
~ScAddressConversionObj()53cdf0e10cSrcweir ScAddressConversionObj::~ScAddressConversionObj()
54cdf0e10cSrcweir {
55cdf0e10cSrcweir     if (pDocShell)
56cdf0e10cSrcweir         pDocShell->GetDocument()->RemoveUnoObject(*this);
57cdf0e10cSrcweir }
58cdf0e10cSrcweir 
Notify(SfxBroadcaster &,const SfxHint & rHint)59cdf0e10cSrcweir void ScAddressConversionObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
60cdf0e10cSrcweir {
61cdf0e10cSrcweir     if ( rHint.ISA( SfxSimpleHint ) &&
62cdf0e10cSrcweir             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
63cdf0e10cSrcweir     {
64cdf0e10cSrcweir         pDocShell = NULL;       // invalid
65cdf0e10cSrcweir     }
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
ParseUIString(const String & rUIString,::formula::FormulaGrammar::AddressConvention eConv)68cdf0e10cSrcweir sal_Bool ScAddressConversionObj::ParseUIString( const String& rUIString, ::formula::FormulaGrammar::AddressConvention eConv )
69cdf0e10cSrcweir {
70cdf0e10cSrcweir     if (!pDocShell)
71cdf0e10cSrcweir         return sal_False;
72cdf0e10cSrcweir 
73cdf0e10cSrcweir     ScDocument* pDoc = pDocShell->GetDocument();
74cdf0e10cSrcweir     sal_Bool bSuccess = sal_False;
75cdf0e10cSrcweir     if ( bIsRange )
76cdf0e10cSrcweir     {
77cdf0e10cSrcweir         sal_uInt16 nResult = aRange.ParseAny( rUIString, pDoc, eConv );
78cdf0e10cSrcweir         if ( nResult & SCA_VALID )
79cdf0e10cSrcweir         {
80cdf0e10cSrcweir             if ( ( nResult & SCA_TAB_3D ) == 0 )
81cdf0e10cSrcweir                 aRange.aStart.SetTab( static_cast<SCTAB>(nRefSheet) );
82cdf0e10cSrcweir             if ( ( nResult & SCA_TAB2_3D ) == 0 )
83cdf0e10cSrcweir                 aRange.aEnd.SetTab( aRange.aStart.Tab() );
84cdf0e10cSrcweir             // different sheets are not supported in CellRangeAddress
85cdf0e10cSrcweir             if ( aRange.aStart.Tab() == aRange.aEnd.Tab() )
86cdf0e10cSrcweir                 bSuccess = sal_True;
87cdf0e10cSrcweir         }
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir     else
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         sal_uInt16 nResult = aRange.aStart.Parse( rUIString, pDoc, eConv );
92cdf0e10cSrcweir         if ( nResult & SCA_VALID )
93cdf0e10cSrcweir         {
94cdf0e10cSrcweir             if ( ( nResult & SCA_TAB_3D ) == 0 )
95cdf0e10cSrcweir                 aRange.aStart.SetTab( static_cast<SCTAB>(nRefSheet) );
96cdf0e10cSrcweir             bSuccess = sal_True;
97cdf0e10cSrcweir         }
98cdf0e10cSrcweir     }
99cdf0e10cSrcweir     return bSuccess;
100cdf0e10cSrcweir }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir // XPropertySet
103cdf0e10cSrcweir 
getPropertySetInfo()104cdf0e10cSrcweir uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAddressConversionObj::getPropertySetInfo()
105cdf0e10cSrcweir                                                         throw(uno::RuntimeException)
106cdf0e10cSrcweir {
107cdf0e10cSrcweir     ScUnoGuard aGuard;
108cdf0e10cSrcweir 
109cdf0e10cSrcweir     if ( bIsRange )
110cdf0e10cSrcweir     {
111cdf0e10cSrcweir         static SfxItemPropertyMapEntry aPropertyMap[] =
112cdf0e10cSrcweir         {
113cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_ADDRESS),  0,  &getCppuType((table::CellRangeAddress*)0), 0, 0 },
114cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_PERSREPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
115cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_REFSHEET), 0,  &getCppuType((sal_Int32*)0),        0, 0 },
116cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_UIREPR),   0,  &getCppuType((rtl::OUString*)0),    0, 0 },
117cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_XLA1REPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
118cdf0e10cSrcweir             {0,0,0,0,0,0}
119cdf0e10cSrcweir         };
120cdf0e10cSrcweir         static uno::Reference<beans::XPropertySetInfo> aRef(new SfxItemPropertySetInfo( aPropertyMap ));
121cdf0e10cSrcweir         return aRef;
122cdf0e10cSrcweir     }
123cdf0e10cSrcweir     else
124cdf0e10cSrcweir     {
125cdf0e10cSrcweir         static SfxItemPropertyMapEntry aPropertyMap[] =
126cdf0e10cSrcweir         {
127cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_ADDRESS),  0,  &getCppuType((table::CellAddress*)0), 0, 0 },
128cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_PERSREPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
129cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_REFSHEET), 0,  &getCppuType((sal_Int32*)0),        0, 0 },
130cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_UIREPR),   0,  &getCppuType((rtl::OUString*)0),    0, 0 },
131cdf0e10cSrcweir             {MAP_CHAR_LEN(SC_UNONAME_XLA1REPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
132cdf0e10cSrcweir             {0,0,0,0,0,0}
133cdf0e10cSrcweir         };
134cdf0e10cSrcweir         static uno::Reference<beans::XPropertySetInfo> aRef(new SfxItemPropertySetInfo( aPropertyMap ));
135cdf0e10cSrcweir         return aRef;
136cdf0e10cSrcweir     }
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
setPropertyValue(const rtl::OUString & aPropertyName,const uno::Any & aValue)139cdf0e10cSrcweir void SAL_CALL ScAddressConversionObj::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
140cdf0e10cSrcweir                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
141cdf0e10cSrcweir                         lang::IllegalArgumentException, lang::WrappedTargetException,
142cdf0e10cSrcweir                         uno::RuntimeException)
143cdf0e10cSrcweir {
144cdf0e10cSrcweir     if ( !pDocShell )
145cdf0e10cSrcweir         throw uno::RuntimeException();
146cdf0e10cSrcweir 
147cdf0e10cSrcweir     sal_Bool bSuccess = sal_False;
148cdf0e10cSrcweir     String aNameStr(aPropertyName);
149cdf0e10cSrcweir     if ( aNameStr.EqualsAscii( SC_UNONAME_ADDRESS ) )
150cdf0e10cSrcweir     {
151cdf0e10cSrcweir         //  read the cell/range address from API struct
152cdf0e10cSrcweir         if ( bIsRange )
153cdf0e10cSrcweir         {
154cdf0e10cSrcweir             table::CellRangeAddress aRangeAddress;
155cdf0e10cSrcweir             if ( aValue >>= aRangeAddress )
156cdf0e10cSrcweir             {
157cdf0e10cSrcweir                 ScUnoConversion::FillScRange( aRange, aRangeAddress );
158cdf0e10cSrcweir                 bSuccess = sal_True;
159cdf0e10cSrcweir             }
160cdf0e10cSrcweir         }
161cdf0e10cSrcweir         else
162cdf0e10cSrcweir         {
163cdf0e10cSrcweir             table::CellAddress aCellAddress;
164cdf0e10cSrcweir             if ( aValue >>= aCellAddress )
165cdf0e10cSrcweir             {
166cdf0e10cSrcweir                 ScUnoConversion::FillScAddress( aRange.aStart, aCellAddress );
167cdf0e10cSrcweir                 bSuccess = sal_True;
168cdf0e10cSrcweir             }
169cdf0e10cSrcweir         }
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir     else if ( aNameStr.EqualsAscii( SC_UNONAME_REFSHEET ) )
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         //  set the reference sheet
174cdf0e10cSrcweir         sal_Int32 nIntVal = 0;
175cdf0e10cSrcweir         if ( aValue >>= nIntVal )
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir             nRefSheet = nIntVal;
178cdf0e10cSrcweir             bSuccess = sal_True;
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir     }
181cdf0e10cSrcweir     else if ( aNameStr.EqualsAscii( SC_UNONAME_UIREPR ) )
182cdf0e10cSrcweir     {
183cdf0e10cSrcweir         //  parse the UI representation string
184cdf0e10cSrcweir         rtl::OUString sRepresentation;
185cdf0e10cSrcweir         if (aValue >>= sRepresentation)
186cdf0e10cSrcweir         {
187cdf0e10cSrcweir             String aUIString = sRepresentation;
188cdf0e10cSrcweir             bSuccess = ParseUIString( aUIString );
189cdf0e10cSrcweir         }
190cdf0e10cSrcweir     }
191cdf0e10cSrcweir     else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) )
192cdf0e10cSrcweir     {
193cdf0e10cSrcweir         ::formula::FormulaGrammar::AddressConvention eConv = aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ?
194cdf0e10cSrcweir             ::formula::FormulaGrammar::CONV_XL_A1 : ::formula::FormulaGrammar::CONV_OOO;
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         //  parse the file format string
197cdf0e10cSrcweir         rtl::OUString sRepresentation;
198cdf0e10cSrcweir         if (aValue >>= sRepresentation)
199cdf0e10cSrcweir         {
200cdf0e10cSrcweir             String aUIString(sRepresentation);
201cdf0e10cSrcweir 
202cdf0e10cSrcweir             //  cell or range: strip a single "." at the start
203cdf0e10cSrcweir             if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
204cdf0e10cSrcweir                 aUIString.Erase( 0, 1 );
205cdf0e10cSrcweir 
206cdf0e10cSrcweir             if ( bIsRange )
207cdf0e10cSrcweir             {
208cdf0e10cSrcweir                 //  range: also strip a "." after the last colon
209cdf0e10cSrcweir                 sal_Int32 nColon = rtl::OUString(aUIString).lastIndexOf( (sal_Unicode) ':' );
210cdf0e10cSrcweir                 if ( nColon >= 0 && nColon < aUIString.Len() - 1 &&
211cdf0e10cSrcweir                      aUIString.GetChar((xub_StrLen)nColon+1) == (sal_Unicode) '.' )
212cdf0e10cSrcweir                     aUIString.Erase( (xub_StrLen)nColon+1, 1 );
213cdf0e10cSrcweir             }
214cdf0e10cSrcweir 
215cdf0e10cSrcweir             //  parse the rest like a UI string
216cdf0e10cSrcweir             bSuccess = ParseUIString( aUIString, eConv );
217cdf0e10cSrcweir         }
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir     else
220cdf0e10cSrcweir         throw beans::UnknownPropertyException();
221cdf0e10cSrcweir 
222cdf0e10cSrcweir     if ( !bSuccess )
223cdf0e10cSrcweir         throw lang::IllegalArgumentException();
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
getPropertyValue(const rtl::OUString & aPropertyName)226cdf0e10cSrcweir uno::Any SAL_CALL ScAddressConversionObj::getPropertyValue( const rtl::OUString& aPropertyName )
227cdf0e10cSrcweir                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
228cdf0e10cSrcweir                         uno::RuntimeException)
229cdf0e10cSrcweir {
230cdf0e10cSrcweir     if ( !pDocShell )
231cdf0e10cSrcweir         throw uno::RuntimeException();
232cdf0e10cSrcweir 
233cdf0e10cSrcweir     ScDocument* pDoc = pDocShell->GetDocument();
234cdf0e10cSrcweir     uno::Any aRet;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     String aNameStr(aPropertyName);
237cdf0e10cSrcweir     if ( aNameStr.EqualsAscii( SC_UNONAME_ADDRESS ) )
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         if ( bIsRange )
240cdf0e10cSrcweir         {
241cdf0e10cSrcweir             table::CellRangeAddress aRangeAddress;
242cdf0e10cSrcweir             ScUnoConversion::FillApiRange( aRangeAddress, aRange );
243cdf0e10cSrcweir             aRet <<= aRangeAddress;
244cdf0e10cSrcweir         }
245cdf0e10cSrcweir         else
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             table::CellAddress aCellAddress;
248cdf0e10cSrcweir             ScUnoConversion::FillApiAddress( aCellAddress, aRange.aStart );
249cdf0e10cSrcweir             aRet <<= aCellAddress;
250cdf0e10cSrcweir         }
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir     else if ( aNameStr.EqualsAscii( SC_UNONAME_REFSHEET ) )
253cdf0e10cSrcweir     {
254cdf0e10cSrcweir         aRet <<= nRefSheet;
255cdf0e10cSrcweir     }
256cdf0e10cSrcweir     else if ( aNameStr.EqualsAscii( SC_UNONAME_UIREPR ) )
257cdf0e10cSrcweir     {
258cdf0e10cSrcweir         //  generate UI representation string - include sheet only if different from ref sheet
259cdf0e10cSrcweir         String aFormatStr;
260cdf0e10cSrcweir         sal_uInt16 nFlags = SCA_VALID;
261cdf0e10cSrcweir         if ( aRange.aStart.Tab() != nRefSheet )
262cdf0e10cSrcweir             nFlags |= SCA_TAB_3D;
263cdf0e10cSrcweir         if ( bIsRange )
264cdf0e10cSrcweir             aRange.Format( aFormatStr, nFlags, pDoc );
265cdf0e10cSrcweir         else
266cdf0e10cSrcweir             aRange.aStart.Format( aFormatStr, nFlags, pDoc );
267cdf0e10cSrcweir         aRet <<= rtl::OUString( aFormatStr );
268cdf0e10cSrcweir     }
269cdf0e10cSrcweir     else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) )
270cdf0e10cSrcweir     {
271cdf0e10cSrcweir         ::formula::FormulaGrammar::AddressConvention eConv = aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ?
272cdf0e10cSrcweir             ::formula::FormulaGrammar::CONV_XL_A1 : ::formula::FormulaGrammar::CONV_OOO;
273cdf0e10cSrcweir 
274cdf0e10cSrcweir         //  generate file format string - always include sheet
275cdf0e10cSrcweir         String aFormatStr;
276cdf0e10cSrcweir         aRange.aStart.Format( aFormatStr, SCA_VALID | SCA_TAB_3D, pDoc, eConv );
277cdf0e10cSrcweir         if ( bIsRange )
278cdf0e10cSrcweir         {
279cdf0e10cSrcweir             //  manually concatenate range so both parts always have the sheet name
280cdf0e10cSrcweir             aFormatStr.Append( (sal_Unicode) ':' );
281cdf0e10cSrcweir             String aSecond;
282cdf0e10cSrcweir             sal_uInt16 nFlags = SCA_VALID;
283cdf0e10cSrcweir             if( eConv != ::formula::FormulaGrammar::CONV_XL_A1 )
284cdf0e10cSrcweir                 nFlags |= SCA_TAB_3D;
285cdf0e10cSrcweir             aRange.aEnd.Format( aSecond, nFlags, pDoc, eConv );
286cdf0e10cSrcweir             aFormatStr.Append( aSecond );
287cdf0e10cSrcweir         }
288cdf0e10cSrcweir         aRet <<= rtl::OUString( aFormatStr );
289cdf0e10cSrcweir     }
290cdf0e10cSrcweir     else
291cdf0e10cSrcweir         throw beans::UnknownPropertyException();
292cdf0e10cSrcweir 
293cdf0e10cSrcweir     return aRet;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
SC_IMPL_DUMMY_PROPERTY_LISTENER(ScAddressConversionObj)296cdf0e10cSrcweir SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAddressConversionObj )
297cdf0e10cSrcweir 
298cdf0e10cSrcweir // lang::XServiceInfo
299cdf0e10cSrcweir 
300cdf0e10cSrcweir rtl::OUString SAL_CALL ScAddressConversionObj::getImplementationName() throw(uno::RuntimeException)
301cdf0e10cSrcweir {
302cdf0e10cSrcweir     return rtl::OUString::createFromAscii( "ScAddressConversionObj" );
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
supportsService(const rtl::OUString & rServiceName)305cdf0e10cSrcweir sal_Bool SAL_CALL ScAddressConversionObj::supportsService( const rtl::OUString& rServiceName )
306cdf0e10cSrcweir                                                     throw(uno::RuntimeException)
307cdf0e10cSrcweir {
308cdf0e10cSrcweir     String aServiceStr( rServiceName );
309cdf0e10cSrcweir     return aServiceStr.EqualsAscii( bIsRange ? SC_SERVICENAME_RANGEADDRESS
310cdf0e10cSrcweir                                              : SC_SERVICENAME_CELLADDRESS );
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
getSupportedServiceNames()313cdf0e10cSrcweir uno::Sequence<rtl::OUString> SAL_CALL ScAddressConversionObj::getSupportedServiceNames()
314cdf0e10cSrcweir                                                     throw(uno::RuntimeException)
315cdf0e10cSrcweir {
316cdf0e10cSrcweir     uno::Sequence<rtl::OUString> aRet(1);
317cdf0e10cSrcweir     rtl::OUString* pArray = aRet.getArray();
318cdf0e10cSrcweir     pArray[0] = rtl::OUString::createFromAscii( bIsRange ? SC_SERVICENAME_RANGEADDRESS
319cdf0e10cSrcweir                                                          : SC_SERVICENAME_CELLADDRESS );
320cdf0e10cSrcweir     return aRet;
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
323