/**************************************************************
 *
 * 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 time only ...
        // Otherwise it will be tried more than once and show the same interaction more than 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 formatted 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 seems 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 seems 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();
	}
}
