/**************************************************************
 * 
 * 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)
		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 whith 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
//........................................................................
