LibreOffice Module sc (master) 1
fapihelper.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 <fapihelper.hxx>
21
22#include <algorithm>
23#include <com/sun/star/frame/XModel.hpp>
24#include <com/sun/star/lang/XServiceName.hpp>
25#include <com/sun/star/lang/XMultiServiceFactory.hpp>
26#include <com/sun/star/beans/NamedValue.hpp>
27#include <com/sun/star/beans/XPropertyState.hpp>
28#include <com/sun/star/beans/XPropertySetOption.hpp>
29#include <com/sun/star/beans/XMultiPropertySet.hpp>
32#include <sal/log.hxx>
33#include <sfx2/objsh.hxx>
34#include <sfx2/docfile.hxx>
35#include <sfx2/frame.hxx>
36#include <sfx2/sfxsids.hrc>
37#include <svl/stritem.hxx>
38#include <svl/itemset.hxx>
39#include <miscuno.hxx>
40
41using ::com::sun::star::uno::Any;
42using ::com::sun::star::uno::Reference;
43using ::com::sun::star::uno::Sequence;
44using ::com::sun::star::uno::Exception;
45using ::com::sun::star::uno::UNO_QUERY;
46using ::com::sun::star::uno::UNO_QUERY_THROW;
47using ::com::sun::star::uno::XInterface;
48using ::com::sun::star::beans::XPropertySet;
49using ::com::sun::star::beans::XPropertyState;
50using ::com::sun::star::lang::XServiceName;
51using ::com::sun::star::lang::XMultiServiceFactory;
52
53using namespace ::com::sun::star;
54
55// Static helper functions ====================================================
56
57OUString ScfApiHelper::GetServiceName( const Reference< XInterface >& xInt )
58{
59 OUString aService;
60 Reference< XServiceName > xServiceName( xInt, UNO_QUERY );
61 if( xServiceName.is() )
62 aService = xServiceName->getServiceName();
63 return aService;
64}
65
66Reference< XMultiServiceFactory > ScfApiHelper::GetServiceFactory( const SfxObjectShell* pShell )
67{
68 Reference< XMultiServiceFactory > xFactory;
69 if( pShell )
70 xFactory.set( pShell->GetModel(), UNO_QUERY );
71 return xFactory;
72}
73
74Reference< XInterface > ScfApiHelper::CreateInstance(
75 const Reference< XMultiServiceFactory >& xFactory, const OUString& rServiceName )
76{
77 Reference< XInterface > xInt;
78 if( xFactory.is() )
79 {
80 try
81 {
82 xInt = xFactory->createInstance( rServiceName );
83 }
84 catch( Exception& )
85 {
86 OSL_FAIL( "ScfApiHelper::CreateInstance - cannot create instance" );
87 }
88 }
89 return xInt;
90}
91
92Reference< XInterface > ScfApiHelper::CreateInstance( const SfxObjectShell* pShell, const OUString& rServiceName )
93{
94 return CreateInstance( GetServiceFactory( pShell ), rServiceName );
95}
96
97Reference< XInterface > ScfApiHelper::CreateInstance( const OUString& rServiceName )
98{
99 return CreateInstance( ::comphelper::getProcessServiceFactory(), rServiceName );
100}
101
102uno::Sequence< beans::NamedValue > ScfApiHelper::QueryEncryptionDataForMedium( SfxMedium& rMedium,
103 ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords )
104{
105 uno::Sequence< beans::NamedValue > aEncryptionData;
106 const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(rMedium.GetItemSet(), SID_ENCRYPTIONDATA, false);
107 if ( pEncryptionDataItem )
108 pEncryptionDataItem->GetValue() >>= aEncryptionData;
109
110 OUString aPassword;
111 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(rMedium.GetItemSet(), SID_PASSWORD, false);
112 if ( pPasswordItem )
113 aPassword = pPasswordItem->GetValue();
114
115 bool bIsDefaultPassword = false;
117 rVerifier, aEncryptionData, aPassword, rMedium.GetInteractionHandler(), rMedium.GetOrigURL(),
118 ::comphelper::DocPasswordRequestType::MS, pDefaultPasswords, &bIsDefaultPassword );
119
120 rMedium.GetItemSet()->ClearItem( SID_PASSWORD );
121 rMedium.GetItemSet()->ClearItem( SID_ENCRYPTIONDATA );
122
123 if( !bIsDefaultPassword && aEncryptionData.hasElements() )
124 rMedium.GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::Any( aEncryptionData ) ) );
125
126 return aEncryptionData;
127}
128
129// Property sets ==============================================================
130
132{
133 Reference<beans::XPropertySetOption> xPropSetOpt(mxPropSet, UNO_QUERY);
134 if (xPropSetOpt.is())
135 // Turn the property value change notification back on when finished.
136 xPropSetOpt->enableChangeListenerNotification(true);
137}
138
139void ScfPropertySet::Set( Reference< XPropertySet > const & xPropSet )
140{
141 mxPropSet = xPropSet;
142 mxMultiPropSet.set( mxPropSet, UNO_QUERY );
143 Reference<beans::XPropertySetOption> xPropSetOpt(mxPropSet, UNO_QUERY);
144 if (xPropSetOpt.is())
145 // We don't want to broadcast property value changes during import to
146 // improve performance.
147 xPropSetOpt->enableChangeListenerNotification(false);
148}
149
151{
153}
154
155// Get properties -------------------------------------------------------------
156
157bool ScfPropertySet::HasProperty( const OUString& rPropName ) const
158{
159 bool bHasProp = false;
160 try
161 {
162 Reference< XPropertyState > xPropState( mxPropSet, UNO_QUERY_THROW );
163 bHasProp = xPropState->getPropertyState( rPropName ) == css::beans::PropertyState_DIRECT_VALUE;
164 }
165 catch( Exception& )
166 {
167 }
168 return bHasProp;
169}
170
171bool ScfPropertySet::GetAnyProperty( Any& rValue, const OUString& rPropName ) const
172{
173 bool bHasValue = false;
174 try
175 {
176 if( mxPropSet.is() )
177 {
178 rValue = mxPropSet->getPropertyValue( rPropName );
179 bHasValue = true;
180 }
181 }
182 catch( Exception& )
183 {
184 }
185 return bHasValue;
186}
187
188bool ScfPropertySet::GetBoolProperty( const OUString& rPropName ) const
189{
190 Any aAny;
191 return GetAnyProperty( aAny, rPropName ) && ScUnoHelpFunctions::GetBoolFromAny( aAny );
192}
193
194OUString ScfPropertySet::GetStringProperty( const OUString& rPropName ) const
195{
196 OUString aOUString;
197 GetProperty( aOUString, rPropName );
198 return aOUString;
199}
200
201bool ScfPropertySet::GetColorProperty( Color& rColor, const OUString& rPropName ) const
202{
203 sal_Int32 nApiColor = 0;
204 bool bRet = GetProperty( nApiColor, rPropName );
205 rColor = Color( ColorTransparency, nApiColor );
206 return bRet;
207}
208
209void ScfPropertySet::GetProperties( Sequence< Any >& rValues, const Sequence< OUString >& rPropNames ) const
210{
211 try
212 {
213 OSL_ENSURE( mxMultiPropSet.is(), "ScfPropertySet::GetProperties - multi property set not available" );
214 if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
215 {
216 rValues = mxMultiPropSet->getPropertyValues( rPropNames );
217 }
218 else if( mxPropSet.is() )
219 {
220 sal_Int32 nLen = rPropNames.getLength();
221 rValues.realloc( nLen );
222 std::transform(rPropNames.begin(), rPropNames.end(), rValues.getArray(),
223 [this](const OUString& rPropName) -> Any { return mxPropSet->getPropertyValue(rPropName); });
224 }
225 }
226 catch( Exception& )
227 {
228 }
229}
230
231// Set properties -------------------------------------------------------------
232
233void ScfPropertySet::SetAnyProperty( const OUString& rPropName, const Any& rValue )
234{
235 try
236 {
237 if( mxPropSet.is() )
238 mxPropSet->setPropertyValue( rPropName, rValue );
239 }
240 catch (const Exception&)
241 {
242 SAL_WARN("sc", "ScfPropertySet::SetAnyProperty - cannot set property \"" + rPropName + "\"");
243 }
244}
245
246void ScfPropertySet::SetProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
247{
248 OSL_ENSURE( rPropNames.getLength() == rValues.getLength(), "ScfPropertySet::SetProperties - length of sequences different" );
249 try
250 {
251 if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
252 {
253 mxMultiPropSet->setPropertyValues( rPropNames, rValues );
254 }
255 else if( mxPropSet.is() )
256 {
257 OSL_FAIL( "ScfPropertySet::SetProperties - multi property set not available" );
258 const OUString* pPropName = rPropNames.getConstArray();
259 const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
260 const Any* pValue = rValues.getConstArray();
261 for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
262 mxPropSet->setPropertyValue( *pPropName, *pValue );
263 }
264 }
265 catch( Exception& )
266 {
267 OSL_FAIL( "ScfPropertySet::SetAnyProperty - cannot set multiple properties" );
268 }
269}
270
271ScfPropSetHelper::ScfPropSetHelper( const char* const* ppcPropNames ) :
272 mnNextIdx( 0 )
273{
274 OSL_ENSURE( ppcPropNames, "ScfPropSetHelper::ScfPropSetHelper - no strings found" );
275
276 // create OUStrings from ASCII property names
277 typedef ::std::pair< OUString, size_t > IndexedOUString;
278 std::vector<IndexedOUString> aPropNameVec;
279 for( size_t nVecIdx = 0; *ppcPropNames; ++ppcPropNames, ++nVecIdx )
280 {
281 OUString aPropName = OUString::createFromAscii( *ppcPropNames );
282 aPropNameVec.emplace_back( aPropName, nVecIdx );
283 }
284
285 // sorts the pairs, which will be sorted by first component (the property name)
286 ::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
287
288 // resize member sequences
289 size_t nSize = aPropNameVec.size();
290 maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
291 auto pNameSeq = maNameSeq.getArray();
292 maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
293 maNameOrder.resize( nSize );
294
295 // fill the property name sequence and store original sort order
296 sal_Int32 nSeqIdx = 0;
297 for( auto& aPropName : aPropNameVec )
298 {
299 pNameSeq[ nSeqIdx ] = aPropName.first;
300 maNameOrder[ aPropName.second ] = nSeqIdx;
301 ++nSeqIdx;
302 }
303}
304
305// read properties ------------------------------------------------------------
306
308{
310 mnNextIdx = 0;
311}
312
313void ScfPropSetHelper::ReadValue( Any& rAny )
314{
315 Any* pAny = GetNextAny();
316 if( pAny )
317 rAny = *pAny;
318}
319
321{
322 sal_Int32 nApiColor(0);
323 ReadValue( nApiColor );
324 rColor = Color( ColorTransparency, nApiColor );
325}
326
327void ScfPropSetHelper::ReadValue( bool& rbValue )
328{
329 Any aAny;
330 ReadValue( aAny );
331 rbValue = ScUnoHelpFunctions::GetBoolFromAny( aAny );
332}
333
334// write properties -----------------------------------------------------------
335
337{
338 mnNextIdx = 0;
339}
340
341void ScfPropSetHelper::WriteValue( const Any& rAny )
342{
343 if( Any* pAny = GetNextAny() )
344 *pAny = rAny;
345}
346
348{
349 if( Any* pAny = GetNextAny() )
350 *pAny <<= rbValue;
351}
352
354{
356}
357
358// private --------------------------------------------------------------------
359
361{
362 OSL_ENSURE( mnNextIdx < maNameOrder.size(), "ScfPropSetHelper::GetNextAny - sequence overflow" );
363 Any* pAny = nullptr;
364 if( mnNextIdx < maNameOrder.size() )
365 pAny = &maValueSeq.getArray()[ maNameOrder[ mnNextIdx++ ] ];
366 return pAny;
367}
368
369/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const OUString & GetValue() const
static bool GetBoolFromAny(const css::uno::Any &aAny)
Definition: miscuno.cxx:138
static OUString GetServiceName(const css::uno::Reference< css::uno::XInterface > &xInt)
Returns the service name provided via the XServiceName interface, or an empty string on error.
Definition: fapihelper.cxx:57
static css::uno::Reference< css::lang::XMultiServiceFactory > GetServiceFactory(const SfxObjectShell *pShell)
Returns the multi service factory from a document shell.
Definition: fapihelper.cxx:66
static css::uno::Sequence< css::beans::NamedValue > QueryEncryptionDataForMedium(SfxMedium &rMedium, ::comphelper::IDocPasswordVerifier &rVerifier, const ::std::vector< OUString > *pDefaultPasswords)
Opens a password dialog and returns the encryption data.
Definition: fapihelper.cxx:102
static css::uno::Reference< css::uno::XInterface > CreateInstance(const css::uno::Reference< css::lang::XMultiServiceFactory > &xFactory, const OUString &rServiceName)
Creates an instance from the passed service name, using the passed service factory.
css::uno::Sequence< css::uno::Any > maValueSeq
Sequence of property names.
Definition: fapihelper.hxx:259
css::uno::Sequence< OUString > maNameSeq
Definition: fapihelper.hxx:258
size_t mnNextIdx
Maps initial order to alphabetical order.
Definition: fapihelper.hxx:261
void WriteValue(const Type &rValue)
Writes the next value to the value sequence.
Definition: fapihelper.hxx:273
ScfPropSetHelper(const char *const *ppcPropNames)
Definition: fapihelper.cxx:271
void ReadValue(Type &rValue)
Reads the next value from the value sequence.
Definition: fapihelper.hxx:265
ScfInt32Vec maNameOrder
Sequence of property values.
Definition: fapihelper.hxx:260
void ReadFromPropertySet(const ScfPropertySet &rPropSet)
Reads all values from the passed property set.
Definition: fapihelper.cxx:307
void WriteToPropertySet(ScfPropertySet &rPropSet) const
Writes all values to the passed property set.
Definition: fapihelper.cxx:353
void InitializeWrite()
Must be called before reading or storing property values in the helper.
Definition: fapihelper.cxx:336
css::uno::Any * GetNextAny()
Returns a pointer to the next Any to be written to.
Definition: fapihelper.cxx:360
A wrapper for a UNO property set.
Definition: fapihelper.hxx:104
css::uno::Reference< css::beans::XPropertySet > mxPropSet
Definition: fapihelper.hxx:195
void GetProperties(css::uno::Sequence< css::uno::Any > &rValues, const css::uno::Sequence< OUString > &rPropNames) const
Gets the specified properties from the property set.
Definition: fapihelper.cxx:209
void Set(css::uno::Reference< css::beans::XPropertySet > const &xPropSet)
Sets the passed UNO property set and releases the old UNO property set.
bool GetBoolProperty(const OUString &rPropName) const
Gets the specified Boolean property from the property set.
Definition: fapihelper.cxx:188
bool GetProperty(Type &rValue, const OUString &rPropName) const
Gets the specified property from the property set.
Definition: fapihelper.hxx:148
css::uno::Reference< css::beans::XMultiPropertySet > mxMultiPropSet
The mandatory property set interface.
Definition: fapihelper.hxx:196
OUString GetServiceName() const
Returns the service name provided via the XServiceName interface, or an empty string on error.
Definition: fapihelper.cxx:150
bool GetAnyProperty(css::uno::Any &rValue, const OUString &rPropName) const
Gets the specified property from the property set.
Definition: fapihelper.cxx:171
OUString GetStringProperty(const OUString &rPropName) const
Gets the specified Boolean property from the property set.
Definition: fapihelper.cxx:194
bool GetColorProperty(Color &rColor, const OUString &rPropName) const
Gets the specified color property from the property set.
Definition: fapihelper.cxx:201
bool HasProperty(const OUString &rPropName) const
Returns true, if the property set contains the specified property.
Definition: fapihelper.cxx:157
void SetProperties(const css::uno::Sequence< OUString > &rPropNames, const css::uno::Sequence< css::uno::Any > &rValues)
Puts the passed properties into the property set.
Definition: fapihelper.cxx:246
void SetAnyProperty(const OUString &rPropName, const css::uno::Any &rValue)
Puts the passed Any into the property set.
Definition: fapihelper.cxx:233
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SfxItemSet * GetItemSet() const
const OUString & GetOrigURL() const
css::uno::Reference< css::task::XInteractionHandler > GetInteractionHandler(bool bGetAlways=false)
css::uno::Reference< css::frame::XModel3 > GetModel() const
const css::uno::Any & GetValue() const
static css::uno::Sequence< css::beans::NamedValue > requestAndVerifyDocPassword(IDocPasswordVerifier &rVerifier, const css::uno::Sequence< css::beans::NamedValue > &rMediaEncData, const OUString &rMediaPassword, const css::uno::Reference< css::task::XInteractionHandler > &rxInteractHandler, const OUString &rDocumentUrl, DocPasswordRequestType eRequestType, const ::std::vector< OUString > *pDefaultPasswords=nullptr, bool *pbIsDefaultPassword=nullptr)
ColorTransparency
Reference< XSingleServiceFactory > xFactory
#define SAL_WARN(area, stream)
@ Exception
OUString aPropName