1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/table/CellAddress.hpp>
21 #include <com/sun/star/table/CellRangeAddress.hpp>
22 #include <cppuhelper/supportsservice.hxx>
24 #include <svl/itemprop.hxx>
25 #include <vcl/svapp.hxx>
28 #include <unonames.hxx>
29 #include <miscuno.hxx>
30 #include <convuno.hxx>
31 #include <addruno.hxx>
33 using namespace com::sun::star
;
35 ScAddressConversionObj::ScAddressConversionObj(ScDocShell
* pDocSh
, bool _bIsRange
) :
40 pDocShell
->GetDocument().AddUnoObject(*this);
43 ScAddressConversionObj::~ScAddressConversionObj()
48 pDocShell
->GetDocument().RemoveUnoObject(*this);
51 void ScAddressConversionObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
53 if ( rHint
.GetId() == SfxHintId::Dying
)
55 pDocShell
= nullptr; // invalid
59 bool ScAddressConversionObj::ParseUIString( const OUString
& rUIString
, ::formula::FormulaGrammar::AddressConvention eConv
)
64 ScDocument
& rDoc
= pDocShell
->GetDocument();
65 bool bSuccess
= false;
68 ScRefFlags nResult
= aRange
.ParseAny( rUIString
, rDoc
, eConv
);
69 if ( nResult
& ScRefFlags::VALID
)
71 if ( ( nResult
& ScRefFlags::TAB_3D
) == ScRefFlags::ZERO
)
72 aRange
.aStart
.SetTab( static_cast<SCTAB
>(nRefSheet
) );
73 if ( ( nResult
& ScRefFlags::TAB2_3D
) == ScRefFlags::ZERO
)
74 aRange
.aEnd
.SetTab( aRange
.aStart
.Tab() );
75 // different sheets are not supported in CellRangeAddress
76 if ( aRange
.aStart
.Tab() == aRange
.aEnd
.Tab() )
82 ScRefFlags nResult
= aRange
.aStart
.Parse( rUIString
, rDoc
, eConv
);
83 if ( nResult
& ScRefFlags::VALID
)
85 if ( ( nResult
& ScRefFlags::TAB_3D
) == ScRefFlags::ZERO
)
86 aRange
.aStart
.SetTab( static_cast<SCTAB
>(nRefSheet
) );
95 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScAddressConversionObj::getPropertySetInfo()
97 SolarMutexGuard aGuard
;
101 static const SfxItemPropertyMapEntry aPropertyMap
[] =
103 { SC_UNONAME_ADDRESS
, 0, cppu::UnoType
<table::CellRangeAddress
>::get(), 0, 0 },
104 { SC_UNONAME_PERSREPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
105 { SC_UNONAME_XLA1REPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
106 { SC_UNONAME_REFSHEET
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0 },
107 { SC_UNONAME_UIREPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
108 { SC_UNONAME_XLA1REPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
110 static uno::Reference
<beans::XPropertySetInfo
> aRef(new SfxItemPropertySetInfo( aPropertyMap
));
115 static const SfxItemPropertyMapEntry aPropertyMap
[] =
117 { SC_UNONAME_ADDRESS
, 0, cppu::UnoType
<table::CellAddress
>::get(), 0, 0 },
118 { SC_UNONAME_PERSREPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
119 { SC_UNONAME_XLA1REPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
120 { SC_UNONAME_REFSHEET
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0 },
121 { SC_UNONAME_UIREPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
122 { SC_UNONAME_XLA1REPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
124 static uno::Reference
<beans::XPropertySetInfo
> aRef(new SfxItemPropertySetInfo( aPropertyMap
));
129 void SAL_CALL
ScAddressConversionObj::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
132 throw uno::RuntimeException();
134 bool bSuccess
= false;
135 if ( aPropertyName
== SC_UNONAME_ADDRESS
)
137 // read the cell/range address from API struct
140 table::CellRangeAddress aRangeAddress
;
141 if ( aValue
>>= aRangeAddress
)
143 ScUnoConversion::FillScRange( aRange
, aRangeAddress
);
149 table::CellAddress aCellAddress
;
150 if ( aValue
>>= aCellAddress
)
152 ScUnoConversion::FillScAddress( aRange
.aStart
, aCellAddress
);
157 else if ( aPropertyName
== SC_UNONAME_REFSHEET
)
159 // set the reference sheet
160 sal_Int32 nIntVal
= 0;
161 if ( aValue
>>= nIntVal
)
167 else if ( aPropertyName
== SC_UNONAME_UIREPR
)
169 // parse the UI representation string
170 OUString sRepresentation
;
171 if (aValue
>>= sRepresentation
)
173 bSuccess
= ParseUIString( sRepresentation
);
176 else if ( aPropertyName
== SC_UNONAME_PERSREPR
|| aPropertyName
== SC_UNONAME_XLA1REPR
)
178 ::formula::FormulaGrammar::AddressConvention eConv
= aPropertyName
== SC_UNONAME_XLA1REPR
?
179 ::formula::FormulaGrammar::CONV_XL_A1
: ::formula::FormulaGrammar::CONV_OOO
;
181 // parse the file format string
182 OUString sRepresentation
;
183 if (aValue
>>= sRepresentation
)
185 OUString
aUIString(sRepresentation
);
187 // cell or range: strip a single "." at the start
188 if ( aUIString
[0]== '.' )
189 aUIString
= aUIString
.copy( 1 );
193 // range: also strip a "." after the last colon
194 sal_Int32 nColon
= aUIString
.lastIndexOf( ':' );
195 if ( nColon
>= 0 && nColon
< aUIString
.getLength() - 1 &&
196 aUIString
[nColon
+1] == '.' )
197 aUIString
= aUIString
.replaceAt( nColon
+1, 1, u
"" );
200 // parse the rest like a UI string
201 bSuccess
= ParseUIString( aUIString
, eConv
);
205 throw beans::UnknownPropertyException(aPropertyName
);
208 throw lang::IllegalArgumentException();
211 uno::Any SAL_CALL
ScAddressConversionObj::getPropertyValue( const OUString
& aPropertyName
)
214 throw uno::RuntimeException();
216 ScDocument
& rDoc
= pDocShell
->GetDocument();
219 if ( aPropertyName
== SC_UNONAME_ADDRESS
)
223 table::CellRangeAddress aRangeAddress
;
224 ScUnoConversion::FillApiRange( aRangeAddress
, aRange
);
225 aRet
<<= aRangeAddress
;
229 table::CellAddress aCellAddress
;
230 ScUnoConversion::FillApiAddress( aCellAddress
, aRange
.aStart
);
231 aRet
<<= aCellAddress
;
234 else if ( aPropertyName
== SC_UNONAME_REFSHEET
)
238 else if ( aPropertyName
== SC_UNONAME_UIREPR
)
240 // generate UI representation string - include sheet only if different from ref sheet
242 ScRefFlags nFlags
= ScRefFlags::VALID
;
243 if ( aRange
.aStart
.Tab() != nRefSheet
)
244 nFlags
|= ScRefFlags::TAB_3D
;
246 aFormatStr
= aRange
.Format(rDoc
, nFlags
);
248 aFormatStr
= aRange
.aStart
.Format(nFlags
, &rDoc
);
251 else if ( aPropertyName
== SC_UNONAME_PERSREPR
|| aPropertyName
== SC_UNONAME_XLA1REPR
)
253 ::formula::FormulaGrammar::AddressConvention eConv
= aPropertyName
== SC_UNONAME_XLA1REPR
?
254 ::formula::FormulaGrammar::CONV_XL_A1
: ::formula::FormulaGrammar::CONV_OOO
;
256 // generate file format string - always include sheet
257 OUString
aFormatStr(aRange
.aStart
.Format(ScRefFlags::VALID
| ScRefFlags::TAB_3D
, &rDoc
, eConv
));
260 // manually concatenate range so both parts always have the sheet name
262 ScRefFlags nFlags
= ScRefFlags::VALID
;
263 if( eConv
!= ::formula::FormulaGrammar::CONV_XL_A1
)
264 nFlags
|= ScRefFlags::TAB_3D
;
265 OUString
aSecond(aRange
.aEnd
.Format(nFlags
, &rDoc
, eConv
));
266 aFormatStr
+= aSecond
;
271 throw beans::UnknownPropertyException(aPropertyName
);
276 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAddressConversionObj
)
278 // lang::XServiceInfo
280 OUString SAL_CALL
ScAddressConversionObj::getImplementationName()
282 return u
"ScAddressConversionObj"_ustr
;
285 sal_Bool SAL_CALL
ScAddressConversionObj::supportsService( const OUString
& rServiceName
)
287 return cppu::supportsService(this, rServiceName
);
290 uno::Sequence
<OUString
> SAL_CALL
ScAddressConversionObj::getSupportedServiceNames()
293 return {SC_SERVICENAME_RANGEADDRESS
};
295 return {SC_SERVICENAME_CELLADDRESS
};
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */