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