1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scfilt.hxx"
26 #include "fapihelper.hxx"
27
28 #include <algorithm>
29 #include <com/sun/star/lang/XServiceName.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/beans/XPropertyState.hpp>
32 #include <comphelper/docpasswordhelper.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <tools/urlobj.hxx>
35 #include <sfx2/objsh.hxx>
36 #include <sfx2/docfile.hxx>
37 #include <sfx2/request.hxx>
38 #include <sfx2/frame.hxx>
39 #include <sfx2/sfxsids.hrc>
40 #include <svl/stritem.hxx>
41 #include <svl/itemset.hxx>
42 #include "miscuno.hxx"
43
44 using ::rtl::OUString;
45 using ::com::sun::star::uno::Any;
46 using ::com::sun::star::uno::Reference;
47 using ::com::sun::star::uno::Sequence;
48 using ::com::sun::star::uno::Exception;
49 using ::com::sun::star::uno::UNO_QUERY;
50 using ::com::sun::star::uno::UNO_QUERY_THROW;
51 using ::com::sun::star::uno::UNO_SET_THROW;
52 using ::com::sun::star::uno::TypeClass_BOOLEAN;
53 using ::com::sun::star::uno::XInterface;
54 using ::com::sun::star::beans::XPropertySet;
55 using ::com::sun::star::beans::XPropertyState;
56 using ::com::sun::star::lang::XServiceName;
57 using ::com::sun::star::lang::XMultiServiceFactory;
58 using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER;
59
60 using namespace ::com::sun::star;
61
62 // Static helper functions ====================================================
63
GetServiceName(Reference<XInterface> xInt)64 OUString ScfApiHelper::GetServiceName( Reference< XInterface > xInt )
65 {
66 OUString aService;
67 Reference< XServiceName > xServiceName( xInt, UNO_QUERY );
68 if( xServiceName.is() )
69 aService = xServiceName->getServiceName();
70 return aService;
71 }
72
GetServiceFactory(SfxObjectShell * pShell)73 Reference< XMultiServiceFactory > ScfApiHelper::GetServiceFactory( SfxObjectShell* pShell )
74 {
75 Reference< XMultiServiceFactory > xFactory;
76 if( pShell )
77 xFactory.set( pShell->GetModel(), UNO_QUERY );
78 return xFactory;
79 }
80
CreateInstance(Reference<XMultiServiceFactory> xFactory,const OUString & rServiceName)81 Reference< XInterface > ScfApiHelper::CreateInstance(
82 Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName )
83 {
84 Reference< XInterface > xInt;
85 if( xFactory.is() )
86 {
87 try
88 {
89 xInt = xFactory->createInstance( rServiceName );
90 }
91 catch( Exception& )
92 {
93 DBG_ERRORFILE( "ScfApiHelper::CreateInstance - cannot create instance" );
94 }
95 }
96 return xInt;
97 }
98
CreateInstance(SfxObjectShell * pShell,const OUString & rServiceName)99 Reference< XInterface > ScfApiHelper::CreateInstance( SfxObjectShell* pShell, const OUString& rServiceName )
100 {
101 return CreateInstance( GetServiceFactory( pShell ), rServiceName );
102 }
103
CreateInstance(const OUString & rServiceName)104 Reference< XInterface > ScfApiHelper::CreateInstance( const OUString& rServiceName )
105 {
106 return CreateInstance( ::comphelper::getProcessServiceFactory(), rServiceName );
107 }
108
CreateInstanceWithArgs(Reference<XMultiServiceFactory> xFactory,const OUString & rServiceName,const Sequence<Any> & rArgs)109 Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
110 Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName, const Sequence< Any >& rArgs )
111 {
112 Reference< XInterface > xInt;
113 if( xFactory.is() )
114 {
115 try
116 {
117 xInt = xFactory->createInstanceWithArguments( rServiceName, rArgs );
118 }
119 catch( Exception& )
120 {
121 DBG_ERRORFILE( "ScfApiHelper::CreateInstanceWithArgs - cannot create instance" );
122 }
123 }
124 return xInt;
125 }
126
127 //UNUSED2008-05 Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
128 //UNUSED2008-05 SfxObjectShell* pShell, const OUString& rServiceName, const Sequence< Any >& rArgs )
129 //UNUSED2008-05 {
130 //UNUSED2008-05 return CreateInstanceWithArgs( GetServiceFactory( pShell ), rServiceName, rArgs );
131 //UNUSED2008-05 }
132
CreateInstanceWithArgs(const OUString & rServiceName,const Sequence<Any> & rArgs)133 Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
134 const OUString& rServiceName, const Sequence< Any >& rArgs )
135 {
136 return CreateInstanceWithArgs( ::comphelper::getProcessServiceFactory(), rServiceName, rArgs );
137 }
138
QueryEncryptionDataForMedium(SfxMedium & rMedium,::comphelper::IDocPasswordVerifier & rVerifier,const::std::vector<OUString> * pDefaultPasswords)139 uno::Sequence< beans::NamedValue > ScfApiHelper::QueryEncryptionDataForMedium( SfxMedium& rMedium,
140 ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords )
141 {
142 uno::Sequence< beans::NamedValue > aEncryptionData;
143 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False);
144 if ( pEncryptionDataItem )
145 pEncryptionDataItem->GetValue() >>= aEncryptionData;
146
147 ::rtl::OUString aPassword;
148 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
149 if ( pPasswordItem )
150 aPassword = pPasswordItem->GetValue();
151
152 OUString aDocName = INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET );
153
154 bool bIsDefaultPassword = false;
155 aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
156 rVerifier, aEncryptionData, aPassword, rMedium.GetInteractionHandler(), aDocName,
157 ::comphelper::DocPasswordRequestType_MS, pDefaultPasswords, &bIsDefaultPassword );
158
159 rMedium.GetItemSet()->ClearItem( SID_PASSWORD );
160 rMedium.GetItemSet()->ClearItem( SID_ENCRYPTIONDATA );
161
162 if( !bIsDefaultPassword && (aEncryptionData.getLength() > 0) )
163 rMedium.GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
164
165 return aEncryptionData;
166 }
167
168 // Property sets ==============================================================
169
Set(Reference<XPropertySet> xPropSet)170 void ScfPropertySet::Set( Reference< XPropertySet > xPropSet )
171 {
172 mxPropSet = xPropSet;
173 mxMultiPropSet.set( mxPropSet, UNO_QUERY );
174 }
175
GetServiceName() const176 OUString ScfPropertySet::GetServiceName() const
177 {
178 return ScfApiHelper::GetServiceName( mxPropSet );
179 }
180
181 // Get properties -------------------------------------------------------------
182
HasProperty(const OUString & rPropName) const183 bool ScfPropertySet::HasProperty( const OUString& rPropName ) const
184 {
185 bool bHasProp = false;
186 try
187 {
188 Reference< XPropertyState > xPropState( mxPropSet, UNO_QUERY_THROW );
189 bHasProp = xPropState->getPropertyState( rPropName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
190 }
191 catch( Exception& )
192 {
193 }
194 return bHasProp;
195 }
196
GetAnyProperty(Any & rValue,const OUString & rPropName) const197 bool ScfPropertySet::GetAnyProperty( Any& rValue, const OUString& rPropName ) const
198 {
199 bool bHasValue = false;
200 try
201 {
202 if( mxPropSet.is() )
203 {
204 rValue = mxPropSet->getPropertyValue( rPropName );
205 bHasValue = true;
206 }
207 }
208 catch( Exception& )
209 {
210 }
211 return bHasValue;
212 }
213
GetBoolProperty(const::rtl::OUString & rPropName) const214 bool ScfPropertySet::GetBoolProperty( const ::rtl::OUString& rPropName ) const
215 {
216 Any aAny;
217 return GetAnyProperty( aAny, rPropName ) && ScUnoHelpFunctions::GetBoolFromAny( aAny );
218 }
219
GetStringProperty(String & rValue,const OUString & rPropName) const220 bool ScfPropertySet::GetStringProperty( String& rValue, const OUString& rPropName ) const
221 {
222 OUString aOUString;
223 bool bRet = GetProperty( aOUString, rPropName );
224 rValue = aOUString;
225 return bRet;
226 }
227
GetColorProperty(Color & rColor,const::rtl::OUString & rPropName) const228 bool ScfPropertySet::GetColorProperty( Color& rColor, const ::rtl::OUString& rPropName ) const
229 {
230 sal_Int32 nApiColor = 0;
231 bool bRet = GetProperty( nApiColor, rPropName );
232 rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
233 return bRet;
234 }
235
GetProperties(Sequence<Any> & rValues,const Sequence<OUString> & rPropNames) const236 void ScfPropertySet::GetProperties( Sequence< Any >& rValues, const Sequence< OUString >& rPropNames ) const
237 {
238 try
239 {
240 DBG_ASSERT( mxMultiPropSet.is(), "ScfPropertySet::GetProperties - multi property set not available" );
241 if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
242 {
243 rValues = mxMultiPropSet->getPropertyValues( rPropNames );
244 }
245 else if( mxPropSet.is() )
246 {
247 sal_Int32 nLen = rPropNames.getLength();
248 const OUString* pPropName = rPropNames.getConstArray();
249 const OUString* pPropNameEnd = pPropName + nLen;
250 rValues.realloc( nLen );
251 Any* pValue = rValues.getArray();
252 for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
253 *pValue = mxPropSet->getPropertyValue( *pPropName );
254 }
255 }
256 catch( Exception& )
257 {
258 }
259 }
260
261 // Set properties -------------------------------------------------------------
262
SetAnyProperty(const OUString & rPropName,const Any & rValue)263 void ScfPropertySet::SetAnyProperty( const OUString& rPropName, const Any& rValue )
264 {
265 try
266 {
267 if( mxPropSet.is() )
268 mxPropSet->setPropertyValue( rPropName, rValue );
269 }
270 catch( Exception& )
271 {
272 DBG_ERRORFILE(
273 ByteString( "ScfPropertySet::SetAnyProperty - cannot set property \"" ).
274 Append( ByteString( String( rPropName ), RTL_TEXTENCODING_ASCII_US ) ).
275 Append( '"' ).
276 GetBuffer() );
277 }
278 }
279
SetProperties(const Sequence<OUString> & rPropNames,const Sequence<Any> & rValues)280 void ScfPropertySet::SetProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
281 {
282 DBG_ASSERT( rPropNames.getLength() == rValues.getLength(), "ScfPropertySet::SetProperties - length of sequences different" );
283 try
284 {
285 if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
286 {
287 mxMultiPropSet->setPropertyValues( rPropNames, rValues );
288 }
289 else if( mxPropSet.is() )
290 {
291 DBG_ERRORFILE( "ScfPropertySet::SetProperties - multi property set not available" );
292 const OUString* pPropName = rPropNames.getConstArray();
293 const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
294 const Any* pValue = rValues.getConstArray();
295 for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
296 mxPropSet->setPropertyValue( *pPropName, *pValue );
297 }
298 }
299 catch( Exception& )
300 {
301 DBG_ERRORFILE( "ScfPropertySet::SetAnyProperty - cannot set multiple properties" );
302 }
303 }
304
305 // ============================================================================
306
ScfPropSetHelper(const sal_Char * const * ppcPropNames)307 ScfPropSetHelper::ScfPropSetHelper( const sal_Char* const* ppcPropNames ) :
308 mnNextIdx( 0 )
309 {
310 DBG_ASSERT( ppcPropNames, "ScfPropSetHelper::ScfPropSetHelper - no strings found" );
311
312 // create OUStrings from ASCII property names
313 typedef ::std::pair< OUString, size_t > IndexedOUString;
314 typedef ::std::vector< IndexedOUString > IndexedOUStringVec;
315 IndexedOUStringVec aPropNameVec;
316 for( size_t nVecIdx = 0; *ppcPropNames; ++ppcPropNames, ++nVecIdx )
317 {
318 OUString aPropName = OUString::createFromAscii( *ppcPropNames );
319 aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx ) );
320 }
321
322 // sorts the pairs, which will be sorted by first component (the property name)
323 ::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
324
325 // resize member sequences
326 size_t nSize = aPropNameVec.size();
327 maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
328 maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
329 maNameOrder.resize( nSize );
330
331 // fill the property name sequence and store original sort order
332 sal_Int32 nSeqIdx = 0;
333 for( IndexedOUStringVec::const_iterator aIt = aPropNameVec.begin(),
334 aEnd = aPropNameVec.end(); aIt != aEnd; ++aIt, ++nSeqIdx )
335 {
336 maNameSeq[ nSeqIdx ] = aIt->first;
337 maNameOrder[ aIt->second ] = nSeqIdx;
338 }
339 }
340
341 // read properties ------------------------------------------------------------
342
ReadFromPropertySet(const ScfPropertySet & rPropSet)343 void ScfPropSetHelper::ReadFromPropertySet( const ScfPropertySet& rPropSet )
344 {
345 rPropSet.GetProperties( maValueSeq, maNameSeq );
346 mnNextIdx = 0;
347 }
348
ReadValue(UnoAny & rAny)349 bool ScfPropSetHelper::ReadValue( UnoAny& rAny )
350 {
351 UnoAny* pAny = GetNextAny();
352 if( pAny )
353 rAny = *pAny;
354 return pAny != 0;
355 }
356
ReadValue(String & rString)357 bool ScfPropSetHelper::ReadValue( String& rString )
358 {
359 OUString aOUString;
360 bool bRet = ReadValue( aOUString );
361 rString = aOUString;
362 return bRet;
363 }
364
ReadValue(Color & rColor)365 bool ScfPropSetHelper::ReadValue( Color& rColor )
366 {
367 sal_Int32 nApiColor(0);
368 bool bRet = ReadValue( nApiColor );
369 rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
370 return bRet;
371 }
372
ReadValue(bool & rbValue)373 bool ScfPropSetHelper::ReadValue( bool& rbValue )
374 {
375 Any aAny;
376 bool bRet = ReadValue( aAny );
377 rbValue = ScUnoHelpFunctions::GetBoolFromAny( aAny );
378 return bRet;
379 }
380
381 // write properties -----------------------------------------------------------
382
InitializeWrite(bool bClearAllAnys)383 void ScfPropSetHelper::InitializeWrite( bool bClearAllAnys )
384 {
385 mnNextIdx = 0;
386 if( bClearAllAnys )
387 for( sal_Int32 nIdx = 0, nLen = maValueSeq.getLength(); nIdx < nLen; ++nIdx )
388 maValueSeq[ nIdx ].clear();
389 }
390
WriteValue(const Any & rAny)391 void ScfPropSetHelper::WriteValue( const Any& rAny )
392 {
393 if( UnoAny* pAny = GetNextAny() )
394 *pAny = rAny;
395 }
396
WriteValue(const bool & rbValue)397 void ScfPropSetHelper::WriteValue( const bool& rbValue )
398 {
399 if( Any* pAny = GetNextAny() )
400 ScUnoHelpFunctions::SetBoolInAny( *pAny, rbValue );
401 }
402
WriteToPropertySet(ScfPropertySet & rPropSet) const403 void ScfPropSetHelper::WriteToPropertySet( ScfPropertySet& rPropSet ) const
404 {
405 rPropSet.SetProperties( maNameSeq, maValueSeq );
406 }
407
408 // private --------------------------------------------------------------------
409
GetNextAny()410 Any* ScfPropSetHelper::GetNextAny()
411 {
412 DBG_ASSERT( mnNextIdx < maNameOrder.size(), "ScfPropSetHelper::GetNextAny - sequence overflow" );
413 Any* pAny = 0;
414 if( mnNextIdx < maNameOrder.size() )
415 pAny = &maValueSeq[ maNameOrder[ mnNextIdx++ ] ];
416 return pAny;
417 }
418
419 // ============================================================================
420
421