/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"

#include "fltfnc.hxx"
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/datatransfer/DataFlavor.hpp>
#include <com/sun/star/document/XTypeDetection.hpp>
#include <com/sun/star/container/XContainerQuery.hpp>

#include <comphelper/sequenceashashmap.hxx>

#ifndef _EXCHANGE_HXX //autogen
#include <sot/exchange.hxx>
#endif
#include <tools/config.hxx>
#include <basic/sbmeth.hxx>
#include <basic/basmgr.hxx>
#include <basic/sbstar.hxx>
#include <basic/sbxobj.hxx>
#include <basic/sbxmeth.hxx>
#include <basic/sbxcore.hxx>
#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _RTL_USTRING_HXX //autogen
#include <rtl/ustring.hxx>
#endif
#include <rtl/ustrbuf.hxx>
#include <svl/eitem.hxx>
#include <svl/intitem.hxx>
#include <svl/stritem.hxx>
#include <svl/lckbitem.hxx>
#include <svl/inettype.hxx>
#include <svl/rectitem.hxx>

#include <sot/storage.hxx>
#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/XStatusListener.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
#include <com/sun/star/frame/FeatureStateEvent.hpp>
#include <com/sun/star/frame/DispatchDescriptor.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XFrameActionListener.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/FrameActionEvent.hpp>
#include <com/sun/star/frame/FrameAction.hpp>
#include <com/sun/star/frame/XFrameLoader.hpp>
#include <com/sun/star/frame/XLoadEventListener.hpp>
#include <com/sun/star/frame/XFilterDetect.hpp>
#include <com/sun/star/loader/XImplementationLoader.hpp>
#include <com/sun/star/loader/CannotActivateFactoryException.hpp>
#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif
#include <com/sun/star/beans/PropertyValue.hpp>

#include <sal/types.h>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/ucb/XContent.hpp>
#include <rtl/ustring.hxx>
#include <vos/process.hxx>
#include <unotools/pathoptions.hxx>
#include <unotools/moduleoptions.hxx>
#include <comphelper/mediadescriptor.hxx>
#include <tools/urlobj.hxx>

#include <rtl/logfile.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::beans;
using namespace ::vos;
#include <svl/ctypeitm.hxx>
#include <svtools/sfxecode.hxx>
#include <unotools/syslocale.hxx>

#include "sfx2/sfxhelp.hxx"
#include <sfx2/docfilt.hxx>
#include <sfx2/docfac.hxx>
#include "sfxtypes.hxx"
#include <sfx2/sfxuno.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/progress.hxx>
#include "openflag.hxx"
#include "bastyp.hrc"
#include "sfx2/sfxresid.hxx"
#include <sfx2/doctempl.hxx>
#include <sfx2/frame.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include "helper.hxx"
#include "fltlst.hxx"
#include <sfx2/request.hxx>
#include "arrdecl.hxx"
#include <sfx2/appuno.hxx>
#include <sfx2/viewfrm.hxx>

static SfxFilterList_Impl* pFilterArr = 0;
static sal_Bool bFirstRead = sal_True;

static void CreateFilterArr()
{
	pFilterArr = new SfxFilterList_Impl;
	new SfxFilterListener();
}

//----------------------------------------------------------------
inline String ToUpper_Impl( const String &rStr )
{
    return SvtSysLocale().GetCharClass().upper( rStr );
}

//----------------------------------------------------------------
class SfxFilterContainer_Impl
{
public:
    String 				aName;
    String 				aServiceName;

						SfxFilterContainer_Impl( const String& rName )
							: aName( rName )
						{
							aServiceName = SfxObjectShell::GetServiceNameFromFactory( rName );
						}
};

#define IMPL_FORWARD_LOOP( aMethod, ArgType, aArg )         \
const SfxFilter* SfxFilterContainer::aMethod( ArgType aArg, SfxFilterFlags nMust, SfxFilterFlags nDont ) const \
{\
	SfxFilterMatcher aMatch( pImpl->aName ); \
	return aMatch.aMethod( aArg, nMust, nDont ); \
}

IMPL_FORWARD_LOOP( GetFilter4Mime, const String&, rMime );
IMPL_FORWARD_LOOP( GetFilter4ClipBoardId, sal_uInt32, nId );
IMPL_FORWARD_LOOP( GetFilter4EA, const String&, rEA );
IMPL_FORWARD_LOOP( GetFilter4Extension, const String&, rExt );
IMPL_FORWARD_LOOP( GetFilter4FilterName, const String&, rName );
IMPL_FORWARD_LOOP( GetFilter4UIName, const String&, rName );

const SfxFilter* SfxFilterContainer::GetAnyFilter( SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	SfxFilterMatcher aMatch( pImpl->aName );
	return aMatch.GetAnyFilter( nMust, nDont );
}

//----------------------------------------------------------------

SfxFilterContainer::SfxFilterContainer( const String& rName )
{
	pImpl = new SfxFilterContainer_Impl( rName );
}

//----------------------------------------------------------------

SfxFilterContainer::~SfxFilterContainer()
{
	delete pImpl;
}

//----------------------------------------------------------------

const String SfxFilterContainer::GetName() const
{
    return pImpl->aName;
}

const SfxFilter* SfxFilterContainer::GetDefaultFilter_Impl( const String& rName )
{
	// Try to find out the type of factory.
	// Interpret given name as Service- and ShortName!
	SvtModuleOptions aOpt;
    SvtModuleOptions::EFactory eFactory = aOpt.ClassifyFactoryByServiceName(rName);
    if (eFactory == SvtModuleOptions::E_UNKNOWN_FACTORY)
		eFactory = aOpt.ClassifyFactoryByShortName(rName);

	// could not classify factory by its service nor by its short name.
	// Must be an unknown factory! => return NULL
	if (eFactory == SvtModuleOptions::E_UNKNOWN_FACTORY)
		return NULL;

	// For the following code we need some additional informations.
	String sServiceName   = aOpt.GetFactoryName(eFactory);
	String sShortName     = aOpt.GetFactoryShortName(eFactory);
    String sDefaultFilter = aOpt.GetFactoryDefaultFilter(eFactory);

	// Try to get the default filter. Dont fiorget to verify it.
	// May the set default filter does not exists any longer or
	// does not fit the given factory.
    const SfxFilterMatcher aMatcher;
    const SfxFilter* pFilter = aMatcher.GetFilter4FilterName(sDefaultFilter);

	if (
		(pFilter																			) &&
		(pFilter->GetServiceName().CompareIgnoreCaseToAscii( sServiceName ) != COMPARE_EQUAL)
	   )
	{
		pFilter = 0;
	}

	// If at least no default filter could be located - use any filter of this
	// factory.
	if (!pFilter)
    {
        if ( bFirstRead )
            ReadFilters_Impl();

        sal_uInt16 nCount = ( sal_uInt16 ) pFilterArr->Count();
        for( sal_uInt16 n = 0; n < nCount; n++ )
        {
            const SfxFilter* pCheckFilter = pFilterArr->GetObject( n );
            if ( pCheckFilter->GetServiceName().CompareIgnoreCaseToAscii( sServiceName ) == COMPARE_EQUAL )
            {
                pFilter = pCheckFilter;
                break;
            }
        }
    }

    return pFilter;
}


//----------------------------------------------------------------

class SfxFilterMatcherArr_Impl;
static SfxFilterMatcherArr_Impl* pImplArr = 0;

// Impl-Data is shared between all FilterMatchers of the same factory
class SfxFilterMatcher_Impl
{
public:
	::rtl::OUString 	aName;
	SfxFilterList_Impl* pList;		// is created on demand

	void				InitForIterating() const;
	void				Update();
						SfxFilterMatcher_Impl()
							: pList(0)
						{}
};

DECL_PTRARRAY( SfxFilterMatcherArr_Impl, SfxFilterMatcher_Impl*, 2, 2 )

SfxFilterMatcher::SfxFilterMatcher( const String& rName )
	: pImpl( 0 )
{
	if ( !pImplArr )
		// keep track of created filter matchers to recycle the FilterLists
		pImplArr = new SfxFilterMatcherArr_Impl;

	String aName = SfxObjectShell::GetServiceNameFromFactory( rName );
    DBG_ASSERT(aName.Len(), "Found boes type :-)");
	for ( sal_uInt16 n=0; n<pImplArr->Count(); n++ )
	{
		// find the impl-Data of any comparable FilterMatcher that was created before
		SfxFilterMatcher_Impl* pImp = pImplArr->GetObject(n);
		if ( String(pImp->aName) == aName )
			pImpl = pImp;
	}

	if ( !pImpl )
	{
		// first Matcher created for this factory
    	pImpl = new SfxFilterMatcher_Impl;
		pImpl->aName = aName;
		pImplArr->Insert( pImplArr->Count(), pImpl );
	}
}

SfxFilterMatcher::SfxFilterMatcher()
{
	// global FilterMatcher always uses global filter array (also created on demand)
    pImpl = new SfxFilterMatcher_Impl;
}

SfxFilterMatcher::~SfxFilterMatcher()
{
	if ( !pImpl->aName.getLength() )
		// only the global Matcher owns his ImplData
		delete pImpl;
}

void SfxFilterMatcher_Impl::Update()
{
	if ( pList )
	{
		// this List was already used
		pList->Clear();
		for ( sal_uInt16 n=0; n<pFilterArr->Count(); n++ )
		{
			SfxFilter* pFilter = pFilterArr->GetObject(n);
			if ( pFilter->GetServiceName() == String(aName) )
				pList->Insert( pFilter, LIST_APPEND );
		}
	}
}

void SfxFilterMatcher_Impl::InitForIterating() const
{
	if ( pList )
		return;

	if ( bFirstRead )
		// global filter array has not been created yet
		SfxFilterContainer::ReadFilters_Impl();

	if ( aName.getLength() )
	{
		// matcher of factory: use only filters of that document type
		((SfxFilterMatcher_Impl*)this)->pList = new SfxFilterList_Impl;
		((SfxFilterMatcher_Impl*)this)->Update();
	}
	else
	{
		// global matcher: use global filter array
		((SfxFilterMatcher_Impl*)this)->pList = pFilterArr;
	}
}

const SfxFilter* SfxFilterMatcher::GetAnyFilter( SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	pImpl->InitForIterating();
    sal_uInt16 nCount = ( sal_uInt16 ) pImpl->pList->Count();
    for( sal_uInt16 n = 0; n < nCount; n++ )
    {
        const SfxFilter* pFilter = pImpl->pList->GetObject( n );
        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
        if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) )
            return pFilter;
    }

    return NULL;
}

//----------------------------------------------------------------

sal_uInt32  SfxFilterMatcher::GuessFilterIgnoringContent(
    SfxMedium& rMedium,
    const SfxFilter**ppFilter,
    SfxFilterFlags /*nMust*/,
    SfxFilterFlags /*nDont*/ ) const
{
    Reference< XTypeDetection > xDetection( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection")), UNO_QUERY );
    ::rtl::OUString sTypeName;
    try
    {
		//!MBA: nmust, ndont?
        sTypeName = xDetection->queryTypeByURL( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
    }
    catch( Exception& )
    {
    }

	*ppFilter = NULL;
	if ( sTypeName.getLength() )
		*ppFilter = GetFilter4EA( sTypeName );

	return *ppFilter ? ERRCODE_NONE : ERRCODE_ABORT;
}

//----------------------------------------------------------------

#define CHECKERROR()											\
if( nErr == 1 || nErr == USHRT_MAX || nErr == ULONG_MAX )		\
{																\
	ByteString aText = "Fehler in FilterDetection: Returnwert ";\
	aText += ByteString::CreateFromInt32(nErr);					\
	if( pFilter )												\
	{															\
		aText += ' ';											\
        aText += ByteString(U2S(pFilter->GetFilterName()));     \
	}															\
	DBG_ERROR( aText.GetBuffer() );								\
	nErr = ERRCODE_ABORT;										\
}

//----------------------------------------------------------------

sal_uInt32  SfxFilterMatcher::GuessFilter( SfxMedium& rMedium, const SfxFilter**ppFilter, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	return GuessFilterControlDefaultUI( rMedium, ppFilter, nMust, nDont, sal_True );
}

//----------------------------------------------------------------

sal_uInt32  SfxFilterMatcher::GuessFilterControlDefaultUI( SfxMedium& rMedium, const SfxFilter** ppFilter, SfxFilterFlags nMust, SfxFilterFlags nDont, sal_Bool /*bDefUI*/ ) const
{
    const SfxFilter* pOldFilter = *ppFilter;

    // no detection service -> nothing to do !
    Reference< XTypeDetection > xDetection( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection")), UNO_QUERY );
    if (!xDetection.is())
        return ERRCODE_ABORT;

    ::rtl::OUString sTypeName;
    try
    {
        // open the stream one times only ...
        // Otherwhise it will be tried more then once and show the same interaction more then once ...

        ::rtl::OUString sURL( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
        ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInStream = rMedium.GetInputStream();

        // stream exists => deep detection (with preselection ... if possible)
        if (xInStream.is())
        {
            ::comphelper::MediaDescriptor aDescriptor;

            aDescriptor[::comphelper::MediaDescriptor::PROP_URL()               ] <<= sURL;
            aDescriptor[::comphelper::MediaDescriptor::PROP_INPUTSTREAM()       ] <<= xInStream;
            aDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= rMedium.GetInteractionHandler();

            if ( pImpl->aName.getLength() )
                aDescriptor[::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE()] <<= pImpl->aName;

            if ( pOldFilter )
            {
                aDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()  ] <<= ::rtl::OUString( pOldFilter->GetTypeName()   );
                aDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= ::rtl::OUString( pOldFilter->GetFilterName() );
            }

            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > lDescriptor = aDescriptor.getAsConstPropertyValueList();
            sTypeName = xDetection->queryTypeByDescriptor(lDescriptor, sal_True); // lDescriptor is used as In/Out param ... dont use aDescriptor.getAsConstPropertyValueList() directly!
        }
        // no stream exists => try flat detection without preselection as fallback
        else
            sTypeName = xDetection->queryTypeByURL(sURL);

        if (sTypeName.getLength())
        {
            // detect filter by given type
            // In case of this matcher is bound to a particular document type:
            // If there is no acceptable type for this document at all, the type detection has possibly returned something else.
            // The DocumentService property is only a preselection, and all preselections are considered as optional!
            // This "wrong" type will be sorted out now because we match only allowed filters to the detected type
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > lQuery(1);
            lQuery[0].Name = ::rtl::OUString::createFromAscii("Name");
            lQuery[0].Value <<= sTypeName;

            const SfxFilter* pFilter = GetFilterForProps(lQuery, nMust, nDont);
            if (pFilter)
            {
                *ppFilter = pFilter;
                return ERRCODE_NONE;
            }
        }
    }
    catch(const Exception&)
    {}

    return ERRCODE_ABORT;
}

//----------------------------------------------------------------
sal_Bool SfxFilterMatcher::IsFilterInstalled_Impl( const SfxFilter* pFilter )
{
	if ( pFilter->GetFilterFlags() & SFX_FILTER_MUSTINSTALL )
	{
		// Hier k"onnte noch eine Nachinstallation angeboten werden
		String aText( SfxResId( STR_FILTER_NOT_INSTALLED ) );
		aText.SearchAndReplaceAscii( "$(FILTER)", pFilter->GetUIName() );
        QueryBox aQuery( NULL, WB_YES_NO | WB_DEF_YES, aText );
		short nRet = aQuery.Execute();
		if ( nRet == RET_YES )
		{
#ifdef DBG_UTIL
			// Setup starten
            InfoBox( NULL, DEFINE_CONST_UNICODE("Hier soll jetzt das Setup starten!") ).Execute();
#endif
			// Installation mu\s hier noch mitteilen, ob es geklappt hat, dann kann das
			// Filterflag gel"oscht werden
		}

		return ( !(pFilter->GetFilterFlags() & SFX_FILTER_MUSTINSTALL) );
	}
	else if ( pFilter->GetFilterFlags() & SFX_FILTER_CONSULTSERVICE )
	{
		String aText( SfxResId( STR_FILTER_CONSULT_SERVICE ) );
		aText.SearchAndReplaceAscii( "$(FILTER)", pFilter->GetUIName() );
        InfoBox ( NULL, aText ).Execute();
		return sal_False;
	}
	else
		return sal_True;
}


sal_uInt32 SfxFilterMatcher::DetectFilter( SfxMedium& rMedium, const SfxFilter**ppFilter, sal_Bool /*bPlugIn*/, sal_Bool bAPI ) const
/*  [Beschreibung]

    Hier wird noch die Filterauswahlbox hochgezogen. Sonst GuessFilter
 */

{
    const SfxFilter* pOldFilter = rMedium.GetFilter();
    if ( pOldFilter )
    {
        if( !IsFilterInstalled_Impl( pOldFilter ) )
            pOldFilter = 0;
        else
        {
            SFX_ITEMSET_ARG( rMedium.GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
            if ( ( pOldFilter->GetFilterFlags() & SFX_FILTER_PACKED ) && pSalvageItem )
                // Salvage is always done without packing
                pOldFilter = 0;
        }
    }

    const SfxFilter* pFilter = pOldFilter;

    sal_Bool bPreview = rMedium.IsPreview_Impl();
	SFX_ITEMSET_ARG(rMedium.GetItemSet(), pReferer, SfxStringItem, SID_REFERER, sal_False);
    if ( bPreview && rMedium.IsRemote() && ( !pReferer || pReferer->GetValue().CompareToAscii("private:searchfolder:",21 ) != COMPARE_EQUAL ) )
        return ERRCODE_ABORT;

	ErrCode nErr = GuessFilter( rMedium, &pFilter );
	if ( nErr == ERRCODE_ABORT )
		return nErr;

	if ( nErr == ERRCODE_IO_PENDING )
	{
		*ppFilter = pFilter;
		return nErr;
	}

	if ( !pFilter )
	{
    	const SfxFilter* pInstallFilter = NULL;

		// Jetzt auch Filter testen, die nicht installiert sind ( ErrCode ist irrelevant )
		GuessFilter( rMedium, &pInstallFilter, SFX_FILTER_IMPORT, SFX_FILTER_CONSULTSERVICE );
		if ( pInstallFilter )
		{
			if ( IsFilterInstalled_Impl( pInstallFilter ) )
				// Eventuell wurde der Filter nachinstalliert
				pFilter = pInstallFilter;
		}
		else
		{
			// Jetzt auch Filter testen, die erst von Star bezogen werden m"ussen ( ErrCode ist irrelevant )
			GuessFilter( rMedium, &pInstallFilter, SFX_FILTER_IMPORT, 0 );
			if ( pInstallFilter )
				IsFilterInstalled_Impl( pInstallFilter );
		}
	}

    sal_Bool bHidden = bPreview;
	SFX_ITEMSET_ARG( rMedium.GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, sal_False);
    if ( !bHidden && pFlags )
    {
        String aFlags( pFlags->GetValue() );
        aFlags.ToUpperAscii();
        if( STRING_NOTFOUND != aFlags.Search( 'H' ) )
            bHidden = sal_True;
    }
    *ppFilter = pFilter;

    if ( bHidden || (bAPI && nErr == ERRCODE_SFX_CONSULTUSER) )
		nErr = pFilter ? ERRCODE_NONE : ERRCODE_ABORT;
    return nErr;
}

const SfxFilter* SfxFilterMatcher::GetFilterForProps( const com::sun::star::uno::Sequence < ::com::sun::star::beans::NamedValue >& aSeq, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery > xTypeCFG;
    if( xServiceManager.is() == sal_True )
        xTypeCFG   = ::com::sun::star::uno::Reference < com::sun::star::container::XContainerQuery >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" ) ), ::com::sun::star::uno::UNO_QUERY );
    if ( xTypeCFG.is() )
    {
        // make query for all types matching the properties
        ::com::sun::star::uno::Reference < com::sun::star::container::XEnumeration > xEnum = xTypeCFG->createSubSetEnumerationByProperties( aSeq );
        while ( xEnum->hasMoreElements() )
        {
            ::comphelper::SequenceAsHashMap aProps( xEnum->nextElement() );
            ::rtl::OUString aValue;

            // try to get the preferred filter (works without loading all filters!)
            if ( (aProps[::rtl::OUString::createFromAscii("PreferredFilter")] >>= aValue) && aValue.getLength() )
            {
                const SfxFilter* pFilter = SfxFilter::GetFilterByName( aValue );
                if ( !pFilter || (pFilter->GetFilterFlags() & nMust) != nMust || (pFilter->GetFilterFlags() & nDont ) )
                    // check for filter flags
                    // pFilter == 0: if preferred filter is a Writer filter, but Writer module is not installed
					continue;

                if ( pImpl->aName.getLength() )
                {
                    // if this is not the global FilterMatcher: check if filter matches the document type
                    ::rtl::OUString aService;
                    if ( pFilter->GetServiceName() != String(pImpl->aName) )
                    {
                        // preferred filter belongs to another document type; now we must search the filter
                        pImpl->InitForIterating();
                        aProps[::rtl::OUString::createFromAscii("Name")] >>= aValue;
                        pFilter = GetFilter4EA( aValue, nMust, nDont );
                        if ( pFilter )
                            return pFilter;
                    }
                    else
                        return pFilter;
                }
                else
                    return pFilter;
            }
        }
    }

    return 0;
}

const SfxFilter* SfxFilterMatcher::GetFilter4Mime( const String& rMediaType,SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	if ( pImpl->pList )
	{
	    sal_uInt16 nCount = ( sal_uInt16 ) pImpl->pList->Count();
	    for( sal_uInt16 n = 0; n < nCount; n++ )
	    {
	        const SfxFilter* pFilter = pImpl->pList->GetObject( n );
	        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
	        if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetMimeType() == rMediaType )
				return pFilter;
		}

		return 0;
	}

	com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
	aSeq[0].Name = ::rtl::OUString::createFromAscii("MediaType");
	aSeq[0].Value <<= ::rtl::OUString( rMediaType );
	return GetFilterForProps( aSeq, nMust, nDont );
}

const SfxFilter* SfxFilterMatcher::GetFilter4EA( const String& rType,SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	if ( pImpl->pList )
	{
	    sal_uInt16 nCount = ( sal_uInt16 ) pImpl->pList->Count();
        const SfxFilter* pFirst = 0;
	    for( sal_uInt16 n = 0; n < nCount; n++ )
	    {
	        const SfxFilter* pFilter = pImpl->pList->GetObject( n );
	        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
	        if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetTypeName() == rType )
            {
                if (nFlags & SFX_FILTER_PREFERED)
                    return pFilter;
                if (!pFirst)
                    pFirst = pFilter;
            }
		}
        if (pFirst)
            return pFirst;

		return 0;
	}

	com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
	aSeq[0].Name = ::rtl::OUString::createFromAscii("Name");
	aSeq[0].Value <<= ::rtl::OUString( rType );
	return GetFilterForProps( aSeq, nMust, nDont );
}

const SfxFilter* SfxFilterMatcher::GetFilter4Extension( const String& rExt, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	if ( pImpl->pList )
	{
	    sal_uInt16 nCount = ( sal_uInt16 ) pImpl->pList->Count();
	    for( sal_uInt16 n = 0; n < nCount; n++ )
	    {
	        const SfxFilter* pFilter = pImpl->pList->GetObject( n );
	        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
	        if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) )
			{
				String sWildCard = ToUpper_Impl( pFilter->GetWildcard().GetWildCard() );
				String sExt      = ToUpper_Impl( rExt );

				if (!sExt.Len())
					continue;

				if (sExt.GetChar(0) != (sal_Unicode)'.')
					sExt.Insert((sal_Unicode)'.', 0);

				WildCard aCheck(sWildCard, ';');
				if (aCheck.Matches(sExt))
					return pFilter;
			}
		}

		return 0;
	}

    // Use extension without dot!
    String sExt( rExt );
    if ( sExt.Len() && ( sExt.GetChar(0) == (sal_Unicode)'.' ))
        sExt.Erase(0,1);

    com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
	aSeq[0].Name = ::rtl::OUString::createFromAscii("Extensions");
	::com::sun::star::uno::Sequence < ::rtl::OUString > aExts(1);
	aExts[0] = sExt;
	aSeq[0].Value <<= aExts;
	return GetFilterForProps( aSeq, nMust, nDont );
}

const SfxFilter* SfxFilterMatcher::GetFilter4ClipBoardId( sal_uInt32 nId, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	if (nId == 0)
		return 0;

	com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
	::rtl::OUString aName = SotExchange::GetFormatName( nId );
	aSeq[0].Name = ::rtl::OUString::createFromAscii("ClipboardFormat");
	aSeq[0].Value <<= aName;
	return GetFilterForProps( aSeq, nMust, nDont );
}

const SfxFilter* SfxFilterMatcher::GetFilter4UIName( const String& rName, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	pImpl->InitForIterating();
    const SfxFilter* pFirstFilter=0;
    sal_uInt16 nCount = ( sal_uInt16 ) pImpl->pList->Count();
    for( sal_uInt16 n = 0; n < nCount; n++ )
    {
        const SfxFilter* pFilter = pImpl->pList->GetObject( n );
        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
        if ( (nFlags & nMust) == nMust &&
             !(nFlags & nDont ) && pFilter->GetUIName() == rName )
        {
            if ( pFilter->GetFilterFlags() & SFX_FILTER_PREFERED )
                return pFilter;
            else if ( !pFirstFilter )
                pFirstFilter = pFilter;
        }
    }
    return pFirstFilter;
}

const SfxFilter* SfxFilterMatcher::GetFilter4FilterName( const String& rName, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
{
	String aName( rName );
	sal_uInt16 nIndex = aName.SearchAscii(": ");
	if (  nIndex != STRING_NOTFOUND )
	{
		DBG_ERROR("Old filter name used!");
		aName = rName.Copy( nIndex + 2 );
	}

	if ( bFirstRead )
	{
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >     xFilterCFG                                                ;
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >     xTypeCFG                                                  ;
        if( xServiceManager.is() == sal_True )
        {
            xFilterCFG = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), ::com::sun::star::uno::UNO_QUERY );
            xTypeCFG   = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" ) ), ::com::sun::star::uno::UNO_QUERY );
        }

		if( xFilterCFG.is() && xTypeCFG.is() )
		{
			if ( !pFilterArr )
				CreateFilterArr();
			else
			{
			    for( sal_uInt16 n=0; n<pFilterArr->Count(); n++ )
			    {
	        		const SfxFilter* pFilter = pFilterArr->GetObject( n );
			        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
			        if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetFilterName().CompareIgnoreCaseToAscii( aName ) == COMPARE_EQUAL )
			        	return pFilter;
				}
			}

			SfxFilterContainer::ReadSingleFilter_Impl( rName, xTypeCFG, xFilterCFG, sal_False );
		}
	}

    SfxFilterList_Impl* pList = pImpl->pList;
	if ( !pList )
		pList = pFilterArr;

    sal_uInt16 nCount = ( sal_uInt16 ) pList->Count();
    for( sal_uInt16 n = 0; n < nCount; n++ )
    {
        const SfxFilter* pFilter = pList->GetObject( n );
        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
        if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetFilterName().CompareIgnoreCaseToAscii( aName ) == COMPARE_EQUAL )
        	return pFilter;
    }

    return NULL;
}

IMPL_STATIC_LINK( SfxFilterMatcher, MaybeFileHdl_Impl, String*, pString )
{
	const SfxFilter* pFilter = pThis->GetFilter4Extension( *pString, SFX_FILTER_IMPORT );
	if( pFilter && !pFilter->GetWildcard().Matches( String() ) &&
		pFilter->GetWildcard() != DEFINE_CONST_UNICODE("*.*") && pFilter->GetWildcard() != '*' )
		return sal_True;
	return sal_False;
}

//----------------------------------------------------------------

SfxFilterMatcherIter::SfxFilterMatcherIter(
    const SfxFilterMatcher* pMatchP,
	SfxFilterFlags nOrMaskP, SfxFilterFlags nAndMaskP )
    : nOrMask( nOrMaskP ), nAndMask( nAndMaskP ),
      nCurrent(0), pMatch( pMatchP->pImpl)
{
    if( nOrMask == 0xffff ) //Wg. Fehlbuild auf s
        nOrMask = 0;
	pMatch->InitForIterating();
}

//----------------------------------------------------------------

const SfxFilter* SfxFilterMatcherIter::Find_Impl()
{
    const SfxFilter* pFilter = 0;
    while( nCurrent < pMatch->pList->Count() )
    {
    	pFilter = pMatch->pList->GetObject(nCurrent++);
        SfxFilterFlags nFlags = pFilter->GetFilterFlags();
        if( ((nFlags & nOrMask) == nOrMask ) && !(nFlags & nAndMask ) )
            break;
		pFilter = 0;
    }

    return pFilter;
}

const SfxFilter* SfxFilterMatcherIter::First()
{
	nCurrent = 0;
	return Find_Impl();
}

//----------------------------------------------------------------

const SfxFilter* SfxFilterMatcherIter::Next()
{
	return Find_Impl();
}

/*---------------------------------------------------------------
    helper to build own formated string from given stringlist by
    using given seperator
  ---------------------------------------------------------------*/
::rtl::OUString implc_convertStringlistToString( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& lList     ,
                                                 const sal_Unicode&                                        cSeperator,
                                                 const ::rtl::OUString&                                    sPrefix   )
{
    ::rtl::OUStringBuffer   sString ( 1000 )           ;
    sal_Int32               nCount  = lList.getLength();
    sal_Int32               nItem   = 0                ;
    for( nItem=0; nItem<nCount; ++nItem )
    {
        if( sPrefix.getLength() > 0 )
        {
            sString.append( sPrefix );
        }
        sString.append( lList[nItem] );
        if( nItem+1<nCount )
        {
            sString.append( cSeperator );
        }
    }
    return sString.makeStringAndClear();
}


void SfxFilterContainer::ReadSingleFilter_Impl(
	const ::rtl::OUString& rName,
    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xTypeCFG,
	const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xFilterCFG,
	sal_Bool bUpdate
	)
{
	::rtl::OUString sFilterName( rName );
	SfxFilterList_Impl& rList = *pFilterArr;
	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > lFilterProperties                           ;
    ::com::sun::star::uno::Any aResult;
    try
    {
        aResult = xFilterCFG->getByName( sFilterName );
    }
    catch( ::com::sun::star::container::NoSuchElementException& )
    {
        aResult = ::com::sun::star::uno::Any();
    }

    if( aResult >>= lFilterProperties )
    {
        // collect informations to add filter to container
        // (attention: some informations aren't available on filter directly ... you must search for corresponding type too!)
        sal_Int32       nFlags          = 0 ;
        sal_Int32       nClipboardId    = 0 ;
        sal_Int32       nDocumentIconId = 0 ;
        sal_Int32       nFormatVersion  = 0 ;
        ::rtl::OUString sMimeType           ;
        ::rtl::OUString sType               ;
        ::rtl::OUString sUIName             ;
        ::rtl::OUString sHumanName          ;
        ::rtl::OUString sDefaultTemplate    ;
        ::rtl::OUString sUserData           ;
        ::rtl::OUString sExtension          ;
        ::rtl::OUString sPattern            ;
        ::rtl::OUString sServiceName        ;

        // first get directly available properties
        sal_Int32 nFilterPropertyCount = lFilterProperties.getLength();
        sal_Int32 nFilterProperty      = 0                            ;
        for( nFilterProperty=0; nFilterProperty<nFilterPropertyCount; ++nFilterProperty )
        {
            if( lFilterProperties[nFilterProperty].Name.compareToAscii( "FileFormatVersion" ) == 0 )
            {
                lFilterProperties[nFilterProperty].Value >>= nFormatVersion;
            }
            else if( lFilterProperties[nFilterProperty].Name.compareToAscii( "TemplateName" ) == 0 )
            {
                lFilterProperties[nFilterProperty].Value >>= sDefaultTemplate;
            }
            else if( lFilterProperties[nFilterProperty].Name.compareToAscii( "Flags" ) == 0 )
            {
                lFilterProperties[nFilterProperty].Value >>= nFlags;
            }
            else if( lFilterProperties[nFilterProperty].Name.compareToAscii( "UIName" ) == 0 )
            {
                lFilterProperties[nFilterProperty].Value >>= sUIName;
            }
            else if( lFilterProperties[nFilterProperty].Name.compareToAscii( "UserData" ) == 0 )
            {
                ::com::sun::star::uno::Sequence< ::rtl::OUString > lUserData;
                lFilterProperties[nFilterProperty].Value >>= lUserData;
                sUserData = implc_convertStringlistToString( lUserData, ',', ::rtl::OUString() );
            }
            else if( lFilterProperties[nFilterProperty].Name.compareToAscii( "DocumentService" ) == 0 )
            {
                lFilterProperties[nFilterProperty].Value >>= sServiceName;
            }
            else if( lFilterProperties[nFilterProperty].Name.compareToAscii( "Type" ) == 0 )
            {
                lFilterProperties[nFilterProperty].Value >>= sType;
                // Try to get filter .. but look for any exceptions!
                // May be filter was deleted by another thread ...
                try
                {
                    aResult = xTypeCFG->getByName( sType );
                }
                catch( ::com::sun::star::container::NoSuchElementException& )
                {
                    aResult = ::com::sun::star::uno::Any();
                }

                ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > lTypeProperties;
                if( aResult >>= lTypeProperties )
                {
                    // get indirect available properties then (types)
                    sal_Int32 nTypePropertyCount = lTypeProperties.getLength();
                    sal_Int32 nTypeProperty      = 0                          ;
                    for( nTypeProperty=0; nTypeProperty<nTypePropertyCount; ++nTypeProperty )
                    {
                        if( lTypeProperties[nTypeProperty].Name.compareToAscii( "ClipboardFormat" ) == 0 )
                        {
                            lTypeProperties[nTypeProperty].Value >>= sHumanName;
                        }
                        else if( lTypeProperties[nTypeProperty].Name.compareToAscii( "DocumentIconID" ) == 0 )
                        {
                            lTypeProperties[nTypeProperty].Value >>= nDocumentIconId;
                        }
                        else if( lTypeProperties[nTypeProperty].Name.compareToAscii( "MediaType" ) == 0 )
                        {
                            lTypeProperties[nTypeProperty].Value >>= sMimeType;
                        }
                        else if( lTypeProperties[nTypeProperty].Name.compareToAscii( "Extensions" ) == 0 )
                        {
                            ::com::sun::star::uno::Sequence< ::rtl::OUString > lExtensions;
                            lTypeProperties[nTypeProperty].Value >>= lExtensions;
                            sExtension = implc_convertStringlistToString( lExtensions, ';', DEFINE_CONST_UNICODE("*.") );
                        }
                        else if( lTypeProperties[nTypeProperty].Name.compareToAscii( "URLPattern" ) == 0 )
                        {
                                ::com::sun::star::uno::Sequence< ::rtl::OUString > lPattern;
                                lTypeProperties[nTypeProperty].Value >>= lPattern;
                                sPattern = implc_convertStringlistToString( lPattern, ';', ::rtl::OUString() );
                        }
                    }
                }
            }
        }

		if ( !sServiceName.getLength() )
			return;

        // old formats are found ... using HumanPresentableName!
        if( sHumanName.getLength() )
        {
            nClipboardId = SotExchange::RegisterFormatName( sHumanName );

			// #100570# For external filters ignore clipboard IDs
			if((nFlags & SFX_FILTER_STARONEFILTER) == SFX_FILTER_STARONEFILTER)
			{
				nClipboardId = 0;
			}
        }
        // register SfxFilter
        // first erase module name from old filter names!
        // e.g: "scalc: DIF" => "DIF"
        sal_Int32 nStartRealName = sFilterName.indexOf( DEFINE_CONST_UNICODE(": "), 0 );
        if( nStartRealName != -1 )
        {
            DBG_ERROR("Old format, not supported!");
            sFilterName = sFilterName.copy( nStartRealName+2 );
        }

		SfxFilter* pFilter = bUpdate ? (SfxFilter*) SfxFilter::GetFilterByName( sFilterName ) : 0;
        sal_Bool bNew = sal_False;
        if (!pFilter)
        {
            bNew = sal_True;
            pFilter = new SfxFilter( sFilterName             ,
                                     sExtension              ,
                                     nFlags                  ,
                                     nClipboardId            ,
                                     sType                   ,
                                     (sal_uInt16)nDocumentIconId ,
                                     sMimeType               ,
                                     sUserData               ,
									 sServiceName );
        }
        else
        {
            pFilter->aFilterName  = sFilterName;
            pFilter->aWildCard    = WildCard(sExtension, ';');
            pFilter->nFormatType  = nFlags;
            pFilter->lFormat      = nClipboardId;
            pFilter->aTypeName    = sType;
            pFilter->nDocIcon     = (sal_uInt16)nDocumentIconId;
            pFilter->aMimeType    = sMimeType;
            pFilter->aUserData    = sUserData;
			pFilter->aServiceName = sServiceName;
        }

        // Don't forget to set right UIName!
        // Otherwise internal name is used as fallback ...
        pFilter->SetUIName( sUIName );
        pFilter->SetDefaultTemplate( sDefaultTemplate );
        if( nFormatVersion )
        {
            pFilter->SetVersion( nFormatVersion );
        }
        pFilter->SetURLPattern(sPattern);

        if (bNew)
			rList.Insert( pFilter, USHRT_MAX );
    }
}

void SfxFilterContainer::ReadFilters_Impl( sal_Bool bUpdate )
{
    RTL_LOGFILE_CONTEXT( aMeasure, "sfx2 (as96863) ::SfxFilterContainer::ReadFilters" );
	if ( !pFilterArr )
		CreateFilterArr();

	bFirstRead = sal_False;
	SfxFilterList_Impl& rList = *pFilterArr;

    try
    {
        // get the FilterFactory service to access the registered filters ... and types!
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >     xFilterCFG                                                ;
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >     xTypeCFG                                                  ;
        if( xServiceManager.is() == sal_True )
        {
            xFilterCFG = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), ::com::sun::star::uno::UNO_QUERY );
            xTypeCFG   = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" ) ), ::com::sun::star::uno::UNO_QUERY );
        }

        if(
            ( xFilterCFG.is() == sal_True ) &&
            ( xTypeCFG.is()   == sal_True )
          )
        {
            // select right query to get right set of filters for search modul
            ::com::sun::star::uno::Sequence< ::rtl::OUString > lFilterNames = xFilterCFG->getElementNames();
			if ( lFilterNames.getLength() )
            {
                // If list of filters already exist ...
                // ReadExternalFilters must work in update mode.
                // Best way seams to mark all filters NOT_INSTALLED
                // and change it back for all valid filters afterwards.
                if( rList.Count() > 0 )
                {
                    bUpdate = sal_True;
                    sal_uInt16 nCount = (sal_uInt16)rList.Count();
                    SfxFilter* pFilter;
                    for (sal_uInt16 f=0; f<nCount; ++f)
                    {
						pFilter = NULL;
                        pFilter = rList.GetObject(f);
                        pFilter->nFormatType |= SFX_FILTER_NOTINSTALLED;
                    }
                }

                // get all properties of filters ... put it into the filter container
                sal_Int32 nFilterCount = lFilterNames.getLength();
                sal_Int32 nFilter=0;
                for( nFilter=0; nFilter<nFilterCount; ++nFilter )
                {
                    // Try to get filter .. but look for any exceptions!
                    // May be filter was deleted by another thread ...
                    ::rtl::OUString sFilterName = lFilterNames[nFilter];

                    // This debug code can be used to break on inserting/updating
                    // special debug filters at runtime.
                    // Otherwise you have to check more then 300 filter names manually .-)
                    // And conditional breakpoints on unicode values seams not to be supported .-(
                    #ifdef DEBUG
                    bool bDBGStop = sal_False;
                    if (sFilterName.indexOf(::rtl::OUString::createFromAscii("DBG_"))>-1)
                        bDBGStop = sal_True;
                    #endif

					ReadSingleFilter_Impl( sFilterName, xTypeCFG, xFilterCFG, bUpdate );
                }
            }
        }
    }
    catch( ::com::sun::star::uno::Exception& )
    {
        DBG_ASSERT( sal_False, "SfxFilterContainer::ReadFilter()\nException detected. Possible not all filters could be cached.\n" );
    }

	if ( pImplArr && bUpdate )
	{
		// global filter arry was modified, factory specific ones might need an update too
		for ( sal_uInt16 n=0; n<pImplArr->Count(); n++ )
			pImplArr->GetObject(n)->Update();
	}
}
