blob: 02071c23dbf03fd7219a7374eaf58f296ae42623 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include "fapihelper.hxx"
#include <algorithm>
#include <com/sun/star/lang/XServiceName.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
#include <comphelper/docpasswordhelper.hxx>
#include <comphelper/processfactory.hxx>
#include <tools/urlobj.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/request.hxx>
#include <sfx2/frame.hxx>
#include <sfx2/sfxsids.hrc>
#include <svl/stritem.hxx>
#include <svl/itemset.hxx>
#include "miscuno.hxx"
using ::rtl::OUString;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::UNO_SET_THROW;
using ::com::sun::star::uno::TypeClass_BOOLEAN;
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::beans::XPropertyState;
using ::com::sun::star::lang::XServiceName;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER;
using namespace ::com::sun::star;
// Static helper functions ====================================================
OUString ScfApiHelper::GetServiceName( Reference< XInterface > xInt )
{
OUString aService;
Reference< XServiceName > xServiceName( xInt, UNO_QUERY );
if( xServiceName.is() )
aService = xServiceName->getServiceName();
return aService;
}
Reference< XMultiServiceFactory > ScfApiHelper::GetServiceFactory( SfxObjectShell* pShell )
{
Reference< XMultiServiceFactory > xFactory;
if( pShell )
xFactory.set( pShell->GetModel(), UNO_QUERY );
return xFactory;
}
Reference< XInterface > ScfApiHelper::CreateInstance(
Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName )
{
Reference< XInterface > xInt;
if( xFactory.is() )
{
try
{
xInt = xFactory->createInstance( rServiceName );
}
catch( Exception& )
{
DBG_ERRORFILE( "ScfApiHelper::CreateInstance - cannot create instance" );
}
}
return xInt;
}
Reference< XInterface > ScfApiHelper::CreateInstance( SfxObjectShell* pShell, const OUString& rServiceName )
{
return CreateInstance( GetServiceFactory( pShell ), rServiceName );
}
Reference< XInterface > ScfApiHelper::CreateInstance( const OUString& rServiceName )
{
return CreateInstance( ::comphelper::getProcessServiceFactory(), rServiceName );
}
Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName, const Sequence< Any >& rArgs )
{
Reference< XInterface > xInt;
if( xFactory.is() )
{
try
{
xInt = xFactory->createInstanceWithArguments( rServiceName, rArgs );
}
catch( Exception& )
{
DBG_ERRORFILE( "ScfApiHelper::CreateInstanceWithArgs - cannot create instance" );
}
}
return xInt;
}
//UNUSED2008-05 Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
//UNUSED2008-05 SfxObjectShell* pShell, const OUString& rServiceName, const Sequence< Any >& rArgs )
//UNUSED2008-05 {
//UNUSED2008-05 return CreateInstanceWithArgs( GetServiceFactory( pShell ), rServiceName, rArgs );
//UNUSED2008-05 }
Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
const OUString& rServiceName, const Sequence< Any >& rArgs )
{
return CreateInstanceWithArgs( ::comphelper::getProcessServiceFactory(), rServiceName, rArgs );
}
uno::Sequence< beans::NamedValue > ScfApiHelper::QueryEncryptionDataForMedium( SfxMedium& rMedium,
::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords )
{
uno::Sequence< beans::NamedValue > aEncryptionData;
SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False);
if ( pEncryptionDataItem )
pEncryptionDataItem->GetValue() >>= aEncryptionData;
::rtl::OUString aPassword;
SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
if ( pPasswordItem )
aPassword = pPasswordItem->GetValue();
OUString aDocName = INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET );
bool bIsDefaultPassword = false;
aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
rVerifier, aEncryptionData, aPassword, rMedium.GetInteractionHandler(), aDocName,
::comphelper::DocPasswordRequestType_MS, pDefaultPasswords, &bIsDefaultPassword );
rMedium.GetItemSet()->ClearItem( SID_PASSWORD );
rMedium.GetItemSet()->ClearItem( SID_ENCRYPTIONDATA );
if( !bIsDefaultPassword && (aEncryptionData.getLength() > 0) )
rMedium.GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
return aEncryptionData;
}
// Property sets ==============================================================
void ScfPropertySet::Set( Reference< XPropertySet > xPropSet )
{
mxPropSet = xPropSet;
mxMultiPropSet.set( mxPropSet, UNO_QUERY );
}
OUString ScfPropertySet::GetServiceName() const
{
return ScfApiHelper::GetServiceName( mxPropSet );
}
// Get properties -------------------------------------------------------------
bool ScfPropertySet::HasProperty( const OUString& rPropName ) const
{
bool bHasProp = false;
try
{
Reference< XPropertyState > xPropState( mxPropSet, UNO_QUERY_THROW );
bHasProp = xPropState->getPropertyState( rPropName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
}
catch( Exception& )
{
}
return bHasProp;
}
bool ScfPropertySet::GetAnyProperty( Any& rValue, const OUString& rPropName ) const
{
bool bHasValue = false;
try
{
if( mxPropSet.is() )
{
rValue = mxPropSet->getPropertyValue( rPropName );
bHasValue = true;
}
}
catch( Exception& )
{
}
return bHasValue;
}
bool ScfPropertySet::GetBoolProperty( const ::rtl::OUString& rPropName ) const
{
Any aAny;
return GetAnyProperty( aAny, rPropName ) && ScUnoHelpFunctions::GetBoolFromAny( aAny );
}
bool ScfPropertySet::GetStringProperty( String& rValue, const OUString& rPropName ) const
{
OUString aOUString;
bool bRet = GetProperty( aOUString, rPropName );
rValue = aOUString;
return bRet;
}
bool ScfPropertySet::GetColorProperty( Color& rColor, const ::rtl::OUString& rPropName ) const
{
sal_Int32 nApiColor = 0;
bool bRet = GetProperty( nApiColor, rPropName );
rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
return bRet;
}
void ScfPropertySet::GetProperties( Sequence< Any >& rValues, const Sequence< OUString >& rPropNames ) const
{
try
{
DBG_ASSERT( mxMultiPropSet.is(), "ScfPropertySet::GetProperties - multi property set not available" );
if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
{
rValues = mxMultiPropSet->getPropertyValues( rPropNames );
}
else if( mxPropSet.is() )
{
sal_Int32 nLen = rPropNames.getLength();
const OUString* pPropName = rPropNames.getConstArray();
const OUString* pPropNameEnd = pPropName + nLen;
rValues.realloc( nLen );
Any* pValue = rValues.getArray();
for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
*pValue = mxPropSet->getPropertyValue( *pPropName );
}
}
catch( Exception& )
{
}
}
// Set properties -------------------------------------------------------------
void ScfPropertySet::SetAnyProperty( const OUString& rPropName, const Any& rValue )
{
try
{
if( mxPropSet.is() )
mxPropSet->setPropertyValue( rPropName, rValue );
}
catch( Exception& )
{
DBG_ERRORFILE(
ByteString( "ScfPropertySet::SetAnyProperty - cannot set property \"" ).
Append( ByteString( String( rPropName ), RTL_TEXTENCODING_ASCII_US ) ).
Append( '"' ).
GetBuffer() );
}
}
void ScfPropertySet::SetProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
{
DBG_ASSERT( rPropNames.getLength() == rValues.getLength(), "ScfPropertySet::SetProperties - length of sequences different" );
try
{
if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
{
mxMultiPropSet->setPropertyValues( rPropNames, rValues );
}
else if( mxPropSet.is() )
{
DBG_ERRORFILE( "ScfPropertySet::SetProperties - multi property set not available" );
const OUString* pPropName = rPropNames.getConstArray();
const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
const Any* pValue = rValues.getConstArray();
for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
mxPropSet->setPropertyValue( *pPropName, *pValue );
}
}
catch( Exception& )
{
DBG_ERRORFILE( "ScfPropertySet::SetAnyProperty - cannot set multiple properties" );
}
}
// ============================================================================
ScfPropSetHelper::ScfPropSetHelper( const sal_Char* const* ppcPropNames ) :
mnNextIdx( 0 )
{
DBG_ASSERT( ppcPropNames, "ScfPropSetHelper::ScfPropSetHelper - no strings found" );
// create OUStrings from ASCII property names
typedef ::std::pair< OUString, size_t > IndexedOUString;
typedef ::std::vector< IndexedOUString > IndexedOUStringVec;
IndexedOUStringVec aPropNameVec;
for( size_t nVecIdx = 0; *ppcPropNames; ++ppcPropNames, ++nVecIdx )
{
OUString aPropName = OUString::createFromAscii( *ppcPropNames );
aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx ) );
}
// sorts the pairs, which will be sorted by first component (the property name)
::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
// resize member sequences
size_t nSize = aPropNameVec.size();
maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
maNameOrder.resize( nSize );
// fill the property name sequence and store original sort order
sal_Int32 nSeqIdx = 0;
for( IndexedOUStringVec::const_iterator aIt = aPropNameVec.begin(),
aEnd = aPropNameVec.end(); aIt != aEnd; ++aIt, ++nSeqIdx )
{
maNameSeq[ nSeqIdx ] = aIt->first;
maNameOrder[ aIt->second ] = nSeqIdx;
}
}
// read properties ------------------------------------------------------------
void ScfPropSetHelper::ReadFromPropertySet( const ScfPropertySet& rPropSet )
{
rPropSet.GetProperties( maValueSeq, maNameSeq );
mnNextIdx = 0;
}
bool ScfPropSetHelper::ReadValue( UnoAny& rAny )
{
UnoAny* pAny = GetNextAny();
if( pAny )
rAny = *pAny;
return pAny != 0;
}
bool ScfPropSetHelper::ReadValue( String& rString )
{
OUString aOUString;
bool bRet = ReadValue( aOUString );
rString = aOUString;
return bRet;
}
bool ScfPropSetHelper::ReadValue( Color& rColor )
{
sal_Int32 nApiColor(0);
bool bRet = ReadValue( nApiColor );
rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
return bRet;
}
bool ScfPropSetHelper::ReadValue( bool& rbValue )
{
Any aAny;
bool bRet = ReadValue( aAny );
rbValue = ScUnoHelpFunctions::GetBoolFromAny( aAny );
return bRet;
}
// write properties -----------------------------------------------------------
void ScfPropSetHelper::InitializeWrite( bool bClearAllAnys )
{
mnNextIdx = 0;
if( bClearAllAnys )
for( sal_Int32 nIdx = 0, nLen = maValueSeq.getLength(); nIdx < nLen; ++nIdx )
maValueSeq[ nIdx ].clear();
}
void ScfPropSetHelper::WriteValue( const Any& rAny )
{
if( UnoAny* pAny = GetNextAny() )
*pAny = rAny;
}
void ScfPropSetHelper::WriteValue( const bool& rbValue )
{
if( Any* pAny = GetNextAny() )
ScUnoHelpFunctions::SetBoolInAny( *pAny, rbValue );
}
void ScfPropSetHelper::WriteToPropertySet( ScfPropertySet& rPropSet ) const
{
rPropSet.SetProperties( maNameSeq, maValueSeq );
}
// private --------------------------------------------------------------------
Any* ScfPropSetHelper::GetNextAny()
{
DBG_ASSERT( mnNextIdx < maNameOrder.size(), "ScfPropSetHelper::GetNextAny - sequence overflow" );
Any* pAny = 0;
if( mnNextIdx < maNameOrder.size() )
pAny = &maValueSeq[ maNameOrder[ mnNextIdx++ ] ];
return pAny;
}
// ============================================================================