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