/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_unotools.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 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 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 setDefaultFilter( const ::rtl::OUString& sNewDefaultFilter ) { if( sDefaultFilter != sNewDefaultFilter ) { sDefaultFilter = sNewDefaultFilter; bChangedDefaultFilter = 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 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_FAIL( "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; nFactorygetChangedProperties() 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 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=0 && eFactory=0 && eFactory=0 && eFactory=0 && eFactory=0 && eFactory=0 && eFactory=0 && eFactory=0 && eFactory 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& 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; nSetNodefree(); 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 lReadonlyStates = GetReadOnlyStates(lFactories); for (i=0; iIsModuleInstalled( 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; } namespace { class theModuleOptionsMutex : public rtl::Static {}; } /*-****************************************************************************************************//** @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() { return theModuleOptionsMutex::get(); } ::rtl::OUString SvtModuleOptions::GetModuleName( EModule eModule ) const { switch( eModule ) { case SvtModuleOptions::E_SWRITER : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Writer")); } case SvtModuleOptions::E_SWEB : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Web")); } case SvtModuleOptions::E_SGLOBAL : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Global")); } case SvtModuleOptions::E_SCALC : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Calc")); } case SvtModuleOptions::E_SDRAW : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Draw")); } case SvtModuleOptions::E_SIMPRESS : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Impress")); } case SvtModuleOptions::E_SMATH : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Math")); } case SvtModuleOptions::E_SCHART : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Chart")); } case SvtModuleOptions::E_SBASIC : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Basic")); } case SvtModuleOptions::E_SDATABASE : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Database")); } default: OSL_FAIL( "unknown module" ); break; } return ::rtl::OUString(); } ::rtl::OUString SvtModuleOptions::GetModuleName( EFactory eFactory ) const { switch( eFactory ) { case SvtModuleOptions::E_WRITER : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Writer")); } case SvtModuleOptions::E_WRITERWEB : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Writer")); } case SvtModuleOptions::E_WRITERGLOBAL : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Writer")); } case SvtModuleOptions::E_CALC : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Calc")); } case SvtModuleOptions::E_DRAW : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Draw")); } case SvtModuleOptions::E_IMPRESS : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Impress")); } case SvtModuleOptions::E_MATH : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Math")); } case SvtModuleOptions::E_CHART : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Chart")); } case SvtModuleOptions::E_BASIC : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Basic")); } case SvtModuleOptions::E_DATABASE : { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Database")); } default: OSL_FAIL( "unknown factory" ); break; } return ::rtl::OUString(); } /*----------------------------------------------- 07.03.2004 15:03 -----------------------------------------------*/ SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByShortName(const ::rtl::OUString& sName) { if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("swriter"))) return E_WRITER; if (sName.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("swriter/Web"))) // sometimes they are registerd for swriter/web :-( return E_WRITERWEB; if (sName.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("swriter/GlobalDocument"))) // sometimes they are registerd for swriter/globaldocument :-( return E_WRITERGLOBAL; if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("scalc"))) return E_CALC; if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sdraw"))) return E_DRAW; if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("simpress"))) return E_IMPRESS; if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("schart"))) return E_CHART; if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("smath"))) return E_MATH; if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sbasic"))) return E_BASIC; if (sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("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(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.FilterFactory"))), css::uno::UNO_QUERY); xTypeCfg = css::uno::Reference< css::container::XNameAccess >( xSMGR->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("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(RTL_CONSTASCII_USTRINGPARAM("FilterName")), ::rtl::OUString()); if (sFilterName.getLength()) { try { ::comphelper::SequenceAsHashMap stlFilterProps (xFilterCfg->getByName(sFilterName)); ::rtl::OUString sDocumentService = stlFilterProps.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("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(RTL_CONSTASCII_USTRINGPARAM("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(RTL_CONSTASCII_USTRINGPARAM("PreferredFilter")), ::rtl::OUString()); ::comphelper::SequenceAsHashMap stlFilterProps (xFilterCfg->getByName(sPreferredFilter)); ::rtl::OUString sDocumentService = stlFilterProps.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("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 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; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */