diff options
Diffstat (limited to 'unotools/source')
88 files changed, 45485 insertions, 0 deletions
diff --git a/unotools/source/accessibility/accessiblerelationsethelper.cxx b/unotools/source/accessibility/accessiblerelationsethelper.cxx new file mode 100644 index 000000000000..60e807ee9320 --- /dev/null +++ b/unotools/source/accessibility/accessiblerelationsethelper.cxx @@ -0,0 +1,272 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + + +#include "unotools/accessiblerelationsethelper.hxx" +#include <rtl/uuid.h> +#include <vector> +#include <comphelper/sequence.hxx> + +using namespace ::utl; +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +class AccessibleRelationSetHelperImpl +{ +public: + AccessibleRelationSetHelperImpl(); + AccessibleRelationSetHelperImpl(const AccessibleRelationSetHelperImpl& rImpl); + ~AccessibleRelationSetHelperImpl(); + + sal_Int32 getRelationCount( ) + throw (uno::RuntimeException); + AccessibleRelation getRelation( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, + uno::RuntimeException); + sal_Bool containsRelation( sal_Int16 aRelationType ) + throw (uno::RuntimeException); + AccessibleRelation getRelationByType( sal_Int16 aRelationType ) + throw (uno::RuntimeException); + void AddRelation(const AccessibleRelation& rRelation) + throw (uno::RuntimeException); + +private: + std::vector<AccessibleRelation> maRelations; +}; + +AccessibleRelationSetHelperImpl::AccessibleRelationSetHelperImpl() +{ +} + +AccessibleRelationSetHelperImpl::AccessibleRelationSetHelperImpl(const AccessibleRelationSetHelperImpl& rImpl) + : maRelations(rImpl.maRelations) +{ +} + +AccessibleRelationSetHelperImpl::~AccessibleRelationSetHelperImpl() +{ +} + +sal_Int32 AccessibleRelationSetHelperImpl::getRelationCount( ) + throw (uno::RuntimeException) +{ + return maRelations.size(); +} + +AccessibleRelation AccessibleRelationSetHelperImpl::getRelation( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, + uno::RuntimeException) +{ + if ((nIndex < 0) || (static_cast<sal_uInt32>(nIndex) >= maRelations.size())) + throw lang::IndexOutOfBoundsException(); + return maRelations[nIndex]; +} + +sal_Bool AccessibleRelationSetHelperImpl::containsRelation( sal_Int16 aRelationType ) + throw (uno::RuntimeException) +{ + AccessibleRelation defaultRelation; // default is INVALID + AccessibleRelation relationByType = getRelationByType(aRelationType); + return relationByType.RelationType != defaultRelation.RelationType; +} + +AccessibleRelation AccessibleRelationSetHelperImpl::getRelationByType( sal_Int16 aRelationType ) + throw (uno::RuntimeException) +{ + sal_Int32 nCount(getRelationCount()); + sal_Int32 i(0); + sal_Bool bFound(sal_False); + while ((i < nCount) && !bFound) + { + if (maRelations[i].RelationType == aRelationType) + return maRelations[i]; + else + i++; + } + return AccessibleRelation(); +} + +void AccessibleRelationSetHelperImpl::AddRelation(const AccessibleRelation& rRelation) + throw (uno::RuntimeException) +{ + sal_Int32 nCount(getRelationCount()); + sal_Int32 i(0); + sal_Bool bFound(sal_False); + while ((i < nCount) && !bFound) + { + if (maRelations[i].RelationType == rRelation.RelationType) + bFound = sal_True; + else + i++; + } + if (bFound) + maRelations[i].TargetSet = comphelper::concatSequences(maRelations[i].TargetSet, rRelation.TargetSet); + else + maRelations.push_back(rRelation); +} + +//===== internal ============================================================ + +AccessibleRelationSetHelper::AccessibleRelationSetHelper () + : mpHelperImpl(NULL) +{ + mpHelperImpl = new AccessibleRelationSetHelperImpl(); +} + +AccessibleRelationSetHelper::AccessibleRelationSetHelper (const AccessibleRelationSetHelper& rHelper) + : cppu::WeakImplHelper1<XAccessibleRelationSet>() + , mpHelperImpl(NULL) +{ + if (rHelper.mpHelperImpl) + mpHelperImpl = new AccessibleRelationSetHelperImpl(*rHelper.mpHelperImpl); + else + mpHelperImpl = new AccessibleRelationSetHelperImpl(); +} + +AccessibleRelationSetHelper::~AccessibleRelationSetHelper(void) +{ + delete mpHelperImpl; +} + +//===== XAccessibleRelationSet ============================================== + + /** Returns the number of relations in this relation set. + + @return + Returns the number of relations or zero if there are none. + */ +sal_Int32 SAL_CALL + AccessibleRelationSetHelper::getRelationCount( ) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + return mpHelperImpl->getRelationCount(); +} + + /** Returns the relation of this relation set that is specified by + the given index. + + @param nIndex + This index specifies the relatio to return. + + @return + For a valid index, i.e. inside the range 0 to the number of + relations minus one, the returned value is the requested + relation. If the index is invalid then the returned relation + has the type INVALID. + + */ + AccessibleRelation SAL_CALL + AccessibleRelationSetHelper::getRelation( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, + uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + return mpHelperImpl->getRelation(nIndex); +} + + /** Tests whether the relation set contains a relation matching the + specified key. + + @param aRelationType + The type of relation to look for in this set of relations. This + has to be one of the constants of + <type>AccessibleRelationType</type>. + + @return + Returns <TRUE/> if there is a (at least one) relation of the + given type and <FALSE/> if there is no such relation in the set. + */ +sal_Bool SAL_CALL + AccessibleRelationSetHelper::containsRelation( sal_Int16 aRelationType ) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + return mpHelperImpl->containsRelation(aRelationType); +} + + /** Retrieve and return the relation with the given relation type. + + @param aRelationType + The type of the relation to return. This has to be one of the + constants of <type>AccessibleRelationType</type>. + + @return + If a relation with the given type could be found than (a copy + of) this relation is returned. Otherwise a relation with the + type INVALID is returned. + */ +AccessibleRelation SAL_CALL + AccessibleRelationSetHelper::getRelationByType( sal_Int16 aRelationType ) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + return mpHelperImpl->getRelationByType(aRelationType); +} + +void AccessibleRelationSetHelper::AddRelation(const AccessibleRelation& rRelation) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + mpHelperImpl->AddRelation(rRelation); +} + +//===== XTypeProvider ======================================================= + +uno::Sequence< ::com::sun::star::uno::Type> + AccessibleRelationSetHelper::getTypes (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + const ::com::sun::star::uno::Type aTypeList[] = { + ::getCppuType((const uno::Reference< + XAccessibleRelationSet>*)0), + ::getCppuType((const uno::Reference< + lang::XTypeProvider>*)0) + }; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> + aTypeSequence (aTypeList, 2); + return aTypeSequence; +} + +uno::Sequence<sal_Int8> SAL_CALL + AccessibleRelationSetHelper::getImplementationId (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + static uno::Sequence<sal_Int8> aId; + if (aId.getLength() == 0) + { + aId.realloc (16); + rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True); + } + return aId; +} diff --git a/unotools/source/accessibility/accessiblestatesethelper.cxx b/unotools/source/accessibility/accessiblestatesethelper.cxx new file mode 100644 index 000000000000..be7bf3fbeb28 --- /dev/null +++ b/unotools/source/accessibility/accessiblestatesethelper.cxx @@ -0,0 +1,346 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + + +#include "unotools/accessiblestatesethelper.hxx" +#include <rtl/uuid.h> +#include <tools/debug.hxx> + +#if 0 +#include <bitset> +#endif + +// defines how many states the bitfield can contain +// it has the size of 64 because I use a uInt64 +#define BITFIELDSIZE 64 + +using namespace ::utl; +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +class AccessibleStateSetHelperImpl +{ +public: + AccessibleStateSetHelperImpl(); + AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl); + ~AccessibleStateSetHelperImpl(); + + sal_Bool IsEmpty () + throw (uno::RuntimeException); + sal_Bool Contains (sal_Int16 aState) + throw (uno::RuntimeException); + uno::Sequence<sal_Int16> GetStates() + throw (uno::RuntimeException); + void AddState(sal_Int16 aState) + throw (uno::RuntimeException); + void RemoveState(sal_Int16 aState) + throw (uno::RuntimeException); + sal_Bool Compare(const AccessibleStateSetHelperImpl* pComparativeValue, + AccessibleStateSetHelperImpl* pOldStates, + AccessibleStateSetHelperImpl* pNewStates) + throw (uno::RuntimeException); + + inline void AddStates( const sal_Int64 _nStates ) SAL_THROW( ( ) ); + +private: +#if 0 + ::std::bitset<BITFIELDSIZE> maStates; //Bitfield +#endif + sal_uInt64 maStates; +}; + +AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl() + : maStates(0) +{ +} + +AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl) + : maStates(rImpl.maStates) +{ +} + +AccessibleStateSetHelperImpl::~AccessibleStateSetHelperImpl() +{ +} + +inline sal_Bool AccessibleStateSetHelperImpl::IsEmpty () + throw (uno::RuntimeException) +{ +#if 0 + return maStates.none(); +#endif + return maStates == 0; +} + +inline sal_Bool AccessibleStateSetHelperImpl::Contains (sal_Int16 aState) + throw (uno::RuntimeException) +{ + DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small"); +#if 0 + return maStates.test(aState); +#endif + sal_uInt64 aTempBitSet(1); + aTempBitSet <<= aState; + return ((aTempBitSet & maStates) != 0); +} + +inline uno::Sequence<sal_Int16> AccessibleStateSetHelperImpl::GetStates() + throw (uno::RuntimeException) +{ + uno::Sequence<sal_Int16> aRet(BITFIELDSIZE); + sal_Int16* pSeq = aRet.getArray(); + sal_Int16 nStateCount(0); + for (sal_Int16 i = 0; i < BITFIELDSIZE; ++i) + if (Contains(i)) + { + *pSeq = i; + ++pSeq; + ++nStateCount; + } + aRet.realloc(nStateCount); + return aRet; +} + +inline void AccessibleStateSetHelperImpl::AddStates( const sal_Int64 _nStates ) SAL_THROW( ( ) ) +{ + maStates |= _nStates; +} + +inline void AccessibleStateSetHelperImpl::AddState(sal_Int16 aState) + throw (uno::RuntimeException) +{ + DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small"); +#if 0 + maStates.set(aState); +#endif + sal_uInt64 aTempBitSet(1); + aTempBitSet <<= aState; + maStates |= aTempBitSet; +} + +inline void AccessibleStateSetHelperImpl::RemoveState(sal_Int16 aState) + throw (uno::RuntimeException) +{ + DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small"); +#if 0 + maStates.set(aState, 0); +#endif + sal_uInt64 aTempBitSet(1); + aTempBitSet <<= aState; + aTempBitSet = ~aTempBitSet; + maStates &= aTempBitSet; +} + +inline sal_Bool AccessibleStateSetHelperImpl::Compare( + const AccessibleStateSetHelperImpl* pComparativeValue, + AccessibleStateSetHelperImpl* pOldStates, + AccessibleStateSetHelperImpl* pNewStates) + throw (uno::RuntimeException) +{ + sal_Bool bResult(sal_False); + if (pComparativeValue && pOldStates && pNewStates) + { + if (maStates == pComparativeValue->maStates) + bResult = sal_True; + else + { +#if 0 + std::bitset<BITFIELDSIZE> aTempBitSet(maStates); +#endif + sal_uInt64 aTempBitSet(maStates); + aTempBitSet ^= pComparativeValue->maStates; + pOldStates->maStates = aTempBitSet; + pOldStates->maStates &= maStates; + pNewStates->maStates = aTempBitSet; + pNewStates->maStates &= pComparativeValue->maStates; + } + } + return bResult; +} + + +//===== internal ============================================================ + +AccessibleStateSetHelper::AccessibleStateSetHelper () + : mpHelperImpl(NULL) +{ + mpHelperImpl = new AccessibleStateSetHelperImpl(); +} + +AccessibleStateSetHelper::AccessibleStateSetHelper ( const sal_Int64 _nInitialStates ) + : mpHelperImpl(NULL) +{ + mpHelperImpl = new AccessibleStateSetHelperImpl(); + mpHelperImpl->AddStates( _nInitialStates ); +} + +AccessibleStateSetHelper::AccessibleStateSetHelper (const AccessibleStateSetHelper& rHelper) + : cppu::WeakImplHelper1<XAccessibleStateSet>() + , mpHelperImpl(NULL) +{ + if (rHelper.mpHelperImpl) + mpHelperImpl = new AccessibleStateSetHelperImpl(*rHelper.mpHelperImpl); + else + mpHelperImpl = new AccessibleStateSetHelperImpl(); +} + +AccessibleStateSetHelper::~AccessibleStateSetHelper(void) +{ + delete mpHelperImpl; +} + +//===== XAccessibleStateSet ============================================== + + /** Checks whether the current state set is empty. + + @return + Returns <TRUE/> if there is no state in this state set and + <FALSE/> if there is at least one state set in it. + */ +sal_Bool SAL_CALL AccessibleStateSetHelper::isEmpty () + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + return mpHelperImpl->IsEmpty(); +} + + /** Checks if the given state is a member of the state set of this + object. + + @param aState + The state for which to check membership. This has to be one of + the constants of <type>AccessibleStateType</type>. + + @return + Returns <TRUE/> if the given state is a memeber of this object's + state set and <FALSE/> otherwise. + */ +sal_Bool SAL_CALL AccessibleStateSetHelper::contains (sal_Int16 aState) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + return mpHelperImpl->Contains(aState); +} + + /** Checks if all of the given states are in this object's state + set. + + @param aStateSet + This sequence of states is interpreted as set and every of its + members, duplicates are ignored, is checked for membership in + this object's state set. Each state has to be one of the + constants of <type>AccessibleStateType</type>. + + @return + Returns <TRUE/> if all states of the given state set are members + of this object's state set. <FALSE/> is returned if at least + one of the states in the given state is not a member of this + object's state set. + */ +sal_Bool SAL_CALL AccessibleStateSetHelper::containsAll + (const uno::Sequence<sal_Int16>& rStateSet) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + sal_Int32 nCount(rStateSet.getLength()); + const sal_Int16* pStates = rStateSet.getConstArray(); + sal_Int32 i = 0; + sal_Bool bFound(sal_True); + while (i < nCount) + { + bFound = mpHelperImpl->Contains(pStates[i]); + i++; + } + return bFound; +} + +uno::Sequence<sal_Int16> SAL_CALL AccessibleStateSetHelper::getStates() + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard(maMutex); + return mpHelperImpl->GetStates(); +} + +void AccessibleStateSetHelper::AddState(sal_Int16 aState) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + mpHelperImpl->AddState(aState); +} + +void AccessibleStateSetHelper::RemoveState(sal_Int16 aState) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + mpHelperImpl->RemoveState(aState); +} + +sal_Bool AccessibleStateSetHelper::Compare( + const AccessibleStateSetHelper& rComparativeValue, + AccessibleStateSetHelper& rOldStates, + AccessibleStateSetHelper& rNewStates) + throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + return mpHelperImpl->Compare(rComparativeValue.mpHelperImpl, + rOldStates.mpHelperImpl, rNewStates.mpHelperImpl); +} + +//===== XTypeProvider ======================================================= + +uno::Sequence< ::com::sun::star::uno::Type> + AccessibleStateSetHelper::getTypes (void) + throw (::com::sun::star::uno::RuntimeException) +{ + const ::com::sun::star::uno::Type aTypeList[] = { + ::getCppuType((const uno::Reference< + XAccessibleStateSet>*)0), + ::getCppuType((const uno::Reference< + lang::XTypeProvider>*)0) + }; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> + aTypeSequence (aTypeList, 2); + return aTypeSequence; +} + +uno::Sequence<sal_Int8> SAL_CALL + AccessibleStateSetHelper::getImplementationId (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard (maMutex); + static uno::Sequence<sal_Int8> aId; + if (aId.getLength() == 0) + { + aId.realloc (16); + rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True); + } + return aId; +} diff --git a/unotools/source/accessibility/makefile.mk b/unotools/source/accessibility/makefile.mk new file mode 100644 index 000000000000..59536b12e517 --- /dev/null +++ b/unotools/source/accessibility/makefile.mk @@ -0,0 +1,48 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=accessibility + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +SLOFILES= $(SLO)$/accessiblestatesethelper.obj \ + $(SLO)$/accessiblerelationsethelper.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/config/accelcfg.cxx b/unotools/source/config/accelcfg.cxx new file mode 100644 index 000000000000..fc0e6108138b --- /dev/null +++ b/unotools/source/config/accelcfg.cxx @@ -0,0 +1,289 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif +#include "rtl/instance.hxx" +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> + +#include <osl/mutex.hxx> +#include <tools/string.hxx> +#include <tools/urlobj.hxx> +#include <unotools/streamwrap.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <comphelper/processfactory.hxx> + +#include <unotools/accelcfg.hxx> +#include <unotools/xmlaccelcfg.hxx> +#include <unotools/pathoptions.hxx> +#include "itemholder1.hxx" + + +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::io; +using namespace com::sun::star::xml::sax; + + +static SvtAcceleratorConfig_Impl* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +class SvtAcceleratorConfig_Impl +{ +public: + + SvtAcceleratorItemList aList; + bool bModified; + + SvtAcceleratorConfig_Impl() + : bModified( FALSE ) + {} + + SvtAcceleratorConfig_Impl( Reference< XInputStream >& xInputStream ); + bool Commit( Reference< XOutputStream >& xOutputStream ); +}; + +// ----------------------------------------------------------------------- + +SvtAcceleratorConfig_Impl::SvtAcceleratorConfig_Impl( Reference< XInputStream >& rInputStream ) + : bModified( false ) +{ + Reference< XParser > xParser( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Parser" )), + UNO_QUERY); + + // connect stream to input stream to the parser + InputSource aInputSource; + aInputSource.aInputStream = rInputStream; + + // get filter + Reference< XDocumentHandler > xFilter( new OReadAccelatorDocumentHandler( aList )); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + xParser->parseStream( aInputSource ); +} + +bool SvtAcceleratorConfig_Impl::Commit( Reference< XOutputStream >& rOutputStream ) +{ + Reference< XDocumentHandler > xWriter; + + xWriter = Reference< XDocumentHandler >( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" )), UNO_QUERY) ; + + Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY ); + xDataSource->setOutputStream( rOutputStream ); + try + { + OWriteAccelatorDocumentHandler aWriteHandler( aList, xWriter ); + aWriteHandler.WriteAcceleratorDocument(); + rOutputStream->flush(); + return true; + } + catch ( RuntimeException& ) + { + } + catch ( SAXException& ) + { + } + catch ( ::com::sun::star::io::IOException& ) + { + } + + return false; +} + +namespace +{ + class LocalSingleton : public rtl::Static< osl::Mutex, LocalSingleton > + { + }; +} + +SvtAcceleratorConfiguration::SvtAcceleratorConfiguration() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + if ( !pOptions ) + { + SvStream* pStream = GetDefaultStream( STREAM_STD_READ ); + ::utl::OInputStreamWrapper aHelper( *pStream ); + com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xOut( &aHelper ); + + try + { + pOptions = new SvtAcceleratorConfig_Impl( xOut ); + } + catch ( RuntimeException& ) + { + pOptions = new SvtAcceleratorConfig_Impl(); + } + catch( SAXException& ) + { + pOptions = new SvtAcceleratorConfig_Impl(); + } + catch( ::com::sun::star::io::IOException& ) + { + pOptions = new SvtAcceleratorConfig_Impl(); + } + + if (pOptions) + ItemHolder1::holdConfigItem(E_ACCELCFG); + + delete pStream; + } + + ++nRefCount; + pImp = pOptions; +} + +SvtAcceleratorConfiguration* SvtAcceleratorConfiguration::CreateFromStream( SvStream& rStream ) +{ + SvtAcceleratorConfiguration* pRet = new SvtAcceleratorConfiguration; + ::utl::OInputStreamWrapper aHelper( rStream ); + com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xOut( &aHelper ); + try + { + pRet->pImp = new SvtAcceleratorConfig_Impl( xOut ); + } + catch ( RuntimeException& ) + { + DELETEZ( pRet ); + } + catch( SAXException& ) + { + DELETEZ( pRet ); + } + catch( ::com::sun::star::io::IOException& ) + { + DELETEZ( pRet ); + } + + return pRet; +} + +// ----------------------------------------------------------------------- + +SvtAcceleratorConfiguration::~SvtAcceleratorConfiguration() +{ + if ( pImp == pOptions ) + { + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + if ( !--nRefCount ) + { + if ( pImp->bModified ) + { + String aUserConfig = SvtPathOptions().GetUserConfigPath(); + INetURLObject aObj( aUserConfig ); + aObj.insertName( String::CreateFromAscii("GlobalKeyBindings.xml") ); + SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READWRITE|STREAM_TRUNC ); + ::utl::OOutputStreamWrapper aHelper( *pStream ); + com::sun::star::uno::Reference < ::com::sun::star::io::XOutputStream > xOut( &aHelper ); + pImp->Commit( xOut ); + delete pStream; + } + + DELETEZ( pOptions ); + } + } + else + { + delete pImp; + } +} + +::rtl::OUString SvtAcceleratorConfiguration::GetCommand( const ::com::sun::star::awt::KeyEvent& rKeyEvent ) +{ + sal_Int16 nCode=rKeyEvent.KeyCode, nModifier=rKeyEvent.Modifiers; + if ( !nCode ) + nCode = rKeyEvent.KeyFunc; + + std::list< SvtAcceleratorConfigItem>::const_iterator p; + for ( p = pImp->aList.begin(); p != pImp->aList.end(); p++ ) + if ( p->nCode == nCode && p->nModifier == nModifier ) + return p->aCommand; + + return ::rtl::OUString(); +} + +const SvtAcceleratorItemList& SvtAcceleratorConfiguration::GetItems() +{ + return pImp->aList; +} + +void SvtAcceleratorConfiguration::SetCommand( const SvtAcceleratorConfigItem& rItem ) +{ + std::list< SvtAcceleratorConfigItem>::iterator p; + for ( p = pImp->aList.begin(); p != pImp->aList.end(); p++ ) + if ( p->nCode == rItem.nCode && p->nModifier == rItem.nModifier ) + { + p->aCommand = rItem.aCommand; + return; + } + + pImp->aList.push_back( rItem ); + +} + +void SvtAcceleratorConfiguration::SetItems( const SvtAcceleratorItemList& rItems, bool bClear ) +{ + if ( bClear ) + { + pImp->aList = rItems; + } + else + { + std::list< SvtAcceleratorConfigItem>::const_iterator p; + for ( p = rItems.begin(); p != rItems.end(); p++ ) + SetCommand( *p ); + } +} + +String SvtAcceleratorConfiguration::GetStreamName() +{ + return String::CreateFromAscii("KeyBindings.xml"); +} + +SvStream* SvtAcceleratorConfiguration::GetDefaultStream( StreamMode nMode ) +{ + String aUserConfig = SvtPathOptions().GetUserConfigPath(); + INetURLObject aObj( aUserConfig ); + aObj.insertName( GetStreamName() ); + return ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), nMode ); +} diff --git a/unotools/source/config/bootstrap.cxx b/unotools/source/config/bootstrap.cxx new file mode 100644 index 000000000000..b2e1bf1739f8 --- /dev/null +++ b/unotools/source/config/bootstrap.cxx @@ -0,0 +1,912 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <stdio.h> + +#include "unotools/bootstrap.hxx" + +// --------------------------------------------------------------------------------------- +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/file.hxx> +#include <osl/mutex.hxx> +#include <osl/diagnose.h> +// --------------------------------------------------------------------------------------- +#include <rtl/bootstrap.hxx> +#include <osl/process.h> // for osl_getExecutableFile +#include "tools/getprocessworkingdir.hxx" + +// --------------------------------------------------------------------------------------- +// #define this to a non-zero value, if remembering defaults is not supported properly +#define RTL_BOOTSTRAP_DEFAULTS_BROKEN 1 + +// --------------------------------------------------------------------------------------- +#define BOOTSTRAP_DATA_NAME SAL_CONFIGFILE("bootstrap") + +#define BOOTSTRAP_ITEM_PRODUCT_KEY "ProductKey" +#define BOOTSTRAP_ITEM_PRODUCT_SOURCE "ProductSource" +#define BOOTSTRAP_ITEM_VERSIONFILE "Location" +#define BOOTSTRAP_ITEM_BUILDID "buildid" + +#define BOOTSTRAP_ITEM_BASEINSTALLATION "BaseInstallation" +#define BOOTSTRAP_ITEM_USERINSTALLATION "UserInstallation" + +#define BOOTSTRAP_ITEM_SHAREDIR "SharedDataDir" +#define BOOTSTRAP_ITEM_USERDIR "UserDataDir" + +#define BOOTSTRAP_DEFAULT_BASEINSTALL "$SYSBINDIR/.." + +#define BOOTSTRAP_DIRNAME_SHAREDIR "share" +#define BOOTSTRAP_DIRNAME_USERDIR "user" + +#define VERSIONFILE_SECTION "Versions" + +#define SETUP_DATA_NAME SAL_CONFIGFILE("setup") +#define SETUP_ITEM_ALLUSERS "ALLUSERS" +// --------------------------------------------------------------------------------------- +typedef char const * AsciiString; +// --------------------------------------------------------------------------------------- + +namespace utl +{ +// --------------------------------------------------------------------------------------- + using ::rtl::OUString; + using ::rtl::OUStringBuffer; + using ::rtl::OString; + +// --------------------------------------------------------------------------------------- +// Implementation class: Bootstrap::Impl +// --------------------------------------------------------------------------------------- + + class Bootstrap::Impl + { + OUString const m_aImplName; + public: // struct to cache the result of a path lookup + struct PathData + { + OUString path; + PathStatus status; + + PathData() + : path() + , status(DATA_UNKNOWN) + {} + }; + public: // data members + // base install data + PathData aBaseInstall_; + + // user install data + PathData aUserInstall_; + + // INI files + PathData aBootstrapINI_; + PathData aVersionINI_; + + // overall status + Status status_; + + public: // construction and initialization + explicit + Impl(OUString const& _aImplName) + : m_aImplName(_aImplName) + { + status_ = initialize(); + } + + Status initialize(); + + // access helper + OUString getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const; + sal_Bool getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault) const; + + OUString getImplName() const { return m_aImplName; } + + private: // implementation + bool initBaseInstallationData(rtl::Bootstrap& _rData); + bool initUserInstallationData(rtl::Bootstrap& _rData); + }; +// --------------------------------------------------------------------------------------- + static OUString getExecutableDirectory(); +// --------------------------------------------------------------------------------------- + + static Bootstrap::Impl* s_pData = NULL; + + Bootstrap::Impl const& Bootstrap::data() + { + + if (!s_pData) + { + using namespace osl; + MutexGuard aGuard( Mutex::getGlobalMutex() ); + + // static Impl s_theData(getExecutableDirectory() + OUString(RTL_CONSTASCII_USTRINGPARAM("/"BOOTSTRAP_DATA_NAME))); + // s_pData = &s_theData; + rtl::OUString uri; + rtl::Bootstrap::get( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BRAND_BASE_DIR")), uri); + s_pData = new Impl(uri + OUString(RTL_CONSTASCII_USTRINGPARAM("/program/"BOOTSTRAP_DATA_NAME))); + } + return *s_pData; + } + + void Bootstrap::reloadData() + { + if (s_pData != NULL) { + delete s_pData; + s_pData = NULL; + } + } + +// --------------------------------------------------------------------------------------- +// helper +// --------------------------------------------------------------------------------------- + +typedef Bootstrap::PathStatus PathStatus; + +sal_Unicode const cURLSeparator = '/'; + +// --------------------------------------------------------------------------------------- +static +inline +OUString getURLSeparator() +{ + static OUString theSep(&cURLSeparator,1); + return theSep; +} + +// --------------------------------------------------------------------------------------- +// path status utility function +static +PathStatus implCheckStatusOfURL(OUString const& _sURL, osl::DirectoryItem& aDirItem) +{ + using namespace osl; + + PathStatus eStatus = Bootstrap::DATA_UNKNOWN; + + if (_sURL.getLength() != 0) + { + switch( DirectoryItem::get(_sURL, aDirItem) ) + { + case DirectoryItem::E_None: // Success + eStatus = Bootstrap::PATH_EXISTS; + break; + + case DirectoryItem::E_NOENT: // No such file or directory<br> + eStatus = Bootstrap::PATH_VALID; + break; + + case DirectoryItem::E_INVAL: // the format of the parameters was not valid<br> + case DirectoryItem::E_NAMETOOLONG: // File name too long<br> + case DirectoryItem::E_NOTDIR: // A component of the path prefix of path is not a directory<p> + eStatus = Bootstrap::DATA_INVALID; + break; + + // how to handle these ? + case DirectoryItem::E_LOOP: // Too many symbolic links encountered<br> + case DirectoryItem::E_ACCES: // permission denied<br> + // any other error - what to do ? + default: + eStatus = Bootstrap::DATA_UNKNOWN; + break; + } + } + else + eStatus = Bootstrap::DATA_MISSING; + + return eStatus; +} +// --------------------------------------------------------------------------------------- + +static +bool implNormalizeURL(OUString & _sURL, osl::DirectoryItem& aDirItem) +{ + using namespace osl; + + OSL_PRECOND(aDirItem.is(), "Opened DirItem required"); + + static const sal_uInt32 cFileStatusMask = FileStatusMask_FileURL; + + FileStatus aFileStatus(cFileStatusMask); + + if (aDirItem.getFileStatus(aFileStatus) != DirectoryItem::E_None) + return false; + + OUString aNormalizedURL = aFileStatus.getFileURL(); + + if (aNormalizedURL.getLength() == 0) + return false; + + // #109863# sal/osl returns final slash for file URLs contradicting + // the URL/URI RFCs. + if ( aNormalizedURL.getStr()[aNormalizedURL.getLength()-1] != cURLSeparator ) + _sURL = aNormalizedURL; + else + _sURL = aNormalizedURL.copy( 0, aNormalizedURL.getLength()-1 ); + + return true; +} +// --------------------------------------------------------------------------------------- +static +bool implEnsureAbsolute(OUString & _rsURL) // also strips embedded dots !! +{ + using osl::File; + + OUString sBasePath; + OSL_VERIFY(tools::getProcessWorkingDir(&sBasePath)); + + OUString sAbsolute; + if ( File::E_None == File::getAbsoluteFileURL(sBasePath, _rsURL, sAbsolute)) + { + _rsURL = sAbsolute; + return true; + } + else + { + OSL_ENSURE(false, "Could not get absolute file URL for URL"); + return false; + } +} +/* old code to strip embedded dots + static OUString const sDots(RTL_CONSTASCII_USTRINGPARAM("/..")); + + sal_Int32 nDotsIndex = _rsURL.indexOf(sDots); + while (nDotsIndex >= 0) + { + OSL_ASSERT(_rsURL.indexOf(sDots) == nDotsIndex); + + sal_Int32 nStripIndex = _rsURL.lastIndexOf(cURLSeparator,nDotsIndex); + if (nStripIndex < 0 || nStripIndex+1 == nDotsIndex) + { + OSL_TRACE("Invalid use of dots in bootstrap URL"); + return false; + } + _rsURL = _rsURL.copy(0,nStripIndex) + _rsURL.copy(nDotsIndex + sDots.getLength()); + + nDotsIndex = _rsURL.indexOf(sDots,nStripIndex); + } + return true; +} + +*/ +// --------------------------------------------------------------------------------------- + +static +bool implMakeAbsoluteURL(OUString & _rsPathOrURL) +{ + using namespace osl; + + bool bURL; + + OUString sOther; + // check if it already was normalized + if ( File::E_None == File::getSystemPathFromFileURL(_rsPathOrURL, sOther) ) + { + bURL = true; + } + + else if ( File::E_None == File::getFileURLFromSystemPath(_rsPathOrURL, sOther) ) + { + _rsPathOrURL = sOther; + bURL = true; + } + else + bURL = false; + + return bURL && implEnsureAbsolute(_rsPathOrURL); +} +// --------------------------------------------------------------------------------------- +#if OSL_DEBUG_LEVEL > 0 +static +PathStatus dbgCheckStatusOfURL(OUString const& _sURL) +{ + using namespace osl; + + DirectoryItem aDirItem; + + return implCheckStatusOfURL(_sURL,aDirItem); +} +// --------------------------------------------------------------------------------------- +#endif + +static +PathStatus checkStatusAndNormalizeURL(OUString & _sURL) +{ + using namespace osl; + + PathStatus eStatus = Bootstrap::DATA_UNKNOWN; + + if (_sURL.getLength() == 0) + eStatus = Bootstrap::DATA_MISSING; + + else if ( !implMakeAbsoluteURL(_sURL) ) + eStatus = Bootstrap::DATA_INVALID; + + else + { + DirectoryItem aDirItem; + + eStatus = implCheckStatusOfURL(_sURL,aDirItem); + + if (eStatus == Bootstrap::PATH_EXISTS) + { + if (!implNormalizeURL(_sURL,aDirItem)) + OSL_ENSURE(false,"Unexpected failure getting actual URL for existing object"); + } + } + return eStatus; +} + + +// ---------------------------------------------------------------------------------- +// helpers to build and check a nested URL +static +PathStatus getDerivedPath( + OUString& _rURL, + OUString const& _aBaseURL, PathStatus _aBaseStatus, + OUString const& _sRelativeURL, + rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter + ) +{ + OUString sDerivedURL; + + OSL_PRECOND(!_rData.getFrom(_sBootstrapParameter,sDerivedURL),"Setting for derived path is already defined"); + OSL_PRECOND(_sRelativeURL.getLength() != 0 && _sRelativeURL[0] != cURLSeparator,"Invalid Relative URL"); + + PathStatus aStatus = _aBaseStatus; + + // do we have a base path ? + if (_aBaseURL.getLength()) + { + OSL_PRECOND(_aBaseURL[_aBaseURL.getLength()-1] != cURLSeparator,"Unexpected: base URL ends in slash"); + + sDerivedURL = _aBaseURL + getURLSeparator() + _sRelativeURL; + + // a derived (nested) URL can only exist or have a lesser status, if the parent exists + if (aStatus == Bootstrap::PATH_EXISTS) + aStatus = checkStatusAndNormalizeURL(sDerivedURL); + + else // the relative appendix must be valid + OSL_ASSERT(aStatus != Bootstrap::PATH_VALID || dbgCheckStatusOfURL(sDerivedURL) == Bootstrap::PATH_VALID); + + _rData.getFrom(_sBootstrapParameter, _rURL, sDerivedURL); + + OSL_ENSURE(sDerivedURL == _rURL,"Could not set derived URL via Bootstrap default parameter"); + OSL_POSTCOND(RTL_BOOTSTRAP_DEFAULTS_BROKEN || + _rData.getFrom(_sBootstrapParameter,sDerivedURL) && sDerivedURL==_rURL,"Use of default did not affect bootstrap value"); + } + else + { + // clear the result + _rURL = _aBaseURL; + + // if we have no data it can't be a valid path + OSL_ASSERT( aStatus > Bootstrap::PATH_VALID ); + } + + + return aStatus; +} + +// ---------------------------------------------------------------------------------- +static +inline +PathStatus getDerivedPath( + OUString& _rURL, + Bootstrap::Impl::PathData const& _aBaseData, + OUString const& _sRelativeURL, + rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter + ) +{ + return getDerivedPath(_rURL,_aBaseData.path,_aBaseData.status,_sRelativeURL,_rData,_sBootstrapParameter); +} + +// --------------------------------------------------------------------------------------- + +static +OUString getExecutableBaseName() +{ + OUString sExecutable; + + if (osl_Process_E_None == osl_getExecutableFile(&sExecutable.pData)) + { + // split the executable name + sal_Int32 nSepIndex = sExecutable.lastIndexOf(cURLSeparator); + + sExecutable = sExecutable.copy(nSepIndex + 1); + + // ... and get the basename (strip the extension) + sal_Unicode const cExtensionSep = '.'; + + sal_Int32 const nExtIndex = sExecutable.lastIndexOf(cExtensionSep); + sal_Int32 const nExtLength = sExecutable.getLength() - nExtIndex - 1; + if (0 < nExtIndex && nExtLength < 4) + sExecutable = sExecutable.copy(0,nExtIndex); + } + else + OSL_TRACE("Cannot get executable name: osl_getExecutableFile failed\n"); + + return sExecutable; +} + +// --------------------------------------------------------------------------------------- +static +OUString getExecutableDirectory() +{ + OUString sFileName; + OSL_VERIFY(osl_Process_E_None == osl_getExecutableFile(&sFileName.pData)); + + sal_Int32 nDirEnd = sFileName.lastIndexOf(cURLSeparator); + + OSL_ENSURE(nDirEnd >= 0, "Cannot locate executable directory"); + + return sFileName.copy(0,nDirEnd); +} + +// ---------------------------------------------------------------------------------- + +static +inline +Bootstrap::PathStatus updateStatus(Bootstrap::Impl::PathData & _rResult) +{ + return _rResult.status = checkStatusAndNormalizeURL(_rResult.path); +} +// --------------------------------------------------------------------------------------- + +static +Bootstrap::PathStatus implGetBootstrapFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rBootstrapFile) +{ + _rData.getIniName(_rBootstrapFile.path); + + return updateStatus(_rBootstrapFile); +} +// --------------------------------------------------------------------------------------- + +static +Bootstrap::PathStatus implGetVersionFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rVersionFile) +{ + OUString const csVersionFileItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_VERSIONFILE)); + + _rData.getFrom(csVersionFileItem,_rVersionFile.path); + + return updateStatus(_rVersionFile); +} +// --------------------------------------------------------------------------------------- +// Error reporting + +static char const IS_MISSING[] = "is missing"; +static char const IS_INVALID[] = "is corrupt"; +static char const PERIOD[] = ". "; + +// --------------------------------------------------------------------------------------- +static void addFileError(OUStringBuffer& _rBuf, OUString const& _aPath, AsciiString _sWhat) +{ + OUString sSimpleFileName = _aPath.copy(1 +_aPath.lastIndexOf(cURLSeparator)); + + _rBuf.appendAscii("The configuration file"); + _rBuf.appendAscii(" '").append(sSimpleFileName).appendAscii("' "); + _rBuf.appendAscii(_sWhat).appendAscii(PERIOD); +} +// --------------------------------------------------------------------------------------- + +static void addMissingDirectoryError(OUStringBuffer& _rBuf, OUString const& _aPath) +{ + _rBuf.appendAscii("The configuration directory"); + _rBuf.appendAscii(" '").append(_aPath).appendAscii("' "); + _rBuf.appendAscii(IS_MISSING).appendAscii(PERIOD); +} +// --------------------------------------------------------------------------------------- + +static void addUnexpectedError(OUStringBuffer& _rBuf, AsciiString _sExtraInfo = NULL) +{ + if (NULL == _sExtraInfo) + _sExtraInfo = "An internal failure occurred"; + + _rBuf.appendAscii(_sExtraInfo).appendAscii(PERIOD); +} +// --------------------------------------------------------------------------------------- + +static Bootstrap::FailureCode describeError(OUStringBuffer& _rBuf, Bootstrap::Impl const& _rData) +{ + Bootstrap::FailureCode eErrCode = Bootstrap::INVALID_BOOTSTRAP_DATA; + + _rBuf.appendAscii("The program cannot be started. "); + + switch (_rData.aUserInstall_.status) + { + case Bootstrap::PATH_EXISTS: + switch (_rData.aBaseInstall_.status) + { + case Bootstrap::PATH_VALID: + addMissingDirectoryError(_rBuf, _rData.aBaseInstall_.path); + eErrCode = Bootstrap::MISSING_INSTALL_DIRECTORY; + break; + + case Bootstrap::DATA_INVALID: + addUnexpectedError(_rBuf,"The installation path is invalid"); + break; + + case Bootstrap::DATA_MISSING: + addUnexpectedError(_rBuf,"The installation path is not available"); + break; + + case Bootstrap::PATH_EXISTS: // seems to be all fine (?) + addUnexpectedError(_rBuf,""); + break; + + default: OSL_ASSERT(false); + addUnexpectedError(_rBuf); + break; + } + break; + + case Bootstrap::PATH_VALID: + addMissingDirectoryError(_rBuf, _rData.aUserInstall_.path); + eErrCode = Bootstrap::MISSING_USER_DIRECTORY; + break; + + // else fall through + case Bootstrap::DATA_INVALID: + if (_rData.aVersionINI_.status == Bootstrap::PATH_EXISTS) + { + addFileError(_rBuf, _rData.aVersionINI_.path, IS_INVALID); + eErrCode = Bootstrap::INVALID_VERSION_FILE_ENTRY; + break; + } + // else fall through + + case Bootstrap::DATA_MISSING: + switch (_rData.aVersionINI_.status) + { + case Bootstrap::PATH_EXISTS: + addFileError(_rBuf, _rData.aVersionINI_.path, "does not support the current version"); + eErrCode = Bootstrap::MISSING_VERSION_FILE_ENTRY; + break; + + case Bootstrap::PATH_VALID: + addFileError(_rBuf, _rData.aVersionINI_.path, IS_MISSING); + eErrCode = Bootstrap::MISSING_VERSION_FILE; + break; + + default: + switch (_rData.aBootstrapINI_.status) + { + case Bootstrap::PATH_EXISTS: + addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_INVALID); + + if (_rData.aVersionINI_.status == Bootstrap::DATA_MISSING) + eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY; + else + eErrCode = Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY; + break; + + case Bootstrap::DATA_INVALID: OSL_ASSERT(false); + case Bootstrap::PATH_VALID: + addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_MISSING); + eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE; + break; + + default: + addUnexpectedError(_rBuf); + break; + } + break; + } + break; + + default: OSL_ASSERT(false); + addUnexpectedError(_rBuf); + break; + } + + return eErrCode; +} +// --------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------- +// class Bootstrap +// --------------------------------------------------------------------------------------- + +OUString Bootstrap::getProductKey() +{ + OUString const csProductKeyItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_PRODUCT_KEY)); + + OUString const sDefaultProductKey = getExecutableBaseName(); + + return data().getBootstrapValue( csProductKeyItem, sDefaultProductKey ); +} +// --------------------------------------------------------------------------------------- + +OUString Bootstrap::getProductKey(OUString const& _sDefault) +{ + OUString const csProductKeyItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_PRODUCT_KEY)); + + return data().getBootstrapValue( csProductKeyItem, _sDefault ); +} +// --------------------------------------------------------------------------------------- + +OUString Bootstrap::getProductSource(OUString const& _sDefault) +{ + OUString const csProductSourceItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_PRODUCT_SOURCE)); + + OUString sProductSource; + // read ProductSource from version.ini (versionrc) + data().getVersionValue( csProductSourceItem, sProductSource, _sDefault ); + return sProductSource; +} +// --------------------------------------------------------------------------------------- + +OUString Bootstrap::getBuildIdData(OUString const& _sDefault) +{ + OUString const csBuildIdItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_BUILDID)); + + OUString sBuildId; + // read buildid from version.ini (versionrc), if it doesn't exist or buildid is empty + if ( data().getVersionValue( csBuildIdItem, sBuildId, _sDefault ) != sal_True || + sBuildId.getLength() == 0 ) + // read buildid from bootstrap.ini (bootstraprc) + sBuildId = data().getBootstrapValue( csBuildIdItem, _sDefault ); + return sBuildId; +} +// --------------------------------------------------------------------------------------- + +OUString Bootstrap::getAllUsersValue(OUString const& _sDefault) +{ + OUString const csAllUsersItem(RTL_CONSTASCII_USTRINGPARAM(SETUP_ITEM_ALLUSERS)); + + rtl::Bootstrap aData( getExecutableDirectory() + OUString( RTL_CONSTASCII_USTRINGPARAM( "/"SETUP_DATA_NAME ) ) ); + OUString sResult; + aData.getFrom( csAllUsersItem, sResult, _sDefault ); + return sResult; +} +// --------------------------------------------------------------------------------------- + +Bootstrap::PathStatus Bootstrap::locateBaseInstallation(OUString& _rURL) +{ + Impl::PathData const& aPathData = data().aBaseInstall_; + + _rURL = aPathData.path; + return aPathData.status; +} +// --------------------------------------------------------------------------------------- + +PathStatus Bootstrap::locateUserInstallation(OUString& _rURL) +{ + Impl::PathData const& aPathData = data().aUserInstall_; + + _rURL = aPathData.path; + return aPathData.status; +} +// --------------------------------------------------------------------------------------- + +PathStatus Bootstrap::locateSharedData(OUString& _rURL) +{ + OUString const csShareDirItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_SHAREDIR)); + + rtl::Bootstrap aData( data().getImplName() ); + + if ( aData.getFrom(csShareDirItem, _rURL) ) + { + return checkStatusAndNormalizeURL(_rURL); + } + else + { + OUString const csShareDir(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DIRNAME_SHAREDIR)); + return getDerivedPath(_rURL, data().aBaseInstall_, csShareDir, aData, csShareDirItem); + } +} +// --------------------------------------------------------------------------------------- + +PathStatus Bootstrap::locateUserData(OUString& _rURL) +{ + OUString const csUserDirItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_USERDIR)); + + rtl::Bootstrap aData( data().getImplName() ); + + if ( aData.getFrom(csUserDirItem, _rURL) ) + { + return checkStatusAndNormalizeURL(_rURL); + } + else + { + OUString const csUserDir(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DIRNAME_USERDIR)); + return getDerivedPath(_rURL, data().aUserInstall_ ,csUserDir, aData, csUserDirItem); + } +} +// --------------------------------------------------------------------------------------- + +PathStatus Bootstrap::locateBootstrapFile(OUString& _rURL) +{ + Impl::PathData const& aPathData = data().aBootstrapINI_; + + _rURL = aPathData.path; + return aPathData.status; +} +// --------------------------------------------------------------------------------------- + +PathStatus Bootstrap::locateVersionFile(OUString& _rURL) +{ + Impl::PathData const& aPathData = data().aVersionINI_; + + _rURL = aPathData.path; + return aPathData.status; +} +// --------------------------------------------------------------------------------------- + +Bootstrap::Status Bootstrap::checkBootstrapStatus(OUString& _rDiagnosticMessage) +{ + FailureCode eDummyCode(NO_FAILURE); + + return checkBootstrapStatus(_rDiagnosticMessage,eDummyCode); +} +// --------------------------------------------------------------------------------------- + +Bootstrap::Status Bootstrap::checkBootstrapStatus(rtl::OUString& _rDiagnosticMessage, FailureCode& _rErrCode) +{ + Impl const& aData = data(); + + Status result = aData.status_; + + // maybe do further checks here + + OUStringBuffer sErrorBuffer; + if (result != DATA_OK) + _rErrCode = describeError(sErrorBuffer,aData); + + else + _rErrCode = NO_FAILURE; + + _rDiagnosticMessage = sErrorBuffer.makeStringAndClear(); + + return result; +} + +// --------------------------------------------------------------------------------------- +// class Bootstrap::Impl +// --------------------------------------------------------------------------------------- + +bool Bootstrap::Impl::initBaseInstallationData(rtl::Bootstrap& _rData) +{ + OUString const csBaseInstallItem( RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_BASEINSTALLATION) ); + OUString const csBaseInstallDefault( RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DEFAULT_BASEINSTALL) ); + + _rData.getFrom(csBaseInstallItem, aBaseInstall_.path, csBaseInstallDefault); + + bool bResult = (PATH_EXISTS == updateStatus(aBaseInstall_)); + + implGetBootstrapFile(_rData, aBootstrapINI_); + + return bResult; +} +// --------------------------------------------------------------------------------------- + +bool Bootstrap::Impl::initUserInstallationData(rtl::Bootstrap& _rData) +{ + OUString const csUserInstallItem( RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_USERINSTALLATION) ); + + if (_rData.getFrom(csUserInstallItem, aUserInstall_.path)) + { + updateStatus(aUserInstall_); + } + else + { + // should we do just this + aUserInstall_.status = DATA_MISSING; + + // .. or this - look for a single-user user directory ? + OUString const csUserDirItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_USERDIR)); + OUString sDummy; + // look for $BASEINSTALLATION/user only if default UserDir setting is used + if (! _rData.getFrom(csUserDirItem, sDummy)) + { + OUString const csUserDir(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DIRNAME_USERDIR)); + + if ( PATH_EXISTS == getDerivedPath(sDummy, aBaseInstall_, csUserDir, _rData, csUserDirItem) ) + aUserInstall_ = aBaseInstall_; + } + } + + bool bResult = (PATH_EXISTS == aUserInstall_.status); + + implGetVersionFile(_rData, aVersionINI_); + + return bResult; +} +// --------------------------------------------------------------------------------------- + +Bootstrap::Status Bootstrap::Impl::initialize() +{ + Bootstrap::Status result; + + rtl::Bootstrap aData( m_aImplName ); + + if (!initBaseInstallationData(aData)) + { + result = INVALID_BASE_INSTALL; + } + else if (!initUserInstallationData(aData)) + { + result = INVALID_USER_INSTALL; + + if (aUserInstall_.status >= DATA_MISSING) + { + switch (aVersionINI_.status) + { + case PATH_EXISTS: + case PATH_VALID: + result = MISSING_USER_INSTALL; + break; + + case DATA_INVALID: + case DATA_MISSING: + result = INVALID_BASE_INSTALL; + break; + default: + break; + } + } + } + else + { + result = DATA_OK; + } + return result; +} +// --------------------------------------------------------------------------------------- + +OUString Bootstrap::Impl::getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const +{ + rtl::Bootstrap aData( m_aImplName ); + + OUString sResult; + aData.getFrom(_sName,sResult,_sDefault); + return sResult; +} +// --------------------------------------------------------------------------------------- + +sal_Bool Bootstrap::Impl::getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault) const +{ + // try to open version.ini (versionrc) + rtl::OUString uri; + rtl::Bootstrap::get( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BRAND_BASE_DIR")), uri); + rtl::Bootstrap aData( uri + + OUString(RTL_CONSTASCII_USTRINGPARAM("/program/"SAL_CONFIGFILE("version"))) ); + if ( aData.getHandle() == NULL ) + // version.ini (versionrc) doesn't exist + return sal_False; + + // read value + aData.getFrom(_sName,_rValue,_sDefault); + return sal_True; +} +// --------------------------------------------------------------------------------------- + +} // namespace utl + diff --git a/unotools/source/config/cacheoptions.cxx b/unotools/source/config/cacheoptions.cxx new file mode 100644 index 000000000000..2b2b612274ac --- /dev/null +++ b/unotools/source/config/cacheoptions.cxx @@ -0,0 +1,512 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/cacheoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl; +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star::uno; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_START OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Cache" )) +#define DEFAULT_WRITEROLE 20 +#define DEFAULT_DRAWINGOLE 20 +#define DEFAULT_GRFMGR_TOTALSIZE 10000000 +#define DEFAULT_GRFMGR_OBJECTSIZE 2400000 +#define DEFAULT_GRFMGR_OBJECTRELEASE 600 + +#define PROPERTYNAME_WRITEROLE OUString(RTL_CONSTASCII_USTRINGPARAM("Writer/OLE_Objects")) +#define PROPERTYNAME_DRAWINGOLE OUString(RTL_CONSTASCII_USTRINGPARAM("DrawingEngine/OLE_Objects")) +#define PROPERTYNAME_GRFMGR_TOTALSIZE OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicManager/TotalCacheSize")) +#define PROPERTYNAME_GRFMGR_OBJECTSIZE OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicManager/ObjectCacheSize")) +#define PROPERTYNAME_GRFMGR_OBJECTRELEASE OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicManager/ObjectReleaseTime")) + +#define PROPERTYHANDLE_WRITEROLE 0 +#define PROPERTYHANDLE_DRAWINGOLE 1 +#define PROPERTYHANDLE_GRFMGR_TOTALSIZE 2 +#define PROPERTYHANDLE_GRFMGR_OBJECTSIZE 3 +#define PROPERTYHANDLE_GRFMGR_OBJECTRELEASE 4 + +#define PROPERTYCOUNT 5 + +class SvtCacheOptions_Impl : public ConfigItem +{ +public: + +//--------------------------------------------------------------------------------------------------------- +// constructor / destructor +//--------------------------------------------------------------------------------------------------------- + + SvtCacheOptions_Impl(); + ~SvtCacheOptions_Impl(); + +//--------------------------------------------------------------------------------------------------------- +// overloaded methods of baseclass +//--------------------------------------------------------------------------------------------------------- + + virtual void Commit(); + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + +//--------------------------------------------------------------------------------------------------------- +// public interface +//--------------------------------------------------------------------------------------------------------- + + sal_Int32 GetWriterOLE_Objects() const; + sal_Int32 GetDrawingEngineOLE_Objects() const; + sal_Int32 GetGraphicManagerTotalCacheSize() const; + sal_Int32 GetGraphicManagerObjectCacheSize() const; + sal_Int32 GetGraphicManagerObjectReleaseTime() const; + + void SetWriterOLE_Objects( sal_Int32 nObjects ); + void SetDrawingEngineOLE_Objects( sal_Int32 nObjects ); + void SetGraphicManagerTotalCacheSize( sal_Int32 nTotalCacheSize ); + void SetGraphicManagerObjectCacheSize( sal_Int32 nObjectCacheSize ); + void SetGraphicManagerObjectReleaseTime( sal_Int32 nReleaseTimeSeconds ); + +//------------------------------------------------------------------------------------------------------------- +// private methods +//------------------------------------------------------------------------------------------------------------- + +private: + + static Sequence< OUString > impl_GetPropertyNames(); + +//------------------------------------------------------------------------------------------------------------- +// private member +//------------------------------------------------------------------------------------------------------------- + +private: + + sal_Int32 mnWriterOLE; + sal_Int32 mnDrawingOLE; + sal_Int32 mnGrfMgrTotalSize; + sal_Int32 mnGrfMgrObjectSize; + sal_Int32 mnGrfMgrObjectRelease; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtCacheOptions_Impl::SvtCacheOptions_Impl() : + ConfigItem( ROOTNODE_START ), + mnWriterOLE( DEFAULT_WRITEROLE ), + mnDrawingOLE( DEFAULT_DRAWINGOLE ), + mnGrfMgrTotalSize( DEFAULT_GRFMGR_TOTALSIZE ), + mnGrfMgrObjectSize( DEFAULT_GRFMGR_OBJECTSIZE ), + mnGrfMgrObjectRelease( DEFAULT_GRFMGR_OBJECTRELEASE ) +{ + Sequence< OUString > seqNames( impl_GetPropertyNames() ); + Sequence< Any > seqValues = GetProperties( seqNames ) ; + + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtCacheOptions_Impl::SvtCacheOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + sal_Int32 nProperty = 0; + + for( nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + if( seqValues[ nProperty ].hasValue() ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_WRITEROLE: + { + if( seqValues[ nProperty ].getValueTypeClass() == TypeClass_LONG ) + seqValues[nProperty] >>= mnWriterOLE; + } + break; + + case PROPERTYHANDLE_DRAWINGOLE: + { + if( seqValues[ nProperty ].getValueTypeClass() == TypeClass_LONG ) + seqValues[nProperty] >>= mnDrawingOLE; + } + break; + + case PROPERTYHANDLE_GRFMGR_TOTALSIZE: + { + if( seqValues[ nProperty ].getValueTypeClass() == TypeClass_LONG ) + seqValues[nProperty] >>= mnGrfMgrTotalSize; + } + break; + + case PROPERTYHANDLE_GRFMGR_OBJECTSIZE: + { + if( seqValues[ nProperty ].getValueTypeClass() == TypeClass_LONG ) + seqValues[nProperty] >>= mnGrfMgrObjectSize; + } + break; + + case PROPERTYHANDLE_GRFMGR_OBJECTRELEASE: + { + if( seqValues[ nProperty ].getValueTypeClass() == TypeClass_LONG ) + seqValues[nProperty] >>= mnGrfMgrObjectRelease; + } + break; + } + } + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtCacheOptions_Impl::~SvtCacheOptions_Impl() +{ + if( IsModified() ) + Commit(); +} + +//***************************************************************************************************************** +// Commit +//***************************************************************************************************************** +void SvtCacheOptions_Impl::Commit() +{ + Sequence< OUString > aSeqNames( impl_GetPropertyNames() ); + Sequence< Any > aSeqValues( aSeqNames.getLength() ); + + for( sal_Int32 nProperty = 0, nCount = aSeqNames.getLength(); nProperty < nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_WRITEROLE: + aSeqValues[nProperty] <<= mnWriterOLE; + break; + + case PROPERTYHANDLE_DRAWINGOLE: + aSeqValues[nProperty] <<= mnDrawingOLE; + break; + + case PROPERTYHANDLE_GRFMGR_TOTALSIZE: + aSeqValues[nProperty] <<= mnGrfMgrTotalSize; + break; + + case PROPERTYHANDLE_GRFMGR_OBJECTSIZE: + aSeqValues[nProperty] <<= mnGrfMgrObjectSize; + break; + + case PROPERTYHANDLE_GRFMGR_OBJECTRELEASE: + aSeqValues[nProperty] <<= mnGrfMgrObjectRelease; + break; + } + } + + PutProperties( aSeqNames, aSeqValues ); +} + +void SvtCacheOptions_Impl::Notify( const Sequence< rtl::OUString >& ) +{ +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions_Impl::GetWriterOLE_Objects() const +{ + return mnWriterOLE; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions_Impl::GetDrawingEngineOLE_Objects() const +{ + return mnDrawingOLE; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions_Impl::GetGraphicManagerTotalCacheSize() const +{ + return mnGrfMgrTotalSize; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions_Impl::GetGraphicManagerObjectCacheSize() const +{ + return mnGrfMgrObjectSize; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions_Impl::GetGraphicManagerObjectReleaseTime() const +{ + return mnGrfMgrObjectRelease; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions_Impl::SetWriterOLE_Objects( sal_Int32 nWriterOLE ) +{ + mnWriterOLE = nWriterOLE; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions_Impl::SetDrawingEngineOLE_Objects( sal_Int32 nDrawingOLE ) +{ + mnDrawingOLE = nDrawingOLE; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions_Impl::SetGraphicManagerTotalCacheSize( sal_Int32 nGrfMgrTotalSize ) +{ + mnGrfMgrTotalSize = nGrfMgrTotalSize; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions_Impl::SetGraphicManagerObjectCacheSize( sal_Int32 nGrfMgrObjectSize ) +{ + mnGrfMgrObjectSize = nGrfMgrObjectSize; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions_Impl::SetGraphicManagerObjectReleaseTime( sal_Int32 nGrfMgrObjectReleaseTime ) +{ + mnGrfMgrObjectRelease = nGrfMgrObjectReleaseTime; + SetModified(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtCacheOptions_Impl::impl_GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_WRITEROLE, + PROPERTYNAME_DRAWINGOLE, + PROPERTYNAME_GRFMGR_TOTALSIZE, + PROPERTYNAME_GRFMGR_OBJECTSIZE, + PROPERTYNAME_GRFMGR_OBJECTRELEASE + }; + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtCacheOptions_Impl* SvtCacheOptions::m_pDataContainer = NULL; +sal_Int32 SvtCacheOptions::m_nRefCount = 0; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtCacheOptions::SvtCacheOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already! + if( m_pDataContainer == NULL ) + { + m_pDataContainer = new SvtCacheOptions_Impl(); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtCacheOptions::~SvtCacheOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions::GetWriterOLE_Objects() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetWriterOLE_Objects(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions::GetDrawingEngineOLE_Objects() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetDrawingEngineOLE_Objects(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions::GetGraphicManagerTotalCacheSize() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetGraphicManagerTotalCacheSize(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions::GetGraphicManagerObjectCacheSize() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetGraphicManagerObjectCacheSize(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtCacheOptions::GetGraphicManagerObjectReleaseTime() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetGraphicManagerObjectReleaseTime(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions::SetWriterOLE_Objects( sal_Int32 nWriterOLE ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetWriterOLE_Objects( nWriterOLE ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions::SetDrawingEngineOLE_Objects( sal_Int32 nDrawingOLE ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetDrawingEngineOLE_Objects( nDrawingOLE ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions::SetGraphicManagerTotalCacheSize( sal_Int32 nGrfMgrTotalSize ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetGraphicManagerTotalCacheSize( nGrfMgrTotalSize ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions::SetGraphicManagerObjectCacheSize( sal_Int32 nGrfMgrObjectSize ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetGraphicManagerObjectCacheSize( nGrfMgrObjectSize ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCacheOptions::SetGraphicManagerObjectReleaseTime( sal_Int32 nGrfMgrObjectReleaseTime ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetGraphicManagerObjectReleaseTime( nGrfMgrObjectReleaseTime ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtCacheOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/cmdoptions.cxx b/unotools/source/config/cmdoptions.cxx new file mode 100644 index 000000000000..fd4fb07e7918 --- /dev/null +++ b/unotools/source/config/cmdoptions.cxx @@ -0,0 +1,628 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/cmdoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <cppuhelper/weakref.hxx> +#include <tools/urlobj.hxx> +#include <rtl/ustrbuf.hxx> + +#include <itemholder1.hxx> + +#include <algorithm> +#include <hash_map> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::std ; +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::beans ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_CMDOPTIONS OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Commands/Execute" )) +#define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" )) + +#define SETNODE_DISABLED OUString(RTL_CONSTASCII_USTRINGPARAM("Disabled" )) + +#define PROPERTYNAME_CMD OUString(RTL_CONSTASCII_USTRINGPARAM("Command" )) + +#define PROPERTYCOUNT 1 + +#define OFFSET_CMD 0 + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +// Method to retrieve a hash code from a string. May be we have to change it to decrease collisions in the hash map +struct OUStringHashCode +{ + size_t operator()( const ::rtl::OUString& sString ) const + { + return sString.hashCode(); + } +}; + +/*-**************************************************************************************************************** + @descr support simple command option structures and operations on it +****************************************************************************************************************-*/ +class SvtCmdOptions +{ + public: + //--------------------------------------------------------------------------------------------------------- + // the only way to free memory! + void Clear() + { + m_aCommandHashMap.clear(); + } + + sal_Bool HasEntries() const + { + return ( m_aCommandHashMap.size() > 0 ); + } + + void SetContainerSize( sal_Int32 nSize ) + { + m_aCommandHashMap.resize( nSize ); + } + + sal_Bool Lookup( const OUString& aCmd ) const + { + CommandHashMap::const_iterator pEntry = m_aCommandHashMap.find( aCmd ); + return ( pEntry != m_aCommandHashMap.end() ); + } + + void AddCommand( const OUString& aCmd ) + { + m_aCommandHashMap.insert( CommandHashMap::value_type( aCmd, 0 ) ); + } + + //--------------------------------------------------------------------------------------------------------- + // convert internal list to external format + // for using it on right menus realy + // Notice: We build a property list with 4 entries and set it on result list then. + // The while-loop starts with pointer on internal member list lSetupEntries, change to + // lUserEntries then and stop after that with NULL! + // Separator entries will be packed in another way then normal entries! We define + // special strings "sEmpty" and "sSeperator" to perform too ... + Sequence< OUString > GetList() const + { + sal_Int32 nCount = (sal_Int32)m_aCommandHashMap.size(); + sal_Int32 nIndex = 0; + Sequence< OUString > aList( nCount ); + + CommandHashMap::const_iterator pEntry = m_aCommandHashMap.begin(); + while ( pEntry != m_aCommandHashMap.end() ) + aList[nIndex++] = pEntry->first; + + return aList; + } + + private: + class CommandHashMap : public ::std::hash_map< ::rtl::OUString , + sal_Int32 , + OUStringHashCode , + ::std::equal_to< ::rtl::OUString > > + { + public: + inline void free() + { + CommandHashMap().swap( *this ); + } + }; + + CommandHashMap m_aCommandHashMap; +}; + +typedef ::std::vector< ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame > > SvtFrameVector; + +class SvtCommandOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtCommandOptions_Impl(); + ~SvtCommandOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "lPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& lPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short base implementation of public interface for "SvtDynamicMenuOptions"! + @descr These class is used as static member of "SvtDynamicMenuOptions" ... + => The code exist only for one time and isn't duplicated for every instance! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + void Clear ( SvtCommandOptions::CmdOption eCmdOption ); + sal_Bool HasEntries ( SvtCommandOptions::CmdOption eOption ) const; + sal_Bool Lookup ( SvtCommandOptions::CmdOption eCmdOption, const OUString& ) const; + Sequence< OUString > GetList ( SvtCommandOptions::CmdOption eCmdOption ) const ; + void AddCommand ( SvtCommandOptions::CmdOption eCmdOption, + const OUString& sURL ); + void EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame); + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of key names of our configuration management which represent oue module tree + @descr These methods return the current list of key names! We need it to get needed values from our + configuration management and support dynamical menu item lists! + + @seealso - + + @param "nDisabledCount" , returns count of menu entries for "new" + @return A list of configuration key names is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + Sequence< OUString > impl_GetPropertyNames(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + SvtCmdOptions m_aDisabledCommands; + SvtFrameVector m_lFrames; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtCommandOptions_Impl::SvtCommandOptions_Impl() + // Init baseclasses first + : ConfigItem( ROOTNODE_CMDOPTIONS ) + // Init member then... +{ + // Get names and values of all accessable menu entries and fill internal structures. + // See impl_GetPropertyNames() for further informations. + Sequence< OUString > lNames = impl_GetPropertyNames (); + Sequence< Any > lValues = GetProperties ( lNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + // Attention: List for names and values have an internal construction pattern! + sal_Int32 nItem = 0 ; + OUString sCmd ; + + // Set size of hash_map reach a used size of approx. 60% + m_aDisabledCommands.SetContainerSize( lNames.getLength() * 10 / 6 ); + + // Get names/values for disabled commands. + for( nItem=0; nItem < lNames.getLength(); ++nItem ) + { + // Currently only one value + lValues[nItem] >>= sCmd; + m_aDisabledCommands.AddCommand( sCmd ); + } + +/*TODO: Not used in the moment! see Notify() ... + // Enable notification mechanism of ouer baseclass. + // We need it to get information about changes outside these class on ouer used configuration keys! */ + Sequence< OUString > aNotifySeq( 1 ); + aNotifySeq[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Disabled" )); + EnableNotification( aNotifySeq, sal_True ); +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtCommandOptions_Impl::~SvtCommandOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions_Impl::Notify( const Sequence< OUString >& ) +{ + MutexGuard aGuard( SvtCommandOptions::GetOwnStaticMutex() ); + + Sequence< OUString > lNames = impl_GetPropertyNames (); + Sequence< Any > lValues = GetProperties ( lNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + // Attention: List for names and values have an internal construction pattern! + sal_Int32 nItem = 0 ; + OUString sCmd ; + + // Set size of hash_map reach a used size of approx. 60% + m_aDisabledCommands.Clear(); + m_aDisabledCommands.SetContainerSize( lNames.getLength() * 10 / 6 ); + + // Get names/values for disabled commands. + for( nItem=0; nItem < lNames.getLength(); ++nItem ) + { + // Currently only one value + lValues[nItem] >>= sCmd; + m_aDisabledCommands.AddCommand( sCmd ); + } + + // dont forget to update all existing frames and her might cached dispatch objects! + // But look for already killed frames. We hold weak references instead of hard ones ... + for (SvtFrameVector::const_iterator pIt = m_lFrames.begin(); + pIt != m_lFrames.end() ; + ++pIt ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame(pIt->get(), ::com::sun::star::uno::UNO_QUERY); + if (xFrame.is()) + xFrame->contextChanged(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions_Impl::Commit() +{ + DBG_ERROR( "SvtCommandOptions_Impl::Commit()\nNot implemented yet!\n" ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions_Impl::Clear( SvtCommandOptions::CmdOption eCmdOption ) +{ + switch( eCmdOption ) + { + case SvtCommandOptions::CMDOPTION_DISABLED: + { + m_aDisabledCommands.Clear(); + SetModified(); + } + break; + + default: + DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::Clear()\nUnknown option type given!\n" ); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtCommandOptions_Impl::HasEntries( SvtCommandOptions::CmdOption eOption ) const +{ + if ( eOption == SvtCommandOptions::CMDOPTION_DISABLED ) + return ( m_aDisabledCommands.HasEntries() > 0 ); + else + return sal_False; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< OUString > SvtCommandOptions_Impl::GetList( SvtCommandOptions::CmdOption eCmdOption ) const +{ + Sequence< OUString > lReturn; + + switch( eCmdOption ) + { + case SvtCommandOptions::CMDOPTION_DISABLED: + { + lReturn = m_aDisabledCommands.GetList(); + } + break; + + default: + DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" ); + } + + return lReturn; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtCommandOptions_Impl::Lookup( SvtCommandOptions::CmdOption eCmdOption, const OUString& aCommand ) const +{ + switch( eCmdOption ) + { + case SvtCommandOptions::CMDOPTION_DISABLED: + { + return m_aDisabledCommands.Lookup( aCommand ); + } + default: + DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" ); + } + + return sal_False; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions_Impl::AddCommand( SvtCommandOptions::CmdOption eCmdOption, const OUString& sCmd ) +{ + switch( eCmdOption ) + { + case SvtCommandOptions::CMDOPTION_DISABLED: + { + m_aDisabledCommands.AddCommand( sCmd ); + SetModified(); + } + break; + + default: + DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" ); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions_Impl::EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame) +{ + // check if frame already exists inside list + // ignore double registrations + // every frame must be notified one times only! + ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame > xWeak(xFrame); + SvtFrameVector::const_iterator pIt = ::std::find(m_lFrames.begin(), m_lFrames.end(), xWeak); + if (pIt == m_lFrames.end()) + m_lFrames.push_back(xWeak); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtCommandOptions_Impl::impl_GetPropertyNames() +{ + // First get ALL names of current existing list items in configuration! + Sequence< OUString > lDisabledItems = GetNodeNames( SETNODE_DISABLED, utl::CONFIG_NAME_LOCAL_PATH ); + + OUString aSetNode( SETNODE_DISABLED ); + aSetNode += PATHDELIMITER; + + OUString aCommandKey( PATHDELIMITER ); + aCommandKey += PROPERTYNAME_CMD; + + // Expand all keys + for (sal_Int32 i=0; i<lDisabledItems.getLength(); ++i ) + { + OUStringBuffer aBuffer( 32 ); + aBuffer.append( aSetNode ); + aBuffer.append( lDisabledItems[i] ); + aBuffer.append( aCommandKey ); + lDisabledItems[i] = aBuffer.makeStringAndClear(); + } + + // Return result. + return lDisabledItems; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtCommandOptions_Impl* SvtCommandOptions::m_pDataContainer = NULL ; +sal_Int32 SvtCommandOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtCommandOptions::SvtCommandOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + m_pDataContainer = new SvtCommandOptions_Impl; + ItemHolder1::holdConfigItem(E_CMDOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtCommandOptions::~SvtCommandOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions::Clear( CmdOption eCmdOption ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->Clear( eCmdOption ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtCommandOptions::HasEntries( CmdOption eOption ) const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->HasEntries( eOption ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtCommandOptions::Lookup( CmdOption eCmdOption, const OUString& aCommandURL ) const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->Lookup( eCmdOption, aCommandURL ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< OUString > SvtCommandOptions::GetList( CmdOption eCmdOption ) const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetList( eCmdOption ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions::AddCommand( CmdOption eCmdOption, const OUString& sURL ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->AddCommand( eCmdOption, sURL ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCommandOptions::EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->EstablisFrameCallback(xFrame); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtCommandOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/compatibility.cxx b/unotools/source/config/compatibility.cxx new file mode 100644 index 000000000000..61ebe0211817 --- /dev/null +++ b/unotools/source/config/compatibility.cxx @@ -0,0 +1,804 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/compatibility.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#ifndef __SGI_STL_VECTOR +#include <vector> +#endif + +#include <itemholder1.hxx> + +#include <algorithm> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::std; +using namespace ::utl; +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_OPTIONS OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.Compatibility/" ) ) +#define PATHDELIMITER OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) +#define SETNODE_ALLFILEFORMATS OUString( RTL_CONSTASCII_USTRINGPARAM( "AllFileFormats" ) ) + +#define PROPERTYNAME_NAME COMPATIBILITY_PROPERTYNAME_NAME +#define PROPERTYNAME_MODULE COMPATIBILITY_PROPERTYNAME_MODULE +#define PROPERTYNAME_USEPRTMETRICS COMPATIBILITY_PROPERTYNAME_USEPRTMETRICS +#define PROPERTYNAME_ADDSPACING COMPATIBILITY_PROPERTYNAME_ADDSPACING +#define PROPERTYNAME_ADDSPACINGATPAGES COMPATIBILITY_PROPERTYNAME_ADDSPACINGATPAGES +#define PROPERTYNAME_USEOURTABSTOPS COMPATIBILITY_PROPERTYNAME_USEOURTABSTOPS +#define PROPERTYNAME_NOEXTLEADING COMPATIBILITY_PROPERTYNAME_NOEXTLEADING +#define PROPERTYNAME_USELINESPACING COMPATIBILITY_PROPERTYNAME_USELINESPACING +#define PROPERTYNAME_ADDTABLESPACING COMPATIBILITY_PROPERTYNAME_ADDTABLESPACING +#define PROPERTYNAME_USEOBJPOS COMPATIBILITY_PROPERTYNAME_USEOBJECTPOSITIONING +#define PROPERTYNAME_USEOURTEXTWRAP COMPATIBILITY_PROPERTYNAME_USEOURTEXTWRAPPING +#define PROPERTYNAME_CONSIDERWRAPSTYLE COMPATIBILITY_PROPERTYNAME_CONSIDERWRAPPINGSTYLE +#define PROPERTYNAME_EXPANDWORDSPACE COMPATIBILITY_PROPERTYNAME_EXPANDWORDSPACE + +#define PROPERTYCOUNT 13 + +#define OFFSET_NAME 0 +#define OFFSET_MODULE 1 +#define OFFSET_USEPRTMETRICS 2 +#define OFFSET_ADDSPACING 3 +#define OFFSET_ADDSPACINGATPAGES 4 +#define OFFSET_USEOURTABSTOPS 5 +#define OFFSET_NOEXTLEADING 6 +#define OFFSET_USELINESPACING 7 +#define OFFSET_ADDTABLESPACING 8 +#define OFFSET_USEOBJPOS 9 +#define OFFSET_USEOURTEXTWRAPPING 10 +#define OFFSET_CONSIDERWRAPPINGSTYLE 11 +#define OFFSET_EXPANDWORDSPACE 12 + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +/*-**************************************************************************************************************** + @descr struct to hold information about one compatibility entry +****************************************************************************************************************-*/ +struct SvtCompatibilityEntry +{ + public: + SvtCompatibilityEntry() : + bUsePrtMetrics( false ), bAddSpacing( false ), + bAddSpacingAtPages( false ), bUseOurTabStops( false ), + bNoExtLeading( false ), bUseLineSpacing( false ), + bAddTableSpacing( false ), bUseObjPos( false ), + bUseOurTextWrapping( false ), bConsiderWrappingStyle( false ), + bExpandWordSpace( true ) {} + SvtCompatibilityEntry( + const OUString& _rName, const OUString& _rNewModule ) : + sName( _rName ), sModule( _rNewModule ), + bUsePrtMetrics( false ), bAddSpacing( false ), + bAddSpacingAtPages( false ), bUseOurTabStops( false ), + bNoExtLeading( false ), bUseLineSpacing( false ), + bAddTableSpacing( false ), bUseObjPos( false ), + bUseOurTextWrapping( false ), bConsiderWrappingStyle( false ), + bExpandWordSpace( true ) {} + + inline void SetUsePrtMetrics( bool _bSet ) { bUsePrtMetrics = _bSet; } + inline void SetAddSpacing( bool _bSet ) { bAddSpacing = _bSet; } + inline void SetAddSpacingAtPages( bool _bSet ) { bAddSpacingAtPages = _bSet; } + inline void SetUseOurTabStops( bool _bSet ) { bUseOurTabStops = _bSet; } + inline void SetNoExtLeading( bool _bSet ) { bNoExtLeading = _bSet; } + inline void SetUseLineSpacing( bool _bSet ) { bUseLineSpacing = _bSet; } + inline void SetAddTableSpacing( bool _bSet ) { bAddTableSpacing = _bSet; } + inline void SetUseObjPos( bool _bSet ) { bUseObjPos = _bSet; } + inline void SetUseOurTextWrapping( bool _bSet ) { bUseOurTextWrapping = _bSet; } + inline void SetConsiderWrappingStyle( bool _bSet ) { bConsiderWrappingStyle = _bSet; } + inline void SetExpandWordSpace( bool _bSet ) { bExpandWordSpace = _bSet; } + + public: + OUString sName; + OUString sModule; + bool bUsePrtMetrics; + bool bAddSpacing; + bool bAddSpacingAtPages; + bool bUseOurTabStops; + bool bNoExtLeading; + bool bUseLineSpacing; + bool bAddTableSpacing; + bool bUseObjPos; + bool bUseOurTextWrapping; + bool bConsiderWrappingStyle; + bool bExpandWordSpace; +}; + +/*-**************************************************************************************************************** + @descr support simple menu structures and operations on it +****************************************************************************************************************-*/ +class SvtCompatibility +{ + public: + //--------------------------------------------------------------------------------------------------------- + // append one entry + void AppendEntry( const SvtCompatibilityEntry& rEntry ) + { + lEntries.push_back( rEntry ); + } + + //--------------------------------------------------------------------------------------------------------- + // the only way to free memory! + void Clear() + { + lEntries.clear(); + } + + //--------------------------------------------------------------------------------------------------------- + // convert internal list to external format + Sequence< Sequence< PropertyValue > > GetList() const + { + sal_Int32 nCount = (sal_Int32)lEntries.size(); + sal_Int32 nStep = 0; + Sequence< PropertyValue > lProperties( PROPERTYCOUNT ); + Sequence< Sequence< PropertyValue > > lResult( nCount ); + const vector< SvtCompatibilityEntry >* pList = &lEntries; + + lProperties[ OFFSET_NAME ].Name = PROPERTYNAME_NAME; + lProperties[ OFFSET_MODULE ].Name = PROPERTYNAME_MODULE; + lProperties[ OFFSET_USEPRTMETRICS ].Name = PROPERTYNAME_USEPRTMETRICS; + lProperties[ OFFSET_ADDSPACING ].Name = PROPERTYNAME_ADDSPACING; + lProperties[ OFFSET_ADDSPACINGATPAGES ].Name = PROPERTYNAME_ADDSPACINGATPAGES; + lProperties[ OFFSET_USEOURTABSTOPS ].Name = PROPERTYNAME_USEOURTABSTOPS; + lProperties[ OFFSET_NOEXTLEADING ].Name = PROPERTYNAME_NOEXTLEADING; + lProperties[ OFFSET_USELINESPACING ].Name = PROPERTYNAME_USELINESPACING; + lProperties[ OFFSET_ADDTABLESPACING ].Name = PROPERTYNAME_ADDTABLESPACING; + lProperties[ OFFSET_USEOBJPOS ].Name = PROPERTYNAME_USEOBJPOS; + lProperties[ OFFSET_USEOURTEXTWRAPPING ].Name = PROPERTYNAME_USEOURTEXTWRAP; + lProperties[ OFFSET_CONSIDERWRAPPINGSTYLE ].Name = PROPERTYNAME_CONSIDERWRAPSTYLE; + lProperties[ OFFSET_EXPANDWORDSPACE ].Name = PROPERTYNAME_EXPANDWORDSPACE; + + for ( vector< SvtCompatibilityEntry >::const_iterator pItem = pList->begin(); + pItem != pList->end(); ++pItem ) + { + lProperties[ OFFSET_NAME ].Value <<= pItem->sName; + lProperties[ OFFSET_MODULE ].Value <<= pItem->sModule; + lProperties[ OFFSET_USEPRTMETRICS ].Value <<= pItem->bUsePrtMetrics; + lProperties[ OFFSET_ADDSPACING ].Value <<= pItem->bAddSpacing; + lProperties[ OFFSET_ADDSPACINGATPAGES ].Value <<= pItem->bAddSpacingAtPages; + lProperties[ OFFSET_USEOURTABSTOPS ].Value <<= pItem->bUseOurTabStops; + lProperties[ OFFSET_NOEXTLEADING ].Value <<= pItem->bNoExtLeading; + lProperties[ OFFSET_USELINESPACING ].Value <<= pItem->bUseLineSpacing; + lProperties[ OFFSET_ADDTABLESPACING ].Value <<= pItem->bAddTableSpacing; + lProperties[ OFFSET_USEOBJPOS ].Value <<= pItem->bUseObjPos; + lProperties[ OFFSET_USEOURTEXTWRAPPING ].Value <<= pItem->bUseOurTextWrapping; + lProperties[ OFFSET_CONSIDERWRAPPINGSTYLE ].Value <<= pItem->bConsiderWrappingStyle; + lProperties[ OFFSET_EXPANDWORDSPACE ].Value <<= pItem->bExpandWordSpace; + lResult[ nStep ] = lProperties; + ++nStep; + } + + return lResult; + } + + int size() const + { + return lEntries.size(); + } + + const SvtCompatibilityEntry& operator[]( int i ) + { + return lEntries[i]; + } + + private: + vector< SvtCompatibilityEntry > lEntries; +}; + +class SvtCompatibilityOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtCompatibilityOptions_Impl(); + ~SvtCompatibilityOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "lPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& lPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short base implementation of public interface for "SvtCompatibilityOptions"! + @descr These class is used as static member of "SvtCompatibilityOptions" ... + => The code exist only for one time and isn't duplicated for every instance! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + void Clear(); + Sequence< Sequence< PropertyValue > > GetList() const; + void AppendItem( const ::rtl::OUString& _sName, + const ::rtl::OUString& _sModule, + bool _bUsePrtMetrics, + bool _bAddSpacing, + bool _bAddSpacingAtPages, + bool _bUseOurTabStops, + bool _bNoExtLeading, + bool _bUseLineSpacing, + bool _bAddTableSpacing, + bool _bUseObjPos, + bool _bUseOurTextWrapping, + bool _bConsiderWrappingStyle, + bool _bExpandWordSpace ); + + inline bool IsUsePrtDevice() const { return m_aDefOptions.bUsePrtMetrics; } + inline bool IsAddSpacing() const { return m_aDefOptions.bAddSpacing; } + inline bool IsAddSpacingAtPages() const { return m_aDefOptions.bAddSpacingAtPages; } + inline bool IsUseOurTabStops() const { return m_aDefOptions.bUseOurTabStops; } + inline bool IsNoExtLeading() const { return m_aDefOptions.bNoExtLeading; } + inline bool IsUseLineSpacing() const { return m_aDefOptions.bUseLineSpacing; } + inline bool IsAddTableSpacing() const { return m_aDefOptions.bAddTableSpacing; } + inline bool IsUseObjPos() const { return m_aDefOptions.bUseObjPos; } + inline bool IsUseOurTextWrapping() const { return m_aDefOptions.bUseOurTextWrapping; } + inline bool IsConsiderWrappingStyle() const { return m_aDefOptions.bConsiderWrappingStyle; } + inline bool IsExpandWordSpace() const { return m_aDefOptions.bExpandWordSpace; } + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of key names of our configuration management which represent one module tree + @descr These methods return the current list of key names! We need it to get needed values from our + configuration management and support dynamical menu item lists! + + @seealso - + + @param - + @return A list of configuration key names is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + Sequence< OUString > impl_GetPropertyNames( Sequence< OUString >& rItems ); + + /*-****************************************************************************************************//** + @short expand the list for all well known properties to destination + @descr - + @attention - + + @seealso method impl_GetPropertyNames() + + @param "lSource" , original list + @param "lDestination" , destination of operation + @return A list of configuration key names is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + void impl_ExpandPropertyNames( const Sequence< OUString >& lSource, + Sequence< OUString >& lDestination ); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + + SvtCompatibility m_aOptions; + SvtCompatibilityEntry m_aDefOptions; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl() + // Init baseclasses first + : ConfigItem( ROOTNODE_OPTIONS ) + // Init member then... +{ + // Get names and values of all accessable menu entries and fill internal structures. + // See impl_GetPropertyNames() for further informations. + Sequence< OUString > lNodes; + Sequence< OUString > lNames = impl_GetPropertyNames( lNodes ); + sal_uInt32 nCount = lNodes.getLength(); + Sequence< Any > lValues = GetProperties( lNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !( lNames.getLength()!=lValues.getLength() ), "SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl()\nI miss some values of configuration keys!\n" ); + + SvtCompatibilityEntry aItem; + sal_uInt32 nItem = 0; + sal_uInt32 nPosition = 0; + + // Get names/values for new menu. + // 4 subkeys for every item! + bool bDefaultFound = false; + for( nItem = 0; nItem < nCount; ++nItem ) + { + aItem.sName = lNodes[ nItem ]; + lValues[ nPosition++ ] >>= aItem.sModule; + lValues[ nPosition++ ] >>= aItem.bUsePrtMetrics; + lValues[ nPosition++ ] >>= aItem.bAddSpacing; + lValues[ nPosition++ ] >>= aItem.bAddSpacingAtPages; + lValues[ nPosition++ ] >>= aItem.bUseOurTabStops; + lValues[ nPosition++ ] >>= aItem.bNoExtLeading; + lValues[ nPosition++ ] >>= aItem.bUseLineSpacing; + lValues[ nPosition++ ] >>= aItem.bAddTableSpacing; + lValues[ nPosition++ ] >>= aItem.bUseObjPos; + lValues[ nPosition++ ] >>= aItem.bUseOurTextWrapping; + lValues[ nPosition++ ] >>= aItem.bConsiderWrappingStyle; + lValues[ nPosition++ ] >>= aItem.bExpandWordSpace; + m_aOptions.AppendEntry( aItem ); + + if ( !bDefaultFound && aItem.sName.equals( COMPATIBILITY_DEFAULT_NAME ) != sal_False ) + { + m_aDefOptions = aItem; + bDefaultFound = true; + } + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtCompatibilityOptions_Impl::~SvtCompatibilityOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCompatibilityOptions_Impl::Notify( const Sequence< OUString >& ) +{ + DBG_ASSERT( sal_False, "SvtCompatibilityOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCompatibilityOptions_Impl::Commit() +{ + // Write all properties! + // Delete complete set first. + ClearNodeSet( SETNODE_ALLFILEFORMATS ); + + SvtCompatibilityEntry aItem; + OUString sNode; + Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT - 1 ); + sal_uInt32 nItem = 0; + sal_uInt32 nNewCount = m_aOptions.size(); + for( nItem = 0; nItem < nNewCount; ++nItem ) + { + aItem = m_aOptions[ nItem ]; + sNode = SETNODE_ALLFILEFORMATS + PATHDELIMITER + aItem.sName + PATHDELIMITER; + + lPropertyValues[ OFFSET_MODULE - 1 ].Name = sNode + PROPERTYNAME_MODULE; + lPropertyValues[ OFFSET_USEPRTMETRICS - 1 ].Name = sNode + PROPERTYNAME_USEPRTMETRICS; + lPropertyValues[ OFFSET_ADDSPACING - 1 ].Name = sNode + PROPERTYNAME_ADDSPACING; + lPropertyValues[ OFFSET_ADDSPACINGATPAGES - 1 ].Name = sNode + PROPERTYNAME_ADDSPACINGATPAGES; + lPropertyValues[ OFFSET_USEOURTABSTOPS - 1 ].Name = sNode + PROPERTYNAME_USEOURTABSTOPS; + lPropertyValues[ OFFSET_NOEXTLEADING - 1 ].Name = sNode + PROPERTYNAME_NOEXTLEADING; + lPropertyValues[ OFFSET_USELINESPACING - 1 ].Name = sNode + PROPERTYNAME_USELINESPACING; + lPropertyValues[ OFFSET_ADDTABLESPACING - 1 ].Name = sNode + PROPERTYNAME_ADDTABLESPACING; + lPropertyValues[ OFFSET_USEOBJPOS - 1 ].Name = sNode + PROPERTYNAME_USEOBJPOS; + lPropertyValues[ OFFSET_USEOURTEXTWRAPPING - 1 ].Name = sNode + PROPERTYNAME_USEOURTEXTWRAP; + lPropertyValues[ OFFSET_CONSIDERWRAPPINGSTYLE - 1 ].Name = sNode + PROPERTYNAME_CONSIDERWRAPSTYLE; + lPropertyValues[ OFFSET_EXPANDWORDSPACE - 1 ].Name = sNode + PROPERTYNAME_EXPANDWORDSPACE; + + lPropertyValues[ OFFSET_MODULE - 1 ].Value <<= aItem.sModule; + lPropertyValues[ OFFSET_USEPRTMETRICS - 1 ].Value <<= aItem.bUsePrtMetrics; + lPropertyValues[ OFFSET_ADDSPACING - 1 ].Value <<= aItem.bAddSpacing; + lPropertyValues[ OFFSET_ADDSPACINGATPAGES - 1 ].Value <<= aItem.bAddSpacingAtPages; + lPropertyValues[ OFFSET_USEOURTABSTOPS - 1 ].Value <<= aItem.bUseOurTabStops; + lPropertyValues[ OFFSET_NOEXTLEADING - 1 ].Value <<= aItem.bNoExtLeading; + lPropertyValues[ OFFSET_USELINESPACING - 1 ].Value <<= aItem.bUseLineSpacing; + lPropertyValues[ OFFSET_ADDTABLESPACING - 1 ].Value <<= aItem.bAddTableSpacing; + lPropertyValues[ OFFSET_USEOBJPOS - 1 ].Value <<= aItem.bUseObjPos; + lPropertyValues[ OFFSET_USEOURTEXTWRAPPING - 1 ].Value <<= aItem.bUseOurTextWrapping; + lPropertyValues[ OFFSET_CONSIDERWRAPPINGSTYLE - 1 ].Value <<= aItem.bConsiderWrappingStyle; + lPropertyValues[ OFFSET_EXPANDWORDSPACE - 1 ].Value <<= aItem.bExpandWordSpace; + + SetSetProperties( SETNODE_ALLFILEFORMATS, lPropertyValues ); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCompatibilityOptions_Impl::Clear() +{ + m_aOptions.Clear(); + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< Sequence< PropertyValue > > SvtCompatibilityOptions_Impl::GetList() const +{ + Sequence< Sequence< PropertyValue > > lReturn; + lReturn = m_aOptions.GetList(); + return lReturn; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** + +void SvtCompatibilityOptions_Impl::AppendItem( const ::rtl::OUString& _sName, + const ::rtl::OUString& _sModule, + bool _bUsePrtMetrics, + bool _bAddSpacing, + bool _bAddSpacingAtPages, + bool _bUseOurTabStops, + bool _bNoExtLeading, + bool _bUseLineSpacing, + bool _bAddTableSpacing, + bool _bUseObjPos, + bool _bUseOurTextWrapping, + bool _bConsiderWrappingStyle, + bool _bExpandWordSpace ) +{ + SvtCompatibilityEntry aItem( _sName, _sModule ); + aItem.SetUsePrtMetrics( _bUsePrtMetrics ); + aItem.SetAddSpacing( _bAddSpacing ); + aItem.SetAddSpacingAtPages( _bAddSpacingAtPages ); + aItem.SetUseOurTabStops( _bUseOurTabStops ); + aItem.SetNoExtLeading( _bNoExtLeading ); + aItem.SetUseLineSpacing( _bUseLineSpacing ); + aItem.SetAddTableSpacing( _bAddTableSpacing ); + aItem.SetUseObjPos( _bUseObjPos ); + aItem.SetUseOurTextWrapping( _bUseOurTextWrapping ); + aItem.SetConsiderWrappingStyle( _bConsiderWrappingStyle ); + aItem.SetExpandWordSpace( _bExpandWordSpace ); + m_aOptions.AppendEntry( aItem ); + + // default item reset? + if ( _sName.equals( COMPATIBILITY_DEFAULT_NAME ) != sal_False ) + m_aDefOptions = aItem; + + SetModified(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtCompatibilityOptions_Impl::impl_GetPropertyNames( Sequence< OUString >& rItems ) +{ + // First get ALL names of current existing list items in configuration! + rItems = GetNodeNames( SETNODE_ALLFILEFORMATS ); + // expand list to result list ... + Sequence< OUString > lProperties( rItems.getLength() * ( PROPERTYCOUNT - 1 ) ); + impl_ExpandPropertyNames( rItems, lProperties ); + // Return result. + return lProperties; +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +void SvtCompatibilityOptions_Impl::impl_ExpandPropertyNames( + const Sequence< OUString >& lSource, Sequence< OUString >& lDestination ) +{ + OUString sFixPath; + sal_Int32 nDestStep = 0; + sal_Int32 nSourceCount = lSource.getLength(); + // Copy entries to destination and expand every item with 2 supported sub properties. + for( sal_Int32 nSourceStep = 0; nSourceStep < nSourceCount; ++nSourceStep ) + { + sFixPath = SETNODE_ALLFILEFORMATS; + sFixPath += PATHDELIMITER; + sFixPath += lSource[ nSourceStep ]; + sFixPath += PATHDELIMITER; + + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_MODULE; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_USEPRTMETRICS; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_ADDSPACING; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_ADDSPACINGATPAGES; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_USEOURTABSTOPS; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_NOEXTLEADING; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_USELINESPACING; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_ADDTABLESPACING; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_USEOBJPOS; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_USEOURTEXTWRAP; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_CONSIDERWRAPSTYLE; + ++nDestStep; + lDestination[nDestStep] = sFixPath; + lDestination[nDestStep] += PROPERTYNAME_EXPANDWORDSPACE; + ++nDestStep; + } +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtCompatibilityOptions_Impl* SvtCompatibilityOptions::m_pDataContainer = NULL; +sal_Int32 SvtCompatibilityOptions::m_nRefCount = 0; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtCompatibilityOptions::SvtCompatibilityOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + m_pDataContainer = new SvtCompatibilityOptions_Impl; + ItemHolder1::holdConfigItem(E_COMPATIBILITY); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtCompatibilityOptions::~SvtCompatibilityOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCompatibilityOptions::Clear() +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->Clear(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtCompatibilityOptions::AppendItem( const ::rtl::OUString& sName, + const ::rtl::OUString& sModule, + bool bUsePrtMetrics, + bool bAddSpacing, + bool bAddSpacingAtPages, + bool bUseOurTabStops, + bool bNoExtLeading, + bool bUseLineSpacing, + bool bAddTableSpacing, + bool bUseObjPos, + bool bUseOurTextWrapping, + bool bConsiderWrappingStyle, + bool bExpandWordSpace ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->AppendItem( + sName, sModule, bUsePrtMetrics, bAddSpacing, + bAddSpacingAtPages, bUseOurTabStops, bNoExtLeading, + bUseLineSpacing, bAddTableSpacing, bUseObjPos, + bUseOurTextWrapping, bConsiderWrappingStyle, bExpandWordSpace ); +} + +bool SvtCompatibilityOptions::IsUsePrtDevice() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsUsePrtDevice(); +} + +bool SvtCompatibilityOptions::IsAddSpacing() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsAddSpacing(); +} + +bool SvtCompatibilityOptions::IsAddSpacingAtPages() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsAddSpacingAtPages(); +} + +bool SvtCompatibilityOptions::IsUseOurTabStops() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsUseOurTabStops(); +} + +bool SvtCompatibilityOptions::IsNoExtLeading() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsNoExtLeading(); +} + +bool SvtCompatibilityOptions::IsUseLineSpacing() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsUseLineSpacing(); +} + +bool SvtCompatibilityOptions::IsAddTableSpacing() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsAddTableSpacing(); +} + +bool SvtCompatibilityOptions::IsUseObjectPositioning() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsUseObjPos(); +} + +bool SvtCompatibilityOptions::IsUseOurTextWrapping() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsUseOurTextWrapping(); +} + +bool SvtCompatibilityOptions::IsConsiderWrappingStyle() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsConsiderWrappingStyle(); +} + +bool SvtCompatibilityOptions::IsExpandWordSpace() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsExpandWordSpace(); +} + +Sequence< Sequence< PropertyValue > > SvtCompatibilityOptions::GetList() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetList(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtCompatibilityOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} + diff --git a/unotools/source/config/configitem.cxx b/unotools/source/config/configitem.cxx new file mode 100644 index 000000000000..e191f471057a --- /dev/null +++ b/unotools/source/config/configitem.cxx @@ -0,0 +1,1422 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include "unotools/configitem.hxx" +#include "unotools/configmgr.hxx" +#include "unotools/configpathes.hxx" +#include <comphelper/processfactory.hxx> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XHierarchicalName.hpp> +#include <com/sun/star/configuration/XTemplateContainer.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/awt/XRequestCallback.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/util/XStringEscape.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <osl/diagnose.h> +#include <tools/solarmutex.hxx> +#include <rtl/ustrbuf.hxx> + +using namespace utl; +using rtl::OUString; +using rtl::OString; +using namespace com::sun::star::uno; +using namespace com::sun::star::util; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace com::sun::star::configuration; + +#define C2U(cChar) OUString::createFromAscii(cChar) +#include <cppuhelper/implbase1.hxx> // helper for implementations + +#ifdef DBG_UTIL +inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx) +{ + OString sMsg(cText); + sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); +} +#define CATCH_INFO(a) \ +catch(Exception& rEx) \ +{ \ + lcl_CFG_DBG_EXCEPTION(a, rEx);\ +} +#else + #define lcl_CFG_DBG_EXCEPTION( a, b) + #define CATCH_INFO(a) catch(Exception& ){} +#endif + +/* + The ConfigChangeListener_Impl receives notifications from the configuration about changes that + have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its + "CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired + before doing so. +*/ + +namespace utl{ + class ConfigChangeListener_Impl : public cppu::WeakImplHelper1 + < + com::sun::star::util::XChangesListener + > + { + public: + ConfigItem* pParent; + const Sequence< OUString > aPropertyNames; + ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames); + ~ConfigChangeListener_Impl(); + + //XChangesListener + virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException); + + //XEventListener + virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); + }; +/* -----------------------------12.02.01 11:38-------------------------------- + + ---------------------------------------------------------------------------*/ +struct ConfigItem_Impl +{ + utl::ConfigManager* pManager; + sal_Int16 nMode; + sal_Bool bIsModified; + sal_Bool bEnableInternalNotification; + + sal_Int16 nInValueChange; + ConfigItem_Impl() : + pManager(0), + nMode(0), + bIsModified(sal_False), + bEnableInternalNotification(sal_False), + nInValueChange(0) + {} +}; +} +/* -----------------------------04.12.00 10:25-------------------------------- + + ---------------------------------------------------------------------------*/ +class ValueCounter_Impl +{ + sal_Int16& rCnt; +public: + ValueCounter_Impl(sal_Int16& rCounter): + rCnt(rCounter) + {rCnt++;} + ~ValueCounter_Impl() + { + OSL_ENSURE(rCnt>0, "RefCount < 0 ??"); + rCnt--; + } +}; +/* -----------------------------03.12.02 ------------------------------------- + + ---------------------------------------------------------------------------*/ +namespace +{ + // helper to achieve exception - safe handling of an Item under construction + template <class TYP> + class AutoDeleter // : Noncopyable + { + TYP* m_pItem; + public: + AutoDeleter(TYP * pItem) + : m_pItem(pItem) + { + } + + ~AutoDeleter() + { + delete m_pItem; + } + + void keep() { m_pItem = 0; } + }; +} +/* -----------------------------29.08.00 16:34-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigChangeListener_Impl::ConfigChangeListener_Impl( + ConfigItem& rItem, const Sequence< OUString >& rNames) : + pParent(&rItem), + aPropertyNames(rNames) +{ +} +/* -----------------------------29.08.00 16:34-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigChangeListener_Impl::~ConfigChangeListener_Impl() +{ +} +/* -----------------------------29.08.00 16:34-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool lcl_Find( + const rtl::OUString& rTemp, + const OUString* pCheckPropertyNames, + sal_Int32 nLength) +{ + //return true if the path is completely correct or if it is longer + //i.e ...Print/Content/Graphic and .../Print + for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++) + if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) ) + return sal_True; + return sal_False; +} +//----------------------------------------------------------------------------- +void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException) +{ + const ElementChange* pElementChanges = rEvent.Changes.getConstArray(); + + Sequence<OUString> aChangedNames(rEvent.Changes.getLength()); + OUString* pNames = aChangedNames.getArray(); + + const OUString* pCheckPropertyNames = aPropertyNames.getConstArray(); + + sal_Int32 nNotify = 0; + for(int i = 0; i < aChangedNames.getLength(); i++) + { + OUString sTemp; + pElementChanges[i].Accessor >>= sTemp; + if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength())) + pNames[nNotify++] = sTemp; + } + if( nNotify ) + { + if ( ::tools::SolarMutex::Acquire() ) + { + aChangedNames.realloc(nNotify); + pParent->CallNotify(aChangedNames); + ::tools::SolarMutex::Release(); + } + } +} + +/* -----------------------------29.08.00 16:34-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException) +{ + pParent->RemoveChangesListener(); +} +/* -----------------------------29.08.00 12:50-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigItem::ConfigItem(const OUString rSubTree, sal_Int16 nSetMode ) : + sSubTree(rSubTree), + pImpl(new ConfigItem_Impl) +{ + AutoDeleter<ConfigItem_Impl> aNewImpl(pImpl); + + pImpl->pManager = ConfigManager::GetConfigManager(); + pImpl->nMode = nSetMode; + if(0 != (nSetMode&CONFIG_MODE_RELEASE_TREE)) + pImpl->pManager->AddConfigItem(*this); + else + m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this); + + // no more exceptions after c'tor has finished + aNewImpl.keep(); + pImpl->nMode &= ~CONFIG_MODE_PROPAGATE_ERRORS; +} +/* -----------------------------17.11.00 13:53-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigItem::ConfigItem(utl::ConfigManager& rManager, const rtl::OUString rSubTree) : + sSubTree(rSubTree), + pImpl(new ConfigItem_Impl) +{ + pImpl->pManager = &rManager; + pImpl->nMode = CONFIG_MODE_IMMEDIATE_UPDATE; // does not allow exceptions + m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this); +} +//--------------------------------------------------------------------- +//--- 02.08.2002 16:33:23 ----------------------------------------------- +sal_Bool ConfigItem::IsValidConfigMgr() const +{ + return ( pImpl->pManager && pImpl->pManager->GetConfigurationProvider().is() ); +} + +/* -----------------------------29.08.00 12:52-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigItem::~ConfigItem() +{ + if(pImpl->pManager) + { + RemoveChangesListener(); + pImpl->pManager->RemoveConfigItem(*this); + } + delete pImpl; +} +/* -----------------------------29.08.00 12:52-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::ReleaseConfigMgr() +{ + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + try + { + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + xBatch->commitChanges(); + } + CATCH_INFO("Exception from commitChanges(): ") + } + RemoveChangesListener(); + OSL_ENSURE(pImpl->pManager, "ConfigManager already released"); + pImpl->pManager = 0; +} +/* -----------------------------29.08.00 12:52-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames ) +{ + // the call is forwarded to the virtual Notify() method + // it is pure virtual, so all classes deriving from ConfigItem have to decide how they + // want to notify listeners + if(!IsInValueChange() || pImpl->bEnableInternalNotification) + Notify(rPropertyNames); +} + +/* -----------------------------12.12.00 17:09-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool lcl_IsLocalProperty(const OUString& rSubTree, const OUString& rProperty) +{ + static const sal_Char* aLocalProperties[] = + { + "Office.Common/Path/Current/Storage", + "Office.Common/Path/Current/Temp" + }; + static const int aLocalPropLen[] = + { + 34, + 31 + }; + OUString sProperty(rSubTree); + sProperty += C2U("/"); + sProperty += rProperty; + + if(sProperty.equalsAsciiL( aLocalProperties[0], aLocalPropLen[0]) || + sProperty.equalsAsciiL( aLocalProperties[1], aLocalPropLen[1])) + return sal_True; + + return sal_False; +} +/* -----------------------------10.04.01 15:00-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& lInNames , + const Sequence< Any >& lInValues , + Sequence< Any >& lOutValues ) +{ + // Safe impossible cases. + // This method should be called for special ConfigItem-mode only! + OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" ); + + sal_Int32 nSourceCounter ; // used to step during input lists + sal_Int32 nSourceSize ; // marks end of loop over input lists + sal_Int32 nDestinationCounter ; // actual position in output lists + sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue > + sal_Int32 nPropertiesSize ; // marks end of inner loop + Sequence< OUString > lPropertyNames ; // list of all locales for localized entry + Sequence< PropertyValue > lProperties ; // localized values of an configuration entry packed for return + Reference< XInterface > xLocalizedNode ; // if cfg entry is localized ... lInValues contains an XInterface! + + // Optimise follow algorithm ... A LITTLE BIT :-) + // There exist two different possibilities: + // i ) There exist no localized entries ... => size of lOutValues will be the same like lInNames/lInValues! + // ii) There exist some (mostly one or two) localized entries ... => size of lOutValues will be the same like lInNames/lInValues! + // ... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service). + // We read all his child nodes and pack it into Sequence< PropertyValue >. + // The result list we pack into the return any. We never change size of lists! + nSourceSize = lInNames.getLength(); + lOutValues.realloc( nSourceSize ); + + // Algorithm: + // Copy all names and values from in to out lists. + // Look for special localized entries ... You can detect it as "XInterface" packed into an Any. + // Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >. + // Add this list to out lists then. + + nDestinationCounter = 0; + for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter ) + { + // If item a special localized one ... convert and pack it ... + if( lInValues[nSourceCounter].getValueTypeName() == C2U("com.sun.star.uno.XInterface") ) + { + lInValues[nSourceCounter] >>= xLocalizedNode; + Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY ); + if( xSetAccess.is() == sal_True ) + { + lPropertyNames = xSetAccess->getElementNames() ; + nPropertiesSize = lPropertyNames.getLength() ; + lProperties.realloc( nPropertiesSize ) ; + + for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter ) + { + #if OSL_DEBUG_LEVEL > 1 + // Sometimes it's better to see what's going on :-) + OUString sPropName = lInNames[nSourceCounter]; + OUString sLocaleName = lPropertyNames[nPropertyCounter]; + #endif + lProperties[nPropertyCounter].Name = lPropertyNames[nPropertyCounter] ; + OUString sLocaleValue; + xSetAccess->getByName( lPropertyNames[nPropertyCounter] ) >>= sLocaleValue ; + lProperties[nPropertyCounter].Value <<= sLocaleValue; + } + + lOutValues[nDestinationCounter] <<= lProperties; + } + } + // ... or copy normal items to return lists directly. + else + { + lOutValues[nDestinationCounter] = lInValues[nSourceCounter]; + } + ++nDestinationCounter; + } +} +/* -----------------------------10.04.01 15:00-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::impl_unpackLocalizedProperties( const Sequence< OUString >& lInNames , + const Sequence< Any >& lInValues , + Sequence< OUString >& lOutNames , + Sequence< Any >& lOutValues ) +{ + // Safe impossible cases. + // This method should be called for special ConfigItem-mode only! + OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_unpackLocalizedProperties()\nWrong call of this method detected!\n" ); + + sal_Int32 nSourceCounter ; // used to step during input lists + sal_Int32 nSourceSize ; // marks end of loop over input lists + sal_Int32 nDestinationCounter ; // actual position in output lists + sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue > + sal_Int32 nPropertiesSize ; // marks end of inner loop + OUString sNodeName ; // base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" ) + Sequence< PropertyValue > lProperties ; // localized values of an configuration entry getted from lInValues-Any + + // Optimise follow algorithm ... A LITTLE BIT :-) + // There exist two different possibilities: + // i ) There exist no localized entries ... => size of lOutNames/lOutValues will be the same like lInNames/lInValues! + // ii) There exist some (mostly one or two) localized entries ... => size of lOutNames/lOutValues will be some bytes greater then lInNames/lInValues. + // => I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast. + // We should reserve same space for output list like input ones first. + // Follow algorithm looks for these borders and change it for ii) only! + // It will be faster then a "realloc()" call in every loop ... + nSourceSize = lInNames.getLength(); + + lOutNames.realloc ( nSourceSize ); + lOutValues.realloc ( nSourceSize ); + + // Algorithm: + // Copy all names and values from const to return lists. + // Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any. + // Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues. + + nDestinationCounter = 0; + for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter ) + { + // If item a special localized one ... split it and insert his parts to output lists ... + if( lInValues[nSourceCounter].getValueType() == ::getCppuType( (const Sequence< PropertyValue >*)NULL ) ) + { + lInValues[nSourceCounter] >>= lProperties ; + sNodeName = lInNames[nSourceCounter] ; + sNodeName += C2U("/") ; + nPropertiesSize = lProperties.getLength() ; + + if( (nDestinationCounter+nPropertiesSize) > lOutNames.getLength() ) + { + lOutNames.realloc ( nDestinationCounter+nPropertiesSize ); + lOutValues.realloc ( nDestinationCounter+nPropertiesSize ); + } + + for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter ) + { + lOutNames [nDestinationCounter] = sNodeName + lProperties[nPropertyCounter].Name ; + lOutValues[nDestinationCounter] = lProperties[nPropertyCounter].Value ; + ++nDestinationCounter; + } + } + // ... or copy normal items to return lists directly. + else + { + if( (nDestinationCounter+1) > lOutNames.getLength() ) + { + lOutNames.realloc ( nDestinationCounter+1 ); + lOutValues.realloc ( nDestinationCounter+1 ); + } + + lOutNames [nDestinationCounter] = lInNames [nSourceCounter]; + lOutValues[nDestinationCounter] = lInValues[nSourceCounter]; + ++nDestinationCounter; + } + } +} +/* -----------------------------03.02.2003 14:44------------------------------ + + ---------------------------------------------------------------------------*/ +Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const com::sun::star::uno::Sequence< rtl::OUString >& rNames) +{ + sal_Int32 i; + + // size of return list is fix! + // Every item must match to length of incoming name list. + sal_Int32 nCount = rNames.getLength(); + Sequence< sal_Bool > lStates(nCount); + + // We must be shure to return a valid information everytime! + // Set default to non readonly ... similar to the configuration handling of this property. + for ( i=0; i<nCount; ++i) + lStates[i] = sal_False; + + // no access - no informations ... + Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree(); + if (!xHierarchyAccess.is()) + return lStates; + + for (i=0; i<nCount; ++i) + { + try + { + if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, rNames[i])) + { + OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nlocal mode seams to be used!?\n"); + continue; + } + + OUString sName = rNames[i]; + OUString sPath; + OUString sProperty; + + ::utl::splitLastFromConfigurationPath(sName,sPath,sProperty); + if (!sPath.getLength() && !sProperty.getLength()) + { + OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nsplitt failed\n"); + continue; + } + + Reference< XInterface > xNode; + Reference< XPropertySet > xSet ; + Reference< XPropertySetInfo > xInfo; + if (sPath.getLength()) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(sPath); + if (!(aNode >>= xNode) || !xNode.is()) + { + OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno set available\n"); + continue; + } + } + else + { + xNode = Reference< XInterface >(xHierarchyAccess, UNO_QUERY); + } + + xSet = Reference< XPropertySet >(xNode, UNO_QUERY); + if (xSet.is()) + { + xInfo = xSet->getPropertySetInfo(); + OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\ngetPropertySetInfo failed ...\n"); + } + else + { + xInfo = Reference< XPropertySetInfo >(xNode, UNO_QUERY); + OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\nUNO_QUERY failed ...\n"); + } + + if (!xInfo.is()) + { + OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno prop info available\n"); + continue; + } + + Property aProp = xInfo->getPropertyByName(sProperty); + lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY); + } + catch(Exception&){} + } + + return lStates; +} + +/* -----------------------------29.08.00 15:10-------------------------------- + + ---------------------------------------------------------------------------*/ +Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames) +{ + Sequence< Any > aRet(rNames.getLength()); + const OUString* pNames = rNames.getConstArray(); + Any* pRet = aRet.getArray(); + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + for(int i = 0; i < rNames.getLength(); i++) + { + try + { + if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i])) + { + OUString sProperty(sSubTree); + sProperty += C2U("/"); + sProperty += pNames[i]; + pRet[i] = pImpl->pManager->GetLocalProperty(sProperty); + } + else + pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]); + } + catch(Exception& rEx) + { +#if OSL_DEBUG_LEVEL > 0 + OString sMsg("XHierarchicalNameAccess: "); + sMsg += OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + sMsg += OString("\n"); + sMsg += OString(ConfigManager::GetConfigBaseURL().getStr(), + ConfigManager::GetConfigBaseURL().getLength(), + RTL_TEXTENCODING_ASCII_US); + sMsg += OString(sSubTree.getStr(), + sSubTree.getLength(), + RTL_TEXTENCODING_ASCII_US); + sMsg += OString("/"); + sMsg += OString(pNames[i].getStr(), + pNames[i].getLength(), + RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); +#else + (void) rEx; // avoid warning +#endif + } + } + + // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >. + if((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES) + { + Sequence< Any > lValues; + impl_packLocalizedProperties( rNames, aRet, lValues ); + aRet = lValues; + } + } + return aRet; +} +/* -----------------------------29.08.00 17:28-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::PutProperties( const Sequence< OUString >& rNames, + const Sequence< Any>& rValues) +{ + ValueCounter_Impl aCounter(pImpl->nInValueChange); + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY); + sal_Bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is(); + if(bRet) + { + Sequence< OUString > lNames ; + Sequence< Any > lValues ; + const OUString* pNames = NULL ; + const Any* pValues = NULL ; + sal_Int32 nNameCount ; + if(( pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES ) + { + // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue > + // as value of an localized configuration entry! + // How we can do that? + // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"! + impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues ); + pNames = lNames.getConstArray (); + pValues = lValues.getConstArray (); + nNameCount = lNames.getLength (); + } + else + { + // This is the normal mode ... + // Use given input lists directly. + pNames = rNames.getConstArray (); + pValues = rValues.getConstArray (); + nNameCount = rNames.getLength (); + } + for(int i = 0; i < nNameCount; i++) + { + if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i])) + { + OUString sProperty(sSubTree); + sProperty += C2U("/"); + sProperty += pNames[i]; + pImpl->pManager->PutLocalProperty(sProperty, pValues[i]); + } + else + { + try + { + OUString sNode, sProperty; + if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty)) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(sNode); + + Reference<XNameAccess> xNodeAcc; + aNode >>= xNodeAcc; + Reference<XNameReplace> xNodeReplace(xNodeAcc, UNO_QUERY); + Reference<XNameContainer> xNodeCont (xNodeAcc, UNO_QUERY); + + sal_Bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty)); + if (bExist && xNodeReplace.is()) + xNodeReplace->replaceByName(sProperty, pValues[i]); + else + if (!bExist && xNodeCont.is()) + xNodeCont->insertByName(sProperty, pValues[i]); + else + bRet = sal_False; + } + else //direct value + { + xTopNodeReplace->replaceByName(sProperty, pValues[i]); + } + } + CATCH_INFO("Exception from PutProperties: "); + } + } + try + { + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + xBatch->commitChanges(); + } + CATCH_INFO("Exception from commitChanges(): ") + } + + return bRet; +} +/* -----------------------------08.12.05 15:27-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::DisableNotification() +{ + OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" ); + RemoveChangesListener(); +} +/* -----------------------------29.08.00 16:19-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::EnableNotification(const Sequence< OUString >& rNames, + sal_Bool bEnableInternalNotification ) + +{ + OSL_ENSURE(0 == (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "notification in CONFIG_MODE_RELEASE_TREE mode not possible"); + pImpl->bEnableInternalNotification = bEnableInternalNotification; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY); + if(!xChgNot.is()) + return sal_False; + + OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called"); + if(xChangeLstnr.is()) + xChgNot->removeChangesListener( xChangeLstnr ); + sal_Bool bRet = sal_True; + + try + { + xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames); + xChgNot->addChangesListener( xChangeLstnr ); + } + catch(RuntimeException& ) + { + bRet = sal_False; + } + return bRet; +} +/* -----------------------------29.08.00 16:47-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::RemoveChangesListener() +{ + Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY); + if(xChgNot.is() && xChangeLstnr.is()) + { + try + { + xChgNot->removeChangesListener( xChangeLstnr ); + xChangeLstnr = 0; + } + catch(Exception & ) + { + } + } +} +/* -----------------------------10.07.00 -------------------------------- + + ---------------------------------------------------------------------------*/ +void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode) +{ + switch (_eFormat) + { + case CONFIG_NAME_LOCAL_NAME: + // unaltered - this is our input format + break; + + case CONFIG_NAME_FULL_PATH: + { + Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY); + if (xFormatter.is()) + { + OUString * pNames = _rNames.getArray(); + for(int i = 0; i<_rNames.getLength(); ++i) + try + { + pNames[i] = xFormatter->composeHierarchicalName(pNames[i]); + } + CATCH_INFO("Exception from composeHierarchicalName(): ") + break; + } + } + OSL_ENSURE(false, "Cannot create absolute pathes: missing interface"); + // make local pathes instaed + + case CONFIG_NAME_LOCAL_PATH: + { + Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY); + if (xTypeContainer.is()) + { + OUString sTypeName = xTypeContainer->getElementTemplateName(); + sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1); + + OUString * pNames = _rNames.getArray(); + for(int i = 0; i<_rNames.getLength(); ++i) + { + pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName); + } + } + else + { + static const OUString sSetService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.SetAccess")); + Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY); + if (xSVI.is() && xSVI->supportsService(sSetService)) + { + OUString * pNames = _rNames.getArray(); + for(int i = 0; i<_rNames.getLength(); ++i) + { + pNames[i] = wrapConfigurationElementName(pNames[i]); + } + } + } + } + break; + + case CONFIG_NAME_PLAINTEXT_NAME: + { + Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY); + if (xEscaper.is()) + { + OUString * pNames = _rNames.getArray(); + for(int i = 0; i<_rNames.getLength(); ++i) + try + { + pNames[i] = xEscaper->unescapeString(pNames[i]); + } + CATCH_INFO("Exception from unescapeString(): ") + } + } + break; + + } +} +/* -----------------------------10.07.00 -------------------------------- + + ---------------------------------------------------------------------------*/ +Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode) +{ + ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT; + + return GetNodeNames(rNode, eDefaultFormat); +} +/* -----------------------------15.09.00 12:06-------------------------------- + + ---------------------------------------------------------------------------*/ +Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat) +{ + Sequence< OUString > aRet; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + try + { + Reference<XNameAccess> xCont; + if(rNode.getLength()) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY); + if(xCont.is()) + { + aRet = xCont->getElementNames(); + lcl_normalizeLocalNames(aRet,eFormat,xCont); + } + + } + CATCH_INFO("Exception from GetNodeNames: "); + } + return aRet; +} +/* -----------------------------15.09.00 15:52-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::ClearNodeSet(const OUString& rNode) +{ + ValueCounter_Impl aCounter(pImpl->nInValueChange); + sal_Bool bRet = sal_False; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + try + { + Reference<XNameContainer> xCont; + if(rNode.getLength()) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return sal_False; + Sequence< OUString > aNames = xCont->getElementNames(); + const OUString* pNames = aNames.getConstArray(); + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + for(sal_Int32 i = 0; i < aNames.getLength(); i++) + { + try + { + xCont->removeByName(pNames[i]); + } + CATCH_INFO("Exception from removeByName(): ") + } + xBatch->commitChanges(); + bRet = sal_True; + } + CATCH_INFO("Exception from ClearNodeSet") + } + return bRet; +} +/* -----------------------------24.11.00 10:58-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements) +{ + ValueCounter_Impl aCounter(pImpl->nInValueChange); + sal_Bool bRet = sal_False; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + const OUString* pElements = rElements.getConstArray(); + try + { + Reference<XNameContainer> xCont; + if(rNode.getLength()) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return sal_False; + try + { + for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++) + { + xCont->removeByName(pElements[nElement]); + } + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + xBatch->commitChanges(); + } + CATCH_INFO("Exception from commitChanges(): ") + bRet = sal_True; + } + CATCH_INFO("Exception from GetNodeNames: ") + } + return bRet; +} +//---------------------------------------------------------------------------- +static inline +OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix ) +{ + OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix); + return extractFirstFromConfigurationPath( sSubPath ); +} +//---------------------------------------------------------------------------- +static +Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix ) +{ + const PropertyValue* pProperties = rValues.getConstArray(); + + Sequence< OUString > aSubNodeNames(rValues.getLength()); + OUString* pSubNodeNames = aSubNodeNames.getArray(); + + OUString sLastSubNode; + sal_Int32 nSubIndex = 0; + + for(sal_Int32 i = 0; i < rValues.getLength(); i++) + { + OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix); + OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath ); + + if(sLastSubNode != sSubNode) + { + pSubNodeNames[nSubIndex++] = sSubNode; + } + + sLastSubNode = sSubNode; + } + aSubNodeNames.realloc(nSubIndex); + + return aSubNodeNames; +} +/* -----------------------------15.09.00 15:52-------------------------------- + add or change properties + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::SetSetProperties( + const OUString& rNode, Sequence< PropertyValue > rValues) +{ + ValueCounter_Impl aCounter(pImpl->nInValueChange); + sal_Bool bRet = sal_True; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + try + { + Reference<XNameContainer> xCont; + if(rNode.getLength()) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return sal_False; + + Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); + + if(xFac.is()) + { + const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); + + const sal_Int32 nSubNodeCount = aSubNodeNames.getLength(); + + for(sal_Int32 j = 0; j <nSubNodeCount ; j++) + { + if(!xCont->hasByName(aSubNodeNames[j])) + { + Reference<XInterface> xInst = xFac->createInstance(); + Any aVal; aVal <<= xInst; + xCont->insertByName(aSubNodeNames[j], aVal); + } + //set values + } + try + { + xBatch->commitChanges(); + } + CATCH_INFO("Exception from commitChanges(): ") + + const PropertyValue* pProperties = rValues.getConstArray(); + + Sequence< OUString > aSetNames(rValues.getLength()); + OUString* pSetNames = aSetNames.getArray(); + + Sequence< Any> aSetValues(rValues.getLength()); + Any* pSetValues = aSetValues.getArray(); + + sal_Bool bEmptyNode = rNode.getLength() == 0; + for(sal_Int32 k = 0; k < rValues.getLength(); k++) + { + pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); + pSetValues[k] = pProperties[k].Value; + } + bRet = PutProperties(aSetNames, aSetValues); + } + else + { + //if no factory is available then the node contains basic data elements + const PropertyValue* pValues = rValues.getConstArray(); + for(int nValue = 0; nValue < rValues.getLength();nValue++) + { + try + { + OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode ); + + if(xCont->hasByName(sSubNode)) + xCont->replaceByName(sSubNode, pValues[nValue].Value); + else + xCont->insertByName(sSubNode, pValues[nValue].Value); + + OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name), + "Invalid config path" ); + } + CATCH_INFO("Exception form insert/replaceByName(): ") + } + xBatch->commitChanges(); + } + } +#ifdef DBG_UTIL + catch(Exception& rEx) + { + lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx); +#else + catch(Exception&) + { +#endif + bRet = sal_False; + } + } + return bRet; +} +/* -----------------------------15.09.00 15:52-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::ReplaceSetProperties( + const OUString& rNode, Sequence< PropertyValue > rValues) +{ + ValueCounter_Impl aCounter(pImpl->nInValueChange); + sal_Bool bRet = sal_True; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + try + { + Reference<XNameContainer> xCont; + if(rNode.getLength()) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return sal_False; + + // JB: Change: now the same name handling for sets of simple values + const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); + const OUString* pSubNodeNames = aSubNodeNames.getConstArray(); + const sal_Int32 nSubNodeCount = aSubNodeNames.getLength(); + + Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); + const bool isSimpleValueSet = !xFac.is(); + + //remove unknown members first + { + const Sequence<OUString> aContainerSubNodes = xCont->getElementNames(); + const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray(); + + for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++) + { + sal_Bool bFound = sal_False; + for(sal_Int32 j = 0; j < nSubNodeCount; j++) + { + if(pSubNodeNames[j] == pContainerSubNodes[nContSub]) + { + bFound = sal_True; + break; + } + } + if(!bFound) + try + { + xCont->removeByName(pContainerSubNodes[nContSub]); + } + catch (Exception & ) + { + if (isSimpleValueSet) + try + { + // #i37322#: fallback action: replace with <void/> + xCont->replaceByName(pContainerSubNodes[nContSub], Any()); + // fallback successfull: continue looping + continue; + } + catch (Exception &) + {} // propagate original exception, if fallback fails + + throw; + } + } + try { xBatch->commitChanges(); } + CATCH_INFO("Exception from commitChanges(): ") + } + + if(xFac.is()) // !isSimpleValueSet + { + for(sal_Int32 j = 0; j < nSubNodeCount; j++) + { + if(!xCont->hasByName(pSubNodeNames[j])) + { + //create if not available + Reference<XInterface> xInst = xFac->createInstance(); + Any aVal; aVal <<= xInst; + xCont->insertByName(pSubNodeNames[j], aVal); + } + } + try { xBatch->commitChanges(); } + CATCH_INFO("Exception from commitChanges(): ") + + const PropertyValue* pProperties = rValues.getConstArray(); + + Sequence< OUString > aSetNames(rValues.getLength()); + OUString* pSetNames = aSetNames.getArray(); + + Sequence< Any> aSetValues(rValues.getLength()); + Any* pSetValues = aSetValues.getArray(); + + sal_Bool bEmptyNode = rNode.getLength() == 0; + for(sal_Int32 k = 0; k < rValues.getLength(); k++) + { + pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); + pSetValues[k] = pProperties[k].Value; + } + bRet = PutProperties(aSetNames, aSetValues); + } + else + { + const PropertyValue* pValues = rValues.getConstArray(); + + //if no factory is available then the node contains basic data elements + for(int nValue = 0; nValue < rValues.getLength();nValue++) + { + try + { + OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode ); + + if(xCont->hasByName(sSubNode)) + xCont->replaceByName(sSubNode, pValues[nValue].Value); + else + xCont->insertByName(sSubNode, pValues[nValue].Value); + } + CATCH_INFO("Exception from insert/replaceByName(): "); + } + xBatch->commitChanges(); + } + } +#ifdef DBG_UTIL + catch(Exception& rEx) + { + lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx); +#else + catch(Exception&) + { +#endif + bRet = sal_False; + } + } + return bRet; +} +/* -----------------------------07.05.01 12:15-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::getUniqueSetElementName( const ::rtl::OUString& _rSetNode, ::rtl::OUString& _rName) +{ + ::rtl::OUString sNewElementName; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + sal_Bool bRet = sal_False; + if(xHierarchyAccess.is()) + { + try + { + Reference< XNameAccess > xSetNode; + xHierarchyAccess->getByHierarchicalName(_rSetNode) >>= xSetNode; + if (xSetNode.is()) + { + const sal_uInt32 nPrime = 65521; // a prime number + const sal_uInt32 nPrimeLess2 = nPrime - 2; + sal_uInt32 nEngendering = (rand() % nPrimeLess2) + 2; // the engendering of the field + + // the element which will loop through the field + sal_uInt32 nFieldElement = nEngendering; + + for (; 1 != nFieldElement; nFieldElement = (nFieldElement * nEngendering) % nPrime) + { + ::rtl::OUString sThisRoundTrial = _rName; + sThisRoundTrial += ::rtl::OUString::valueOf((sal_Int32)nFieldElement); + + if (!xSetNode->hasByName(sThisRoundTrial)) + { + _rName = sThisRoundTrial; + bRet = sal_True; + break; + } + } + } + } + CATCH_INFO("Exception from getUniqueSetElementName(): ") + } + return bRet; +} +/* -----------------------------23.01.01 12:49-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::AddNode(const rtl::OUString& rNode, const rtl::OUString& rNewNode) +{ + ValueCounter_Impl aCounter(pImpl->nInValueChange); + sal_Bool bRet = sal_True; + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + { + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + try + { + Reference<XNameContainer> xCont; + if(rNode.getLength()) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return sal_False; + + Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); + + if(xFac.is()) + { + if(!xCont->hasByName(rNewNode)) + { + Reference<XInterface> xInst = xFac->createInstance(); + Any aVal; aVal <<= xInst; + xCont->insertByName(rNewNode, aVal); + } + try + { + xBatch->commitChanges(); + } + CATCH_INFO("Exception from commitChanges(): ") + } + else + { + //if no factory is available then the node contains basic data elements + try + { + if(!xCont->hasByName(rNewNode)) + xCont->insertByName(rNewNode, Any()); + } + CATCH_INFO("Exception from AddNode(): ") + } + xBatch->commitChanges(); + } +#ifdef DBG_UTIL + catch(Exception& rEx) + { + lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx); +#else + catch(Exception&) + { +#endif + bRet = sal_False; + } + } + return bRet; +} +/* -----------------------------12.02.01 11:38-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Int16 ConfigItem::GetMode() const +{ + return pImpl->nMode; +} +/* -----------------------------12.02.01 13:31-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::SetModified() +{ + pImpl->bIsModified = sal_True; +} +/* -----------------------------05.05.01 14:07-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::ClearModified() +{ + pImpl->bIsModified = sal_False; +} +/* -----------------------------12.02.01 13:31-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::IsModified() const +{ + return pImpl->bIsModified; +} +/* -----------------------------12.02.01 13:33-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigItem::IsInValueChange() const +{ + return pImpl->nInValueChange > 0; +} +/* -----------------------------21.06.01 12:26-------------------------------- + + ---------------------------------------------------------------------------*/ +Reference< XHierarchicalNameAccess> ConfigItem::GetTree() +{ + Reference< XHierarchicalNameAccess> xRet; + if(!m_xHierarchyAccess.is()) + xRet = pImpl->pManager->AcquireTree(*this); + else + xRet = m_xHierarchyAccess; + OSL_ENSURE(xRet.is(), "AcquireTree failed"); + return xRet; +} +/* -----------------------------22.06.01 08:42-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::LockTree() +{ + OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call LockTree in CONFIG_MODE_RELEASE_TREE mode, only"); + m_xHierarchyAccess = GetTree(); +} +/* -----------------------------22.06.01 08:42-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigItem::UnlockTree() +{ + OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call UnlockTree in CONFIG_MODE_RELEASE_TREE mode, only"); + if(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE)) + m_xHierarchyAccess = 0; +} + + diff --git a/unotools/source/config/configmgr.cxx b/unotools/source/config/configmgr.cxx new file mode 100644 index 000000000000..0df6d49afe59 --- /dev/null +++ b/unotools/source/config/configmgr.cxx @@ -0,0 +1,747 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include "unotools/configmgr.hxx" +#include "unotools/configitem.hxx" +#include "unotools/configpathes.hxx" +#include <unotools/processfactory.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <osl/diagnose.h> +#include <rtl/bootstrap.hxx> +#include <rtl/instance.hxx> +#if OSL_DEBUG_LEVEL > 0 +#include <rtl/strbuf.hxx> +#endif + +#include <list> + +//----------------------------------------------------------------------------- + +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; + +#define C2U(cChar) OUString::createFromAscii(cChar) +#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) + +//----------------------------------------------------------------------------- +const char* cConfigBaseURL = "/org.openoffice."; +//const char* cConfigBaseURL = "/com.sun.star."; +const char* cAccessSrvc = "com.sun.star.configuration.ConfigurationUpdateAccess"; + +namespace +{ + struct BrandName + : public rtl::Static< ::rtl::OUString, BrandName > {}; + struct ProductVersion + : public rtl::Static< ::rtl::OUString, ProductVersion > {}; + struct AboutBoxProductVersion + : public rtl::Static< ::rtl::OUString, AboutBoxProductVersion > {}; + struct OOOVendor + : public rtl::Static< ::rtl::OUString, OOOVendor > {}; + struct ProductExtension + : public rtl::Static< ::rtl::OUString, ProductExtension > {}; + struct XMLFileFormatName + : public rtl::Static< ::rtl::OUString, XMLFileFormatName > {}; + struct XMLFileFormatVersion + : public rtl::Static< ::rtl::OUString, XMLFileFormatVersion > {}; + struct WriterCompatibilityVersionOOo11 + : public rtl::Static< ::rtl::OUString, WriterCompatibilityVersionOOo11 > {}; + struct OpenSourceContext : public rtl::StaticWithInit< sal_Int32, OpenSourceContext > + { + sal_Int32 operator() () { return sal_Int32( -1 ); } + }; + +} + +//----------------------------------------------------------------------------- +struct ConfigItemListEntry_Impl +{ + ConfigItem* pConfigItem; + + ConfigItemListEntry_Impl(ConfigItem* pItem ) : + pConfigItem(pItem){} +}; +typedef std::list<ConfigItemListEntry_Impl> ConfigItemList; +struct utl::ConfigMgr_Impl +{ + ConfigItemList aItemList; +}; + +/* -----------------------------28.08.00 15:35-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigManager::ConfigManager() : + pMgrImpl(new utl::ConfigMgr_Impl) +{ + GetConfigurationProvider(); // attempt to create the provider early +} +/* -----------------------------17.11.00 13:51-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigManager::ConfigManager(Reference< XMultiServiceFactory > xConfigProv) : + xConfigurationProvider(xConfigProv), + pMgrImpl(new utl::ConfigMgr_Impl) +{ +} +/* -----------------------------28.08.00 15:35-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigManager::~ConfigManager() +{ + //check list content -> should be empty! + OSL_ENSURE(pMgrImpl->aItemList.empty(), "some ConfigItems are still alive"); + if(!pMgrImpl->aItemList.empty()) + { + ConfigItemList::iterator aListIter; + for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter) + { + ConfigItemListEntry_Impl& rEntry = *aListIter; + rEntry.pConfigItem->ReleaseConfigMgr(); + } + pMgrImpl->aItemList.erase(pMgrImpl->aItemList.begin(), pMgrImpl->aItemList.end()); + } + delete pMgrImpl; + +} +/* -----------------------------28.08.00 16:17-------------------------------- + + ---------------------------------------------------------------------------*/ +Reference< XMultiServiceFactory > ConfigManager::GetConfigurationProvider() +{ + if(!xConfigurationProvider.is()) + { + Reference< XMultiServiceFactory > xMSF = ::utl::getProcessServiceFactory(); + if ( xMSF.is() ) + { + try + { + xConfigurationProvider = Reference< XMultiServiceFactory > + (xMSF->createInstance( + C2U("com.sun.star.configuration.ConfigurationProvider")), + UNO_QUERY); + } +#ifdef DBG_UTIL + catch(Exception& rEx) + { + static sal_Bool bMessage = sal_True; + if(bMessage) + { + bMessage = sal_False; + OString sMsg("CreateInstance with arguments exception: "); + sMsg += OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); + } + } +#else + catch(Exception&){} +#endif + } + } + return xConfigurationProvider; +} +/* -----------------------------03.12.02 ------------------------------------- + + ---------------------------------------------------------------------------*/ +namespace +{ + // helper to achieve exception - safe registration of a ConfigItem under construction + class RegisterConfigItemHelper // : Noncopyable + { + utl::ConfigManager & rCfgMgr; + utl::ConfigItem* pCfgItem; + public: + RegisterConfigItemHelper(utl::ConfigManager & rMgr, utl::ConfigItem& rCfgItem) + : rCfgMgr(rMgr) + , pCfgItem(&rCfgItem) + { + rCfgMgr.RegisterConfigItem(rCfgItem); + } + + ~RegisterConfigItemHelper() + { + if (pCfgItem) rCfgMgr.RemoveConfigItem(*pCfgItem); + } + + void keep() { pCfgItem = 0; } + }; +} +/* -----------------------------12.12.00 17:19-------------------------------- + + ---------------------------------------------------------------------------*/ +Reference< XMultiServiceFactory > ConfigManager::GetLocalConfigurationProvider() +{ + return GetConfigurationProvider(); +} +/* -----------------------------29.08.00 12:35-------------------------------- + + ---------------------------------------------------------------------------*/ +Reference< XHierarchicalNameAccess > ConfigManager::AddConfigItem(utl::ConfigItem& rCfgItem) +{ + RegisterConfigItemHelper registeredItem(*this,rCfgItem); + Reference< XHierarchicalNameAccess > xTree = AcquireTree(rCfgItem); + registeredItem.keep(); + return xTree; +} +/* -----------------------------21.06.01 12:20-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigManager::RegisterConfigItem(utl::ConfigItem& rCfgItem) +{ + ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin(); +#ifdef DBG_UTIL + for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter) + { + ConfigItemListEntry_Impl& rEntry = *aListIter; + if(rEntry.pConfigItem == &rCfgItem) + OSL_ENSURE(sal_False, "RegisterConfigItem: already inserted!"); + } +#endif + pMgrImpl->aItemList.insert(aListIter, ConfigItemListEntry_Impl(&rCfgItem)); +} +/* -----------------------------21.06.01 12:20-------------------------------- + + ---------------------------------------------------------------------------*/ +Reference< XHierarchicalNameAccess> ConfigManager::AcquireTree(utl::ConfigItem& rCfgItem) +{ + ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin(); +#ifdef DBG_UTIL + sal_Bool bFound = sal_False; + for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter) + { + ConfigItemListEntry_Impl& rEntry = *aListIter; + if(rEntry.pConfigItem == &rCfgItem) + { + bFound = sal_True; + break; + } + } + OSL_ENSURE(bFound, "AcquireTree: ConfigItem unknown!"); +#endif + OUString sPath = C2U(cConfigBaseURL); + sPath += rCfgItem.GetSubTreeName(); + Sequence< Any > aArgs(2); + Any* pArgs = aArgs.getArray(); + PropertyValue aPath; + aPath.Name = C2U("nodepath"); + aPath.Value <<= sPath; + pArgs[0] <<= aPath; + sal_Bool bLazy = 0 != (rCfgItem.GetMode()&CONFIG_MODE_DELAYED_UPDATE); + PropertyValue aUpdate; + aUpdate.Name = C2U("lazywrite"); + aUpdate.Value.setValue(&bLazy, ::getBooleanCppuType()); + pArgs[1] <<= aUpdate; + + // Initialize item with support for reading/writing more then one locales at same time! + // It's neccessary for creation of a complete configuration entry without changing office locale + // at runtime. + if((rCfgItem.GetMode() & CONFIG_MODE_ALL_LOCALES) == CONFIG_MODE_ALL_LOCALES) + { + sal_Int32 nCount = aArgs.getLength(); + aArgs.realloc(nCount+1); + + PropertyValue aAllLocale; + aAllLocale.Name = C2U("locale"); + aAllLocale.Value <<= C2U("*" ); + aArgs[nCount] <<= aAllLocale; + } + + Reference< XMultiServiceFactory > xCfgProvider = GetConfigurationProvider(); + Reference< XInterface > xIFace; + if(xCfgProvider.is()) + { + try + { + xIFace = xCfgProvider->createInstanceWithArguments( + C2U(cAccessSrvc), + aArgs); + } + catch(Exception& rEx) + { + if (CONFIG_MODE_PROPAGATE_ERRORS & rCfgItem.GetMode()) + { + OSL_TRACE("ConfigItem: Propagating creation error: %s\n", + OUStringToOString(rEx.Message,RTL_TEXTENCODING_ASCII_US).getStr()); + + throw; + } +#ifdef DBG_UTIL + if(0 == (CONFIG_MODE_IGNORE_ERRORS & rCfgItem.GetMode())) + { + OString sMsg("CreateInstance exception: "); + sMsg += OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); + } +#endif + } + } + return Reference<XHierarchicalNameAccess>(xIFace, UNO_QUERY); +} +/* -----------------------------29.08.00 12:35-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigManager::RemoveConfigItem(utl::ConfigItem& rCfgItem) +{ + if( !pMgrImpl->aItemList.empty() ) + { + ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin(); + for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter) + { + ConfigItemListEntry_Impl& rEntry = *aListIter; + if(rEntry.pConfigItem == &rCfgItem) + { + pMgrImpl->aItemList.erase(aListIter); + break; + } + } + } +} +/* -----------------------------30.08.00 15:04-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigManager::StoreConfigItems() +{ + if(!pMgrImpl->aItemList.empty()) + { + ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin(); + for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter) + { + ConfigItemListEntry_Impl& rEntry = *aListIter; + if(rEntry.pConfigItem->IsModified()) + { + rEntry.pConfigItem->Commit(); + rEntry.pConfigItem->ClearModified(); + } + } + } +} +ConfigManager* ConfigManager::pConfigManager = 0; +/* -----------------------------07.09.00 11:06-------------------------------- + + ---------------------------------------------------------------------------*/ +ConfigManager* ConfigManager::GetConfigManager() +{ + if(!pConfigManager) + { + pConfigManager = new ConfigManager(); + } + return pConfigManager; +} +/* -----------------------------07.09.00 11:06-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigManager::RemoveConfigManager() +{ + if(pConfigManager) + { + delete pConfigManager; + pConfigManager = 0; + } +} +/* -----------------------------08.09.00 13:22-------------------------------- + + ---------------------------------------------------------------------------*/ +rtl::OUString ConfigManager::GetConfigBaseURL() +{ + return C2U(cConfigBaseURL); +} +/* -----------------------------25.09.00 16:34-------------------------------- + + ---------------------------------------------------------------------------*/ +Any ConfigManager::GetDirectConfigProperty(ConfigProperty eProp) +{ + switch(eProp) + { + case INSTALLPATH: + OSL_ENSURE( false, + "ConfigManager::GetDirectConfigProperty: " + "INSTALLPATH no longer supported." ); + return Any(); + case USERINSTALLURL: + OSL_ENSURE( false, + "ConfigManager::GetDirectConfigProperty: " + "USERINSTALLURL no longer supported." ); + return Any(); + case OFFICEINSTALL: + OSL_ENSURE( false, + "ConfigManager::GetDirectConfigProperty: " + "OFFICEINSTALL no longer supported." ); + return Any(); + case OFFICEINSTALLURL: + OSL_ENSURE( false, + "ConfigManager::GetDirectConfigProperty: " + "OFFICEINSTALLURL no longer supported." ); + return Any(); + default: + break; + } + + Any aRet; + ::rtl::OUString &rBrandName = BrandName::get(); + if ( eProp == PRODUCTNAME && rBrandName.getLength() ) + { + aRet <<= rBrandName; + return aRet; + } + + rtl::OUString &rProductVersion = ProductVersion::get(); + if ( eProp == PRODUCTVERSION && rProductVersion.getLength() ) + { + aRet <<= rProductVersion; + return aRet; + } + + rtl::OUString &rAboutBoxProductVersion = AboutBoxProductVersion::get(); + if ( eProp == ABOUTBOXPRODUCTVERSION && rAboutBoxProductVersion.getLength() ) + { + aRet <<= rAboutBoxProductVersion; + return aRet; + } + + rtl::OUString &rOOOVendor = OOOVendor::get(); + if ( eProp == OOOVENDOR && rOOOVendor.getLength() ) + { + aRet <<= rOOOVendor; + return aRet; + } + + + rtl::OUString &rProductExtension = ProductExtension::get(); + if ( eProp == PRODUCTEXTENSION && rProductExtension.getLength() ) + { + aRet <<= rProductExtension; + return aRet; + } + + rtl::OUString &rXMLFileFormatName = XMLFileFormatName::get(); + if ( eProp == PRODUCTXMLFILEFORMATNAME && rXMLFileFormatName.getLength() ) + { + aRet <<= rXMLFileFormatName; + return aRet; + } + + rtl::OUString &rXMLFileFormatVersion = XMLFileFormatVersion::get(); + if ( eProp == PRODUCTXMLFILEFORMATVERSION && rXMLFileFormatVersion.getLength() ) + { + aRet <<= rXMLFileFormatVersion; + return aRet; + } + + sal_Int32 &rOpenSourceContext = OpenSourceContext::get(); + if ( eProp == OPENSOURCECONTEXT && ( rOpenSourceContext >= 0 ) ) + { + aRet <<= rOpenSourceContext; + return aRet; + } + + rtl::OUString &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get(); + if ( eProp == WRITERCOMPATIBILITYVERSIONOOO11 && rWriterCompatibilityVersionOOo11.getLength() ) + { + aRet <<= rWriterCompatibilityVersionOOo11; + return aRet; + } + + if (eProp == PRODUCTEXTENSION) { + rtl::OUString name( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "${BRAND_BASE_DIR}/program/edition/edition.ini"))); + rtl::Bootstrap::expandMacros(name); + if (rtl::Bootstrap(name).getFrom( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EDITIONNAME")), + rProductExtension)) + { + return com::sun::star::uno::Any(rProductExtension); + } + } + + OUString sPath = C2U(cConfigBaseURL); + switch(eProp) + { + case LOCALE: sPath += C2U("Setup/L10N"); break; + + case PRODUCTNAME: + case PRODUCTVERSION: + case PRODUCTEXTENSION: + case PRODUCTXMLFILEFORMATNAME : + case PRODUCTXMLFILEFORMATVERSION: + case OPENSOURCECONTEXT: + case OOOVENDOR: + case ABOUTBOXPRODUCTVERSION: sPath += C2U("Setup/Product"); break; + + case DEFAULTCURRENCY: sPath += C2U("Setup/L10N"); break; + + case WRITERCOMPATIBILITYVERSIONOOO11: + sPath += C2U("Office.Compatibility/WriterCompatibilityVersion"); break; + default: + break; + } + Sequence< Any > aArgs(1); + aArgs[0] <<= sPath; + Reference< XMultiServiceFactory > xCfgProvider = GetConfigManager()->GetConfigurationProvider(); + if(!xCfgProvider.is()) + return aRet; + Reference< XInterface > xIFace; + try + { + xIFace = xCfgProvider->createInstanceWithArguments( + C2U(cAccessSrvc), + aArgs); + + } + catch(Exception&){} + Reference<XNameAccess> xDirectAccess(xIFace, UNO_QUERY); + if(xDirectAccess.is()) + { + OUString sProperty; + switch(eProp) + { + case LOCALE: sProperty = C2U("ooLocale"); break; + case PRODUCTNAME: sProperty = C2U("ooName"); break; + case PRODUCTVERSION: sProperty = C2U("ooSetupVersion"); break; + case ABOUTBOXPRODUCTVERSION: sProperty = C2U("ooSetupVersionAboutBox"); break; + case OOOVENDOR: sProperty = C2U("ooVendor"); break; + case PRODUCTEXTENSION: sProperty = C2U("ooSetupExtension"); break; + case PRODUCTXMLFILEFORMATNAME: sProperty = C2U("ooXMLFileFormatName"); break; + case PRODUCTXMLFILEFORMATVERSION: sProperty = C2U("ooXMLFileFormatVersion"); break; + case OPENSOURCECONTEXT: sProperty = C2U("ooOpenSourceContext"); break; + case DEFAULTCURRENCY: sProperty = C2U("ooSetupCurrency"); break; + case WRITERCOMPATIBILITYVERSIONOOO11: sProperty = C2U("OOo11"); break; + default: + break; + } + try + { + aRet = xDirectAccess->getByName(sProperty); + } + catch(Exception&) + { + #if OSL_DEBUG_LEVEL > 0 + rtl::OStringBuffer aBuf(256); + aBuf.append( "ConfigManager::GetDirectConfigProperty: could not retrieve the property \"" ); + aBuf.append( rtl::OUStringToOString( sProperty, RTL_TEXTENCODING_ASCII_US ) ); + aBuf.append( "\" under \"" ); + aBuf.append( rtl::OUStringToOString( sPath, RTL_TEXTENCODING_ASCII_US ) ); + aBuf.append( "\" (caught an exception)!" ); + OSL_ENSURE( sal_False, aBuf.getStr() ); + #endif + } + } + + if ( eProp == PRODUCTNAME ) + aRet >>= rBrandName; + + if ( eProp == PRODUCTXMLFILEFORMATNAME ) + aRet >>= rXMLFileFormatName; + + if ( eProp == PRODUCTXMLFILEFORMATVERSION ) + aRet >>= rXMLFileFormatVersion; + + if ( eProp == PRODUCTVERSION ) + aRet >>= rProductVersion; + + if( eProp == OOOVENDOR ) + aRet >>= rOOOVendor; + + if ( eProp == ABOUTBOXPRODUCTVERSION ) + { + aRet >>= rAboutBoxProductVersion; + getBasisAboutBoxProductVersion( rAboutBoxProductVersion ); + aRet <<= rAboutBoxProductVersion; + } + + if ( eProp == PRODUCTEXTENSION ) + aRet >>= rProductExtension; + + if ( eProp == WRITERCOMPATIBILITYVERSIONOOO11 ) + aRet >>= rWriterCompatibilityVersionOOo11; + + if ( eProp == OPENSOURCECONTEXT ) + aRet >>= rOpenSourceContext; + + return aRet; +} + +/*---------------------------------------------------------------------------*/ +void ConfigManager::getBasisAboutBoxProductVersion( OUString& rVersion ) +{ + rtl::OUString aPackageVersion = UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":OOOPackageVersion}" ); + rtl::Bootstrap::expandMacros( aPackageVersion ); + + if ( aPackageVersion.getLength() ) + { + sal_Int32 nTokIndex = 0; + rtl::OUString aVersionMinor = aPackageVersion.getToken( 1, '.', nTokIndex ); + rtl::OUString aVersionMicro; + + if ( nTokIndex > 0 ) + aVersionMicro = aPackageVersion.getToken( 0, '.', nTokIndex ); + + if ( aVersionMinor.getLength() == 0 ) + aVersionMinor = UNISTRING( "0" ); + if ( aVersionMicro.getLength() == 0 ) + aVersionMicro = UNISTRING( "0" ); + + sal_Int32 nIndex = rVersion.indexOf( '.' ); + if ( nIndex == -1 ) + { + rVersion += UNISTRING( "." ); + rVersion += aVersionMinor; + } + else + { + nIndex = rVersion.indexOf( '.', nIndex+1 ); + } + if ( nIndex == -1 ) + { + rVersion += UNISTRING( "." ); + rVersion += aVersionMicro; + } + else + { + rVersion = rVersion.replaceAt( nIndex+1, rVersion.getLength()-nIndex-1, aVersionMicro ); + } + } +} + +/* -----------------------------12.12.00 17:22-------------------------------- + + ---------------------------------------------------------------------------*/ +Reference< XHierarchicalNameAccess> ConfigManager::GetHierarchyAccess(const OUString& rFullPath) +{ + Sequence< Any > aArgs(1); + aArgs[0] <<= rFullPath; + Reference< XMultiServiceFactory > xCfgProvider = GetLocalConfigurationProvider(); + Reference< XInterface > xIFace; + if(xCfgProvider.is()) + { + try + { + xIFace = xCfgProvider->createInstanceWithArguments( + C2U(cAccessSrvc), + aArgs); + } +#ifdef DBG_UTIL + catch(Exception& rEx) + { + OString sMsg("CreateInstance exception: "); + sMsg += OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); + } +#else + catch(Exception&){} +#endif + } + return Reference<XHierarchicalNameAccess>(xIFace, UNO_QUERY); +} +/* -----------------------------12.12.00 17:17-------------------------------- + + ---------------------------------------------------------------------------*/ +Any ConfigManager::GetLocalProperty(const OUString& rProperty) +{ + OUString sPath = C2U(cConfigBaseURL); + sPath += rProperty; + + OUString sNode, sProperty; + OSL_VERIFY( splitLastFromConfigurationPath(sPath, sNode, sProperty) ); + + Reference< XNameAccess> xAccess( GetHierarchyAccess(sNode), UNO_QUERY ); + Any aRet; + try + { + if(xAccess.is()) + aRet = xAccess->getByName(sProperty); + } +#ifdef DBG_UTIL + catch(Exception& rEx) + { + OString sMsg("GetLocalProperty: "); + sMsg += OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); + } +#else + catch(Exception&){} +#endif + return aRet; +} +/* -----------------------------12.12.00 17:17-------------------------------- + + ---------------------------------------------------------------------------*/ +void ConfigManager::PutLocalProperty(const OUString& rProperty, const Any& rValue) +{ + OUString sPath = C2U(cConfigBaseURL); + sPath += rProperty; + + OUString sNode, sProperty; + OSL_VERIFY( splitLastFromConfigurationPath(sPath, sNode, sProperty) ); + + Reference<XNameReplace> xNodeReplace(GetHierarchyAccess(sNode), UNO_QUERY); + if(xNodeReplace.is()) + { + try + { + xNodeReplace->replaceByName(sProperty, rValue); + } +#ifdef DBG_UTIL + catch(Exception& rEx) + { + OString sMsg("PutLocalProperty: "); + sMsg += OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); + } +#else + catch(Exception& ){} +#endif + } +} +/* -----------------------------13.12.00 08:47-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool ConfigManager::IsLocalConfigProvider() +{ + return false; +} + diff --git a/unotools/source/config/confignode.cxx b/unotools/source/config/confignode.cxx new file mode 100644 index 000000000000..181c7ca46c8f --- /dev/null +++ b/unotools/source/config/confignode.cxx @@ -0,0 +1,665 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/confignode.hxx> +#include <unotools/configpathes.hxx> +#include <tools/diagnose_ex.h> +#include <osl/diagnose.h> +#include <com/sun/star/container/XHierarchicalName.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/util/XStringEscape.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <comphelper/extract.hxx> +#include <comphelper/componentcontext.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <rtl/string.hxx> +#if OSL_DEBUG_LEVEL > 0 +#include <rtl/strbuf.hxx> +#endif + +//........................................................................ +namespace utl +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::container; + + //======================================================================== + //= OConfigurationNode + //======================================================================== + //------------------------------------------------------------------------ + OConfigurationNode::OConfigurationNode(const Reference< XInterface >& _rxNode ) + :m_bEscapeNames(sal_False) + { + OSL_ENSURE(_rxNode.is(), "OConfigurationNode::OConfigurationNode: invalid node interface!"); + if (_rxNode.is()) + { + // collect all interfaces necessary + m_xHierarchyAccess = Reference< XHierarchicalNameAccess >(_rxNode, UNO_QUERY); + m_xDirectAccess = Reference< XNameAccess >(_rxNode, UNO_QUERY); + + // reset _all_ interfaces if _one_ of them is not supported + if (!m_xHierarchyAccess.is() || !m_xDirectAccess.is()) + { + m_xHierarchyAccess = NULL; + m_xDirectAccess = NULL; + } + + // now for the non-critical interfaces + m_xReplaceAccess = Reference< XNameReplace >(_rxNode, UNO_QUERY); + m_xContainerAccess = Reference< XNameContainer >(_rxNode, UNO_QUERY); + } + + Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY); + if (xConfigNodeComp.is()) + startComponentListening(xConfigNodeComp); + + if (isValid()) + setEscape(isSetNode()); + } + + //------------------------------------------------------------------------ + OConfigurationNode::OConfigurationNode(const OConfigurationNode& _rSource) + :OEventListenerAdapter() + ,m_xHierarchyAccess(_rSource.m_xHierarchyAccess) + ,m_xDirectAccess(_rSource.m_xDirectAccess) + ,m_xReplaceAccess(_rSource.m_xReplaceAccess) + ,m_xContainerAccess(_rSource.m_xContainerAccess) + ,m_bEscapeNames(_rSource.m_bEscapeNames) + ,m_sCompletePath(_rSource.m_sCompletePath) + { + Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY); + if (xConfigNodeComp.is()) + startComponentListening(xConfigNodeComp); + } + + //------------------------------------------------------------------------ + const OConfigurationNode& OConfigurationNode::operator=(const OConfigurationNode& _rSource) + { + stopAllComponentListening(); + + m_xHierarchyAccess = _rSource.m_xHierarchyAccess; + m_xDirectAccess = _rSource.m_xDirectAccess; + m_xContainerAccess = _rSource.m_xContainerAccess; + m_xReplaceAccess = _rSource.m_xReplaceAccess; + m_bEscapeNames = _rSource.m_bEscapeNames; + m_sCompletePath = _rSource.m_sCompletePath; + + Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY); + if (xConfigNodeComp.is()) + startComponentListening(xConfigNodeComp); + + return *this; + } + + //------------------------------------------------------------------------ + void OConfigurationNode::_disposing( const EventObject& _rSource ) + { + Reference< XComponent > xDisposingSource(_rSource.Source, UNO_QUERY); + Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY); + if (xDisposingSource.get() == xConfigNodeComp.get()) + clear(); + } + + //------------------------------------------------------------------------ + ::rtl::OUString OConfigurationNode::getLocalName() const + { + ::rtl::OUString sLocalName; + try + { + Reference< XNamed > xNamed( m_xDirectAccess, UNO_QUERY_THROW ); + sLocalName = xNamed->getName(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return sLocalName; + } + + //------------------------------------------------------------------------ + ::rtl::OUString OConfigurationNode::getNodePath() const + { + ::rtl::OUString sNodePath; + try + { + Reference< XHierarchicalName > xNamed( m_xDirectAccess, UNO_QUERY_THROW ); + sNodePath = xNamed->getHierarchicalName(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return sNodePath; + } + + //------------------------------------------------------------------------ + ::rtl::OUString OConfigurationNode::normalizeName(const ::rtl::OUString& _rName, NAMEORIGIN _eOrigin) const + { + ::rtl::OUString sName(_rName); + if (getEscape()) + { + Reference< XStringEscape > xEscaper(m_xDirectAccess, UNO_QUERY); + if (xEscaper.is() && sName.getLength()) + { + try + { + if (NO_CALLER == _eOrigin) + sName = xEscaper->escapeString(sName); + else + sName = xEscaper->unescapeString(sName); + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + return sName; + } + + //------------------------------------------------------------------------ + Sequence< ::rtl::OUString > OConfigurationNode::getNodeNames() const throw() + { + OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::getNodeNames: object is invalid!"); + Sequence< ::rtl::OUString > aReturn; + if (m_xDirectAccess.is()) + { + try + { + aReturn = m_xDirectAccess->getElementNames(); + // normalize the names + ::rtl::OUString* pNames = aReturn.getArray(); + for (sal_Int32 i=0; i<aReturn.getLength(); ++i, ++pNames) + *pNames = normalizeName(*pNames, NO_CONFIGURATION); + } + catch(Exception&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::getNodeNames: caught a generic exception!"); + } + } + + return aReturn; + } + + //------------------------------------------------------------------------ + sal_Bool OConfigurationNode::removeNode(const ::rtl::OUString& _rName) const throw() + { + OSL_ENSURE(m_xContainerAccess.is(), "OConfigurationNode::removeNode: object is invalid!"); + if (m_xContainerAccess.is()) + { + try + { + ::rtl::OUString sName = normalizeName(_rName, NO_CALLER); + m_xContainerAccess->removeByName(sName); + return sal_True; + } + catch (NoSuchElementException&) + { + #if OSL_DEBUG_LEVEL > 0 + rtl::OStringBuffer aBuf( 256 ); + aBuf.append("OConfigurationNode::removeNode: there is no element named!"); + aBuf.append( rtl::OUStringToOString( _rName, RTL_TEXTENCODING_ASCII_US ) ); + aBuf.append( "!" ); + OSL_ENSURE(sal_False, aBuf.getStr()); + #endif + } + catch (WrappedTargetException&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::removeNode: caught a WrappedTargetException!"); + } + catch(Exception&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::removeNode: caught a generic exception!"); + } + } + return sal_False; + } + //------------------------------------------------------------------------ + OConfigurationNode OConfigurationNode::insertNode(const ::rtl::OUString& _rName,const Reference< XInterface >& _xNode) const throw() + { + if(_xNode.is()) + { + try + { + ::rtl::OUString sName = normalizeName(_rName, NO_CALLER); + m_xContainerAccess->insertByName(sName, makeAny(_xNode)); + // if we're here, all was ok ... + return OConfigurationNode( _xNode ); + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + + // dispose the child if it has already been created, but could not be inserted + Reference< XComponent > xChildComp(_xNode, UNO_QUERY); + if (xChildComp.is()) + try { xChildComp->dispose(); } catch(Exception&) { } + } + + return OConfigurationNode(); + } + //------------------------------------------------------------------------ + OConfigurationNode OConfigurationNode::createNode(const ::rtl::OUString& _rName) const throw() + { + Reference< XSingleServiceFactory > xChildFactory(m_xContainerAccess, UNO_QUERY); + OSL_ENSURE(xChildFactory.is(), "OConfigurationNode::createNode: object is invalid or read-only!"); + + if (xChildFactory.is()) // implies m_xContainerAccess.is() + { + Reference< XInterface > xNewChild; + try + { + xNewChild = xChildFactory->createInstance(); + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + return insertNode(_rName,xNewChild); + } + + return OConfigurationNode(); + } + + //------------------------------------------------------------------------ + OConfigurationNode OConfigurationNode::appendNode(const ::rtl::OUString& _rName,const OConfigurationNode& _aNewNode) const throw() + { + return insertNode(_rName,_aNewNode.m_xDirectAccess); + } + //------------------------------------------------------------------------ + OConfigurationNode OConfigurationNode::openNode(const ::rtl::OUString& _rPath) const throw() + { + OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::openNode: object is invalid!"); + OSL_ENSURE(m_xHierarchyAccess.is(), "OConfigurationNode::openNode: object is invalid!"); + try + { + ::rtl::OUString sNormalized = normalizeName(_rPath, NO_CALLER); + + Reference< XInterface > xNode; + if (m_xDirectAccess.is() && m_xDirectAccess->hasByName(sNormalized)) + { + if (!::cppu::extractInterface(xNode, m_xDirectAccess->getByName(sNormalized))) + OSL_ENSURE(sal_False, "OConfigurationNode::openNode: could not open the node!"); + } + else if (m_xHierarchyAccess.is()) + { + if (!::cppu::extractInterface(xNode, m_xHierarchyAccess->getByHierarchicalName(_rPath))) + OSL_ENSURE(sal_False, "OConfigurationNode::openNode: could not open the node!"); + } + if (xNode.is()) + return OConfigurationNode( xNode ); + } + catch(NoSuchElementException& e) + { + (void)e; + #if OSL_DEBUG_LEVEL > 0 + rtl::OStringBuffer aBuf( 256 ); + aBuf.append("OConfigurationNode::openNode: there is no element named "); + aBuf.append( rtl::OUStringToOString( _rPath, RTL_TEXTENCODING_ASCII_US ) ); + aBuf.append("!"); + OSL_ENSURE(sal_False, aBuf.getStr()); + #endif + } + catch(Exception&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::openNode: caught an exception while retrieving the node!"); + } + return OConfigurationNode(); + } + + //------------------------------------------------------------------------ + void OConfigurationNode::setEscape(sal_Bool _bEnable) + { + m_bEscapeNames = _bEnable && Reference< XStringEscape >::query(m_xDirectAccess).is(); + } + + //------------------------------------------------------------------------ + sal_Bool OConfigurationNode::isSetNode() const + { + sal_Bool bIsSet = sal_False; + Reference< XServiceInfo > xSI(m_xHierarchyAccess, UNO_QUERY); + if (xSI.is()) + { + try { bIsSet = xSI->supportsService(::rtl::OUString::createFromAscii("com.sun.star.configuration.SetAccess")); } + catch(Exception&) { } + } + return bIsSet; + } + + //--------------------------------------------------------------------- + //--- 20.08.01 19:03:20 ----------------------------------------------- + + sal_Bool OConfigurationNode::hasByHierarchicalName( const ::rtl::OUString& _rName ) const throw() + { + OSL_ENSURE( m_xHierarchyAccess.is(), "OConfigurationNode::hasByHierarchicalName: no hierarchy access!" ); + try + { + if ( m_xHierarchyAccess.is() ) + { + ::rtl::OUString sName = normalizeName( _rName, NO_CALLER ); + return m_xHierarchyAccess->hasByHierarchicalName( sName ); + } + } + catch(Exception&) + { + } + return sal_False; + } + + //------------------------------------------------------------------------ + sal_Bool OConfigurationNode::hasByName(const ::rtl::OUString& _rName) const throw() + { + OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::hasByName: object is invalid!"); + try + { + ::rtl::OUString sName = normalizeName(_rName, NO_CALLER); + if (m_xDirectAccess.is()) + return m_xDirectAccess->hasByName(sName); + } + catch(Exception&) + { + } + return sal_False; + } + + //------------------------------------------------------------------------ + sal_Bool OConfigurationNode::setNodeValue(const ::rtl::OUString& _rPath, const Any& _rValue) const throw() + { + sal_Bool bResult = false; + + OSL_ENSURE(m_xReplaceAccess.is(), "OConfigurationNode::setNodeValue: object is invalid!"); + if (m_xReplaceAccess.is()) + { + try + { + // check if _rPath is a level-1 path + ::rtl::OUString sNormalizedName = normalizeName(_rPath, NO_CALLER); + if (m_xReplaceAccess->hasByName(sNormalizedName)) + { + m_xReplaceAccess->replaceByName(sNormalizedName, _rValue); + bResult = true; + } + + // check if the name refers to a indirect descendant + else if (m_xHierarchyAccess.is() && m_xHierarchyAccess->hasByHierarchicalName(_rPath)) + { + OSL_ASSERT(_rPath.getLength()); + + ::rtl::OUString sParentPath, sLocalName; + + if ( splitLastFromConfigurationPath(_rPath, sParentPath, sLocalName) ) + { + OConfigurationNode aParentAccess = openNode(sParentPath); + if (aParentAccess.isValid()) + bResult = aParentAccess.setNodeValue(sLocalName, _rValue); + } + else + { + m_xReplaceAccess->replaceByName(sLocalName, _rValue); + bResult = true; + } + } + + } + catch(IllegalArgumentException&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught an IllegalArgumentException!"); + } + catch(NoSuchElementException&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught a NoSuchElementException!"); + } + catch(WrappedTargetException&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught a WrappedTargetException!"); + } + catch(Exception&) + { + OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught a generic Exception!"); + } + + + } + return bResult; + } + + //------------------------------------------------------------------------ + Any OConfigurationNode::getNodeValue(const ::rtl::OUString& _rPath) const throw() + { + OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::hasByName: object is invalid!"); + OSL_ENSURE(m_xHierarchyAccess.is(), "OConfigurationNode::hasByName: object is invalid!"); + Any aReturn; + try + { + ::rtl::OUString sNormalizedPath = normalizeName(_rPath, NO_CALLER); + if (m_xDirectAccess.is() && m_xDirectAccess->hasByName(sNormalizedPath) ) + { + aReturn = m_xDirectAccess->getByName(sNormalizedPath); + } + else if (m_xHierarchyAccess.is()) + { + aReturn = m_xHierarchyAccess->getByHierarchicalName(_rPath); + } + } + catch(const NoSuchElementException&) + { + DBG_UNHANDLED_EXCEPTION(); + } + return aReturn; + } + + //------------------------------------------------------------------------ + void OConfigurationNode::clear() throw() + { + m_xHierarchyAccess.clear(); + m_xDirectAccess.clear(); + m_xReplaceAccess.clear(); + m_xContainerAccess.clear(); + } + + //======================================================================== + //= helper + //======================================================================== + namespace + { + //-------------------------------------------------------------------- + static const ::rtl::OUString& lcl_getProviderServiceName( ) + { + static ::rtl::OUString s_sProviderServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ); + return s_sProviderServiceName; + } + + //-------------------------------------------------------------------- + Reference< XMultiServiceFactory > lcl_getConfigProvider( const ::comphelper::ComponentContext& i_rContext ) + { + try + { + Reference< XMultiServiceFactory > xProvider( i_rContext.createComponent( lcl_getProviderServiceName() ), UNO_QUERY_THROW ); + return xProvider; + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return NULL; + } + + //-------------------------------------------------------------------- + Reference< XInterface > lcl_createConfigurationRoot( const Reference< XMultiServiceFactory >& i_rxConfigProvider, + const ::rtl::OUString& i_rNodePath, const bool i_bUpdatable, const sal_Int32 i_nDepth, const bool i_bLazyWrite ) + { + ENSURE_OR_RETURN( i_rxConfigProvider.is(), "invalid provider", NULL ); + try + { + ::comphelper::NamedValueCollection aArgs; + aArgs.put( "nodepath", i_rNodePath ); + aArgs.put( "lazywrite", i_bLazyWrite ); + aArgs.put( "depth", i_nDepth ); + + ::rtl::OUString sAccessService = ::rtl::OUString::createFromAscii( + i_bUpdatable + ? "com.sun.star.configuration.ConfigurationUpdateAccess" + : "com.sun.star.configuration.ConfigurationAccess" ); + + Reference< XInterface > xRoot( + i_rxConfigProvider->createInstanceWithArguments( sAccessService, aArgs.getWrappedPropertyValues() ), + UNO_SET_THROW + ); + return xRoot; + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return NULL; + } + } + //======================================================================== + //= OConfigurationTreeRoot + //======================================================================== + //------------------------------------------------------------------------ + OConfigurationTreeRoot::OConfigurationTreeRoot( const Reference< XChangesBatch >& _rxRootNode ) + :OConfigurationNode( _rxRootNode.get() ) + ,m_xCommitter(_rxRootNode) + { + } + + //------------------------------------------------------------------------ + OConfigurationTreeRoot::OConfigurationTreeRoot( const Reference< XInterface >& _rxRootNode ) + :OConfigurationNode( _rxRootNode ) + ,m_xCommitter( _rxRootNode, UNO_QUERY ) + { + } + + //------------------------------------------------------------------------ + OConfigurationTreeRoot::OConfigurationTreeRoot( const ::comphelper::ComponentContext& i_rContext, const sal_Char* i_pAsciiNodePath, const bool i_bUpdatable ) + :OConfigurationNode( lcl_createConfigurationRoot( lcl_getConfigProvider( i_rContext.getLegacyServiceFactory() ), + ::rtl::OUString::createFromAscii( i_pAsciiNodePath ), i_bUpdatable, -1, false ).get() ) + ,m_xCommitter() + { + if ( i_bUpdatable ) + { + m_xCommitter.set( getUNONode(), UNO_QUERY ); + OSL_ENSURE( m_xCommitter.is(), "OConfigurationTreeRoot::OConfigurationTreeRoot: could not create an updatable node!" ); + } + } + + //------------------------------------------------------------------------ + OConfigurationTreeRoot::OConfigurationTreeRoot( const ::comphelper::ComponentContext& i_rContext, const ::rtl::OUString& i_rNodePath, const bool i_bUpdatable ) + :OConfigurationNode( lcl_createConfigurationRoot( lcl_getConfigProvider( i_rContext.getLegacyServiceFactory() ), + i_rNodePath, i_bUpdatable, -1, false ).get() ) + ,m_xCommitter() + { + if ( i_bUpdatable ) + { + m_xCommitter.set( getUNONode(), UNO_QUERY ); + OSL_ENSURE( m_xCommitter.is(), "OConfigurationTreeRoot::OConfigurationTreeRoot: could not create an updatable node!" ); + } + } + + //------------------------------------------------------------------------ + void OConfigurationTreeRoot::clear() throw() + { + OConfigurationNode::clear(); + m_xCommitter.clear(); + } + + //------------------------------------------------------------------------ + sal_Bool OConfigurationTreeRoot::commit() const throw() + { + OSL_ENSURE(isValid(), "OConfigurationTreeRoot::commit: object is invalid!"); + if (!isValid()) + return sal_False; + OSL_ENSURE(m_xCommitter.is(), "OConfigurationTreeRoot::commit: I'm a readonly node!"); + if (!m_xCommitter.is()) + return sal_False; + + try + { + m_xCommitter->commitChanges(); + return sal_True; + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + return sal_False; + } + + //------------------------------------------------------------------------ + OConfigurationTreeRoot OConfigurationTreeRoot::createWithProvider(const Reference< XMultiServiceFactory >& _rxConfProvider, const ::rtl::OUString& _rPath, sal_Int32 _nDepth, CREATION_MODE _eMode, sal_Bool _bLazyWrite) + { + Reference< XInterface > xRoot( lcl_createConfigurationRoot( + _rxConfProvider, _rPath, _eMode != CM_READONLY, _nDepth, _bLazyWrite ) ); + if ( xRoot.is() ) + return OConfigurationTreeRoot( xRoot ); + return OConfigurationTreeRoot(); + } + + //------------------------------------------------------------------------ + OConfigurationTreeRoot OConfigurationTreeRoot::createWithServiceFactory( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rPath, sal_Int32 _nDepth, CREATION_MODE _eMode, sal_Bool _bLazyWrite ) + { + return createWithProvider( lcl_getConfigProvider( _rxORB ), _rPath, _nDepth, _eMode, _bLazyWrite ); + } + + //------------------------------------------------------------------------ + OConfigurationTreeRoot OConfigurationTreeRoot::tryCreateWithServiceFactory( const Reference< XMultiServiceFactory >& _rxORB, + const ::rtl::OUString& _rPath, sal_Int32 _nDepth , CREATION_MODE _eMode , sal_Bool _bLazyWrite ) + { + OSL_ENSURE( _rxORB.is(), "OConfigurationTreeRoot::tryCreateWithServiceFactory: invalid service factory!" ); + if ( _rxORB.is() ) + { + try + { + Reference< XMultiServiceFactory > xConfigFactory( _rxORB->createInstance( lcl_getProviderServiceName( ) ), UNO_QUERY ); + if ( xConfigFactory.is() ) + return createWithProvider( xConfigFactory, _rPath, _nDepth, _eMode, _bLazyWrite ); + } + catch(const Exception&) + { + // silence this, 'cause the contract of this method states "no assertions" + } + } + return OConfigurationTreeRoot(); + } + +//........................................................................ +} // namespace utl +//........................................................................ + diff --git a/unotools/source/config/configpathes.cxx b/unotools/source/config/configpathes.cxx new file mode 100644 index 000000000000..5e7a4c80813e --- /dev/null +++ b/unotools/source/config/configpathes.cxx @@ -0,0 +1,308 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include "unotools/configpathes.hxx" +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> + +//---------------------------------------------------------------------------- +namespace utl +{ +//---------------------------------------------------------------------------- + + using ::rtl::OUString; + using ::rtl::OUStringBuffer; + +//---------------------------------------------------------------------------- + +static +void lcl_resolveCharEntities(OUString & aLocalString) +{ + sal_Int32 nEscapePos=aLocalString.indexOf('&'); + if (nEscapePos < 0) return; + + OUStringBuffer aResult; + sal_Int32 nStart = 0; + + do + { + sal_Unicode ch = 0; + if (aLocalString.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("&"),nEscapePos)) + ch = '&'; + + else if (aLocalString.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("'"),nEscapePos)) + ch = '\''; + + else if (aLocalString.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("""),nEscapePos)) + ch = '"'; + + OSL_ENSURE(ch,"Configuration path contains '&' that is not part of a valid character escape"); + if (ch) + { + aResult.append(aLocalString.copy(nStart,nEscapePos-nStart)).append(ch); + + sal_Int32 nEscapeEnd=aLocalString.indexOf(';',nEscapePos); + nStart = nEscapeEnd+1; + nEscapePos=aLocalString.indexOf('&',nStart); + } + else + { + nEscapePos=aLocalString.indexOf('&',nEscapePos+1); + } + } + while ( nEscapePos > 0); + + aResult.append(aLocalString.copy(nStart)); + + aLocalString = aResult.makeStringAndClear(); +} + +//---------------------------------------------------------------------------- +sal_Bool splitLastFromConfigurationPath(OUString const& _sInPath, + OUString& _rsOutPath, + OUString& _rsLocalName) +{ + sal_Int32 nStart,nEnd; + + sal_Int32 nPos = _sInPath.getLength()-1; + + // strip trailing slash + if (nPos > 0 && _sInPath[ nPos ] == sal_Unicode('/')) + { + OSL_ENSURE(false, "Invalid config path: trailing '/' is not allowed"); + --nPos; + } + + // check for predicate ['xxx'] or ["yyy"] + if (nPos > 0 && _sInPath[ nPos ] == sal_Unicode(']')) + { + sal_Unicode chQuote = _sInPath[--nPos]; + + if (chQuote == '\'' || chQuote == '\"') + { + nEnd = nPos; + nPos = _sInPath.lastIndexOf(chQuote,nEnd); + nStart = nPos + 1; + --nPos; // nPos = rInPath.lastIndexOf('[',nPos); + } + else // allow [xxx] + { + nEnd = nPos + 1; + nPos = _sInPath.lastIndexOf('[',nEnd); + nStart = nPos + 1; + } + + OSL_ENSURE(nPos >= 0 && _sInPath[nPos] == '[', "Invalid config path: unmatched quotes or brackets"); + if (nPos >= 0 && _sInPath[nPos] == '[') + { + nPos = _sInPath.lastIndexOf('/',nPos); + } + else // defined behavior for invalid pathes + { + nStart = 0, nEnd = _sInPath.getLength(); + nPos = -1; + } + + } + else + { + nEnd = nPos+1; + nPos = _sInPath.lastIndexOf('/',nEnd); + nStart = nPos + 1; + } + OSL_ASSERT( -1 <= nPos && + nPos < nStart && + nStart < nEnd && + nEnd <= _sInPath.getLength() ); + + OSL_ASSERT(nPos == -1 || _sInPath[nPos] == '/'); + OSL_ENSURE(nPos != 0 , "Invalid config child path: immediate child of root"); + + _rsLocalName = _sInPath.copy(nStart, nEnd-nStart); + _rsOutPath = (nPos > 0) ? _sInPath.copy(0,nPos) : OUString(); + lcl_resolveCharEntities(_rsLocalName); + + return nPos >= 0; +} + +//---------------------------------------------------------------------------- +OUString extractFirstFromConfigurationPath(OUString const& _sInPath, OUString* _sOutPath) +{ + sal_Int32 nSep = _sInPath.indexOf('/'); + sal_Int32 nBracket = _sInPath.indexOf('['); + + sal_Int32 nStart = nBracket + 1; + sal_Int32 nEnd = nSep; + + if (0 <= nBracket) // found a bracket-quoted relative path + { + if (nSep < 0 || nBracket < nSep) // and the separator comes after it + { + sal_Unicode chQuote = _sInPath[nStart]; + if (chQuote == '\'' || chQuote == '\"') + { + ++nStart; + nEnd = _sInPath.indexOf(chQuote, nStart+1); + nBracket = nEnd+1; + } + else + { + nEnd = _sInPath.indexOf(']',nStart); + nBracket = nEnd; + } + OSL_ENSURE(nEnd > nStart && _sInPath[nBracket] == ']', "Invalid config path: improper mismatch of quote or bracket"); + OSL_ENSURE((nBracket+1 == _sInPath.getLength() && nSep == -1) || (_sInPath[nBracket+1] == '/' && nSep == nBracket+1), "Invalid config path: brackets not followed by slash"); + } + else // ... but our initial element name is in simple form + nStart = 0; + } + + OUString sResult = (nEnd >= 0) ? _sInPath.copy(nStart, nEnd-nStart) : _sInPath; + lcl_resolveCharEntities(sResult); + + if (_sOutPath != 0) + { + *_sOutPath = (nSep >= 0) ? _sInPath.copy(nSep + 1) : OUString(); + } + + return sResult; +} + +//---------------------------------------------------------------------------- + +// find the position after the prefix in the nested path +static inline +sal_Int32 lcl_findPrefixEnd(OUString const& _sNestedPath, OUString const& _sPrefixPath) +{ + // TODO: currently handles only exact prefix matches + sal_Int32 nPrefixLength = _sPrefixPath.getLength(); + + OSL_ENSURE(nPrefixLength == 0 || _sPrefixPath[nPrefixLength-1] != '/', + "Cannot handle slash-terminated prefix pathes"); + + sal_Bool bIsPrefix; + if (_sNestedPath.getLength() > nPrefixLength) + { + bIsPrefix = _sNestedPath[nPrefixLength] == '/' && + _sNestedPath.compareTo(_sPrefixPath,nPrefixLength) == 0; + ++nPrefixLength; + } + else if (_sNestedPath.getLength() == nPrefixLength) + { + bIsPrefix = _sNestedPath.equals(_sPrefixPath); + } + else + { + bIsPrefix = false; + } + + return bIsPrefix ? nPrefixLength : 0; +} + +//---------------------------------------------------------------------------- +sal_Bool isPrefixOfConfigurationPath(OUString const& _sNestedPath, + OUString const& _sPrefixPath) +{ + return _sPrefixPath.getLength() == 0 || lcl_findPrefixEnd(_sNestedPath,_sPrefixPath) != 0; +} + +//---------------------------------------------------------------------------- +OUString dropPrefixFromConfigurationPath(OUString const& _sNestedPath, + OUString const& _sPrefixPath) +{ + if ( sal_Int32 nPrefixEnd = lcl_findPrefixEnd(_sNestedPath,_sPrefixPath) ) + { + return _sNestedPath.copy(nPrefixEnd); + } + else + { + OSL_ENSURE(_sPrefixPath.getLength() == 0, "Path does not start with expected prefix"); + + return _sNestedPath; + } +} + +//---------------------------------------------------------------------------- +static +OUString lcl_wrapName(const OUString& _sContent, const OUString& _sType) +{ + const sal_Unicode * const pBeginContent = _sContent.getStr(); + const sal_Unicode * const pEndContent = pBeginContent + _sContent.getLength(); + + OSL_PRECOND(_sType.getLength(), "Unexpected config type name: empty"); + OSL_PRECOND(pBeginContent <= pEndContent, "Invalid config name: empty"); + + if (pBeginContent == pEndContent) + return _sType; + + rtl::OUStringBuffer aNormalized(_sType.getLength() + _sContent.getLength() + 4); // reserve approximate size initially + + // prefix: type, opening bracket and quote + aNormalized.append( _sType ).appendAscii( RTL_CONSTASCII_STRINGPARAM("['") ); + + // content: copy over each char and handle escaping + for(const sal_Unicode* pCur = pBeginContent; pCur != pEndContent; ++pCur) + { + // append (escape if needed) + switch(*pCur) + { + case sal_Unicode('&') : aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM("&") ); break; + case sal_Unicode('\''): aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM("'") ); break; + case sal_Unicode('\"'): aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM(""") ); break; + + default: aNormalized.append( *pCur ); + } + } + + // suffix: closing quote and bracket + aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM("']") ); + + return aNormalized.makeStringAndClear(); +} + +//---------------------------------------------------------------------------- + +OUString wrapConfigurationElementName(OUString const& _sElementName) +{ + return lcl_wrapName(_sElementName, OUString(RTL_CONSTASCII_USTRINGPARAM("*")) ); +} + +//---------------------------------------------------------------------------- + +OUString wrapConfigurationElementName(OUString const& _sElementName, + OUString const& _sTypeName) +{ + // todo: check that _sTypeName is valid + return lcl_wrapName(_sElementName, _sTypeName); +} + +//---------------------------------------------------------------------------- +} // namespace utl diff --git a/unotools/source/config/configvaluecontainer.cxx b/unotools/source/config/configvaluecontainer.cxx new file mode 100644 index 000000000000..653305f92f74 --- /dev/null +++ b/unotools/source/config/configvaluecontainer.cxx @@ -0,0 +1,456 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/configvaluecontainer.hxx> +#include <unotools/confignode.hxx> +#include <tools/debug.hxx> +#include <comphelper/stl_types.hxx> +#include <uno/data.h> +#include <algorithm> + +#ifdef DBG_UTIL +#include <rtl/strbuf.hxx> +#endif + +//......................................................................... +namespace utl +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + + //===================================================================== + //= NodeValueAccessor + //===================================================================== + enum LocationType + { + ltSimplyObjectInstance, + ltAnyInstance, + + ltUnbound + }; + + struct NodeValueAccessor + { + private: + ::rtl::OUString sRelativePath; // the relative path of the node + LocationType eLocationType; // the type of location where the value is stored + void* pLocation; // the pointer to the location + Type aDataType; // the type object pointed to by pLocation + + public: + NodeValueAccessor( const ::rtl::OUString& _rNodePath ); + + void bind( void* _pLocation, const Type& _rType ); + void bind( Any* _pLocation ); + + bool isBound( ) const { return ( ltUnbound != eLocationType ) && ( NULL != pLocation ); } + const ::rtl::OUString& getPath( ) const { return sRelativePath; } + LocationType getLocType( ) const { return eLocationType; } + void* getLocation( ) const { return pLocation; } + const Type& getDataType( ) const { return aDataType; } + + bool operator == ( const NodeValueAccessor& rhs ) const; + bool operator != ( const NodeValueAccessor& rhs ) const { return !operator == ( rhs ); } + }; + + //--------------------------------------------------------------------- + //--- 20.08.01 17:21:13 ----------------------------------------------- + + NodeValueAccessor::NodeValueAccessor( const ::rtl::OUString& _rNodePath ) + :sRelativePath( _rNodePath ) + ,eLocationType( ltUnbound ) + ,pLocation( NULL ) + { + } + + //--------------------------------------------------------------------- + //--- 20.08.01 17:06:36 ----------------------------------------------- + + bool NodeValueAccessor::operator == ( const NodeValueAccessor& rhs ) const + { + return ( sRelativePath == rhs.sRelativePath ) + && ( eLocationType == rhs.eLocationType ) + && ( pLocation == rhs.pLocation ); + } + + //--------------------------------------------------------------------- + //--- 20.08.01 17:47:43 ----------------------------------------------- + + void NodeValueAccessor::bind( void* _pLocation, const Type& _rType ) + { + DBG_ASSERT( !isBound(), "NodeValueAccessor::bind: already bound!" ); + + eLocationType = ltSimplyObjectInstance; + pLocation = _pLocation; + aDataType = _rType; + } + + //--------------------------------------------------------------------- + //--- 20.08.01 17:48:47 ----------------------------------------------- + + void NodeValueAccessor::bind( Any* _pLocation ) + { + DBG_ASSERT( !isBound(), "NodeValueAccessor::bind: already bound!" ); + + eLocationType = ltAnyInstance; + pLocation = _pLocation; + aDataType = ::getCppuType( _pLocation ); + } + + //--------------------------------------------------------------------- + //--- 20.08.01 17:42:17 ----------------------------------------------- + + #ifndef UNX + static + #endif + void lcl_copyData( const NodeValueAccessor& _rAccessor, const Any& _rData, ::osl::Mutex& _rMutex ) + { + ::osl::MutexGuard aGuard( _rMutex ); + + DBG_ASSERT( _rAccessor.isBound(), "::utl::lcl_copyData: invalid accessor!" ); + switch ( _rAccessor.getLocType() ) + { + case ltSimplyObjectInstance: + { + if ( _rData.hasValue() ) + { +#ifdef DBG_UTIL + sal_Bool bSuccess = +#endif + // assign the value + uno_type_assignData( + _rAccessor.getLocation(), _rAccessor.getDataType().getTypeLibType(), + const_cast< void* >( _rData.getValue() ), _rData.getValueType().getTypeLibType(), + (uno_QueryInterfaceFunc)cpp_queryInterface, (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release + ); + #ifdef DBG_UTIL + rtl::OStringBuffer aBuf( 256 ); + aBuf.append("::utl::lcl_copyData( Accessor, Any ): could not assign the data (node path: "); + aBuf.append( rtl::OUStringToOString( _rAccessor.getPath(), RTL_TEXTENCODING_ASCII_US ) ); + aBuf.append( " !" ); + DBG_ASSERT( bSuccess, aBuf.getStr() ); + #endif + } + else { + DBG_WARNING( "::utl::lcl_copyData: NULL value lost!" ); + } + } + break; + case ltAnyInstance: + // a simple assignment of an Any ... + *static_cast< Any* >( _rAccessor.getLocation() ) = _rData; + break; + default: + break; + } + } + + //--------------------------------------------------------------------- + //--- 21.08.01 12:06:43 ----------------------------------------------- + + #ifndef UNX + static + #endif + void lcl_copyData( Any& _rData, const NodeValueAccessor& _rAccessor, ::osl::Mutex& _rMutex ) + { + ::osl::MutexGuard aGuard( _rMutex ); + + DBG_ASSERT( _rAccessor.isBound(), "::utl::lcl_copyData: invalid accessor!" ); + switch ( _rAccessor.getLocType() ) + { + case ltSimplyObjectInstance: + // a simple setValue .... + _rData.setValue( _rAccessor.getLocation(), _rAccessor.getDataType() ); + break; + + case ltAnyInstance: + // a simple assignment of an Any ... + _rData = *static_cast< Any* >( _rAccessor.getLocation() ); + break; + default: + break; + } + } + + //===================================================================== + //= functors on NodeValueAccessor instances + //===================================================================== + + //--------------------------------------------------------------------- + //--- 21.08.01 12:01:16 ----------------------------------------------- + + /// base class for functors syncronizing between exchange locations and config sub nodes + struct SubNodeAccess : public ::std::unary_function< NodeValueAccessor, void > + { + protected: + const OConfigurationNode& m_rRootNode; + ::osl::Mutex& m_rMutex; + + public: + SubNodeAccess( const OConfigurationNode& _rRootNode, ::osl::Mutex& _rMutex ) + :m_rRootNode( _rRootNode ) + ,m_rMutex( _rMutex ) + { + } + }; + + //--------------------------------------------------------------------- + //--- 21.08.01 11:25:56 ----------------------------------------------- + + struct UpdateFromConfig : public SubNodeAccess + { + public: + UpdateFromConfig( const OConfigurationNode& _rRootNode, ::osl::Mutex& _rMutex ) : SubNodeAccess( _rRootNode, _rMutex ) { } + + void operator() ( NodeValueAccessor& _rAccessor ) + { + ::utl::lcl_copyData( _rAccessor, m_rRootNode.getNodeValue( _rAccessor.getPath( ) ), m_rMutex ); + } + }; + + //--------------------------------------------------------------------- + //--- 21.08.01 11:25:56 ----------------------------------------------- + + struct UpdateToConfig : public SubNodeAccess + { + public: + UpdateToConfig( const OConfigurationNode& _rRootNode, ::osl::Mutex& _rMutex ) : SubNodeAccess( _rRootNode, _rMutex ) { } + + void operator() ( NodeValueAccessor& _rAccessor ) + { + Any aNewValue; + lcl_copyData( aNewValue, _rAccessor, m_rMutex ); + m_rRootNode.setNodeValue( _rAccessor.getPath( ), aNewValue ); + } + }; + + //--------------------------------------------------------------------- + //--- 20.08.01 16:58:24 ----------------------------------------------- + + DECLARE_STL_VECTOR( NodeValueAccessor, NodeValueAccessors ); + + //===================================================================== + //= OConfigurationValueContainerImpl + //===================================================================== + struct OConfigurationValueContainerImpl + { + Reference< XMultiServiceFactory > xORB; // the service factory + ::osl::Mutex& rMutex; // the mutex for accessing the data containers + OConfigurationTreeRoot aConfigRoot; // the configuration node we're accessing + + NodeValueAccessors aAccessors; // the accessors to the node values + + OConfigurationValueContainerImpl( const Reference< XMultiServiceFactory >& _rxORB, ::osl::Mutex& _rMutex ) + :xORB( _rxORB ) + ,rMutex( _rMutex ) + { + } + }; + + //===================================================================== + //= OConfigurationValueContainer + //===================================================================== + + //--------------------------------------------------------------------- + //--- 20.08.01 15:53:35 ----------------------------------------------- + + OConfigurationValueContainer::OConfigurationValueContainer( + const Reference< XMultiServiceFactory >& _rxORB, ::osl::Mutex& _rAccessSafety, + const sal_Char* _pConfigLocation, const sal_uInt16 _nAccessFlags, const sal_Int32 _nLevels ) + :m_pImpl( new OConfigurationValueContainerImpl( _rxORB, _rAccessSafety ) ) + { + implConstruct( ::rtl::OUString::createFromAscii( _pConfigLocation ), _nAccessFlags, _nLevels ); + } + + //--------------------------------------------------------------------- + //--- 20.08.01 15:55:20 ----------------------------------------------- + + OConfigurationValueContainer::OConfigurationValueContainer( + const Reference< XMultiServiceFactory >& _rxORB, ::osl::Mutex& _rAccessSafety, + const ::rtl::OUString& _rConfigLocation, const sal_uInt16 _nAccessFlags, const sal_Int32 _nLevels ) + :m_pImpl( new OConfigurationValueContainerImpl( _rxORB, _rAccessSafety ) ) + { + implConstruct( _rConfigLocation, _nAccessFlags, _nLevels ); + } + + //--------------------------------------------------------------------- + //--- 20.08.01 16:01:29 ----------------------------------------------- + + OConfigurationValueContainer::~OConfigurationValueContainer() + { + delete m_pImpl; + } + + //--------------------------------------------------------------------- + //--- 20.08.01 15:59:13 ----------------------------------------------- + + const Reference< XMultiServiceFactory >& OConfigurationValueContainer::getServiceFactory( ) const + { + return m_pImpl->xORB; + } + + //--------------------------------------------------------------------- + //--- 20.08.01 16:02:07 ----------------------------------------------- + + void OConfigurationValueContainer::implConstruct( const ::rtl::OUString& _rConfigLocation, + const sal_uInt16 _nAccessFlags, const sal_Int32 _nLevels ) + { + DBG_ASSERT( !m_pImpl->aConfigRoot.isValid(), "OConfigurationValueContainer::implConstruct: already initialized!" ); + + // ................................. + // create the configuration node we're about to work with + m_pImpl->aConfigRoot = OConfigurationTreeRoot::createWithServiceFactory( + m_pImpl->xORB, + _rConfigLocation, + _nLevels, + ( _nAccessFlags & CVC_UPDATE_ACCESS ) ? OConfigurationTreeRoot::CM_UPDATABLE : OConfigurationTreeRoot::CM_READONLY, + ( _nAccessFlags & CVC_IMMEDIATE_UPDATE ) ? sal_False : sal_True + ); + #ifdef DBG_UTIL + rtl::OStringBuffer aBuf(256); + aBuf.append("Could not access the configuration node located at "); + aBuf.append( rtl::OUStringToOString( _rConfigLocation, RTL_TEXTENCODING_ASCII_US ) ); + aBuf.append( " !" ); + DBG_ASSERT( m_pImpl->aConfigRoot.isValid(), aBuf.getStr() ); + #endif + } + + //--------------------------------------------------------------------- + //--- 20.08.01 16:39:05 ----------------------------------------------- + + void OConfigurationValueContainer::registerExchangeLocation( const sal_Char* _pRelativePath, + void* _pContainer, const Type& _rValueType ) + { + // checks .... + DBG_ASSERT( _pContainer, "OConfigurationValueContainer::registerExchangeLocation: invalid container location!" ); + DBG_ASSERT( ( TypeClass_CHAR == _rValueType.getTypeClass( ) ) + || ( TypeClass_BOOLEAN == _rValueType.getTypeClass( ) ) + || ( TypeClass_BYTE == _rValueType.getTypeClass( ) ) + || ( TypeClass_SHORT == _rValueType.getTypeClass( ) ) + || ( TypeClass_LONG == _rValueType.getTypeClass( ) ) + || ( TypeClass_DOUBLE == _rValueType.getTypeClass( ) ) + || ( TypeClass_STRING == _rValueType.getTypeClass( ) ) + || ( TypeClass_SEQUENCE == _rValueType.getTypeClass( ) ), + "OConfigurationValueContainer::registerExchangeLocation: invalid type!" ); + + // build an accessor for this container + NodeValueAccessor aNewAccessor( ::rtl::OUString::createFromAscii( _pRelativePath ) ); + aNewAccessor.bind( _pContainer, _rValueType ); + + // insert it into our structure + implRegisterExchangeLocation( aNewAccessor ); + } + + //--------------------------------------------------------------------- + //--- 21.08.01 14:44:45 ----------------------------------------------- + + void OConfigurationValueContainer::registerNullValueExchangeLocation( const sal_Char* _pRelativePath, Any* _pContainer ) + { + // build an accessor for this container + NodeValueAccessor aNewAccessor( ::rtl::OUString::createFromAscii( _pRelativePath ) ); + aNewAccessor.bind( _pContainer ); + + // insert it into our structure + implRegisterExchangeLocation( aNewAccessor ); + } + + //--------------------------------------------------------------------- + //--- 21.08.01 10:23:34 ----------------------------------------------- + + void OConfigurationValueContainer::read( ) + { + for_each( + m_pImpl->aAccessors.begin(), + m_pImpl->aAccessors.end(), + UpdateFromConfig( m_pImpl->aConfigRoot, m_pImpl->rMutex ) + ); + } + + //--------------------------------------------------------------------- + //--- 21.08.01 12:04:48 ----------------------------------------------- + + void OConfigurationValueContainer::write( sal_Bool _bCommit ) + { + // collect the current values in the exchange locations + for_each( + m_pImpl->aAccessors.begin(), + m_pImpl->aAccessors.end(), + UpdateToConfig( m_pImpl->aConfigRoot, m_pImpl->rMutex ) + ); + + // commit the changes done (if requested) + if ( _bCommit ) + commit( sal_False ); + } + + //--------------------------------------------------------------------- + //--- 21.08.01 12:09:45 ----------------------------------------------- + + void OConfigurationValueContainer::commit( sal_Bool _bWrite ) + { + // write the current values in the exchange locations (if requested) + if ( _bWrite ) + write( sal_False ); + + // commit the changes done + m_pImpl->aConfigRoot.commit( ); + } + + //--------------------------------------------------------------------- + //--- 20.08.01 17:29:27 ----------------------------------------------- + + void OConfigurationValueContainer::implRegisterExchangeLocation( const NodeValueAccessor& _rAccessor ) + { + // some checks + DBG_ASSERT( !m_pImpl->aConfigRoot.isValid() || m_pImpl->aConfigRoot.hasByHierarchicalName( _rAccessor.getPath() ), + "OConfigurationValueContainer::implRegisterExchangeLocation: invalid relative path!" ); + +#ifdef DBG_UTIL + // another check (should be the first container for this node) + ConstNodeValueAccessorsIterator aExistent = ::std::find( + m_pImpl->aAccessors.begin(), + m_pImpl->aAccessors.end(), + _rAccessor + ); + DBG_ASSERT( m_pImpl->aAccessors.end() == aExistent, "OConfigurationValueContainer::implRegisterExchangeLocation: already registered a container for this subnode!" ); +#endif + + // remember the accessor + m_pImpl->aAccessors.push_back( _rAccessor ); + + // and initially fill the value + lcl_copyData( _rAccessor, m_pImpl->aConfigRoot.getNodeValue( _rAccessor.getPath() ), m_pImpl->rMutex ); + } + +//......................................................................... +} // namespace utl +//......................................................................... + diff --git a/unotools/source/config/defaultoptions.cxx b/unotools/source/config/defaultoptions.cxx new file mode 100644 index 000000000000..1567bd1b841d --- /dev/null +++ b/unotools/source/config/defaultoptions.cxx @@ -0,0 +1,363 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/defaultoptions.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/configitem.hxx> +#include <unotools/configmgr.hxx> +#include <tools/debug.hxx> +#include <tools/resmgr.hxx> +#include <tools/urlobj.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <osl/mutex.hxx> + +#include <vos/process.hxx> +#include <unotools/localfilehelper.hxx> +#include <rtl/instance.hxx> + +#include <itemholder1.hxx> + +using namespace osl; +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; + +// define ---------------------------------------------------------------- + +#define ASCII_STR(s) OUString( RTL_CONSTASCII_USTRINGPARAM(s) ) + +#define DEFAULTPATH__ADDIN 0 +#define DEFAULTPATH__AUTOCORRECT 1 +#define DEFAULTPATH__AUTOTEXT 2 +#define DEFAULTPATH__BACKUP 3 +#define DEFAULTPATH__BASIC 4 +#define DEFAULTPATH__BITMAP 5 +#define DEFAULTPATH__CONFIG 6 +#define DEFAULTPATH__DICTIONARY 7 +#define DEFAULTPATH__FAVORITES 8 +#define DEFAULTPATH__FILTER 9 +#define DEFAULTPATH__GALLERY 10 +#define DEFAULTPATH__GRAPHIC 11 +#define DEFAULTPATH__HELP 12 +#define DEFAULTPATH__LINGUISTIC 13 +#define DEFAULTPATH__MODULE 14 +#define DEFAULTPATH__PALETTE 15 +#define DEFAULTPATH__PLUGIN 16 +#define DEFAULTPATH__TEMP 17 +#define DEFAULTPATH__TEMPLATE 18 +#define DEFAULTPATH__USERCONFIG 19 +#define DEFAULTPATH__WORK 20 +#define DEFAULTPATH__USERDICTIONARY 21 + +// class SvtDefaultOptions_Impl ------------------------------------------ + +class SvtDefaultOptions_Impl : public utl::ConfigItem +{ +public: + String m_aAddinPath; + String m_aAutoCorrectPath; + String m_aAutoTextPath; + String m_aBackupPath; + String m_aBasicPath; + String m_aBitmapPath; + String m_aConfigPath; + String m_aDictionaryPath; + String m_aFavoritesPath; + String m_aFilterPath; + String m_aGalleryPath; + String m_aGraphicPath; + String m_aHelpPath; + String m_aLinguisticPath; + String m_aModulePath; + String m_aPalettePath; + String m_aPluginPath; + String m_aTempPath; + String m_aTemplatePath; + String m_aUserConfigPath; + String m_aWorkPath; + String m_aUserDictionaryPath; + + SvtDefaultOptions_Impl(); + + String GetDefaultPath( USHORT nId ) const; + virtual void Commit(); + virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames); +}; + +// global ---------------------------------------------------------------- + +static SvtDefaultOptions_Impl* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +typedef String SvtDefaultOptions_Impl:: *PathStrPtr; + +struct PathToDefaultMapping_Impl +{ + SvtPathOptions::Pathes _ePath; + PathStrPtr _pDefaultPath; +}; + +static PathToDefaultMapping_Impl __READONLY_DATA PathMap_Impl[] = +{ + { SvtPathOptions::PATH_ADDIN, &SvtDefaultOptions_Impl::m_aAddinPath }, + { SvtPathOptions::PATH_AUTOCORRECT, &SvtDefaultOptions_Impl::m_aAutoCorrectPath }, + { SvtPathOptions::PATH_AUTOTEXT, &SvtDefaultOptions_Impl::m_aAutoTextPath }, + { SvtPathOptions::PATH_BACKUP, &SvtDefaultOptions_Impl::m_aBackupPath }, + { SvtPathOptions::PATH_BASIC, &SvtDefaultOptions_Impl::m_aBasicPath }, + { SvtPathOptions::PATH_BITMAP, &SvtDefaultOptions_Impl::m_aBitmapPath }, + { SvtPathOptions::PATH_CONFIG, &SvtDefaultOptions_Impl::m_aConfigPath }, + { SvtPathOptions::PATH_DICTIONARY, &SvtDefaultOptions_Impl::m_aDictionaryPath }, + { SvtPathOptions::PATH_FAVORITES, &SvtDefaultOptions_Impl::m_aFavoritesPath }, + { SvtPathOptions::PATH_FILTER, &SvtDefaultOptions_Impl::m_aFilterPath }, + { SvtPathOptions::PATH_GALLERY, &SvtDefaultOptions_Impl::m_aGalleryPath }, + { SvtPathOptions::PATH_GRAPHIC, &SvtDefaultOptions_Impl::m_aGraphicPath }, + { SvtPathOptions::PATH_HELP, &SvtDefaultOptions_Impl::m_aHelpPath }, + { SvtPathOptions::PATH_LINGUISTIC, &SvtDefaultOptions_Impl::m_aLinguisticPath }, + { SvtPathOptions::PATH_MODULE, &SvtDefaultOptions_Impl::m_aModulePath }, + { SvtPathOptions::PATH_PALETTE, &SvtDefaultOptions_Impl::m_aPalettePath }, + { SvtPathOptions::PATH_PLUGIN, &SvtDefaultOptions_Impl::m_aPluginPath }, + { SvtPathOptions::PATH_TEMP, &SvtDefaultOptions_Impl::m_aTempPath }, + { SvtPathOptions::PATH_TEMPLATE, &SvtDefaultOptions_Impl::m_aTemplatePath }, + { SvtPathOptions::PATH_USERCONFIG, &SvtDefaultOptions_Impl::m_aUserConfigPath }, + { SvtPathOptions::PATH_WORK, &SvtDefaultOptions_Impl::m_aWorkPath } +}; + +// functions ------------------------------------------------------------- + +Sequence< OUString > GetDefaultPropertyNames() +{ + static const char* aPropNames[] = + { + "Addin", // PATH_ADDIN + "AutoCorrect", // PATH_AUTOCORRECT + "AutoText", // PATH_AUTOTEXT + "Backup", // PATH_BACKUP + "Basic", // PATH_BASIC + "Bitmap", // PATH_BITMAP + "Config", // PATH_CONFIG + "Dictionary", // PATH_DICTIONARY + "Favorite", // PATH_FAVORITES + "Filter", // PATH_FILTER + "Gallery", // PATH_GALLERY + "Graphic", // PATH_GRAPHIC + "Help", // PATH_HELP + "Linguistic", // PATH_LINGUISTIC + "Module", // PATH_MODULE + "Palette", // PATH_PALETTE + "Plugin", // PATH_PLUGIN + "Temp", // PATH_TEMP + "Template", // PATH_TEMPLATE + "UserConfig", // PATH_USERCONFIG + "Work" // PATH_WORK + }; + + const int nCount = sizeof( aPropNames ) / sizeof( const char* ); + Sequence< OUString > aNames( nCount ); + OUString* pNames = aNames.getArray(); + for ( int i = 0; i < nCount; i++ ) + pNames[i] = OUString::createFromAscii( aPropNames[i] ); + + return aNames; +} + +void SvtDefaultOptions_Impl::Notify( const Sequence< rtl::OUString >& ) +{ + // no notification, will never be changed +} + +void SvtDefaultOptions_Impl::Commit() +{ + // will never be changed +} + +// class SvtDefaultOptions_Impl ------------------------------------------ + +String SvtDefaultOptions_Impl::GetDefaultPath( USHORT nId ) const +{ + String aRet; + USHORT nIdx = 0; + + while ( PathMap_Impl[nIdx]._ePath <= SvtPathOptions::PATH_WORK ) + { + if ( nId == PathMap_Impl[nIdx]._ePath && PathMap_Impl[nIdx]._pDefaultPath ) + { + aRet = this->*(PathMap_Impl[nIdx]._pDefaultPath); + if ( nId == SvtPathOptions::PATH_ADDIN || + nId == SvtPathOptions::PATH_FILTER || + nId == SvtPathOptions::PATH_HELP || + nId == SvtPathOptions::PATH_MODULE || + nId == SvtPathOptions::PATH_PLUGIN ) + { + String aTmp; + ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aRet, aTmp ); + aRet = aTmp; + } + + break; + } + ++nIdx; + } + + return aRet; +} + +// ----------------------------------------------------------------------- + +SvtDefaultOptions_Impl::SvtDefaultOptions_Impl() : ConfigItem( ASCII_STR("Office.Common/Path/Default") ) +{ + /*ConfigManager* pCfgMgr =*/ ConfigManager::GetConfigManager(); + Sequence< OUString > aNames = GetDefaultPropertyNames(); + Sequence< Any > aValues = GetProperties( aNames ); + EnableNotification( aNames ); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" ); + if ( aValues.getLength() == aNames.getLength() ) + { + SvtPathOptions aPathOpt; + OUString aTempStr, aFullPath; + + for ( int nProp = 0; nProp < aNames.getLength(); nProp++ ) + { + if ( pValues[nProp].hasValue() ) + { + switch ( pValues[nProp].getValueTypeClass() ) + { + case ::com::sun::star::uno::TypeClass_STRING : + { + // multi pathes + if ( pValues[nProp] >>= aTempStr ) + aFullPath = aPathOpt.SubstituteVariable( aTempStr ); + else + { + DBG_ERRORFILE( "any operator >>= failed" ); + } + break; + } + + case ::com::sun::star::uno::TypeClass_SEQUENCE : + { + // single pathes + aFullPath = OUString(); + Sequence < OUString > aList; + if ( pValues[nProp] >>= aList ) + { + sal_Int32 nCount = aList.getLength(); + for ( sal_Int32 nPosition = 0; nPosition < nCount; ++nPosition ) + { + aTempStr = aPathOpt.SubstituteVariable( aList[ nPosition ] ); + aFullPath += aTempStr; + if ( nPosition < nCount-1 ) + aFullPath += OUString( RTL_CONSTASCII_USTRINGPARAM(";") ); + } + } + else + { + DBG_ERRORFILE( "any operator >>= failed" ); + } + break; + } + + default: + { + DBG_ERRORFILE( "Wrong any type" ); + } + } + + switch ( nProp ) + { + case DEFAULTPATH__ADDIN: m_aAddinPath = String( aFullPath ); break; + case DEFAULTPATH__AUTOCORRECT: m_aAutoCorrectPath = String( aFullPath ); break; + case DEFAULTPATH__AUTOTEXT: m_aAutoTextPath = String( aFullPath ); break; + case DEFAULTPATH__BACKUP: m_aBackupPath = String( aFullPath ); break; + case DEFAULTPATH__BASIC: m_aBasicPath = String( aFullPath ); break; + case DEFAULTPATH__BITMAP: m_aBitmapPath = String( aFullPath ); break; + case DEFAULTPATH__CONFIG: m_aConfigPath = String( aFullPath ); break; + case DEFAULTPATH__DICTIONARY: m_aDictionaryPath = String( aFullPath ); break; + case DEFAULTPATH__FAVORITES: m_aFavoritesPath = String( aFullPath ); break; + case DEFAULTPATH__FILTER: m_aFilterPath = String( aFullPath ); break; + case DEFAULTPATH__GALLERY: m_aGalleryPath = String( aFullPath ); break; + case DEFAULTPATH__GRAPHIC: m_aGraphicPath = String( aFullPath ); break; + case DEFAULTPATH__HELP: m_aHelpPath = String( aFullPath ); break; + case DEFAULTPATH__LINGUISTIC: m_aLinguisticPath = String( aFullPath ); break; + case DEFAULTPATH__MODULE: m_aModulePath = String( aFullPath ); break; + case DEFAULTPATH__PALETTE: m_aPalettePath = String( aFullPath ); break; + case DEFAULTPATH__PLUGIN: m_aPluginPath = String( aFullPath ); break; + case DEFAULTPATH__TEMP: m_aTempPath = String( aFullPath ); break; + case DEFAULTPATH__TEMPLATE: m_aTemplatePath = String( aFullPath ); break; + case DEFAULTPATH__USERCONFIG: m_aUserConfigPath = String( aFullPath ); break; + case DEFAULTPATH__WORK: m_aWorkPath = String( aFullPath ); break; + case DEFAULTPATH__USERDICTIONARY: m_aUserDictionaryPath = String( aFullPath );break; + + default: + DBG_ERRORFILE( "invalid index to load a default path" ); + } + } + } + } +} + +// class SvtDefaultOptions ----------------------------------------------- +namespace { struct lclMutex : public rtl::Static< ::osl::Mutex, lclMutex > {}; } + +SvtDefaultOptions::SvtDefaultOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( lclMutex::get() ); + if ( !pOptions ) + { + pOptions = new SvtDefaultOptions_Impl; + ItemHolder1::holdConfigItem(E_DEFAULTOPTIONS); + } + ++nRefCount; + pImp = pOptions; +} + +// ----------------------------------------------------------------------- + +SvtDefaultOptions::~SvtDefaultOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( lclMutex::get() ); + if ( !--nRefCount ) + { + if ( pOptions->IsModified() ) + pOptions->Commit(); + DELETEZ( pOptions ); + } +} + +// ----------------------------------------------------------------------- + +String SvtDefaultOptions::GetDefaultPath( USHORT nId ) const +{ + return pImp->GetDefaultPath( nId ); +} + diff --git a/unotools/source/config/docinfohelper.cxx b/unotools/source/config/docinfohelper.cxx new file mode 100644 index 000000000000..677432e1f7d3 --- /dev/null +++ b/unotools/source/config/docinfohelper.cxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <rtl/ustrbuf.hxx> +#include <tools/inetdef.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/bootstrap.hxx> +#include <unotools/docinfohelper.hxx> + +using namespace ::com::sun::star; + +namespace utl +{ + +::rtl::OUString DocInfoHelper::GetGeneratorString() +{ + rtl::OUStringBuffer aResult; + + // First product: branded name + version + // version is <product_versions>_<product_extension>$<platform> + utl::ConfigManager* pMgr = utl::ConfigManager::GetConfigManager(); + if ( pMgr ) + { + // plain product name + rtl::OUString aValue; + uno::Any aAny = pMgr->GetDirectConfigProperty( + utl::ConfigManager::PRODUCTNAME); + if ( (aAny >>= aValue) && aValue.getLength() ) + { + aResult.append( aValue.replace( ' ', '_' ) ); + aResult.append( (sal_Unicode)'/' ); + + aAny = pMgr->GetDirectConfigProperty( + utl::ConfigManager::PRODUCTVERSION); + if ( (aAny >>= aValue) && aValue.getLength() ) + { + aResult.append( aValue.replace( ' ', '_' ) ); + + aAny = pMgr->GetDirectConfigProperty( + utl::ConfigManager::PRODUCTEXTENSION); + if ( (aAny >>= aValue) && aValue.getLength() ) + { + aResult.append( (sal_Unicode)'_' ); + aResult.append( aValue.replace( ' ', '_' ) ); + } + } + + aResult.append( (sal_Unicode)'$' ); + aResult.append( ::rtl::OUString::createFromAscii( + TOOLS_INETDEF_OS ).replace( ' ', '_' ) ); + + aResult.append( (sal_Unicode)' ' ); + } + } + + // second product: OpenOffice.org_project/<build_information> + // build_information has '(' and '[' encoded as '$', ')' and ']' ignored + // and ':' replaced by '-' + { + aResult.appendAscii( "OpenOffice.org_project/" ); + ::rtl::OUString aDefault; + ::rtl::OUString aBuildId( Bootstrap::getBuildIdData( aDefault ) ); + for( sal_Int32 i=0; i < aBuildId.getLength(); i++ ) + { + sal_Unicode c = aBuildId[i]; + switch( c ) + { + case '(': + case '[': + aResult.append( (sal_Unicode)'$' ); + break; + case ')': + case ']': + break; + case ':': + aResult.append( (sal_Unicode)'-' ); + break; + default: + aResult.append( c ); + break; + } + } + } + + return aResult.makeStringAndClear(); +} + +} // end of namespace utl + diff --git a/unotools/source/config/dynamicmenuoptions.cxx b/unotools/source/config/dynamicmenuoptions.cxx new file mode 100644 index 000000000000..6ef88002a442 --- /dev/null +++ b/unotools/source/config/dynamicmenuoptions.cxx @@ -0,0 +1,920 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/dynamicmenuoptions.hxx> +#include <unotools/moduleoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#ifndef __SGI_STL_VECTOR +#include <vector> +#endif + +#include <itemholder1.hxx> + +#include <algorithm> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::std ; +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::beans ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_MENUS OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Menus/" )) +#define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" )) + +#define SETNODE_NEWMENU OUString(RTL_CONSTASCII_USTRINGPARAM("New" )) +#define SETNODE_WIZARDMENU OUString(RTL_CONSTASCII_USTRINGPARAM("Wizard" )) +#define SETNODE_HELPBOOKMARKS OUString(RTL_CONSTASCII_USTRINGPARAM("HelpBookmarks" )) + +#define PROPERTYNAME_URL DYNAMICMENU_PROPERTYNAME_URL +#define PROPERTYNAME_TITLE DYNAMICMENU_PROPERTYNAME_TITLE +#define PROPERTYNAME_IMAGEIDENTIFIER DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER +#define PROPERTYNAME_TARGETNAME DYNAMICMENU_PROPERTYNAME_TARGETNAME + +#define PROPERTYCOUNT 4 + +#define OFFSET_URL 0 +#define OFFSET_TITLE 1 +#define OFFSET_IMAGEIDENTIFIER 2 +#define OFFSET_TARGETNAME 3 + +#define PATHPREFIX_SETUP OUString(RTL_CONSTASCII_USTRINGPARAM("m" )) +#define PATHPREFIX_USER OUString(RTL_CONSTASCII_USTRINGPARAM("u" )) + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +/*-**************************************************************************************************************** + @descr struct to hold information about one menu entry. +****************************************************************************************************************-*/ +struct SvtDynMenuEntry +{ + public: + SvtDynMenuEntry() {}; + + SvtDynMenuEntry( const OUString& sNewURL , + const OUString& sNewTitle , + const OUString& sNewImageIdentifier , + const OUString& sNewTargetName ) + { + sURL = sNewURL ; + sTitle = sNewTitle ; + sImageIdentifier = sNewImageIdentifier ; + sTargetName = sNewTargetName ; + } + + public: + OUString sName ; + OUString sURL ; + OUString sTitle ; + OUString sImageIdentifier ; + OUString sTargetName ; +}; + +/*-**************************************************************************************************************** + @descr support simple menu structures and operations on it +****************************************************************************************************************-*/ +class SvtDynMenu +{ + public: + //--------------------------------------------------------------------------------------------------------- + // append setup written menu entry + // Don't touch name of entry. It was defined by setup and must be the same everytime! + // Look for double menu entries here too ... may be some seperator items are supeflous ... + void AppendSetupEntry( const SvtDynMenuEntry& rEntry ) + { + if( + ( lSetupEntries.size() < 1 ) || + ( lSetupEntries.rbegin()->sURL != rEntry.sURL ) + ) + { + lSetupEntries.push_back( rEntry ); + } + } + + //--------------------------------------------------------------------------------------------------------- + // append user specific menu entry + // We must find unique name for it by using special prefix + // and next count of user setted entries! + // Look for double menu entries here too ... may be some seperator items are supeflous ... + void AppendUserEntry( SvtDynMenuEntry& rEntry ) + { + if( + ( lUserEntries.size() < 1 ) || + ( lUserEntries.rbegin()->sURL != rEntry.sURL ) + ) + { + rEntry.sName = PATHPREFIX_USER; + rEntry.sName += OUString::valueOf( (sal_Int32)impl_getNextUserEntryNr() ); + lUserEntries.push_back( rEntry ); + } + } + + //--------------------------------------------------------------------------------------------------------- + // the only way to free memory! + void Clear() + { + lSetupEntries.clear(); + lUserEntries.clear(); + } + + //--------------------------------------------------------------------------------------------------------- + // convert internal list to external format + // for using it on right menus realy + // Notice: We build a property list with 4 entries and set it on result list then. + // The while-loop starts with pointer on internal member list lSetupEntries, change to + // lUserEntries then and stop after that with NULL! + // Separator entries will be packed in another way then normal entries! We define + // special strings "sEmpty" and "sSeperator" to perform too ... + Sequence< Sequence< PropertyValue > > GetList() const + { + sal_Int32 nSetupCount = (sal_Int32)lSetupEntries.size(); + sal_Int32 nUserCount = (sal_Int32)lUserEntries.size(); + sal_Int32 nStep = 0; + Sequence< PropertyValue > lProperties ( PROPERTYCOUNT ); + Sequence< Sequence< PropertyValue > > lResult ( nSetupCount+nUserCount ); + OUString sSeperator ( RTL_CONSTASCII_USTRINGPARAM("private:separator") ); + OUString sEmpty ; + const vector< SvtDynMenuEntry >* pList = &lSetupEntries; + + lProperties[OFFSET_URL ].Name = PROPERTYNAME_URL ; + lProperties[OFFSET_TITLE ].Name = PROPERTYNAME_TITLE ; + lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER ; + lProperties[OFFSET_TARGETNAME ].Name = PROPERTYNAME_TARGETNAME ; + + while( pList != NULL ) + { + for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin(); + pItem!=pList->end() ; + ++pItem ) + { + if( pItem->sURL == sSeperator ) + { + lProperties[OFFSET_URL ].Value <<= sSeperator ; + lProperties[OFFSET_TITLE ].Value <<= sEmpty ; + lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= sEmpty ; + lProperties[OFFSET_TARGETNAME ].Value <<= sEmpty ; + } + else + { + lProperties[OFFSET_URL ].Value <<= pItem->sURL ; + lProperties[OFFSET_TITLE ].Value <<= pItem->sTitle ; + lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier; + lProperties[OFFSET_TARGETNAME ].Value <<= pItem->sTargetName ; + } + lResult[nStep] = lProperties; + ++nStep; + } + if( pList == &lSetupEntries ) + pList = &lUserEntries; + else + pList = NULL; + } + return lResult; + } + + private: + //--------------------------------------------------------------------------------------------------------- + // search for an entry named "ux" with x=[0..i] inside our menu + // which has set highest number x. So we can add another user entry. + sal_Int32 impl_getNextUserEntryNr() const + { + sal_Int32 nNr = 0; + for( vector< SvtDynMenuEntry >::const_iterator pItem =lUserEntries.begin(); + pItem!=lUserEntries.end() ; + ++pItem ) + { + if( pItem->sName.compareTo( PATHPREFIX_USER, 1 ) == 0 ) + { + OUString sNr = pItem->sName.copy( 1, pItem->sName.getLength()-1 ); + sal_Int32 nCheckNr = sNr.toInt32(); + if( nCheckNr > nNr ) + nNr = nCheckNr; + } + } + // Attention: Code isn't prepared for recyling of unused fragmented numbers! + // If we reach end of sal_Int32 range ... we must stop further working ... + // But I think nobody expand a menu to more then 1000 ... 100000 ... entries ... or? + DBG_ASSERT( !(nNr>0x7fffffff), "Menu::impl_getNextUserEntryNr()\nUser count can be out of range next time ...\n" ); + return nNr; + } + + private: + vector< SvtDynMenuEntry > lSetupEntries; + vector< SvtDynMenuEntry > lUserEntries ; +}; + +class SvtDynamicMenuOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtDynamicMenuOptions_Impl(); + ~SvtDynamicMenuOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "lPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& lPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short base implementation of public interface for "SvtDynamicMenuOptions"! + @descr These class is used as static member of "SvtDynamicMenuOptions" ... + => The code exist only for one time and isn't duplicated for every instance! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + void Clear ( EDynamicMenuType eMenu ); + Sequence< Sequence< PropertyValue > > GetMenu ( EDynamicMenuType eMenu ) const ; + void AppendItem ( EDynamicMenuType eMenu , + const OUString& sURL , + const OUString& sTitle , + const OUString& sImageIdentifier, + const OUString& sTargetName ); + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of key names of our configuration management which represent oue module tree + @descr These methods return the current list of key names! We need it to get needed values from our + configuration management and support dynamical menu item lists! + + @seealso - + + @param "nNewCount" , returns count of menu entries for "new" + @param "nWizardCount" , returns count of menu entries for "wizard" + @return A list of configuration key names is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount ); + + /*-****************************************************************************************************//** + @short sort given source list and expand it for all well known properties to destination + @descr We must support sets of entries with count inside the name .. but some of them could be missing! + e.g. s1-s2-s3-s0-u1-s6-u5-u7 + Then we must sort it by name and expand it to the follow one: + sSetNode/s0/URL + sSetNode/s0/Title + sSetNode/s0/... + sSetNode/s1/URL + sSetNode/s1/Title + sSetNode/s1/... + ... + sSetNode/s6/URL + sSetNode/s6/Title + sSetNode/s6/... + sSetNode/u1/URL + sSetNode/u1/Title + sSetNode/u1/... + ... + sSetNode/u7/URL + sSetNode/u7/Title + sSetNode/u7/... + Rules: We start with all setup written entries names "sx" and x=[0..n]. + Then we handle all "ux" items. Inside these blocks we sort it ascending by number. + + @attention We add these expanded list to the end of given "lDestination" list! + So we must start on "lDestination.getLength()". + Reallocation of memory of destination list is done by us! + + @seealso method impl_GetPropertyNames() + + @param "lSource" , original list (e.g. [m1-m2-m3-m6-m0] ) + @param "lDestination" , destination of operation + @param "sSetNode" , name of configuration set to build complete path + @return A list of configuration key names is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource , + Sequence< OUString >& lDestination , + const OUString& sSetNode ); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + + SvtDynMenu m_aNewMenu ; + SvtDynMenu m_aWizardMenu ; + SvtDynMenu m_aHelpBookmarksMenu ; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl() + // Init baseclasses first + : ConfigItem( ROOTNODE_MENUS ) + // Init member then... +{ + // Get names and values of all accessable menu entries and fill internal structures. + // See impl_GetPropertyNames() for further informations. + sal_uInt32 nNewCount = 0; + sal_uInt32 nWizardCount = 0; + sal_uInt32 nHelpBookmarksCount = 0; + Sequence< OUString > lNames = impl_GetPropertyNames ( nNewCount , + nWizardCount , + nHelpBookmarksCount ); + Sequence< Any > lValues = GetProperties ( lNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + // Attention: List for names and values have an internal construction pattern! + // + // first "New" menu ... + // Name Value + // /New/1/URL "private:factory/swriter" + // /New/1/Title "Neues Writer Dokument" + // /New/1/ImageIdentifier "icon_writer" + // /New/1/TargetName "_blank" + // + // /New/2/URL "private:factory/scalc" + // /New/2/Title "Neues Calc Dokument" + // /New/2/ImageIdentifier "icon_calc" + // /New/2/TargetName "_blank" + // + // second "Wizard" menu ... + // /Wizard/1/URL "file://b" + // /Wizard/1/Title "MalWas" + // /Wizard/1/ImageIdentifier "icon_?" + // /Wizard/1/TargetName "_self" + // + // ... and so on ... + + sal_uInt32 nItem = 0 ; + sal_uInt32 nPosition = 0 ; + OUString sName ; + + // We must use these one instance object(!) to get information about installed modules. + // These information are used to filter menu entries wich need not installed modules ... + // Such entries shouldnt be available then! + // see impl_IsEntrySupported() too + SvtModuleOptions aModuleOptions; + + // Get names/values for new menu. + // 4 subkeys for every item! + for( nItem=0; nItem<nNewCount; ++nItem ) + { + SvtDynMenuEntry aItem ; + lValues[nPosition] >>= aItem.sURL ; + ++nPosition; + lValues[nPosition] >>= aItem.sTitle ; + ++nPosition; + lValues[nPosition] >>= aItem.sImageIdentifier ; + ++nPosition; + lValues[nPosition] >>= aItem.sTargetName ; + ++nPosition; + m_aNewMenu.AppendSetupEntry( aItem ); + } + + // Attention: Don't reset nPosition here! + + // Get names/values for wizard menu. + // 4 subkeys for every item! + for( nItem=0; nItem<nWizardCount; ++nItem ) + { + SvtDynMenuEntry aItem ; + lValues[nPosition] >>= aItem.sURL ; + ++nPosition; + lValues[nPosition] >>= aItem.sTitle ; + ++nPosition; + lValues[nPosition] >>= aItem.sImageIdentifier ; + ++nPosition; + lValues[nPosition] >>= aItem.sTargetName ; + ++nPosition; + m_aWizardMenu.AppendSetupEntry( aItem ); + } + + // Attention: Don't reset nPosition here! + + // Get names/values for wizard menu. + // 4 subkeys for every item! + for( nItem=0; nItem<nHelpBookmarksCount; ++nItem ) + { + SvtDynMenuEntry aItem ; + lValues[nPosition] >>= aItem.sURL ; + ++nPosition; + lValues[nPosition] >>= aItem.sTitle ; + ++nPosition; + lValues[nPosition] >>= aItem.sImageIdentifier ; + ++nPosition; + lValues[nPosition] >>= aItem.sTargetName ; + ++nPosition; + m_aHelpBookmarksMenu.AppendSetupEntry( aItem ); + } + +/*TODO: Not used in the moment! see Notify() ... + // Enable notification mechanism of ouer baseclass. + // We need it to get information about changes outside these class on ouer used configuration keys! + EnableNotification( lNames ); +*/ +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& ) +{ + DBG_ASSERT( sal_False, "SvtDynamicMenuOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtDynamicMenuOptions_Impl::Commit() +{ + DBG_ERROR( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" ); + /* + // Write all properties! + // Delete complete sets first. + ClearNodeSet( SETNODE_NEWMENU ); + ClearNodeSet( SETNODE_WIZARDMENU ); + ClearNodeSet( SETNODE_HELPBOOKMARKS ); + + MenuEntry aItem ; + OUString sNode ; + Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT ); + sal_uInt32 nItem = 0 ; + + // Copy "new" menu entries to save-list! + sal_uInt32 nNewCount = m_aNewMenu.size(); + for( nItem=0; nItem<nNewCount; ++nItem ) + { + aItem = m_aNewMenu[nItem]; + // Format: "New/1/URL" + // "New/1/Title" + // ... + sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER; + + lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ; + lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ; + lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ; + lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ; + + lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ; + lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ; + lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ; + lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ; + + SetSetProperties( SETNODE_NEWMENU, lPropertyValues ); + } + + // Copy "wizard" menu entries to save-list! + sal_uInt32 nWizardCount = m_aWizardMenu.size(); + for( nItem=0; nItem<nWizardCount; ++nItem ) + { + aItem = m_aWizardMenu[nItem]; + // Format: "Wizard/1/URL" + // "Wizard/1/Title" + // ... + sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER; + + lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ; + lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ; + lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ; + lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ; + + lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ; + lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ; + lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ; + lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ; + + SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues ); + } + + // Copy help bookmarks entries to save-list! + sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size(); + for( nItem=0; nItem<nHelpBookmarksCount; ++nItem ) + { + aItem = m_aHelpBookmarksMenu[nItem]; + // Format: "HelpBookmarks/1/URL" + // "HelpBookmarks/1/Title" + // ... + sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER; + + lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ; + lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ; + lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ; + lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ; + + lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ; + lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ; + lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ; + lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ; + + SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues ); + } + */ +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtDynamicMenuOptions_Impl::Clear( EDynamicMenuType eMenu ) +{ + switch( eMenu ) + { + case E_NEWMENU : { + m_aNewMenu.Clear(); + SetModified(); + } + break; + + case E_WIZARDMENU : { + m_aWizardMenu.Clear(); + SetModified(); + } + break; + + case E_HELPBOOKMARKS : { + m_aHelpBookmarksMenu.Clear(); + SetModified(); + } + break; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const +{ + Sequence< Sequence< PropertyValue > > lReturn; + switch( eMenu ) + { + case E_NEWMENU : { + lReturn = m_aNewMenu.GetList(); + } + break; + + case E_WIZARDMENU : { + lReturn = m_aWizardMenu.GetList(); + } + break; + + case E_HELPBOOKMARKS : { + lReturn = m_aHelpBookmarksMenu.GetList(); + } + break; + } + return lReturn; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtDynamicMenuOptions_Impl::AppendItem( EDynamicMenuType eMenu , + const OUString& sURL , + const OUString& sTitle , + const OUString& sImageIdentifier, + const OUString& sTargetName ) +{ + SvtDynMenuEntry aItem( sURL, sTitle, sImageIdentifier, sTargetName ); + + switch( eMenu ) + { + case E_NEWMENU : { + m_aNewMenu.AppendUserEntry( aItem ); + SetModified(); + } + break; + + case E_WIZARDMENU : { + m_aWizardMenu.AppendUserEntry( aItem ); + SetModified(); + } + break; + + case E_HELPBOOKMARKS : { + m_aHelpBookmarksMenu.AppendUserEntry( aItem ); + SetModified(); + } + break; + } +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount ) +{ + // First get ALL names of current existing list items in configuration! + Sequence< OUString > lNewItems = GetNodeNames( SETNODE_NEWMENU ); + Sequence< OUString > lWizardItems = GetNodeNames( SETNODE_WIZARDMENU ); + Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS ); + + // Get information about list counts ... + nNewCount = lNewItems.getLength (); + nWizardCount = lWizardItems.getLength (); + nHelpBookmarksCount = lHelpBookmarksItems.getLength(); + + // Sort and expand all three list to result list ... + Sequence< OUString > lProperties; + impl_SortAndExpandPropertyNames( lNewItems , lProperties, SETNODE_NEWMENU ); + impl_SortAndExpandPropertyNames( lWizardItems , lProperties, SETNODE_WIZARDMENU ); + impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS ); + + // Return result. + return lProperties; +} + +//***************************************************************************************************************** +// private helper +//***************************************************************************************************************** +class CountWithPrefixSort +{ + public: + int operator() ( const OUString& s1 , + const OUString& s2 ) const + { + // Get order numbers from entry name without prefix. + // e.g. "m10" => 10 + // "m5" => 5 + sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32(); + sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32(); + // MUST be in [0,1] ... because it's a difference between + // insert-positions of given entries in sorted list! + return( n1<n2 ); + } +}; + +class SelectByPrefix +{ + public: + bool operator() ( const OUString& s ) const + { + // Prefer setup written entries by check first letter of given string. It must be a "s". + return( s.indexOf( PATHPREFIX_SETUP ) == 0 ); + } +}; + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource , + Sequence< OUString >& lDestination , + const OUString& sSetNode ) +{ + OUString sFixPath ; + vector< OUString > lTemp ; + sal_Int32 nSourceCount = lSource.getLength() ; + sal_Int32 nDestinationStep = lDestination.getLength() ; // start on end of current list ...! + + lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ... + + // Copy all items to temp. vector to use fast sort operations :-) + for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep ) + lTemp.push_back( lSource[nSourceStep] ); + + // Sort all entries by number ... + stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() ); + // and split into setup & user written entries! + stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() ); + + // Copy sorted entries to destination and expand every item with + // 4 supported sub properties. + for( vector< OUString >::const_iterator pItem =lTemp.begin() ; + pItem!=lTemp.end() ; + ++pItem ) + { + sFixPath = sSetNode ; + sFixPath += PATHDELIMITER ; + sFixPath += *pItem ; + sFixPath += PATHDELIMITER ; + + lDestination[nDestinationStep] = sFixPath ; + lDestination[nDestinationStep] += PROPERTYNAME_URL ; + ++nDestinationStep; + lDestination[nDestinationStep] = sFixPath ; + lDestination[nDestinationStep] += PROPERTYNAME_TITLE ; + ++nDestinationStep; + lDestination[nDestinationStep] = sFixPath ; + lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER ; + ++nDestinationStep; + lDestination[nDestinationStep] = sFixPath ; + lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME ; + ++nDestinationStep; + } +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtDynamicMenuOptions_Impl* SvtDynamicMenuOptions::m_pDataContainer = NULL ; +sal_Int32 SvtDynamicMenuOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtDynamicMenuOptions::SvtDynamicMenuOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + m_pDataContainer = new SvtDynamicMenuOptions_Impl; + ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtDynamicMenuOptions::~SvtDynamicMenuOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtDynamicMenuOptions::Clear( EDynamicMenuType eMenu ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->Clear( eMenu ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetMenu( eMenu ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtDynamicMenuOptions::AppendItem( EDynamicMenuType eMenu , + const OUString& sURL , + const OUString& sTitle , + const OUString& sImageIdentifier, + const OUString& sTargetName ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->AppendItem( eMenu, sURL, sTitle, sImageIdentifier, sTargetName ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/eventcfg.cxx b/unotools/source/config/eventcfg.cxx new file mode 100644 index 000000000000..a07c99b70381 --- /dev/null +++ b/unotools/source/config/eventcfg.cxx @@ -0,0 +1,455 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/eventcfg.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <cppuhelper/weakref.hxx> + +#ifndef __SGI_STL_HASH_MAP +#include <hash_map> +#endif +#include <tools/urlobj.hxx> +#include <rtl/ustrbuf.hxx> + +#include <itemholder1.hxx> + +#include <algorithm> + +using namespace ::std ; +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star; + +#define ROOTNODE_EVENTS OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Events/ApplicationEvents" )) +#define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +#define SETNODE_BINDINGS OUString(RTL_CONSTASCII_USTRINGPARAM("Bindings" )) +#define PROPERTYNAME_BINDINGURL OUString(RTL_CONSTASCII_USTRINGPARAM("BindingURL")) + +const char* pEventAsciiNames[] = +{ +"OnStartApp", +"OnCloseApp", +"OnCreate", +"OnNew", +"OnLoadFinished", +"OnLoad", +"OnPrepareUnload", +"OnUnload", +"OnSave", +"OnSaveDone", +"OnSaveFailed", +"OnSaveAs", +"OnSaveAsDone", +"OnSaveAsFailed", +"OnCopyTo", +"OnCopyToDone", +"OnCopyToFailed", +"OnFocus", +"OnUnfocus", +"OnPrint", +"OnViewCreated", +"OnPrepareViewClosing", +"OnViewClosed", +"OnModifyChanged", +"OnTitleChanged", +"OnVisAreaChanged", +"OnModeChanged", +"OnStorageChanged" +}; + +GlobalEventConfig_Impl::GlobalEventConfig_Impl() + : ConfigItem( ROOTNODE_EVENTS, CONFIG_MODE_IMMEDIATE_UPDATE ) +{ + // the supported event names + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_STARTAPP] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_CLOSEAPP] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_DOCCREATED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_CREATEDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_LOADFINISHED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_OPENDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_PREPARECLOSEDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_CLOSEDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVEDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVEDOCDONE] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVEDOCFAILED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVEASDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVEASDOCDONE] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVEASDOCFAILED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVETODOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVETODOCDONE] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_SAVETODOCFAILED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_ACTIVATEDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_DEACTIVATEDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_PRINTDOC] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_VIEWCREATED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_PREPARECLOSEVIEW] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_CLOSEVIEW] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_MODIFYCHANGED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_TITLECHANGED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_VISAREACHANGED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_MODECHANGED] ) ); + m_supportedEvents.push_back(::rtl::OUString::createFromAscii( pEventAsciiNames[STR_EVENT_STORAGECHANGED] ) ); + + initBindingInfo(); + +/*TODO: Not used in the moment! see Notify() ... + // Enable notification mechanism of our baseclass. + // We need it to get information about changes outside these class on our used configuration keys! */ + Sequence< OUString > aNotifySeq( 1 ); + aNotifySeq[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Events" )); + EnableNotification( aNotifySeq, sal_True ); +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +GlobalEventConfig_Impl::~GlobalEventConfig_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +::rtl::OUString GlobalEventConfig_Impl::GetEventName( sal_Int32 nIndex ) +{ + if ( nIndex < (sal_Int32) m_supportedEvents.size() ) + return m_supportedEvents[nIndex]; + else + return rtl::OUString(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void GlobalEventConfig_Impl::Notify( const Sequence< OUString >& ) +{ + MutexGuard aGuard( GlobalEventConfig::GetOwnStaticMutex() ); + + initBindingInfo(); + + // dont forget to update all existing frames and her might cached dispatch objects! + // But look for already killed frames. We hold weak references instead of hard ones ... + for (FrameVector::const_iterator pIt = m_lFrames.begin(); + pIt != m_lFrames.end() ; + ++pIt ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame(pIt->get(), ::com::sun::star::uno::UNO_QUERY); + if (xFrame.is()) + xFrame->contextChanged(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void GlobalEventConfig_Impl::Commit() +{ + //DF need to check it this is correct?? + OSL_TRACE("In GlobalEventConfig_Impl::Commit"); + EventBindingHash::const_iterator it = m_eventBindingHash.begin(); + EventBindingHash::const_iterator it_end = m_eventBindingHash.end(); + // clear the existing nodes + ClearNodeSet( SETNODE_BINDINGS ); + Sequence< beans::PropertyValue > seqValues( 1 ); + OUString sNode; + static const OUString sPrefix(SETNODE_BINDINGS + PATHDELIMITER + OUString::createFromAscii("BindingType['")); + static const OUString sPostfix(OUString::createFromAscii("']") + PATHDELIMITER + PROPERTYNAME_BINDINGURL); + //step through the list of events + for(int i=0;it!=it_end;++it,++i) + { + //no point in writing out empty bindings! + if(it->second.getLength() == 0 ) + continue; + sNode = sPrefix + it->first + sPostfix; + OSL_TRACE("writing binding for: %s",::rtl::OUStringToOString(sNode , RTL_TEXTENCODING_ASCII_US ).pData->buffer); + seqValues[ 0 ].Name = sNode; + seqValues[ 0 ].Value <<= it->second; + //write the data to the registry + SetSetProperties(SETNODE_BINDINGS,seqValues); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void GlobalEventConfig_Impl::EstablishFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame) +{ + // check if frame already exists inside list + // ignore double registrations + // every frame must be notified one times only! + ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame > xWeak(xFrame); + FrameVector::const_iterator pIt = ::std::find(m_lFrames.begin(), m_lFrames.end(), xWeak); + if (pIt == m_lFrames.end()) + m_lFrames.push_back(xWeak); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +void GlobalEventConfig_Impl::initBindingInfo() +{ + // Get ALL names of current existing list items in configuration! + Sequence< OUString > lEventNames = GetNodeNames( SETNODE_BINDINGS, utl::CONFIG_NAME_LOCAL_PATH ); + + OUString aSetNode( SETNODE_BINDINGS ); + aSetNode += PATHDELIMITER; + + OUString aCommandKey( PATHDELIMITER ); + aCommandKey += PROPERTYNAME_BINDINGURL; + + // Expand all keys + Sequence< OUString > lMacros(1); + for (sal_Int32 i=0; i<lEventNames.getLength(); ++i ) + { + OUStringBuffer aBuffer( 32 ); + aBuffer.append( aSetNode ); + aBuffer.append( lEventNames[i] ); + aBuffer.append( aCommandKey ); + lMacros[0] = aBuffer.makeStringAndClear(); + OSL_TRACE("reading binding for: %s",::rtl::OUStringToOString(lMacros[0] , RTL_TEXTENCODING_ASCII_US ).pData->buffer); + Sequence< Any > lValues = GetProperties( lMacros ); + OUString sMacroURL; + if( lValues.getLength() > 0 ) + { + lValues[0] >>= sMacroURL; + sal_Int32 startIndex = lEventNames[i].indexOf('\''); + sal_Int32 endIndex = lEventNames[i].lastIndexOf('\''); + if( startIndex >=0 && endIndex > 0 ) + { + startIndex++; + OUString eventName = lEventNames[i].copy(startIndex,endIndex-startIndex); + m_eventBindingHash[ eventName ] = sMacroURL; + } + } + } +} + +Reference< container::XNameReplace > SAL_CALL GlobalEventConfig_Impl::getEvents() throw (::com::sun::star::uno::RuntimeException) +{ + //how to return this object as an XNameReplace? + Reference< container::XNameReplace > ret; + return ret; +} + +void SAL_CALL GlobalEventConfig_Impl::replaceByName( const OUString& aName, const Any& aElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + Sequence< beans::PropertyValue > props; + //DF should we prepopulate the hash with a list of valid event Names? + if( sal_False == ( aElement >>= props ) ) + { + throw lang::IllegalArgumentException( OUString(), + Reference< XInterface > (), 2); + } + OUString macroURL; + sal_Int32 nPropCount = props.getLength(); + for( sal_Int32 index = 0 ; index < nPropCount ; ++index ) + { + if ( props[ index ].Name.compareToAscii( "Script" ) == 0 ) + props[ index ].Value >>= macroURL; + } + m_eventBindingHash[ aName ] = macroURL; + SetModified(); +} + +Any SAL_CALL GlobalEventConfig_Impl::getByName( const OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + Any aRet; + Sequence< beans::PropertyValue > props(2); + props[0].Name = OUString::createFromAscii("EventType"); + props[0].Value <<= OUString::createFromAscii("Script"); + props[1].Name = OUString::createFromAscii("Script"); + EventBindingHash::const_iterator it = m_eventBindingHash.find( aName ); + if( it != m_eventBindingHash.end() ) + { + props[1].Value <<= it->second; + } + else + { + // not yet accessed - is it a supported name? + SupportedEventsVector::const_iterator pos = ::std::find( + m_supportedEvents.begin(), m_supportedEvents.end(), aName ); + if ( pos == m_supportedEvents.end() ) + throw container::NoSuchElementException( aName, NULL ); + + props[1].Value <<= OUString(); + } + aRet <<= props; + return aRet; +} + +Sequence< OUString > SAL_CALL GlobalEventConfig_Impl::getElementNames( ) throw (RuntimeException) +{ + const ::rtl::OUString* pRet = m_supportedEvents.empty() ? NULL : &m_supportedEvents[0]; + return uno::Sequence< ::rtl::OUString >(pRet, m_supportedEvents.size()); +} + +sal_Bool SAL_CALL GlobalEventConfig_Impl::hasByName( const OUString& aName ) throw (RuntimeException) +{ + if ( m_eventBindingHash.find( aName ) != m_eventBindingHash.end() ) + return sal_True; + + // never accessed before - is it supported in general? + SupportedEventsVector::const_iterator pos = ::std::find( + m_supportedEvents.begin(), m_supportedEvents.end(), aName ); + if ( pos != m_supportedEvents.end() ) + return sal_True; + + return sal_False; +} + +Type SAL_CALL GlobalEventConfig_Impl::getElementType( ) throw (RuntimeException) +{ + //DF definitly not sure about this?? + return ::getCppuType((const Sequence<beans::PropertyValue>*)0); +} + +sal_Bool SAL_CALL GlobalEventConfig_Impl::hasElements( ) throw (RuntimeException) +{ + return ( m_eventBindingHash.empty() ); +} + +// and now the wrapper + + +//initialize static member +GlobalEventConfig_Impl* GlobalEventConfig::m_pImpl = NULL ; +sal_Int32 GlobalEventConfig::m_nRefCount = 0 ; + +GlobalEventConfig::GlobalEventConfig() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase our refcount ... + ++m_nRefCount; + // ... and initialize our data container only if it not already exist! + if( m_pImpl == NULL ) + { + m_pImpl = new GlobalEventConfig_Impl; + ItemHolder1::holdConfigItem(E_EVENTCFG); + } +} + +GlobalEventConfig::~GlobalEventConfig() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease our refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy our static data container! + if( m_nRefCount <= 0 ) + { + delete m_pImpl; + m_pImpl = NULL; + } +} + +void GlobalEventConfig::EstablishFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pImpl->EstablishFrameCallback( xFrame ); +} + +Reference< container::XNameReplace > SAL_CALL GlobalEventConfig::getEvents() throw (::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + Reference< container::XNameReplace > ret(this); + return ret; +} + +void SAL_CALL GlobalEventConfig::replaceByName( const OUString& aName, const Any& aElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pImpl->replaceByName( aName, aElement ); +} +Any SAL_CALL GlobalEventConfig::getByName( const OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pImpl->getByName( aName ); +} +Sequence< OUString > SAL_CALL GlobalEventConfig::getElementNames( ) throw (RuntimeException) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pImpl->getElementNames( ); +} +sal_Bool SAL_CALL GlobalEventConfig::hasByName( const OUString& aName ) throw (RuntimeException) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pImpl->hasByName( aName ); +} +Type SAL_CALL GlobalEventConfig::getElementType( ) throw (RuntimeException) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pImpl->getElementType( ); +} +sal_Bool SAL_CALL GlobalEventConfig::hasElements( ) throw (RuntimeException) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pImpl->hasElements( ); +} + +Mutex& GlobalEventConfig::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect following code with + // the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that + // another instance of our class will be faster then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} + +::rtl::OUString GlobalEventConfig::GetEventName( sal_Int32 nIndex ) +{ + return GlobalEventConfig().m_pImpl->GetEventName( nIndex ); +} + diff --git a/unotools/source/config/extendedsecurityoptions.cxx b/unotools/source/config/extendedsecurityoptions.cxx new file mode 100644 index 000000000000..716733e2d090 --- /dev/null +++ b/unotools/source/config/extendedsecurityoptions.cxx @@ -0,0 +1,538 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/extendedsecurityoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <tools/urlobj.hxx> +#include <tools/wldcrd.hxx> +#include <rtl/ustrbuf.hxx> + +#include <unotools/pathoptions.hxx> + +#include <hash_map> + +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_SECURITY OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Security")) + +#define SECURE_EXTENSIONS_SET OUString(RTL_CONSTASCII_USTRINGPARAM("SecureExtensions")) +#define EXTENSION_PROPNAME OUString(RTL_CONSTASCII_USTRINGPARAM("/Extension")) + +#define PROPERTYNAME_HYPERLINKS_OPEN OUString(RTL_CONSTASCII_USTRINGPARAM("Hyperlinks/Open")) + +#define PROPERTYHANDLE_HYPERLINKS_OPEN 0 + +#define PROPERTYCOUNT 1 + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +struct OUStringHashCode +{ + size_t operator()( const ::rtl::OUString& sString ) const + { + return sString.hashCode(); + } +}; + +class ExtensionHashMap : public ::std::hash_map< ::rtl::OUString, + sal_Int32, + OUStringHashCode, + ::std::equal_to< ::rtl::OUString > > +{ + public: + inline void free() + { + ExtensionHashMap().swap( *this ); + } +}; + +class SvtExtendedSecurityOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtExtendedSecurityOptions_Impl(); + ~SvtExtendedSecurityOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& seqPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short Access method to check for security problems + @descr Different methods to check for security related problems. + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + sal_Bool IsSecureHyperlink( const rtl::OUString& aURL ) const; + Sequence< rtl::OUString > GetSecureExtensionList() const; + + SvtExtendedSecurityOptions::OpenHyperlinkMode GetOpenHyperlinkMode(); + void SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode aMode ); + sal_Bool IsOpenHyperlinkModeReadOnly() const; + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of key names of ouer configuration management which represent oue module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. + + @seealso - + + @param - + @return A list of needed configuration keys is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + static Sequence< OUString > GetPropertyNames(); + + /*-****************************************************************************************************//** + @short Fills the hash map with all extensions known to be secure + @descr These methods fills the given hash map object with all extensions known to be secure. + + @seealso - + + @param aHashMap + A hash map to be filled with secure extension strings. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + void FillExtensionHashMap( ExtensionHashMap& aHashMap ); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + OUString m_aSecureExtensionsSetName; + OUString m_aExtensionPropName; + + SvtExtendedSecurityOptions::OpenHyperlinkMode m_eOpenHyperlinkMode; + sal_Bool m_bROOpenHyperlinkMode; + ExtensionHashMap m_aExtensionHashMap; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl() + // Init baseclasses first + : ConfigItem ( ROOTNODE_SECURITY ), + m_aSecureExtensionsSetName( SECURE_EXTENSIONS_SET ), + m_aExtensionPropName( EXTENSION_PROPNAME ), + m_bROOpenHyperlinkMode(sal_False) + // Init member then. +{ + // Fill the extension hash map with all secure extension strings + FillExtensionHashMap( m_aExtensionHashMap ); + + Sequence< OUString > seqNames = GetPropertyNames(); + Sequence< Any > seqValues = GetProperties( seqNames ); + Sequence< sal_Bool > seqRO = GetReadOnlyStates ( seqNames ); + + sal_Int32 nPropertyCount = seqValues.getLength(); + for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + // Safe impossible cases. + // Check any for valid value. + DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()\nInvalid property value detected!\n" ); + switch( nProperty ) + { + case PROPERTYHANDLE_HYPERLINKS_OPEN: + { + DBG_ASSERT( ( seqValues[nProperty].getValueTypeClass() == TypeClass_LONG ), "SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()\nWho has changed the value type of 'Hyperlink/Open'?" ); + + sal_Int32 nMode = SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK; + if ( seqValues[nProperty] >>= nMode ) + m_eOpenHyperlinkMode = (SvtExtendedSecurityOptions::OpenHyperlinkMode)nMode; + else { + DBG_ERROR("Wrong type for Open mode!"); + } + m_bROOpenHyperlinkMode = seqRO[nProperty]; + } + break; + } + } + + // Enable notification mechanism of our baseclass. + // We need it to get information about changes outside these class on ouer used configuration keys! + Sequence< OUString > seqNotifyNames( 1 ); + seqNotifyNames[0] = m_aSecureExtensionsSetName; + EnableNotification( seqNotifyNames ); +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtExtendedSecurityOptions_Impl::~SvtExtendedSecurityOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtExtendedSecurityOptions_Impl::Notify( const Sequence< OUString >& ) +{ + // Not implemented +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtExtendedSecurityOptions_Impl::Commit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + Sequence< OUString > seqNames = GetPropertyNames (); + sal_Int32 nCount = seqNames.getLength(); + Sequence< Any > seqValues ( nCount ); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_HYPERLINKS_OPEN: { + seqValues[nProperty] <<= (sal_Int32)m_eOpenHyperlinkMode; + } + break; + } + } + + // Set properties in configuration. + PutProperties( seqNames, seqValues ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtExtendedSecurityOptions_Impl::IsSecureHyperlink( const OUString& aURL ) const +{ + INetURLObject aURLObject( aURL ); + + String aExtension = aURLObject.getExtension(); + aExtension.ToLowerAscii(); + + ExtensionHashMap::const_iterator pIter = m_aExtensionHashMap.find( aExtension ); + if ( pIter != m_aExtensionHashMap.end() ) + return sal_True; + else + return sal_False; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< OUString > SvtExtendedSecurityOptions_Impl::GetSecureExtensionList() const +{ + Sequence< OUString > aResult( m_aExtensionHashMap.size() ); + + sal_Int32 nIndex = 0; + for ( ExtensionHashMap::const_iterator pIter = m_aExtensionHashMap.begin(); + pIter != m_aExtensionHashMap.end(); pIter++ ) + { + aResult[nIndex++] = pIter->first; + } + + return aResult; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +SvtExtendedSecurityOptions::OpenHyperlinkMode SvtExtendedSecurityOptions_Impl::GetOpenHyperlinkMode() +{ + return m_eOpenHyperlinkMode; +} +/* -----------------09.07.2003 11:26----------------- + + --------------------------------------------------*/ +sal_Bool SvtExtendedSecurityOptions_Impl::IsOpenHyperlinkModeReadOnly() const +{ + return m_bROOpenHyperlinkMode; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtExtendedSecurityOptions_Impl::SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode eNewMode ) +{ + m_eOpenHyperlinkMode = eNewMode; + SetModified(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +void SvtExtendedSecurityOptions_Impl::FillExtensionHashMap( ExtensionHashMap& aHashMap ) +{ + // Get sequence with secure extensions from configuration + Sequence< OUString > seqNodes = GetNodeNames( m_aSecureExtensionsSetName ); + + OUString aValue; + Sequence< Any > aValues; + Sequence< OUString > aPropSeq( 1 ); + for ( int i = 0; i < seqNodes.getLength(); i++ ) + { + // Create access name for property + OUStringBuffer aExtEntryProp( m_aSecureExtensionsSetName ); + aExtEntryProp.appendAscii( "/" ); + aExtEntryProp.append( seqNodes[i] ); + aExtEntryProp.append( m_aExtensionPropName ); + + aPropSeq[0] = aExtEntryProp.makeStringAndClear(); + aValues = GetProperties( aPropSeq ); + if ( aValues.getLength() == 1 ) + { + // Don't use value if sequence has not the correct length + if ( aValues[0] >>= aValue ) + // Add extension into secure extensions hash map + aHashMap.insert( ExtensionHashMap::value_type( aValue.toAsciiLowerCase(), 1 ) ); + else + { + DBG_ERRORFILE( "SvtExtendedSecurityOptions_Impl::FillExtensionHashMap(): not string value?" ); + } + } + } +} + +//***************************************************************************************************************** +// private method (currently not used) +//***************************************************************************************************************** +Sequence< OUString > SvtExtendedSecurityOptions_Impl::GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_HYPERLINKS_OPEN + }; + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtExtendedSecurityOptions_Impl* SvtExtendedSecurityOptions::m_pDataContainer = NULL ; +sal_Int32 SvtExtendedSecurityOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtExtendedSecurityOptions::SvtExtendedSecurityOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetInitMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtExtendedSecurityOptions_Impl::ctor()"); + m_pDataContainer = new SvtExtendedSecurityOptions_Impl; + + ItemHolder1::holdConfigItem(E_EXTENDEDSECURITYOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtExtendedSecurityOptions::~SvtExtendedSecurityOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetInitMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtExtendedSecurityOptions::IsSecureHyperlink( const rtl::OUString& aURL ) const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsSecureHyperlink( aURL ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< rtl::OUString > SvtExtendedSecurityOptions::GetSecureExtensionList() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->GetSecureExtensionList(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +SvtExtendedSecurityOptions::OpenHyperlinkMode SvtExtendedSecurityOptions::GetOpenHyperlinkMode() +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->GetOpenHyperlinkMode(); +} +/* -----------------09.07.2003 11:26----------------- + + --------------------------------------------------*/ +sal_Bool SvtExtendedSecurityOptions::IsOpenHyperlinkModeReadOnly() const +{ + return m_pDataContainer->IsOpenHyperlinkModeReadOnly(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtExtendedSecurityOptions::SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode eMode ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetOpenHyperlinkMode( eMode ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtExtendedSecurityOptions::GetInitMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/fltrcfg.cxx b/unotools/source/config/fltrcfg.cxx new file mode 100644 index 000000000000..94f7ff07d7d7 --- /dev/null +++ b/unotools/source/config/fltrcfg.cxx @@ -0,0 +1,616 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/fltrcfg.hxx> +#include <tools/debug.hxx> + +#include <rtl/logfile.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; + +#define C2U(cChar) OUString::createFromAscii(cChar) + +// ----------------------------------------------------------------------- +#define FILTERCFG_WORD_CODE 0x0001 +#define FILTERCFG_WORD_STORAGE 0x0002 +#define FILTERCFG_EXCEL_CODE 0x0004 +#define FILTERCFG_EXCEL_STORAGE 0x0008 +#define FILTERCFG_PPOINT_CODE 0x0010 +#define FILTERCFG_PPOINT_STORAGE 0x0020 +#define FILTERCFG_MATH_LOAD 0x0100 +#define FILTERCFG_MATH_SAVE 0x0200 +#define FILTERCFG_WRITER_LOAD 0x0400 +#define FILTERCFG_WRITER_SAVE 0x0800 +#define FILTERCFG_CALC_LOAD 0x1000 +#define FILTERCFG_CALC_SAVE 0x2000 +#define FILTERCFG_IMPRESS_LOAD 0x4000 +#define FILTERCFG_IMPRESS_SAVE 0x8000 +#define FILTERCFG_EXCEL_EXECTBL 0x10000 +#define FILTERCFG_ENABLE_PPT_PREVIEW 0x20000 +#define FILTERCFG_ENABLE_EXCEL_PREVIEW 0x40000 +#define FILTERCFG_ENABLE_WORD_PREVIEW 0x80000 +#define FILTERCFG_USE_ENHANCED_FIELDS 0x100000 + +static SvtFilterOptions* pOptions=0; + +/* -----------------------------22.01.01 10:23-------------------------------- + + ---------------------------------------------------------------------------*/ +class SvtAppFilterOptions_Impl : public utl::ConfigItem +{ + sal_Bool bLoadVBA; + sal_Bool bSaveVBA; +public: + SvtAppFilterOptions_Impl(const OUString& rRoot) : + utl::ConfigItem(rRoot), + bLoadVBA(sal_False), + bSaveVBA(sal_False) {} + ~SvtAppFilterOptions_Impl(); + virtual void Commit(); + virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames); + void Load(); + + sal_Bool IsLoad() const {return bLoadVBA;} + void SetLoad(sal_Bool bSet) + { + if(bSet != bLoadVBA) + SetModified(); + bLoadVBA = bSet; + } + sal_Bool IsSave() const {return bSaveVBA;} + void SetSave(sal_Bool bSet) + { + if(bSet != bSaveVBA) + SetModified(); + bSaveVBA = bSet; + } +}; + +/* -----------------------------22.01.01 11:08-------------------------------- + + ---------------------------------------------------------------------------*/ +SvtAppFilterOptions_Impl::~SvtAppFilterOptions_Impl() +{ + if(IsModified()) + Commit(); +} +/* -----------------------------22.01.01 10:38-------------------------------- + + ---------------------------------------------------------------------------*/ +void SvtAppFilterOptions_Impl::Commit() +{ + Sequence<OUString> aNames(2); + OUString* pNames = aNames.getArray(); + pNames[0] = C2U("Load"); + pNames[1] = C2U("Save"); + Sequence<Any> aValues(aNames.getLength()); + Any* pValues = aValues.getArray(); + + const Type& rType = ::getBooleanCppuType(); + pValues[0].setValue(&bLoadVBA, rType); + pValues[1].setValue(&bSaveVBA, rType); + + PutProperties(aNames, aValues); +} + +void SvtAppFilterOptions_Impl::Notify( const Sequence< rtl::OUString >& ) +{ + // no listeners supported yet +} + + +/* -----------------------------22.01.01 10:38-------------------------------- + + ---------------------------------------------------------------------------*/ +void SvtAppFilterOptions_Impl::Load() +{ + Sequence<OUString> aNames(2); + OUString* pNames = aNames.getArray(); + pNames[0] = C2U("Load"); + pNames[1] = C2U("Save"); + + Sequence<Any> aValues = GetProperties(aNames); + const Any* pValues = aValues.getConstArray(); + + if(pValues[0].hasValue()) + bLoadVBA = *(sal_Bool*)pValues[0].getValue(); + if(pValues[1].hasValue()) + bSaveVBA = *(sal_Bool*)pValues[1].getValue(); +} + +// ----------------------------------------------------------------------- +class SvtCalcFilterOptions_Impl : public SvtAppFilterOptions_Impl +{ + sal_Bool bLoadExecutable; +public: + SvtCalcFilterOptions_Impl(const OUString& rRoot) : + SvtAppFilterOptions_Impl(rRoot), + bLoadExecutable(sal_False) + {} + virtual void Commit(); + void Load(); + + sal_Bool IsLoadExecutable() const {return bLoadExecutable;} + void SetLoadExecutable(sal_Bool bSet) + { + if(bSet != bLoadExecutable) + SetModified(); + bLoadExecutable = bSet; + } +}; + +void SvtCalcFilterOptions_Impl::Commit() +{ + SvtAppFilterOptions_Impl::Commit(); + + Sequence<OUString> aNames(1); + aNames[0] = C2U("Executable"); + Sequence<Any> aValues(1); + aValues[0] <<= bLoadExecutable; + + PutProperties(aNames, aValues); +} + +void SvtCalcFilterOptions_Impl::Load() +{ + SvtAppFilterOptions_Impl::Load(); + + Sequence<OUString> aNames(1); + aNames[0] = C2U("Executable"); + + Sequence<Any> aValues = GetProperties(aNames); + const Any* pValues = aValues.getConstArray(); + if(pValues[0].hasValue()) + bLoadExecutable = *(sal_Bool*)pValues[0].getValue(); +} + +/* -----------------------------22.01.01 10:32-------------------------------- + + ---------------------------------------------------------------------------*/ +struct SvtFilterOptions_Impl +{ + ULONG nFlags; + SvtAppFilterOptions_Impl aWriterCfg; + SvtCalcFilterOptions_Impl aCalcCfg; + SvtAppFilterOptions_Impl aImpressCfg; + + SvtFilterOptions_Impl() : + aWriterCfg(C2U("Office.Writer/Filter/Import/VBA")), + aCalcCfg(C2U("Office.Calc/Filter/Import/VBA")), + aImpressCfg(C2U("Office.Impress/Filter/Import/VBA")) + { + nFlags = FILTERCFG_WORD_CODE | + FILTERCFG_WORD_STORAGE | + FILTERCFG_EXCEL_CODE | + FILTERCFG_EXCEL_STORAGE | + FILTERCFG_PPOINT_CODE | + FILTERCFG_PPOINT_STORAGE | + FILTERCFG_MATH_LOAD | + FILTERCFG_MATH_SAVE | + FILTERCFG_WRITER_LOAD | + FILTERCFG_WRITER_SAVE | + FILTERCFG_CALC_LOAD | + FILTERCFG_CALC_SAVE | + FILTERCFG_IMPRESS_LOAD | + FILTERCFG_IMPRESS_SAVE | + FILTERCFG_USE_ENHANCED_FIELDS; + Load(); + } + + void SetFlag( ULONG nFlag, BOOL bSet ); + BOOL IsFlag( ULONG nFlag ) const; + void Load() + { + aWriterCfg.Load(); + aCalcCfg.Load(); + aImpressCfg.Load(); + } +}; +/* -----------------------------22.01.01 10:34-------------------------------- + + ---------------------------------------------------------------------------*/ +void SvtFilterOptions_Impl::SetFlag( ULONG nFlag, BOOL bSet ) +{ + switch(nFlag) + { + case FILTERCFG_WORD_CODE: aWriterCfg.SetLoad(bSet);break; + case FILTERCFG_WORD_STORAGE: aWriterCfg.SetSave(bSet);break; + case FILTERCFG_EXCEL_CODE: aCalcCfg.SetLoad(bSet);break; + case FILTERCFG_EXCEL_STORAGE: aCalcCfg.SetSave(bSet);break; + case FILTERCFG_EXCEL_EXECTBL: aCalcCfg.SetLoadExecutable(bSet);break; + case FILTERCFG_PPOINT_CODE: aImpressCfg.SetLoad(bSet);break; + case FILTERCFG_PPOINT_STORAGE: aImpressCfg.SetSave(bSet);break; + default: + if( bSet ) + nFlags |= nFlag; + else + nFlags &= ~nFlag; + } +} +/* -----------------------------22.01.01 10:35-------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SvtFilterOptions_Impl::IsFlag( ULONG nFlag ) const +{ + BOOL bRet; + switch(nFlag) + { + case FILTERCFG_WORD_CODE : bRet = aWriterCfg.IsLoad();break; + case FILTERCFG_WORD_STORAGE : bRet = aWriterCfg.IsSave();break; + case FILTERCFG_EXCEL_CODE : bRet = aCalcCfg.IsLoad();break; + case FILTERCFG_EXCEL_STORAGE : bRet = aCalcCfg.IsSave();break; + case FILTERCFG_EXCEL_EXECTBL : bRet = aCalcCfg.IsLoadExecutable();break; + case FILTERCFG_PPOINT_CODE : bRet = aImpressCfg.IsLoad();break; + case FILTERCFG_PPOINT_STORAGE : bRet = aImpressCfg.IsSave();break; + default: + bRet = 0 != (nFlags & nFlag ); + } + return bRet; +} + +// ----------------------------------------------------------------------- + +SvtFilterOptions::SvtFilterOptions() : + ConfigItem( C2U("Office.Common/Filter/Microsoft") ), + pImp(new SvtFilterOptions_Impl) +{ + RTL_LOGFILE_CONTEXT(aLog, "unotools SvtFilterOptions::SvtFilterOptions()"); + EnableNotification(GetPropertyNames()); + Load(); +} +// ----------------------------------------------------------------------- +SvtFilterOptions::~SvtFilterOptions() +{ + delete pImp; +} +/* -----------------------------22.01.01 08:45-------------------------------- + + ---------------------------------------------------------------------------*/ +const Sequence<OUString>& SvtFilterOptions::GetPropertyNames() +{ + static Sequence<OUString> aNames; + if(!aNames.getLength()) + { + int nCount = 12; + aNames.realloc(nCount); + static const char* aPropNames[] = + { + "Import/MathTypeToMath", // 0 + "Import/WinWordToWriter", // 1 + "Import/PowerPointToImpress", // 2 + "Import/ExcelToCalc", // 3 + "Export/MathToMathType", // 4 + "Export/WriterToWinWord", // 5 + "Export/ImpressToPowerPoint", // 6 + "Export/CalcToExcel", // 7 + "Export/EnablePowerPointPreview", // 8 + "Export/EnableExcelPreview", // 9 + "Export/EnableWordPreview", // 10 + "Import/ImportWWFieldsAsEnhancedFields" // 11 + }; + OUString* pNames = aNames.getArray(); + for(int i = 0; i < nCount; i++) + pNames[i] = C2U(aPropNames[i]); + } + return aNames; +} +//----------------------------------------------------------------------- +static ULONG lcl_GetFlag(sal_Int32 nProp) +{ + ULONG nFlag = 0; + switch(nProp) + { + case 0: nFlag = FILTERCFG_MATH_LOAD; break; + case 1: nFlag = FILTERCFG_WRITER_LOAD; break; + case 2: nFlag = FILTERCFG_IMPRESS_LOAD; break; + case 3: nFlag = FILTERCFG_CALC_LOAD; break; + case 4: nFlag = FILTERCFG_MATH_SAVE; break; + case 5: nFlag = FILTERCFG_WRITER_SAVE; break; + case 6: nFlag = FILTERCFG_IMPRESS_SAVE; break; + case 7: nFlag = FILTERCFG_CALC_SAVE; break; + case 8: nFlag = FILTERCFG_ENABLE_PPT_PREVIEW; break; + case 9: nFlag = FILTERCFG_ENABLE_EXCEL_PREVIEW; break; + case 10: nFlag = FILTERCFG_ENABLE_WORD_PREVIEW; break; + case 11: nFlag = FILTERCFG_USE_ENHANCED_FIELDS; break; + + default: DBG_ERROR("illegal value"); + } + return nFlag; +} +/*-- 22.01.01 08:53:03--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtFilterOptions::Notify( const Sequence<OUString>& ) +{ + Load(); +} +/*-- 22.01.01 08:53:04--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtFilterOptions::Commit() +{ + const Sequence<OUString>& aNames = GetPropertyNames(); + Sequence<Any> aValues(aNames.getLength()); + Any* pValues = aValues.getArray(); + + const Type& rType = ::getBooleanCppuType(); + for(int nProp = 0; nProp < aNames.getLength(); nProp++) + { + ULONG nFlag = lcl_GetFlag(nProp); + sal_Bool bVal = pImp->IsFlag( nFlag); + pValues[nProp].setValue(&bVal, rType); + + } + PutProperties(aNames, aValues); +} +/*-- 22.01.01 08:53:04--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtFilterOptions::Load() +{ + pImp->Load(); + const Sequence<OUString>& rNames = GetPropertyNames(); + Sequence<Any> aValues = GetProperties(rNames); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT(aValues.getLength() == rNames.getLength(), "GetProperties failed"); + if(aValues.getLength() == rNames.getLength()) + { + for(int nProp = 0; nProp < rNames.getLength(); nProp++) + { + if(pValues[nProp].hasValue()) + { + sal_Bool bVal = *(sal_Bool*)pValues[nProp].getValue(); + ULONG nFlag = lcl_GetFlag(nProp); + pImp->SetFlag( nFlag, bVal); + } + } + } +} +// ----------------------------------------------------------------------- + +void SvtFilterOptions::SetLoadWordBasicCode( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_WORD_CODE, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsLoadWordBasicCode() const +{ + return pImp->IsFlag( FILTERCFG_WORD_CODE ); +} + +void SvtFilterOptions::SetLoadWordBasicStorage( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_WORD_STORAGE, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsLoadWordBasicStorage() const +{ + return pImp->IsFlag( FILTERCFG_WORD_STORAGE ); +} + +// ----------------------------------------------------------------------- + +void SvtFilterOptions::SetLoadExcelBasicCode( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_EXCEL_CODE, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsLoadExcelBasicCode() const +{ + return pImp->IsFlag( FILTERCFG_EXCEL_CODE ); +} + +void SvtFilterOptions::SetLoadExcelBasicExecutable( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_EXCEL_EXECTBL, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsLoadExcelBasicExecutable() const +{ + return pImp->IsFlag( FILTERCFG_EXCEL_EXECTBL ); +} + +void SvtFilterOptions::SetLoadExcelBasicStorage( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_EXCEL_STORAGE, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsLoadExcelBasicStorage() const +{ + return pImp->IsFlag( FILTERCFG_EXCEL_STORAGE ); +} + +// ----------------------------------------------------------------------- + +void SvtFilterOptions::SetLoadPPointBasicCode( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_PPOINT_CODE, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsLoadPPointBasicCode() const +{ + return pImp->IsFlag( FILTERCFG_PPOINT_CODE ); +} + +void SvtFilterOptions::SetLoadPPointBasicStorage( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_PPOINT_STORAGE, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsLoadPPointBasicStorage() const +{ + return pImp->IsFlag( FILTERCFG_PPOINT_STORAGE ); +} + +// ----------------------------------------------------------------------- + +BOOL SvtFilterOptions::IsMathType2Math() const +{ + return pImp->IsFlag( FILTERCFG_MATH_LOAD ); +} + +void SvtFilterOptions::SetMathType2Math( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_MATH_LOAD, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsMath2MathType() const +{ + return pImp->IsFlag( FILTERCFG_MATH_SAVE ); +} + +void SvtFilterOptions::SetMath2MathType( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_MATH_SAVE, bFlag ); + SetModified(); +} + + +// ----------------------------------------------------------------------- +BOOL SvtFilterOptions::IsWinWord2Writer() const +{ + return pImp->IsFlag( FILTERCFG_WRITER_LOAD ); +} + +void SvtFilterOptions::SetWinWord2Writer( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_WRITER_LOAD, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsWriter2WinWord() const +{ + return pImp->IsFlag( FILTERCFG_WRITER_SAVE ); +} + +void SvtFilterOptions::SetWriter2WinWord( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_WRITER_SAVE, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsUseEnhancedFields() const +{ + return false; // disable for now; +// return pImp->IsFlag( FILTERCFG_USE_ENHANCED_FIELDS ); +} + +void SvtFilterOptions::SetUseEnhancedFields( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_USE_ENHANCED_FIELDS, bFlag ); + SetModified(); +} + +// ----------------------------------------------------------------------- +BOOL SvtFilterOptions::IsExcel2Calc() const +{ + return pImp->IsFlag( FILTERCFG_CALC_LOAD ); +} + +void SvtFilterOptions::SetExcel2Calc( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_CALC_LOAD, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsCalc2Excel() const +{ + return pImp->IsFlag( FILTERCFG_CALC_SAVE ); +} + +void SvtFilterOptions::SetCalc2Excel( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_CALC_SAVE, bFlag ); + SetModified(); +} + + +// ----------------------------------------------------------------------- +BOOL SvtFilterOptions::IsPowerPoint2Impress() const +{ + return pImp->IsFlag( FILTERCFG_IMPRESS_LOAD ); +} + +void SvtFilterOptions::SetPowerPoint2Impress( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_IMPRESS_LOAD, bFlag ); + SetModified(); +} + +BOOL SvtFilterOptions::IsImpress2PowerPoint() const +{ + return pImp->IsFlag( FILTERCFG_IMPRESS_SAVE ); +} + +void SvtFilterOptions::SetImpress2PowerPoint( BOOL bFlag ) +{ + pImp->SetFlag( FILTERCFG_IMPRESS_SAVE, bFlag ); + SetModified(); +} + +SvtFilterOptions* SvtFilterOptions::Get() +{ + if ( !pOptions ) + pOptions = new SvtFilterOptions; + return pOptions; +} + +// ----------------------------------------------------------------------- + +BOOL SvtFilterOptions::IsEnablePPTPreview() const +{ + return pImp->IsFlag( FILTERCFG_ENABLE_PPT_PREVIEW ); +} + + +BOOL SvtFilterOptions::IsEnableCalcPreview() const +{ + return pImp->IsFlag( FILTERCFG_ENABLE_EXCEL_PREVIEW ); +} + + +BOOL SvtFilterOptions::IsEnableWordPreview() const +{ + return pImp->IsFlag( FILTERCFG_ENABLE_WORD_PREVIEW ); +} + + diff --git a/unotools/source/config/fontcfg.cxx b/unotools/source/config/fontcfg.cxx new file mode 100644 index 000000000000..e8ae78d0aed2 --- /dev/null +++ b/unotools/source/config/fontcfg.cxx @@ -0,0 +1,1224 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/fontcfg.hxx> +#include <unotools/fontdefs.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <unotools/configpathes.hxx> +#include <unotools/syslocale.hxx> +#include <rtl/ustrbuf.hxx> +#include <tools/debug.hxx> + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +#include <string.h> +#include <list> +#include <algorithm> + +#define DEFAULTFONT_CONFIGNODE "VCL/DefaultFonts" +#define SUBSTFONT_CONFIGNODE "VCL/FontSubstitutions" + +using namespace rtl; +using namespace utl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; + +static DefaultFontConfiguration* mpDefaultFontConfiguration = 0; + +static FontSubstConfiguration* mpFontSubstConfiguration = 0; + +/* + * DefaultFontConfiguration + */ + +static const char* getKeyType( int nKeyType ) +{ + switch( nKeyType ) + { + case DEFAULTFONT_CJK_DISPLAY: return "CJK_DISPLAY"; + case DEFAULTFONT_CJK_HEADING: return "CJK_HEADING"; + case DEFAULTFONT_CJK_PRESENTATION: return "CJK_PRESENTATION"; + case DEFAULTFONT_CJK_SPREADSHEET: return "CJK_SPREADSHEET"; + case DEFAULTFONT_CJK_TEXT: return "CJK_TEXT"; + case DEFAULTFONT_CTL_DISPLAY: return "CTL_DISPLAY"; + case DEFAULTFONT_CTL_HEADING: return "CTL_HEADING"; + case DEFAULTFONT_CTL_PRESENTATION: return "CTL_PRESENTATION"; + case DEFAULTFONT_CTL_SPREADSHEET: return "CTL_SPREADSHEET"; + case DEFAULTFONT_CTL_TEXT: return "CTL_TEXT"; + case DEFAULTFONT_FIXED: return "FIXED"; + case DEFAULTFONT_LATIN_DISPLAY: return "LATIN_DISPLAY"; + case DEFAULTFONT_LATIN_FIXED: return "LATIN_FIXED"; + case DEFAULTFONT_LATIN_HEADING: return "LATIN_HEADING"; + case DEFAULTFONT_LATIN_PRESENTATION: return "LATIN_PRESENTATION"; + case DEFAULTFONT_LATIN_SPREADSHEET: return "LATIN_SPREADSHEET"; + case DEFAULTFONT_LATIN_TEXT: return "LATIN_TEXT"; + case DEFAULTFONT_SANS: return "SANS"; + case DEFAULTFONT_SANS_UNICODE: return "SANS_UNICODE"; + case DEFAULTFONT_SERIF: return "SERIF"; + case DEFAULTFONT_SYMBOL: return "SYMBOL"; + case DEFAULTFONT_UI_FIXED: return "UI_FIXED"; + case DEFAULTFONT_UI_SANS: return "UI_SANS"; + default: + DBG_ERROR( "unmatched type" ); + return ""; + } +} + +DefaultFontConfiguration* DefaultFontConfiguration::get() +{ + if( !mpDefaultFontConfiguration ) + mpDefaultFontConfiguration = new DefaultFontConfiguration(); + return mpDefaultFontConfiguration; +} + +DefaultFontConfiguration::DefaultFontConfiguration() +{ + try + { + // get service provider + Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() ); + // create configuration hierachical access name + if( xSMgr.is() ) + { + try + { + m_xConfigProvider = + Reference< XMultiServiceFactory >( + xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationProvider" ))), + UNO_QUERY ); + if( m_xConfigProvider.is() ) + { + Sequence< Any > aArgs(1); + PropertyValue aVal; + aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); + aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.VCL/DefaultFonts" ) ); + aArgs.getArray()[0] <<= aVal; + m_xConfigAccess = + Reference< XNameAccess >( + m_xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationAccess" )), + aArgs ), + UNO_QUERY ); + if( m_xConfigAccess.is() ) + { + Sequence< OUString > aLocales = m_xConfigAccess->getElementNames(); + // fill config hash with empty interfaces + int nLocales = aLocales.getLength(); + const OUString* pLocaleStrings = aLocales.getConstArray(); + Locale aLoc; + for( int i = 0; i < nLocales; i++ ) + { + sal_Int32 nIndex = 0; + aLoc.Language = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiLowerCase(); + if( nIndex != -1 ) + aLoc.Country = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); + else + aLoc.Country = OUString(); + if( nIndex != -1 ) + aLoc.Variant = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); + else + aLoc.Variant = OUString(); + m_aConfig[ aLoc ] = LocaleAccess(); + m_aConfig[ aLoc ].aConfigLocaleString = pLocaleStrings[i]; + } + } + } + } + catch( Exception& ) + { + // configuration is awry + m_xConfigProvider.clear(); + m_xConfigAccess.clear(); + } + } + } + catch( WrappedTargetException& ) + { + } + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "config provider: %s, config access: %s\n", + m_xConfigProvider.is() ? "true" : "false", + m_xConfigAccess.is() ? "true" : "false" + ); + #endif +} + +DefaultFontConfiguration::~DefaultFontConfiguration() +{ + // release all nodes + m_aConfig.clear(); + // release top node + m_xConfigAccess.clear(); + // release config provider + m_xConfigProvider.clear(); +} + +OUString DefaultFontConfiguration::tryLocale( const Locale& rLocale, const OUString& rType ) const +{ + OUString aRet; + + std::hash_map< Locale, LocaleAccess, LocaleHash >::const_iterator it = + m_aConfig.find( rLocale ); + if( it != m_aConfig.end() ) + { + if( !it->second.xAccess.is() ) + { + try + { + Reference< XNameAccess > xNode; + if ( m_xConfigAccess->hasByName( it->second.aConfigLocaleString ) ) + { + Any aAny = m_xConfigAccess->getByName( it->second.aConfigLocaleString ); + if( aAny >>= xNode ) + it->second.xAccess = xNode; + } + } + catch( NoSuchElementException ) + { + } + catch( WrappedTargetException ) + { + } + } + if( it->second.xAccess.is() ) + { + try + { + if ( it->second.xAccess->hasByName( rType ) ) + { + Any aAny = it->second.xAccess->getByName( rType ); + aAny >>= aRet; + } + } + catch( NoSuchElementException& ) + { + } + catch( WrappedTargetException& ) + { + } + } + } + + return aRet; +} + +OUString DefaultFontConfiguration::getDefaultFont( const Locale& rLocale, int nType ) const +{ + Locale aLocale; + aLocale.Language = rLocale.Language.toAsciiLowerCase(); + aLocale.Country = rLocale.Country.toAsciiUpperCase(); + aLocale.Variant = rLocale.Variant.toAsciiUpperCase(); + + OUString aType = OUString::createFromAscii( getKeyType( nType ) ); + OUString aRet = tryLocale( aLocale, aType ); + if( ! aRet.getLength() && aLocale.Variant.getLength() ) + { + aLocale.Variant = OUString(); + aRet = tryLocale( aLocale, aType ); + } + if( ! aRet.getLength() && aLocale.Country.getLength() ) + { + aLocale.Country = OUString(); + aRet = tryLocale( aLocale, aType ); + } + if( ! aRet.getLength() ) + { + aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) ); + aRet = tryLocale( aLocale, aType ); + } + return aRet; +} + +OUString DefaultFontConfiguration::getUserInterfaceFont( const Locale& rLocale ) const +{ + Locale aLocale = rLocale; + if( ! aLocale.Language.getLength() ) + aLocale = SvtSysLocale().GetUILocale(); + + OUString aUIFont = getDefaultFont( aLocale, DEFAULTFONT_UI_SANS ); + + if( aUIFont.getLength() ) + return aUIFont; + + // fallback mechanism (either no configuration or no entry in configuration + + #define FALLBACKFONT_UI_SANS "Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Bitstream Vera Sans;gnu-unifont;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System" + #define FALLBACKFONT_UI_SANS_LATIN2 "Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Luxi Sans;Bitstream Vera Sans;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System" + #define FALLBACKFONT_UI_SANS_ARABIC "Tahoma;Traditional Arabic;Simplified Arabic;Lucidasans;Lucida Sans;Supplement;Andale Sans UI;clearlyU;Interface User;Arial Unicode MS;Lucida Sans Unicode;WarpSans;Geneva;MS Sans Serif;Helv;Dialog;Albany;Lucida;Helvetica;Charcoal;Chicago;Arial;Helmet;Interface System;Sans Serif" + #define FALLBACKFONT_UI_SANS_THAI "OONaksit;Tahoma;Lucidasans;Arial Unicode MS" + #define FALLBACKFONT_UI_SANS_KOREAN "SunGulim;BaekmukGulim;Gulim;Roundgothic;Arial Unicode MS;Lucida Sans Unicode;gnu-unifont;Andale Sans UI" + #define FALLBACKFONT_UI_SANS_JAPANESE1 "HG-GothicB-Sun;Andale Sans UI;HG MhinchoLightJ" + #define FALLBACKFONT_UI_SANS_JAPANESE2 "Kochi Gothic;Gothic" + #define FALLBACKFONT_UI_SANS_CHINSIM "Andale Sans UI;Arial Unicode MS;ZYSong18030;AR PL SungtiL GB;AR PL KaitiM GB;SimSun;Lucida Sans Unicode;Fangsong;Hei;Song;Kai;Ming;gnu-unifont;Interface User;" + #define FALLBACKFONT_UI_SANS_CHINTRD "Andale Sans UI;Arial Unicode MS;AR PL Mingti2L Big5;AR PL KaitiM Big5;Kai;PMingLiU;MingLiU;Ming;Lucida Sans Unicode;gnu-unifont;Interface User;" + + // we need localized names for japanese fonts + static sal_Unicode const aMSGothic[] = { 0xFF2D, 0xFF33, ' ', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; + static sal_Unicode const aMSPGothic[] = { 0xFF2D, 0xFF33, ' ', 0xFF30, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; + static sal_Unicode const aTLPGothic[] = { 0x0054, 0x004C, 0x0050, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; + static sal_Unicode const aLXGothic[] = { 0x004C, 0x0058, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; + static sal_Unicode const aKochiGothic[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; + + String aFallBackJapaneseLocalized( RTL_CONSTASCII_USTRINGPARAM( "MS UI Gothic;" ) ); + aFallBackJapaneseLocalized += String( RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_JAPANESE1 ) ); + aFallBackJapaneseLocalized += String( aMSPGothic ); + aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); + aFallBackJapaneseLocalized += String( aMSGothic ); + aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); + aFallBackJapaneseLocalized += String( aTLPGothic ); + aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); + aFallBackJapaneseLocalized += String( aLXGothic ); + aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); + aFallBackJapaneseLocalized += String( aKochiGothic ); + aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); + aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_JAPANESE2 ) ); + static const OUString aFallBackJapanese( aFallBackJapaneseLocalized ); + static const OUString aFallback (RTL_CONSTASCII_USTRINGPARAM(FALLBACKFONT_UI_SANS)); + static const OUString aFallbackLatin2 (RTL_CONSTASCII_USTRINGPARAM(FALLBACKFONT_UI_SANS_LATIN2)); + static const OUString aFallBackArabic (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_ARABIC ) ); + static const OUString aFallBackThai (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_THAI ) ); + static const OUString aFallBackChineseSIM (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_CHINSIM ) ); + static const OUString aFallBackChineseTRD (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_CHINTRD ) ); + + // we need localized names for korean fonts + static sal_Unicode const aSunGulim[] = { 0xC36C, 0xAD74, 0xB9BC, 0 }; + static sal_Unicode const aBaekmukGulim[] = { 0xBC31, 0xBC35, 0xAD74, 0xB9BC, 0 }; + String aFallBackKoreanLocalized( aSunGulim ); + aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); + aFallBackKoreanLocalized += String( aBaekmukGulim ); + aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); + aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_KOREAN ) ); + static const OUString aFallBackKorean( aFallBackKoreanLocalized ); + + // optimize font list for some locales, as long as Andale Sans UI does not support them + if( aLocale.Language.equalsAscii( "ar" ) || + aLocale.Language.equalsAscii( "he" ) || + aLocale.Language.equalsAscii( "iw" ) ) + { + return aFallBackArabic; + } + else if( aLocale.Language.equalsAscii( "th" ) ) + { + return aFallBackThai; + } + else if( aLocale.Language.equalsAscii( "ko" ) ) + { + return aFallBackKorean; + } + else if( aLocale.Language.equalsAscii( "cs" ) || + aLocale.Language.equalsAscii( "hu" ) || + aLocale.Language.equalsAscii( "pl" ) || + aLocale.Language.equalsAscii( "ro" ) || + aLocale.Language.equalsAscii( "rm" ) || + aLocale.Language.equalsAscii( "hr" ) || + aLocale.Language.equalsAscii( "sk" ) || + aLocale.Language.equalsAscii( "sl" ) || + aLocale.Language.equalsAscii( "sb" ) ) + { + return aFallbackLatin2; + } + else if( aLocale.Language.equalsAscii( "zh" ) ) + { + if( ! aLocale.Country.equalsAscii( "cn" ) ) + return aFallBackChineseTRD; + else + return aFallBackChineseSIM; + } + else if( aLocale.Language.equalsAscii( "ja" ) ) + { + return aFallBackJapanese; + } + + return aFallback; +} + +// ------------------------------------------------------------------------------------ + +/* + * FontSubstConfigItem::get + */ + +FontSubstConfiguration* FontSubstConfiguration::get() +{ + if( !mpFontSubstConfiguration ) + mpFontSubstConfiguration = new FontSubstConfiguration(); + return mpFontSubstConfiguration; +} + +/* + * FontSubstConfigItem::FontSubstConfigItem + */ + +FontSubstConfiguration::FontSubstConfiguration() : + maSubstHash( 300 ) +{ + try + { + // get service provider + Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() ); + // create configuration hierachical access name + if( xSMgr.is() ) + { + try + { + m_xConfigProvider = + Reference< XMultiServiceFactory >( + xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationProvider" ))), + UNO_QUERY ); + if( m_xConfigProvider.is() ) + { + Sequence< Any > aArgs(1); + PropertyValue aVal; + aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); + aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.VCL/FontSubstitutions" ) ); + aArgs.getArray()[0] <<= aVal; + m_xConfigAccess = + Reference< XNameAccess >( + m_xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationAccess" )), + aArgs ), + UNO_QUERY ); + if( m_xConfigAccess.is() ) + { + Sequence< OUString > aLocales = m_xConfigAccess->getElementNames(); + // fill config hash with empty interfaces + int nLocales = aLocales.getLength(); + const OUString* pLocaleStrings = aLocales.getConstArray(); + Locale aLoc; + for( int i = 0; i < nLocales; i++ ) + { + sal_Int32 nIndex = 0; + aLoc.Language = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiLowerCase(); + if( nIndex != -1 ) + aLoc.Country = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); + else + aLoc.Country = OUString(); + if( nIndex != -1 ) + aLoc.Variant = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); + else + aLoc.Variant = OUString(); + m_aSubst[ aLoc ] = LocaleSubst(); + m_aSubst[ aLoc ].aConfigLocaleString = pLocaleStrings[i]; + } + } + } + } + catch( Exception& ) + { + // configuration is awry + m_xConfigProvider.clear(); + m_xConfigAccess.clear(); + } + } + } + catch( WrappedTargetException& ) + { + } + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "config provider: %s, config access: %s\n", + m_xConfigProvider.is() ? "true" : "false", + m_xConfigAccess.is() ? "true" : "false" + ); + #endif +} + +/* + * FontSubstConfigItem::~FontSubstConfigItem + */ + +FontSubstConfiguration::~FontSubstConfiguration() +{ + // release config access + m_xConfigAccess.clear(); + // release config provider + m_xConfigProvider.clear(); +} + +/* + * FontSubstConfigItem::getMapName + */ +// ======================================================================= + +static const char* const aImplKillLeadingList[] = +{ + "microsoft", + "monotype", + "linotype", + "baekmuk", + "adobe", + "nimbus", + "zycjk", + "itc", + "sun", + "amt", + "ms", + "mt", + "cg", + "hg", + "fz", + "ipa", + "sazanami", + "kochi", + NULL +}; + +// ----------------------------------------------------------------------- + +static const char* const aImplKillTrailingList[] = +{ + "microsoft", + "monotype", + "linotype", + "adobe", + "nimbus", + "itc", + "sun", + "amt", + "ms", + "mt", + "clm", + // Scripts, for compatibility with older versions + "we", + "cyr", + "tur", + "wt", + "greek", + "wl", + // CJK extensions + "gb", + "big5", + "pro", + "z01", + "z02", + "z03", + "z13", + "b01", + "w3x12", + // Old Printer Fontnames + "5cpi", + "6cpi", + "7cpi", + "8cpi", + "9cpi", + "10cpi", + "11cpi", + "12cpi", + "13cpi", + "14cpi", + "15cpi", + "16cpi", + "18cpi", + "24cpi", + "scale", + "pc", + NULL +}; + +// ----------------------------------------------------------------------- + +static const char* const aImplKillTrailingWithExceptionsList[] = +{ + "ce", "monospace", "oldface", NULL, + "ps", "caps", NULL, + NULL +}; + +// ----------------------------------------------------------------------- + +struct ImplFontAttrWeightSearchData +{ + const char* mpStr; + FontWeight meWeight; +}; + +static ImplFontAttrWeightSearchData const aImplWeightAttrSearchList[] = +{ +// the attribute names are ordered by "first match wins" +// e.g. "semilight" should wins over "semi" +{ "extrablack", WEIGHT_BLACK }, +{ "ultrablack", WEIGHT_BLACK }, +{ "ultrabold", WEIGHT_ULTRABOLD }, +{ "semibold", WEIGHT_SEMIBOLD }, +{ "semilight", WEIGHT_SEMILIGHT }, +{ "semi", WEIGHT_SEMIBOLD }, +{ "demi", WEIGHT_SEMIBOLD }, +{ "black", WEIGHT_BLACK }, +{ "bold", WEIGHT_BOLD }, +{ "heavy", WEIGHT_BLACK }, +{ "ultralight", WEIGHT_ULTRALIGHT }, +{ "light", WEIGHT_LIGHT }, +{ "medium", WEIGHT_MEDIUM }, +{ NULL, WEIGHT_DONTKNOW }, +}; + +// ----------------------------------------------------------------------- + +struct ImplFontAttrWidthSearchData +{ + const char* mpStr; + FontWidth meWidth; +}; + +static ImplFontAttrWidthSearchData const aImplWidthAttrSearchList[] = +{ +{ "narrow", WIDTH_CONDENSED }, +{ "semicondensed", WIDTH_SEMI_CONDENSED }, +{ "ultracondensed", WIDTH_ULTRA_CONDENSED }, +{ "semiexpanded", WIDTH_SEMI_EXPANDED }, +{ "ultraexpanded", WIDTH_ULTRA_EXPANDED }, +{ "expanded", WIDTH_EXPANDED }, +{ "wide", WIDTH_ULTRA_EXPANDED }, +{ "condensed", WIDTH_CONDENSED }, +{ "cond", WIDTH_CONDENSED }, +{ "cn", WIDTH_CONDENSED }, +{ NULL, WIDTH_DONTKNOW }, +}; + +struct ImplFontAttrTypeSearchData +{ + const char* mpStr; + ULONG mnType; +}; + +static ImplFontAttrTypeSearchData const aImplTypeAttrSearchList[] = +{ +{ "monotype", 0 }, +{ "linotype", 0 }, +{ "titling", IMPL_FONT_ATTR_TITLING }, +{ "captitals", IMPL_FONT_ATTR_CAPITALS }, +{ "captital", IMPL_FONT_ATTR_CAPITALS }, +{ "caps", IMPL_FONT_ATTR_CAPITALS }, +{ "italic", IMPL_FONT_ATTR_ITALIC }, +{ "oblique", IMPL_FONT_ATTR_ITALIC }, +{ "rounded", IMPL_FONT_ATTR_ROUNDED }, +{ "outline", IMPL_FONT_ATTR_OUTLINE }, +{ "shadow", IMPL_FONT_ATTR_SHADOW }, +{ "handwriting", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT }, +{ "hand", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT }, +{ "signet", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT }, +{ "script", IMPL_FONT_ATTR_BRUSHSCRIPT | IMPL_FONT_ATTR_SCRIPT }, +{ "calligraphy", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT }, +{ "chancery", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT }, +{ "corsiva", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT }, +{ "gothic", IMPL_FONT_ATTR_SANSSERIF | IMPL_FONT_ATTR_GOTHIC }, +{ "schoolbook", IMPL_FONT_ATTR_SERIF | IMPL_FONT_ATTR_SCHOOLBOOK }, +{ "schlbk", IMPL_FONT_ATTR_SERIF | IMPL_FONT_ATTR_SCHOOLBOOK }, +{ "typewriter", IMPL_FONT_ATTR_TYPEWRITER | IMPL_FONT_ATTR_FIXED }, +{ "lineprinter", IMPL_FONT_ATTR_TYPEWRITER | IMPL_FONT_ATTR_FIXED }, +{ "monospaced", IMPL_FONT_ATTR_FIXED }, +{ "monospace", IMPL_FONT_ATTR_FIXED }, +{ "mono", IMPL_FONT_ATTR_FIXED }, +{ "fixed", IMPL_FONT_ATTR_FIXED }, +{ "sansserif", IMPL_FONT_ATTR_SANSSERIF }, +{ "sans", IMPL_FONT_ATTR_SANSSERIF }, +{ "swiss", IMPL_FONT_ATTR_SANSSERIF }, +{ "serif", IMPL_FONT_ATTR_SERIF }, +{ "bright", IMPL_FONT_ATTR_SERIF }, +{ "symbols", IMPL_FONT_ATTR_SYMBOL }, +{ "symbol", IMPL_FONT_ATTR_SYMBOL }, +{ "dingbats", IMPL_FONT_ATTR_SYMBOL }, +{ "dings", IMPL_FONT_ATTR_SYMBOL }, +{ "ding", IMPL_FONT_ATTR_SYMBOL }, +{ "bats", IMPL_FONT_ATTR_SYMBOL }, +{ "math", IMPL_FONT_ATTR_SYMBOL }, +{ "oldstyle", IMPL_FONT_ATTR_OTHERSTYLE }, +{ "oldface", IMPL_FONT_ATTR_OTHERSTYLE }, +{ "old", IMPL_FONT_ATTR_OTHERSTYLE }, +{ "new", 0 }, +{ "modern", 0 }, +{ "lucida", 0 }, +{ "regular", 0 }, +{ "extended", 0 }, +{ "extra", IMPL_FONT_ATTR_OTHERSTYLE }, +{ "ext", 0 }, +{ "scalable", 0 }, +{ "scale", 0 }, +{ "nimbus", 0 }, +{ "adobe", 0 }, +{ "itc", 0 }, +{ "amt", 0 }, +{ "mt", 0 }, +{ "ms", 0 }, +{ "cpi", 0 }, +{ "no", 0 }, +{ NULL, 0 }, +}; + +// ----------------------------------------------------------------------- + +static bool ImplKillLeading( String& rName, const char* const* ppStr ) +{ + for(; *ppStr; ++ppStr ) + { + const char* pStr = *ppStr; + const xub_Unicode* pNameStr = rName.GetBuffer(); + while ( (*pNameStr == (xub_Unicode)(unsigned char)*pStr) && *pStr ) + { + pNameStr++; + pStr++; + } + if ( !*pStr ) + { + xub_StrLen nLen = sal::static_int_cast<xub_StrLen>(pNameStr - rName.GetBuffer()); + rName.Erase( 0, nLen ); + return true; + } + } + + // special case for Baekmuk + // TODO: allow non-ASCII KillLeading list + const xub_Unicode* pNameStr = rName.GetBuffer(); + if( (pNameStr[0]==0xBC31) && (pNameStr[1]==0xBC35) ) + { + xub_StrLen nLen = (pNameStr[2]==0x0020) ? 3 : 2; + rName.Erase( 0, nLen ); + return true; + } + + return false; +} + +// ----------------------------------------------------------------------- + +static xub_StrLen ImplIsTrailing( const String& rName, const char* pStr ) +{ + xub_StrLen nStrLen = static_cast<xub_StrLen>( strlen( pStr ) ); + if( nStrLen >= rName.Len() ) + return 0; + + const xub_Unicode* pEndName = rName.GetBuffer() + rName.Len(); + const sal_Unicode* pNameStr = pEndName - nStrLen; + do if( *(pNameStr++) != *(pStr++) ) + return 0; + while( *pStr ); + + return nStrLen; +} + +// ----------------------------------------------------------------------- + +static bool ImplKillTrailing( String& rName, const char* const* ppStr ) +{ + for(; *ppStr; ++ppStr ) + { + xub_StrLen nTrailLen = ImplIsTrailing( rName, *ppStr ); + if( nTrailLen ) + { + rName.Erase( rName.Len()-nTrailLen ); + return true; + } + } + + return false; +} + +// ----------------------------------------------------------------------- + +static bool ImplKillTrailingWithExceptions( String& rName, const char* const* ppStr ) +{ + for(; *ppStr; ++ppStr ) + { + xub_StrLen nTrailLen = ImplIsTrailing( rName, *ppStr ); + if( nTrailLen ) + { + // check string match against string exceptions + while( *++ppStr ) + if( ImplIsTrailing( rName, *ppStr ) ) + return false; + + rName.Erase( rName.Len()-nTrailLen ); + return true; + } + else + { + // skip exception strings + while( *++ppStr ) ; + } + } + + return false; +} + +// ----------------------------------------------------------------------- + +static BOOL ImplFindAndErase( String& rName, const char* pStr ) +{ + xub_StrLen nPos = rName.SearchAscii( pStr ); + if ( nPos == STRING_NOTFOUND ) + return FALSE; + + const char* pTempStr = pStr; + while ( *pTempStr ) + pTempStr++; + rName.Erase( nPos, (xub_StrLen)(pTempStr-pStr) ); + return TRUE; +} + +// ======================================================================= + +void FontSubstConfiguration::getMapName( const String& rOrgName, String& rShortName, + String& rFamilyName, FontWeight& rWeight, FontWidth& rWidth, ULONG& rType ) +{ + rShortName = rOrgName; + + // TODO: get rid of the crazy O(N*strlen) searches below + // they should be possible in O(strlen) + + // Kill leading vendor names and other unimportant data + ImplKillLeading( rShortName, aImplKillLeadingList ); + + // Kill trailing vendor names and other unimportant data + ImplKillTrailing( rShortName, aImplKillTrailingList ); + ImplKillTrailingWithExceptions( rShortName, aImplKillTrailingWithExceptionsList ); + + rFamilyName = rShortName; + + // Kill attributes from the name and update the data + // Weight + const ImplFontAttrWeightSearchData* pWeightList = aImplWeightAttrSearchList; + while ( pWeightList->mpStr ) + { + if ( ImplFindAndErase( rFamilyName, pWeightList->mpStr ) ) + { + if ( (rWeight == WEIGHT_DONTKNOW) || (rWeight == WEIGHT_NORMAL) ) + rWeight = pWeightList->meWeight; + break; + } + pWeightList++; + } + + // Width + const ImplFontAttrWidthSearchData* pWidthList = aImplWidthAttrSearchList; + while ( pWidthList->mpStr ) + { + if ( ImplFindAndErase( rFamilyName, pWidthList->mpStr ) ) + { + if ( (rWidth == WIDTH_DONTKNOW) || (rWidth == WIDTH_NORMAL) ) + rWidth = pWidthList->meWidth; + break; + } + pWidthList++; + } + + // Type + rType = 0; + const ImplFontAttrTypeSearchData* pTypeList = aImplTypeAttrSearchList; + while ( pTypeList->mpStr ) + { + if ( ImplFindAndErase( rFamilyName, pTypeList->mpStr ) ) + rType |= pTypeList->mnType; + pTypeList++; + } + + // Remove numbers + // TODO: also remove localized and fullwidth digits + xub_StrLen i = 0; + while ( i < rFamilyName.Len() ) + { + sal_Unicode c = rFamilyName.GetChar( i ); + if ( (c >= 0x0030) && (c <= 0x0039) ) + rFamilyName.Erase( i, 1 ); + else + i++; + } +} + + +struct StrictStringSort : public ::std::binary_function< const FontNameAttr&, const FontNameAttr&, bool > +{ + bool operator()( const FontNameAttr& rLeft, const FontNameAttr& rRight ) + { return rLeft.Name.CompareTo( rRight.Name ) == COMPARE_LESS ; } +}; + +static const char* const pAttribNames[] = +{ + "default", + "standard", + "normal", + "symbol", + "fixed", + "sansserif", + "serif", + "decorative", + "special", + "italic", + "title", + "capitals", + "cjk", + "cjk_jp", + "cjk_sc", + "cjk_tc", + "cjk_kr", + "ctl", + "nonelatin", + "full", + "outline", + "shadow", + "rounded", + "typewriter", + "script", + "handwriting", + "chancery", + "comic", + "brushscript", + "gothic", + "schoolbook", + "other" +}; + +struct enum_convert +{ + const char* pName; + int nEnum; +}; + + +static const enum_convert pWeightNames[] = +{ + { "normal", WEIGHT_NORMAL }, + { "medium", WEIGHT_MEDIUM }, + { "bold", WEIGHT_BOLD }, + { "black", WEIGHT_BLACK }, + { "semibold", WEIGHT_SEMIBOLD }, + { "light", WEIGHT_LIGHT }, + { "semilight", WEIGHT_SEMILIGHT }, + { "ultrabold", WEIGHT_ULTRABOLD }, + { "semi", WEIGHT_SEMIBOLD }, + { "demi", WEIGHT_SEMIBOLD }, + { "heavy", WEIGHT_BLACK }, + { "unknown", WEIGHT_DONTKNOW }, + { "thin", WEIGHT_THIN }, + { "ultralight", WEIGHT_ULTRALIGHT } +}; + +static const enum_convert pWidthNames[] = +{ + { "normal", WIDTH_NORMAL }, + { "condensed", WIDTH_CONDENSED }, + { "expanded", WIDTH_EXPANDED }, + { "unknown", WIDTH_DONTKNOW }, + { "ultracondensed", WIDTH_ULTRA_CONDENSED }, + { "extracondensed", WIDTH_EXTRA_CONDENSED }, + { "semicondensed", WIDTH_SEMI_CONDENSED }, + { "semiexpanded", WIDTH_SEMI_EXPANDED }, + { "extraexpanded", WIDTH_EXTRA_EXPANDED }, + { "ultraexpanded", WIDTH_ULTRA_EXPANDED } +}; + +void FontSubstConfiguration::fillSubstVector( const com::sun::star::uno::Reference< XNameAccess > xFont, + const rtl::OUString& rType, + std::vector< String >& rSubstVector ) const +{ + try + { + Any aAny = xFont->getByName( rType ); + if( aAny.getValueTypeClass() == TypeClass_STRING ) + { + const OUString* pLine = (const OUString*)aAny.getValue(); + sal_Int32 nIndex = 0; + sal_Int32 nLength = pLine->getLength(); + if( nLength ) + { + const sal_Unicode* pStr = pLine->getStr(); + sal_Int32 nTokens = 0; + // count tokens + while( nLength-- ) + { + if( *pStr++ == sal_Unicode(';') ) + nTokens++; + } + rSubstVector.clear(); + // optimize performance, heap fragmentation + rSubstVector.reserve( nTokens ); + while( nIndex != -1 ) + { + OUString aSubst( pLine->getToken( 0, ';', nIndex ) ); + if( aSubst.getLength() ) + { + UniqueSubstHash::iterator aEntry = maSubstHash.find( aSubst ); + if (aEntry != maSubstHash.end()) + aSubst = *aEntry; + else + maSubstHash.insert( aSubst ); + rSubstVector.push_back( aSubst ); + } + } + } + } + } + catch( NoSuchElementException ) + { + } + catch( WrappedTargetException ) + { + } +} + +FontWeight FontSubstConfiguration::getSubstWeight( const com::sun::star::uno::Reference< XNameAccess > xFont, + const rtl::OUString& rType ) const +{ + int weight = -1; + try + { + Any aAny = xFont->getByName( rType ); + if( aAny.getValueTypeClass() == TypeClass_STRING ) + { + const OUString* pLine = (const OUString*)aAny.getValue(); + if( pLine->getLength() ) + { + for( weight=sizeof(pWeightNames)/sizeof(pWeightNames[0])-1; weight >= 0; weight-- ) + if( pLine->equalsIgnoreAsciiCaseAscii( pWeightNames[weight].pName ) ) + break; + } +#if OSL_DEBUG_LEVEL > 1 + if( weight < 0 ) + fprintf( stderr, "Error: invalid weight %s\n", + OUStringToOString( *pLine, RTL_TEXTENCODING_ASCII_US ).getStr() ); +#endif + } + } + catch( NoSuchElementException ) + { + } + catch( WrappedTargetException ) + { + } + return (FontWeight)( weight >= 0 ? pWeightNames[weight].nEnum : WEIGHT_DONTKNOW ); +} + +FontWidth FontSubstConfiguration::getSubstWidth( const com::sun::star::uno::Reference< XNameAccess > xFont, + const rtl::OUString& rType ) const +{ + int width = -1; + try + { + Any aAny = xFont->getByName( rType ); + if( aAny.getValueTypeClass() == TypeClass_STRING ) + { + const OUString* pLine = (const OUString*)aAny.getValue(); + if( pLine->getLength() ) + { + for( width=sizeof(pWidthNames)/sizeof(pWidthNames[0])-1; width >= 0; width-- ) + if( pLine->equalsIgnoreAsciiCaseAscii( pWidthNames[width].pName ) ) + break; + } +#if OSL_DEBUG_LEVEL > 1 + if( width < 0 ) + fprintf( stderr, "Error: invalid width %s\n", + OUStringToOString( *pLine, RTL_TEXTENCODING_ASCII_US ).getStr() ); +#endif + } + } + catch( NoSuchElementException ) + { + } + catch( WrappedTargetException ) + { + } + return (FontWidth)( width >= 0 ? pWidthNames[width].nEnum : WIDTH_DONTKNOW ); +} + +unsigned long FontSubstConfiguration::getSubstType( const com::sun::star::uno::Reference< XNameAccess > xFont, + const rtl::OUString& rType ) const +{ + unsigned long type = 0; + try + { + Any aAny = xFont->getByName( rType ); + if( aAny.getValueTypeClass() == TypeClass_STRING ) + { + const OUString* pLine = (const OUString*)aAny.getValue(); + if( pLine->getLength() ) + { + sal_Int32 nIndex = 0; + while( nIndex != -1 ) + { + String aToken( pLine->getToken( 0, ',', nIndex ) ); + for( int k = 0; k < 32; k++ ) + if( aToken.EqualsIgnoreCaseAscii( pAttribNames[k] ) ) + { + type |= 1 << k; + break; + } + } + } + } + } + catch( NoSuchElementException ) + { + } + catch( WrappedTargetException ) + { + } + + return type; +} + +void FontSubstConfiguration::readLocaleSubst( const com::sun::star::lang::Locale& rLocale ) const +{ + std::hash_map< Locale, LocaleSubst, LocaleHash >::const_iterator it = + m_aSubst.find( rLocale ); + if( it != m_aSubst.end() ) + { + if( ! it->second.bConfigRead ) + { + it->second.bConfigRead = true; + Reference< XNameAccess > xNode; + try + { + Any aAny = m_xConfigAccess->getByName( it->second.aConfigLocaleString ); + aAny >>= xNode; + } + catch( NoSuchElementException ) + { + } + catch( WrappedTargetException ) + { + } + if( xNode.is() ) + { + Sequence< OUString > aFonts = xNode->getElementNames(); + int nFonts = aFonts.getLength(); + const OUString* pFontNames = aFonts.getConstArray(); + // improve performance, heap fragmentation + it->second.aSubstAttributes.reserve( nFonts ); + + // strings for subst retrieval, construct only once + OUString aSubstFontsStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFonts" ) ); + OUString aSubstFontsMSStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsMS" ) ); + OUString aSubstFontsPSStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsPS" ) ); + OUString aSubstFontsHTMLStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsHTML" ) ); + OUString aSubstWeightStr ( RTL_CONSTASCII_USTRINGPARAM( "FontWeight" ) ); + OUString aSubstWidthStr ( RTL_CONSTASCII_USTRINGPARAM( "FontWidth" ) ); + OUString aSubstTypeStr ( RTL_CONSTASCII_USTRINGPARAM( "FontType" ) ); + for( int i = 0; i < nFonts; i++ ) + { + Reference< XNameAccess > xFont; + try + { + Any aAny = xNode->getByName( pFontNames[i] ); + aAny >>= xFont; + } + catch( NoSuchElementException ) + { + } + catch( WrappedTargetException ) + { + } + if( ! xFont.is() ) + { + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "did not get font attributes for %s\n", + OUStringToOString( pFontNames[i], RTL_TEXTENCODING_UTF8 ).getStr() ); + #endif + continue; + } + + FontNameAttr aAttr; + // read subst attributes from config + aAttr.Name = pFontNames[i]; + fillSubstVector( xFont, aSubstFontsStr, aAttr.Substitutions ); + fillSubstVector( xFont, aSubstFontsMSStr, aAttr.MSSubstitutions ); + fillSubstVector( xFont, aSubstFontsPSStr, aAttr.PSSubstitutions ); + fillSubstVector( xFont, aSubstFontsHTMLStr, aAttr.HTMLSubstitutions ); + aAttr.Weight = getSubstWeight( xFont, aSubstWeightStr ); + aAttr.Width = getSubstWidth( xFont, aSubstWidthStr ); + aAttr.Type = getSubstType( xFont, aSubstTypeStr ); + + // finally insert this entry + it->second.aSubstAttributes.push_back( aAttr ); + } + std::sort( it->second.aSubstAttributes.begin(), it->second.aSubstAttributes.end(), StrictStringSort() ); + } + } + } +} + +const FontNameAttr* FontSubstConfiguration::getSubstInfo( const String& rFontName, const Locale& rLocale ) const +{ + if( !rFontName.Len() ) + return NULL; + + // search if a (language dep.) replacement table for the given font exists + // fallback is english + String aSearchFont( rFontName ); + aSearchFont.ToLowerAscii(); + FontNameAttr aSearchAttr; + aSearchAttr.Name = aSearchFont; + + Locale aLocale; + aLocale.Language = rLocale.Language.toAsciiLowerCase(); + aLocale.Country = rLocale.Country.toAsciiUpperCase(); + aLocale.Variant = rLocale.Variant.toAsciiUpperCase(); + + if( ! aLocale.Language.getLength() ) + aLocale = SvtSysLocale().GetUILocale(); + + while( aLocale.Language.getLength() ) + { + std::hash_map< Locale, LocaleSubst, LocaleHash >::const_iterator lang = m_aSubst.find( aLocale ); + if( lang != m_aSubst.end() ) + { + if( ! lang->second.bConfigRead ) + readLocaleSubst( aLocale ); + // try to find an exact match + // because the list is sorted this will also find fontnames of the form searchfontname* + std::vector< FontNameAttr >::const_iterator it = ::std::lower_bound( lang->second.aSubstAttributes.begin(), lang->second.aSubstAttributes.end(), aSearchAttr, StrictStringSort() ); + if( it != lang->second.aSubstAttributes.end()) + { + const FontNameAttr& rFoundAttr = *it; + // a search for "abcblack" may match with an entry for "abc" + // the reverse is not a good idea (e.g. #i112731# alba->albani) + if( rFoundAttr.Name.Len() <= aSearchFont.Len() ) + if( aSearchFont.CompareTo( rFoundAttr.Name, rFoundAttr.Name.Len() ) == COMPARE_EQUAL ) + return &rFoundAttr; + } + } + // gradually become more unspecific + if( aLocale.Variant.getLength() ) + aLocale.Variant = OUString(); + else if( aLocale.Country.getLength() ) + aLocale.Country = OUString(); + else if( ! aLocale.Language.equalsAscii( "en" ) ) + aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) ); + else + aLocale.Language = OUString(); + } + return NULL; +} + diff --git a/unotools/source/config/fontoptions.cxx b/unotools/source/config/fontoptions.cxx new file mode 100644 index 000000000000..5853dd36af98 --- /dev/null +++ b/unotools/source/config/fontoptions.cxx @@ -0,0 +1,511 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/fontoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_FONT OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Font" )) + +#define PROPERTYNAME_REPLACEMENTTABLE OUString(RTL_CONSTASCII_USTRINGPARAM("Substitution/Replacement" )) +#define PROPERTYNAME_FONTHISTORY OUString(RTL_CONSTASCII_USTRINGPARAM("View/History" )) +#define PROPERTYNAME_FONTWYSIWYG OUString(RTL_CONSTASCII_USTRINGPARAM("View/ShowFontBoxWYSIWYG" )) + +#define PROPERTYHANDLE_REPLACEMENTTABLE 0 +#define PROPERTYHANDLE_FONTHISTORY 1 +#define PROPERTYHANDLE_FONTWYSIWYG 2 + +#define PROPERTYCOUNT 3 + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +class SvtFontOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtFontOptions_Impl(); + ~SvtFontOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& seqPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short access method to get internal values + @descr These method give us a chance to regulate acces to ouer internal values. + It's not used in the moment - but it's possible for the feature! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + sal_Bool IsReplacementTableEnabled ( ) const ; + void EnableReplacementTable ( sal_Bool bState ) ; + + sal_Bool IsFontHistoryEnabled ( ) const ; + void EnableFontHistory ( sal_Bool bState ) ; + + sal_Bool IsFontWYSIWYGEnabled ( ) const ; + void EnableFontWYSIWYG ( sal_Bool bState ) ; + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of key names of ouer configuration management which represent oue module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. + + @seealso - + + @param - + @return A list of needed configuration keys is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + static Sequence< OUString > impl_GetPropertyNames(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + + sal_Bool m_bReplacementTable ; + sal_Bool m_bFontHistory ; + sal_Bool m_bFontWYSIWYG ; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtFontOptions_Impl::SvtFontOptions_Impl() + // Init baseclasses first + : ConfigItem ( ROOTNODE_FONT ) + // Init member then. + , m_bReplacementTable ( sal_False ) + , m_bFontHistory ( sal_False ) + , m_bFontWYSIWYG ( sal_False ) +{ + // Use our static list of configuration keys to get his values. + Sequence< OUString > seqNames = impl_GetPropertyNames ( ); + Sequence< Any > seqValues = GetProperties ( seqNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + // Safe impossible cases. + // Check any for valid value. + DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nInvalid property value detected!\n" ); + switch( nProperty ) + { + case PROPERTYHANDLE_REPLACEMENTTABLE : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nWho has changed the value type of \"Office.Common\\Font\\Substitution\\Replacement\"?" ); + seqValues[nProperty] >>= m_bReplacementTable; + } + break; + case PROPERTYHANDLE_FONTHISTORY : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nWho has changed the value type of \"Office.Common\\Font\\View\\History\"?" ); + seqValues[nProperty] >>= m_bFontHistory; + } + break; + case PROPERTYHANDLE_FONTWYSIWYG : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nWho has changed the value type of \"Office.Common\\Font\\View\\ShowFontBoxWYSIWYG\"?" ); + seqValues[nProperty] >>= m_bFontWYSIWYG; + } + break; + } + } + + // Enable notification mechanism of ouer baseclass. + // We need it to get information about changes outside these class on ouer used configuration keys! + EnableNotification( seqNames ); +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtFontOptions_Impl::~SvtFontOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames ) +{ + // Use given list of updated properties to get his values from configuration directly! + Sequence< Any > seqValues = GetProperties( seqPropertyNames ); + // Safe impossible cases. + // We need values from ALL notified configuration keys. + DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtFontOptions_Impl::Notify()\nI miss some values of configuration keys!\n" ); + // Step over list of property names and get right value from coreesponding value list to set it on internal members! + sal_Int32 nCount = seqPropertyNames.getLength(); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + if( seqPropertyNames[nProperty] == PROPERTYNAME_REPLACEMENTTABLE ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Font\\Substitution\\Replacement\"?" ); + seqValues[nProperty] >>= m_bReplacementTable; + } + else + if( seqPropertyNames[nProperty] == PROPERTYNAME_FONTHISTORY ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Font\\View\\History\"?" ); + seqValues[nProperty] >>= m_bFontHistory; + } + else + if( seqPropertyNames[nProperty] == PROPERTYNAME_FONTWYSIWYG ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Font\\View\\ShowFontBoxWYSIWYG\"?" ); + seqValues[nProperty] >>= m_bFontWYSIWYG; + } + #if OSL_DEBUG_LEVEL > 1 + else DBG_ASSERT( sal_False, "SvtFontOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" ); + #endif + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions_Impl::Commit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + Sequence< OUString > seqNames = impl_GetPropertyNames(); + sal_Int32 nCount = seqNames.getLength(); + Sequence< Any > seqValues ( nCount ); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_REPLACEMENTTABLE : { + seqValues[nProperty] <<= m_bReplacementTable; + } + break; + case PROPERTYHANDLE_FONTHISTORY : { + seqValues[nProperty] <<= m_bFontHistory; + } + break; + case PROPERTYHANDLE_FONTWYSIWYG : { + seqValues[nProperty] <<= m_bFontWYSIWYG; + } + break; + } + } + // Set properties in configuration. + PutProperties( seqNames, seqValues ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtFontOptions_Impl::IsReplacementTableEnabled() const +{ + return m_bReplacementTable; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions_Impl::EnableReplacementTable( sal_Bool bState ) +{ + m_bReplacementTable = bState; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtFontOptions_Impl::IsFontHistoryEnabled() const +{ + return m_bFontHistory; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions_Impl::EnableFontHistory( sal_Bool bState ) +{ + m_bFontHistory = bState; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtFontOptions_Impl::IsFontWYSIWYGEnabled() const +{ + return m_bFontWYSIWYG; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions_Impl::EnableFontWYSIWYG( sal_Bool bState ) +{ + m_bFontWYSIWYG = bState; + SetModified(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtFontOptions_Impl::impl_GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_REPLACEMENTTABLE , + PROPERTYNAME_FONTHISTORY , + PROPERTYNAME_FONTWYSIWYG , + }; + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtFontOptions_Impl* SvtFontOptions::m_pDataContainer = NULL ; +sal_Int32 SvtFontOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtFontOptions::SvtFontOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtFontOptions_Impl::ctor()"); + m_pDataContainer = new SvtFontOptions_Impl; + + ItemHolder1::holdConfigItem(E_FONTOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtFontOptions::~SvtFontOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtFontOptions::IsReplacementTableEnabled() const +{ + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsReplacementTableEnabled(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions::EnableReplacementTable( sal_Bool bState ) +{ + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + m_pDataContainer->EnableReplacementTable( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtFontOptions::IsFontHistoryEnabled() const +{ + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsFontHistoryEnabled(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions::EnableFontHistory( sal_Bool bState ) +{ + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + m_pDataContainer->EnableFontHistory( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtFontOptions::IsFontWYSIWYGEnabled() const +{ + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsFontWYSIWYGEnabled(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtFontOptions::EnableFontWYSIWYG( sal_Bool bState ) +{ + MutexGuard aGuard( impl_GetOwnStaticMutex() ); + m_pDataContainer->EnableFontWYSIWYG( bState ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtFontOptions::impl_GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/historyoptions.cxx b/unotools/source/config/historyoptions.cxx new file mode 100644 index 000000000000..5cb74f9bbf35 --- /dev/null +++ b/unotools/source/config/historyoptions.cxx @@ -0,0 +1,745 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/historyoptions.hxx> +#include <unotools/historyoptions_const.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#ifndef __SGI_STL_DEQUE +#include <deque> +#endif + +#ifndef __SGI_STL_ALGORITHM +#include <algorithm> +#endif + +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif + +#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ +#include <com/sun/star/container/XNameAccess.hpp> +#endif + +#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ +#include <com/sun/star/container/XNameContainer.hpp> +#endif + +#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#endif + +#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_ +#include <comphelper/configurationhelper.hxx> +#endif + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif + +#ifndef _SVT_LOGHELPER_HXX +#include <unotools/loghelper.hxx> +#endif + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::std ; +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::beans ; + +namespace css = ::com::sun::star; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +namespace { + static const ::sal_Int32 s_nOffsetURL = 0; + static const ::sal_Int32 s_nOffsetFilter = 1; + static const ::sal_Int32 s_nOffsetTitle = 2; + static const ::sal_Int32 s_nOffsetPassword = 3; +} + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +struct IMPL_THistoryItem +{ + IMPL_THistoryItem() + { + } + + IMPL_THistoryItem( const OUString& sNewURL , + const OUString& sNewFilter , + const OUString& sNewTitle , + const OUString& sNewPassword ) + { + sURL = sNewURL ; + sFilter = sNewFilter ; + sTitle = sNewTitle ; + sPassword = sNewPassword ; + } + + sal_Bool operator==( const OUString& sSearchedURL ) + { + return( sURL == sSearchedURL ); + } + + OUString sURL ; + OUString sFilter ; + OUString sTitle ; + OUString sPassword ; +}; + +//***************************************************************************************************************** +// class SvtHistoryOptions_Impl +// redesigned +//***************************************************************************************************************** +class SvtHistoryOptions_Impl +{ +public: + SvtHistoryOptions_Impl(); + ~SvtHistoryOptions_Impl(); + + sal_uInt32 GetSize( EHistoryType eHistory ); + void SetSize( EHistoryType eHistory, sal_uInt32 nSize ); + void Clear( EHistoryType eHistory ); + Sequence< Sequence< PropertyValue > > GetList( EHistoryType eHistory ); + void AppendItem( EHistoryType eHistory , + const OUString& sURL , + const OUString& sFilter , + const OUString& sTitle , + const OUString& sPassword ); + +private: + void impl_truncateList (EHistoryType eHistory, sal_uInt32 nSize); + +private: + css::uno::Reference< css::container::XNameAccess > m_xCfg; + css::uno::Reference< css::container::XNameAccess > m_xCommonXCU; +}; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtHistoryOptions_Impl::SvtHistoryOptions_Impl() +{ + try + { + m_xCfg = Reference< css::container::XNameAccess > ( + ::comphelper::ConfigurationHelper::openConfig( + utl::getProcessServiceFactory(), + s_sHistories, + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY ); + + m_xCommonXCU = Reference< css::container::XNameAccess > ( + ::comphelper::ConfigurationHelper::openConfig( + utl::getProcessServiceFactory(), + s_sCommonHistory, + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY ); + } + catch(const css::uno::Exception& ex) + { + m_xCfg.clear(); + m_xCommonXCU.clear(); + + LogHelper::logIt(ex); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtHistoryOptions_Impl::~SvtHistoryOptions_Impl() +{ +} + +//***************************************************************************************************************** +// public method +// Attention: We return the max. size of our internal lists - That is the capacity not the size! +//***************************************************************************************************************** +sal_uInt32 SvtHistoryOptions_Impl::GetSize( EHistoryType eHistory ) +{ + sal_uInt32 nSize = 0 ; + css::uno::Reference< css::beans::XPropertySet > xListAccess(m_xCommonXCU, css::uno::UNO_QUERY); + + try + { + switch( eHistory ) + { + case ePICKLIST: + xListAccess->getPropertyValue(s_sPickListSize) >>= nSize; + break; + + case eHISTORY: + xListAccess->getPropertyValue(s_sURLHistorySize) >>= nSize; + break; + + case eHELPBOOKMARKS: + xListAccess->getPropertyValue(s_sHelpBookmarksSize) >>= nSize; + break; + + default: + break; + } + } + catch(const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } + + return nSize; +} + +//***************************************************************************************************************** +// public method +// Attention: We return the max. size of our internal lists - That is the capacity not the size! +//***************************************************************************************************************** +void SvtHistoryOptions_Impl::SetSize( EHistoryType eHistory, sal_uInt32 nSize ) +{ + css::uno::Reference< css::beans::XPropertySet > xListAccess(m_xCommonXCU, css::uno::UNO_QUERY); + if (! xListAccess.is ()) + return; + + try + { + switch( eHistory ) + { + case ePICKLIST: + if(nSize!=GetSize(ePICKLIST)) + { + xListAccess->setPropertyValue(s_sPickListSize, css::uno::makeAny(nSize)); + ::comphelper::ConfigurationHelper::flush(m_xCommonXCU); + } + break; + + case eHISTORY: + if(nSize!=GetSize(eHISTORY)) + { + xListAccess->setPropertyValue(s_sURLHistorySize, css::uno::makeAny(nSize)); + ::comphelper::ConfigurationHelper::flush(m_xCommonXCU); + } + break; + + case eHELPBOOKMARKS: + if(nSize!=GetSize(eHELPBOOKMARKS)) + { + xListAccess->setPropertyValue(s_sHelpBookmarksSize, css::uno::makeAny(nSize)); + ::comphelper::ConfigurationHelper::flush(m_xCommonXCU); + } + break; + + default: + break; + } + + impl_truncateList (eHistory, nSize); + } + catch(const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +//***************************************************************************************************************** +void SvtHistoryOptions_Impl::impl_truncateList ( EHistoryType eHistory, sal_uInt32 nSize ) +{ + css::uno::Reference< css::container::XNameAccess > xList; + css::uno::Reference< css::container::XNameContainer > xItemList; + css::uno::Reference< css::container::XNameContainer > xOrderList; + css::uno::Reference< css::beans::XPropertySet > xSet; + + try + { + switch( eHistory ) + { + case ePICKLIST: + m_xCfg->getByName(s_sPickList) >>= xList; + break; + + case eHISTORY: + m_xCfg->getByName(s_sURLHistory) >>= xList; + break; + + case eHELPBOOKMARKS: + m_xCfg->getByName(s_sHelpBookmarks) >>= xList; + break; + + default: + break; + } + + // If too much items in current list ... + // truncate the oldest items BEFORE you set the new one. + if ( ! xList.is()) + return; + + xList->getByName(s_sOrderList) >>= xOrderList; + xList->getByName(s_sItemList) >>= xItemList; + + const sal_uInt32 nLength = xOrderList->getElementNames().getLength(); + if (nSize < nLength) + { + for (sal_uInt32 i=nLength-1; i>=nSize; --i) + { + ::rtl::OUString sTmp; + const ::rtl::OUString sRemove = ::rtl::OUString::valueOf((sal_Int32)i); + xOrderList->getByName(sRemove) >>= xSet; + xSet->getPropertyValue(s_sHistoryItemRef) >>= sTmp; + xItemList->removeByName(sTmp); + xOrderList->removeByName(sRemove); + } + + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + catch(const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +//***************************************************************************************************************** +// public method +// Clear specified history list +//***************************************************************************************************************** +void SvtHistoryOptions_Impl::Clear( EHistoryType eHistory ) +{ + css::uno::Reference< css::container::XNameAccess > xListAccess; + css::uno::Reference< css::container::XNameContainer > xNode; + Sequence< ::rtl::OUString > lOrders; + + try + { + switch( eHistory ) + { + case ePICKLIST: + { + m_xCfg->getByName(s_sPickList) >>= xListAccess; + break; + } + + case eHISTORY: + { + m_xCfg->getByName(s_sURLHistory) >>= xListAccess; + break; + } + + case eHELPBOOKMARKS: + { + m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess; + break; + } + + default: + break; + } + + if (xListAccess.is()) + { + // clear ItemList + xListAccess->getByName(s_sItemList) >>= xNode ; + lOrders = xNode->getElementNames(); + const sal_Int32 nLength = lOrders.getLength(); + for(sal_Int32 i=0; i<nLength; ++i) + xNode->removeByName(lOrders[i]); + + // clear OrderList + xListAccess->getByName(s_sOrderList) >>= xNode ; + lOrders = xNode->getElementNames(); + for(sal_Int32 j=0; j<nLength; ++j) + xNode->removeByName(lOrders[j]); + + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + catch(const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +//***************************************************************************************************************** +// public method +// get a sequence list from the items +//***************************************************************************************************************** +Sequence< Sequence< PropertyValue > > SvtHistoryOptions_Impl::GetList( EHistoryType eHistory ) +{ + impl_truncateList (eHistory, GetSize (eHistory)); + + Sequence< Sequence< PropertyValue > > seqReturn; // Set default return value. + Sequence< PropertyValue > seqProperties( 4 ); + Sequence< ::rtl::OUString > lOrders; + + css::uno::Reference< css::container::XNameAccess > xListAccess; + css::uno::Reference< css::container::XNameAccess > xItemList; + css::uno::Reference< css::container::XNameAccess > xOrderList; + css::uno::Reference< css::beans::XPropertySet > xSet; + + seqProperties[s_nOffsetURL ].Name = HISTORY_PROPERTYNAME_URL; + seqProperties[s_nOffsetFilter ].Name = HISTORY_PROPERTYNAME_FILTER; + seqProperties[s_nOffsetTitle ].Name = HISTORY_PROPERTYNAME_TITLE; + seqProperties[s_nOffsetPassword ].Name = HISTORY_PROPERTYNAME_PASSWORD; + + try + { + switch( eHistory ) + { + case ePICKLIST: + { + m_xCfg->getByName(s_sPickList) >>= xListAccess; + break; + } + + case eHISTORY: + { + m_xCfg->getByName(s_sURLHistory) >>= xListAccess; + break; + } + + case eHELPBOOKMARKS: + { + m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess; + break; + } + + default: + break; + } + + if (xListAccess.is()) + { + xListAccess->getByName(s_sItemList) >>= xItemList; + xListAccess->getByName(s_sOrderList) >>= xOrderList; + + const sal_Int32 nLength = xOrderList->getElementNames().getLength(); + Sequence< Sequence< PropertyValue > > aRet(nLength); + + for(sal_Int32 nItem=0; nItem<nLength; ++nItem) + { + ::rtl::OUString sUrl; + xOrderList->getByName(::rtl::OUString::valueOf(nItem)) >>= xSet; + xSet->getPropertyValue(s_sHistoryItemRef) >>= sUrl; + + xItemList->getByName(sUrl) >>= xSet; + seqProperties[s_nOffsetURL ].Value <<= sUrl; + xSet->getPropertyValue(s_sFilter) >>= seqProperties[s_nOffsetFilter ].Value; + xSet->getPropertyValue(s_sTitle) >>= seqProperties[s_nOffsetTitle ].Value; + xSet->getPropertyValue(s_sPassword) >>= seqProperties[s_nOffsetPassword ].Value; + aRet[nItem] = seqProperties; + } + seqReturn = aRet; + } + } + catch(const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } + + return seqReturn; +} + +//***************************************************************************************************************** +// public method +// implements a deque in XML +//***************************************************************************************************************** +void SvtHistoryOptions_Impl::AppendItem( EHistoryType eHistory , + const OUString& sURL , + const OUString& sFilter , + const OUString& sTitle , + const OUString& sPassword ) +{ + impl_truncateList (eHistory, GetSize (eHistory)); + + css::uno::Reference< css::container::XNameAccess > xListAccess; + sal_Int32 nMaxSize = 0; + + switch(eHistory) + { + case ePICKLIST: + { + m_xCfg->getByName(s_sPickList) >>= xListAccess; + nMaxSize = GetSize(ePICKLIST); + } + break; + case eHISTORY: + { + m_xCfg->getByName(s_sURLHistory) >>= xListAccess; + nMaxSize = GetSize(eHISTORY); + } + break; + case eHELPBOOKMARKS: + { + m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess; + nMaxSize = GetSize(eHELPBOOKMARKS); + } + break; + default: + break; + } + + if (nMaxSize==0) + return; + + css::uno::Reference< css::container::XNameContainer > xItemList; + css::uno::Reference< css::container::XNameContainer > xOrderList; + css::uno::Reference< css::beans::XPropertySet > xSet; + + try + { + xListAccess->getByName(s_sItemList) >>= xItemList; + xListAccess->getByName(s_sOrderList) >>= xOrderList; + sal_Int32 nLength = xOrderList->getElementNames().getLength(); + + // The item to be appended is already existing! + if (xItemList->hasByName(sURL)) + { + for (sal_Int32 i=0; i<nLength; ++i) + { + ::rtl::OUString sTmp; + xOrderList->getByName(::rtl::OUString::valueOf(i)) >>= xSet; + xSet->getPropertyValue(s_sHistoryItemRef) >>= sTmp; + + if(sURL == sTmp) + { + ::rtl::OUString sFind; + xOrderList->getByName( ::rtl::OUString::valueOf(i) ) >>= xSet; + xSet->getPropertyValue(s_sHistoryItemRef) >>= sFind; + for (sal_Int32 j=i-1; j>=0; --j) + { + css::uno::Reference< css::beans::XPropertySet > xPrevSet; + css::uno::Reference< css::beans::XPropertySet > xNextSet; + xOrderList->getByName( ::rtl::OUString::valueOf(j+1) ) >>= xPrevSet; + xOrderList->getByName( ::rtl::OUString::valueOf(j) ) >>= xNextSet; + + ::rtl::OUString sTemp; + xNextSet->getPropertyValue(s_sHistoryItemRef) >>= sTemp; + xPrevSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sTemp)); + } + xOrderList->getByName( ::rtl::OUString::valueOf((sal_Int32)0) ) >>= xSet; + xSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sFind)); + + ::comphelper::ConfigurationHelper::flush(m_xCfg); + break; + } + } + } + + // The item to be appended is not existing! + else + { + css::uno::Reference< css::lang::XSingleServiceFactory > xFac; + css::uno::Reference< css::uno::XInterface > xInst; + css::uno::Reference< css::beans::XPropertySet > xPrevSet; + css::uno::Reference< css::beans::XPropertySet > xNextSet; + + // Append new item to OrderList. + if ( nLength == nMaxSize ) + { + ::rtl::OUString sRemove; + xOrderList->getByName(::rtl::OUString::valueOf(nLength-1)) >>= xSet; + xSet->getPropertyValue(s_sHistoryItemRef) >>= sRemove; + xItemList->removeByName(sRemove); + } + if ( nLength != nMaxSize ) + { + xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xOrderList, css::uno::UNO_QUERY); + xInst = xFac->createInstance(); + ::rtl::OUString sPush = ::rtl::OUString::valueOf(nLength++); + xOrderList->insertByName(sPush, css::uno::makeAny(xInst)); + } + for (sal_Int32 j=nLength-1; j>0; --j) + { + xOrderList->getByName( ::rtl::OUString::valueOf(j) ) >>= xPrevSet; + xOrderList->getByName( ::rtl::OUString::valueOf(j-1) ) >>= xNextSet; + ::rtl::OUString sTemp; + xNextSet->getPropertyValue(s_sHistoryItemRef) >>= sTemp; + xPrevSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sTemp)); + } + xOrderList->getByName( ::rtl::OUString::valueOf((sal_Int32)0) ) >>= xSet; + xSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sURL)); + + // Append the item to ItemList. + xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xItemList, css::uno::UNO_QUERY); + xInst = xFac->createInstance(); + xItemList->insertByName(sURL, css::uno::makeAny(xInst)); + xSet = css::uno::Reference< css::beans::XPropertySet >(xInst, css::uno::UNO_QUERY); + xSet->setPropertyValue(s_sFilter, css::uno::makeAny(sFilter)); + xSet->setPropertyValue(s_sTitle, css::uno::makeAny(sTitle)); + xSet->setPropertyValue(s_sPassword, css::uno::makeAny(sPassword)); + + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + catch(const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtHistoryOptions_Impl* SvtHistoryOptions::m_pDataContainer = NULL ; +sal_Int32 SvtHistoryOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtHistoryOptions::SvtHistoryOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtHistoryOptions_Impl::ctor()"); + m_pDataContainer = new SvtHistoryOptions_Impl; + + ItemHolder1::holdConfigItem(E_HISTORYOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtHistoryOptions::~SvtHistoryOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_uInt32 SvtHistoryOptions::GetSize( EHistoryType eHistory ) const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetSize( eHistory ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtHistoryOptions::SetSize( EHistoryType eHistory, sal_uInt32 nSize ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetSize( eHistory, nSize ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtHistoryOptions::Clear( EHistoryType eHistory ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->Clear( eHistory ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< Sequence< PropertyValue > > SvtHistoryOptions::GetList( EHistoryType eHistory ) const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetList( eHistory ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtHistoryOptions::AppendItem( EHistoryType eHistory , + const OUString& sURL , + const OUString& sFilter , + const OUString& sTitle , + const OUString& sPassword ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->AppendItem( eHistory, sURL, sFilter, sTitle, sPassword ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtHistoryOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/inetoptions.cxx b/unotools/source/config/inetoptions.cxx new file mode 100644 index 000000000000..15bf425af744 --- /dev/null +++ b/unotools/source/config/inetoptions.cxx @@ -0,0 +1,554 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/inetoptions.hxx> +#include "rtl/instance.hxx" +#include <tools/urlobj.hxx> +#ifndef _WILDCARD_HXX +#include <tools/wldcrd.hxx> +#endif + +#include <algorithm> +#include <map> +#include <set> +#include <vector> +#include <utility> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/beans/XPropertiesChangeListener.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/system/XProxySettings.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <osl/mutex.hxx> +#include <rtl/ustring.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <unotools/configitem.hxx> +#include <unotools/processfactory.hxx> +#include <osl/diagnose.h> +#include <salhelper/refobj.hxx> +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +using namespace com::sun; + +//============================================================================ +// +// takeAny +// +//============================================================================ + +namespace { + +template< typename T > inline T takeAny(star::uno::Any const & rAny) +{ + T aValue = T(); + rAny >>= aValue; + return aValue; +} + +} + +//============================================================================ +// +// SvtInetOptions::Impl +// +//============================================================================ + +class SvtInetOptions::Impl: public salhelper::ReferenceObject, + public utl::ConfigItem +{ +public: + enum Index + { + INDEX_NO_PROXY, + INDEX_PROXY_TYPE, + INDEX_FTP_PROXY_NAME, + INDEX_FTP_PROXY_PORT, + INDEX_HTTP_PROXY_NAME, + INDEX_HTTP_PROXY_PORT + }; + + Impl(); + + star::uno::Any getProperty(Index nIndex); + + void + setProperty(Index nIndex, star::uno::Any const & rValue, bool bFlush); + + inline void flush() { Commit(); } + + void + addPropertiesChangeListener( + star::uno::Sequence< rtl::OUString > const & rPropertyNames, + star::uno::Reference< star::beans::XPropertiesChangeListener > const & + rListener); + + void + removePropertiesChangeListener( + star::uno::Sequence< rtl::OUString > const & rPropertyNames, + star::uno::Reference< star::beans::XPropertiesChangeListener > const & + rListener); + +private: + enum { ENTRY_COUNT = INDEX_HTTP_PROXY_PORT + 1 }; + + struct Entry + { + enum State { UNKNOWN, KNOWN, MODIFIED }; + + inline Entry(): m_eState(UNKNOWN) {} + + rtl::OUString m_aName; + star::uno::Any m_aValue; + State m_eState; + }; + + // MSVC has problems with the below Map type when + // star::uno::Reference< star::beans::XPropertiesChangeListener > is not + // wrapped in class Listener: + class Listener: + public star::uno::Reference< star::beans::XPropertiesChangeListener > + { + public: + Listener(star::uno::Reference< + star::beans::XPropertiesChangeListener > const & + rListener): + star::uno::Reference< star::beans::XPropertiesChangeListener >( + rListener) + {} + }; + + typedef std::map< Listener, std::set< rtl::OUString > > Map; + + osl::Mutex m_aMutex; + Entry m_aEntries[ENTRY_COUNT]; + Map m_aListeners; + + virtual inline ~Impl() { Commit(); } + + virtual void Notify(star::uno::Sequence< rtl::OUString > const & rKeys); + + virtual void Commit(); + + void notifyListeners(star::uno::Sequence< rtl::OUString > const & rKeys); +}; + +//============================================================================ +// virtual +void +SvtInetOptions::Impl::Notify(star::uno::Sequence< rtl::OUString > const & + rKeys) +{ + { + osl::MutexGuard aGuard(m_aMutex); + for (sal_Int32 i = 0; i < rKeys.getLength(); ++i) + for (sal_Int32 j = 0; j < ENTRY_COUNT; ++j) + if (rKeys[i] == m_aEntries[j].m_aName) + { + m_aEntries[j].m_eState = Entry::UNKNOWN; + break; + } + } + notifyListeners(rKeys); +} + +//============================================================================ +// virtual +void SvtInetOptions::Impl::Commit() +{ + star::uno::Sequence< rtl::OUString > aKeys(ENTRY_COUNT); + star::uno::Sequence< star::uno::Any > aValues(ENTRY_COUNT); + sal_Int32 nCount = 0; + { + osl::MutexGuard aGuard(m_aMutex); + for (sal_Int32 i = 0; i < ENTRY_COUNT; ++i) + if (m_aEntries[i].m_eState == Entry::MODIFIED) + { + aKeys[nCount] = m_aEntries[i].m_aName; + aValues[nCount] = m_aEntries[i].m_aValue; + ++nCount; + m_aEntries[i].m_eState = Entry::KNOWN; + } + } + if (nCount > 0) + { + aKeys.realloc(nCount); + aValues.realloc(nCount); + PutProperties(aKeys, aValues); + } +} + +//============================================================================ +void +SvtInetOptions::Impl::notifyListeners( + star::uno::Sequence< rtl::OUString > const & rKeys) +{ + typedef + std::vector< std::pair< star::uno::Reference< + star::beans::XPropertiesChangeListener >, + star::uno::Sequence< + star::beans::PropertyChangeEvent > > > + List; + List aNotifications; + { + osl::MutexGuard aGuard(m_aMutex); + aNotifications.reserve(m_aListeners.size()); + Map::const_iterator aMapEnd(m_aListeners.end()); + for (Map::const_iterator aIt(m_aListeners.begin()); aIt != aMapEnd; + ++aIt) + { + const Map::mapped_type &rSet = aIt->second; + Map::mapped_type::const_iterator aSetEnd(rSet.end()); + star::uno::Sequence< star::beans::PropertyChangeEvent > + aEvents(rKeys.getLength()); + sal_Int32 nCount = 0; + for (sal_Int32 i = 0; i < rKeys.getLength(); ++i) + { + rtl::OUString + aTheKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Inet/"))); + aTheKey += rKeys[i]; + if (rSet.find(aTheKey) != aSetEnd) + { + aEvents[nCount].PropertyName = aTheKey; + aEvents[nCount].PropertyHandle = -1; + ++nCount; + } + } + if (nCount > 0) + { + aEvents.realloc(nCount); + aNotifications. + push_back(std::make_pair< List::value_type::first_type, + List::value_type::second_type >( + aIt->first, aEvents)); + } + } + } + for (List::size_type i = 0; i < aNotifications.size(); ++i) + if (aNotifications[i].first.is()) + aNotifications[i].first-> + propertiesChange(aNotifications[i].second); +} + +//============================================================================ +SvtInetOptions::Impl::Impl(): + ConfigItem(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Inet/Settings"))) +{ + m_aEntries[INDEX_NO_PROXY].m_aName + = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetNoProxy")); + m_aEntries[INDEX_PROXY_TYPE].m_aName + = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetProxyType")); + m_aEntries[INDEX_FTP_PROXY_NAME].m_aName + = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetFTPProxyName")); + m_aEntries[INDEX_FTP_PROXY_PORT].m_aName + = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetFTPProxyPort")); + m_aEntries[INDEX_HTTP_PROXY_NAME].m_aName + = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetHTTPProxyName")); + m_aEntries[INDEX_HTTP_PROXY_PORT].m_aName + = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetHTTPProxyPort")); + + star::uno::Sequence< rtl::OUString > aKeys(ENTRY_COUNT); + for (sal_Int32 i = 0; i < ENTRY_COUNT; ++i) + aKeys[i] = m_aEntries[i].m_aName; + if (!EnableNotification(aKeys)) + OSL_ENSURE(false, + "SvtInetOptions::Impl::Impl(): Bad EnableNotifications()"); +} + +//============================================================================ +star::uno::Any SvtInetOptions::Impl::getProperty(Index nPropIndex) +{ + for (int nTryCount = 0; nTryCount < 10; ++nTryCount) + { + { + osl::MutexGuard aGuard(m_aMutex); + if (m_aEntries[nPropIndex].m_eState != Entry::UNKNOWN) + return m_aEntries[nPropIndex].m_aValue; + } + star::uno::Sequence< rtl::OUString > aKeys(ENTRY_COUNT); + int nIndices[ENTRY_COUNT]; + sal_Int32 nCount = 0; + { + osl::MutexGuard aGuard(m_aMutex); + for (int i = 0; i < ENTRY_COUNT; ++i) + if (m_aEntries[i].m_eState == Entry::UNKNOWN) + { + aKeys[nCount] = m_aEntries[i].m_aName; + nIndices[nCount] = i; + ++nCount; + } + } + if (nCount > 0) + { + aKeys.realloc(nCount); + star::uno::Sequence< star::uno::Any > + aValues(GetProperties(aKeys)); + OSL_ENSURE(aValues.getLength() == nCount, + "SvtInetOptions::Impl::getProperty():" + " Bad GetProperties() result"); + nCount = std::min(nCount, aValues.getLength()); + { + osl::MutexGuard aGuard(m_aMutex); + for (sal_Int32 i = 0; i < nCount; ++i) + { + int nIndex = nIndices[i]; + if (m_aEntries[nIndex].m_eState == Entry::UNKNOWN) + { + m_aEntries[nIndices[i]].m_aValue = aValues[i]; + m_aEntries[nIndices[i]].m_eState = Entry::KNOWN; + } + } + } + } + } + OSL_ENSURE(false, + "SvtInetOptions::Impl::getProperty(): Possible life lock"); + { + osl::MutexGuard aGuard(m_aMutex); + return m_aEntries[nPropIndex].m_aValue; + } +} + +//============================================================================ +void SvtInetOptions::Impl::setProperty(Index nIndex, + star::uno::Any const & rValue, + bool bFlush) +{ + SetModified(); + { + osl::MutexGuard aGuard(m_aMutex); + m_aEntries[nIndex].m_aValue = rValue; + m_aEntries[nIndex].m_eState = bFlush ? Entry::KNOWN : Entry::MODIFIED; + } + + star::uno::Sequence< rtl::OUString > aKeys(1); + aKeys[0] = m_aEntries[nIndex].m_aName; + if (bFlush) + { + star::uno::Sequence< star::uno::Any > aValues(1); + aValues[0] = rValue; + PutProperties(aKeys, aValues); + } + else + notifyListeners(aKeys); +} + +//============================================================================ +void +SvtInetOptions::Impl::addPropertiesChangeListener( + star::uno::Sequence< rtl::OUString > const & rPropertyNames, + star::uno::Reference< star::beans::XPropertiesChangeListener > const & + rListener) +{ + osl::MutexGuard aGuard(m_aMutex); + Map::mapped_type & rEntry = m_aListeners[rListener]; + for (sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i) + rEntry.insert(rPropertyNames[i]); +} + +//============================================================================ +void +SvtInetOptions::Impl::removePropertiesChangeListener( + star::uno::Sequence< rtl::OUString > const & rPropertyNames, + star::uno::Reference< star::beans::XPropertiesChangeListener > const & + rListener) +{ + osl::MutexGuard aGuard(m_aMutex); + Map::iterator aIt(m_aListeners.find(rListener)); + if (aIt != m_aListeners.end()) + { + for (sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i) + aIt->second.erase(rPropertyNames[i]); + if (aIt->second.empty()) + m_aListeners.erase(aIt); + } +} + +//============================================================================ +// +// SvtInetOptions +// +//============================================================================ + +namespace +{ + class LocalSingleton : public rtl::Static< osl::Mutex, LocalSingleton > + { + }; +} + +// static +SvtInetOptions::Impl * SvtInetOptions::m_pImpl = 0; + +//============================================================================ +SvtInetOptions::SvtInetOptions() +{ + osl::MutexGuard aGuard(LocalSingleton::get()); + if (!m_pImpl) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtInetOptions_Impl::ctor()"); + m_pImpl = new Impl; + + ItemHolder1::holdConfigItem(E_INETOPTIONS); + } + m_pImpl->acquire(); +} + +//============================================================================ +SvtInetOptions::~SvtInetOptions() +{ + osl::MutexGuard aGuard(LocalSingleton::get()); + if (m_pImpl->release() == 0) + m_pImpl = 0; +} + +//============================================================================ +rtl::OUString SvtInetOptions::GetProxyNoProxy() const +{ + return takeAny< rtl::OUString >(m_pImpl-> + getProperty(Impl::INDEX_NO_PROXY)); +} + +//============================================================================ +sal_Int32 SvtInetOptions::GetProxyType() const +{ + return takeAny< sal_Int32 >(m_pImpl-> + getProperty(Impl::INDEX_PROXY_TYPE)); +} + +//============================================================================ +rtl::OUString SvtInetOptions::GetProxyFtpName() const +{ + return takeAny< rtl::OUString >(m_pImpl-> + getProperty( + Impl::INDEX_FTP_PROXY_NAME)); +} + +//============================================================================ +sal_Int32 SvtInetOptions::GetProxyFtpPort() const +{ + return takeAny< sal_Int32 >(m_pImpl-> + getProperty(Impl::INDEX_FTP_PROXY_PORT)); +} + +//============================================================================ +rtl::OUString SvtInetOptions::GetProxyHttpName() const +{ + return takeAny< rtl::OUString >(m_pImpl-> + getProperty( + Impl::INDEX_HTTP_PROXY_NAME)); +} + +//============================================================================ +sal_Int32 SvtInetOptions::GetProxyHttpPort() const +{ + return takeAny< sal_Int32 >(m_pImpl-> + getProperty(Impl::INDEX_HTTP_PROXY_PORT)); +} + +//============================================================================ +void SvtInetOptions::SetProxyNoProxy(rtl::OUString const & rValue, + bool bFlush) +{ + m_pImpl->setProperty(Impl::INDEX_NO_PROXY, + star::uno::makeAny(rValue), + bFlush); +} + +//============================================================================ +void SvtInetOptions::SetProxyType(ProxyType eValue, bool bFlush) +{ + m_pImpl->setProperty(Impl::INDEX_PROXY_TYPE, + star::uno::makeAny(sal_Int32(eValue)), + bFlush); +} + +//============================================================================ +void SvtInetOptions::SetProxyFtpName(rtl::OUString const & rValue, + bool bFlush) +{ + m_pImpl->setProperty(Impl::INDEX_FTP_PROXY_NAME, + star::uno::makeAny(rValue), + bFlush); +} + +//============================================================================ +void SvtInetOptions::SetProxyFtpPort(sal_Int32 nValue, bool bFlush) +{ + m_pImpl->setProperty(Impl::INDEX_FTP_PROXY_PORT, + star::uno::makeAny(nValue), + bFlush); +} + +//============================================================================ +void SvtInetOptions::SetProxyHttpName(rtl::OUString const & rValue, + bool bFlush) +{ + m_pImpl->setProperty(Impl::INDEX_HTTP_PROXY_NAME, + star::uno::makeAny(rValue), + bFlush); +} + +//============================================================================ +void SvtInetOptions::SetProxyHttpPort(sal_Int32 nValue, bool bFlush) +{ + m_pImpl->setProperty(Impl::INDEX_HTTP_PROXY_PORT, + star::uno::makeAny(nValue), + bFlush); +} + +//============================================================================ +void SvtInetOptions::flush() +{ + m_pImpl->flush(); +} + +//============================================================================ +void +SvtInetOptions::addPropertiesChangeListener( + star::uno::Sequence< rtl::OUString > const & rPropertyNames, + star::uno::Reference< star::beans::XPropertiesChangeListener > const & + rListener) +{ + m_pImpl->addPropertiesChangeListener(rPropertyNames, rListener); +} + +//============================================================================ +void +SvtInetOptions::removePropertiesChangeListener( + star::uno::Sequence< rtl::OUString > const & rPropertyNames, + star::uno::Reference< star::beans::XPropertiesChangeListener > const & + rListener) +{ + m_pImpl->removePropertiesChangeListener(rPropertyNames, rListener); +} diff --git a/unotools/source/config/internaloptions.cxx b/unotools/source/config/internaloptions.cxx new file mode 100644 index 000000000000..310b52f8c98f --- /dev/null +++ b/unotools/source/config/internaloptions.cxx @@ -0,0 +1,628 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <deque> + +#include <unotools/internaloptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::std ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::beans ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_INTERNAL OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Internal" )) +#define DEFAULT_SLOTCFG sal_False +#define DEFAULT_SENDCRASHMAIL sal_False +#define DEFAULT_USEMAILUI sal_True +#define DEFAULT_CURRENTTEMPURL OUString(RTL_CONSTASCII_USTRINGPARAM("")) + +#define FIXPROPERTYNAME_SLOTCFG OUString(RTL_CONSTASCII_USTRINGPARAM("Slot" )) +#define FIXPROPERTYNAME_SENDCRASHMAIL OUString(RTL_CONSTASCII_USTRINGPARAM("SendCrashMail" )) +#define FIXPROPERTYNAME_USEMAILUI OUString(RTL_CONSTASCII_USTRINGPARAM("UseMailUI" )) +#define FIXPROPERTYNAME_CURRENTTEMPURL OUString(RTL_CONSTASCII_USTRINGPARAM("CurrentTempURL" )) +//#define FIXPROPERTYNAME_REMOVEMENUENTRYCLOSE OUString(RTL_CONSTASCII_USTRINGPARAM("RemoveMenuEntryClose")) +//#define FIXPROPERTYNAME_REMOVEMENUENTRYBACKTOWEBTOP OUString(RTL_CONSTASCII_USTRINGPARAM("RemoveMenuEntryBackToWebtop")) +//#define FIXPROPERTYNAME_REMOVEMENUENTRYNEWWEBTOP OUString(RTL_CONSTASCII_USTRINGPARAM("RemoveMenuEntryNewWebtop")) +//#define FIXPROPERTYNAME_REMOVEMENUENTRYLOGOUT OUString(RTL_CONSTASCII_USTRINGPARAM("RemoveMenuEntryLogout")) + +#define FIXPROPERTYHANDLE_SLOTCFG 0 +#define FIXPROPERTYHANDLE_SENDCRASHMAIL 1 +#define FIXPROPERTYHANDLE_USEMAILUI 2 +#define FIXPROPERTYHANDLE_CURRENTTEMPURL 3 +//#define FIXPROPERTYHANDLE_REMOVEMENUENTRYCLOSE 3 +//#define FIXPROPERTYHANDLE_REMOVEMENUENTRYBACKTOWEBTOP 4 +//#define FIXPROPERTYHANDLE_REMOVEMENUENTRYNEWWEBTOP 5 +//#define FIXPROPERTYHANDLE_REMOVEMENUENTRYLOGOUT 6 + +#define FIXPROPERTYCOUNT 4 +/* +#define PROPERTYNAME_RECOVERYLIST OUString(RTL_CONSTASCII_USTRINGPARAM("RecoveryList" )) +#define PROPERTYNAME_URL OUString(RTL_CONSTASCII_USTRINGPARAM("OrgURL" )) +#define PROPERTYNAME_FILTER OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName" )) +#define PROPERTYNAME_TEMPNAME OUString(RTL_CONSTASCII_USTRINGPARAM("TempURL" )) + +#define OFFSET_URL 0 +#define OFFSET_FILTER 1 +#define OFFSET_TEMPNAME 2 +*/ +#define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" )) +#define FIXR OUString(RTL_CONSTASCII_USTRINGPARAM("r" )) + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ +/* +struct tIMPL_RecoveryEntry +{ + OUString sURL ; + OUString sFilter ; + OUString sTempName ; + + tIMPL_RecoveryEntry() + { + sURL = OUString(); + sFilter = OUString(); + sTempName = OUString(); + } + + tIMPL_RecoveryEntry( const OUString& sNewURL , + const OUString& sNewFilter , + const OUString& sNewTempName ) + { + sURL = sNewURL ; + sFilter = sNewFilter ; + sTempName = sNewTempName ; + } +}; + +typedef deque< tIMPL_RecoveryEntry > tIMPL_RecoveryStack; +*/ +class SvtInternalOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + + sal_Bool m_bRemoveMenuEntryClose; + sal_Bool m_bRemoveMenuEntryBackToWebtop; + sal_Bool m_bRemoveMenuEntryNewWebtop; + sal_Bool m_bRemoveMenuEntryLogout; + sal_Bool m_bSlotCFG ; /// cache "Slot" of Internal section + sal_Bool m_bSendCrashMail ; /// cache "SendCrashMail" of Internal section + sal_Bool m_bUseMailUI; + OUString m_aCurrentTempURL ; + // tIMPL_RecoveryStack m_aRecoveryList ; /// cache "RecoveryList" of Internal section + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtInternalOptions_Impl(); + ~SvtInternalOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& ) + { + DBG_ASSERT( sal_False, "SvtInternalOptions::Notify()\nNot used yet ... but called!?\n" ); + } + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short access method to get internal values + @descr These method give us a chance to regulate acces to ouer internal values. + It's not used in the moment - but it's possible for the feature! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + sal_Bool IsRemoveMenuEntryClose() const { return m_bRemoveMenuEntryClose; } + sal_Bool IsRemoveMenuEntryBackToWebtop() const { return m_bRemoveMenuEntryBackToWebtop; } + sal_Bool IsRemoveMenuEntryNewWebtop() const { return m_bRemoveMenuEntryNewWebtop; } + sal_Bool IsRemoveMenuEntryLogout() const { return m_bRemoveMenuEntryLogout; } + sal_Bool SlotCFGEnabled () const { return m_bSlotCFG; } + sal_Bool CrashMailEnabled () const { return m_bSendCrashMail; } + sal_Bool MailUIEnabled () const { return m_bUseMailUI; } + + OUString GetCurrentTempURL() const { return m_aCurrentTempURL; } + void SetCurrentTempURL( const OUString& aNewCurrentTempURL ); +/* + void PushRecoveryItem ( const OUString& sURL , + const OUString& sFilter , + const OUString& sTempName ); + void PopRecoveryItem ( OUString& sURL , + OUString& sFilter , + OUString& sTempName ); + sal_Bool IsRecoveryListEmpty ( ) const; +*/ + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of fix key names of ouer configuration management which represent oue module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. We return well known key names only - because the "UserData" node + is handled in a special way! + + @seealso - + + @param - + @return A list of needed configuration keys is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + Sequence< OUString > impl_GetPropertyNames(); +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtInternalOptions_Impl::SvtInternalOptions_Impl() + // Init baseclasses first + : ConfigItem ( ROOTNODE_INTERNAL, CONFIG_MODE_IMMEDIATE_UPDATE ) + // Init member then. + , m_bRemoveMenuEntryClose ( sal_False ) + , m_bRemoveMenuEntryBackToWebtop ( sal_False ) + , m_bRemoveMenuEntryNewWebtop ( sal_False ) + , m_bRemoveMenuEntryLogout ( sal_False ) + , m_bSlotCFG ( DEFAULT_SLOTCFG ) + , m_bSendCrashMail ( DEFAULT_SENDCRASHMAIL ) + , m_bUseMailUI ( DEFAULT_USEMAILUI ) + , m_aCurrentTempURL ( DEFAULT_CURRENTTEMPURL ) +{ + // Use our list of configuration keys to get his values. + // structure of internal section: (first 2 entries are fixed - all other are member of a set!) + // "Slot" + // "SendCrashMail" + // "RecoveryList/r1/URL" + // "RecoveryList/r1/Filter" + // "RecoveryList/r1/TempName" + // "RecoveryList/r2/URL" + // "RecoveryList/r2/Filter" + // "RecoveryList/r2/TempName" + // "RecoveryList/.." + Sequence< OUString > seqNames = impl_GetPropertyNames() ; + Sequence< Any > seqValues = GetProperties( seqNames ) ; + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtInternalOptions_Impl::SvtInternalOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Read fixed values first! + DBG_ASSERT(!(seqValues[FIXPROPERTYHANDLE_SLOTCFG].getValueTypeClass()!=TypeClass_BOOLEAN) , "SvtInternalOptions_Impl::SvtInternalOptions_Impl()\nWho has changed the value type of \"Office.Common\\Internal\\Slot\"?" ); + DBG_ASSERT(!(seqValues[FIXPROPERTYHANDLE_SENDCRASHMAIL].getValueTypeClass()!=TypeClass_BOOLEAN) , "SvtInternalOptions_Impl::SvtInternalOptions_Impl()\nWho has changed the value type of \"Office.Common\\Internal\\SendCrashMail\"?" ); + seqValues[FIXPROPERTYHANDLE_SLOTCFG ] >>= m_bSlotCFG ; + seqValues[FIXPROPERTYHANDLE_SENDCRASHMAIL ] >>= m_bSendCrashMail ; + seqValues[FIXPROPERTYHANDLE_USEMAILUI ] >>= m_bUseMailUI ; + seqValues[FIXPROPERTYHANDLE_CURRENTTEMPURL ] >>= m_aCurrentTempURL ; +// seqValues[FIXPROPERTYHANDLE_REMOVEMENUENTRYCLOSE ] >>= m_bRemoveMenuEntryClose ; +// seqValues[FIXPROPERTYHANDLE_REMOVEMENUENTRYBACKTOWEBTOP ] >>= m_bRemoveMenuEntryBackToWebtop ; +// seqValues[FIXPROPERTYHANDLE_REMOVEMENUENTRYNEWWEBTOP ] >>= m_bRemoveMenuEntryNewWebtop ; +// seqValues[FIXPROPERTYHANDLE_REMOVEMENUENTRYLOGOUT ] >>= m_bRemoveMenuEntryLogout ; +/* + // Read dynamical set "RecoveryList" then. + // 3 subkeys for every item! + // Attention: Start at next element after last fixed entry! We must ignore "Slot" and "SendCrashMail" ... + tIMPL_RecoveryEntry aEntry; + sal_uInt32 nCount = seqValues.getLength() ; + sal_uInt32 nPosition = FIXPROPERTYCOUNT ; + + while( nPosition<nCount ) + { + seqValues[nPosition] >>= aEntry.sURL ; + ++nPosition; + seqValues[nPosition] >>= aEntry.sFilter ; + ++nPosition; + seqValues[nPosition] >>= aEntry.sTempName ; + ++nPosition; + m_aRecoveryList.push_front( aEntry ); + } +*/ + // We don't need any notifications here. + // "Slot" and "SendCrashMail" are readonly(!) and our recovery list should not modified during runtime - it's used + // by our crash guard only ... otherwise we have a big problem. +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtInternalOptions_Impl::~SvtInternalOptions_Impl() +{ + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtInternalOptions_Impl::Commit() +{ + // We have to write our current temp URL + Sequence< OUString > aNames( 1 ); + OUString* pNames = aNames.getArray(); + Sequence< Any > aValues( 1 ); + Any* pValues = aValues.getArray(); + + pNames[0] = FIXPROPERTYNAME_CURRENTTEMPURL; + pValues[0] <<= m_aCurrentTempURL; + + PutProperties( aNames, aValues ); + +/* + // Write set of dynamic properties then. + ClearNodeSet( PROPERTYNAME_RECOVERYLIST ); + + tIMPL_RecoveryEntry aItem ; + OUString sNode ; + Sequence< PropertyValue > seqPropertyValues( 3 ) ; // Every node in set has 3 sub-nodes!( url, filter, tempname ) + + // Copy list entries to save-list and write it to configuration. + + sal_uInt32 nCount = m_aRecoveryList.size(); + for( sal_uInt32 nItem=0; nItem<nCount; ++nItem ) + { + aItem = m_aRecoveryList.top(); + m_aRecoveryList.pop(); + sNode = PROPERTYNAME_RECOVERYLIST + PATHDELIMITER + FIXR + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER; + seqPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ; + seqPropertyValues[OFFSET_FILTER ].Name = sNode + PROPERTYNAME_FILTER ; + seqPropertyValues[OFFSET_TEMPNAME ].Name = sNode + PROPERTYNAME_TEMPNAME ; + seqPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ; + seqPropertyValues[OFFSET_FILTER ].Value <<= aItem.sFilter ; + seqPropertyValues[OFFSET_TEMPNAME ].Value <<= aItem.sTempName ; + + SetSetProperties( PROPERTYNAME_RECOVERYLIST, seqPropertyValues ); + } + + tIMPL_RecoveryStack::iterator iRecovery = m_aRecoveryList.begin(); + for ( sal_uInt32 nItem=0; iRecovery != m_aRecoveryList.end(); ++nItem, ++iRecovery) + { + aItem = *iRecovery; + sNode = PROPERTYNAME_RECOVERYLIST + PATHDELIMITER + FIXR + + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER; + seqPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ; + seqPropertyValues[OFFSET_FILTER ].Name = sNode + PROPERTYNAME_FILTER ; + seqPropertyValues[OFFSET_TEMPNAME ].Name = sNode + PROPERTYNAME_TEMPNAME ; + seqPropertyValues[OFFSET_URL ].Value <<= iRecovery->sURL ; + seqPropertyValues[OFFSET_FILTER ].Value <<= iRecovery->sFilter ; + seqPropertyValues[OFFSET_TEMPNAME ].Value <<= iRecovery->sTempName ; + SetSetProperties( PROPERTYNAME_RECOVERYLIST, seqPropertyValues ); + } + + */ +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtInternalOptions_Impl::SetCurrentTempURL( const OUString& aNewCurrentTempURL ) +{ + m_aCurrentTempURL = aNewCurrentTempURL; + SetModified(); + Commit(); +} + +#if 0 +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtInternalOptions_Impl::PushRecoveryItem( const OUString& sURL , + const OUString& sFilter , + const OUString& sTempName ) +{ + tIMPL_RecoveryEntry aEntry( sURL, sFilter, sTempName ); + m_aRecoveryList.push_front( aEntry ); + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtInternalOptions_Impl::PopRecoveryItem( OUString& sURL , + OUString& sFilter , + OUString& sTempName ) +{ + tIMPL_RecoveryEntry aEntry = m_aRecoveryList.front(); + m_aRecoveryList.pop_front(); + SetModified(); // Don't forget it - we delete an entry here! + sURL = aEntry.sURL ; + sFilter = aEntry.sFilter ; + sTempName = aEntry.sTempName ; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtInternalOptions_Impl::IsRecoveryListEmpty() const +{ + return ( m_aRecoveryList.empty() ); +} +#endif + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtInternalOptions_Impl::impl_GetPropertyNames() +{ + /* + // First get ALL names of current existing list items in configuration! + Sequence< OUString > seqRecoveryItems = GetNodeNames( PROPERTYNAME_RECOVERYLIST ); + // Get information about list counts ... + sal_Int32 nRecoveryCount = seqRecoveryItems.getLength(); + // ... and create a property list with right size! (+2...for fix properties!) (*3 ... = sub nodes for every set node!) + Sequence< OUString > seqProperties( FIXPROPERTYCOUNT + (nRecoveryCount*3) ); + */ + Sequence< OUString > seqProperties(4); + + // Add names of fix properties to list. + seqProperties[FIXPROPERTYHANDLE_SLOTCFG ] = FIXPROPERTYNAME_SLOTCFG ; + seqProperties[FIXPROPERTYHANDLE_SENDCRASHMAIL ] = FIXPROPERTYNAME_SENDCRASHMAIL ; + seqProperties[FIXPROPERTYHANDLE_USEMAILUI ] = FIXPROPERTYNAME_USEMAILUI ; + seqProperties[FIXPROPERTYHANDLE_CURRENTTEMPURL ] = FIXPROPERTYNAME_CURRENTTEMPURL ; +// seqProperties[FIXPROPERTYHANDLE_REMOVEMENUENTRYCLOSE ] = FIXPROPERTYNAME_REMOVEMENUENTRYCLOSE; +// seqProperties[FIXPROPERTYHANDLE_REMOVEMENUENTRYBACKTOWEBTOP ] = FIXPROPERTYNAME_REMOVEMENUENTRYBACKTOWEBTOP; +// seqProperties[FIXPROPERTYHANDLE_REMOVEMENUENTRYNEWWEBTOP ] = FIXPROPERTYNAME_REMOVEMENUENTRYNEWWEBTOP; +// seqProperties[FIXPROPERTYHANDLE_REMOVEMENUENTRYLOGOUT ] = FIXPROPERTYNAME_REMOVEMENUENTRYLOGOUT; +/* + sal_uInt32 nPosition = FIXPROPERTYCOUNT; + // Add names for recovery list to list. + // 3 subkeys for every item! + // nPosition is the start point of an list item, nItem an index into right list of node names! + for( sal_Int32 nItem=0; nItem<nRecoveryCount; ++nItem ) + { + seqProperties[nPosition] = PROPERTYNAME_RECOVERYLIST + PATHDELIMITER + seqRecoveryItems[nItem] + PATHDELIMITER + PROPERTYNAME_URL ; + ++nPosition; + seqProperties[nPosition] = PROPERTYNAME_RECOVERYLIST + PATHDELIMITER + seqRecoveryItems[nItem] + PATHDELIMITER + PROPERTYNAME_FILTER ; + ++nPosition; + seqProperties[nPosition] = PROPERTYNAME_RECOVERYLIST + PATHDELIMITER + seqRecoveryItems[nItem] + PATHDELIMITER + PROPERTYNAME_TEMPNAME ; + ++nPosition; + } +*/ + // Return result. + return seqProperties; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtInternalOptions_Impl* SvtInternalOptions::m_pDataContainer = NULL ; +sal_Int32 SvtInternalOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtInternalOptions::SvtInternalOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already! + if( m_pDataContainer == NULL ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtInternalOptions_Impl::ctor()"); + m_pDataContainer = new SvtInternalOptions_Impl(); + + ItemHolder1::holdConfigItem(E_INTERNALOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtInternalOptions::~SvtInternalOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtInternalOptions::SlotCFGEnabled() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->SlotCFGEnabled(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtInternalOptions::CrashMailEnabled() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->CrashMailEnabled(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtInternalOptions::MailUIEnabled() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->MailUIEnabled(); +} + +//***************************************************************************************************************** +// public methods +//***************************************************************************************************************** +sal_Bool SvtInternalOptions::IsRemoveMenuEntryClose() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsRemoveMenuEntryClose(); +} + +sal_Bool SvtInternalOptions::IsRemoveMenuEntryBackToWebtop() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsRemoveMenuEntryBackToWebtop(); +} + +sal_Bool SvtInternalOptions::IsRemoveMenuEntryNewWebtop() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsRemoveMenuEntryNewWebtop(); +} + +sal_Bool SvtInternalOptions::IsRemoveMenuEntryLogout() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsRemoveMenuEntryLogout(); +} + +OUString SvtInternalOptions::GetCurrentTempURL() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetCurrentTempURL(); +} + +void SvtInternalOptions::SetCurrentTempURL( const OUString& aNewCurrentTempURL ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetCurrentTempURL( aNewCurrentTempURL ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtInternalOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/itemholder1.cxx b/unotools/source/config/itemholder1.cxx new file mode 100644 index 000000000000..48b1decc4983 --- /dev/null +++ b/unotools/source/config/itemholder1.cxx @@ -0,0 +1,329 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include "itemholder1.hxx" + +//----------------------------------------------- +// includes +#include <comphelper/processfactory.hxx> +#include <com/sun/star/lang/XComponent.hpp> + +#include <unotools/misccfg.hxx> +#include <unotools/undoopt.hxx> +#include <unotools/useroptions.hxx> +#include <unotools/accelcfg.hxx> +#include <unotools/cacheoptions.hxx> +#include <unotools/cmdoptions.hxx> +#include <unotools/compatibility.hxx> +#include <unotools/defaultoptions.hxx> +#include <unotools/dynamicmenuoptions.hxx> +#include <unotools/eventcfg.hxx> +#include <unotools/extendedsecurityoptions.hxx> +#include <unotools/fltrcfg.hxx> +#include <unotools/fontoptions.hxx> +#include <unotools/historyoptions.hxx> +#include <unotools/inetoptions.hxx> +#include <unotools/internaloptions.hxx> +#include <unotools/javaoptions.hxx> +#include <unotools/lingucfg.hxx> +#include <unotools/localisationoptions.hxx> +#include <unotools/moduleoptions.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/printwarningoptions.hxx> +#include <unotools/regoptions.hxx> +#include <unotools/optionsdlg.hxx> +#include <unotools/saveopt.hxx> +#include <unotools/searchopt.hxx> +#include <unotools/securityoptions.hxx> +#include <unotools/sourceviewconfig.hxx> +#include <unotools/startoptions.hxx> +#include <unotools/viewoptions.hxx> +#include <unotools/workingsetoptions.hxx> +#include <unotools/xmlaccelcfg.hxx> +#include <unotools/options.hxx> +#include <unotools/syslocaleoptions.hxx> + +//----------------------------------------------- +// namespaces + +namespace css = ::com::sun::star; + +//----------------------------------------------- +// declarations + +//----------------------------------------------- +ItemHolder1::ItemHolder1() + : ItemHolderMutexBase() +{ + try + { + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); + css::uno::Reference< css::lang::XComponent > xCfg( + xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), + css::uno::UNO_QUERY); + if (xCfg.is()) + xCfg->addEventListener(static_cast< css::lang::XEventListener* >(this)); + } +// #i37892 got errorhandling from ConfigManager::GetConfigurationProvider() +#ifdef DBG_UTIL + catch(css::uno::Exception& rEx) + { + static sal_Bool bMessage = sal_True; + if(bMessage) + { + bMessage = sal_False; + ::rtl::OString sMsg("CreateInstance with arguments exception: "); + sMsg += ::rtl::OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + OSL_ENSURE(sal_False, sMsg.getStr()); + } + } +#else + catch(css::uno::Exception&){} +#endif +} + +//----------------------------------------------- +ItemHolder1::~ItemHolder1() +{ + impl_releaseAllItems(); +} + +//----------------------------------------------- +void ItemHolder1::holdConfigItem(EItem eItem) +{ + static ItemHolder1* pHolder = new ItemHolder1(); + pHolder->impl_addItem(eItem); +} + +//----------------------------------------------- +void SAL_CALL ItemHolder1::disposing(const css::lang::EventObject&) + throw(css::uno::RuntimeException) +{ + css::uno::Reference< css::uno::XInterface > xSelfHold(static_cast< css::lang::XEventListener* >(this), css::uno::UNO_QUERY); + impl_releaseAllItems(); +} + +//----------------------------------------------- +void ItemHolder1::impl_addItem(EItem eItem) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + TItems::const_iterator pIt; + for ( pIt = m_lItems.begin(); + pIt != m_lItems.end() ; + ++pIt ) + { + const TItemInfo& rInfo = *pIt; + if (rInfo.eItem == eItem) + return; + } + + TItemInfo aNewItem; + aNewItem.eItem = eItem; + impl_newItem(aNewItem); + if (aNewItem.pItem) + m_lItems.push_back(aNewItem); +} + +//----------------------------------------------- +void ItemHolder1::impl_releaseAllItems() +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + TItems::iterator pIt; + for ( pIt = m_lItems.begin(); + pIt != m_lItems.end() ; + ++pIt ) + { + TItemInfo& rInfo = *pIt; + impl_deleteItem(rInfo); + } + m_lItems.clear(); +} + +//----------------------------------------------- +void ItemHolder1::impl_newItem(TItemInfo& rItem) +{ + switch(rItem.eItem) + { + case E_ACCELCFG : + rItem.pItem = new SvtAcceleratorConfiguration(); + break; + + case E_CMDOPTIONS : + rItem.pItem = new SvtCommandOptions(); + break; + + case E_COMPATIBILITY : + rItem.pItem = new SvtCompatibilityOptions(); + break; + + case E_DEFAULTOPTIONS : + rItem.pItem = new SvtDefaultOptions(); + break; + + case E_DYNAMICMENUOPTIONS : + rItem.pItem = new SvtDynamicMenuOptions(); + break; + + case E_EVENTCFG : + //rItem.pItem = new GlobalEventConfig(); + break; + + case E_EXTENDEDSECURITYOPTIONS : + rItem.pItem = new SvtExtendedSecurityOptions(); + break; + + case E_FLTRCFG : +// no ref count rItem.pItem = new SvtFilterOptions(); + break; + + case E_FONTOPTIONS : + rItem.pItem = new SvtFontOptions(); + break; + + case E_HISTORYOPTIONS : + rItem.pItem = new SvtHistoryOptions(); + break; + + case E_INETOPTIONS : + rItem.pItem = new SvtInetOptions(); + break; + + case E_INTERNALOPTIONS : + rItem.pItem = new SvtInternalOptions(); + break; + + case E_JAVAOPTIONS : +// no ref count rItem.pItem = new SvtJavaOptions(); + break; + + case E_LINGUCFG : + rItem.pItem = new SvtLinguConfig(); + break; + + case E_LOCALISATIONOPTIONS : + rItem.pItem = new SvtLocalisationOptions(); + break; + + case E_MODULEOPTIONS : + rItem.pItem = new SvtModuleOptions(); + break; + + case E_OPTIONSDLGOPTIONS : + rItem.pItem = new SvtOptionsDialogOptions(); + break; + + case E_PATHOPTIONS : + rItem.pItem = new SvtPathOptions(); + break; + + case E_PRINTWARNINGOPTIONS : + rItem.pItem = new SvtPrintWarningOptions(); + break; + + case E_MISCCFG : + rItem.pItem = new ::utl::MiscCfg(); + break; + + case E_SAVEOPTIONS : + rItem.pItem = new SvtSaveOptions(); + break; + + case E_SEARCHOPT : +// no ref count rItem.pItem = new SvtSearchOptions(); + break; + + case E_SECURITYOPTIONS : + rItem.pItem = new SvtSecurityOptions(); + break; + + case E_SOURCEVIEWCONFIG : + rItem.pItem = new ::utl::SourceViewConfig(); + break; + + case E_STARTOPTIONS : + rItem.pItem = new SvtStartOptions(); + break; + + case E_VIEWOPTIONS_DIALOG : + rItem.pItem = new SvtViewOptions(E_DIALOG, ::rtl::OUString()); + break; + + case E_VIEWOPTIONS_TABDIALOG : + rItem.pItem = new SvtViewOptions(E_TABDIALOG, ::rtl::OUString()); + break; + + case E_VIEWOPTIONS_TABPAGE : + rItem.pItem = new SvtViewOptions(E_TABPAGE, ::rtl::OUString()); + break; + + case E_VIEWOPTIONS_WINDOW : + rItem.pItem = new SvtViewOptions(E_WINDOW, ::rtl::OUString()); + break; + + case E_WORKINGSETOPTIONS : + rItem.pItem = new SvtWorkingSetOptions(); + break; + + case E_XMLACCELCFG : + // ??? TODO + break; + + case E_UNDOOPTIONS : + rItem.pItem = new SvtUndoOptions(); + break; + + case E_USEROPTIONS : + rItem.pItem = new SvtUserOptions(); + break; + + case E_SYSLOCALEOPTIONS : + rItem.pItem = new SvtSysLocaleOptions(); + break; + + default: + OSL_ASSERT( "unknown item type" ); + break; + } +} + +//----------------------------------------------- +void ItemHolder1::impl_deleteItem(TItemInfo& rItem) +{ + if (rItem.pItem) + { + delete rItem.pItem; + rItem.pItem = 0; + } +} + diff --git a/unotools/source/config/itemholder1.hxx b/unotools/source/config/itemholder1.hxx new file mode 100644 index 000000000000..8e7fd285cc0a --- /dev/null +++ b/unotools/source/config/itemholder1.hxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_unotools_ITEMHOLDER1_HXX_ +#define INCLUDED_unotools_ITEMHOLDER1_HXX_ + +//----------------------------------------------- +// includes + +#include <unotools/itemholderbase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/lang/XEventListener.hpp> + +//----------------------------------------------- +// namespaces + +#ifdef css +#error "Cant use css as namespace alias." +#else +#define css ::com::sun::star +#endif + +//----------------------------------------------- +// definitions + +class ItemHolder1 : private ItemHolderMutexBase + , public ::cppu::WeakImplHelper1< css::lang::XEventListener > +{ + //........................................... + // member + private: + + TItems m_lItems; + + //........................................... + // c++ interface + public: + + ItemHolder1(); + virtual ~ItemHolder1(); + static void holdConfigItem(EItem eItem); + + //........................................... + // uno interface + public: + + virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) + throw(css::uno::RuntimeException); + + //........................................... + // helper + private: + + void impl_addItem(EItem eItem); + void impl_releaseAllItems(); + void impl_newItem(TItemInfo& rItem); + void impl_deleteItem(TItemInfo& rItem); +}; + +//----------------------------------------------- +// namespaces + +#undef css + +#endif // INCLUDED_unotools_ITEMHOLDER1_HXX_ diff --git a/unotools/source/config/javaoptions.cxx b/unotools/source/config/javaoptions.cxx new file mode 100644 index 000000000000..8c41aac2d3de --- /dev/null +++ b/unotools/source/config/javaoptions.cxx @@ -0,0 +1,369 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +#ifndef _unotools_JAVAPTIONS_HXX +#include <unotools/javaoptions.hxx> +#endif +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <rtl/logfile.hxx> + + +using namespace ::com::sun::star::uno; +using namespace ::rtl; + +#define C2U(cChar) OUString::createFromAscii(cChar) +#define CFG_READONLY_DEFAULT sal_False +/* -----------------------------10.04.01 12:39-------------------------------- + + ---------------------------------------------------------------------------*/ +class SvtExecAppletsItem_Impl : public utl::ConfigItem +{ + sal_Bool bExecute; + sal_Bool bRO; +public: + SvtExecAppletsItem_Impl(); + + virtual void Commit(); + void Notify( const Sequence< rtl::OUString >& ); + + sal_Bool IsExecuteApplets() const {return bExecute;} + void SetExecuteApplets(sal_Bool bSet); + sal_Bool IsReadOnly() const {return bRO;} +}; +/* -----------------------------10.02.2003 07:46------------------------------ + + ---------------------------------------------------------------------------*/ +void SvtExecAppletsItem_Impl::SetExecuteApplets(sal_Bool bSet) +{ + OSL_ENSURE(!bRO, "SvtExecAppletsItem_Impl::SetExecuteApplets()\nYou tried to write on a readonly value!\n"); + if (!bRO) + { + bExecute = bSet; + SetModified(); + } +} +/* -----------------------------18.05.01 14:44-------------------------------- + + ---------------------------------------------------------------------------*/ +SvtExecAppletsItem_Impl::SvtExecAppletsItem_Impl() : + utl::ConfigItem(C2U("Office.Common/Java/Applet")), + bExecute (sal_False ), + bRO (CFG_READONLY_DEFAULT ) +{ + RTL_LOGFILE_CONTEXT(aLog, "unotools SvtExecAppletsItem_Impl::SvtExecAppletsItem_Impl()"); + + Sequence< OUString > aNames(1); + aNames.getArray()[0] = C2U("Enable"); + Sequence< Any > aValues = GetProperties(aNames); + Sequence< sal_Bool > aROStates = GetReadOnlyStates(aNames); + const Any* pValues = aValues.getConstArray(); + const sal_Bool* pROStates = aROStates.getConstArray(); + if(aValues.getLength() && aROStates.getLength() && pValues[0].hasValue()) + { + bExecute = *(sal_Bool*)pValues[0].getValue(); + bRO = pROStates[0]; + } +} +void SvtExecAppletsItem_Impl::Commit() +{ + if (bRO) + return; + + Sequence< OUString > aNames(1); + aNames.getArray()[0] = C2U("Enable"); + Sequence< Any > aValues(1); + aValues.getArray()[0].setValue(&bExecute, ::getBooleanCppuType()); + PutProperties(aNames, aValues); +} + +void SvtExecAppletsItem_Impl::Notify( const Sequence< rtl::OUString >& ) +{ + // no listeners supported yet +} + +struct SvtJavaOptions_Impl +{ + SvtExecAppletsItem_Impl aExecItem; + Sequence<OUString> aPropertyNames; + sal_Bool bEnabled; + sal_Bool bSecurity; + sal_Int32 nNetAccess; + rtl::OUString sUserClassPath; + + sal_Bool bROEnabled; + sal_Bool bROSecurity; + sal_Bool bRONetAccess; + sal_Bool bROUserClassPath; + + SvtJavaOptions_Impl() : + aPropertyNames(4), + bEnabled (sal_False), + bSecurity (sal_False), + nNetAccess (0), + bROEnabled (CFG_READONLY_DEFAULT), + bROSecurity (CFG_READONLY_DEFAULT), + bRONetAccess (CFG_READONLY_DEFAULT), + bROUserClassPath (CFG_READONLY_DEFAULT) + { + OUString* pNames = aPropertyNames.getArray(); + pNames[0] = C2U("Enable"); + pNames[1] = C2U("Security"); + pNames[2] = C2U("NetAccess"); + pNames[3] = C2U("UserClassPath"); + } +}; +/* -----------------------------18.05.01 13:28-------------------------------- + + ---------------------------------------------------------------------------*/ +SvtJavaOptions::SvtJavaOptions() : + utl::ConfigItem(C2U("Office.Java/VirtualMachine")), + pImpl(new SvtJavaOptions_Impl) +{ + RTL_LOGFILE_CONTEXT(aLog, "unotools SvtJavaOptions::SvtJavaOptions()"); + + Sequence< Any > aValues = GetProperties(pImpl->aPropertyNames); + Sequence< sal_Bool > aROStates = GetReadOnlyStates(pImpl->aPropertyNames); + const Any* pValues = aValues.getConstArray(); + const sal_Bool* pROStates = aROStates.getConstArray(); + if ( aValues.getLength() == pImpl->aPropertyNames.getLength() && aROStates.getLength() == pImpl->aPropertyNames.getLength() ) + { + for ( int nProp = 0; nProp < pImpl->aPropertyNames.getLength(); nProp++ ) + { + if( pValues[nProp].hasValue() ) + { + switch ( nProp ) + { + case 0: pImpl->bEnabled = *(sal_Bool*)pValues[nProp].getValue(); break; + case 1: pImpl->bSecurity = *(sal_Bool*)pValues[nProp].getValue();break; + case 2: pValues[nProp] >>= pImpl->nNetAccess; break; + case 3: pValues[nProp] >>= pImpl->sUserClassPath; break; + } + } + } + pImpl->bROEnabled = pROStates[0]; + pImpl->bROSecurity = pROStates[1]; + pImpl->bRONetAccess = pROStates[2]; + pImpl->bROUserClassPath = pROStates[3]; + } +} +/* -----------------------------18.05.01 13:28-------------------------------- + + ---------------------------------------------------------------------------*/ +SvtJavaOptions::~SvtJavaOptions() +{ + delete pImpl; +} +/*-- 18.05.01 13:28:35--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtJavaOptions::Commit() +{ + pImpl->aExecItem.Commit(); + + sal_Int32 nOrgCount = pImpl->aPropertyNames.getLength(); + Sequence< OUString > aNames(nOrgCount); + Sequence< Any > aValues(nOrgCount); + sal_Int32 nRealCount = 0; + + const Type& rType = ::getBooleanCppuType(); + for(int nProp = 0; nProp < nOrgCount; nProp++) + { + switch(nProp) + { + case 0: + { + if (!pImpl->bROEnabled) + { + aValues[nRealCount].setValue(&pImpl->bEnabled, rType); + aNames[nRealCount] = pImpl->aPropertyNames[nProp]; + ++nRealCount; + } + } + break; + case 1: + { + if (!pImpl->bROSecurity) + { + aValues[nRealCount].setValue(&pImpl->bSecurity, rType); + aNames[nRealCount] = pImpl->aPropertyNames[nProp]; + ++nRealCount; + } + } + break; + case 2: + { + if (!pImpl->bRONetAccess) + { + aValues[nRealCount] <<= pImpl->nNetAccess; + aNames[nRealCount] = pImpl->aPropertyNames[nProp]; + ++nRealCount; + } + } + break; + case 3: + { + if (!pImpl->bROUserClassPath) + { + aValues[nRealCount] <<= pImpl->sUserClassPath; + aNames[nRealCount] = pImpl->aPropertyNames[nProp]; + ++nRealCount; + } + } + break; + } + } + aValues.realloc(nRealCount); + aNames.realloc(nRealCount); + PutProperties(aNames,aValues); +} +/*-- 18.05.01 13:28:35--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtJavaOptions::IsEnabled() const +{ + return pImpl->bEnabled; +} +/*-- 18.05.01 13:28:35--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtJavaOptions::IsSecurity()const +{ + return pImpl->bSecurity; +} +/*-- 18.05.01 13:28:35--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Int32 SvtJavaOptions::GetNetAccess() const +{ + return pImpl->nNetAccess; +} +/*-- 18.05.01 13:28:36--------------------------------------------------- + + -----------------------------------------------------------------------*/ +rtl::OUString& SvtJavaOptions::GetUserClassPath()const +{ + return pImpl->sUserClassPath; +} +/*-- 18.05.01 13:28:37--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtJavaOptions::SetEnabled(sal_Bool bSet) +{ + OSL_ENSURE(!pImpl->bROEnabled, "SvtJavaOptions::SetEnabled()\nYou tried to write on a readonly value!\n"); + if(!pImpl->bROEnabled && pImpl->bEnabled != bSet) + { + pImpl->bEnabled = bSet; + SetModified(); + } +} +/*-- 18.05.01 13:28:38--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtJavaOptions::SetSecurity(sal_Bool bSet) +{ + OSL_ENSURE(!pImpl->bROSecurity, "SvtJavaOptions::SetSecurity()\nYou tried to write on a readonly value!\n"); + if(!pImpl->bROSecurity && pImpl->bSecurity != bSet) + { + pImpl->bSecurity = bSet; + SetModified(); + } +} +/*-- 18.05.01 13:28:38--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtJavaOptions::SetNetAccess(sal_Int32 nSet) +{ + OSL_ENSURE(!pImpl->bRONetAccess, "SvtJavaOptions::SetNetAccess()\nYou tried to write on a readonly value!\n"); + if(!pImpl->bRONetAccess && pImpl->nNetAccess != nSet) + { + pImpl->nNetAccess = nSet; + SetModified(); + } +} +/*-- 18.05.01 13:28:38--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtJavaOptions::SetUserClassPath(const rtl::OUString& rSet) +{ + OSL_ENSURE(!pImpl->bROUserClassPath, "SvtJavaOptions::SetUserClassPath()\nYou tried to write on a readonly value!\n"); + if(!pImpl->bROUserClassPath && pImpl->sUserClassPath != rSet) + { + pImpl->sUserClassPath = rSet; + SetModified(); + } +} + +/*-- 18.05.01 14:34:32--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtJavaOptions::IsExecuteApplets() const +{ + return pImpl->aExecItem.IsExecuteApplets(); +} +/*-- 18.05.01 14:34:32--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtJavaOptions::SetExecuteApplets(sal_Bool bSet) +{ + if(!pImpl->aExecItem.IsReadOnly() && pImpl->aExecItem.IsExecuteApplets() != bSet) + { + pImpl->aExecItem.SetExecuteApplets(bSet); + SetModified(); + } +} +/*--10.02.2003 08:40--------------------------------------------------- + +-----------------------------------------------------------------------*/ +sal_Bool SvtJavaOptions::IsReadOnly( EOption eOption ) const +{ + sal_Bool bRO = sal_True; + switch(eOption) + { + case E_ENABLED : + bRO = pImpl->bROEnabled; + break; + case E_SECURITY : + bRO = pImpl->bROSecurity; + break; + case E_NETACCESS : + bRO = pImpl->bRONetAccess; + break; + case E_USERCLASSPATH : + bRO = pImpl->bROUserClassPath; + break; + case E_EXECUTEAPPLETS : + bRO = pImpl->aExecItem.IsReadOnly(); + break; + } + return bRO; +} diff --git a/unotools/source/config/lingucfg.cxx b/unotools/source/config/lingucfg.cxx new file mode 100755 index 000000000000..39233f022534 --- /dev/null +++ b/unotools/source/config/lingucfg.cxx @@ -0,0 +1,1501 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + + +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include "com/sun/star/util/XMacroExpander.hpp" +#include "com/sun/star/beans/XPropertySet.hpp" +#include <rtl/uri.hxx> +#include <vos/mutex.hxx> +#include <i18npool/mslangid.hxx> +#include <tools/debug.hxx> +#include <tools/string.hxx> +#include <unotools/lingucfg.hxx> +#include <unotools/linguprops.hxx> + +#include <comphelper/processfactory.hxx> + +#include <itemholder1.hxx> + +using namespace rtl; +using namespace com::sun::star; + +#define A2OU(x) ::rtl::OUString::createFromAscii( x ) +#define EXPAND_PROTOCOL "vnd.sun.star.expand:" +#define FILE_PROTOCOL "file:///" + +/////////////////////////////////////////////////////////////////////////// + + +static osl::Mutex & GetOwnMutex() +{ + static osl::Mutex aMutex; + return aMutex; +} + + +/////////////////////////////////////////////////////////////////////////// + + +static BOOL lcl_SetLocale( INT16 &rLanguage, const uno::Any &rVal ) +{ + BOOL bSucc = FALSE; + + lang::Locale aNew; + if (rVal >>= aNew) // conversion successful? + { + INT16 nNew = MsLangId::convertLocaleToLanguage( aNew ); + if (nNew != rLanguage) + { + rLanguage = nNew; + bSucc = TRUE; + } + } + return bSucc; +} + + +static inline const OUString lcl_LanguageToCfgLocaleStr( INT16 nLanguage ) +{ + OUString aRes; + if (LANGUAGE_SYSTEM != nLanguage) + aRes = MsLangId::convertLanguageToIsoString( nLanguage ); + return aRes; +} + + +static INT16 lcl_CfgAnyToLanguage( const uno::Any &rVal ) +{ + OUString aTmp; + rVal >>= aTmp; + return (aTmp.getLength() == 0) ? LANGUAGE_SYSTEM : MsLangId::convertIsoStringToLanguage( aTmp ); +} + + +////////////////////////////////////////////////////////////////////// + +SvtLinguOptions::SvtLinguOptions() +{ + nDefaultLanguage = LANGUAGE_NONE; + nDefaultLanguage_CJK = LANGUAGE_NONE; + nDefaultLanguage_CTL = LANGUAGE_NONE; + + // general options + bIsUseDictionaryList = + bIsIgnoreControlCharacters = TRUE; + + // spelling options + bIsSpellCapitalization = + bIsSpellSpecial = TRUE; + bIsSpellAuto = + bIsSpellReverse = + bIsSpellWithDigits = + bIsSpellUpperCase = FALSE; + + // text conversion options + bIsIgnorePostPositionalWord = TRUE; + bIsAutoCloseDialog = + bIsShowEntriesRecentlyUsedFirst = + bIsAutoReplaceUniqueEntries = FALSE; + bIsDirectionToSimplified = TRUE; + bIsUseCharacterVariants = + bIsTranslateCommonTerms = + bIsReverseMapping = FALSE; + + bROIsDirectionToSimplified = + bROIsUseCharacterVariants = + bROIsTranslateCommonTerms = + bROIsReverseMapping = FALSE; + + // hyphenation options + bIsHyphSpecial = TRUE; + bIsHyphAuto = FALSE; + nHyphMinLeading = + nHyphMinTrailing = 2; + nHyphMinWordLength = 0; + + nDataFilesChangedCheckValue = 0; + + //grammar options + bIsGrammarAuto = sal_False, + bIsGrammarInteractive = sal_False; + +} + + +////////////////////////////////////////////////////////////////////// + + +class SvtLinguConfigItem : public utl::ConfigItem +{ + SvtLinguOptions aOpt; + + // disallow copy-constructor and assignment-operator for now + SvtLinguConfigItem( const SvtLinguConfigItem & ); + SvtLinguConfigItem & operator = ( const SvtLinguConfigItem & ); + + static BOOL GetHdlByName( INT32 &rnHdl, const OUString &rPropertyName, sal_Bool bFullPropName = sal_False ); + static const uno::Sequence< OUString > & GetPropertyNames(); + BOOL LoadOptions( const uno::Sequence< OUString > &rProperyNames ); + BOOL SaveOptions( const uno::Sequence< OUString > &rProperyNames ); + +public: + SvtLinguConfigItem(); + virtual ~SvtLinguConfigItem(); + + // utl::ConfigItem + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames ); + virtual void Commit(); + + // make some protected functions of utl::ConfigItem public + using utl::ConfigItem::GetNodeNames; + using utl::ConfigItem::GetProperties; + //using utl::ConfigItem::PutProperties; + //using utl::ConfigItem::SetSetProperties; + using utl::ConfigItem::ReplaceSetProperties; + //using utl::ConfigItem::GetReadOnlyStates; + + + com::sun::star::uno::Any + GetProperty( const rtl::OUString &rPropertyName ) const; + com::sun::star::uno::Any + GetProperty( INT32 nPropertyHandle ) const; + + BOOL SetProperty( const rtl::OUString &rPropertyName, + const com::sun::star::uno::Any &rValue ); + BOOL SetProperty( INT32 nPropertyHandle, + const com::sun::star::uno::Any &rValue ); + + BOOL GetOptions( SvtLinguOptions &rOptions ) const; + BOOL SetOptions( const SvtLinguOptions &rOptions ); + + BOOL IsReadOnly( const rtl::OUString &rPropertyName ) const; + BOOL IsReadOnly( INT32 nPropertyHandle ) const; +}; + + +SvtLinguConfigItem::SvtLinguConfigItem() : + utl::ConfigItem( String::CreateFromAscii( "Office.Linguistic" ) ) +{ + LoadOptions( GetPropertyNames() ); + ClearModified(); + + // request notify events when properties change + EnableNotification( GetPropertyNames() ); +} + + +SvtLinguConfigItem::~SvtLinguConfigItem() +{ + //! Commit (SaveOptions) will be called by the d-tor of the base called ! +} + + +void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames ) +{ + LoadOptions( rPropertyNames ); + NotifyListeners(0); +} + + +void SvtLinguConfigItem::Commit() +{ + SaveOptions( GetPropertyNames() ); +} + + +static struct NamesToHdl +{ + const char *pFullPropName; // full qualified name as used in configuration + const char *pPropName; // property name only (atom) of above + INT32 nHdl; // numeric handle representing the property +}aNamesToHdl[] = +{ +{/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE}, +{/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES}, +{/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST}, +{/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS}, +{/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK}, +{/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL}, + +{/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE}, +{/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS}, +{/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION}, +{/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO}, +{/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL}, +{/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE}, + +{/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING}, +{/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING}, +{/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH}, +{/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL}, +{/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO}, + +{/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES}, +{/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD}, +{/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG}, +{/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST}, +{/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES}, +{/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED}, +{/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS}, +{/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS}, +{/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING}, + +{/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE}, + +{/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO}, +{/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE}, + + /* similar to entry 0 (thus no own configuration entry) but with different property name and type */ +{ NULL, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE}, + +{ NULL, NULL, -1} +}; + + +const uno::Sequence< OUString > & SvtLinguConfigItem::GetPropertyNames() +{ + static uno::Sequence< OUString > aNames; + static sal_Bool bInitialized = sal_False; + + if (!bInitialized) + { + INT32 nMax = sizeof(aNamesToHdl) / sizeof(aNamesToHdl[0]); + + aNames.realloc( nMax ); + OUString *pNames = aNames.getArray(); + INT32 nIdx = 0; + for (INT32 i = 0; i < nMax; ++i) + { + const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName; + if (pFullPropName) + pNames[ nIdx++ ] = A2OU( pFullPropName ); + } + aNames.realloc( nIdx ); + bInitialized = sal_True; + } + return aNames; +} + + +BOOL SvtLinguConfigItem::GetHdlByName( + INT32 &rnHdl, + const OUString &rPropertyName, + sal_Bool bFullPropName ) +{ + NamesToHdl *pEntry = &aNamesToHdl[0]; + + if (bFullPropName) + { + while (pEntry && pEntry->pFullPropName != NULL) + { + if (0 == rPropertyName.compareToAscii( pEntry->pFullPropName )) + { + rnHdl = pEntry->nHdl; + break; + } + ++pEntry; + } + return pEntry && pEntry->pFullPropName != NULL; + } + else + { + while (pEntry && pEntry->pPropName != NULL) + { + if (0 == rPropertyName.compareToAscii( pEntry->pPropName )) + { + rnHdl = pEntry->nHdl; + break; + } + ++pEntry; + } + return pEntry && pEntry->pPropName != NULL; + } +} + + +uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + INT32 nHdl; + return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any(); +} + + +uno::Any SvtLinguConfigItem::GetProperty( INT32 nPropertyHandle ) const +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + uno::Any aRes; + + const INT16 *pnVal = 0; + const BOOL *pbVal = 0; + const INT32 *pnInt32Val = 0; + + const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt; + switch (nPropertyHandle) + { + case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break; + case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break; + case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break; + case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break; + case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break; + case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break; + case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break; + case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break; + case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break; + case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break; + case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break; + case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break; + case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break; + case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break; + case UPH_ACTIVE_DICTIONARIES : + { + aRes <<= rOpt.aActiveDics; + break; + } + case UPH_ACTIVE_CONVERSION_DICTIONARIES : + { + aRes <<= rOpt.aActiveConvDics; + break; + } + case UPH_DEFAULT_LOCALE : + { + lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage, false ) ); + aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 )); + break; + } + case UPH_DEFAULT_LOCALE_CJK : + { + lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CJK, false ) ); + aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 )); + break; + } + case UPH_DEFAULT_LOCALE_CTL : + { + lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CTL, false ) ); + aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 )); + break; + } + case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break; + case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break; + case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break; + case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break; + + case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break; + case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break; + case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break; + case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break; + + case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break; + case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break; + case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break; + default : + DBG_ASSERT( 0, "unexpected property handle" ); + } + + if (pbVal) + aRes <<= *pbVal; + else if (pnVal) + aRes <<= *pnVal; + else if (pnInt32Val) + aRes <<= *pnInt32Val; + + return aRes; +} + + +BOOL SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue ) +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + BOOL bSucc = FALSE; + INT32 nHdl; + if (GetHdlByName( nHdl, rPropertyName )) + bSucc = SetProperty( nHdl, rValue ); + return bSucc; +} + + +BOOL SvtLinguConfigItem::SetProperty( INT32 nPropertyHandle, const uno::Any &rValue ) +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + BOOL bSucc = FALSE; + if (!rValue.hasValue()) + return bSucc; + + BOOL bMod = FALSE; + + INT16 *pnVal = 0; + BOOL *pbVal = 0; + INT32 *pnInt32Val = 0; + + SvtLinguOptions &rOpt = aOpt; + switch (nPropertyHandle) + { + case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break; + case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break; + case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break; + case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break; + case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break; + case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break; + case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break; + case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break; + case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break; + case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break; + case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break; + case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break; + case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break; + case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break; + case UPH_ACTIVE_DICTIONARIES : + { + rValue >>= rOpt.aActiveDics; + bMod = TRUE; + break; + } + case UPH_ACTIVE_CONVERSION_DICTIONARIES : + { + rValue >>= rOpt.aActiveConvDics; + bMod = TRUE; + break; + } + case UPH_DEFAULT_LOCALE : + { + bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue ); + bMod = bSucc; + break; + } + case UPH_DEFAULT_LOCALE_CJK : + { + bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue ); + bMod = bSucc; + break; + } + case UPH_DEFAULT_LOCALE_CTL : + { + bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue ); + bMod = bSucc; + break; + } + case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break; + case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break; + case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break; + case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break; + + case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break; + case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break; + case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break; + case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break; + + case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break; + case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break; + case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break; + default : + DBG_ASSERT( 0, "unexpected property handle" ); + } + + if (pbVal) + { + BOOL bNew = BOOL(); + if (rValue >>= bNew) + { + if (bNew != *pbVal) + { + *pbVal = bNew; + bMod = TRUE; + } + bSucc = TRUE; + } + } + else if (pnVal) + { + INT16 nNew = INT16(); + if (rValue >>= nNew) + { + if (nNew != *pnVal) + { + *pnVal = nNew; + bMod = TRUE; + } + bSucc = TRUE; + } + } + else if (pnInt32Val) + { + INT32 nNew = INT32(); + if (rValue >>= nNew) + { + if (nNew != *pnInt32Val) + { + *pnInt32Val = nNew; + bMod = TRUE; + } + bSucc = TRUE; + } + } + + if (bMod) + SetModified(); + + NotifyListeners(0); + return bSucc; +} + + +BOOL SvtLinguConfigItem::GetOptions( SvtLinguOptions &rOptions ) const +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + rOptions = aOpt; + return TRUE; +} + + +BOOL SvtLinguConfigItem::SetOptions( const SvtLinguOptions &rOptions ) +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + aOpt = rOptions; + SetModified(); + NotifyListeners(0); + return TRUE; +} + + +BOOL SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames ) +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + BOOL bRes = FALSE; + + const OUString *pProperyNames = rProperyNames.getConstArray(); + INT32 nProps = rProperyNames.getLength(); + + const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames ); + const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames ); + + if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps) + { + SvtLinguOptions &rOpt = aOpt; + + const uno::Any *pValue = aValues.getConstArray(); + const sal_Bool *pROStates = aROStates.getConstArray(); + for (INT32 i = 0; i < nProps; ++i) + { + const uno::Any &rVal = pValue[i]; + INT32 nPropertyHandle; + GetHdlByName( nPropertyHandle, pProperyNames[i], sal_True ); + switch ( nPropertyHandle ) + { + case UPH_DEFAULT_LOCALE : + { rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break; + case UPH_ACTIVE_DICTIONARIES : + { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break; + case UPH_IS_USE_DICTIONARY_LIST : + { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break; + case UPH_IS_IGNORE_CONTROL_CHARACTERS : + { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break; + case UPH_DEFAULT_LOCALE_CJK : + { rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal ); } break; + case UPH_DEFAULT_LOCALE_CTL : + { rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal ); } break; + + case UPH_IS_SPELL_UPPER_CASE : + { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break; + case UPH_IS_SPELL_WITH_DIGITS : + { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break; + case UPH_IS_SPELL_CAPITALIZATION : + { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break; + case UPH_IS_SPELL_AUTO : + { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break; + case UPH_IS_SPELL_SPECIAL : + { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break; + case UPH_IS_WRAP_REVERSE : + { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break; + + case UPH_HYPH_MIN_LEADING : + { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break; + case UPH_HYPH_MIN_TRAILING : + { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break; + case UPH_HYPH_MIN_WORD_LENGTH : + { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break; + case UPH_IS_HYPH_SPECIAL : + { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break; + case UPH_IS_HYPH_AUTO : + { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break; + + case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break; + + case UPH_IS_IGNORE_POST_POSITIONAL_WORD : + { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break; + case UPH_IS_AUTO_CLOSE_DIALOG : + { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break; + case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : + { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break; + case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : + { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break; + + case UPH_IS_DIRECTION_TO_SIMPLIFIED : + { rOpt.bROIsDirectionToSimplified = pROStates[i]; + if( ! (rVal >>= rOpt.bIsDirectionToSimplified) ) + { + //default is locale dependent: + if( rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_HONGKONG + || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_MACAU + || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_TRADITIONAL ) + { + rOpt.bIsDirectionToSimplified = FALSE; + } + else + { + rOpt.bIsDirectionToSimplified = TRUE; + } + } + } break; + case UPH_IS_USE_CHARACTER_VARIANTS : + { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break; + case UPH_IS_TRANSLATE_COMMON_TERMS : + { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break; + case UPH_IS_REVERSE_MAPPING : + { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break; + + case UPH_DATA_FILES_CHANGED_CHECK_VALUE : + { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break; + + case UPH_IS_GRAMMAR_AUTO: + { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; } + break; + case UPH_IS_GRAMMAR_INTERACTIVE: + { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; } + break; + + default: + DBG_ASSERT( 0, "unexpected case" ); + } + } + + bRes = TRUE; + } + DBG_ASSERT( bRes, "LoadOptions failed" ); + + return bRes; +} + + +BOOL SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames ) +{ + if (!IsModified()) + return TRUE; + + osl::MutexGuard aGuard( GetOwnMutex() ); + + BOOL bRet = FALSE; + const uno::Type &rBOOL = ::getBooleanCppuType(); + const uno::Type &rINT16 = ::getCppuType( (INT16 *) NULL ); + const uno::Type &rINT32 = ::getCppuType( (INT32 *) NULL ); + + INT32 nProps = rProperyNames.getLength(); + uno::Sequence< uno::Any > aValues( nProps ); + uno::Any *pValue = aValues.getArray(); + + if (nProps && aValues.getLength() == nProps) + { + const SvtLinguOptions &rOpt = aOpt; + + OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) ); + *pValue++ = uno::makeAny( aTmp ); // 0 + *pValue++ = uno::makeAny( rOpt.aActiveDics ); // 1 + pValue++->setValue( &rOpt.bIsUseDictionaryList, rBOOL ); // 2 + pValue++->setValue( &rOpt.bIsIgnoreControlCharacters, rBOOL ); // 3 + aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK ); + *pValue++ = uno::makeAny( aTmp ); // 5 + aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL ); + *pValue++ = uno::makeAny( aTmp ); // 6 + + pValue++->setValue( &rOpt.bIsSpellUpperCase, rBOOL ); // 7 + pValue++->setValue( &rOpt.bIsSpellWithDigits, rBOOL ); // 8 + pValue++->setValue( &rOpt.bIsSpellCapitalization, rBOOL ); // 9 + pValue++->setValue( &rOpt.bIsSpellAuto, rBOOL ); // 10 + pValue++->setValue( &rOpt.bIsSpellSpecial, rBOOL ); // 11 + pValue++->setValue( &rOpt.bIsSpellReverse, rBOOL ); // 14 + + pValue++->setValue( &rOpt.nHyphMinLeading, rINT16 ); // 15 + pValue++->setValue( &rOpt.nHyphMinTrailing, rINT16 ); // 16 + pValue++->setValue( &rOpt.nHyphMinWordLength, rINT16 ); // 17 + pValue++->setValue( &rOpt.bIsHyphSpecial, rBOOL ); // 18 + pValue++->setValue( &rOpt.bIsHyphAuto, rBOOL ); // 19 + + *pValue++ = uno::makeAny( rOpt.aActiveConvDics ); // 20 + + pValue++->setValue( &rOpt.bIsIgnorePostPositionalWord, rBOOL ); // 21 + pValue++->setValue( &rOpt.bIsAutoCloseDialog, rBOOL ); // 22 + pValue++->setValue( &rOpt.bIsShowEntriesRecentlyUsedFirst, rBOOL ); // 23 + pValue++->setValue( &rOpt.bIsAutoReplaceUniqueEntries, rBOOL ); // 24 + + pValue++->setValue( &rOpt.bIsDirectionToSimplified, rBOOL ); // 25 + pValue++->setValue( &rOpt.bIsUseCharacterVariants, rBOOL ); // 26 + pValue++->setValue( &rOpt.bIsTranslateCommonTerms, rBOOL ); // 27 + pValue++->setValue( &rOpt.bIsReverseMapping, rBOOL ); // 28 + + pValue++->setValue( &rOpt.nDataFilesChangedCheckValue, rINT32 ); // 29 + pValue++->setValue( &rOpt.bIsGrammarAuto, rBOOL ); // 30 + pValue++->setValue( &rOpt.bIsGrammarInteractive, rBOOL ); // 31 + + bRet |= PutProperties( rProperyNames, aValues ); + } + + if (bRet) + ClearModified(); + + return bRet; +} + +BOOL SvtLinguConfigItem::IsReadOnly( const rtl::OUString &rPropertyName ) const +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + BOOL bReadOnly = FALSE; + INT32 nHdl; + if (GetHdlByName( nHdl, rPropertyName )) + bReadOnly = IsReadOnly( nHdl ); + return bReadOnly; +} + +BOOL SvtLinguConfigItem::IsReadOnly( INT32 nPropertyHandle ) const +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + BOOL bReadOnly = FALSE; + + const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt; + switch(nPropertyHandle) + { + case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList ; break; + case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break; + case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto ; break; + case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial ; break; + case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto ; break; + case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial ; break; + case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse ; break; + case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage ; break; + case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization ; break; + case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits ; break; + case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase ; break; + case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading ; break; + case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing ; break; + case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength ; break; + case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics ; break; + case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics ; break; + case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage ; break; + case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK ; break; + case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL ; break; + case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break; + case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break; + case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break; + case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break; + case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break; + case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break; + case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break; + case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break; + case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break; + case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break; + case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break; + default : + DBG_ASSERT( 0, "unexpected property handle" ); + } + return bReadOnly; +} + +////////////////////////////////////////////////////////////////////// + +static SvtLinguConfigItem *pCfgItem = 0; +static sal_Int32 nCfgItemRefCount = 0; + +static const rtl::OUString aG_SupportedDictionaryFormats( A2OU("SupportedDictionaryFormats") ); +static const rtl::OUString aG_Dictionaries( A2OU("Dictionaries") ); +static const rtl::OUString aG_Locations( A2OU("Locations") ); +static const rtl::OUString aG_Format( A2OU("Format") ); +static const rtl::OUString aG_Locales( A2OU("Locales") ); +static const rtl::OUString aG_DisabledDictionaries( A2OU("DisabledDictionaries") ); +static const rtl::OUString aG_LastActiveDictionaries( A2OU("LastActiveDictionaries") ); + +SvtLinguConfig::SvtLinguConfig() +{ + // Global access, must be guarded (multithreading) + osl::MutexGuard aGuard( GetOwnMutex() ); + ++nCfgItemRefCount; +} + + +SvtLinguConfig::~SvtLinguConfig() +{ + osl::MutexGuard aGuard( GetOwnMutex() ); + + if (pCfgItem && pCfgItem->IsModified()) + pCfgItem->Commit(); + + if (--nCfgItemRefCount <= 0) + { + if (pCfgItem) + delete pCfgItem; + pCfgItem = 0; + } +} + + +SvtLinguConfigItem & SvtLinguConfig::GetConfigItem() +{ + // Global access, must be guarded (multithreading) + osl::MutexGuard aGuard( GetOwnMutex() ); + if (!pCfgItem) + { + pCfgItem = new SvtLinguConfigItem; + ItemHolder1::holdConfigItem(E_LINGUCFG); + } + return *pCfgItem; +} + + +uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode ) +{ + return GetConfigItem().GetNodeNames( rNode ); +} + + +uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames ) +{ + return GetConfigItem().GetProperties(rNames); +} + + +sal_Bool SvtLinguConfig::ReplaceSetProperties( + const OUString &rNode, uno::Sequence< beans::PropertyValue > rValues ) +{ + return GetConfigItem().ReplaceSetProperties( rNode, rValues ); +} + + +uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const +{ + return GetConfigItem().GetProperty( rPropertyName ); +} + + +uno::Any SvtLinguConfig::GetProperty( INT32 nPropertyHandle ) const +{ + return GetConfigItem().GetProperty( nPropertyHandle ); +} + + +BOOL SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue ) +{ + return GetConfigItem().SetProperty( rPropertyName, rValue ); +} + + +BOOL SvtLinguConfig::SetProperty( INT32 nPropertyHandle, const uno::Any &rValue ) +{ + return GetConfigItem().SetProperty( nPropertyHandle, rValue ); +} + + +BOOL SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const +{ + return GetConfigItem().GetOptions( rOptions ); +} + + +BOOL SvtLinguConfig::SetOptions( const SvtLinguOptions &rOptions ) +{ + return GetConfigItem().SetOptions( rOptions ); +} + + +BOOL SvtLinguConfig::IsReadOnly( const rtl::OUString &rPropertyName ) const +{ + return GetConfigItem().IsReadOnly( rPropertyName ); +} + +BOOL SvtLinguConfig::IsReadOnly( INT32 nPropertyHandle ) const +{ + return GetConfigItem().IsReadOnly( nPropertyHandle ); +} + +BOOL SvtLinguConfig::GetElementNamesFor( + const rtl::OUString &rNodeName, + uno::Sequence< rtl::OUString > &rElementNames ) const +{ + bool bSuccess = false; + try + { + uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW ); + rElementNames = xNA->getElementNames(); + bSuccess = true; + } + catch (uno::Exception &) + { + } + return bSuccess; +} + +static uno::Reference< container::XNameAccess > GetOrCreateSetEntry_Impl( + const uno::Reference< container::XNameAccess > &rxSetNameAccess, + const rtl::OUString &rEntryName ) +{ + uno::Reference< container::XNameAccess > xResult; + try + { + if (!rxSetNameAccess->hasByName( rEntryName )) + { + uno::Reference< lang::XSingleServiceFactory > xFactory( rxSetNameAccess, uno::UNO_QUERY_THROW); + uno::Reference< uno::XInterface > xNewEntry( xFactory->createInstance() ); + uno::Reference< container::XNameContainer > xNC( rxSetNameAccess, uno::UNO_QUERY_THROW ); + xNC->insertByName( rEntryName, makeAny( xNewEntry ) ); + } + xResult.set( rxSetNameAccess->getByName( rEntryName ), uno::UNO_QUERY_THROW ); + } + catch (uno::Exception &) + { + } + return xResult; +} + +BOOL SvtLinguConfig::GetSupportedDictionaryFormatsFor( + const rtl::OUString &rSetName, + const rtl::OUString &rSetEntry, + uno::Sequence< rtl::OUString > &rFormatList ) const +{ + if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0) + return sal_False; + bool bSuccess = false; + try + { + uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW ); + if (xNA->getByName( aG_SupportedDictionaryFormats ) >>= rFormatList) + bSuccess = true; + DBG_ASSERT( rFormatList.getLength(), "supported dictionary format list is empty" ); + } + catch (uno::Exception &) + { + } + return bSuccess; +} + +void SvtLinguConfig::SetOrCreateSupportedDictionaryFormatsFor( + const rtl::OUString &rSetName, + const rtl::OUString &rSetEntry, + const uno::Sequence< rtl::OUString > &rFormatList ) const +{ + if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0) + return; + try + { + DBG_ASSERT( rFormatList.getLength(), "applying empty format list. Really??" ); + + uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() ); + uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW ); + xNA = GetOrCreateSetEntry_Impl( xNA, rSetEntry ); + + uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW ); + xNR->replaceByName( aG_SupportedDictionaryFormats, uno::makeAny( rFormatList ) ); + + xUpdateAccess->commitChanges(); + } + catch (uno::Exception &) + { + } +} + + +static uno::WeakReference< util::XMacroExpander > aG_xMacroExpander; + +static uno::Reference< util::XMacroExpander > lcl_GetMacroExpander() +{ + uno::Reference< util::XMacroExpander > xMacroExpander( aG_xMacroExpander ); + if ( !xMacroExpander.is() ) + { + if ( !xMacroExpander.is() ) + { + uno::Reference< uno::XComponentContext > xContext; + uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY ); + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext; + if ( xContext.is() ) + { + aG_xMacroExpander = uno::Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName( + OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))), + uno::UNO_QUERY ); + xMacroExpander = aG_xMacroExpander; + } + } + } + + return xMacroExpander; +} + + +static bool lcl_GetFileUrlFromOrigin( + OUString /*out*/ &rFileUrl, + const OUString &rOrigin, + uno::Reference< util::XMacroExpander > &rxMacroExpander ) +{ + bool bSuccess = false; + if (rOrigin.getLength() > 0 && rxMacroExpander.is()) + { + rtl::OUString aURL( rOrigin ); + if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) && + rxMacroExpander.is() ) + { + // cut protocol + OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) ); + // decode uric class chars + aMacro = Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); + // expand macro string + aURL = rxMacroExpander->expandMacros( aMacro ); + + bool bIsFileUrl = aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( FILE_PROTOCOL )) == 0; + if (bIsFileUrl) + { + rFileUrl = aURL; + bSuccess = true; + } + else + { + DBG_ASSERT( bIsFileUrl, "not a file URL"); + } + } + else + { + DBG_ASSERT( 0, "failed to get file URL" ); + } + } + return bSuccess; +} + + +BOOL SvtLinguConfig::GetDictionaryEntry( + const rtl::OUString &rNodeName, + SvtLinguConfigDictionaryEntry &rDicEntry ) const +{ + if (rNodeName.getLength() == 0) + return sal_False; + bool bSuccess = false; + try + { + uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW ); + + // read group data... + uno::Sequence< rtl::OUString > aLocations; + rtl::OUString aFormatName; + uno::Sequence< rtl::OUString > aLocaleNames; + bSuccess = (xNA->getByName( aG_Locations ) >>= aLocations) && + (xNA->getByName( aG_Format ) >>= aFormatName) && + (xNA->getByName( aG_Locales ) >>= aLocaleNames); + DBG_ASSERT( aLocations.getLength(), "Dictionary locations not set" ); + DBG_ASSERT( aFormatName.getLength(), "Dictionary format name not set" ); + DBG_ASSERT( aLocaleNames.getLength(), "No locales set for the dictionary" ); + + // if sucessful continue + if (bSuccess) + { + // get file URL's for the locations + uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() ); + for (sal_Int32 i = 0; i < aLocations.getLength(); ++i) + { + rtl::OUString &rLocation = aLocations[i]; + if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation, xMacroExpander )) + bSuccess = false; + } + + // if everything was fine return the result + if (bSuccess) + { + rDicEntry.aLocations = aLocations; + rDicEntry.aFormatName = aFormatName; + rDicEntry.aLocaleNames = aLocaleNames; + } + } + } + catch (uno::Exception &) + { + } + return bSuccess; +} + +void SvtLinguConfig::SetOrCreateDictionaryEntry( + const rtl::OUString &rNodeName, + const SvtLinguConfigDictionaryEntry &rDicEntry ) const +{ + if (rNodeName.getLength() == 0) + return; + try + { + uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() ); + uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW ); + xNA = GetOrCreateSetEntry_Impl( xNA, rNodeName ); + + DBG_ASSERT( rDicEntry.aLocations.getLength(), "Applying empty dictionary locations. Really correct??" ); + DBG_ASSERT( rDicEntry.aFormatName.getLength(), "Applying empty dictionary format name. Really correct??" ); + DBG_ASSERT( rDicEntry.aLocaleNames.getLength(), "Applying empty list of locales for the dictionary. Really correct??" ); + + uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW ); + xNR->replaceByName( aG_Locations, uno::makeAny( rDicEntry.aLocations ) ); + xNR->replaceByName( aG_Format, uno::makeAny( rDicEntry.aFormatName ) ); + xNR->replaceByName( aG_Locales, uno::makeAny( rDicEntry.aLocaleNames ) ); + + xUpdateAccess->commitChanges(); + } + catch (uno::Exception &) + { + } +} + +uno::Sequence< rtl::OUString > SvtLinguConfig::GetDisabledDictionaries() const +{ + uno::Sequence< rtl::OUString > aResult; + try + { + uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + xNA->getByName( aG_DisabledDictionaries ) >>= aResult; + } + catch (uno::Exception &) + { + } + return aResult; +} + +void SvtLinguConfig::SetDisabledDictionaries( + const uno::Sequence< rtl::OUString > &rDictionaries ) const +{ + try + { + uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() ); + uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + if (xNA->hasByName( aG_DisabledDictionaries )) + { + uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW ); + xNR->replaceByName( aG_DisabledDictionaries, makeAny( rDictionaries ) ); + } + else + { + uno::Reference< container::XNameContainer > xNC( xNA, uno::UNO_QUERY_THROW ); + xNC->insertByName( aG_DisabledDictionaries, makeAny( rDictionaries ) ); + } + + xUpdateAccess->commitChanges(); + } + catch (uno::Exception &) + { + } +} + +std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat( + const rtl::OUString &rFormatName ) +{ + std::vector< SvtLinguConfigDictionaryEntry > aRes; + if (rFormatName.getLength() == 0) + return aRes; + + try + { + uno::Sequence< rtl::OUString > aElementNames; + GetElementNamesFor( aG_Dictionaries, aElementNames ); + sal_Int32 nLen = aElementNames.getLength(); + const rtl::OUString *pElementNames = aElementNames.getConstArray(); + + SvtLinguConfigDictionaryEntry aDicEntry; + for (sal_Int32 i = 0; i < nLen; ++i) + { + // does dictionary match the format we are looking for? + if (GetDictionaryEntry( pElementNames[i], aDicEntry ) && + aDicEntry.aFormatName == rFormatName) + { + // check if it is active or not + bool bDicIsActive = true; + const uno::Sequence< rtl::OUString > aDisabledDics( GetDisabledDictionaries() ); + for (sal_Int32 k = 0; bDicIsActive && k < aDisabledDics.getLength(); ++k) + { + if (aDisabledDics[k] == pElementNames[i]) + bDicIsActive = false; + } + + if (bDicIsActive) + { + DBG_ASSERT( aDicEntry.aFormatName.getLength(), + "FormatName not set" ); + DBG_ASSERT( aDicEntry.aLocations.getLength(), + "Locations not set" ); + DBG_ASSERT( aDicEntry.aLocaleNames.getLength(), + "Locales not set" ); + aRes.push_back( aDicEntry ); + } + } + } + } + catch (uno::Exception &) + { + } + + return aRes; +} + + +uno::Reference< util::XChangesBatch > SvtLinguConfig::GetMainUpdateAccess() const +{ + if (!m_xMainUpdateAccess.is()) + { + try + { + // get configuration provider + uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider; + uno::Reference< lang::XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory(); + if (xMgr.is()) + { + xConfigurationProvider = uno::Reference< lang::XMultiServiceFactory > ( + xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationProvider" ) ) ), + uno::UNO_QUERY_THROW ) ; + } + + // get configuration update access + beans::PropertyValue aValue; + aValue.Name = A2OU( "nodepath" ); + aValue.Value = uno::makeAny( A2OU("org.openoffice.Office.Linguistic") ); + uno::Sequence< uno::Any > aProps(1); + aProps[0] <<= aValue; + m_xMainUpdateAccess = uno::Reference< util::XChangesBatch >( + xConfigurationProvider->createInstanceWithArguments( + A2OU( "com.sun.star.configuration.ConfigurationUpdateAccess" ), aProps ), + uno::UNO_QUERY_THROW ); + } + catch (uno::Exception &) + { + } + } + + return m_xMainUpdateAccess; +} + + +rtl::OUString SvtLinguConfig::GetVendorImageUrl_Impl( + const rtl::OUString &rServiceImplName, + const rtl::OUString &rImageName ) const +{ + rtl::OUString aRes; + try + { + uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); + xImagesNA.set( xImagesNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW ); + + uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName( A2OU("ServiceNameEntries") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW ); + uno::Any aAny( xNA->getByName( A2OU("VendorImagesNode") ) ); + rtl::OUString aVendorImagesNode; + if (aAny >>= aVendorImagesNode) + { + xNA = xImagesNA; + xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW ); + aAny = xNA->getByName( rImageName ); + rtl::OUString aTmp; + if (aAny >>= aTmp) + { + uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() ); + if (lcl_GetFileUrlFromOrigin( aTmp, aTmp, xMacroExpander )) + aRes = aTmp; + } + } + } + catch (uno::Exception &) + { + DBG_ASSERT( 0, "exception caught. GetVendorImageUrl_Impl failed" ); + } + return aRes; +} + + +rtl::OUString SvtLinguConfig::GetSpellAndGrammarDialogImage( + const rtl::OUString &rServiceImplName, + bool bHighContrast ) const +{ + rtl::OUString aRes; + if (rServiceImplName.getLength() > 0) + { + rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarDialogImage_HC" : "SpellAndGrammarDialogImage" )); + rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); + aRes = aPath; + } + return aRes; +} + + +rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage( + const rtl::OUString &rServiceImplName, + bool bHighContrast ) const +{ + rtl::OUString aRes; + if (rServiceImplName.getLength() > 0) + { + rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuSuggestionImage_HC" : "SpellAndGrammarContextMenuSuggestionImage" )); + rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); + aRes = aPath; + } + return aRes; +} + + +rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage( + const rtl::OUString &rServiceImplName, + bool bHighContrast ) const +{ + rtl::OUString aRes; + if (rServiceImplName.getLength() > 0) + { + rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuDictionaryImage_HC" : "SpellAndGrammarContextMenuDictionaryImage" )); + rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); + aRes = aPath; + } + return aRes; +} + + +::rtl::OUString SvtLinguConfig::GetThesaurusDialogImage( + const ::rtl::OUString &rServiceImplName, + bool bHighContrast ) const +{ + rtl::OUString aRes; + if (rServiceImplName.getLength() > 0) + { + rtl::OUString aImageName( A2OU( bHighContrast ? "ThesaurusDialogImage_HC" : "ThesaurusDialogImage" )); + rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); + aRes = aPath; + } + return aRes; +} + + +::rtl::OUString SvtLinguConfig::GetSynonymsContextImage( + const ::rtl::OUString &rServiceImplName, + bool bHighContrast ) const +{ + rtl::OUString aRes; + if (rServiceImplName.getLength() > 0) + { + rtl::OUString aImageName( A2OU( bHighContrast ? "SynonymsContextMenuImage_HC" : "SynonymsContextMenuImage" )); + rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); + aRes = aPath; + } + return aRes; +} + + +bool SvtLinguConfig::HasVendorImages( const char *pImageName ) const +{ + bool bRes = false; + if (pImageName) + { + try + { + uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW ); + + uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() ); + sal_Int32 nVendors = aElementNames.getLength(); + const rtl::OUString *pVendor = aElementNames.getConstArray(); + for (sal_Int32 i = 0; i < nVendors; ++i) + { + uno::Reference< container::XNameAccess > xNA2( xNA->getByName( pVendor[i] ), uno::UNO_QUERY_THROW ); + uno::Sequence< rtl::OUString > aPropNames( xNA2->getElementNames() ); + sal_Int32 nProps = aPropNames.getLength(); + const rtl::OUString *pPropNames = aPropNames.getConstArray(); + for (sal_Int32 k = 0; k < nProps; ++k) + { + // for a quicker check we ignore the HC image names here + const OUString &rName = pPropNames[k]; + if (rName.equalsAscii( pImageName )) + { + bRes = true; + break; + } + } + } + } + catch (uno::Exception &) + { + DBG_ASSERT( 0, "exception caught. HasVendorImages failed" ); + } + } + return bRes; +} + + +bool SvtLinguConfig::HasGrammarChecker() const +{ + bool bRes = false; + + try + { + uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); + xNA.set( xNA->getByName( A2OU("GrammarCheckerList") ), uno::UNO_QUERY_THROW ); + + uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() ); + bRes = aElementNames.getLength() > 0; + } + catch (uno::Exception &) + { + } + + return bRes; +} + +////////////////////////////////////////////////////////////////////// + diff --git a/unotools/source/config/localisationoptions.cxx b/unotools/source/config/localisationoptions.cxx new file mode 100644 index 000000000000..f4b8bbd087ef --- /dev/null +++ b/unotools/source/config/localisationoptions.cxx @@ -0,0 +1,458 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/localisationoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_LOCALISATION OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/View/Localisation")) +#define DEFAULT_AUTOMNEMONIC sal_False +#define DEFAULT_DIALOGSCALE 0 + +#define PROPERTYNAME_AUTOMNEMONIC OUString(RTL_CONSTASCII_USTRINGPARAM("AutoMnemonic" )) +#define PROPERTYNAME_DIALOGSCALE OUString(RTL_CONSTASCII_USTRINGPARAM("DialogScale" )) + +#define PROPERTYHANDLE_AUTOMNEMONIC 0 +#define PROPERTYHANDLE_DIALOGSCALE 1 + +#define PROPERTYCOUNT 2 + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +class SvtLocalisationOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtLocalisationOptions_Impl(); + ~SvtLocalisationOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& seqPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short access method to get internal values + @descr These method give us a chance to regulate acces to ouer internal values. + It's not used in the moment - but it's possible for the feature! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + sal_Bool IsAutoMnemonic ( ) const ; + void SetAutoMnemonic ( sal_Bool bState ) ; + sal_Int32 GetDialogScale ( ) const ; + void SetDialogScale ( sal_Int32 nScale ) ; + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of key names of ouer configuration management which represent oue module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. + + @seealso - + + @param - + @return A list of needed configuration keys is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + static Sequence< OUString > GetPropertyNames(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + + sal_Bool m_bAutoMnemonic ; + sal_Int32 m_nDialogScale ; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl() + // Init baseclasses first + : ConfigItem ( ROOTNODE_LOCALISATION ) + // Init member then. + , m_bAutoMnemonic ( DEFAULT_AUTOMNEMONIC ) + , m_nDialogScale ( DEFAULT_DIALOGSCALE ) +{ + // Use our static list of configuration keys to get his values. + Sequence< OUString > seqNames = GetPropertyNames ( ); + Sequence< Any > seqValues = GetProperties ( seqNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + // Safe impossible cases. + // Check any for valid value. + DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nInvalid property value detected!\n" ); + switch( nProperty ) + { + case PROPERTYHANDLE_AUTOMNEMONIC : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\AutoMnemonic\"?" ); + seqValues[nProperty] >>= m_bAutoMnemonic; + } + break; + + case PROPERTYHANDLE_DIALOGSCALE : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\DialogScale\"?" ); + seqValues[nProperty] >>= m_nDialogScale; + } + break; + } + } + + // Enable notification mechanism of ouer baseclass. + // We need it to get information about changes outside these class on ouer used configuration keys! + EnableNotification( seqNames ); +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtLocalisationOptions_Impl::~SvtLocalisationOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtLocalisationOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames ) +{ + // Use given list of updated properties to get his values from configuration directly! + Sequence< Any > seqValues = GetProperties( seqPropertyNames ); + // Safe impossible cases. + // We need values from ALL notified configuration keys. + DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtLocalisationOptions_Impl::Notify()\nI miss some values of configuration keys!\n" ); + // Step over list of property names and get right value from coreesponding value list to set it on internal members! + sal_Int32 nCount = seqPropertyNames.getLength(); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + if( seqPropertyNames[nProperty] == PROPERTYNAME_AUTOMNEMONIC ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\AutoMnemonic\"?" ); + seqValues[nProperty] >>= m_bAutoMnemonic; + } + else + if( seqPropertyNames[nProperty] == PROPERTYNAME_DIALOGSCALE ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\DialogScale\"?" ); + seqValues[nProperty] >>= m_nDialogScale; + } + #if OSL_DEBUG_LEVEL > 1 + else DBG_ASSERT( sal_False, "SvtLocalisationOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" ); + #endif + } + + NotifyListeners(0); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtLocalisationOptions_Impl::Commit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + Sequence< OUString > seqNames = GetPropertyNames (); + sal_Int32 nCount = seqNames.getLength(); + Sequence< Any > seqValues ( nCount ); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_AUTOMNEMONIC : { + seqValues[nProperty] <<= m_bAutoMnemonic; + } + break; + + case PROPERTYHANDLE_DIALOGSCALE : { + seqValues[nProperty] <<= m_nDialogScale; + } + break; + } + } + // Set properties in configuration. + PutProperties( seqNames, seqValues ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtLocalisationOptions_Impl::IsAutoMnemonic() const +{ + return m_bAutoMnemonic; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtLocalisationOptions_Impl::SetAutoMnemonic( sal_Bool bState ) +{ + m_bAutoMnemonic = bState; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtLocalisationOptions_Impl::GetDialogScale() const +{ + return m_nDialogScale; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtLocalisationOptions_Impl::SetDialogScale( sal_Int32 nScale ) +{ + m_nDialogScale = nScale; + SetModified(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtLocalisationOptions_Impl::GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_AUTOMNEMONIC , + PROPERTYNAME_DIALOGSCALE , + }; + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtLocalisationOptions_Impl* SvtLocalisationOptions::m_pDataContainer = NULL ; +sal_Int32 SvtLocalisationOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtLocalisationOptions::SvtLocalisationOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtLocalisationOptions_Impl::ctor()"); + m_pDataContainer = new SvtLocalisationOptions_Impl; + + ItemHolder1::holdConfigItem(E_LOCALISATIONOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtLocalisationOptions::~SvtLocalisationOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtLocalisationOptions::IsAutoMnemonic() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsAutoMnemonic(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtLocalisationOptions::SetAutoMnemonic( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetAutoMnemonic( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtLocalisationOptions::GetDialogScale() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetDialogScale(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtLocalisationOptions::SetDialogScale( sal_Int32 nScale ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetDialogScale( nScale ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtLocalisationOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/makefile.mk b/unotools/source/config/makefile.mk new file mode 100644 index 000000000000..27e8f67f8888 --- /dev/null +++ b/unotools/source/config/makefile.mk @@ -0,0 +1,91 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=config + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + + +# --- Files ------------------------------------- + +SLOFILES=\ + $(SLO)$/syslocaleoptions.obj \ + $(SLO)$/configvaluecontainer.obj \ + $(SLO)$/confignode.obj \ + $(SLO)$/configitem.obj \ + $(SLO)$/configmgr.obj \ + $(SLO)$/configpathes.obj \ + $(SLO)$/docinfohelper.obj \ + $(SLO)$/bootstrap.obj \ + $(SLO)$/accelcfg.obj \ + $(SLO)$/cacheoptions.obj \ + $(SLO)$/cmdoptions.obj \ + $(SLO)$/compatibility.obj \ + $(SLO)$/defaultoptions.obj \ + $(SLO)$/dynamicmenuoptions.obj \ + $(SLO)$/eventcfg.obj \ + $(SLO)$/extendedsecurityoptions.obj \ + $(SLO)$/fltrcfg.obj \ + $(SLO)$/fontcfg.obj \ + $(SLO)$/fontoptions.obj \ + $(SLO)$/historyoptions.obj \ + $(SLO)$/inetoptions.obj \ + $(SLO)$/internaloptions.obj \ + $(SLO)$/itemholder1.obj \ + $(SLO)$/javaoptions.obj \ + $(SLO)$/lingucfg.obj \ + $(SLO)$/localisationoptions.obj \ + $(SLO)$/misccfg.obj \ + $(SLO)$/moduleoptions.obj \ + $(SLO)$/options.obj \ + $(SLO)$/optionsdlg.obj \ + $(SLO)$/pathoptions.obj \ + $(SLO)$/printwarningoptions.obj \ + $(SLO)$/regoptions.obj \ + $(SLO)$/saveopt.obj \ + $(SLO)$/searchopt.obj \ + $(SLO)$/securityoptions.obj \ + $(SLO)$/sourceviewconfig.obj \ + $(SLO)$/startoptions.obj \ + $(SLO)$/undoopt.obj \ + $(SLO)$/useroptions.obj \ + $(SLO)$/viewoptions.obj \ + $(SLO)$/workingsetoptions.obj \ + $(SLO)$/xmlaccelcfg.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/config/misccfg.cxx b/unotools/source/config/misccfg.cxx new file mode 100644 index 000000000000..e2cc8686d444 --- /dev/null +++ b/unotools/source/config/misccfg.cxx @@ -0,0 +1,310 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/misccfg.hxx> +#include "rtl/instance.hxx" +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <vos/mutex.hxx> +#include <osl/mutex.hxx> +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +#define DEFAULT_TAB 2000 + +#define DEF_INCH 2540L +#define DEF_RELTWIP 1440L + +using namespace rtl; +using namespace com::sun::star::uno; + +#define C2U(cChar) OUString::createFromAscii(cChar) + +namespace utl +{ + +static SfxMiscCfg* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +class SfxMiscCfg : public utl::ConfigItem +{ + BOOL bPaperSize; // printer warnings + BOOL bPaperOrientation; + BOOL bNotFound; + sal_Int32 nYear2000; // two digit year representation + + const com::sun::star::uno::Sequence<rtl::OUString>& GetPropertyNames(); + void Load(); + +public: + SfxMiscCfg( ); + ~SfxMiscCfg( ); + + virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames); + virtual void Commit(); + + BOOL IsNotFoundWarning() const {return bNotFound;} + void SetNotFoundWarning( BOOL bSet); + + BOOL IsPaperSizeWarning() const {return bPaperSize;} + void SetPaperSizeWarning(BOOL bSet); + + BOOL IsPaperOrientationWarning() const {return bPaperOrientation;} + void SetPaperOrientationWarning( BOOL bSet); + + // 0 ... 99 + sal_Int32 GetYear2000() const { return nYear2000; } + void SetYear2000( sal_Int32 nSet ); + +}; + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ +SfxMiscCfg::SfxMiscCfg() : + ConfigItem(C2U("Office.Common") ), + bPaperSize(FALSE), + bPaperOrientation (FALSE), + bNotFound (FALSE), + nYear2000( 1930 ) +{ + RTL_LOGFILE_CONTEXT(aLog, "svl SfxMiscCfg::SfxMiscCfg()"); + + Load(); +} +/* -----------------------------02.03.01 15:31-------------------------------- + + ---------------------------------------------------------------------------*/ +SfxMiscCfg::~SfxMiscCfg() +{ +} +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SfxMiscCfg::SetNotFoundWarning( BOOL bSet) +{ + if(bNotFound != bSet) + SetModified(); + bNotFound = bSet; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SfxMiscCfg::SetPaperSizeWarning( BOOL bSet) +{ + if(bPaperSize != bSet) + SetModified(); + bPaperSize = bSet; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ +void SfxMiscCfg::SetPaperOrientationWarning( BOOL bSet) +{ + if(bPaperOrientation != bSet) + SetModified(); + bPaperOrientation = bSet; +} +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SfxMiscCfg::SetYear2000( sal_Int32 nSet ) +{ + if(nYear2000 != nSet) + SetModified(); + nYear2000 = nSet; +} +/* -----------------------------02.03.01 15:31-------------------------------- + + ---------------------------------------------------------------------------*/ +const Sequence<OUString>& SfxMiscCfg::GetPropertyNames() +{ + static Sequence<OUString> aNames; + if(!aNames.getLength()) + { + static const char* aPropNames[] = + { + "Print/Warning/PaperSize", // 0 + "Print/Warning/PaperOrientation", // 1 + "Print/Warning/NotFound", // 2 + "DateFormat/TwoDigitYear", // 3 + }; + const int nCount = 4; + aNames.realloc(nCount); + OUString* pNames = aNames.getArray(); + for(int i = 0; i < nCount; i++) + pNames[i] = OUString::createFromAscii(aPropNames[i]); + } + return aNames; +} +/* -----------------------------02.03.01 15:31-------------------------------- + + ---------------------------------------------------------------------------*/ +void SfxMiscCfg::Load() +{ + const Sequence<OUString>& aNames = GetPropertyNames(); + Sequence<Any> aValues = GetProperties(aNames); + EnableNotification(aNames); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); + if(aValues.getLength() == aNames.getLength()) + { + for(int nProp = 0; nProp < aNames.getLength(); nProp++) + { + if(pValues[nProp].hasValue()) + { + switch(nProp) + { + case 0: bPaperSize = *(sal_Bool*)pValues[nProp].getValue(); break; //"Print/Warning/PaperSize", + case 1: bPaperOrientation = *(sal_Bool*)pValues[nProp].getValue(); break; //"Print/Warning/PaperOrientation", + case 2: bNotFound = *(sal_Bool*)pValues[nProp].getValue() ; break; //"Print/Warning/NotFound", + case 3: pValues[nProp] >>= nYear2000;break; //"DateFormat/TwoDigitYear", + } + } + } + } +} +/* -----------------------------02.03.01 15:31-------------------------------- + + ---------------------------------------------------------------------------*/ +void SfxMiscCfg::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& ) +{ + Load(); +} +/* -----------------------------02.03.01 15:31-------------------------------- + + ---------------------------------------------------------------------------*/ +void SfxMiscCfg::Commit() +{ + const Sequence<OUString>& aNames = GetPropertyNames(); + Sequence<Any> aValues(aNames.getLength()); + Any* pValues = aValues.getArray(); + + const Type& rType = ::getBooleanCppuType(); + for(int nProp = 0; nProp < aNames.getLength(); nProp++) + { + switch(nProp) + { + case 0: pValues[nProp].setValue(&bPaperSize, rType);break; //"Print/Warning/PaperSize", + case 1: pValues[nProp].setValue(&bPaperOrientation, rType);break; //"Print/Warning/PaperOrientation", + case 2: pValues[nProp].setValue(&bNotFound, rType);break; //"Print/Warning/NotFound", + case 3: pValues[nProp] <<= nYear2000;break; //"DateFormat/TwoDigitYear", + } + } + PutProperties(aNames, aValues); +} +// ----------------------------------------------------------------------- +namespace +{ + class LocalSingleton : public rtl::Static< osl::Mutex, LocalSingleton > + { + }; +} + +MiscCfg::MiscCfg( ) +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + if ( !pOptions ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) SfxMiscCfg::ctor()"); + pOptions = new SfxMiscCfg; + + ItemHolder1::holdConfigItem(E_MISCCFG); + } + + ++nRefCount; + pImpl = pOptions; + pImpl->AddListener(this); +} + +MiscCfg::~MiscCfg( ) +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + pImpl->RemoveListener(this); + if ( !--nRefCount ) + { + if ( pOptions->IsModified() ) + pOptions->Commit(); + DELETEZ( pOptions ); + } +} + +BOOL MiscCfg::IsNotFoundWarning() const +{ + return pImpl->IsNotFoundWarning(); +} + +void MiscCfg::SetNotFoundWarning( BOOL bSet) +{ + pImpl->SetNotFoundWarning( bSet ); +} + +BOOL MiscCfg::IsPaperSizeWarning() const +{ + return pImpl->IsPaperSizeWarning(); +} + +void MiscCfg::SetPaperSizeWarning(BOOL bSet) +{ + pImpl->SetPaperSizeWarning( bSet ); +} + +BOOL MiscCfg::IsPaperOrientationWarning() const +{ + return pImpl->IsPaperOrientationWarning(); +} + +void MiscCfg::SetPaperOrientationWarning( BOOL bSet) +{ + pImpl->SetPaperOrientationWarning( bSet ); +} + +sal_Int32 MiscCfg::GetYear2000() const +{ + return pImpl->GetYear2000(); +} + +void MiscCfg::SetYear2000( sal_Int32 nSet ) +{ + pImpl->SetYear2000( nSet ); +} + +} + diff --git a/unotools/source/config/moduleoptions.cxx b/unotools/source/config/moduleoptions.cxx new file mode 100644 index 000000000000..afce713ccc49 --- /dev/null +++ b/unotools/source/config/moduleoptions.cxx @@ -0,0 +1,1597 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/moduleoptions.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <unotools/processfactory.hxx> +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> + +#include <rtl/logfile.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <com/sun/star/util/XStringSubstitution.hpp> + +#include "itemholder1.hxx" + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +#ifndef css +namespace css = ::com::sun::star; +#endif + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr These values are used to define neccessary keys from our configuration management to support + all functionality of these implementation. + It's a fast way to make changes if some keys change his name or location! + + Property handle are neccessary to specify right position in return list of configuration + for asked values. We ask it with a list of properties to get his values. The returned list + has the same order like our given name list! + e.g.: + NAMELIST[ PROPERTYHANDLE_xxx ] => VALUELIST[ PROPERTYHANDLE_xxx ] +*//*-*************************************************************************************************************/ +#define ROOTNODE_FACTORIES ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Setup/Office/Factories" )) +#define PATHSEPERATOR ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/" )) + +// Attention: The property "ooSetupFactoryEmptyDocumentURL" is read from configuration but not used! There is +// special code that uses hard coded strings to return them. +#define PROPERTYNAME_SHORTNAME ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryShortName" )) +#define PROPERTYNAME_TEMPLATEFILE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryTemplateFile" )) +#define PROPERTYNAME_WINDOWATTRIBUTES ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryWindowAttributes")) +#define PROPERTYNAME_EMPTYDOCUMENTURL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryEmptyDocumentURL")) +#define PROPERTYNAME_DEFAULTFILTER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryDefaultFilter" )) +#define PROPERTYNAME_ICON ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryIcon" )) + +#define PROPERTYHANDLE_SHORTNAME 0 +#define PROPERTYHANDLE_TEMPLATEFILE 1 +#define PROPERTYHANDLE_WINDOWATTRIBUTES 2 +#define PROPERTYHANDLE_EMPTYDOCUMENTURL 3 +#define PROPERTYHANDLE_DEFAULTFILTER 4 +#define PROPERTYHANDLE_ICON 5 + +#define PROPERTYCOUNT 6 + +#define FACTORYNAME_WRITER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextDocument" )) +#define FACTORYNAME_WRITERWEB ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.WebDocument" )) +#define FACTORYNAME_WRITERGLOBAL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.GlobalDocument" )) +#define FACTORYNAME_CALC ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument" )) +#define FACTORYNAME_DRAW ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocument" )) +#define FACTORYNAME_IMPRESS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument")) +#define FACTORYNAME_MATH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.formula.FormulaProperties" )) +#define FACTORYNAME_CHART ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.ChartDocument" )) +#define FACTORYNAME_DATABASE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.OfficeDatabaseDocument" )) +#define FACTORYNAME_STARTMODULE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule" )) + +#define FACTORYCOUNT 10 + +/*-************************************************************************************************************//** + @descr This struct hold information about one factory. We declare a complete array which can hold infos + for all well known factories. Values of enum "EFactory" (see header!) are directly used as index! + So we can support a fast access on these informations. +*//*-*************************************************************************************************************/ +struct FactoryInfo +{ + public: + //--------------------------------------------------------------------------------------------------------- + // initialize empty struct + FactoryInfo() + { + free(); + // @@@ should be supplied from outside! + xSMgr = ::utl::getProcessServiceFactory(); + } + + //--------------------------------------------------------------------------------------------------------- + // easy way to reset struct member! + void free() + { + bInstalled = sal_False ; + sFactory = ::rtl::OUString() ; + sShortName = ::rtl::OUString() ; + sTemplateFile = ::rtl::OUString() ; + sWindowAttributes = ::rtl::OUString() ; + sEmptyDocumentURL = ::rtl::OUString() ; + sDefaultFilter = ::rtl::OUString() ; + nIcon = 0 ; + bChangedTemplateFile = sal_False ; + bChangedWindowAttributes = sal_False ; + bChangedEmptyDocumentURL = sal_False ; + bChangedDefaultFilter = sal_False ; + bChangedIcon = sal_False ; + bDefaultFilterReadonly = sal_False ; + } + + //--------------------------------------------------------------------------------------------------------- + // returns list of properties, which has changed only! + // We use given value of sNodeBase to build full qualified pathes ... + // Last sign of it must be "/". Beacuse we use it directly, without any additional things! + css::uno::Sequence< css::beans::PropertyValue > getChangedProperties( const ::rtl::OUString& sNodeBase ) + { + // a) reserve memory for max. count of changed properties + // b) add names and values of changed ones only and count it + // c) resize return list by using count + css::uno::Sequence< css::beans::PropertyValue > lProperties ( 4 ); + sal_Int8 nRealyChanged = 0 ; + + if( bChangedTemplateFile == sal_True ) + { + lProperties[nRealyChanged].Name = sNodeBase + PROPERTYNAME_TEMPLATEFILE; + + if ( sTemplateFile.getLength() > 0 ) + { + lProperties[nRealyChanged].Value + <<= getStringSubstitution() + ->reSubstituteVariables( sTemplateFile ); + } + else + { + lProperties[nRealyChanged].Value <<= sTemplateFile; + } + + ++nRealyChanged; + } + if( bChangedWindowAttributes == sal_True ) + { + lProperties[nRealyChanged].Name = sNodeBase + PROPERTYNAME_WINDOWATTRIBUTES; + lProperties[nRealyChanged].Value <<= sWindowAttributes; + ++nRealyChanged; + } + if( bChangedEmptyDocumentURL == sal_True ) + { + lProperties[nRealyChanged].Name = sNodeBase + PROPERTYNAME_EMPTYDOCUMENTURL; + lProperties[nRealyChanged].Value <<= sEmptyDocumentURL; + ++nRealyChanged; + } + if( bChangedDefaultFilter == sal_True ) + { + lProperties[nRealyChanged].Name = sNodeBase + PROPERTYNAME_DEFAULTFILTER; + lProperties[nRealyChanged].Value <<= sDefaultFilter; + ++nRealyChanged; + } + if( bChangedIcon == sal_True ) + { + lProperties[nRealyChanged].Name = sNodeBase + PROPERTYNAME_ICON; + lProperties[nRealyChanged].Value <<= nIcon; + ++nRealyChanged; + } + + // Don't forget to reset changed flags! Otherwise we save it again and again and ... + bChangedTemplateFile = sal_False ; + bChangedWindowAttributes = sal_False ; + bChangedEmptyDocumentURL = sal_False ; + bChangedDefaultFilter = sal_False ; + bChangedIcon = sal_False ; + + lProperties.realloc( nRealyChanged ); + return lProperties; + } + + //--------------------------------------------------------------------------------------------------------- + // We must support setting AND marking of changed values. + // That's why we can't make our member public. We must use get/set/init methods + // to control access on it! + sal_Bool getInstalled () const { return bInstalled; }; + ::rtl::OUString getFactory () const { return sFactory; }; + ::rtl::OUString getShortName () const { return sShortName; }; + ::rtl::OUString getTemplateFile () const { return sTemplateFile; }; + ::rtl::OUString getWindowAttributes () const { return sWindowAttributes; }; + ::rtl::OUString getEmptyDocumentURL () const { return sEmptyDocumentURL; }; + ::rtl::OUString getDefaultFilter () const { return sDefaultFilter; }; + sal_Bool isDefaultFilterReadonly() const { return bDefaultFilterReadonly; } + sal_Int32 getIcon () const { return nIcon; }; + + //--------------------------------------------------------------------------------------------------------- + // If you call set-methods - we check for changes of valkues and mark it. + // But if you whish to set it without that ... you must initialize it! + void initInstalled ( sal_Bool bNewInstalled ) { bInstalled = bNewInstalled ; } + void initFactory ( const ::rtl::OUString& sNewFactory ) { sFactory = sNewFactory ; } + void initShortName ( const ::rtl::OUString& sNewShortName ) { sShortName = sNewShortName ; } + void initWindowAttributes ( const ::rtl::OUString& sNewWindowAttributes ) { sWindowAttributes = sNewWindowAttributes ; } + void initEmptyDocumentURL ( const ::rtl::OUString& sNewEmptyDocumentURL ) { sEmptyDocumentURL = sNewEmptyDocumentURL ; } + void initDefaultFilter ( const ::rtl::OUString& sNewDefaultFilter ) { sDefaultFilter = sNewDefaultFilter ; } + void setDefaultFilterReadonly( const sal_Bool bVal){bDefaultFilterReadonly = bVal;} + void initIcon ( sal_Int32 nNewIcon ) { nIcon = nNewIcon ; } + + //--------------------------------------------------------------------------------------------------------- + void initTemplateFile( const ::rtl::OUString& sNewTemplateFile ) + { + if ( sNewTemplateFile.getLength() > 0 ) + { + sTemplateFile + = getStringSubstitution() + ->substituteVariables( sNewTemplateFile, sal_False ); + } + else + { + sTemplateFile = sNewTemplateFile; + } + } + + //--------------------------------------------------------------------------------------------------------- + void setInstalled( sal_Bool bNewInstalled ) + { + bInstalled = bNewInstalled; + }; + + //--------------------------------------------------------------------------------------------------------- + void setFactory( const ::rtl::OUString& sNewFactory ) + { + sFactory = sNewFactory; + }; + + //--------------------------------------------------------------------------------------------------------- + void setShortName( const ::rtl::OUString& sNewShortName ) + { + sShortName = sNewShortName; + }; + + //--------------------------------------------------------------------------------------------------------- + void setTemplateFile( const ::rtl::OUString& sNewTemplateFile ) + { + if( sTemplateFile != sNewTemplateFile ) + { + sTemplateFile = sNewTemplateFile; + bChangedTemplateFile = sal_True ; + } + }; + + //--------------------------------------------------------------------------------------------------------- + void setWindowAttributes( const ::rtl::OUString& sNewWindowAttributes ) + { + if( sWindowAttributes != sNewWindowAttributes ) + { + sWindowAttributes = sNewWindowAttributes; + bChangedWindowAttributes = sal_True ; + } + }; + + //--------------------------------------------------------------------------------------------------------- + void setEmptyDocumentURL( const ::rtl::OUString& sNewEmptyDocumentURL ) + { + if( sEmptyDocumentURL != sNewEmptyDocumentURL ) + { + sEmptyDocumentURL = sNewEmptyDocumentURL; + bChangedEmptyDocumentURL = sal_True ; + } + }; + + //--------------------------------------------------------------------------------------------------------- + void setDefaultFilter( const ::rtl::OUString& sNewDefaultFilter ) + { + if( sDefaultFilter != sNewDefaultFilter ) + { + sDefaultFilter = sNewDefaultFilter; + bChangedDefaultFilter = sal_True ; + } + }; + + //--------------------------------------------------------------------------------------------------------- + void setIcon( sal_Int32 nNewIcon ) + { + if( nNewIcon != nNewIcon ) + { + nNewIcon = nNewIcon; + bChangedIcon = sal_True; + } + }; + + private: + css::uno::Reference< css::util::XStringSubstitution > getStringSubstitution() + { + if ( !xSubstVars.is() ) + { + xSubstVars + = css::uno::Reference< css::util::XStringSubstitution >( + xSMgr->createInstance( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.PathSubstitution" ) ) ), + css::uno::UNO_QUERY ); + if ( !xSubstVars.is() ) + throw css::uno::RuntimeException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Cannot instanciate service " + "com.sun.star.util.PathSubstitution" ) ), + css::uno::Reference< css::uno::XInterface >() ); + } + return xSubstVars; + } + + sal_Bool bInstalled ; + ::rtl::OUString sFactory ; + ::rtl::OUString sShortName ; + ::rtl::OUString sTemplateFile ; + ::rtl::OUString sWindowAttributes ; + ::rtl::OUString sEmptyDocumentURL ; + ::rtl::OUString sDefaultFilter ; + sal_Int32 nIcon ; + + sal_Bool bChangedTemplateFile :1 ; + sal_Bool bChangedWindowAttributes :1 ; + sal_Bool bChangedEmptyDocumentURL :1 ; + sal_Bool bChangedDefaultFilter :1 ; + sal_Bool bChangedIcon :1 ; + sal_Bool bDefaultFilterReadonly :1 ; + + css::uno::Reference< css::lang::XMultiServiceFactory > xSMgr; + css::uno::Reference< css::util::XStringSubstitution > xSubstVars; +}; + +typedef FactoryInfo FactoryInfoList[FACTORYCOUNT]; + +/*-************************************************************************************************************//** + @short IMPL data container for wrapper class SvtModulOptions! + @descr These class is used as a static data container of class SvtModuleOptions. The hold it by using + a refcount and make it threadsafe by using an osl mutex. So we don't must do anything for that. + We can implement pure functionality to read/write configuration data only. + + @implements - + @base ConfigItem + + @devstatus ready to use + @threadsafe no +*//*-*************************************************************************************************************/ +class SvtModuleOptions_Impl : public ::utl::ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + SvtModuleOptions_Impl(SvtModuleOptions* pOutsideClass); + ~SvtModuleOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + virtual void Notify( const css::uno::Sequence< ::rtl::OUString >& lPropertyNames ); + virtual void Commit( ); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + sal_Bool IsModuleInstalled ( SvtModuleOptions::EModule eModule ) const; + ::com::sun::star::uno::Sequence < ::rtl::OUString > GetAllServiceNames(); + ::rtl::OUString GetFactoryName ( SvtModuleOptions::EFactory eFactory ) const; + ::rtl::OUString GetFactoryShortName ( SvtModuleOptions::EFactory eFactory ) const; + ::rtl::OUString GetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory ) const; + ::rtl::OUString GetFactoryWindowAttributes( SvtModuleOptions::EFactory eFactory ) const; + ::rtl::OUString GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory eFactory ) const; + ::rtl::OUString GetFactoryDefaultFilter ( SvtModuleOptions::EFactory eFactory ) const; + sal_Bool IsDefaultFilterReadonly( SvtModuleOptions::EFactory eFactory ) const; + sal_Int32 GetFactoryIcon ( SvtModuleOptions::EFactory eFactory ) const; + static sal_Bool ClassifyFactoryByName ( const ::rtl::OUString& sName , + SvtModuleOptions::EFactory& eFactory ); + void SetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory , + const ::rtl::OUString& sTemplate ); + void SetFactoryWindowAttributes( SvtModuleOptions::EFactory eFactory , + const ::rtl::OUString& sAttributes); + void SetFactoryDefaultFilter ( SvtModuleOptions::EFactory eFactory , + const ::rtl::OUString& sFilter ); + void MakeReadonlyStatesAvailable(); + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + private: + static css::uno::Sequence< ::rtl::OUString > impl_ExpandSetNames ( const css::uno::Sequence< ::rtl::OUString >& lSetNames ); + void impl_Read ( const css::uno::Sequence< ::rtl::OUString >& lSetNames ); + + //------------------------------------------------------------------------------------------------------------- + // private types + //------------------------------------------------------------------------------------------------------------- + private: + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + private: + FactoryInfoList m_lFactories; + sal_Bool m_bReadOnlyStatesWellKnown; + SvtModuleOptions* m_pOutsideClass; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short default ctor + @descr We open our configuration here and read all neccessary values from it. + These values are cached till everyone call Commit(). Then we write changed ones back to cfg. + + @seealso baseclass ConfigItem + @seealso method impl_Read() + + @param - + @return - + + @onerror - + @threadsafe no +*//*-*************************************************************************************************************/ +SvtModuleOptions_Impl::SvtModuleOptions_Impl(SvtModuleOptions* pOutsideClass) + : ::utl::ConfigItem( ROOTNODE_FACTORIES ) + , m_bReadOnlyStatesWellKnown( sal_False ) + , m_pOutsideClass( pOutsideClass ) +{ + // First initialize list of factory infos! Otherwise we couldnt gurantee right working of these class. + for( sal_Int32 nFactory=0; nFactory<FACTORYCOUNT; ++nFactory ) + m_lFactories[nFactory].free(); + + // Get name list of all existing set node names in configuration to read her properties in impl_Read(). + // These list is a list of long names of our factories. + const css::uno::Sequence< ::rtl::OUString > lFactories = GetNodeNames( ::rtl::OUString() ); + impl_Read( lFactories ); + + // Enable notification for changes by using configuration directly. + // So we can update our internal values immediatly. + EnableNotification( lFactories ); +} + +/*-************************************************************************************************************//** + @short default dtor + @descr If any values of our cache was modified we should write it back to configuration. + + @attention Don't forget to call "SetModified()" method of base class ConfigItem if any interface method + of this class modify internal member list m_lFactories! Otherwise Commit() will never be called!!! + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + @threadsafe no +*//*-*************************************************************************************************************/ +SvtModuleOptions_Impl::~SvtModuleOptions_Impl() +{ + if( IsModified() == sal_True ) + { + Commit(); + } +} + +/*-************************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update our + internal values. + + @attention We are registered for pure set node names only. So we can use our internal method "impl_Read()" to + update our info list. Because - these method expand given name list to full qualified property list + and use it to read the values. These values are filled into our internal member list m_lFactories + at right position. + + @seealso method impl_Read() + + @param "lNames" is the list of set node entries which should be updated. + @return - + + @onerror - + @threadsafe no +*//*-*************************************************************************************************************/ +void SvtModuleOptions_Impl::Notify( const css::uno::Sequence< ::rtl::OUString >& ) +{ + OSL_ENSURE( sal_False, "SvtModuleOptions_Impl::Notify()\nNot implemented yet!\n" ); +} + +/*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @attention We clear complete set in configuration first and write it completly new! So we don't must + distinguish between existing, added or removed elements. Our internal cached values + are the only and right ones. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + @threadsafe no +*//*-*****************************************************************************************************/ +void SvtModuleOptions_Impl::Commit() +{ + // Reserve memory for ALL possible factory properties! + // Step over all factories and get her realy changed values only. + // Build list of these ones and use it for commit. + css::uno::Sequence< css::beans::PropertyValue > lCommitProperties( FACTORYCOUNT*PROPERTYCOUNT ); + FactoryInfo* pInfo = NULL ; + sal_Int32 nRealCount = 0 ; + ::rtl::OUString sBasePath ; + for( sal_Int32 nFactory=0; nFactory<FACTORYCOUNT; ++nFactory ) + { + pInfo = &(m_lFactories[nFactory]); + + // These path is used to build full qualified property names .... + // See pInfo->getChangedProperties() for further informations + sBasePath = PATHSEPERATOR + pInfo->getFactory() + PATHSEPERATOR; + + const css::uno::Sequence< css::beans::PropertyValue > lChangedProperties = pInfo->getChangedProperties ( sBasePath ); + const css::beans::PropertyValue* pChangedProperties = lChangedProperties.getConstArray(); + sal_Int32 nPropertyCount = lChangedProperties.getLength(); + for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + lCommitProperties[nRealCount] = pChangedProperties[nProperty]; + ++nRealCount; + } + } + // Resize commit list to real size. + // If nothing to do - suppress calling of configuration ... + // It could be to expensive :-) + if( nRealCount > 0 ) + { + lCommitProperties.realloc( nRealCount ); + SetSetProperties( ::rtl::OUString(), lCommitProperties ); + } +} + +/*-****************************************************************************************************//** + @short access method to get internal values + @descr These methods implement easy access to our internal values. + You give us right enum value to specify which module interest you ... we return right information. + + @attention Some poeple use any value as enum ... but we support in header specified values only! + We use it directly as index in our internal list. If enum value isn't right - we crash with an + "index out of range"!!! Please use me right - otherwise there is no guarantee. + + @seealso - + + @param "eModule" , index in list - specify module + @param "eFactory" , index in list - specify factory + @param "sTemplate", set new standard template for these factory + @return Queried information. + + @onerror We return default values. (mostly "not installed"!) + @threadsafe no +*//*-*****************************************************************************************************/ +sal_Bool SvtModuleOptions_Impl::IsModuleInstalled( SvtModuleOptions::EModule eModule ) const +{ + sal_Bool bInstalled = sal_False; + switch( eModule ) + { + case SvtModuleOptions::E_SWRITER : bInstalled = m_lFactories[SvtModuleOptions::E_WRITER].getInstalled(); + break; + case SvtModuleOptions::E_SWEB : bInstalled = m_lFactories[SvtModuleOptions::E_WRITERWEB].getInstalled(); + break; + case SvtModuleOptions::E_SGLOBAL : bInstalled = m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getInstalled(); + break; + case SvtModuleOptions::E_SCALC : bInstalled = m_lFactories[SvtModuleOptions::E_CALC].getInstalled(); + break; + case SvtModuleOptions::E_SDRAW : bInstalled = m_lFactories[SvtModuleOptions::E_DRAW].getInstalled(); + break; + case SvtModuleOptions::E_SIMPRESS : bInstalled = m_lFactories[SvtModuleOptions::E_IMPRESS].getInstalled(); + break; + case SvtModuleOptions::E_SMATH : bInstalled = m_lFactories[SvtModuleOptions::E_MATH].getInstalled(); + break; + case SvtModuleOptions::E_SCHART : bInstalled = m_lFactories[SvtModuleOptions::E_CHART].getInstalled(); + break; + case SvtModuleOptions::E_SSTARTMODULE : bInstalled = m_lFactories[SvtModuleOptions::E_STARTMODULE].getInstalled(); + break; + case SvtModuleOptions::E_SBASIC : bInstalled = sal_True; // Couldn't be deselected by setup yet! + break; + case SvtModuleOptions::E_SDATABASE : bInstalled = m_lFactories[SvtModuleOptions::E_DATABASE].getInstalled(); + break; + } + + return bInstalled; +} + +::com::sun::star::uno::Sequence < ::rtl::OUString > SvtModuleOptions_Impl::GetAllServiceNames() +{ + sal_uInt32 nCount=0; + if( m_lFactories[SvtModuleOptions::E_WRITER].getInstalled() ) + nCount++; + if ( m_lFactories[SvtModuleOptions::E_WRITERWEB].getInstalled() ) + nCount++; + if ( m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getInstalled() ) + nCount++; + if( m_lFactories[SvtModuleOptions::E_SCALC].getInstalled() ) + nCount++; + if( m_lFactories[SvtModuleOptions::E_SDRAW].getInstalled() ) + nCount++; + if( m_lFactories[SvtModuleOptions::E_SIMPRESS].getInstalled() ) + nCount++; + if( m_lFactories[SvtModuleOptions::E_SCHART].getInstalled() ) + nCount++; + if( m_lFactories[SvtModuleOptions::E_SMATH].getInstalled() ) + nCount++; + if( m_lFactories[SvtModuleOptions::E_SBASIC].getInstalled() ) + nCount++; + if( m_lFactories[SvtModuleOptions::E_SDATABASE].getInstalled() ) + nCount++; + + css::uno::Sequence < ::rtl::OUString > aRet( nCount ); + sal_Int32 n=0; + if( m_lFactories[SvtModuleOptions::E_WRITER].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_WRITER].getFactory(); + if ( m_lFactories[SvtModuleOptions::E_WRITERWEB].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_WRITERWEB].getFactory(); + if ( m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getFactory(); + if( m_lFactories[SvtModuleOptions::E_SCALC].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_SCALC].getFactory(); + if( m_lFactories[SvtModuleOptions::E_SDRAW].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_SDRAW].getFactory(); + if( m_lFactories[SvtModuleOptions::E_SIMPRESS].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_SIMPRESS].getFactory(); + if( m_lFactories[SvtModuleOptions::E_SCHART].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_SCHART].getFactory(); + if( m_lFactories[SvtModuleOptions::E_SMATH].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_SMATH].getFactory(); + if( m_lFactories[SvtModuleOptions::E_SBASIC].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_SBASIC].getFactory(); + if( m_lFactories[SvtModuleOptions::E_SDATABASE].getInstalled() ) + aRet[n++] = m_lFactories[SvtModuleOptions::E_SDATABASE].getFactory(); + + return aRet; +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions_Impl::GetFactoryName( SvtModuleOptions::EFactory eFactory ) const +{ + ::rtl::OUString sName; + + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + sName = m_lFactories[eFactory].getFactory(); + } + + return sName; +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions_Impl::GetFactoryShortName( SvtModuleOptions::EFactory eFactory ) const +{ + // Attention: Hard configured yet ... because it's not fine to make changes possible by xml file yet. + // But it's good to plan further possibilities! + + //return m_lFactories[eFactory].sShortName; + + ::rtl::OUString sShortName; + switch( eFactory ) + { + case SvtModuleOptions::E_WRITER : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swriter")); + break; + case SvtModuleOptions::E_WRITERWEB : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swriter/web")); + break; + case SvtModuleOptions::E_WRITERGLOBAL : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swriter/GlobalDocument")); + break; + case SvtModuleOptions::E_CALC : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("scalc")); + break; + case SvtModuleOptions::E_DRAW : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdraw")); + break; + case SvtModuleOptions::E_IMPRESS : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simpress")); + break; + case SvtModuleOptions::E_MATH : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("smath")); + break; + case SvtModuleOptions::E_CHART : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("schart")); + break; + case SvtModuleOptions::E_BASIC : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sbasic")); + break; + case SvtModuleOptions::E_DATABASE : sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdatabase")); + break; + default: + OSL_ASSERT( "unknown factory" ); + break; + } + + return sShortName; +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions_Impl::GetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory ) const +{ + ::rtl::OUString sFile; + + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + sFile = m_lFactories[eFactory].getTemplateFile(); + } + + return sFile; +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions_Impl::GetFactoryWindowAttributes( SvtModuleOptions::EFactory eFactory ) const +{ + ::rtl::OUString sAttributes; + + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + sAttributes = m_lFactories[eFactory].getWindowAttributes(); + } + + return sAttributes; +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions_Impl::GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory eFactory ) const +{ + // Attention: Hard configured yet ... because it's not fine to make changes possible by xml file yet. + // But it's good to plan further possibilities! + + //return m_lFactories[eFactory].getEmptyDocumentURL(); + + ::rtl::OUString sURL; + switch( eFactory ) + { + case SvtModuleOptions::E_WRITER : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter")); + break; + case SvtModuleOptions::E_WRITERWEB : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter/web")); + break; + case SvtModuleOptions::E_WRITERGLOBAL : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter/GlobalDocument")); + break; + case SvtModuleOptions::E_CALC : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/scalc")); + break; + case SvtModuleOptions::E_DRAW : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/sdraw")); + break; + case SvtModuleOptions::E_IMPRESS : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/simpress?slot=6686")); + break; + case SvtModuleOptions::E_MATH : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/smath")); + break; + case SvtModuleOptions::E_CHART : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/schart")); + break; + case SvtModuleOptions::E_BASIC : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/sbasic")); + break; + case SvtModuleOptions::E_DATABASE : sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/sdatabase?Interactive")); + break; + default: + OSL_ASSERT( "unknown factory" ); + break; + } + return sURL; +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions_Impl::GetFactoryDefaultFilter( SvtModuleOptions::EFactory eFactory ) const +{ + ::rtl::OUString sDefaultFilter; + + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + sDefaultFilter = m_lFactories[eFactory].getDefaultFilter(); + } + return sDefaultFilter; +} +//***************************************************************************************************************** +sal_Bool SvtModuleOptions_Impl::IsDefaultFilterReadonly( SvtModuleOptions::EFactory eFactory ) const +{ + sal_Bool bRet = sal_False; + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + bRet = m_lFactories[eFactory].isDefaultFilterReadonly(); + } + return bRet; +} + +//***************************************************************************************************************** +sal_Int32 SvtModuleOptions_Impl::GetFactoryIcon( SvtModuleOptions::EFactory eFactory ) const +{ + sal_Int32 nIcon = 0; + + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + nIcon = m_lFactories[eFactory].getIcon(); + } + + return nIcon; +} + +//***************************************************************************************************************** +void SvtModuleOptions_Impl::SetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory , + const ::rtl::OUString& sTemplate ) +{ + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + m_lFactories[eFactory].setTemplateFile( sTemplate ); + SetModified(); + } +} + +//***************************************************************************************************************** +void SvtModuleOptions_Impl::SetFactoryWindowAttributes( SvtModuleOptions::EFactory eFactory , + const ::rtl::OUString& sAttributes) +{ + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + m_lFactories[eFactory].setWindowAttributes( sAttributes ); + SetModified(); + } +} + +//***************************************************************************************************************** +void SvtModuleOptions_Impl::SetFactoryDefaultFilter( SvtModuleOptions::EFactory eFactory, + const ::rtl::OUString& sFilter ) +{ + if( eFactory>=0 && eFactory<FACTORYCOUNT ) + { + m_lFactories[eFactory].setDefaultFilter( sFilter ); + SetModified(); + } +} + +/*-************************************************************************************************************//** + @short return list of key names of ouer configuration management which represent our module tree + @descr You give use a list of current existing set node names .. and we expand it for all + well known properties which are neccessary for this implementation. + These full expanded list should be used to get values of this properties. + + @seealso ctor + + @param - + @return List of all relative addressed properties of given set entry names. + + @onerror List will be empty. + @threadsafe no +*//*-*************************************************************************************************************/ +css::uno::Sequence< ::rtl::OUString > SvtModuleOptions_Impl::impl_ExpandSetNames( const css::uno::Sequence< ::rtl::OUString >& lSetNames ) +{ + sal_Int32 nCount = lSetNames.getLength() ; + css::uno::Sequence< ::rtl::OUString > lPropNames ( nCount*PROPERTYCOUNT ); + ::rtl::OUString* pPropNames = lPropNames.getArray() ; + sal_Int32 nPropStart = 0 ; + + for( sal_Int32 nName=0; nName<nCount; ++nName ) + { + pPropNames[nPropStart+PROPERTYHANDLE_SHORTNAME ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_SHORTNAME ; + pPropNames[nPropStart+PROPERTYHANDLE_TEMPLATEFILE ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_TEMPLATEFILE ; + pPropNames[nPropStart+PROPERTYHANDLE_WINDOWATTRIBUTES] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_WINDOWATTRIBUTES; + pPropNames[nPropStart+PROPERTYHANDLE_EMPTYDOCUMENTURL] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_EMPTYDOCUMENTURL; + pPropNames[nPropStart+PROPERTYHANDLE_DEFAULTFILTER ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_DEFAULTFILTER ; + pPropNames[nPropStart+PROPERTYHANDLE_ICON ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_ICON ; + nPropStart += PROPERTYCOUNT; + } + + return lPropNames; +} + +/*-************************************************************************************************************//** + @short helper to classify given factory by name + @descr Every factory has his own long and short name. So we can match right enum value for internal using. + + @attention We change in/out parameter "eFactory" in every case! But you should use it only, if return value is TRUE! + Algorithm: Set out-parameter to propably value ... and check the longname. + If it match with these factory - break operation and return true AND right set parameter. + Otherwise try next one and so on. If no factory was found return false. Out parameter eFactory + is set to last tried value but shouldn't be used! Because our return value is false! + + @seealso - + + @param "sLongName" , long name of factory, which should be classified + @return "eFactory" , right enum value, which match given long name + and true for successfully classification, false otherwise + + @onerror We return false. + @threadsafe no +*//*-*************************************************************************************************************/ +sal_Bool SvtModuleOptions_Impl::ClassifyFactoryByName( const ::rtl::OUString& sName, SvtModuleOptions::EFactory& eFactory ) +{ + sal_Bool bState; + + eFactory = SvtModuleOptions::E_WRITER ; + bState = ( sName == FACTORYNAME_WRITER ); + + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_WRITERWEB ; + bState = ( sName == FACTORYNAME_WRITERWEB ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_WRITERGLOBAL ; + bState = ( sName == FACTORYNAME_WRITERGLOBAL ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_CALC ; + bState = ( sName == FACTORYNAME_CALC ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_DRAW ; + bState = ( sName == FACTORYNAME_DRAW ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_IMPRESS ; + bState = ( sName == FACTORYNAME_IMPRESS ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_MATH ; + bState = ( sName == FACTORYNAME_MATH ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_CHART ; + bState = ( sName == FACTORYNAME_CHART ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_DATABASE ; + bState = ( sName == FACTORYNAME_DATABASE ); + } + // no else! + if( bState == sal_False ) + { + eFactory = SvtModuleOptions::E_STARTMODULE ; + bState = ( sName == FACTORYNAME_STARTMODULE); + } + + return bState; +} + +/*-************************************************************************************************************//** + @short read factory configuration + @descr Give us a list of pure factory names (long names!) which can be used as + direct set node names ... and we read her property values and fill internal list. + These method can be used by initial reading at ctor and later updating by "Notify()". + + @seealso ctor + @seealso method Notify() + + @param "lFactories" is the list of set node entries which should be readed. + @return - + + @onerror We do nothing. + @threadsafe no +*//*-*************************************************************************************************************/ +void SvtModuleOptions_Impl::impl_Read( const css::uno::Sequence< ::rtl::OUString >& lFactories ) +{ + // Expand every set node name in lFactories to full qualified pathes to his properties + // and get right values from configuration. + const css::uno::Sequence< ::rtl::OUString > lProperties = impl_ExpandSetNames( lFactories ); + const css::uno::Sequence< css::uno::Any > lValues = GetProperties( lProperties ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + OSL_ENSURE( !(lProperties.getLength()!=lValues.getLength()), "SvtModuleOptions_Impl::impl_Read()\nI miss some values of configuration keys!\n" ); + + // Algorithm: We step over all given factory names and classify it. These enum value can be used as direct index + // in our member list m_lFactories! VAriable nPropertyStart marks start position of every factory + // and her properties in expanded property/value list. The defines PROPERTHANDLE_xxx are used as offset values + // added to nPropertyStart. So we can address every property relative in these lists. + // If we found any valid values ... we reset all existing informations for corresponding m_lFactories-entry and + // use a pointer to these struct in memory directly to set new values. + // But we set it only, if bInstalled is true. Otherwise all other values of a factory can be undeclared .. They + // shouldn't be used then. + // Attention: If a propertyset of a factory will be ignored we must step to next start position of next factory infos! + // see "nPropertyStart += PROPERTYCOUNT" ... + + sal_Int32 nPropertyStart = 0 ; + sal_Int32 nNodeCount = lFactories.getLength(); + FactoryInfo* pInfo = NULL ; + SvtModuleOptions::EFactory eFactory ; + + for( sal_Int32 nSetNode=0; nSetNode<nNodeCount; ++nSetNode ) + { + const ::rtl::OUString& sFactoryName = lFactories[nSetNode]; + if( ClassifyFactoryByName( sFactoryName, eFactory ) == sal_True ) + { + ::rtl::OUString sTemp; + sal_Int32 nTemp = 0; + + pInfo = &(m_lFactories[eFactory]); + pInfo->free(); + + pInfo->initInstalled( sal_True ); + pInfo->initFactory ( sFactoryName ); + + if (lValues[nPropertyStart+PROPERTYHANDLE_SHORTNAME] >>= sTemp) + pInfo->initShortName( sTemp ); + if (lValues[nPropertyStart+PROPERTYHANDLE_TEMPLATEFILE] >>= sTemp) + pInfo->initTemplateFile( sTemp ); + if (lValues[nPropertyStart+PROPERTYHANDLE_WINDOWATTRIBUTES] >>= sTemp) + pInfo->initWindowAttributes( sTemp ); + if (lValues[nPropertyStart+PROPERTYHANDLE_EMPTYDOCUMENTURL] >>= sTemp) + pInfo->initEmptyDocumentURL( sTemp ); + if (lValues[nPropertyStart+PROPERTYHANDLE_DEFAULTFILTER ] >>= sTemp) + pInfo->initDefaultFilter( sTemp ); + if (lValues[nPropertyStart+PROPERTYHANDLE_ICON] >>= nTemp) + pInfo->initIcon( nTemp ); + } + nPropertyStart += PROPERTYCOUNT; + } +} + +//***************************************************************************************************************** +void SvtModuleOptions_Impl::MakeReadonlyStatesAvailable() +{ + if (m_bReadOnlyStatesWellKnown) + return; + + css::uno::Sequence< ::rtl::OUString > lFactories = GetNodeNames(::rtl::OUString()); + sal_Int32 c = lFactories.getLength(); + sal_Int32 i = 0; + for (i=0; i<c; ++i) + { + ::rtl::OUStringBuffer sPath(256); + sPath.append(lFactories[i] ); + sPath.append(PATHSEPERATOR ); + sPath.append(PROPERTYNAME_DEFAULTFILTER); + + lFactories[i] = sPath.makeStringAndClear(); + } + + css::uno::Sequence< sal_Bool > lReadonlyStates = GetReadOnlyStates(lFactories); + for (i=0; i<c; ++i) + { + ::rtl::OUString& rFactoryName = lFactories[i]; + SvtModuleOptions::EFactory eFactory ; + + if (!ClassifyFactoryByName(rFactoryName, eFactory)) + continue; + + FactoryInfo& rInfo = m_lFactories[eFactory]; + rInfo.setDefaultFilterReadonly(lReadonlyStates[i]); + } + + m_bReadOnlyStatesWellKnown = sal_True; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtModuleOptions_Impl* SvtModuleOptions::m_pDataContainer = NULL ; +sal_Int32 SvtModuleOptions::m_nRefCount = 0 ; + +/*-************************************************************************************************************//** + @short standard constructor and destructor + @descr This will initialize an instance with default values. We initialize/deinitialize our static data + container and create a static mutex, which is used for threadsafe code in further time of this object. + + @seealso method impl_GetOwnStaticMutex() + + @param - + @return - + + @onerror - + @threadsafe yes +*//*-*************************************************************************************************************/ +SvtModuleOptions::SvtModuleOptions() +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + ++m_nRefCount; + if( m_nRefCount == 1 ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtModuleOptions_Impl::ctor()"); + m_pDataContainer = new SvtModuleOptions_Impl(this); + + ItemHolder1::holdConfigItem(E_MODULEOPTIONS); + } +} + +//***************************************************************************************************************** +SvtModuleOptions::~SvtModuleOptions() +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + --m_nRefCount; + if( m_nRefCount == 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +/*-************************************************************************************************************//** + @short access to configuration data + @descr This methods allow read/write access to configuration values. + They are threadsafe. All calls are forwarded to impl-data-container. See there for further informations! + + @seealso method impl_GetOwnStaticMutex() + + @param - + @return - + + @onerror - + @threadsafe yes +*//*-*************************************************************************************************************/ +sal_Bool SvtModuleOptions::IsModuleInstalled( EModule eModule ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( eModule ); +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions::GetFactoryName( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetFactoryName( eFactory ); +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions::GetFactoryShortName( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetFactoryShortName( eFactory ); +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions::GetFactoryStandardTemplate( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetFactoryStandardTemplate( eFactory ); +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions::GetFactoryWindowAttributes( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetFactoryWindowAttributes( eFactory ); +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions::GetFactoryEmptyDocumentURL( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetFactoryEmptyDocumentURL( eFactory ); +} + +//***************************************************************************************************************** +::rtl::OUString SvtModuleOptions::GetFactoryDefaultFilter( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetFactoryDefaultFilter( eFactory ); +} +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsDefaultFilterReadonly( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + m_pDataContainer->MakeReadonlyStatesAvailable(); + return m_pDataContainer->IsDefaultFilterReadonly( eFactory ); +} +//***************************************************************************************************************** +sal_Int32 SvtModuleOptions::GetFactoryIcon( EFactory eFactory ) const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetFactoryIcon( eFactory ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::ClassifyFactoryByName( const ::rtl::OUString& sName , + EFactory& eFactory ) +{ + // We don't need any mutex here ... because we don't use any member here! + return SvtModuleOptions_Impl::ClassifyFactoryByName( sName, eFactory ); +} + +//***************************************************************************************************************** +void SvtModuleOptions::SetFactoryStandardTemplate( EFactory eFactory , + const ::rtl::OUString& sTemplate ) +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + m_pDataContainer->SetFactoryStandardTemplate( eFactory, sTemplate ); +} + +//***************************************************************************************************************** +void SvtModuleOptions::SetFactoryWindowAttributes( EFactory eFactory , + const ::rtl::OUString& sAttributes) +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + m_pDataContainer->SetFactoryWindowAttributes( eFactory, sAttributes ); +} + +//***************************************************************************************************************** +void SvtModuleOptions::SetFactoryDefaultFilter( EFactory eFactory, + const ::rtl::OUString& sFilter ) +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + m_pDataContainer->SetFactoryDefaultFilter( eFactory, sFilter ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsMath() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( E_SMATH ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsChart() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( E_SCHART ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsCalc() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( E_SCALC ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsDraw() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( E_SDRAW ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsWriter() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( E_SWRITER ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsImpress() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( E_SIMPRESS ); +} + +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsBasicIDE() const +{ + return sal_True; +} +//***************************************************************************************************************** +sal_Bool SvtModuleOptions::IsDataBase() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->IsModuleInstalled( E_SDATABASE ); +} +//***************************************************************************************************************** +sal_uInt32 SvtModuleOptions::GetFeatures() const +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + + sal_uInt32 nFeature = 0; + + if( m_pDataContainer->IsModuleInstalled( E_SWRITER ) == sal_True ) + nFeature |= FEATUREFLAG_WRITER; + if( m_pDataContainer->IsModuleInstalled( E_SCALC ) == sal_True ) + nFeature |= FEATUREFLAG_CALC; + if( m_pDataContainer->IsModuleInstalled( E_SDRAW ) == sal_True ) + nFeature |= FEATUREFLAG_DRAW; + if( m_pDataContainer->IsModuleInstalled( E_SIMPRESS ) == sal_True ) + nFeature |= FEATUREFLAG_IMPRESS; + if( m_pDataContainer->IsModuleInstalled( E_SCHART ) == sal_True ) + nFeature |= FEATUREFLAG_CHART; + if( m_pDataContainer->IsModuleInstalled( E_SMATH ) == sal_True ) + nFeature |= FEATUREFLAG_MATH; + if( m_pDataContainer->IsModuleInstalled( E_SBASIC ) == sal_True ) + nFeature |= FEATUREFLAG_BASICIDE; + if( m_pDataContainer->IsModuleInstalled( E_SDATABASE ) == sal_True ) + nFeature |= FEATUREFLAG_INSIGHT; + + return nFeature; +} + +/*-****************************************************************************************************//** + @short return a reference to a static mutex + @descr These class is threadsafe. + We create a static mutex only for one time and use it to protect our refcount and container + member! + + @seealso - + + @param - + @return A reference to a static mutex member. + + @onerror - + @threadsafe yes +*//*-*****************************************************************************************************/ +::osl::Mutex& SvtModuleOptions::impl_GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static ::osl::Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static ::osl::Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} + +::rtl::OUString SvtModuleOptions::GetModuleName( EModule eModule ) const +{ + switch( eModule ) + { + case SvtModuleOptions::E_SWRITER : { return ::rtl::OUString::createFromAscii("Writer"); } + case SvtModuleOptions::E_SWEB : { return ::rtl::OUString::createFromAscii("Web"); } + case SvtModuleOptions::E_SGLOBAL : { return ::rtl::OUString::createFromAscii("Global"); } + case SvtModuleOptions::E_SCALC : { return ::rtl::OUString::createFromAscii("Calc"); } + case SvtModuleOptions::E_SDRAW : { return ::rtl::OUString::createFromAscii("Draw"); } + case SvtModuleOptions::E_SIMPRESS : { return ::rtl::OUString::createFromAscii("Impress"); } + case SvtModuleOptions::E_SMATH : { return ::rtl::OUString::createFromAscii("Math"); } + case SvtModuleOptions::E_SCHART : { return ::rtl::OUString::createFromAscii("Chart"); } + case SvtModuleOptions::E_SBASIC : { return ::rtl::OUString::createFromAscii("Basic"); } + case SvtModuleOptions::E_SDATABASE : { return ::rtl::OUString::createFromAscii("Database"); } + default: + OSL_ASSERT( "unknown module" ); + break; + } + + return ::rtl::OUString(); +} + +::rtl::OUString SvtModuleOptions::GetModuleName( EFactory eFactory ) const +{ + switch( eFactory ) + { + case SvtModuleOptions::E_WRITER : { return ::rtl::OUString::createFromAscii("Writer"); } + case SvtModuleOptions::E_WRITERWEB : { return ::rtl::OUString::createFromAscii("Writer"); } + case SvtModuleOptions::E_WRITERGLOBAL : { return ::rtl::OUString::createFromAscii("Writer"); } + case SvtModuleOptions::E_CALC : { return ::rtl::OUString::createFromAscii("Calc"); } + case SvtModuleOptions::E_DRAW : { return ::rtl::OUString::createFromAscii("Draw"); } + case SvtModuleOptions::E_IMPRESS : { return ::rtl::OUString::createFromAscii("Impress"); } + case SvtModuleOptions::E_MATH : { return ::rtl::OUString::createFromAscii("Math"); } + case SvtModuleOptions::E_CHART : { return ::rtl::OUString::createFromAscii("Chart"); } + case SvtModuleOptions::E_BASIC : { return ::rtl::OUString::createFromAscii("Basic"); } + case SvtModuleOptions::E_DATABASE : { return ::rtl::OUString::createFromAscii("Database"); } + default: + OSL_ASSERT( "unknown factory" ); + break; + } + + return ::rtl::OUString(); +} + +/*----------------------------------------------- + 07.03.2004 15:03 +-----------------------------------------------*/ +SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByShortName(const ::rtl::OUString& sName) +{ + if (sName.equalsAscii("swriter")) + return E_WRITER; + if (sName.equalsIgnoreAsciiCaseAscii("swriter/Web")) // sometimes they are registerd for swriter/web :-( + return E_WRITERWEB; + if (sName.equalsIgnoreAsciiCaseAscii("swriter/GlobalDocument")) // sometimes they are registerd for swriter/globaldocument :-( + return E_WRITERGLOBAL; + if (sName.equalsAscii("scalc")) + return E_CALC; + if (sName.equalsAscii("sdraw")) + return E_DRAW; + if (sName.equalsAscii("simpress")) + return E_IMPRESS; + if (sName.equalsAscii("schart")) + return E_CHART; + if (sName.equalsAscii("smath")) + return E_MATH; + if (sName.equalsAscii("sbasic")) + return E_BASIC; + if (sName.equalsAscii("sdatabase")) + return E_DATABASE; + + return E_UNKNOWN_FACTORY; +} + +/*----------------------------------------------- + 31.07.2003 10:41 +-----------------------------------------------*/ +SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByServiceName(const ::rtl::OUString& sName) +{ + if (sName.equals(FACTORYNAME_WRITERGLOBAL)) + return E_WRITERGLOBAL; + if (sName.equals(FACTORYNAME_WRITERWEB)) + return E_WRITERWEB; + if (sName.equals(FACTORYNAME_WRITER)) + return E_WRITER; + if (sName.equals(FACTORYNAME_CALC)) + return E_CALC; + if (sName.equals(FACTORYNAME_DRAW)) + return E_DRAW; + if (sName.equals(FACTORYNAME_IMPRESS)) + return E_IMPRESS; + if (sName.equals(FACTORYNAME_MATH)) + return E_MATH; + if (sName.equals(FACTORYNAME_CHART)) + return E_CHART; + if (sName.equals(FACTORYNAME_DATABASE)) + return E_DATABASE; + + return E_UNKNOWN_FACTORY; +} + +/*----------------------------------------------- + 31.07.2003 14:39 +-----------------------------------------------*/ +SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByURL(const ::rtl::OUString& sURL , + const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor) +{ + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory(); + if (!xSMGR.is()) + return E_UNKNOWN_FACTORY; + + css::uno::Reference< css::container::XNameAccess > xFilterCfg; + css::uno::Reference< css::container::XNameAccess > xTypeCfg ; + try + { + xFilterCfg = css::uno::Reference< css::container::XNameAccess >( + xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.FilterFactory")), css::uno::UNO_QUERY); + xTypeCfg = css::uno::Reference< css::container::XNameAccess >( + xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection")), css::uno::UNO_QUERY); + } + catch(const css::uno::RuntimeException&) + { throw; } + catch(const css::uno::Exception&) + { return E_UNKNOWN_FACTORY; } + + ::comphelper::SequenceAsHashMap stlDesc(lMediaDescriptor); + + // is there already a filter inside the descriptor? + ::rtl::OUString sFilterName = stlDesc.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("FilterName"), ::rtl::OUString()); + if (sFilterName.getLength()) + { + try + { + ::comphelper::SequenceAsHashMap stlFilterProps (xFilterCfg->getByName(sFilterName)); + ::rtl::OUString sDocumentService = stlFilterProps.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("DocumentService"), ::rtl::OUString()); + SvtModuleOptions::EFactory eApp = SvtModuleOptions::ClassifyFactoryByServiceName(sDocumentService); + + if (eApp != E_UNKNOWN_FACTORY) + return eApp; + } + catch(const css::uno::RuntimeException&) + { throw; } + catch(const css::uno::Exception&) + { /* do nothing here ... may the following code can help!*/ } + } + + // is there already a type inside the descriptor? + ::rtl::OUString sTypeName = stlDesc.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("TypeName"), ::rtl::OUString()); + if (!sTypeName.getLength()) + { + // no :-( + // start flat detection of URL + css::uno::Reference< css::document::XTypeDetection > xDetect(xTypeCfg, css::uno::UNO_QUERY); + sTypeName = xDetect->queryTypeByURL(sURL); + } + + if (!sTypeName.getLength()) + return E_UNKNOWN_FACTORY; + + // yes - there is a type info + // Try to find the preferred filter. + try + { + ::comphelper::SequenceAsHashMap stlTypeProps (xTypeCfg->getByName(sTypeName)); + ::rtl::OUString sPreferredFilter = stlTypeProps.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("PreferredFilter"), ::rtl::OUString()); + ::comphelper::SequenceAsHashMap stlFilterProps (xFilterCfg->getByName(sPreferredFilter)); + ::rtl::OUString sDocumentService = stlFilterProps.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("DocumentService"), ::rtl::OUString()); + SvtModuleOptions::EFactory eApp = SvtModuleOptions::ClassifyFactoryByServiceName(sDocumentService); + + if (eApp != E_UNKNOWN_FACTORY) + return eApp; + } + catch(const css::uno::RuntimeException&) + { throw; } + catch(const css::uno::Exception&) + { /* do nothing here ... may the following code can help!*/ } + + // no filter/no type/no detection result => no fun :-) + return E_UNKNOWN_FACTORY; +} + +/*----------------------------------------------- + 31.07.2003 10:41 +-----------------------------------------------*/ +SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByModel(const css::uno::Reference< css::frame::XModel >& xModel) +{ + css::uno::Reference< css::lang::XServiceInfo > xInfo(xModel, css::uno::UNO_QUERY); + if (!xInfo.is()) + return E_UNKNOWN_FACTORY; + + const css::uno::Sequence< ::rtl::OUString > lServices = xInfo->getSupportedServiceNames(); + const ::rtl::OUString* pServices = lServices.getConstArray(); + + for (sal_Int32 i=0; i<lServices.getLength() ; ++i) + { + SvtModuleOptions::EFactory eApp = SvtModuleOptions::ClassifyFactoryByServiceName(pServices[i]); + if (eApp != E_UNKNOWN_FACTORY) + return eApp; + } + + return E_UNKNOWN_FACTORY; +} + +::com::sun::star::uno::Sequence < ::rtl::OUString > SvtModuleOptions::GetAllServiceNames() +{ + ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() ); + return m_pDataContainer->GetAllServiceNames(); +} + +::rtl::OUString SvtModuleOptions::GetDefaultModuleName() +{ + ::rtl::OUString aModule; + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SWRITER)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_WRITER); + else + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SCALC)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_CALC); + else + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SIMPRESS)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_IMPRESS); + else + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SDATABASE)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_DATABASE); + else + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SDRAW)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_DRAW); + else + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SWEB)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_WRITERWEB); + else + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SGLOBAL)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_WRITERGLOBAL); + else + if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SMATH)) + aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_MATH); + return aModule; +} + diff --git a/unotools/source/config/options.cxx b/unotools/source/config/options.cxx new file mode 100644 index 000000000000..c65fd09efd0c --- /dev/null +++ b/unotools/source/config/options.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include "sal/config.h" +#include <tools/list.hxx> +#include <unotools/options.hxx> + +namespace utl +{ + DECLARE_LIST( IMPL_ConfigurationListenerList, ConfigurationListener* ) +} + +using utl::detail::Options; +using utl::ConfigurationBroadcaster; + +ConfigurationBroadcaster::ConfigurationBroadcaster() +: mpList(0) +, m_nBroadcastBlocked( 0 ) +, m_nBlockedHint( 0 ) +{ +} + +ConfigurationBroadcaster::~ConfigurationBroadcaster() +{ + delete mpList; +} + +void ConfigurationBroadcaster::AddListener( utl::ConfigurationListener* pListener ) +{ + if ( !mpList ) + mpList = new IMPL_ConfigurationListenerList; + mpList->Insert( pListener ); +} + +void ConfigurationBroadcaster::RemoveListener( utl::ConfigurationListener* pListener ) +{ + if ( mpList ) + mpList->Remove( pListener ); +} + +void ConfigurationBroadcaster::NotifyListeners( sal_uInt32 nHint ) +{ + if ( m_nBroadcastBlocked ) + m_nBlockedHint |= nHint; + else + { + nHint |= m_nBlockedHint; + m_nBlockedHint = 0; + if ( mpList ) + for ( sal_uInt32 n=0; n<mpList->Count(); n++ ) + mpList->GetObject(n)->ConfigurationChanged( this, nHint ); + } +} + +void ConfigurationBroadcaster::BlockBroadcasts( bool bBlock ) +{ + if ( bBlock ) + ++m_nBroadcastBlocked; + else if ( m_nBroadcastBlocked ) + { + if ( --m_nBroadcastBlocked == 0 ) + NotifyListeners( 0 ); + } +} + +Options::Options() +{ +} + +Options::~Options() +{ +} + +void Options::ConfigurationChanged( ConfigurationBroadcaster*, sal_uInt32 nHint ) +{ + NotifyListeners( nHint ); +} + + diff --git a/unotools/source/config/optionsdlg.cxx b/unotools/source/config/optionsdlg.cxx new file mode 100644 index 000000000000..cb98e8514358 --- /dev/null +++ b/unotools/source/config/optionsdlg.cxx @@ -0,0 +1,290 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/optionsdlg.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <osl/mutex.hxx> +#include <comphelper/stl_types.hxx> + +#include <hash_map> +#include "itemholder1.hxx" + +using namespace utl; +using namespace rtl; +using namespace com::sun::star::beans ; +using namespace com::sun::star::uno; + +#define CFG_FILENAME OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.OptionsDialog" ) ) +#define ROOT_NODE OUString( RTL_CONSTASCII_USTRINGPARAM( "OptionsDialogGroups" ) ) +#define PAGES_NODE OUString( RTL_CONSTASCII_USTRINGPARAM( "Pages" ) ) +#define OPTIONS_NODE OUString( RTL_CONSTASCII_USTRINGPARAM( "Options" ) ) +#define PROPERTY_HIDE OUString( RTL_CONSTASCII_USTRINGPARAM( "Hide" ) ) + +static SvtOptionsDlgOptions_Impl* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +class SvtOptionsDlgOptions_Impl : public utl::ConfigItem +{ +private: + struct OUStringHashCode + { + size_t operator()( const ::rtl::OUString& sString ) const + { + return sString.hashCode(); + } + }; + + typedef std::hash_map< OUString, sal_Bool, OUStringHashCode, ::std::equal_to< OUString > > OptionNodeList; + + OUString m_sPathDelimiter; + OptionNodeList m_aOptionNodeList; + + enum NodeType{ NT_Group, NT_Page, NT_Option }; + void ReadNode( const OUString& _rNode, NodeType _eType ); + sal_Bool IsHidden( const OUString& _rPath ) const; + +public: + SvtOptionsDlgOptions_Impl(); + + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + virtual void Commit(); + + static ::osl::Mutex & getInitMutex(); + + sal_Bool IsGroupHidden ( const OUString& _rGroup ) const; + sal_Bool IsPageHidden ( const OUString& _rPage, + const OUString& _rGroup ) const; + sal_Bool IsOptionHidden ( const OUString& _rOption, + const OUString& _rPage, + const OUString& _rGroup ) const; +}; + +::osl::Mutex & SvtOptionsDlgOptions_Impl::getInitMutex() +{ + static ::osl::Mutex *pMutex = 0; + + if( ! pMutex ) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if( ! pMutex ) + { + static ::osl::Mutex mutex; + pMutex = &mutex; + } + } + return *pMutex; +} + +// ----------------------------------------------------------------------- + +SvtOptionsDlgOptions_Impl::SvtOptionsDlgOptions_Impl() + : ConfigItem( OUString( CFG_FILENAME ) ), + + m_sPathDelimiter( RTL_CONSTASCII_USTRINGPARAM( "/" ) ), + m_aOptionNodeList( OptionNodeList() ) + +{ + OUString sRootNode( ROOT_NODE ); + Sequence< OUString > aNodeSeq = GetNodeNames( sRootNode ); + OUString sNode( sRootNode + m_sPathDelimiter ); + sal_uInt32 nCount = aNodeSeq.getLength(); + for ( sal_uInt32 n = 0; n < nCount; n++ ) + { + OUString sSubNode( sNode + aNodeSeq[n] ); + ReadNode( sSubNode, NT_Group ); + } +} + +// ----------------------------------------------------------------------- + +void SvtOptionsDlgOptions_Impl::Commit() +{ + // nothing to commit +} + +// ----------------------------------------------------------------------- + +void SvtOptionsDlgOptions_Impl::Notify( const Sequence< rtl::OUString >& ) +{ + // nothing to notify +} + +void SvtOptionsDlgOptions_Impl::ReadNode( const OUString& _rNode, NodeType _eType ) +{ + OUString sNode( _rNode + m_sPathDelimiter ); + OUString sSet; + sal_Int32 nLen = 0; + switch ( _eType ) + { + case NT_Group : + { + sSet = PAGES_NODE; + nLen = 2; + break; + } + + case NT_Page : + { + sSet = OPTIONS_NODE; + nLen = 2; + break; + } + + case NT_Option : + { + nLen = 1; + break; + } + } + + Sequence< OUString > lResult( nLen ); + lResult[0] = OUString( sNode + PROPERTY_HIDE ); + if ( _eType != NT_Option ) + lResult[1] = OUString( sNode + sSet ); + + Sequence< Any > aValues; + aValues = GetProperties( lResult ); + sal_Bool bHide = sal_False; + if ( aValues[0] >>= bHide ) + m_aOptionNodeList.insert( OptionNodeList::value_type( sNode, bHide ) ); + + if ( _eType != NT_Option ) + { + OUString sNodes( sNode + sSet ); + Sequence< OUString > aNodes = GetNodeNames( sNodes ); + if ( aNodes.getLength() > 0 ) + { + for ( sal_uInt32 n = 0; n < (sal_uInt32)aNodes.getLength(); ++n ) + { + OUString sSubNodeName( sNodes + m_sPathDelimiter + aNodes[n] ); + ReadNode( sSubNodeName, _eType == NT_Group ? NT_Page : NT_Option ); + } + } + } +} + +// ----------------------------------------------------------------------- + +OUString getGroupPath( const OUString& _rGroup ) +{ + return OUString( ROOT_NODE + OUString('/') + _rGroup + OUString('/') ); +} +OUString getPagePath( const OUString& _rPage ) +{ + return OUString( PAGES_NODE + OUString('/') + _rPage + OUString('/') ); +} +OUString getOptionPath( const OUString& _rOption ) +{ + return OUString( OPTIONS_NODE + OUString('/') + _rOption + OUString('/') ); +} + +// ----------------------------------------------------------------------- + +sal_Bool SvtOptionsDlgOptions_Impl::IsHidden( const OUString& _rPath ) const +{ + sal_Bool bRet = sal_False; + OptionNodeList::const_iterator pIter = m_aOptionNodeList.find( _rPath ); + if ( pIter != m_aOptionNodeList.end() ) + bRet = pIter->second; + return bRet; +} + +// ----------------------------------------------------------------------- + +sal_Bool SvtOptionsDlgOptions_Impl::IsGroupHidden( const OUString& _rGroup ) const +{ + return IsHidden( getGroupPath( _rGroup ) ); +} + +// ----------------------------------------------------------------------- + +sal_Bool SvtOptionsDlgOptions_Impl::IsPageHidden( const OUString& _rPage, const OUString& _rGroup ) const +{ + return IsHidden( getGroupPath( _rGroup ) + getPagePath( _rPage ) ); +} + +// ----------------------------------------------------------------------- + +sal_Bool SvtOptionsDlgOptions_Impl::IsOptionHidden( + const OUString& _rOption, const OUString& _rPage, const OUString& _rGroup ) const +{ + return IsHidden( getGroupPath( _rGroup ) + getPagePath( _rPage ) + getOptionPath( _rOption ) ); +} + +// ----------------------------------------------------------------------- + +SvtOptionsDialogOptions::SvtOptionsDialogOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( SvtOptionsDlgOptions_Impl::getInitMutex() ); + ++nRefCount; + if ( !pOptions ) + { + pOptions = new SvtOptionsDlgOptions_Impl; + + ItemHolder1::holdConfigItem( E_OPTIONSDLGOPTIONS ); + } + m_pImp = pOptions; +} + +// ----------------------------------------------------------------------- + +SvtOptionsDialogOptions::~SvtOptionsDialogOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( SvtOptionsDlgOptions_Impl::getInitMutex() ); + if ( !--nRefCount ) + { + if ( pOptions->IsModified() ) + pOptions->Commit(); + DELETEZ( pOptions ); + } +} + +sal_Bool SvtOptionsDialogOptions::IsGroupHidden( const String& _rGroup ) const +{ + return m_pImp->IsGroupHidden( _rGroup ); +} + +sal_Bool SvtOptionsDialogOptions::IsPageHidden( const String& _rPage, const String& _rGroup ) const +{ + return m_pImp->IsPageHidden( _rPage, _rGroup ); +} + +sal_Bool SvtOptionsDialogOptions::IsOptionHidden( + const String& _rOption, const String& _rPage, const String& _rGroup ) const +{ + return m_pImp->IsOptionHidden( _rOption, _rPage, _rGroup ); +} + diff --git a/unotools/source/config/optionsdrawinglayer.cxx b/unotools/source/config/optionsdrawinglayer.cxx new file mode 100644 index 000000000000..c15f5a97e435 --- /dev/null +++ b/unotools/source/config/optionsdrawinglayer.cxx @@ -0,0 +1,1705 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/optionsdrawinglayer.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_START OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Drawinglayer" )) +#define DEFAULT_OVERLAYBUFFER sal_True +#define DEFAULT_PAINTBUFFER sal_True +#define DEFAULT_STRIPE_COLOR_A 0 +#define DEFAULT_STRIPE_COLOR_B 16581375 +#define DEFAULT_STRIPE_LENGTH 4 + +// #i73602# +// #i74769#, #i75172# : Change default for Calc and Writer to True +#define DEFAULT_OVERLAYBUFFER_CALC sal_True +#define DEFAULT_OVERLAYBUFFER_WRITER sal_True +#define DEFAULT_OVERLAYBUFFER_DRAWIMPRESS sal_True + +// #i74769#, #i75172# +#define DEFAULT_PAINTBUFFER_CALC sal_True +#define DEFAULT_PAINTBUFFER_WRITER sal_True +#define DEFAULT_PAINTBUFFER_DRAWIMPRESS sal_True + +// #i4219# +#define DEFAULT_MAXIMUMPAPERWIDTH 300 +#define DEFAULT_MAXIMUMPAPERHEIGHT 300 +#define DEFAULT_MAXIMUMPAPERLEFTMARGIN 9999 +#define DEFAULT_MAXIMUMPAPERRIGHTMARGIN 9999 +#define DEFAULT_MAXIMUMPAPERTOPMARGIN 9999 +#define DEFAULT_MAXIMUMPAPERBOTTOMMARGIN 9999 + +// primitives +#define DEFAULT_ANTIALIASING sal_True +#define DEFAULT_SNAPHORVERLINESTODISCRETE sal_True +#define DEFAULT_SOLIDDRAGCREATE sal_True +#define DEFAULT_RENDERDECORATEDTEXTDIRECT sal_True +#define DEFAULT_RENDERSIMPLETEXTDIRECT sal_True +#define DEFAULT_QUADRATIC3DRENDERLIMIT 1000000 +#define DEFAULT_QUADRATICFORMCONTROLRENDERLIMIT 45000 + +// #i97672# selection settings +#define DEFAULT_TRANSPARENTSELECTION sal_True +#define DEFAULT_TRANSPARENTSELECTIONPERCENT 75 +#define DEFAULT_SELECTIONMAXIMUMLUMINANCEPERCENT 70 + +#define PROPERTYNAME_OVERLAYBUFFER OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer" )) +#define PROPERTYNAME_PAINTBUFFER OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer" )) +#define PROPERTYNAME_STRIPE_COLOR_A OUString(RTL_CONSTASCII_USTRINGPARAM("StripeColorA" )) +#define PROPERTYNAME_STRIPE_COLOR_B OUString(RTL_CONSTASCII_USTRINGPARAM("StripeColorB" )) +#define PROPERTYNAME_STRIPE_LENGTH OUString(RTL_CONSTASCII_USTRINGPARAM("StripeLength" )) + +// #i73602# +#define PROPERTYNAME_OVERLAYBUFFER_CALC OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer_Calc")) +#define PROPERTYNAME_OVERLAYBUFFER_WRITER OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer_Writer")) +#define PROPERTYNAME_OVERLAYBUFFER_DRAWIMPRESS OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer_DrawImpress")) + +// #i74769#, #i75172# +#define PROPERTYNAME_PAINTBUFFER_CALC OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer_Calc")) +#define PROPERTYNAME_PAINTBUFFER_WRITER OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer_Writer")) +#define PROPERTYNAME_PAINTBUFFER_DRAWIMPRESS OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer_DrawImpress")) + +// #i4219# +#define PROPERTYNAME_MAXIMUMPAPERWIDTH OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperWidth")) +#define PROPERTYNAME_MAXIMUMPAPERHEIGHT OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperHeight")) +#define PROPERTYNAME_MAXIMUMPAPERLEFTMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperLeftMargin")) +#define PROPERTYNAME_MAXIMUMPAPERRIGHTMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperRightMargin")) +#define PROPERTYNAME_MAXIMUMPAPERTOPMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperTopMargin")) +#define PROPERTYNAME_MAXIMUMPAPERBOTTOMMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperBottomMargin")) + +// primitives +#define PROPERTYNAME_ANTIALIASING OUString(RTL_CONSTASCII_USTRINGPARAM("AntiAliasing")) +#define PROPERTYNAME_SNAPHORVERLINESTODISCRETE OUString(RTL_CONSTASCII_USTRINGPARAM("SnapHorVerLinesToDiscrete")) +#define PROPERTYNAME_SOLIDDRAGCREATE OUString(RTL_CONSTASCII_USTRINGPARAM("SolidDragCreate")) +#define PROPERTYNAME_RENDERDECORATEDTEXTDIRECT OUString(RTL_CONSTASCII_USTRINGPARAM("RenderDecoratedTextDirect")) +#define PROPERTYNAME_RENDERSIMPLETEXTDIRECT OUString(RTL_CONSTASCII_USTRINGPARAM("RenderSimpleTextDirect")) +#define PROPERTYNAME_QUADRATIC3DRENDERLIMIT OUString(RTL_CONSTASCII_USTRINGPARAM("Quadratic3DRenderLimit")) +#define PROPERTYNAME_QUADRATICFORMCONTROLRENDERLIMIT OUString(RTL_CONSTASCII_USTRINGPARAM("QuadraticFormControlRenderLimit")) + +// #i97672# selection settings +#define PROPERTYNAME_TRANSPARENTSELECTION OUString(RTL_CONSTASCII_USTRINGPARAM("TransparentSelection")) +#define PROPERTYNAME_TRANSPARENTSELECTIONPERCENT OUString(RTL_CONSTASCII_USTRINGPARAM("TransparentSelectionPercent")) +#define PROPERTYNAME_SELECTIONMAXIMUMLUMINANCEPERCENT OUString(RTL_CONSTASCII_USTRINGPARAM("SelectionMaximumLuminancePercent")) + +#define PROPERTYHANDLE_OVERLAYBUFFER 0 +#define PROPERTYHANDLE_PAINTBUFFER 1 +#define PROPERTYHANDLE_STRIPE_COLOR_A 2 +#define PROPERTYHANDLE_STRIPE_COLOR_B 3 +#define PROPERTYHANDLE_STRIPE_LENGTH 4 + +// #i73602# +#define PROPERTYHANDLE_OVERLAYBUFFER_CALC 5 +#define PROPERTYHANDLE_OVERLAYBUFFER_WRITER 6 +#define PROPERTYHANDLE_OVERLAYBUFFER_DRAWIMPRESS 7 + +// #i74769#, #i75172# +#define PROPERTYHANDLE_PAINTBUFFER_CALC 8 +#define PROPERTYHANDLE_PAINTBUFFER_WRITER 9 +#define PROPERTYHANDLE_PAINTBUFFER_DRAWIMPRESS 10 + +// #i4219# +#define PROPERTYHANDLE_MAXIMUMPAPERWIDTH 11 +#define PROPERTYHANDLE_MAXIMUMPAPERHEIGHT 12 +#define PROPERTYHANDLE_MAXIMUMPAPERLEFTMARGIN 13 +#define PROPERTYHANDLE_MAXIMUMPAPERRIGHTMARGIN 14 +#define PROPERTYHANDLE_MAXIMUMPAPERTOPMARGIN 15 +#define PROPERTYHANDLE_MAXIMUMPAPERBOTTOMMARGIN 16 + +// primitives +#define PROPERTYHANDLE_ANTIALIASING 17 +#define PROPERTYHANDLE_SNAPHORVERLINESTODISCRETE 18 +#define PROPERTYHANDLE_SOLIDDRAGCREATE 19 +#define PROPERTYHANDLE_RENDERDECORATEDTEXTDIRECT 20 +#define PROPERTYHANDLE_RENDERSIMPLETEXTDIRECT 21 +#define PROPERTYHANDLE_QUADRATIC3DRENDERLIMIT 22 +#define PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT 23 + +// #i97672# selection settings +#define PROPERTYHANDLE_TRANSPARENTSELECTION 24 +#define PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT 25 +#define PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT 26 + +#define PROPERTYCOUNT 27 + +class SvtOptionsDrawinglayer_Impl : public ConfigItem +{ +public: + +//--------------------------------------------------------------------------------------------------------- +// constructor / destructor +//--------------------------------------------------------------------------------------------------------- + + SvtOptionsDrawinglayer_Impl(); + ~SvtOptionsDrawinglayer_Impl(); + +//--------------------------------------------------------------------------------------------------------- +// overloaded methods of baseclass +//--------------------------------------------------------------------------------------------------------- + + virtual void Commit(); + +//--------------------------------------------------------------------------------------------------------- +// public interface +//--------------------------------------------------------------------------------------------------------- + + sal_Bool IsOverlayBuffer() const; + sal_Bool IsPaintBuffer() const; + Color GetStripeColorA() const; + Color GetStripeColorB() const; + sal_uInt16 GetStripeLength() const; + + // #i73602# + sal_Bool IsOverlayBuffer_Calc() const; + sal_Bool IsOverlayBuffer_Writer() const; + sal_Bool IsOverlayBuffer_DrawImpress() const; + + // #i74769#, #i75172# + sal_Bool IsPaintBuffer_Calc() const; + sal_Bool IsPaintBuffer_Writer() const; + sal_Bool IsPaintBuffer_DrawImpress() const; + + void SetOverlayBuffer( sal_Bool bState ); + void SetPaintBuffer( sal_Bool bState ); + void SetStripeColorA( Color aColor ); + void SetStripeColorB( Color aColor ); + void SetStripeLength( sal_uInt16 nLength ); + + // #i73602# + void SetOverlayBuffer_Calc( sal_Bool bState ); + void SetOverlayBuffer_Writer( sal_Bool bState ); + void SetOverlayBuffer_DrawImpress( sal_Bool bState ); + + // #i74769#, #i75172# + void SetPaintBuffer_Calc( sal_Bool bState ); + void SetPaintBuffer_Writer( sal_Bool bState ); + void SetPaintBuffer_DrawImpress( sal_Bool bState ); + + // #i4219# + sal_uInt32 GetMaximumPaperWidth() const; + sal_uInt32 GetMaximumPaperHeight() const; + sal_uInt32 GetMaximumPaperLeftMargin() const; + sal_uInt32 GetMaximumPaperRightMargin() const; + sal_uInt32 GetMaximumPaperTopMargin() const; + sal_uInt32 GetMaximumPaperBottomMargin() const; + + void SetMaximumPaperWidth(sal_uInt32 nNew); + void SetMaximumPaperHeight(sal_uInt32 nNew); + void SetMaximumPaperLeftMargin(sal_uInt32 nNew); + void SetMaximumPaperRightMargin(sal_uInt32 nNew); + void SetMaximumPaperTopMargin(sal_uInt32 nNew); + void SetMaximumPaperBottomMargin(sal_uInt32 nNew); + + // helper + sal_Bool IsAAPossibleOnThisSystem() const; + + // primitives + sal_Bool IsAntiAliasing() const; + sal_Bool IsSnapHorVerLinesToDiscrete() const; + sal_Bool IsSolidDragCreate() const; + sal_Bool IsRenderDecoratedTextDirect() const; + sal_Bool IsRenderSimpleTextDirect() const; + sal_uInt32 GetQuadratic3DRenderLimit() const; + sal_uInt32 GetQuadraticFormControlRenderLimit() const; + + void SetAntiAliasing( sal_Bool bState ); + void SetSnapHorVerLinesToDiscrete( sal_Bool bState ); + void SetSolidDragCreate( sal_Bool bState ); + void SetRenderDecoratedTextDirect( sal_Bool bState ); + void SetRenderSimpleTextDirect( sal_Bool bState ); + void SetQuadratic3DRenderLimit(sal_uInt32 nNew); + void SetQuadraticFormControlRenderLimit(sal_uInt32 nNew); + + // #i97672# selection settings + sal_Bool IsTransparentSelection() const; + sal_uInt16 GetTransparentSelectionPercent() const; + sal_uInt16 GetSelectionMaximumLuminancePercent() const; + + void SetTransparentSelection( sal_Bool bState ); + void SetTransparentSelectionPercent( sal_uInt16 nPercent ); + void SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent ); + +//------------------------------------------------------------------------------------------------------------- +// private methods +//------------------------------------------------------------------------------------------------------------- + +private: + + static Sequence< OUString > impl_GetPropertyNames(); + +//------------------------------------------------------------------------------------------------------------- +// private member +//------------------------------------------------------------------------------------------------------------- + +private: + + sal_Bool m_bOverlayBuffer; + sal_Bool m_bPaintBuffer; + Color m_bStripeColorA; + Color m_bStripeColorB; + sal_uInt16 m_nStripeLength; + + // #i73602# + sal_Bool m_bOverlayBuffer_Calc; + sal_Bool m_bOverlayBuffer_Writer; + sal_Bool m_bOverlayBuffer_DrawImpress; + + // #i74769#, #i75172# + sal_Bool m_bPaintBuffer_Calc; + sal_Bool m_bPaintBuffer_Writer; + sal_Bool m_bPaintBuffer_DrawImpress; + + // #i4219# + sal_uInt32 m_nMaximumPaperWidth; + sal_uInt32 m_nMaximumPaperHeight; + sal_uInt32 m_nMaximumPaperLeftMargin; + sal_uInt32 m_nMaximumPaperRightMargin; + sal_uInt32 m_nMaximumPaperTopMargin; + sal_uInt32 m_nMaximumPaperBottomMargin; + + // primitives + sal_Bool m_bAntiAliasing; + sal_Bool m_bSnapHorVerLinesToDiscrete; + sal_Bool m_bSolidDragCreate; + sal_Bool m_bRenderDecoratedTextDirect; + sal_Bool m_bRenderSimpleTextDirect; + sal_uInt32 m_nQuadratic3DRenderLimit; + sal_uInt32 m_nQuadraticFormControlRenderLimit; + + // #i97672# selection settings + sal_uInt16 m_nTransparentSelectionPercent; + sal_uInt16 m_nSelectionMaximumLuminancePercent; + sal_Bool m_bTransparentSelection; + + // local values + bool m_bAllowAA : 1; + bool m_bAllowAAChecked : 1; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl() : + ConfigItem( ROOTNODE_START ), + m_bOverlayBuffer( DEFAULT_OVERLAYBUFFER ), + m_bPaintBuffer( DEFAULT_PAINTBUFFER ), + m_bStripeColorA(Color(DEFAULT_STRIPE_COLOR_A)), + m_bStripeColorB(Color(DEFAULT_STRIPE_COLOR_B)), + m_nStripeLength(DEFAULT_STRIPE_LENGTH), + + // #i73602# + m_bOverlayBuffer_Calc( DEFAULT_OVERLAYBUFFER_CALC ), + m_bOverlayBuffer_Writer( DEFAULT_OVERLAYBUFFER_WRITER ), + m_bOverlayBuffer_DrawImpress( DEFAULT_OVERLAYBUFFER_DRAWIMPRESS ), + + // #i74769#, #i75172# + m_bPaintBuffer_Calc( DEFAULT_PAINTBUFFER_CALC ), + m_bPaintBuffer_Writer( DEFAULT_PAINTBUFFER_WRITER ), + m_bPaintBuffer_DrawImpress( DEFAULT_PAINTBUFFER_DRAWIMPRESS ), + + // #i4219# + m_nMaximumPaperWidth(DEFAULT_MAXIMUMPAPERWIDTH), + m_nMaximumPaperHeight(DEFAULT_MAXIMUMPAPERHEIGHT), + m_nMaximumPaperLeftMargin(DEFAULT_MAXIMUMPAPERLEFTMARGIN), + m_nMaximumPaperRightMargin(DEFAULT_MAXIMUMPAPERRIGHTMARGIN), + m_nMaximumPaperTopMargin(DEFAULT_MAXIMUMPAPERTOPMARGIN), + m_nMaximumPaperBottomMargin(DEFAULT_MAXIMUMPAPERBOTTOMMARGIN), + + // primitives + m_bAntiAliasing(DEFAULT_ANTIALIASING), + m_bSnapHorVerLinesToDiscrete(DEFAULT_SNAPHORVERLINESTODISCRETE), + m_bSolidDragCreate(DEFAULT_SOLIDDRAGCREATE), + m_bRenderDecoratedTextDirect(DEFAULT_RENDERDECORATEDTEXTDIRECT), + m_bRenderSimpleTextDirect(DEFAULT_RENDERSIMPLETEXTDIRECT), + m_nQuadratic3DRenderLimit(DEFAULT_QUADRATIC3DRENDERLIMIT), + m_nQuadraticFormControlRenderLimit(DEFAULT_QUADRATICFORMCONTROLRENDERLIMIT), + + // #i97672# selection settings + m_nTransparentSelectionPercent(DEFAULT_TRANSPARENTSELECTIONPERCENT), + m_nSelectionMaximumLuminancePercent(DEFAULT_SELECTIONMAXIMUMLUMINANCEPERCENT), + m_bTransparentSelection(DEFAULT_TRANSPARENTSELECTION), + + // local values + m_bAllowAA(true), + m_bAllowAAChecked(false) +{ + Sequence< OUString > seqNames( impl_GetPropertyNames() ); + Sequence< Any > seqValues = GetProperties( seqNames ) ; + + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + sal_Int32 nProperty = 0; + + for( nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nInvalid property value for property detected!\n" ); + + switch( nProperty ) + { + case PROPERTYHANDLE_OVERLAYBUFFER: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer\"?" ); + seqValues[nProperty] >>= m_bOverlayBuffer; + } + break; + + case PROPERTYHANDLE_PAINTBUFFER: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer\"?" ); + seqValues[nProperty] >>= m_bPaintBuffer; + } + break; + + case PROPERTYHANDLE_STRIPE_COLOR_A: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\StripeColorA\"?" ); + sal_Int32 nValue = 0; + seqValues[nProperty] >>= nValue; + m_bStripeColorA = nValue; + } + break; + + case PROPERTYHANDLE_STRIPE_COLOR_B: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\StripeColorB\"?" ); + sal_Int32 nValue = 0; + seqValues[nProperty] >>= nValue; + m_bStripeColorB = nValue; + } + break; + + case PROPERTYHANDLE_STRIPE_LENGTH: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\StripeLength\"?" ); + seqValues[nProperty] >>= m_nStripeLength; + } + break; + + // #i73602# + case PROPERTYHANDLE_OVERLAYBUFFER_CALC: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer_Calc\"?" ); + seqValues[nProperty] >>= m_bOverlayBuffer_Calc; + } + break; + + case PROPERTYHANDLE_OVERLAYBUFFER_WRITER: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer_Writer\"?" ); + seqValues[nProperty] >>= m_bOverlayBuffer_Writer; + } + break; + + case PROPERTYHANDLE_OVERLAYBUFFER_DRAWIMPRESS: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer_DrawImpress\"?" ); + seqValues[nProperty] >>= m_bOverlayBuffer_DrawImpress; + } + break; + + // #i74769#, #i75172# + case PROPERTYHANDLE_PAINTBUFFER_CALC: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer_Calc\"?" ); + seqValues[nProperty] >>= m_bPaintBuffer_Calc; + } + break; + + case PROPERTYHANDLE_PAINTBUFFER_WRITER: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer_Writer\"?" ); + seqValues[nProperty] >>= m_bPaintBuffer_Writer; + } + break; + + case PROPERTYHANDLE_PAINTBUFFER_DRAWIMPRESS: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer_DrawImpress\"?" ); + seqValues[nProperty] >>= m_bPaintBuffer_DrawImpress; + } + break; + + // #i4219# + case PROPERTYHANDLE_MAXIMUMPAPERWIDTH: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperWidth\"?" ); + seqValues[nProperty] >>= m_nMaximumPaperWidth; + } + break; + + case PROPERTYHANDLE_MAXIMUMPAPERHEIGHT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperHeight\"?" ); + seqValues[nProperty] >>= m_nMaximumPaperHeight; + } + break; + + case PROPERTYHANDLE_MAXIMUMPAPERLEFTMARGIN: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperLeftMargin\"?" ); + seqValues[nProperty] >>= m_nMaximumPaperLeftMargin; + } + break; + + case PROPERTYHANDLE_MAXIMUMPAPERRIGHTMARGIN: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperRightMargin\"?" ); + seqValues[nProperty] >>= m_nMaximumPaperRightMargin; + } + break; + + case PROPERTYHANDLE_MAXIMUMPAPERTOPMARGIN: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperTopMargin\"?" ); + seqValues[nProperty] >>= m_nMaximumPaperTopMargin; + } + break; + + case PROPERTYHANDLE_MAXIMUMPAPERBOTTOMMARGIN: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperBottomMargin\"?" ); + seqValues[nProperty] >>= m_nMaximumPaperBottomMargin; + } + break; + + // primitives + case PROPERTYHANDLE_ANTIALIASING: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\AntiAliasing\"?" ); + seqValues[nProperty] >>= m_bAntiAliasing; + } + break; + + // primitives + case PROPERTYHANDLE_SNAPHORVERLINESTODISCRETE: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\SnapHorVerLinesToDiscrete\"?" ); + seqValues[nProperty] >>= m_bSnapHorVerLinesToDiscrete; + } + break; + + case PROPERTYHANDLE_SOLIDDRAGCREATE: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\SolidDragCreate\"?" ); + seqValues[nProperty] >>= m_bSolidDragCreate; + } + break; + + case PROPERTYHANDLE_RENDERDECORATEDTEXTDIRECT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\RenderDecoratedTextDirect\"?" ); + seqValues[nProperty] >>= m_bRenderDecoratedTextDirect; + } + break; + + case PROPERTYHANDLE_RENDERSIMPLETEXTDIRECT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\RenderSimpleTextDirect\"?" ); + seqValues[nProperty] >>= m_bRenderSimpleTextDirect; + } + break; + + case PROPERTYHANDLE_QUADRATIC3DRENDERLIMIT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\Quadratic3DRenderLimit\"?" ); + seqValues[nProperty] >>= m_nQuadratic3DRenderLimit; + } + break; + + case PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\QuadraticFormControlRenderLimit\"?" ); + seqValues[nProperty] >>= m_nQuadraticFormControlRenderLimit; + } + break; + + // #i97672# selection settings + case PROPERTYHANDLE_TRANSPARENTSELECTION: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\TransparentSelection\"?" ); + seqValues[nProperty] >>= m_bTransparentSelection; + } + break; + + case PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\TransparentSelectionPercent\"?" ); + seqValues[nProperty] >>= m_nTransparentSelectionPercent; + } + + case PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\SelectionMaximumLuminancePercent\"?" ); + seqValues[nProperty] >>= m_nSelectionMaximumLuminancePercent; + } + break; + } + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtOptionsDrawinglayer_Impl::~SvtOptionsDrawinglayer_Impl() +{ + if( IsModified() ) + Commit(); +} + +//***************************************************************************************************************** +// Commit +//***************************************************************************************************************** +void SvtOptionsDrawinglayer_Impl::Commit() +{ + Sequence< OUString > aSeqNames( impl_GetPropertyNames() ); + Sequence< Any > aSeqValues( aSeqNames.getLength() ); + + for( sal_Int32 nProperty = 0, nCount = aSeqNames.getLength(); nProperty < nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_OVERLAYBUFFER: + aSeqValues[nProperty] <<= m_bOverlayBuffer; + break; + + case PROPERTYHANDLE_PAINTBUFFER: + aSeqValues[nProperty] <<= m_bPaintBuffer; + break; + + case PROPERTYHANDLE_STRIPE_COLOR_A: + aSeqValues[nProperty] <<= m_bStripeColorA.GetColor(); + break; + + case PROPERTYHANDLE_STRIPE_COLOR_B: + aSeqValues[nProperty] <<= m_bStripeColorB.GetColor(); + break; + + case PROPERTYHANDLE_STRIPE_LENGTH: + aSeqValues[nProperty] <<= m_nStripeLength; + break; + + // #i73602# + case PROPERTYHANDLE_OVERLAYBUFFER_CALC: + aSeqValues[nProperty] <<= m_bOverlayBuffer_Calc; + break; + + case PROPERTYHANDLE_OVERLAYBUFFER_WRITER: + aSeqValues[nProperty] <<= m_bOverlayBuffer_Writer; + break; + + case PROPERTYHANDLE_OVERLAYBUFFER_DRAWIMPRESS: + aSeqValues[nProperty] <<= m_bOverlayBuffer_DrawImpress; + break; + + // #i74769#, #i75172# + case PROPERTYHANDLE_PAINTBUFFER_CALC: + aSeqValues[nProperty] <<= m_bPaintBuffer_Calc; + break; + + case PROPERTYHANDLE_PAINTBUFFER_WRITER: + aSeqValues[nProperty] <<= m_bPaintBuffer_Writer; + break; + + case PROPERTYHANDLE_PAINTBUFFER_DRAWIMPRESS: + aSeqValues[nProperty] <<= m_bPaintBuffer_DrawImpress; + break; + + // #i4219# + case PROPERTYHANDLE_MAXIMUMPAPERWIDTH: + aSeqValues[nProperty] <<= m_nMaximumPaperWidth; + break; + + case PROPERTYHANDLE_MAXIMUMPAPERHEIGHT: + aSeqValues[nProperty] <<= m_nMaximumPaperHeight; + break; + + case PROPERTYHANDLE_MAXIMUMPAPERLEFTMARGIN: + aSeqValues[nProperty] <<= m_nMaximumPaperLeftMargin; + break; + + case PROPERTYHANDLE_MAXIMUMPAPERRIGHTMARGIN: + aSeqValues[nProperty] <<= m_nMaximumPaperRightMargin; + break; + + case PROPERTYHANDLE_MAXIMUMPAPERTOPMARGIN: + aSeqValues[nProperty] <<= m_nMaximumPaperTopMargin; + break; + + case PROPERTYHANDLE_MAXIMUMPAPERBOTTOMMARGIN: + aSeqValues[nProperty] <<= m_nMaximumPaperBottomMargin; + break; + + // primitives + case PROPERTYHANDLE_ANTIALIASING: + aSeqValues[nProperty] <<= m_bAntiAliasing; + break; + + case PROPERTYHANDLE_SNAPHORVERLINESTODISCRETE: + aSeqValues[nProperty] <<= m_bSnapHorVerLinesToDiscrete; + break; + + case PROPERTYHANDLE_SOLIDDRAGCREATE: + aSeqValues[nProperty] <<= m_bSolidDragCreate; + break; + + case PROPERTYHANDLE_RENDERDECORATEDTEXTDIRECT: + aSeqValues[nProperty] <<= m_bRenderDecoratedTextDirect; + break; + + case PROPERTYHANDLE_RENDERSIMPLETEXTDIRECT: + aSeqValues[nProperty] <<= m_bRenderSimpleTextDirect; + break; + + case PROPERTYHANDLE_QUADRATIC3DRENDERLIMIT: + aSeqValues[nProperty] <<= m_nQuadratic3DRenderLimit; + break; + + case PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT: + aSeqValues[nProperty] <<= m_nQuadraticFormControlRenderLimit; + break; + + // #i97672# selection settings + case PROPERTYHANDLE_TRANSPARENTSELECTION: + aSeqValues[nProperty] <<= m_bTransparentSelection; + break; + + case PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT: + aSeqValues[nProperty] <<= m_nTransparentSelectionPercent; + break; + + case PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT: + aSeqValues[nProperty] <<= m_nSelectionMaximumLuminancePercent; + break; + } + } + + PutProperties( aSeqNames, aSeqValues ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer() const +{ + return m_bOverlayBuffer; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer() const +{ + return m_bPaintBuffer; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Color SvtOptionsDrawinglayer_Impl::GetStripeColorA() const +{ + return m_bStripeColorA; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Color SvtOptionsDrawinglayer_Impl::GetStripeColorB() const +{ + return m_bStripeColorB; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_uInt16 SvtOptionsDrawinglayer_Impl::GetStripeLength() const +{ + return m_nStripeLength; +} + +// #i73602# +sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer_Calc() const +{ + return m_bOverlayBuffer_Calc; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer_Writer() const +{ + return m_bOverlayBuffer_Writer; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer_DrawImpress() const +{ + return m_bOverlayBuffer_DrawImpress; +} + +// #i74769#, #i75172# +sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer_Calc() const +{ + return m_bPaintBuffer_Calc; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer_Writer() const +{ + return m_bPaintBuffer_Writer; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer_DrawImpress() const +{ + return m_bPaintBuffer_DrawImpress; +} + +// #i4219# +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperWidth() const +{ + return m_nMaximumPaperWidth; +} + +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperHeight() const +{ + return m_nMaximumPaperHeight; +} + +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperLeftMargin() const +{ + return m_nMaximumPaperLeftMargin; +} + +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperRightMargin() const +{ + return m_nMaximumPaperRightMargin; +} + +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperTopMargin() const +{ + return m_nMaximumPaperTopMargin; +} + +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperBottomMargin() const +{ + return m_nMaximumPaperBottomMargin; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer( sal_Bool bState ) +{ + if(m_bOverlayBuffer != bState) + { + m_bOverlayBuffer = bState; + SetModified(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer_Impl::SetPaintBuffer( sal_Bool bState ) +{ + if(m_bPaintBuffer != bState) + { + m_bPaintBuffer = bState; + SetModified(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer_Impl::SetStripeColorA( Color aColor ) +{ + if(m_bStripeColorA != aColor) + { + m_bStripeColorA = aColor; + SetModified(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer_Impl::SetStripeColorB( Color aColor ) +{ + if(m_bStripeColorB != aColor) + { + m_bStripeColorB = aColor; + SetModified(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer_Impl::SetStripeLength( sal_uInt16 nLength ) +{ + if(m_nStripeLength != nLength) + { + m_nStripeLength = nLength; + SetModified(); + } +} + +// #i73602# +void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer_Calc( sal_Bool bState ) +{ + if(m_bOverlayBuffer_Calc != bState) + { + m_bOverlayBuffer_Calc = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer_Writer( sal_Bool bState ) +{ + if(m_bOverlayBuffer_Writer != bState) + { + m_bOverlayBuffer_Writer = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer_DrawImpress( sal_Bool bState ) +{ + if(m_bOverlayBuffer_DrawImpress != bState) + { + m_bOverlayBuffer_DrawImpress = bState; + SetModified(); + } +} + +// #i74769#, #i75172# +void SvtOptionsDrawinglayer_Impl::SetPaintBuffer_Calc( sal_Bool bState ) +{ + if(m_bPaintBuffer_Calc != bState) + { + m_bPaintBuffer_Calc = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetPaintBuffer_Writer( sal_Bool bState ) +{ + if(m_bPaintBuffer_Writer != bState) + { + m_bPaintBuffer_Writer = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetPaintBuffer_DrawImpress( sal_Bool bState ) +{ + if(m_bPaintBuffer_DrawImpress != bState) + { + m_bPaintBuffer_DrawImpress = bState; + SetModified(); + } +} + +// #i4219# +void SvtOptionsDrawinglayer_Impl::SetMaximumPaperWidth( sal_uInt32 nNew ) +{ + if(m_nMaximumPaperWidth != nNew) + { + m_nMaximumPaperWidth = nNew; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetMaximumPaperHeight( sal_uInt32 nNew ) +{ + if(m_nMaximumPaperHeight != nNew) + { + m_nMaximumPaperHeight = nNew; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetMaximumPaperLeftMargin( sal_uInt32 nNew ) +{ + if(m_nMaximumPaperLeftMargin != nNew) + { + m_nMaximumPaperLeftMargin = nNew; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetMaximumPaperRightMargin( sal_uInt32 nNew ) +{ + if(m_nMaximumPaperRightMargin != nNew) + { + m_nMaximumPaperRightMargin = nNew; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetMaximumPaperTopMargin( sal_uInt32 nNew ) +{ + if(m_nMaximumPaperTopMargin != nNew) + { + m_nMaximumPaperTopMargin = nNew; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetMaximumPaperBottomMargin( sal_uInt32 nNew ) +{ + if(m_nMaximumPaperBottomMargin != nNew) + { + m_nMaximumPaperBottomMargin = nNew; + SetModified(); + } +} + +// helper +sal_Bool SvtOptionsDrawinglayer_Impl::IsAAPossibleOnThisSystem() const +{ + if(!m_bAllowAAChecked) + { + SvtOptionsDrawinglayer_Impl* pThat = const_cast< SvtOptionsDrawinglayer_Impl* >(this); + pThat->m_bAllowAAChecked = true; + +#ifdef WIN32 + // WIN32 uses GDIPlus with VCL forthe first incarnation; this will be enhanced + // in the future to use canvases and the canvas renderer, thus a AA-abled + // canvas needs to be checked here in the future. + // Currently, just allow AA for WIN32 +#endif + + // check XRenderExtension + if(m_bAllowAA && !Application::GetDefaultDevice()->supportsOperation( OutDevSupport_TransparentRect )) + { + pThat->m_bAllowAA = false; + } + } + + return m_bAllowAA; +} + +// primitives +sal_Bool SvtOptionsDrawinglayer_Impl::IsAntiAliasing() const +{ + return m_bAntiAliasing; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsSnapHorVerLinesToDiscrete() const +{ + return m_bSnapHorVerLinesToDiscrete; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsSolidDragCreate() const +{ + return m_bSolidDragCreate; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsRenderDecoratedTextDirect() const +{ + return m_bRenderDecoratedTextDirect; +} + +sal_Bool SvtOptionsDrawinglayer_Impl::IsRenderSimpleTextDirect() const +{ + return m_bRenderSimpleTextDirect; +} + +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetQuadratic3DRenderLimit() const +{ + return m_nQuadratic3DRenderLimit; +} + +sal_uInt32 SvtOptionsDrawinglayer_Impl::GetQuadraticFormControlRenderLimit() const +{ + return m_nQuadraticFormControlRenderLimit; +} + +void SvtOptionsDrawinglayer_Impl::SetAntiAliasing( sal_Bool bState ) +{ + if(m_bAntiAliasing != bState) + { + m_bAntiAliasing = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetSnapHorVerLinesToDiscrete( sal_Bool bState ) +{ + if(m_bSnapHorVerLinesToDiscrete != bState) + { + m_bSnapHorVerLinesToDiscrete = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetSolidDragCreate( sal_Bool bState ) +{ + if(m_bSolidDragCreate != bState) + { + m_bSolidDragCreate = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetRenderDecoratedTextDirect( sal_Bool bState ) +{ + if(m_bRenderDecoratedTextDirect != bState) + { + m_bRenderDecoratedTextDirect = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetRenderSimpleTextDirect( sal_Bool bState ) +{ + if(m_bRenderSimpleTextDirect != bState) + { + m_bRenderSimpleTextDirect = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetQuadratic3DRenderLimit(sal_uInt32 nNew) +{ + if(m_nQuadratic3DRenderLimit != nNew) + { + m_nQuadratic3DRenderLimit = nNew; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetQuadraticFormControlRenderLimit(sal_uInt32 nNew) +{ + if(m_nQuadraticFormControlRenderLimit != nNew) + { + m_nQuadraticFormControlRenderLimit = nNew; + SetModified(); + } +} + +// #i97672# selection settings +sal_Bool SvtOptionsDrawinglayer_Impl::IsTransparentSelection() const +{ + return m_bTransparentSelection; +} + +void SvtOptionsDrawinglayer_Impl::SetTransparentSelection( sal_Bool bState ) +{ + if(m_bTransparentSelection != bState) + { + m_bTransparentSelection = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetTransparentSelectionPercent( sal_uInt16 nPercent ) +{ + if(m_nTransparentSelectionPercent != nPercent) + { + m_nTransparentSelectionPercent = nPercent; + SetModified(); + } +} + +sal_uInt16 SvtOptionsDrawinglayer_Impl::GetTransparentSelectionPercent() const +{ + return m_nTransparentSelectionPercent; +} + +void SvtOptionsDrawinglayer_Impl::SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent ) +{ + if(m_nSelectionMaximumLuminancePercent != nPercent) + { + m_nSelectionMaximumLuminancePercent = nPercent; + SetModified(); + } +} + +sal_uInt16 SvtOptionsDrawinglayer_Impl::GetSelectionMaximumLuminancePercent() const +{ + return m_nSelectionMaximumLuminancePercent; +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtOptionsDrawinglayer_Impl::impl_GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_OVERLAYBUFFER , + PROPERTYNAME_PAINTBUFFER , + PROPERTYNAME_STRIPE_COLOR_A , + PROPERTYNAME_STRIPE_COLOR_B , + PROPERTYNAME_STRIPE_LENGTH , + + // #i73602# + PROPERTYNAME_OVERLAYBUFFER_CALC, + PROPERTYNAME_OVERLAYBUFFER_WRITER, + PROPERTYNAME_OVERLAYBUFFER_DRAWIMPRESS, + + // #i74769#, #i75172# + PROPERTYNAME_PAINTBUFFER_CALC, + PROPERTYNAME_PAINTBUFFER_WRITER, + PROPERTYNAME_PAINTBUFFER_DRAWIMPRESS, + + // #i4219# + PROPERTYNAME_MAXIMUMPAPERWIDTH, + PROPERTYNAME_MAXIMUMPAPERHEIGHT, + PROPERTYNAME_MAXIMUMPAPERLEFTMARGIN, + PROPERTYNAME_MAXIMUMPAPERRIGHTMARGIN, + PROPERTYNAME_MAXIMUMPAPERTOPMARGIN, + PROPERTYNAME_MAXIMUMPAPERBOTTOMMARGIN, + + // primitives + PROPERTYNAME_ANTIALIASING, + PROPERTYNAME_SNAPHORVERLINESTODISCRETE, + PROPERTYNAME_SOLIDDRAGCREATE, + PROPERTYNAME_RENDERDECORATEDTEXTDIRECT, + PROPERTYNAME_RENDERSIMPLETEXTDIRECT, + PROPERTYNAME_QUADRATIC3DRENDERLIMIT, + PROPERTYNAME_QUADRATICFORMCONTROLRENDERLIMIT, + + // #i97672# selection settings + PROPERTYNAME_TRANSPARENTSELECTION, + PROPERTYNAME_TRANSPARENTSELECTIONPERCENT, + PROPERTYNAME_SELECTIONMAXIMUMLUMINANCEPERCENT + }; + + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtOptionsDrawinglayer_Impl* SvtOptionsDrawinglayer::m_pDataContainer = NULL; +sal_Int32 SvtOptionsDrawinglayer::m_nRefCount = 0; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtOptionsDrawinglayer::SvtOptionsDrawinglayer() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already! + if( m_pDataContainer == NULL ) + { + m_pDataContainer = new SvtOptionsDrawinglayer_Impl(); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtOptionsDrawinglayer::~SvtOptionsDrawinglayer() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsOverlayBuffer(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsPaintBuffer(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Color SvtOptionsDrawinglayer::GetStripeColorA() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetStripeColorA(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Color SvtOptionsDrawinglayer::GetStripeColorB() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetStripeColorB(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_uInt16 SvtOptionsDrawinglayer::GetStripeLength() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetStripeLength(); +} + +// #i73602# +sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer_Calc() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsOverlayBuffer_Calc(); +} + +sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer_Writer() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsOverlayBuffer_Writer(); +} + +sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer_DrawImpress() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsOverlayBuffer_DrawImpress(); +} + +// #i74769#, #i75172# +sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer_Calc() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsPaintBuffer_Calc(); +} + +sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer_Writer() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsPaintBuffer_Writer(); +} + +sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer_DrawImpress() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsPaintBuffer_DrawImpress(); +} + +// #i4219# +sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperWidth() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetMaximumPaperWidth(); +} + +sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperHeight() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetMaximumPaperHeight(); +} + +sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperLeftMargin() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetMaximumPaperLeftMargin(); +} + +sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperRightMargin() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetMaximumPaperRightMargin(); +} + +sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperTopMargin() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetMaximumPaperTopMargin(); +} + +sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperBottomMargin() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetMaximumPaperBottomMargin(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer::SetOverlayBuffer( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetOverlayBuffer( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer::SetPaintBuffer( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetPaintBuffer( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer::SetStripeColorA( Color aColor ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetStripeColorA( aColor ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer::SetStripeColorB( Color aColor ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetStripeColorB( aColor ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtOptionsDrawinglayer::SetStripeLength( sal_uInt16 nLength ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetStripeLength( nLength ); +} + +// #i73602# +void SvtOptionsDrawinglayer::SetOverlayBuffer_Calc( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetOverlayBuffer_Calc( bState ); +} + +void SvtOptionsDrawinglayer::SetOverlayBuffer_Writer( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetOverlayBuffer_Writer( bState ); +} + +void SvtOptionsDrawinglayer::SetOverlayBuffer_DrawImpress( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetOverlayBuffer_DrawImpress( bState ); +} + +// #i74769#, #i75172# +void SvtOptionsDrawinglayer::SetPaintBuffer_Calc( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetPaintBuffer_Calc( bState ); +} + +void SvtOptionsDrawinglayer::SetPaintBuffer_Writer( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetPaintBuffer_Writer( bState ); +} + +void SvtOptionsDrawinglayer::SetPaintBuffer_DrawImpress( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetPaintBuffer_DrawImpress( bState ); +} + +// #i4219# +void SvtOptionsDrawinglayer::SetMaximumPaperWidth( sal_uInt32 nNew ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetMaximumPaperWidth( nNew ); +} + +void SvtOptionsDrawinglayer::SetMaximumPaperHeight( sal_uInt32 nNew ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetMaximumPaperHeight( nNew ); +} + +void SvtOptionsDrawinglayer::SetMaximumPaperLeftMargin( sal_uInt32 nNew ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetMaximumPaperLeftMargin( nNew ); +} + +void SvtOptionsDrawinglayer::SetMaximumPaperRightMargin( sal_uInt32 nNew ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetMaximumPaperRightMargin( nNew ); +} + +void SvtOptionsDrawinglayer::SetMaximumPaperTopMargin( sal_uInt32 nNew ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetMaximumPaperTopMargin( nNew ); +} + +void SvtOptionsDrawinglayer::SetMaximumPaperBottomMargin( sal_uInt32 nNew ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetMaximumPaperBottomMargin( nNew ); +} + +// helper +sal_Bool SvtOptionsDrawinglayer::IsAAPossibleOnThisSystem() const +{ + return m_pDataContainer->IsAAPossibleOnThisSystem(); +} + +// primitives +sal_Bool SvtOptionsDrawinglayer::IsAntiAliasing() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsAntiAliasing() && IsAAPossibleOnThisSystem(); +} + +sal_Bool SvtOptionsDrawinglayer::IsSnapHorVerLinesToDiscrete() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsAntiAliasing() && m_pDataContainer->IsSnapHorVerLinesToDiscrete(); +} + +sal_Bool SvtOptionsDrawinglayer::IsSolidDragCreate() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsSolidDragCreate(); +} + +sal_Bool SvtOptionsDrawinglayer::IsRenderDecoratedTextDirect() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsRenderDecoratedTextDirect(); +} + +sal_Bool SvtOptionsDrawinglayer::IsRenderSimpleTextDirect() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsRenderSimpleTextDirect(); +} + +sal_uInt32 SvtOptionsDrawinglayer::GetQuadratic3DRenderLimit() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetQuadratic3DRenderLimit(); +} + +sal_uInt32 SvtOptionsDrawinglayer::GetQuadraticFormControlRenderLimit() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetQuadraticFormControlRenderLimit(); +} + +void SvtOptionsDrawinglayer::SetAntiAliasing( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetAntiAliasing( bState ); +} + +void SvtOptionsDrawinglayer::SetSnapHorVerLinesToDiscrete( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetSnapHorVerLinesToDiscrete( bState ); +} + +void SvtOptionsDrawinglayer::SetSolidDragCreate( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetSolidDragCreate( bState ); +} + +void SvtOptionsDrawinglayer::SetRenderDecoratedTextDirect( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetRenderDecoratedTextDirect( bState ); +} + +void SvtOptionsDrawinglayer::SetRenderSimpleTextDirect( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetRenderSimpleTextDirect( bState ); +} + +void SvtOptionsDrawinglayer::SetQuadratic3DRenderLimit(sal_uInt32 nNew) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetQuadratic3DRenderLimit( nNew ); +} + +void SvtOptionsDrawinglayer::SetQuadraticFormControlRenderLimit(sal_uInt32 nNew) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetQuadraticFormControlRenderLimit( nNew ); +} + +// #i97672# selection settings +sal_Bool SvtOptionsDrawinglayer::IsTransparentSelection() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsTransparentSelection(); +} + +void SvtOptionsDrawinglayer::SetTransparentSelection( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetTransparentSelection( bState ); +} + +sal_uInt16 SvtOptionsDrawinglayer::GetTransparentSelectionPercent() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + sal_uInt16 aRetval(m_pDataContainer->GetTransparentSelectionPercent()); + + // crop to range [10% .. 90%] + if(aRetval < 10) + { + aRetval = 10; + } + + if(aRetval > 90) + { + aRetval = 90; + } + + return aRetval; +} + +void SvtOptionsDrawinglayer::SetTransparentSelectionPercent( sal_uInt16 nPercent ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + + // crop to range [10% .. 90%] + if(nPercent < 10) + { + nPercent = 10; + } + + if(nPercent > 90) + { + nPercent = 90; + } + + m_pDataContainer->SetTransparentSelectionPercent( nPercent ); +} + +sal_uInt16 SvtOptionsDrawinglayer::GetSelectionMaximumLuminancePercent() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + sal_uInt16 aRetval(m_pDataContainer->GetSelectionMaximumLuminancePercent()); + + // crop to range [0% .. 100%] + if(aRetval > 90) + { + aRetval = 90; + } + + return aRetval; +} + +void SvtOptionsDrawinglayer::SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + + // crop to range [0% .. 100%] + if(nPercent > 90) + { + nPercent = 90; + } + + m_pDataContainer->SetSelectionMaximumLuminancePercent( nPercent ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtOptionsDrawinglayer::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} + +// eof + diff --git a/unotools/source/config/pathoptions.cxx b/unotools/source/config/pathoptions.cxx new file mode 100644 index 000000000000..3cf43a1f3bc9 --- /dev/null +++ b/unotools/source/config/pathoptions.cxx @@ -0,0 +1,1104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +#include <unotools/pathoptions.hxx> +#include <unotools/configitem.hxx> +#include <unotools/configmgr.hxx> +#include <tools/debug.hxx> +#include <tools/resmgr.hxx> +#include <tools/urlobj.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <osl/mutex.hxx> +#include <osl/file.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/bootstrap.hxx> + +#include <unotools/ucbhelper.hxx> +#include <vos/process.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/componentcontext.hxx> +#include <com/sun/star/beans/XFastPropertySet.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/util/XStringSubstitution.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <rtl/instance.hxx> + +#include <itemholder1.hxx> + +#include <vector> +#include <hash_map> + +using namespace osl; +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::util; +using namespace com::sun::star::lang; + +// define ---------------------------------------------------------------- + +#define SEARCHPATH_DELIMITER ';' + +#define ASCII_STR(s) OUString( RTL_CONSTASCII_USTRINGPARAM(s) ) + +#define SIGN_STARTVARIABLE ASCII_STR("$(") +#define SIGN_ENDVARIABLE ASCII_STR(")") + +// Supported variables by the old SvtPathOptions implementation +#define SUBSTITUTE_INST "$(inst)" +#define SUBSTITUTE_PROG "$(prog)" +#define SUBSTITUTE_USER "$(user)" +#define SUBSTITUTE_INSTPATH "$(instpath)" +#define SUBSTITUTE_PROGPATH "$(progpath)" +#define SUBSTITUTE_USERPATH "$(userpath)" +#define SUBSTITUTE_INSTURL "$(insturl)" +#define SUBSTITUTE_PROGURL "$(progurl)" +#define SUBSTITUTE_USERURL "$(userurl)" +#define SUBSTITUTE_PATH "$(path)" +//#define SUBSTITUTE_LANG "$(lang)" +#define SUBSTITUTE_LANGID "$(langid)" +#define SUBSTITUTE_VLANG "$(vlang)" +#define SUBSTITUTE_WORKDIRURL "$(workdirurl)" + +#define STRPOS_NOTFOUND -1 + +struct OUStringHashCode +{ + size_t operator()( const ::rtl::OUString& sString ) const + { + return sString.hashCode(); + } +}; + +enum VarNameProperty +{ + VAR_NEEDS_SYSTEM_PATH, + VAR_NEEDS_FILEURL +}; + +class NameToHandleMap : public ::std::hash_map< ::rtl::OUString, sal_Int32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > +{ + public: + inline void free() { NameToHandleMap().swap( *this ); } +}; + +class EnumToHandleMap : public ::std::hash_map< sal_Int32, sal_Int32, std::hash< sal_Int32 >, std::equal_to< sal_Int32 > > +{ + public: + inline void free() { EnumToHandleMap().swap( *this ); } +}; + +class VarNameToEnumMap : public ::std::hash_map< OUString, VarNameProperty, OUStringHashCode, ::std::equal_to< OUString > > +{ + public: + inline void free() { VarNameToEnumMap().swap( *this ); } +}; + + +// class SvtPathOptions_Impl --------------------------------------------- +class SvtPathOptions_Impl +{ + private: + // Local variables to return const references + std::vector< String > m_aPathArray; + Reference< XFastPropertySet > m_xPathSettings; + Reference< XStringSubstitution > m_xSubstVariables; + mutable EnumToHandleMap m_aMapEnumToPropHandle; + VarNameToEnumMap m_aMapVarNamesToEnum; + + ::com::sun::star::lang::Locale m_aLocale; + String m_aEmptyString; + mutable ::osl::Mutex m_aMutex; + + public: + SvtPathOptions_Impl(); + + // get the pathes, not const because of using a mutex + const String& GetPath( SvtPathOptions::Pathes ); + const String& GetAddinPath() { return GetPath( SvtPathOptions::PATH_ADDIN ); } + const String& GetAutoCorrectPath() { return GetPath( SvtPathOptions::PATH_AUTOCORRECT ); } + const String& GetAutoTextPath() { return GetPath( SvtPathOptions::PATH_AUTOTEXT ); } + const String& GetBackupPath() { return GetPath( SvtPathOptions::PATH_BACKUP ); } + const String& GetBasicPath() { return GetPath( SvtPathOptions::PATH_BASIC ); } + const String& GetBitmapPath() { return GetPath( SvtPathOptions::PATH_BITMAP ); } + const String& GetConfigPath() { return GetPath( SvtPathOptions::PATH_CONFIG ); } + const String& GetDictionaryPath() { return GetPath( SvtPathOptions::PATH_DICTIONARY ); } + const String& GetFavoritesPath() { return GetPath( SvtPathOptions::PATH_FAVORITES ); } + const String& GetFilterPath() { return GetPath( SvtPathOptions::PATH_FILTER ); } + const String& GetGalleryPath() { return GetPath( SvtPathOptions::PATH_GALLERY ); } + const String& GetGraphicPath() { return GetPath( SvtPathOptions::PATH_GRAPHIC ); } + const String& GetHelpPath() { return GetPath( SvtPathOptions::PATH_HELP ); } + const String& GetLinguisticPath() { return GetPath( SvtPathOptions::PATH_LINGUISTIC ); } + const String& GetModulePath() { return GetPath( SvtPathOptions::PATH_MODULE ); } + const String& GetPalettePath() { return GetPath( SvtPathOptions::PATH_PALETTE ); } + const String& GetPluginPath() { return GetPath( SvtPathOptions::PATH_PLUGIN ); } + const String& GetStoragePath() { return GetPath( SvtPathOptions::PATH_STORAGE ); } + const String& GetTempPath() { return GetPath( SvtPathOptions::PATH_TEMP ); } + const String& GetTemplatePath() { return GetPath( SvtPathOptions::PATH_TEMPLATE ); } + const String& GetUserConfigPath() { return GetPath( SvtPathOptions::PATH_USERCONFIG ); } + const String& GetWorkPath() { return GetPath( SvtPathOptions::PATH_WORK ); } + const String& GetUIConfigPath() { return GetPath( SvtPathOptions::PATH_UICONFIG ); } + const String& GetFingerprintPath() { return GetPath( SvtPathOptions::PATH_FINGERPRINT ); } + + // set the pathes + void SetPath( SvtPathOptions::Pathes, const String& rNewPath ); + void SetAddinPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_ADDIN, rPath ); } + void SetAutoCorrectPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_AUTOCORRECT, rPath ); } + void SetAutoTextPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_AUTOTEXT, rPath ); } + void SetBackupPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BACKUP, rPath ); } + void SetBasicPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BASIC, rPath ); } + void SetBitmapPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BITMAP, rPath ); } + void SetConfigPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_CONFIG, rPath ); } + void SetDictionaryPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_DICTIONARY, rPath ); } + void SetFavoritesPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_FAVORITES, rPath ); } + void SetFilterPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_FILTER, rPath ); } + void SetGalleryPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_GALLERY, rPath ); } + void SetGraphicPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_GRAPHIC, rPath ); } + void SetHelpPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_HELP, rPath ); } + void SetLinguisticPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_LINGUISTIC, rPath ); } + void SetModulePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_MODULE, rPath ); } + void SetPalettePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_PALETTE, rPath ); } + void SetPluginPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_PLUGIN, rPath ); } + void SetStoragePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_STORAGE, rPath ); } + void SetTempPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_TEMP, rPath ); } + void SetTemplatePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_TEMPLATE, rPath ); } + void SetUserConfigPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_USERCONFIG, rPath ); } + void SetWorkPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_WORK, rPath ); } + + rtl::OUString SubstVar( const rtl::OUString& rVar ); + rtl::OUString SubstituteAndConvert( const rtl::OUString& rPath ); + rtl::OUString UsePathVariables( const rtl::OUString& rPath ); + + ::com::sun::star::lang::Locale GetLocale() const { return m_aLocale; } + + BOOL IsPathReadonly(SvtPathOptions::Pathes ePath)const; +}; + +// global ---------------------------------------------------------------- + +static SvtPathOptions_Impl* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +// functions ------------------------------------------------------------- +struct PropertyStruct +{ + const char* pPropName; // The ascii name of the Office path + SvtPathOptions::Pathes ePath; // The enum value used by SvtPathOptions +}; + +struct VarNameAttribute +{ + const char* pVarName; // The name of the path variable + VarNameProperty eVarProperty; // Which return value is needed by this path variable +}; + +static PropertyStruct aPropNames[] = +{ + { "Addin", SvtPathOptions::PATH_ADDIN }, + { "AutoCorrect", SvtPathOptions::PATH_AUTOCORRECT }, + { "AutoText", SvtPathOptions::PATH_AUTOTEXT }, + { "Backup", SvtPathOptions::PATH_BACKUP }, + { "Basic", SvtPathOptions::PATH_BASIC }, + { "Bitmap", SvtPathOptions::PATH_BITMAP }, + { "Config", SvtPathOptions::PATH_CONFIG }, + { "Dictionary", SvtPathOptions::PATH_DICTIONARY }, + { "Favorite", SvtPathOptions::PATH_FAVORITES }, + { "Filter", SvtPathOptions::PATH_FILTER }, + { "Gallery", SvtPathOptions::PATH_GALLERY }, + { "Graphic", SvtPathOptions::PATH_GRAPHIC }, + { "Help", SvtPathOptions::PATH_HELP }, + { "Linguistic", SvtPathOptions::PATH_LINGUISTIC }, + { "Module", SvtPathOptions::PATH_MODULE }, + { "Palette", SvtPathOptions::PATH_PALETTE }, + { "Plugin", SvtPathOptions::PATH_PLUGIN }, + { "Storage", SvtPathOptions::PATH_STORAGE }, + { "Temp", SvtPathOptions::PATH_TEMP }, + { "Template", SvtPathOptions::PATH_TEMPLATE }, + { "UserConfig", SvtPathOptions::PATH_USERCONFIG }, + { "Work", SvtPathOptions::PATH_WORK }, + { "UIConfig", SvtPathOptions::PATH_UICONFIG }, + { "Fingerprint", SvtPathOptions::PATH_FINGERPRINT } +}; + +static VarNameAttribute aVarNameAttribute[] = +{ + { SUBSTITUTE_INSTPATH, VAR_NEEDS_SYSTEM_PATH }, // $(instpath) + { SUBSTITUTE_PROGPATH, VAR_NEEDS_SYSTEM_PATH }, // $(progpath) + { SUBSTITUTE_USERPATH, VAR_NEEDS_SYSTEM_PATH }, // $(userpath) + { SUBSTITUTE_PATH, VAR_NEEDS_SYSTEM_PATH }, // $(path) +}; + +#if 0 +// currently unused +static Sequence< OUString > GetPathPropertyNames() +{ + const int nCount = sizeof( aPropNames ) / sizeof( PropertyStruct ); + Sequence< OUString > aNames( nCount ); + OUString* pNames = aNames.getArray(); + for ( int i = 0; i < nCount; i++ ) + pNames[i] = OUString::createFromAscii( aPropNames[i].pPropName ); + + return aNames; +} +#endif + +// class SvtPathOptions_Impl --------------------------------------------- + +const String& SvtPathOptions_Impl::GetPath( SvtPathOptions::Pathes ePath ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( ePath < SvtPathOptions::PATH_COUNT ) + { + OUString aPathValue; + String aResult; + sal_Int32 nHandle = m_aMapEnumToPropHandle[ (sal_Int32)ePath ]; + + // Substitution is done by the service itself using the substition service + Any a = m_xPathSettings->getFastPropertyValue( nHandle ); + a >>= aPathValue; + if( ePath == SvtPathOptions::PATH_ADDIN || + ePath == SvtPathOptions::PATH_FILTER || + ePath == SvtPathOptions::PATH_HELP || + ePath == SvtPathOptions::PATH_MODULE || + ePath == SvtPathOptions::PATH_PLUGIN || + ePath == SvtPathOptions::PATH_STORAGE + ) + { + // These office paths have to be converted to system pathes + utl::LocalFileHelper::ConvertURLToPhysicalName( aPathValue, aResult ); + aPathValue = aResult; + } + + m_aPathArray[ ePath ] = aPathValue; + return m_aPathArray[ ePath ]; + } + + return m_aEmptyString; +} +// ----------------------------------------------------------------------- +BOOL SvtPathOptions_Impl::IsPathReadonly(SvtPathOptions::Pathes ePath)const +{ + ::osl::MutexGuard aGuard( m_aMutex ); + BOOL bReadonly = FALSE; + if ( ePath < SvtPathOptions::PATH_COUNT ) + { + Reference<XPropertySet> xPrSet(m_xPathSettings, UNO_QUERY); + if(xPrSet.is()) + { + Reference<XPropertySetInfo> xInfo = xPrSet->getPropertySetInfo(); + const char* pA = aPropNames[ePath].pPropName; + ::rtl::OUString sU = OUString::createFromAscii(pA); + Property aProperty = xInfo->getPropertyByName(sU); + bReadonly = 0 != (aProperty.Attributes & PropertyAttribute::READONLY); + } + } + return bReadonly; +} +// ----------------------------------------------------------------------- + +void SvtPathOptions_Impl::SetPath( SvtPathOptions::Pathes ePath, const String& rNewPath ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( ePath < SvtPathOptions::PATH_COUNT ) + { + String aResult; + OUString aNewValue; + Any a; + + switch ( ePath ) + { + case SvtPathOptions::PATH_ADDIN: + case SvtPathOptions::PATH_FILTER: + case SvtPathOptions::PATH_HELP: + case SvtPathOptions::PATH_MODULE: + case SvtPathOptions::PATH_PLUGIN: + case SvtPathOptions::PATH_STORAGE: + { + // These office paths have to be convert back to UCB-URL's + utl::LocalFileHelper::ConvertPhysicalNameToURL( rNewPath, aResult ); + aNewValue = aResult; + } + break; + + default: + aNewValue = rNewPath; + } + + // Resubstitution is done by the service itself using the substition service + a <<= aNewValue; + try + { + m_xPathSettings->setFastPropertyValue( m_aMapEnumToPropHandle[ (sal_Int32)ePath], a ); + } + catch (const Exception&) + { + } + } +} + +// ----------------------------------------------------------------------- + +OUString SvtPathOptions_Impl::SubstituteAndConvert( const rtl::OUString& rPath ) +{ + return SubstVar( rPath ); +} + +//------------------------------------------------------------------------- + +OUString SvtPathOptions_Impl::UsePathVariables( const OUString& rPath ) +{ + return m_xSubstVariables->reSubstituteVariables( rPath ); +} + +// ----------------------------------------------------------------------- + +OUString SvtPathOptions_Impl::SubstVar( const OUString& rVar ) +{ + // Don't work at parameter-string directly. Copy it. + OUString aWorkText = rVar; + + // Convert the returned path to system path! + BOOL bConvertLocal = FALSE; + + // Search for first occure of "$(...". + sal_Int32 nPosition = aWorkText.indexOf( SIGN_STARTVARIABLE ); // = first position of "$(" in string + sal_Int32 nLength = 0; // = count of letters from "$(" to ")" in string + + // Have we found any variable like "$(...)"? + if ( nPosition != STRPOS_NOTFOUND ) + { + // Yes; Get length of found variable. + // If no ")" was found - nLength is set to 0 by default! see before. + sal_Int32 nEndPosition = aWorkText.indexOf( SIGN_ENDVARIABLE, nPosition ); + if ( nEndPosition != STRPOS_NOTFOUND ) + nLength = nEndPosition - nPosition + 1; + } + + // Is there another path variable? + while ( ( nPosition != STRPOS_NOTFOUND ) && ( nLength > 0 ) ) + { + // YES; Get the next variable for replace. + OUString aReplacement; + OUString aSubString = aWorkText.copy( nPosition, nLength ); + aSubString = aSubString.toAsciiLowerCase(); + + // Look for special variable that needs a system path. + VarNameToEnumMap::const_iterator pIter = m_aMapVarNamesToEnum.find( aSubString ); + if ( pIter != m_aMapVarNamesToEnum.end() ) + bConvertLocal = TRUE; + + nPosition += nLength; + + // We must control index in string before call something at OUString! + // The OUString-implementation don't do it for us :-( but the result is not defined otherwise. + if ( nPosition + 1 > aWorkText.getLength() ) + { + // Position is out of range. Break loop! + nPosition = STRPOS_NOTFOUND; + nLength = 0; + } + else + { + // Else; Position is valid. Search for next variable. + nPosition = aWorkText.indexOf( SIGN_STARTVARIABLE, nPosition ); + // Have we found any variable like "$(...)"? + if ( nPosition != STRPOS_NOTFOUND ) + { + // Yes; Get length of found variable. If no ")" was found - nLength must set to 0! + nLength = 0; + sal_Int32 nEndPosition = aWorkText.indexOf( SIGN_ENDVARIABLE, nPosition ); + if ( nEndPosition != STRPOS_NOTFOUND ) + nLength = nEndPosition - nPosition + 1; + } + } + } + + aWorkText = m_xSubstVariables->substituteVariables( rVar, sal_False ); + + if ( bConvertLocal ) + { + // Convert the URL to a system path for special path variables + String aReturn; + utl::LocalFileHelper::ConvertURLToPhysicalName( aWorkText, aReturn ); + return aReturn; + } + + return aWorkText; +} + +// ----------------------------------------------------------------------- + +SvtPathOptions_Impl::SvtPathOptions_Impl() : + m_aPathArray( (sal_Int32)SvtPathOptions::PATH_COUNT ) +{ + Reference< XMultiServiceFactory > xSMgr = comphelper::getProcessServiceFactory(); + + // Create necessary services + m_xPathSettings = Reference< XFastPropertySet >( xSMgr->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.PathSettings" ))), + UNO_QUERY ); + if ( !m_xPathSettings.is() ) + { + // #112719#: check for existance + DBG_ERROR( "SvtPathOptions_Impl::SvtPathOptions_Impl(): #112719# happened again!" ); + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Service com.sun.star.util.PathSettings cannot be created" )), + Reference< XInterface >() ); + } + + m_xSubstVariables = Reference< XStringSubstitution >( xSMgr->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.PathSubstitution" ))), + UNO_QUERY ); + if ( !m_xSubstVariables.is() ) + { + // #112719#: check for existance + DBG_ERROR( "SvtPathOptions_Impl::SvtPathOptions_Impl(): #112719# happened again!" ); + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Service com.sun.star.util.PathSubstitution cannot be created" )), + Reference< XInterface >() ); + } + + // Create temporary hash map to have a mapping between property names and property handles + Reference< XPropertySet > xPropertySet = Reference< XPropertySet >( m_xPathSettings, UNO_QUERY ); + Reference< XPropertySetInfo > xPropSetInfo = xPropertySet->getPropertySetInfo(); + Sequence< Property > aPathPropSeq = xPropSetInfo->getProperties(); + + NameToHandleMap aTempHashMap; + for ( sal_Int32 n = 0; n < aPathPropSeq.getLength(); n++ ) + { + const com::sun::star::beans::Property& aProperty = aPathPropSeq[n]; + aTempHashMap.insert( NameToHandleMap::value_type( aProperty.Name, aProperty.Handle )); + } + + // Create mapping between internal enum (SvtPathOptions::Pathes) and property handle + sal_Int32 nCount = sizeof( aPropNames ) / sizeof( PropertyStruct ); + sal_Int32 i; + for ( i = 0; i < nCount; i++ ) + { + NameToHandleMap::const_iterator pIter = + aTempHashMap.find( rtl::OUString::createFromAscii( aPropNames[i].pPropName )); + + if ( pIter != aTempHashMap.end() ) + { + sal_Int32 nHandle = pIter->second; + sal_Int32 nEnum = aPropNames[i].ePath; + m_aMapEnumToPropHandle.insert( EnumToHandleMap::value_type( nEnum, nHandle )); + } + } + + // Create hash map for path variables that need a system path as a return value! + nCount = sizeof( aVarNameAttribute ) / sizeof( VarNameAttribute ); + for ( i = 0; i < nCount; i++ ) + { + m_aMapVarNamesToEnum.insert( VarNameToEnumMap::value_type( + OUString::createFromAscii( aVarNameAttribute[i].pVarName ), + aVarNameAttribute[i].eVarProperty )); + } + + // Set language type! + Any aLocale = ConfigManager::GetConfigManager()->GetDirectConfigProperty( ConfigManager::LOCALE ); + OUString aLocaleStr; + if ( aLocale >>= aLocaleStr ) + { + sal_Int32 nIndex = 0; + m_aLocale.Language = aLocaleStr.getToken(0, '-', nIndex ); + m_aLocale.Country = aLocaleStr.getToken(0, '-', nIndex ); + m_aLocale.Variant = aLocaleStr.getToken(0, '-', nIndex ); + } + else + { + DBG_ERRORFILE( "wrong any type" ); + m_aLocale.Language = OStringToOUString(OString("en"), RTL_TEXTENCODING_UTF8); + m_aLocale.Country = OStringToOUString(OString("US"), RTL_TEXTENCODING_UTF8); + m_aLocale.Variant = OStringToOUString(OString(""), RTL_TEXTENCODING_UTF8); + } +} + +// ----------------------------------------------------------------------- + +// class SvtPathOptions -------------------------------------------------- + +namespace { struct lclMutex : public rtl::Static< ::osl::Mutex, lclMutex > {}; } + +SvtPathOptions::SvtPathOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( lclMutex::get() ); + if ( !pOptions ) + { + pOptions = new SvtPathOptions_Impl; + ItemHolder1::holdConfigItem(E_PATHOPTIONS); + } + ++nRefCount; + pImp = pOptions; +} + +// ----------------------------------------------------------------------- + +SvtPathOptions::~SvtPathOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( lclMutex::get() ); + if ( !--nRefCount ) + { + DELETEZ( pOptions ); + } +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetAddinPath() const +{ + return pImp->GetAddinPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetAutoCorrectPath() const +{ + return pImp->GetAutoCorrectPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetAutoTextPath() const +{ + return pImp->GetAutoTextPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetBackupPath() const +{ + return pImp->GetBackupPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetBasicPath() const +{ + return pImp->GetBasicPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetBitmapPath() const +{ + return pImp->GetBitmapPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetConfigPath() const +{ + return pImp->GetConfigPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetDictionaryPath() const +{ + return pImp->GetDictionaryPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetFavoritesPath() const +{ + return pImp->GetFavoritesPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetFilterPath() const +{ + return pImp->GetFilterPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetGalleryPath() const +{ + return pImp->GetGalleryPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetGraphicPath() const +{ + return pImp->GetGraphicPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetHelpPath() const +{ + return pImp->GetHelpPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetLinguisticPath() const +{ + return pImp->GetLinguisticPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetFingerprintPath() const +{ + return pImp->GetFingerprintPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetModulePath() const +{ + return pImp->GetModulePath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetPalettePath() const +{ + return pImp->GetPalettePath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetPluginPath() const +{ + return pImp->GetPluginPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetStoragePath() const +{ + return pImp->GetStoragePath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetTempPath() const +{ + return pImp->GetTempPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetTemplatePath() const +{ + return pImp->GetTemplatePath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetUserConfigPath() const +{ + return pImp->GetUserConfigPath(); +} + +const String& SvtPathOptions::GetUIConfigPath() const +{ + return pImp->GetUIConfigPath(); +} + +// ----------------------------------------------------------------------- + +const String& SvtPathOptions::GetWorkPath() const +{ + return pImp->GetWorkPath(); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetAddinPath( const String& rPath ) +{ + pImp->SetAddinPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetAutoCorrectPath( const String& rPath ) +{ + pImp->SetAutoCorrectPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetAutoTextPath( const String& rPath ) +{ + pImp->SetAutoTextPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetBackupPath( const String& rPath ) +{ + pImp->SetBackupPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetBasicPath( const String& rPath ) +{ + pImp->SetBasicPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetBitmapPath( const String& rPath ) +{ + pImp->SetBitmapPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetConfigPath( const String& rPath ) +{ + pImp->SetConfigPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetDictionaryPath( const String& rPath ) +{ + pImp->SetDictionaryPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetFavoritesPath( const String& rPath ) +{ + pImp->SetFavoritesPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetFilterPath( const String& rPath ) +{ + pImp->SetFilterPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetGalleryPath( const String& rPath ) +{ + pImp->SetGalleryPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetGraphicPath( const String& rPath ) +{ + pImp->SetGraphicPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetHelpPath( const String& rPath ) +{ + pImp->SetHelpPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetLinguisticPath( const String& rPath ) +{ + pImp->SetLinguisticPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetModulePath( const String& rPath ) +{ + pImp->SetModulePath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetPalettePath( const String& rPath ) +{ + pImp->SetPalettePath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetPluginPath( const String& rPath ) +{ + pImp->SetPluginPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetStoragePath( const String& rPath ) +{ + pImp->SetStoragePath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetTempPath( const String& rPath ) +{ + pImp->SetTempPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetTemplatePath( const String& rPath ) +{ + pImp->SetTemplatePath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetUserConfigPath( const String& rPath ) +{ + pImp->SetUserConfigPath( rPath ); +} + +// ----------------------------------------------------------------------- + +void SvtPathOptions::SetWorkPath( const String& rPath ) +{ + pImp->SetWorkPath( rPath ); +} + +// ----------------------------------------------------------------------- + +String SvtPathOptions::SubstituteVariable( const String& rVar ) +{ + String aRet = pImp->SubstituteAndConvert( rVar ); + return aRet; +} + +String SvtPathOptions::UseVariable( const String& rPath ) +{ + String aRet = pImp->UsePathVariables( rPath ); + return aRet; +} + +// ----------------------------------------------------------------------- + +sal_Bool SvtPathOptions::SearchFile( String& rIniFile, Pathes ePath ) +{ + // check parameter: empty inifile name? + if ( !rIniFile.Len() ) + { + DBG_ERRORFILE( "SvtPathOptions::SearchFile(): invalid parameter" ); + return sal_False; + } + + String aIniFile = pImp->SubstVar( rIniFile ); + sal_Bool bRet = sal_False; + + switch ( ePath ) + { + case PATH_USERCONFIG: + { + // path is a URL + bRet = sal_True; + INetURLObject aObj( GetUserConfigPath() ); + xub_StrLen i, nCount = aIniFile.GetTokenCount( '/' ); + for ( i = 0; i < nCount; ++i ) + aObj.insertName( aIniFile.GetToken( i, '/' ) ); + + if ( !::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + aObj.SetSmartURL( GetConfigPath() ); + aObj.insertName( aIniFile ); + bRet = ::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); + } + + if ( bRet ) + rIniFile = aObj.GetMainURL( INetURLObject::NO_DECODE ); + + break; + } + + default: + { + String aPath; + switch ( ePath ) + { + case PATH_ADDIN: aPath = GetAddinPath(); break; + case PATH_AUTOCORRECT: aPath = GetAutoCorrectPath(); break; + case PATH_AUTOTEXT: aPath = GetAutoTextPath(); break; + case PATH_BACKUP: aPath = GetBackupPath(); break; + case PATH_BASIC: aPath = GetBasicPath(); break; + case PATH_BITMAP: aPath = GetBitmapPath(); break; + case PATH_CONFIG: aPath = GetConfigPath(); break; + case PATH_DICTIONARY: aPath = GetDictionaryPath(); break; + case PATH_FAVORITES: aPath = GetFavoritesPath(); break; + case PATH_FILTER: aPath = GetFilterPath(); break; + case PATH_GALLERY: aPath = GetGalleryPath(); break; + case PATH_GRAPHIC: aPath = GetGraphicPath(); break; + case PATH_HELP: aPath = GetHelpPath(); break; + case PATH_LINGUISTIC: aPath = GetLinguisticPath(); break; + case PATH_MODULE: aPath = GetModulePath(); break; + case PATH_PALETTE: aPath = GetPalettePath(); break; + case PATH_PLUGIN: aPath = GetPluginPath(); break; + case PATH_STORAGE: aPath = GetStoragePath(); break; + case PATH_TEMP: aPath = GetTempPath(); break; + case PATH_TEMPLATE: aPath = GetTemplatePath(); break; + case PATH_WORK: aPath = GetWorkPath(); break; + case PATH_UICONFIG: aPath = GetUIConfigPath(); break; + case PATH_FINGERPRINT: aPath = GetFingerprintPath(); break; + case PATH_USERCONFIG:/*-Wall???*/ break; + case PATH_COUNT: /*-Wall???*/ break; + } + + sal_uInt16 j, nIdx = 0, nTokenCount = aPath.GetTokenCount( SEARCHPATH_DELIMITER ); + for ( j = 0; j < nTokenCount; ++j ) + { + BOOL bIsURL = TRUE; + String aPathToken = aPath.GetToken( 0, SEARCHPATH_DELIMITER, nIdx ); + INetURLObject aObj( aPathToken ); + if ( aObj.HasError() ) + { + bIsURL = FALSE; + String aURL; + if ( LocalFileHelper::ConvertPhysicalNameToURL( aPathToken, aURL ) ) + aObj.SetURL( aURL ); + } + if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND ) + { + ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); + Reference< XMacroExpander > xMacroExpander( aContext.getSingleton( "com.sun.star.util.theMacroExpander" ), UNO_QUERY ); + OSL_ENSURE( xMacroExpander.is(), "SvtPathOptions::SearchFile: unable to access the MacroExpander singleton!" ); + if ( xMacroExpander.is() ) + { + const ::rtl::OUString sExpandedPath = xMacroExpander->expandMacros( aObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) ); + aObj.SetURL( sExpandedPath ); + } + } + + xub_StrLen i, nCount = aIniFile.GetTokenCount( '/' ); + for ( i = 0; i < nCount; ++i ) + aObj.insertName( aIniFile.GetToken( i, '/' ) ); + bRet = ::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); + + if ( bRet ) + { + if ( !bIsURL ) + ::utl::LocalFileHelper::ConvertURLToPhysicalName( + aObj.GetMainURL( INetURLObject::NO_DECODE ), rIniFile ); + else + rIniFile = aObj.GetMainURL( INetURLObject::NO_DECODE ); + break; + } + } + } + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +::com::sun::star::lang::Locale SvtPathOptions::GetLocale() const +{ + return pImp->GetLocale(); +} +// ----------------------------------------------------------------------- +BOOL SvtPathOptions::IsPathReadonly(Pathes ePath)const +{ + return pImp->IsPathReadonly(ePath); +} +// ----------------------------------------------------------------------- +const String& SvtPathOptions::GetPath(Pathes ePath)const +{ + return pImp->GetPath(ePath); +} +// ----------------------------------------------------------------------- +void SvtPathOptions::SetPath( SvtPathOptions::Pathes ePath, const String& rNewPath ) +{ + pImp->SetPath(ePath, rNewPath); +} + +// class PathService ----------------------------------------------------- +#include <com/sun/star/frame/XConfigManager.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase2.hxx> + +class PathService : public ::cppu::WeakImplHelper2< ::com::sun::star::frame::XConfigManager, ::com::sun::star::lang::XServiceInfo > +{ + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL substituteVariables( const ::rtl::OUString& sText ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& sKeyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& sKeyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL flush( ) throw(::com::sun::star::uno::RuntimeException); +}; + +// class PathService ----------------------------------------------------- + +void SAL_CALL PathService::addPropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::uno::RuntimeException) {} +void SAL_CALL PathService::removePropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::uno::RuntimeException) {} +void SAL_CALL PathService::flush( ) throw(::com::sun::star::uno::RuntimeException) {} + +::rtl::OUString SAL_CALL PathService::substituteVariables( const ::rtl::OUString& sText ) throw(::com::sun::star::uno::RuntimeException) +{ + return SvtPathOptions().SubstituteVariable( sText ); +} + +::rtl::OUString SAL_CALL PathService::getImplementationName( ) throw(::com::sun::star::uno::RuntimeException) +{ + return OUString::createFromAscii("com.sun.star.comp.unotools.PathService"); +} + +sal_Bool SAL_CALL PathService::supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException) +{ + if ( ServiceName.compareToAscii("com.sun.star.config.SpecialConfigManager") == COMPARE_EQUAL ) + return sal_True; + else + return sal_False; +} + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL PathService::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > aRet(1); + *aRet.getArray() = OUString::createFromAscii("com.sun.star.config.SpecialConfigManager"); + return aRet; +} diff --git a/unotools/source/config/printwarningoptions.cxx b/unotools/source/config/printwarningoptions.cxx new file mode 100644 index 000000000000..d723b3c068d4 --- /dev/null +++ b/unotools/source/config/printwarningoptions.cxx @@ -0,0 +1,421 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/printwarningoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <itemholder1.hxx> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_START OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Print")) + +#define PROPERTYNAME_PAPERSIZE OUString(RTL_CONSTASCII_USTRINGPARAM("Warning/PaperSize")) +#define PROPERTYNAME_PAPERORIENTATION OUString(RTL_CONSTASCII_USTRINGPARAM("Warning/PaperOrientation")) +#define PROPERTYNAME_NOTFOUND OUString(RTL_CONSTASCII_USTRINGPARAM("Warning/NotFound")) +#define PROPERTYNAME_TRANSPARENCY OUString(RTL_CONSTASCII_USTRINGPARAM("Warning/Transparency")) +#define PROPERTYNAME_PRINTINGMODIFIESDOCUMENT OUString(RTL_CONSTASCII_USTRINGPARAM("PrintingModifiesDocument")) + +#define PROPERTYHANDLE_PAPERSIZE 0 +#define PROPERTYHANDLE_PAPERORIENTATION 1 +#define PROPERTYHANDLE_NOTFOUND 2 +#define PROPERTYHANDLE_TRANSPARENCY 3 +#define PROPERTYHDL_PRINTINGMODIFIESDOCUMENT 4 + +#define PROPERTYCOUNT 5 + +class SvtPrintWarningOptions_Impl : public ConfigItem +{ +public: + +//--------------------------------------------------------------------------------------------------------- +// constructor / destructor +//--------------------------------------------------------------------------------------------------------- + + SvtPrintWarningOptions_Impl(); + ~SvtPrintWarningOptions_Impl(); + +//--------------------------------------------------------------------------------------------------------- +// overloaded methods of baseclass +//--------------------------------------------------------------------------------------------------------- + + virtual void Commit(); + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + +//--------------------------------------------------------------------------------------------------------- +// public interface +//--------------------------------------------------------------------------------------------------------- + + sal_Bool IsPaperSize() const { return m_bPaperSize; } + sal_Bool IsPaperOrientation() const { return m_bPaperOrientation; } + sal_Bool IsNotFound() const { return m_bNotFound; } + sal_Bool IsTransparency() const { return m_bTransparency; } + sal_Bool IsModifyDocumentOnPrintingAllowed() const { return m_bModifyDocumentOnPrintingAllowed; } + + void SetPaperSize( sal_Bool bState ) { m_bPaperSize = bState; SetModified(); } + void SetPaperOrientation( sal_Bool bState ) { m_bPaperOrientation = bState; SetModified(); } + void SetNotFound( sal_Bool bState ) { m_bNotFound = bState; SetModified(); } + void SetTransparency( sal_Bool bState ) { m_bTransparency = bState; SetModified(); } + void SetModifyDocumentOnPrintingAllowed( sal_Bool bState ) { m_bModifyDocumentOnPrintingAllowed = bState; SetModified(); } + +//------------------------------------------------------------------------------------------------------------- +// private methods +//------------------------------------------------------------------------------------------------------------- + +private: + + static Sequence< OUString > impl_GetPropertyNames(); + +//------------------------------------------------------------------------------------------------------------- +// private member +//------------------------------------------------------------------------------------------------------------- + +private: + + sal_Bool m_bPaperSize; + sal_Bool m_bPaperOrientation; + sal_Bool m_bNotFound; + sal_Bool m_bTransparency; + sal_Bool m_bModifyDocumentOnPrintingAllowed; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtPrintWarningOptions_Impl::SvtPrintWarningOptions_Impl() : + ConfigItem( ROOTNODE_START ), + m_bPaperSize( sal_False ), + m_bPaperOrientation( sal_False ), + m_bNotFound( sal_False ), + m_bTransparency( sal_True ), + m_bModifyDocumentOnPrintingAllowed( sal_True ) +{ + Sequence< OUString > seqNames( impl_GetPropertyNames() ); + Sequence< Any > seqValues( GetProperties( seqNames ) ); + + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtPrintWarningOptions_Impl::SvtPrintWarningOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to our internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + sal_Int32 nProperty = 0; + + for( nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtPrintWarningOptions_Impl::SvtPrintWarningOptions_Impl()\nInvalid property value for property detected!\n" ); + + switch( nProperty ) + { + case PROPERTYHANDLE_PAPERSIZE: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "Invalid type" ); + seqValues[nProperty] >>= m_bPaperSize; + } + break; + + case PROPERTYHANDLE_PAPERORIENTATION: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "Invalid type" ); + seqValues[nProperty] >>= m_bPaperOrientation; + } + break; + + case PROPERTYHANDLE_NOTFOUND: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "Invalid type" ); + seqValues[nProperty] >>= m_bNotFound; + } + break; + + case PROPERTYHANDLE_TRANSPARENCY: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "Invalid type" ); + seqValues[nProperty] >>= m_bTransparency; + } + break; + case PROPERTYHDL_PRINTINGMODIFIESDOCUMENT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "Invalid type" ); + seqValues[nProperty] >>= m_bModifyDocumentOnPrintingAllowed; + } + break; + + } + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtPrintWarningOptions_Impl::~SvtPrintWarningOptions_Impl() +{ + if( IsModified() ) + Commit(); +} + +//***************************************************************************************************************** +// Commit +//***************************************************************************************************************** +void SvtPrintWarningOptions_Impl::Commit() +{ + Sequence< OUString > aSeqNames( impl_GetPropertyNames() ); + Sequence< Any > aSeqValues( aSeqNames.getLength() ); + + for( sal_Int32 nProperty = 0, nCount = aSeqNames.getLength(); nProperty < nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_PAPERSIZE: + aSeqValues[nProperty] <<= m_bPaperSize; + break; + + case PROPERTYHANDLE_PAPERORIENTATION: + aSeqValues[nProperty] <<= m_bPaperOrientation; + break; + + case PROPERTYHANDLE_NOTFOUND: + aSeqValues[nProperty] <<= m_bNotFound; + break; + + case PROPERTYHANDLE_TRANSPARENCY: + aSeqValues[nProperty] <<= m_bTransparency; + break; + case PROPERTYHDL_PRINTINGMODIFIESDOCUMENT: + aSeqValues[nProperty] <<= m_bModifyDocumentOnPrintingAllowed; + break; + } + } + + PutProperties( aSeqNames, aSeqValues ); +} + +void SvtPrintWarningOptions_Impl::Notify( const Sequence< rtl::OUString >& ) +{ +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtPrintWarningOptions_Impl::impl_GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_PAPERSIZE, + PROPERTYNAME_PAPERORIENTATION, + PROPERTYNAME_NOTFOUND, + PROPERTYNAME_TRANSPARENCY, + PROPERTYNAME_PRINTINGMODIFIESDOCUMENT + }; + + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtPrintWarningOptions_Impl* SvtPrintWarningOptions::m_pDataContainer = NULL; +sal_Int32 SvtPrintWarningOptions::m_nRefCount = 0; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtPrintWarningOptions::SvtPrintWarningOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already! + if( m_pDataContainer == NULL ) + { + m_pDataContainer = new SvtPrintWarningOptions_Impl(); + ItemHolder1::holdConfigItem(E_PRINTWARNINGOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtPrintWarningOptions::~SvtPrintWarningOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtPrintWarningOptions::IsPaperSize() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsPaperSize(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtPrintWarningOptions::IsPaperOrientation() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsPaperOrientation(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtPrintWarningOptions::IsNotFound() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsNotFound(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtPrintWarningOptions::IsTransparency() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsTransparency(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtPrintWarningOptions::SetPaperSize( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetPaperSize( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtPrintWarningOptions::SetPaperOrientation( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetPaperOrientation( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtPrintWarningOptions::SetNotFound( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetNotFound( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtPrintWarningOptions::SetTransparency( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetTransparency( bState ); +} +// ----------------------------------------------------------------------------- + +sal_Bool SvtPrintWarningOptions::IsModifyDocumentOnPrintingAllowed() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsModifyDocumentOnPrintingAllowed(); +} + +// ----------------------------------------------------------------------------- + +void SvtPrintWarningOptions::SetModifyDocumentOnPrintingAllowed( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetModifyDocumentOnPrintingAllowed( bState ) ; +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtPrintWarningOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/regoptions.cxx b/unotools/source/config/regoptions.cxx new file mode 100644 index 000000000000..81f089919dfd --- /dev/null +++ b/unotools/source/config/regoptions.cxx @@ -0,0 +1,550 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/regoptions.hxx> +#include <unotools/confignode.hxx> +#include <tools/date.hxx> +#include <comphelper/processfactory.hxx> +#include <osl/mutex.hxx> +#include <unotools/bootstrap.hxx> +#include <rtl/ustring.hxx> + +//........................................................................ +namespace utl +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + + //==================================================================== + //= local helpers + //==================================================================== + //-------------------------------------------------------------------- + /** converts a string representation of a date into a integer representation + <p>No semantic check is made, i.e. if the string describes the 40.12, this is not recognized. In opposite, + the string must have a valid structure (DD.MM.YYYY).</p> + @return + the integer representation of the date which can be used with the Date class, + or 0 if the given string was no valid date representation + */ + static sal_Int32 lcl_convertString2Date( const ::rtl::OUString& _rStringRep ) + { + sal_Int32 nDateIntRep = 0; + if ( _rStringRep.getLength() == 2 + 1 + 2 + 1 + 4 ) // DD.MM.YYYY + { + // validate the string + sal_Bool bValid = sal_True; + + const sal_Unicode* pStringRep = _rStringRep.getStr(); + sal_Int32 nLen = _rStringRep.getLength(); + for ( sal_Int32 nPos = 0; + bValid && ( nPos < nLen ); + ++nPos, ++pStringRep + ) + { + if ( ( 2 == nPos ) || ( 5 == nPos ) ) + bValid = '.' == *pStringRep; // the number separators + else + bValid = ( *pStringRep >= '0' ) && ( *pStringRep <= '9' ); + } + + // passed the test? + if ( bValid ) + { + Date aDate; + aDate.SetDay ( (USHORT)_rStringRep.copy( 0, 2 ).toInt32( ) ); + aDate.SetMonth ( (USHORT)_rStringRep.copy( 3, 2 ).toInt32( ) ); + aDate.SetYear ( (USHORT)_rStringRep.copy( 6, 4 ).toInt32( ) ); + nDateIntRep = aDate.GetDate(); + } + } + + return nDateIntRep; + } + + //-------------------------------------------------------------------- + static const ::rtl::OUString& lcl_fillToken( const sal_Int32 /* [in] */ _nToken, const sal_Int16 /* [in] */ _nDigits, ::rtl::OUString& /* [out] */ _rToken ) + { + // convert into string + ::rtl::OUString sLeanToken = ::rtl::OUString::valueOf( _nToken ); + // check length + if ( sLeanToken.getLength() < _nDigits ) + { // fill + OSL_ENSURE( _nDigits <= 4, "lcl_fillToken: invalid digit number!" ); + _rToken = ::rtl::OUString( "0000", _nDigits - sLeanToken.getLength(), RTL_TEXTENCODING_ASCII_US ); + _rToken += sLeanToken; + } + else + _rToken = sLeanToken; + + return _rToken; + } + + //-------------------------------------------------------------------- + /** converts a integer representation of a date into a string representation + */ + static ::rtl::OUString lcl_ConvertDate2String( const Date& _rDate ) + { + OSL_ENSURE( _rDate.IsValid(), "lcl_ConvertDate2String: invalid integer representation!" ); + + sal_Unicode cSeparator( '.' ); + ::rtl::OUString sSeparator( &cSeparator, 1 ); + + ::rtl::OUString sStringRep; + ::rtl::OUString sToken; + sStringRep += lcl_fillToken( (sal_Int32)_rDate.GetDay(), 2, sToken ); + sStringRep += sSeparator; + sStringRep += lcl_fillToken( (sal_Int32)_rDate.GetMonth(), 2, sToken ); + sStringRep += sSeparator; + sStringRep += lcl_fillToken( (sal_Int32)_rDate.GetYear(), 4, sToken ); + + return sStringRep; + } + + //-------------------------------------------------------------------- + /// checks whether a given trigger date is reached (i.e. is _before_ the current date) + static sal_Bool lcl_reachedTriggerDate( const Date& _rTriggerDate ) + { + return _rTriggerDate <= Date(); + } + + //-------------------------------------------------------------------- + #define DECLARE_STATIC_LAZY_USTRING( name ) \ + static const ::rtl::OUString& lcl_get##name##Name() \ + { \ + static const ::rtl::OUString sName = ::rtl::OUString::createFromAscii( #name ); \ + return sName; \ + } + + DECLARE_STATIC_LAZY_USTRING( ReminderDate ); + DECLARE_STATIC_LAZY_USTRING( RequestDialog ); + DECLARE_STATIC_LAZY_USTRING( ShowMenuItem ); + DECLARE_STATIC_LAZY_USTRING( Patch ); + + //==================================================================== + //= RegOptionsImpl + //==================================================================== + class RegOptionsImpl + { + private: + OConfigurationTreeRoot m_aRegistrationNode; // the configuration node we need to access our persistent data + + String m_sRegistrationURL; // the URL to use when doing an online registration + Date m_aReminderDate; // the reminder date as found in the configuration + sal_Int32 m_nDialogCounter; // the dialog counter - see getDialogPermission + sal_Bool m_bShowMenuItem; // the flag indicating if the registration menu item is allowed + + static RegOptionsImpl* s_pSingleInstance; // the one and only instance of this class + static sal_Int32 s_nInstanceCount; // reference counter for the instances + static sal_Bool s_bThisSessionDone; // the flag indicating if for this session, everything beeing relevant has already been done + + private: + RegOptionsImpl( ); + + static ::osl::Mutex& getStaticMutex(); // get the mutex used to protect the static members of this class + + void commit( ); + sal_Int32 getBuildId() const; + + private: + RegOptions::DialogPermission implGetDialogPermission( ) const; + + public: + static RegOptionsImpl* registerClient( ); + static void revokeClient( ); + + inline sal_Bool hasURL( ) const { return ( 0 != m_sRegistrationURL.Len() ); } + inline sal_Bool allowMenu( ) const { return hasURL() && m_bShowMenuItem; } + inline String getRegistrationURL( ) const { return m_sRegistrationURL; } + + RegOptions::DialogPermission getDialogPermission( ) const; + void markSessionDone( ); + void activateReminder( sal_Int32 _nDaysFromNow ); + void removeReminder(); + bool hasReminderDateCome() const; + }; + + //-------------------------------------------------------------------- + RegOptionsImpl* RegOptionsImpl::s_pSingleInstance = NULL; + sal_Bool RegOptionsImpl::s_bThisSessionDone = sal_False; + sal_Int32 RegOptionsImpl::s_nInstanceCount = 0; + + //-------------------------------------------------------------------- + ::osl::Mutex& RegOptionsImpl::getStaticMutex() + { + static ::osl::Mutex* s_pStaticMutex = NULL; + if ( !s_pStaticMutex ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !s_pStaticMutex ) + { + static ::osl::Mutex s_aStaticMutex; + s_pStaticMutex = &s_aStaticMutex; + } + } + return *s_pStaticMutex; + } + + //-------------------------------------------------------------------- + void RegOptionsImpl::commit( ) + { + m_aRegistrationNode.commit( ); + } + + //-------------------------------------------------------------------- + RegOptionsImpl* RegOptionsImpl::registerClient( ) + { + ::osl::MutexGuard aGuard( getStaticMutex() ); + + if ( !s_pSingleInstance ) + s_pSingleInstance = new RegOptionsImpl; + + ++s_nInstanceCount; + return s_pSingleInstance; + } + + //-------------------------------------------------------------------- + void RegOptionsImpl::revokeClient( ) + { + ::osl::MutexGuard aGuard( getStaticMutex() ); + OSL_ENSURE( s_nInstanceCount, "RegOptionsImpl::revokeClient: there are no clients alive!" ); + OSL_ENSURE( s_pSingleInstance || !s_nInstanceCount, "RegOptionsImpl::revokeClient: invalid instance pointer!" ); + + if ( s_nInstanceCount ) + { + if ( s_pSingleInstance ) + // commit the changes done by this client + s_pSingleInstance->commit(); + + if ( 0 == --s_nInstanceCount ) + { + delete s_pSingleInstance; + s_pSingleInstance = NULL; + } + } + } + + //-------------------------------------------------------------------- + RegOptionsImpl::RegOptionsImpl( ) + :m_nDialogCounter ( 0 ) + ,m_bShowMenuItem ( sal_False ) + { + // create the config node for all our registration information + m_aRegistrationNode = OConfigurationTreeRoot::createWithServiceFactory( + ::comphelper::getProcessServiceFactory(), + ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Common/Help/Registration" ) + ); + + // cache some data + //the URL to use for online registration + ::rtl::OUString sStringValue; + m_aRegistrationNode.getNodeValue( ::rtl::OUString::createFromAscii( "URL" ) ) >>= sStringValue; + m_sRegistrationURL = sStringValue; + + // the state of the dialog + m_aRegistrationNode.getNodeValue( lcl_getRequestDialogName() ) >>= m_nDialogCounter; + + // the flag for showing the menu item + sal_Bool bBoolValue = sal_False; + m_aRegistrationNode.getNodeValue( lcl_getShowMenuItemName() ) >>= bBoolValue; + m_bShowMenuItem = bBoolValue; + + // the reminder date (if any) + sal_Int32 nIntDate = 0; + sStringValue = ::rtl::OUString(); + m_aRegistrationNode.getNodeValue( lcl_getReminderDateName() ) >>= sStringValue; + bool bIsPatchDate = ( sStringValue.equals( lcl_getPatchName() ) != sal_False ); + if ( !bIsPatchDate && sStringValue.getLength() ) + nIntDate = lcl_convertString2Date( sStringValue ); + m_aReminderDate.SetDate( nIntDate ); + } + + //-------------------------------------------------------------------- + RegOptions::DialogPermission RegOptionsImpl::implGetDialogPermission( ) const + { + RegOptions::DialogPermission eResult = RegOptions::dpDisabled; + // no URL or a counter already decreased to zero means the dialog is disabled + if ( hasURL() && ( m_nDialogCounter > 0 ) ) + { + // during every session, the counter will be decreased + // If it reaches zero, the dialog shall be executed + if ( 1 == m_nDialogCounter ) + { + if ( m_aReminderDate.IsValid( ) ) + { // valid reminder date + // assume remind later + eResult = RegOptions::dpRemindLater; + // and check if we reached the reminder date + if ( lcl_reachedTriggerDate( m_aReminderDate ) ) + eResult = RegOptions::dpThisSession; + } + else + eResult = RegOptions::dpThisSession; // execute in this session + } + else + eResult = RegOptions::dpNotThisSession; // first trigger session not reached + + // a last check .... + if ( ( s_bThisSessionDone ) // this session is already marked as "done" + && ( RegOptions::dpThisSession == eResult )// but without this, the state would be "now" + ) + eResult = RegOptions::dpDisabled; // -> change state to "disabled" + } + + return eResult; + } + + //-------------------------------------------------------------------- + RegOptions::DialogPermission RegOptionsImpl::getDialogPermission( ) const + { + OSL_ENSURE( !s_bThisSessionDone, "RegOptionsImpl::getDialogPermission: should never be asked in this session, again!" ); + // Somebody already marked this session as "everything relevant happened". So why sombody (else?) asks + // me again? + + return implGetDialogPermission( ); + } + + //-------------------------------------------------------------------- + void RegOptionsImpl::activateReminder( sal_Int32 _nDaysFromNow ) + { + OSL_ENSURE( s_bThisSessionDone || ( implGetDialogPermission( ) != RegOptions::dpDisabled ), "RegOptionsImpl::activateReminder: invalid call!" ); + OSL_ENSURE( _nDaysFromNow > 0, "RegOptionsImpl::activateReminder: invalid argument!" ); + + // calc the reminder + m_aReminderDate = Date() + _nDaysFromNow; // today (default ctor) + days + + // remember the date + m_aRegistrationNode.setNodeValue( + lcl_getReminderDateName(), + makeAny( lcl_ConvertDate2String( m_aReminderDate ) ) + ); + // to be on the save side, write the counter + m_aRegistrationNode.setNodeValue( + lcl_getRequestDialogName(), + makeAny( (sal_Int32)1 ) + ); + + // mark this session as done + if ( !s_bThisSessionDone ) + markSessionDone( ); + } + + //-------------------------------------------------------------------- + void RegOptionsImpl::removeReminder() + { + ::rtl::OUString aDefault; + ::rtl::OUString aReminderValue( lcl_getPatchName() ); + aReminderValue += ::rtl::OUString::valueOf(getBuildId()); + + m_aRegistrationNode.setNodeValue( + lcl_getReminderDateName(), + Any( aReminderValue ) + ); + } + + //-------------------------------------------------------------------- + sal_Int32 RegOptionsImpl::getBuildId() const + { + sal_Int32 nBuildId( 0 ); + ::rtl::OUString aDefault; + ::rtl::OUString aBuildIdData = utl::Bootstrap::getBuildIdData( aDefault ); + sal_Int32 nIndex1 = aBuildIdData.indexOf(':'); + sal_Int32 nIndex2 = aBuildIdData.indexOf(')'); + if (( nIndex1 > 0 ) && ( nIndex2 > 0 ) && ( nIndex2-1 > nIndex1+1 )) + { + ::rtl::OUString aBuildId = aBuildIdData.copy( nIndex1+1, nIndex2-nIndex1-1 ); + nBuildId = aBuildId.toInt32(); + } + + return nBuildId; + } + + //-------------------------------------------------------------------- + bool RegOptionsImpl::hasReminderDateCome() const + { + bool bRet = false; + sal_Int32 nDate = 0; + ::rtl::OUString sDate; + m_aRegistrationNode.getNodeValue( lcl_getReminderDateName() ) >>= sDate; + if ( sDate.getLength() ) + { + if ( sDate.indexOf( lcl_getPatchName() ) == 0) + { + if (sDate.equals( lcl_getPatchName() )) + bRet = true; + else if (sDate.getLength() > lcl_getPatchName().getLength() ) + { + // Check the build ID to determine if the registration + // dialog needs to be shown. + sal_Int32 nBuildId = getBuildId(); + ::rtl::OUString aStoredBuildId( sDate.copy(lcl_getPatchName().getLength())); + + // remind if the current build ID is not the same as the stored one + if ( nBuildId != aStoredBuildId.toInt32() ) + bRet = true; + } + } + else + { + nDate = lcl_convertString2Date( sDate ); + if ( nDate > 0 ) + { + Date aReminderDate; + aReminderDate.SetDate( nDate ); + bRet = aReminderDate <= Date(); + } + } + } + else + bRet = true; + + return bRet; + } + + //-------------------------------------------------------------------- + void RegOptionsImpl::markSessionDone( ) + { + OSL_ENSURE( !s_bThisSessionDone, "RegOptionsImpl::markSessionDone: already marked!" ); + OSL_ENSURE( implGetDialogPermission( ) != RegOptions::dpDisabled, "RegOptionsImpl::markSessionDone: invalid call!" ); + if ( !s_bThisSessionDone ) + { + RegOptions::DialogPermission eOldPermission = implGetDialogPermission( ); + + s_bThisSessionDone = sal_True; + + if ( RegOptions::dpRemindLater == eOldPermission ) + { // no action required. If we shall remind later, the counter is already at 1, we should not change this, + // as the next smaller number (which is 0 :) means that the dialog would be disabled + OSL_ENSURE( 1 == m_nDialogCounter, "RegOptionsImpl::markSessionDone: invalid session counter (1)!" ); + } + else + { + OSL_ENSURE( m_nDialogCounter > 0, "RegOptionsImpl::markSessionDone: invalid session counter (2)!" ); + --m_nDialogCounter; + + // decrease the session counter + m_aRegistrationNode.setNodeValue( + lcl_getRequestDialogName(), + makeAny( (sal_Int32)m_nDialogCounter ) + ); + + // and clear the reminder date + removeReminder(); + } + } + } + + //==================================================================== + //= RegOptions + //==================================================================== + //-------------------------------------------------------------------- + RegOptions::RegOptions() + :m_pImpl( NULL ) + { + } + + //-------------------------------------------------------------------- + void RegOptions::ensureImpl( ) + { + if ( !m_pImpl ) + m_pImpl = RegOptionsImpl::registerClient(); + } + + //-------------------------------------------------------------------- + RegOptions::~RegOptions() + { + if ( m_pImpl ) + { + RegOptionsImpl::revokeClient(); + m_pImpl = NULL; + } + } + + //-------------------------------------------------------------------- + String RegOptions::getRegistrationURL( ) const + { + const_cast< RegOptions* >( this )->ensureImpl( ); + return m_pImpl->getRegistrationURL(); + } + + //-------------------------------------------------------------------- + RegOptions::DialogPermission RegOptions::getDialogPermission( ) const + { + const_cast< RegOptions* >( this )->ensureImpl( ); + return m_pImpl->getDialogPermission(); + } + + //-------------------------------------------------------------------- + void RegOptions::markSessionDone( ) + { + const_cast< RegOptions* >( this )->ensureImpl( ); + m_pImpl->markSessionDone(); + } + + //-------------------------------------------------------------------- + void RegOptions::activateReminder( sal_Int32 _nDaysFromNow ) + { + const_cast< RegOptions* >( this )->ensureImpl( ); + m_pImpl->activateReminder( _nDaysFromNow ); + } + + //-------------------------------------------------------------------- + sal_Bool RegOptions::allowMenu( ) const + { + /// we cache this setting, 'cause it is needed very often + static sal_Bool bKnowMenuPermission = sal_False; + static sal_Bool bAllowMenu = sal_False; + + if ( !bKnowMenuPermission ) + { + const_cast< RegOptions* >( this )->ensureImpl( ); + bAllowMenu = m_pImpl->allowMenu(); + bKnowMenuPermission = sal_True; + } + return bAllowMenu; + } + + //-------------------------------------------------------------------- + void RegOptions::removeReminder() + { + const_cast< RegOptions* >( this )->ensureImpl( ); + m_pImpl->removeReminder(); + } + + //-------------------------------------------------------------------- + bool RegOptions::hasReminderDateCome() const + { + const_cast< RegOptions* >( this )->ensureImpl( ); + return m_pImpl->hasReminderDateCome(); + } + +//........................................................................ +} // namespace utl +//........................................................................ + diff --git a/unotools/source/config/saveopt.cxx b/unotools/source/config/saveopt.cxx new file mode 100644 index 000000000000..cbb7e763b38a --- /dev/null +++ b/unotools/source/config/saveopt.cxx @@ -0,0 +1,1002 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#ifndef GCC +#endif + +#include <unotools/saveopt.hxx> +#include "rtl/instance.hxx" +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <osl/mutex.hxx> +#include <comphelper/configurationhelper.hxx> +#include <unotools/processfactory.hxx> +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; +namespace css = ::com::sun::star; + +class SvtSaveOptions_Impl; +class SvtLoadOptions_Impl; + +#define CFG_READONLY_DEFAULT sal_False + +struct SvtLoadSaveOptions_Impl +{ + SvtSaveOptions_Impl* pSaveOpt; + SvtLoadOptions_Impl* pLoadOpt; +}; + +static SvtLoadSaveOptions_Impl* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +class SvtSaveOptions_Impl : public utl::ConfigItem +{ + sal_Int32 nAutoSaveTime; + sal_Bool bUseUserData, + bBackup, + bAutoSave, + bAutoSavePrompt, + bDocInfSave, + bSaveWorkingSet, + bSaveDocView, + bSaveRelINet, + bSaveRelFSys, + bSaveUnpacked, + bDoPrettyPrinting, + bWarnAlienFormat, + bLoadDocPrinter; + + sal_Bool bROAutoSaveTime, + bROUseUserData, + bROBackup, + bROAutoSave, + bROAutoSavePrompt, + bRODocInfSave, + bROSaveWorkingSet, + bROSaveDocView, + bROSaveRelINet, + bROSaveRelFSys, + bROSaveUnpacked, + bROWarnAlienFormat, + bRODoPrettyPrinting, + bROLoadDocPrinter, + bROODFDefaultVersion; + + SvtSaveOptions::ODFDefaultVersion eODFDefaultVersion; + +public: + SvtSaveOptions_Impl(); + ~SvtSaveOptions_Impl(); + + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + virtual void Commit(); + + sal_Int32 GetAutoSaveTime() const { return nAutoSaveTime; } + BOOL IsUseUserData() const { return bUseUserData; } + BOOL IsBackup() const { return bBackup; } + BOOL IsAutoSave() const { return bAutoSave; } + BOOL IsAutoSavePrompt() const { return bAutoSavePrompt; } + BOOL IsDocInfoSave() const { return bDocInfSave; } + BOOL IsSaveWorkingSet() const { return bSaveWorkingSet; } + BOOL IsSaveDocView() const { return bSaveDocView; } + BOOL IsSaveRelINet() const { return bSaveRelINet; } + BOOL IsSaveRelFSys() const { return bSaveRelFSys; } + BOOL IsSaveUnpacked() const { return bSaveUnpacked; } + sal_Bool IsPrettyPrintingEnabled( ) const { return bDoPrettyPrinting; } + sal_Bool IsWarnAlienFormat() const { return bWarnAlienFormat; } + sal_Bool IsLoadDocPrinter() const { return bLoadDocPrinter; } + SvtSaveOptions::ODFDefaultVersion + GetODFDefaultVersion() const { return eODFDefaultVersion; } + + void SetAutoSaveTime( sal_Int32 n ); + void SetUseUserData( BOOL b ); + void SetBackup( BOOL b ); + void SetAutoSave( BOOL b ); + void SetAutoSavePrompt( BOOL b ); + void SetDocInfoSave( BOOL b ); + void SetSaveWorkingSet( BOOL b ); + void SetSaveDocView( BOOL b ); + void SetSaveRelINet( BOOL b ); + void SetSaveRelFSys( BOOL b ); + void SetSaveUnpacked( BOOL b ); + void EnablePrettyPrinting( sal_Bool _bDoPP ); + void SetWarnAlienFormat( sal_Bool _bDoPP ); + void SetLoadDocPrinter( sal_Bool bNew ); + void SetODFDefaultVersion( SvtSaveOptions::ODFDefaultVersion eNew ); + + sal_Bool IsReadOnly( SvtSaveOptions::EOption eOption ) const; +}; + +void SvtSaveOptions_Impl::SetAutoSaveTime( sal_Int32 n ) +{ + if (!bROAutoSaveTime && nAutoSaveTime!=n) + { + nAutoSaveTime = n; + SetModified(); + Commit(); + } +} + +void SvtSaveOptions_Impl::SetUseUserData( BOOL b ) +{ + if (!bROUseUserData && bUseUserData!=b) + { + bUseUserData = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetBackup( BOOL b ) +{ + if (!bROBackup && bBackup!=b) + { + bBackup = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetAutoSave( BOOL b ) +{ + if (!bROAutoSave && bAutoSave!=b) + { + bAutoSave = b; + SetModified(); + Commit(); + } +} + +void SvtSaveOptions_Impl::SetAutoSavePrompt( BOOL b ) +{ + if (!bROAutoSavePrompt && bAutoSavePrompt!=b) + { + bAutoSavePrompt = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetDocInfoSave(BOOL b) +{ + if (!bRODocInfSave && bDocInfSave!=b) + { + bDocInfSave = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetSaveWorkingSet( BOOL b ) +{ + if (!bROSaveWorkingSet && bSaveWorkingSet!=b) + { + bSaveWorkingSet = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetSaveDocView( BOOL b ) +{ + if (!bROSaveDocView && bSaveDocView!=b) + { + bSaveDocView = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetSaveRelINet( BOOL b ) +{ + if (!bROSaveRelINet && bSaveRelINet!=b) + { + bSaveRelINet = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetSaveRelFSys( BOOL b ) +{ + if (!bROSaveRelFSys && bSaveRelFSys!=b) + { + bSaveRelFSys = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetSaveUnpacked( BOOL b ) +{ + if (!bROSaveUnpacked && bSaveUnpacked!=b) + { + bSaveUnpacked = b; + SetModified(); + } +} + +void SvtSaveOptions_Impl::EnablePrettyPrinting( sal_Bool _bDoPP ) +{ + if (!bRODoPrettyPrinting && bDoPrettyPrinting!=_bDoPP) + { + bDoPrettyPrinting = _bDoPP; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetWarnAlienFormat( sal_Bool _bDoPP ) +{ + if (!bROWarnAlienFormat && bWarnAlienFormat!=_bDoPP) + { + bWarnAlienFormat = _bDoPP; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetLoadDocPrinter( sal_Bool bNew ) +{ + if ( !bROLoadDocPrinter && bLoadDocPrinter != bNew ) + { + bLoadDocPrinter = bNew; + SetModified(); + } +} + +void SvtSaveOptions_Impl::SetODFDefaultVersion( SvtSaveOptions::ODFDefaultVersion eNew ) +{ + if ( !bROODFDefaultVersion && eODFDefaultVersion != eNew ) + { + eODFDefaultVersion = eNew; + SetModified(); + } +} + +sal_Bool SvtSaveOptions_Impl::IsReadOnly( SvtSaveOptions::EOption eOption ) const +{ + sal_Bool bReadOnly = CFG_READONLY_DEFAULT; + switch(eOption) + { + case SvtSaveOptions::E_AUTOSAVETIME : + bReadOnly = bROAutoSaveTime; + break; + case SvtSaveOptions::E_USEUSERDATA : + bReadOnly = bROUseUserData; + break; + case SvtSaveOptions::E_BACKUP : + bReadOnly = bROBackup; + break; + case SvtSaveOptions::E_AUTOSAVE : + bReadOnly = bROAutoSave; + break; + case SvtSaveOptions::E_AUTOSAVEPROMPT : + bReadOnly = bROAutoSavePrompt; + break; + case SvtSaveOptions::E_DOCINFSAVE : + bReadOnly = bRODocInfSave; + break; + case SvtSaveOptions::E_SAVEWORKINGSET : + bReadOnly = bROSaveWorkingSet; + break; + case SvtSaveOptions::E_SAVEDOCVIEW : + bReadOnly = bROSaveDocView; + break; + case SvtSaveOptions::E_SAVERELINET : + bReadOnly = bROSaveRelINet; + break; + case SvtSaveOptions::E_SAVERELFSYS : + bReadOnly = bROSaveRelFSys; + break; + case SvtSaveOptions::E_SAVEUNPACKED : + bReadOnly = bROSaveUnpacked; + break; + case SvtSaveOptions::E_DOPRETTYPRINTING : + bReadOnly = bRODoPrettyPrinting; + break; + case SvtSaveOptions::E_WARNALIENFORMAT : + bReadOnly = bROWarnAlienFormat; + break; + case SvtSaveOptions::E_LOADDOCPRINTER : + bReadOnly = bROLoadDocPrinter; + break; + case SvtSaveOptions::E_ODFDEFAULTVERSION : + bReadOnly = bROLoadDocPrinter; + break; + } + return bReadOnly; +} + +#define FORMAT 0 +#define TIMEINTERVALL 1 +#define USEUSERDATA 2 +#define CREATEBACKUP 3 +#define AUTOSAVE 4 +#define PROMPT 5 +#define EDITPROPERTY 6 +#define SAVEVIEWINFO 7 +#define UNPACKED 8 +#define PRETTYPRINTING 9 +#define WARNALIENFORMAT 10 +#define LOADDOCPRINTER 11 +#define FILESYSTEM 12 +#define INTERNET 13 +#define SAVEWORKINGSET 14 +#define ODFDEFAULTVERSION 15 + +Sequence< OUString > GetPropertyNames() +{ + static const char* aPropNames[] = + { + "Graphic/Format", + "Document/AutoSaveTimeIntervall", + "Document/UseUserData", + "Document/CreateBackup", + "Document/AutoSave", + "Document/AutoSavePrompt", + "Document/EditProperty", + "Document/ViewInfo", + "Document/Unpacked", + "Document/PrettyPrinting", + "Document/WarnAlienFormat", + "Document/LoadPrinter", + "URL/FileSystem", + "URL/Internet", + "WorkingSet", + "ODF/DefaultVersion" + }; + + const int nCount = sizeof( aPropNames ) / sizeof( const char* ); + Sequence< OUString > aNames( nCount ); + OUString* pNames = aNames.getArray(); + for ( int i = 0; i < nCount; i++ ) + pNames[i] = OUString::createFromAscii( aPropNames[i] ); + + return aNames; +} + +// ----------------------------------------------------------------------- + +SvtSaveOptions_Impl::SvtSaveOptions_Impl() + : ConfigItem( OUString::createFromAscii("Office.Common/Save") ) + , nAutoSaveTime( 0 ) + , bUseUserData( sal_False ) + , bBackup( sal_False ) + , bAutoSave( sal_False ) + , bAutoSavePrompt( sal_False ) + , bDocInfSave( sal_False ) + , bSaveWorkingSet( sal_False ) + , bSaveDocView( sal_False ) + , bSaveRelINet( sal_False ) + , bSaveRelFSys( sal_False ) + , bSaveUnpacked( sal_False ) + , bDoPrettyPrinting( sal_False ) + , bWarnAlienFormat( sal_True ) + , bLoadDocPrinter( sal_True ) + , bROAutoSaveTime( CFG_READONLY_DEFAULT ) + , bROUseUserData( CFG_READONLY_DEFAULT ) + , bROBackup( CFG_READONLY_DEFAULT ) + , bROAutoSave( CFG_READONLY_DEFAULT ) + , bROAutoSavePrompt( CFG_READONLY_DEFAULT ) + , bRODocInfSave( CFG_READONLY_DEFAULT ) + , bROSaveWorkingSet( CFG_READONLY_DEFAULT ) + , bROSaveDocView( CFG_READONLY_DEFAULT ) + , bROSaveRelINet( CFG_READONLY_DEFAULT ) + , bROSaveRelFSys( CFG_READONLY_DEFAULT ) + , bROSaveUnpacked( CFG_READONLY_DEFAULT ) + , bROWarnAlienFormat( CFG_READONLY_DEFAULT ) + , bRODoPrettyPrinting( CFG_READONLY_DEFAULT ) + , bROLoadDocPrinter( CFG_READONLY_DEFAULT ) + , bROODFDefaultVersion( CFG_READONLY_DEFAULT ) + , eODFDefaultVersion( SvtSaveOptions::ODFVER_LATEST ) +{ + Sequence< OUString > aNames = GetPropertyNames(); + Sequence< Any > aValues = GetProperties( aNames ); + Sequence< sal_Bool > aROStates = GetReadOnlyStates( aNames ); + EnableNotification( aNames ); + const Any* pValues = aValues.getConstArray(); + const sal_Bool* pROStates = aROStates.getConstArray(); + DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" ); + DBG_ASSERT( aROStates.getLength() == aNames.getLength(), "GetReadOnlyStates failed" ); + if ( aValues.getLength() == aNames.getLength() && aROStates.getLength() == aNames.getLength() ) + { + for ( int nProp = 0; nProp < aNames.getLength(); nProp++ ) + { + DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" ); + if ( pValues[nProp].hasValue() ) + { + sal_Int32 nTemp = 0; + switch ( nProp ) + { + case FORMAT: + // not supported anymore + break; + + case TIMEINTERVALL : + if ( pValues[nProp] >>= nTemp ) + nAutoSaveTime = nTemp; + else { + DBG_ERROR( "Wrong Type!" ); + }; + bROAutoSaveTime = pROStates[nProp]; + break; + + case ODFDEFAULTVERSION : + { + sal_Int16 nTmp = 0; + if ( pValues[nProp] >>= nTmp ) + { + if( nTmp == 3 ) + eODFDefaultVersion = SvtSaveOptions::ODFVER_LATEST; + else + eODFDefaultVersion = SvtSaveOptions::ODFDefaultVersion( nTmp ); + } + else { + DBG_ERRORFILE( "SvtSaveOptions_Impl::SvtSaveOptions_Impl(): Wrong Type!" ); + }; + bROODFDefaultVersion = pROStates[nProp]; + break; + } + + default: + { + sal_Bool bTemp = sal_Bool(); + if ( pValues[nProp] >>= bTemp ) + { + switch ( nProp ) + { + case USEUSERDATA : + bUseUserData = bTemp; + bROUseUserData = pROStates[nProp]; + break; + case CREATEBACKUP : + bBackup = bTemp; + bROBackup = pROStates[nProp]; + break; + case AUTOSAVE : + bAutoSave = bTemp; + bROAutoSave = pROStates[nProp]; + break; + case PROMPT : + bAutoSavePrompt = bTemp; + bROAutoSavePrompt = pROStates[nProp]; + break; + case EDITPROPERTY : + bDocInfSave = bTemp; + bRODocInfSave = pROStates[nProp]; + break; + case SAVEWORKINGSET : + bSaveWorkingSet = bTemp; + bROSaveWorkingSet = pROStates[nProp]; + break; + case SAVEVIEWINFO : + bSaveDocView = bTemp; + bROSaveDocView = pROStates[nProp]; + break; + case FILESYSTEM : + bSaveRelFSys = bTemp; + bROSaveRelFSys = pROStates[nProp]; + break; + case INTERNET : + bSaveRelINet = bTemp; + bROSaveRelINet = pROStates[nProp]; + break; + case UNPACKED : + bSaveUnpacked = bTemp; + bROSaveUnpacked = pROStates[nProp]; + break; + + case PRETTYPRINTING: + bDoPrettyPrinting = bTemp; + bRODoPrettyPrinting = pROStates[nProp]; + break; + + case WARNALIENFORMAT: + bWarnAlienFormat = bTemp; + bROWarnAlienFormat = pROStates[nProp]; + break; + + case LOADDOCPRINTER: + bLoadDocPrinter = bTemp; + bROLoadDocPrinter = pROStates[nProp]; + break; + + default : + DBG_ERRORFILE( "invalid index to load a path" ); + } + } + else + { + DBG_ERROR( "Wrong Type!" ); + } + } + } + } + } + } + + try + { + css::uno::Reference< css::uno::XInterface > xCFG = ::comphelper::ConfigurationHelper::openConfig( + ::utl::getProcessServiceFactory(), + ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery"), + ::comphelper::ConfigurationHelper::E_READONLY); + + ::comphelper::ConfigurationHelper::readRelativeKey( + xCFG, + ::rtl::OUString::createFromAscii("AutoSave"), + ::rtl::OUString::createFromAscii("Enabled")) >>= bAutoSave; + + ::comphelper::ConfigurationHelper::readRelativeKey( + xCFG, + ::rtl::OUString::createFromAscii("AutoSave"), + ::rtl::OUString::createFromAscii("TimeIntervall")) >>= nAutoSaveTime; + } + catch(const css::uno::Exception&) + { DBG_ERROR("Could not find needed informations for AutoSave feature."); } +} + +SvtSaveOptions_Impl::~SvtSaveOptions_Impl() +{} + +void SvtSaveOptions_Impl::Commit() +{ + Sequence< OUString > aOrgNames = GetPropertyNames(); + OUString* pOrgNames = aOrgNames.getArray(); + sal_Int32 nOrgCount = aOrgNames.getLength(); + + Sequence< OUString > aNames( nOrgCount ); + Sequence< Any > aValues( nOrgCount ); + OUString* pNames = aNames.getArray(); + Any* pValues = aValues.getArray(); + sal_Int32 nRealCount = 0; + + for (sal_Int32 i=0; i<nOrgCount; ++i) + { + switch (i) + { + case FORMAT: + // not supported anymore + break; + case TIMEINTERVALL : + if (!bROAutoSaveTime) + { + pValues[nRealCount] <<= nAutoSaveTime; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case USEUSERDATA : + if (!bROUseUserData) + { + pValues[nRealCount] <<= bUseUserData; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case CREATEBACKUP : + if (!bROBackup) + { + pValues[nRealCount] <<= bBackup; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case AUTOSAVE : + if (!bROAutoSave) + { + pValues[nRealCount] <<= bAutoSave; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case PROMPT : + if (!bROAutoSavePrompt) + { + pValues[nRealCount] <<= bAutoSavePrompt; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case EDITPROPERTY : + if (!bRODocInfSave) + { + pValues[nRealCount] <<= bDocInfSave; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case SAVEWORKINGSET : + if (!bROSaveWorkingSet) + { + pValues[nRealCount] <<= bSaveWorkingSet; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case SAVEVIEWINFO : + if (!bROSaveDocView) + { + pValues[nRealCount] <<= bSaveDocView; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case FILESYSTEM : + if (!bROSaveRelFSys) + { + pValues[nRealCount] <<= bSaveRelFSys; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case INTERNET : + if (!bROSaveRelINet) + { + pValues[nRealCount] <<= bSaveRelINet; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case UNPACKED : + if (!bROSaveUnpacked) + { + pValues[nRealCount] <<= bSaveUnpacked; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case PRETTYPRINTING: + if (!bRODoPrettyPrinting) + { + pValues[nRealCount] <<= bDoPrettyPrinting; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case WARNALIENFORMAT: + if (!bROWarnAlienFormat) + { + pValues[nRealCount] <<= bWarnAlienFormat; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case LOADDOCPRINTER: + if (!bROLoadDocPrinter) + { + pValues[nRealCount] <<= bLoadDocPrinter; + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + case ODFDEFAULTVERSION: + if (!bROODFDefaultVersion) + { + pValues[nRealCount] <<= (eODFDefaultVersion == SvtSaveOptions::ODFVER_LATEST) ? sal_Int16( 3 ) : sal_Int16( eODFDefaultVersion ); + pNames[nRealCount] = pOrgNames[i]; + ++nRealCount; + } + break; + default: + DBG_ERRORFILE( "invalid index to save a path" ); + } + } + + aNames.realloc(nRealCount); + aValues.realloc(nRealCount); + PutProperties( aNames, aValues ); + + css::uno::Reference< css::uno::XInterface > xCFG = ::comphelper::ConfigurationHelper::openConfig( + ::utl::getProcessServiceFactory(), + ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery"), + ::comphelper::ConfigurationHelper::E_STANDARD); + + ::comphelper::ConfigurationHelper::writeRelativeKey( + xCFG, + ::rtl::OUString::createFromAscii("AutoSave"), + ::rtl::OUString::createFromAscii("TimeIntervall"), + css::uno::makeAny(nAutoSaveTime)); + + ::comphelper::ConfigurationHelper::writeRelativeKey( + xCFG, + ::rtl::OUString::createFromAscii("AutoSave"), + ::rtl::OUString::createFromAscii("Enabled"), + css::uno::makeAny(bAutoSave)); + + ::comphelper::ConfigurationHelper::flush(xCFG); +} + +// ----------------------------------------------------------------------- + +void SvtSaveOptions_Impl::Notify( const Sequence<rtl::OUString>& ) +{ +} + + +class SvtLoadOptions_Impl : public utl::ConfigItem +{ + + sal_Bool bLoadUserDefinedSettings; + +public: + SvtLoadOptions_Impl(); + ~SvtLoadOptions_Impl(); + + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + virtual void Commit(); + + void SetLoadUserSettings(sal_Bool b){bLoadUserDefinedSettings = b; SetModified();} + sal_Bool IsLoadUserSettings() const {return bLoadUserDefinedSettings;} +}; +// ----------------------------------------------------------------------- +const sal_Char cUserDefinedSettings[] = "UserDefinedSettings"; + +SvtLoadOptions_Impl::SvtLoadOptions_Impl() + : ConfigItem( OUString::createFromAscii("Office.Common/Load") ) + , bLoadUserDefinedSettings( sal_False ) +{ + Sequence< OUString > aNames(1); + aNames[0] = OUString::createFromAscii(cUserDefinedSettings); + Sequence< Any > aValues = GetProperties( aNames ); + EnableNotification( aNames ); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" ); + if (pValues[0].getValueTypeClass() == ::com::sun::star::uno::TypeClass_BOOLEAN) + bLoadUserDefinedSettings = *(sal_Bool *)pValues[0].getValue(); +} +// ----------------------------------------------------------------------- +SvtLoadOptions_Impl::~SvtLoadOptions_Impl() +{ +} +// ----------------------------------------------------------------------- +void SvtLoadOptions_Impl::Commit() +{ + Sequence< OUString > aNames(1); + aNames[0] = OUString::createFromAscii(cUserDefinedSettings); + Sequence< Any > aValues( 1 ); + aValues[0].setValue(&bLoadUserDefinedSettings, ::getBooleanCppuType()); + PutProperties( aNames, aValues ); +} +// ----------------------------------------------------------------------- +void SvtLoadOptions_Impl::Notify( const Sequence<rtl::OUString>& ) +{ + DBG_ERRORFILE( "properties have been changed" ); +} +// ----------------------------------------------------------------------- + +namespace +{ + class LocalSingleton : public rtl::Static< osl::Mutex, LocalSingleton > + { + }; +} + +// ----------------------------------------------------------------------- +SvtSaveOptions::SvtSaveOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + if ( !pOptions ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtSaveOptions_Impl::ctor()"); + pOptions = new SvtLoadSaveOptions_Impl; + pOptions->pSaveOpt = new SvtSaveOptions_Impl; + pOptions->pLoadOpt = new SvtLoadOptions_Impl; + + ItemHolder1::holdConfigItem(E_SAVEOPTIONS); + } + ++nRefCount; + pImp = pOptions; +} + +// ----------------------------------------------------------------------- + +SvtSaveOptions::~SvtSaveOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + if ( !--nRefCount ) + { + if ( pOptions->pSaveOpt->IsModified() ) + pOptions->pSaveOpt->Commit(); + if ( pOptions->pLoadOpt->IsModified() ) + pOptions->pLoadOpt->Commit(); + + DELETEZ( pOptions->pLoadOpt ); + DELETEZ( pOptions->pSaveOpt ); + DELETEZ( pOptions ); + } +} + +void SvtSaveOptions::SetAutoSaveTime( sal_Int32 n ) +{ + pImp->pSaveOpt->SetAutoSaveTime( n ); +} + +sal_Int32 SvtSaveOptions::GetAutoSaveTime() const +{ + return pImp->pSaveOpt->GetAutoSaveTime(); +} + +void SvtSaveOptions::SetUseUserData( sal_Bool b ) +{ + pImp->pSaveOpt->SetUseUserData( b ); +} + +sal_Bool SvtSaveOptions::IsUseUserData() const +{ + return pImp->pSaveOpt->IsUseUserData(); +} + +void SvtSaveOptions::SetBackup( sal_Bool b ) +{ + pImp->pSaveOpt->SetBackup( b ); +} + +sal_Bool SvtSaveOptions::IsBackup() const +{ + return pImp->pSaveOpt->IsBackup(); +} + +void SvtSaveOptions::SetAutoSave( sal_Bool b ) +{ + pImp->pSaveOpt->SetAutoSave( b ); +} + +sal_Bool SvtSaveOptions::IsAutoSave() const +{ + return pImp->pSaveOpt->IsAutoSave(); +} + +void SvtSaveOptions::SetAutoSavePrompt( sal_Bool b ) +{ + pImp->pSaveOpt->SetAutoSavePrompt( b ); +} + +sal_Bool SvtSaveOptions::IsAutoSavePrompt() const +{ + return pImp->pSaveOpt->IsAutoSavePrompt(); +} + +void SvtSaveOptions::SetDocInfoSave(sal_Bool b) +{ + pImp->pSaveOpt->SetDocInfoSave( b ); +} + +sal_Bool SvtSaveOptions::IsDocInfoSave() const +{ + return pImp->pSaveOpt->IsDocInfoSave(); +} + +void SvtSaveOptions::SetSaveWorkingSet( sal_Bool b ) +{ + pImp->pSaveOpt->SetSaveWorkingSet( b ); +} + +sal_Bool SvtSaveOptions::IsSaveWorkingSet() const +{ + return pImp->pSaveOpt->IsSaveWorkingSet(); +} + +void SvtSaveOptions::SetSaveDocView( sal_Bool b ) +{ + pImp->pSaveOpt->SetSaveDocView( b ); +} + +sal_Bool SvtSaveOptions::IsSaveDocView() const +{ + return pImp->pSaveOpt->IsSaveDocView(); +} + +void SvtSaveOptions::SetSaveRelINet( sal_Bool b ) +{ + pImp->pSaveOpt->SetSaveRelINet( b ); +} + +sal_Bool SvtSaveOptions::IsSaveRelINet() const +{ + return pImp->pSaveOpt->IsSaveRelINet(); +} + +void SvtSaveOptions::SetSaveRelFSys( sal_Bool b ) +{ + pImp->pSaveOpt->SetSaveRelFSys( b ); +} + +sal_Bool SvtSaveOptions::IsSaveRelFSys() const +{ + return pImp->pSaveOpt->IsSaveRelFSys(); +} + +void SvtSaveOptions::SetSaveUnpacked( sal_Bool b ) +{ + pImp->pSaveOpt->SetSaveUnpacked( b ); +} + +sal_Bool SvtSaveOptions::IsSaveUnpacked() const +{ + return pImp->pSaveOpt->IsSaveUnpacked(); +} + +void SvtSaveOptions::SetLoadUserSettings(sal_Bool b) +{ + pImp->pLoadOpt->SetLoadUserSettings(b); +} + +sal_Bool SvtSaveOptions::IsLoadUserSettings() const +{ + return pImp->pLoadOpt->IsLoadUserSettings(); +} + +void SvtSaveOptions::SetPrettyPrinting( sal_Bool _bEnable ) +{ + pImp->pSaveOpt->EnablePrettyPrinting( _bEnable ); +} + +sal_Bool SvtSaveOptions::IsPrettyPrinting() const +{ + return pImp->pSaveOpt->IsPrettyPrintingEnabled(); +} + +void SvtSaveOptions::SetWarnAlienFormat( sal_Bool _bEnable ) +{ + pImp->pSaveOpt->SetWarnAlienFormat( _bEnable ); +} + +sal_Bool SvtSaveOptions::IsWarnAlienFormat() const +{ + return pImp->pSaveOpt->IsWarnAlienFormat(); +} + +void SvtSaveOptions::SetLoadDocumentPrinter( sal_Bool _bEnable ) +{ + pImp->pSaveOpt->SetLoadDocPrinter( _bEnable ); +} + +sal_Bool SvtSaveOptions::IsLoadDocumentPrinter() const +{ + return pImp->pSaveOpt->IsLoadDocPrinter(); +} + +void SvtSaveOptions::SetODFDefaultVersion( SvtSaveOptions::ODFDefaultVersion eVersion ) +{ + pImp->pSaveOpt->SetODFDefaultVersion( eVersion ); +} + +SvtSaveOptions::ODFDefaultVersion SvtSaveOptions::GetODFDefaultVersion() const +{ + return pImp->pSaveOpt->GetODFDefaultVersion(); +} + +sal_Bool SvtSaveOptions::IsReadOnly( SvtSaveOptions::EOption eOption ) const +{ + return pImp->pSaveOpt->IsReadOnly(eOption); +} + diff --git a/unotools/source/config/searchopt.cxx b/unotools/source/config/searchopt.cxx new file mode 100644 index 000000000000..f9318f150589 --- /dev/null +++ b/unotools/source/config/searchopt.cxx @@ -0,0 +1,636 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/searchopt.hxx> +#include <tools/solar.h> +#include <tools/debug.hxx> +#include <unotools/configitem.hxx> +#include <com/sun/star/i18n/TransliterationModules.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Any.h> +#include <rtl/logfile.hxx> + + +using namespace rtl; +using namespace utl; +using namespace com::sun::star::uno; +using namespace com::sun::star::i18n; + +#define MAX_FLAGS_OFFSET 25 + +////////////////////////////////////////////////////////////////////// + + +class SvtSearchOptions_Impl : public ConfigItem +{ + INT32 nFlags; + BOOL bModified; + + // disallow copy-constructor and assignment-operator for now + SvtSearchOptions_Impl( const SvtSearchOptions_Impl & ); + SvtSearchOptions_Impl & operator = ( const SvtSearchOptions_Impl & ); + +protected: + BOOL IsModified() const { return bModified; } + using ConfigItem::SetModified; + void SetModified( BOOL bVal ); + BOOL Load(); + BOOL Save(); + + Sequence< OUString > GetPropertyNames() const; + +public: + SvtSearchOptions_Impl(); + virtual ~SvtSearchOptions_Impl(); + + // ConfigItem + virtual void Commit(); + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + + BOOL GetFlag( USHORT nOffset ) const; + void SetFlag( USHORT nOffset, BOOL bVal ); +}; + + + +SvtSearchOptions_Impl::SvtSearchOptions_Impl() : + ConfigItem( OUString::createFromAscii( "Office.Common/SearchOptions" ) ) +{ + RTL_LOGFILE_CONTEXT(aLog, "unotools SvtSearchOptions_Impl::SvtSearchOptions_Impl()"); + nFlags = 0x0003FFFF; // set all options values to 'true' + Load(); + SetModified( FALSE ); +} + + +SvtSearchOptions_Impl::~SvtSearchOptions_Impl() +{ + Commit(); +} + + +void SvtSearchOptions_Impl::Commit() +{ + if (IsModified()) + Save(); +} + +void SvtSearchOptions_Impl::Notify( const Sequence< rtl::OUString >& ) +{ +} + + +BOOL SvtSearchOptions_Impl::GetFlag( USHORT nOffset ) const +{ + DBG_ASSERT( nOffset <= MAX_FLAGS_OFFSET, "offset out of range"); + return ((nFlags >> nOffset) & 0x01) ? TRUE : FALSE; +} + + +void SvtSearchOptions_Impl::SetFlag( USHORT nOffset, BOOL bVal ) +{ + DBG_ASSERT( nOffset <= MAX_FLAGS_OFFSET, "offset out of range"); + INT32 nOldFlags = nFlags; + INT32 nMask = ((INT32) 1) << nOffset; + if (bVal) + nFlags |= nMask; + else + nFlags &= ~nMask; + if (nFlags != nOldFlags) + SetModified( TRUE ); +} + + +void SvtSearchOptions_Impl::SetModified( BOOL bVal ) +{ + bModified = bVal; + if (bModified) + { + ConfigItem::SetModified(); + } +} + + +Sequence< OUString > SvtSearchOptions_Impl::GetPropertyNames() const +{ + static const char* aPropNames[ MAX_FLAGS_OFFSET + 1 ] = + { + "IsWholeWordsOnly", // 0 + "IsBackwards", // 1 + "IsUseRegularExpression", // 2 + //"IsCurrentSelectionOnly", // interactively set or not... + "IsSearchForStyles", // 3 + "IsSimilaritySearch", // 4 + "IsUseAsianOptions", // 5 + "IsMatchCase", // 6 + "Japanese/IsMatchFullHalfWidthForms", // 7 + "Japanese/IsMatchHiraganaKatakana", // 8 + "Japanese/IsMatchContractions", // 9 + "Japanese/IsMatchMinusDashCho-on", // 10 + "Japanese/IsMatchRepeatCharMarks", // 11 + "Japanese/IsMatchVariantFormKanji", // 12 + "Japanese/IsMatchOldKanaForms", // 13 + "Japanese/IsMatch_DiZi_DuZu", // 14 + "Japanese/IsMatch_BaVa_HaFa", // 15 + "Japanese/IsMatch_TsiThiChi_DhiZi", // 16 + "Japanese/IsMatch_HyuIyu_ByuVyu", // 17 + "Japanese/IsMatch_SeShe_ZeJe", // 18 + "Japanese/IsMatch_IaIya", // 19 + "Japanese/IsMatch_KiKu", // 20 + "Japanese/IsIgnorePunctuation", // 21 + "Japanese/IsIgnoreWhitespace", // 22 + "Japanese/IsIgnoreProlongedSoundMark", // 23 + "Japanese/IsIgnoreMiddleDot", // 24 + "IsNotes" // 25 + }; + + const int nCount = sizeof( aPropNames ) / sizeof( aPropNames[0] ); + Sequence< OUString > aNames( nCount ); + OUString* pNames = aNames.getArray(); + for (INT32 i = 0; i < nCount; ++i) + pNames[i] = OUString::createFromAscii( aPropNames[i] ); + + return aNames; +} + + +BOOL SvtSearchOptions_Impl::Load() +{ + BOOL bSucc = FALSE; + + Sequence< OUString > aNames = GetPropertyNames(); + INT32 nProps = aNames.getLength(); + + const Sequence< Any > aValues = GetProperties( aNames ); + DBG_ASSERT( aValues.getLength() == aNames.getLength(), + "GetProperties failed" ); + //EnableNotification( aNames ); + + if (nProps && aValues.getLength() == nProps) + { + bSucc = TRUE; + + const Any* pValues = aValues.getConstArray(); + for (USHORT i = 0; i < nProps; ++i) + { + const Any &rVal = pValues[i]; + DBG_ASSERT( rVal.hasValue(), "property value missing" ); + if (rVal.hasValue()) + { + BOOL bVal = BOOL(); + if (rVal >>= bVal) + { + if (i <= MAX_FLAGS_OFFSET) + { + // use index in sequence as flag index + SetFlag( i, bVal ); + } + else { + DBG_ERROR( "unexpected index" ); + } + } + else + { + DBG_ERROR( "unexpected type" ); + bSucc = FALSE; + } + } + else + { + DBG_ERROR( "value missing" ); + bSucc = FALSE; + } + } + } + DBG_ASSERT( bSucc, "LoadConfig failed" ); + + return bSucc; +} + + +BOOL SvtSearchOptions_Impl::Save() +{ + BOOL bSucc = FALSE; + + const Sequence< OUString > aNames = GetPropertyNames(); + INT32 nProps = aNames.getLength(); + + Sequence< Any > aValues( nProps ); + Any *pValue = aValues.getArray(); + + DBG_ASSERT( nProps == MAX_FLAGS_OFFSET + 1, + "unexpected size of index" ); + if (nProps && nProps == MAX_FLAGS_OFFSET + 1) + { + for (USHORT i = 0; i < nProps; ++i) + pValue[i] <<= (BOOL) GetFlag(i); + bSucc |= PutProperties( aNames, aValues ); + } + + if (bSucc) + SetModified( FALSE ); + + return bSucc; +} + + +////////////////////////////////////////////////////////////////////// + +SvtSearchOptions::SvtSearchOptions() +{ + pImpl = new SvtSearchOptions_Impl; +} + + +SvtSearchOptions::~SvtSearchOptions() +{ + delete pImpl; +} + + +INT32 SvtSearchOptions::GetTransliterationFlags() const +{ + INT32 nRes = 0; + + if (!IsMatchCase()) // 'IsMatchCase' means act case sensitive + nRes |= TransliterationModules_IGNORE_CASE; + if ( IsMatchFullHalfWidthForms()) + nRes |= TransliterationModules_IGNORE_WIDTH; + if ( IsMatchHiraganaKatakana()) + nRes |= TransliterationModules_IGNORE_KANA; + if ( IsMatchContractions()) + nRes |= TransliterationModules_ignoreSize_ja_JP; + if ( IsMatchMinusDashChoon()) + nRes |= TransliterationModules_ignoreMinusSign_ja_JP; + if ( IsMatchRepeatCharMarks()) + nRes |= TransliterationModules_ignoreIterationMark_ja_JP; + if ( IsMatchVariantFormKanji()) + nRes |= TransliterationModules_ignoreTraditionalKanji_ja_JP; + if ( IsMatchOldKanaForms()) + nRes |= TransliterationModules_ignoreTraditionalKana_ja_JP; + if ( IsMatchDiziDuzu()) + nRes |= TransliterationModules_ignoreZiZu_ja_JP; + if ( IsMatchBavaHafa()) + nRes |= TransliterationModules_ignoreBaFa_ja_JP; + if ( IsMatchTsithichiDhizi()) + nRes |= TransliterationModules_ignoreTiJi_ja_JP; + if ( IsMatchHyuiyuByuvyu()) + nRes |= TransliterationModules_ignoreHyuByu_ja_JP; + if ( IsMatchSesheZeje()) + nRes |= TransliterationModules_ignoreSeZe_ja_JP; + if ( IsMatchIaiya()) + nRes |= TransliterationModules_ignoreIandEfollowedByYa_ja_JP; + if ( IsMatchKiku()) + nRes |= TransliterationModules_ignoreKiKuFollowedBySa_ja_JP; + if ( IsIgnorePunctuation()) + nRes |= TransliterationModules_ignoreSeparator_ja_JP; + if ( IsIgnoreWhitespace()) + nRes |= TransliterationModules_ignoreSpace_ja_JP; + if ( IsIgnoreProlongedSoundMark()) + nRes |= TransliterationModules_ignoreProlongedSoundMark_ja_JP; + if ( IsIgnoreMiddleDot()) + nRes |= TransliterationModules_ignoreMiddleDot_ja_JP; + + return nRes; +} + + +BOOL SvtSearchOptions::IsWholeWordsOnly() const +{ + return pImpl->GetFlag( 0 ); +} + + +void SvtSearchOptions::SetWholeWordsOnly( BOOL bVal ) +{ + pImpl->SetFlag( 0, bVal ); +} + + +BOOL SvtSearchOptions::IsBackwards() const +{ + return pImpl->GetFlag( 1 ); +} + + +void SvtSearchOptions::SetBackwards( BOOL bVal ) +{ + pImpl->SetFlag( 1, bVal ); +} + + +BOOL SvtSearchOptions::IsUseRegularExpression() const +{ + return pImpl->GetFlag( 2 ); +} + + +void SvtSearchOptions::SetUseRegularExpression( BOOL bVal ) +{ + pImpl->SetFlag( 2, bVal ); +} + + +BOOL SvtSearchOptions::IsSearchForStyles() const +{ + return pImpl->GetFlag( 3 ); +} + + +void SvtSearchOptions::SetSearchForStyles( BOOL bVal ) +{ + pImpl->SetFlag( 3, bVal ); +} + + +BOOL SvtSearchOptions::IsSimilaritySearch() const +{ + return pImpl->GetFlag( 4 ); +} + + +void SvtSearchOptions::SetSimilaritySearch( BOOL bVal ) +{ + pImpl->SetFlag( 4, bVal ); +} + + +BOOL SvtSearchOptions::IsUseAsianOptions() const +{ + return pImpl->GetFlag( 5 ); +} + + +void SvtSearchOptions::SetUseAsianOptions( BOOL bVal ) +{ + pImpl->SetFlag( 5, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchCase() const +{ + return pImpl->GetFlag( 6 ); +} + + +void SvtSearchOptions::SetMatchCase( BOOL bVal ) +{ + pImpl->SetFlag( 6, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchFullHalfWidthForms() const +{ + return pImpl->GetFlag( 7 ); +} + + +void SvtSearchOptions::SetMatchFullHalfWidthForms( BOOL bVal ) +{ + pImpl->SetFlag( 7, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchHiraganaKatakana() const +{ + return pImpl->GetFlag( 8 ); +} + + +void SvtSearchOptions::SetMatchHiraganaKatakana( BOOL bVal ) +{ + pImpl->SetFlag( 8, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchContractions() const +{ + return pImpl->GetFlag( 9 ); +} + + +void SvtSearchOptions::SetMatchContractions( BOOL bVal ) +{ + pImpl->SetFlag( 9, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchMinusDashChoon() const +{ + return pImpl->GetFlag( 10 ); +} + + +void SvtSearchOptions::SetMatchMinusDashChoon( BOOL bVal ) +{ + pImpl->SetFlag( 10, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchRepeatCharMarks() const +{ + return pImpl->GetFlag( 11 ); +} + + +void SvtSearchOptions::SetMatchRepeatCharMarks( BOOL bVal ) +{ + pImpl->SetFlag( 11, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchVariantFormKanji() const +{ + return pImpl->GetFlag( 12 ); +} + + +void SvtSearchOptions::SetMatchVariantFormKanji( BOOL bVal ) +{ + pImpl->SetFlag( 12, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchOldKanaForms() const +{ + return pImpl->GetFlag( 13 ); +} + + +void SvtSearchOptions::SetMatchOldKanaForms( BOOL bVal ) +{ + pImpl->SetFlag( 13, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchDiziDuzu() const +{ + return pImpl->GetFlag( 14 ); +} + + +void SvtSearchOptions::SetMatchDiziDuzu( BOOL bVal ) +{ + pImpl->SetFlag( 14, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchBavaHafa() const +{ + return pImpl->GetFlag( 15 ); +} + + +void SvtSearchOptions::SetMatchBavaHafa( BOOL bVal ) +{ + pImpl->SetFlag( 15, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchTsithichiDhizi() const +{ + return pImpl->GetFlag( 16 ); +} + + +void SvtSearchOptions::SetMatchTsithichiDhizi( BOOL bVal ) +{ + pImpl->SetFlag( 16, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchHyuiyuByuvyu() const +{ + return pImpl->GetFlag( 17 ); +} + + +void SvtSearchOptions::SetMatchHyuiyuByuvyu( BOOL bVal ) +{ + pImpl->SetFlag( 17, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchSesheZeje() const +{ + return pImpl->GetFlag( 18 ); +} + + +void SvtSearchOptions::SetMatchSesheZeje( BOOL bVal ) +{ + pImpl->SetFlag( 18, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchIaiya() const +{ + return pImpl->GetFlag( 19 ); +} + + +void SvtSearchOptions::SetMatchIaiya( BOOL bVal ) +{ + pImpl->SetFlag( 19, bVal ); +} + + +BOOL SvtSearchOptions::IsMatchKiku() const +{ + return pImpl->GetFlag( 20 ); +} + + +void SvtSearchOptions::SetMatchKiku( BOOL bVal ) +{ + pImpl->SetFlag( 20, bVal ); +} + + +BOOL SvtSearchOptions::IsIgnorePunctuation() const +{ + return pImpl->GetFlag( 21 ); +} + + +void SvtSearchOptions::SetIgnorePunctuation( BOOL bVal ) +{ + pImpl->SetFlag( 21, bVal ); +} + + +BOOL SvtSearchOptions::IsIgnoreWhitespace() const +{ + return pImpl->GetFlag( 22 ); +} + + +void SvtSearchOptions::SetIgnoreWhitespace( BOOL bVal ) +{ + pImpl->SetFlag( 22, bVal ); +} + + +BOOL SvtSearchOptions::IsIgnoreProlongedSoundMark() const +{ + return pImpl->GetFlag( 23 ); +} + + +void SvtSearchOptions::SetIgnoreProlongedSoundMark( BOOL bVal ) +{ + pImpl->SetFlag( 23, bVal ); +} + + +BOOL SvtSearchOptions::IsIgnoreMiddleDot() const +{ + return pImpl->GetFlag( 24 ); +} + + +void SvtSearchOptions::SetIgnoreMiddleDot( BOOL bVal ) +{ + pImpl->SetFlag( 24, bVal ); +} + +BOOL SvtSearchOptions::IsNotes() const +{ + return pImpl->GetFlag( 25 ); +} + + +void SvtSearchOptions::SetNotes( BOOL bVal ) +{ + pImpl->SetFlag( 25, bVal ); +} + +////////////////////////////////////////////////////////////////////// + diff --git a/unotools/source/config/securityoptions.cxx b/unotools/source/config/securityoptions.cxx new file mode 100644 index 000000000000..526e33d1917c --- /dev/null +++ b/unotools/source/config/securityoptions.cxx @@ -0,0 +1,1309 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/securityoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <tools/urlobj.hxx> +#include <tools/wldcrd.hxx> + +#include <unotools/pathoptions.hxx> + +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_SECURITY OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Security/Scripting")) +#define DEFAULT_SECUREURL Sequence< OUString >() +#define DEFAULT_SECLEVEL 3 +#define DEFAULT_TRUSTEDAUTHORS Sequence< SvtSecurityOptions::Certificate >() + +// xmlsec05 depricated +#define DEFAULT_STAROFFICEBASIC eALWAYS_EXECUTE + +#define CSTR_SECUREURL "SecureURL" +#define CSTR_DOCWARN_SAVEORSEND "WarnSaveOrSendDoc" +#define CSTR_DOCWARN_SIGNING "WarnSignDoc" +#define CSTR_DOCWARN_PRINT "WarnPrintDoc" +#define CSTR_DOCWARN_CREATEPDF "WarnCreatePDF" +#define CSTR_DOCWARN_REMOVEPERSONALINFO "RemovePersonalInfoOnSaving" +#define CSTR_DOCWARN_RECOMMENDPASSWORD "RecommendPasswordProtection" +#define CSTR_CTRLCLICK_HYPERLINK "HyperlinksWithCtrlClick" +#define CSTR_MACRO_SECLEVEL "MacroSecurityLevel" +#define CSTR_MACRO_TRUSTEDAUTHORS "TrustedAuthors" +#define CSTR_MACRO_DISABLE "DisableMacrosExecution" +#define CSTR_TRUSTEDAUTHOR_SUBJECTNAME "SubjectName" +#define CSTR_TRUSTEDAUTHOR_SERIALNUMBER "SerialNumber" +#define CSTR_TRUSTEDAUTHOR_RAWDATA "RawData" + +#define PROPERTYNAME_SECUREURL OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_SECUREURL )) +#define PROPERTYNAME_DOCWARN_SAVEORSEND OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_DOCWARN_SAVEORSEND )) +#define PROPERTYNAME_DOCWARN_SIGNING OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_DOCWARN_SIGNING )) +#define PROPERTYNAME_DOCWARN_PRINT OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_DOCWARN_PRINT )) +#define PROPERTYNAME_DOCWARN_CREATEPDF OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_DOCWARN_CREATEPDF )) +#define PROPERTYNAME_DOCWARN_REMOVEPERSONALINFO OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_DOCWARN_REMOVEPERSONALINFO )) +#define PROPERTYNAME_DOCWARN_RECOMMENDPASSWORD OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_DOCWARN_RECOMMENDPASSWORD )) +#define PROPERTYNAME_CTRLCLICK_HYPERLINK OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_CTRLCLICK_HYPERLINK )) +#define PROPERTYNAME_MACRO_SECLEVEL OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_MACRO_SECLEVEL )) +#define PROPERTYNAME_MACRO_TRUSTEDAUTHORS OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_MACRO_TRUSTEDAUTHORS )) +#define PROPERTYNAME_MACRO_DISABLE OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_MACRO_DISABLE )) +#define PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_TRUSTEDAUTHOR_SUBJECTNAME)) +#define PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_TRUSTEDAUTHOR_SERIALNUMBER)) +#define PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA OUString(RTL_CONSTASCII_USTRINGPARAM(CSTR_TRUSTEDAUTHOR_RAWDATA)) + +// xmlsec05 depricated +#define PROPERTYNAME_STAROFFICEBASIC OUString(RTL_CONSTASCII_USTRINGPARAM("OfficeBasic" )) +#define PROPERTYNAME_EXECUTEPLUGINS OUString(RTL_CONSTASCII_USTRINGPARAM("ExecutePlugins" )) +#define PROPERTYNAME_WARNINGENABLED OUString(RTL_CONSTASCII_USTRINGPARAM("Warning" )) +#define PROPERTYNAME_CONFIRMATIONENABLED OUString(RTL_CONSTASCII_USTRINGPARAM("Confirmation" )) +// xmlsec05 depricated + + +#define PROPERTYHANDLE_SECUREURL 0 + +// xmlsec05 depricated +#define PROPERTYHANDLE_STAROFFICEBASIC 1 +#define PROPERTYHANDLE_EXECUTEPLUGINS 2 +#define PROPERTYHANDLE_WARNINGENABLED 3 +#define PROPERTYHANDLE_CONFIRMATIONENABLED 4 +// xmlsec05 depricated + +#define PROPERTYHANDLE_DOCWARN_SAVEORSEND 5 +#define PROPERTYHANDLE_DOCWARN_SIGNING 6 +#define PROPERTYHANDLE_DOCWARN_PRINT 7 +#define PROPERTYHANDLE_DOCWARN_CREATEPDF 8 +#define PROPERTYHANDLE_DOCWARN_REMOVEPERSONALINFO 9 +#define PROPERTYHANDLE_DOCWARN_RECOMMENDPASSWORD 10 +#define PROPERTYHANDLE_CTRLCLICK_HYPERLINK 11 +#define PROPERTYHANDLE_MACRO_SECLEVEL 12 +#define PROPERTYHANDLE_MACRO_TRUSTEDAUTHORS 13 +#define PROPERTYHANDLE_MACRO_DISABLE 14 + +#define PROPERTYCOUNT 15 +#define PROPERTYHANDLE_INVALID -1 + +#define CFG_READONLY_DEFAULT sal_False + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +class SvtSecurityOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtSecurityOptions_Impl(); + ~SvtSecurityOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& seqPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + sal_Bool IsReadOnly ( SvtSecurityOptions::EOption eOption ) const ; + + Sequence< OUString > GetSecureURLs ( ) const ; + void SetSecureURLs ( const Sequence< OUString >& seqURLList ) ; + sal_Bool IsSecureURL ( const OUString& sURL, + const OUString& sReferer ) const ; + inline sal_Int32 GetMacroSecurityLevel ( ) const ; + void SetMacroSecurityLevel ( sal_Int32 _nLevel ) ; + + inline sal_Bool IsMacroDisabled ( ) const ; + + Sequence< SvtSecurityOptions::Certificate > GetTrustedAuthors ( ) const ; + void SetTrustedAuthors ( const Sequence< SvtSecurityOptions::Certificate >& rAuthors ) ; + sal_Bool IsTrustedAuthorsEnabled ( ) ; + + sal_Bool IsOptionSet ( SvtSecurityOptions::EOption eOption ) const ; + sal_Bool SetOption ( SvtSecurityOptions::EOption eOption, sal_Bool bValue ) ; + sal_Bool IsOptionEnabled ( SvtSecurityOptions::EOption eOption ) const ; +private: + + /*-****************************************************************************************************//** + @short return list of key names of ouer configuration management which represent our module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. + + @seealso - + + @param - + @return A list of needed configuration keys is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + void SetProperty( sal_Int32 nHandle, const Any& rValue, sal_Bool bReadOnly ); + void LoadAuthors( void ); + static sal_Int32 GetHandle( const OUString& rPropertyName ); + bool GetOption( SvtSecurityOptions::EOption eOption, sal_Bool*& rpValue, sal_Bool*& rpRO ); + + static Sequence< OUString > GetPropertyNames(); + + Sequence< OUString > m_seqSecureURLs; + sal_Bool m_bSaveOrSend; + sal_Bool m_bSigning; + sal_Bool m_bPrint; + sal_Bool m_bCreatePDF; + sal_Bool m_bRemoveInfo; + sal_Bool m_bRecommendPwd; + sal_Bool m_bCtrlClickHyperlink; + sal_Int32 m_nSecLevel; + Sequence< SvtSecurityOptions::Certificate > m_seqTrustedAuthors; + sal_Bool m_bDisableMacros; + + sal_Bool m_bROSecureURLs; + sal_Bool m_bROSaveOrSend; + sal_Bool m_bROSigning; + sal_Bool m_bROPrint; + sal_Bool m_bROCreatePDF; + sal_Bool m_bRORemoveInfo; + sal_Bool m_bRORecommendPwd; + sal_Bool m_bROCtrlClickHyperlink; + sal_Bool m_bROSecLevel; + sal_Bool m_bROTrustedAuthors; + sal_Bool m_bRODisableMacros; + + + // xmlsec05 depricated + EBasicSecurityMode m_eBasicMode; + sal_Bool m_bExecutePlugins; + sal_Bool m_bWarning; + sal_Bool m_bConfirmation; + + sal_Bool m_bROConfirmation; + sal_Bool m_bROWarning; + sal_Bool m_bROExecutePlugins; + sal_Bool m_bROBasicMode; + public: + sal_Bool IsWarningEnabled() const; + void SetWarningEnabled( sal_Bool bSet ); + sal_Bool IsConfirmationEnabled() const; + void SetConfirmationEnabled( sal_Bool bSet ); + sal_Bool IsExecutePlugins() const; + void SetExecutePlugins( sal_Bool bSet ); + EBasicSecurityMode GetBasicMode ( ) const ; + void SetBasicMode ( EBasicSecurityMode eMode ) ; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtSecurityOptions_Impl::SvtSecurityOptions_Impl() + :ConfigItem ( ROOTNODE_SECURITY ) + ,m_seqSecureURLs ( DEFAULT_SECUREURL ) + ,m_bSaveOrSend ( sal_True ) + ,m_bSigning ( sal_True ) + ,m_bPrint ( sal_True ) + ,m_bCreatePDF ( sal_True ) + ,m_bRemoveInfo ( sal_True ) + ,m_nSecLevel ( sal_True ) + ,m_seqTrustedAuthors ( DEFAULT_TRUSTEDAUTHORS ) + ,m_bDisableMacros ( sal_False ) + ,m_bROSecureURLs ( CFG_READONLY_DEFAULT ) + ,m_bROSaveOrSend ( CFG_READONLY_DEFAULT ) + ,m_bROSigning ( CFG_READONLY_DEFAULT ) + ,m_bROPrint ( CFG_READONLY_DEFAULT ) + ,m_bROCreatePDF ( CFG_READONLY_DEFAULT ) + ,m_bRORemoveInfo ( CFG_READONLY_DEFAULT ) + ,m_bROSecLevel ( CFG_READONLY_DEFAULT ) + ,m_bROTrustedAuthors ( CFG_READONLY_DEFAULT ) + ,m_bRODisableMacros ( sal_True ) // currently is not intended to be changed + + // xmlsec05 depricated + , m_eBasicMode ( DEFAULT_STAROFFICEBASIC ) + , m_bExecutePlugins ( sal_True ) + , m_bWarning ( sal_True ) + , m_bConfirmation ( sal_True ) + , m_bROConfirmation ( CFG_READONLY_DEFAULT ) + , m_bROWarning ( CFG_READONLY_DEFAULT ) + , m_bROExecutePlugins ( CFG_READONLY_DEFAULT ) + , m_bROBasicMode ( CFG_READONLY_DEFAULT ) + // xmlsec05 depricated + +{ + Sequence< OUString > seqNames = GetPropertyNames ( ); + Sequence< Any > seqValues = GetProperties ( seqNames ); + Sequence< sal_Bool > seqRO = GetReadOnlyStates ( seqNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtSecurityOptions_Impl::SvtSecurityOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to our internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + for( sal_Int32 nProperty = 0 ; nProperty < nPropertyCount ; ++nProperty ) + SetProperty( nProperty, seqValues[ nProperty ], seqRO[ nProperty ] ); + + LoadAuthors(); + + // Enable notification mechanism of our baseclass. + // We need it to get information about changes outside these class on our used configuration keys!*/ + + EnableNotification( seqNames ); +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtSecurityOptions_Impl::~SvtSecurityOptions_Impl() +{ + if( IsModified() ) + Commit(); +} + +void SvtSecurityOptions_Impl::SetProperty( sal_Int32 nProperty, const Any& rValue, sal_Bool bRO ) +{ + switch( nProperty ) + { + case PROPERTYHANDLE_SECUREURL: + { + m_seqSecureURLs.realloc( 0 ); + rValue >>= m_seqSecureURLs; + SvtPathOptions aOpt; + sal_uInt32 nCount = m_seqSecureURLs.getLength(); + for( sal_uInt32 nItem = 0 ; nItem < nCount ; ++nItem ) + m_seqSecureURLs[ nItem ] = aOpt.SubstituteVariable( m_seqSecureURLs[ nItem ] ); + m_bROSecureURLs = bRO; + } + break; + + case PROPERTYHANDLE_DOCWARN_SAVEORSEND: + { + rValue >>= m_bSaveOrSend; + m_bROSaveOrSend = bRO; + } + break; + + case PROPERTYHANDLE_DOCWARN_SIGNING: + { + rValue >>= m_bSigning; + m_bROSigning = bRO; + } + break; + + case PROPERTYHANDLE_DOCWARN_PRINT: + { + rValue >>= m_bPrint; + m_bROPrint = bRO; + } + break; + + case PROPERTYHANDLE_DOCWARN_CREATEPDF: + { + rValue >>= m_bCreatePDF; + m_bROCreatePDF = bRO; + } + break; + + case PROPERTYHANDLE_DOCWARN_REMOVEPERSONALINFO: + { + rValue >>= m_bRemoveInfo; + m_bRORemoveInfo = bRO; + } + break; + + case PROPERTYHANDLE_DOCWARN_RECOMMENDPASSWORD: + { + rValue >>= m_bRecommendPwd; + m_bRORecommendPwd = bRO; + } + break; + + case PROPERTYHANDLE_CTRLCLICK_HYPERLINK: + { + rValue >>= m_bCtrlClickHyperlink; + m_bROCtrlClickHyperlink = bRO; + } + break; + + case PROPERTYHANDLE_MACRO_SECLEVEL: + { + rValue >>= m_nSecLevel; + m_bROSecLevel = bRO; + } + break; + + case PROPERTYHANDLE_MACRO_TRUSTEDAUTHORS: + { + // don't care about value here... + m_bROTrustedAuthors = bRO; + } + break; + + case PROPERTYHANDLE_MACRO_DISABLE: + { + rValue >>= m_bDisableMacros; + m_bRODisableMacros = bRO; + } + break; + + + // xmlsec05 depricated + case PROPERTYHANDLE_STAROFFICEBASIC: + { + sal_Int32 nMode = 0; + rValue >>= nMode; + m_eBasicMode = (EBasicSecurityMode)nMode; + m_bROBasicMode = bRO; + } + break; + case PROPERTYHANDLE_EXECUTEPLUGINS: + { + rValue >>= m_bExecutePlugins; + m_bROExecutePlugins = bRO; + } + break; + case PROPERTYHANDLE_WARNINGENABLED: + { + rValue >>= m_bWarning; + m_bROWarning = bRO; + } + break; + case PROPERTYHANDLE_CONFIRMATIONENABLED: + { + rValue >>= m_bConfirmation; + m_bROConfirmation = bRO; + } + break; + // xmlsec05 depricated + + + #if OSL_DEBUG_LEVEL > 1 + default: + DBG_ASSERT( false, "SvtSecurityOptions_Impl::SetProperty()\nUnkown property!\n" ); + #endif + } +} + +void SvtSecurityOptions_Impl::LoadAuthors( void ) +{ + m_seqTrustedAuthors.realloc( 0 ); // first clear + Sequence< OUString > lAuthors = GetNodeNames( PROPERTYNAME_MACRO_TRUSTEDAUTHORS ); + sal_Int32 c1 = lAuthors.getLength(); + if( c1 ) + { + sal_Int32 c2 = c1 * 3; // 3 Properties inside Struct TrustedAuthor + Sequence< OUString > lAllAuthors( c2 ); + + sal_Int32 i1; + sal_Int32 i2; + OUString aSep( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); + for( i1 = 0, i2 = 0 ; i1 < c1 ; ++i1 ) + { + lAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + lAuthors[ i1 ] + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME; + ++i2; + lAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + lAuthors[ i1 ] + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER; + ++i2; + lAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + lAuthors[ i1 ] + aSep + PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA; + ++i2; + } + + Sequence< Any > lValues = GetProperties( lAllAuthors ); + if( lValues.getLength() == c2 ) + { + m_seqTrustedAuthors.realloc( c1 ); + SvtSecurityOptions::Certificate aCert( 3 ); + for( i1 = 0, i2 = 0 ; i1 < c1 ; ++i1 ) + { + lValues[ i2 ] >>= aCert[ 0 ]; + ++i2; + lValues[ i2 ] >>= aCert[ 1 ]; + ++i2; + lValues[ i2 ] >>= aCert[ 2 ]; + ++i2; + m_seqTrustedAuthors[ i1 ] = aCert; + } + } + } +} + +sal_Int32 SvtSecurityOptions_Impl::GetHandle( const OUString& rName ) +{ + sal_Int32 nHandle; + + if( rName.compareToAscii( CSTR_SECUREURL ) == 0 ) + nHandle = PROPERTYHANDLE_SECUREURL; + else if( rName.compareToAscii( CSTR_DOCWARN_SAVEORSEND ) == 0 ) + nHandle = PROPERTYHANDLE_DOCWARN_SAVEORSEND; + else if( rName.compareToAscii( CSTR_DOCWARN_SIGNING ) == 0 ) + nHandle = PROPERTYHANDLE_DOCWARN_SIGNING; + else if( rName.compareToAscii( CSTR_DOCWARN_PRINT ) == 0 ) + nHandle = PROPERTYHANDLE_DOCWARN_PRINT; + else if( rName.compareToAscii( CSTR_DOCWARN_CREATEPDF ) == 0 ) + nHandle = PROPERTYHANDLE_DOCWARN_CREATEPDF; + else if( rName.compareToAscii( CSTR_DOCWARN_REMOVEPERSONALINFO ) == 0 ) + nHandle = PROPERTYHANDLE_DOCWARN_REMOVEPERSONALINFO; + else if( rName.compareToAscii( CSTR_DOCWARN_RECOMMENDPASSWORD ) == 0 ) + nHandle = PROPERTYHANDLE_DOCWARN_RECOMMENDPASSWORD; + else if( rName.compareToAscii( CSTR_CTRLCLICK_HYPERLINK ) == 0 ) + nHandle = PROPERTYHANDLE_CTRLCLICK_HYPERLINK; + else if( rName.compareToAscii( CSTR_MACRO_SECLEVEL ) == 0 ) + nHandle = PROPERTYHANDLE_MACRO_SECLEVEL; + else if( rName.compareToAscii( CSTR_MACRO_TRUSTEDAUTHORS ) == 0 ) + nHandle = PROPERTYHANDLE_MACRO_TRUSTEDAUTHORS; + else if( rName.compareToAscii( CSTR_MACRO_DISABLE ) == 0 ) + nHandle = PROPERTYHANDLE_MACRO_DISABLE; + + // xmlsec05 depricated + else if( rName == PROPERTYNAME_STAROFFICEBASIC ) + nHandle = PROPERTYHANDLE_STAROFFICEBASIC; + else if( rName == PROPERTYNAME_EXECUTEPLUGINS ) + nHandle = PROPERTYHANDLE_EXECUTEPLUGINS; + else if( rName == PROPERTYNAME_WARNINGENABLED ) + nHandle = PROPERTYHANDLE_WARNINGENABLED; + else if( rName == PROPERTYNAME_CONFIRMATIONENABLED ) + nHandle = PROPERTYHANDLE_CONFIRMATIONENABLED; + // xmlsec05 depricated + + else + nHandle = PROPERTYHANDLE_INVALID; + + return nHandle; +} + +bool SvtSecurityOptions_Impl::GetOption( SvtSecurityOptions::EOption eOption, sal_Bool*& rpValue, sal_Bool*& rpRO ) +{ + switch( eOption ) + { + case SvtSecurityOptions::E_DOCWARN_SAVEORSEND: + rpValue = &m_bSaveOrSend; + rpRO = &m_bROSaveOrSend; + break; + case SvtSecurityOptions::E_DOCWARN_SIGNING: + rpValue = &m_bSigning; + rpRO = &m_bROSigning; + break; + case SvtSecurityOptions::E_DOCWARN_PRINT: + rpValue = &m_bPrint; + rpRO = &m_bROPrint; + break; + case SvtSecurityOptions::E_DOCWARN_CREATEPDF: + rpValue = &m_bCreatePDF; + rpRO = &m_bROCreatePDF; + break; + case SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO: + rpValue = &m_bRemoveInfo; + rpRO = &m_bRORemoveInfo; + break; + case SvtSecurityOptions::E_DOCWARN_RECOMMENDPASSWORD: + rpValue = &m_bRecommendPwd; + rpRO = &m_bRORecommendPwd; + break; + case SvtSecurityOptions::E_CTRLCLICK_HYPERLINK: + rpValue = &m_bCtrlClickHyperlink; + rpRO = &m_bROCtrlClickHyperlink; + break; + default: + rpValue = NULL; + rpRO = NULL; + break; + } + + return rpValue != NULL; +} + +void SvtSecurityOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames ) +{ + // Use given list of updated properties to get his values from configuration directly! + Sequence< Any > seqValues = GetProperties( seqPropertyNames ); + Sequence< sal_Bool > seqRO = GetReadOnlyStates( seqPropertyNames ); + // Safe impossible cases. + // We need values from ALL notified configuration keys. + DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtSecurityOptions_Impl::Notify()\nI miss some values of configuration keys!\n" ); + // Step over list of property names and get right value from coreesponding value list to set it on internal members! + sal_Int32 nCount = seqPropertyNames.getLength(); + for( sal_Int32 nProperty = 0 ; nProperty < nCount ; ++nProperty ) + SetProperty( GetHandle( seqPropertyNames[ nProperty ] ), seqValues[ nProperty ], seqRO[ nProperty ] ); + + // read set of trusted authors separately + LoadAuthors(); +} + +void SvtSecurityOptions_Impl::Commit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + Sequence< OUString > lOrgNames = GetPropertyNames(); + sal_Int32 nOrgCount = lOrgNames.getLength(); + + Sequence< OUString > lNames(nOrgCount); + Sequence< Any > lValues(nOrgCount); + sal_Int32 nRealCount = 0; + bool bDone; + + ClearNodeSet( PROPERTYNAME_MACRO_TRUSTEDAUTHORS ); + + for( sal_Int32 nProperty = 0 ; nProperty < nOrgCount ; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_SECUREURL: + { + bDone = !m_bROSecureURLs; + if( bDone ) + { + Sequence< OUString > lURLs( m_seqSecureURLs ); + SvtPathOptions aOpt; + sal_Int32 nURLsCnt = lURLs.getLength(); + for( sal_Int32 nItem = 0 ; nItem < nURLsCnt ; ++nItem ) + lURLs[ nItem ] = aOpt.UseVariable( lURLs[ nItem ] ); + lValues[ nRealCount ] <<= lURLs; + } + } + break; + + case PROPERTYHANDLE_DOCWARN_SAVEORSEND: + { + bDone = !m_bROSaveOrSend; + if( bDone ) + lValues[ nRealCount ] <<= m_bSaveOrSend; + } + break; + + case PROPERTYHANDLE_DOCWARN_SIGNING: + { + bDone = !m_bROSigning; + if( bDone ) + lValues[ nRealCount ] <<= m_bSigning; + } + break; + + case PROPERTYHANDLE_DOCWARN_PRINT: + { + bDone = !m_bROPrint; + if( bDone ) + lValues[ nRealCount ] <<= m_bPrint; + } + break; + + case PROPERTYHANDLE_DOCWARN_CREATEPDF: + { + bDone = !m_bROCreatePDF; + if( bDone ) + lValues[ nRealCount ] <<= m_bCreatePDF; + } + break; + + case PROPERTYHANDLE_DOCWARN_REMOVEPERSONALINFO: + { + bDone = !m_bRORemoveInfo; + if( bDone ) + lValues[ nRealCount ] <<= m_bRemoveInfo; + } + break; + + case PROPERTYHANDLE_DOCWARN_RECOMMENDPASSWORD: + { + bDone = !m_bRORecommendPwd; + if( bDone ) + lValues[ nRealCount ] <<= m_bRecommendPwd; + } + break; + + case PROPERTYHANDLE_CTRLCLICK_HYPERLINK: + { + bDone = !m_bROCtrlClickHyperlink; + if( bDone ) + lValues[ nRealCount ] <<= m_bCtrlClickHyperlink; + } + break; + + case PROPERTYHANDLE_MACRO_SECLEVEL: + { + bDone = !m_bROSecLevel; + if( bDone ) + lValues[ nRealCount ] <<= m_nSecLevel; + } + break; + + case PROPERTYHANDLE_MACRO_TRUSTEDAUTHORS: + { + bDone = !m_bROTrustedAuthors; + if( bDone ) + { + sal_Int32 nCnt = m_seqTrustedAuthors.getLength(); + if( nCnt ) + { + String s; + s.AppendAscii( CSTR_MACRO_TRUSTEDAUTHORS ); + s.AppendAscii( "/a" ); + + Sequence< Sequence< com::sun::star::beans::PropertyValue > > lPropertyValuesSeq( nCnt ); + for( sal_Int32 i = 0 ; i < nCnt ; ++i ) + { + String aPrefix( s ); + aPrefix += String::CreateFromInt32( i ); + aPrefix.AppendAscii( "/" ); + Sequence< com::sun::star::beans::PropertyValue > lPropertyValues( 3 ); + lPropertyValues[ 0 ].Name = aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME; + lPropertyValues[ 0 ].Value <<= m_seqTrustedAuthors[ i ][0]; + lPropertyValues[ 1 ].Name = aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER; + lPropertyValues[ 1 ].Value <<= m_seqTrustedAuthors[ i ][1]; + lPropertyValues[ 2 ].Name = aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA; + lPropertyValues[ 2 ].Value <<= m_seqTrustedAuthors[ i ][2]; + + + SetSetProperties( PROPERTYNAME_MACRO_TRUSTEDAUTHORS, lPropertyValues ); + } + + bDone = false; // because we save in loop above! + } + else + bDone = false; + } + } + break; + + case PROPERTYHANDLE_MACRO_DISABLE: + { + bDone = !m_bRODisableMacros; + if( bDone ) + lValues[ nRealCount ] <<= (sal_Bool)m_bDisableMacros; + } + break; + + + // xmlsec05 depricated + case PROPERTYHANDLE_STAROFFICEBASIC: + { + bDone = !m_bROBasicMode; + if( bDone ) + lValues[ nRealCount ] <<= (sal_Int32)m_eBasicMode; + } + break; + case PROPERTYHANDLE_EXECUTEPLUGINS: + { + bDone = !m_bROExecutePlugins; + if( bDone ) + lValues[ nRealCount ] <<= m_bExecutePlugins; + } + break; + case PROPERTYHANDLE_WARNINGENABLED: + { + bDone = !m_bROWarning; + if( bDone ) + lValues[ nRealCount ] <<= m_bWarning; + } + break; + case PROPERTYHANDLE_CONFIRMATIONENABLED: + { + bDone = !m_bROConfirmation; + if( bDone ) + lValues[ nRealCount ] <<= m_bConfirmation; + } + break; + // xmlsec05 depricated + + + default: + bDone = false; + } + + if( bDone ) + { + lNames[ nRealCount ] = lOrgNames[ nProperty ]; + ++nRealCount; + } + } + // Set properties in configuration. + lNames.realloc(nRealCount); + lValues.realloc(nRealCount); + PutProperties( lNames, lValues ); +} + +sal_Bool SvtSecurityOptions_Impl::IsReadOnly( SvtSecurityOptions::EOption eOption ) const +{ + sal_Bool bReadonly; + switch(eOption) + { + case SvtSecurityOptions::E_SECUREURLS : + bReadonly = m_bROSecureURLs; + break; + case SvtSecurityOptions::E_DOCWARN_SAVEORSEND: + bReadonly = m_bROSaveOrSend; + break; + case SvtSecurityOptions::E_DOCWARN_SIGNING: + bReadonly = m_bROSigning; + break; + case SvtSecurityOptions::E_DOCWARN_PRINT: + bReadonly = m_bROPrint; + break; + case SvtSecurityOptions::E_DOCWARN_CREATEPDF: + bReadonly = m_bROCreatePDF; + break; + case SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO: + bReadonly = m_bRORemoveInfo; + break; + case SvtSecurityOptions::E_DOCWARN_RECOMMENDPASSWORD: + bReadonly = m_bRORecommendPwd; + break; + case SvtSecurityOptions::E_MACRO_SECLEVEL: + bReadonly = m_bROSecLevel; + break; + case SvtSecurityOptions::E_MACRO_TRUSTEDAUTHORS: + bReadonly = m_bROTrustedAuthors; + break; + case SvtSecurityOptions::E_MACRO_DISABLE: + bReadonly = m_bRODisableMacros; + break; + case SvtSecurityOptions::E_CTRLCLICK_HYPERLINK: + bReadonly = m_bROCtrlClickHyperlink; + break; + + + // xmlsec05 depricated + case SvtSecurityOptions::E_BASICMODE: + bReadonly = m_bROBasicMode; + break; + case SvtSecurityOptions::E_EXECUTEPLUGINS: + bReadonly = m_bROExecutePlugins; + break; + case SvtSecurityOptions::E_WARNING: + bReadonly = m_bROWarning; + break; + case SvtSecurityOptions::E_CONFIRMATION: + bReadonly = m_bROConfirmation; + break; + // xmlsec05 depricated + + + default: + bReadonly = sal_True; + } + + return bReadonly; +} + +Sequence< OUString > SvtSecurityOptions_Impl::GetSecureURLs() const +{ + return m_seqSecureURLs; +} + +void SvtSecurityOptions_Impl::SetSecureURLs( const Sequence< OUString >& seqURLList ) +{ + DBG_ASSERT(!m_bROSecureURLs, "SvtSecurityOptions_Impl::SetSecureURLs()\nYou tried to write on a readonly value!\n"); + if (!m_bROSecureURLs && m_seqSecureURLs!=seqURLList) + { + m_seqSecureURLs = seqURLList; + SetModified(); + } +} + +sal_Bool SvtSecurityOptions_Impl::IsSecureURL( const OUString& sURL , + const OUString& sReferer) const +{ + sal_Bool bState = sal_False; + + // Check for uncritical protocols first + // All protocols different from "macro..." and "slot..." are secure per definition and must not be checked. + // "macro://#..." means AppBasic macros that are considered safe + INetURLObject aURL ( sURL ); + INetProtocol aProtocol = aURL.GetProtocol(); + + // All other URLs must checked in combination with referer and internal information about security + if ( (aProtocol != INET_PROT_MACRO && aProtocol != INET_PROT_SLOT) || + aURL.GetMainURL( INetURLObject::NO_DECODE ).matchIgnoreAsciiCaseAsciiL( "macro:///", 9 ) == 0) + { + // security check only for "macro" ( without app basic ) or "slot" protocols + bState = sal_True; + } + else + { + // check list of allowed URL patterns + // Trusted referer given? + // NO => bState will be false per default + // YES => search for it in our internal url list + if( sReferer.getLength() > 0 ) + { + // Search in internal list + ::rtl::OUString sRef = sReferer.toAsciiLowerCase(); + sal_uInt32 nCount = m_seqSecureURLs.getLength(); + for( sal_uInt32 nItem=0; nItem<nCount; ++nItem ) + { + OUString sCheckURL = m_seqSecureURLs[nItem].toAsciiLowerCase(); + sCheckURL += OUString(RTL_CONSTASCII_USTRINGPARAM("*")); + if( WildCard( sCheckURL ).Matches( sRef ) == sal_True ) + { + bState = sal_True; + break; + } + } + + if ( !bState ) + bState = sRef.compareToAscii("private:user") == COMPARE_EQUAL; + } + } + + // Return result of operation. + return bState; +} + +inline sal_Int32 SvtSecurityOptions_Impl::GetMacroSecurityLevel() const +{ + return m_nSecLevel; +} + +inline sal_Bool SvtSecurityOptions_Impl::IsMacroDisabled() const +{ + return m_bDisableMacros; +} + +void SvtSecurityOptions_Impl::SetMacroSecurityLevel( sal_Int32 _nLevel ) +{ + if( !m_bROSecLevel ) + { + if( _nLevel > 3 || _nLevel < 0 ) + _nLevel = 3; + + if( m_nSecLevel != _nLevel ) + { + m_nSecLevel = _nLevel; + SetModified(); + } + } +} + +Sequence< SvtSecurityOptions::Certificate > SvtSecurityOptions_Impl::GetTrustedAuthors() const +{ + return m_seqTrustedAuthors; +} + +void SvtSecurityOptions_Impl::SetTrustedAuthors( const Sequence< SvtSecurityOptions::Certificate >& rAuthors ) +{ + DBG_ASSERT(!m_bROTrustedAuthors, "SvtSecurityOptions_Impl::SetTrustedAuthors()\nYou tried to write on a readonly value!\n"); + if( !m_bROTrustedAuthors && rAuthors != m_seqTrustedAuthors ) + { + m_seqTrustedAuthors = rAuthors; + SetModified(); + } +} + +sal_Bool SvtSecurityOptions_Impl::IsTrustedAuthorsEnabled() +{ + return m_bROTrustedAuthors; +} + +sal_Bool SvtSecurityOptions_Impl::IsOptionSet( SvtSecurityOptions::EOption eOption ) const +{ + sal_Bool* pValue; + sal_Bool* pRO; + sal_Bool bRet = sal_False; + + if( ( const_cast< SvtSecurityOptions_Impl* >( this ) )->GetOption( eOption, pValue, pRO ) ) + bRet = *pValue; + + return bRet; +} + +sal_Bool SvtSecurityOptions_Impl::SetOption( SvtSecurityOptions::EOption eOption, sal_Bool bValue ) +{ + sal_Bool* pValue; + sal_Bool* pRO; + sal_Bool bRet = sal_False; + + if( GetOption( eOption, pValue, pRO ) ) + { + if( !*pRO ) + { + bRet = sal_True; + if( *pValue != bValue ) + { + *pValue = bValue; + SetModified(); + } + } + } + + return bRet; +} + +sal_Bool SvtSecurityOptions_Impl::IsOptionEnabled( SvtSecurityOptions::EOption eOption ) const +{ + sal_Bool* pValue; + sal_Bool* pRO; + sal_Bool bRet = sal_False; + + if( ( const_cast< SvtSecurityOptions_Impl* >( this ) )->GetOption( eOption, pValue, pRO ) ) + bRet = !*pRO; + + return bRet; +} + +Sequence< OUString > SvtSecurityOptions_Impl::GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_SECUREURL, + PROPERTYNAME_STAROFFICEBASIC, + PROPERTYNAME_EXECUTEPLUGINS, + PROPERTYNAME_WARNINGENABLED, + PROPERTYNAME_CONFIRMATIONENABLED, + PROPERTYNAME_DOCWARN_SAVEORSEND, + PROPERTYNAME_DOCWARN_SIGNING, + PROPERTYNAME_DOCWARN_PRINT, + PROPERTYNAME_DOCWARN_CREATEPDF, + PROPERTYNAME_DOCWARN_REMOVEPERSONALINFO, + PROPERTYNAME_DOCWARN_RECOMMENDPASSWORD, + PROPERTYNAME_CTRLCLICK_HYPERLINK, + PROPERTYNAME_MACRO_SECLEVEL, + PROPERTYNAME_MACRO_TRUSTEDAUTHORS, + PROPERTYNAME_MACRO_DISABLE + }; + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtSecurityOptions_Impl* SvtSecurityOptions::m_pDataContainer = NULL ; +sal_Int32 SvtSecurityOptions::m_nRefCount = 0 ; + +SvtSecurityOptions::SvtSecurityOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetInitMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtSecurityOptions_Impl::ctor()"); + m_pDataContainer = new SvtSecurityOptions_Impl; + + ItemHolder1::holdConfigItem(E_SECURITYOPTIONS); + } +} + +SvtSecurityOptions::~SvtSecurityOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetInitMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +sal_Bool SvtSecurityOptions::IsReadOnly( EOption eOption ) const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsReadOnly(eOption); +} + +Sequence< OUString > SvtSecurityOptions::GetSecureURLs() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->GetSecureURLs(); +} + +void SvtSecurityOptions::SetSecureURLs( const Sequence< OUString >& seqURLList ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetSecureURLs( seqURLList ); +} + +sal_Bool SvtSecurityOptions::IsSecureURL( const OUString& sURL , + const OUString& sReferer ) const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsSecureURL( sURL, sReferer ); +} + +sal_Int32 SvtSecurityOptions::GetMacroSecurityLevel() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->GetMacroSecurityLevel(); +} + +void SvtSecurityOptions::SetMacroSecurityLevel( sal_Int32 _nLevel ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetMacroSecurityLevel( _nLevel ); +} + +sal_Bool SvtSecurityOptions::IsMacroDisabled() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsMacroDisabled(); +} + +Sequence< SvtSecurityOptions::Certificate > SvtSecurityOptions::GetTrustedAuthors() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->GetTrustedAuthors(); +} + +void SvtSecurityOptions::SetTrustedAuthors( const Sequence< Certificate >& rAuthors ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetTrustedAuthors( rAuthors ); +} + +sal_Bool SvtSecurityOptions::IsTrustedAuthorsEnabled() +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsTrustedAuthorsEnabled(); +} + +bool SvtSecurityOptions::IsOptionSet( EOption eOption ) const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsOptionSet( eOption ); +} + +bool SvtSecurityOptions::SetOption( EOption eOption, bool bValue ) +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->SetOption( eOption, bValue ); +} + +bool SvtSecurityOptions::IsOptionEnabled( EOption eOption ) const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsOptionEnabled( eOption ); +} + +Mutex& SvtSecurityOptions::GetInitMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be faster then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} + + + + +// xmlsec05 depricated + +EBasicSecurityMode SvtSecurityOptions_Impl::GetBasicMode() const +{ + return m_eBasicMode; +} + +void SvtSecurityOptions_Impl::SetBasicMode( EBasicSecurityMode eMode ) +{ + DBG_ASSERT(!m_bROBasicMode, "SvtSecurityOptions_Impl::SetBasicMode()\nYou tried to write on a readonly value!\n"); + if (!m_bROBasicMode && m_eBasicMode!=eMode) + { + m_eBasicMode = eMode; + SetModified(); + } +} + +sal_Bool SvtSecurityOptions_Impl::IsExecutePlugins() const +{ + return m_bExecutePlugins; +} + +void SvtSecurityOptions_Impl::SetExecutePlugins( sal_Bool bSet ) +{ + DBG_ASSERT(!m_bROExecutePlugins, "SvtSecurityOptions_Impl::SetExecutePlugins()\nYou tried to write on a readonly value!\n"); + if (!m_bROExecutePlugins && m_bExecutePlugins!=bSet) + { + m_bExecutePlugins = bSet; + SetModified(); + } +} + +sal_Bool SvtSecurityOptions_Impl::IsWarningEnabled() const +{ + return m_bWarning; +} + +void SvtSecurityOptions_Impl::SetWarningEnabled( sal_Bool bSet ) +{ + DBG_ASSERT(!m_bROWarning, "SvtSecurityOptions_Impl::SetWarningEnabled()\nYou tried to write on a readonly value!\n"); + if (!m_bROWarning && m_bWarning!=bSet) + { + m_bWarning = bSet; + SetModified(); + } +} + +sal_Bool SvtSecurityOptions_Impl::IsConfirmationEnabled() const +{ + return m_bConfirmation; +} + +void SvtSecurityOptions_Impl::SetConfirmationEnabled( sal_Bool bSet ) +{ + DBG_ASSERT(!m_bROConfirmation, "SvtSecurityOptions_Impl::SetConfirmationEnabled()\nYou tried to write on a readonly value!\n"); + if (!m_bROConfirmation && m_bConfirmation!=bSet) + { + m_bConfirmation = bSet; + SetModified(); + } +} + + +sal_Bool SvtSecurityOptions::IsExecutePlugins() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsExecutePlugins(); +} + +void SvtSecurityOptions::SetExecutePlugins( sal_Bool bSet ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetExecutePlugins( bSet ); +} + +sal_Bool SvtSecurityOptions::IsWarningEnabled() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsWarningEnabled(); +} + +void SvtSecurityOptions::SetWarningEnabled( sal_Bool bSet ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetWarningEnabled( bSet ); +} + +sal_Bool SvtSecurityOptions::IsConfirmationEnabled() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->IsConfirmationEnabled(); +} + +void SvtSecurityOptions::SetConfirmationEnabled( sal_Bool bSet ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetConfirmationEnabled( bSet ); +} + +void SvtSecurityOptions::SetBasicMode( EBasicSecurityMode eMode ) +{ + MutexGuard aGuard( GetInitMutex() ); + m_pDataContainer->SetBasicMode( eMode ); +} + +EBasicSecurityMode SvtSecurityOptions::GetBasicMode() const +{ + MutexGuard aGuard( GetInitMutex() ); + return m_pDataContainer->GetBasicMode(); +} + diff --git a/unotools/source/config/sourceviewconfig.cxx b/unotools/source/config/sourceviewconfig.cxx new file mode 100644 index 000000000000..cb37db74138d --- /dev/null +++ b/unotools/source/config/sourceviewconfig.cxx @@ -0,0 +1,268 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/sourceviewconfig.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <rtl/instance.hxx> + +#include <itemholder1.hxx> + +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; +namespace utl +{ +class SourceViewConfig_Impl : public utl::ConfigItem +{ +private: + OUString m_sFontName; + sal_Int16 m_nFontHeight; + sal_Bool m_bProportionalFontOnly; + + void Load(); + + static Sequence< OUString > GetPropertyNames(); + +public: + SourceViewConfig_Impl(); + ~SourceViewConfig_Impl(); + + virtual void Notify( const Sequence< rtl::OUString >& aPropertyNames ); + virtual void Commit(); + + const rtl::OUString& GetFontName() const + {return m_sFontName;} + void SetFontName(const rtl::OUString& rName) + { + if(rName != m_sFontName) + { + m_sFontName = rName; + SetModified(); + } + } + + sal_Int16 GetFontHeight() const + {return m_nFontHeight;} + void SetFontHeight(sal_Int16 nHeight) + { + if(m_nFontHeight != nHeight) + { + m_nFontHeight = nHeight; + SetModified(); + } + } + + sal_Bool IsShowProportionalFontsOnly() const + {return m_bProportionalFontOnly;} + void SetShowProportionalFontsOnly(sal_Bool bSet) + { + if(m_bProportionalFontOnly != bSet) + { + m_bProportionalFontOnly = bSet; + SetModified(); + } + } +}; +// initialization of static members -------------------------------------- +SourceViewConfig_Impl* SourceViewConfig::m_pImplConfig = 0; +sal_Int32 SourceViewConfig::m_nRefCount = 0; +namespace { struct lclMutex : public rtl::Static< ::osl::Mutex, lclMutex > {}; } +/* -----------------------------28.08.2002 16:45------------------------------ + + ---------------------------------------------------------------------------*/ +SourceViewConfig_Impl::SourceViewConfig_Impl() : + ConfigItem(OUString::createFromAscii("Office.Common/Font/SourceViewFont")), + m_nFontHeight(12), + m_bProportionalFontOnly(sal_False) +{ + Load(); +} +/* -----------------------------28.08.2002 16:45------------------------------ + + ---------------------------------------------------------------------------*/ +SourceViewConfig_Impl::~SourceViewConfig_Impl() +{ +} +/* -----------------------------28.08.2002 16:25------------------------------ + + ---------------------------------------------------------------------------*/ +Sequence< OUString > SourceViewConfig_Impl::GetPropertyNames() +{ + //this list needs exactly to mach the enum PropertyNameIndex + static const char* aPropNames[] = + { + "FontName" // 0 + ,"FontHeight" // 1 + ,"NonProportionalFontsOnly" // 2 + }; + const int nCount = sizeof( aPropNames ) / sizeof( const char* ); + Sequence< OUString > aNames( nCount ); + OUString* pNames = aNames.getArray(); + for ( int i = 0; i < nCount; i++ ) + pNames[i] = OUString::createFromAscii( aPropNames[i] ); + + return aNames; +} + +/*-- 28.08.2002 16:37:59--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SourceViewConfig_Impl::Load() +{ + Sequence< OUString > aNames = GetPropertyNames(); + Sequence< Any > aValues = GetProperties( aNames ); + EnableNotification( aNames ); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" ); + if ( aValues.getLength() == aNames.getLength() ) + { + for ( int nProp = 0; nProp < aNames.getLength(); nProp++ ) + { + if ( pValues[nProp].hasValue() ) + { + switch( nProp ) + { + case 0: pValues[nProp] >>= m_sFontName; break; + case 1: pValues[nProp] >>= m_nFontHeight; break; + case 2: pValues[nProp] >>= m_bProportionalFontOnly; break; + } + } + } + } +} +/*-- 28.08.2002 16:38:00--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SourceViewConfig_Impl::Notify( const Sequence< OUString >& ) +{ + Load(); +} +/*-- 28.08.2002 16:38:00--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SourceViewConfig_Impl::Commit() +{ + ClearModified(); + Sequence< OUString > aNames = GetPropertyNames(); + Sequence< Any > aValues( aNames.getLength() ); + Any* pValues = aValues.getArray(); + for ( int nProp = 0; nProp < aNames.getLength(); nProp++ ) + { + switch( nProp ) + { + case 0: pValues[nProp] <<= m_sFontName; break; + case 1: pValues[nProp] <<= m_nFontHeight; break; + case 2: pValues[nProp] <<= m_bProportionalFontOnly; break; + default: + DBG_ERRORFILE( "invalid index to save a user token" ); + } + } + PutProperties( aNames, aValues ); + + NotifyListeners(0); +} +/*-- 28.08.2002 16:32:19--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SourceViewConfig::SourceViewConfig() +{ + { + ::osl::MutexGuard aGuard( lclMutex::get() ); + if(!m_pImplConfig) + { + m_pImplConfig = new SourceViewConfig_Impl; + ItemHolder1::holdConfigItem(E_SOURCEVIEWCONFIG); + } + + ++m_nRefCount; + } + + m_pImplConfig->AddListener( this ); +} +/*-- 28.08.2002 16:32:19--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SourceViewConfig::~SourceViewConfig() +{ + m_pImplConfig->RemoveListener( this ); + ::osl::MutexGuard aGuard( lclMutex::get() ); + if( !--m_nRefCount ) + { + if( m_pImplConfig->IsModified() ) + m_pImplConfig->Commit(); + DELETEZ( m_pImplConfig ); + } +} +/*-- 28.08.2002 16:32:19--------------------------------------------------- + + -----------------------------------------------------------------------*/ +const OUString& SourceViewConfig::GetFontName() const +{ + return m_pImplConfig->GetFontName(); +} +/*-- 28.08.2002 16:32:20--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SourceViewConfig::SetFontName(const OUString& rName) +{ + m_pImplConfig->SetFontName(rName); +} +/*-- 28.08.2002 16:32:20--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Int16 SourceViewConfig::GetFontHeight() const +{ + return m_pImplConfig->GetFontHeight(); +} +/*-- 28.08.2002 16:32:20--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SourceViewConfig::SetFontHeight(sal_Int16 nHeight) +{ + m_pImplConfig->SetFontHeight(nHeight); +} +/*-- 28.08.2002 16:32:20--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SourceViewConfig::IsShowProportionalFontsOnly() const +{ + return m_pImplConfig->IsShowProportionalFontsOnly(); +} +/*-- 28.08.2002 16:32:20--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SourceViewConfig::SetShowProportionalFontsOnly(sal_Bool bSet) +{ + m_pImplConfig->SetShowProportionalFontsOnly(bSet); +} +} +// namespace utl diff --git a/unotools/source/config/startoptions.cxx b/unotools/source/config/startoptions.cxx new file mode 100644 index 000000000000..d6012c0ad84f --- /dev/null +++ b/unotools/source/config/startoptions.cxx @@ -0,0 +1,458 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/startoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define DEFAULT_SHOWINTRO sal_True +#define DEFAULT_CONNECTIONURL OUString() + +#define ROOTNODE_START OUString(RTL_CONSTASCII_USTRINGPARAM("Setup/Office" )) +#define PROPERTYNAME_SHOWINTRO OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupShowIntro" )) +#define PROPERTYNAME_CONNECTIONURL OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupConnectionURL" )) + +#define PROPERTYHANDLE_SHOWINTRO 0 +#define PROPERTYHANDLE_CONNECTIONURL 1 + +#define PROPERTYCOUNT 2 + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +class SvtStartOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtStartOptions_Impl(); + ~SvtStartOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @ATTENTION We don't implement these method - because we support readonly values at runtime only! + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& seqPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @ATTENTION We don't implement these method - because we support readonly values at runtime only! + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short access method to get internal values + @descr These method give us a chance to regulate acces to ouer internal values. + It's not used in the moment - but it's possible for the feature! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + sal_Bool IsIntroEnabled ( ) const ; + void EnableIntro ( sal_Bool bState ) ; + OUString GetConnectionURL( ) const ; + void SetConnectionURL( const OUString& sURL ) ; + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of fix key names of ouer configuration management which represent oue module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. We return well known key names only - because the "UserData" node + is handled in a special way! + + @seealso - + + @param - + @return A list of needed configuration keys is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + static Sequence< OUString > impl_GetPropertyNames(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + + sal_Bool m_bShowIntro ; /// cache "ShowIntro" of Start section + OUString m_sConnectionURL ; /// cache "Connection" of Start section +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtStartOptions_Impl::SvtStartOptions_Impl() + // Init baseclasses first + : ConfigItem ( ROOTNODE_START ) + // Init member then. + , m_bShowIntro ( DEFAULT_SHOWINTRO ) +{ + // Use our static list of configuration keys to get his values. + Sequence< OUString > seqNames = impl_GetPropertyNames(); + Sequence< Any > seqValues = GetProperties( seqNames ) ; + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + sal_Int32 nPropertyCount = seqValues.getLength() ; + sal_Int32 nProperty = 0 ; + for( nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + // Safe impossible cases. + // Check any for valid value. + DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nInvalid property value for property detected!\n" ); + switch( nProperty ) + { + case PROPERTYHANDLE_SHOWINTRO : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nWho has changed the value type of \"Office.Common\\Start\\ShowIntro\"?" ); + seqValues[nProperty] >>= m_bShowIntro; + } + break; + + case PROPERTYHANDLE_CONNECTIONURL : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_STRING), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nWho has changed the value type of \"Office.Common\\Start\\Connection\"?" ); + seqValues[nProperty] >>= m_sConnectionURL; + } + break; + } + } + + // Don't enable notification mechanism of ouer baseclass! + // We support readonly variables in the moment. +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtStartOptions_Impl::~SvtStartOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtStartOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames ) +{ + // Use given list of updated properties to get his values from configuration directly! + Sequence< Any > seqValues = GetProperties( seqPropertyNames ); + // Safe impossible cases. + // We need values from ALL notified configuration keys. + DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtStartOptions_Impl::Notify()\nI miss some values of configuration keys!\n" ); + // Step over list of property names and get right value from coreesponding value list to set it on internal members! + sal_Int32 nCount = seqPropertyNames.getLength(); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + if( seqPropertyNames[nProperty] == PROPERTYNAME_SHOWINTRO ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtStartOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Start\\ShowIntro\"?" ); + seqValues[nProperty] >>= m_bShowIntro; + } + else + if( seqPropertyNames[nProperty] == PROPERTYNAME_CONNECTIONURL ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_STRING), "SvtStartOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Start\\Connection\"?" ); + seqValues[nProperty] >>= m_sConnectionURL; + } + #if OSL_DEBUG_LEVEL > 1 + else DBG_ASSERT( sal_False, "SvtStartOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" ); + #endif + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtStartOptions_Impl::Commit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + Sequence< OUString > seqNames = impl_GetPropertyNames(); + sal_Int32 nCount = seqNames.getLength(); + Sequence< Any > seqValues ( nCount ); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_SHOWINTRO : { + seqValues[nProperty] <<= m_bShowIntro; + } + break; + case PROPERTYHANDLE_CONNECTIONURL : { + seqValues[nProperty] <<= m_sConnectionURL; + } + break; + } + } + // Set properties in configuration. + PutProperties( seqNames, seqValues ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtStartOptions_Impl::IsIntroEnabled() const +{ + return m_bShowIntro; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtStartOptions_Impl::EnableIntro( sal_Bool bState ) +{ + m_bShowIntro = bState; + SetModified(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +OUString SvtStartOptions_Impl::GetConnectionURL() const +{ + return m_sConnectionURL; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtStartOptions_Impl::SetConnectionURL( const OUString& sURL ) +{ + m_sConnectionURL = sURL; + SetModified(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtStartOptions_Impl::impl_GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_SHOWINTRO , + PROPERTYNAME_CONNECTIONURL , + }; + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtStartOptions_Impl* SvtStartOptions::m_pDataContainer = NULL ; +sal_Int32 SvtStartOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtStartOptions::SvtStartOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already! + if( m_pDataContainer == NULL ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtStartOptions_Impl::ctor()"); + m_pDataContainer = new SvtStartOptions_Impl(); + + ItemHolder1::holdConfigItem(E_STARTOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtStartOptions::~SvtStartOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtStartOptions::IsIntroEnabled() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsIntroEnabled(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtStartOptions::EnableIntro( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->EnableIntro( bState ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +OUString SvtStartOptions::GetConnectionURL() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetConnectionURL(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtStartOptions::SetConnectionURL( const OUString& sURL ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetConnectionURL( sURL ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtStartOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/syslocaleoptions.cxx b/unotools/source/config/syslocaleoptions.cxx new file mode 100644 index 000000000000..35333b0db6a8 --- /dev/null +++ b/unotools/source/config/syslocaleoptions.cxx @@ -0,0 +1,702 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <com/sun/star/uno/Sequence.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/instance.hxx> +#include <rtl/logfile.hxx> +#include <i18npool/mslangid.hxx> +#include <tools/string.hxx> +#include <tools/debug.hxx> +#include <unotools/syslocaleoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <com/sun/star/uno/Any.hxx> + +#include "itemholder1.hxx" + +#define CFG_READONLY_DEFAULT sal_False + +using namespace osl; +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + + +SvtSysLocaleOptions_Impl* SvtSysLocaleOptions::pOptions = NULL; +sal_Int32 SvtSysLocaleOptions::nRefCount = 0; +namespace +{ + struct CurrencyChangeLink + : public rtl::Static<Link, CurrencyChangeLink> {}; +} + +com::sun::star::lang::Locale lcl_str_to_locale( const ::rtl::OUString rStr ) +{ + com::sun::star::lang::Locale aRet; + if ( rStr.getLength() ) + { + aRet = com::sun::star::lang::Locale(); + sal_Int32 nSep = rStr.indexOf('-'); + if (nSep < 0) + aRet.Language = rStr; + else + { + aRet.Language = rStr.copy(0, nSep); + if (nSep < rStr.getLength()) + aRet.Country = rStr.copy(nSep+1, rStr.getLength() - (nSep+1)); + } + } + + return aRet; +} + +class SvtSysLocaleOptions_Impl : public utl::ConfigItem +{ + Locale m_aRealLocale; + Locale m_aRealUILocale; + LanguageType m_eRealLanguage; + LanguageType m_eRealUILanguage; + OUString m_aLocaleString; // en-US or de-DE or empty for SYSTEM + OUString m_aUILocaleString; // en-US or de-DE or empty for SYSTEM + OUString m_aCurrencyString; // USD-en-US or EUR-de-DE + ULONG m_nBlockedHint; // pending hints + sal_Bool m_bDecimalSeparator; //use decimal separator same as locale + + sal_Bool m_bROLocale; + sal_Bool m_bROUILocale; + sal_Bool m_bROCurrency; + sal_Bool m_bRODecimalSeparator; + + static const Sequence< /* const */ OUString > GetPropertyNames(); + void MakeRealLocale(); + void MakeRealUILocale(); + +public: + SvtSysLocaleOptions_Impl(); + virtual ~SvtSysLocaleOptions_Impl(); + + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + virtual void Commit(); + + const OUString& GetLocaleString() const + { return m_aLocaleString; } + void SetLocaleString( const OUString& rStr ); + + const OUString& GetUILocaleString() const + { return m_aUILocaleString; } + void SetUILocaleString( const OUString& rStr ); + + const OUString& GetCurrencyString() const + { return m_aCurrencyString; } + void SetCurrencyString( const OUString& rStr ); + + sal_Bool IsDecimalSeparatorAsLocale() const { return m_bDecimalSeparator;} + void SetDecimalSeparatorAsLocale( sal_Bool bSet); + + sal_Bool IsReadOnly( SvtSysLocaleOptions::EOption eOption ) const; + const Locale& GetRealLocale() { return m_aRealLocale; } + const Locale& GetRealUILocale() { return m_aRealUILocale; } + LanguageType GetRealLanguage() { return m_eRealLanguage; } + LanguageType GetRealUILanguage() { return m_eRealUILanguage; } +}; + + +#define ROOTNODE_SYSLOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("Setup/L10N")) + +#define PROPERTYNAME_LOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupSystemLocale")) +#define PROPERTYNAME_UILOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("ooLocale")) +#define PROPERTYNAME_CURRENCY OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupCurrency")) +#define PROPERTYNAME_DECIMALSEPARATOR OUString(RTL_CONSTASCII_USTRINGPARAM("DecimalSeparatorAsLocale")) + +#define PROPERTYHANDLE_LOCALE 0 +#define PROPERTYHANDLE_UILOCALE 1 +#define PROPERTYHANDLE_CURRENCY 2 +#define PROPERTYHANDLE_DECIMALSEPARATOR 3 + +#define PROPERTYCOUNT 4 + +const Sequence< OUString > SvtSysLocaleOptions_Impl::GetPropertyNames() +{ + static const OUString pProperties[] = + { + PROPERTYNAME_LOCALE, + PROPERTYNAME_UILOCALE, + PROPERTYNAME_CURRENCY, + PROPERTYNAME_DECIMALSEPARATOR + }; + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + return seqPropertyNames; +} + +// ----------------------------------------------------------------------- + +SvtSysLocaleOptions_Impl::SvtSysLocaleOptions_Impl() + : ConfigItem( ROOTNODE_SYSLOCALE ) + , m_nBlockedHint( 0 ) + , m_bDecimalSeparator( sal_True ) + , m_bROLocale(CFG_READONLY_DEFAULT) + , m_bROUILocale(CFG_READONLY_DEFAULT) + , m_bROCurrency(CFG_READONLY_DEFAULT) + , m_bRODecimalSeparator(sal_False) + +{ + if ( IsValidConfigMgr() ) + { + const Sequence< OUString > aNames = GetPropertyNames(); + Sequence< Any > aValues = GetProperties( aNames ); + Sequence< sal_Bool > aROStates = GetReadOnlyStates( aNames ); + const Any* pValues = aValues.getConstArray(); + const sal_Bool* pROStates = aROStates.getConstArray(); + DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" ); + DBG_ASSERT( aROStates.getLength() == aNames.getLength(), "GetReadOnlyStates failed" ); + if ( aValues.getLength() == aNames.getLength() && aROStates.getLength() == aNames.getLength() ) + { + for ( sal_Int32 nProp = 0; nProp < aNames.getLength(); nProp++ ) + { + DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" ); + if ( pValues[nProp].hasValue() ) + { + switch ( nProp ) + { + case PROPERTYHANDLE_LOCALE : + { + OUString aStr; + if ( pValues[nProp] >>= aStr ) + m_aLocaleString = aStr; + else + { + DBG_ERRORFILE( "Wrong property type!" ); + } + m_bROLocale = pROStates[nProp]; + } + break; + case PROPERTYHANDLE_UILOCALE : + { + OUString aStr; + if ( pValues[nProp] >>= aStr ) + m_aUILocaleString = aStr; + else + { + DBG_ERRORFILE( "Wrong property type!" ); + } + m_bROUILocale = pROStates[nProp]; + } + break; + case PROPERTYHANDLE_CURRENCY : + { + OUString aStr; + if ( pValues[nProp] >>= aStr ) + m_aCurrencyString = aStr; + else + { + DBG_ERRORFILE( "Wrong property type!" ); + } + m_bROCurrency = pROStates[nProp]; + } + break; + case PROPERTYHANDLE_DECIMALSEPARATOR: + { + sal_Bool bValue = sal_Bool(); + if ( pValues[nProp] >>= bValue ) + m_bDecimalSeparator = bValue; + else + { + DBG_ERRORFILE( "Wrong property type!" ); + } + m_bRODecimalSeparator = pROStates[nProp]; + } + break; + default: + DBG_ERRORFILE( "Wrong property type!" ); + } + } + } + } +// UpdateMiscSettings_Impl(); + EnableNotification( aNames ); + } + + MakeRealLocale(); + MakeRealUILocale(); +} + + +SvtSysLocaleOptions_Impl::~SvtSysLocaleOptions_Impl() +{ + if ( IsModified() ) + Commit(); +} + +void SvtSysLocaleOptions_Impl::MakeRealLocale() +{ + m_aRealLocale = lcl_str_to_locale( m_aLocaleString ); + if ( m_aRealLocale.Language.getLength() ) + { + m_eRealLanguage = MsLangId::convertLocaleToLanguage( m_aRealLocale ); + } + else + { + m_eRealLanguage = MsLangId::getSystemLanguage(); + MsLangId::convertLanguageToLocale( m_eRealLanguage, m_aRealLocale ); + } +} + +void SvtSysLocaleOptions_Impl::MakeRealUILocale() +{ + if ( !m_aRealUILocale.Language.getLength() ) + { + // as we can't switch UILocale at runtime, we only store changes in the configuration + m_aRealUILocale = lcl_str_to_locale( m_aUILocaleString ); + if ( m_aRealUILocale.Language.getLength() ) + { + m_eRealUILanguage = MsLangId::convertLocaleToLanguage( m_aRealUILocale ); + } + else + { + m_eRealUILanguage = MsLangId::getSystemUILanguage(); + MsLangId::convertLanguageToLocale( m_eRealUILanguage, m_aRealUILocale ); + } + } +} + +sal_Bool SvtSysLocaleOptions_Impl::IsReadOnly( SvtSysLocaleOptions::EOption eOption ) const +{ + sal_Bool bReadOnly = CFG_READONLY_DEFAULT; + switch(eOption) + { + case SvtSysLocaleOptions::E_LOCALE : + { + bReadOnly = m_bROLocale; + break; + } + case SvtSysLocaleOptions::E_UILOCALE : + { + bReadOnly = m_bROUILocale; + break; + } + case SvtSysLocaleOptions::E_CURRENCY : + { + bReadOnly = m_bROCurrency; + break; + } + } + return bReadOnly; +} + + +void SvtSysLocaleOptions_Impl::Commit() +{ + const Sequence< OUString > aOrgNames = GetPropertyNames(); + sal_Int32 nOrgCount = aOrgNames.getLength(); + + Sequence< OUString > aNames( nOrgCount ); + Sequence< Any > aValues( nOrgCount ); + + OUString* pNames = aNames.getArray(); + Any* pValues = aValues.getArray(); + sal_Int32 nRealCount = 0; + + for ( sal_Int32 nProp = 0; nProp < nOrgCount; nProp++ ) + { + switch ( nProp ) + { + case PROPERTYHANDLE_LOCALE : + { + if (!m_bROLocale) + { + pNames[nRealCount] = aOrgNames[nProp]; + pValues[nRealCount] <<= m_aLocaleString; + ++nRealCount; + } + } + break; + case PROPERTYHANDLE_UILOCALE : + { + if (!m_bROUILocale) + { + pNames[nRealCount] = aOrgNames[nProp]; + pValues[nRealCount] <<= m_aUILocaleString; + ++nRealCount; + } + } + break; + case PROPERTYHANDLE_CURRENCY : + { + if (!m_bROCurrency) + { + pNames[nRealCount] = aOrgNames[nProp]; + pValues[nRealCount] <<= m_aCurrencyString; + ++nRealCount; + } + } + break; + case PROPERTYHANDLE_DECIMALSEPARATOR: + if( !m_bRODecimalSeparator ) + { + pNames[nRealCount] = aOrgNames[nProp]; + pValues[nRealCount] <<= m_bDecimalSeparator; + ++nRealCount; + } + break; + default: + DBG_ERRORFILE( "invalid index to save a path" ); + } + } + aNames.realloc(nRealCount); + aValues.realloc(nRealCount); + PutProperties( aNames, aValues ); + ClearModified(); +} + + +void SvtSysLocaleOptions_Impl::SetLocaleString( const OUString& rStr ) +{ + if (!m_bROLocale && rStr != m_aLocaleString ) + { + m_aLocaleString = rStr; + MakeRealLocale(); + MsLangId::setConfiguredSystemLanguage( m_eRealLanguage ); + SetModified(); + ULONG nHint = SYSLOCALEOPTIONS_HINT_LOCALE; + if ( !m_aCurrencyString.getLength() ) + nHint |= SYSLOCALEOPTIONS_HINT_CURRENCY; + NotifyListeners( nHint ); + } +} + +void SvtSysLocaleOptions_Impl::SetUILocaleString( const OUString& rStr ) +{ + if (!m_bROUILocale && rStr != m_aUILocaleString ) + { + m_aUILocaleString = rStr; +/* + // as we can't switch UILocale at runtime, we only store changes in the configuration + MakeRealUILocale(); + MsLangId::setConfiguredSystemLanguage( m_eRealUILanguage ); + SetModified(); + NotifyListeners( SYSLOCALEOPTIONS_HINT_UILOCALE ); +*/ + } +} + +void SvtSysLocaleOptions_Impl::SetCurrencyString( const OUString& rStr ) +{ + if (!m_bROCurrency && rStr != m_aCurrencyString ) + { + m_aCurrencyString = rStr; + SetModified(); + NotifyListeners( SYSLOCALEOPTIONS_HINT_CURRENCY ); + } +} + +void SvtSysLocaleOptions_Impl::SetDecimalSeparatorAsLocale( sal_Bool bSet) +{ + if(bSet != m_bDecimalSeparator) + { + m_bDecimalSeparator = bSet; + SetModified(); + NotifyListeners( SYSLOCALEOPTIONS_HINT_DECSEP ); + } +} + +void SvtSysLocaleOptions_Impl::Notify( const Sequence< rtl::OUString >& seqPropertyNames ) +{ + ULONG nHint = 0; + Sequence< Any > seqValues = GetProperties( seqPropertyNames ); + Sequence< sal_Bool > seqROStates = GetReadOnlyStates( seqPropertyNames ); + sal_Int32 nCount = seqPropertyNames.getLength(); + for( sal_Int32 nProp = 0; nProp < nCount; ++nProp ) + { + if( seqPropertyNames[nProp] == PROPERTYNAME_LOCALE ) + { + DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "Locale property type" ); + seqValues[nProp] >>= m_aLocaleString; + m_bROLocale = seqROStates[nProp]; + nHint |= SYSLOCALEOPTIONS_HINT_LOCALE; + if ( !m_aCurrencyString.getLength() ) + nHint |= SYSLOCALEOPTIONS_HINT_CURRENCY; + MakeRealLocale(); + } + if( seqPropertyNames[nProp] == PROPERTYNAME_UILOCALE ) + { + DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "Locale property type" ); + seqValues[nProp] >>= m_aUILocaleString; + m_bROUILocale = seqROStates[nProp]; + nHint |= SYSLOCALEOPTIONS_HINT_UILOCALE; + MakeRealUILocale(); + } + else if( seqPropertyNames[nProp] == PROPERTYNAME_CURRENCY ) + { + DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "Currency property type" ); + seqValues[nProp] >>= m_aCurrencyString; + m_bROCurrency = seqROStates[nProp]; + nHint |= SYSLOCALEOPTIONS_HINT_CURRENCY; + } + else if( seqPropertyNames[nProp] == PROPERTYNAME_DECIMALSEPARATOR ) + { + seqValues[nProp] >>= m_bDecimalSeparator; + m_bRODecimalSeparator = seqROStates[nProp]; + } + } + if ( nHint ) + NotifyListeners( nHint ); +} + +// ==================================================================== + +SvtSysLocaleOptions::SvtSysLocaleOptions() +{ + MutexGuard aGuard( GetMutex() ); + if ( !pOptions ) + { + RTL_LOGFILE_CONTEXT(aLog, "svl ( ??? ) ::SvtSysLocaleOptions_Impl::ctor()"); + pOptions = new SvtSysLocaleOptions_Impl; + + ItemHolder1::holdConfigItem(E_SYSLOCALEOPTIONS); + } + ++nRefCount; + pOptions->AddListener(this); +} + + +SvtSysLocaleOptions::~SvtSysLocaleOptions() +{ + MutexGuard aGuard( GetMutex() ); + pOptions->RemoveListener(this); + if ( !--nRefCount ) + { + delete pOptions; + pOptions = NULL; + } +} + + +// static +Mutex& SvtSysLocaleOptions::GetMutex() +{ + static Mutex* pMutex = NULL; + if( !pMutex ) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if( !pMutex ) + { + // #i77768# Due to a static reference in the toolkit lib + // we need a mutex that lives longer than the svl library. + // Otherwise the dtor would use a destructed mutex!! + pMutex = new Mutex; + } + } + return *pMutex; +} + + +sal_Bool SvtSysLocaleOptions::IsModified() +{ + MutexGuard aGuard( GetMutex() ); + return pOptions->IsModified(); +} + + +void SvtSysLocaleOptions::Commit() +{ + MutexGuard aGuard( GetMutex() ); + pOptions->Commit(); +} + + +void SvtSysLocaleOptions::BlockBroadcasts( bool bBlock ) +{ + MutexGuard aGuard( GetMutex() ); + pOptions->BlockBroadcasts( bBlock ); +} + + +const OUString& SvtSysLocaleOptions::GetLocaleConfigString() const +{ + MutexGuard aGuard( GetMutex() ); + return pOptions->GetLocaleString(); +} + +void SvtSysLocaleOptions::SetLocaleConfigString( const OUString& rStr ) +{ + MutexGuard aGuard( GetMutex() ); + pOptions->SetLocaleString( rStr ); +} + +const OUString& SvtSysLocaleOptions::GetUILocaleConfigString() const +{ + MutexGuard aGuard( GetMutex() ); + return pOptions->GetUILocaleString(); +} + +void SvtSysLocaleOptions::SetUILocaleConfigString( const OUString& rStr ) +{ + MutexGuard aGuard( GetMutex() ); + pOptions->SetUILocaleString( rStr ); +} + +const OUString& SvtSysLocaleOptions::GetCurrencyConfigString() const +{ + MutexGuard aGuard( GetMutex() ); + return pOptions->GetCurrencyString(); +} + + +void SvtSysLocaleOptions::SetCurrencyConfigString( const OUString& rStr ) +{ + MutexGuard aGuard( GetMutex() ); + pOptions->SetCurrencyString( rStr ); +} + + + +/*-- 11.02.2004 13:31:41--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtSysLocaleOptions::IsDecimalSeparatorAsLocale() const +{ + MutexGuard aGuard( GetMutex() ); + return pOptions->IsDecimalSeparatorAsLocale(); +} +/*-- 11.02.2004 13:31:41--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtSysLocaleOptions::SetDecimalSeparatorAsLocale( sal_Bool bSet) +{ + MutexGuard aGuard( GetMutex() ); + pOptions->SetDecimalSeparatorAsLocale(bSet); +} + + +sal_Bool SvtSysLocaleOptions::IsReadOnly( EOption eOption ) const +{ + MutexGuard aGuard( GetMutex() ); + return pOptions->IsReadOnly( eOption ); +} + +// static +void SvtSysLocaleOptions::GetCurrencyAbbrevAndLanguage( String& rAbbrev, + LanguageType& eLang, const ::rtl::OUString& rConfigString ) +{ + sal_Int32 nDelim = rConfigString.indexOf( '-' ); + if ( nDelim >= 0 ) + { + rAbbrev = rConfigString.copy( 0, nDelim ); + String aIsoStr( rConfigString.copy( nDelim+1 ) ); + eLang = MsLangId::convertIsoStringToLanguage( aIsoStr ); + } + else + { + rAbbrev = rConfigString; + eLang = (rAbbrev.Len() ? LANGUAGE_NONE : LANGUAGE_SYSTEM); + } +} + + +// static +::rtl::OUString SvtSysLocaleOptions::CreateCurrencyConfigString( + const String& rAbbrev, LanguageType eLang ) +{ + String aIsoStr( MsLangId::convertLanguageToIsoString( eLang ) ); + if ( aIsoStr.Len() ) + { + ::rtl::OUStringBuffer aStr( rAbbrev.Len() + 1 + aIsoStr.Len() ); + aStr.append( rAbbrev.GetBuffer(), rAbbrev.Len() ); + aStr.append( sal_Unicode('-') ); + aStr.append( aIsoStr.GetBuffer(), aIsoStr.Len() ); + return aStr.makeStringAndClear(); + } + else + return rAbbrev; +} + + +// static +void SvtSysLocaleOptions::SetCurrencyChangeLink( const Link& rLink ) +{ + MutexGuard aGuard( GetMutex() ); + DBG_ASSERT( !CurrencyChangeLink::get().IsSet(), "SvtSysLocaleOptions::SetCurrencyChangeLink: already set" ); + CurrencyChangeLink::get() = rLink; +} + + +// static +const Link& SvtSysLocaleOptions::GetCurrencyChangeLink() +{ + MutexGuard aGuard( GetMutex() ); + return CurrencyChangeLink::get(); +} + + +void SvtSysLocaleOptions::ConfigurationChanged( utl::ConfigurationBroadcaster* p, sal_uInt32 nHint ) +{ + if ( nHint & SYSLOCALEOPTIONS_HINT_CURRENCY ) + { + const Link& rLink = GetCurrencyChangeLink(); + if ( rLink.IsSet() ) + rLink.Call( NULL ); + } + + ::utl::detail::Options::ConfigurationChanged( p, nHint ); +} + +com::sun::star::lang::Locale SvtSysLocaleOptions::GetLocale() const +{ + return lcl_str_to_locale( GetLocaleConfigString() ); +} + +com::sun::star::lang::Locale SvtSysLocaleOptions::GetUILocale() const +{ + return lcl_str_to_locale( GetUILocaleConfigString() ); +} + +com::sun::star::lang::Locale SvtSysLocaleOptions::GetRealLocale() const +{ + return pOptions->GetRealLocale(); +} + +com::sun::star::lang::Locale SvtSysLocaleOptions::GetRealUILocale() const +{ + return pOptions->GetRealUILocale(); +} + +LanguageType SvtSysLocaleOptions::GetRealLanguage() const +{ + return pOptions->GetRealLanguage(); +} + +LanguageType SvtSysLocaleOptions::GetRealUILanguage() const +{ + return pOptions->GetRealUILanguage(); +} + + diff --git a/unotools/source/config/undoopt.cxx b/unotools/source/config/undoopt.cxx new file mode 100644 index 000000000000..25cb7837008f --- /dev/null +++ b/unotools/source/config/undoopt.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/undoopt.hxx> +#include "rtl/instance.hxx" +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <vos/mutex.hxx> +#include <osl/mutex.hxx> +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +using namespace utl; +using namespace rtl; +using namespace com::sun::star::uno; + +static SvtUndoOptions_Impl* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +#define STEPS 0 + +class SvtUndoOptions_Impl : public utl::ConfigItem +{ + sal_Int32 nUndoCount; + Sequence< rtl::OUString > m_aPropertyNames; + +public: + SvtUndoOptions_Impl(); + + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + virtual void Commit(); + void Load(); + + void SetUndoCount( sal_Int32 n ) { nUndoCount = n; SetModified(); } + sal_Int32 GetUndoCount() const { return nUndoCount; } +}; + +// ----------------------------------------------------------------------- + +SvtUndoOptions_Impl::SvtUndoOptions_Impl() + : ConfigItem( OUString::createFromAscii("Office.Common/Undo") ) + , nUndoCount( 20 ) +{ + Load(); +} + +void SvtUndoOptions_Impl::Commit() +{ + Sequence< Any > aValues( m_aPropertyNames.getLength() ); + Any* pValues = aValues.getArray(); + for ( int nProp = 0; nProp < m_aPropertyNames.getLength(); nProp++ ) + { + switch ( nProp ) + { + case STEPS : + pValues[nProp] <<= nUndoCount; + break; + default: + DBG_ERRORFILE( "invalid index to save a path" ); + } + } + + PutProperties( m_aPropertyNames, aValues ); + NotifyListeners(0); +} + +// ----------------------------------------------------------------------- +void SvtUndoOptions_Impl::Load() +{ + if(!m_aPropertyNames.getLength()) + { + static const char* aPropNames[] = + { + "Steps", + }; + + const int nCount = sizeof( aPropNames ) / sizeof( const char* ); + m_aPropertyNames.realloc(nCount); + OUString* pNames = m_aPropertyNames.getArray(); + for ( int i = 0; i < nCount; i++ ) + pNames[i] = OUString::createFromAscii( aPropNames[i] ); + EnableNotification( m_aPropertyNames ); + } + + Sequence< Any > aValues = GetProperties( m_aPropertyNames ); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT( aValues.getLength() == m_aPropertyNames.getLength(), "GetProperties failed" ); + if ( aValues.getLength() == m_aPropertyNames.getLength() ) + { + for ( int nProp = 0; nProp < m_aPropertyNames.getLength(); nProp++ ) + { + DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" ); + if ( pValues[nProp].hasValue() ) + { + switch ( nProp ) + { + case STEPS : + { + sal_Int32 nTemp = 0; + if ( pValues[nProp] >>= nTemp ) + nUndoCount = nTemp; + else + { + DBG_ERROR( "Wrong Type!" ); + } + break; + } + + default: + DBG_ERROR( "Wrong Type!" ); + break; + } + } + } + } +} +// ----------------------------------------------------------------------- +void SvtUndoOptions_Impl::Notify( const Sequence<rtl::OUString>& ) +{ + Load(); +} + +// ----------------------------------------------------------------------- +namespace +{ + class LocalSingleton : public rtl::Static< osl::Mutex, LocalSingleton > + { + }; +} + +// ----------------------------------------------------------------------- +SvtUndoOptions::SvtUndoOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + if ( !pOptions ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtUndoOptions_Impl::ctor()"); + pOptions = new SvtUndoOptions_Impl; + + ItemHolder1::holdConfigItem(E_UNDOOPTIONS); + } + ++nRefCount; + pImp = pOptions; + pImp->AddListener(this); +} + +// ----------------------------------------------------------------------- + +SvtUndoOptions::~SvtUndoOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( LocalSingleton::get() ); + pImp->RemoveListener(this); + if ( !--nRefCount ) + { + if ( pOptions->IsModified() ) + pOptions->Commit(); + DELETEZ( pOptions ); + } +} + +void SvtUndoOptions::SetUndoCount( sal_Int32 n ) +{ + pImp->SetUndoCount( n ); +} + +sal_Int32 SvtUndoOptions::GetUndoCount() const +{ + return pImp->GetUndoCount(); +} diff --git a/unotools/source/config/useroptions.cxx b/unotools/source/config/useroptions.cxx new file mode 100644 index 000000000000..6c63bbfee34b --- /dev/null +++ b/unotools/source/config/useroptions.cxx @@ -0,0 +1,1297 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/useroptions.hxx> +#include <unotools/useroptions_const.hxx> + +#include <unotools/configmgr.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <vos/mutex.hxx> +#include <rtl/instance.hxx> +#include <rtl/logfile.hxx> +#include "itemholder1.hxx" + +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <com/sun/star/util/ChangesEvent.hpp> +#include <comphelper/configurationhelper.hxx> +#include <unotools/processfactory.hxx> +#include <unotools/loghelper.hxx> + +using namespace utl; +using namespace rtl; +using namespace com::sun::star; +using namespace com::sun::star::uno; + +namespace css = ::com::sun::star; + +// class SvtUserOptions_Impl --------------------------------------------- +class SvtUserOptions_Impl; +class SvtUserConfigChangeListener_Impl : public cppu::WeakImplHelper1 +< + com::sun::star::util::XChangesListener +> +{ + SvtUserOptions_Impl& m_rParent; + public: + SvtUserConfigChangeListener_Impl(SvtUserOptions_Impl& rParent); + ~SvtUserConfigChangeListener_Impl(); + + //XChangesListener + virtual void SAL_CALL changesOccurred( const util::ChangesEvent& Event ) throw(RuntimeException); + //XEventListener + virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw(RuntimeException); +}; + +class SvtUserOptions_Impl : public utl::ConfigurationBroadcaster +{ +public: + SvtUserOptions_Impl(); + ~SvtUserOptions_Impl(); + + // get the user token + ::rtl::OUString GetCompany() const; + ::rtl::OUString GetFirstName() const; + ::rtl::OUString GetLastName() const; + ::rtl::OUString GetID() const; + ::rtl::OUString GetStreet() const; + ::rtl::OUString GetCity() const; + ::rtl::OUString GetState() const; + ::rtl::OUString GetZip() const; + ::rtl::OUString GetCountry() const; + ::rtl::OUString GetPosition() const; + ::rtl::OUString GetTitle() const; + ::rtl::OUString GetTelephoneHome() const; + ::rtl::OUString GetTelephoneWork() const; + ::rtl::OUString GetFax() const; + ::rtl::OUString GetEmail() const; + ::rtl::OUString GetCustomerNumber() const; + ::rtl::OUString GetFathersName() const; + ::rtl::OUString GetApartment() const; + + ::rtl::OUString GetFullName() const; + ::rtl::OUString GetLocale() const { return m_aLocale; } + + // set the address token + void SetCompany( const ::rtl::OUString& rNewToken ); + void SetFirstName( const ::rtl::OUString& rNewToken ); + void SetLastName( const ::rtl::OUString& rNewToken ); + void SetID( const ::rtl::OUString& rNewToken ); + void SetStreet( const ::rtl::OUString& rNewToken ); + void SetCity( const ::rtl::OUString& rNewToken ); + void SetState( const ::rtl::OUString& rNewToken ); + void SetZip( const ::rtl::OUString& rNewToken ); + void SetCountry( const ::rtl::OUString& rNewToken ); + void SetPosition( const ::rtl::OUString& rNewToken ); + void SetTitle( const ::rtl::OUString& rNewToken ); + void SetTelephoneHome( const ::rtl::OUString& rNewToken ); + void SetTelephoneWork( const ::rtl::OUString& rNewToken ); + void SetFax( const ::rtl::OUString& rNewToken ); + void SetEmail( const ::rtl::OUString& rNewToken ); + void SetCustomerNumber( const ::rtl::OUString& rNewToken ); + void SetFathersName( const ::rtl::OUString& rNewToken ); + void SetApartment( const ::rtl::OUString& rNewToken ); + + sal_Bool IsTokenReadonly( USHORT nToken ) const; + ::rtl::OUString GetToken(USHORT nToken) const; + void Notify(); + +private: + uno::Reference< util::XChangesListener > m_xChangeListener; + css::uno::Reference< css::container::XNameAccess > m_xCfg; + css::uno::Reference< css::beans::XPropertySet > m_xData; + ::rtl::OUString m_aLocale; +}; + +// global ---------------------------------------------------------------- + +static SvtUserOptions_Impl* pOptions = NULL; +static sal_Int32 nRefCount = 0; + +#define READONLY_DEFAULT sal_False + +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtUserConfigChangeListener_Impl::SvtUserConfigChangeListener_Impl(SvtUserOptions_Impl& rParent) : + m_rParent( rParent ) +{ +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtUserConfigChangeListener_Impl::~SvtUserConfigChangeListener_Impl() +{ +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtUserConfigChangeListener_Impl::changesOccurred( const util::ChangesEvent& rEvent ) throw(RuntimeException) +{ + if(rEvent.Changes.getLength()) + m_rParent.Notify(); +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtUserConfigChangeListener_Impl::disposing( const lang::EventObject& rSource ) throw(RuntimeException) +{ + try + { + uno::Reference< util::XChangesNotifier > xChgNot( rSource.Source, UNO_QUERY_THROW); + xChgNot->removeChangesListener(this); + } + catch(Exception& ) + { + } +} + +// class SvtUserOptions_Impl --------------------------------------------- + +// ----------------------------------------------------------------------- +SvtUserOptions_Impl::SvtUserOptions_Impl() : + m_xChangeListener( new SvtUserConfigChangeListener_Impl(*this) ) +{ + try + { + m_xCfg = Reference< css::container::XNameAccess > ( + ::comphelper::ConfigurationHelper::openConfig( + utl::getProcessServiceFactory(), + s_sData, + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY ); + + m_xData = css::uno::Reference< css::beans::XPropertySet >(m_xCfg, css::uno::UNO_QUERY); + uno::Reference< util::XChangesNotifier > xChgNot( m_xCfg, UNO_QUERY); + try + { + xChgNot->addChangesListener( m_xChangeListener ); + } + catch(RuntimeException& ) + { + } + } + catch(const css::uno::Exception& ex) + { + m_xCfg.clear(); + LogHelper::logIt(ex); + } + + Any aAny = ConfigManager::GetConfigManager()->GetDirectConfigProperty( ConfigManager::LOCALE ); + ::rtl::OUString aLocale; + if ( aAny >>= aLocale ) + m_aLocale = aLocale; + else + { + DBG_ERRORFILE( "SvtUserOptions_Impl::SvtUserOptions_Impl(): no locale found" ); + } +} + +// ----------------------------------------------------------------------- + +SvtUserOptions_Impl::~SvtUserOptions_Impl() +{ +} + +::rtl::OUString SvtUserOptions_Impl::GetCompany() const +{ + ::rtl::OUString sCompany; + + try + { + m_xData->getPropertyValue(s_so) >>= sCompany; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sCompany; +} + +::rtl::OUString SvtUserOptions_Impl::GetFirstName() const +{ + ::rtl::OUString sFirstName; + + try + { + m_xData->getPropertyValue(s_sgivenname) >>= sFirstName; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sFirstName; +} + +::rtl::OUString SvtUserOptions_Impl::GetLastName() const +{ + ::rtl::OUString sLastName; + + try + { + m_xData->getPropertyValue(s_ssn) >>= sLastName; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sLastName; +} + +::rtl::OUString SvtUserOptions_Impl::GetID() const +{ + ::rtl::OUString sID; + + try + { + m_xData->getPropertyValue(s_sinitials) >>= sID; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sID; +} + +::rtl::OUString SvtUserOptions_Impl::GetStreet() const +{ + ::rtl::OUString sStreet; + + try + { + m_xData->getPropertyValue(s_sstreet) >>= sStreet; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sStreet; +} + +::rtl::OUString SvtUserOptions_Impl::GetCity() const +{ + ::rtl::OUString sCity; + + try + { + m_xData->getPropertyValue(s_sl) >>= sCity; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sCity; +} + +::rtl::OUString SvtUserOptions_Impl::GetState() const +{ + ::rtl::OUString sState; + + try + { + m_xData->getPropertyValue(s_sst) >>= sState; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sState; +} + +::rtl::OUString SvtUserOptions_Impl::GetZip() const +{ + ::rtl::OUString sZip; + + try + { + m_xData->getPropertyValue(s_spostalcode) >>= sZip; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sZip; +} + +::rtl::OUString SvtUserOptions_Impl::GetCountry() const +{ + ::rtl::OUString sCountry; + + try + { + m_xData->getPropertyValue(s_sc) >>= sCountry; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sCountry; +} + +::rtl::OUString SvtUserOptions_Impl::GetPosition() const +{ + ::rtl::OUString sPosition; + + try + { + m_xData->getPropertyValue(s_sposition) >>= sPosition; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sPosition; +} + +::rtl::OUString SvtUserOptions_Impl::GetTitle() const +{ + ::rtl::OUString sTitle; + + try + { + m_xData->getPropertyValue(s_stitle) >>= sTitle; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sTitle; +} + +::rtl::OUString SvtUserOptions_Impl::GetTelephoneHome() const +{ + ::rtl::OUString sTelephoneHome; + + try + { + m_xData->getPropertyValue(s_shomephone) >>= sTelephoneHome; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sTelephoneHome; +} + +::rtl::OUString SvtUserOptions_Impl::GetTelephoneWork() const +{ + ::rtl::OUString sTelephoneWork; + + try + { + m_xData->getPropertyValue(s_stelephonenumber) >>= sTelephoneWork; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sTelephoneWork; +} + +::rtl::OUString SvtUserOptions_Impl::GetFax() const +{ + ::rtl::OUString sFax; + + try + { + m_xData->getPropertyValue(s_sfacsimiletelephonenumber) >>= sFax; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sFax; +} + +::rtl::OUString SvtUserOptions_Impl::GetEmail() const +{ + ::rtl::OUString sEmail; + + try + { + m_xData->getPropertyValue(s_smail) >>= sEmail; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sEmail; +} + +::rtl::OUString SvtUserOptions_Impl::GetCustomerNumber() const +{ + ::rtl::OUString sCustomerNumber; + + try + { + m_xData->getPropertyValue(s_scustomernumber) >>= sCustomerNumber; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sCustomerNumber; +} + +::rtl::OUString SvtUserOptions_Impl::GetFathersName() const +{ + ::rtl::OUString sFathersName; + + try + { + m_xData->getPropertyValue(s_sfathersname) >>= sFathersName; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sFathersName; +} + +::rtl::OUString SvtUserOptions_Impl::GetApartment() const +{ + ::rtl::OUString sApartment; + + try + { + m_xData->getPropertyValue(s_sapartment) >>= sApartment; + } + catch ( const css::uno::Exception& ex ) + { + LogHelper::logIt(ex); + } + + return sApartment; +} + +void SvtUserOptions_Impl::SetCompany( const ::rtl::OUString& sCompany ) +{ + try + { + m_xData->setPropertyValue(s_so, css::uno::makeAny(::rtl::OUString(sCompany))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetFirstName( const ::rtl::OUString& sFirstName ) +{ + try + { + m_xData->setPropertyValue(s_sgivenname, css::uno::makeAny(::rtl::OUString(sFirstName))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetLastName( const ::rtl::OUString& sLastName ) +{ + try + { + m_xData->setPropertyValue(s_ssn, css::uno::makeAny(::rtl::OUString(sLastName))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} +void SvtUserOptions_Impl::SetID( const ::rtl::OUString& sID ) +{ + try + { + m_xData->setPropertyValue(s_sinitials, css::uno::makeAny(::rtl::OUString(sID))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetStreet( const ::rtl::OUString& sStreet ) +{ + try + { + m_xData->setPropertyValue(s_sstreet, css::uno::makeAny(::rtl::OUString(sStreet))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetCity( const ::rtl::OUString& sCity ) +{ + try + { + m_xData->setPropertyValue(s_sl, css::uno::makeAny(::rtl::OUString(sCity))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetState( const ::rtl::OUString& sState ) +{ + try + { + m_xData->setPropertyValue(s_sst, css::uno::makeAny(::rtl::OUString(sState))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetZip( const ::rtl::OUString& sZip ) +{ + try + { + m_xData->setPropertyValue(s_spostalcode, css::uno::makeAny(::rtl::OUString(sZip))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetCountry( const ::rtl::OUString& sCountry ) +{ + try + { + m_xData->setPropertyValue(s_sc, css::uno::makeAny(::rtl::OUString(sCountry))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetPosition( const ::rtl::OUString& sPosition ) +{ + try + { + m_xData->setPropertyValue(s_sposition, css::uno::makeAny(::rtl::OUString(sPosition))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetTitle( const ::rtl::OUString& sTitle ) +{ + try + { + m_xData->setPropertyValue(s_stitle, css::uno::makeAny(::rtl::OUString(sTitle))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetTelephoneHome( const ::rtl::OUString& sTelephoneHome ) +{ + try + { + m_xData->setPropertyValue(s_shomephone, css::uno::makeAny(::rtl::OUString(sTelephoneHome))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetTelephoneWork( const ::rtl::OUString& sTelephoneWork ) +{ + try + { + m_xData->setPropertyValue(s_stelephonenumber, css::uno::makeAny(::rtl::OUString(sTelephoneWork))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetFax( const ::rtl::OUString& sFax ) +{ + try + { + m_xData->setPropertyValue(s_sfacsimiletelephonenumber, css::uno::makeAny(::rtl::OUString(sFax))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetEmail( const ::rtl::OUString& sEmail ) +{ + try + { + m_xData->setPropertyValue(s_smail, css::uno::makeAny(::rtl::OUString(sEmail))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetCustomerNumber( const ::rtl::OUString& sCustomerNumber ) +{ + try + { + m_xData->setPropertyValue(s_scustomernumber, css::uno::makeAny(::rtl::OUString(sCustomerNumber))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetFathersName( const ::rtl::OUString& sFathersName ) +{ + try + { + m_xData->setPropertyValue(s_sfathersname, css::uno::makeAny(::rtl::OUString(sFathersName))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +void SvtUserOptions_Impl::SetApartment( const ::rtl::OUString& sApartment ) +{ + try + { + m_xData->setPropertyValue(s_sapartment, css::uno::makeAny(::rtl::OUString(sApartment))); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + catch ( const css::uno::Exception& ex) + { + LogHelper::logIt(ex); + } +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions_Impl::GetFullName() const +{ + ::rtl::OUString sFullName; + + sFullName = GetFirstName(); + sFullName.trim(); + if ( sFullName.getLength() ) + sFullName += ::rtl::OUString::createFromAscii(" "); + sFullName += GetLastName(); + sFullName.trim(); + + return sFullName; +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions_Impl::Notify() +{ + NotifyListeners(0); +} + +// ----------------------------------------------------------------------- + +sal_Bool SvtUserOptions_Impl::IsTokenReadonly( USHORT nToken ) const +{ + css::uno::Reference< css::beans::XPropertySet > xData(m_xCfg, css::uno::UNO_QUERY); + css::uno::Reference< css::beans::XPropertySetInfo > xInfo = xData->getPropertySetInfo(); + css::beans::Property aProp; + sal_Bool bRet = sal_False; + + switch ( nToken ) + { + case USER_OPT_COMPANY: + { + aProp = xInfo->getPropertyByName(s_so); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_FIRSTNAME: + { + aProp = xInfo->getPropertyByName(s_sgivenname); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_LASTNAME: + { + aProp = xInfo->getPropertyByName(s_ssn); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_ID: + { + aProp = xInfo->getPropertyByName(s_sinitials); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_STREET: + { + aProp = xInfo->getPropertyByName(s_sstreet); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_CITY: + { + aProp = xInfo->getPropertyByName(s_sl); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_STATE: + { + aProp = xInfo->getPropertyByName(s_sst); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_ZIP: + { + aProp = xInfo->getPropertyByName(s_spostalcode); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_COUNTRY: + { + aProp = xInfo->getPropertyByName(s_sc); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_POSITION: + { + aProp = xInfo->getPropertyByName(s_sposition); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_TITLE: + { + aProp = xInfo->getPropertyByName(s_stitle); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_TELEPHONEHOME: + { + aProp = xInfo->getPropertyByName(s_shomephone); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_TELEPHONEWORK: + { + aProp = xInfo->getPropertyByName(s_stelephonenumber); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_FAX: + { + aProp = xInfo->getPropertyByName(s_sfacsimiletelephonenumber); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_EMAIL: + { + aProp = xInfo->getPropertyByName(s_smail); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_FATHERSNAME: + { + aProp = xInfo->getPropertyByName(s_sfathersname); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + case USER_OPT_APARTMENT: + { + aProp = xInfo->getPropertyByName(s_sapartment); + bRet = ((aProp.Attributes & css::beans::PropertyAttribute::READONLY) == css::beans::PropertyAttribute::READONLY); + break; + } + default: + DBG_ERRORFILE( "SvtUserOptions_Impl::IsTokenReadonly(): invalid token" ); + } + + return bRet; +} + +//------------------------------------------------------------------------ +::rtl::OUString SvtUserOptions_Impl::GetToken(USHORT nToken) const +{ + ::rtl::OUString pRet; + switch(nToken) + { + case USER_OPT_COMPANY: pRet = GetCompany(); break; + case USER_OPT_FIRSTNAME: pRet = GetFirstName(); break; + case USER_OPT_LASTNAME: pRet = GetLastName(); break; + case USER_OPT_ID: pRet = GetID(); break; + case USER_OPT_STREET: pRet = GetStreet(); break; + case USER_OPT_CITY: pRet = GetCity(); break; + case USER_OPT_STATE: pRet = GetState(); break; + case USER_OPT_ZIP: pRet = GetZip(); break; + case USER_OPT_COUNTRY: pRet = GetCountry(); break; + case USER_OPT_POSITION: pRet = GetPosition(); break; + case USER_OPT_TITLE: pRet = GetTitle(); break; + case USER_OPT_TELEPHONEHOME: pRet = GetTelephoneHome(); break; + case USER_OPT_TELEPHONEWORK: pRet = GetTelephoneWork(); break; + case USER_OPT_FAX: pRet = GetFax(); break; + case USER_OPT_EMAIL: pRet = GetEmail(); break; + case USER_OPT_FATHERSNAME: pRet = GetFathersName(); break; + case USER_OPT_APARTMENT: pRet = GetApartment(); break; + default: + DBG_ERRORFILE( "SvtUserOptions_Impl::GetToken(): invalid token" ); + } + return pRet; +} + +// class SvtUserOptions -------------------------------------------------- + +SvtUserOptions::SvtUserOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( GetInitMutex() ); + + if ( !pOptions ) + { + RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtUserOptions_Impl::ctor()"); + pOptions = new SvtUserOptions_Impl; + + ItemHolder1::holdConfigItem(E_USEROPTIONS); + } + ++nRefCount; + pImp = pOptions; + pImp->AddListener(this); +} + +// ----------------------------------------------------------------------- + +SvtUserOptions::~SvtUserOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->RemoveListener(this); + if ( !--nRefCount ) + { + //if ( pOptions->IsModified() ) + // pOptions->Commit(); + DELETEZ( pOptions ); + } +} + +// ----------------------------------------------------------------------- + +::osl::Mutex& SvtUserOptions::GetInitMutex() +{ + // Initialize static mutex only for one time! + static ::osl::Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if ( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + // We must check our pointer again - + // because another instance of our class will be faster then this instance! + if ( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static ::osl::Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetCompany() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetCompany(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetFirstName() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetFirstName(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetLastName() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetLastName(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetID() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetID(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetStreet() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetStreet(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetCity() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetCity(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetState() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetState(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetZip() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetZip(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetCountry() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetCountry(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetPosition() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetPosition(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetTitle() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetTitle(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetTelephoneHome() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetTelephoneHome(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetTelephoneWork() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetTelephoneWork(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetFax() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetFax(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetEmail() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetEmail(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetCustomerNumber() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetCustomerNumber(); +} +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetFathersName() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetFathersName() ; +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetApartment() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetApartment(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetFullName() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetFullName(); +} + +// ----------------------------------------------------------------------- + +::rtl::OUString SvtUserOptions::GetLocale() const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetLocale(); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetCompany( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetCompany( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetFirstName( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetFirstName( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetLastName( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetLastName( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetID( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetID( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetStreet( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetStreet( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetCity( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetCity( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetState( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetState( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetZip( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetZip( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetCountry( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetCountry( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetPosition( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetPosition( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetTitle( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetTitle( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetTelephoneHome( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetTelephoneHome( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetTelephoneWork( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetTelephoneWork( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetFax( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetFax( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetEmail( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetEmail( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetCustomerNumber( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetCustomerNumber( rNewToken ); +} +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetFathersName( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetFathersName( rNewToken ); +} + +// ----------------------------------------------------------------------- + +void SvtUserOptions::SetApartment( const ::rtl::OUString& rNewToken ) +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + pImp->SetApartment( rNewToken ); +} + +// ----------------------------------------------------------------------- + +sal_Bool SvtUserOptions::IsTokenReadonly( USHORT nToken ) const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->IsTokenReadonly( nToken ); +} +//------------------------------------------------------------------------ +::rtl::OUString SvtUserOptions::GetToken(USHORT nToken) const +{ + ::osl::MutexGuard aGuard( GetInitMutex() ); + return pImp->GetToken( nToken ); +} diff --git a/unotools/source/config/viewoptions.cxx b/unotools/source/config/viewoptions.cxx new file mode 100644 index 000000000000..f76ce48eebdf --- /dev/null +++ b/unotools/source/config/viewoptions.cxx @@ -0,0 +1,1301 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/viewoptions.hxx> +#include <com/sun/star/uno/Any.hxx> + +#include <hash_map> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <rtl/ustrbuf.hxx> +#include <unotools/configpathes.hxx> +#include <comphelper/configurationhelper.hxx> +#include <unotools/processfactory.hxx> + +#include <itemholder1.hxx> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +namespace css = ::com::sun::star; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#ifdef CONST_ASCII + #error "Who define CONST_ASCII before! I use it to create const ascii strings ..." +#else + #define CONST_ASCII(SASCIIVALUE) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SASCIIVALUE)) +#endif + +#define PATHSEPERATOR CONST_ASCII("/") + +#define PACKAGE_VIEWS CONST_ASCII("org.openoffice.Office.Views") + +#define LIST_DIALOGS CONST_ASCII("Dialogs" ) +#define LIST_TABDIALOGS CONST_ASCII("TabDialogs") +#define LIST_TABPAGES CONST_ASCII("TabPages" ) +#define LIST_WINDOWS CONST_ASCII("Windows" ) + +#define PROPERTY_WINDOWSTATE CONST_ASCII("WindowState") +#define PROPERTY_PAGEID CONST_ASCII("PageID" ) +#define PROPERTY_VISIBLE CONST_ASCII("Visible" ) +#define PROPERTY_USERDATA CONST_ASCII("UserData" ) + +#define PROPCOUNT_DIALOGS 1 +#define PROPCOUNT_TABDIALOGS 2 +#define PROPCOUNT_TABPAGES 1 +#define PROPCOUNT_WINDOWS 2 + +#define DEFAULT_WINDOWSTATE ::rtl::OUString() +#define DEFAULT_USERDATA css::uno::Sequence< css::beans::NamedValue >() +#define DEFAULT_PAGEID 0 +#define DEFAULT_VISIBLE sal_False + +//#define DEBUG_VIEWOPTIONS + +#ifdef DEBUG_VIEWOPTIONS + #define _LOG_COUNTER_( _SVIEW_, _NREAD_, _NWRITE_ ) \ + { \ + FILE* pFile = fopen( "viewdbg.txt", "a" ); \ + fprintf( pFile, "%s[%d, %d]\n", ::rtl::OUStringToOString(_SVIEW_, RTL_TEXTENCODING_UTF8).getStr(), _NREAD_, _NWRITE_ ); \ + fclose( pFile ); \ + } +#endif // DEBUG_VIEWOPTIONS + +#define SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION_PARAM_EXCEPTION) \ + { \ + ::rtl::OUStringBuffer sMsg(256); \ + sMsg.appendAscii("Unexpected exception catched. Original message was:\n\"" ); \ + sMsg.append (SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION_PARAM_EXCEPTION.Message); \ + sMsg.appendAscii("\"" ); \ + OSL_ENSURE(sal_False, ::rtl::OUStringToOString(sMsg.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr()); \ + } + +//_________________________________________________________________________________________________________________ +// initialization! +//_________________________________________________________________________________________________________________ + +SvtViewOptionsBase_Impl* SvtViewOptions::m_pDataContainer_Dialogs = NULL ; +sal_Int32 SvtViewOptions::m_nRefCount_Dialogs = 0 ; +SvtViewOptionsBase_Impl* SvtViewOptions::m_pDataContainer_TabDialogs = NULL ; +sal_Int32 SvtViewOptions::m_nRefCount_TabDialogs = 0 ; +SvtViewOptionsBase_Impl* SvtViewOptions::m_pDataContainer_TabPages = NULL ; +sal_Int32 SvtViewOptions::m_nRefCount_TabPages = 0 ; +SvtViewOptionsBase_Impl* SvtViewOptions::m_pDataContainer_Windows = NULL ; +sal_Int32 SvtViewOptions::m_nRefCount_Windows = 0 ; + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr declare one configuration item + These struct hold information about one view item. But not all member are used for all entries! + User must decide which information are usefull and which not. We are a container iztem only and doesnt + know anything about the context. + But; we support a feature: + decision between items with default values (should not realy exist in configuration!) + and items with real values - changed by user. So user can suppress saving of realy unused items + to disk - because; defaulted items could be restored on runtime without reading from disk!!! + And if only items with valid information was written to cfg - we mustn't read so much and save time. + So we start with an member m_bDefault=True and reset it to False after first set-call. + Deficiencies of these solution - we cant allow direct read/write access to our member. We must + support it by set/get-methods ... +*//*-*************************************************************************************************************/ +class IMPL_TViewData +{ + public: + //--------------------------------------------------------------------------------------------------------- + // create "default" item + IMPL_TViewData() + { + m_sWindowState = DEFAULT_WINDOWSTATE ; + m_lUserData = DEFAULT_USERDATA ; + m_nPageID = DEFAULT_PAGEID ; + m_bVisible = DEFAULT_VISIBLE ; + + m_bDefault = sal_True ; + } + + //--------------------------------------------------------------------------------------------------------- + // write access - with reseting of default state + void setWindowState( const ::rtl::OUString& sValue ) + { + m_bDefault = ( + ( m_bDefault == sal_True ) && + ( sValue == DEFAULT_WINDOWSTATE ) + ); + m_sWindowState = sValue; + } + + //--------------------------------------------------------------------------------------------------------- + void setUserData( const css::uno::Sequence< css::beans::NamedValue >& lValue ) + { + m_bDefault = ( + ( m_bDefault == sal_True ) && + ( lValue == DEFAULT_USERDATA ) + ); + m_lUserData = lValue; + } + + //--------------------------------------------------------------------------------------------------------- + void setPageID( sal_Int32 nValue ) + { + m_bDefault = ( + ( m_bDefault == sal_True ) && + ( nValue == DEFAULT_PAGEID ) + ); + m_nPageID = nValue; + } + + //--------------------------------------------------------------------------------------------------------- + void setVisible( sal_Bool bValue ) + { + m_bDefault = ( + ( m_bDefault == sal_True ) && + ( bValue == DEFAULT_VISIBLE ) + ); + m_bVisible = bValue; + } + + //--------------------------------------------------------------------------------------------------------- + // read access + ::rtl::OUString getWindowState() { return m_sWindowState; } + css::uno::Sequence< css::beans::NamedValue > getUserData () { return m_lUserData ; } + sal_Int32 getPageID () { return m_nPageID ; } + sal_Bool getVisible () { return m_bVisible ; } + + //--------------------------------------------------------------------------------------------------------- + // special operation for easy access on user data + void setUserItem( const ::rtl::OUString& sName , + const css::uno::Any& aValue ) + { + // we change UserData in every case! + // a) we change already existing item + // or b) we add a new one + m_bDefault = sal_False; + + sal_Bool bExist = sal_False; + sal_Int32 nCount = m_lUserData.getLength(); + + // change it, if it already exist ... + for( sal_Int32 nStep=0; nStep<nCount; ++nStep ) + { + if( m_lUserData[nStep].Name == sName ) + { + m_lUserData[nStep].Value = aValue ; + bExist = sal_True; + break; + } + } + + // ... or create new list item + if( bExist == sal_False ) + { + m_lUserData.realloc( nCount+1 ); + m_lUserData[nCount].Name = sName ; + m_lUserData[nCount].Value = aValue ; + } + } + + //--------------------------------------------------------------------------------------------------------- + css::uno::Any getUserItem( const ::rtl::OUString& sName ) + { + // default value - if item not exist! + css::uno::Any aValue; + + sal_Int32 nCount = m_lUserData.getLength(); + for( sal_Int32 nStep=0; nStep<nCount; ++nStep ) + { + if( m_lUserData[nStep].Name == sName ) + { + aValue = m_lUserData[nStep].Value; + break; + } + } + return aValue; + } + + //--------------------------------------------------------------------------------------------------------- + // check for default items + sal_Bool isDefault() { return m_bDefault; } + + private: + ::rtl::OUString m_sWindowState ; + css::uno::Sequence< css::beans::NamedValue > m_lUserData ; + sal_Int32 m_nPageID ; + sal_Bool m_bVisible ; + + sal_Bool m_bDefault ; +}; + +struct IMPL_TStringHashCode +{ + size_t operator()(const ::rtl::OUString& sString) const + { + return sString.hashCode(); + } +}; + +typedef ::std::hash_map< ::rtl::OUString , + IMPL_TViewData , + IMPL_TStringHashCode , + ::std::equal_to< ::rtl::OUString > > IMPL_TViewHash; + +/*-************************************************************************************************************//** + @descr Implement base data container for view options elements. + Every item support ALL possible configuration informations. + But not every superclass should use them! Because some view types don't + have it realy. + + @attention We implement a write-througt-cache! We use it for reading - but write all changes directly to + configuration. (changes are made on internal cache too!). So it's easier to distinguish + between added/changed/removed elements without any complex mask or bool flag informations. + Caches from configuration and our own one are synchronized every time - if we do so. +*//*-*************************************************************************************************************/ +class SvtViewOptionsBase_Impl +{ + //------------------------------------------------------------------------------------------------------------- + public: + SvtViewOptionsBase_Impl ( const ::rtl::OUString& sList ); + virtual ~SvtViewOptionsBase_Impl ( ); + sal_Bool Exists ( const ::rtl::OUString& sName ); + sal_Bool Delete ( const ::rtl::OUString& sName ); + ::rtl::OUString GetWindowState ( const ::rtl::OUString& sName ); + void SetWindowState ( const ::rtl::OUString& sName , + const ::rtl::OUString& sState ); + css::uno::Sequence< css::beans::NamedValue > GetUserData ( const ::rtl::OUString& sName ); + void SetUserData ( const ::rtl::OUString& sName , + const css::uno::Sequence< css::beans::NamedValue >& lData ); + sal_Int32 GetPageID ( const ::rtl::OUString& sName ); + void SetPageID ( const ::rtl::OUString& sName , + sal_Int32 nID ); + sal_Bool GetVisible ( const ::rtl::OUString& sName ); + void SetVisible ( const ::rtl::OUString& sName , + sal_Bool bVisible ); + css::uno::Any GetUserItem ( const ::rtl::OUString& sName , + const ::rtl::OUString& sItem ); + void SetUserItem ( const ::rtl::OUString& sName , + const ::rtl::OUString& sItem , + const css::uno::Any& aValue ); + + //------------------------------------------------------------------------------------------------------------- + private: + css::uno::Reference< css::uno::XInterface > impl_getSetNode( const ::rtl::OUString& sNode , + sal_Bool bCreateIfMissing); + + //------------------------------------------------------------------------------------------------------------- + private: + ::rtl::OUString m_sListName; + css::uno::Reference< css::container::XNameAccess > m_xRoot; + css::uno::Reference< css::container::XNameAccess > m_xSet; + + #ifdef DEBUG_VIEWOPTIONS + sal_Int32 m_nReadCount ; + sal_Int32 m_nWriteCount ; + #endif +}; + +/*-************************************************************************************************************//** + @descr Implement the base data container. +*//*-*************************************************************************************************************/ + +/*-************************************************************************************************************//** + @short ctor + @descr We use it to open right configuration file and let configuration objects fill her caches. + Then we read all existing entries from right list and cached it inside our object too. + Normaly we should enable notifications for changes on these values too ... but these feature + isn't full implemented in the moment. + + @seealso baseclass ::utl::ConfigItem + @seealso method Notify() + + @param - + @return - + + @last change 19.10.2001 07:54 +*//*-*************************************************************************************************************/ +SvtViewOptionsBase_Impl::SvtViewOptionsBase_Impl( const ::rtl::OUString& sList ) + : m_sListName ( sList ) // we must know, which view type we must support + #ifdef DEBUG_VIEWOPTIONS + , m_nReadCount ( 0 ) + , m_nWriteCount( 0 ) + #endif +{ + try + { + m_xRoot = css::uno::Reference< css::container::XNameAccess >( + ::comphelper::ConfigurationHelper::openConfig( + ::utl::getProcessServiceFactory(), + PACKAGE_VIEWS, + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY); + if (m_xRoot.is()) + m_xRoot->getByName(sList) >>= m_xSet; + } + catch(const css::uno::Exception& ex) + { + m_xRoot.clear(); + m_xSet.clear(); + + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } +} + +/*-************************************************************************************************************//** + @short dtor + @descr clean up something + + @attention We implement a write through cache! So we mustn't do it realy. All changes was written to cfg directly. + Commit isn't neccessary then. + + @seealso baseclass ::utl::ConfigItem + @seealso method IsModified() + @seealso method SetModified() + @seealso method Commit() + + @param - + @return - + + @last change 19.10.2001 08:02 +*//*-*************************************************************************************************************/ +SvtViewOptionsBase_Impl::~SvtViewOptionsBase_Impl() +{ + // dont flush configuration changes here to m_xRoot. + // That must be done inside every SetXXX() method already ! + // Here its to late - DisposedExceptions from used configuration access can occure otherwise. + + m_xRoot.clear(); + m_xSet.clear(); + + #ifdef DEBUG_VIEWOPTIONS + _LOG_COUNTER_( m_sListName, m_nReadCount, m_nWriteCount ) + #endif // DEBUG_VIEWOPTIONS +} + +/*-************************************************************************************************************//** + @short checks for already existing entries + @descr If user don't know, if an entry already exist - he can get this information by calling this method. + + @seealso member m_aList + + @param "sName", name of entry to check exist state + @return true , if item exist + false, otherwise +*//*-*************************************************************************************************************/ +sal_Bool SvtViewOptionsBase_Impl::Exists( const ::rtl::OUString& sName ) +{ + sal_Bool bExists = sal_False; + + try + { + if (m_xSet.is()) + bExists = m_xSet->hasByName(sName); + } + catch(const css::uno::Exception& ex) + { + bExists = sal_False; + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return bExists; +} + +/*-************************************************************************************************************//** + @short delete entry + @descr Use it to delete set entry by given name. + + @seealso member m_aList + + @param "sName", name of entry to delete it + @return true , if item not exist(!) or could be deleted (should be the same!) + false, otherwise +*//*-*************************************************************************************************************/ +sal_Bool SvtViewOptionsBase_Impl::Delete( const ::rtl::OUString& sName ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nWriteCount; + #endif + + sal_Bool bDeleted = sal_False; + try + { + css::uno::Reference< css::container::XNameContainer > xSet(m_xSet, css::uno::UNO_QUERY_THROW); + xSet->removeByName(sName); + bDeleted = sal_True; + ::comphelper::ConfigurationHelper::flush(m_xRoot); + } + catch(const css::container::NoSuchElementException&) + { bDeleted = sal_True; } + catch(const css::uno::Exception& ex) + { + bDeleted = sal_False; + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return bDeleted; +} + +/*-************************************************************************************************************//** + @short read/write access to cache view items and her properties + @descr Follow methods support read/write access to all cache view items. + + @seealso member m_sList + + @param - + @return - +*//*-*************************************************************************************************************/ +::rtl::OUString SvtViewOptionsBase_Impl::GetWindowState( const ::rtl::OUString& sName ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nReadCount; + #endif + + ::rtl::OUString sWindowState; + try + { + css::uno::Reference< css::beans::XPropertySet > xNode( + impl_getSetNode(sName, sal_False), + css::uno::UNO_QUERY); + if (xNode.is()) + xNode->getPropertyValue(PROPERTY_WINDOWSTATE) >>= sWindowState; + } + catch(const css::uno::Exception& ex) + { + sWindowState = ::rtl::OUString(); + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return sWindowState; +} + +//***************************************************************************************************************** +void SvtViewOptionsBase_Impl::SetWindowState( const ::rtl::OUString& sName , + const ::rtl::OUString& sState ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nWriteCount; + #endif + + try + { + css::uno::Reference< css::beans::XPropertySet > xNode( + impl_getSetNode(sName, sal_True), + css::uno::UNO_QUERY_THROW); + xNode->setPropertyValue(PROPERTY_WINDOWSTATE, css::uno::makeAny(sState)); + ::comphelper::ConfigurationHelper::flush(m_xRoot); + } + catch(const css::uno::Exception& ex) + { + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } +} + +//***************************************************************************************************************** +css::uno::Sequence< css::beans::NamedValue > SvtViewOptionsBase_Impl::GetUserData( const ::rtl::OUString& sName ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nReadCount; + #endif + + try + { + css::uno::Reference< css::container::XNameAccess > xNode( + impl_getSetNode(sName, sal_False), + css::uno::UNO_QUERY); // no _THROW ! because we dont create missing items here. So we have to live with zero references .-) + css::uno::Reference< css::container::XNameAccess > xUserData; + if (xNode.is()) + xNode->getByName(PROPERTY_USERDATA) >>= xUserData; + if (xUserData.is()) + { + const css::uno::Sequence< ::rtl::OUString > lNames = xUserData->getElementNames(); + const ::rtl::OUString* pNames = lNames.getConstArray(); + sal_Int32 c = lNames.getLength(); + sal_Int32 i = 0; + css::uno::Sequence< css::beans::NamedValue > lUserData(c); + + for (i=0; i<c; ++i) + { + lUserData[i].Name = pNames[i]; + lUserData[i].Value = xUserData->getByName(pNames[i]); + } + + return lUserData; + } + } + catch(const css::uno::Exception& ex) + { + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return css::uno::Sequence< css::beans::NamedValue >(); +} + +//***************************************************************************************************************** +void SvtViewOptionsBase_Impl::SetUserData( const ::rtl::OUString& sName , + const css::uno::Sequence< css::beans::NamedValue >& lData ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nWriteCount; + #endif + + try + { + css::uno::Reference< css::container::XNameAccess > xNode( + impl_getSetNode(sName, sal_True), + css::uno::UNO_QUERY_THROW); + css::uno::Reference< css::container::XNameContainer > xUserData; + xNode->getByName(PROPERTY_USERDATA) >>= xUserData; + if (xUserData.is()) + { + const css::beans::NamedValue* pData = lData.getConstArray(); + sal_Int32 c = lData.getLength(); + sal_Int32 i = 0; + for (i=0; i<c; ++i) + { + if (xUserData->hasByName(pData[i].Name)) + xUserData->replaceByName(pData[i].Name, pData[i].Value); + else + xUserData->insertByName(pData[i].Name, pData[i].Value); + } + } + ::comphelper::ConfigurationHelper::flush(m_xRoot); + } + catch(const css::uno::Exception& ex) + { + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } +} + +//***************************************************************************************************************** +css::uno::Any SvtViewOptionsBase_Impl::GetUserItem( const ::rtl::OUString& sName , + const ::rtl::OUString& sItem ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nReadCount; + #endif + + css::uno::Any aItem; + try + { + css::uno::Reference< css::container::XNameAccess > xNode( + impl_getSetNode(sName, sal_False), + css::uno::UNO_QUERY); + css::uno::Reference< css::container::XNameAccess > xUserData; + if (xNode.is()) + xNode->getByName(PROPERTY_USERDATA) >>= xUserData; + if (xUserData.is()) + aItem = xUserData->getByName(sItem); + } + catch(const css::container::NoSuchElementException&) + { aItem.clear(); } + catch(const css::uno::Exception& ex) + { + aItem.clear(); + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return aItem; +} + +//***************************************************************************************************************** +void SvtViewOptionsBase_Impl::SetUserItem( const ::rtl::OUString& sName , + const ::rtl::OUString& sItem , + const css::uno::Any& aValue ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nWriteCount; + #endif + + try + { + css::uno::Reference< css::container::XNameAccess > xNode( + impl_getSetNode(sName, sal_True), + css::uno::UNO_QUERY_THROW); + css::uno::Reference< css::container::XNameContainer > xUserData; + xNode->getByName(PROPERTY_USERDATA) >>= xUserData; + if (xUserData.is()) + { + if (xUserData->hasByName(sItem)) + xUserData->replaceByName(sItem, aValue); + else + xUserData->insertByName(sItem, aValue); + } + ::comphelper::ConfigurationHelper::flush(m_xRoot); + } + catch(const css::uno::Exception& ex) + { + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } +} + +//***************************************************************************************************************** +sal_Int32 SvtViewOptionsBase_Impl::GetPageID( const ::rtl::OUString& sName ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nReadCount; + #endif + + sal_Int32 nID = 0; + try + { + css::uno::Reference< css::beans::XPropertySet > xNode( + impl_getSetNode(sName, sal_False), + css::uno::UNO_QUERY); + if (xNode.is()) + xNode->getPropertyValue(PROPERTY_PAGEID) >>= nID; + } + catch(const css::uno::Exception& ex) + { + nID = 0; + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return nID; +} + +//***************************************************************************************************************** +void SvtViewOptionsBase_Impl::SetPageID( const ::rtl::OUString& sName , + sal_Int32 nID ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nWriteCount; + #endif + + try + { + css::uno::Reference< css::beans::XPropertySet > xNode( + impl_getSetNode(sName, sal_True), + css::uno::UNO_QUERY_THROW); + xNode->setPropertyValue(PROPERTY_PAGEID, css::uno::makeAny(nID)); + ::comphelper::ConfigurationHelper::flush(m_xRoot); + } + catch(const css::uno::Exception& ex) + { + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } +} + +//***************************************************************************************************************** +sal_Bool SvtViewOptionsBase_Impl::GetVisible( const ::rtl::OUString& sName ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nReadCount; + #endif + + sal_Bool bVisible = sal_False; + try + { + css::uno::Reference< css::beans::XPropertySet > xNode( + impl_getSetNode(sName, sal_False), + css::uno::UNO_QUERY); + if (xNode.is()) + xNode->getPropertyValue(PROPERTY_VISIBLE) >>= bVisible; + } + catch(const css::uno::Exception& ex) + { + bVisible = sal_False; + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return bVisible; +} + +//***************************************************************************************************************** +void SvtViewOptionsBase_Impl::SetVisible( const ::rtl::OUString& sName , + sal_Bool bVisible ) +{ + #ifdef DEBUG_VIEWOPTIONS + ++m_nWriteCount; + #endif + + try + { + css::uno::Reference< css::beans::XPropertySet > xNode( + impl_getSetNode(sName, sal_True), + css::uno::UNO_QUERY_THROW); + xNode->setPropertyValue(PROPERTY_VISIBLE, css::uno::makeAny(bVisible)); + ::comphelper::ConfigurationHelper::flush(m_xRoot); + } + catch(const css::uno::Exception& ex) + { + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } +} + +/*-************************************************************************************************************//** + @short create new set node with default values on disk + @descr To create a new UserData item - the super node of these property must already exist! + You can call this method to create these new entry with default values and change UserData then. + + @seealso method impl_writeDirectProp() + + @param "sNode", name of new entry + @return - + + @last change 19.10.2001 08:42 +*//*-*************************************************************************************************************/ +css::uno::Reference< css::uno::XInterface > SvtViewOptionsBase_Impl::impl_getSetNode( const ::rtl::OUString& sNode , + sal_Bool bCreateIfMissing) +{ + css::uno::Reference< css::uno::XInterface > xNode; + + try + { + if (bCreateIfMissing) + xNode = ::comphelper::ConfigurationHelper::makeSureSetNodeExists(m_xRoot, m_sListName, sNode); + else + { + if (m_xSet.is() && m_xSet->hasByName(sNode) ) + m_xSet->getByName(sNode) >>= xNode; + } + } + catch(const css::container::NoSuchElementException&) + { xNode.clear(); } + catch(const css::uno::Exception& ex) + { + xNode.clear(); + SVTVIEWOPTIONS_LOG_UNEXPECTED_EXCEPTION(ex) + } + + return xNode; +} + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtViewOptions::SvtViewOptions( EViewType eType , + const ::rtl::OUString& sViewName ) + : m_eViewType ( eType ) + , m_sViewName ( sViewName ) +{ + // Global access, must be guarded (multithreading!) + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + // Search for right dat container for this view type and initialize right data container or set right ref count! + switch( eType ) + { + case E_DIALOG : { + // Increase ref count for dialog data container first. + ++m_nRefCount_Dialogs; + // If these instance the first user of the dialog data container - create these impl static container! + if( m_nRefCount_Dialogs == 1 ) + { + //m_pDataContainer_Dialogs = new SvtViewDialogOptions_Impl( LIST_DIALOGS ); + m_pDataContainer_Dialogs = new SvtViewOptionsBase_Impl( LIST_DIALOGS ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_DIALOG); + } + } + break; + case E_TABDIALOG : { + // Increase ref count for tab-dialog data container first. + ++m_nRefCount_TabDialogs; + // If these instance the first user of the tab-dialog data container - create these impl static container! + if( m_nRefCount_TabDialogs == 1 ) + { + m_pDataContainer_TabDialogs = new SvtViewOptionsBase_Impl( LIST_TABDIALOGS ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_TABDIALOG); + } + } + break; + case E_TABPAGE : { + // Increase ref count for tab-page data container first. + ++m_nRefCount_TabPages; + // If these instance the first user of the tab-page data container - create these impl static container! + if( m_nRefCount_TabPages == 1 ) + { + m_pDataContainer_TabPages = new SvtViewOptionsBase_Impl( LIST_TABPAGES ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_TABPAGE); + } + } + break; + case E_WINDOW : { + // Increase ref count for window data container first. + ++m_nRefCount_Windows; + // If these instance the first user of the window data container - create these impl static container! + if( m_nRefCount_Windows == 1 ) + { + m_pDataContainer_Windows = new SvtViewOptionsBase_Impl( LIST_WINDOWS ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_WINDOW); + } + } + break; + default : OSL_ENSURE( sal_False, "SvtViewOptions::SvtViewOptions()\nThese view type is unknown! All following calls at these instance will do nothing!\n" ); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtViewOptions::~SvtViewOptions() +{ + // Global access, must be guarded (multithreading!) + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + // Search for right dat container for this view type and deinitialize right data container or set right ref count! + switch( m_eViewType ) + { + case E_DIALOG : { + // Decrease ref count for dialog data container first. + --m_nRefCount_Dialogs; + // If these instance the last user of the dialog data container - delete these impl static container! + if( m_nRefCount_Dialogs == 0 ) + { + delete m_pDataContainer_Dialogs; + m_pDataContainer_Dialogs = NULL; + } + } + break; + case E_TABDIALOG : { + // Decrease ref count for tab-dialog data container first. + --m_nRefCount_TabDialogs; + // If these instance the last user of the tab-dialog data container - delete these impl static container! + if( m_nRefCount_TabDialogs == 0 ) + { + delete m_pDataContainer_TabDialogs; + m_pDataContainer_TabDialogs = NULL; + } + } + break; + case E_TABPAGE : { + // Decrease ref count for tab-page data container first. + --m_nRefCount_TabPages; + // If these instance the last user of the tab-page data container - delete these impl static container! + if( m_nRefCount_TabPages == 0 ) + { + delete m_pDataContainer_TabPages; + m_pDataContainer_TabPages = NULL; + } + } + break; + case E_WINDOW : { + // Decrease ref count for window data container first. + --m_nRefCount_Windows; + // If these instance the last user of the window data container - delete these impl static container! + if( m_nRefCount_Windows == 0 ) + { + delete m_pDataContainer_Windows; + m_pDataContainer_Windows = NULL; + } + } + break; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtViewOptions::Exists() const +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + sal_Bool bExists = sal_False; + switch( m_eViewType ) + { + case E_DIALOG : { + bExists = m_pDataContainer_Dialogs->Exists( m_sViewName ); + } + break; + case E_TABDIALOG : { + bExists = m_pDataContainer_TabDialogs->Exists( m_sViewName ); + } + break; + case E_TABPAGE : { + bExists = m_pDataContainer_TabPages->Exists( m_sViewName ); + } + break; + case E_WINDOW : { + bExists = m_pDataContainer_Windows->Exists( m_sViewName ); + } + break; + } + return bExists; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtViewOptions::Delete() +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + sal_Bool bState = sal_False; + switch( m_eViewType ) + { + case E_DIALOG : { + bState = m_pDataContainer_Dialogs->Delete( m_sViewName ); + } + break; + case E_TABDIALOG : { + bState = m_pDataContainer_TabDialogs->Delete( m_sViewName ); + } + break; + case E_TABPAGE : { + bState = m_pDataContainer_TabPages->Delete( m_sViewName ); + } + break; + case E_WINDOW : { + bState = m_pDataContainer_Windows->Delete( m_sViewName ); + } + break; + } + return bState; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +::rtl::OUString SvtViewOptions::GetWindowState() const +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + ::rtl::OUString sState; + switch( m_eViewType ) + { + case E_DIALOG : { + sState = m_pDataContainer_Dialogs->GetWindowState( m_sViewName ); + } + break; + case E_TABDIALOG : { + sState = m_pDataContainer_TabDialogs->GetWindowState( m_sViewName ); + } + break; + case E_TABPAGE : { + sState = m_pDataContainer_TabPages->GetWindowState( m_sViewName ); + } + break; + case E_WINDOW : { + sState = m_pDataContainer_Windows->GetWindowState( m_sViewName ); + } + break; + } + return sState; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtViewOptions::SetWindowState( const ::rtl::OUString& sState ) +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + switch( m_eViewType ) + { + case E_DIALOG : { + m_pDataContainer_Dialogs->SetWindowState( m_sViewName, sState ); + } + break; + case E_TABDIALOG : { + m_pDataContainer_TabDialogs->SetWindowState( m_sViewName, sState ); + } + break; + case E_TABPAGE : { + m_pDataContainer_TabPages->SetWindowState( m_sViewName, sState ); + } + break; + case E_WINDOW : { + m_pDataContainer_Windows->SetWindowState( m_sViewName, sState ); + } + break; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Int32 SvtViewOptions::GetPageID() const +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + // Safe impossible cases. + // These call isn't allowed for dialogs, tab-pages or windows! + OSL_ENSURE( !(m_eViewType==E_DIALOG||m_eViewType==E_TABPAGE||m_eViewType==E_WINDOW), "SvtViewOptions::GetPageID()\nCall not allowed for Dialogs, TabPages or Windows! I do nothing!\n" ); + + sal_Int32 nID = 0; + if( m_eViewType == E_TABDIALOG ) + nID = m_pDataContainer_TabDialogs->GetPageID( m_sViewName ); + return nID; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtViewOptions::SetPageID( sal_Int32 nID ) +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + // Safe impossible cases. + // These call isn't allowed for dialogs, tab-pages or windows! + OSL_ENSURE( !(m_eViewType==E_DIALOG||m_eViewType==E_TABPAGE||m_eViewType==E_WINDOW), "SvtViewOptions::SetPageID()\nCall not allowed for Dialogs, TabPages or Windows! I do nothing!\n" ); + + if( m_eViewType == E_TABDIALOG ) + m_pDataContainer_TabDialogs->SetPageID( m_sViewName, nID ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +sal_Bool SvtViewOptions::IsVisible() const +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + // Safe impossible cases. + // These call isn't allowed for dialogs, tab-dialogs or tab-pages! + OSL_ENSURE( !(m_eViewType==E_DIALOG||m_eViewType==E_TABDIALOG||m_eViewType==E_TABPAGE), "SvtViewOptions::IsVisible()\nCall not allowed for Dialogs, TabDialogs or TabPages! I do nothing!\n" ); + + sal_Bool bState = sal_False; + if( m_eViewType == E_WINDOW ) + bState = m_pDataContainer_Windows->GetVisible( m_sViewName ); + + return bState; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtViewOptions::SetVisible( sal_Bool bState ) +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + // Safe impossible cases. + // These call isn't allowed for dialogs, tab-dialogs or tab-pages! + OSL_ENSURE( !(m_eViewType==E_DIALOG||m_eViewType==E_TABDIALOG||m_eViewType==E_TABPAGE), "SvtViewOptions::SetVisible()\nCall not allowed for Dialogs, TabDialogs or TabPages! I do nothing!\n" ); + + if( m_eViewType == E_WINDOW ) + m_pDataContainer_Windows->SetVisible( m_sViewName, bState ); +} + +//***************************************************************************************************************** +css::uno::Sequence< css::beans::NamedValue > SvtViewOptions::GetUserData() const +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + css::uno::Sequence< css::beans::NamedValue > lData; + switch( m_eViewType ) + { + case E_DIALOG : { + lData = m_pDataContainer_Dialogs->GetUserData( m_sViewName ); + } + break; + case E_TABDIALOG : { + lData = m_pDataContainer_TabDialogs->GetUserData( m_sViewName ); + } + break; + case E_TABPAGE : { + lData = m_pDataContainer_TabPages->GetUserData( m_sViewName ); + } + break; + case E_WINDOW : { + lData = m_pDataContainer_Windows->GetUserData( m_sViewName ); + } + break; + } + return lData; +} + +//***************************************************************************************************************** +void SvtViewOptions::SetUserData( const css::uno::Sequence< css::beans::NamedValue >& lData ) +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + switch( m_eViewType ) + { + case E_DIALOG : { + m_pDataContainer_Dialogs->SetUserData( m_sViewName, lData ); + } + break; + case E_TABDIALOG : { + m_pDataContainer_TabDialogs->SetUserData( m_sViewName, lData ); + } + break; + case E_TABPAGE : { + m_pDataContainer_TabPages->SetUserData( m_sViewName, lData ); + } + break; + case E_WINDOW : { + m_pDataContainer_Windows->SetUserData( m_sViewName, lData ); + } + break; + } +} + +//***************************************************************************************************************** +css::uno::Any SvtViewOptions::GetUserItem( const ::rtl::OUString& sName ) const +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + css::uno::Any aItem; + switch( m_eViewType ) + { + case E_DIALOG : { + aItem = m_pDataContainer_Dialogs->GetUserItem( m_sViewName, sName ); + } + break; + case E_TABDIALOG : { + aItem = m_pDataContainer_TabDialogs->GetUserItem( m_sViewName, sName ); + } + break; + case E_TABPAGE : { + aItem = m_pDataContainer_TabPages->GetUserItem( m_sViewName, sName ); + } + break; + case E_WINDOW : { + aItem = m_pDataContainer_Windows->GetUserItem( m_sViewName, sName ); + } + break; + } + return aItem; +} + +//***************************************************************************************************************** +void SvtViewOptions::SetUserItem( const ::rtl::OUString& sName , + const css::uno::Any& aValue ) +{ + // Ready for multithreading + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + + switch( m_eViewType ) + { + case E_DIALOG : { + m_pDataContainer_Dialogs->SetUserItem( m_sViewName, sName, aValue ); + } + break; + case E_TABDIALOG : { + m_pDataContainer_TabDialogs->SetUserItem( m_sViewName, sName, aValue ); + } + break; + case E_TABPAGE : { + m_pDataContainer_TabPages->SetUserItem( m_sViewName, sName, aValue ); + } + break; + case E_WINDOW : { + m_pDataContainer_Windows->SetUserItem( m_sViewName, sName, aValue ); + } + break; + } +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +::osl::Mutex& SvtViewOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static ::osl::Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static ::osl::Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} + +void SvtViewOptions::AcquireOptions() +{ + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + if( ++m_nRefCount_Dialogs == 1 ) + { + m_pDataContainer_Dialogs = new SvtViewOptionsBase_Impl( LIST_DIALOGS ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_DIALOG); + } + if( ++m_nRefCount_TabDialogs == 1 ) + { + m_pDataContainer_TabDialogs = new SvtViewOptionsBase_Impl( LIST_TABDIALOGS ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_TABDIALOG); + } + if( ++m_nRefCount_TabPages == 1 ) + { + m_pDataContainer_TabPages = new SvtViewOptionsBase_Impl( LIST_TABPAGES ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_TABPAGE); + } + if( ++m_nRefCount_Windows == 1 ) + { + m_pDataContainer_Windows = new SvtViewOptionsBase_Impl( LIST_WINDOWS ); + ItemHolder1::holdConfigItem(E_VIEWOPTIONS_WINDOW); + } +} + +void SvtViewOptions::ReleaseOptions() +{ + ::osl::MutexGuard aGuard( GetOwnStaticMutex() ); + if( --m_nRefCount_Dialogs == 0 ) + { + delete m_pDataContainer_Dialogs; + m_pDataContainer_Dialogs = NULL; + } + if( --m_nRefCount_TabDialogs == 0 ) + { + delete m_pDataContainer_TabDialogs; + m_pDataContainer_TabDialogs = NULL; + } + if( --m_nRefCount_TabPages == 0 ) + { + delete m_pDataContainer_TabPages; + m_pDataContainer_TabPages = NULL; + } + if( --m_nRefCount_Windows == 0 ) + { + delete m_pDataContainer_Windows; + m_pDataContainer_Windows = NULL; + } +} diff --git a/unotools/source/config/workingsetoptions.cxx b/unotools/source/config/workingsetoptions.cxx new file mode 100644 index 000000000000..aebac3377510 --- /dev/null +++ b/unotools/source/config/workingsetoptions.cxx @@ -0,0 +1,393 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <unotools/workingsetoptions.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <itemholder1.hxx> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::utl ; +using namespace ::rtl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +#define ROOTNODE_WORKINGSET OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/WorkingSet")) +#define DEFAULT_WINDOWLIST Sequence< OUString >() + +#define PROPERTYNAME_WINDOWLIST OUString(RTL_CONSTASCII_USTRINGPARAM("WindowList" )) + +#define PROPERTYHANDLE_WINDOWLIST 0 + +#define PROPERTYCOUNT 1 + +//_________________________________________________________________________________________________________________ +// private declarations! +//_________________________________________________________________________________________________________________ + +class SvtWorkingSetOptions_Impl : public ConfigItem +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------------------------------------------- + // constructor / destructor + //--------------------------------------------------------------------------------------------------------- + + SvtWorkingSetOptions_Impl(); + ~SvtWorkingSetOptions_Impl(); + + //--------------------------------------------------------------------------------------------------------- + // overloaded methods of baseclass + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short called for notify of configmanager + @descr These method is called from the ConfigManager before application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& seqPropertyNames ); + + /*-****************************************************************************************************//** + @short write changes to configuration + @descr These method writes the changed values into the sub tree + and should always called in our destructor to guarantee consistency of config data. + + @seealso baseclass ConfigItem + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + virtual void Commit(); + + //--------------------------------------------------------------------------------------------------------- + // public interface + //--------------------------------------------------------------------------------------------------------- + + /*-****************************************************************************************************//** + @short access method to get internal values + @descr These method give us a chance to regulate acces to ouer internal values. + It's not used in the moment - but it's possible for the feature! + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + + Sequence< OUString > GetWindowList( ) const ; + void SetWindowList( const Sequence< OUString >& seqWindowList ) ; + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + + private: + + /*-****************************************************************************************************//** + @short return list of key names of ouer configuration management which represent oue module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. + + @seealso - + + @param - + @return A list of needed configuration keys is returned. + + @onerror - + *//*-*****************************************************************************************************/ + + static Sequence< OUString > GetPropertyNames(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + + private: + + Sequence< OUString > m_seqWindowList ; +}; + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl() + // Init baseclasses first + : ConfigItem ( ROOTNODE_WORKINGSET ) + // Init member then. + , m_seqWindowList ( DEFAULT_WINDOWLIST ) +{ + // Use our static list of configuration keys to get his values. + Sequence< OUString > seqNames = GetPropertyNames ( ); + Sequence< Any > seqValues = GetProperties ( seqNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to ouer internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + // Safe impossible cases. + // Check any for valid value. + DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl()\nInvalid property value detected!\n" ); + switch( nProperty ) + { + case PROPERTYHANDLE_WINDOWLIST : { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SEQUENCE), "SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl()\nWho has changed the value type of \"Office.Common\\WorkingSet\\WindowList\"?" ); + seqValues[nProperty] >>= m_seqWindowList; + } + break; + } + } + + // Enable notification mechanism of ouer baseclass. + // We need it to get information about changes outside these class on ouer used configuration keys! + EnableNotification( seqNames ); +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtWorkingSetOptions_Impl::~SvtWorkingSetOptions_Impl() +{ + // We must save our current values .. if user forget it! + if( IsModified() == sal_True ) + { + Commit(); + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtWorkingSetOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames ) +{ + // Use given list of updated properties to get his values from configuration directly! + Sequence< Any > seqValues = GetProperties( seqPropertyNames ); + // Safe impossible cases. + // We need values from ALL notified configuration keys. + DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtWorkingSetOptions_Impl::Notify()\nI miss some values of configuration keys!\n" ); + // Step over list of property names and get right value from coreesponding value list to set it on internal members! + sal_Int32 nCount = seqPropertyNames.getLength(); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + if( seqPropertyNames[nProperty] == PROPERTYNAME_WINDOWLIST ) + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SEQUENCE), "SvtWorkingSetOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\WorkingSet\\WindowList\"?" ); + seqValues[nProperty] >>= m_seqWindowList; + } + #if OSL_DEBUG_LEVEL > 1 + else DBG_ASSERT( sal_False, "SvtWorkingSetOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" ); + #endif + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtWorkingSetOptions_Impl::Commit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + Sequence< OUString > seqNames = GetPropertyNames (); + sal_Int32 nCount = seqNames.getLength(); + Sequence< Any > seqValues ( nCount ); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_WINDOWLIST : { + seqValues[nProperty] <<= m_seqWindowList; + } + break; + } + } + // Set properties in configuration. + PutProperties( seqNames, seqValues ); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< OUString > SvtWorkingSetOptions_Impl::GetWindowList() const +{ + return m_seqWindowList; +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtWorkingSetOptions_Impl::SetWindowList( const Sequence< OUString >& seqWindowList ) +{ + m_seqWindowList = seqWindowList; + SetModified(); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Sequence< OUString > SvtWorkingSetOptions_Impl::GetPropertyNames() +{ + // Build static list of configuration key names. + static const OUString pProperties[] = + { + PROPERTYNAME_WINDOWLIST , + }; + // Initialize return sequence with these list ... + static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); + // ... and return it. + return seqPropertyNames; +} + +//***************************************************************************************************************** +// initialize static member +// DON'T DO IT IN YOUR HEADER! +// see definition for further informations +//***************************************************************************************************************** +SvtWorkingSetOptions_Impl* SvtWorkingSetOptions::m_pDataContainer = NULL ; +sal_Int32 SvtWorkingSetOptions::m_nRefCount = 0 ; + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +SvtWorkingSetOptions::SvtWorkingSetOptions() +{ + // Global access, must be guarded (multithreading!). + MutexGuard aGuard( GetOwnStaticMutex() ); + // Increase ouer refcount ... + ++m_nRefCount; + // ... and initialize ouer data container only if it not already exist! + if( m_pDataContainer == NULL ) + { + m_pDataContainer = new SvtWorkingSetOptions_Impl; + ItemHolder1::holdConfigItem(E_WORKINGSETOPTIONS); + } +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +SvtWorkingSetOptions::~SvtWorkingSetOptions() +{ + // Global access, must be guarded (multithreading!) + MutexGuard aGuard( GetOwnStaticMutex() ); + // Decrease ouer refcount. + --m_nRefCount; + // If last instance was deleted ... + // we must destroy ouer static data container! + if( m_nRefCount <= 0 ) + { + delete m_pDataContainer; + m_pDataContainer = NULL; + } +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +Sequence< OUString > SvtWorkingSetOptions::GetWindowList() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->GetWindowList(); +} + +//***************************************************************************************************************** +// public method +//***************************************************************************************************************** +void SvtWorkingSetOptions::SetWindowList( const Sequence< OUString >& seqWindowList ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetWindowList( seqWindowList ); +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Mutex& SvtWorkingSetOptions::GetOwnStaticMutex() +{ + // Initialize static mutex only for one time! + static Mutex* pMutex = NULL; + // If these method first called (Mutex not already exist!) ... + if( pMutex == NULL ) + { + // ... we must create a new one. Protect follow code with the global mutex - + // It must be - we create a static variable! + MutexGuard aGuard( Mutex::getGlobalMutex() ); + // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! + if( pMutex == NULL ) + { + // Create the new mutex and set it for return on static variable. + static Mutex aMutex; + pMutex = &aMutex; + } + } + // Return new created or already existing mutex object. + return *pMutex; +} diff --git a/unotools/source/config/xmlaccelcfg.cxx b/unotools/source/config/xmlaccelcfg.cxx new file mode 100644 index 000000000000..a446c60bbdc5 --- /dev/null +++ b/unotools/source/config/xmlaccelcfg.cxx @@ -0,0 +1,415 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/xmlaccelcfg.hxx> + +#include <vector> +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <cppuhelper/implbase1.hxx> + +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::xml::sax; + +#define ELEMENT_ACCELERATORLIST "acceleratorlist" +#define ELEMENT_ACCELERATORITEM "item" + +#define ATTRIBUTE_KEYCODE "code" +#define ATTRIBUTE_MODIFIER "modifier" +#define ATTRIBUTE_URL "url" + +#define ATTRIBUTE_TYPE_CDATA "CDATA" + +// ------------------------------------------------------------------ + +struct AttributeListImpl_impl; +class AttributeListImpl : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XAttributeList > +{ +protected: + ~AttributeListImpl(); + +public: + AttributeListImpl(); + AttributeListImpl( const AttributeListImpl & ); + +public: + virtual sal_Int16 SAL_CALL getLength(void) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTypeByName(const ::rtl::OUString& aName) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getValueByName(const ::rtl::OUString& aName) throw (::com::sun::star::uno::RuntimeException); + +public: + void addAttribute( const ::rtl::OUString &sName , const ::rtl::OUString &sType , const ::rtl::OUString &sValue ); + void clear(); + +private: + struct AttributeListImpl_impl *m_pImpl; +}; + +struct TagAttribute +{ + TagAttribute(){} + TagAttribute( const OUString &aName, const OUString &aType , const OUString &aValue ) + { + sName = aName; + sType = aType; + sValue = aValue; + } + + OUString sName; + OUString sType; + OUString sValue; +}; + +struct AttributeListImpl_impl +{ + AttributeListImpl_impl() + { + // performance improvement during adding + vecAttribute.reserve(20); + } + ::std::vector<struct TagAttribute> vecAttribute; +}; + + + +sal_Int16 SAL_CALL AttributeListImpl::getLength(void) throw (RuntimeException) +{ + return sal::static_int_cast< sal_Int16 >(m_pImpl->vecAttribute.size()); +} + + +AttributeListImpl::AttributeListImpl( const AttributeListImpl &r ) : + cppu::WeakImplHelper1<com::sun::star::xml::sax::XAttributeList>(r) +{ + m_pImpl = new AttributeListImpl_impl; + *m_pImpl = *(r.m_pImpl); +} + +OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { + return m_pImpl->vecAttribute[i].sName; + } + return OUString(); +} + + +OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { + return m_pImpl->vecAttribute[i].sType; + } + return OUString(); +} + +OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { + return m_pImpl->vecAttribute[i].sValue; + } + return OUString(); + +} + +OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException) +{ + ::std::vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin(); + + for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) { + if( (*ii).sName == sName ) { + return (*ii).sType; + } + } + return OUString(); +} + +OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException) +{ + ::std::vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin(); + + for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) { + if( (*ii).sName == sName ) { + return (*ii).sValue; + } + } + return OUString(); +} + + +AttributeListImpl::AttributeListImpl() +{ + m_pImpl = new AttributeListImpl_impl; +} + + + +AttributeListImpl::~AttributeListImpl() +{ + delete m_pImpl; +} + + +void AttributeListImpl::addAttribute( const OUString &sName , + const OUString &sType , + const OUString &sValue ) +{ + m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) ); +} + +void AttributeListImpl::clear() +{ + ::std::vector<struct TagAttribute> dummy; + m_pImpl->vecAttribute.swap( dummy ); + + OSL_ASSERT( ! getLength() ); +} + +// ------------------------------------------------------------------ + +Any SAL_CALL OReadAccelatorDocumentHandler::queryInterface( const Type & rType ) throw( RuntimeException ) +{ + Any a = ::cppu::queryInterface( rType ,SAL_STATIC_CAST( XDocumentHandler*, this )); + if ( a.hasValue() ) + return a; + else + return OWeakObject::queryInterface( rType ); +} + +void SAL_CALL OReadAccelatorDocumentHandler::ignorableWhitespace( + const OUString& ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadAccelatorDocumentHandler::processingInstruction( + const OUString&, const OUString& ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadAccelatorDocumentHandler::setDocumentLocator( + const Reference< XLocator > &xLocator) +throw( SAXException, RuntimeException ) +{ + m_xLocator = xLocator; +} + +::rtl::OUString OReadAccelatorDocumentHandler::getErrorLineString() +{ + char buffer[32]; + + if ( m_xLocator.is() ) + { + return OUString::createFromAscii( buffer ); + } + else + return OUString(); +} + +void SAL_CALL OReadAccelatorDocumentHandler::startDocument(void) + throw ( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadAccelatorDocumentHandler::endDocument(void) + throw( SAXException, RuntimeException ) +{ + if ( m_nElementDepth > 0 ) + { + OUString aErrorMessage = getErrorLineString(); + aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + + +void SAL_CALL OReadAccelatorDocumentHandler::startElement( + const OUString& aElementName, const Reference< XAttributeList > &xAttrList ) +throw( SAXException, RuntimeException ) +{ + m_nElementDepth++; + + if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST ))) + { + // acceleratorlist + if ( m_bAcceleratorMode ) + { + OUString aErrorMessage = getErrorLineString(); + aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + else + m_bAcceleratorMode = sal_True; + } + else if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM ))) + { + // accelerator item + if ( !m_bAcceleratorMode ) + { + OUString aErrorMessage = getErrorLineString(); + aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list element has to be used before!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + else + { + // read accelerator item + m_bItemCloseExpected = sal_True; + + SvtAcceleratorConfigItem aItem; + + // read attributes for accelerator + for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) + { + OUString aName = xAttrList->getNameByIndex( i ); + OUString aValue = xAttrList->getValueByIndex( i ); + + if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_URL ))) + aItem.aCommand = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_MODIFIER ))) + aItem.nModifier = (sal_uInt16)aValue.toInt32(); + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_KEYCODE ))) + aItem.nCode = (sal_uInt16)aValue.toInt32(); + } + + m_aReadAcceleratorList.push_back( aItem ); + } + } + else + { + OUString aErrorMessage = getErrorLineString(); + aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown element found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + + +void SAL_CALL OReadAccelatorDocumentHandler::characters(const rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadAccelatorDocumentHandler::endElement( const OUString& aName ) + throw( SAXException, RuntimeException ) +{ + m_nElementDepth--; + + if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST ))) + { + // acceleratorlist + if ( !m_bAcceleratorMode ) + { + OUString aErrorMessage = getErrorLineString(); + aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM ))) + { + if ( !m_bItemCloseExpected ) + { + OUString aErrorMessage = getErrorLineString(); + aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Closing accelerator item element expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + else + { + OUString aErrorMessage = getErrorLineString(); + aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown closing element found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + +// ------------------------------------------------------------------ + +OWriteAccelatorDocumentHandler::OWriteAccelatorDocumentHandler( + const SvtAcceleratorItemList& aWriteAcceleratorList, Reference< XDocumentHandler > xDocumentHandler ) : + m_xWriteDocumentHandler( xDocumentHandler ), + m_aWriteAcceleratorList( aWriteAcceleratorList ) +{ + m_aAttributeType = OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); +} + +OWriteAccelatorDocumentHandler::~OWriteAccelatorDocumentHandler() +{ +} + +void OWriteAccelatorDocumentHandler::WriteAcceleratorDocument() + throw ( SAXException, RuntimeException ) +{ + AttributeListImpl* pList = new AttributeListImpl; + Reference< XAttributeList > rList( (XAttributeList *)pList , UNO_QUERY ); + + m_xWriteDocumentHandler->startDocument(); + m_xWriteDocumentHandler->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )), rList ); + m_xWriteDocumentHandler->ignorableWhitespace( OUString() ); + + std::list< SvtAcceleratorConfigItem>::const_iterator p; + for ( p = m_aWriteAcceleratorList.begin(); p != m_aWriteAcceleratorList.end(); p++ ) + WriteAcceleratorItem( *p ); + + m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )) ); + m_xWriteDocumentHandler->endDocument(); +} + +void OWriteAccelatorDocumentHandler::WriteAcceleratorItem( + const SvtAcceleratorConfigItem& aAcceleratorItem ) + throw( SAXException, RuntimeException ) +{ + AttributeListImpl* pAcceleratorAttributes = new AttributeListImpl; + Reference< XAttributeList > xAcceleratorAttrList( (XAttributeList *)pAcceleratorAttributes , UNO_QUERY ); + + // set attributes + pAcceleratorAttributes->addAttribute( + OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_KEYCODE )), + m_aAttributeType, + OUString::valueOf( aAcceleratorItem.nCode )); + + pAcceleratorAttributes->addAttribute( + OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MODIFIER )), + m_aAttributeType, + OUString::valueOf( aAcceleratorItem.nModifier )); + + pAcceleratorAttributes->addAttribute( + OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL )), + m_aAttributeType, + aAcceleratorItem.aCommand ); + + // write start element + m_xWriteDocumentHandler->startElement( + OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )), + xAcceleratorAttrList ); + m_xWriteDocumentHandler->ignorableWhitespace( OUString() ); + m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )) ); +} diff --git a/unotools/source/i18n/calendarwrapper.cxx b/unotools/source/i18n/calendarwrapper.cxx new file mode 100644 index 000000000000..ebf8146ef0fa --- /dev/null +++ b/unotools/source/i18n/calendarwrapper.cxx @@ -0,0 +1,680 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/calendarwrapper.hxx> +#include <tools/string.hxx> +#include <tools/debug.hxx> + +#ifndef _COMPHELPER_COMPONENTFACTORY_HXX_ +#include <comphelper/componentfactory.hxx> +#endif +#include <com/sun/star/i18n/CalendarFieldIndex.hpp> +#include <com/sun/star/i18n/XExtendedCalendar.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#define CALENDAR_LIBRARYNAME "i18n" +#define CALENDAR_SERVICENAME "com.sun.star.i18n.LocaleCalendar" + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::uno; + + +const double MILLISECONDS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0; + + +CalendarWrapper::CalendarWrapper( + const Reference< lang::XMultiServiceFactory > & xSF + ) + : + xSMgr( xSF ), + aEpochStart( Date( 1, 1, 1970 ) ) +{ + if ( xSMgr.is() ) + { + try + { + xC = Reference< XExtendedCalendar > ( xSMgr->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CALENDAR_SERVICENAME ) ) ), + uno::UNO_QUERY ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "CalendarWrapper ctor: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + } + else + { // try to get an instance somehow + DBG_ERRORFILE( "CalendarWrapper: no service manager, trying own" ); + try + { + Reference< XInterface > xI = ::comphelper::getComponentInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( CALENDAR_LIBRARYNAME ) ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CALENDAR_SERVICENAME ) ) ); + if ( xI.is() ) + { + Any x = xI->queryInterface( ::getCppuType((const Reference< XExtendedCalendar >*)0) ); + x >>= xC; + } + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getComponentInstance: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + } +} + + +CalendarWrapper::~CalendarWrapper() +{ +} + + +void CalendarWrapper::loadDefaultCalendar( const ::com::sun::star::lang::Locale& rLocale ) +{ + try + { + if ( xC.is() ) + xC->loadDefaultCalendar( rLocale ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "loadDefaultCalendar: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +void CalendarWrapper::loadCalendar( const ::rtl::OUString& rUniqueID, const ::com::sun::star::lang::Locale& rLocale ) +{ + try + { + if ( xC.is() ) + xC->loadCalendar( rUniqueID, rLocale ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "loadCalendar: Exception caught\nrequested: " ); + aMsg += ByteString( String( rUniqueID ), RTL_TEXTENCODING_UTF8 ); + aMsg += " Locale: "; + aMsg += ByteString( String( rLocale.Language ), RTL_TEXTENCODING_UTF8 ); + aMsg += '_'; + aMsg += ByteString( String( rLocale.Country ), RTL_TEXTENCODING_UTF8 ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +::com::sun::star::i18n::Calendar CalendarWrapper::getLoadedCalendar() const +{ + try + { + if ( xC.is() ) + return xC->getLoadedCalendar(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getLoadedCalendar: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::i18n::Calendar(); +} + + +::com::sun::star::uno::Sequence< ::rtl::OUString > CalendarWrapper::getAllCalendars( const ::com::sun::star::lang::Locale& rLocale ) const +{ + try + { + if ( xC.is() ) + return xC->getAllCalendars( rLocale ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getAllCalendars: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::rtl::OUString > (0); +} + + +::rtl::OUString CalendarWrapper::getUniqueID() const +{ + try + { + if ( xC.is() ) + return xC->getUniqueID(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getUniqueID: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::rtl::OUString(); +} + + +void CalendarWrapper::setDateTime( double nTimeInDays ) +{ + try + { + if ( xC.is() ) + xC->setDateTime( nTimeInDays ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "setDateTime: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +double CalendarWrapper::getDateTime() const +{ + try + { + if ( xC.is() ) + return xC->getDateTime(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getDateTime: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0.0; +} + + +sal_Int32 CalendarWrapper::getCombinedOffsetInMillis( + sal_Int16 nParentFieldIndex, sal_Int16 nChildFieldIndex ) const +{ + sal_Int32 nOffset = 0; + try + { + if ( xC.is() ) + { + nOffset = static_cast<sal_Int32>( xC->getValue( nParentFieldIndex )) * 60000; + sal_Int16 nSecondMillis = xC->getValue( nChildFieldIndex ); + if (nOffset < 0) + nOffset -= static_cast<sal_uInt16>( nSecondMillis); + else + nOffset += static_cast<sal_uInt16>( nSecondMillis); + } + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "setLocalDateTime: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return nOffset; +} + + +sal_Int32 CalendarWrapper::getZoneOffsetInMillis() const +{ + return getCombinedOffsetInMillis( CalendarFieldIndex::ZONE_OFFSET, + CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS); +} + + +sal_Int32 CalendarWrapper::getDSTOffsetInMillis() const +{ + return getCombinedOffsetInMillis( CalendarFieldIndex::DST_OFFSET, + CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS); +} + + +void CalendarWrapper::setLocalDateTime( double nTimeInDays ) +{ + try + { + if ( xC.is() ) + { + // First set a nearby value to obtain the timezone and DST offset. + // This is necessary to let ICU choose the corresponding + // OlsonTimeZone transitions. Since ICU incorporates also + // historical data even the timezone may differ for different + // dates! (Which was the cause for #i76623# when the timezone of a + // previously set date was used.) Timezone may also include + // seconds, so use milliseconds field as well. + xC->setDateTime( nTimeInDays ); + sal_Int32 nZone1 = getZoneOffsetInMillis(); + sal_Int32 nDST1 = getDSTOffsetInMillis(); + double nLoc = nTimeInDays - (double)(nZone1 + nDST1) / MILLISECONDS_PER_DAY; + xC->setDateTime( nLoc ); + sal_Int32 nZone2 = getZoneOffsetInMillis(); + sal_Int32 nDST2 = getDSTOffsetInMillis(); + // If DSTs differ after calculation, we crossed boundaries. Do it + // again, this time using the DST corrected initial value for the + // real local time. + // See also localtime/gmtime conversion pitfalls at + // http://www.erack.de/download/timetest.c + if ( nDST1 != nDST2 ) + { + nLoc = nTimeInDays - (double)(nZone2 + nDST2) / MILLISECONDS_PER_DAY; + xC->setDateTime( nLoc ); + // #i17222# If the DST onset rule says to switch from 00:00 to + // 01:00 and we tried to set onsetDay 00:00 with DST, the + // result was onsetDay-1 23:00 and no DST, which is not what we + // want. So once again without DST, resulting in onsetDay + // 01:00 and DST. Yes, this seems to be weird, but logically + // correct. + sal_Int32 nDST3 = getDSTOffsetInMillis(); + if ( nDST2 != nDST3 && !nDST3 ) + { + nLoc = nTimeInDays - (double)(nZone2 + nDST3) / MILLISECONDS_PER_DAY; + xC->setDateTime( nLoc ); + } + } + } + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "setLocalDateTime: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +double CalendarWrapper::getLocalDateTime() const +{ + try + { + if ( xC.is() ) + { + double nTimeInDays = xC->getDateTime(); + sal_Int32 nZone = getZoneOffsetInMillis(); + sal_Int32 nDST = getDSTOffsetInMillis(); + nTimeInDays += (double)(nZone + nDST) / MILLISECONDS_PER_DAY; + return nTimeInDays; + } + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getLocalDateTime: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0.0; +} + + +void CalendarWrapper::setValue( sal_Int16 nFieldIndex, sal_Int16 nValue ) +{ + try + { + if ( xC.is() ) + xC->setValue( nFieldIndex, nValue ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "setValue: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +sal_Bool CalendarWrapper::isValid() const +{ + try + { + if ( xC.is() ) + return xC->isValid(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "isValid: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return sal_False; +} + + +sal_Int16 CalendarWrapper::getValue( sal_Int16 nFieldIndex ) const +{ + try + { + if ( xC.is() ) + return xC->getValue( nFieldIndex ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getValue: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0; +} + + +void CalendarWrapper::addValue( sal_Int16 nFieldIndex, sal_Int32 nAmount ) +{ + try + { + if ( xC.is() ) + xC->addValue( nFieldIndex, nAmount ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "addValue: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +sal_Int16 CalendarWrapper::getFirstDayOfWeek() const +{ + try + { + if ( xC.is() ) + return xC->getFirstDayOfWeek(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getFirstDayOfWeek: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0; +} + + +void CalendarWrapper::setFirstDayOfWeek( sal_Int16 nDay ) +{ + try + { + if ( xC.is() ) + xC->setFirstDayOfWeek( nDay ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "setFirstDayOfWeek: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +void CalendarWrapper::setMinimumNumberOfDaysForFirstWeek( sal_Int16 nDays ) +{ + try + { + if ( xC.is() ) + xC->setMinimumNumberOfDaysForFirstWeek( nDays ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "setMinimumNumberOfDaysForFirstWeek: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } +} + + +sal_Int16 CalendarWrapper::getMinimumNumberOfDaysForFirstWeek() const +{ + try + { + if ( xC.is() ) + return xC->getMinimumNumberOfDaysForFirstWeek(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getMinimumNumberOfDaysForFirstWeek: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0; +} + + +sal_Int16 CalendarWrapper::getNumberOfMonthsInYear() const +{ + try + { + if ( xC.is() ) + return xC->getNumberOfMonthsInYear(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getNumberOfMonthsInYear: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0; +} + + +sal_Int16 CalendarWrapper::getNumberOfDaysInWeek() const +{ + try + { + if ( xC.is() ) + return xC->getNumberOfDaysInWeek(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getNumberOfDaysInWeek: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0; +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > CalendarWrapper::getMonths() const +{ + try + { + if ( xC.is() ) + return xC->getMonths(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getMonths: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > (0); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > CalendarWrapper::getDays() const +{ + try + { + if ( xC.is() ) + return xC->getDays(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getDays: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > (0); +} + + +String CalendarWrapper::getDisplayName( sal_Int16 nCalendarDisplayIndex, sal_Int16 nIdx, sal_Int16 nNameType ) const +{ + try + { + if ( xC.is() ) + return xC->getDisplayName( nCalendarDisplayIndex, nIdx, nNameType ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getDisplayName: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return String(); +} + + +// --- XExtendedCalendar ----------------------------------------------------- + +String CalendarWrapper::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode ) const +{ + try + { + if ( xC.is() ) + return xC->getDisplayString( nCalendarDisplayCode, nNativeNumberMode ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getDisplayString: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return String(); +} + diff --git a/unotools/source/i18n/charclass.cxx b/unotools/source/i18n/charclass.cxx new file mode 100644 index 000000000000..e82fd7a603ad --- /dev/null +++ b/unotools/source/i18n/charclass.cxx @@ -0,0 +1,582 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/charclass.hxx> +#include <tools/string.hxx> +#include <tools/debug.hxx> + +#ifndef _COMPHELPER_COMPONENTFACTORY_HXX_ +#include <comphelper/componentfactory.hxx> +#endif +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#define CHARCLASS_LIBRARYNAME "i18n" +#define CHARCLASS_SERVICENAME "com.sun.star.i18n.CharacterClassification" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::uno; + + +CharClass::CharClass( + const Reference< lang::XMultiServiceFactory > & xSF, + const lang::Locale& rLocale + ) + : + xSMgr( xSF ) +{ + setLocale( rLocale ); + if ( xSMgr.is() ) + { + try + { + xCC = Reference< XCharacterClassification > ( xSMgr->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CHARCLASS_SERVICENAME ) ) ), + uno::UNO_QUERY ); + } + catch ( Exception& ) + { + DBG_ERRORFILE( "CharClass ctor: Exception caught!" ); + } + } + else + { // try to get an instance somehow + getComponentInstance(); + } +} + + +CharClass::CharClass( + const ::com::sun::star::lang::Locale& rLocale ) +{ + setLocale( rLocale ); + getComponentInstance(); +} + + +CharClass::~CharClass() +{ +} + + +void CharClass::getComponentInstance() +{ + try + { + // CharClass may be needed by "small tools" like the Setup + // => maybe no service manager => loadLibComponentFactory + Reference < XInterface > xI = ::comphelper::getComponentInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( CHARCLASS_LIBRARYNAME ) ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CHARCLASS_SERVICENAME ) ) ); + if ( xI.is() ) + { + Any x = xI->queryInterface( ::getCppuType((const Reference< XCharacterClassification >*)0) ); + x >>= xCC; + } + } + catch ( Exception& ) + { + DBG_ERRORFILE( "getComponentInstance: Exception caught!" ); + } +} + + +void CharClass::setLocale( const ::com::sun::star::lang::Locale& rLocale ) +{ + ::osl::MutexGuard aGuard( aMutex ); + aLocale.Language = rLocale.Language; + aLocale.Country = rLocale.Country; + aLocale.Variant = rLocale.Variant; +} + + +const ::com::sun::star::lang::Locale& CharClass::getLocale() const +{ + ::osl::MutexGuard aGuard( aMutex ); + return aLocale; +} + + +// static +sal_Bool CharClass::isAsciiNumeric( const String& rStr ) +{ + if ( !rStr.Len() ) + return sal_False; + register const sal_Unicode* p = rStr.GetBuffer(); + register const sal_Unicode* const pStop = p + rStr.Len(); + do + { + if ( !isAsciiDigit( *p ) ) + return sal_False; + } while ( ++p < pStop ); + return sal_True; +} + + +// static +sal_Bool CharClass::isAsciiAlpha( const String& rStr ) +{ + if ( !rStr.Len() ) + return sal_False; + register const sal_Unicode* p = rStr.GetBuffer(); + register const sal_Unicode* const pStop = p + rStr.Len(); + do + { + if ( !isAsciiAlpha( *p ) ) + return sal_False; + } while ( ++p < pStop ); + return sal_True; +} + + +// static +sal_Bool CharClass::isAsciiAlphaNumeric( const String& rStr ) +{ + if ( !rStr.Len() ) + return sal_False; + register const sal_Unicode* p = rStr.GetBuffer(); + register const sal_Unicode* const pStop = p + rStr.Len(); + do + { + if ( !isAsciiAlphaNumeric( *p ) ) + return sal_False; + } while ( ++p < pStop ); + return sal_True; +} + + +sal_Bool CharClass::isAlpha( const String& rStr, xub_StrLen nPos ) const +{ + sal_Unicode c = rStr.GetChar( nPos ); + if ( c < 128 ) + return isAsciiAlpha( c ); + + try + { + if ( xCC.is() ) + return (xCC->getCharacterType( rStr, nPos, getLocale() ) & + nCharClassAlphaType) != 0; + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isAlpha: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isAlpha( const String& rStr ) const +{ + try + { + if ( xCC.is() ) + return isAlphaType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) ); + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isAlpha: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isLetter( const String& rStr, xub_StrLen nPos ) const +{ + sal_Unicode c = rStr.GetChar( nPos ); + if ( c < 128 ) + return isAsciiAlpha( c ); + + try + { + if ( xCC.is() ) + return (xCC->getCharacterType( rStr, nPos, getLocale() ) & + nCharClassLetterType) != 0; + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isLetter: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isLetter( const String& rStr ) const +{ + try + { + if ( xCC.is() ) + return isLetterType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) ); + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isLetter: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isDigit( const String& rStr, xub_StrLen nPos ) const +{ + sal_Unicode c = rStr.GetChar( nPos ); + if ( c < 128 ) + return isAsciiDigit( c ); + + try + { + if ( xCC.is() ) + return (xCC->getCharacterType( rStr, nPos, getLocale() ) & + KCharacterType::DIGIT) != 0; + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isDigit: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isNumeric( const String& rStr ) const +{ + try + { + if ( xCC.is() ) + return isNumericType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) ); + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isNumeric: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isAlphaNumeric( const String& rStr, xub_StrLen nPos ) const +{ + sal_Unicode c = rStr.GetChar( nPos ); + if ( c < 128 ) + return isAsciiAlphaNumeric( c ); + + try + { + if ( xCC.is() ) + return (xCC->getCharacterType( rStr, nPos, getLocale() ) & + (nCharClassAlphaType | KCharacterType::DIGIT)) != 0; + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isAlphaNumeric: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isAlphaNumeric( const String& rStr ) const +{ + try + { + if ( xCC.is() ) + return isAlphaNumericType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) ); + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isAlphaNumeric: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isLetterNumeric( const String& rStr, xub_StrLen nPos ) const +{ + sal_Unicode c = rStr.GetChar( nPos ); + if ( c < 128 ) + return isAsciiAlphaNumeric( c ); + + try + { + if ( xCC.is() ) + return (xCC->getCharacterType( rStr, nPos, getLocale() ) & + (nCharClassLetterType | KCharacterType::DIGIT)) != 0; + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isLetterNumeric: Exception caught!" ); + return sal_False; + } +} + + +sal_Bool CharClass::isLetterNumeric( const String& rStr ) const +{ + try + { + if ( xCC.is() ) + return isLetterNumericType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) ); + else + return sal_False; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "isLetterNumeric: Exception caught!" ); + return sal_False; + } +} + + +String CharClass::toUpper( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const +{ + return toUpper_rtl(rStr, nPos, nCount); +} + + +String CharClass::toLower( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const +{ + return toLower_rtl(::rtl::OUString(rStr), nPos, nCount); +} + + +String CharClass::toTitle( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const +{ + try + { + if ( xCC.is() ) + return xCC->toTitle( rStr, nPos, nCount, getLocale() ); + else + return rStr.Copy( nPos, nCount ); + } + catch ( Exception& ) + { + DBG_ERRORFILE( "toTitle: Exception caught!" ); + return rStr.Copy( nPos, nCount ); + } +} + + +::rtl::OUString CharClass::toUpper_rtl( const ::rtl::OUString& rStr, sal_Int32 nPos, sal_Int32 nCount ) const +{ + try + { + if ( xCC.is() ) + return xCC->toUpper( rStr, nPos, nCount, getLocale() ); + else + return rStr.copy( nPos, nCount ); + } + catch ( Exception& ) + { + DBG_ERRORFILE( "toUpper: Exception caught!" ); + return rStr.copy( nPos, nCount ); + } +} + + +::rtl::OUString CharClass::toLower_rtl( const ::rtl::OUString& rStr, sal_Int32 nPos, sal_Int32 nCount ) const +{ + try + { + if ( xCC.is() ) + return xCC->toLower( rStr, nPos, nCount, getLocale() ); + else + return rStr.copy( nPos, nCount ); + } + catch ( Exception& ) + { + DBG_ERRORFILE( "toLower: Exception caught!" ); + return rStr.copy( nPos, nCount ); + } +} + + +sal_Int16 CharClass::getType( const String& rStr, xub_StrLen nPos ) const +{ + try + { + if ( xCC.is() ) + return xCC->getType( rStr, nPos ); + else + return 0; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "getType: Exception caught!" ); + return 0; + } +} + + +sal_Int16 CharClass::getCharacterDirection( const String& rStr, xub_StrLen nPos ) const +{ + try + { + if ( xCC.is() ) + return xCC->getCharacterDirection( rStr, nPos ); + else + return 0; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "getCharacterDirection: Exception caught!" ); + return 0; + } +} + + +sal_Int16 CharClass::getScript( const String& rStr, xub_StrLen nPos ) const +{ + try + { + if ( xCC.is() ) + return xCC->getScript( rStr, nPos ); + else + return 0; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "getScript: Exception caught!" ); + return 0; + } +} + + +sal_Int32 CharClass::getCharacterType( const String& rStr, xub_StrLen nPos ) const +{ + try + { + if ( xCC.is() ) + return xCC->getCharacterType( rStr, nPos, getLocale() ); + else + return 0; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "getCharacterType: Exception caught!" ); + return 0; + } +} + + +sal_Int32 CharClass::getStringType( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const +{ + try + { + if ( xCC.is() ) + return xCC->getStringType( rStr, nPos, nCount, getLocale() ); + else + return 0; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "getStringType: Exception caught!" ); + return 0; + } +} + + +::com::sun::star::i18n::ParseResult CharClass::parseAnyToken( + const String& rStr, + sal_Int32 nPos, + sal_Int32 nStartCharFlags, + const String& userDefinedCharactersStart, + sal_Int32 nContCharFlags, + const String& userDefinedCharactersCont ) const +{ + try + { + if ( xCC.is() ) + return xCC->parseAnyToken( rStr, nPos, getLocale(), + nStartCharFlags, userDefinedCharactersStart, + nContCharFlags, userDefinedCharactersCont ); + else + return ParseResult(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "parseAnyToken: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + return ParseResult(); + } +} + + +::com::sun::star::i18n::ParseResult CharClass::parsePredefinedToken( + sal_Int32 nTokenType, + const String& rStr, + sal_Int32 nPos, + sal_Int32 nStartCharFlags, + const String& userDefinedCharactersStart, + sal_Int32 nContCharFlags, + const String& userDefinedCharactersCont ) const +{ + try + { + if ( xCC.is() ) + return xCC->parsePredefinedToken( nTokenType, rStr, nPos, getLocale(), + nStartCharFlags, userDefinedCharactersStart, + nContCharFlags, userDefinedCharactersCont ); + else + return ParseResult(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "parsePredefinedToken: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + return ParseResult(); + } +} + + + diff --git a/unotools/source/i18n/collatorwrapper.cxx b/unotools/source/i18n/collatorwrapper.cxx new file mode 100644 index 000000000000..f4d679607424 --- /dev/null +++ b/unotools/source/i18n/collatorwrapper.cxx @@ -0,0 +1,214 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/collatorwrapper.hxx> +#include <tools/debug.hxx> + +#ifndef _COMPHELPER_COMPONENTFACTORY_HXX_ +#include <comphelper/componentfactory.hxx> +#endif +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +using namespace ::com::sun::star; + +CollatorWrapper::CollatorWrapper ( + const uno::Reference< lang::XMultiServiceFactory > &xServiceFactory) + : mxServiceFactory (xServiceFactory) +{ + ::rtl::OUString aService (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.Collator")); + + if (mxServiceFactory.is()) + { + try + { + mxInternationalCollator = uno::Reference< i18n::XCollator > ( + mxServiceFactory->createInstance(aService), uno::UNO_QUERY); + } + catch (uno::Exception& rException) + { + (void)rException; + DBG_ERRORFILE ("CollatorWrapper: failed to create instance"); + } + } + else + { + ::rtl::OUString aLibrary (RTL_CONSTASCII_USTRINGPARAM(LLCF_LIBNAME("i18n"))); + + try + { + uno::Reference< uno::XInterface > xInstance = + ::comphelper::getComponentInstance (aLibrary, aService); + + if (xInstance.is()) + { + uno::Any xInterface = xInstance->queryInterface ( + ::getCppuType((const uno::Reference< i18n::XCollator >*)0) ); + xInterface >>= mxInternationalCollator; + } + } + catch (uno::Exception& rException) + { + (void)rException; + DBG_ERRORFILE ("CollatorWrapper: failed to get component instance!"); + } + } + + DBG_ASSERT (mxInternationalCollator.is(), "CollatorWrapper: no i18n collator"); +} + +CollatorWrapper::~CollatorWrapper() +{ +} + +sal_Int32 +CollatorWrapper::compareSubstring ( + const ::rtl::OUString& s1, sal_Int32 off1, sal_Int32 len1, + const ::rtl::OUString& s2, sal_Int32 off2, sal_Int32 len2) const +{ + try + { + if (mxInternationalCollator.is()) + return mxInternationalCollator->compareSubstring ( + s1, off1, len1, s2, off2, len2); + } + catch (uno::RuntimeException& rRuntimeException) + { + (void)rRuntimeException; + DBG_ERRORFILE ("CollatorWrapper: compareSubstring failed"); + } + + return 0; +} + +sal_Int32 +CollatorWrapper::compareString (const ::rtl::OUString& s1, const ::rtl::OUString& s2) const +{ + try + { + if (mxInternationalCollator.is()) + return mxInternationalCollator->compareString (s1, s2); + } + catch (uno::RuntimeException& rRuntimeException) + { + (void)rRuntimeException; + DBG_ERRORFILE ("CollatorWrapper: compareString failed"); + } + + return 0; +} + +uno::Sequence< ::rtl::OUString > +CollatorWrapper::listCollatorAlgorithms (const lang::Locale& rLocale) const +{ + try + { + if (mxInternationalCollator.is()) + return mxInternationalCollator->listCollatorAlgorithms (rLocale); + } + catch (uno::RuntimeException& rRuntimeException) + { + (void)rRuntimeException; + DBG_ERRORFILE ("CollatorWrapper: listCollatorAlgorithms failed"); + } + + return uno::Sequence< ::rtl::OUString > (); +} + +uno::Sequence< sal_Int32 > +CollatorWrapper::listCollatorOptions (const ::rtl::OUString& rAlgorithm) const +{ + try + { + if (mxInternationalCollator.is()) + return mxInternationalCollator->listCollatorOptions (rAlgorithm); + } + catch (uno::RuntimeException& rRuntimeException) + { + (void)rRuntimeException; + DBG_ERRORFILE ("CollatorWrapper: listCollatorOptions failed"); + } + + return uno::Sequence< sal_Int32 > (); +} + +sal_Int32 +CollatorWrapper::loadDefaultCollator (const lang::Locale& rLocale, sal_Int32 nOptions) +{ + try + { + if (mxInternationalCollator.is()) + return mxInternationalCollator->loadDefaultCollator (rLocale, nOptions); + } + catch (uno::RuntimeException& rRuntimeException) + { + (void)rRuntimeException; + DBG_ERRORFILE ("CollatorWrapper: loadDefaultCollator failed"); + } + + return 0; +} + +sal_Int32 +CollatorWrapper::loadCollatorAlgorithm (const ::rtl::OUString& rAlgorithm, + const lang::Locale& rLocale, sal_Int32 nOptions) +{ + try + { + if (mxInternationalCollator.is()) + return mxInternationalCollator->loadCollatorAlgorithm ( + rAlgorithm, rLocale, nOptions); + } + catch (uno::RuntimeException& rRuntimeException) + { + (void)rRuntimeException; + DBG_ERRORFILE ("CollatorWrapper: loadCollatorAlgorithm failed"); + } + + return 0; + +} + +void +CollatorWrapper::loadCollatorAlgorithmWithEndUserOption ( + const ::rtl::OUString& rAlgorithm, + const lang::Locale& rLocale, const uno::Sequence< sal_Int32 >& rOption) +{ + try + { + if (mxInternationalCollator.is()) + mxInternationalCollator->loadCollatorAlgorithmWithEndUserOption ( + rAlgorithm, rLocale, rOption); + } + catch (uno::RuntimeException& rRuntimeException) + { + (void)rRuntimeException; + DBG_ERRORFILE ("CollatorWrapper: loadCollatorAlgorithmWithEndUserOption failed"); + } +} diff --git a/unotools/source/i18n/intlwrapper.cxx b/unotools/source/i18n/intlwrapper.cxx new file mode 100644 index 000000000000..9f52cc60bfeb --- /dev/null +++ b/unotools/source/i18n/intlwrapper.cxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include "unotools/intlwrapper.hxx" +#include <com/sun/star/i18n/CollatorOptions.hpp> +#include <i18npool/mslangid.hxx> + +IntlWrapper::IntlWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF, + const ::com::sun::star::lang::Locale& rLocale ) + : + aLocale( rLocale ), + xSMgr( xSF ), + pCharClass( NULL ), + pLocaleData( NULL ), + pCalendar( NULL ), + pCollator( NULL ), + pCaseCollator( NULL ) +{ + eLanguage = MsLangId::convertLocaleToLanguage( aLocale ); +} + + +IntlWrapper::IntlWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF, + LanguageType eLang ) + : + xSMgr( xSF ), + pCharClass( NULL ), + pLocaleData( NULL ), + pCalendar( NULL ), + pCollator( NULL ), + pCaseCollator( NULL ), + eLanguage( eLang ) +{ + MsLangId::convertLanguageToLocale( eLanguage, aLocale ); +} + + +IntlWrapper::~IntlWrapper() +{ + delete pCharClass; + delete pLocaleData; + delete pCalendar; + delete pCollator; + delete pCaseCollator; +} + + +void IntlWrapper::ImplNewCharClass() const +{ + ((IntlWrapper*)this)->pCharClass = new CharClass( xSMgr, aLocale ); +} + + +void IntlWrapper::ImplNewLocaleData() const +{ + ((IntlWrapper*)this)->pLocaleData = new LocaleDataWrapper( xSMgr, aLocale ); +} + + +void IntlWrapper::ImplNewCalendar() const +{ + CalendarWrapper* p = new CalendarWrapper( xSMgr ); + p->loadDefaultCalendar( aLocale ); + ((IntlWrapper*)this)->pCalendar = p; +} + + +void IntlWrapper::ImplNewCollator( BOOL bCaseSensitive ) const +{ + CollatorWrapper* p = new CollatorWrapper( xSMgr ); + if ( bCaseSensitive ) + { + p->loadDefaultCollator( aLocale, 0 ); + ((IntlWrapper*)this)->pCaseCollator = p; + } + else + { + p->loadDefaultCollator( aLocale, ::com::sun::star::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE ); + ((IntlWrapper*)this)->pCollator = p; + } +} diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx new file mode 100644 index 000000000000..8bbe6f182862 --- /dev/null +++ b/unotools/source/i18n/localedatawrapper.cxx @@ -0,0 +1,2007 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <string.h> // memcpy() +#include <stdio.h> // fprintf(), stderr + +#include <unotools/localedatawrapper.hxx> +#include <unotools/numberformatcodewrapper.hxx> +#include <unotools/calendarwrapper.hxx> +#include <unotools/digitgroupingiterator.hxx> +#include <tools/string.hxx> +#include <tools/debug.hxx> +#include <i18npool/mslangid.hxx> + +#ifndef _COMPHELPER_COMPONENTFACTORY_HXX_ +#include <comphelper/componentfactory.hxx> +#endif +#include <unotools/processfactory.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/i18n/KNumberFormatUsage.hpp> +#include <com/sun/star/i18n/KNumberFormatType.hpp> +#include <com/sun/star/i18n/CalendarFieldIndex.hpp> +#include <com/sun/star/i18n/CalendarDisplayIndex.hpp> + +#ifndef _COM_SUN_STAR_I18N_NUMBERFORMATINDEX_HPP_ +#include <com/sun/star/i18n/NumberFormatIndex.hdl> +#endif +#include <rtl/instance.hxx> + +#define LOCALEDATA_LIBRARYNAME "i18npool" +#define LOCALEDATA_SERVICENAME "com.sun.star.i18n.LocaleData" + +static const int nDateFormatInvalid = -1; +static const USHORT nCurrFormatInvalid = 0xffff; +static const USHORT nCurrFormatDefault = 0; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::uno; + +namespace +{ + struct InstalledLocales + : public rtl::Static< + uno::Sequence< lang::Locale >, InstalledLocales > + {}; + + struct InstalledLanguageTypes + : public rtl::Static< + uno::Sequence< sal_uInt16 >, InstalledLanguageTypes > + {}; +} + +BYTE LocaleDataWrapper::nLocaleDataChecking = 0; + +LocaleDataWrapper::LocaleDataWrapper( + const Reference< lang::XMultiServiceFactory > & xSF, + const lang::Locale& rLocale + ) + : + xSMgr( xSF ), + bLocaleDataItemValid( FALSE ), + bReservedWordValid( FALSE ) +{ + setLocale( rLocale ); + if ( xSMgr.is() ) + { + try + { + xLD = Reference< XLocaleData2 > ( xSMgr->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ), + uno::UNO_QUERY ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "LocaleDataWrapper ctor: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + } + else + { // try to get an instance somehow + DBG_ERRORFILE( "LocaleDataWrapper: no service manager, trying own" ); + try + { + Reference< XInterface > xI = ::comphelper::getComponentInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( LOCALEDATA_LIBRARYNAME ) ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ); + if ( xI.is() ) + { + Any x = xI->queryInterface( ::getCppuType((const Reference< XLocaleData2 >*)0) ); + x >>= xLD; + } + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getComponentInstance: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + } +} + + +LocaleDataWrapper::~LocaleDataWrapper() +{ +} + + +void LocaleDataWrapper::setLocale( const ::com::sun::star::lang::Locale& rLocale ) +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nCriticalChange ); + aLocale = rLocale; + invalidateData(); +} + + +const ::com::sun::star::lang::Locale& LocaleDataWrapper::getLocale() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + return aLocale; +} + + +void LocaleDataWrapper::invalidateData() +{ + aCurrSymbol.Erase(); + aCurrBankSymbol.Erase(); + nDateFormat = nLongDateFormat = nDateFormatInvalid; + nCurrPositiveFormat = nCurrNegativeFormat = nCurrDigits = nCurrFormatInvalid; + if ( bLocaleDataItemValid ) + { + for ( sal_Int32 j=0; j<LocaleItem::COUNT; j++ ) + { + aLocaleItem[j].Erase(); + } + bLocaleDataItemValid = FALSE; + } + if ( bReservedWordValid ) + { + for ( sal_Int16 j=0; j<reservedWords::COUNT; j++ ) + { + aReservedWord[j].Erase(); + } + bReservedWordValid = FALSE; + } + xDefaultCalendar.reset(); + if (aGrouping.getLength()) + aGrouping[0] = 0; + // dummies + cCurrZeroChar = '0'; +} + + +::com::sun::star::i18n::LanguageCountryInfo LocaleDataWrapper::getLanguageCountryInfo() const +{ + try + { + if ( xLD.is() ) + return xLD->getLanguageCountryInfo( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getLanguageCountryInfo: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::i18n::LanguageCountryInfo(); +} + + +::com::sun::star::i18n::LocaleDataItem LocaleDataWrapper::getLocaleItem() const +{ + try + { + if ( xLD.is() ) + return xLD->getLocaleItem( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getLocaleItem: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::i18n::LocaleDataItem(); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Calendar > LocaleDataWrapper::getAllCalendars() const +{ + try + { + if ( xLD.is() ) + return xLD->getAllCalendars( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getAllCalendars: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Calendar >(0); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Currency2 > LocaleDataWrapper::getAllCurrencies() const +{ + try + { + if ( xLD.is() ) + return xLD->getAllCurrencies2( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getAllCurrencies: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Currency2 >(0); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::FormatElement > LocaleDataWrapper::getAllFormats() const +{ + try + { + if ( xLD.is() ) + return xLD->getAllFormats( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getAllFormats: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::FormatElement >(0); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Implementation > LocaleDataWrapper::getCollatorImplementations() const +{ + try + { + if ( xLD.is() ) + return xLD->getCollatorImplementations( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getCollatorImplementations: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Implementation >(0); +} + + +::com::sun::star::uno::Sequence< ::rtl::OUString > LocaleDataWrapper::getTransliterations() const +{ + try + { + if ( xLD.is() ) + return xLD->getTransliterations( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getTransliterations: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::rtl::OUString >(0); +} + + +::com::sun::star::i18n::ForbiddenCharacters LocaleDataWrapper::getForbiddenCharacters() const +{ + try + { + if ( xLD.is() ) + return xLD->getForbiddenCharacters( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getForbiddenCharacters: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::i18n::ForbiddenCharacters(); +} + + +::com::sun::star::uno::Sequence< ::rtl::OUString > LocaleDataWrapper::getReservedWord() const +{ + try + { + if ( xLD.is() ) + return xLD->getReservedWord( getLocale() ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getReservedWord: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::rtl::OUString >(0); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > LocaleDataWrapper::getAllInstalledLocaleNames() const +{ + uno::Sequence< lang::Locale > &rInstalledLocales = InstalledLocales::get(); + + if ( rInstalledLocales.getLength() ) + return rInstalledLocales; + + try + { + if ( xLD.is() ) + rInstalledLocales = xLD->getAllInstalledLocaleNames(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getAllInstalledLocaleNames: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return rInstalledLocales; +} + + +// --- Impl and helpers ---------------------------------------------------- + +// static +::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > LocaleDataWrapper::getInstalledLocaleNames() +{ + const uno::Sequence< lang::Locale > &rInstalledLocales = + InstalledLocales::get(); + + if ( !rInstalledLocales.getLength() ) + { + LocaleDataWrapper aLDW( ::comphelper::getProcessServiceFactory(), lang::Locale() ); + aLDW.getAllInstalledLocaleNames(); + } + return rInstalledLocales; +} + +// static +::com::sun::star::uno::Sequence< sal_uInt16 > LocaleDataWrapper::getInstalledLanguageTypes() +{ + uno::Sequence< sal_uInt16 > &rInstalledLanguageTypes = + InstalledLanguageTypes::get(); + + if ( rInstalledLanguageTypes.getLength() ) + return rInstalledLanguageTypes; + + ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > xLoc = + getInstalledLocaleNames(); + sal_Int32 nCount = xLoc.getLength(); + ::com::sun::star::uno::Sequence< sal_uInt16 > xLang( nCount ); + sal_Int32 nLanguages = 0; + for ( sal_Int32 i=0; i<nCount; i++ ) + { + String aDebugLocale; + if (areChecksEnabled()) + { + aDebugLocale = xLoc[i].Language; + if ( xLoc[i].Country.getLength() ) + { + aDebugLocale += '_'; + aDebugLocale += String( xLoc[i].Country); + if ( xLoc[i].Variant.getLength() ) + { + aDebugLocale += '_'; + aDebugLocale += String( xLoc[i].Variant); + } + } + } + + if ( xLoc[i].Variant.getLength() ) + { + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getInstalledLanguageTypes: Variants not supported, locale\n")); + aMsg += aDebugLocale; + outputCheckMessage( aMsg ); + } + continue; + } + LanguageType eLang = MsLangId::convertLocaleToLanguage( xLoc[i] ); + + // In checks, exclude known problems because no MS-LCID defined. + if (areChecksEnabled() && eLang == LANGUAGE_DONTKNOW +// && !aDebugLocale.EqualsAscii( "br_AE" ) // ?!? Breton in United Arabic Emirates + ) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "ConvertIsoNamesToLanguage: unknown MS-LCID for locale\n")); + aMsg += aDebugLocale; + outputCheckMessage( aMsg ); + } + + switch ( eLang ) + { + case LANGUAGE_NORWEGIAN : // no_NO, not Bokmal (nb_NO), not Nynorsk (nn_NO) + eLang = LANGUAGE_DONTKNOW; // don't offer "Unknown" language + break; + } + if ( eLang != LANGUAGE_DONTKNOW ) + { + rtl::OUString aLanguage, aCountry; + MsLangId::convertLanguageToIsoNames( eLang, aLanguage, aCountry ); + if ( xLoc[i].Language != aLanguage || + xLoc[i].Country != aCountry ) + { + // In checks, exclude known problems because no MS-LCID defined + // and default for Language found. + if ( areChecksEnabled() + && !aDebugLocale.EqualsAscii( "ar_SD" ) // Sudan/ar + && !aDebugLocale.EqualsAscii( "en_CB" ) // Carribean is not a country +// && !aDebugLocale.EqualsAscii( "en_BG" ) // ?!? Bulgaria/en +// && !aDebugLocale.EqualsAscii( "es_BR" ) // ?!? Brazil/es + ) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "ConvertIsoNamesToLanguage/ConvertLanguageToIsoNames: ambiguous locale (MS-LCID?)\n")); + aMsg += aDebugLocale; + aMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " -> 0x" ) ); + aMsg += String::CreateFromInt32( eLang, 16 ); + aMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " -> " ) ); + aMsg += String( aLanguage); + if ( aCountry.getLength() ) + { + aMsg += '_'; + aMsg += String( aCountry); + } + outputCheckMessage( aMsg ); + } + eLang = LANGUAGE_DONTKNOW; + } + } + if ( eLang != LANGUAGE_DONTKNOW ) + xLang[ nLanguages++ ] = eLang; + } + if ( nLanguages < nCount ) + xLang.realloc( nLanguages ); + rInstalledLanguageTypes = xLang; + + return rInstalledLanguageTypes; +} + +const String& LocaleDataWrapper::getOneLocaleItem( sal_Int16 nItem ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( nItem >= LocaleItem::COUNT ) + { + DBG_ERRORFILE( "getOneLocaleItem: bounds" ); + return aLocaleItem[0]; + } + if ( aLocaleItem[nItem].Len() == 0 ) + { // no cached content + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getOneLocaleItemImpl( nItem ); + } + return aLocaleItem[nItem]; +} + + +void LocaleDataWrapper::getOneLocaleItemImpl( sal_Int16 nItem ) +{ + if ( !bLocaleDataItemValid ) + { + aLocaleDataItem = getLocaleItem(); + bLocaleDataItemValid = TRUE; + } + switch ( nItem ) + { + case LocaleItem::DATE_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.dateSeparator; + break; + case LocaleItem::THOUSAND_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.thousandSeparator; + break; + case LocaleItem::DECIMAL_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.decimalSeparator; + break; + case LocaleItem::TIME_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.timeSeparator; + break; + case LocaleItem::TIME_100SEC_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.time100SecSeparator; + break; + case LocaleItem::LIST_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.listSeparator; + break; + case LocaleItem::SINGLE_QUOTATION_START : + aLocaleItem[nItem] = aLocaleDataItem.quotationStart; + break; + case LocaleItem::SINGLE_QUOTATION_END : + aLocaleItem[nItem] = aLocaleDataItem.quotationEnd; + break; + case LocaleItem::DOUBLE_QUOTATION_START : + aLocaleItem[nItem] = aLocaleDataItem.doubleQuotationStart; + break; + case LocaleItem::DOUBLE_QUOTATION_END : + aLocaleItem[nItem] = aLocaleDataItem.doubleQuotationEnd; + break; + case LocaleItem::MEASUREMENT_SYSTEM : + aLocaleItem[nItem] = aLocaleDataItem.measurementSystem; + break; + case LocaleItem::TIME_AM : + aLocaleItem[nItem] = aLocaleDataItem.timeAM; + break; + case LocaleItem::TIME_PM : + aLocaleItem[nItem] = aLocaleDataItem.timePM; + break; + case LocaleItem::LONG_DATE_DAY_OF_WEEK_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.LongDateDayOfWeekSeparator; + break; + case LocaleItem::LONG_DATE_DAY_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.LongDateDaySeparator; + break; + case LocaleItem::LONG_DATE_MONTH_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.LongDateMonthSeparator; + break; + case LocaleItem::LONG_DATE_YEAR_SEPARATOR : + aLocaleItem[nItem] = aLocaleDataItem.LongDateYearSeparator; + break; + default: + DBG_ERRORFILE( "getOneLocaleItemImpl: which one?" ); + } +} + + +void LocaleDataWrapper::getOneReservedWordImpl( sal_Int16 nWord ) +{ + if ( !bReservedWordValid ) + { + aReservedWordSeq = getReservedWord(); + bReservedWordValid = TRUE; + } + DBG_ASSERT( nWord < aReservedWordSeq.getLength(), "getOneReservedWordImpl: which one?" ); + if ( nWord < aReservedWordSeq.getLength() ) + aReservedWord[nWord] = aReservedWordSeq[nWord]; +} + + +const String& LocaleDataWrapper::getOneReservedWord( sal_Int16 nWord ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( nWord < 0 || nWord >= reservedWords::COUNT ) + { + DBG_ERRORFILE( "getOneReservedWord: bounds" ); + nWord = reservedWords::FALSE_WORD; + } + if ( aReservedWord[nWord].Len() == 0 ) + { // no cached content + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getOneReservedWordImpl( nWord ); + } + return aReservedWord[nWord]; +} + + +MeasurementSystem LocaleDataWrapper::mapMeasurementStringToEnum( const String& rMS ) const +{ +//! TODO: could be cached too + if ( rMS.EqualsIgnoreCaseAscii( "metric" ) ) + return MEASURE_METRIC; +//! TODO: other measurement systems? => extend enum MeasurementSystem + return MEASURE_US; +} + + +void LocaleDataWrapper::getDefaultCalendarImpl() +{ + if (!xDefaultCalendar) + { + Sequence< Calendar > xCals = getAllCalendars(); + sal_Int32 nCount = xCals.getLength(); + sal_Int32 nDef = 0; + if (nCount > 1) + { + const Calendar* pArr = xCals.getArray(); + for (sal_Int32 i=0; i<nCount; ++i) + { + if (pArr[i].Default) + { + nDef = i; + break; + } + } + } + xDefaultCalendar.reset( new Calendar( xCals[nDef])); + } +} + + +const ::boost::shared_ptr< ::com::sun::star::i18n::Calendar > LocaleDataWrapper::getDefaultCalendar() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if (!xDefaultCalendar) + { // no cached content + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getDefaultCalendarImpl(); + } + return xDefaultCalendar; +} + + +const ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > LocaleDataWrapper::getDefaultCalendarDays() const +{ + return getDefaultCalendar()->Days; +} + + +const ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > LocaleDataWrapper::getDefaultCalendarMonths() const +{ + return getDefaultCalendar()->Months; +} + + +// --- currencies ----------------------------------------------------- + +const String& LocaleDataWrapper::getCurrSymbol() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( !aCurrSymbol.Len() ) + { + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getCurrSymbolsImpl(); + } + return aCurrSymbol; +} + + +const String& LocaleDataWrapper::getCurrBankSymbol() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( !aCurrBankSymbol.Len() ) + { + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getCurrSymbolsImpl(); + } + return aCurrBankSymbol; +} + + +USHORT LocaleDataWrapper::getCurrPositiveFormat() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( nCurrPositiveFormat == nCurrFormatInvalid ) + { + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getCurrFormatsImpl(); + } + return nCurrPositiveFormat; +} + + +USHORT LocaleDataWrapper::getCurrNegativeFormat() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( nCurrNegativeFormat == nCurrFormatInvalid ) + { + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getCurrFormatsImpl(); + } + return nCurrNegativeFormat; +} + + +USHORT LocaleDataWrapper::getCurrDigits() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( nCurrDigits == nCurrFormatInvalid ) + { + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getCurrSymbolsImpl(); + } + return nCurrDigits; +} + + +void LocaleDataWrapper::getCurrSymbolsImpl() +{ + Sequence< Currency2 > aCurrSeq = getAllCurrencies(); + sal_Int32 nCnt = aCurrSeq.getLength(); + Currency2 const * const pCurrArr = aCurrSeq.getArray(); + sal_Int32 nElem; + for ( nElem = 0; nElem < nCnt; nElem++ ) + { + if ( pCurrArr[nElem].Default ) + break; + } + if ( nElem >= nCnt ) + { + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getCurrSymbolsImpl: no default currency")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + nElem = 0; + if ( nElem >= nCnt ) + { + if (areChecksEnabled()) + outputCheckMessage( String( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getCurrSymbolsImpl: no currency at all, using ShellsAndPebbles"))); + aCurrSymbol.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "ShellsAndPebbles" ) ); + aCurrBankSymbol = aCurrSymbol; + nCurrPositiveFormat = nCurrNegativeFormat = nCurrFormatDefault; + nCurrDigits = 2; + return ; + } + } + aCurrSymbol = pCurrArr[nElem].Symbol; + aCurrBankSymbol = pCurrArr[nElem].BankSymbol; + nCurrDigits = pCurrArr[nElem].DecimalPlaces; +} + + +void LocaleDataWrapper::scanCurrFormatImpl( const String& rCode, + xub_StrLen nStart, xub_StrLen& nSign, xub_StrLen& nPar, + xub_StrLen& nNum, xub_StrLen& nBlank, xub_StrLen& nSym ) +{ + nSign = nPar = nNum = nBlank = nSym = STRING_NOTFOUND; + const sal_Unicode* const pStr = rCode.GetBuffer(); + const sal_Unicode* const pStop = pStr + rCode.Len(); + const sal_Unicode* p = pStr + nStart; + int nInSection = 0; + BOOL bQuote = FALSE; + while ( p < pStop ) + { + if ( bQuote ) + { + if ( *p == '"' && *(p-1) != '\\' ) + bQuote = FALSE; + } + else + { + switch ( *p ) + { + case '"' : + if ( pStr == p || *(p-1) != '\\' ) + bQuote = TRUE; + break; + case '-' : + if ( !nInSection && nSign == STRING_NOTFOUND ) + nSign = (xub_StrLen)(p - pStr); + break; + case '(' : + if ( !nInSection && nPar == STRING_NOTFOUND ) + nPar = (xub_StrLen)(p - pStr); + break; + case '0' : + case '#' : + if ( !nInSection && nNum == STRING_NOTFOUND ) + nNum = (xub_StrLen)(p - pStr); + break; + case '[' : + nInSection++; + break; + case ']' : + if ( nInSection ) + { + nInSection--; + if ( !nInSection && nBlank == STRING_NOTFOUND + && nSym != STRING_NOTFOUND && p < pStop-1 && *(p+1) == ' ' ) + nBlank = (xub_StrLen)(p - pStr + 1); + } + break; + case '$' : + if ( nSym == STRING_NOTFOUND && nInSection && *(p-1) == '[' ) + { + nSym = (xub_StrLen)(p - pStr + 1); + if ( nNum != STRING_NOTFOUND && *(p-2) == ' ' ) + nBlank = (xub_StrLen)(p - pStr - 2); + } + break; + case ';' : + if ( !nInSection ) + p = pStop; + break; + default: + if ( !nInSection && nSym == STRING_NOTFOUND && rCode.Equals( aCurrSymbol, (xub_StrLen)(p-pStr), aCurrSymbol.Len() ) ) + { // currency symbol not surrounded by [$...] + nSym = (xub_StrLen)(p - pStr); + if ( nBlank == STRING_NOTFOUND && pStr < p && *(p-1) == ' ' ) + nBlank = (xub_StrLen)(p - pStr - 1); + p += aCurrSymbol.Len() - 1; + if ( nBlank == STRING_NOTFOUND && p < pStop-2 && *(p+2) == ' ' ) + nBlank = (xub_StrLen)(p - pStr + 2); + } + } + } + p++; + } +} + + +void LocaleDataWrapper::getCurrFormatsImpl() +{ + NumberFormatCodeWrapper aNumberFormatCode( xSMgr, getLocale() ); + uno::Sequence< NumberFormatCode > aFormatSeq + = aNumberFormatCode.getAllFormatCode( KNumberFormatUsage::CURRENCY ); + sal_Int32 nCnt = aFormatSeq.getLength(); + if ( !nCnt ) + { // bad luck + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getCurrFormatsImpl: no currency formats")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + nCurrPositiveFormat = nCurrNegativeFormat = nCurrFormatDefault; + return ; + } + // find a negative code (medium preferred) and a default (medium preferred) (not necessarily the same) + NumberFormatCode const * const pFormatArr = aFormatSeq.getArray(); + sal_Int32 nElem, nDef, nNeg, nMedium; + nDef = nNeg = nMedium = -1; + for ( nElem = 0; nElem < nCnt; nElem++ ) + { + if ( pFormatArr[nElem].Type == KNumberFormatType::MEDIUM ) + { + if ( pFormatArr[nElem].Default ) + { + nDef = nElem; + nMedium = nElem; + if ( pFormatArr[nElem].Code.indexOf( ';' ) >= 0 ) + nNeg = nElem; + } + else + { + if ( (nNeg == -1 || nMedium == -1) && pFormatArr[nElem].Code.indexOf( ';' ) >= 0 ) + nNeg = nElem; + if ( nMedium == -1 ) + nMedium = nElem; + } + } + else + { + if ( nDef == -1 && pFormatArr[nElem].Default ) + nDef = nElem; + if ( nNeg == -1 && pFormatArr[nElem].Code.indexOf( ';' ) >= 0 ) + nNeg = nElem; + } + } + + // make sure it's loaded + getCurrSymbol(); + + xub_StrLen nSign, nPar, nNum, nBlank, nSym; + + // positive format + nElem = (nDef >= 0 ? nDef : (nNeg >= 0 ? nNeg : 0)); + scanCurrFormatImpl( pFormatArr[nElem].Code, 0, nSign, nPar, nNum, nBlank, nSym ); + if (areChecksEnabled() && (nNum == STRING_NOTFOUND || nSym == STRING_NOTFOUND)) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getCurrFormatsImpl: CurrPositiveFormat?")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + if ( nBlank == STRING_NOTFOUND ) + { + if ( nSym < nNum ) + nCurrPositiveFormat = 0; // $1 + else + nCurrPositiveFormat = 1; // 1$ + } + else + { + if ( nSym < nNum ) + nCurrPositiveFormat = 2; // $ 1 + else + nCurrPositiveFormat = 3; // 1 $ + } + + // negative format + if ( nNeg < 0 ) + nCurrNegativeFormat = nCurrFormatDefault; + else + { + const ::rtl::OUString& rCode = pFormatArr[nNeg].Code; + xub_StrLen nDelim = (xub_StrLen)rCode.indexOf( ';' ); + scanCurrFormatImpl( rCode, nDelim+1, nSign, nPar, nNum, nBlank, nSym ); + if (areChecksEnabled() && (nNum == STRING_NOTFOUND || + nSym == STRING_NOTFOUND || (nPar == STRING_NOTFOUND && + nSign == STRING_NOTFOUND))) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getCurrFormatsImpl: CurrNegativeFormat?")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + if ( nBlank == STRING_NOTFOUND ) + { + if ( nSym < nNum ) + { + if ( nPar < nSym ) + nCurrNegativeFormat = 0; // ($1) + else if ( nSign < nSym ) + nCurrNegativeFormat = 1; // -$1 + else if ( nNum < nSign ) + nCurrNegativeFormat = 3; // $1- + else + nCurrNegativeFormat = 2; // $-1 + } + else + { + if ( nPar < nNum ) + nCurrNegativeFormat = 4; // (1$) + else if ( nSign < nNum ) + nCurrNegativeFormat = 5; // -1$ + else if ( nSym < nSign ) + nCurrNegativeFormat = 7; // 1$- + else + nCurrNegativeFormat = 6; // 1-$ + } + } + else + { + if ( nSym < nNum ) + { + if ( nPar < nSym ) + nCurrNegativeFormat = 14; // ($ 1) + else if ( nSign < nSym ) + nCurrNegativeFormat = 9; // -$ 1 + else if ( nNum < nSign ) + nCurrNegativeFormat = 12; // $ 1- + else + nCurrNegativeFormat = 11; // $ -1 + } + else + { + if ( nPar < nNum ) + nCurrNegativeFormat = 15; // (1 $) + else if ( nSign < nNum ) + nCurrNegativeFormat = 8; // -1 $ + else if ( nSym < nSign ) + nCurrNegativeFormat = 10; // 1 $- + else + nCurrNegativeFormat = 13; // 1- $ + } + } + } +} + + +// --- date ----------------------------------------------------------- + +DateFormat LocaleDataWrapper::getDateFormat() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( nDateFormat == nDateFormatInvalid ) + { + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getDateFormatsImpl(); + } + return (DateFormat) nDateFormat; +} + + +DateFormat LocaleDataWrapper::getLongDateFormat() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if ( nLongDateFormat == nDateFormatInvalid ) + { + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getDateFormatsImpl(); + } + return (DateFormat) nLongDateFormat; +} + + +DateFormat LocaleDataWrapper::scanDateFormatImpl( const String& rCode ) +{ + // Only some european versions were translated, the ones with different + // keyword combinations are: + // English DMY, German TMJ, Spanish DMA, French JMA, Italian GMA, + // Dutch DMJ, Finnish PKV + + // default is English keywords for every other language + xub_StrLen nDay = rCode.Search( 'D' ); + xub_StrLen nMonth = rCode.Search( 'M' ); + xub_StrLen nYear = rCode.Search( 'Y' ); + if ( nDay == STRING_NOTFOUND || nMonth == STRING_NOTFOUND || nYear == STRING_NOTFOUND ) + { // This algorithm assumes that all three parts (DMY) are present + if ( nMonth == STRING_NOTFOUND ) + { // only Finnish has something else than 'M' for month + nMonth = rCode.Search( 'K' ); + if ( nMonth != STRING_NOTFOUND ) + { + nDay = rCode.Search( 'P' ); + nYear = rCode.Search( 'V' ); + } + } + else if ( nDay == STRING_NOTFOUND ) + { // We have a month 'M' if we reach this branch. + // Possible languages containing 'M' but no 'D': + // German, French, Italian + nDay = rCode.Search( 'T' ); // German + if ( nDay != STRING_NOTFOUND ) + nYear = rCode.Search( 'J' ); + else + { + nYear = rCode.Search( 'A' ); // French, Italian + if ( nYear != STRING_NOTFOUND ) + { + nDay = rCode.Search( 'J' ); // French + if ( nDay == STRING_NOTFOUND ) + nDay = rCode.Search( 'G' ); // Italian + } + } + } + else + { // We have a month 'M' and a day 'D'. + // Possible languages containing 'D' and 'M' but not 'Y': + // Spanish, Dutch + nYear = rCode.Search( 'A' ); // Spanish + if ( nYear == STRING_NOTFOUND ) + nYear = rCode.Search( 'J' ); // Dutch + } + if ( nDay == STRING_NOTFOUND || nMonth == STRING_NOTFOUND || nYear == STRING_NOTFOUND ) + { + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::scanDateFormat: not all DMY present")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + if ( nDay == STRING_NOTFOUND ) + nDay = rCode.Len(); + if ( nMonth == STRING_NOTFOUND ) + nMonth = rCode.Len(); + if ( nYear == STRING_NOTFOUND ) + nYear = rCode.Len(); + } + } + // compare with <= because each position may equal rCode.Len() + if ( nDay <= nMonth && nMonth <= nYear ) + return DMY; // also if every position equals rCode.Len() + else if ( nMonth <= nDay && nDay <= nYear ) + return MDY; + else if ( nYear <= nMonth && nMonth <= nDay ) + return YMD; + else + { + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::scanDateFormat: no magic applyable")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + return DMY; + } +} + + +void LocaleDataWrapper::getDateFormatsImpl() +{ + NumberFormatCodeWrapper aNumberFormatCode( xSMgr, getLocale() ); + uno::Sequence< NumberFormatCode > aFormatSeq + = aNumberFormatCode.getAllFormatCode( KNumberFormatUsage::DATE ); + sal_Int32 nCnt = aFormatSeq.getLength(); + if ( !nCnt ) + { // bad luck + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getDateFormatsImpl: no date formats")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + nDateFormat = nLongDateFormat = DMY; + return ; + } + // find the edit (21), a default (medium preferred), + // a medium (default preferred), and a long (default preferred) + NumberFormatCode const * const pFormatArr = aFormatSeq.getArray(); + sal_Int32 nElem, nEdit, nDef, nMedium, nLong; + nEdit = nDef = nMedium = nLong = -1; + for ( nElem = 0; nElem < nCnt; nElem++ ) + { + if ( nEdit == -1 && pFormatArr[nElem].Index == NumberFormatIndex::DATE_SYS_DDMMYYYY ) + nEdit = nElem; + if ( nDef == -1 && pFormatArr[nElem].Default ) + nDef = nElem; + switch ( pFormatArr[nElem].Type ) + { + case KNumberFormatType::MEDIUM : + { + if ( pFormatArr[nElem].Default ) + { + nDef = nElem; + nMedium = nElem; + } + else if ( nMedium == -1 ) + nMedium = nElem; + } + break; + case KNumberFormatType::LONG : + { + if ( pFormatArr[nElem].Default ) + nLong = nElem; + else if ( nLong == -1 ) + nLong = nElem; + } + break; + } + } + if ( nEdit == -1 ) + { + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getDateFormatsImpl: no edit")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + if ( nDef == -1 ) + { + if (areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "LocaleDataWrapper::getDateFormatsImpl: no default")); + outputCheckMessage( appendLocaleInfo( aMsg ) ); + } + if ( nMedium != -1 ) + nDef = nMedium; + else if ( nLong != -1 ) + nDef = nLong; + else + nDef = 0; + } + nEdit = nDef; + } + DateFormat nDF = scanDateFormatImpl( pFormatArr[nEdit].Code ); + if ( pFormatArr[nEdit].Type == KNumberFormatType::LONG ) + { // normally this is not the case + nLongDateFormat = nDateFormat = nDF; + } + else + { + nDateFormat = nDF; + if ( nLong == -1 ) + nLongDateFormat = nDF; + else + nLongDateFormat = scanDateFormatImpl( pFormatArr[nLong].Code ); + } +} + + +// --- digit grouping ------------------------------------------------- + +void LocaleDataWrapper::getDigitGroupingImpl() +{ + /* TODO: This is a very simplified grouping setup that only serves its + * current purpose for Indian locales. A free-form flexible one would + * obtain grouping from locale data where it could be specified using, for + * example, codes like #,### and #,##,### that would generate the integer + * sequence. Needed additional API and a locale data element. + */ + + if (!aGrouping.getLength()) + { + aGrouping.realloc(3); // room for {3,2,0} + aGrouping[0] = 0; // invalidate + } + if (!aGrouping[0]) + { + i18n::LanguageCountryInfo aLCInfo( getLanguageCountryInfo()); + if (aLCInfo.Country.equalsIgnoreAsciiCaseAscii( "IN") || // India + aLCInfo.Country.equalsIgnoreAsciiCaseAscii( "BT")) // Bhutan + { + aGrouping[0] = 3; + aGrouping[1] = 2; + aGrouping[2] = 0; + } + else + { + aGrouping[0] = 3; + aGrouping[1] = 0; + } + } +} + + +const ::com::sun::star::uno::Sequence< sal_Int32 > LocaleDataWrapper::getDigitGrouping() const +{ + ::utl::ReadWriteGuard aGuard( aMutex ); + if (!aGrouping.getLength() || aGrouping[0] == 0) + { // no cached content + aGuard.changeReadToWrite(); + ((LocaleDataWrapper*)this)->getDigitGroupingImpl(); + } + return aGrouping; +} + + +// --- simple number formatting helpers ------------------------------- + +// The ImplAdd... methods are taken from class International and modified to +// suit the needs. + +static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber ) +{ + // fill temp buffer with digits + sal_Unicode aTempBuf[64]; + sal_Unicode* pTempBuf = aTempBuf; + do + { + *pTempBuf = (sal_Unicode)(nNumber % 10) + '0'; + pTempBuf++; + nNumber /= 10; + } + while ( nNumber ); + + // copy temp buffer to buffer passed + do + { + pTempBuf--; + *pBuf = *pTempBuf; + pBuf++; + } + while ( pTempBuf != aTempBuf ); + + return pBuf; +} + + +static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber, int nMinLen ) +{ + // fill temp buffer with digits + sal_Unicode aTempBuf[64]; + sal_Unicode* pTempBuf = aTempBuf; + do + { + *pTempBuf = (sal_Unicode)(nNumber % 10) + '0'; + pTempBuf++; + nNumber /= 10; + nMinLen--; + } + while ( nNumber ); + + // fill with zeros up to the minimal length + while ( nMinLen > 0 ) + { + *pBuf = '0'; + pBuf++; + nMinLen--; + } + + // copy temp buffer to real buffer + do + { + pTempBuf--; + *pBuf = *pTempBuf; + pBuf++; + } + while ( pTempBuf != aTempBuf ); + + return pBuf; +} + + +static sal_Unicode* ImplAdd2UNum( sal_Unicode* pBuf, USHORT nNumber, int bLeading ) +{ + DBG_ASSERT( nNumber < 100, "ImplAdd2UNum() - Number >= 100" ); + + if ( nNumber < 10 ) + { + if ( bLeading ) + { + *pBuf = '0'; + pBuf++; + } + *pBuf = nNumber + '0'; + } + else + { + USHORT nTemp = nNumber % 10; + nNumber /= 10; + *pBuf = nNumber + '0'; + pBuf++; + *pBuf = nTemp + '0'; + } + + pBuf++; + return pBuf; +} + + +inline sal_Unicode* ImplAddString( sal_Unicode* pBuf, const String& rStr ) +{ + if ( rStr.Len() == 1 ) + *pBuf++ = rStr.GetChar(0); + else if ( rStr.Len() == 0 ) + ; + else + { + memcpy( pBuf, rStr.GetBuffer(), rStr.Len() * sizeof(sal_Unicode) ); + pBuf += rStr.Len(); + } + return pBuf; +} + + +inline sal_Unicode* ImplAddString( sal_Unicode* pBuf, sal_Unicode c ) +{ + *pBuf = c; + pBuf++; + return pBuf; +} + + +inline sal_Unicode* ImplAddString( sal_Unicode* pBuf, const sal_Unicode* pCopyBuf, xub_StrLen nLen ) +{ + memcpy( pBuf, pCopyBuf, nLen * sizeof(sal_Unicode) ); + return pBuf + nLen; +} + + +sal_Unicode* LocaleDataWrapper::ImplAddFormatNum( sal_Unicode* pBuf, + sal_Int64 nNumber, USHORT nDecimals, BOOL bUseThousandSep, + BOOL bTrailingZeros ) const +{ + sal_Unicode aNumBuf[64]; + sal_Unicode* pNumBuf; + USHORT nNumLen; + USHORT i = 0; + BOOL bNeg; + + // negative number + if ( nNumber < 0 ) + { + nNumber *= -1; + bNeg = TRUE; + *pBuf = '-'; + pBuf++; + } + else + bNeg = FALSE; + + // convert number + pNumBuf = ImplAddUNum( aNumBuf, (sal_uInt64)nNumber ); + nNumLen = (USHORT)(ULONG)(pNumBuf-aNumBuf); + pNumBuf = aNumBuf; + + if ( nNumLen <= nDecimals ) + { + // strip .0 in decimals? + if ( !nNumber && !bTrailingZeros ) + { + *pBuf = '0'; + pBuf++; + } + else + { + // LeadingZero, insert 0 + if ( isNumLeadingZero() ) + { + *pBuf = '0'; + pBuf++; + } + + // append decimal separator + pBuf = ImplAddString( pBuf, getNumDecimalSep() ); + + // fill with zeros + while ( i < (nDecimals-nNumLen) ) + { + *pBuf = '0'; + pBuf++; + i++; + } + + // append decimals + while ( nNumLen ) + { + *pBuf = *pNumBuf; + pBuf++; + pNumBuf++; + nNumLen--; + } + } + } + else + { + const String& rThoSep = getNumThousandSep(); + + // copy number to buffer (excluding decimals) + USHORT nNumLen2 = nNumLen-nDecimals; + uno::Sequence< sal_Bool > aGroupPos; + if (bUseThousandSep) + aGroupPos = utl::DigitGroupingIterator::createForwardSequence( + nNumLen2, getDigitGrouping()); + for ( ; i < nNumLen2; ++i ) + { + *pBuf = *pNumBuf; + pBuf++; + pNumBuf++; + + // add thousand separator? + if ( bUseThousandSep && aGroupPos[i] ) + pBuf = ImplAddString( pBuf, rThoSep ); + } + + // append decimals + if ( nDecimals ) + { + pBuf = ImplAddString( pBuf, getNumDecimalSep() ); + + BOOL bNullEnd = TRUE; + while ( i < nNumLen ) + { + if ( *pNumBuf != '0' ) + bNullEnd = FALSE; + + *pBuf = *pNumBuf; + pBuf++; + pNumBuf++; + i++; + } + + // strip .0 in decimals? + if ( bNullEnd && !bTrailingZeros ) + pBuf -= nDecimals+1; + } + } + + return pBuf; +} + + +// --- simple date and time formatting -------------------------------- + +String LocaleDataWrapper::getDate( const Date& rDate ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); +//!TODO: leading zeros et al + sal_Unicode aBuf[128]; + sal_Unicode* pBuf = aBuf; + USHORT nDay = rDate.GetDay(); + USHORT nMonth = rDate.GetMonth(); + USHORT nYear = rDate.GetYear(); + USHORT nYearLen; + + if ( TRUE /* IsDateCentury() */ ) + nYearLen = 4; + else + { + nYearLen = 2; + nYear %= 100; + } + + switch ( getDateFormat() ) + { + case DMY : + pBuf = ImplAdd2UNum( pBuf, nDay, TRUE /* IsDateDayLeadingZero() */ ); + pBuf = ImplAddString( pBuf, getDateSep() ); + pBuf = ImplAdd2UNum( pBuf, nMonth, TRUE /* IsDateMonthLeadingZero() */ ); + pBuf = ImplAddString( pBuf, getDateSep() ); + pBuf = ImplAddUNum( pBuf, nYear, nYearLen ); + break; + case MDY : + pBuf = ImplAdd2UNum( pBuf, nMonth, TRUE /* IsDateMonthLeadingZero() */ ); + pBuf = ImplAddString( pBuf, getDateSep() ); + pBuf = ImplAdd2UNum( pBuf, nDay, TRUE /* IsDateDayLeadingZero() */ ); + pBuf = ImplAddString( pBuf, getDateSep() ); + pBuf = ImplAddUNum( pBuf, nYear, nYearLen ); + break; + default: + pBuf = ImplAddUNum( pBuf, nYear, nYearLen ); + pBuf = ImplAddString( pBuf, getDateSep() ); + pBuf = ImplAdd2UNum( pBuf, nMonth, TRUE /* IsDateMonthLeadingZero() */ ); + pBuf = ImplAddString( pBuf, getDateSep() ); + pBuf = ImplAdd2UNum( pBuf, nDay, TRUE /* IsDateDayLeadingZero() */ ); + } + + return String( aBuf, (xub_StrLen)(ULONG)(pBuf-aBuf) ); +} + + +String LocaleDataWrapper::getTime( const Time& rTime, BOOL bSec, BOOL b100Sec ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); +//!TODO: leading zeros et al + sal_Unicode aBuf[128]; + sal_Unicode* pBuf = aBuf; + USHORT nHour = rTime.GetHour(); + BOOL bHour12 = FALSE; //!TODO: AM/PM from default time format code + + if ( bHour12 ) + { + nHour %= 12; + // 0:00 -> 12:00 + if ( !nHour ) + nHour = 12; + } + else + nHour %= 24; + + pBuf = ImplAdd2UNum( pBuf, nHour, TRUE /* IsTimeLeadingZero() */ ); + pBuf = ImplAddString( pBuf, getTimeSep() ); + pBuf = ImplAdd2UNum( pBuf, rTime.GetMin(), TRUE ); + if ( bSec ) + { + pBuf = ImplAddString( pBuf, getTimeSep() ); + pBuf = ImplAdd2UNum( pBuf, rTime.GetSec(), TRUE ); + + if ( b100Sec ) + { + pBuf = ImplAddString( pBuf, getTime100SecSep() ); + pBuf = ImplAdd2UNum( pBuf, rTime.Get100Sec(), TRUE ); + } + } + + String aStr( aBuf, (xub_StrLen)(ULONG)(pBuf-aBuf) ); + + if ( bHour12 ) + { + if ( (rTime.GetHour() % 24) >= 12 ) + aStr += getTimePM(); + else + aStr += getTimeAM(); + } +#if 0 +//!TODO: do we need a time string? like "o'clock" or "Uhr" or similar + else + aStr += getTimeStr(); +#endif + + return aStr; +} + + +String LocaleDataWrapper::getLongDate( const Date& rDate, CalendarWrapper& rCal, + sal_Int16 nDisplayDayOfWeek, sal_Bool bDayOfMonthWithLeadingZero, + sal_Int16 nDisplayMonth, sal_Bool bTwoDigitYear ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); + using namespace ::com::sun::star::i18n; + sal_Unicode aBuf[20]; + sal_Unicode* pBuf; + String aStr; + sal_Int16 nVal; + rCal.setGregorianDateTime( rDate ); + // day of week + nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_WEEK ); + aStr += rCal.getDisplayName( CalendarDisplayIndex::DAY, nVal, nDisplayDayOfWeek ); + aStr += getLongDateDayOfWeekSep(); + // day of month + nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_MONTH ); + pBuf = ImplAdd2UNum( aBuf, nVal, bDayOfMonthWithLeadingZero ); + String aDay( aBuf, (xub_StrLen)(ULONG)(pBuf-aBuf) ); + // month of year + nVal = rCal.getValue( CalendarFieldIndex::MONTH ); + String aMonth( rCal.getDisplayName( CalendarDisplayIndex::MONTH, nVal, nDisplayMonth ) ); + // year + nVal = rCal.getValue( CalendarFieldIndex::YEAR ); + if ( bTwoDigitYear ) + pBuf = ImplAddUNum( aBuf, nVal % 100, 2 ); + else + pBuf = ImplAddUNum( aBuf, nVal ); + String aYear( aBuf, (xub_StrLen)(ULONG)(pBuf-aBuf) ); + // concatenate + switch ( getLongDateFormat() ) + { + case DMY : + aStr += aDay; + aStr += getLongDateDaySep(); + aStr += aMonth; + aStr += getLongDateMonthSep(); + aStr += aYear; + break; + case MDY : + aStr += aMonth; + aStr += getLongDateMonthSep(); + aStr += aDay; + aStr += getLongDateDaySep(); + aStr += aYear; + break; + default: // YMD + aStr += aYear; + aStr += getLongDateYearSep(); + aStr += aMonth; + aStr += getLongDateMonthSep(); + aStr += aDay; + } + return aStr; +} + + +String LocaleDataWrapper::getDuration( const Time& rTime, BOOL bSec, BOOL b100Sec ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); + sal_Unicode aBuf[128]; + sal_Unicode* pBuf = aBuf; + + if ( rTime < Time( 0 ) ) + pBuf = ImplAddString( pBuf, ' ' ); + + if ( TRUE /* IsTimeLeadingZero() */ ) + pBuf = ImplAddUNum( pBuf, rTime.GetHour(), 2 ); + else + pBuf = ImplAddUNum( pBuf, rTime.GetHour() ); + pBuf = ImplAddString( pBuf, getTimeSep() ); + pBuf = ImplAdd2UNum( pBuf, rTime.GetMin(), TRUE ); + if ( bSec ) + { + pBuf = ImplAddString( pBuf, getTimeSep() ); + pBuf = ImplAdd2UNum( pBuf, rTime.GetSec(), TRUE ); + + if ( b100Sec ) + { + pBuf = ImplAddString( pBuf, getTime100SecSep() ); + pBuf = ImplAdd2UNum( pBuf, rTime.Get100Sec(), TRUE ); + } + } + + return String( aBuf, (xub_StrLen)(ULONG)(pBuf-aBuf) ); +} + + +// --- simple number formatting --------------------------------------- + +inline size_t ImplGetNumberStringLengthGuess( const LocaleDataWrapper& rLoc, USHORT nDecimals ) +{ + // approximately 3.2 bits per digit + const size_t nDig = ((sizeof(sal_Int64) * 8) / 3) + 1; + // digits, separators (pessimized for insane "every digit may be grouped"), leading zero, sign + size_t nGuess = ((nDecimals < nDig) ? + (((nDig - nDecimals) * rLoc.getNumThousandSep().Len()) + nDig) : + nDecimals) + rLoc.getNumDecimalSep().Len() + 3; + return nGuess; +} + + +String LocaleDataWrapper::getNum( sal_Int64 nNumber, USHORT nDecimals, + BOOL bUseThousandSep, BOOL bTrailingZeros ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); + sal_Unicode aBuf[128]; // big enough for 64-bit long and crazy grouping + // check if digits and separators will fit into fixed buffer or allocate + size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals ); + sal_Unicode* const pBuffer = (nGuess < 118 ? aBuf : + new sal_Unicode[nGuess + 16]); + + sal_Unicode* pBuf = ImplAddFormatNum( pBuffer, nNumber, nDecimals, + bUseThousandSep, bTrailingZeros ); + String aStr( pBuffer, (xub_StrLen)(ULONG)(pBuf-pBuffer) ); + + if ( pBuffer != aBuf ) + delete [] pBuffer; + return aStr; +} + + +String LocaleDataWrapper::getCurr( sal_Int64 nNumber, USHORT nDecimals, + const String& rCurrencySymbol, BOOL bUseThousandSep ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); + sal_Unicode aBuf[192]; + sal_Unicode aNumBuf[128]; // big enough for 64-bit long and crazy grouping + sal_Unicode cZeroChar = getCurrZeroChar(); + + // check if digits and separators will fit into fixed buffer or allocate + size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals ); + sal_Unicode* const pNumBuffer = (nGuess < 118 ? aNumBuf : + new sal_Unicode[nGuess + 16]); + + sal_Unicode* const pBuffer = + ((size_t(rCurrencySymbol.Len()) + nGuess + 20) < sizeof(aBuf)/sizeof(aBuf[0]) ? aBuf : + new sal_Unicode[ rCurrencySymbol.Len() + nGuess + 20 ]); + sal_Unicode* pBuf = pBuffer; + + BOOL bNeg; + if ( nNumber < 0 ) + { + bNeg = TRUE; + nNumber *= -1; + } + else + bNeg = FALSE; + + // convert number + sal_Unicode* pEndNumBuf = ImplAddFormatNum( pNumBuffer, nNumber, nDecimals, + bUseThousandSep, TRUE ); + xub_StrLen nNumLen = (xub_StrLen)(ULONG)(pEndNumBuf-pNumBuffer); + + // replace zeros with zero character + if ( (cZeroChar != '0') && nDecimals /* && IsNumTrailingZeros() */ ) + { + sal_Unicode* pTempBuf; + USHORT i; + BOOL bZero = TRUE; + + pTempBuf = pNumBuffer+nNumLen-nDecimals; + i = 0; + do + { + if ( *pTempBuf != '0' ) + { + bZero = FALSE; + break; + } + + pTempBuf++; + i++; + } + while ( i < nDecimals ); + + if ( bZero ) + { + pTempBuf = pNumBuffer+nNumLen-nDecimals; + i = 0; + do + { + *pTempBuf = cZeroChar; + pTempBuf++; + i++; + } + while ( i < nDecimals ); + } + } + + if ( !bNeg ) + { + switch( getCurrPositiveFormat() ) + { + case 0: + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + break; + case 1: + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + break; + case 2: + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + break; + case 3: + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + break; + } + } + else + { + switch( getCurrNegativeFormat() ) + { + case 0: + pBuf = ImplAddString( pBuf, '(' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, ')' ); + break; + case 1: + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + break; + case 2: + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + break; + case 3: + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, '-' ); + break; + case 4: + pBuf = ImplAddString( pBuf, '(' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, ')' ); + break; + case 5: + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + break; + case 6: + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + break; + case 7: + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, '-' ); + break; + case 8: + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + break; + case 9: + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + break; + case 10: + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, '-' ); + break; + case 11: + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + break; + case 12: + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, '-' ); + break; + case 13: + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, '-' ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + break; + case 14: + pBuf = ImplAddString( pBuf, '(' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, ')' ); + break; + case 15: + pBuf = ImplAddString( pBuf, '(' ); + pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); + pBuf = ImplAddString( pBuf, ' ' ); + pBuf = ImplAddString( pBuf, rCurrencySymbol ); + pBuf = ImplAddString( pBuf, ')' ); + break; + } + } + + String aNumber( pBuffer, (xub_StrLen)(ULONG)(pBuf-pBuffer) ); + + if ( pBuffer != aBuf ) + delete [] pBuffer; + if ( pNumBuffer != aNumBuf ) + delete [] pNumBuffer; + + return aNumber; +} + + +// --- mixed ---------------------------------------------------------- + +::com::sun::star::lang::Locale LocaleDataWrapper::getLoadedLocale() const +{ + LanguageCountryInfo aLCInfo = getLanguageCountryInfo(); + return lang::Locale( aLCInfo.Language, aLCInfo.Country, aLCInfo.Variant ); +} + + +String& LocaleDataWrapper::appendLocaleInfo( String& rDebugMsg ) const +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); + rDebugMsg += '\n'; + rDebugMsg += String( aLocale.Language); + rDebugMsg += '_'; + rDebugMsg += String( aLocale.Country); + rDebugMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " requested\n" ) ); + lang::Locale aLoaded = getLoadedLocale(); + rDebugMsg += String( aLoaded.Language); + rDebugMsg += '_'; + rDebugMsg += String( aLoaded.Country); + rDebugMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " loaded" ) ); + return rDebugMsg; +} + + +// static +void LocaleDataWrapper::outputCheckMessage( const String& rMsg ) +{ + outputCheckMessage( ByteString( rMsg, RTL_TEXTENCODING_UTF8).GetBuffer()); +} + + +// static +void LocaleDataWrapper::outputCheckMessage( const char* pStr ) +{ + fprintf( stderr, "\n%s\n", pStr); + fflush( stderr); + DBG_ERROR( pStr); +} + + +// static +void LocaleDataWrapper::evaluateLocaleDataChecking() +{ + // Using the rtl_Instance template here wouldn't solve all threaded write + // accesses, since we want to assign the result to the static member + // variable and would need to dereference the pointer returned and assign + // the value unguarded. This is the same pattern manually coded. + BYTE nCheck = nLocaleDataChecking; + if (!nCheck) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex()); + nCheck = nLocaleDataChecking; + if (!nCheck) + { +#ifdef DBG_UTIL + nCheck = 1; +#else + const char* pEnv = getenv( "OOO_ENABLE_LOCALE_DATA_CHECKS"); + if (pEnv && (pEnv[0] == 'Y' || pEnv[0] == 'y' || pEnv[0] == '1')) + nCheck = 1; + else + nCheck = 2; +#endif + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + nLocaleDataChecking = nCheck; + } + } + else { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + } +} diff --git a/unotools/source/i18n/makefile.mk b/unotools/source/i18n/makefile.mk new file mode 100644 index 000000000000..bb21d65625cb --- /dev/null +++ b/unotools/source/i18n/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=i18n + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +SLOFILES= \ + $(SLO)$/charclass.obj \ + $(SLO)$/calendarwrapper.obj \ + $(SLO)$/collatorwrapper.obj \ + $(SLO)$/intlwrapper.obj \ + $(SLO)$/localedatawrapper.obj \ + $(SLO)$/nativenumberwrapper.obj \ + $(SLO)$/numberformatcodewrapper.obj \ + $(SLO)$/readwritemutexguard.obj \ + $(SLO)$/transliterationwrapper.obj \ + $(SLO)$/textsearch.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/i18n/nativenumberwrapper.cxx b/unotools/source/i18n/nativenumberwrapper.cxx new file mode 100644 index 000000000000..f6df87615c6c --- /dev/null +++ b/unotools/source/i18n/nativenumberwrapper.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/nativenumberwrapper.hxx> +#include <tools/debug.hxx> + +#ifndef _COMPHELPER_COMPONENTFACTORY_HXX_ +#include <comphelper/componentfactory.hxx> +#endif +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#define LOCALEDATA_LIBRARYNAME "i18npool" +#define LOCALEDATA_SERVICENAME "com.sun.star.i18n.NativeNumberSupplier" + +using namespace ::com::sun::star; + + +NativeNumberWrapper::NativeNumberWrapper( + const uno::Reference< lang::XMultiServiceFactory > & xSF + ) + : + xSMgr( xSF ) +{ + if ( xSMgr.is() ) + { + try + { + xNNS = uno::Reference< i18n::XNativeNumberSupplier > ( xSMgr->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ), + uno::UNO_QUERY ); + } + catch ( uno::Exception& e ) + { + (void)e; + DBG_ERRORFILE( "NativeNumberWrapper ctor: Exception caught!" ); + } + } + else + { // try to get an instance somehow + DBG_ERRORFILE( "NativeNumberWrapper: no service manager, trying own" ); + try + { + uno::Reference< uno::XInterface > xI = ::comphelper::getComponentInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( LOCALEDATA_LIBRARYNAME ) ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ); + if ( xI.is() ) + { + uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< i18n::XNativeNumberSupplier >*)0) ); + x >>= xNNS; + } + } + catch ( uno::Exception& e ) + { + (void)e; + DBG_ERRORFILE( "getComponentInstance: Exception caught!" ); + } + } + DBG_ASSERT( xNNS.is(), "NativeNumberWrapper: no NativeNumberSupplier" ); +} + + +NativeNumberWrapper::~NativeNumberWrapper() +{ +} + + +::rtl::OUString +NativeNumberWrapper::getNativeNumberString( + const ::rtl::OUString& rNumberString, + const ::com::sun::star::lang::Locale& rLocale, + sal_Int16 nNativeNumberMode ) const +{ + try + { + if ( xNNS.is() ) + return xNNS->getNativeNumberString( rNumberString, rLocale, nNativeNumberMode ); + } + catch ( uno::Exception& e ) + { + (void)e; + DBG_ERRORFILE( "getNativeNumberString: Exception caught!" ); + } + return ::rtl::OUString(); +} + + +sal_Bool +NativeNumberWrapper::isValidNatNum( + const ::com::sun::star::lang::Locale& rLocale, + sal_Int16 nNativeNumberMode ) const +{ + try + { + if ( xNNS.is() ) + return xNNS->isValidNatNum( rLocale, nNativeNumberMode ); + } + catch ( uno::Exception& e ) + { + (void)e; + DBG_ERRORFILE( "isValidNatNum: Exception caught!" ); + } + return sal_False; +} + + +i18n::NativeNumberXmlAttributes +NativeNumberWrapper::convertToXmlAttributes( + const ::com::sun::star::lang::Locale& rLocale, + sal_Int16 nNativeNumberMode ) const +{ + try + { + if ( xNNS.is() ) + return xNNS->convertToXmlAttributes( rLocale, nNativeNumberMode ); + } + catch ( uno::Exception& e ) + { + (void)e; + DBG_ERRORFILE( "convertToXmlAttributes: Exception caught!" ); + } + return i18n::NativeNumberXmlAttributes(); +} + + +sal_Int16 +NativeNumberWrapper::convertFromXmlAttributes( + const i18n::NativeNumberXmlAttributes& rAttr ) const +{ + try + { + if ( xNNS.is() ) + return xNNS->convertFromXmlAttributes( rAttr ); + } + catch ( uno::Exception& e ) + { + (void)e; + DBG_ERRORFILE( "convertFromXmlAttributes: Exception caught!" ); + } + return 0; +} + + diff --git a/unotools/source/i18n/numberformatcodewrapper.cxx b/unotools/source/i18n/numberformatcodewrapper.cxx new file mode 100644 index 000000000000..2638e6730164 --- /dev/null +++ b/unotools/source/i18n/numberformatcodewrapper.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/numberformatcodewrapper.hxx> +#include <tools/debug.hxx> + +#ifndef _COMPHELPER_COMPONENTFACTORY_HXX_ +#include <comphelper/componentfactory.hxx> +#endif +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#define LOCALEDATA_LIBRARYNAME "i18npool" +#define LOCALEDATA_SERVICENAME "com.sun.star.i18n.NumberFormatMapper" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::uno; + + +NumberFormatCodeWrapper::NumberFormatCodeWrapper( + const Reference< lang::XMultiServiceFactory > & xSF, + const lang::Locale& rLocale + ) + : + xSMgr( xSF ) +{ + setLocale( rLocale ); + if ( xSMgr.is() ) + { + try + { + xNFC = Reference< XNumberFormatCode > ( xSMgr->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ), + uno::UNO_QUERY ); + } + catch ( Exception& e ) + { + (void)e; + DBG_ERRORFILE( "NumberFormatCodeWrapper ctor: Exception caught!" ); + } + } + else + { // try to get an instance somehow + DBG_ERRORFILE( "NumberFormatCodeWrapper: no service manager, trying own" ); + try + { + Reference< XInterface > xI = ::comphelper::getComponentInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( LOCALEDATA_LIBRARYNAME ) ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ); + if ( xI.is() ) + { + Any x = xI->queryInterface( ::getCppuType((const Reference< XNumberFormatCode >*)0) ); + x >>= xNFC; + } + } + catch ( Exception& e ) + { + (void)e; + DBG_ERRORFILE( "getComponentInstance: Exception caught!" ); + } + } + DBG_ASSERT( xNFC.is(), "NumberFormatCodeWrapper: no NumberFormatMapper" ); +} + + +NumberFormatCodeWrapper::~NumberFormatCodeWrapper() +{ +} + + +void NumberFormatCodeWrapper::setLocale( const ::com::sun::star::lang::Locale& rLocale ) +{ + aLocale = rLocale; +} + + +::com::sun::star::i18n::NumberFormatCode +NumberFormatCodeWrapper::getDefault( sal_Int16 formatType, sal_Int16 formatUsage ) const +{ + try + { + if ( xNFC.is() ) + return xNFC->getDefault( formatType, formatUsage, aLocale ); + } + catch ( Exception& e ) + { + (void)e; + DBG_ERRORFILE( "getDefault: Exception caught!" ); + } + return ::com::sun::star::i18n::NumberFormatCode(); +} + + +::com::sun::star::i18n::NumberFormatCode +NumberFormatCodeWrapper::getFormatCode( sal_Int16 formatIndex ) const +{ + try + { + if ( xNFC.is() ) + return xNFC->getFormatCode( formatIndex, aLocale ); + } + catch ( Exception& e ) + { + (void)e; + DBG_ERRORFILE( "getFormatCode: Exception caught!" ); + } + return ::com::sun::star::i18n::NumberFormatCode(); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode > +NumberFormatCodeWrapper::getAllFormatCode( sal_Int16 formatUsage ) const +{ + try + { + if ( xNFC.is() ) + return xNFC->getAllFormatCode( formatUsage, aLocale ); + } + catch ( Exception& e ) + { + (void)e; + DBG_ERRORFILE( "getAllFormatCode: Exception caught!" ); + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode > (0); +} + + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode > +NumberFormatCodeWrapper::getAllFormatCodes() const +{ + try + { + if ( xNFC.is() ) + return xNFC->getAllFormatCodes( aLocale ); + } + catch ( Exception& e ) + { + (void)e; + DBG_ERRORFILE( "getAllFormatCodes: Exception caught!" ); + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode > (0); +} diff --git a/unotools/source/i18n/readwritemutexguard.cxx b/unotools/source/i18n/readwritemutexguard.cxx new file mode 100644 index 000000000000..6adc5bab14bf --- /dev/null +++ b/unotools/source/i18n/readwritemutexguard.cxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include "unotools/readwritemutexguard.hxx" +#include <tools/debug.hxx> + + +namespace utl { + +ReadWriteGuard::ReadWriteGuard( ReadWriteMutex& rMutexP, + sal_Int32 nRequestMode ) + : rMutex( rMutexP ) +{ + // don't do anything until a pending write completed (or another + // ReadWriteGuard leaves the ctor phase) + ::osl::MutexGuard aGuard( rMutex.pWriteMutex ); + nMode = nRequestMode; + if ( nMode & ReadWriteGuardMode::nWrite ) + { + rMutex.pWriteMutex->acquire(); + // wait for any read to complete +// TODO: set up a waiting thread instead of a loop + sal_Bool bWait = sal_True; + do + { + rMutex.pMutex->acquire(); + bWait = (rMutex.nReadCount != 0); + if ( nMode & ReadWriteGuardMode::nCriticalChange ) + bWait |= (rMutex.nBlockCriticalCount != 0); + rMutex.pMutex->release(); + } while ( bWait ); + } + else if ( nMode & ReadWriteGuardMode::nBlockCritical ) + { + rMutex.pMutex->acquire(); + ++rMutex.nBlockCriticalCount; + rMutex.pMutex->release(); + } + else + { + rMutex.pMutex->acquire(); + ++rMutex.nReadCount; + rMutex.pMutex->release(); + } +} + + +ReadWriteGuard::~ReadWriteGuard() +{ + if ( nMode & ReadWriteGuardMode::nWrite ) + rMutex.pWriteMutex->release(); + else if ( nMode & ReadWriteGuardMode::nBlockCritical ) + { + rMutex.pMutex->acquire(); + --rMutex.nBlockCriticalCount; + rMutex.pMutex->release(); + } + else + { + rMutex.pMutex->acquire(); + --rMutex.nReadCount; + rMutex.pMutex->release(); + } +} + + +void ReadWriteGuard::changeReadToWrite() +{ + sal_Bool bOk = !(nMode & (ReadWriteGuardMode::nWrite | ReadWriteGuardMode::nBlockCritical)); + DBG_ASSERT( bOk, "ReadWriteGuard::changeReadToWrite: can't" ); + if ( bOk ) + { + // MUST release read before acquiring write mutex or dead lock would + // occur if there was a write in another thread waiting for this read + // to complete. + rMutex.pMutex->acquire(); + --rMutex.nReadCount; + rMutex.pMutex->release(); + + rMutex.pWriteMutex->acquire(); + nMode |= ReadWriteGuardMode::nWrite; + // wait for any other read to complete +// TODO: set up a waiting thread instead of a loop + sal_Bool bWait = sal_True; + do + { + rMutex.pMutex->acquire(); + bWait = (rMutex.nReadCount != 0); + rMutex.pMutex->release(); + } while ( bWait ); + } +} + +} // namespace utl diff --git a/unotools/source/i18n/textsearch.cxx b/unotools/source/i18n/textsearch.cxx new file mode 100644 index 000000000000..3f722adb0dba --- /dev/null +++ b/unotools/source/i18n/textsearch.cxx @@ -0,0 +1,398 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <i18npool/mslangid.hxx> +#include <tools/debug.hxx> +#ifndef _INTN_HXX //autogen +//#include <tools/intn.hxx> +#endif +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#ifndef _COM_SUN_STAR_UTIL_SEARCHFLAGS_HDL_ +#include <com/sun/star/util/SearchFlags.hdl> +#endif +#include <com/sun/star/i18n/TransliterationModules.hpp> +#include <unotools/charclass.hxx> +#include <comphelper/processfactory.hxx> +#include <unotools/textsearch.hxx> + +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +// ............................................................................ +namespace utl +{ +// ............................................................................ + +SearchParam::SearchParam( const String &rText, + SearchType eType, + BOOL bCaseSensitive, + BOOL bWrdOnly, + BOOL bSearchInSel ) +{ + sSrchStr = rText; + eSrchType = eType; + + bWordOnly = bWrdOnly; + bSrchInSel = bSearchInSel; + bCaseSense = bCaseSensitive; + + nTransliterationFlags = 0; + + // Werte fuer "Gewichtete Levenshtein-Distanz" + bLEV_Relaxed = TRUE; + nLEV_OtherX = 2; + nLEV_ShorterY = 1; + nLEV_LongerZ = 3; +} + +SearchParam::SearchParam( const SearchParam& rParam ) +{ + sSrchStr = rParam.sSrchStr; + sReplaceStr = rParam.sReplaceStr; + eSrchType = rParam.eSrchType; + + bWordOnly = rParam.bWordOnly; + bSrchInSel = rParam.bSrchInSel; + bCaseSense = rParam.bCaseSense; + + bLEV_Relaxed = rParam.bLEV_Relaxed; + nLEV_OtherX = rParam.nLEV_OtherX; + nLEV_ShorterY = rParam.nLEV_ShorterY; + nLEV_LongerZ = rParam.nLEV_LongerZ; + + nTransliterationFlags = rParam.nTransliterationFlags; +} + +// Klasse zum Suchen eines Strings in einem Text. Es wird genau nach +// dem String gesucht. +// ( Die Unterscheidung der Gross/Klein-Schreibung kann mit einen Flag +// unterdrueckt werden ) + +TextSearch::CachedTextSearch TextSearch::maCache; + +static bool lcl_Equals( const SearchOptions& rSO1, const SearchOptions& rSO2 ) +{ + return rSO1.algorithmType == rSO2.algorithmType && + rSO1.searchFlag == rSO2.searchFlag && + rSO1.searchString.equals(rSO2.searchString) && + rSO1.replaceString.equals(rSO2.replaceString) && + rSO1.changedChars == rSO2.changedChars && + rSO1.deletedChars == rSO2.deletedChars && + rSO1.insertedChars == rSO2.insertedChars && + rSO1.Locale.Language == rSO2.Locale.Language && + rSO1.Locale.Country == rSO2.Locale.Country && + rSO1.Locale.Variant == rSO2.Locale.Variant && + rSO1.transliterateFlags == rSO2.transliterateFlags; +} + +Reference<XTextSearch> TextSearch::getXTextSearch( const SearchOptions& rPara ) +{ + osl::MutexGuard aGuard(maCache.mutex); + + if ( lcl_Equals(maCache.Options, rPara) ) + return maCache.xTextSearch; + + try + { + Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + maCache.xTextSearch.set( xMSF->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.TextSearch" ) ) ), UNO_QUERY_THROW ); + maCache.xTextSearch->setOptions( rPara ); + maCache.Options = rPara; + } + catch ( Exception& ) + { + DBG_ERRORFILE( "TextSearch ctor: Exception caught!" ); + } + return maCache.xTextSearch; +} + +TextSearch::TextSearch(const SearchParam & rParam, LanguageType eLang ) +{ + if( LANGUAGE_NONE == eLang ) + eLang = LANGUAGE_SYSTEM; + ::com::sun::star::lang::Locale aLocale( + MsLangId::convertLanguageToLocale( LanguageType(eLang))); + + Init( rParam, aLocale); +} + +TextSearch::TextSearch(const SearchParam & rParam, const CharClass& rCClass ) +{ + Init( rParam, rCClass.getLocale() ); +} + +TextSearch::TextSearch( const SearchOptions& rPara ) +{ + xTextSearch = getXTextSearch( rPara ); +} + +void TextSearch::Init( const SearchParam & rParam, + const ::com::sun::star::lang::Locale& rLocale ) +{ + // convert SearchParam to the UNO SearchOptions + SearchOptions aSOpt; + + switch( rParam.GetSrchType() ) + { + case SearchParam::SRCH_REGEXP: + aSOpt.algorithmType = SearchAlgorithms_REGEXP; + if( rParam.IsSrchInSelection() ) + aSOpt.searchFlag |= SearchFlags::REG_NOT_BEGINOFLINE | + SearchFlags::REG_NOT_ENDOFLINE; + break; + + case SearchParam::SRCH_LEVDIST: + aSOpt.algorithmType = SearchAlgorithms_APPROXIMATE; + aSOpt.changedChars = rParam.GetLEVOther(); + aSOpt.deletedChars = rParam.GetLEVLonger(); + aSOpt.insertedChars = rParam.GetLEVShorter(); + if( rParam.IsSrchRelaxed() ) + aSOpt.searchFlag |= SearchFlags::LEV_RELAXED; + break; + +// case SearchParam::SRCH_NORMAL: + default: + aSOpt.algorithmType = SearchAlgorithms_ABSOLUTE; + if( rParam.IsSrchWordOnly() ) + aSOpt.searchFlag |= SearchFlags::NORM_WORD_ONLY; + break; + } + aSOpt.searchString = rParam.GetSrchStr(); + aSOpt.replaceString = rParam.GetReplaceStr(); + aSOpt.Locale = rLocale; + aSOpt.transliterateFlags = rParam.GetTransliterationFlags(); + if( !rParam.IsCaseSensitive() ) + { + aSOpt.searchFlag |= SearchFlags::ALL_IGNORE_CASE; + aSOpt.transliterateFlags |= ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE; + } + + xTextSearch = getXTextSearch( aSOpt ); +} + +void TextSearch::SetLocale( const ::com::sun::star::util::SearchOptions& rOptions, + const ::com::sun::star::lang::Locale& rLocale ) +{ + // convert SearchParam to the UNO SearchOptions + SearchOptions aSOpt( rOptions ); + aSOpt.Locale = rLocale; + + xTextSearch = getXTextSearch( aSOpt ); +} + + +TextSearch::~TextSearch() +{ +} + +/* + * Die allgemeinen Methoden zu Suchen. Diese rufen dann die entpsrecheden + * Methoden fuer die normale Suche oder der Suche nach Regular-Expressions + * ueber die MethodenPointer auf. + */ +#if defined _MSC_VER +#pragma optimize("", off) +#pragma warning(push) +#pragma warning(disable: 4748) +#endif +int TextSearch::SearchFrwrd( const String & rStr, xub_StrLen* pStart, + xub_StrLen* pEnde, SearchResult* pRes ) +{ + int nRet = 0; + try + { + if( xTextSearch.is() ) + { + SearchResult aRet( xTextSearch->searchForward( + rStr, *pStart, *pEnde )); + if( aRet.subRegExpressions > 0 ) + { + nRet = 1; + // the XTextsearch returns in startOffset the higher position + // and the endposition is allways exclusive. + // The caller of this function will have in startPos the + // lower pos. and end + *pStart = (xub_StrLen)aRet.startOffset[ 0 ]; + *pEnde = (xub_StrLen)aRet.endOffset[ 0 ]; + if( pRes ) + *pRes = aRet; + } + } + } + catch ( Exception& ) + { + DBG_ERRORFILE( "SearchForward: Exception caught!" ); + } + return nRet; +} + +int TextSearch::SearchBkwrd( const String & rStr, xub_StrLen* pStart, + xub_StrLen* pEnde, SearchResult* pRes ) +{ + int nRet = 0; + try + { + if( xTextSearch.is() ) + { + SearchResult aRet( xTextSearch->searchBackward( + rStr, *pStart, *pEnde )); + if( aRet.subRegExpressions ) + { + nRet = 1; + // the XTextsearch returns in startOffset the higher position + // and the endposition is allways exclusive. + // The caller of this function will have in startPos the + // lower pos. and end + *pEnde = (xub_StrLen)aRet.startOffset[ 0 ]; + *pStart = (xub_StrLen)aRet.endOffset[ 0 ]; + if( pRes ) + *pRes = aRet; + } + } + } + catch ( Exception& ) + { + DBG_ERRORFILE( "SearchBackward: Exception caught!" ); + } + return nRet; +} + +void TextSearch::ReplaceBackReferences( String& rReplaceStr, const String &rStr, const SearchResult& rResult ) +{ + if( rResult.subRegExpressions > 0 ) + { + String sTab( '\t' ); + sal_Unicode sSrchChrs[] = {'\\', '&', '$', 0}; + String sTmp; + xub_StrLen nPos = 0; + sal_Unicode sFndChar; + while( STRING_NOTFOUND != ( nPos = rReplaceStr.SearchChar( sSrchChrs, nPos )) ) + { + if( rReplaceStr.GetChar( nPos ) == '&') + { + USHORT nStart = (USHORT)(rResult.startOffset[0]); + USHORT nLength = (USHORT)(rResult.endOffset[0] - rResult.startOffset[0]); + rReplaceStr.Erase( nPos, 1 ); // delete ampersand + // replace by found string + rReplaceStr.Insert( rStr, nStart, nLength, nPos ); + // jump over + nPos = nPos + nLength; + } + else if( rReplaceStr.GetChar( nPos ) == '$') + { + if( nPos + 1 < rReplaceStr.Len()) + { + sFndChar = rReplaceStr.GetChar( nPos + 1 ); + switch(sFndChar) + { // placeholder for a backward reference? + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + rReplaceStr.Erase( nPos, 2 ); // delete both + int i = sFndChar - '0'; // index + if(i < rResult.subRegExpressions) + { + USHORT nSttReg = (USHORT)(rResult.startOffset[i]); + USHORT nRegLen = (USHORT)(rResult.endOffset[i]); + if( nRegLen > nSttReg ) + nRegLen = nRegLen - nSttReg; + else + { + nRegLen = nSttReg - nRegLen; + nSttReg = (USHORT)(rResult.endOffset[i]); + } + // Copy reference from found string + sTmp = rStr.Copy((USHORT)nSttReg, (USHORT)nRegLen); + // insert + rReplaceStr.Insert( sTmp, nPos ); + // and step over + nPos = nPos + sTmp.Len(); + } + } + break; + default: + nPos += 2; // leave both chars unchanged + break; + } + } + else + ++nPos; + } + else + { + // at least another character? + if( nPos + 1 < rReplaceStr.Len()) + { + sFndChar = rReplaceStr.GetChar( nPos + 1 ); + switch(sFndChar) + { + case '\\': + case '&': + case '$': + rReplaceStr.Erase( nPos, 1 ); + nPos++; + break; + case 't': + rReplaceStr.Erase( nPos, 2 ); // delete both + rReplaceStr.Insert( sTab, nPos ); // insert tabulator + nPos++; // step over + break; + default: + nPos += 2; // ignore both characters + break; + } + } + else + ++nPos; + } + } + } +} + + +#if defined _MSC_VER +#pragma optimize("", on) +#pragma warning(pop) +#endif + +// ............................................................................ +} // namespace utl +// ............................................................................ + diff --git a/unotools/source/i18n/transliterationwrapper.cxx b/unotools/source/i18n/transliterationwrapper.cxx new file mode 100644 index 000000000000..a10a52802e19 --- /dev/null +++ b/unotools/source/i18n/transliterationwrapper.cxx @@ -0,0 +1,345 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/transliterationwrapper.hxx> +#include <tools/debug.hxx> +#include <i18npool/mslangid.hxx> +#include <comphelper/componentfactory.hxx> + +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/i18n/TransliterationModulesExtra.hpp> + +#define TRANSLIT_LIBRARYNAME "i18n" +#define TRANSLIT_SERVICENAME "com.sun.star.i18n.Transliteration" + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::uno; +using namespace ::utl; + +TransliterationWrapper::TransliterationWrapper( + const Reference< XMultiServiceFactory > & xSF, + sal_uInt32 nTyp ) + : xSMgr( xSF ), nType( nTyp ), nLanguage( 0 ), bFirstCall( sal_True ) +{ + if( xSMgr.is() ) + { + try { + xTrans = Reference< XExtendedTransliteration > ( + xSMgr->createInstance( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + TRANSLIT_SERVICENAME))), UNO_QUERY ); + } + catch ( Exception& ) + { + DBG_ERRORFILE( "TransliterationWrapper: Exception caught!" ); + } + } + else + { // try to get an instance somehow + DBG_ERRORFILE( "TransliterationWrapper: no service manager, trying own" ); + try + { + Reference< XInterface > xI = ::comphelper::getComponentInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( + TRANSLIT_LIBRARYNAME ))), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + TRANSLIT_SERVICENAME))); + if ( xI.is() ) + { + Any x = xI->queryInterface( + ::getCppuType((const Reference< XExtendedTransliteration>*)0) ); + x >>= xTrans ; + } + } + catch ( Exception& ) + { + DBG_ERRORFILE( "getComponentInstance: Exception caught!" ); + } + } + DBG_ASSERT( xTrans.is(), "TransliterationWrapper: no Transliteraion available" ); +} + + +TransliterationWrapper::~TransliterationWrapper() +{ +} + + +String TransliterationWrapper::transliterate( + const String& rStr, sal_uInt16 nLang, + xub_StrLen nStart, xub_StrLen nLen, + Sequence <sal_Int32>* pOffset ) +{ + String sRet; + if( xTrans.is() ) + { + try + { + loadModuleIfNeeded( nLang ); + + if ( pOffset ) + sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset ); + else + sRet = xTrans->transliterateString2String( rStr, nStart, nLen); + } + catch( Exception& ) + { + DBG_ERRORFILE( "transliterate: Exception caught!" ); + } + } + return sRet; +} + + +String TransliterationWrapper::transliterate( + const String& rStr, + xub_StrLen nStart, xub_StrLen nLen, + Sequence <sal_Int32>* pOffset ) const +{ + String sRet( rStr ); + if( xTrans.is() ) + { + try + { + if ( pOffset ) + sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset ); + else + sRet = xTrans->transliterateString2String( rStr, nStart, nLen); + } + catch( Exception& ) + { + DBG_ERRORFILE( "transliterate: Exception caught!" ); + } + } + return sRet; +} + +sal_Bool TransliterationWrapper::needLanguageForTheMode() const +{ + return TransliterationModules_UPPERCASE_LOWERCASE == nType || + TransliterationModules_LOWERCASE_UPPERCASE == nType || + TransliterationModules_IGNORE_CASE == nType || + (sal_uInt32) TransliterationModulesExtra::SENTENCE_CASE == (sal_uInt32) nType || + (sal_uInt32) TransliterationModulesExtra::TITLE_CASE == (sal_uInt32) nType || + (sal_uInt32) TransliterationModulesExtra::TOGGLE_CASE == (sal_uInt32) nType; +} + + +void TransliterationWrapper::setLanguageLocaleImpl( sal_uInt16 nLang ) +{ + nLanguage = nLang; + if( LANGUAGE_NONE == nLanguage ) + nLanguage = LANGUAGE_SYSTEM; + MsLangId::convertLanguageToLocale( nLanguage, aLocale); +} + + +void TransliterationWrapper::loadModuleIfNeeded( sal_uInt16 nLang ) +{ + sal_Bool bLoad = bFirstCall; + bFirstCall = sal_False; + + if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::SENTENCE_CASE ) + { + if( bLoad ) + loadModuleByImplName(String::CreateFromAscii("SENTENCE_CASE"), nLang); + } + else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TITLE_CASE ) + { + if( bLoad ) + loadModuleByImplName(String::CreateFromAscii("TITLE_CASE"), nLang); + } + else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TOGGLE_CASE ) + { + if( bLoad ) + loadModuleByImplName(String::CreateFromAscii("TOGGLE_CASE"), nLang); + } + else + { + if( nLanguage != nLang ) + { + setLanguageLocaleImpl( nLang ); + if( !bLoad ) + bLoad = needLanguageForTheMode(); + } + if( bLoad ) + loadModuleImpl(); + } +} + + +void TransliterationWrapper::loadModuleImpl() const +{ + if ( bFirstCall ) + ((TransliterationWrapper*)this)->setLanguageLocaleImpl( LANGUAGE_SYSTEM ); + + try + { + if ( xTrans.is() ) + xTrans->loadModule( (TransliterationModules)nType, aLocale ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "loadModuleImpl: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + + bFirstCall = sal_False; +} + + +void TransliterationWrapper::loadModuleByImplName( + const String& rModuleName, sal_uInt16 nLang ) +{ + try + { + setLanguageLocaleImpl( nLang ); + // Reset LanguageType, so the next call to loadModuleIfNeeded() forces + // new settings. + nLanguage = LANGUAGE_DONTKNOW; + if ( xTrans.is() ) + xTrans->loadModuleByImplName( rModuleName, aLocale ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "loadModuleByImplName: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + + bFirstCall = sal_False; +} + + +sal_Bool TransliterationWrapper::equals( + const String& rStr1, sal_Int32 nPos1, sal_Int32 nCount1, sal_Int32& nMatch1, + const String& rStr2, sal_Int32 nPos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) const +{ + try + { + if( bFirstCall ) + loadModuleImpl(); + if ( xTrans.is() ) + return xTrans->equals( rStr1, nPos1, nCount1, nMatch1, rStr2, nPos2, nCount2, nMatch2 ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "equals: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return sal_False; +} + + +sal_Int32 TransliterationWrapper::compareSubstring( + const String& rStr1, sal_Int32 nOff1, sal_Int32 nLen1, + const String& rStr2, sal_Int32 nOff2, sal_Int32 nLen2 ) const +{ + try + { + if( bFirstCall ) + loadModuleImpl(); + if ( xTrans.is() ) + return xTrans->compareSubstring( rStr1, nOff1, nLen1, rStr2, nOff2, nLen2 ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "compareSubstring: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0; +} + + +sal_Int32 TransliterationWrapper::compareString( const String& rStr1, const String& rStr2 ) const +{ + try + { + if( bFirstCall ) + loadModuleImpl(); + if ( xTrans.is() ) + return xTrans->compareString( rStr1, rStr2 ); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "compareString: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return 0; +} + + +// --- helpers -------------------------------------------------------- + +sal_Bool TransliterationWrapper::isEqual( const String& rStr1, const String& rStr2 ) const +{ + sal_Int32 nMatch1, nMatch2; + sal_Bool bMatch = equals( + rStr1, 0, rStr1.Len(), nMatch1, + rStr2, 0, rStr2.Len(), nMatch2 ); + return bMatch; +} + + +sal_Bool TransliterationWrapper::isMatch( const String& rStr1, const String& rStr2 ) const +{ + sal_Int32 nMatch1, nMatch2; + equals( + rStr1, 0, rStr1.Len(), nMatch1, + rStr2, 0, rStr2.Len(), nMatch2 ); + return (nMatch1 <= nMatch2) && (nMatch1 == rStr1.Len()); +} diff --git a/unotools/source/misc/atom.cxx b/unotools/source/misc/atom.cxx new file mode 100644 index 000000000000..3d7ccd1dd10e --- /dev/null +++ b/unotools/source/misc/atom.cxx @@ -0,0 +1,383 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/atom.hxx> + +using namespace utl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +#define NMSP_UTIL ::com::sun::star::util + +AtomProvider::AtomProvider() +{ + m_nAtoms = 1; +} + +AtomProvider::~AtomProvider() +{ +} + +int AtomProvider::getAtom( const ::rtl::OUString& rString, sal_Bool bCreate ) +{ + ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::iterator it = m_aAtomMap.find( rString ); + if( it != m_aAtomMap.end() ) + return it->second; + if( ! bCreate ) + return INVALID_ATOM; + m_aAtomMap[ rString ] = m_nAtoms; + m_aStringMap[ m_nAtoms ] = rString; + m_nAtoms++; + return m_nAtoms-1; +} + +void AtomProvider::getAll( ::std::list< ::utl::AtomDescription >& atoms ) +{ + atoms.clear(); + ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin(); + + ::utl::AtomDescription aDesc; + while( it != m_aAtomMap.end() ) + { + aDesc.atom = it->second; + aDesc.description = it->first; + atoms.push_back( aDesc ); + ++it; + } +} + +void AtomProvider::getRecent( int atom, ::std::list< ::utl::AtomDescription >& atoms ) +{ + atoms.clear(); + + ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin(); + + ::utl::AtomDescription aDesc; + while( it != m_aAtomMap.end() ) + { + if( it->second > atom ) + { + aDesc.atom = it->second; + aDesc.description = it->first; + atoms.push_back( aDesc ); + } + ++it; + } +} + +const ::rtl::OUString& AtomProvider::getString( int nAtom ) const +{ + static ::rtl::OUString aEmpty; + ::std::hash_map< int, ::rtl::OUString, ::std::hash< int > >::const_iterator it = m_aStringMap.find( nAtom ); + + return it == m_aStringMap.end() ? aEmpty : it->second; +} + +void AtomProvider::overrideAtom( int atom, const ::rtl::OUString& description ) +{ + m_aAtomMap[ description ] = atom; + m_aStringMap[ atom ] = description; + if( m_nAtoms <= atom ) + m_nAtoms=atom+1; +} + +sal_Bool AtomProvider::hasAtom( int atom ) const +{ + return m_aStringMap.find( atom ) != m_aStringMap.end() ? sal_True : sal_False; +} + +// ----------------------------------------------------------------------- + +MultiAtomProvider::MultiAtomProvider() +{ +} + +MultiAtomProvider::~MultiAtomProvider() +{ + for( ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it = m_aAtomLists.begin(); it != m_aAtomLists.end(); ++it ) + delete it->second; +} + + +sal_Bool MultiAtomProvider::insertAtomClass( int atomClass ) +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it = + m_aAtomLists.find( atomClass ); + if( it != m_aAtomLists.end() ) + return sal_False; + m_aAtomLists[ atomClass ] = new AtomProvider(); + return sal_True; +} + +int MultiAtomProvider::getAtom( int atomClass, const ::rtl::OUString& rString, sal_Bool bCreate ) +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it = + m_aAtomLists.find( atomClass ); + if( it != m_aAtomLists.end() ) + return it->second->getAtom( rString, bCreate ); + + if( bCreate ) + { + AtomProvider* pNewClass; + m_aAtomLists[ atomClass ] = pNewClass = new AtomProvider(); + return pNewClass->getAtom( rString, bCreate ); + } + return INVALID_ATOM; +} + +int MultiAtomProvider::getLastAtom( int atomClass ) const +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = + m_aAtomLists.find( atomClass ); + + return it != m_aAtomLists.end() ? it->second->getLastAtom() : INVALID_ATOM; +} + +void MultiAtomProvider::getRecent( int atomClass, int atom, ::std::list< ::utl::AtomDescription >& atoms ) +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = + m_aAtomLists.find( atomClass ); + if( it != m_aAtomLists.end() ) + it->second->getRecent( atom, atoms ); + else + atoms.clear(); +} + +const ::rtl::OUString& MultiAtomProvider::getString( int atomClass, int atom ) const +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = + m_aAtomLists.find( atomClass ); + if( it != m_aAtomLists.end() ) + return it->second->getString( atom ); + + static ::rtl::OUString aEmpty; + return aEmpty; +} + +sal_Bool MultiAtomProvider::hasAtom( int atomClass, int atom ) const +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass ); + return it != m_aAtomLists.end() ? it->second->hasAtom( atom ) : sal_False; +} + +void MultiAtomProvider::getClass( int atomClass, ::std::list< ::utl::AtomDescription >& atoms) const +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass ); + + if( it != m_aAtomLists.end() ) + it->second->getAll( atoms ); + else + atoms.clear(); +} + +void MultiAtomProvider::overrideAtom( int atomClass, int atom, const ::rtl::OUString& description ) +{ + ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass ); + if( it == m_aAtomLists.end() ) + m_aAtomLists[ atomClass ] = new AtomProvider(); + m_aAtomLists[ atomClass ]->overrideAtom( atom, description ); +} + +// ----------------------------------------------------------------------- + +AtomServer::AtomServer() +{ +} + +AtomServer::~AtomServer() +{ +} + +sal_Int32 AtomServer::getAtom( sal_Int32 atomClass, const ::rtl::OUString& description, sal_Bool create ) throw() +{ + ::osl::Guard< ::osl::Mutex > guard( m_aMutex ); + + return m_aProvider.getAtom( atomClass, description, create ); +} + +Sequence< Sequence< NMSP_UTIL::AtomDescription > > AtomServer::getClasses( const Sequence< sal_Int32 >& atomClasses ) throw() +{ + ::osl::Guard< ::osl::Mutex > guard( m_aMutex ); + + Sequence< Sequence< NMSP_UTIL::AtomDescription > > aRet( atomClasses.getLength() ); + for( int i = 0; i < atomClasses.getLength(); i++ ) + { + aRet.getArray()[i] = getClass( atomClasses.getConstArray()[i] ); + } + return aRet; +} + +Sequence< NMSP_UTIL::AtomDescription > AtomServer::getClass( sal_Int32 atomClass ) throw() +{ + ::osl::Guard< ::osl::Mutex > guard( m_aMutex ); + + ::std::list< ::utl::AtomDescription > atoms; + m_aProvider.getClass( atomClass, atoms ); + + Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() ); + for( int i = aRet.getLength()-1; i >= 0; i-- ) + { + aRet.getArray()[i].atom = atoms.back().atom; + aRet.getArray()[i].description = atoms.back().description; + atoms.pop_back(); + } + + return aRet; +} + +Sequence< NMSP_UTIL::AtomDescription > AtomServer::getRecentAtoms( sal_Int32 atomClass, sal_Int32 atom ) throw() +{ + ::osl::Guard< ::osl::Mutex > guard( m_aMutex ); + + ::std::list< ::utl::AtomDescription > atoms; + m_aProvider.getRecent( atomClass, atom, atoms ); + + Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() ); + for( int i = aRet.getLength()-1; i >= 0; i-- ) + { + aRet.getArray()[i].atom = atoms.back().atom; + aRet.getArray()[i].description = atoms.back().description; + atoms.pop_back(); + } + + return aRet; +} + +Sequence< ::rtl::OUString > AtomServer::getAtomDescriptions( const Sequence< AtomClassRequest >& atoms ) throw() +{ + ::osl::Guard< ::osl::Mutex > guard( m_aMutex ); + + int nStrings = 0, i; + for( i = 0; i < atoms.getLength(); i++ ) + nStrings += atoms.getConstArray()[ i ].atoms.getLength(); + Sequence< ::rtl::OUString > aRet( nStrings ); + for( i = 0, nStrings = 0; i < atoms.getLength(); i++ ) + { + const AtomClassRequest& rRequest = atoms.getConstArray()[i]; + for( int n = 0; n < rRequest.atoms.getLength(); n++ ) + aRet.getArray()[ nStrings++ ] = m_aProvider.getString( rRequest.atomClass, rRequest.atoms.getConstArray()[ n ] ); + } + return aRet; +} + +// ----------------------------------------------------------------------- + +AtomClient::AtomClient( const Reference< XAtomServer >& xServer ) : + m_xServer( xServer ) +{ +} + +AtomClient::~AtomClient() +{ +} + +int AtomClient::getAtom( int atomClass, const ::rtl::OUString& description, sal_Bool bCreate ) +{ + int nAtom = m_aProvider.getAtom( atomClass, description, sal_False ); + if( nAtom == INVALID_ATOM && bCreate ) + { + try + { + nAtom = m_xServer->getAtom( atomClass, description, bCreate ); + } + catch( RuntimeException& ) + { + return INVALID_ATOM; + } + if( nAtom != INVALID_ATOM ) + m_aProvider.overrideAtom( atomClass, nAtom, description ); + } + return nAtom; +} + +const ::rtl::OUString& AtomClient::getString( int atomClass, int atom ) +{ + static ::rtl::OUString aEmpty; + + if( ! m_aProvider.hasAtom( atomClass, atom ) ) + { + Sequence< NMSP_UTIL::AtomDescription > aSeq; + try + { + aSeq = m_xServer->getRecentAtoms( atomClass, m_aProvider.getLastAtom( atomClass ) ); + } + catch( RuntimeException& ) + { + return aEmpty; + } + const NMSP_UTIL::AtomDescription* pDescriptions = aSeq.getConstArray(); + for( int i = 0; i < aSeq.getLength(); i++ ) + m_aProvider.overrideAtom( atomClass, + pDescriptions[i].atom, + pDescriptions[i].description + ); + + if( ! m_aProvider.hasAtom( atomClass, atom ) ) + { + // holes may occur by the above procedure! + Sequence< AtomClassRequest > aReq( 1 ); + aReq.getArray()[0].atomClass = atomClass; + aReq.getArray()[0].atoms.realloc( 1 ); + aReq.getArray()[0].atoms.getArray()[0] = atom; + Sequence< ::rtl::OUString > aRet; + try + { + aRet = m_xServer->getAtomDescriptions( aReq ); + } + catch( RuntimeException& ) + { + return aEmpty; + } + if( aRet.getLength() == 1 ) + m_aProvider.overrideAtom( atomClass, atom, aRet.getConstArray()[0] ); + } + } + return m_aProvider.getString( atomClass, atom ); +} + +void AtomClient::updateAtomClasses( const Sequence< sal_Int32 >& atomClasses ) +{ + Sequence< Sequence< NMSP_UTIL::AtomDescription > > aUpdate; + try + { + aUpdate = m_xServer->getClasses( atomClasses ); + } + catch( RuntimeException& ) + { + return; + } + for( int i = 0; i < atomClasses.getLength(); i++ ) + { + int nClass = atomClasses.getConstArray()[i]; + const Sequence< NMSP_UTIL::AtomDescription >& rClass = aUpdate.getConstArray()[i]; + const NMSP_UTIL::AtomDescription* pDesc = rClass.getConstArray(); + for( int n = 0; n < rClass.getLength(); n++, pDesc++ ) + m_aProvider.overrideAtom( nClass, pDesc->atom, pDesc->description ); + } +} diff --git a/unotools/source/misc/componentresmodule.cxx b/unotools/source/misc/componentresmodule.cxx new file mode 100644 index 000000000000..21c50d9ec7f1 --- /dev/null +++ b/unotools/source/misc/componentresmodule.cxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/componentresmodule.hxx> + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ +#include <tools/resmgr.hxx> +#include <osl/diagnose.h> + +//........................................................................ +namespace utl +{ +//........................................................................ + + //==================================================================== + //= OComponentResModuleImpl + //==================================================================== + /** PIMPL-class for OComponentResourceModule + + not threadsafe! + */ + class OComponentResModuleImpl + { + private: + ResMgr* m_pRessources; + bool m_bInitialized; + ::rtl::OString m_sResFilePrefix; + + public: + OComponentResModuleImpl( const ::rtl::OString& _rResFilePrefix ) + :m_pRessources( NULL ) + ,m_bInitialized( false ) + ,m_sResFilePrefix( _rResFilePrefix ) + { + } + + ~OComponentResModuleImpl() + { + freeResManager(); + } + + /** releases our resource manager + */ + void freeResManager(); + + /** retrieves our resource manager + */ + ResMgr* getResManager(); + + private: + OComponentResModuleImpl(); // never implemented + OComponentResModuleImpl( const OComponentResModuleImpl& ); // never implemented + OComponentResModuleImpl& operator=( const OComponentResModuleImpl& ); // never implemented + }; + + //-------------------------------------------------------------------- + void OComponentResModuleImpl::freeResManager() + { + delete m_pRessources, m_pRessources = NULL; + m_bInitialized = false; + } + + //-------------------------------------------------------------------- + ResMgr* OComponentResModuleImpl::getResManager() + { + if ( !m_pRessources && !m_bInitialized ) + { + // create a manager with a fixed prefix + ByteString aMgrName = m_sResFilePrefix; + + m_pRessources = ResMgr::CreateResMgr( aMgrName.GetBuffer() ); + OSL_ENSURE( m_pRessources, + ( ByteString( "OModuleImpl::getResManager: could not create the resource manager (file name: " ) + += aMgrName + += ByteString( ")!" ) ).GetBuffer() ); + + m_bInitialized = sal_True; + } + return m_pRessources; + } + + //==================================================================== + //= OComponentResourceModule + //==================================================================== + //-------------------------------------------------------------------- + OComponentResourceModule::OComponentResourceModule( const ::rtl::OString& _rResFilePrefix ) + :BaseClass() + ,m_pImpl( new OComponentResModuleImpl( _rResFilePrefix ) ) + { + } + + //-------------------------------------------------------------------- + OComponentResourceModule::~OComponentResourceModule() + { + } + + //------------------------------------------------------------------------- + ResMgr* OComponentResourceModule::getResManager() + { + ::osl::MutexGuard aGuard( m_aMutex ); + return m_pImpl->getResManager(); + } + + //-------------------------------------------------------------------------- + void OComponentResourceModule::onFirstClient() + { + BaseClass::onFirstClient(); + } + + //-------------------------------------------------------------------------- + void OComponentResourceModule::onLastClient() + { + m_pImpl->freeResManager(); + BaseClass::onLastClient(); + } + +//........................................................................ +} // namespace utl +//........................................................................ diff --git a/unotools/source/misc/datetime.cxx b/unotools/source/misc/datetime.cxx new file mode 100644 index 000000000000..6bfd053b3fe9 --- /dev/null +++ b/unotools/source/misc/datetime.cxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/datetime.hxx> +#include <tools/date.hxx> +#include <tools/time.hxx> +#include <tools/datetime.hxx> + +//......................................................................... +namespace utl +{ +//......................................................................... + +//------------------------------------------------------------------ +void typeConvert(const Time& _rTime, starutil::Time& _rOut) +{ + _rOut.Hours = _rTime.GetHour(); + _rOut.Minutes = _rTime.GetMin(); + _rOut.Seconds = _rTime.GetSec(); + _rOut.HundredthSeconds = _rTime.Get100Sec(); +} + +//------------------------------------------------------------------ +void typeConvert(const starutil::Time& _rTime, Time& _rOut) +{ + _rOut = Time(_rTime.Hours, _rTime.Minutes, _rTime.Seconds, _rTime.HundredthSeconds); +} + +//------------------------------------------------------------------ +void typeConvert(const Date& _rDate, starutil::Date& _rOut) +{ + _rOut.Day = _rDate.GetDay(); + _rOut.Month = _rDate.GetMonth(); + _rOut.Year = _rDate.GetYear(); +} + +//------------------------------------------------------------------ +void typeConvert(const starutil::Date& _rDate, Date& _rOut) +{ + _rOut = Date(_rDate.Day, _rDate.Month, _rDate.Year); +} + +//------------------------------------------------------------------ +void typeConvert(const DateTime& _rDateTime, starutil::DateTime& _rOut) +{ + _rOut.Year = _rDateTime.GetYear(); + _rOut.Month = _rDateTime.GetMonth(); + _rOut.Day = _rDateTime.GetDay(); + _rOut.Hours = _rDateTime.GetHour(); + _rOut.Minutes = _rDateTime.GetMin(); + _rOut.Seconds = _rDateTime.GetSec(); + _rOut.HundredthSeconds = _rDateTime.Get100Sec(); +} + +//------------------------------------------------------------------ +void typeConvert(const starutil::DateTime& _rDateTime, DateTime& _rOut) +{ + Date aDate(_rDateTime.Day, _rDateTime.Month, _rDateTime.Year); + Time aTime(_rDateTime.Hours, _rDateTime.Minutes, _rDateTime.Seconds, _rDateTime.HundredthSeconds); + _rOut = DateTime(aDate, aTime); +} + +//------------------------------------------------------------------------- +sal_Bool operator ==(const starutil::DateTime& _rLeft, const starutil::DateTime& _rRight) +{ + return ( _rLeft.HundredthSeconds == _rRight.HundredthSeconds) && + ( _rLeft.Seconds == _rRight.Seconds) && + ( _rLeft.Minutes == _rRight.Minutes) && + ( _rLeft.Hours == _rRight.Hours) && + ( _rLeft.Day == _rRight.Day) && + ( _rLeft.Month == _rRight.Month) && + ( _rLeft.Year == _rRight.Year) ; +} + +//------------------------------------------------------------------------- +sal_Bool operator ==(const starutil::Date& _rLeft, const starutil::Date& _rRight) +{ + return ( _rLeft.Day == _rRight.Day) && + ( _rLeft.Month == _rRight.Month) && + ( _rLeft.Year == _rRight.Year) ; +} + +//------------------------------------------------------------------------- +sal_Bool operator ==(const starutil::Time& _rLeft, const starutil::Time& _rRight) +{ + return ( _rLeft.HundredthSeconds == _rRight.HundredthSeconds) && + ( _rLeft.Seconds == _rRight.Seconds) && + ( _rLeft.Minutes == _rRight.Minutes) && + ( _rLeft.Hours == _rRight.Hours) ; +} + +//......................................................................... +} // namespace utl +//......................................................................... + diff --git a/unotools/source/misc/desktopterminationobserver.cxx b/unotools/source/misc/desktopterminationobserver.cxx new file mode 100644 index 000000000000..3900449f03c9 --- /dev/null +++ b/unotools/source/misc/desktopterminationobserver.cxx @@ -0,0 +1,231 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/desktopterminationobserver.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +/** === end UNO includes === **/ +#include <cppuhelper/implbase1.hxx> +#include <comphelper/processfactory.hxx> + +#include <list> + +//........................................................................ +namespace utl +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::frame; + + namespace + { + //................................................................ + typedef ::std::list< ITerminationListener* > Listeners; + + struct ListenerAdminData + { + Listeners aListeners; + bool bAlreadyTerminated; + bool bCreatedAdapter; + + ListenerAdminData() : bAlreadyTerminated( false ), bCreatedAdapter( false ) { } + }; + + //................................................................ + ListenerAdminData& getListenerAdminData() + { + static ListenerAdminData s_aData; + return s_aData; + } + + //================================================================ + //= OObserverImpl + //================================================================ + class OObserverImpl : public ::cppu::WeakImplHelper1< XTerminateListener > + { + public: + static void ensureObservation(); + + protected: + OObserverImpl(); + ~OObserverImpl(); + + private: + // XTerminateListener + virtual void SAL_CALL queryTermination( const EventObject& Event ) throw (TerminationVetoException, RuntimeException); + virtual void SAL_CALL notifyTermination( const EventObject& Event ) throw (RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + }; + + //-------------------------------------------------------------------- + OObserverImpl::OObserverImpl() + { + } + + //-------------------------------------------------------------------- + OObserverImpl::~OObserverImpl() + { + } + + //-------------------------------------------------------------------- + void OObserverImpl::ensureObservation() + { + { + if ( getListenerAdminData().bCreatedAdapter ) + return; + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( getListenerAdminData().bCreatedAdapter ) + return; + + getListenerAdminData().bCreatedAdapter = true; + } + + try + { + Reference< XDesktop > xDesktop; + xDesktop = xDesktop.query( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ) ); + OSL_ENSURE( xDesktop.is(), "OObserverImpl::ensureObservation: could not ensureObservation the desktop!" ); + if ( xDesktop.is() ) + xDesktop->addTerminateListener( new OObserverImpl ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "OObserverImpl::ensureObservation: caught an exception!" ); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OObserverImpl::queryTermination( const EventObject& /*Event*/ ) throw (TerminationVetoException, RuntimeException) + { + Listeners aToNotify; + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + aToNotify = getListenerAdminData().aListeners; + } + + for ( Listeners::const_iterator listener = aToNotify.begin(); + listener != aToNotify.end(); + ++listener + ) + { + if ( !(*listener)->queryTermination() ) + throw TerminationVetoException(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OObserverImpl::notifyTermination( const EventObject& /*Event*/ ) throw (RuntimeException) + { + // get the listeners + Listeners aToNotify; + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + OSL_ENSURE( !getListenerAdminData().bAlreadyTerminated, "OObserverImpl::notifyTermination: terminated twice?" ); + aToNotify = getListenerAdminData().aListeners; + getListenerAdminData().bAlreadyTerminated = true; + } + + // notify the listeners + for ( Listeners::const_iterator listener = aToNotify.begin(); + listener != aToNotify.end(); + ++listener + ) + { + (*listener)->notifyTermination(); + } + + // clear the listener container + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + getListenerAdminData().aListeners.clear(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OObserverImpl::disposing( const EventObject& /*Event*/ ) throw (RuntimeException) + { +#if OSL_DEBUG_LEVEL > 0 + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + OSL_ENSURE( getListenerAdminData().bAlreadyTerminated, "OObserverImpl::disposing: disposing without terminated?" ); +#endif + // not interested in + } + } + + //==================================================================== + //= DesktopTerminationObserver + //==================================================================== + //-------------------------------------------------------------------- + void DesktopTerminationObserver::registerTerminationListener( ITerminationListener* _pListener ) + { + if ( !_pListener ) + return; + + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( getListenerAdminData().bAlreadyTerminated ) + { + _pListener->notifyTermination(); + return; + } + + getListenerAdminData().aListeners.push_back( _pListener ); + } + + OObserverImpl::ensureObservation(); + } + + //-------------------------------------------------------------------- + void DesktopTerminationObserver::revokeTerminationListener( ITerminationListener* _pListener ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + Listeners& rListeners = getListenerAdminData().aListeners; + for ( Listeners::iterator lookup = rListeners.begin(); + lookup != rListeners.end(); + ++lookup + ) + { + if ( *lookup == _pListener ) + { + rListeners.erase( lookup ); + break; + } + } + } + +//........................................................................ +} // namespace utl +//........................................................................ + diff --git a/unotools/source/misc/eventlisteneradapter.cxx b/unotools/source/misc/eventlisteneradapter.cxx new file mode 100644 index 000000000000..0e14a54cd3c0 --- /dev/null +++ b/unotools/source/misc/eventlisteneradapter.cxx @@ -0,0 +1,182 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/eventlisteneradapter.hxx> +#include <osl/diagnose.h> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/stl_types.hxx> + +//......................................................................... +namespace utl +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + + //===================================================================== + //= OEventListenerImpl + //===================================================================== + class OEventListenerImpl : public ::cppu::WeakImplHelper1< XEventListener > + { + protected: + OEventListenerAdapter* m_pAdapter; + Reference< XEventListener > m_xKeepMeAlive; + // imagine an implementation of XComponent which holds it's listeners with a weak reference ... + // would be very bad if we don't hold ourself + Reference< XComponent > m_xComponent; + + public: + OEventListenerImpl( OEventListenerAdapter* _pAdapter, const Reference< XComponent >& _rxComp ); + + void dispose(); + const Reference< XComponent >& getComponent() const { return m_xComponent; } + + protected: + virtual void SAL_CALL disposing( const EventObject& _rSource ) throw (RuntimeException); + }; + + //--------------------------------------------------------------------- + OEventListenerImpl::OEventListenerImpl( OEventListenerAdapter* _pAdapter, const Reference< XComponent >& _rxComp ) + :m_pAdapter(_pAdapter) + { + OSL_ENSURE(m_pAdapter, "OEventListenerImpl::OEventListenerImpl: invalid adapter!"); + // no checks of _rxComp !! + // (OEventListenerAdapter is responsible for this) + + // just in case addEventListener throws an exception ... don't initialize m_xKeepMeAlive before this + // is done + Reference< XEventListener > xMeMyselfAndI = this; + _rxComp->addEventListener(xMeMyselfAndI); + + m_xComponent = _rxComp; + m_xKeepMeAlive = xMeMyselfAndI; + } + + //--------------------------------------------------------------------- + void OEventListenerImpl::dispose() + { + if (m_xComponent.is()) + { + m_xComponent->removeEventListener(m_xKeepMeAlive); + m_xComponent.clear(); + m_xKeepMeAlive.clear(); + } + } + + //--------------------------------------------------------------------- + void SAL_CALL OEventListenerImpl::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + Reference< XEventListener > xDeleteUponLeaving = m_xKeepMeAlive; + m_xKeepMeAlive.clear(); + m_xComponent.clear(); + + m_pAdapter->_disposing(_rSource); + } + + //===================================================================== + //= OEventListenerAdapterImpl + //===================================================================== + struct OEventListenerAdapterImpl + { + public: + ::std::vector< void* > aListeners; + }; + + //===================================================================== + //= OEventListenerAdapter + //===================================================================== + //--------------------------------------------------------------------- + OEventListenerAdapter::OEventListenerAdapter() + :m_pImpl(new OEventListenerAdapterImpl) + { + } + + //--------------------------------------------------------------------- + OEventListenerAdapter::~OEventListenerAdapter() + { + stopAllComponentListening( ); + delete m_pImpl; + m_pImpl = NULL; + } + + //--------------------------------------------------------------------- + void OEventListenerAdapter::stopComponentListening( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _rxComp ) + { + if ( m_pImpl->aListeners.empty() ) + return; + + ::std::vector< void* >::iterator dispose = m_pImpl->aListeners.begin(); + do + { + OEventListenerImpl* pListenerImpl = static_cast< OEventListenerImpl* >( *dispose ); + if ( pListenerImpl->getComponent().get() == _rxComp.get() ) + { + pListenerImpl->dispose(); + pListenerImpl->release(); + dispose = m_pImpl->aListeners.erase( dispose ); + } + else + ++dispose; + } + while ( dispose != m_pImpl->aListeners.end() ); + } + + //--------------------------------------------------------------------- + void OEventListenerAdapter::stopAllComponentListening( ) + { + for ( ::std::vector< void* >::const_iterator aDisposeLoop = m_pImpl->aListeners.begin(); + aDisposeLoop != m_pImpl->aListeners.end(); + ++aDisposeLoop + ) + { + OEventListenerImpl* pListenerImpl = static_cast< OEventListenerImpl* >(*aDisposeLoop); + pListenerImpl->dispose(); + pListenerImpl->release(); + } + m_pImpl->aListeners.clear(); + } + + //--------------------------------------------------------------------- + void OEventListenerAdapter::startComponentListening( const Reference< XComponent >& _rxComp ) + { + if (!_rxComp.is()) + { + OSL_ENSURE(sal_False, "OEventListenerAdapter::startComponentListening: invalid component!"); + return; + } + + OEventListenerImpl* pListenerImpl = new OEventListenerImpl(this, _rxComp); + pListenerImpl->acquire(); + m_pImpl->aListeners.push_back(pListenerImpl); + } + +//......................................................................... +} // namespace utl +//......................................................................... diff --git a/unotools/source/misc/fontcvt.cxx b/unotools/source/misc/fontcvt.cxx new file mode 100644 index 000000000000..2bb682e4915b --- /dev/null +++ b/unotools/source/misc/fontcvt.cxx @@ -0,0 +1,1520 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/fontcvt.hxx> +#include <unotools/fontdefs.hxx> + +#ifndef _STLP_MAP +#include <map> +#endif +#ifndef _STLP_VECTOR +#include <vector> +#endif +#ifndef _STLP_ALGORITHM +#include <algorithm> +#endif +#ifndef _STLP_FUNCTIONAL +#include <functional> +#endif + +//======================================================================= +// note: the character mappings that are only approximations +// are marked (with an empty comment) + +static const sal_Unicode aStarBatsTab[224] = +{ + // F020 + 0x0020, 0x263a, 0x25cf, 0x274d, + 0x25a0, 0x25a1, 0xE000, 0x2751, + 0x2752, 0xE001, 0xE002, 0xE003, + 0x2756, 0xE004, 0xE005, 0x27a2, + // F030 + 0xE006, 0x2794, 0x2713, 0x2612, + 0x2611, 0x27b2, 0x261b, 0x270d, + 0x270e, 0xE007, 0x2714, 0xE008, + 0xE009, 0xE00A, 0x274f, 0x2750, + // F040 + 0xE00B, 0xE00C, 0xE00D, 0xE00E, + 0x2722, 0x2723, 0x2724, 0x2725, + 0x2733, 0x2734, 0x2735, 0x2736, + 0x2737, 0x2738, 0x2739, 0x2717, + // F050 + 0x2718, 0x2719, 0x271a, 0x271b, + 0x271c, 0x272b, 0x272c, 0x272d, + 0x272e, 0x272f, 0x2730, 0, + 0xE00F, 0x278a, 0x278b, 0x278c, + // F060 + 0x278d, 0x278e, 0x278f, 0x2790, + 0x2791, 0x2792, 0x2793, 0xE010, + 0x2780, 0x2781, 0x2782, 0x2783, + 0x2784, 0x2785, 0x2786, 0x2787, + // F070 + 0x2788, 0x2789, 0xE011, 0xE012, + 0x260e, 0xE013, 0xE014, 0xE015, + 0xE016, 0xE017, 0xE018, 0xE019, + 0xE01A, 0x261e, 0xE01B, 0, + // F080 + 0x20ac, 0, 0x201a, 0x0192, + 0x201e, 0x2026, 0x2020, 0x2021, + 0xE01c, 0x2030, 0x0160, 0x2039, + 0x0152, 0, 0x017d, 0, + // F090 + 0, 0x2018, 0x2019, 0x201c, + 0x201d, 0x2022, 0x2013, 0x2014, + 0xE01d, 0x2122, 0x0161, 0x203a, + 0x0153, 0, 0x017e, 0x0178, + // F0A0 + 0, 0x21e7, 0x21e8, 0x21e9, + 0x21e6, 0xE01e, 0xE01f, 0x00a7, + 0xE020, 0xE021, 0xE022, 0x00ab, + 0xE023, 0x2639, 0xE024, 0xE025, + // F0B0 + 0xE026, 0xE027, 0xE028, 0x21e5, + 0x21e4, 0x2192, 0x2193, 0x2190, + 0x2191, 0xE029, 0xE02a, 0x00bb, + 0xE02b, 0xE02c, 0xE02d, 0xE02e, + // F0C0 + 0xE02f, 0xE030, 0xE031, 0xE032, + 0x25be, 0x25b4, 0x25bf, 0x25b5, + 0xE033, 0xE034, 0xE035, 0x2702, + 0x2708, 0x2721, 0x273f, 0x2744, + // F0D0 + 0x25d7, 0x2759, 0xE036, 0xE037, + 0x2762, 0x2663, 0x2665, 0x2660, + 0x2194, 0x2195, 0x2798, 0x279a, + 0x27b8, 0, 0x00b6, 0, + // F0E0 + 0x00a2, 0x00a4, 0x00a5, 0xE038, + 0x20a1, 0x20a2, 0x20a3, 0x20a4, + 0x20a9, 0x20ab, 0x20a8, 0xE039, + 0, 0, 0, 0, + // F0F0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0xE03a +}; + +// ----------------------------------------------------------------------- + +static const sal_Unicode aStarMathTab[224] = +{ + // F020 + 0x0020, 0x0021, 0x0022, 0x0023, + 0xE080, 0x0025, 0x0026, 0x221e, + 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, + // F030 + 0x2224, 0x21d2, 0x21d0, 0x21d4, + 0xE081, 0xE082, 0x00b0, 0, + 0, 0, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x00bf, + // F040 + 0x2260, 0xE083, 0x2212, 0x2217, + 0x00d7, 0x22c5, 0x00f7, 0x00b1, + 0x2213, 0x2295, 0x2296, 0x2297, + 0x2298, 0x2299, 0x222a, 0x2229, + // F050 + 0xE084, 0xE085, 0x2264, 0x2265, + 0xE086, 0xE087, 0x226a, 0x226b, + 0x007e, 0x2243, 0x2248, 0x225d, + 0x2261, 0x221d, 0x2202, 0x2282, + // F060 + 0x2283, 0x2286, 0x2287, 0x2284, + 0x2285, 0x2288, 0x2289, 0x2208, + 0x2209, 0xE089, 0x2203, 0x220d, + 0x2135, 0x2111, 0x211c, 0x2118, + // F070 + 0xE08a, 0x2221, 0x2222, 0x2223, + 0x2225, 0x22a5, 0xE08b, 0x22ef, + 0x22ee, 0x22f0, 0x22f1, 0x22b6, + 0x22b7, 0xE08c, 0x2216, 0x00ac, + // F080 + 0x222b, 0x222c, 0x222d, 0x222e, + 0x222f, 0x2230, 0x221a, 0xE08d, + 0xE08e, 0xE08f, 0x2210, 0x220f, + 0x2211, 0x2207, 0x2200, 0xE090, + // F090 + 0xE091, 0xE092, 0xE093, 0xE094, + 0xE095, 0xE096, 0xE097, 0xE098, + 0x02d9, 0x00a8, 0xE09b, 0x02da, + 0x2227, 0x2228, 0x220b, 0x2205, + // F0A0 + 0x007b, 0x007d, 0xe09e, 0xe09f, + 0x2329, 0x232a, 0x005b, 0x005d, + 0xE0a0, 0x22be, 0xE0a1, 0x2259, + 0x2254, 0x2255, 0x21b3, 0x2197, + // F0B0 + 0x2198, 0x2245, 0x301a, 0x301b, + 0x2373, 0xE0a5, 0xE0a6, 0x22a4, + 0x2112, 0x2130, 0x2131, 0, + 0xE0a7, 0xE0a8, 0xE0a9, 0xE0aa, + // F0C0 + 0x2308, 0x230a, 0x2309, 0x230b, + 0, 0xe0ab, 0xe0ac, 0xe0ad, + 0xe0ae, 0xe0af, 0xe0b0, 0xe0b1, + 0xe0b2, 0xe0b3, 0xe0b4, 0xe0b5, + // F0D0 + 0xe0b6, 0xe0b7, 0xe0b8, 0xe0b9, + 0xe0ba, 0xe0bb, 0xe0bc, 0xe0bd, + 0xe0be, 0xe0bf, 0xe0c0, 0xe0c1, + 0xe0c2, 0xe0c3, 0xe0c4, 0xe0c5, + // F0E0 + 0xe0c6, 0xe0c7, 0xe0c8, 0xe0c9, + 0xe0ca, 0xe0cb, 0xe0cc, 0xe0cd, + 0xe0ce, 0xe0cf, 0xe0d0, 0xe0d1, + 0x03f1, 0xe0d3, 0xe0d4, 0xe0d5, + // F0F0 + 0x2113, 0xe0d6, 0x2107, 0x2127, + 0x210a, 0xe0d9, 0x210f, 0x019b, + 0xe0db, 0xe0dc, 0xe0dd, 0x2115, + 0x2124, 0x211a, 0x211d, 0x2102 +}; + +// ----------------------------------------------------------------------- + +static const sal_Unicode aWingDingsTab[224] = +{ + // F020 + 0x0020, 0xe400, 0xe401, 0xe402, + 0xe403, 0xe404, 0xe405, 0xe406, + 0xe407, 0xe408, 0xe409, 0xe40a, + 0xe40b, 0xe40c, 0xe40d, 0xe40e, + // F030 + 0xe40f, 0xe410, 0xe411, 0xe412, + 0xe413, 0xe414, 0xe415, 0xe416, + 0xe417, 0xe418, 0xe419, 0xe41a, + 0xe41b, 0xe41c, 0x2707, 0xe41d, + // F040 + 0xe41e, 0xe41f, 0xe420, 0xe421, + 0x261c, 0xe423, 0x261d, 0x261f, + 0x261f, 0xe424, 0xe425, 0xe426, + 0xe427, 0xe428, 0xe429, 0xe42a, + // F050 + 0xe42b, 0xe42c, 0x263c, 0xe42d, + 0xe42e, 0xe42f, 0xe430, 0xe431, + 0xe432, 0xe433, 0x262a, 0x262f, + 0x0950, 0xe434, 0x2648, 0x2649, + // F060 + 0x264a, 0x264b, 0x264c, 0x264d, + 0x264e, 0x264f, 0x2650, 0x2651, + 0x2652, 0x2653, 0xe435, 0xe436, + 0xe437, 0xe438, 0xe439, 0xe43a, + // F070 + 0xe43b, 0xe43c, 0xe43d, 0xe43e, + 0xe43f, 0xe440, 0xe441, 0xe442, + 0xe443, 0x2353, 0x2318, 0xe444, + 0xe445, 0xe446, 0xe447, 0, + // F080 + 0xe448, 0xe449, 0xe44a, 0xe44b, + 0xe44c, 0xe44d, 0xe44e, 0xe44f, + 0xe450, 0xe451, 0xe452, 0xe453, + 0xe454, 0xe455, 0xe456, 0xe457, + // F090 + 0xe458, 0xe459, 0xe45a, 0xe45b, + 0xe45c, 0xe45d, 0xe45e, 0xe45f, + 0xe460, 0xe461, 0xe462, 0xe463, + 0xe464, 0xe465, 0xe466, 0xe467, + // F0a0 + 0xe468, 0xe469, 0xe46a, 0xe46b, + 0xe46c, 0xe46d, 0xe46e, 0xe46f, + 0xe470, 0xe471, 0xe472, 0xe473, + 0xe474, 0xe475, 0xe476, 0xe477, + // F0b0 + 0xe478, 0xe479, 0xe47a, 0xe47b, + 0xe47c, 0xe47d, 0xe47e, 0xe47f, + 0xe480, 0xe481, 0xe482, 0xe483, + 0xe484, 0xe485, 0xe486, 0xe487, + // F0c0 + 0xe488, 0xe489, 0xe48a, 0xe48b, + 0xe48c, 0xe48d, 0xe48e, 0xe48f, + 0xe490, 0xe491, 0xe492, 0xe493, + 0xe494, 0xe495, 0xe496, 0xe497, + // F0d0 + 0xe498, 0xe499, 0xe49a, 0xe49b, + 0xe49c, 0x232b, 0x2326, 0xe49d, + 0xe49e, 0xe49f, 0xe4a0, 0xe4a1, + 0xe4a2, 0xe4a3, 0xe4a4, 0xe4a5, + // F0e0 + 0xe4a6, 0xe4a7, 0xe4a8, 0xe4a9, + 0xe4aa, 0xe4ab, 0xe4ac, 0xe4ad, + 0xe4ae, 0xe4af, 0xe4b0, 0xe4b1, + 0xe4b2, 0xe4b3, 0xe4b4, 0xe4b5, + // F0f0 + 0xe4b6, 0xe4b7, 0xe4b8, 0xe4b9, + 0xe4ba, 0xe4bb, 0xe4bc, 0xe4bd, + 0xe4be, 0xe4bf, 0xe4c0, 0xe4c1, + 0xe4c2, 0xe4c3, 0xe4c4, 0xe4c5 +}; + +// ----------------------------------------------------------------------- + +static const sal_Unicode aWingDings2Tab[224] = +{ + // F020 + 0x0020, 0xe500, 0xe501, 0xe502, + 0xe503, 0xe504, 0xe505, 0xe506, + 0xe507, 0xe508, 0xe509, 0xe50a, + 0xe50b, 0xe50c, 0xe50d, 0xe50e, + // F030 + 0xe50f, 0xe510, 0xe511, 0xe512, + 0xe513, 0xe514, 0xe515, 0xe516, + 0xe517, 0xe518, 0xe519, 0xe51a, + 0xe51b, 0xe51c, 0xe51d, 0xe51e, + // F040 + 0xe51f, 0xe520, 0xe521, 0xe522, + 0xe523, 0xe524, 0xe525, 0xe526, + 0xe527, 0xe528, 0xe529, 0xe52a, + 0xe52b, 0xe52c, 0xe52d, 0xe52e, + // F050 + 0xe52f, 0xe530, 0xe531, 0xe532, + 0xe533, 0xe534, 0xe535, 0xe536, + 0xe537, 0x203D, 0x203D, 0x203D, + 0xe53b, 0xe53c, 0xe53d, 0xe53e, + // F060 + 0xe53f, 0xe540, 0xe541, 0xe542, + 0xe543, 0xe544, 0xe545, 0xe546, + 0xe547, 0x24EA, 0x2460, 0x2461, + 0x2462, 0x2463, 0x2464, 0x2465, + // F070 + 0x2466, 0x2467, 0x2468, 0x2469, + 0xE453, 0x278A, 0x278B, 0x278C, + 0x278D, 0x278E, 0x278F, 0x2790, + 0x2791, 0x2792, 0x2793, 0, + // F080 + 0x2609, 0x25cb, 0x263d, 0x263e, + 0xe55d, 0xe55e, 0xe55f, 0xe560, + 0xe561, 0xe562, 0xe563, 0xe564, + 0xe565, 0xe566, 0xe567, 0xe568, + // F090 + 0xe569, 0xe56a, 0xe56b, 0xe56c, + 0xe56d, 0xe56e, 0xe56f, 0xe570, + 0xe571, 0xe572, 0xe573, 0xe574, + 0xe575, 0xe576, 0xe577, 0xe578, + // F0a0 + 0xe579, 0xe57a, 0xe57b, 0xe57c, + 0xe57d, 0xe57e, 0xe57f, 0xe580, + 0xe581, 0xe582, 0xe583, 0xe584, + 0xe585, 0xe586, 0xe587, 0xe588, + // F0b0 + 0xe589, 0xe58a, 0xe58b, 0xe58c, + 0xe58d, 0xe58e, 0xe58f, 0xe590, + 0xe591, 0xe592, 0xe593, 0xe594, + 0xe595, 0xe596, 0xe597, 0xe598, + // F0c0 + 0xe599, 0xe59a, 0xe59b, 0xe59c, + 0xe59d, 0xe59e, 0xe59f, 0xe5a0, + 0xe5a1, 0xe5a2, 0xe5a3, 0xe5a4, + 0xe5a5, 0xe5a6, 0xe5a7, 0xe5a8, + // F0d0 + 0xe5a9, 0xe5aa, 0xe5ab, 0xe5ac, + 0xe5ad, 0xe5ae, 0xe5af, 0xe5b0, + 0xe5b1, 0xe5b2, 0xe5b3, 0xe5b4, + 0xe5b5, 0xe5b6, 0xe5b7, 0xe5b8, + // F0e0 + 0xe5b9, 0xe5ba, 0xe5bb, 0xe5bc, + 0xe5bd, 0xe5be, 0xe5bf, 0xe5c0, + 0xe5c1, 0xe5c2, 0xe5c3, 0xe5c4, + 0xe5c5, 0xe5c6, 0xe5c7, 0xe5c8, + // F0f0 + 0xe5c9, 0x2022, 0xe5cb, 0xe5cc, + 0xe5cd, 0xe5ce, 0xe5cf, 0xe5d0, + 0x203b, 0x2042, 0, 0, + 0, 0, 0, 0 +}; + +// ----------------------------------------------------------------------- + +static const sal_Unicode aWingDings3Tab[224] = +{ + // F020 + 0x0020, 0xe600, 0xe601, 0xe602, + 0xe603, 0x2196, 0xe604, 0x2199, + 0xe605, 0xe606, 0xe607, 0xe608, + 0xe609, 0xe60a, 0xe60b, 0x21de, + // F030 + 0x21df, 0xe60c, 0xe60d, 0xe60e, + 0x21e2, 0x21e1, 0x21e3, 0x21af, + 0x21b5, 0xe60f, 0xe610, 0xe611, + 0xe612, 0xe613, 0xe614, 0xe615, + // F040 + 0xe616, 0xe617, 0xe618, 0xe619, + 0x21c4, 0x21c5, 0xe61a, 0xe61b, + 0x21c7, 0x21c9, 0x21c8, 0x21ca, + 0x21b6, 0x21b7, 0xe61c, 0xe61d, + // F050 + 0x21bb, 0x21ba, 0xe61e, 0x2324, + 0x2303, 0x2325, 0x2334, 0xe61f, + 0x21ea, 0xe620, 0xe621, 0xe622, + 0xe623, 0xe624, 0xe625, 0xe626, + // F060 + 0xe627, 0xe628, 0xe629, 0xe62a, + 0xe62b, 0xe62c, 0xe62d, 0xe62e, + 0xe62f, 0xe630, 0xe631, 0xe632, + 0xe633, 0xe634, 0xe635, 0xe636, + // F070 + 0xe637, 0xe638, 0x25b3, 0x25bd, + 0x25c0, 0x25b6, 0x25c1, 0x25b7, + 0x25e3, 0xe639, 0x25e4, 0x25e5, + 0x25c2, 0x25b8, 0xe63a, 0, + // F080 + 0xe63b, 0xe63c, 0xe63d, 0xe63e, + 0xe63f, 0xe640, 0xe641, 0xe642, + 0xe643, 0xe644, 0xe645, 0xe646, + 0xe647, 0xe648, 0xe649, 0xe64a, + // F090 + 0xe64b, 0xe64c, 0xe64d, 0xe64e, + 0xe64f, 0xe650, 0xe651, 0xe652, + 0xe653, 0xe654, 0xe655, 0xe656, + 0xe657, 0xe658, 0xe659, 0xe65a, + // F0a0 + 0xe65b, 0xe65c, 0xe65d, 0xe65e, + 0xe65f, 0xe660, 0xe661, 0xe662, + 0xe663, 0xe664, 0xe665, 0xe666, + 0xe667, 0xe668, 0xe669, 0xe66a, + // F0b0 + 0xe66b, 0xe66c, 0xe66d, 0xe66e, + 0xe66f, 0xe670, 0xe671, 0xe672, + 0xe673, 0xe674, 0xe675, 0xe676, + 0xe677, 0xe678, 0xe679, 0xe67a, + // F0c0 + 0xe67b, 0xe67c, 0xe67d, 0xe67e, + 0xe67f, 0xe680, 0xe681, 0xe682, + 0xe683, 0xe684, 0xe685, 0xe686, + 0xe687, 0xe688, 0xe689, 0xe68a, + // F0d0 + 0xe68b, 0xe68c, 0xe68d, 0xe68e, + 0xe68f, 0xe690, 0xe691, 0xe692, + 0xe693, 0xe694, 0xe695, 0xe696, + 0xe697, 0xe698, 0xe699, 0xe69a, + // F0e0 + 0xe69b, 0xe69c, 0xe69d, 0xe69e, + 0xe69f, 0xe6a0, 0xe6a1, 0xe6a2, + 0xe6a3, 0xe6a4, 0xe6a5, 0xe6a6, + 0xe6a7, 0xe6a8, 0xe6a9, 0xe6aa, + // F0f0 + 0xe6ab, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +// ----------------------------------------------------------------------- + +static const sal_Unicode aWebDingsTab[224] = +{ + // F020 + 0x0020, 0xe300, 0xe301, 0xe302, + 0xe303, 0xe304, 0xe305, 0xe306, + 0xe307, 0xe308, 0xe309, 0xe30a, + 0xe30b, 0xe30c, 0xe30d, 0xe30e, + // F030 + 0xe30f, 0xe310, 0xe311, 0xe312, + 0xe313, 0xe314, 0xe315, 0xe316, + 0xe317, 0xe318, 0xe319, 0xe31a, + 0xe31b, 0xe31c, 0xe31d, 0xe31e, + // F040 + 0xe31f, 0xe320, 0xe321, 0xe322, + 0xe323, 0xe324, 0xe325, 0xe326, + 0xe327, 0xe328, 0xe329, 0xe32a, + 0xe32b, 0xe32c, 0xe32d, 0xe32e, + // F050 + 0xe32f, 0xe330, 0xe331, 0xe332, + 0xe333, 0xe334, 0xe335, 0xe336, + 0xe337, 0xe338, 0xe339, 0xe33a, + 0xe33b, 0xe33c, 0xe33d, 0xe33e, + // F060 + 0xe33f, 0xe340, 0xe341, 0xe342, + 0xe343, 0xe344, 0xe345, 0xe346, + 0xe347, 0xe348, 0xe349, 0xe34a, + 0xe34b, 0xe34c, 0xe34d, 0xe34e, + // F070 + 0xe34f, 0xe350, 0xe351, 0xe352, + 0xe353, 0xe354, 0xe355, 0xe356, + 0xe357, 0xe358, 0xe359, 0xe35a, + 0xe35b, 0xe35c, 0xe35d, 0, + // F080 + 0xe35e, 0xe35f, 0xe360, 0xe361, + 0xe362, 0xe363, 0xe364, 0xe365, + 0xe366, 0xe367, 0xe368, 0xe369, + 0xe36a, 0xe36b, 0xe36c, 0xe36d, + // F090 + 0xe36e, 0xe36f, 0xe370, 0xe371, + 0xe372, 0xe373, 0xe374, 0xe375, + 0xe376, 0xe377, 0xe378, 0xe379, + 0xe37a, 0xe37b, 0xe37c, 0xe37d, + // F0a0 + 0xe37e, 0xe37f, 0xe380, 0xe381, + 0xe382, 0xe383, 0xe384, 0xe385, + 0xe386, 0xe387, 0xe388, 0xe389, + 0xe38a, 0xe38b, 0xe38c, 0xe38d, + // F0b0 + 0xe38e, 0xe38f, 0xe390, 0xe391, + 0xe392, 0xe393, 0xe394, 0xe395, + 0xe396, 0xe397, 0xe398, 0xe399, + 0xe39a, 0xe39b, 0xe39c, 0xe39d, + // F0c0 + 0xe39e, 0xe39f, 0xe3a0, 0xe3a1, + 0xe3a2, 0xe3a3, 0xe3a4, 0xe3a5, + 0xe3a6, 0xe3a7, 0xe3a8, 0xe3a9, + 0xe3aa, 0xe3ab, 0xe3ac, 0xe3ad, + // F0d0 + 0xe3ae, 0xe3af, 0xe3b0, 0xe3b1, + 0xe3b2, 0xe3b3, 0xe3b4, 0xe3b5, + 0xe3b6, 0xe3b7, 0xe3b8, 0xe3b9, + 0xe3ba, 0xe3bb, 0xe3bc, 0xe3bd, + // F0e0 + 0xe3be, 0xe3bf, 0xe3c0, 0xe3c1, + 0xe3c2, 0xe3c3, 0xe3c4, 0xe3c5, + 0xe3c6, 0xe3c7, 0xe3c8, 0xe3c9, + 0xe3ca, 0xe3cb, 0xe3cd, 0xe3ce, + // F0f0 + 0xe3cf, 0xe3d0, 0xe3d1, 0xe3d2, + 0xe3d3, 0xe3d4, 0xe3d5, 0xe3d6, + 0xe3d7, 0xe3d8, 0xe3d9, 0xe3da, + 0xe3db, 0xe3dc, 0xe3dd, 0xe3de +}; + +// ----------------------------------------------------------------------- + +static const sal_Unicode aAdobeSymbolTab[224] = +{ +//TODO: + // F020 + 0x0020, 0xe100, 0xe101, 0xe102, + 0xe103, 0xe104, 0xe16a, 0xe105, + 0xe106, 0xe107, 0xe108, 0xe109, + 0xe10a, 0xe10b, 0xe10c, 0xe10d, + // F030 + 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0xe10e, 0xe10f, + 0xe110, 0xe111, 0xe112, 0x003f, + // F040 + 0xe113, 0x0391, 0x0392, 0x03a7, + 0x0394, 0x0395, 0x03a6, 0x0393, + 0x0397, 0x0399, 0x03d1, 0x039a, + 0x039b, 0x039c, 0x039d, 0x039f, + // F050 + 0x03a0, 0x0398, 0x03a1, 0x03a3, + 0x03a4, 0x03a5, 0x03c2, 0x03a9, + 0x039e, 0x03a8, 0x0396, 0xe114, + 0x2234, 0xe115, 0xe116, 0x005f, + // F060 + 0x00af, 0x03b1, 0x03b2, 0x03c7, + 0x03b4, 0x03b5, 0x03d5, 0x03b3, + 0x03b7, 0x03b9, 0x03c6, 0x03ba, + 0x03bb, 0x03bc, 0x03bd, 0x03bf, + // F070 + 0x03c0, 0x03b8, 0x03c1, 0x03c3, + 0x03c4, 0x03c5, 0x03d6, 0x03c9, + 0x03be, 0x03c8, 0x03b6, 0xe117, + 0x007c, 0xe118, 0xe119, 0, + // F080 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F090 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0a0 + 0xe11a, 0x03d2, 0x0384, 0xe11b, + 0x2215, 0xe11c, 0xe11d, 0xe11e, + 0x2666, 0xe11f, 0xe120, 0xe121, + 0xe122, 0xe123, 0xe124, 0xe125, + // F0b0 + 0xe126, 0xe127, 0x2033, 0xe128, + 0xe129, 0xe12a, 0xe12b, 0xe12c, + 0xe12d, 0xe12e, 0xe12f, 0xe130, + 0xe131, 0x2502, 0x2500, 0x21b2, + // F0c0 + 0xe132, 0xe133, 0xe134, 0xe135, + 0xe136, 0xe137, 0xe138, 0xe139, + 0xe13a, 0xe13b, 0xe13c, 0xe13d, + 0xe13e, 0xe13f, 0xe140, 0xe141, + // F0d0 + 0x2220, 0xe142, 0x00ae, 0x00a9, + 0xe143, 0xe144, 0xe145, 0xe146, + 0xe147, 0xe148, 0xe149, 0xe14a, + 0xe14b, 0x21d1, 0xe14c, 0x21d3, + // F0e0 + 0x25ca, 0xe14d, 0xe14e, 0xe14f, + 0xe150, 0xe151, 0xe152, 0xe153, + 0xe154, 0xe155, 0xe156, 0xe157, + 0xe158, 0xe159, 0xe15a, 0xe15b, + // F0f0 + 0, 0xe15c, 0xe15d, 0xe15e, + 0xe15f, 0xe160, 0xe161, 0xe162, + 0xe163, 0xe164, 0xe165, 0xe166, + 0xe167, 0xe168, 0xe169, 0, +}; + +// ----------------------------------------------------------------------- + +static const sal_Unicode aMonotypeSortsTab[224] = +{ + // F020 + 0x0020, 0x2701, 0xe200, 0x2703, + 0x2704, 0xe201, 0x2706, 0xe202, + 0xe203, 0xe203, 0xe204, 0xe205, + 0x270c, 0xe206, 0xe207, 0xe208, + // F030 + 0x2710, 0x2711, 0x2712, 0xe209, + 0xe20a, 0x2715, 0x2716, 0xe20b, + 0xe20c, 0xe20d, 0xe20e, 0xe20f, + 0xe210, 0x271d, 0x271e, 0x271f, + // F040 + 0x2720, 0xe211, 0xe212, 0xe213, + 0xe214, 0xe215, 0x2726, 0x2727, + 0x2605, 0x2729, 0x272a, 0xe216, + 0xe217, 0xe218, 0xe219, 0xe21a, + // F050 + 0xe21b, 0xe21c, 0x2732, 0xe21d, + 0xe21e, 0xe21f, 0xe220, 0xe221, + 0xe222, 0xe223, 0x273a, 0x273b, + 0x273c, 0x273d, 0x273e, 0xe224, + // F060 + 0x2740, 0x2741, 0x2742, 0x2743, + 0xe225, 0x2745, 0x2746, 0x2747, + 0x2748, 0x2749, 0x274a, 0x274b, + 0xe226, 0xe227, 0xe228, 0xe229, + // F070 + 0xe22a, 0xe22b, 0xe22c, 0x25b2, + 0x25bc, 0xe22d, 0xe22e, 0xe22f, + 0x2758, 0xe230, 0x275a, 0x275b, + 0x275c, 0x275d, 0x275e, 0, + // F080 + 0xe231, 0xe232, 0xe233, 0xe234, + 0xe235, 0xe236, 0xe237, 0xe238, + 0xe239, 0xe23a, 0xe23b, 0xe23c, + 0xe23d, 0xe23e, 0, 0, + // F090 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0a0 + 0, 0xe23f, 0xe240, 0x2763, + 0x2764, 0x2765, 0x2766, 0x2767, + 0xe241, 0xe242, 0xe243, 0xe244, + 0x2460, 0x2461, 0x2462, 0x2463, + // F0b0 + 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0x2776, 0x2777, + 0x2778, 0x2779, 0x277a, 0x277b, + 0x277c, 0x277d, 0x277e, 0x277f, + // F0c0 + 0xe245, 0xe246, 0xe247, 0xe248, + 0xe249, 0xe24a, 0xe24b, 0xe24c, + 0xe24d, 0xe24e, 0xe24f, 0xe250, + 0xe251, 0xe252, 0xe253, 0xe254, + // F0d0 + 0xe255, 0xe256, 0xe257, 0xe258, + 0xe259, 0xe25a, 0xe25b, 0xe25c, + 0xe25d, 0x2799, 0xe25e, 0x279b, + 0x279c, 0x279d, 0x279e, 0x279f, + // F0e0 + 0x27a0, 0x27a1, 0xe25f, 0x27a3, + 0x27a4, 0x27a5, 0x27a6, 0x27a7, + 0x27a8, 0x27a9, 0x27aa, 0x27ab, + 0x27ac, 0x27ad, 0x27ae, 0x27af, + // F0f0 + 0, 0x27b1, 0xe260, 0x27b3, + 0x27b4, 0x27b5, 0x27b6, 0x27b7, + 0xe261, 0x27b9, 0x27ba, 0x27bb, + 0x27bc, 0x27bd, 0x27be, 0, +}; + +// ----------------------------------------------------------------------- + +/* +static const sal_Unicode aMonotypeSorts2Tab[224] = +{ +//TODO: + // F020 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F030 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F040 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F050 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F060 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F070 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F080 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F090 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0a0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0b0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0c0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0d0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0e0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0f0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +}; +*/ + +static const sal_Unicode aMTExtraTab[224] = +{ + // F020 + 0x0020, 0, 0, 0xE095, + 0xE091, 0xE096, 0x02D9, 0, + 0xE093, 0, 0, 0, + 0, 0, 0, 0, + // F030 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0x25C1, 0, 0x25B7, 0, + // F040 + 0, 0, 0x2210, 0x019b, + 0, 0, 0, 0, + 0, 0x2229, 0, 0xE08B, + 0x22EF, 0x22EE, 0x22F0, 0x22F1, + // F050 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F060 + 0xE095, 0, 0xE25C, 0xE4BA, + 0, 0, 0x210F, 0, + 0, 0, 0, 0, + 0x2113, 0x2213, 0, 0x00B0, + // F070 + 0, 0, 0xE098, 0, + 0, 0xE097, 0, 0, + 0, 0, 0, 0xE081, + 0, 0xE082, 0, 0, + // F080 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F090 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0a0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0b0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0c0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0d0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0e0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // F0f0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 +}; + + +//======================================================================= + +static sal_Unicode ImplStarSymbolToStarBats( sal_Unicode c ) +{ + switch ( c ) + { + case 0x00A2: c = 0xF0E0; break; + case 0x00A4: c = 0xF0E1; break; + case 0x00A5: c = 0xF0E2; break; + case 0x00A7: c = 0xF0A7; break; + case 0x00AB: c = 0xF0AB; break; + case 0x00B6: c = 0xF0DE; break; + case 0x00BB: c = 0xF0BB; break; + + case 0x0152: c = 0xF08C; break; + case 0x0153: c = 0xF09C; break; + case 0x0160: c = 0xF08A; break; + case 0x0161: c = 0xF09A; break; + case 0x0178: c = 0xF09F; break; + case 0x017D: c = 0xF08E; break; + case 0x017E: c = 0xF09E; break; + + case 0x0192: c = 0xF083; break; + case 0x02C6: c = 0xF088; break; + case 0x02DC: c = 0xF098; break; + case 0x2013: c = 0xF096; break; + case 0x2014: c = 0xF097; break; + case 0x2018: c = 0xF091; break; + + case 0x2019: c = 0xF092; break; + case 0x201A: c = 0xF082; break; + case 0x201C: c = 0xF093; break; + case 0x201D: c = 0xF094; break; + case 0x201E: c = 0xF084; break; + case 0x2020: c = 0xF086; break; + + case 0x2021: c = 0xF087; break; + case 0x2022: c = 0xF095; break; + case 0x2026: c = 0xF085; break; + case 0x2030: c = 0xF089; break; + case 0x2039: c = 0xF08B; break; + case 0x203A: c = 0xF09B; break; + + case 0x20A1: c = 0xF0E4; break; + case 0x20A2: c = 0xF0E5; break; + case 0x20A3: c = 0xF0E6; break; + case 0x20A4: c = 0xF0E7; break; + case 0x20A8: c = 0xF0EA; break; + case 0x20A9: c = 0xF0E8; break; + case 0x20AB: c = 0xF0E9; break; + case 0x20AC: c = 0xF080; break; + + case 0x2122: c = 0xF099; break; + case 0x2190: c = 0xF0B7; break; + case 0x2191: c = 0xF0B8; break; + case 0x2192: c = 0xF0B5; break; + case 0x2193: c = 0xF0B6; break; + case 0x2194: c = 0xF0D8; break; + case 0x2195: c = 0xF0D9; break; + + case 0x21E4: c = 0xF0B4; break; + case 0x21E5: c = 0xF0B3; break; + case 0x21E6: c = 0xF0A4; break; + case 0x21E7: c = 0xF0B2; break; + case 0x21E8: c = 0xF0AF; break; + case 0x21E9: c = 0xF0A3; break; + + case 0x25A0: c = 0xF024; break; + case 0x25A1: c = 0xF025; break; + case 0x25B4: c = 0xF0C5; break; + case 0x25B5: c = 0xF0C7; break; + case 0x25BE: c = 0xF0C4; break; + case 0x25BF: c = 0xF0C6; break; + case 0x25C6: c = 0xF043; break; + case 0x25CF: c = 0xF022; break; + case 0x25D7: c = 0xF0D0; break; + + case 0x260E: c = 0xF074; break; + case 0x2611: c = 0xF034; break; + case 0x2612: c = 0xF033; break; + case 0x261B: c = 0xF036; break; + case 0x261E: c = 0xF07D; break; + case 0x2639: c = 0xF0AD; break; + case 0x263A: c = 0xF021; break; + + case 0x2702: c = 0xF0CB; break; + case 0x2708: c = 0xF0CC; break; + case 0x270D: c = 0xF07E; break; + case 0x270E: c = 0xF038; break; + + case 0x2713: c = 0xF039; break; + case 0x2714: c = 0xF03A; break; + case 0x2717: c = 0xF04F; break; + case 0x2718: c = 0xF050; break; + case 0x2719: c = 0xF051; break; + case 0x271A: c = 0xF052; break; + case 0x271B: c = 0xF053; break; + case 0x271C: c = 0xF054; break; + + case 0x2721: c = 0xF0CD; break; + case 0x2722: c = 0xF044; break; + case 0x2723: c = 0xF045; break; + case 0x2724: c = 0xF046; break; + case 0x2725: c = 0xF047; break; + case 0x272B: c = 0xF055; break; + case 0x272C: c = 0xF056; break; + case 0x272D: c = 0xF057; break; + case 0x272E: c = 0xF058; break; + case 0x272F: c = 0xF059; break; + + case 0x2730: c = 0xF05A; break; + case 0x2733: c = 0xF048; break; + case 0x2734: c = 0xF049; break; + case 0x2735: c = 0xF04A; break; + case 0x2736: c = 0xF04B; break; + case 0x2737: c = 0xF04C; break; + case 0x2738: c = 0xF04D; break; + case 0x2739: c = 0xF04E; break; + case 0x273F: c = 0xF0CE; break; + + case 0x2744: c = 0xF0CF; break; + case 0x274D: c = 0xF023; break; + case 0x274F: c = 0xF03E; break; + case 0x2750: c = 0xF03F; break; + case 0x2751: c = 0xF027; break; + case 0x2752: c = 0xF028; break; + case 0x2756: c = 0xF02C; break; + case 0x2759: c = 0xF0D1; break; + case 0x2762: c = 0xF0D4; break; + + case 0x2780: c = 0xF068; break; + case 0x2781: c = 0xF069; break; + case 0x2782: c = 0xF06A; break; + case 0x2783: c = 0xF06B; break; + case 0x2784: c = 0xF06C; break; + case 0x2785: c = 0xF06D; break; + case 0x2786: c = 0xF06E; break; + case 0x2787: c = 0xF06F; break; + case 0x2788: c = 0xF070; break; + case 0x2789: c = 0xF071; break; + case 0x278A: c = 0xF05D; break; + case 0x278B: c = 0xF05E; break; + case 0x278C: c = 0xF05F; break; + case 0x278D: c = 0xF060; break; + case 0x278E: c = 0xF061; break; + case 0x278F: c = 0xF062; break; + + case 0x2790: c = 0xF063; break; + case 0x2791: c = 0xF064; break; + case 0x2792: c = 0xF065; break; + case 0x2793: c = 0xF066; break; + case 0x2794: c = 0xF031; break; + case 0x2798: c = 0xF0DA; break; + case 0x279A: c = 0xF0DB; break; + + case 0x27A2: c = 0xF02F; break; + case 0x27B2: c = 0xF035; break; + case 0x27B8: c = 0xF0DC; break; + + case 0xE000: c = 0xF000+38; break; + case 0xE001: c = 0xF000+41; break; + case 0xE002: c = 0xF000+42; break; + case 0xE003: c = 0xF000+43; break; + case 0xE004: c = 0xF000+45; break; + case 0xE005: c = 0xF000+46; break; + case 0xE006: c = 0xF000+48; break; + case 0xE007: c = 0xF000+57; break; + + case 0xE008: c = 0xF000+59; break; + case 0xE009: c = 0xF000+60; break; + case 0xE00a: c = 0xF000+61; break; + case 0xE00b: c = 0xF000+64; break; + case 0xE00c: c = 0xF000+65; break; + case 0xE00d: c = 0xF000+66; break; + case 0xE00e: c = 0xF000+67; break; + case 0xE00f: c = 0xF000+92; break; + + case 0xE010: c = 0xF000+103; break; + case 0xE011: c = 0xF000+114; break; + case 0xE012: c = 0xF000+115; break; + case 0xE013: c = 0xF000+117; break; + case 0xE014: c = 0xF000+118; break; + case 0xE015: c = 0xF000+119; break; + case 0xE016: c = 0xF000+120; break; + case 0xE017: c = 0xF000+121; break; + + case 0xE018: c = 0xF000+122; break; + case 0xE019: c = 0xF000+123; break; + case 0xE01a: c = 0xF000+124; break; + case 0xE01b: c = 0xF000+126; break; + case 0xE01c: c = 0xF000+136; break; + case 0xE01d: c = 0xF000+155; break; + case 0xE01e: c = 0xF000+165; break; + case 0xE01f: c = 0xF000+166; break; + + case 0xE020: c = 0xF000+168; break; + case 0xE021: c = 0xF000+169; break; + case 0xE022: c = 0xF000+170; break; + case 0xE023: c = 0xF000+172; break; + case 0xE024: c = 0xF000+174; break; + case 0xE025: c = 0xF000+175; break; + case 0xE026: c = 0xF000+176; break; + case 0xE027: c = 0xF000+177; break; + + case 0xE028: c = 0xF000+178; break; + case 0xE029: c = 0xF000+185; break; + case 0xE02a: c = 0xF000+186; break; + case 0xE02b: c = 0xF000+188; break; + case 0xE02c: c = 0xF000+189; break; + case 0xE02d: c = 0xF000+190; break; + case 0xE02e: c = 0xF000+191; break; + case 0xE02f: c = 0xF000+192; break; + + case 0xE030: c = 0xF000+193; break; + case 0xE031: c = 0xF000+194; break; + case 0xE032: c = 0xF000+195; break; + case 0xE033: c = 0xF000+200; break; + case 0xE034: c = 0xF000+201; break; + case 0xE035: c = 0xF000+202; break; + case 0xE036: c = 0xF000+210; break; + case 0xE037: c = 0xF000+211; break; + + case 0xE038: c = 0xF000+227; break; + case 0xE039: c = 0xF000+235; break; + case 0xE03a: c = 0xF000+255; break; + + default: c = 0; break; + } + + return c; +} + +enum SymbolFont +{ + Symbol=1, Wingdings=2, MonotypeSorts=4, Webdings=8, Wingdings2=16, + Wingdings3=32, MTExtra=64, TimesNewRoman=128 +}; + +const char *aSymbolNames[] = +{ + "Symbol", "Wingdings", "Monotype Sorts", "Webdings", "Wingdings 2", + "Wingdings 3", "MT Extra", "Times New Roman" +}; + +struct SymbolEntry +{ + sal_uInt8 cIndex; + enum SymbolFont eFont; +}; + +class StarSymbolToMSMultiFontImpl : public StarSymbolToMSMultiFont +{ +private: + ::std::multimap<sal_Unicode, SymbolEntry> maMagicMap; +public: + StarSymbolToMSMultiFontImpl(bool bPerfectOnly); + String ConvertChar(sal_Unicode &rChar); + String ConvertString(String &rString, xub_StrLen& rIndex); +}; + +struct ExtraTable { sal_Unicode cStar; sal_uInt8 cMS;}; + +ExtraTable aWingDingsExtraTab[] = +{ + {0x25cf, 0x6C}, {0x2714, 0xFC}, {0x2717, 0xFB}, {0x2794, 0xE8}, + {0x27a2, 0xD8}, {0xe000, 0x6F}, {0xe001, 0x73}, {0xe002, 0x74}, + {0xe003, 0x75}, {0xe004, 0x77}, {0xe005, 0xA6}, {0xe006, 0xE0}, + {0xe007, 0xFC}, {0xe008, 0x6C}, {0xe009, 0x6D}, {0xe00a, 0x6E}, + {0xe00b, 0x72}, {0xe00c, 0x75}, {0xe00d, 0x76}, {0xe00e, 0x74}, + {0xe00f, 0x8B}, {0xe010, 0x80}, {0xe011, 0x2B}, {0xe012, 0x3A}, + {0xe013, 0x5D}, {0xe014, 0x29}, {0xe015, 0x3A}, {0xe016, 0x3C}, + {0xe017, 0x38}, {0xe018, 0x3A}, {0xe019, 0x2A}, {0xe01a, 0x2B}, + {0xe01b, 0x3F}, {0xe01c, 0x9F}, {0xe01d, 0x80}, {0xe01e, 0x8B}, + {0xe023, 0x4A}, {0xe025, 0xF0}, {0xe026, 0xF2}, {0xe027, 0xEF}, + {0xe028, 0xF1}, {0xe029, 0x52}, {0xe02a, 0x29}, {0xe02b, 0xE0}, + {0xe02c, 0xE2}, {0xe02d, 0xDF}, {0xe02e, 0xE1}, {0xe02f, 0xAC}, + {0xe030, 0xAD}, {0xe031, 0xAE}, {0xe032, 0x7C}, {0xe033, 0x43}, + {0xe034, 0x4D}, {0xe0aa, 0x71}, {0xe422, 0x44} +}; + +ExtraTable aSymbolExtraTab2[] = +{ + {0x0020, 0x20}, {0x00A0, 0x20}, {0x0021, 0x21}, {0x2200, 0x22}, + {0x0023, 0x23}, {0x2203, 0x24}, {0x0025, 0x25}, {0x0026, 0x26}, + {0x220B, 0x27}, {0x0028, 0x28}, {0x0029, 0x29}, {0x2217, 0x2A}, + {0x002B, 0x2B}, {0x002C, 0x2C}, {0x2212, 0x2D}, {0x002E, 0x2E}, + {0x002F, 0x2F}, {0x003A, 0x3A}, {0x003B, 0x3B}, {0x003C, 0x3C}, + {0x003D, 0x3D}, {0x003E, 0x3E}, {0x2245, 0x40}, {0x2206, 0x44}, + {0x2126, 0x57}, {0x005B, 0x5B}, {0x005D, 0x5D}, {0x22A5, 0x5E}, + {0x03C6, 0x66}, {0x03D5, 0x6A}, {0x00B5, 0x6D}, {0x007B, 0x7B}, + {0x007C, 0x7C}, {0x007D, 0x7D}, {0x223C, 0x7E}, {0x20AC, 0xA0}, + {0x2032, 0xA2}, {0x2264, 0xA3}, {0x2044, 0xA4}, {0x221E, 0xA5}, + {0x0192, 0xA6}, {0x2663, 0xA7}, {0x2665, 0xA9}, {0x2660, 0xAA}, + {0x2194, 0xAB}, {0x2190, 0xAC}, {0x2191, 0xAD}, {0x2192, 0xAE}, + {0x2193, 0xAF}, {0x00B0, 0xB0}, {0x00B1, 0xB1}, {0x2265, 0xB3}, + {0x00D7, 0xB4}, {0x221D, 0xB5}, {0x2202, 0xB6}, {0x2022, 0xB7}, + {0x00F7, 0xB8}, {0x2260, 0xB9}, {0x2261, 0xBA}, {0x2248, 0xBB}, + {0x2026, 0xBC}, {0x21B5, 0xBF}, {0x2135, 0xC0}, {0x2111, 0xC1}, + {0x211C, 0xC2}, {0x2118, 0xC3}, {0x2297, 0xC4}, {0x2295, 0xC5}, + {0x2205, 0xC6}, {0x2229, 0xC7}, {0x222A, 0xC8}, {0x2283, 0xC9}, + {0x2287, 0xCA}, {0x2284, 0xCB}, {0x2282, 0xCC}, {0x2286, 0xCD}, + {0x2208, 0xCE}, {0x2209, 0xCF}, {0x2207, 0xD1}, {0x220F, 0xD5}, + {0x221A, 0xD6}, {0x22C5, 0xD7}, {0x00AC, 0xD8}, {0x2227, 0xD9}, + {0x2228, 0xDA}, {0x21D4, 0xDB}, {0x21D0, 0xDC}, {0x21D2, 0xDE}, + {0x2329, 0xE1}, {0x2211, 0xE5}, {0x232A, 0xF1}, {0x222B, 0xF2}, + {0x2320, 0xF3}, {0x2321, 0xF5}, {0x2013, 0x2D} +}; + +ExtraTable aSymbolExtraTab[] = +{ + {0xe021, 0xD3}, {0xe024, 0xD2}, {0xe035, 0x20}, {0xe036, 0x28}, + {0xe037, 0x29}, {0xe039, 0x20}, {0xe083, 0x2B}, {0xe084, 0x3C}, + {0xe085, 0x3E}, {0xe086, 0xA3}, {0xe087, 0xB3}, {0xe089, 0xCE}, + {0xe08a, 0xA6}, {0xe08c, 0xAE}, {0xe08d, 0xD6}, {0xe08e, 0xD6}, + {0xe08f, 0xD6}, {0xe094, 0xA2}, {0xe09e, 0x28}, {0xe09f, 0x29}, + {0xe0a0, 0xD0}, {0xe0a6, 0xA2}, {0xe0a7, 0x7C}, {0xe0a8, 0x2F}, + {0xe0ab, 0x7C}, {0xe0ac, 0x47}, {0xe0ad, 0x44}, {0xe0ae, 0x51}, + {0xe0af, 0x4C}, {0xe0b0, 0x58}, {0xe0b1, 0x50}, {0xe0b2, 0x53}, + {0xe0b3, 0x55}, {0xe0b4, 0x46}, {0xe0b5, 0x59}, {0xe0b6, 0x57}, + {0xe0b7, 0x61}, {0xe0b8, 0x62}, {0xe0b9, 0x67}, {0xe0ba, 0x64}, + {0xe0bb, 0x65}, {0xe0bc, 0x7A}, {0xe0bd, 0x68}, {0xe0be, 0x71}, + {0xe0bf, 0x69}, {0xe0c0, 0x6B}, {0xe0c1, 0x6C}, {0xe0c2, 0x6D}, + {0xe0c3, 0x6E}, {0xe0c4, 0x78}, {0xe0c5, 0x6F}, {0xe0c6, 0x70}, + {0xe0c7, 0x72}, {0xe0c8, 0x73}, {0xe0c9, 0x74}, {0xe0ca, 0x75}, + {0xe0cb, 0x66}, {0xe0cc, 0x63}, {0xe0cd, 0x79}, {0xe0ce, 0x77}, + {0xe0cf, 0x65}, {0xe0d0, 0x4A}, {0xe0d1, 0x76}, {0xe0d3, 0x56}, + {0xe0d4, 0x6A}, {0xe0d5, 0xB6}, {0xe0d6, 0x69}, {0xe0db, 0xAC}, + {0xe0dc, 0xAD}, {0xe0dd, 0xAF} +}; + +ExtraTable aTNRExtraTab[] = +{ + {0xe021, 0xA9}, + {0xe022, 0x40}, + {0xe024, 0xAE}, + {0xe035, 0x20}, + {0xe036, '('}, + {0xe037, ')'}, + {0xe039, 0x20}, + {0xe03a, 0x80}, + {0xe080, 0x89}, + {0xe083, '+'}, + {0xe084, '<'}, + {0xe085, '>'}, + {0xe0a9, '\\'} +}; + +StarSymbolToMSMultiFontImpl::StarSymbolToMSMultiFontImpl(bool bPerfectOnly) +{ + struct ConvertTable + { + enum SymbolFont meFont; + const sal_Unicode* pTab; + }; + + //In order of preference + const ConvertTable aConservativeTable[] = + { + {Symbol, aAdobeSymbolTab}, + {Wingdings, aWingDingsTab}, + {MonotypeSorts, aMonotypeSortsTab}, + {Webdings, aWebDingsTab}, + {Wingdings2, aWingDings2Tab}, + {Wingdings3, aWingDings3Tab}, + {MTExtra, aMTExtraTab} + }; + + struct ExtendedConvertTable + { + enum SymbolFont meFont; + const ExtraTable *mpTable; + size_t mnSize; + ExtendedConvertTable(SymbolFont eFont, const ExtraTable *pTable, + size_t nSize) + : meFont(eFont), mpTable(pTable), mnSize(nSize) {} + }; + + //Reverse map from a given starsymbol char to exact matches in ms symbol + //fonts. + int nEntries = sizeof(aConservativeTable) / sizeof(aConservativeTable[0]); + int i; + for (i = 0; i < nEntries; ++i) + { + const ConvertTable& r = aConservativeTable[i]; + SymbolEntry aEntry; + aEntry.eFont = r.meFont; + for (aEntry.cIndex = 0xFF; aEntry.cIndex >= 0x20; --aEntry.cIndex) + { + if (sal_Unicode cChar = r.pTab[aEntry.cIndex-0x20]) + maMagicMap.insert( + ::std::multimap<sal_Unicode, SymbolEntry>::value_type( + cChar, aEntry)); + } + } + + //In order of preference + const ExtendedConvertTable aAgressiveTable[] = + { + ExtendedConvertTable(Symbol, aSymbolExtraTab2, + sizeof(aSymbolExtraTab2)), + ExtendedConvertTable(Symbol, aSymbolExtraTab, + sizeof(aSymbolExtraTab)), + ExtendedConvertTable(Wingdings, aWingDingsExtraTab, + sizeof(aWingDingsExtraTab)), + ExtendedConvertTable(TimesNewRoman, aTNRExtraTab, + sizeof(aTNRExtraTab)) + }; + + //Allow extra conversions that are not perfect, but "good enough" + if (!bPerfectOnly) + nEntries = sizeof(aAgressiveTable) / sizeof(aAgressiveTable[0]); + else + nEntries = 1; + + for (i = 0; i < nEntries; ++i) + { + const ExtendedConvertTable& r = aAgressiveTable[i]; + SymbolEntry aEntry; + aEntry.eFont = r.meFont; + for (int j = r.mnSize / sizeof(r.mpTable[0]); j >=0; --j) + { + aEntry.cIndex = r.mpTable[j].cMS; + maMagicMap.insert( + ::std::multimap<sal_Unicode, SymbolEntry>::value_type( + r.mpTable[j].cStar, aEntry)); + } + } +} + +const char *SymbolFontToString(int nResult) +{ + const char **ppName = aSymbolNames; + int nI = Symbol; + while (nI <= nResult) + { + if (!(nI & nResult)) + nI = nI << 1; + else + break; + ppName++; + } + return *ppName; +} + +String StarSymbolToMSMultiFontImpl::ConvertChar(sal_Unicode &rChar) +{ + String sRet; + + ::std::multimap<sal_Unicode, SymbolEntry>::const_iterator aResult = + maMagicMap.find(rChar); + + if (aResult != maMagicMap.end()) + { + const SymbolEntry &rEntry = (*aResult).second; + sRet.AssignAscii(SymbolFontToString(rEntry.eFont)); + rChar = rEntry.cIndex; + } + + return sRet; +} + +String StarSymbolToMSMultiFontImpl::ConvertString(String &rString, + xub_StrLen& rIndex) +{ + typedef ::std::multimap<sal_Unicode, SymbolEntry>::iterator MI; + typedef ::std::pair<MI, MI> Result; + + String sRet; + + xub_StrLen nLen = rString.Len(); + if (rIndex >= nLen) + return sRet; + + int nTotal = 0, nResult = 0; + ::std::vector<Result> aPossibilities; + aPossibilities.reserve(nLen - rIndex); + xub_StrLen nStart = rIndex; + do + { + Result aResult = maMagicMap.equal_range(rString.GetChar(rIndex)); + int nBitfield = 0; + for (MI aIndex = aResult.first; aIndex != aResult.second; ++aIndex) + nBitfield |= aIndex->second.eFont; + + if (!nTotal) + nTotal = nBitfield; + else + { + if (nTotal != nBitfield) //Allow a series of failures + { + nTotal &= nBitfield; + if (!nTotal) + break; + } + } + nResult = nTotal; + if (nResult) //Don't bother storing a series of failures + aPossibilities.push_back(aResult); + ++rIndex; + }while(rIndex < nLen); + + if (nResult) + { + int nI = Symbol; + while (nI <= nResult) + { + if (!(nI & nResult)) + nI = nI << 1; + else + break; + } + sRet.AssignAscii(SymbolFontToString(nI)); + + xub_StrLen nSize = sal::static_int_cast<xub_StrLen>(aPossibilities.size()); + for(xub_StrLen nPos = 0; nPos < nSize; ++nPos) + { + const Result &rResult = aPossibilities[nPos]; + + for (MI aIndex = rResult.first; aIndex != rResult.second; ++aIndex) + { + if (aIndex->second.eFont == nI) + { + rString.SetChar(nPos+nStart, aIndex->second.cIndex); + break; + } + } + } + } + + return sRet; +} + +StarSymbolToMSMultiFont *CreateStarSymbolToMSMultiFont(bool bPerfectOnly) +{ + return new StarSymbolToMSMultiFontImpl(bPerfectOnly); +} + +//======================================================================= + +sal_Unicode ConvertChar::RecodeChar( sal_Unicode cChar ) const +{ + sal_Unicode cRetVal = 0; + if( mpCvtFunc ) + { + // use a conversion function for recoding + cRetVal = mpCvtFunc( cChar ); + } + else + { + // use a conversion table for recoding + sal_Unicode cIndex = cChar; + // allow symbol aliasing + if( cIndex & 0xFF00 ) + cIndex -= 0xF000; + // recode the symbol + if( cIndex>=0x0020 && cIndex<=0x00FF ) + cRetVal = mpCvtTab[ cIndex - 0x0020 ]; + } + + return cRetVal ? cRetVal : cChar; +} + +// ----------------------------------------------------------------------- + +// recode the string assuming the character codes are symbol codes +// from an traditional symbol font (i.e. U+F020..U+F0FF) +void ConvertChar::RecodeString( String& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const +{ + ULONG nLastIndex = (ULONG)nIndex + nLen; + if( nLastIndex > rStr.Len() ) + nLastIndex = rStr.Len(); + + for(; nIndex < nLastIndex; ++nIndex ) + { + sal_Unicode cOrig = rStr.GetChar( nIndex ); + // only recode symbols and their U+00xx aliases + if( ((cOrig < 0x0020) || (cOrig > 0x00FF)) + && ((cOrig < 0xF020) || (cOrig > 0xF0FF)) ) + continue; + + // recode a symbol + sal_Unicode cNew = RecodeChar( cOrig ); + if( cOrig != cNew ) + rStr.SetChar( nIndex, cNew ); + } +} + +//======================================================================= + +struct RecodeTable { const char* pOrgName; ConvertChar aCvt;}; + +static RecodeTable aRecodeTable[] = +{ + // the first two entries must be StarMath and StarBats; do not reorder! + // reason: fgrep for FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS + {"starbats", {aStarBatsTab, "StarSymbol", NULL}}, + {"starmath", {aStarMathTab, "StarSymbol", NULL}}, + + {"symbol", {aAdobeSymbolTab, "StarSymbol", NULL}}, + {"standardsymbols", {aAdobeSymbolTab, "StarSymbol", NULL}}, + {"standardsymbolsl",{aAdobeSymbolTab, "StarSymbol", NULL}}, + + {"monotypesorts", {aMonotypeSortsTab, "StarSymbol", NULL}}, +// {"monotypesorts2", {aMonotypeSorts2Tab, "StarSymbol", NULL}} + {"zapfdingbats", {aMonotypeSortsTab, "StarSymbol", NULL}}, //ZapfDingbats=MonotypeSorts-X? + {"itczapfdingbats", {aMonotypeSortsTab, "StarSymbol", NULL}}, + {"dingbats", {aMonotypeSortsTab, "StarSymbol", NULL}}, + + {"webdings", {aWebDingsTab, "StarSymbol", NULL}}, + {"wingdings", {aWingDingsTab, "StarSymbol", NULL}}, + {"wingdings2", {aWingDings2Tab, "StarSymbol", NULL}}, + {"wingdings3", {aWingDings3Tab, "StarSymbol", NULL}}, + {"mtextra", {aMTExtraTab, "StarSymbol", NULL}} +}; + +static ConvertChar aImplStarSymbolCvt = { NULL, "StarBats", ImplStarSymbolToStarBats }; + +// ----------------------------------------------------------------------- + +const ConvertChar* ConvertChar::GetRecodeData( const String& rOrgFontName, const String& rMapFontName ) +{ + const ConvertChar* pCvt = NULL; + String aOrgName( rOrgFontName ); + GetEnglishSearchFontName( aOrgName ); + String aMapName( rMapFontName ); + GetEnglishSearchFontName( aMapName ); + + if( aMapName.EqualsAscii( "starsymbol" ) + || aMapName.EqualsAscii( "opensymbol" ) ) + { + int nEntries = sizeof(aRecodeTable) / sizeof(aRecodeTable[0]); + for( int i = 0; i < nEntries; ++i) + { + RecodeTable& r = aRecodeTable[i]; + if( aOrgName.EqualsAscii( r.pOrgName ) ) + { pCvt = &r.aCvt; break; } + } + } + else if( aMapName.EqualsAscii( "starbats" ) ) + { + if( aOrgName.EqualsAscii( "starsymbol" ) ) + pCvt = &aImplStarSymbolCvt; + else if( aOrgName.EqualsAscii( "opensymbol" ) ) + pCvt = &aImplStarSymbolCvt; + } + + return pCvt; +} + +//======================================================================= + +FontToSubsFontConverter CreateFontToSubsFontConverter( + const String& rOrgName, ULONG nFlags ) +{ + const ConvertChar* pCvt = NULL; + + String aName = rOrgName; + GetEnglishSearchFontName( aName ); + + if ( nFlags & FONTTOSUBSFONT_IMPORT ) + { + int nEntries = sizeof(aRecodeTable) / sizeof(aRecodeTable[0]); + if ( nFlags & FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS ) // only StarMath+StarBats + nEntries = 2; + for( int i = 0; i < nEntries; ++i ) + { + RecodeTable& r = aRecodeTable[i]; + if( aName.EqualsAscii( r.pOrgName ) ) + { pCvt = &r.aCvt; break; } + } + } + else + { + // TODO: FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS + if( aName.EqualsAscii( "starsymbol" ) ) pCvt = &aImplStarSymbolCvt; + else if( aName.EqualsAscii( "opensymbol" ) ) pCvt = &aImplStarSymbolCvt; + } + + return (FontToSubsFontConverter)pCvt; +} + +// ----------------------------------------------------------------------- + +void DestroyFontToSubsFontConverter( FontToSubsFontConverter ) +{ + // nothing to do for now, because we use static ImplCvtChars +} + +// ----------------------------------------------------------------------- + +sal_Unicode ConvertFontToSubsFontChar( + FontToSubsFontConverter hConverter, sal_Unicode cChar ) +{ + if ( hConverter ) + return ((ConvertChar*)hConverter)->RecodeChar( cChar ); + else + return cChar; +} + +// ----------------------------------------------------------------------- + +String GetFontToSubsFontName( FontToSubsFontConverter hConverter ) +{ + if ( !hConverter ) + return String(); + + const char* pName = ((ConvertChar*)hConverter)->mpSubsFontName; + return String::CreateFromAscii( pName ); +} + diff --git a/unotools/source/misc/fontdefs.cxx b/unotools/source/misc/fontdefs.cxx new file mode 100644 index 000000000000..c1c222755599 --- /dev/null +++ b/unotools/source/misc/fontdefs.cxx @@ -0,0 +1,598 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/fontdefs.hxx> +#include <unotools/fontcfg.hxx> +#include <hash_map> + +struct ImplLocalizedFontName +{ + const char* mpEnglishName; + const sal_Unicode* mpLocalizedNames; +}; + +// TODO: where did the 0,0 delimiters come from? A single 0 should suffice... +static sal_Unicode const aBatang[] = { 0xBC14, 0xD0D5, 0, 0 }; +static sal_Unicode const aBatangChe[] = { 0xBC14, 0xD0D5, 0xCCB4, 0, 0 }; +static sal_Unicode const aGungsuh[] = { 0xAD81, 0xC11C, 0, 0 }; +static sal_Unicode const aGungsuhChe[] = { 0xAD81, 0xC11C, 0xCCB4, 0, 0 }; +static sal_Unicode const aGulim[] = { 0xAD74, 0xB9BC, 0, 0 }; +static sal_Unicode const aGulimChe[] = { 0xAD74, 0xB9BC, 0xCCB4, 0, 0 }; +static sal_Unicode const aDotum[] = { 0xB3CB, 0xC6C0, 0, 0 }; +static sal_Unicode const aDotumChe[] = { 0xB3CB, 0xC6C0, 0xCCB4, 0, 0 }; +static sal_Unicode const aSimSun[] = { 0x5B8B, 0x4F53, 0, 0 }; +static sal_Unicode const aNSimSun[] = { 0x65B0, 0x5B8B, 0x4F53, 0, 0 }; +static sal_Unicode const aSimHei[] = { 0x9ED1, 0x4F53, 0, 0 }; +static sal_Unicode const aSimKai[] = { 0x6977, 0x4F53, 0, 0 }; +static sal_Unicode const azycjkSun[] = { 0x4E2D, 0x6613, 0x5B8B, 0x4F53, 0, 0 }; +static sal_Unicode const azycjkHei[] = { 0x4E2D, 0x6613, 0x9ED1, 0x4F53, 0, 0 }; +static sal_Unicode const azycjkKai[] = { 0x4E2D, 0x6613, 0x6977, 0x4F53, 0, 0 }; +static sal_Unicode const aFZHei[] = { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0, 0 }; +static sal_Unicode const aFZKai[] = { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0, 0 }; +static sal_Unicode const aFZSongYI[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4E00, 0, 0 }; +static sal_Unicode const aFZShuSong[] = { 0x65B9, 0x6B63, 0x4E66, 0x5B8B, 0, 0 }; +static sal_Unicode const aFZFangSong[] = { 0x65B9, 0x6B63, 0x4EFF, 0x5B8B, 0, 0 }; +// Attention: this fonts includes the wrong encoding vector - so we double the names with correct and wrong encoding +// First one is the GB-Encoding (we think the correct one), second is the big5 encoded name +static sal_Unicode const aMHei[] = { 'm', 0x7B80, 0x9ED1, 0, 'm', 0x6F60, 0x7AAA, 0, 0 }; +static sal_Unicode const aMKai[] = { 'm', 0x7B80, 0x6977, 0x566C, 0, 'm', 0x6F60, 0x7FF1, 0x628E, 0, 0 }; +static sal_Unicode const aMSong[] = { 'm', 0x7B80, 0x5B8B, 0, 'm', 0x6F60, 0x51BC, 0, 0 }; +static sal_Unicode const aCFangSong[] = { 'm', 0x7B80, 0x592B, 0x5B8B, 0, 'm', 0x6F60, 0x6E98, 0x51BC, 0, 0 }; +static sal_Unicode const aMingLiU[] = { 0x7D30, 0x660E, 0x9AD4, 0, 0 }; +static sal_Unicode const aPMingLiU[] = { 0x65B0, 0x7D30, 0x660E, 0x9AD4, 0, 0 }; +static sal_Unicode const aHei[] = { 0x6865, 0, 0 }; +static sal_Unicode const aKai[] = { 0x6B61, 0, 0 }; +static sal_Unicode const aMing[] = { 0x6D69, 0x6E67, 0, 0 }; +static sal_Unicode const aMSGothic[] = { 'm','s', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; +static sal_Unicode const aMSPGothic[] = { 'm','s','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; +static sal_Unicode const aMSMincho[] = { 'm', 's', 0x660E, 0x671D, 0 }; +static sal_Unicode const aMSPMincho[] = { 'm','s','p', 0x660E, 0x671D, 0 }; +static sal_Unicode const aMSYaHei[] = { 0x5FAE, 0x8F6F, 0x96C5, 0x9ED1, 0 }; +static sal_Unicode const aMSJhengHei[] = { 0x5FAE, 0x8EDF, 0x6B63, 0x9ED1, 0x9AD4, 0 }; +static sal_Unicode const aMeiryo[] = { 0x30e1, 0x30a4, 0x30ea, 0x30aa, 0 }; +static sal_Unicode const aHGMinchoL[] = { 'h','g', 0x660E, 0x671D, 'l', 0, 0 }; +static sal_Unicode const aHGGothicB[] = { 'h','g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 }; +static sal_Unicode const aHGPMinchoL[] = { 'h','g','p', 0x660E, 0x671D, 'l', 0 }; +static sal_Unicode const aHGPGothicB[] = { 'h','g','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 }; +static sal_Unicode const aHGMinchoLSun[] = { 'h','g', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 }; +static sal_Unicode const aHGPMinchoLSun[] = { 'h','g','p', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 }; +static sal_Unicode const aHGGothicBSun[] = { 'h', 'g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 }; +static sal_Unicode const aHGPGothicBSun[] = { 'h', 'g', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 }; +static sal_Unicode const aHGHeiseiMin[] = { 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 0, 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 'w', '3', 'x', '1', '2', 0, 0 }; +static sal_Unicode const aIPAMincho[] = { 'i', 'p', 'a', 0x660E, 0x671D, 0 }; +static sal_Unicode const aIPAPMincho[] = { 'i', 'p', 'a', 'p', 0x660E, 0x671D, 0 }; +static sal_Unicode const aIPAGothic[] = { 'i', 'p', 'a', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 }; +static sal_Unicode const aIPAPGothic[] = { 'i', 'p', 'a', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 }; +static sal_Unicode const aIPAUIGothic[] = { 'i', 'p', 'a', 'u', 'i', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 }; +static sal_Unicode const aSazanamiMincho[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x660E, 0x671D, 0, 0 }; +static sal_Unicode const aSazanamiGothic[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; +static sal_Unicode const aKochiMincho[] = { 0x6771, 0x98A8, 0x660E, 0x671D, 0, 0 }; +static sal_Unicode const aKochiGothic[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; +static sal_Unicode const aSunDotum[] = { 0xC36C, 0xB3CB, 0xC6C0, 0, 0 }; +static sal_Unicode const aSunGulim[] = { 0xC36C, 0xAD74, 0xB9BC, 0, 0 }; +static sal_Unicode const aSunBatang[] = { 0xC36C, 0xBC14, 0xD0D5, 0, 0 }; +static sal_Unicode const aBaekmukDotum[] = { 0xBC31, 0xBB35, 0xB3CB, 0xC6C0, 0, 0 }; +static sal_Unicode const aBaekmukGulim[] = { 0xBC31, 0xBB35, 0xAD74, 0xB9BC, 0, 0 }; +static sal_Unicode const aBaekmukBatang[] = { 0xBC31, 0xBB35, 0xBC14, 0xD0D5, 0, 0 }; +static sal_Unicode const aFzMingTi[] = { 0x65B9, 0x6B63, 0x660E, 0x9AD4, 0, 0 }; +static sal_Unicode const aFzHeiTiTW[]= { 0x65B9, 0x6B63, 0x9ED1, 0x9AD4, 0, 0 }; +static sal_Unicode const aFzKaiTiTW[]= { 0x65B9, 0x6B63, 0x6977, 0x9AD4, 0, 0 }; +static sal_Unicode const aFzHeiTiCN[]= { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0, 0 }; +static sal_Unicode const aFzKaiTiCN[]= { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0, 0 }; +static sal_Unicode const aFzSongTi[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4F53, 0, 0 }; +static sal_Unicode const aHYMyeongJoExtra[] = { 'h', 'y', 0xACAC, 0xBA85, 0xC870, 0, 0 }; +static sal_Unicode const aHYSinMyeongJoMedium[] = { 'h', 'y', 0xC2E0, 0xBA85, 0xC870, 0, 0 }; +static sal_Unicode const aHYGothicMedium[] = { 'h', 'y', 0xC911, 0xACE0, 0xB515, 0, 0 }; +static sal_Unicode const aHYGraphicMedium[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 'm', 0, 0 }; +static sal_Unicode const aHYGraphic[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 0, 0 }; +static sal_Unicode const aNewGulim[] = { 0xC0C8, 0xAD74, 0xB9BC, 0, 0 }; +static sal_Unicode const aSunGungseo[] = { 0xC36C, 0xAD81, 0xC11C, 0, 0 }; +static sal_Unicode const aHYGungSoBold[] = { 'h','y', 0xAD81, 0xC11C, 'b', 0, 0 }; +static sal_Unicode const aHYGungSo[] = { 'h','y', 0xAD81, 0xC11C, 0, 0 }; +static sal_Unicode const aSunHeadLine[] = { 0xC36C, 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0, 0 }; +static sal_Unicode const aHYHeadLineMedium[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 'm', 0, 0 }; +static sal_Unicode const aHYHeadLine[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0, 0 }; +static sal_Unicode const aYetR[] = { 0xD734, 0xBA3C, 0xC61B, 0xCCB4, 0, 0 }; +static sal_Unicode const aHYGothicExtra[] = { 'h', 'y', 0xACAC, 0xACE0, 0xB515, 0, 0 }; +static sal_Unicode const aSunMokPan[] = { 0xC36C, 0xBAA9, 0xD310, 0, 0 }; +static sal_Unicode const aSunYeopseo[] = { 0xC36C, 0xC5FD, 0xC11C, 0, 0 }; +static sal_Unicode const aSunBaekSong[] = { 0xC36C, 0xBC31, 0xC1A1, 0, 0 }; +static sal_Unicode const aHYPostLight[] = { 'h', 'y', 0xC5FD, 0xC11C, 'l', 0, 0 }; +static sal_Unicode const aHYPost[] = { 'h', 'y', 0xC5FD, 0xC11C, 0, 0 }; +static sal_Unicode const aMagicR[] = { 0xD734, 0xBA3C, 0xB9E4, 0xC9C1, 0xCCB4, 0, 0 }; +static sal_Unicode const aSunCrystal[] = { 0xC36C, 0xD06C, 0xB9AC, 0xC2A4, 0xD0C8, 0, 0 }; +static sal_Unicode const aSunSaemmul[] = { 0xC36C, 0xC0D8, 0xBB3C, 0, 0 }; +static sal_Unicode const aHaansoftBatang[] = { 0xD55C, 0xCEF4, 0xBC14, 0xD0D5, 0, 0 }; +static sal_Unicode const aHaansoftDotum[] = { 0xD55C, 0xCEF4, 0xB3CB, 0xC6C0, 0, 0 }; +static sal_Unicode const aHyhaeseo[] = { 0xD55C, 0xC591, 0xD574, 0xC11C, 0, 0 }; +static sal_Unicode const aMDSol[] = { 'm', 'd', 0xC194, 0xCCB4, 0, 0 }; +static sal_Unicode const aMDGaesung[] = { 'm', 'd', 0xAC1C, 0xC131, 0xCCB4, 0, 0 }; +static sal_Unicode const aMDArt[] = { 'm', 'd', 0xC544, 0xD2B8, 0xCCB4, 0, 0 }; +static sal_Unicode const aMDAlong[] = { 'm', 'd', 0xC544, 0xB871, 0xCCB4, 0, 0 }; +static sal_Unicode const aMDEasop[] = { 'm', 'd', 0xC774, 0xC19D, 0xCCB4, 0, 0 }; +static sal_Unicode const aHYShortSamulMedium[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 'm', 0 }; +static sal_Unicode const aHYShortSamul[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 0 }; +static sal_Unicode const aHGGothicE[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 }; +static sal_Unicode const aHGPGothicE[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 }; +static sal_Unicode const aHGSGothicE[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 }; +static sal_Unicode const aHGGothicM[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 }; +static sal_Unicode const aHGPGothicM[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 }; +static sal_Unicode const aHGSGothicM[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 }; +static sal_Unicode const aHGGyoshotai[] = { 'h','g', 0x884C, 0x66F8, 0x4F53, 0 }; +static sal_Unicode const aHGPGyoshotai[] = { 'h','g','p', 0x884C, 0x66F8, 0x4F53, 0 }; +static sal_Unicode const aHGSGyoshotai[] = { 'h','g','s', 0x884C, 0x66F8, 0x4F53, 0 }; +static sal_Unicode const aHGKyokashotai[] = { 'h','g', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 }; +static sal_Unicode const aHGPKyokashotai[] = { 'h','g','p', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 }; +static sal_Unicode const aHGSKyokashotai[] = { 'h','g','s', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 }; +static sal_Unicode const aHGMinchoB[] = { 'h','g', 0x660E, 0x671D, 'b', 0 }; +static sal_Unicode const aHGPMinchoB[] = { 'h','g','p', 0x660E, 0x671D, 'b', 0 }; +static sal_Unicode const aHGSMinchoB[] = { 'h','g','s', 0x660E, 0x671D, 'b', 0 }; +static sal_Unicode const aHGMinchoE[] = { 'h','g', 0x660E, 0x671D, 'e', 0 }; +static sal_Unicode const aHGPMinchoE[] = { 'h','g','p', 0x660E, 0x671D, 'e', 0 }; +static sal_Unicode const aHGSMinchoE[] = { 'h','g','s', 0x660E, 0x671D, 'e', 0 }; +static sal_Unicode const aHGSoeiKakupoptai[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF8E, + 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0}; +static sal_Unicode const aHGPSoeiKakupoptai[] = { 'h','g', 'p', 0x5275,0x82F1,0x89D2,0xFF8E, + 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0}; +static sal_Unicode const aHGSSoeiKakupoptai[] = { 'h','g', 's', 0x5275,0x82F1,0x89D2,0xFF8E, + 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0}; +static sal_Unicode const aHGSoeiPresenceEB[] = { 'h','g', 0x5275,0x82F1,0xFF8C,0xFF9F, + 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0}; +static sal_Unicode const aHGPSoeiPresenceEB[] = { 'h','g','p', 0x5275,0x82F1,0xFF8C,0xFF9F, + 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0}; +static sal_Unicode const aHGSSoeiPresenceEB[] = { 'h','g','s', 0x5275,0x82F1,0xFF8C,0xFF9F, + 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0}; +static sal_Unicode const aHGSoeiKakugothicUB[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF7A, + 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0}; +static sal_Unicode const aHGPSoeiKakugothicUB[] = { 'h','g','p', 0x5275,0x82F1,0x89D2,0xFF7A, + 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0}; +static sal_Unicode const aHGSSoeiKakugothicUB[] = { 'h','g','s', 0x5275,0x82F1,0x89D2,0xFF7A, + 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0}; +static sal_Unicode const aHGSeikaishotaiPRO[] = { 'h','g', 0x6B63,0x6977,0x66F8,0x4F53, '-','p','r','o',0}; +static sal_Unicode const aHGMaruGothicMPRO[] = { 'h','g', 0x4E38,0xFF7A,0xFF9E,0xFF7C,0xFF6F,0xFF78, '-','p','r','o',0}; +static sal_Unicode const aHiraginoMinchoPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o',0}; +static sal_Unicode const aHiraginoMinchoProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o','n',0}; +static sal_Unicode const aHiraginoKakuGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o',0}; +static sal_Unicode const aHiraginoKakuGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o','n',0}; +static sal_Unicode const aHiraginoMaruGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o',0}; +static sal_Unicode const aHiraginoMaruGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o','n',0}; + +static ImplLocalizedFontName aImplLocalizedNamesList[] = +{ +{ "batang", aBatang }, +{ "batangche", aBatangChe }, +{ "gungshu", aGungsuh }, +{ "gungshuche", aGungsuhChe }, +{ "gulim", aGulim }, +{ "gulimche", aGulimChe }, +{ "dotum", aDotum }, +{ "dotumche", aDotumChe }, +{ "simsun", aSimSun }, +{ "nsimsun", aNSimSun }, +{ "simhei", aSimHei }, +{ "simkai", aSimKai }, +{ "zycjksun", azycjkSun }, +{ "zycjkhei", azycjkHei }, +{ "zycjkkai", azycjkKai }, +{ "fzhei", aFZHei }, +{ "fzkai", aFZKai }, +{ "fzsong", aFZSongYI }, +{ "fzshusong", aFZShuSong }, +{ "fzfangsong", aFZFangSong }, +{ "mhei", aMHei }, +{ "mkai", aMKai }, +{ "msong", aMSong }, +{ "cfangsong", aCFangSong }, +{ "mingliu", aMingLiU }, +{ "pmingliu", aPMingLiU }, +{ "hei", aHei }, +{ "kai", aKai }, +{ "ming", aMing }, +{ "msgothic", aMSGothic }, +{ "mspgothic", aMSPGothic }, +{ "msmincho", aMSMincho }, +{ "mspmincho", aMSPMincho }, +{ "microsoftjhenghei", aMSJhengHei }, +{ "microsoftyahei", aMSYaHei }, +{ "meiryo", aMeiryo }, +{ "hgminchol", aHGMinchoL }, +{ "hggothicb", aHGGothicB }, +{ "hgpminchol", aHGPMinchoL }, +{ "hgpgothicb", aHGPGothicB }, +{ "hgmincholsun", aHGMinchoLSun }, +{ "hggothicbsun", aHGGothicBSun }, +{ "hgpmincholsun", aHGPMinchoLSun }, +{ "hgpgothicbsun", aHGPGothicBSun }, +{ "hgheiseimin", aHGHeiseiMin }, +{ "ipamincho", aIPAMincho }, +{ "ipapmincho", aIPAPMincho }, +{ "ipagothic", aIPAGothic }, +{ "ipapgothic", aIPAPGothic }, +{ "ipauigothic", aIPAUIGothic }, +{ "sazanamimincho", aSazanamiMincho }, +{ "sazanamigothic", aSazanamiGothic }, +{ "kochimincho", aKochiMincho }, +{ "kochigothic", aKochiGothic }, +{ "sundotum", aSunDotum }, +{ "sungulim", aSunGulim }, +{ "sunbatang", aSunBatang }, +{ "baekmukdotum", aBaekmukDotum }, +{ "baekmukgulim", aBaekmukGulim }, +{ "baekmukbatang", aBaekmukBatang }, +{ "fzheiti", aFzHeiTiCN }, +{ "fzheiti", aFzHeiTiTW }, +{ "fzkaiti", aFzKaiTiCN }, +{ "fzkaitib", aFzKaiTiTW }, +{ "fzmingtib", aFzMingTi }, +{ "fzsongti", aFzSongTi }, +{ "hymyeongjoextra", aHYMyeongJoExtra }, +{ "hysinmyeongjomedium", aHYSinMyeongJoMedium }, +{ "hygothicmedium", aHYGothicMedium }, +{ "hygraphicmedium", aHYGraphicMedium }, +{ "hygraphic", aHYGraphic }, +{ "newgulim", aNewGulim }, +{ "sungungseo", aSunGungseo }, +{ "hygungsobold", aHYGungSoBold }, +{ "hygungso", aHYGungSo }, +{ "sunheadline", aSunHeadLine }, +{ "hyheadlinemedium", aHYHeadLineMedium }, +{ "hyheadline", aHYHeadLine }, +{ "yetr", aYetR }, +{ "hygothicextra", aHYGothicExtra }, +{ "sunmokpan", aSunMokPan }, +{ "sunyeopseo", aSunYeopseo }, +{ "sunbaeksong", aSunBaekSong }, +{ "hypostlight", aHYPostLight }, +{ "hypost", aHYPost }, +{ "magicr", aMagicR }, +{ "suncrystal", aSunCrystal }, +{ "sunsaemmul", aSunSaemmul }, +{ "hyshortsamulmedium", aHYShortSamulMedium }, +{ "hyshortsamul", aHYShortSamul }, +{ "haansoftbatang", aHaansoftBatang }, +{ "haansoftdotum", aHaansoftDotum }, +{ "hyhaeseo", aHyhaeseo }, +{ "mdsol", aMDSol }, +{ "mdgaesung", aMDGaesung }, +{ "mdart", aMDArt }, +{ "mdalong", aMDAlong }, +{ "mdeasop", aMDEasop }, +{ "hggothice", aHGGothicE }, +{ "hgpgothice", aHGPGothicE }, +{ "hgpothice", aHGSGothicE }, +{ "hggothicm", aHGGothicM }, +{ "hgpgothicm", aHGPGothicM }, +{ "hgpgothicm", aHGSGothicM }, +{ "hggyoshotai", aHGGyoshotai }, +{ "hgpgyoshotai", aHGPGyoshotai }, +{ "hgsgyoshotai", aHGSGyoshotai }, +{ "hgkyokashotai", aHGKyokashotai }, +{ "hgpkyokashotai", aHGPKyokashotai }, +{ "hgskyokashotai", aHGSKyokashotai }, +{ "hgminchob", aHGMinchoB }, +{ "hgpminchob", aHGPMinchoB }, +{ "hgsminchob", aHGSMinchoB }, +{ "hgminchoe", aHGMinchoE }, +{ "hgpminchoe", aHGPMinchoE }, +{ "hgsminchoe", aHGSMinchoE }, +{ "hgsoeikakupoptai", aHGSoeiKakupoptai }, +{ "hgpsoeikakupopta", aHGPSoeiKakupoptai }, +{ "hgssoeikakupopta", aHGSSoeiKakupoptai }, +{ "hgsoeipresenceeb", aHGSoeiPresenceEB }, +{ "hgpsoeipresenceeb", aHGPSoeiPresenceEB }, +{ "hgssoeipresenceeb", aHGSSoeiPresenceEB }, +{ "hgsoeikakugothicub", aHGSoeiKakugothicUB }, +{ "hgpsoeikakugothicub", aHGPSoeiKakugothicUB }, +{ "hgssoeikakugothicub", aHGSSoeiKakugothicUB }, +{ "hgseikaishotaipro", aHGSeikaishotaiPRO }, +{ "hgmarugothicmpro", aHGMaruGothicMPRO }, +{ "hiraginominchopro", aHiraginoMinchoPro }, +{ "hiraginominchopron", aHiraginoMinchoProN }, +{ "hiraginokakugothicpro", aHiraginoKakuGothicPro }, +{ "hiraginokakugothicpron", aHiraginoKakuGothicProN }, +{ "hiraginomarugothicpro", aHiraginoMaruGothicPro }, +{ "hiraginomarugothicpron", aHiraginoMaruGothicProN }, +{ NULL, NULL }, +}; + +// ----------------------------------------------------------------------- + +void GetEnglishSearchFontName( String& rName ) +{ + bool bNeedTranslation = false; + xub_StrLen nLen = rName.Len(); + + // Remove trailing whitespaces + xub_StrLen i = nLen; + while ( i && (rName.GetChar( i-1 ) < 32) ) + i--; + if ( i != nLen ) + rName.Erase( i ); + + // Remove Script at the end + // Scriptname must be the last part of the fontname and + // looks like "fontname (scriptname)". So there can only be a + // script name at the and of the fontname, when the last char is ')' + if ( (nLen >= 3) && rName.GetChar( nLen-1 ) == ')' ) + { + int nOpen = 1; + xub_StrLen nTempLen = nLen-2; + while ( nTempLen ) + { + if ( rName.GetChar( nTempLen ) == '(' ) + { + nOpen--; + if ( !nOpen ) + { + // Remove Space at the end + if ( nTempLen && (rName.GetChar( nTempLen-1 ) == ' ') ) + nTempLen--; + rName.Erase( nTempLen ); + nLen = nTempLen; + break; + } + } + if ( rName.GetChar( nTempLen ) == ')' ) + nOpen++; + nTempLen--; + } + } + + // remove all whitespaces and converts to lower case ASCII + // TODO: better transliteration to ASCII e.g. all digits + i = 0; + while ( i < nLen ) + { + sal_Unicode c = rName.GetChar( i ); + if ( c > 127 ) + { + // Translate to Lowercase-ASCII + // FullWidth-ASCII to half ASCII + if ( (c >= 0xFF00) && (c <= 0xFF5E) ) + { + c -= 0xFF00-0x0020; + // Upper to Lower + if ( (c >= 'A') && (c <= 'Z') ) + c += 'a' - 'A'; + rName.SetChar( i, c ); + } + else + { + // Only Fontnames with None-Ascii-Characters must be translated + bNeedTranslation = true; + } + } + // not lowercase Ascii + else if ( !((c >= 'a') && (c <= 'z')) ) + { + // To Lowercase-Ascii + if ( (c >= 'A') && (c <= 'Z') ) + { + c += 'a' - 'A'; + rName.SetChar( i, c ); + } + else if( ((c < '0') || (c > '9')) && (c != ';') ) // not 0-9 or semicolon + { + // Remove white spaces and special characters + rName.Erase( i, 1 ); + nLen--; + continue; + } + } + + i++; + } + + // translate normalized localized name to its normalized English ASCII name + if( bNeedTranslation ) + { + typedef std::hash_map<const String, const char*,FontNameHash> FontNameDictionary; + static FontNameDictionary aDictionary( sizeof(aImplLocalizedNamesList) / sizeof(*aImplLocalizedNamesList) ); + // the font name dictionary needs to be intialized once + if( aDictionary.empty() ) + { + // TODO: check if all dictionary entries are already normalized? + const ImplLocalizedFontName* pList = aImplLocalizedNamesList; + for(; pList->mpEnglishName; ++pList ) + aDictionary[ pList->mpLocalizedNames ] = pList->mpEnglishName; + } + + FontNameDictionary::const_iterator it = aDictionary.find( rName ); + if( it != aDictionary.end() ) + rName.AssignAscii( it->second ); + } +} + +// ----------------------------------------------------------------------- + +String GetNextFontToken( const String& rTokenStr, xub_StrLen& rIndex ) +{ + // check for valid start index + int nStringLen = rTokenStr.Len(); + if( rIndex >= nStringLen ) + { + rIndex = STRING_NOTFOUND; + return String(); + } + + // find the next token delimiter and return the token substring + const sal_Unicode* pStr = rTokenStr.GetBuffer() + rIndex; + const sal_Unicode* pEnd = rTokenStr.GetBuffer() + nStringLen; + for(; pStr < pEnd; ++pStr ) + if( (*pStr == ';') || (*pStr == ',') ) + break; + + xub_StrLen nTokenStart = rIndex; + xub_StrLen nTokenLen; + if( pStr < pEnd ) + { + rIndex = sal::static_int_cast<xub_StrLen>(pStr - rTokenStr.GetBuffer()); + nTokenLen = rIndex - nTokenStart; + ++rIndex; // skip over token separator + } + else + { + // no token delimiter found => handle last token + rIndex = STRING_NOTFOUND; + nTokenLen = STRING_LEN; + + // optimize if the token string consists of just one token + if( !nTokenStart ) + return rTokenStr; + } + + return String( rTokenStr, nTokenStart, nTokenLen ); +} + +// TODO: get rid of this in another incompatible build with SW project. +// SW's WW8 and RTF filters still use this (from fontcvt.hxx) +String GetFontToken( const String& rTokenStr, xub_StrLen nToken, xub_StrLen& rIndex ) +{ + // skip nToken Tokens + for( xub_StrLen i = 0; (i < nToken) && (rIndex != STRING_NOTFOUND); ++i ) + GetNextFontToken( rTokenStr, rIndex ); + + return GetNextFontToken( rTokenStr, rIndex ); +} + +// ======================================================================= + +static bool ImplIsFontToken( const String& rName, const String& rToken ) +{ + String aTempName; + xub_StrLen nIndex = 0; + do + { + aTempName = GetNextFontToken( rName, nIndex ); + if ( rToken == aTempName ) + return true; + } + while ( nIndex != STRING_NOTFOUND ); + + return false; +} + +// ----------------------------------------------------------------------- + +static void ImplAppendFontToken( String& rName, const String& rNewToken ) +{ + if ( rName.Len() ) + { + rName.Append( ';' ); + rName.Append( rNewToken ); + } + else + rName = rNewToken; +} + +void AddTokenFontName( String& rName, const String& rNewToken ) +{ + if ( !ImplIsFontToken( rName, rNewToken ) ) + ImplAppendFontToken( rName, rNewToken ); +} + +// ======================================================================= + +String GetSubsFontName( const String& rName, ULONG nFlags ) +{ + String aName; + + xub_StrLen nIndex = 0; + String aOrgName = GetNextFontToken( rName, nIndex ); + GetEnglishSearchFontName( aOrgName ); + + // #93662# do not try to replace StarSymbol with MS only font + if( nFlags == (SUBSFONT_MS|SUBSFONT_ONLYONE) + && ( aOrgName.EqualsAscii( "starsymbol" ) + || aOrgName.EqualsAscii( "opensymbol" ) ) ) + return aName; + + const utl::FontNameAttr* pAttr = utl::FontSubstConfiguration::get()->getSubstInfo( aOrgName ); + if ( pAttr ) + { + for( int i = 0; i < 3; i++ ) + { + const ::std::vector< String >* pVector = NULL; + switch( i ) + { + case 0: + if( nFlags & SUBSFONT_MS && pAttr->MSSubstitutions.size() ) + pVector = &pAttr->MSSubstitutions; + break; + case 1: + if( nFlags & SUBSFONT_PS && pAttr->PSSubstitutions.size() ) + pVector = &pAttr->PSSubstitutions; + break; + case 2: + if( nFlags & SUBSFONT_HTML && pAttr->HTMLSubstitutions.size() ) + pVector = &pAttr->HTMLSubstitutions; + break; + } + if( ! pVector ) + continue; + for( ::std::vector< String >::const_iterator it = pVector->begin(); it != pVector->end(); ++it ) + if( ! ImplIsFontToken( rName, *it ) ) + { + ImplAppendFontToken( aName, *it ); + if( nFlags & SUBSFONT_ONLYONE ) + { + i = 4; + break; + } + } + } + } + + return aName; +} + +// ----------------------------------------------------------------------- + +// TODO: use a more generic String hash +int FontNameHash::operator()( const String& rStr ) const +{ + // this simple hash just has to be good enough for font names + int nHash = 0; + const int nLen = rStr.Len(); + const sal_Unicode* p = rStr.GetBuffer(); + switch( nLen ) + { + default: nHash = (p[0]<<16) - (p[1]<<8) + p[2]; + nHash += nLen; + p += nLen - 3; + // fall through + case 3: nHash += (p[2]<<16); // fall through + case 2: nHash += (p[1]<<8); // fall through + case 1: nHash += p[0]; // fall through + case 0: break; + }; + + return nHash; +} + diff --git a/unotools/source/misc/makefile.mk b/unotools/source/misc/makefile.mk new file mode 100644 index 000000000000..46e173b9a055 --- /dev/null +++ b/unotools/source/misc/makefile.mk @@ -0,0 +1,55 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=misc + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +SLOFILES= $(SLO)$/atom.obj \ + $(SLO)$/datetime.obj \ + $(SLO)$/syslocale.obj \ + $(SLO)$/eventlisteneradapter.obj \ + $(SLO)$/fontcvt.obj \ + $(SLO)$/fontdefs.obj \ + $(SLO)$/desktopterminationobserver.obj \ + $(SLO)$/sharedunocomponent.obj \ + $(SLO)$/componentresmodule.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/misc/sharedunocomponent.cxx b/unotools/source/misc/sharedunocomponent.cxx new file mode 100644 index 000000000000..5402ebc06085 --- /dev/null +++ b/unotools/source/misc/sharedunocomponent.cxx @@ -0,0 +1,246 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/sharedunocomponent.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <cppuhelper/implbase1.hxx> +#include <tools/debug.hxx> + +//............................................................................ +namespace utl +{ +//............................................................................ + + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::lang::EventObject; + using ::com::sun::star::util::XCloseable; + using ::com::sun::star::util::XCloseListener; + using ::com::sun::star::util::CloseVetoException; + + //======================================================================== + //= DisposableComponent + //======================================================================== + //------------------------------------------------------------------------ + DisposableComponent::DisposableComponent( const Reference< XInterface >& _rxComponent ) + :m_xComponent( _rxComponent, UNO_QUERY ) + { + DBG_ASSERT( m_xComponent.is() || !_rxComponent.is(), "DisposableComponent::DisposableComponent: should be an XComponent!" ); + } + + //------------------------------------------------------------------------ + DisposableComponent::~DisposableComponent() + { + if ( m_xComponent.is() ) + { + try + { + m_xComponent->dispose(); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "DisposableComponent::~DisposableComponent: caught an exception!" ); + } + m_xComponent.clear(); + } + } + + //======================================================================== + //= CloseableComponentImpl + //======================================================================== + DBG_NAME( CloseableComponentImpl ) + typedef ::cppu::WeakImplHelper1 < XCloseListener + > CloseableComponentImpl_Base; + class CloseableComponentImpl : public CloseableComponentImpl_Base + { + private: + Reference< XCloseable > m_xCloseable; + + public: + CloseableComponentImpl( const Reference< XInterface >& _rxComponent ); + + /** closes the component + + @nofail + */ + void nf_closeComponent(); + + protected: + virtual ~CloseableComponentImpl(); + + // XCloseListener overridables + virtual void SAL_CALL queryClosing( const EventObject& Source, ::sal_Bool GetsOwnership ) throw (CloseVetoException, RuntimeException); + virtual void SAL_CALL notifyClosing( const EventObject& Source ) throw (RuntimeException); + + // XEventListener overridables + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + + private: + /** starts or stops being a CloseListener at the component + + Only to be called upon construction of the instance, or when the component + is to be closed. + + @nofail + */ + void impl_nf_switchListening( bool _bListen ); + + + private: + CloseableComponentImpl(); // never implemented + CloseableComponentImpl( const CloseableComponentImpl& ); // never implemented + CloseableComponentImpl& operator=( const CloseableComponentImpl& ); // never implemented + }; + + //------------------------------------------------------------------------ + CloseableComponentImpl::CloseableComponentImpl( const Reference< XInterface >& _rxComponent ) + :m_xCloseable( _rxComponent, UNO_QUERY ) + { + DBG_CTOR( CloseableComponentImpl, NULL ); + DBG_ASSERT( m_xCloseable.is() || !_rxComponent.is(), "CloseableComponentImpl::CloseableComponentImpl: component is not an XCloseable!" ); + impl_nf_switchListening( true ); + } + //------------------------------------------------------------------------ + CloseableComponentImpl::~CloseableComponentImpl() + { + nf_closeComponent(); + DBG_DTOR( CloseableComponentImpl, NULL ); + } + + //------------------------------------------------------------------------ + void CloseableComponentImpl::nf_closeComponent() + { + if ( !m_xCloseable.is() ) + // nothing to do + return; + + // stop listening + impl_nf_switchListening( false ); + + // close + try + { + m_xCloseable->close( sal_True ); + } + catch( const CloseVetoException& ) { /* fine */ } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "CloseableComponentImpl::nf_closeComponent: caught an unexpected exception!" ); + } + + // reset + m_xCloseable.clear(); + } + + //------------------------------------------------------------------------ + void CloseableComponentImpl::impl_nf_switchListening( bool _bListen ) + { + if ( !m_xCloseable.is() ) + return; + + try + { + if ( _bListen ) + m_xCloseable->addCloseListener( this ); + else + m_xCloseable->removeCloseListener( this ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "CloseableComponentImpl::impl_nf_switchListening: caught an exception!" ); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL CloseableComponentImpl::queryClosing( const EventObject& + #ifdef DBG_UTIL + Source + #endif + , ::sal_Bool /*GetsOwnership*/ ) throw (CloseVetoException, RuntimeException) + { + // as long as we live, somebody wants to keep the object alive. So, veto the + // closing + DBG_ASSERT( Source.Source == m_xCloseable, "CloseableComponentImpl::queryClosing: where did this come from?" ); + throw CloseVetoException(); + } + + //-------------------------------------------------------------------- + void SAL_CALL CloseableComponentImpl::notifyClosing( const EventObject& + #ifdef DBG_UTIL + Source + #endif + ) throw (RuntimeException) + { + DBG_ASSERT( Source.Source == m_xCloseable, "CloseableComponentImpl::notifyClosing: where did this come from?" ); + + // this should be unreachable: As long as we're a CloseListener, we veto the closing. If we're going + // to close the component ourself, then we revoke ourself as listener *before* the close call. So, + // if this here fires, something went definately wrong. + DBG_ERROR( "CloseableComponentImpl::notifyClosing: unreachable!" ); + } + + //-------------------------------------------------------------------- + void SAL_CALL CloseableComponentImpl::disposing( const EventObject& + #ifdef DBG_UTIL + Source + #endif + ) throw (RuntimeException) + { + DBG_ASSERT( Source.Source == m_xCloseable, "CloseableComponentImpl::disposing: where did this come from?" ); + DBG_ERROR( "CloseableComponentImpl::disposing: unreachable!" ); + // same reasoning for this assertion as in ->notifyClosing + } + + //======================================================================== + //= CloseableComponentImpl + //======================================================================== + DBG_NAME( CloseableComponent ) + //------------------------------------------------------------------------ + CloseableComponent::CloseableComponent( const Reference< XInterface >& _rxComponent ) + :m_pImpl( new CloseableComponentImpl( _rxComponent ) ) + { + DBG_CTOR( CloseableComponent, NULL ); + } + + //------------------------------------------------------------------------ + CloseableComponent::~CloseableComponent() + { + // close the component, deliver ownership to anybody who wants to veto the close + m_pImpl->nf_closeComponent(); + DBG_DTOR( CloseableComponent, NULL ); + } + +//............................................................................ +} // namespace utl +//............................................................................ diff --git a/unotools/source/misc/syslocale.cxx b/unotools/source/misc/syslocale.cxx new file mode 100644 index 000000000000..f51ef35512cb --- /dev/null +++ b/unotools/source/misc/syslocale.cxx @@ -0,0 +1,214 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#ifndef GCC +#endif + +#include <unotools/syslocale.hxx> +#include <tools/string.hxx> +#include <unotools/syslocaleoptions.hxx> +#include <unotools/localedatawrapper.hxx> +#include <comphelper/processfactory.hxx> +#include <i18npool/mslangid.hxx> +#include <rtl/tencinfo.h> +#include <rtl/locale.h> +#include <osl/nlsupport.h> + +using namespace osl; +using namespace com::sun::star; + + +SvtSysLocale_Impl* SvtSysLocale::pImpl = NULL; +sal_Int32 SvtSysLocale::nRefCount = 0; + + +class SvtSysLocale_Impl : public utl::ConfigurationListener +{ +public: + SvtSysLocaleOptions aSysLocaleOptions; + LocaleDataWrapper* pLocaleData; + CharClass* pCharClass; + + SvtSysLocale_Impl(); + virtual ~SvtSysLocale_Impl(); + + CharClass* GetCharClass(); + virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 ); +}; + +// ----------------------------------------------------------------------- + +SvtSysLocale_Impl::SvtSysLocale_Impl() : pCharClass(NULL) +{ + pLocaleData = new LocaleDataWrapper( ::comphelper::getProcessServiceFactory(), aSysLocaleOptions.GetRealLocale() ); + + // listen for further changes + aSysLocaleOptions.AddListener( this ); +} + + +SvtSysLocale_Impl::~SvtSysLocale_Impl() +{ + aSysLocaleOptions.RemoveListener( this ); + delete pCharClass; + delete pLocaleData; +} + +CharClass* SvtSysLocale_Impl::GetCharClass() +{ + if ( !pCharClass ) + pCharClass = new CharClass(::comphelper::getProcessServiceFactory(), aSysLocaleOptions.GetRealLocale() ); + return pCharClass; +} + +void SvtSysLocale_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint ) +{ + MutexGuard aGuard( SvtSysLocale::GetMutex() ); + if ( nHint & SYSLOCALEOPTIONS_HINT_LOCALE ) + { + com::sun::star::lang::Locale aLocale( aSysLocaleOptions.GetRealLocale() ); + pLocaleData->setLocale( aLocale ); + GetCharClass()->setLocale( aLocale ); + } +} + +// ==================================================================== + +SvtSysLocale::SvtSysLocale() +{ + MutexGuard aGuard( GetMutex() ); + if ( !pImpl ) + pImpl = new SvtSysLocale_Impl; + ++nRefCount; +} + + +SvtSysLocale::~SvtSysLocale() +{ + MutexGuard aGuard( GetMutex() ); + if ( !--nRefCount ) + { + delete pImpl; + pImpl = NULL; + } +} + + +// static +Mutex& SvtSysLocale::GetMutex() +{ + static Mutex* pMutex = NULL; + if( !pMutex ) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if( !pMutex ) + { + // #i77768# Due to a static reference in the toolkit lib + // we need a mutex that lives longer than the svl library. + // Otherwise the dtor would use a destructed mutex!! + pMutex = new Mutex; + } + } + return *pMutex; +} + + +const LocaleDataWrapper& SvtSysLocale::GetLocaleData() const +{ + return *(pImpl->pLocaleData); +} + + +const LocaleDataWrapper* SvtSysLocale::GetLocaleDataPtr() const +{ + return pImpl->pLocaleData; +} + + +const CharClass& SvtSysLocale::GetCharClass() const +{ + return *(pImpl->GetCharClass()); +} + + +const CharClass* SvtSysLocale::GetCharClassPtr() const +{ + return pImpl->GetCharClass(); +} + +SvtSysLocaleOptions& SvtSysLocale::GetOptions() const +{ + return pImpl->aSysLocaleOptions; +} + +com::sun::star::lang::Locale SvtSysLocale::GetLocale() const +{ + return pImpl->aSysLocaleOptions.GetRealLocale(); +} + +LanguageType SvtSysLocale::GetLanguage() const +{ + return pImpl->aSysLocaleOptions.GetRealLanguage(); +} + +com::sun::star::lang::Locale SvtSysLocale::GetUILocale() const +{ + return pImpl->aSysLocaleOptions.GetRealUILocale(); +} + +LanguageType SvtSysLocale::GetUILanguage() const +{ + return pImpl->aSysLocaleOptions.GetRealUILanguage(); +} + +//------------------------------------------------------------------------ + +// static +rtl_TextEncoding SvtSysLocale::GetBestMimeEncoding() +{ + const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding( + gsl_getSystemTextEncoding() ); + if ( !pCharSet ) + { + // If the system locale is unknown to us, e.g. LC_ALL=xx, match the UI + // language if possible. + ::com::sun::star::lang::Locale aLocale( SvtSysLocale().GetUILocale() ); + rtl_Locale * pLocale = rtl_locale_register( aLocale.Language.getStr(), + aLocale.Country.getStr(), aLocale.Variant.getStr() ); + rtl_TextEncoding nEnc = osl_getTextEncodingFromLocale( pLocale ); + pCharSet = rtl_getBestMimeCharsetFromTextEncoding( nEnc ); + } + rtl_TextEncoding nRet; + if ( pCharSet ) + nRet = rtl_getTextEncodingFromMimeCharset( pCharSet ); + else + nRet = RTL_TEXTENCODING_UTF8; + return nRet; +} + diff --git a/unotools/source/processfactory/componentfactory.cxx b/unotools/source/processfactory/componentfactory.cxx new file mode 100644 index 000000000000..67055ee215ca --- /dev/null +++ b/unotools/source/processfactory/componentfactory.cxx @@ -0,0 +1,186 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/componentfactory.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HDL_ +#include <com/sun/star/registry/XRegistryKey.hpp> +#endif + +#include <cppuhelper/factory.hxx> + +#include <uno/environment.h> +#include <uno/mapping.hxx> + +#include <rtl/ustring.hxx> +#include <osl/module.h> + + + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; +using namespace ::rtl; + + +namespace utl +{ + +Reference< XInterface > getComponentInstance( + const OUString & rLibraryName, + const OUString & rImplementationName + ) +{ + Reference< XInterface > xI; + Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + if ( xMSF.is() ) + xI = xMSF->createInstance( rImplementationName ); + if( !xI.is() ) + { + Reference< XSingleServiceFactory > xSSF = + loadLibComponentFactory( rLibraryName, rImplementationName, + Reference< XMultiServiceFactory >(), Reference< XRegistryKey >() ); + xI = xSSF->createInstance(); + } + return xI; +} + + +Reference< XSingleServiceFactory > loadLibComponentFactory( + const OUString & rLibName, + const OUString & rImplName, + const Reference< XMultiServiceFactory > & xSF, + const Reference< XRegistryKey > & xKey + ) +{ + Reference< XSingleServiceFactory > xRet; + + oslModule lib = osl_loadModule( rLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL ); + if (lib) + { + void * pSym; + + // ========================= LATEST VERSION ========================= + OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) ); + if (pSym = osl_getSymbol( lib, aGetEnvName.pData )) + { + uno_Environment * pCurrentEnv = 0; + uno_Environment * pEnv = 0; + const sal_Char * pEnvTypeName = 0; + (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv ); + + sal_Bool bNeedsMapping = + (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME )); + + OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) ); + + if (bNeedsMapping) + { + if (! pEnv) + uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 ); + if (pEnv) + { + OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 ); + if (pCurrentEnv) + bNeedsMapping = (pEnv != pCurrentEnv); + } + } + + OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) ); + if (pSym = osl_getSymbol( lib, aGetFactoryName.pData )) + { + OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) ); + + if (bNeedsMapping) + { + if (pEnv && pCurrentEnv) + { + Mapping aCurrent2Env( pCurrentEnv, pEnv ); + Mapping aEnv2Current( pEnv, pCurrentEnv ); + + if (aCurrent2Env.is() && aEnv2Current.is()) + { + void * pSMgr = aCurrent2Env.mapInterface( + xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) ); + void * pKey = aCurrent2Env.mapInterface( + xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) ); + + void * pSSF = (*((component_getFactoryFunc)pSym))( + aImplName.getStr(), pSMgr, pKey ); + + if (pKey) + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey ); + if (pSMgr) + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr ); + + if (pSSF) + { + aEnv2Current.mapInterface( + reinterpret_cast< void ** >( &xRet ), + pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) ); + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF ); + } + } + } + } + else + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *) + (*((component_getFactoryFunc)pSym))( + aImplName.getStr(), xSF.get(), xKey.get() ); + if (pRet) + { + xRet = pRet; + pRet->release(); + } + } + } + + if (pEnv) + (*pEnv->release)( pEnv ); + if (pCurrentEnv) + (*pCurrentEnv->release)( pCurrentEnv ); + } + + + if (! xRet.is()) + osl_unloadModule( lib ); + } + + return xRet; +} + +} // namespace utl diff --git a/unotools/source/processfactory/makefile.mk b/unotools/source/processfactory/makefile.mk new file mode 100644 index 000000000000..0e1e4aeacca8 --- /dev/null +++ b/unotools/source/processfactory/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=procfact + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings common for the whole project ----- + + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +SLOFILES= $(SLO)$/processfactory.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/processfactory/processfactory.cxx b/unotools/source/processfactory/processfactory.cxx new file mode 100644 index 000000000000..e1f0cc876dce --- /dev/null +++ b/unotools/source/processfactory/processfactory.cxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <osl/mutex.hxx> +#include <unotools/processfactory.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace osl; + +namespace utl +{ + // just use the comphelper versions of both functions. The versions here in unotools will become obsolete + // from SRC610 on. + + void setProcessServiceFactory(const Reference< XMultiServiceFactory >& xSMgr) + { + ::comphelper::setProcessServiceFactory(xSMgr); + } + + Reference< XMultiServiceFactory > getProcessServiceFactory() + { + return ::comphelper::getProcessServiceFactory(); + } + +} // namesapce utl + diff --git a/unotools/source/property/makefile.mk b/unotools/source/property/makefile.mk new file mode 100644 index 000000000000..c53f5a8d2cf5 --- /dev/null +++ b/unotools/source/property/makefile.mk @@ -0,0 +1,48 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=property + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +SLOFILES= $(SLO)$/propertysetinfo.obj \ + $(SLO)$/propertysethelper.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/property/propertysethelper.cxx b/unotools/source/property/propertysethelper.cxx new file mode 100644 index 000000000000..fac76bbe882a --- /dev/null +++ b/unotools/source/property/propertysethelper.cxx @@ -0,0 +1,301 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <tools/debug.hxx> + +#include "unotools/propertysetinfo.hxx" +#include "unotools/propertysethelper.hxx" + +/////////////////////////////////////////////////////////////////////// + +using namespace ::utl; +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; + +namespace utl +{ +class PropertySetHelperImpl +{ +public: + PropertyMapEntry* find( const OUString& aName ) const throw(); + + PropertySetInfo* mpInfo; +}; +} + +PropertyMapEntry* PropertySetHelperImpl::find( const OUString& aName ) const throw() +{ + PropertyMap::const_iterator aIter = mpInfo->getPropertyMap()->find( aName ); + + if( mpInfo->getPropertyMap()->end() != aIter ) + { + return (*aIter).second; + } + else + { + return NULL; + } +} + +/////////////////////////////////////////////////////////////////////// + +PropertySetHelper::PropertySetHelper( utl::PropertySetInfo* pInfo ) throw() +{ + mp = new PropertySetHelperImpl; + mp->mpInfo = pInfo; + pInfo->acquire(); +} + +PropertySetHelper::~PropertySetHelper() throw() +{ + mp->mpInfo->release(); + delete mp; +} + +// XPropertySet +Reference< XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo( ) throw(RuntimeException) +{ + return mp->mpInfo; +} + +void SAL_CALL PropertySetHelper::setPropertyValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + PropertyMapEntry* aEntries[2]; + aEntries[0] = mp->find( aPropertyName ); + + if( NULL == aEntries[0] ) + throw UnknownPropertyException(); + + aEntries[1] = NULL; + + _setPropertyValues( (const PropertyMapEntry**)aEntries, &aValue ); +} + +Any SAL_CALL PropertySetHelper::getPropertyValue( const ::rtl::OUString& PropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyMapEntry* aEntries[2]; + aEntries[0] = mp->find( PropertyName ); + + if( NULL == aEntries[0] ) + throw UnknownPropertyException(); + + aEntries[1] = NULL; + + Any aAny; + _getPropertyValues( (const PropertyMapEntry**)aEntries, &aAny ); + + return aAny; +} + +void SAL_CALL PropertySetHelper::addPropertyChangeListener( const ::rtl::OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::removePropertyChangeListener( const ::rtl::OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::addVetoableChangeListener( const ::rtl::OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::removeVetoableChangeListener( const ::rtl::OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +// XMultiPropertySet +void SAL_CALL PropertySetHelper::setPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames, const Sequence< Any >& aValues ) throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + const sal_Int32 nCount = aPropertyNames.getLength(); + + if( nCount != aValues.getLength() ) + throw IllegalArgumentException(); + + if( nCount ) + { + PropertyMapEntry** pEntries = new PropertyMapEntry*[nCount+1]; + const OUString* pNames = aPropertyNames.getConstArray(); + + sal_Bool bUnknown = sal_False; + sal_Int32 n; + for( n = 0; !bUnknown && ( n < nCount ); n++, pNames++ ) + { + pEntries[n] = mp->find( *pNames ); + bUnknown = NULL == pEntries[n]; + } + + if( !bUnknown ) + _setPropertyValues( (const PropertyMapEntry**)pEntries, aValues.getConstArray() ); + + delete [] pEntries; + + if( bUnknown ) + throw UnknownPropertyException(); + } +} + +Sequence< Any > SAL_CALL PropertySetHelper::getPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames ) throw(RuntimeException) +{ + const sal_Int32 nCount = aPropertyNames.getLength(); + + Sequence< Any > aValues; + if( nCount ) + { + PropertyMapEntry** pEntries = new PropertyMapEntry*[nCount+1]; + const OUString* pNames = aPropertyNames.getConstArray(); + + sal_Bool bUnknown = sal_False; + sal_Int32 n; + for( n = 0; !bUnknown && ( n < nCount ); n++, pNames++ ) + { + pEntries[n] = mp->find( *pNames ); + bUnknown = NULL == pEntries[n]; + } + + if( !bUnknown ) + _getPropertyValues( (const PropertyMapEntry**)pEntries, aValues.getArray() ); + + delete [] pEntries; + + if( bUnknown ) + throw UnknownPropertyException(); + } + + return aValues; +} + +void SAL_CALL PropertySetHelper::addPropertiesChangeListener( const Sequence< ::rtl::OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ ) throw(RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& /*xListener*/ ) throw(RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::firePropertiesChangeEvent( const Sequence< ::rtl::OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ ) throw(RuntimeException) +{ + // todo +} + +// XPropertyState +PropertyState SAL_CALL PropertySetHelper::getPropertyState( const ::rtl::OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException) +{ + PropertyMapEntry* aEntries[2]; + + aEntries[0] = mp->find( PropertyName ); + if( aEntries[0] == NULL ) + throw UnknownPropertyException(); + + aEntries[1] = NULL; + + PropertyState aState; + _getPropertyStates( (const PropertyMapEntry**)aEntries, &aState ); + + return aState; +} + +Sequence< PropertyState > SAL_CALL PropertySetHelper::getPropertyStates( const Sequence< ::rtl::OUString >& aPropertyName ) throw(UnknownPropertyException, RuntimeException) +{ + const sal_Int32 nCount = aPropertyName.getLength(); + + Sequence< PropertyState > aStates( nCount ); + + if( nCount ) + { + const OUString* pNames = aPropertyName.getConstArray(); + + sal_Bool bUnknown = sal_False; + + PropertyMapEntry** pEntries = new PropertyMapEntry*[nCount+1]; + + sal_Int32 n; + for( n = 0; !bUnknown && (n < nCount); n++, pNames++ ) + { + pEntries[n] = mp->find( *pNames ); + bUnknown = NULL == pEntries[n]; + } + + pEntries[nCount] = NULL; + + if( !bUnknown ) + _getPropertyStates( (const PropertyMapEntry**)pEntries, aStates.getArray() ); + + delete [] pEntries; + + if( bUnknown ) + throw UnknownPropertyException(); + } + + return aStates; +} + +void SAL_CALL PropertySetHelper::setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException) +{ + PropertyMapEntry *pEntry = mp->find( PropertyName ); + if( NULL == pEntry ) + throw UnknownPropertyException(); + + _setPropertyToDefault( pEntry ); +} + +Any SAL_CALL PropertySetHelper::getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyMapEntry* pEntry = mp->find( aPropertyName ); + if( NULL == pEntry ) + throw UnknownPropertyException(); + + return _getPropertyDefault( pEntry ); +} + +void PropertySetHelper::_getPropertyStates( const utl::PropertyMapEntry** /*ppEntries*/, PropertyState* /*pStates*/ ) throw(UnknownPropertyException ) +{ + DBG_ERROR( "you have to implement this yourself!" ); +} + +void PropertySetHelper::_setPropertyToDefault( const utl::PropertyMapEntry* /*pEntry*/ ) throw(UnknownPropertyException ) +{ + DBG_ERROR( "you have to implement this yourself!" ); +} + +Any PropertySetHelper::_getPropertyDefault( const utl::PropertyMapEntry* /*pEntry*/ ) throw(UnknownPropertyException, WrappedTargetException ) +{ + DBG_ERROR( "you have to implement this yourself!" ); + + Any aAny; + return aAny; +} diff --git a/unotools/source/property/propertysetinfo.cxx b/unotools/source/property/propertysetinfo.cxx new file mode 100644 index 000000000000..a5b8381de942 --- /dev/null +++ b/unotools/source/property/propertysetinfo.cxx @@ -0,0 +1,199 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <tools/debug.hxx> + +#include "unotools/propertysetinfo.hxx" + +using namespace ::utl; +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; + +namespace utl +{ +class PropertyMapImpl +{ +public: + PropertyMapImpl() throw(); + virtual ~PropertyMapImpl() throw(); + + void add( PropertyMapEntry* pMap ) throw(); + void remove( const OUString& aName ) throw(); + + Sequence< Property > getProperties() throw(); + + const PropertyMap* getPropertyMap() const throw(); + + Property getPropertyByName( const OUString& aName ) throw( UnknownPropertyException ); + sal_Bool hasPropertyByName( const OUString& aName ) throw(); + +private: + PropertyMap maPropertyMap; + Sequence< Property > maProperties; +}; +} + +PropertyMapImpl::PropertyMapImpl() throw() +{ +} + +PropertyMapImpl::~PropertyMapImpl() throw() +{ +} + +void PropertyMapImpl::add( PropertyMapEntry* pMap ) throw() +{ + while( pMap->mpName ) + { + OUString aName( pMap->mpName, pMap->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + +#ifdef DBG_UTIL + PropertyMap::iterator aIter = maPropertyMap.find( aName ); + if( aIter != maPropertyMap.end() ) + { + DBG_ERROR( "Warning: PropertyMapEntry added twice, possible error!" ); + } +#endif + if( NULL == pMap->mpType ) + { + DBG_ERROR( "No type in PropertyMapEntry!" ); + pMap->mpType = &::getCppuType((const sal_Int32*)0); + } + + maPropertyMap[aName] = pMap; + + if( maProperties.getLength() ) + maProperties.realloc( 0 ); + + pMap = &pMap[1]; + } +} + +void PropertyMapImpl::remove( const OUString& aName ) throw() +{ + maPropertyMap.erase( aName ); + + if( maProperties.getLength() ) + maProperties.realloc( 0 ); +} + +Sequence< Property > PropertyMapImpl::getProperties() throw() +{ + // maybe we have to generate the properties after + // a change in the property map or at first call + // to getProperties + if( maProperties.getLength() != (sal_Int32)maPropertyMap.size() ) + { + maProperties = Sequence< Property >( maPropertyMap.size() ); + Property* pProperties = maProperties.getArray(); + + PropertyMap::iterator aIter = maPropertyMap.begin(); + const PropertyMap::iterator aEnd = maPropertyMap.end(); + while( aIter != aEnd ) + { + PropertyMapEntry* pEntry = (*aIter).second; + + pProperties->Name = OUString( pEntry->mpName, pEntry->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + pProperties->Handle = pEntry->mnWhich; + pProperties->Type = *pEntry->mpType; + pProperties->Attributes = pEntry->mnFlags; + pProperties++; + aIter++; + } + } + + return maProperties; +} + +const PropertyMap* PropertyMapImpl::getPropertyMap() const throw() +{ + return &maPropertyMap; +} + +Property PropertyMapImpl::getPropertyByName( const OUString& aName ) throw( UnknownPropertyException ) +{ + PropertyMap::iterator aIter = maPropertyMap.find( aName ); + + if( maPropertyMap.end() == aIter ) + throw UnknownPropertyException(); + + PropertyMapEntry* pEntry = (*aIter).second; + + return Property( aName, pEntry->mnWhich, *pEntry->mpType, pEntry->mnFlags ); +} + +sal_Bool PropertyMapImpl::hasPropertyByName( const OUString& aName ) throw() +{ + return maPropertyMap.find( aName ) != maPropertyMap.end(); +} + +/////////////////////////////////////////////////////////////////////// + +PropertySetInfo::PropertySetInfo() throw() +{ + mpMap = new PropertyMapImpl(); +} + +PropertySetInfo::~PropertySetInfo() throw() +{ + delete mpMap; +} + +void PropertySetInfo::add( PropertyMapEntry* pMap ) throw() +{ + mpMap->add( pMap ); +} + +void PropertySetInfo::remove( const rtl::OUString& aName ) throw() +{ + mpMap->remove( aName ); +} + +Sequence< ::com::sun::star::beans::Property > SAL_CALL PropertySetInfo::getProperties() throw(::com::sun::star::uno::RuntimeException) +{ + return mpMap->getProperties(); +} + +Property SAL_CALL PropertySetInfo::getPropertyByName( const ::rtl::OUString& aName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + return mpMap->getPropertyByName( aName ); +} + +sal_Bool SAL_CALL PropertySetInfo::hasPropertyByName( const ::rtl::OUString& Name ) throw(::com::sun::star::uno::RuntimeException) +{ + return mpMap->hasPropertyByName( Name ); +} + +const PropertyMap* PropertySetInfo::getPropertyMap() const throw() +{ + return mpMap->getPropertyMap(); +} diff --git a/unotools/source/streaming/makefile.mk b/unotools/source/streaming/makefile.mk new file mode 100644 index 000000000000..b70d7fea4091 --- /dev/null +++ b/unotools/source/streaming/makefile.mk @@ -0,0 +1,48 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=streaming + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +SLOFILES= $(SLO)$/streamhelper.obj \ + $(SLO)$/streamwrap.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/streaming/streamhelper.cxx b/unotools/source/streaming/streamhelper.cxx new file mode 100644 index 000000000000..0ca20cf1c5e2 --- /dev/null +++ b/unotools/source/streaming/streamhelper.cxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/streamhelper.hxx> +#include <tools/debug.hxx> + +namespace utl +{ + +//------------------------------------------------------------------------------ +void SAL_CALL OInputStreamHelper::acquire() throw () +{ + InputStreamHelper_Base::acquire(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInputStreamHelper::release() throw () +{ + InputStreamHelper_Base::release(); +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OInputStreamHelper::readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) + throw(stario::NotConnectedException, stario::BufferSizeExceededException, stario::IOException, staruno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + if (nBytesToRead < 0) + throw stario::BufferSizeExceededException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + ::osl::MutexGuard aGuard( m_aMutex ); + aData.realloc(nBytesToRead); + + sal_Size nRead; + ErrCode nError = m_xLockBytes->ReadAt(m_nActPos, (void*)aData.getArray(), nBytesToRead, &nRead); + // FIXME nRead could be truncated on 64-bit arches + m_nActPos += (sal_uInt32)nRead; + + if (nError != ERRCODE_NONE) + throw stario::IOException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + // adjust sequence if data read is lower than the desired data + if (nRead < (sal_uInt32)nBytesToRead) + aData.realloc( nRead ); + + return nRead; +} + +void SAL_CALL OInputStreamHelper::seek( sal_Int64 location ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + // cast is truncating, but position would be truncated as soon as + // put into SvLockBytes anyway + m_nActPos = sal::static_int_cast<sal_uInt32>(location); +} + +sal_Int64 SAL_CALL OInputStreamHelper::getPosition( ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + return m_nActPos; +} + +sal_Int64 SAL_CALL OInputStreamHelper::getLength( ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + return 0; + + ::osl::MutexGuard aGuard( m_aMutex ); + SvLockBytesStat aStat; + m_xLockBytes->Stat( &aStat, SVSTATFLAG_DEFAULT ); + return aStat.nSize; +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OInputStreamHelper::readSomeBytes(staruno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead) + throw (stario::NotConnectedException, stario::BufferSizeExceededException, stario::IOException, staruno::RuntimeException) +{ + // read all data desired + return readBytes(aData, nMaxBytesToRead); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInputStreamHelper::skipBytes(sal_Int32 nBytesToSkip) + throw (stario::NotConnectedException, stario::BufferSizeExceededException, stario::IOException, staruno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_xLockBytes.Is()) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + if (nBytesToSkip < 0) + throw stario::BufferSizeExceededException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + m_nActPos += nBytesToSkip; +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OInputStreamHelper::available() + throw (stario::NotConnectedException, stario::IOException, staruno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_xLockBytes.Is()) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + return m_nAvailable; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInputStreamHelper::closeInput() + throw (stario::NotConnectedException, stario::IOException, staruno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_xLockBytes.Is()) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + m_xLockBytes = NULL; +} + +/*************************************************************************/ +//------------------------------------------------------------------------------ +void SAL_CALL OOutputStreamHelper::acquire() throw () +{ + OutputStreamHelper_Base::acquire(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OOutputStreamHelper::release() throw () +{ + OutputStreamHelper_Base::release(); +} +// stario::XOutputStream +//------------------------------------------------------------------------------ +void SAL_CALL OOutputStreamHelper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) + throw (stario::NotConnectedException, stario::BufferSizeExceededException, stario::IOException, staruno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_xLockBytes.Is()) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + sal_Size nWritten; + ErrCode nError = m_xLockBytes->WriteAt( m_nActPos, aData.getConstArray(), aData.getLength(), &nWritten ); + // FIXME nWritten could be truncated on 64-bit arches + m_nActPos += (sal_uInt32)nWritten; + + if (nError != ERRCODE_NONE || + sal::static_int_cast<sal_Int32>(nWritten) != aData.getLength()) + { + throw stario::IOException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + } +} + +//------------------------------------------------------------------ +void SAL_CALL OOutputStreamHelper::flush() + throw (stario::NotConnectedException, stario::BufferSizeExceededException, stario::IOException, staruno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_xLockBytes.Is()) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + ErrCode nError = m_xLockBytes->Flush(); + if (nError != ERRCODE_NONE) + throw stario::IOException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); +} + +//------------------------------------------------------------------ +void SAL_CALL OOutputStreamHelper::closeOutput( ) + throw(stario::NotConnectedException, stario::BufferSizeExceededException, stario::IOException, staruno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_xLockBytes.Is()) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + m_xLockBytes = NULL; +} + +} // namespace utl + + diff --git a/unotools/source/streaming/streamwrap.cxx b/unotools/source/streaming/streamwrap.cxx new file mode 100644 index 000000000000..eefaa7498070 --- /dev/null +++ b/unotools/source/streaming/streamwrap.cxx @@ -0,0 +1,379 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/streamwrap.hxx> +#include <tools/stream.hxx> +#include <tools/debug.hxx> + +namespace utl +{ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; + +//================================================================== +//= OInputStreamWrapper +//================================================================== +DBG_NAME(OInputStreamWrapper) +//------------------------------------------------------------------ +OInputStreamWrapper::OInputStreamWrapper( SvStream& _rStream ) + :m_pSvStream(&_rStream) + ,m_bSvStreamOwner(sal_False) +{ + DBG_CTOR(OInputStreamWrapper,NULL); + +} + +//------------------------------------------------------------------ +OInputStreamWrapper::OInputStreamWrapper( SvStream* pStream, sal_Bool bOwner ) + :m_pSvStream( pStream ) + ,m_bSvStreamOwner( bOwner ) +{ + DBG_CTOR(OInputStreamWrapper,NULL); + +} + +//------------------------------------------------------------------ +OInputStreamWrapper::~OInputStreamWrapper() +{ + if( m_bSvStreamOwner ) + delete m_pSvStream; + + DBG_DTOR(OInputStreamWrapper,NULL); +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OInputStreamWrapper::readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) + throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + checkConnected(); + + if (nBytesToRead < 0) + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + + ::osl::MutexGuard aGuard( m_aMutex ); + + aData.realloc(nBytesToRead); + + sal_uInt32 nRead = m_pSvStream->Read((void*)aData.getArray(), nBytesToRead); + checkError(); + + // Wenn gelesene Zeichen < MaxLength, staruno::Sequence anpassen + if (nRead < (sal_uInt32)nBytesToRead) + aData.realloc( nRead ); + + return nRead; +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OInputStreamWrapper::readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + checkError(); + + if (nMaxBytesToRead < 0) + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + + if (m_pSvStream->IsEof()) + { + aData.realloc(0); + return 0; + } + else + return readBytes(aData, nMaxBytesToRead); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInputStreamWrapper::skipBytes(sal_Int32 nBytesToSkip) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkError(); + +#ifdef DBG_UTIL + sal_uInt32 nCurrentPos = m_pSvStream->Tell(); +#endif + + m_pSvStream->SeekRel(nBytesToSkip); + checkError(); + +#ifdef DBG_UTIL + nCurrentPos = m_pSvStream->Tell(); +#endif +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OInputStreamWrapper::available() throw( stario::NotConnectedException, staruno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkConnected(); + + sal_uInt32 nPos = m_pSvStream->Tell(); + checkError(); + + m_pSvStream->Seek(STREAM_SEEK_TO_END); + checkError(); + + sal_Int32 nAvailable = (sal_Int32)m_pSvStream->Tell() - nPos; + m_pSvStream->Seek(nPos); + checkError(); + + return nAvailable; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInputStreamWrapper::closeInput() throw( stario::NotConnectedException, staruno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkConnected(); + + if (m_bSvStreamOwner) + delete m_pSvStream; + + m_pSvStream = NULL; +} + +//------------------------------------------------------------------------------ +void OInputStreamWrapper::checkConnected() const +{ + if (!m_pSvStream) + throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this))); +} + +//------------------------------------------------------------------------------ +void OInputStreamWrapper::checkError() const +{ + checkConnected(); + + if (m_pSvStream->SvStream::GetError() != ERRCODE_NONE) + // TODO: really evaluate the error + throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this))); +} + +//================================================================== +//= OSeekableInputStreamWrapper +//================================================================== +//------------------------------------------------------------------------------ +OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream& _rStream) +{ + SetStream( &_rStream, FALSE ); +} + +//------------------------------------------------------------------------------ +OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream* _pStream, sal_Bool _bOwner) +{ + SetStream( _pStream, _bOwner ); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OSeekableInputStreamWrapper::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkConnected(); + + m_pSvStream->Seek((sal_uInt32)_nLocation); + checkError(); +} + +//------------------------------------------------------------------------------ +sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getPosition( ) throw (IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkConnected(); + + sal_uInt32 nPos = m_pSvStream->Tell(); + checkError(); + return (sal_Int64)nPos; +} + +//------------------------------------------------------------------------------ +sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getLength( ) throw (IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkConnected(); + + sal_uInt32 nCurrentPos = m_pSvStream->Tell(); + checkError(); + + m_pSvStream->Seek(STREAM_SEEK_TO_END); + sal_uInt32 nEndPos = m_pSvStream->Tell(); + m_pSvStream->Seek(nCurrentPos); + + checkError(); + + return (sal_Int64)nEndPos; +} + +//================================================================== +//= OOutputStreamWrapper +//================================================================== +//------------------------------------------------------------------------------ +void SAL_CALL OOutputStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + sal_uInt32 nWritten = rStream.Write(aData.getConstArray(),aData.getLength()); + ErrCode err = rStream.GetError(); + if ( (ERRCODE_NONE != err) + || (nWritten != (sal_uInt32)aData.getLength()) + ) + { + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + } +} + +//------------------------------------------------------------------ +void SAL_CALL OOutputStreamWrapper::flush() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + rStream.Flush(); + checkError(); +} + +//------------------------------------------------------------------ +void SAL_CALL OOutputStreamWrapper::closeOutput() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ +} + +//------------------------------------------------------------------------------ +void OOutputStreamWrapper::checkError() const +{ + if (rStream.GetError() != ERRCODE_NONE) + // TODO: really evaluate the error + throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this))); +} + +//================================================================== +//= OSeekableOutputStreamWrapper +//================================================================== +//------------------------------------------------------------------------------ +OSeekableOutputStreamWrapper::OSeekableOutputStreamWrapper(SvStream& _rStream) + :OOutputStreamWrapper(_rStream) +{ +} + +//------------------------------------------------------------------------------ +Any SAL_CALL OSeekableOutputStreamWrapper::queryInterface( const Type& _rType ) throw (RuntimeException) +{ + Any aReturn = OOutputStreamWrapper::queryInterface(_rType); + if (!aReturn.hasValue()) + aReturn = OSeekableOutputStreamWrapper_Base::queryInterface(_rType); + return aReturn; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OSeekableOutputStreamWrapper::acquire( ) throw () +{ + OOutputStreamWrapper::acquire(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OSeekableOutputStreamWrapper::release( ) throw () +{ + OOutputStreamWrapper::release(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OSeekableOutputStreamWrapper::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException) +{ + rStream.Seek((sal_uInt32)_nLocation); + checkError(); +} + +//------------------------------------------------------------------------------ +sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getPosition( ) throw (IOException, RuntimeException) +{ + sal_uInt32 nPos = rStream.Tell(); + checkError(); + return (sal_Int64)nPos; +} + +//------------------------------------------------------------------------------ +sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getLength( ) throw (IOException, RuntimeException) +{ + sal_uInt32 nCurrentPos = rStream.Tell(); + checkError(); + + rStream.Seek(STREAM_SEEK_TO_END); + sal_uInt32 nEndPos = rStream.Tell(); + rStream.Seek(nCurrentPos); + + checkError(); + + return (sal_Int64)nEndPos; +} + +//------------------------------------------------------------------------------ +OStreamWrapper::OStreamWrapper(SvStream& _rStream) +{ + SetStream( &_rStream, FALSE ); +} + +//------------------------------------------------------------------------------ +::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL OStreamWrapper::getInputStream( ) throw (::com::sun::star::uno::RuntimeException) +{ + return this; +} + +//------------------------------------------------------------------------------ +::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL OStreamWrapper::getOutputStream( ) throw (::com::sun::star::uno::RuntimeException) +{ + return this; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException) +{ + sal_uInt32 nWritten = m_pSvStream->Write(aData.getConstArray(),aData.getLength()); + ErrCode err = m_pSvStream->GetError(); + if ( (ERRCODE_NONE != err) + || (nWritten != (sal_uInt32)aData.getLength()) + ) + { + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OStreamWrapper::flush() throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException) +{ + m_pSvStream->Flush(); + if (m_pSvStream->GetError() != ERRCODE_NONE) + throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OStreamWrapper::closeOutput() throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException) +{ +} + +//------------------------------------------------------------------------------ +void SAL_CALL OStreamWrapper::truncate() throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + m_pSvStream->SetStreamSize(0); +} + +} // namespace utl + diff --git a/unotools/source/ucbhelper/XTempFile.hxx b/unotools/source/ucbhelper/XTempFile.hxx new file mode 100644 index 000000000000..115f6cf823a7 --- /dev/null +++ b/unotools/source/ucbhelper/XTempFile.hxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XTEMPFILE_HXX_ +#define _XTEMPFILE_HXX_ + +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XTempFile.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase5.hxx> +#ifndef _CPPUHELPER_PROPERTYSETMIXIN_HXX_ +#include <cppuhelper/propertysetmixin.hxx> +#endif +#include <osl/mutex.hxx> + +class SvStream; +namespace utl { class TempFile; } + +typedef ::cppu::WeakImplHelper5< ::com::sun::star::io::XTempFile + , ::com::sun::star::io::XInputStream + , ::com::sun::star::io::XOutputStream + , ::com::sun::star::io::XTruncate + , ::com::sun::star::lang::XServiceInfo + > + OTempFileBase; + +class OTempFileService : + public OTempFileBase, + public ::cppu::PropertySetMixin< ::com::sun::star::io::XTempFile > +{ +protected: + ::utl::TempFile* mpTempFile; + ::osl::Mutex maMutex; + SvStream* mpStream; + sal_Bool mbRemoveFile; + sal_Bool mbInClosed; + sal_Bool mbOutClosed; + + sal_Int64 mnCachedPos; + sal_Bool mbHasCachedPos; + + void checkError () const; + void checkConnected (); + +public: + OTempFileService (::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & context); + + //Methods + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire( ) + throw (); + virtual void SAL_CALL release( ) + throw (); + // XTypeProvider + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getImplementationId( ) + throw (::com::sun::star::uno::RuntimeException); + + // XTempFile + virtual ::sal_Bool SAL_CALL getRemoveFile() + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRemoveFile( ::sal_Bool _removefile ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getUri() + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getResourceName() + throw (::com::sun::star::uno::RuntimeException); + + // XInputStream + virtual ::sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL available( ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeInput( ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + // XOutputStream + virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL flush( ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeOutput( ) + throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + // XSeekable + virtual void SAL_CALL seek( sal_Int64 location ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getPosition( ) + throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getLength( ) + throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + // XStream + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) + throw (::com::sun::star::uno::RuntimeException); + // XTruncate + virtual void SAL_CALL truncate() + throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw (::com::sun::star::uno::RuntimeException); + + //::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > SAL_CALL XTempFile_createInstance( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & context); + static ::rtl::OUString getImplementationName_Static (); + static ::com::sun::star::uno::Sequence < ::rtl::OUString > getSupportedServiceNames_Static(); + + static ::com::sun::star::uno::Reference < com::sun::star::lang::XSingleComponentFactory > createServiceFactory_Static( com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > const & rServiceFactory ); + +private: + OTempFileService( OTempFileService & ); + virtual ~OTempFileService (); + +}; +#endif diff --git a/unotools/source/ucbhelper/localfilehelper.cxx b/unotools/source/ucbhelper/localfilehelper.cxx new file mode 100644 index 000000000000..5ddd1f811923 --- /dev/null +++ b/unotools/source/ucbhelper/localfilehelper.cxx @@ -0,0 +1,242 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/ucb/CommandAbortedException.hpp> + +#include <unotools/localfilehelper.hxx> +#include <ucbhelper/fileidentifierconverter.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <rtl/ustring.hxx> +#include <osl/file.hxx> +#include <tools/debug.hxx> +#include <tools/list.hxx> +#include <tools/urlobj.hxx> +#include <ucbhelper/content.hxx> + +using namespace ::osl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; + +namespace utl +{ + +sal_Bool LocalFileHelper::ConvertSystemPathToURL( const String& rName, const String& rBaseURL, String& rReturn ) +{ + rReturn = ::rtl::OUString(); + + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( !pBroker ) + { + rtl::OUString aRet; + if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None ) + rReturn = aRet; + } + else + { + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager = + pBroker->getContentProviderManagerInterface(); + try + { + rReturn = ::ucbhelper::getFileURLFromSystemPath( xManager, rBaseURL, rName ); + } + catch ( ::com::sun::star::uno::RuntimeException& ) + { + return sal_False; + } + } + + return ( rReturn.Len() != 0 ); +} + +sal_Bool LocalFileHelper::ConvertURLToSystemPath( const String& rName, String& rReturn ) +{ + rReturn = ::rtl::OUString(); + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( !pBroker ) + { + rtl::OUString aRet; + if( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None ) + rReturn = aRet; + } + else + { + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager = + pBroker->getContentProviderManagerInterface(); + try + { + rReturn = ::ucbhelper::getSystemPathFromFileURL( xManager, rName ); + } + catch ( ::com::sun::star::uno::RuntimeException& ) + { + } + } + + return ( rReturn.Len() != 0 ); +} + +sal_Bool LocalFileHelper::ConvertPhysicalNameToURL( const String& rName, String& rReturn ) +{ + rReturn = ::rtl::OUString(); + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( !pBroker ) + { + rtl::OUString aRet; + if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None ) + rReturn = aRet; + } + else + { + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager = + pBroker->getContentProviderManagerInterface(); + + try + { + rtl::OUString aBase( ::ucbhelper::getLocalFileURL( xManager ) ); + rReturn = ::ucbhelper::getFileURLFromSystemPath( xManager, aBase, rName ); + } + catch ( ::com::sun::star::uno::RuntimeException& ) + { + } + } + + return ( rReturn.Len() != 0 ); +} + +sal_Bool LocalFileHelper::ConvertURLToPhysicalName( const String& rName, String& rReturn ) +{ + rReturn = ::rtl::OUString(); + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( !pBroker ) + { + ::rtl::OUString aRet; + if ( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None ) + rReturn = aRet; + } + else + { + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager = + pBroker->getContentProviderManagerInterface(); + try + { + INetURLObject aObj( rName ); + INetURLObject aLocal( ::ucbhelper::getLocalFileURL( xManager ) ); + if ( aObj.GetProtocol() == aLocal.GetProtocol() ) + rReturn = ::ucbhelper::getSystemPathFromFileURL( xManager, rName ); + } + catch ( ::com::sun::star::uno::RuntimeException& ) + { + } + } + + return ( rReturn.Len() != 0 ); +} + +sal_Bool LocalFileHelper::IsLocalFile( const String& rName ) +{ + String aTmp; + return ConvertURLToPhysicalName( rName, aTmp ); +} + +sal_Bool LocalFileHelper::IsFileContent( const String& rName ) +{ + String aTmp; + return ConvertURLToSystemPath( rName, aTmp ); +} + +DECLARE_LIST( StringList_Impl, ::rtl::OUString* ) + +::com::sun::star::uno::Sequence < ::rtl::OUString > LocalFileHelper::GetFolderContents( const ::rtl::OUString& rFolder, sal_Bool bFolder ) +{ + StringList_Impl* pFiles = NULL; + try + { + ::ucbhelper::Content aCnt( rFolder, Reference< XCommandEnvironment > () ); + Reference< ::com::sun::star::sdbc::XResultSet > xResultSet; + ::com::sun::star::uno::Sequence< ::rtl::OUString > aProps(1); + ::rtl::OUString* pProps = aProps.getArray(); + pProps[0] = ::rtl::OUString::createFromAscii( "Url" ); + + try + { + ::ucbhelper::ResultSetInclude eInclude = bFolder ? ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ::ucbhelper::INCLUDE_DOCUMENTS_ONLY; + xResultSet = aCnt.createCursor( aProps, eInclude ); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( Exception& ) + { + } + + if ( xResultSet.is() ) + { + pFiles = new StringList_Impl; + Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); + try + { + while ( xResultSet->next() ) + { + ::rtl::OUString aId = xContentAccess->queryContentIdentifierString(); + ::rtl::OUString* pFile = new ::rtl::OUString( aId ); + pFiles->Insert( pFile, LIST_APPEND ); + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( Exception& ) + { + } + } + } + catch( Exception& ) + { + } + + if ( pFiles ) + { + ULONG nCount = pFiles->Count(); + Sequence < ::rtl::OUString > aRet( nCount ); + ::rtl::OUString* pRet = aRet.getArray(); + for ( USHORT i = 0; i < nCount; ++i ) + { + ::rtl::OUString* pFile = pFiles->GetObject(i); + pRet[i] = *( pFile ); + delete pFile; + } + delete pFiles; + return aRet; + } + else + return Sequence < ::rtl::OUString > (); +} + +} diff --git a/unotools/source/ucbhelper/makefile.mk b/unotools/source/ucbhelper/makefile.mk new file mode 100644 index 000000000000..57088c69ca5c --- /dev/null +++ b/unotools/source/ucbhelper/makefile.mk @@ -0,0 +1,54 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=..$/..$/inc +PRJNAME=unotools +TARGET=ucbhelp + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +SLOFILES=\ + $(SLO)$/ucblockbytes.obj \ + $(SLO)$/localfilehelper.obj \ + $(SLO)$/ucbhelper.obj \ + $(SLO)$/ucbstreamhelper.obj \ + $(SLO)$/tempfile.obj \ + $(SLO)$/xtempfile.obj \ + $(SLO)$/progresshandlerwrap.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/unotools/source/ucbhelper/progresshandlerwrap.cxx b/unotools/source/ucbhelper/progresshandlerwrap.cxx new file mode 100644 index 000000000000..7fdbdacabc4b --- /dev/null +++ b/unotools/source/ucbhelper/progresshandlerwrap.cxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" +#include <unotools/progresshandlerwrap.hxx> + +namespace utl +{ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::ucb; + +ProgressHandlerWrap::ProgressHandlerWrap( ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > xSI ) +: m_xStatusIndicator( xSI ) +{ +} + +sal_Bool getStatusFromAny_Impl( const Any& aAny, ::rtl::OUString& aText, sal_Int32& nNum ) +{ + sal_Bool bNumIsSet = sal_False; + + Sequence< Any > aSetList; + if( ( aAny >>= aSetList ) && aSetList.getLength() ) + for( int ind = 0; ind < aSetList.getLength(); ind++ ) + { + if( !bNumIsSet && ( aSetList[ind] >>= nNum ) ) + bNumIsSet = sal_True; + else + !aText.getLength() && ( aSetList[ind] >>= aText ); + } + + return bNumIsSet; +} + +void SAL_CALL ProgressHandlerWrap::push( const Any& Status ) + throw( RuntimeException ) +{ + if( !m_xStatusIndicator.is() ) + return; + + ::rtl::OUString aText; + sal_Int32 nRange; + + if( getStatusFromAny_Impl( Status, aText, nRange ) ) + m_xStatusIndicator->start( aText, nRange ); +} + +void SAL_CALL ProgressHandlerWrap::update( const Any& Status ) + throw( RuntimeException ) +{ + if( !m_xStatusIndicator.is() ) + return; + + ::rtl::OUString aText; + sal_Int32 nValue; + + if( getStatusFromAny_Impl( Status, aText, nValue ) ) + { + if( aText.getLength() ) m_xStatusIndicator->setText( aText ); + m_xStatusIndicator->setValue( nValue ); + } +} + +void SAL_CALL ProgressHandlerWrap::pop() + throw( RuntimeException ) +{ + if( m_xStatusIndicator.is() ) + m_xStatusIndicator->end(); +} + +} // namespace utl + diff --git a/unotools/source/ucbhelper/tempfile.cxx b/unotools/source/ucbhelper/tempfile.cxx new file mode 100644 index 000000000000..26742151ee3d --- /dev/null +++ b/unotools/source/ucbhelper/tempfile.cxx @@ -0,0 +1,493 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/tempfile.hxx> +#include <tools/tempfile.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <ucbhelper/fileidentifierconverter.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <rtl/ustring.hxx> +#include <rtl/instance.hxx> +#include <osl/file.hxx> +#include <tools/time.hxx> +#include <tools/debug.hxx> +#include <stdio.h> + +#ifdef UNX +#include <sys/stat.h> +#endif + +using namespace osl; + +namespace +{ + struct TempNameBase_Impl + : public rtl::Static< ::rtl::OUString, TempNameBase_Impl > {}; +} + +namespace utl +{ + +struct TempFile_Impl +{ + String aName; + String aURL; + SvStream* pStream; + sal_Bool bIsDirectory; + + TempFile_Impl() + : pStream(0) + {} +}; + +rtl::OUString getParentName( const rtl::OUString& aFileName ) +{ + sal_Int32 lastIndex = aFileName.lastIndexOf( sal_Unicode('/') ); + rtl::OUString aParent = aFileName.copy( 0,lastIndex ); + + if( aParent[ aParent.getLength()-1] == sal_Unicode(':') && aParent.getLength() == 6 ) + aParent += rtl::OUString::createFromAscii( "/" ); + + if( 0 == aParent.compareToAscii( "file://" ) ) + aParent = rtl::OUString::createFromAscii( "file:///" ); + + return aParent; +} + +sal_Bool ensuredir( const rtl::OUString& rUnqPath ) +{ + rtl::OUString aPath; + if ( rUnqPath.getLength() < 1 ) + return sal_False; + + // remove trailing slash + if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) ) + aPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 ); + else + aPath = rUnqPath; + + // HACK: create directory on a mount point with nobrowse option + // returns ENOSYS in any case !! + osl::Directory aDirectory( aPath ); +#ifdef UNX +/* RW permission for the user only! */ + mode_t old_mode = umask(077); +#endif + osl::FileBase::RC nError = aDirectory.open(); +#ifdef UNX +umask(old_mode); +#endif + aDirectory.close(); + if( nError == osl::File::E_None ) + return sal_True; + + // try to create the directory + nError = osl::Directory::create( aPath ); + sal_Bool bSuccess = ( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST ); + if( !bSuccess ) + { + // perhaps parent(s) don't exist + rtl::OUString aParentDir = getParentName( aPath ); + if ( aParentDir != aPath ) + { + bSuccess = ensuredir( getParentName( aPath ) ); + + // After parent directory structure exists try it one's more + if ( bSuccess ) + { + // Parent directory exists, retry creation of directory + nError = osl::Directory::create( aPath ); + bSuccess =( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST ); + } + } + } + + return bSuccess; +} + +#define TMPNAME_SIZE ( 1 + 5 + 5 + 4 + 1 ) +String ConstructTempDir_Impl( const String* pParent ) +{ + String aName; + if ( pParent && pParent->Len() ) + { + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( pBroker ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager = + pBroker->getContentProviderManagerInterface(); + + // if parent given try to use it + rtl::OUString aTmp( *pParent ); + + // test for valid filename + rtl::OUString aRet; + ::osl::FileBase::getFileURLFromSystemPath( + ::ucbhelper::getSystemPathFromFileURL( xManager, aTmp ), + aRet ); + if ( aRet.getLength() ) + { + ::osl::DirectoryItem aItem; + sal_Int32 i = aRet.getLength(); + if ( aRet[i-1] == '/' ) + i--; + + if ( DirectoryItem::get( ::rtl::OUString( aRet, i ), aItem ) == FileBase::E_None ) + aName = aRet; + } + } + else + { + DBG_WARNING( "::unotools::TempFile : UCB not present or not initialized!" ); + } + } + + if ( !aName.Len() ) + { + ::rtl::OUString &rTempNameBase_Impl = TempNameBase_Impl::get(); + if (rTempNameBase_Impl.getLength() == 0) + { + ::rtl::OUString ustrTempDirURL; + ::osl::FileBase::RC rc = ::osl::File::getTempDirURL( + ustrTempDirURL ); + if (rc == ::osl::FileBase::E_None) + rTempNameBase_Impl = ustrTempDirURL; + } + // if no parent or invalid parent : use default directory + DBG_ASSERT( rTempNameBase_Impl.getLength(), "No TempDir!" ); + aName = rTempNameBase_Impl; + ensuredir( aName ); + } + + // Make sure that directory ends with a separator + xub_StrLen i = aName.Len(); + if( i>0 && aName.GetChar(i-1) != '/' ) + aName += '/'; + + return aName; +} + +void CreateTempName_Impl( String& rName, sal_Bool bKeep, sal_Bool bDir = sal_True ) +{ + // add a suitable tempname + // 36 ** 6 == 2176782336 + unsigned const nRadix = 36; + unsigned long const nMax = (nRadix*nRadix*nRadix*nRadix*nRadix*nRadix); + String aName( rName ); + aName += String::CreateFromAscii( "sv" ); + + rName.Erase(); + unsigned long nSeed = Time::GetSystemTicks() % nMax; + for ( unsigned long u = nSeed; ++u != nSeed; ) + { + u %= nMax; + String aTmp( aName ); + aTmp += String::CreateFromInt64( static_cast<sal_Int64>(u), nRadix ); + aTmp += String::CreateFromAscii( ".tmp" ); + + if ( bDir ) + { + FileBase::RC err = Directory::create( aTmp ); + if ( err == FileBase::E_None ) + { + // !bKeep: only for creating a name, not a file or directory + if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None ) + rName = aTmp; + break; + } + else if ( err != FileBase::E_EXIST ) + { + // if f.e. name contains invalid chars stop trying to create dirs + break; + } + } + else + { + DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" ); + File aFile( aTmp ); +#ifdef UNX +/* RW permission for the user only! */ + mode_t old_mode = umask(077); +#endif + FileBase::RC err = aFile.open( osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock ); +#ifdef UNX +umask(old_mode); +#endif + if ( err == FileBase::E_None ) + { + rName = aTmp; + aFile.close(); + break; + } + else if ( err != FileBase::E_EXIST ) + { + // if f.e. name contains invalid chars stop trying to create files + // but if there is a folder with such name proceed further + + DirectoryItem aTmpItem; + FileStatus aTmpStatus( FileStatusMask_Type ); + if ( DirectoryItem::get( aTmp, aTmpItem ) != FileBase::E_None + || aTmpItem.getFileStatus( aTmpStatus ) != FileBase::E_None + || aTmpStatus.getFileType() != FileStatus::Directory ) + break; + } + } + } +} + +void lcl_createName(TempFile_Impl& _rImpl,const String& rLeadingChars,sal_Bool _bStartWithZero, const String* pExtension, const String* pParent, sal_Bool bDirectory) +{ + _rImpl.bIsDirectory = bDirectory; + + // get correct directory + String aName = ConstructTempDir_Impl( pParent ); + + sal_Bool bUseNumber = _bStartWithZero; + // now use special naming scheme ( name takes leading chars and an index counting up from zero + aName += rLeadingChars; + for ( sal_Int32 i=0;; i++ ) + { + String aTmp( aName ); + if ( bUseNumber ) + aTmp += String::CreateFromInt32( i ); + bUseNumber = sal_True; + if ( pExtension ) + aTmp += *pExtension; + else + aTmp += String::CreateFromAscii( ".tmp" ); + if ( bDirectory ) + { + FileBase::RC err = Directory::create( aTmp ); + if ( err == FileBase::E_None ) + { + _rImpl.aName = aTmp; + break; + } + else if ( err != FileBase::E_EXIST ) + // if f.e. name contains invalid chars stop trying to create dirs + break; + } + else + { + File aFile( aTmp ); +#ifdef UNX +/* RW permission for the user only! */ + mode_t old_mode = umask(077); +#endif + FileBase::RC err = aFile.open(osl_File_OpenFlag_Create); +#ifdef UNX +umask(old_mode); +#endif + if ( err == FileBase::E_None ) + { + _rImpl.aName = aTmp; + aFile.close(); + break; + } + else if ( err != FileBase::E_EXIST ) + { + // if f.e. name contains invalid chars stop trying to create dirs + // but if there is a folder with such name proceed further + + DirectoryItem aTmpItem; + FileStatus aTmpStatus( FileStatusMask_Type ); + if ( DirectoryItem::get( aTmp, aTmpItem ) != FileBase::E_None + || aTmpItem.getFileStatus( aTmpStatus ) != FileBase::E_None + || aTmpStatus.getFileType() != FileStatus::Directory ) + break; + } + } + if ( !_bStartWithZero ) + aTmp += String::CreateFromInt32( i ); + } +} + + +String TempFile::CreateTempName( const String* pParent ) +{ + // get correct directory + String aName = ConstructTempDir_Impl( pParent ); + + // get TempFile name with default naming scheme + CreateTempName_Impl( aName, sal_False ); + + // convert to file URL + rtl::OUString aTmp; + if ( aName.Len() ) + FileBase::getSystemPathFromFileURL( aName, aTmp ); + return aTmp; +} + +TempFile::TempFile( const String* pParent, sal_Bool bDirectory ) + : pImp( new TempFile_Impl ) + , bKillingFileEnabled( sal_False ) +{ + pImp->bIsDirectory = bDirectory; + + // get correct directory + pImp->aName = ConstructTempDir_Impl( pParent ); + + // get TempFile with default naming scheme + CreateTempName_Impl( pImp->aName, sal_True, bDirectory ); +} + +TempFile::TempFile( const String& rLeadingChars, const String* pExtension, const String* pParent, sal_Bool bDirectory) + : pImp( new TempFile_Impl ) + , bKillingFileEnabled( sal_False ) +{ + lcl_createName(*pImp,rLeadingChars,sal_True, pExtension, pParent, bDirectory); +} +TempFile::TempFile( const String& rLeadingChars,sal_Bool _bStartWithZero, const String* pExtension, const String* pParent, sal_Bool bDirectory) + : pImp( new TempFile_Impl ) + , bKillingFileEnabled( sal_False ) +{ + lcl_createName(*pImp,rLeadingChars,_bStartWithZero, pExtension, pParent, bDirectory); +} + +TempFile::~TempFile() +{ + delete pImp->pStream; + if ( bKillingFileEnabled ) + { + if ( pImp->bIsDirectory ) + { + // at the moment no recursiv algorithm present + Directory::remove( pImp->aName ); + } + else + { + File::remove( pImp->aName ); + } + } + + delete pImp; +} + +sal_Bool TempFile::IsValid() const +{ + return pImp->aName.Len() != 0; +} + +String TempFile::GetFileName() const +{ + rtl::OUString aTmp; + FileBase::getSystemPathFromFileURL( pImp->aName, aTmp ); + return aTmp; +} + +String TempFile::GetURL() const +{ + if ( !pImp->aURL.Len() ) + { + String aTmp; + LocalFileHelper::ConvertPhysicalNameToURL( GetFileName(), aTmp ); + pImp->aURL = aTmp; + } + + return pImp->aURL; +} + +SvStream* TempFile::GetStream( StreamMode eMode ) +{ + if ( !pImp->pStream ) + { + if ( GetURL().Len() ) + pImp->pStream = UcbStreamHelper::CreateStream( pImp->aURL, eMode, sal_True /* bFileExists */ ); + else + pImp->pStream = new SvMemoryStream( eMode ); + } + + return pImp->pStream; +} + +void TempFile::CloseStream() +{ + if ( pImp->pStream ) + { + delete pImp->pStream; + pImp->pStream = NULL; + } +} + +String TempFile::SetTempNameBaseDirectory( const String &rBaseName ) +{ + if( !rBaseName.Len() ) + return String(); + + rtl::OUString aUnqPath( rBaseName ); + + // remove trailing slash + if ( rBaseName.GetChar( rBaseName.Len() - 1 ) == sal_Unicode( '/' ) ) + aUnqPath = rBaseName.Copy( 0, rBaseName.Len() - 1 ); + + // try to create the directory + sal_Bool bRet = sal_False; + osl::FileBase::RC err = osl::Directory::create( aUnqPath ); + if ( err != FileBase::E_None && err != FileBase::E_EXIST ) + // perhaps parent(s) don't exist + bRet = ensuredir( aUnqPath ); + else + bRet = sal_True; + + // failure to create base directory means returning an empty string + rtl::OUString aTmp; + if ( bRet ) + { + // append own internal directory + bRet = sal_True; + ::rtl::OUString &rTempNameBase_Impl = TempNameBase_Impl::get(); + rTempNameBase_Impl = rBaseName; + rTempNameBase_Impl += String( '/' ); + + TempFile aBase( NULL, sal_True ); + if ( aBase.IsValid() ) + // use it in case of success + rTempNameBase_Impl = aBase.pImp->aName; + + // return system path of used directory + FileBase::getSystemPathFromFileURL( rTempNameBase_Impl, aTmp ); + } + + return aTmp; +} + +String TempFile::GetTempNameBaseDirectory() +{ + const ::rtl::OUString &rTempNameBase_Impl = TempNameBase_Impl::get(); + if ( !rTempNameBase_Impl.getLength() ) + return String(); + + rtl::OUString aTmp; + FileBase::getSystemPathFromFileURL( rTempNameBase_Impl, aTmp ); + return aTmp; +} + +} diff --git a/unotools/source/ucbhelper/ucbhelper.cxx b/unotools/source/ucbhelper/ucbhelper.cxx new file mode 100644 index 000000000000..8befb8a0f209 --- /dev/null +++ b/unotools/source/ucbhelper/ucbhelper.cxx @@ -0,0 +1,925 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include "unotools/ucbhelper.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/ucb/XContentIdentifierFactory.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/ucb/CommandAbortedException.hpp> +#include <com/sun/star/ucb/IllegalIdentifierException.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/ucb/NameClash.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> +#include <com/sun/star/ucb/TransferInfo.hpp> +#include <com/sun/star/ucb/XAnyCompareFactory.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/ucb/ContentInfo.hpp> +#include <com/sun/star/ucb/ContentInfoAttribute.hpp> +#include <com/sun/star/ucb/XDynamicResultSet.hpp> +#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <ucbhelper/commandenvironment.hxx> +#include <ucbhelper/content.hxx> +#include <comphelper/processfactory.hxx> +#include <osl/file.hxx> + +#include <tools/wldcrd.hxx> +#include <tools/ref.hxx> +#include <tools/debug.hxx> +#include <tools/urlobj.hxx> +#include <tools/datetime.hxx> +#include <ucbhelper/contentbroker.hxx> + +#include "unotools/localfilehelper.hxx" + +using namespace ucbhelper; +using namespace com::sun::star; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace com::sun::star::lang; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::task; +using namespace com::sun::star::uno; +using namespace com::sun::star::ucb; +using namespace rtl; +using namespace comphelper; +using namespace osl; + +DECLARE_LIST( StringList_Impl, OUString* ) + +#define CONVERT_DATETIME( aUnoDT, aToolsDT ) \ + aToolsDT = DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \ + Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) ); + +namespace utl +{ + +sal_Bool UCBContentHelper::Transfer_Impl( const String& rSource, const String& rDest, sal_Bool bMoveData, sal_Int32 nNameClash ) +{ + sal_Bool bRet = sal_True, bKillSource = sal_False; + INetURLObject aSourceObj( rSource ); + DBG_ASSERT( aSourceObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + + INetURLObject aDestObj( rDest ); + DBG_ASSERT( aDestObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + if ( bMoveData && aSourceObj.GetProtocol() != aDestObj.GetProtocol() ) + { + bMoveData = sal_False; + bKillSource = sal_True; + } + String aName = aDestObj.getName(); + aDestObj.removeSegment(); + aDestObj.setFinalSlash(); + + try + { + Content aDestPath( aDestObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + uno::Reference< ::com::sun::star::ucb::XCommandInfo > xInfo = aDestPath.getCommands(); + OUString aTransferName = OUString::createFromAscii( "transfer" ); + if ( xInfo->hasCommandByName( aTransferName ) ) + { + aDestPath.executeCommand( aTransferName, makeAny( + ::com::sun::star::ucb::TransferInfo( bMoveData, aSourceObj.GetMainURL( INetURLObject::NO_DECODE ), aName, nNameClash ) ) ); + } + else + { + DBG_ERRORFILE( "transfer command not available" ); + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + bRet = sal_False; + } + catch( ::com::sun::star::uno::Exception& ) + { + bRet = sal_False; + } + + if ( bKillSource ) + UCBContentHelper::Kill( rSource ); + + return bRet; +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::IsDocument( const String& rContent ) +{ + sal_Bool bRet = sal_False; + INetURLObject aObj( rContent ); + DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + + try + { + Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + bRet = aCnt.isDocument(); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + DBG_WARNING( "CommandAbortedException" ); + } + catch( ::com::sun::star::ucb::IllegalIdentifierException& ) + { + DBG_WARNING( "IllegalIdentifierException" ); + } + catch( ContentCreationException& ) + { + DBG_WARNING( "IllegalIdentifierException" ); + } + catch( ::com::sun::star::uno::Exception& ) + { + DBG_WARNING( "Any other exception" ); + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +Any UCBContentHelper::GetProperty( const String& rContent, const ::rtl::OUString& rName ) +{ + INetURLObject aObj( rContent ); + DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + try + { + Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + return aCnt.getPropertyValue( rName ); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + DBG_WARNING( "CommandAbortedException" ); + } + catch( ::com::sun::star::ucb::IllegalIdentifierException& ) + { + DBG_WARNING( "IllegalIdentifierException" ); + } + catch( ContentCreationException& ) + { + DBG_WARNING( "IllegalIdentifierException" ); + } + catch( ::com::sun::star::uno::Exception& ) + { + DBG_WARNING( "Any other exception" ); + } + + return Any(); +} + +sal_Bool UCBContentHelper::IsFolder( const String& rContent ) +{ + sal_Bool bRet = sal_False; + INetURLObject aObj( rContent ); + DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + try + { + Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + bRet = aCnt.isFolder(); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + DBG_WARNING( "CommandAbortedException" ); + } + catch( ::com::sun::star::ucb::IllegalIdentifierException& ) + { + DBG_WARNING( "IllegalIdentifierException" ); + } + catch( ContentCreationException& ) + { + DBG_WARNING( "IllegalIdentifierException" ); + } + catch( ::com::sun::star::uno::Exception& ) + { + DBG_WARNING( "Any other exception" ); + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::GetTitle( const String& rContent, String& rTitle ) +{ + sal_Bool bRet = sal_False; + INetURLObject aObj( rContent ); + DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + try + { + Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + OUString aTemp; + if ( aCnt.getPropertyValue( OUString::createFromAscii( "Title" ) ) >>= aTemp ) + { + rTitle = String( aTemp ); + bRet = sal_True; + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( ::com::sun::star::uno::Exception& ) + { + } + return bRet; +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::Kill( const String& rContent ) +{ + sal_Bool bRet = sal_True; + INetURLObject aDeleteObj( rContent ); + DBG_ASSERT( aDeleteObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + + try + { + Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + DBG_WARNING( "CommandAbortedException" ); + bRet = sal_False; + } + catch( ::com::sun::star::uno::Exception& ) + { + DBG_WARNING( "Any other exception" ); + bRet = sal_False; + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +Sequence < OUString > UCBContentHelper::GetFolderContents( const String& rFolder, sal_Bool bFolder, sal_Bool bSorted ) +{ + StringList_Impl* pFiles = NULL; + INetURLObject aFolderObj( rFolder ); + DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + try + { + Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + uno::Reference< XResultSet > xResultSet; + Sequence< OUString > aProps( bSorted ? 2 : 1 ); + OUString* pProps = aProps.getArray(); + pProps[0] = OUString::createFromAscii( "Title" ); + if ( bSorted ) + pProps[1] = OUString::createFromAscii( "IsFolder" ); + + try + { + ResultSetInclude eInclude = bFolder ? INCLUDE_FOLDERS_AND_DOCUMENTS : INCLUDE_DOCUMENTS_ONLY; + if ( !bSorted ) + { + xResultSet = aCnt.createCursor( aProps, eInclude ); + } + else + { + uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynResultSet; + xDynResultSet = aCnt.createDynamicCursor( aProps, eInclude ); + + uno::Reference < com::sun::star::ucb::XAnyCompareFactory > xFactory; + uno::Reference < XMultiServiceFactory > xMgr = getProcessServiceFactory(); + uno::Reference < com::sun::star::ucb::XSortedDynamicResultSetFactory > xSRSFac( + xMgr->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SortedDynamicResultSetFactory") ), UNO_QUERY ); + + Sequence< com::sun::star::ucb::NumberedSortingInfo > aSortInfo( 2 ); + com::sun::star::ucb::NumberedSortingInfo* pInfo = aSortInfo.getArray(); + pInfo[ 0 ].ColumnIndex = 2; + pInfo[ 0 ].Ascending = sal_False; + pInfo[ 1 ].ColumnIndex = 1; + pInfo[ 1 ].Ascending = sal_True; + + uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynamicResultSet; + xDynamicResultSet = + xSRSFac->createSortedDynamicResultSet( xDynResultSet, aSortInfo, xFactory ); + if ( xDynamicResultSet.is() ) + { + xResultSet = xDynamicResultSet->getStaticResultSet(); + } + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + // folder not exists? + } + catch( ::com::sun::star::uno::Exception& ) + { + } + + if ( xResultSet.is() ) + { + pFiles = new StringList_Impl; + uno::Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); + try + { + while ( xResultSet->next() ) + { + OUString aId = xContentAccess->queryContentIdentifierString(); + OUString* pFile = new OUString( aId ); + pFiles->Insert( pFile, LIST_APPEND ); + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( ::com::sun::star::uno::Exception& ) + { + } + } + } + catch( ::com::sun::star::uno::Exception& ) + { + } + + if ( pFiles ) + { + ULONG nCount = pFiles->Count(); + Sequence < OUString > aRet( nCount ); + OUString* pRet = aRet.getArray(); + for ( ULONG i = 0; i < nCount; ++i ) + { + OUString* pFile = pFiles->GetObject(i); + pRet[i] = *( pFile ); + delete pFile; + } + delete pFiles; + return aRet; + } + else + return Sequence < OUString > (); +} + +// ----------------------------------------------------------------------- + +Sequence < OUString > UCBContentHelper::GetResultSet( const String& rURL ) +{ + StringList_Impl* pList = NULL; + try + { + Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); + uno::Reference< XResultSet > xResultSet; + uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynResultSet; + Sequence< OUString > aProps(3); + OUString* pProps = aProps.getArray(); + pProps[0] = OUString::createFromAscii( "Title" ); + pProps[1] = OUString::createFromAscii( "ContentType" ); + // TODO: can be optimized, property never used: + pProps[2] = OUString::createFromAscii( "IsFolder" ); + + try + { + xDynResultSet = aCnt.createDynamicCursor( aProps, INCLUDE_FOLDERS_AND_DOCUMENTS ); + if ( xDynResultSet.is() ) + xResultSet = xDynResultSet->getStaticResultSet(); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( ::com::sun::star::uno::Exception& ) + { + } + + if ( xResultSet.is() ) + { + pList = new StringList_Impl; + uno::Reference< com::sun::star::sdbc::XRow > xRow( xResultSet, UNO_QUERY ); + uno::Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); + + try + { + while ( xResultSet->next() ) + { + String aTitle( xRow->getString(1) ); + String aType( xRow->getString(2) ); + String aRow = aTitle; + aRow += '\t'; + aRow += aType; + aRow += '\t'; + aRow += String( xContentAccess->queryContentIdentifierString() ); + OUString* pRow = new OUString( aRow ); + pList->Insert( pRow, LIST_APPEND ); + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( ::com::sun::star::uno::Exception& ) + { + } + } + } + catch( ::com::sun::star::uno::Exception& ) + { + } + + if ( pList ) + { + ULONG nCount = pList->Count(); + Sequence < OUString > aRet( nCount ); + OUString* pRet = aRet.getArray(); + for ( ULONG i = 0; i < nCount; ++i ) + { + OUString* pEntry = pList->GetObject(i); + pRet[i] = *( pEntry ); + delete pEntry; + } + delete pList; + return aRet; + } + else + return Sequence < OUString > (); +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::CopyTo( const String& rSource, const String& rDest ) +{ + return Transfer_Impl( rSource, rDest, sal_False, NameClash::ERROR ); +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::MoveTo( const String& rSource, const String& rDest, sal_Int32 nNameClash ) +{ + return Transfer_Impl( rSource, rDest, sal_True, nNameClash ); +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::CanMakeFolder( const String& rFolder ) +{ + try + { + Content aCnt( rFolder, uno::Reference< XCommandEnvironment > () ); + Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo(); + sal_Int32 nCount = aInfo.getLength(); + if ( nCount == 0 ) + return sal_False; + + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + // Simply look for the first KIND_FOLDER... + const ContentInfo & rCurr = aInfo[i]; + if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER ) + return sal_True; + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) {} + catch( RuntimeException& ) {} + catch( Exception& ) {} + + return sal_False; +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::MakeFolder( const String& rFolder, sal_Bool bNewOnly ) +{ + INetURLObject aURL( rFolder ); + DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); + aURL.removeSegment(); + Content aCnt; + Content aNew; + uno::Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< XInteractionHandler > xInteractionHandler = uno::Reference< XInteractionHandler > ( + xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY ); + if ( Content::create( aURL.GetMainURL( INetURLObject::NO_DECODE ), new CommandEnvironment( xInteractionHandler, uno::Reference< XProgressHandler >() ), aCnt ) ) + return MakeFolder( aCnt, aTitle, aNew, bNewOnly ); + else + return sal_False; +} + +sal_Bool UCBContentHelper::MakeFolder( Content& aCnt, const String& aTitle, Content& rNew, sal_Bool bNewOnly ) +{ + sal_Bool bAlreadyExists = sal_False; + + try + { + Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo(); + sal_Int32 nCount = aInfo.getLength(); + if ( nCount == 0 ) + return sal_False; + + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + // Simply look for the first KIND_FOLDER... + const ContentInfo & rCurr = aInfo[i]; + if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER ) + { + // Make sure the only required bootstrap property is "Title", + const Sequence< Property > & rProps = rCurr.Properties; + if ( rProps.getLength() != 1 ) + continue; + + if ( !rProps[ 0 ].Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) + continue; + + Sequence<OUString> aNames(1); + OUString* pNames = aNames.getArray(); + pNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); + Sequence<Any> aValues(1); + Any* pValues = aValues.getArray(); + pValues[0] = makeAny( OUString( aTitle ) ); + + if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, rNew ) ) + continue; + + return sal_True; + } + } + } + catch ( InteractiveIOException& r ) + { + if ( r.Code == IOErrorCode_ALREADY_EXISTING ) + { + bAlreadyExists = sal_True; + } + } + catch ( NameClashException& ) + { + bAlreadyExists = sal_True; + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( RuntimeException& ) + { + } + catch( Exception& ) + { + } + + if( bAlreadyExists && !bNewOnly ) + { + INetURLObject aObj( aCnt.getURL() ); + aObj.Append( aTitle ); + rNew = Content( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference < XCommandEnvironment >() ); + return sal_True; + } + + return sal_False; +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::HasParentFolder( const String& rFolder ) +{ + sal_Bool bRet = sal_False; + try + { + Content aCnt( rFolder, uno::Reference< XCommandEnvironment > () ); + uno::Reference< XChild > xChild( aCnt.get(), UNO_QUERY ); + if ( xChild.is() ) + { + uno::Reference< XContent > xParent( xChild->getParent(), UNO_QUERY ); + if ( xParent.is() ) + { + String aParentURL = String( xParent->getIdentifier()->getContentIdentifier() ); + bRet = ( aParentURL.Len() > 0 && aParentURL != rFolder ); + } + } + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( ::com::sun::star::uno::Exception& ) + { + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +ULONG UCBContentHelper::GetSize( const String& rContent ) +{ + ULONG nSize = 0; + sal_Int64 nTemp = 0; + INetURLObject aObj( rContent ); + DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + try + { + Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= nTemp; + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( ::com::sun::star::uno::Exception& ) + { + } + nSize = (UINT32)nTemp; + return nSize; +} + +// ----------------------------------------------------------------------- + +sal_Bool UCBContentHelper::IsYounger( const String& rIsYoung, const String& rIsOlder ) +{ + DateTime aYoungDate, aOlderDate; + INetURLObject aYoungObj( rIsYoung ); + DBG_ASSERT( aYoungObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + INetURLObject aOlderObj( rIsOlder ); + DBG_ASSERT( aOlderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + try + { + uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > aCmdEnv; + Content aYoung( aYoungObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); + ::com::sun::star::util::DateTime aTempYoungDate; + aYoung.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempYoungDate; + CONVERT_DATETIME( aTempYoungDate, aYoungDate ); + Content aOlder( aOlderObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); + ::com::sun::star::util::DateTime aTempOlderDate; + aOlder.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempOlderDate; + CONVERT_DATETIME( aTempOlderDate, aOlderDate ); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + } + catch( ::com::sun::star::uno::Exception& ) + { + } + + return ( aYoungDate > aOlderDate ); +} + +// ----------------------------------------------------------------------- +sal_Bool UCBContentHelper::Find( const String& rFolder, const String& rName, String& rFile, BOOL bAllowWildCards ) +{ + BOOL bWild = bAllowWildCards && ( rName.Search( '*' ) != STRING_NOTFOUND || rName.Search( '?' ) != STRING_NOTFOUND ); + + sal_Bool bRet = sal_False; + + // get a list of URLs for all children of rFolder + Sequence< ::rtl::OUString > aFiles = GetFolderContents( rFolder, sal_False ); + + const ::rtl::OUString* pFiles = aFiles.getConstArray(); + UINT32 i, nCount = aFiles.getLength(); + for ( i = 0; i < nCount; ++i ) + { + // get the last name of the URLs and compare it with rName + INetURLObject aFileObject( pFiles[i] ); + String aFile = aFileObject.getName( + INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase(); + if ( (bWild && WildCard( rName ).Matches( aFile )) || aFile == rName ) + { + // names match + rFile = aFileObject.GetMainURL( INetURLObject::NO_DECODE ); + bRet = sal_True; + break; + } + } + + return bRet; +} + +// ----------------------------------------------------------------------- +sal_Bool UCBContentHelper::Exists( const String& rURL ) +{ + + String sObjectPhysicalName; + sal_Bool bIsLocalFile = ::utl::LocalFileHelper::ConvertURLToPhysicalName( rURL, sObjectPhysicalName ); + // try to create a directory entry for the URL given + if ( bIsLocalFile ) + { + ::rtl::OUString sIn( sObjectPhysicalName ), sOut; + if ( osl_File_E_None == osl_getFileURLFromSystemPath( sIn.pData, &sOut.pData ) ) + { + // #106526 osl_getDirectoryItem is an existence check + // no further osl_getFileStatus call necessary + DirectoryItem aItem; + return (FileBase::E_None == DirectoryItem::get(sOut, aItem)); + } + return sal_False; + } + + // divide URL into folder and name part + sal_Bool bRet = sal_False; + INetURLObject aObj( rURL ); + ::rtl::OUString aFileName = aObj.getName( + INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase(); + aObj.removeSegment(); + aObj.removeFinalSlash(); + + // get a list of URLs for all children of rFolder + Sequence< ::rtl::OUString > aFiles = GetFolderContents( aObj.GetMainURL( INetURLObject::NO_DECODE ), sal_True, sal_False ); + + const ::rtl::OUString* pFiles = aFiles.getConstArray(); + UINT32 i, nCount = aFiles.getLength(); + for ( i = 0; i < nCount; ++i ) + { + // get the last name of the URLs and compare it with rName + INetURLObject aFileObject( pFiles[i] ); + ::rtl::OUString aFile = aFileObject.getName( + INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase(); + if ( aFile == aFileName ) + { + // names match + bRet = sal_True; + break; + } + } + + return bRet; +} + +// ----------------------------------------------------------------------- +sal_Bool UCBContentHelper::FindInPath( const String& rPath, const String& rName, String& rFile, char cDelim, BOOL bAllowWildCards ) +{ + // extract the single folder names from the path variable and try to find the file in one of these folders + USHORT nTokenCount = rPath.GetTokenCount( cDelim ); + for ( USHORT nToken = 0; nToken < nTokenCount; ++nToken ) + { + String aPath = rPath.GetToken( nToken, cDelim ); + if ( Find( aPath, rName, rFile, bAllowWildCards ) ) + return TRUE; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- +sal_Bool UCBContentHelper::IsSubPath( const ::rtl::OUString& rPath, const ::rtl::OUString& rSubfolderCandidate, const uno::Reference< ::com::sun::star::ucb::XContentProvider >& xProv ) +{ + sal_Bool bResult = sal_False; + + uno::Reference< ::com::sun::star::ucb::XContentProvider > xContentProvider = xProv; + + // the comparing is done in the following way: + // - first compare in case sensitive way + // - if name are different try a fallback comparing inf case insensitive way + // - if the last comparing succeeded get casepreserving normalized names for the files and compare them + // ( the second step is required because retrieving of the normalized names might be very expensive in some cases ) + + INetURLObject aCandidate( rSubfolderCandidate ); + INetURLObject aCandidateLowCase( rSubfolderCandidate.toAsciiLowerCase() ); // will be used for case insensitive comparing + INetURLObject aParentFolder( rPath ); + INetURLObject aParentFolderLowCase( rPath.toAsciiLowerCase() ); // will be used for case insensitive comparing + + if ( aCandidate.GetProtocol() == aParentFolder.GetProtocol() ) + { + if ( !xContentProvider.is() ) + { + ::ucbhelper::ContentBroker* pBroker = NULL; + if ( aCandidate.GetProtocol() == INET_PROT_FILE ) + { + pBroker = ::ucbhelper::ContentBroker::get(); + if ( pBroker ) + xContentProvider = pBroker->getContentProviderInterface(); + } + } + + INetURLObject aLastTmpObj; + do + { + if ( aParentFolder == aCandidate ) + { + // if case sensitive comparing succeeded there is no need for additional checks + bResult = sal_True; + } + else if ( xContentProvider.is() && aParentFolderLowCase == aCandidateLowCase ) + { + // the comparing was done using caseinsensitive way + // the case sensitive comparing have failed already + // the normalized urls must be retrieved + try + { + uno::Reference< ::com::sun::star::ucb::XContent > xSecCont = + xContentProvider->queryContent( + uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory >( + xContentProvider, ::com::sun::star::uno::UNO_QUERY_THROW )->createContentIdentifier( + aParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) ); + + uno::Reference< ::com::sun::star::ucb::XContent > xLocCont = + xContentProvider->queryContent( + uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory >( + xContentProvider, ::com::sun::star::uno::UNO_QUERY_THROW )->createContentIdentifier( + aCandidate.GetMainURL( INetURLObject::NO_DECODE ) ) ); + + if ( !xSecCont.is() || !xLocCont.is() ) + throw ::com::sun::star::uno::RuntimeException(); + + ::rtl::OUString aSecNormStr; + ::rtl::OUString aLocNormStr; + + bResult = + ( ( uno::Reference< ::com::sun::star::ucb::XCommandProcessor >( + xSecCont, ::com::sun::star::uno::UNO_QUERY_THROW )->execute( + ::com::sun::star::ucb::Command( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCasePreservingURL" ) ), + -1, + ::com::sun::star::uno::Any() ), + 0, + uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ) + >>= aSecNormStr ) + && ( uno::Reference< ::com::sun::star::ucb::XCommandProcessor >( + xLocCont, ::com::sun::star::uno::UNO_QUERY_THROW )->execute( + ::com::sun::star::ucb::Command( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCasePreservingURL" ) ), + -1, + ::com::sun::star::uno::Any() ), + 0, + uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ) + >>= aLocNormStr ) + && aLocNormStr.equals( aSecNormStr ) ); + } + catch( ::com::sun::star::uno::Exception& ) + {} + } + + // INetURLObject::removeSegment sometimes return true without exchanging URL, + // for example in case of "file:///" + aLastTmpObj = aCandidate; + + } while( aCandidate.removeSegment() && aCandidateLowCase.removeSegment() && aCandidate != aLastTmpObj && !bResult ); + } + + return bResult; +} + +// ----------------------------------------------------------------------- +sal_Bool UCBContentHelper::EqualURLs( const ::rtl::OUString& aFirstURL, const ::rtl::OUString& aSecondURL ) +{ + sal_Bool bResult = sal_False; + + if ( aFirstURL.getLength() && aSecondURL.getLength() ) + { + INetURLObject aFirst( aFirstURL ); + INetURLObject aSecond( aSecondURL ); + + if ( aFirst.GetProtocol() != INET_PROT_NOT_VALID && aSecond.GetProtocol() != INET_PROT_NOT_VALID ) + { + try + { + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( !pBroker ) + throw uno::RuntimeException(); + + uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory > xIdFac + = pBroker->getContentIdentifierFactoryInterface(); + if ( !xIdFac.is() ) + throw uno::RuntimeException(); + + uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdFirst + = xIdFac->createContentIdentifier( aFirst.GetMainURL( INetURLObject::NO_DECODE ) ); + uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdSecond + = xIdFac->createContentIdentifier( aSecond.GetMainURL( INetURLObject::NO_DECODE ) ); + + if ( xIdFirst.is() && xIdSecond.is() ) + { + uno::Reference< ::com::sun::star::ucb::XContentProvider > xProvider = + pBroker->getContentProviderInterface(); + if ( !xProvider.is() ) + throw uno::RuntimeException(); + bResult = !xProvider->compareContentIds( xIdFirst, xIdSecond ); + } + } + catch( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Can't compare URL's, treat as different!\n" ); + } + } + } + + return bResult; +} + + + +} // namespace utl + diff --git a/unotools/source/ucbhelper/ucblockbytes.cxx b/unotools/source/ucbhelper/ucblockbytes.cxx new file mode 100644 index 000000000000..9f4c39b397e1 --- /dev/null +++ b/unotools/source/ucbhelper/ucblockbytes.cxx @@ -0,0 +1,1755 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/ucblockbytes.hxx> +#include <comphelper/processfactory.hxx> +#include <salhelper/condition.hxx> +#ifndef _OSL_THREAD_HXX_ +#include <osl/thread.hxx> +#endif +#include <tools/urlobj.hxx> +#include <ucbhelper/interactionrequest.hxx> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp> +#include <com/sun/star/ucb/CommandFailedException.hpp> +#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_ +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#endif +#include <com/sun/star/io/XActiveDataStreamer.hpp> +#include <com/sun/star/ucb/DocumentHeaderField.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/PostCommandArgument2.hpp> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp> +#include <com/sun/star/beans/XPropertiesChangeListener.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XActiveDataControl.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <tools/inetmsg.hxx> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +#include <comphelper/storagehelper.hxx> + +#include <ucbhelper/contentbroker.hxx> +#include <ucbhelper/content.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + + +namespace utl +{ + +/** + Helper class for getting a XInputStream when opening a content + */ +class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink > +{ + UcbLockBytesRef m_xLockBytes; + +public: + UcbDataSink_Impl( UcbLockBytes* pLockBytes ) + : m_xLockBytes( pLockBytes ) + {} + + SvLockBytes* getLockBytes (void) + { return m_xLockBytes; } + + // XActiveDataControl. + virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {} + virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {} + virtual void SAL_CALL start (void) throw(RuntimeException) {} + virtual void SAL_CALL terminate (void) throw(RuntimeException) + { m_xLockBytes->terminate_Impl(); } + + // XActiveDataSink. + virtual void SAL_CALL setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException) + { m_xLockBytes->setInputStream_Impl (rxInputStream); } + virtual Reference<XInputStream> SAL_CALL getInputStream (void) throw(RuntimeException) + { return m_xLockBytes->getInputStream_Impl(); } +}; + +/** + Helper class for getting a XStream when opening a content + */ +class UcbStreamer_Impl : public ::cppu::WeakImplHelper2< XActiveDataStreamer, XActiveDataControl > +{ + Reference < XStream > m_xStream; + UcbLockBytesRef m_xLockBytes; + +public: + + UcbStreamer_Impl( UcbLockBytes* pLockBytes ) + : m_xLockBytes( pLockBytes ) + {} + + // XActiveDataControl. + virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {} + virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {} + virtual void SAL_CALL start (void) throw(RuntimeException) {} + virtual void SAL_CALL terminate (void) throw(RuntimeException) + { m_xLockBytes->terminate_Impl(); } + + // XActiveDataStreamer + virtual void SAL_CALL setStream( const Reference< XStream >& aStream ) throw(RuntimeException) + { m_xStream = aStream; m_xLockBytes->setStream_Impl( aStream ); } + virtual Reference< XStream > SAL_CALL getStream() throw(RuntimeException) + { return m_xStream; } +}; + +/** + Helper class for progress handling while executing UCB commands + */ +class ProgressHandler_Impl: public ::cppu::WeakImplHelper1< XProgressHandler > +{ + Link m_aProgress; + +public: + ProgressHandler_Impl( const Link& rLink ) + : m_aProgress( rLink ) + {} + // XProgressHandler + virtual void SAL_CALL push(const Any & /*rStatus*/) throw (RuntimeException) {} + virtual void SAL_CALL pop() throw (RuntimeException) {} + virtual void SAL_CALL update(const Any & /*rStatus*/) throw (RuntimeException) + { if ( m_aProgress.IsSet() ) m_aProgress.Call( 0 ); } +}; + +/** + Helper class for managing interactions and progress when executing UCB commands + */ +class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment > +{ + Reference< XInteractionHandler > m_xInteractionHandler; + Reference< XProgressHandler > m_xProgressHandler; + +public: + UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler, + const Reference< XProgressHandler>& rxProgressHandler ) + : m_xInteractionHandler( rxInteractionHandler ) + , m_xProgressHandler( rxProgressHandler ) + {} + + + virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException) + { return m_xInteractionHandler; } + + virtual Reference<XProgressHandler> SAL_CALL getProgressHandler() throw (RuntimeException) + { return m_xProgressHandler; } +}; + + +/** + Helper class for property change notifies when executing UCB commands +*/ +class UcbPropertiesChangeListener_Impl : public ::cppu::WeakImplHelper1< XPropertiesChangeListener > +{ +public: + UcbLockBytesRef m_xLockBytes; + + UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef ) + : m_xLockBytes( rRef ) + {} + + virtual void SAL_CALL disposing ( const EventObject &/*rEvent*/) throw(RuntimeException) {} + virtual void SAL_CALL propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException); +}; + +void SAL_CALL UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException) +{ + sal_Int32 i, n = rEvent.getLength(); + for (i = 0; i < n; i++) + { + PropertyChangeEvent evt (rEvent[i]); + if (evt.PropertyName == ::rtl::OUString::createFromAscii ("DocumentHeader")) + { + Sequence<DocumentHeaderField> aHead; + if (evt.NewValue >>= aHead) + { + sal_Int32 k, m = aHead.getLength(); + for (k = 0; k < m; k++) + { + String aName( aHead[k].Name ); + String aValue( aHead[k].Value ); + + if (aName.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL) + { + DateTime aExpires (0, 0); + if (INetRFC822Message::ParseDateField (aValue, aExpires)) + { + aExpires.ConvertToLocalTime(); + m_xLockBytes->SetExpireDate_Impl( aExpires ); + } + } + } + } + + m_xLockBytes->SetStreamValid_Impl(); + } + else if (evt.PropertyName == rtl::OUString::createFromAscii ("PresentationURL")) + { + ::rtl::OUString aUrl; + if (evt.NewValue >>= aUrl) + { + ::rtl::OUString aBad (::rtl::OUString::createFromAscii ("private:")); + if (!(aUrl.compareTo (aBad, aBad.getLength()) == 0)) + { + // URL changed (Redirection). + m_xLockBytes->SetRealURL_Impl( aUrl ); + } + } + } + else if (evt.PropertyName == ::rtl::OUString::createFromAscii ("MediaType")) + { + ::rtl::OUString aContentType; + if (evt.NewValue >>= aContentType) + m_xLockBytes->SetContentType_Impl( aContentType ); + } + } +} + + + +class Moderator + : public osl::Thread +{ + // usage restriction: + // It might be possible, that the call to the interactionhandler and/or + // progresshandler is done asynchrounsly, while the 'execute' simply + // returns. This would imply that these class must be refcounted !!! + +public: + + Moderator( + Reference < XContent >& xContent, + Reference < XInteractionHandler >& xInteract, + Reference < XProgressHandler >& xProgress, + const Command& rArg + ) + throw( + ContentCreationException, + RuntimeException + ); + + ~Moderator(); + + + enum ResultType { + NORESULT, + + INTERACTIONREQUEST, // reply expected + + PROGRESSPUSH, + PROGRESSUPDATE, + PROGRESSPOP, + + INPUTSTREAM, + STREAM, + + RESULT, + TIMEDOUT, + COMMANDABORTED, + COMMANDFAILED, + INTERACTIVEIO, + UNSUPPORTED, + GENERAL + }; + + + class ConditionRes + : public salhelper::Condition + { + public: + + ConditionRes(osl::Mutex& aMutex,Moderator& aModerator) + : salhelper::Condition(aMutex), + m_aModerator(aModerator) + { + } + + protected: + + bool applies() const { + return m_aModerator.m_aResultType != NORESULT; + } + + private: + + Moderator& m_aModerator; + }; + + + struct Result { + ResultType type; + Any result; + sal_Int32 ioErrorCode; + }; + + + Result getResult(const sal_uInt32 milliSec); + + + enum ReplyType { + NOREPLY, + EXIT, + RETRY, + REQUESTHANDLED + }; + + + class ConditionRep + : public salhelper::Condition + { + public: + + ConditionRep(osl::Mutex& aMutex,Moderator& aModerator) + : salhelper::Condition(aMutex), + m_aModerator(aModerator) + { + } + + protected: + + bool applies() const { + return m_aModerator.m_aReplyType != NOREPLY; + } + + private: + + Moderator& m_aModerator; + }; + + void setReply(ReplyType); + + + void handle( const Reference<XInteractionRequest >& Request ); + + void push( const Any& Status ); + + void update( const Any& Status ); + + void pop( ); + + void setStream(const Reference< XStream >& aStream); + + void setInputStream(const Reference<XInputStream> &rxInputStream); + + +protected: + + virtual void SAL_CALL run(); + + virtual void SAL_CALL onTerminated(); + +private: + + osl::Mutex m_aMutex; + + friend class ConditionRes; + + ConditionRes m_aRes; + ResultType m_aResultType; + sal_Int32 m_nIOErrorCode; + Any m_aResult; + + friend class ConditionRep; + + ConditionRep m_aRep; + ReplyType m_aReplyType; + + Command m_aArg; + ::ucbhelper::Content m_aContent; +}; + + +class ModeratorsActiveDataStreamer + : public ::cppu::WeakImplHelper1<XActiveDataStreamer> +{ +public: + + ModeratorsActiveDataStreamer(Moderator &theModerator); + + ~ModeratorsActiveDataStreamer(); + + // XActiveDataStreamer + virtual void SAL_CALL + setStream( + const Reference< XStream >& aStream + ) + throw( + RuntimeException + ); + + virtual Reference<XStream> SAL_CALL + getStream ( + void + ) throw( + RuntimeException + ) + { + osl::MutexGuard aGuard(m_aMutex); + return m_xStream; + } + + +private: + + Moderator& m_aModerator; + + osl::Mutex m_aMutex; + Reference<XStream> m_xStream; +}; + + + +class ModeratorsActiveDataSink + : public ::cppu::WeakImplHelper1<XActiveDataSink> +{ +public: + + ModeratorsActiveDataSink(Moderator &theModerator); + + ~ModeratorsActiveDataSink(); + + // XActiveDataSink. + virtual void SAL_CALL + setInputStream ( + const Reference<XInputStream> &rxInputStream + ) + throw( + RuntimeException + ); + + virtual Reference<XInputStream> SAL_CALL + getInputStream ( + void + ) throw( + RuntimeException + ) + { + osl::MutexGuard aGuard(m_aMutex); + return m_xStream; + } + + +private: + + Moderator& m_aModerator; + osl::Mutex m_aMutex; + Reference<XInputStream> m_xStream; +}; + + + +ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator &theModerator) + : m_aModerator(theModerator) +{ +} + + +ModeratorsActiveDataSink::~ModeratorsActiveDataSink() +{ +} + +// XActiveDataSink. +void SAL_CALL +ModeratorsActiveDataSink::setInputStream ( + const Reference<XInputStream> &rxInputStream +) + throw( + RuntimeException + ) +{ + m_aModerator.setInputStream(rxInputStream); + osl::MutexGuard aGuard(m_aMutex); + m_xStream = rxInputStream; +} + + +ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer( + Moderator &theModerator +) + : m_aModerator(theModerator) +{ +} + + +ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer() +{ +} + +// XActiveDataStreamer. +void SAL_CALL +ModeratorsActiveDataStreamer::setStream ( + const Reference<XStream> &rxStream +) + throw( + RuntimeException + ) +{ + m_aModerator.setStream(rxStream); + osl::MutexGuard aGuard(m_aMutex); + m_xStream = rxStream; +} + + + +class ModeratorsInteractionHandler + : public ::cppu::WeakImplHelper1<XInteractionHandler> +{ +public: + + ModeratorsInteractionHandler(Moderator &theModerator); + + ~ModeratorsInteractionHandler(); + + virtual void SAL_CALL + handle( const Reference<XInteractionRequest >& Request ) + throw (RuntimeException); + +private: + + Moderator& m_aModerator; +}; + + +class ModeratorsProgressHandler + : public ::cppu::WeakImplHelper1<XProgressHandler> +{ +public: + + ModeratorsProgressHandler(Moderator &theModerator); + + ~ModeratorsProgressHandler(); + + virtual void SAL_CALL push( const Any& Status ) + throw ( + RuntimeException); + + virtual void SAL_CALL update( const Any& Status ) + throw (RuntimeException); + + virtual void SAL_CALL pop( ) + throw (RuntimeException); + + +private: + + Moderator& m_aModerator; +}; + + +ModeratorsProgressHandler::ModeratorsProgressHandler(Moderator &theModerator) + : m_aModerator(theModerator) +{ +} + +ModeratorsProgressHandler::~ModeratorsProgressHandler() +{ +} + + +void SAL_CALL ModeratorsProgressHandler::push( const Any& Status ) + throw ( + RuntimeException) +{ + m_aModerator.push(Status); +} + + +void SAL_CALL ModeratorsProgressHandler::update( const Any& Status ) + throw (RuntimeException) +{ + m_aModerator.update(Status); +} + + +void SAL_CALL ModeratorsProgressHandler::pop( ) + throw (RuntimeException) +{ + m_aModerator.pop(); +} + + + + +ModeratorsInteractionHandler::ModeratorsInteractionHandler( + Moderator &aModerator) + : m_aModerator(aModerator) +{ +} + + +ModeratorsInteractionHandler::~ModeratorsInteractionHandler() +{ +} + + +void SAL_CALL +ModeratorsInteractionHandler::handle( + const Reference<XInteractionRequest >& Request +) + throw ( + RuntimeException + ) +{ + // wakes up the mainthread + m_aModerator.handle(Request); +} + + + + +Moderator::Moderator( + Reference < XContent >& xContent, + Reference < XInteractionHandler >& xInteract, + Reference < XProgressHandler >& xProgress, + const Command& rArg +) + throw( + ::com::sun::star::ucb::ContentCreationException, + ::com::sun::star::uno::RuntimeException + ) + : m_aMutex(), + + m_aRes(m_aMutex,*this), + m_aResultType(NORESULT), + m_nIOErrorCode(0), + m_aResult(), + + m_aRep(m_aMutex,*this), + m_aReplyType(NOREPLY), + + m_aArg(rArg), + m_aContent( + xContent, + new UcbTaskEnvironment( + xInteract.is() ? new ModeratorsInteractionHandler(*this) : 0, + xProgress.is() ? new ModeratorsProgressHandler(*this) : 0 + )) +{ + // now exchange the whole data sink stuff + // with a thread safe version + + Reference<XInterface> *pxSink = NULL; + + PostCommandArgument2 aPostArg; + OpenCommandArgument2 aOpenArg; + + int dec(2); + if(m_aArg.Argument >>= aPostArg) { + pxSink = &aPostArg.Sink; + dec = 0; + } + else if(m_aArg.Argument >>= aOpenArg) { + pxSink = &aOpenArg.Sink; + dec = 1; + } + + if(dec ==2) + throw ContentCreationException(); + + Reference < XActiveDataSink > xActiveSink(*pxSink,UNO_QUERY); + if(xActiveSink.is()) + *pxSink = Reference<XInterface>( + (cppu::OWeakObject*)new ModeratorsActiveDataSink(*this)); + + Reference<XActiveDataStreamer> xStreamer( *pxSink, UNO_QUERY ); + if ( xStreamer.is() ) + *pxSink = Reference<XInterface>( + (cppu::OWeakObject*)new ModeratorsActiveDataStreamer(*this)); + + if(dec == 0) + m_aArg.Argument <<= aPostArg; + else if(dec == 1) + m_aArg.Argument <<= aOpenArg; +} + + +Moderator::~Moderator() +{ +} + + +Moderator::Result Moderator::getResult(const sal_uInt32 milliSec) +{ + Result ret; + try { + salhelper::ConditionWaiter aWaiter(m_aRes,milliSec); + ret.type = m_aResultType; + ret.result = m_aResult; + ret.ioErrorCode = m_nIOErrorCode; + + // reset + m_aResultType = NORESULT; + } + catch(const salhelper::ConditionWaiter::timedout&) + { + ret.type = TIMEDOUT; + } + + return ret; +} + + +void Moderator::setReply(ReplyType aReplyType ) +{ + salhelper::ConditionModifier aMod(m_aRep); + m_aReplyType = aReplyType; +} + + +void Moderator::handle( const Reference<XInteractionRequest >& Request ) +{ + ReplyType aReplyType; + + do { + { + salhelper::ConditionModifier aMod(m_aRes); + m_aResultType = INTERACTIONREQUEST; + m_aResult <<= Request; + } + + { + salhelper::ConditionWaiter aWait(m_aRep); + aReplyType = m_aReplyType; + + // reset + m_aReplyType = NOREPLY; + } + + if(aReplyType == EXIT) { + Sequence<Reference<XInteractionContinuation> > aSeq( + Request->getContinuations()); + for(sal_Int32 i = 0; i < aSeq.getLength(); ++i) { + Reference<XInteractionAbort> aRef(aSeq[i],UNO_QUERY); + if(aRef.is()) { + aRef->select(); + } + } + + // resignal the exitcondition + setReply(EXIT); + break; + } + } while(aReplyType != REQUESTHANDLED); +} + + + +void Moderator::push( const Any& Status ) +{ + { + salhelper::ConditionModifier aMod(m_aRes); + m_aResultType = PROGRESSPUSH; + m_aResult = Status; + } + ReplyType aReplyType; + { + salhelper::ConditionWaiter aWait(m_aRep); + aReplyType = m_aReplyType; + m_aReplyType = NOREPLY; + } + if(aReplyType == EXIT) + setReply(EXIT); +} + + +void Moderator::update( const Any& Status ) +{ + { + salhelper::ConditionModifier aMod(m_aRes); + m_aResultType = PROGRESSUPDATE; + m_aResult = Status; + } + ReplyType aReplyType; + { + salhelper::ConditionWaiter aWait(m_aRep); + aReplyType = m_aReplyType; + m_aReplyType = NOREPLY; + } + if(aReplyType == EXIT) + setReply(EXIT); +} + + +void Moderator::pop( ) +{ + { + salhelper::ConditionModifier aMod(m_aRes); + m_aResultType = PROGRESSPOP; + } + ReplyType aReplyType; + { + salhelper::ConditionWaiter aWait(m_aRep); + aReplyType = m_aReplyType; + m_aReplyType = NOREPLY; + } + if(aReplyType == EXIT) + setReply(EXIT); +} + + +void Moderator::setStream(const Reference< XStream >& aStream) +{ + { + salhelper::ConditionModifier aMod(m_aRes); + m_aResultType = STREAM; + m_aResult <<= aStream; + } + ReplyType aReplyType; + { + salhelper::ConditionWaiter aWait(m_aRep); + aReplyType = m_aReplyType; + m_aReplyType = NOREPLY; + } + if(aReplyType == EXIT) + setReply(EXIT); +} + + +void Moderator::setInputStream(const Reference<XInputStream> &rxInputStream) +{ + { + salhelper::ConditionModifier aMod(m_aRes); + m_aResultType = INPUTSTREAM; + m_aResult <<= rxInputStream; + } + ReplyType aReplyType; + { + salhelper::ConditionWaiter aWait(m_aRep); + aReplyType = m_aReplyType; + m_aReplyType = NOREPLY; + } + if(aReplyType == EXIT) + setReply(EXIT); +} + + + +void SAL_CALL Moderator::run() +{ + ResultType aResultType; + Any aResult; + sal_Int32 nIOErrorCode = 0; + + try + { + aResult = m_aContent.executeCommand(m_aArg.Name,m_aArg.Argument); + aResultType = RESULT; + } + catch ( CommandAbortedException ) + { + aResultType = COMMANDABORTED; + } + catch ( CommandFailedException ) + { + aResultType = COMMANDFAILED; + } + catch ( InteractiveIOException& r ) + { + nIOErrorCode = r.Code; + aResultType = INTERACTIVEIO; + } + catch ( UnsupportedDataSinkException& ) + { + aResultType = UNSUPPORTED; + } + catch ( Exception ) + { + aResultType = GENERAL; + } + + { + salhelper::ConditionModifier aMod(m_aRes); + m_aResultType = aResultType; + m_aResult = aResult; + m_nIOErrorCode = nIOErrorCode; + } +} + + + +void SAL_CALL Moderator::onTerminated() +{ + { + salhelper::ConditionWaiter aWaiter(m_aRep); + } + delete this; +} + + +/** + Function for opening UCB contents synchronously, + but with handled timeout; +*/ + +static sal_Bool _UCBOpenContentSync( + UcbLockBytesRef xLockBytes, + Reference < XContent > xContent, + const Command& rArg, + Reference < XInterface > xSink, + Reference < XInteractionHandler > xInteract, + Reference < XProgressHandler > xProgress, + UcbLockBytesHandlerRef xHandler ); + + +static sal_Bool UCBOpenContentSync( + UcbLockBytesRef xLockBytes, + Reference < XContent > xContent, + const Command& rArg, + Reference < XInterface > xSink, + Reference < XInteractionHandler > xInteract, + Reference < XProgressHandler > xProgress, + UcbLockBytesHandlerRef xHandler ) +{ + // http protocol must be handled in a special way: + // during the opening process the input stream may change + // only the last inputstream after notifying the document + // headers is valid + + Reference<XContentIdentifier> xContId( + xContent.is() ? xContent->getIdentifier() : 0 ); + + rtl::OUString aScheme; + if(xContId.is()) + aScheme = xContId->getContentProviderScheme(); + + // now determine wether we use a timeout or not; + if( ! aScheme.equalsIgnoreAsciiCaseAscii("http") && + ! aScheme.equalsIgnoreAsciiCaseAscii("https") && + ! aScheme.equalsIgnoreAsciiCaseAscii("vnd.sun.star.webdav") && + ! aScheme.equalsIgnoreAsciiCaseAscii("ftp")) + return _UCBOpenContentSync( + xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler); + + if ( (aScheme.compareToAscii( "http" ) != COMPARE_EQUAL) || + (aScheme.compareToAscii( "https" ) != COMPARE_EQUAL) ) + xLockBytes->SetStreamValid_Impl(); + + Reference< XPropertiesChangeListener > xListener; + Reference< XPropertiesChangeNotifier > xProps(xContent,UNO_QUERY); + if(xProps.is()) { + xListener = + new UcbPropertiesChangeListener_Impl(xLockBytes); + xProps->addPropertiesChangeListener( + Sequence< ::rtl::OUString >(), + xListener); + } + + Any aResult; + bool bException(false); + bool bAborted(false); + bool bResultAchieved(false); + + Moderator* pMod = 0; + try { + pMod = new Moderator(xContent,xInteract,xProgress,rArg); + pMod->create(); + } catch(const ContentCreationException&) { + bResultAchieved = bException = true; + xLockBytes->SetError( ERRCODE_IO_GENERAL ); + } + + sal_uInt32 nTimeout(5000); // initially 5000 milliSec + while(!bResultAchieved) { + + Moderator::Result res; + // try to get the result for with timeout + res = pMod->getResult(nTimeout); + + switch(res.type) { + case Moderator::PROGRESSPUSH: + { + if(xProgress.is()) + xProgress->push(res.result); + pMod->setReply(Moderator::REQUESTHANDLED); + break; + } + case Moderator::PROGRESSUPDATE: + { + if(xProgress.is()) + xProgress->update(res.result); + pMod->setReply(Moderator::REQUESTHANDLED); + break; + } + case Moderator::PROGRESSPOP: + { + if(xProgress.is()) + xProgress->pop(); + pMod->setReply(Moderator::REQUESTHANDLED); + break; + } + case Moderator::STREAM: + { + Reference<XStream> result; + if(res.result >>= result) { + Reference < XActiveDataStreamer > xStreamer( + xSink, UNO_QUERY + ); + + if(xStreamer.is()) + xStreamer->setStream(result); + } + pMod->setReply(Moderator::REQUESTHANDLED); + break; + } + case Moderator::INPUTSTREAM: + { + Reference<XInputStream> result; + res.result >>= result; + Reference < XActiveDataSink > xActiveSink( + xSink, UNO_QUERY + ); + + if(xActiveSink.is()) + xActiveSink->setInputStream(result); + pMod->setReply(Moderator::REQUESTHANDLED); + break; + } + case Moderator::TIMEDOUT: + { + Reference<XInteractionRetry> xRet; + if(xInteract.is()) { + InteractiveNetworkConnectException aExcep; + INetURLObject aURL( + xContId.is() ? + xContId->getContentIdentifier() : + rtl::OUString() ); + aExcep.Server = aURL.GetHost(); + aExcep.Classification = InteractionClassification_ERROR; + aExcep.Message = + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "server not responding after five seconds")); + Any request; + request <<= aExcep; + ucbhelper::InteractionRequest *ir = + new ucbhelper::InteractionRequest(request); + Reference<XInteractionRequest> xIR(ir); + Sequence<Reference<XInteractionContinuation> > aSeq(2); + ucbhelper::InteractionRetry *retryP = + new ucbhelper::InteractionRetry(ir); + aSeq[0] = retryP; + ucbhelper::InteractionAbort *abortP = + new ucbhelper::InteractionAbort(ir); + aSeq[1] = abortP; + + ir->setContinuations(aSeq); + xInteract->handle(xIR); + rtl::Reference< ucbhelper::InteractionContinuation > ref + = ir->getSelection(); + if(ref.is()) { + Reference<XInterface> xInt(ref.get()); + xRet = Reference<XInteractionRetry>(xInt,UNO_QUERY); + } + } + + if(!xRet.is()) { + bAborted = true; + xLockBytes->SetError(ERRCODE_ABORT); + } + + break; + } + case Moderator::INTERACTIONREQUEST: + { + Reference<XInteractionRequest> Request; + res.result >>= Request; + xInteract->handle(Request); + pMod->setReply(Moderator::REQUESTHANDLED); + break; + } + case Moderator::RESULT: + { + bResultAchieved = true; + aResult = res.result; + break; + } + case Moderator::COMMANDABORTED: + { + bAborted = true; + xLockBytes->SetError( ERRCODE_ABORT ); + break; + } + case Moderator::COMMANDFAILED: + { + bAborted = true; + xLockBytes->SetError( ERRCODE_ABORT ); + break; + } + case Moderator::INTERACTIVEIO: + { + bException = true; + if ( res.ioErrorCode == IOErrorCode_ACCESS_DENIED || + res.ioErrorCode == IOErrorCode_LOCKING_VIOLATION ) + xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED ); + else if ( res.ioErrorCode == IOErrorCode_NOT_EXISTING ) + xLockBytes->SetError( ERRCODE_IO_NOTEXISTS ); + else if ( res.ioErrorCode == IOErrorCode_CANT_READ ) + xLockBytes->SetError( ERRCODE_IO_CANTREAD ); + else + xLockBytes->SetError( ERRCODE_IO_GENERAL ); + break; + } + case Moderator::UNSUPPORTED: + { + bException = true; + xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED ); + break; + } + default: + { + bException = true; + xLockBytes->SetError( ERRCODE_IO_GENERAL ); + break; + } + } + + bResultAchieved |= bException; + bResultAchieved |= bAborted; + if(nTimeout == 5000) nTimeout *= 2; + } + + if(pMod) pMod->setReply(Moderator::EXIT); + + if ( bAborted || bException ) + { + if( xHandler.Is() ) + xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes ); + + Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY ); + if ( xActiveSink.is() ) + xActiveSink->setInputStream( Reference < XInputStream >() ); + + Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY ); + if ( xStreamer.is() ) + xStreamer->setStream( Reference < XStream >() ); + } + + Reference < XActiveDataControl > xControl( xSink, UNO_QUERY ); + if ( xControl.is() ) + xControl->terminate(); + + if ( xProps.is() ) + xProps->removePropertiesChangeListener( + Sequence< ::rtl::OUString >(), + xListener ); + + return ( bAborted || bException ); +} + +/** + Function for opening UCB contents synchronously + */ +static sal_Bool _UCBOpenContentSync( + UcbLockBytesRef xLockBytes, + Reference < XContent > xContent, + const Command& rArg, + Reference < XInterface > xSink, + Reference < XInteractionHandler > xInteract, + Reference < XProgressHandler > xProgress, + UcbLockBytesHandlerRef xHandler ) +{ + ::ucbhelper::Content aContent( xContent, new UcbTaskEnvironment( xInteract, xProgress ) ); + Reference < XContentIdentifier > xIdent = xContent->getIdentifier(); + ::rtl::OUString aScheme = xIdent->getContentProviderScheme(); + + // http protocol must be handled in a special way: during the opening process the input stream may change + // only the last inputstream after notifying the document headers is valid + if ( aScheme.compareToAscii("http") != COMPARE_EQUAL ) + xLockBytes->SetStreamValid_Impl(); + + Reference< XPropertiesChangeListener > xListener = new UcbPropertiesChangeListener_Impl( xLockBytes ); + Reference< XPropertiesChangeNotifier > xProps ( xContent, UNO_QUERY ); + if ( xProps.is() ) + xProps->addPropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener ); + + Any aResult; + bool bException = false; + bool bAborted = false; + + try + { + aResult = aContent.executeCommand( rArg.Name, rArg.Argument ); + } + catch ( CommandAbortedException ) + { + bAborted = true; + xLockBytes->SetError( ERRCODE_ABORT ); + } + catch ( CommandFailedException ) + { + bAborted = true; + xLockBytes->SetError( ERRCODE_ABORT ); + } + catch ( InteractiveIOException& r ) + { + bException = true; + if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION ) + xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED ); + else if ( r.Code == IOErrorCode_NOT_EXISTING ) + xLockBytes->SetError( ERRCODE_IO_NOTEXISTS ); + else if ( r.Code == IOErrorCode_CANT_READ ) + xLockBytes->SetError( ERRCODE_IO_CANTREAD ); + else + xLockBytes->SetError( ERRCODE_IO_GENERAL ); + } + catch ( UnsupportedDataSinkException& ) + { + bException = true; + xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED ); + } + catch ( Exception ) + { + bException = true; + xLockBytes->SetError( ERRCODE_IO_GENERAL ); + } + + if ( bAborted || bException ) + { + if( xHandler.Is() ) + xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes ); + + Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY ); + if ( xActiveSink.is() ) + xActiveSink->setInputStream( Reference < XInputStream >() ); + + Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY ); + if ( xStreamer.is() ) + xStreamer->setStream( Reference < XStream >() ); + } + + Reference < XActiveDataControl > xControl( xSink, UNO_QUERY ); + if ( xControl.is() ) + xControl->terminate(); + + + if ( xProps.is() ) + xProps->removePropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener ); + + return ( bAborted || bException ); +} + + +//---------------------------------------------------------------------------- +UcbLockBytes::UcbLockBytes( UcbLockBytesHandler* pHandler ) + : m_xInputStream (NULL) + , m_pCommandThread( NULL ) + , m_xHandler( pHandler ) + , m_nError( ERRCODE_NONE ) + , m_bTerminated (sal_False) + , m_bDontClose( sal_False ) + , m_bStreamValid (sal_False) +{ + SetSynchronMode( TRUE ); +} + +//---------------------------------------------------------------------------- +UcbLockBytes::~UcbLockBytes() +{ + if ( !m_bDontClose ) + { + if ( m_xInputStream.is() ) + { + try + { + m_xInputStream->closeInput(); + } + catch ( RuntimeException const & ) + {} + catch ( IOException const & ) + {} + } + } + + if ( !m_xInputStream.is() && m_xOutputStream.is() ) + { + try + { + m_xOutputStream->closeOutput(); + } + catch ( RuntimeException const & ) + {} + catch ( IOException const & ) + {} + } +} + +Reference < XInputStream > UcbLockBytes::getInputStream() +{ + vos::OClearableGuard aGuard( m_aMutex ); + m_bDontClose = sal_True; + return m_xInputStream; +} + +Reference < XStream > UcbLockBytes::getStream() +{ + vos::OClearableGuard aGuard( m_aMutex ); + Reference < XStream > xStream( m_xSeekable, UNO_QUERY ); + if ( xStream.is() ) + m_bDontClose = sal_True; + return xStream; +} + +//---------------------------------------------------------------------------- + +sal_Bool UcbLockBytes::setStream_Impl( const Reference<XStream>& aStream ) +{ + vos::OClearableGuard aGuard( m_aMutex ); + if ( aStream.is() ) + { + m_xOutputStream = aStream->getOutputStream(); + setInputStream_Impl( aStream->getInputStream(), sal_False ); + m_xSeekable = Reference < XSeekable > ( aStream, UNO_QUERY ); + } + else + { + m_xOutputStream = Reference < XOutputStream >(); + setInputStream_Impl( Reference < XInputStream >() ); + } + + return m_xInputStream.is(); +} + +sal_Bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream, sal_Bool bSetXSeekable ) +{ + sal_Bool bRet = sal_False; + + try + { + vos::OClearableGuard aGuard( m_aMutex ); + + if ( !m_bDontClose && m_xInputStream.is() ) + m_xInputStream->closeInput(); + + m_xInputStream = rxInputStream; + + if( bSetXSeekable ) + { + m_xSeekable = Reference < XSeekable > ( rxInputStream, UNO_QUERY ); + if( !m_xSeekable.is() && rxInputStream.is() ) + { + Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + Reference< XOutputStream > rxTempOut = Reference < XOutputStream > ( + xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ), + UNO_QUERY ); + + if( rxTempOut.is() ) + { + ::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream, rxTempOut ); + m_xInputStream = Reference< XInputStream >( rxTempOut, UNO_QUERY ); + m_xSeekable = Reference < XSeekable > ( rxTempOut, UNO_QUERY ); + } + } + } + + bRet = m_xInputStream.is(); + // aGuard.clear(); + } + catch( Exception& ) + {} + + if ( m_bStreamValid && m_xInputStream.is() ) + m_aInitialized.set(); + + return bRet; +} + +void UcbLockBytes::SetStreamValid_Impl() +{ + m_bStreamValid = sal_True; + if ( m_xInputStream.is() ) + m_aInitialized.set(); +} + +//---------------------------------------------------------------------------- +void UcbLockBytes::terminate_Impl() +{ + m_bTerminated = sal_True; + m_aInitialized.set(); + m_aTerminated.set(); + + if ( GetError() == ERRCODE_NONE && !m_xInputStream.is() ) + { + DBG_ERROR("No InputStream, but no error set!" ); + SetError( ERRCODE_IO_NOTEXISTS ); + } + + if ( m_xHandler.Is() ) + m_xHandler->Handle( UcbLockBytesHandler::DONE, this ); +} + +//---------------------------------------------------------------------------- +void UcbLockBytes::SetSynchronMode (BOOL bSynchron) +{ + SvLockBytes::SetSynchronMode (bSynchron); +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::ReadAt ( ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const +{ + if ( IsSynchronMode() ) + { + UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this ); + pThis->m_aInitialized.wait(); + } + + Reference <XInputStream> xStream = getInputStream_Impl(); + if ( !xStream.is() ) + { + if ( m_bTerminated ) + return ERRCODE_IO_CANTREAD; + else + return ERRCODE_IO_PENDING; + } + + if ( pRead ) + *pRead = 0; + + Reference <XSeekable> xSeekable = getSeekable_Impl(); + if ( !xSeekable.is() ) + return ERRCODE_IO_CANTREAD; + + try + { + xSeekable->seek( nPos ); + } + catch ( IOException ) + { + return ERRCODE_IO_CANTSEEK; + } + catch (com::sun::star::lang::IllegalArgumentException) + { + return ERRCODE_IO_CANTSEEK; + } + + Sequence<sal_Int8> aData; + sal_Int32 nSize; + + nCount = VOS_MIN(nCount, 0x7FFFFFFF); + try + { + if ( !m_bTerminated && !IsSynchronMode() ) + { + sal_uInt64 nLen = xSeekable->getLength(); + if ( nPos + nCount > nLen ) + return ERRCODE_IO_PENDING; + } + + nSize = xStream->readBytes( aData, sal_Int32(nCount) ); + } + catch (IOException) + { + return ERRCODE_IO_CANTREAD; + } + + rtl_copyMemory (pBuffer, aData.getConstArray(), nSize); + if (pRead) + *pRead = ULONG(nSize); + + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::WriteAt ( ULONG nPos, const void *pBuffer, ULONG nCount, ULONG *pWritten) +{ + if ( pWritten ) + *pWritten = 0; + + DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" ); + DBG_ASSERT( m_aInitialized.check(), "Writing bevor stream is ready!" ); + + Reference <XSeekable> xSeekable = getSeekable_Impl(); + Reference <XOutputStream> xOutputStream = getOutputStream_Impl(); + if ( !xOutputStream.is() || !xSeekable.is() ) + return ERRCODE_IO_CANTWRITE; + + try + { + xSeekable->seek( nPos ); + } + catch ( IOException ) + { + return ERRCODE_IO_CANTSEEK; + } + + sal_Int8* pData = (sal_Int8*) pBuffer; + Sequence<sal_Int8> aData( pData, nCount ); + try + { + xOutputStream->writeBytes( aData ); + if ( pWritten ) + *pWritten = nCount; + } + catch ( Exception ) + { + return ERRCODE_IO_CANTWRITE; + } + + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::Flush() const +{ + Reference <XOutputStream > xOutputStream = getOutputStream_Impl(); + if ( !xOutputStream.is() ) + return ERRCODE_IO_CANTWRITE; + + try + { + xOutputStream->flush(); + } + catch( Exception ) + { + return ERRCODE_IO_CANTWRITE; + } + + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::SetSize (ULONG nNewSize) +{ + SvLockBytesStat aStat; + Stat( &aStat, (SvLockBytesStatFlag) 0 ); + ULONG nSize = aStat.nSize; + + if ( nSize > nNewSize ) + { + Reference < XTruncate > xTrunc( getOutputStream_Impl(), UNO_QUERY ); + if ( xTrunc.is() ) + { + xTrunc->truncate(); + nSize = 0; + } + else { + DBG_WARNING("Not truncatable!"); + } + } + + if ( nSize < nNewSize ) + { + ULONG nDiff = nNewSize-nSize, nCount=0; + BYTE* pBuffer = new BYTE[ nDiff ]; + memset(pBuffer, 0, nDiff); // initialize for enhanced security + WriteAt( nSize, pBuffer, nDiff, &nCount ); + delete[] pBuffer; + if ( nCount != nDiff ) + return ERRCODE_IO_CANTWRITE; + } + + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const +{ + if ( IsSynchronMode() ) + { + UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this ); + pThis->m_aInitialized.wait(); + } + + if (!pStat) + return ERRCODE_IO_INVALIDPARAMETER; + + Reference <XInputStream> xStream = getInputStream_Impl(); + Reference <XSeekable> xSeekable = getSeekable_Impl(); + + if ( !xStream.is() ) + { + if ( m_bTerminated ) + return ERRCODE_IO_INVALIDACCESS; + else + return ERRCODE_IO_PENDING; + } + else if( !xSeekable.is() ) + return ERRCODE_IO_CANTTELL; + + try + { + pStat->nSize = ULONG(xSeekable->getLength()); + } + catch (IOException) + { + return ERRCODE_IO_CANTTELL; + } + + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +void UcbLockBytes::Cancel() +{ + // is alive only for compatibility reasons + OSL_ENSURE( m_bTerminated, "UcbLockBytes is not thread safe so it can be used only syncronously!\n" ); +} + +//---------------------------------------------------------------------------- +IMPL_LINK( UcbLockBytes, DataAvailHdl, void*, EMPTYARG ) +{ + if ( hasInputStream_Impl() && m_xHandler.Is() ) + m_xHandler->Handle( UcbLockBytesHandler::DATA_AVAILABLE, this ); + + return 0; +} + +UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( const Reference< XInputStream >& xInputStream ) +{ + if( !xInputStream.is() ) + return NULL;; + + UcbLockBytesRef xLockBytes = new UcbLockBytes(); + xLockBytes->setDontClose_Impl(); + xLockBytes->setInputStream_Impl( xInputStream ); + xLockBytes->terminate_Impl(); + return xLockBytes; +} + +UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference< XStream >& xStream ) +{ + if( !xStream.is() ) + return NULL;; + + UcbLockBytesRef xLockBytes = new UcbLockBytes(); + xLockBytes->setDontClose_Impl(); + xLockBytes->setStream_Impl( xStream ); + xLockBytes->terminate_Impl(); + return xLockBytes; +} + +UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const ::rtl::OUString& rReferer, const ::rtl::OUString& rMediaType, + const Reference < XInputStream >& xPostData, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler ) +{ + if( !xContent.is() ) + return NULL;; + + UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler ); + xLockBytes->SetSynchronMode( !pHandler ); + Reference< XActiveDataControl > xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes ); + + PostCommandArgument2 aArgument; + aArgument.Source = xPostData; + aArgument.Sink = xSink; + aArgument.MediaType = rMediaType; + aArgument.Referer = rReferer; + + Command aCommand; + aCommand.Name = ::rtl::OUString::createFromAscii ("post"); + aCommand.Argument <<= aArgument; + + Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) ); + + sal_Bool bError = UCBOpenContentSync( xLockBytes, + xContent, + aCommand, + xSink, + xInteractionHandler, + xProgressHdl, + pHandler ); + + if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) ) + { + DBG_ERROR("No InputStream, but no error set!" ); + xLockBytes->SetError( ERRCODE_IO_GENERAL ); + } + + return xLockBytes; +} + +UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const Sequence < PropertyValue >& rProps, + StreamMode eOpenMode, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler ) +{ + if( !xContent.is() ) + return NULL;; + + UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler ); + xLockBytes->SetSynchronMode( !pHandler ); + Reference< XActiveDataControl > xSink; + if ( eOpenMode & STREAM_WRITE ) + xSink = (XActiveDataControl*) new UcbStreamer_Impl( xLockBytes ); + else + xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes ); + + if ( rProps.getLength() ) + { + Reference < XCommandProcessor > xProcessor( xContent, UNO_QUERY ); + Command aCommand; + aCommand.Name = ::rtl::OUString::createFromAscii("setPropertyValues"); + aCommand.Handle = -1; /* unknown */ + aCommand.Argument <<= rProps; + xProcessor->execute( aCommand, 0, Reference < XCommandEnvironment >() ); + } + + OpenCommandArgument2 aArgument; + aArgument.Sink = xSink; + aArgument.Mode = OpenMode::DOCUMENT; + + Command aCommand; + aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("open") ); + aCommand.Argument <<= aArgument; + + Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) ); + + sal_Bool bError = UCBOpenContentSync( xLockBytes, + xContent, + aCommand, + xSink, + xInteractionHandler, + xProgressHdl, + pHandler ); + + if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) ) + { + DBG_ERROR("No InputStream, but no error set!" ); + xLockBytes->SetError( ERRCODE_IO_GENERAL ); + } + + return xLockBytes; +} + +} diff --git a/unotools/source/ucbhelper/ucbstreamhelper.cxx b/unotools/source/ucbhelper/ucbstreamhelper.cxx new file mode 100644 index 000000000000..f27f663b3698 --- /dev/null +++ b/unotools/source/ucbhelper/ucbstreamhelper.cxx @@ -0,0 +1,248 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_unotools.hxx" + +#include <unotools/ucblockbytes.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/ucb/CommandAbortedException.hpp> + +#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HDL_ +#include <com/sun/star/ucb/XCommandEnvironment.hdl> +#endif +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/io/XActiveDataStreamer.hpp> + +#include <ucbhelper/contentbroker.hxx> +#include <ucbhelper/content.hxx> +#include <tools/debug.hxx> +#include <unotools/streamwrap.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +namespace utl +{ + +static SvStream* lcl_CreateStream( const String& rFileName, StreamMode eOpenMode, + Reference < XInteractionHandler > xInteractionHandler, + UcbLockBytesHandler* pHandler, sal_Bool /*bForceSynchron*/, sal_Bool bEnsureFileExists ) +{ + SvStream* pStream = NULL; + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( pBroker ) + { + UcbLockBytesRef xLockBytes; + if ( eOpenMode & STREAM_WRITE ) + { + sal_Bool bTruncate = ( eOpenMode & STREAM_TRUNC ) != 0; + if ( bTruncate ) + { + try + { + // truncate is implemented with deleting the original file + ::ucbhelper::Content aCnt( rFileName, Reference < XCommandEnvironment >() ); + aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); + } + + catch ( CommandAbortedException& ) + { + // couldn't truncate/delete + } + catch ( ContentCreationException& ) + { + } + catch ( Exception& ) + { + } + } + + if ( bEnsureFileExists || bTruncate ) + { + try + { + // make sure that the desired file exists before trying to open + SvMemoryStream aStream(0,0); + ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream ); + Reference< XInputStream > xInput( pInput ); + + ::ucbhelper::Content aContent( rFileName, Reference < XCommandEnvironment >() ); + InsertCommandArgument aInsertArg; + aInsertArg.Data = xInput; + + aInsertArg.ReplaceExisting = sal_False; + Any aCmdArg; + aCmdArg <<= aInsertArg; + aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg ); + } + + // it is NOT an error when the stream already exists and no truncation was desired + catch ( CommandAbortedException& ) + { + // currently never an error is detected ! + } + catch ( ContentCreationException& ) + { + } + catch ( Exception& ) + { + } + } + } + + try + { + // create LockBytes using UCB + ::ucbhelper::Content aContent( rFileName, Reference < XCommandEnvironment >() ); + xLockBytes = UcbLockBytes::CreateLockBytes( aContent.get(), Sequence < PropertyValue >(), + eOpenMode, xInteractionHandler, pHandler ); + if ( xLockBytes.Is() ) + { + pStream = new SvStream( xLockBytes ); + pStream->SetBufferSize( 4096 ); + pStream->SetError( xLockBytes->GetError() ); + } + } + catch ( CommandAbortedException& ) + { + } + catch ( ContentCreationException& ) + { + } + catch ( Exception& ) + { + } + } + else + // if no UCB is present at least conventional file io is supported + pStream = new SvFileStream( rFileName, eOpenMode ); + + return pStream; +} + +//============================================================================ + +SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode, + UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron ) +{ + return lcl_CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron, sal_True /* bEnsureFileExists */ ); +} + +SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode, + Reference < XInteractionHandler > xInteractionHandler, + UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron ) +{ + return lcl_CreateStream( rFileName, eOpenMode, xInteractionHandler, pHandler, bForceSynchron, sal_True /* bEnsureFileExists */ ); +} + +SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode, + sal_Bool bFileExists, + UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron ) +{ + return lcl_CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron, !bFileExists ); +} + +SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream ) +{ + SvStream* pStream = NULL; + UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream ); + if ( xLockBytes.Is() ) + { + pStream = new SvStream( xLockBytes ); + pStream->SetBufferSize( 4096 ); + pStream->SetError( xLockBytes->GetError() ); + } + + return pStream; +} + +SvStream* UcbStreamHelper::CreateStream( Reference < XStream > xStream ) +{ + SvStream* pStream = NULL; + if ( xStream->getOutputStream().is() ) + { + UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream ); + if ( xLockBytes.Is() ) + { + pStream = new SvStream( xLockBytes ); + pStream->SetBufferSize( 4096 ); + pStream->SetError( xLockBytes->GetError() ); + } + } + else + return CreateStream( xStream->getInputStream() ); + + return pStream; +} + +SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream, sal_Bool bCloseStream ) +{ + SvStream* pStream = NULL; + UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream ); + if ( xLockBytes.Is() ) + { + if ( !bCloseStream ) + xLockBytes->setDontClose_Impl(); + + pStream = new SvStream( xLockBytes ); + pStream->SetBufferSize( 4096 ); + pStream->SetError( xLockBytes->GetError() ); + } + + return pStream; +}; + +SvStream* UcbStreamHelper::CreateStream( Reference < XStream > xStream, sal_Bool bCloseStream ) +{ + SvStream* pStream = NULL; + if ( xStream->getOutputStream().is() ) + { + UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream ); + if ( xLockBytes.Is() ) + { + if ( !bCloseStream ) + xLockBytes->setDontClose_Impl(); + + pStream = new SvStream( xLockBytes ); + pStream->SetBufferSize( 4096 ); + pStream->SetError( xLockBytes->GetError() ); + } + } + else + return CreateStream( xStream->getInputStream(), bCloseStream ); + + return pStream; +}; + +} diff --git a/unotools/source/ucbhelper/xtempfile.cxx b/unotools/source/ucbhelper/xtempfile.cxx new file mode 100644 index 000000000000..525596fae854 --- /dev/null +++ b/unotools/source/ucbhelper/xtempfile.cxx @@ -0,0 +1,518 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "precompiled_unotools.hxx" +#include <XTempFile.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <unotools/tempfile.hxx> +#include <osl/file.hxx> +#include <unotools/configmgr.hxx> +#include <tools/urlobj.hxx> +#include <tools/debug.hxx> + +namespace css = com::sun::star; + +// copy define from desktop\source\app\appinit.cxx + +#define DESKTOP_TEMPNAMEBASE_DIR "/temp/soffice.tmp" + +OTempFileService::OTempFileService(::css::uno::Reference< ::css::uno::XComponentContext > const & context) +: ::cppu::PropertySetMixin< ::css::io::XTempFile >( + context + , static_cast< Implements >( IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET | IMPLEMENTS_PROPERTY_ACCESS ) + , com::sun::star::uno::Sequence< rtl::OUString >() ) +, mpStream( NULL ) +, mbRemoveFile( sal_True ) +, mbInClosed( sal_False ) +, mbOutClosed( sal_False ) +, mnCachedPos( 0 ) +, mbHasCachedPos( sal_False ) + +{ + mpTempFile = new ::utl::TempFile; + mpTempFile->EnableKillingFile ( sal_True ); +} + +OTempFileService::~OTempFileService () +{ + if ( mpTempFile ) + delete mpTempFile; +} + + +// XInterface + +::css::uno::Any SAL_CALL OTempFileService::queryInterface( ::css::uno::Type const & aType ) +throw ( ::css::uno::RuntimeException ) +{ + ::css::uno::Any aResult( OTempFileBase::queryInterface( aType ) ); + if (!aResult.hasValue()) + aResult = cppu::PropertySetMixin< ::css::io::XTempFile >::queryInterface( aType ) ; + return aResult; +}; +void SAL_CALL OTempFileService::acquire( ) +throw () +{ + OTempFileBase::acquire(); +} +void SAL_CALL OTempFileService::release( ) +throw () +{ + OTempFileBase::release(); +} + +// XTypeProvider + +::css::uno::Sequence< ::css::uno::Type > SAL_CALL OTempFileService::getTypes( ) +throw ( ::css::uno::RuntimeException ) +{ + static ::cppu::OTypeCollection* pTypeCollection = NULL; + if ( pTypeCollection == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; + + if ( pTypeCollection == NULL ) + { + static ::cppu::OTypeCollection aTypeCollection( + ::getCppuType( ( const ::css::uno::Reference< ::css::beans::XPropertySet >*)NULL ) + ,OTempFileBase::getTypes() ); + pTypeCollection = &aTypeCollection; + } + } + return pTypeCollection->getTypes(); +}; +::css::uno::Sequence< sal_Int8 > SAL_CALL OTempFileService::getImplementationId( ) +throw ( ::css::uno::RuntimeException ) +{ + return OTempFileBase::getImplementationId(); +} + +// XTempFile + +sal_Bool SAL_CALL OTempFileService::getRemoveFile() +throw ( ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( !mpTempFile ) + { + // the stream is already disconnected + throw ::css::uno::RuntimeException(); + } + + return mbRemoveFile; +}; +void SAL_CALL OTempFileService::setRemoveFile( sal_Bool _removefile ) +throw ( ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( !mpTempFile ) + { + // the stream is already disconnected + throw ::css::uno::RuntimeException(); + } + + mbRemoveFile = _removefile; + mpTempFile->EnableKillingFile( mbRemoveFile ); +}; +::rtl::OUString SAL_CALL OTempFileService::getUri() +throw ( ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( !mpTempFile ) + { + throw ::css::uno::RuntimeException(); + } + + return ::rtl::OUString( mpTempFile->GetURL() ); + +}; +::rtl::OUString SAL_CALL OTempFileService::getResourceName() +throw ( ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( !mpTempFile ) + { + throw ::css::uno::RuntimeException(); +} + + return ::rtl::OUString( mpTempFile->GetFileName() ); +}; + + + +// XInputStream + +sal_Int32 SAL_CALL OTempFileService::readBytes( ::css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) +throw (::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbInClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + checkConnected(); + if (nBytesToRead < 0) + throw ::css::io::BufferSizeExceededException( ::rtl::OUString(), static_cast< ::css::uno::XWeak * >(this)); + + aData.realloc(nBytesToRead); + + sal_uInt32 nRead = mpStream->Read(static_cast < void* > ( aData.getArray() ), nBytesToRead); + checkError(); + + if (nRead < static_cast < sal_uInt32 > ( nBytesToRead ) ) + aData.realloc( nRead ); + + if ( sal::static_int_cast<sal_uInt32>(nBytesToRead) > nRead ) + { + // usually that means that the stream was read till the end + // TODO/LATER: it is better to get rid of this optimization by avoiding using of multiple temporary files ( there should be only one temporary file? ) + mnCachedPos = mpStream->Tell(); + mbHasCachedPos = sal_True; + + mpStream = NULL; + if ( mpTempFile ) + mpTempFile->CloseStream(); + } + + return nRead; +} +sal_Int32 SAL_CALL OTempFileService::readSomeBytes( ::css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) +throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbInClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + checkConnected(); + checkError(); + + if (nMaxBytesToRead < 0) + throw ::css::io::BufferSizeExceededException( ::rtl::OUString(), static_cast < ::css::uno::XWeak * >( this ) ); + + if (mpStream->IsEof()) + { + aData.realloc(0); + return 0; + } + else + return readBytes(aData, nMaxBytesToRead); +} +void SAL_CALL OTempFileService::skipBytes( sal_Int32 nBytesToSkip ) +throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbInClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + checkConnected(); + checkError(); + mpStream->SeekRel(nBytesToSkip); + checkError(); +} +sal_Int32 SAL_CALL OTempFileService::available( ) +throw ( ::css::io::NotConnectedException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbInClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + checkConnected(); + + sal_uInt32 nPos = mpStream->Tell(); + checkError(); + + mpStream->Seek(STREAM_SEEK_TO_END); + checkError(); + + sal_Int32 nAvailable = (sal_Int32)mpStream->Tell() - nPos; + mpStream->Seek(nPos); + checkError(); + + return nAvailable; +} +void SAL_CALL OTempFileService::closeInput( ) +throw ( ::css::io::NotConnectedException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbInClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + mbInClosed = sal_True; + + if ( mbOutClosed ) + { + // stream will be deleted by TempFile implementation + mpStream = NULL; + + if ( mpTempFile ) + { + delete mpTempFile; + mpTempFile = NULL; + } + } +} + +// XOutputStream + +void SAL_CALL OTempFileService::writeBytes( const ::css::uno::Sequence< sal_Int8 >& aData ) +throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbOutClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + checkConnected(); + sal_uInt32 nWritten = mpStream->Write(aData.getConstArray(),aData.getLength()); + checkError(); + if ( nWritten != (sal_uInt32)aData.getLength()) + throw ::css::io::BufferSizeExceededException( ::rtl::OUString(),static_cast < ::css::uno::XWeak * > ( this ) ); +} +void SAL_CALL OTempFileService::flush( ) +throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbOutClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + checkConnected(); + mpStream->Flush(); + checkError(); +} +void SAL_CALL OTempFileService::closeOutput( ) +throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbOutClosed ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); + + mbOutClosed = sal_True; + + // TODO/LATER: it is better to get rid of this optimization by avoiding using of multiple temporary files ( there should be only one temporary file? ) + if ( mpStream ) + { + mnCachedPos = mpStream->Tell(); + mbHasCachedPos = sal_True; + + mpStream = NULL; + if ( mpTempFile ) + mpTempFile->CloseStream(); + } + + if ( mbInClosed ) + { + // stream will be deleted by TempFile implementation + mpStream = NULL; + + if ( mpTempFile ) + { + delete mpTempFile; + mpTempFile = NULL; + } + } +} + + +void OTempFileService::checkError () const +{ + if (!mpStream || mpStream->SvStream::GetError () != ERRCODE_NONE ) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); +} +void OTempFileService::checkConnected () +{ + if (!mpStream && mpTempFile) + { + mpStream = mpTempFile->GetStream( STREAM_STD_READWRITE ); + if ( mpStream && mbHasCachedPos ) + { + mpStream->Seek( sal::static_int_cast<sal_Size>(mnCachedPos) ); + if ( mpStream->SvStream::GetError () == ERRCODE_NONE ) + { + mbHasCachedPos = sal_False; + mnCachedPos = 0; + } + else + { + mpStream = NULL; + mpTempFile->CloseStream(); + } + } + } + + if (!mpStream) + throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) ); +} + +// XSeekable + +void SAL_CALL OTempFileService::seek( sal_Int64 nLocation ) +throw ( ::css::lang::IllegalArgumentException, ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + checkConnected(); + if ( nLocation < 0 || nLocation > getLength() ) + throw ::css::lang::IllegalArgumentException(); + + mpStream->Seek((sal_uInt32) nLocation ); + checkError(); +} +sal_Int64 SAL_CALL OTempFileService::getPosition( ) +throw ( ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + checkConnected(); + + sal_uInt32 nPos = mpStream->Tell(); + checkError(); + return (sal_Int64)nPos; +} +sal_Int64 SAL_CALL OTempFileService::getLength( ) +throw ( ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + checkConnected(); + + sal_uInt32 nCurrentPos = mpStream->Tell(); + checkError(); + + mpStream->Seek(STREAM_SEEK_TO_END); + sal_uInt32 nEndPos = mpStream->Tell(); + mpStream->Seek(nCurrentPos); + + checkError(); + + return (sal_Int64)nEndPos; +} + + +// XStream + +::css::uno::Reference< ::css::io::XInputStream > SAL_CALL OTempFileService::getInputStream() +throw ( ::css::uno::RuntimeException ) + { + return ::css::uno::Reference< ::css::io::XInputStream >( *this, ::css::uno::UNO_QUERY ); +} + +::css::uno::Reference< ::css::io::XOutputStream > SAL_CALL OTempFileService::getOutputStream() +throw ( ::css::uno::RuntimeException ) + { + return ::css::uno::Reference< ::css::io::XOutputStream >( *this, ::css::uno::UNO_QUERY ); + } + +// XTruncate + +void SAL_CALL OTempFileService::truncate() +throw ( ::css::io::IOException, ::css::uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + checkConnected(); + // SetStreamSize() call does not change the position + mpStream->Seek( 0 ); + mpStream->SetStreamSize( 0 ); + checkError(); +} + +// XServiceInfo + +::rtl::OUString SAL_CALL OTempFileService::getImplementationName() +throw ( ::css::uno::RuntimeException ) +{ + return getImplementationName_Static(); +} + +sal_Bool SAL_CALL OTempFileService::supportsService( ::rtl::OUString const & rServiceName ) +throw ( ::css::uno::RuntimeException ) +{ + ::css::uno::Sequence< ::rtl::OUString > aServices(getSupportedServiceNames_Static()); + return rServiceName == aServices[0]; +} + +::css::uno::Sequence < ::rtl::OUString > SAL_CALL OTempFileService::getSupportedServiceNames() +throw ( ::css::uno::RuntimeException ) +{ + return getSupportedServiceNames_Static(); +} + + + +::rtl::OUString OTempFileService::getImplementationName_Static () +{ + return ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.comp.TempFile" ) ); +} +::css::uno::Sequence < ::rtl::OUString > OTempFileService::getSupportedServiceNames_Static() +{ + ::css::uno::Sequence < ::rtl::OUString > aNames ( 1 ); + aNames[0] = ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) ); + return aNames; +} +::css::uno::Reference < ::css::uno::XInterface >SAL_CALL XTempFile_createInstance( + css::uno::Reference< ::css::uno::XComponentContext > const & context) + SAL_THROW( ( css::uno::Exception ) ) +{ + return static_cast< ::cppu::OWeakObject * >( new OTempFileService(context) ); +} + +::css::uno::Reference < ::css::lang::XSingleComponentFactory > OTempFileService::createServiceFactory_Static( ::css::uno::Reference < ::css::lang::XMultiServiceFactory > const & ) +{ + return ::cppu::createSingleComponentFactory( XTempFile_createInstance, getImplementationName_Static(), getSupportedServiceNames_Static() ); +} + +// C functions to implement this as a component + +extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +/** + * This function is called to get service factories for an implementation. + * @param pImplName name of implementation + * @param pServiceManager generic uno interface providing a service manager to instantiate components + * @param pRegistryKey registry data key to read and write component persistent data + * @return a component factory (generic uno interface) + */ +extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) +{ + void * pRet = 0; + ::css::uno::Reference< ::css::lang::XMultiServiceFactory > xSMgr( + reinterpret_cast< ::css::lang::XMultiServiceFactory * >( pServiceManager ) ); + ::css::uno::Reference< ::css::lang::XSingleComponentFactory > xFactory; + + if (OTempFileService::getImplementationName_Static().compareToAscii( pImplName ) == 0) + xFactory = OTempFileService::createServiceFactory_Static ( xSMgr ); + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} |