/**************************************************************
 * 
 * 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_svx.hxx"


#include "filtnav.hxx"
#include "fmexch.hxx"
#include "fmhelp.hrc"
#include "fmitems.hxx"
#include "fmprop.hrc"
#include "svx/fmresids.hrc"
#include "gridcell.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/form/runtime/XFormController.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/util/XNumberFormatter.hpp>
/** === end UNO includes === **/

#include <comphelper/processfactory.hxx>
#include <svx/fmtools.hxx>
#include <comphelper/property.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/uno3.hxx>
#include <connectivity/dbtools.hxx>
#include <cppuhelper/implbase1.hxx>
#include <fmservs.hxx>
#include <fmshimp.hxx>
#include <rtl/logfile.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/objitem.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/request.hxx>
#include <svx/dialmgr.hxx>
#include <svx/fmshell.hxx>
#include <svx/svxids.hrc>
#include <tools/shl.hxx>
#include <vcl/wrkwin.hxx>

#include <functional>

#define SYNC_DELAY						200
#define DROP_ACTION_TIMER_INITIAL_TICKS 	10
	// solange dauert es, bis das Scrollen anspringt
#define DROP_ACTION_TIMER_SCROLL_TICKS		3
	// in diesen Intervallen wird jeweils eine Zeile gescrollt
#define DROP_ACTION_TIMER_TICK_BASE 		10
	// das ist die Basis, mit der beide Angaben multipliziert werden (in ms)

using namespace ::svxform;
using namespace ::connectivity::simple;
using namespace ::connectivity;


//........................................................................
namespace svxform
{
//........................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::lang::XMultiServiceFactory;
    using ::com::sun::star::awt::TextEvent;
    using ::com::sun::star::container::XIndexAccess;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::form::runtime::XFormController;
    using ::com::sun::star::form::runtime::XFilterController;
    using ::com::sun::star::form::runtime::XFilterControllerListener;
    using ::com::sun::star::form::runtime::FilterEvent;
    using ::com::sun::star::lang::EventObject;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::form::XForm;
    using ::com::sun::star::container::XChild;
    using ::com::sun::star::awt::XControl;
    using ::com::sun::star::sdbc::XConnection;
    using ::com::sun::star::util::XNumberFormatsSupplier;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::util::XNumberFormatter;
    using ::com::sun::star::sdbc::XRowSet;
    using ::com::sun::star::lang::Locale;
    using ::com::sun::star::sdb::SQLContext;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::uno::UNO_SET_THROW;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::awt::XTextComponent;
    using ::com::sun::star::uno::Sequence;
    /** === end UNO using === **/

//========================================================================
OFilterItemExchange::OFilterItemExchange()
{
}

//------------------------------------------------------------------------
void OFilterItemExchange::AddSupportedFormats()
{
	AddFormat(getFormatId());
}

//------------------------------------------------------------------------
sal_uInt32 OFilterItemExchange::getFormatId()
{
	static sal_uInt32 s_nFormat = (sal_uInt32)-1;
	if ((sal_uInt32)-1 == s_nFormat)
	{
		s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"form.FilterControlExchange\""));
		DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OFilterExchangeHelper::getFormatId: bad exchange id!");
	}
	return s_nFormat;
}

//------------------------------------------------------------------------
OLocalExchange* OFilterExchangeHelper::createExchange() const
{
	return new OFilterItemExchange;
}

//========================================================================
TYPEINIT0(FmFilterData);
Image FmFilterData::GetImage( BmpColorMode /*_eMode*/ ) const
{
	return Image();
}

//========================================================================
TYPEINIT1(FmParentData, FmFilterData);
//------------------------------------------------------------------------
FmParentData::~FmParentData()
{
	for (::std::vector<FmFilterData*>::const_iterator i = m_aChildren.begin();
		 i != m_aChildren.end(); i++)
		delete (*i);
}

//========================================================================
TYPEINIT1(FmFormItem, FmParentData);
//------------------------------------------------------------------------
Image FmFormItem::GetImage( BmpColorMode _eMode ) const
{
	static Image aImage;
	static Image aImage_HC;

	if (!aImage)
	{
		ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
		ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );

		aImage = aNavigatorImages.GetImage( RID_SVXIMG_FORM );
		aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FORM );
	}
	return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
}

//========================================================================
TYPEINIT1(FmFilterItems, FmParentData);
//------------------------------------------------------------------------
FmFilterItem* FmFilterItems::Find( const ::sal_Int32 _nFilterComponentIndex ) const
{
	for (   ::std::vector< FmFilterData* >::const_iterator i = m_aChildren.begin();
		    i != m_aChildren.end();
            ++i
        )
	{
		FmFilterItem* pCondition = PTR_CAST( FmFilterItem, *i );
        DBG_ASSERT( pCondition, "FmFilterItems::Find: Wrong element in container!" );
		if ( _nFilterComponentIndex == pCondition->GetComponentIndex() )
			return pCondition;
	}
	return NULL;
}

//------------------------------------------------------------------------
Image FmFilterItems::GetImage( BmpColorMode _eMode ) const
{
	static Image aImage;
	static Image aImage_HC;

	if (!aImage)
	{
		ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
		ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );

		aImage = aNavigatorImages.GetImage( RID_SVXIMG_FILTER );
		aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FILTER );
	}
	return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
}

//========================================================================
TYPEINIT1(FmFilterItem, FmFilterData);
//------------------------------------------------------------------------
FmFilterItem::FmFilterItem( const Reference< XMultiServiceFactory >& _rxFactory,
						    FmFilterItems* pParent,
					        const ::rtl::OUString& aFieldName,
					        const ::rtl::OUString& aText,
					        const sal_Int32 _nComponentIndex )
		  :FmFilterData(_rxFactory,pParent, aText)
		  ,m_aFieldName(aFieldName)
		  ,m_nComponentIndex( _nComponentIndex )
{
}

//------------------------------------------------------------------------
Image FmFilterItem::GetImage( BmpColorMode _eMode ) const
{
	static Image aImage;
	static Image aImage_HC;

	if (!aImage)
	{
		ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
		ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );

		aImage = aNavigatorImages.GetImage( RID_SVXIMG_FIELD );
		aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FIELD );
	}
	return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
}

//========================================================================
// Hints for communicatition between model and view
//========================================================================
class FmFilterHint : public SfxHint
{
	FmFilterData*	m_pData;

public:
	TYPEINFO();
	FmFilterHint(FmFilterData* pData):m_pData(pData){}
	FmFilterData* GetData() const { return m_pData; }
};
TYPEINIT1( FmFilterHint, SfxHint );

//========================================================================
class FmFilterInsertedHint : public FmFilterHint
{
	sal_Int32 m_nPos;	// Position relative to the parent of the data

public:
	TYPEINFO();
	FmFilterInsertedHint(FmFilterData* pData, sal_Int32 nRelPos)
		:FmFilterHint(pData)
		,m_nPos(nRelPos){}

	sal_Int32 GetPos() const { return m_nPos; }
};
TYPEINIT1( FmFilterInsertedHint, FmFilterHint );

//========================================================================
class FmFilterRemovedHint : public FmFilterHint
{
public:
	TYPEINFO();
	FmFilterRemovedHint(FmFilterData* pData)
		:FmFilterHint(pData){}

};
TYPEINIT1( FmFilterRemovedHint, FmFilterHint );

//========================================================================
class FmFilterTextChangedHint : public FmFilterHint
{
public:
	TYPEINFO();
	FmFilterTextChangedHint(FmFilterData* pData)
		:FmFilterHint(pData){}

};
TYPEINIT1( FmFilterTextChangedHint, FmFilterHint );

//========================================================================
class FilterClearingHint : public SfxHint
{
public:
	TYPEINFO();
	FilterClearingHint(){}
};
TYPEINIT1( FilterClearingHint, SfxHint );

//========================================================================
class FmFilterCurrentChangedHint : public SfxHint
{
public:
	TYPEINFO();
	FmFilterCurrentChangedHint(){}
};
TYPEINIT1( FmFilterCurrentChangedHint, SfxHint );

//========================================================================
// class FmFilterAdapter, Listener an den FilterControls
//========================================================================
class FmFilterAdapter : public ::cppu::WeakImplHelper1< XFilterControllerListener >
{
	FmFilterModel*			    m_pModel;
    Reference< XIndexAccess >   m_xControllers;

public:
	FmFilterAdapter(FmFilterModel* pModel, const Reference< XIndexAccess >& xControllers);

// XEventListener
	virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException );

// XFilterControllerListener
    virtual void SAL_CALL predicateExpressionChanged( const FilterEvent& _Event ) throw (RuntimeException);
    virtual void SAL_CALL disjunctiveTermRemoved( const FilterEvent& _Event ) throw (RuntimeException);
    virtual void SAL_CALL disjunctiveTermAdded( const FilterEvent& _Event ) throw (RuntimeException);

// helpers
	void dispose() throw( RuntimeException );

	void AddOrRemoveListener( const Reference< XIndexAccess >& _rxControllers, const bool _bAdd );

	void setText(sal_Int32 nPos,
		const FmFilterItem* pFilterItem,
		const ::rtl::OUString& rText);
};

//------------------------------------------------------------------------
FmFilterAdapter::FmFilterAdapter(FmFilterModel* pModel, const Reference< XIndexAccess >& xControllers)
    :m_pModel( pModel )
    ,m_xControllers( xControllers )
{
    AddOrRemoveListener( m_xControllers, true );
}

//------------------------------------------------------------------------
void FmFilterAdapter::dispose() throw( RuntimeException )
{
    AddOrRemoveListener( m_xControllers, false );
}

//------------------------------------------------------------------------
void FmFilterAdapter::AddOrRemoveListener( const Reference< XIndexAccess >& _rxControllers, const bool _bAdd )
{
	for (sal_Int32 i = 0, nLen = _rxControllers->getCount(); i < nLen; ++i)
	{
		Reference< XIndexAccess > xElement( _rxControllers->getByIndex(i), UNO_QUERY );

		// step down
		AddOrRemoveListener( xElement, _bAdd );

        // handle this particular controller
        Reference< XFilterController > xController( xElement, UNO_QUERY );
        OSL_ENSURE( xController.is(), "FmFilterAdapter::InsertElements: no XFilterController, cannot sync data!" );
        if ( xController.is() )
        {
            if ( _bAdd )
                xController->addFilterControllerListener( this );
            else
                xController->removeFilterControllerListener( this );
        }
	}
}

//------------------------------------------------------------------------
void FmFilterAdapter::setText(sal_Int32 nRowPos,
							  const FmFilterItem* pFilterItem,
							  const ::rtl::OUString& rText)
{
	FmFormItem* pFormItem = PTR_CAST( FmFormItem, pFilterItem->GetParent()->GetParent() );

    try
    {
        Reference< XFilterController > xController( pFormItem->GetController(), UNO_QUERY_THROW );
        xController->setPredicateExpression( pFilterItem->GetComponentIndex(), nRowPos, rText );
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}


// XEventListener
//------------------------------------------------------------------------
void SAL_CALL FmFilterAdapter::disposing(const EventObject& /*e*/) throw( RuntimeException )
{
}

//------------------------------------------------------------------------
namespace
{
    ::rtl::OUString lcl_getLabelName_nothrow( const Reference< XControl >& _rxControl )
    {
        ::rtl::OUString sLabelName;
        try
        {
            Reference< XControl > xControl( _rxControl, UNO_SET_THROW );
            Reference< XPropertySet > xModel( xControl->getModel(), UNO_QUERY_THROW );
            sLabelName = getLabelName( xModel );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return sLabelName;
    }

    Reference< XPropertySet > lcl_getBoundField_nothrow( const Reference< XControl >& _rxControl )
    {
        Reference< XPropertySet > xField;
        try
        {
            Reference< XControl > xControl( _rxControl, UNO_SET_THROW );
            Reference< XPropertySet > xModelProps( xControl->getModel(), UNO_QUERY_THROW );
            xField.set( xModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ), UNO_QUERY_THROW );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return xField;
    }
}

// XFilterControllerListener
//------------------------------------------------------------------------
void FmFilterAdapter::predicateExpressionChanged( const FilterEvent& _Event ) throw( RuntimeException )
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    if ( !m_pModel )
        return;

    // the controller which sent the event
    Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
    Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
    Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );

    FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
    OSL_ENSURE( pFormItem, "FmFilterAdapter::predicateExpressionChanged: don't know this form!" );
    if ( !pFormItem )
        return;

    const sal_Int32 nActiveTerm( xFilterController->getActiveTerm() );

	FmFilterItems* pFilter = PTR_CAST( FmFilterItems, pFormItem->GetChildren()[ nActiveTerm ] );
	FmFilterItem* pFilterItem = pFilter->Find( _Event.FilterComponent );
	if ( pFilterItem )
	{
		if ( _Event.PredicateExpression.getLength())
		{
			pFilterItem->SetText( _Event.PredicateExpression );
			// UI benachrichtigen
			FmFilterTextChangedHint aChangeHint(pFilterItem);
			m_pModel->Broadcast( aChangeHint );
		}
		else
		{
			// no text anymore so remove the condition
			m_pModel->Remove(pFilterItem);
		}
	}
	else
	{
		// searching the component by field name
		::rtl::OUString aFieldName( lcl_getLabelName_nothrow( xFilterController->getFilterComponent( _Event.FilterComponent ) ) );

		pFilterItem = new FmFilterItem( m_pModel->getORB(), pFilter, aFieldName, _Event.PredicateExpression, _Event.FilterComponent );
		m_pModel->Insert(pFilter->GetChildren().end(), pFilterItem);
	}

    // ensure there's one empty term in the filter, just in case the active term was previously empty
    m_pModel->EnsureEmptyFilterRows( *pFormItem );
}

//------------------------------------------------------------------------
void SAL_CALL FmFilterAdapter::disjunctiveTermRemoved( const FilterEvent& _Event ) throw (RuntimeException)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
    Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
    Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );

    FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
    OSL_ENSURE( pFormItem, "FmFilterAdapter::disjunctiveTermRemoved: don't know this form!" );
    if ( !pFormItem )
        return;

	::std::vector< FmFilterData* >& rTermItems = pFormItem->GetChildren();
    const bool bValidIndex = ( _Event.DisjunctiveTerm >= 0 ) && ( (size_t)_Event.DisjunctiveTerm < rTermItems.size() );
    OSL_ENSURE( bValidIndex, "FmFilterAdapter::disjunctiveTermRemoved: invalid term index!" );
    if ( !bValidIndex )
        return;

    // if the first term was removed, then the to-be first term needs its text updated
    if ( _Event.DisjunctiveTerm == 0 )
    {
        rTermItems[1]->SetText( String( SVX_RES( RID_STR_FILTER_FILTER_FOR ) ) );
        FmFilterTextChangedHint aChangeHint( rTermItems[1] );
        m_pModel->Broadcast( aChangeHint );
    }

    // finally remove the entry from the model
    m_pModel->Remove( rTermItems.begin() + _Event.DisjunctiveTerm );

    // ensure there's one empty term in the filter, just in case the currently removed one was the last empty one
    m_pModel->EnsureEmptyFilterRows( *pFormItem );
}

//------------------------------------------------------------------------
void SAL_CALL FmFilterAdapter::disjunctiveTermAdded( const FilterEvent& _Event ) throw (RuntimeException)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
    Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
    Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );

    FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
    OSL_ENSURE( pFormItem, "FmFilterAdapter::disjunctiveTermAdded: don't know this form!" );
    if ( !pFormItem )
        return;

    const sal_Int32 nInsertPos = _Event.DisjunctiveTerm;
    bool bValidIndex = ( nInsertPos >= 0 ) && ( (size_t)nInsertPos <= pFormItem->GetChildren().size() );
    if ( !bValidIndex )
    {
        OSL_ENSURE( false, "FmFilterAdapter::disjunctiveTermAdded: invalid index!" );
        return;
    }

    const ::std::vector< FmFilterData* >::iterator insertPos = pFormItem->GetChildren().begin() + nInsertPos;

    FmFilterItems* pFilterItems = new FmFilterItems( m_pModel->getORB(), pFormItem, String( SVX_RES( RID_STR_FILTER_FILTER_OR ) ) );
    m_pModel->Insert( insertPos, pFilterItems );
}

//========================================================================
// class FmFilterModel
//========================================================================
TYPEINIT1(FmFilterModel, FmParentData);
//------------------------------------------------------------------------
FmFilterModel::FmFilterModel(const Reference< XMultiServiceFactory >& _rxFactory)
			  :FmParentData(_rxFactory,NULL, ::rtl::OUString())
			  ,OSQLParserClient(_rxFactory)
			  ,m_xORB(_rxFactory)
			  ,m_pAdapter(NULL)
			  ,m_pCurrentItems(NULL)
{
}

//------------------------------------------------------------------------
FmFilterModel::~FmFilterModel()
{
	Clear();
}

//------------------------------------------------------------------------
void FmFilterModel::Clear()
{
	// notify
	FilterClearingHint aClearedHint;
	Broadcast( aClearedHint );

	// loose endings
	if (m_pAdapter)
	{
		m_pAdapter->dispose();
		m_pAdapter->release();
		m_pAdapter= NULL;
	}

	m_pCurrentItems  = NULL;
	m_xController	 = NULL;
	m_xControllers	 = NULL;

	for (::std::vector<FmFilterData*>::const_iterator i = m_aChildren.begin();
		 i != m_aChildren.end(); i++)
		delete (*i);

	m_aChildren.clear();
}

//------------------------------------------------------------------------
void FmFilterModel::Update(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
{
	if ( xCurrent == m_xController )
		return;

	if (!xControllers.is())
	{
		Clear();
		return;
	}

	// there is only a new current controller
	if ( m_xControllers != xControllers )
	{
		Clear();

		m_xControllers = xControllers;
		Update(m_xControllers, this);

		DBG_ASSERT(xCurrent.is(), "FmFilterModel::Update(...) no current controller");

		// Listening for TextChanges
		m_pAdapter = new FmFilterAdapter(this, xControllers);
		m_pAdapter->acquire();

		SetCurrentController(xCurrent);
		EnsureEmptyFilterRows( *this );
	}
	else
		SetCurrentController(xCurrent);
}

//------------------------------------------------------------------------
void FmFilterModel::Update(const Reference< XIndexAccess > & xControllers, FmParentData* pParent)
{
    try
    {
        sal_Int32 nCount = xControllers->getCount();
        for ( sal_Int32 i = 0; i < nCount; ++i )
        {
            Reference< XFormController > xController( xControllers->getByIndex(i), UNO_QUERY_THROW );

            Reference< XPropertySet > xFormProperties( xController->getModel(), UNO_QUERY_THROW );
            ::rtl::OUString aName;
            OSL_VERIFY( xFormProperties->getPropertyValue( FM_PROP_NAME ) >>= aName );

            // Insert a new item for the form
            FmFormItem* pFormItem = new FmFormItem( m_xORB, pParent, xController, aName );
            Insert( pParent->GetChildren().end(), pFormItem );

            Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );

            // insert the existing filters for the form
            String aTitle( SVX_RES( RID_STR_FILTER_FILTER_FOR ) );

            Sequence< Sequence< ::rtl::OUString > > aExpressions = xFilterController->getPredicateExpressions();
            for (   const Sequence< ::rtl::OUString >* pConjunctionTerm = aExpressions.getConstArray();
                    pConjunctionTerm != aExpressions.getConstArray() + aExpressions.getLength();
                    ++pConjunctionTerm
                )
            {
                // we always display one row, even if there's no term to be displayed
                FmFilterItems* pFilterItems = new FmFilterItems( m_xORB, pFormItem, aTitle );
                Insert( pFormItem->GetChildren().end(), pFilterItems );

                const Sequence< ::rtl::OUString >& rDisjunction( *pConjunctionTerm );
                for (   const ::rtl::OUString* pDisjunctiveTerm = rDisjunction.getConstArray();
                        pDisjunctiveTerm != rDisjunction.getConstArray() + rDisjunction.getLength();
                        ++pDisjunctiveTerm
                    )
                {
                    if ( pDisjunctiveTerm->getLength() == 0 )
                        // no condition for this particular component in this particular conjunction term
                        continue;

                    const sal_Int32 nComponentIndex = pDisjunctiveTerm - rDisjunction.getConstArray();

                    // determine the display name of the control
                    const Reference< XControl > xFilterControl( xFilterController->getFilterComponent( nComponentIndex ) );
                    const ::rtl::OUString sDisplayName( lcl_getLabelName_nothrow( xFilterControl ) );

                    // insert a new entry
                    FmFilterItem* pANDCondition = new FmFilterItem( m_xORB, pFilterItems, sDisplayName, *pDisjunctiveTerm, nComponentIndex );
                    Insert( pFilterItems->GetChildren().end(), pANDCondition );
                }

                // title for the next conditions
                aTitle = SVX_RES( RID_STR_FILTER_FILTER_OR );
            }

            // now add dependent controllers
            Reference< XIndexAccess > xControllerAsIndex( xController, UNO_QUERY );
            Update( xControllerAsIndex, pFormItem );
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------
FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< XFormController > & xController) const
{
	for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
		 i != rItems.end(); i++)
	{
		FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
		if (pForm)
		{
			if ( xController == pForm->GetController() )
				return pForm;
			else
			{
				pForm = Find(pForm->GetChildren(), xController);
				if (pForm)
					return pForm;
			}
		}
	}
	return NULL;
}

//------------------------------------------------------------------------
FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< XForm >& xForm) const
{
	for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
		 i != rItems.end(); i++)
	{
		FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
		if (pForm)
		{
			if (xForm == pForm->GetController()->getModel())
				return pForm;
			else
			{
				pForm = Find(pForm->GetChildren(), xForm);
				if (pForm)
					return pForm;
			}
		}
	}
	return NULL;
}

//------------------------------------------------------------------------
void FmFilterModel::SetCurrentController(const Reference< XFormController > & xCurrent)
{
	if ( xCurrent == m_xController )
		return;

	m_xController = xCurrent;

    FmFormItem* pItem = Find( m_aChildren, xCurrent );
    if ( !pItem )
        return;

    try
    {
        Reference< XFilterController > xFilterController( m_xController, UNO_QUERY_THROW );
        const sal_Int32 nActiveTerm( xFilterController->getActiveTerm() );
	    if ( pItem->GetChildren().size() > (size_t)nActiveTerm )
        {
		    SetCurrentItems( static_cast< FmFilterItems* >( pItem->GetChildren()[ nActiveTerm ] ) );
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------
void FmFilterModel::AppendFilterItems( FmFormItem& _rFormItem )
{
	// insert the condition behind the last filter items
	::std::vector<FmFilterData*>::reverse_iterator iter;
    for (   iter = _rFormItem.GetChildren().rbegin();
		    iter != _rFormItem.GetChildren().rend();
            ++iter
        )
	{
		if ((*iter)->ISA(FmFilterItems))
			break;
	}

    sal_Int32 nInsertPos = iter.base() - _rFormItem.GetChildren().begin();
	// delegate this to the FilterController, it will notify us, which will let us update our model
    try
    {
        Reference< XFilterController > xFilterController( _rFormItem.GetFilterController(), UNO_SET_THROW );
        if ( nInsertPos >= xFilterController->getDisjunctiveTerms() )
            xFilterController->appendEmptyDisjunctiveTerm();
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------
void FmFilterModel::Insert(const ::std::vector<FmFilterData*>::iterator& rPos, FmFilterData* pData)
{
	::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetChildren();
	sal_Int32 nPos = rPos == rItems.end() ? LIST_APPEND : rPos - rItems.begin();
	rItems.insert(rPos, pData);

	// UI benachrichtigen
	FmFilterInsertedHint aInsertedHint(pData, nPos);
	Broadcast( aInsertedHint );
}

//------------------------------------------------------------------------
void FmFilterModel::Remove(FmFilterData* pData)
{
	FmParentData* pParent = pData->GetParent();
	::std::vector<FmFilterData*>& rItems = pParent->GetChildren();

	// erase the item from the model
	::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pData);
	DBG_ASSERT(i != rItems.end(), "FmFilterModel::Remove(): unknown Item");
	// position within the parent
	sal_Int32 nPos = i - rItems.begin();
	if (pData->ISA(FmFilterItems))
	{
		FmFormItem* pFormItem = (FmFormItem*)pParent;

        try
        {
            Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );

            bool bEmptyLastTerm = ( ( nPos == 0 ) && xFilterController->getDisjunctiveTerms() == 1 );
            if ( bEmptyLastTerm )
            {
			    // remove all children (by setting an empty predicate expression)
			    ::std::vector< FmFilterData* >& rChildren = ((FmFilterItems*)pData)->GetChildren();
			    while ( !rChildren.empty() )
			    {
                    ::std::vector< FmFilterData* >::iterator removePos = rChildren.end() - 1;
				    FmFilterItem* pFilterItem = PTR_CAST( FmFilterItem, *removePos );
				    m_pAdapter->setText( nPos, pFilterItem, ::rtl::OUString() );
				    Remove( removePos );
                }
            }
            else
            {
                xFilterController->removeDisjunctiveTerm( nPos );
            }
        }
        catch( const Exception& )
        {
    	    DBG_UNHANDLED_EXCEPTION();
        }
	}
	else // FormItems can not be deleted
	{
		FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, pData);

		// if its the last condition remove the parent
		if (rItems.size() == 1)
			Remove(pFilterItem->GetParent());
		else
		{
			// find the position of the father within his father
			::std::vector<FmFilterData*>& rParentParentItems = pData->GetParent()->GetParent()->GetChildren();
			::std::vector<FmFilterData*>::iterator j = ::std::find(rParentParentItems.begin(), rParentParentItems.end(), pFilterItem->GetParent());
			DBG_ASSERT(j != rParentParentItems.end(), "FmFilterModel::Remove(): unknown Item");
			sal_Int32 nParentPos = j - rParentParentItems.begin();

			// EmptyText removes the filter
			m_pAdapter->setText(nParentPos, pFilterItem, ::rtl::OUString());
			Remove( i );
		}
	}
}

//------------------------------------------------------------------------
void FmFilterModel::Remove( const ::std::vector<FmFilterData*>::iterator& rPos )
{
    // remove from parent's child list
    FmFilterData* pData = *rPos;
    pData->GetParent()->GetChildren().erase( rPos );

	// notify the view, this will remove the actual SvLBoxEntry
	FmFilterRemovedHint aRemoveHint( pData );
	Broadcast( aRemoveHint );

	delete pData;
}

//------------------------------------------------------------------------
sal_Bool FmFilterModel::ValidateText(FmFilterItem* pItem, UniString& rText, UniString& rErrorMsg) const
{
	FmFormItem* pFormItem = PTR_CAST( FmFormItem, pItem->GetParent()->GetParent() );
    try
    {
        Reference< XFormController > xFormController( pFormItem->GetController() );
        // obtain the connection of the form belonging to the controller
        OStaticDataAccessTools aStaticTools;
        Reference< XRowSet > xRowSet( xFormController->getModel(), UNO_QUERY_THROW );
        Reference< XConnection > xConnection( aStaticTools.getRowSetConnection( xRowSet ) );

        // obtain a number formatter for this connection
        // TODO: shouldn't this be cached?
        Reference< XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats( xConnection, sal_True );
        Reference< XNumberFormatter > xFormatter( m_xORB->createInstance( FM_NUMBER_FORMATTER ), UNO_QUERY );
        xFormatter->attachNumberFormatsSupplier( xFormatSupplier );

        // get the field (database column) which the item is responsible for
        Reference< XFilterController > xFilterController( xFormController, UNO_QUERY_THROW );
        Reference< XPropertySet > xField( lcl_getBoundField_nothrow( xFilterController->getFilterComponent( pItem->GetComponentIndex() ) ), UNO_SET_THROW );

        // parse the given text as filter predicate
        ::rtl::OUString aErr, aTxt( rText );
        ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree( aErr, aTxt, xFormatter, xField );
        rErrorMsg = aErr;
        rText = aTxt;
        if ( xParseNode.is() )
        {
	        ::rtl::OUString aPreparedText;
	        Locale aAppLocale = Application::GetSettings().GetUILocale();
	        xParseNode->parseNodeToPredicateStr(
                aPreparedText, xConnection, xFormatter, xField, aAppLocale, '.', getParseContext() );
	        rText = aPreparedText;
	        return sal_True;
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }

    return sal_False;
}

//------------------------------------------------------------------------
void FmFilterModel::Append(FmFilterItems* pItems, FmFilterItem* pFilterItem)
{
	Insert(pItems->GetChildren().end(), pFilterItem);
}

//------------------------------------------------------------------------
void FmFilterModel::SetTextForItem(FmFilterItem* pItem, const ::rtl::OUString& rText)
{
	::std::vector<FmFilterData*>& rItems = pItem->GetParent()->GetParent()->GetChildren();
	::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pItem->GetParent());
	sal_Int32 nParentPos = i - rItems.begin();

	m_pAdapter->setText(nParentPos, pItem, rText);

	if( rText.isEmpty() )
		Remove(pItem);
	else
	{
		// Change the text
		pItem->SetText(rText);
		FmFilterTextChangedHint aChangeHint(pItem);
		Broadcast( aChangeHint );
	}
}

//------------------------------------------------------------------------
void FmFilterModel::SetCurrentItems(FmFilterItems* pCurrent)
{
	if (m_pCurrentItems == pCurrent)
		return;

	// search for the condition
	if (pCurrent)
	{
		FmFormItem* pFormItem = (FmFormItem*)pCurrent->GetParent();
		::std::vector<FmFilterData*>& rItems = pFormItem->GetChildren();
		::std::vector<FmFilterData*>::const_iterator i = ::std::find(rItems.begin(), rItems.end(), pCurrent);

		if (i != rItems.end())
		{
			// determine the filter position
			sal_Int32 nPos = i - rItems.begin();
            try
            {
                Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );
			    xFilterController->setActiveTerm( nPos );
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }

			if ( m_xController != pFormItem->GetController() )
				// calls SetCurrentItems again
				SetCurrentController( pFormItem->GetController() );
			else
				m_pCurrentItems = pCurrent;
		}
		else
			m_pCurrentItems = NULL;
	}
	else
		m_pCurrentItems = NULL;


	// UI benachrichtigen
	FmFilterCurrentChangedHint aHint;
	Broadcast( aHint );
}

//------------------------------------------------------------------------
void FmFilterModel::EnsureEmptyFilterRows( FmParentData& _rItem )
{
	// checks whether for each form there's one free level for input
	::std::vector< FmFilterData* >& rChildren = _rItem.GetChildren();
	sal_Bool bAppendLevel = _rItem.ISA( FmFormItem );

	for (   ::std::vector<FmFilterData*>::iterator i = rChildren.begin();
		    i != rChildren.end();
            ++i
        )
	{
		FmFilterItems* pItems = PTR_CAST(FmFilterItems, *i);
		if ( pItems && pItems->GetChildren().empty() )
		{
			bAppendLevel = sal_False;
			break;
		}

		FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
		if (pFormItem)
		{
			EnsureEmptyFilterRows( *pFormItem );
			continue;
		}
	}

	if ( bAppendLevel )
    {
        FmFormItem* pFormItem = PTR_CAST( FmFormItem, &_rItem );
        OSL_ENSURE( pFormItem, "FmFilterModel::EnsureEmptyFilterRows: no FmFormItem, but a FmFilterItems child?" );
        if ( pFormItem )
		    AppendFilterItems( *pFormItem );
    }
}

//========================================================================
// class FmFilterItemsString
//========================================================================
class FmFilterItemsString : public SvLBoxString
{
public:
	FmFilterItemsString( SvLBoxEntry* pEntry, sal_uInt16 nFlags,	const XubString& rStr )
		:SvLBoxString(pEntry,nFlags,rStr){}

	virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
	virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
};

const int nxDBmp = 12;
//------------------------------------------------------------------------
void FmFilterItemsString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* pEntry )
{
	FmFilterItems* pRow = (FmFilterItems*)pEntry->GetUserData();
	FmFormItem* pForm = (FmFormItem*)pRow->GetParent();

    // current filter is significant painted
    const bool bIsCurrentFilter = pForm->GetChildren()[ pForm->GetFilterController()->getActiveTerm() ] == pRow;
	if ( bIsCurrentFilter )
    {
        rDev.Push( PUSH_LINECOLOR );

		rDev.SetLineColor( rDev.GetTextColor() );

		Rectangle aRect( rPos, GetSize( &rDev, pEntry ) );
		Point aFirst( rPos.X(), aRect.Bottom() - 6 );
		Point aSecond(aFirst .X() + 2, aFirst.Y() + 3 );

		rDev.DrawLine( aFirst, aSecond );

		aFirst = aSecond;
		aFirst.X() += 1;
		aSecond.X() += 6;
		aSecond.Y() -= 5;

		rDev.DrawLine( aFirst, aSecond );

        rDev.Pop();
	}

	rDev.DrawText( Point(rPos.X() + nxDBmp, rPos.Y()), GetText() );
}

//------------------------------------------------------------------------
void FmFilterItemsString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
{
	if( !pViewData )
		pViewData = pView->GetViewDataItem( pEntry, this );

	Size aSize(pView->GetTextWidth(GetText()), pView->GetTextHeight());
	aSize.Width() += nxDBmp;
	pViewData->aSize = aSize;
}

//========================================================================
// class FmFilterString
//========================================================================
class FmFilterString : public SvLBoxString
{
	UniString m_aName;

public:
	FmFilterString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr, const UniString& aName)
		:SvLBoxString(pEntry,nFlags,rStr)
		,m_aName(aName)
	{
		m_aName.AppendAscii(": ");
	}

	virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
	virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
};

const int nxD = 4;

//------------------------------------------------------------------------
void FmFilterString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
{
	if( !pViewData )
		pViewData = pView->GetViewDataItem( pEntry, this );

	Font aOldFont( pView->GetFont());
	Font aFont( aOldFont );
	aFont.SetWeight(WEIGHT_BOLD);
	pView->SetFont( aFont );

	Size aSize(pView->GetTextWidth(m_aName), pView->GetTextHeight());
	pView->SetFont( aOldFont );
	aSize.Width() += pView->GetTextWidth(GetText()) + nxD;
	pViewData->aSize = aSize;
}

//------------------------------------------------------------------------
void FmFilterString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* /*pEntry*/ )
{
	Font aOldFont( rDev.GetFont());
	Font aFont( aOldFont );
	aFont.SetWeight(WEIGHT_BOLD);
	rDev.SetFont( aFont );

	Point aPos(rPos);
	rDev.DrawText( aPos, m_aName );

	// position for the second text
	aPos.X() += rDev.GetTextWidth(m_aName) + nxD;
	rDev.SetFont( aOldFont );
	rDev.DrawText( aPos, GetText() );
}

//========================================================================
// class FmFilterNavigator
//========================================================================
FmFilterNavigator::FmFilterNavigator( Window* pParent )
				  :SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HASBUTTONSATROOT )
                  ,m_pModel( NULL )
				  ,m_pEditingCurrently( NULL )
				  ,m_aControlExchange( this )
                  ,m_aTimerCounter( 0 )
                  ,m_aDropActionType( DA_SCROLLUP )
{
	SetHelpId( HID_FILTER_NAVIGATOR );

	{
		{
			ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
			SetNodeBitmaps(
				aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
				aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
				BMP_COLOR_NORMAL
			);
		}
		{
			ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
			SetNodeBitmaps(
				aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
				aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
				BMP_COLOR_HIGHCONTRAST
			);
		}
	}

	m_pModel = new FmFilterModel(comphelper::getProcessServiceFactory());
	StartListening( *m_pModel );

	EnableInplaceEditing( sal_True );
	SetSelectionMode(MULTIPLE_SELECTION);

	SetDragDropMode(0xFFFF);

	m_aDropActionTimer.SetTimeoutHdl(LINK(this, FmFilterNavigator, OnDropActionTimer));
}

//------------------------------------------------------------------------
FmFilterNavigator::~FmFilterNavigator()
{
	EndListening( *m_pModel );
	delete m_pModel;
}

//------------------------------------------------------------------------
void FmFilterNavigator::Clear()
{
	m_pModel->Clear();
}

//------------------------------------------------------------------------
void FmFilterNavigator::UpdateContent(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
{
	if (xCurrent == m_pModel->GetCurrentController())
		return;

	m_pModel->Update(xControllers, xCurrent);

	// expand the filters for the current controller
	SvLBoxEntry* pEntry = FindEntry(m_pModel->GetCurrentForm());
	if (pEntry && !IsExpanded(pEntry))
	{
		SelectAll(sal_False);

		if (!IsExpanded(pEntry))
			Expand(pEntry);

		pEntry = FindEntry(m_pModel->GetCurrentItems());
		if (pEntry)
		{
			if (!IsExpanded(pEntry))
				Expand(pEntry);
			Select(pEntry, sal_True);
		}
	}
}

//------------------------------------------------------------------------
sal_Bool FmFilterNavigator::EditingEntry( SvLBoxEntry* pEntry, Selection& rSelection )
{
	m_pEditingCurrently = pEntry;
	if (!SvTreeListBox::EditingEntry( pEntry, rSelection ))
		return sal_False;

	return pEntry && ((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem);
}

//------------------------------------------------------------------------
sal_Bool FmFilterNavigator::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText )
{
	DBG_ASSERT(pEntry == m_pEditingCurrently, "FmFilterNavigator::EditedEntry: suspicious entry!");
	m_pEditingCurrently = NULL;

	if (EditingCanceled())
		return sal_True;

	DBG_ASSERT(((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem),
					"FmFilterNavigator::EditedEntry() wrong entry");

	UniString aText(rNewText);
	aText.EraseTrailingChars();
	aText.EraseLeadingChars();
	if (aText.Len() == 0)
	{
		// deleting the entry asynchron
		sal_uLong nEvent;
		PostUserEvent(nEvent, LINK(this, FmFilterNavigator, OnRemove), pEntry);
	}
	else
	{
		UniString aErrorMsg;

		if (m_pModel->ValidateText((FmFilterItem*)pEntry->GetUserData(), aText, aErrorMsg))
		{
			GrabFocus();
			// this will set the text at the FmFilterItem, as well as update any filter controls
			// which are connected to this particular entry
			m_pModel->SetTextForItem( static_cast< FmFilterItem* >( pEntry->GetUserData() ), aText );

			SetCursor( pEntry, sal_True );
			SetEntryText( pEntry, aText );
		}
		else
		{
			// display the error and return sal_False
			SQLContext aError;
			aError.Message = String(SVX_RES(RID_STR_SYNTAXERROR));
			aError.Details = aErrorMsg;
			displayException(aError, this);

			return sal_False;
		}
	}
	return sal_True;
}

//------------------------------------------------------------------------
IMPL_LINK( FmFilterNavigator, OnRemove, SvLBoxEntry*, pEntry )
{
	// now remove the entry
	m_pModel->Remove((FmFilterData*) pEntry->GetUserData());
	return 0L;
}

//------------------------------------------------------------------------
IMPL_LINK( FmFilterNavigator, OnDropActionTimer, void*, EMPTYARG )
{
	if (--m_aTimerCounter > 0)
		return 0L;

	switch (m_aDropActionType)
	{
		case DA_SCROLLUP :
			ScrollOutputArea(1);
	        m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
			break;
		case DA_SCROLLDOWN :
			ScrollOutputArea(-1);
	        m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
			break;
        case DA_EXPANDNODE:
	    {
		    SvLBoxEntry* pToExpand = GetEntry(m_aTimerTriggered);
		    if (pToExpand && (GetChildCount(pToExpand) > 0) &&	!IsExpanded(pToExpand))
			    // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
			    // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
			    // aber ich denke, die BK sollte es auch so vertragen
			    Expand(pToExpand);

		    // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
		    m_aDropActionTimer.Stop();
	    }
        break;
	}
	return 0L;
}


//------------------------------------------------------------------------
sal_Int8 FmFilterNavigator::AcceptDrop( const AcceptDropEvent& rEvt )
{
	Point aDropPos = rEvt.maPosPixel;

	// kuemmern wir uns erst mal um moeglich DropActions (Scrollen und Aufklappen)
	if (rEvt.mbLeaving)
	{
		if (m_aDropActionTimer.IsActive())
			m_aDropActionTimer.Stop();
	}
	else
	{
		sal_Bool bNeedTrigger = sal_False;
		// auf dem ersten Eintrag ?
		if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
		{
			m_aDropActionType = DA_SCROLLUP;
			bNeedTrigger = sal_True;
		}
		else
		{
			// auf dem letzten (bzw. in dem Bereich, den ein Eintrag einnehmen wuerde, wenn er unten genau buendig
			// abschliessen wuerde) ?
			if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
			{
				m_aDropActionType = DA_SCROLLDOWN;
				bNeedTrigger = sal_True;
			}
			else
			{	// is it an entry with children, and not yet expanded?
				SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
				if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
				{
					// -> aufklappen
					m_aDropActionType = DA_EXPANDNODE;
					bNeedTrigger = sal_True;
				}
			}
		}
		if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
		{
			// neu anfangen zu zaehlen
			m_aTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
			// die Pos merken, da ich auch QueryDrops bekomme, wenn sich die Maus gar nicht bewegt hat
			m_aTimerTriggered = aDropPos;
			// und den Timer los
			if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
			{
				m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
				m_aDropActionTimer.Start();
			}
		}
		else if (!bNeedTrigger)
			m_aDropActionTimer.Stop();
	}


	// Hat das Object das richtige Format?
	if (!m_aControlExchange.isDragSource())
		return DND_ACTION_NONE;

	if (!m_aControlExchange->hasFormat(GetDataFlavorExVector()))
		return DND_ACTION_NONE;

	// do we conain the formitem?
	if (!FindEntry(m_aControlExchange->getFormItem()))
		return DND_ACTION_NONE;

	SvLBoxEntry* pDropTarget = GetEntry(aDropPos);
	if (!pDropTarget)
		return DND_ACTION_NONE;

	FmFilterData* pData = (FmFilterData*)pDropTarget->GetUserData();
	FmFormItem* pForm = NULL;
	if (pData->ISA(FmFilterItem))
	{
		pForm = PTR_CAST(FmFormItem,pData->GetParent()->GetParent());
		if (pForm != m_aControlExchange->getFormItem())
			return DND_ACTION_NONE;
	}
	else if (pData->ISA(FmFilterItems))
	{
		pForm = PTR_CAST(FmFormItem,pData->GetParent());
		if (pForm != m_aControlExchange->getFormItem())
			return DND_ACTION_NONE;
	}
	else
		return DND_ACTION_NONE;

	return rEvt.mnAction;
}
// -----------------------------------------------------------------------------
namespace 
{
	FmFilterItems* getTargetItems(SvLBoxEntry* _pTarget)
	{
		FmFilterData*	pData = static_cast<FmFilterData*>(_pTarget->GetUserData());
		FmFilterItems*	pTargetItems = pData->ISA(FmFilterItems) 
										? 
										PTR_CAST(FmFilterItems,pData)
										: 
									PTR_CAST(FmFilterItems,pData->GetParent());
		return pTargetItems;
	}
}	
//------------------------------------------------------------------------
sal_Int8 FmFilterNavigator::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
	// ware schlecht, wenn nach dem Droppen noch gescrollt wird ...
	if (m_aDropActionTimer.IsActive())
		m_aDropActionTimer.Stop();

	// Format-Ueberpruefung
	if (!m_aControlExchange.isDragSource())
		return DND_ACTION_NONE;

	// das Ziel des Drop sowie einige Daten darueber
	Point aDropPos = rEvt.maPosPixel;
	SvLBoxEntry* pDropTarget = GetEntry( aDropPos );
	if (!pDropTarget)
		return DND_ACTION_NONE;

	// search the container where to add the items
	FmFilterItems*	pTargetItems = getTargetItems(pDropTarget);
	SelectAll(sal_False);
	SvLBoxEntry* pEntry = FindEntry(pTargetItems);
	Select(pEntry, sal_True);
	SetCurEntry(pEntry);

	insertFilterItem(m_aControlExchange->getDraggedEntries(),pTargetItems,DND_ACTION_COPY == rEvt.mnAction);
	
	return sal_True;
}

//------------------------------------------------------------------------
void FmFilterNavigator::InitEntry(SvLBoxEntry* pEntry,
								  const XubString& rStr,
								  const Image& rImg1,
								  const Image& rImg2,
                                                                  SvLBoxButtonKind eButtonKind)
{
	SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
	SvLBoxString* pString = NULL;

	if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
		pString = new FmFilterString(pEntry, 0, rStr, ((FmFilterItem*)pEntry->GetUserData())->GetFieldName());
	else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
		pString = new FmFilterItemsString(pEntry, 0, rStr );

	if (pString)
		pEntry->ReplaceItem( pString, 1 );
}

//------------------------------------------------------------------------
sal_Bool FmFilterNavigator::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
{
	if (bSelect == IsSelected(pEntry))	// das passiert manchmal, ich glaube, die Basisklasse geht zu sehr auf Nummer sicher ;)
		return sal_True;

	if (SvTreeListBox::Select(pEntry, bSelect))
	{
		if (bSelect)
		{
			FmFormItem* pFormItem = NULL;
			if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
				pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
			else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
				pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
			else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
				pFormItem = (FmFormItem*)pEntry->GetUserData();

			if (pFormItem)
			{
				// will the controller be exchanged?
				if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
					m_pModel->SetCurrentItems((FmFilterItems*)((FmFilterItem*)pEntry->GetUserData())->GetParent());
				else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
					m_pModel->SetCurrentItems((FmFilterItems*)pEntry->GetUserData());
				else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
					m_pModel->SetCurrentController(((FmFormItem*)pEntry->GetUserData())->GetController());
			}
		}
		return sal_True;
	}
	else
		return sal_False;
}

//------------------------------------------------------------------------
void FmFilterNavigator::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
{
	if (rHint.ISA(FmFilterInsertedHint))
	{
		FmFilterInsertedHint* pHint = (FmFilterInsertedHint*)&rHint;
		Insert(pHint->GetData(), pHint->GetPos());
	}
	else if( rHint.ISA(FilterClearingHint) )
	{
		SvTreeListBox::Clear();
	}
	else if( rHint.ISA(FmFilterRemovedHint) )
	{
		FmFilterRemovedHint* pHint = (FmFilterRemovedHint*)&rHint;
		Remove(pHint->GetData());
	}
	else if( rHint.ISA(FmFilterTextChangedHint) )
	{
		FmFilterTextChangedHint* pHint = (FmFilterTextChangedHint*)&rHint;
		SvLBoxEntry* pEntry = FindEntry(pHint->GetData());
		if (pEntry)
			SetEntryText( pEntry, pHint->GetData()->GetText());
	}
	else if( rHint.ISA(FmFilterCurrentChangedHint) )
	{
		// invalidate the entries
		for (SvLBoxEntry* pEntry = First(); pEntry != NULL;
			 pEntry = Next(pEntry))
			GetModel()->InvalidateEntry( pEntry );
	}
}

//------------------------------------------------------------------------
SvLBoxEntry* FmFilterNavigator::FindEntry(const FmFilterData* pItem) const
{
	SvLBoxEntry* pEntry = NULL;
	if (pItem)
	{
		for (pEntry = First(); pEntry != NULL; pEntry = Next( pEntry ))
		{
			FmFilterData* pEntryItem = (FmFilterData*)pEntry->GetUserData();
			if (pEntryItem == pItem)
				break;
		}
	}
	return pEntry;
}

//------------------------------------------------------------------------
void FmFilterNavigator::Insert(FmFilterData* pItem, sal_Int32 nPos)
{
	const FmParentData* pParent = pItem->GetParent() ? pItem->GetParent() : GetFilterModel();

	// insert the item
	SvLBoxEntry* pParentEntry = FindEntry( pParent );
	SvLBoxEntry* pNewEntry = InsertEntry(pItem->GetText(), pItem->GetImage(), pItem->GetImage(), pParentEntry, sal_False, nPos, pItem );
	if ( pNewEntry )
	{
		SetExpandedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
		SetCollapsedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
	}
    if ( pParentEntry )
        Expand( pParentEntry );
}

//------------------------------------------------------------------------
void FmFilterNavigator::Remove(FmFilterData* pItem)
{
	// der Entry zu den Daten
	SvLBoxEntry* pEntry = FindEntry(pItem);

	if (pEntry == m_pEditingCurrently)
		// cancel editing
		EndEditing(sal_True);

	if (pEntry)
		GetModel()->Remove( pEntry );
}
// -----------------------------------------------------------------------------
FmFormItem* FmFilterNavigator::getSelectedFilterItems(::std::vector<FmFilterItem*>& _rItemList)
{
	// be sure that the data is only used within only one form!
	FmFormItem* pFirstItem = NULL;

	sal_Bool bHandled = sal_True;
	sal_Bool bFoundSomething = sal_False;
	for (SvLBoxEntry* pEntry = FirstSelected();
		 bHandled && pEntry != NULL;
		 pEntry = NextSelected(pEntry))
	{
		FmFilterItem* pFilter = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
		if (pFilter)
		{
			FmFormItem* pForm = PTR_CAST(FmFormItem,pFilter->GetParent()->GetParent());
			if (!pForm)
				bHandled = sal_False;
			else if (!pFirstItem)
				pFirstItem = pForm;
			else if (pFirstItem != pForm)
				bHandled = sal_False;

			if (bHandled)
			{
				_rItemList.push_back(pFilter);
				bFoundSomething = sal_True;
			}
		}
	}
	if ( !bHandled || !bFoundSomething )
		pFirstItem = NULL;
	return pFirstItem;
}
// -----------------------------------------------------------------------------
void FmFilterNavigator::insertFilterItem(const ::std::vector<FmFilterItem*>& _rFilterList,FmFilterItems* _pTargetItems,sal_Bool _bCopy)
{
	::std::vector<FmFilterItem*>::const_iterator aEnd = _rFilterList.end();
	for (   ::std::vector< FmFilterItem* >::const_iterator i = _rFilterList.begin();
            i != aEnd;
            ++i
        )
	{
        FmFilterItem* pLookupItem( *i );
		if ( pLookupItem->GetParent() == _pTargetItems )
			continue;

		FmFilterItem* pFilterItem = _pTargetItems->Find( pLookupItem->GetComponentIndex() );
		String aText = pLookupItem->GetText();
		if ( !pFilterItem )
		{
			pFilterItem = new FmFilterItem( m_pModel->getORB(), _pTargetItems, pLookupItem->GetFieldName(), aText, pLookupItem->GetComponentIndex() );
			m_pModel->Append( _pTargetItems, pFilterItem );
		}

		if ( !_bCopy )
			m_pModel->Remove( pLookupItem );

		// now set the text for the new dragged item
		m_pModel->SetTextForItem( pFilterItem, aText );
	}

	m_pModel->EnsureEmptyFilterRows( *_pTargetItems->GetParent() );
}

//------------------------------------------------------------------------------
void FmFilterNavigator::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
{
	EndSelection();

	// be sure that the data is only used within a only one form!
	m_aControlExchange.prepareDrag();

	::std::vector<FmFilterItem*> aItemList;
	if ( FmFormItem* pFirstItem = getSelectedFilterItems(aItemList) )
	{
		m_aControlExchange->setDraggedEntries(aItemList);
		m_aControlExchange->setFormItem(pFirstItem);
		m_aControlExchange.startDrag( DND_ACTION_COPYMOVE );
	}
}

//------------------------------------------------------------------------------
void FmFilterNavigator::Command( const CommandEvent& rEvt )
{
	sal_Bool bHandled = sal_False;
	switch (rEvt.GetCommand())
	{
		case COMMAND_CONTEXTMENU:
		{
			// die Stelle, an der geklickt wurde
			Point aWhere;
			SvLBoxEntry* pClicked = NULL;
			if (rEvt.IsMouseEvent())
			{
				aWhere = rEvt.GetMousePosPixel();
				pClicked = GetEntry(aWhere);
				if (pClicked == NULL)
					break;

				if (!IsSelected(pClicked))
				{
					SelectAll(sal_False);
					Select(pClicked, sal_True);
					SetCurEntry(pClicked);
				}
			}
			else
			{
				pClicked = GetCurEntry();
				if (!pClicked)
					break;
				aWhere = GetEntryPosition( pClicked );
			}

			::std::vector<FmFilterData*> aSelectList;
			for (SvLBoxEntry* pEntry = FirstSelected();
				 pEntry != NULL;
				 pEntry = NextSelected(pEntry))
			{
				// don't delete forms
				FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
				if (!pForm)
					aSelectList.push_back((FmFilterData*)pEntry->GetUserData());
			}
			if (aSelectList.size() == 1)
			{
				// don't delete the only empty row of a form
				FmFilterItems* pFilterItems = PTR_CAST(FmFilterItems, aSelectList[0]);
				if (pFilterItems && pFilterItems->GetChildren().empty()
					&& pFilterItems->GetParent()->GetChildren().size() == 1)
					aSelectList.clear();
			}

			PopupMenu aContextMenu(SVX_RES(RID_FM_FILTER_MENU));

			// every condition could be deleted except the first one if its the only one
			aContextMenu.EnableItem( SID_FM_DELETE, !aSelectList.empty() );

			//
			sal_Bool bEdit = PTR_CAST(FmFilterItem, (FmFilterData*)pClicked->GetUserData()) != NULL &&
				IsSelected(pClicked) && GetSelectionCount() == 1;

			aContextMenu.EnableItem( SID_FM_FILTER_EDIT,
				bEdit );
			aContextMenu.EnableItem( SID_FM_FILTER_IS_NULL,
				bEdit );
			aContextMenu.EnableItem( SID_FM_FILTER_IS_NOT_NULL,
				bEdit );

			aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
			sal_uInt16 nSlotId = aContextMenu.Execute( this, aWhere );
			switch( nSlotId )
			{
				case SID_FM_FILTER_EDIT:
				{
					EditEntry( pClicked );
				}	break;
				case SID_FM_FILTER_IS_NULL:
				case SID_FM_FILTER_IS_NOT_NULL:
				{
					UniString aErrorMsg;
					UniString aText;
					if (nSlotId == SID_FM_FILTER_IS_NULL)
						aText.AssignAscii("IS NULL");
					else
						aText.AssignAscii("IS NOT NULL");

					m_pModel->ValidateText((FmFilterItem*)pClicked->GetUserData(),
											aText, aErrorMsg);
					m_pModel->SetTextForItem((FmFilterItem*)pClicked->GetUserData(), aText);
				}	break;
				case SID_FM_DELETE:
				{
					DeleteSelection();
				}	break;
			}
			bHandled = sal_True;
		} break;
	}

	if (!bHandled)
		SvTreeListBox::Command( rEvt );
}
// -----------------------------------------------------------------------------
SvLBoxEntry* FmFilterNavigator::getNextEntry(SvLBoxEntry* _pStartWith)
{
	SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : LastSelected();
	pEntry = Next(pEntry);
	// we need the next filter entry
	while( pEntry && GetChildCount( pEntry ) == 0 && pEntry != Last() )
		pEntry = Next(pEntry);
	return pEntry;
}
// -----------------------------------------------------------------------------
SvLBoxEntry* FmFilterNavigator::getPrevEntry(SvLBoxEntry* _pStartWith)
{
	SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : FirstSelected();
	pEntry = Prev(pEntry);
	// check if the previous entry is a filter, if so get the next prev
	if ( pEntry && GetChildCount( pEntry ) != 0 )
	{
		pEntry = Prev(pEntry);
		// if the entry is still no leaf return
		if ( pEntry && GetChildCount( pEntry ) != 0 )
			pEntry = NULL;
	}
	return pEntry;
}
//------------------------------------------------------------------------
void FmFilterNavigator::KeyInput(const KeyEvent& rKEvt)
{
	const KeyCode&  rKeyCode = rKEvt.GetKeyCode();

    switch ( rKeyCode.GetCode() )
    {
    case KEY_UP:
    case KEY_DOWN:
    {
        if ( !rKeyCode.IsMod1() || !rKeyCode.IsMod2() || rKeyCode.IsShift() )
            break;

        ::std::vector<FmFilterItem*> aItemList;
		if ( !getSelectedFilterItems( aItemList ) )
            break;

		::std::mem_fun1_t<SvLBoxEntry*,FmFilterNavigator,SvLBoxEntry*> getter = ::std::mem_fun(&FmFilterNavigator::getNextEntry);
		if ( rKeyCode.GetCode() == KEY_UP )
			getter = ::std::mem_fun(&FmFilterNavigator::getPrevEntry);

		SvLBoxEntry* pTarget = getter( this, NULL );
		if ( !pTarget )
            break;

        FmFilterItems* pTargetItems = getTargetItems( pTarget );
		if ( !pTargetItems )
            break;

        ::std::vector<FmFilterItem*>::const_iterator aEnd = aItemList.end();
		sal_Bool bNextTargetItem = sal_True;
		while ( bNextTargetItem )
		{
			::std::vector<FmFilterItem*>::const_iterator i = aItemList.begin();
			for (; i != aEnd; ++i)
			{
				if ( (*i)->GetParent() == pTargetItems )
				{
					pTarget = getter(this,pTarget);
					if ( !pTarget )
						return;
					pTargetItems = getTargetItems( pTarget );
					break;
				}
				else
				{
					FmFilterItem* pFilterItem = pTargetItems->Find( (*i)->GetComponentIndex() );
					// we found the text component so jump above
					if ( pFilterItem )
					{
						pTarget = getter( this, pTarget );
						if ( !pTarget )
							return;

                        pTargetItems = getTargetItems( pTarget );
						break;
					}
				}
			}
			bNextTargetItem = i != aEnd && pTargetItems;
		}

		if ( pTargetItems )
		{
			insertFilterItem( aItemList, pTargetItems );
			return;
		}
    }
    break;

    case KEY_DELETE:
    {
        if ( rKeyCode.GetModifier() )
            break;

        if ( !IsSelected( First() ) || GetEntryCount() > 1 )
			DeleteSelection();
		return;
    }
    }

    SvTreeListBox::KeyInput(rKEvt);
}

//------------------------------------------------------------------------------
void FmFilterNavigator::DeleteSelection()
{
	// to avoid the deletion of an entry twice (e.g. deletion of a parent and afterward
	// the deletion of it's child, i have to shrink the selecton list
	::std::vector<SvLBoxEntry*> aEntryList;
	for (SvLBoxEntry* pEntry = FirstSelected();
		 pEntry != NULL;
		 pEntry = NextSelected(pEntry))
	{
		FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
		if (pFilterItem && IsSelected(GetParent(pEntry)))
			continue;

		FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
		if (!pForm)
			aEntryList.push_back(pEntry);
	}

	// Remove the selection
	SelectAll(sal_False);

	for (::std::vector<SvLBoxEntry*>::reverse_iterator i = aEntryList.rbegin();
		// link problems with operator ==
		i.base() != aEntryList.rend().base(); i++)
	{
		m_pModel->Remove((FmFilterData*)(*i)->GetUserData());
	}
}
// -----------------------------------------------------------------------------

//========================================================================
// class FmFilterNavigatorWin
//========================================================================
FmFilterNavigatorWin::FmFilterNavigatorWin( SfxBindings* _pBindings, SfxChildWindow* _pMgr,
							  Window* _pParent )
					 :SfxDockingWindow( _pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_ROLLABLE|WB_3DLOOK|WB_DOCKABLE) )
					 ,SfxControllerItem( SID_FM_FILTER_NAVIGATOR_CONTROL, *_pBindings )
{
	SetHelpId( HID_FILTER_NAVIGATOR_WIN );

	m_pNavigator = new FmFilterNavigator( this );
	m_pNavigator->Show();
	SetText( SVX_RES(RID_STR_FILTER_NAVIGATOR) );
	SfxDockingWindow::SetFloatingSize( Size(200,200) );
}

//------------------------------------------------------------------------
FmFilterNavigatorWin::~FmFilterNavigatorWin()
{
	delete m_pNavigator;
}

//-----------------------------------------------------------------------
void FmFilterNavigatorWin::UpdateContent(FmFormShell* pFormShell)
{
	if (!pFormShell)
		m_pNavigator->UpdateContent( NULL, NULL );
	else
	{
		Reference< XFormController >  xController(pFormShell->GetImpl()->getActiveInternalController());
		Reference< XIndexAccess >	xContainer;
		if (xController.is())
		{
			Reference< XChild >  xChild(xController, UNO_QUERY);
			for (Reference< XInterface >  xParent(xChild->getParent());
				 xParent.is();
				 xParent = xChild.is() ? xChild->getParent() : Reference< XInterface > ())
			{
				xContainer = Reference< XIndexAccess > (xParent, UNO_QUERY);
				xChild = Reference< XChild > (xParent, UNO_QUERY);
			}
		}
		m_pNavigator->UpdateContent(xContainer, xController);
	}
}

//-----------------------------------------------------------------------
void FmFilterNavigatorWin::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
{
	if( !pState  || SID_FM_FILTER_NAVIGATOR_CONTROL != nSID )
		return;

	if( eState >= SFX_ITEM_AVAILABLE )
	{
		FmFormShell* pShell = PTR_CAST( FmFormShell,((SfxObjectItem*)pState)->GetShell() );
		UpdateContent( pShell );
	}
	else
		UpdateContent( NULL );
}

//-----------------------------------------------------------------------
sal_Bool FmFilterNavigatorWin::Close()
{
	if ( m_pNavigator && m_pNavigator->IsEditingActive() )
		m_pNavigator->EndEditing();

	if ( m_pNavigator && m_pNavigator->IsEditingActive() )
		// the EndEditing was vetoed (perhaps of an syntax error or such)
		return sal_False;

	UpdateContent( NULL );
	return SfxDockingWindow::Close();
}

//-----------------------------------------------------------------------
void FmFilterNavigatorWin::FillInfo( SfxChildWinInfo& rInfo ) const
{
	SfxDockingWindow::FillInfo( rInfo );
	rInfo.bVisible = sal_False;
}

//-----------------------------------------------------------------------
Size FmFilterNavigatorWin::CalcDockingSize( SfxChildAlignment eAlign )
{
	if ( ( eAlign == SFX_ALIGN_TOP ) || ( eAlign == SFX_ALIGN_BOTTOM ) )
		return Size();

    return SfxDockingWindow::CalcDockingSize( eAlign );
}

//-----------------------------------------------------------------------
SfxChildAlignment FmFilterNavigatorWin::CheckAlignment( SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
{
	switch (eAlign)
	{
		case SFX_ALIGN_LEFT:
		case SFX_ALIGN_RIGHT:
		case SFX_ALIGN_NOALIGNMENT:
			return (eAlign);
        default:
            break;
	}

	return (eActAlign);
}

//------------------------------------------------------------------------
void FmFilterNavigatorWin::Resize()
{
	SfxDockingWindow::Resize();

	Size aLogOutputSize = PixelToLogic( GetOutputSizePixel(), MAP_APPFONT );
	Size aLogExplSize = aLogOutputSize;
	aLogExplSize.Width() -= 6;
	aLogExplSize.Height() -= 6;

	Point aExplPos = LogicToPixel( Point(3,3), MAP_APPFONT );
	Size aExplSize = LogicToPixel( aLogExplSize, MAP_APPFONT );

	m_pNavigator->SetPosSizePixel( aExplPos, aExplSize );
}
// -----------------------------------------------------------------------------
void FmFilterNavigatorWin::GetFocus()
{
	// oj #97405#
	if ( m_pNavigator )
		m_pNavigator->GrabFocus();
}
// -----------------------------------------------------------------------------


//========================================================================
// class FmFilterNavigatorWinMgr
//========================================================================
SFX_IMPL_DOCKINGWINDOW( FmFilterNavigatorWinMgr, SID_FM_FILTER_NAVIGATOR )

//-----------------------------------------------------------------------
FmFilterNavigatorWinMgr::FmFilterNavigatorWinMgr( Window *_pParent, sal_uInt16 _nId,
									SfxBindings *_pBindings, SfxChildWinInfo* _pInfo )
				 :SfxChildWindow( _pParent, _nId )
{
	pWindow = new FmFilterNavigatorWin( _pBindings, this, _pParent );
	eChildAlignment = SFX_ALIGN_NOALIGNMENT;
	((SfxDockingWindow*)pWindow)->Initialize( _pInfo );
}

//........................................................................
}	// namespace svxform
//........................................................................
