Line data Source code
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/lang/XServiceName.hpp>
24 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
25 : #include <com/sun/star/beans/XPropertyState.hpp>
26 : #include <com/sun/star/beans/XPropertySetOption.hpp>
27 : #include <comphelper/docpasswordhelper.hxx>
28 : #include <comphelper/processfactory.hxx>
29 : #include <tools/urlobj.hxx>
30 : #include <rtl/strbuf.hxx>
31 : #include <sfx2/objsh.hxx>
32 : #include <sfx2/docfile.hxx>
33 : #include <sfx2/request.hxx>
34 : #include <sfx2/frame.hxx>
35 : #include <sfx2/sfxsids.hrc>
36 : #include <svl/stritem.hxx>
37 : #include <svl/itemset.hxx>
38 : #include "miscuno.hxx"
39 :
40 : using ::com::sun::star::uno::Any;
41 : using ::com::sun::star::uno::Reference;
42 : using ::com::sun::star::uno::Sequence;
43 : using ::com::sun::star::uno::Exception;
44 : using ::com::sun::star::uno::UNO_QUERY;
45 : using ::com::sun::star::uno::UNO_QUERY_THROW;
46 : using ::com::sun::star::uno::UNO_SET_THROW;
47 : using ::com::sun::star::uno::TypeClass_BOOLEAN;
48 : using ::com::sun::star::uno::XInterface;
49 : using ::com::sun::star::beans::XPropertySet;
50 : using ::com::sun::star::beans::XPropertyState;
51 : using ::com::sun::star::lang::XServiceName;
52 : using ::com::sun::star::lang::XMultiServiceFactory;
53 : using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER;
54 :
55 : using namespace ::com::sun::star;
56 :
57 : // Static helper functions ====================================================
58 :
59 18 : OUString ScfApiHelper::GetServiceName( const Reference< XInterface >& xInt )
60 : {
61 18 : OUString aService;
62 36 : Reference< XServiceName > xServiceName( xInt, UNO_QUERY );
63 18 : if( xServiceName.is() )
64 18 : aService = xServiceName->getServiceName();
65 36 : return aService;
66 : }
67 :
68 107 : Reference< XMultiServiceFactory > ScfApiHelper::GetServiceFactory( SfxObjectShell* pShell )
69 : {
70 107 : Reference< XMultiServiceFactory > xFactory;
71 107 : if( pShell )
72 107 : xFactory.set( pShell->GetModel(), UNO_QUERY );
73 107 : return xFactory;
74 : }
75 :
76 373 : Reference< XInterface > ScfApiHelper::CreateInstance(
77 : const Reference< XMultiServiceFactory >& xFactory, const OUString& rServiceName )
78 : {
79 373 : Reference< XInterface > xInt;
80 373 : if( xFactory.is() )
81 : {
82 : try
83 : {
84 373 : xInt = xFactory->createInstance( rServiceName );
85 : }
86 0 : catch( Exception& )
87 : {
88 : OSL_FAIL( "ScfApiHelper::CreateInstance - cannot create instance" );
89 : }
90 : }
91 373 : return xInt;
92 : }
93 :
94 107 : Reference< XInterface > ScfApiHelper::CreateInstance( SfxObjectShell* pShell, const OUString& rServiceName )
95 : {
96 107 : return CreateInstance( GetServiceFactory( pShell ), rServiceName );
97 : }
98 :
99 266 : Reference< XInterface > ScfApiHelper::CreateInstance( const OUString& rServiceName )
100 : {
101 266 : return CreateInstance( ::comphelper::getProcessServiceFactory(), rServiceName );
102 : }
103 :
104 0 : uno::Sequence< beans::NamedValue > ScfApiHelper::QueryEncryptionDataForMedium( SfxMedium& rMedium,
105 : ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords )
106 : {
107 0 : uno::Sequence< beans::NamedValue > aEncryptionData;
108 0 : SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false);
109 0 : if ( pEncryptionDataItem )
110 0 : pEncryptionDataItem->GetValue() >>= aEncryptionData;
111 :
112 0 : OUString aPassword;
113 0 : SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, false);
114 0 : if ( pPasswordItem )
115 0 : aPassword = pPasswordItem->GetValue();
116 :
117 0 : OUString aDocName = INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET );
118 :
119 0 : bool bIsDefaultPassword = false;
120 0 : aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
121 : rVerifier, aEncryptionData, aPassword, rMedium.GetInteractionHandler(), aDocName,
122 0 : ::comphelper::DocPasswordRequestType_MS, pDefaultPasswords, &bIsDefaultPassword );
123 :
124 0 : rMedium.GetItemSet()->ClearItem( SID_PASSWORD );
125 0 : rMedium.GetItemSet()->ClearItem( SID_ENCRYPTIONDATA );
126 :
127 0 : if( !bIsDefaultPassword && (aEncryptionData.getLength() > 0) )
128 0 : rMedium.GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
129 :
130 0 : return aEncryptionData;
131 : }
132 :
133 : // Property sets ==============================================================
134 :
135 2748 : ScfPropertySet::~ScfPropertySet()
136 : {
137 1374 : Reference<beans::XPropertySetOption> xPropSetOpt(mxPropSet, UNO_QUERY);
138 1374 : if (xPropSetOpt.is())
139 : // Turn the property value change notification back on when finished.
140 99 : xPropSetOpt->enableChangeListenerNotification(true);
141 1374 : }
142 :
143 1374 : void ScfPropertySet::Set( Reference< XPropertySet > xPropSet )
144 : {
145 1374 : mxPropSet = xPropSet;
146 1374 : mxMultiPropSet.set( mxPropSet, UNO_QUERY );
147 1374 : Reference<beans::XPropertySetOption> xPropSetOpt(mxPropSet, UNO_QUERY);
148 1374 : if (xPropSetOpt.is())
149 : // We don't want to broadcast property value changes during import to
150 : // improve performance.
151 99 : xPropSetOpt->enableChangeListenerNotification(false);
152 1374 : }
153 :
154 6 : OUString ScfPropertySet::GetServiceName() const
155 : {
156 6 : return ScfApiHelper::GetServiceName( mxPropSet );
157 : }
158 :
159 : // Get properties -------------------------------------------------------------
160 :
161 0 : bool ScfPropertySet::HasProperty( const OUString& rPropName ) const
162 : {
163 0 : bool bHasProp = false;
164 : try
165 : {
166 0 : Reference< XPropertyState > xPropState( mxPropSet, UNO_QUERY_THROW );
167 0 : bHasProp = xPropState->getPropertyState( rPropName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
168 : }
169 0 : catch( Exception& )
170 : {
171 : }
172 0 : return bHasProp;
173 : }
174 :
175 578 : bool ScfPropertySet::GetAnyProperty( Any& rValue, const OUString& rPropName ) const
176 : {
177 578 : bool bHasValue = false;
178 : try
179 : {
180 578 : if( mxPropSet.is() )
181 : {
182 570 : rValue = mxPropSet->getPropertyValue( rPropName );
183 564 : bHasValue = true;
184 : }
185 : }
186 6 : catch( Exception& )
187 : {
188 : }
189 578 : return bHasValue;
190 : }
191 :
192 187 : bool ScfPropertySet::GetBoolProperty( const OUString& rPropName ) const
193 : {
194 187 : Any aAny;
195 187 : return GetAnyProperty( aAny, rPropName ) && ScUnoHelpFunctions::GetBoolFromAny( aAny );
196 : }
197 :
198 0 : OUString ScfPropertySet::GetStringProperty( const OUString& rPropName ) const
199 : {
200 0 : OUString aOUString;
201 0 : GetProperty( aOUString, rPropName );
202 0 : return aOUString;
203 : }
204 :
205 6 : bool ScfPropertySet::GetColorProperty( Color& rColor, const OUString& rPropName ) const
206 : {
207 6 : sal_Int32 nApiColor = 0;
208 6 : bool bRet = GetProperty( nApiColor, rPropName );
209 6 : rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
210 6 : return bRet;
211 : }
212 :
213 251 : void ScfPropertySet::GetProperties( Sequence< Any >& rValues, const Sequence< OUString >& rPropNames ) const
214 : {
215 : try
216 : {
217 : OSL_ENSURE( mxMultiPropSet.is(), "ScfPropertySet::GetProperties - multi property set not available" );
218 251 : if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
219 : {
220 249 : rValues = mxMultiPropSet->getPropertyValues( rPropNames );
221 : }
222 2 : else if( mxPropSet.is() )
223 : {
224 2 : sal_Int32 nLen = rPropNames.getLength();
225 2 : const OUString* pPropName = rPropNames.getConstArray();
226 2 : const OUString* pPropNameEnd = pPropName + nLen;
227 2 : rValues.realloc( nLen );
228 2 : Any* pValue = rValues.getArray();
229 12 : for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
230 10 : *pValue = mxPropSet->getPropertyValue( *pPropName );
231 : }
232 : }
233 0 : catch( Exception& )
234 : {
235 : }
236 251 : }
237 :
238 : // Set properties -------------------------------------------------------------
239 :
240 2256 : void ScfPropertySet::SetAnyProperty( const OUString& rPropName, const Any& rValue )
241 : {
242 : try
243 : {
244 2256 : if( mxPropSet.is() )
245 2256 : mxPropSet->setPropertyValue( rPropName, rValue );
246 : }
247 0 : catch (const Exception&)
248 : {
249 : OSL_FAIL(OStringBuffer("ScfPropertySet::SetAnyProperty - cannot set property \"")
250 : .append(OUStringToOString(rPropName,
251 : RTL_TEXTENCODING_ASCII_US))
252 : .append('"').getStr());
253 : }
254 2256 : }
255 :
256 1394 : void ScfPropertySet::SetProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
257 : {
258 : OSL_ENSURE( rPropNames.getLength() == rValues.getLength(), "ScfPropertySet::SetProperties - length of sequences different" );
259 : try
260 : {
261 1394 : if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
262 : {
263 1394 : mxMultiPropSet->setPropertyValues( rPropNames, rValues );
264 : }
265 0 : else if( mxPropSet.is() )
266 : {
267 : OSL_FAIL( "ScfPropertySet::SetProperties - multi property set not available" );
268 0 : const OUString* pPropName = rPropNames.getConstArray();
269 0 : const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
270 0 : const Any* pValue = rValues.getConstArray();
271 0 : for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
272 0 : mxPropSet->setPropertyValue( *pPropName, *pValue );
273 : }
274 : }
275 0 : catch( Exception& )
276 : {
277 : OSL_FAIL( "ScfPropertySet::SetAnyProperty - cannot set multiple properties" );
278 : }
279 1394 : }
280 :
281 1634 : ScfPropSetHelper::ScfPropSetHelper( const sal_Char* const* ppcPropNames ) :
282 1634 : mnNextIdx( 0 )
283 : {
284 : OSL_ENSURE( ppcPropNames, "ScfPropSetHelper::ScfPropSetHelper - no strings found" );
285 :
286 : // create OUStrings from ASCII property names
287 : typedef ::std::pair< OUString, size_t > IndexedOUString;
288 : typedef ::std::vector< IndexedOUString > IndexedOUStringVec;
289 1634 : IndexedOUStringVec aPropNameVec;
290 7912 : for( size_t nVecIdx = 0; *ppcPropNames; ++ppcPropNames, ++nVecIdx )
291 : {
292 6278 : OUString aPropName = OUString::createFromAscii( *ppcPropNames );
293 6278 : aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx ) );
294 6278 : }
295 :
296 : // sorts the pairs, which will be sorted by first component (the property name)
297 1634 : ::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
298 :
299 : // resize member sequences
300 1634 : size_t nSize = aPropNameVec.size();
301 1634 : maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
302 1634 : maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
303 1634 : maNameOrder.resize( nSize );
304 :
305 : // fill the property name sequence and store original sort order
306 1634 : sal_Int32 nSeqIdx = 0;
307 9546 : for( IndexedOUStringVec::const_iterator aIt = aPropNameVec.begin(),
308 1634 : aEnd = aPropNameVec.end(); aIt != aEnd; ++aIt, ++nSeqIdx )
309 : {
310 6278 : maNameSeq[ nSeqIdx ] = aIt->first;
311 6278 : maNameOrder[ aIt->second ] = nSeqIdx;
312 1634 : }
313 1634 : }
314 :
315 : // read properties ------------------------------------------------------------
316 :
317 251 : void ScfPropSetHelper::ReadFromPropertySet( const ScfPropertySet& rPropSet )
318 : {
319 251 : rPropSet.GetProperties( maValueSeq, maNameSeq );
320 251 : mnNextIdx = 0;
321 251 : }
322 :
323 130 : bool ScfPropSetHelper::ReadValue( Any& rAny )
324 : {
325 130 : Any* pAny = GetNextAny();
326 130 : if( pAny )
327 130 : rAny = *pAny;
328 130 : return pAny != 0;
329 : }
330 :
331 135 : bool ScfPropSetHelper::ReadValue( Color& rColor )
332 : {
333 135 : sal_Int32 nApiColor(0);
334 135 : bool bRet = ReadValue( nApiColor );
335 135 : rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
336 135 : return bRet;
337 : }
338 :
339 58 : bool ScfPropSetHelper::ReadValue( bool& rbValue )
340 : {
341 58 : Any aAny;
342 58 : bool bRet = ReadValue( aAny );
343 58 : rbValue = ScUnoHelpFunctions::GetBoolFromAny( aAny );
344 58 : return bRet;
345 : }
346 :
347 : // write properties -----------------------------------------------------------
348 :
349 1394 : void ScfPropSetHelper::InitializeWrite( bool bClearAllAnys )
350 : {
351 1394 : mnNextIdx = 0;
352 1394 : if( bClearAllAnys )
353 0 : for( sal_Int32 nIdx = 0, nLen = maValueSeq.getLength(); nIdx < nLen; ++nIdx )
354 0 : maValueSeq[ nIdx ].clear();
355 1394 : }
356 :
357 330 : void ScfPropSetHelper::WriteValue( const Any& rAny )
358 : {
359 330 : if( Any* pAny = GetNextAny() )
360 330 : *pAny = rAny;
361 330 : }
362 :
363 386 : void ScfPropSetHelper::WriteValue( const bool& rbValue )
364 : {
365 386 : if( Any* pAny = GetNextAny() )
366 386 : ScUnoHelpFunctions::SetBoolInAny( *pAny, rbValue );
367 386 : }
368 :
369 1394 : void ScfPropSetHelper::WriteToPropertySet( ScfPropertySet& rPropSet ) const
370 : {
371 1394 : rPropSet.SetProperties( maNameSeq, maValueSeq );
372 1394 : }
373 :
374 : // private --------------------------------------------------------------------
375 :
376 6258 : Any* ScfPropSetHelper::GetNextAny()
377 : {
378 : OSL_ENSURE( mnNextIdx < maNameOrder.size(), "ScfPropSetHelper::GetNextAny - sequence overflow" );
379 6258 : Any* pAny = 0;
380 6258 : if( mnNextIdx < maNameOrder.size() )
381 6258 : pAny = &maValueSeq[ maNameOrder[ mnNextIdx++ ] ];
382 6258 : return pAny;
383 : }
384 :
385 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|