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 0 : OUString ScfApiHelper::GetServiceName( const Reference< XInterface >& xInt )
60 : {
61 0 : OUString aService;
62 0 : Reference< XServiceName > xServiceName( xInt, UNO_QUERY );
63 0 : if( xServiceName.is() )
64 0 : aService = xServiceName->getServiceName();
65 0 : return aService;
66 : }
67 :
68 0 : Reference< XMultiServiceFactory > ScfApiHelper::GetServiceFactory( SfxObjectShell* pShell )
69 : {
70 0 : Reference< XMultiServiceFactory > xFactory;
71 0 : if( pShell )
72 0 : xFactory.set( pShell->GetModel(), UNO_QUERY );
73 0 : return xFactory;
74 : }
75 :
76 0 : Reference< XInterface > ScfApiHelper::CreateInstance(
77 : const Reference< XMultiServiceFactory >& xFactory, const OUString& rServiceName )
78 : {
79 0 : Reference< XInterface > xInt;
80 0 : if( xFactory.is() )
81 : {
82 : try
83 : {
84 0 : xInt = xFactory->createInstance( rServiceName );
85 : }
86 0 : catch( Exception& )
87 : {
88 : OSL_FAIL( "ScfApiHelper::CreateInstance - cannot create instance" );
89 : }
90 : }
91 0 : return xInt;
92 : }
93 :
94 0 : Reference< XInterface > ScfApiHelper::CreateInstance( SfxObjectShell* pShell, const OUString& rServiceName )
95 : {
96 0 : return CreateInstance( GetServiceFactory( pShell ), rServiceName );
97 : }
98 :
99 0 : Reference< XInterface > ScfApiHelper::CreateInstance( const OUString& rServiceName )
100 : {
101 0 : 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 0 : ScfPropertySet::~ScfPropertySet()
136 : {
137 0 : Reference<beans::XPropertySetOption> xPropSetOpt(mxPropSet, UNO_QUERY);
138 0 : if (xPropSetOpt.is())
139 : // Turn the property value change notification back on when finished.
140 0 : xPropSetOpt->enableChangeListenerNotification(true);
141 0 : }
142 :
143 0 : void ScfPropertySet::Set( Reference< XPropertySet > xPropSet )
144 : {
145 0 : mxPropSet = xPropSet;
146 0 : mxMultiPropSet.set( mxPropSet, UNO_QUERY );
147 0 : Reference<beans::XPropertySetOption> xPropSetOpt(mxPropSet, UNO_QUERY);
148 0 : if (xPropSetOpt.is())
149 : // We don't want to broadcast property value changes during import to
150 : // improve performance.
151 0 : xPropSetOpt->enableChangeListenerNotification(false);
152 0 : }
153 :
154 0 : OUString ScfPropertySet::GetServiceName() const
155 : {
156 0 : 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 0 : bool ScfPropertySet::GetAnyProperty( Any& rValue, const OUString& rPropName ) const
176 : {
177 0 : bool bHasValue = false;
178 : try
179 : {
180 0 : if( mxPropSet.is() )
181 : {
182 0 : rValue = mxPropSet->getPropertyValue( rPropName );
183 0 : bHasValue = true;
184 : }
185 : }
186 0 : catch( Exception& )
187 : {
188 : }
189 0 : return bHasValue;
190 : }
191 :
192 0 : bool ScfPropertySet::GetBoolProperty( const OUString& rPropName ) const
193 : {
194 0 : Any aAny;
195 0 : 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 0 : bool ScfPropertySet::GetColorProperty( Color& rColor, const OUString& rPropName ) const
206 : {
207 0 : sal_Int32 nApiColor = 0;
208 0 : bool bRet = GetProperty( nApiColor, rPropName );
209 0 : rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
210 0 : return bRet;
211 : }
212 :
213 0 : 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 0 : if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
219 : {
220 0 : rValues = mxMultiPropSet->getPropertyValues( rPropNames );
221 : }
222 0 : else if( mxPropSet.is() )
223 : {
224 0 : sal_Int32 nLen = rPropNames.getLength();
225 0 : const OUString* pPropName = rPropNames.getConstArray();
226 0 : const OUString* pPropNameEnd = pPropName + nLen;
227 0 : rValues.realloc( nLen );
228 0 : Any* pValue = rValues.getArray();
229 0 : for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
230 0 : *pValue = mxPropSet->getPropertyValue( *pPropName );
231 : }
232 : }
233 0 : catch( Exception& )
234 : {
235 : }
236 0 : }
237 :
238 : // Set properties -------------------------------------------------------------
239 :
240 0 : void ScfPropertySet::SetAnyProperty( const OUString& rPropName, const Any& rValue )
241 : {
242 : try
243 : {
244 0 : if( mxPropSet.is() )
245 0 : 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 0 : }
255 :
256 0 : 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 0 : if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
262 : {
263 0 : 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 0 : }
280 :
281 0 : ScfPropSetHelper::ScfPropSetHelper( const sal_Char* const* ppcPropNames ) :
282 0 : 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 0 : IndexedOUStringVec aPropNameVec;
290 0 : for( size_t nVecIdx = 0; *ppcPropNames; ++ppcPropNames, ++nVecIdx )
291 : {
292 0 : OUString aPropName = OUString::createFromAscii( *ppcPropNames );
293 0 : aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx ) );
294 0 : }
295 :
296 : // sorts the pairs, which will be sorted by first component (the property name)
297 0 : ::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
298 :
299 : // resize member sequences
300 0 : size_t nSize = aPropNameVec.size();
301 0 : maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
302 0 : maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
303 0 : maNameOrder.resize( nSize );
304 :
305 : // fill the property name sequence and store original sort order
306 0 : sal_Int32 nSeqIdx = 0;
307 0 : for( IndexedOUStringVec::const_iterator aIt = aPropNameVec.begin(),
308 0 : aEnd = aPropNameVec.end(); aIt != aEnd; ++aIt, ++nSeqIdx )
309 : {
310 0 : maNameSeq[ nSeqIdx ] = aIt->first;
311 0 : maNameOrder[ aIt->second ] = nSeqIdx;
312 0 : }
313 0 : }
314 :
315 : // read properties ------------------------------------------------------------
316 :
317 0 : void ScfPropSetHelper::ReadFromPropertySet( const ScfPropertySet& rPropSet )
318 : {
319 0 : rPropSet.GetProperties( maValueSeq, maNameSeq );
320 0 : mnNextIdx = 0;
321 0 : }
322 :
323 0 : bool ScfPropSetHelper::ReadValue( Any& rAny )
324 : {
325 0 : Any* pAny = GetNextAny();
326 0 : if( pAny )
327 0 : rAny = *pAny;
328 0 : return pAny != 0;
329 : }
330 :
331 0 : bool ScfPropSetHelper::ReadValue( Color& rColor )
332 : {
333 0 : sal_Int32 nApiColor(0);
334 0 : bool bRet = ReadValue( nApiColor );
335 0 : rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
336 0 : return bRet;
337 : }
338 :
339 0 : bool ScfPropSetHelper::ReadValue( bool& rbValue )
340 : {
341 0 : Any aAny;
342 0 : bool bRet = ReadValue( aAny );
343 0 : rbValue = ScUnoHelpFunctions::GetBoolFromAny( aAny );
344 0 : return bRet;
345 : }
346 :
347 : // write properties -----------------------------------------------------------
348 :
349 0 : void ScfPropSetHelper::InitializeWrite( bool bClearAllAnys )
350 : {
351 0 : mnNextIdx = 0;
352 0 : if( bClearAllAnys )
353 0 : for( sal_Int32 nIdx = 0, nLen = maValueSeq.getLength(); nIdx < nLen; ++nIdx )
354 0 : maValueSeq[ nIdx ].clear();
355 0 : }
356 :
357 0 : void ScfPropSetHelper::WriteValue( const Any& rAny )
358 : {
359 0 : if( Any* pAny = GetNextAny() )
360 0 : *pAny = rAny;
361 0 : }
362 :
363 0 : void ScfPropSetHelper::WriteValue( const bool& rbValue )
364 : {
365 0 : if( Any* pAny = GetNextAny() )
366 0 : ScUnoHelpFunctions::SetBoolInAny( *pAny, rbValue );
367 0 : }
368 :
369 0 : void ScfPropSetHelper::WriteToPropertySet( ScfPropertySet& rPropSet ) const
370 : {
371 0 : rPropSet.SetProperties( maNameSeq, maValueSeq );
372 0 : }
373 :
374 : // private --------------------------------------------------------------------
375 :
376 0 : Any* ScfPropSetHelper::GetNextAny()
377 : {
378 : OSL_ENSURE( mnNextIdx < maNameOrder.size(), "ScfPropSetHelper::GetNextAny - sequence overflow" );
379 0 : Any* pAny = 0;
380 0 : if( mnNextIdx < maNameOrder.size() )
381 0 : pAny = &maValueSeq[ maNameOrder[ mnNextIdx++ ] ];
382 0 : return pAny;
383 : }
384 :
385 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|