/**************************************************************
 * 
 * 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 "fmitems.hxx"
#include "fmobj.hxx"
#include "fmpgeimp.hxx"
#include "svx/fmtools.hxx"
#include "fmprop.hrc"
#include "svx/fmresids.hrc"
#include "fmservs.hxx"
#include "fmshimp.hxx"
#include "fmtextcontrolshell.hxx"
#include "fmundo.hxx"
#include "fmurl.hxx"
#include "fmvwimp.hxx"
#include "formtoolbars.hxx"
#include "gridcols.hxx"
#include "svx/svditer.hxx"
#include "svx/dialmgr.hxx"
#include "svx/dialogs.hrc"
#include "svx/fmglob.hxx"
#include "svx/fmmodel.hxx"
#include "svx/fmpage.hxx"
#include "svx/fmshell.hxx"
#include "svx/obj3d.hxx"
#include "svx/sdrpagewindow.hxx"
#include "svx/svdpagv.hxx"
#include "svx/svxdlg.hxx"
#include "svx/svxids.hrc"

/** === begin UNO includes === **/
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/awt/XCheckBox.hpp>
#include <com/sun/star/awt/XListBox.hpp>
#include <com/sun/star/awt/XTextComponent.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/form/ListSourceType.hpp>
#include <com/sun/star/form/XBoundComponent.hpp>
#include <com/sun/star/form/XBoundControl.hpp>
#include <com/sun/star/form/XGrid.hpp>
#include <com/sun/star/form/XGridPeer.hpp>
#include <com/sun/star/form/XLoadable.hpp>
#include <com/sun/star/form/XReset.hpp>
#include <com/sun/star/form/binding/XBindableValue.hpp>
#include <com/sun/star/form/binding/XListEntrySink.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/script/XEventAttacherManager.hpp>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/util/XCancellable.hpp>
#include <com/sun/star/util/XModeSelector.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <com/sun/star/util/XNumberFormatter.hpp>
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <com/sun/star/beans/XIntrospection.hpp>
/** === end UNO includes === **/

#include <comphelper/extract.hxx>
#include <comphelper/evtmethodhelper.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/property.hxx>
#include <comphelper/stl_types.hxx>
#include <connectivity/dbtools.hxx>
#include <cppuhelper/servicefactory.hxx>
#include <osl/mutex.hxx>
#include <rtl/logfile.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/frame.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/viewsh.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/color.hxx>
#include <tools/diagnose_ex.h>
#include <tools/shl.hxx>
#include <tools/urlobj.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/waitobj.hxx>
#include <vos/mutex.hxx>

#include <algorithm>
#include <functional>

// wird fuer Invalidate verwendet -> mitpflegen
sal_uInt16 DatabaseSlotMap[] =
{
	SID_FM_RECORD_FIRST,
	SID_FM_RECORD_NEXT,
	SID_FM_RECORD_PREV,
	SID_FM_RECORD_LAST,
	SID_FM_RECORD_NEW,
	SID_FM_RECORD_DELETE,
	SID_FM_RECORD_ABSOLUTE,
	SID_FM_RECORD_TOTAL,
	SID_FM_RECORD_SAVE,
	SID_FM_RECORD_UNDO,
	SID_FM_REMOVE_FILTER_SORT,
	SID_FM_SORTUP,
	SID_FM_SORTDOWN,
	SID_FM_ORDERCRIT,
	SID_FM_AUTOFILTER,
	SID_FM_FORM_FILTERED,
	SID_FM_REFRESH,
    SID_FM_REFRESH_FORM_CONTROL,
	SID_FM_SEARCH,
	SID_FM_FILTER_START,
	SID_FM_VIEW_AS_GRID,
	0
};

// wird fuer Invalidate verwendet -> mitpflegen
// aufsteigend sortieren !!!!!!
sal_Int16 DlgSlotMap[] =	// slots des Controllers
{
	SID_FM_CTL_PROPERTIES,
	SID_FM_PROPERTIES,
	SID_FM_TAB_DIALOG,
	SID_FM_ADD_FIELD,
	SID_FM_SHOW_FMEXPLORER,
	SID_FM_FIELDS_CONTROL,
	SID_FM_SHOW_PROPERTIES,
	SID_FM_PROPERTY_CONTROL,
	SID_FM_FMEXPLORER_CONTROL,
	SID_FM_SHOW_DATANAVIGATOR,
	SID_FM_DATANAVIGATOR_CONTROL,
	0
};

sal_Int16 SelObjectSlotMap[] =	// vom SelObject abhaengige Slots
{
	SID_FM_CONVERTTO_EDIT,
	SID_FM_CONVERTTO_BUTTON,
	SID_FM_CONVERTTO_FIXEDTEXT,
	SID_FM_CONVERTTO_LISTBOX,
	SID_FM_CONVERTTO_CHECKBOX,
	SID_FM_CONVERTTO_RADIOBUTTON,
	SID_FM_CONVERTTO_GROUPBOX,
	SID_FM_CONVERTTO_COMBOBOX,
	SID_FM_CONVERTTO_IMAGEBUTTON,
	SID_FM_CONVERTTO_FILECONTROL,
	SID_FM_CONVERTTO_DATE,
	SID_FM_CONVERTTO_TIME,
	SID_FM_CONVERTTO_NUMERIC,
	SID_FM_CONVERTTO_CURRENCY,
	SID_FM_CONVERTTO_PATTERN,
	SID_FM_CONVERTTO_IMAGECONTROL,
	SID_FM_CONVERTTO_FORMATTED,
    SID_FM_CONVERTTO_SCROLLBAR,
    SID_FM_CONVERTTO_SPINBUTTON,
    SID_FM_CONVERTTO_NAVIGATIONBAR,

	SID_FM_FMEXPLORER_CONTROL,
	SID_FM_DATANAVIGATOR_CONTROL,

	0
};

// die folgenden Arrays muessen kosistent sein, also einander entsprechende Eintraege an der selben relativen Position
// innerhalb ihres jeweiligen Arrays stehen
sal_Int16 nConvertSlots[] =
{
	SID_FM_CONVERTTO_EDIT,
	SID_FM_CONVERTTO_BUTTON,
	SID_FM_CONVERTTO_FIXEDTEXT,
	SID_FM_CONVERTTO_LISTBOX,
	SID_FM_CONVERTTO_CHECKBOX,
	SID_FM_CONVERTTO_RADIOBUTTON,
	SID_FM_CONVERTTO_GROUPBOX,
	SID_FM_CONVERTTO_COMBOBOX,
	SID_FM_CONVERTTO_IMAGEBUTTON,
	SID_FM_CONVERTTO_FILECONTROL,
	SID_FM_CONVERTTO_DATE,
	SID_FM_CONVERTTO_TIME,
	SID_FM_CONVERTTO_NUMERIC,
	SID_FM_CONVERTTO_CURRENCY,
	SID_FM_CONVERTTO_PATTERN,
	SID_FM_CONVERTTO_IMAGECONTROL,
	SID_FM_CONVERTTO_FORMATTED,
    SID_FM_CONVERTTO_SCROLLBAR,
    SID_FM_CONVERTTO_SPINBUTTON,
    SID_FM_CONVERTTO_NAVIGATIONBAR
};

sal_Int16 nCreateSlots[] =
{
	SID_FM_EDIT,
	SID_FM_PUSHBUTTON,
	SID_FM_FIXEDTEXT,
	SID_FM_LISTBOX,
	SID_FM_CHECKBOX,
	SID_FM_RADIOBUTTON,
	SID_FM_GROUPBOX,
	SID_FM_COMBOBOX,
	SID_FM_IMAGEBUTTON,
	SID_FM_FILECONTROL,
	SID_FM_DATEFIELD,
	SID_FM_TIMEFIELD,
	SID_FM_NUMERICFIELD,
	SID_FM_CURRENCYFIELD,
	SID_FM_PATTERNFIELD,
	SID_FM_IMAGECONTROL,
	SID_FM_FORMATTEDFIELD,
    SID_FM_SCROLLBAR,
    SID_FM_SPINBUTTON,
    SID_FM_NAVIGATIONBAR
};

sal_Int16 nObjectTypes[] =
{
	OBJ_FM_EDIT,
	OBJ_FM_BUTTON,
	OBJ_FM_FIXEDTEXT,
	OBJ_FM_LISTBOX,
	OBJ_FM_CHECKBOX,
	OBJ_FM_RADIOBUTTON,
	OBJ_FM_GROUPBOX,
	OBJ_FM_COMBOBOX,
	OBJ_FM_IMAGEBUTTON,
	OBJ_FM_FILECONTROL,
	OBJ_FM_DATEFIELD,
	OBJ_FM_TIMEFIELD,
	OBJ_FM_NUMERICFIELD,
	OBJ_FM_CURRENCYFIELD,
	OBJ_FM_PATTERNFIELD,
	OBJ_FM_IMAGECONTROL,
	OBJ_FM_FORMATTEDFIELD,
	OBJ_FM_SCROLLBAR,
	OBJ_FM_SPINBUTTON,
    OBJ_FM_NAVIGATIONBAR
};

using namespace ::com::sun::star;
using namespace ::com::sun::star::ui;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::form::binding;
using namespace ::com::sun::star::form::runtime;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::view;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::script;
using namespace ::svxform;
using namespace ::svx;

//==============================================================================
//= helper
//==============================================================================
namespace
{
    //..........................................................................
    void collectInterfacesFromMarkList( const SdrMarkList& _rMarkList, InterfaceBag& /* [out] */ _rInterfaces )
    {
        _rInterfaces.clear();

        sal_uInt32 nMarkCount = _rMarkList.GetMarkCount();
        for ( sal_uInt32 i = 0; i < nMarkCount; ++i)
        {
            SdrObject* pCurrent = _rMarkList.GetMark( i )->GetMarkedSdrObj();

            SdrObjListIter* pGroupIterator = NULL;
            if ( pCurrent->IsGroupObject() )
            {
                pGroupIterator = new SdrObjListIter( *pCurrent->GetSubList() );
                pCurrent = pGroupIterator->IsMore() ? pGroupIterator->Next() : NULL;
            }

            while ( pCurrent )
            {
                FmFormObj* pAsFormObject = FmFormObj::GetFormObject( pCurrent );
                    // note this will de-reference virtual objects, if necessary/possible
                if ( pAsFormObject )
                {
                    Reference< XInterface > xControlModel( pAsFormObject->GetUnoControlModel(), UNO_QUERY );
                        // the UNO_QUERY is important for normalization
                    if ( xControlModel.is() )
                        _rInterfaces.insert( xControlModel );
                }

                // next element
                pCurrent = pGroupIterator && pGroupIterator->IsMore() ? pGroupIterator->Next() : NULL;
            }

            if ( pGroupIterator )
                delete pGroupIterator;
        }
    }

    //..........................................................................
    sal_Int16 GridView2ModelPos(const Reference< XIndexAccess>& rColumns, sal_Int16 nViewPos)
    {
        try
        {
            if (rColumns.is())
            {
                // loop through all columns
                sal_Int16 i;
                Reference< XPropertySet> xCur;
                for (i=0; i<rColumns->getCount(); ++i)
                {
                    rColumns->getByIndex(i) >>= xCur;
                    if (!::comphelper::getBOOL(xCur->getPropertyValue(FM_PROP_HIDDEN)))
                    {
                        // for every visible col : if nViewPos is greater zero, decrement it, else we
                        // have found the model position
                        if (!nViewPos)
                            break;
                        else
                            --nViewPos;
                    }
                }
                if (i<rColumns->getCount())
                    return i;
            }
        }
        catch(const Exception&)
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return (sal_Int16)-1;
    }

    //..........................................................................
    void TransferEventScripts(const Reference< XControlModel>& xModel, const Reference< XControl>& xControl,
	    const Sequence< ScriptEventDescriptor>& rTransferIfAvailable)
    {
	    // first check if we have a XEventAttacherManager for the model
	    Reference< XChild> xModelChild(xModel, UNO_QUERY);
	    if (!xModelChild.is())
		    return; // nothing to do

	    Reference< XEventAttacherManager> xEventManager(xModelChild->getParent(), UNO_QUERY);
	    if (!xEventManager.is())
		    return; // nothing to do

	    if (!rTransferIfAvailable.getLength())
		    return; // nothing to do

	    // check for the index of the model within it's parent
	    Reference< XIndexAccess> xParentIndex(xModelChild->getParent(), UNO_QUERY);
	    if (!xParentIndex.is())
		    return; // nothing to do
	    sal_Int32 nIndex = getElementPos(xParentIndex, xModel);
	    if (nIndex<0 || nIndex>=xParentIndex->getCount())
		    return; // nothing to do

	    // then we need informations about the listeners supported by the control and the model
	    Sequence< Type> aModelListeners;
	    Sequence< Type> aControlListeners;

	    Reference< XIntrospection> xModelIntrospection(::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.beans.Introspection")), UNO_QUERY);
	    Reference< XIntrospection> xControlIntrospection(::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.beans.Introspection")), UNO_QUERY);

	    if (xModelIntrospection.is() && xModel.is())
	    {
		    Any aModel(makeAny(xModel));
		    aModelListeners = xModelIntrospection->inspect(aModel)->getSupportedListeners();
	    }

	    if (xControlIntrospection.is() && xControl.is())
	    {
		    Any aControl(makeAny(xControl));
		    aControlListeners = xControlIntrospection->inspect(aControl)->getSupportedListeners();
	    }

	    sal_Int32 nMaxNewLen = aModelListeners.getLength() + aControlListeners.getLength();
	    if (!nMaxNewLen)
		    return; // the model and the listener don't support any listeners (or we were unable to retrieve these infos)

	    Sequence< ScriptEventDescriptor>	aTransferable(nMaxNewLen);
	    ScriptEventDescriptor* pTransferable = aTransferable.getArray();

	    const ScriptEventDescriptor* pCurrent = rTransferIfAvailable.getConstArray();
	    sal_Int32 i,j,k;
	    for (i=0; i<rTransferIfAvailable.getLength(); ++i, ++pCurrent)
	    {
		    // search the model/control idl classes for the event described by pCurrent
		    for (	Sequence< Type>* pCurrentArray = &aModelListeners;
				    pCurrentArray;
				    pCurrentArray = (pCurrentArray == &aModelListeners) ? &aControlListeners : NULL
			    )
		    {
			    const Type* pCurrentListeners = pCurrentArray->getConstArray();
			    for (j=0; j<pCurrentArray->getLength(); ++j, ++pCurrentListeners)
			    {
				    UniString aListener = (*pCurrentListeners).getTypeName();
				    xub_StrLen nTokens = aListener.GetTokenCount('.');
				    if (nTokens)
					    aListener = aListener.GetToken(nTokens - 1, '.');

				    if (aListener == pCurrent->ListenerType.getStr())
					    // the current ScriptEventDescriptor doesn't match the current listeners class
					    continue;

				    // now check the methods
					Sequence< ::rtl::OUString> aMethodsNames = ::comphelper::getEventMethodsForType(*pCurrentListeners);

				    const ::rtl::OUString* pMethodsNames = aMethodsNames.getConstArray();
				    for (k=0; k<aMethodsNames.getLength(); ++k, ++pMethodsNames)
				    {
					    if ((*pMethodsNames).compareTo(pCurrent->EventMethod) != COMPARE_EQUAL)
						    // the current ScriptEventDescriptor doesn't match the current listeners current method
						    continue;

					    // we can transfer the script event : the model (control) supports it
					    *pTransferable = *pCurrent;
					    ++pTransferable;
					    break;
				    }
				    if (k<aMethodsNames.getLength())
					    break;
			    }
		    }
	    }

	    sal_Int32 nRealNewLen = pTransferable - aTransferable.getArray();
	    aTransferable.realloc(nRealNewLen);

	    xEventManager->registerScriptEvents(nIndex, aTransferable);
    }

    //------------------------------------------------------------------------------
    ::rtl::OUString getServiceNameByControlType(sal_Int16 nType)
    {
	    switch (nType)
	    {
		    case OBJ_FM_EDIT			: return FM_COMPONENT_TEXTFIELD;
		    case OBJ_FM_BUTTON			: return FM_COMPONENT_COMMANDBUTTON;
		    case OBJ_FM_FIXEDTEXT		: return FM_COMPONENT_FIXEDTEXT;
		    case OBJ_FM_LISTBOX 		: return FM_COMPONENT_LISTBOX;
		    case OBJ_FM_CHECKBOX		: return FM_COMPONENT_CHECKBOX;
		    case OBJ_FM_RADIOBUTTON 	: return FM_COMPONENT_RADIOBUTTON;
		    case OBJ_FM_GROUPBOX		: return FM_COMPONENT_GROUPBOX;
		    case OBJ_FM_COMBOBOX		: return FM_COMPONENT_COMBOBOX;
		    case OBJ_FM_GRID			: return FM_COMPONENT_GRIDCONTROL;
		    case OBJ_FM_IMAGEBUTTON 	: return FM_COMPONENT_IMAGEBUTTON;
		    case OBJ_FM_FILECONTROL 	: return FM_COMPONENT_FILECONTROL;
		    case OBJ_FM_DATEFIELD		: return FM_COMPONENT_DATEFIELD;
		    case OBJ_FM_TIMEFIELD		: return FM_COMPONENT_TIMEFIELD;
		    case OBJ_FM_NUMERICFIELD	: return FM_COMPONENT_NUMERICFIELD;
		    case OBJ_FM_CURRENCYFIELD	: return FM_COMPONENT_CURRENCYFIELD;
		    case OBJ_FM_PATTERNFIELD	: return FM_COMPONENT_PATTERNFIELD;
		    case OBJ_FM_HIDDEN			: return FM_COMPONENT_HIDDENCONTROL;
		    case OBJ_FM_IMAGECONTROL	: return FM_COMPONENT_IMAGECONTROL;
		    case OBJ_FM_FORMATTEDFIELD	: return FM_COMPONENT_FORMATTEDFIELD;
		    case OBJ_FM_SCROLLBAR       : return FM_SUN_COMPONENT_SCROLLBAR;
		    case OBJ_FM_SPINBUTTON      : return FM_SUN_COMPONENT_SPINBUTTON;
            case OBJ_FM_NAVIGATIONBAR   : return FM_SUN_COMPONENT_NAVIGATIONBAR;
	    }
	    return ::rtl::OUString();
    }

}

//------------------------------------------------------------------------------
// check if the control has one of the interfaces we can use for searching
// *_pCurrentText will be filled with the current text of the control (as used when searching this control)
sal_Bool IsSearchableControl( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& _rxControl,
    ::rtl::OUString* _pCurrentText )
{
	if ( !_rxControl.is() )
		return sal_False;

	Reference< XTextComponent > xAsText( _rxControl, UNO_QUERY );
	if ( xAsText.is() )
	{
		if ( _pCurrentText )
			*_pCurrentText = xAsText->getText();
		return sal_True;
	}

	Reference< XListBox > xListBox( _rxControl, UNO_QUERY );
	if ( xListBox.is() )
	{
		if ( _pCurrentText )
			*_pCurrentText = xListBox->getSelectedItem();
		return sal_True;
	}

	Reference< XCheckBox > xCheckBox( _rxControl, UNO_QUERY );
	if ( xCheckBox.is() )
	{
		if ( _pCurrentText )
		{
			switch ( (TriState)xCheckBox->getState() )
			{
				case STATE_NOCHECK: *_pCurrentText = ::rtl::OUString::createFromAscii( "0" ); break;
				case STATE_CHECK: *_pCurrentText = ::rtl::OUString::createFromAscii( "1" ); break;
				default: *_pCurrentText = ::rtl::OUString(); break;
			}
		}
		return sal_True;
	}

	return sal_False;
}

//------------------------------------------------------------------------------
sal_Bool FmXBoundFormFieldIterator::ShouldStepInto(const Reference< XInterface>& _rContainer) const
{
	if (_rContainer == m_xStartingPoint)
		// would be quite stupid to step over the root ....
		return sal_True;

	return Reference< XControlModel>(_rContainer, UNO_QUERY).is();
}

//------------------------------------------------------------------------------
sal_Bool FmXBoundFormFieldIterator::ShouldHandleElement(const Reference< XInterface>& _rElement)
{
	if (!_rElement.is())
		// NULL element
		return sal_False;

	if (Reference< XForm>(_rElement, UNO_QUERY).is() || Reference< XGrid>(_rElement, UNO_QUERY).is())
		// a forms or a grid
		return sal_False;

	Reference< XPropertySet> xSet(_rElement, UNO_QUERY);
	if (!xSet.is() || !::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
		// no "BoundField" property
		return sal_False;

	Any aVal( xSet->getPropertyValue(FM_PROP_BOUNDFIELD) );
	if (aVal.getValueTypeClass() != TypeClass_INTERFACE)
		// void or invalid property value
		return sal_False;

	return aVal.hasValue();
}

//------------------------------------------------------------------------------
sal_Bool isControlList(const SdrMarkList& rMarkList)
{
	// enthaelt die liste nur Controls und mindestens ein control
	sal_uInt32 nMarkCount = rMarkList.GetMarkCount();
	sal_Bool  bControlList = nMarkCount != 0;

	sal_Bool bHadAnyLeafs = sal_False;

	for (sal_uInt32 i = 0; i < nMarkCount && bControlList; i++)
	{
		SdrObject *pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
		E3dObject* pAs3DObject = PTR_CAST(E3dObject, pObj);
		// E3dObject's do not contain any 2D-objects (by definition)
		// we need this extra check here : an E3dObject->IsGroupObject says "YES", but an SdrObjListIter working
		// with an E3dObject doesn't give me any Nodes (E3dObject has a sub list, but no members in that list,
		// cause there implementation differs from the one of "normal" SdrObject's. Unfortunally SdrObject::IsGroupObject
		// doesn't check the element count of the sub list, which is simply a bug in IsGroupObject we can't fix at the moment).
		// So at the end of this function bControlList would have the same value it was initialized with above : sal_True
		// And this would be wrong :)
		// 03.02.00 - 72529 - FS
		if (!pAs3DObject)
		{
			if (pObj->IsGroupObject())
			{
				SdrObjListIter aIter(*pObj->GetSubList());
				while (aIter.IsMore() && bControlList)
				{
					bControlList = FmFormInventor == aIter.Next()->GetObjInventor();
					bHadAnyLeafs = sal_True;
				}
			}
			else
			{
				bHadAnyLeafs = sal_True;
				bControlList = FmFormInventor == pObj->GetObjInventor();
			}
		}
	}

	return bControlList && bHadAnyLeafs;
}

//------------------------------------------------------------------------
Reference< XForm > GetForm(const Reference< XInterface>& _rxElement)
{
    Reference< XForm > xForm( _rxElement, UNO_QUERY );
    if ( xForm.is() )
        return xForm;

    Reference< XChild > xChild( _rxElement, UNO_QUERY );
	if ( xChild.is() )
        return GetForm( xChild->getParent() );

	return Reference< XForm >();
}

//========================================================================
// class FmXFormShell_Base_Disambiguation
//========================================================================
FmXFormShell_Base_Disambiguation::FmXFormShell_Base_Disambiguation( ::osl::Mutex& _rMutex )
	:FmXFormShell_BD_BASE( _rMutex )
{
}

void SAL_CALL FmXFormShell_Base_Disambiguation::disposing()
{
	WeakComponentImplHelperBase::disposing();
	// Note:
	// This is a HACK.
	// Normally it should be sufficient to call the "disposing" of our direct
	// base class, but SUN PRO 5 does not like this and claims there is a conflict
	// with the XEventListener::disposing(EventObject) of our various listener
	// base classes.
}

//========================================================================
// class FmXFormShell
//========================================================================
DBG_NAME(FmXFormShell);
//------------------------------------------------------------------------
FmXFormShell::FmXFormShell( FmFormShell& _rShell, SfxViewFrame* _pViewFrame )
		:FmXFormShell_BASE(m_aMutex)
		,FmXFormShell_CFGBASE(::rtl::OUString::createFromAscii("Office.Common/Misc"), CONFIG_MODE_DELAYED_UPDATE)
		,m_eNavigate( NavigationBarMode_NONE )
		,m_nInvalidationEvent( 0 )
        ,m_nActivationEvent( 0 )
		,m_pShell( &_rShell )
        ,m_pTextShell( new ::svx::FmTextControlShell( _pViewFrame ) )
        ,m_aActiveControllerFeatures( ::comphelper::getProcessServiceFactory(), this )
        ,m_aNavControllerFeatures( ::comphelper::getProcessServiceFactory(), this )
        ,m_eDocumentType( eUnknownDocumentType )
		,m_nLockSlotInvalidation( 0 )
		,m_bHadPropertyBrowserInDesignMode( sal_False )
		,m_bTrackProperties( sal_True )
		,m_bUseWizards( sal_True )
		,m_bDatabaseBar( sal_False )
        ,m_bInActivate( sal_False )
		,m_bSetFocus( sal_False )
		,m_bFilterMode( sal_False )
		,m_bChangingDesignMode( sal_False )
		,m_bPreparedClose( sal_False )
        ,m_bFirstActivation( sal_True )
{
	DBG_CTOR(FmXFormShell,NULL);
	m_aMarkTimer.SetTimeout(100);
	m_aMarkTimer.SetTimeoutHdl(LINK(this,FmXFormShell,OnTimeOut));

	if ( _pViewFrame )
		m_xAttachedFrame = _pViewFrame->GetFrame().GetFrameInterface();

	// to prevent deletion of this we acquire our refcounter once
	::comphelper::increment(FmXFormShell_BASE::m_refCount);

	// correct the refcounter
	::comphelper::decrement(FmXFormShell_BASE::m_refCount);

	// cache the current configuration settings we're interested in
	implAdjustConfigCache();
	// and register for changes on this settings
	Sequence< ::rtl::OUString > aNames(1);
	aNames[0] = ::rtl::OUString::createFromAscii("FormControlPilotsEnabled");
	EnableNotification(aNames);
}

//------------------------------------------------------------------------
FmXFormShell::~FmXFormShell()
{
    delete m_pTextShell;
	DBG_DTOR(FmXFormShell,NULL);
}

//------------------------------------------------------------------
Reference< XModel > FmXFormShell::getContextDocument() const
{
    Reference< XModel > xModel;

    // determine the type of document we live in
    try
    {
        Reference< XController > xController;
        if ( m_xAttachedFrame.is() )
	        xController = m_xAttachedFrame->getController();
        if ( xController.is() )
	        xModel = xController->getModel();
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
    return xModel;
}

//------------------------------------------------------------------
bool FmXFormShell::isEnhancedForm() const
{
	return getDocumentType() == eEnhancedForm;
}

//------------------------------------------------------------------
bool FmXFormShell::impl_checkDisposed() const
{
    if ( !m_pShell )
    {
        OSL_ENSURE( false, "FmXFormShell::impl_checkDisposed: already disposed!" );
        return true;
    }
    return false;
}

//------------------------------------------------------------------
::svxform::DocumentType FmXFormShell::getDocumentType() const
{
    if ( m_eDocumentType != eUnknownDocumentType )
        return m_eDocumentType;

    // determine the type of document we live in
    Reference< XModel > xModel = getContextDocument();
    if ( xModel.is() )
        m_eDocumentType = DocumentClassification::classifyDocument( xModel );
    else
    {
        OSL_ENSURE( sal_False, "FmXFormShell::getDocumentType: can't determine the document type!" );
        m_eDocumentType = eTextDocument;
            // fallback, just to have a defined state
    }

    return m_eDocumentType;
}

//------------------------------------------------------------------
bool FmXFormShell::IsReadonlyDoc() const
{
    if ( impl_checkDisposed() )
        return true;

	FmFormModel* pModel = m_pShell->GetFormModel();
    if ( pModel && pModel->GetObjectShell() )
        return pModel->GetObjectShell()->IsReadOnly() || pModel->GetObjectShell()->IsReadOnlyUI();
    return true;
}

//------------------------------------------------------------------
Any SAL_CALL FmXFormShell::queryInterface( const Type& type) throw ( RuntimeException )
{
	return FmXFormShell_BASE::queryInterface(type);
}
//------------------------------------------------------------------------------
Sequence< Type > SAL_CALL FmXFormShell::getTypes(  ) throw(RuntimeException)
{
	return FmXFormShell_BASE::getTypes();
}
//------------------------------------------------------------------------------
Sequence< sal_Int8 > SAL_CALL FmXFormShell::getImplementationId() throw(RuntimeException)
{
    static ::cppu::OImplementationId* pId = 0;
	if (! pId)
	{
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
		if (! pId)
		{
			static ::cppu::OImplementationId aId;
			pId = &aId;
		}
	}
	return pId->getImplementationId();
}
//	EventListener
//------------------------------------------------------------------------------
void SAL_CALL FmXFormShell::disposing(const EventObject& e) throw( RuntimeException )
{
    impl_checkDisposed();

	if (m_xActiveController == e.Source)
	{
		// wird der Controller freigeben dann alles loslassen
		stopListening();
		m_xActiveForm = NULL;
		m_xActiveController = NULL;
		m_xNavigationController = NULL;

        m_aActiveControllerFeatures.dispose();
        m_aNavControllerFeatures.dispose();

        if ( m_pShell )
		    m_pShell->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell);
	}

	if (e.Source == m_xExternalViewController)
	{
        Reference< runtime::XFormController > xFormController( m_xExternalViewController, UNO_QUERY );
        OSL_ENSURE( xFormController.is(), "FmXFormShell::disposing: invalid external view controller!" );
		if (xFormController.is())
			xFormController->removeActivateListener((XFormControllerListener*)this);

		Reference< ::com::sun::star::lang::XComponent> xComp(m_xExternalViewController, UNO_QUERY);
		if (xComp.is())
			xComp->removeEventListener((XEventListener*)(XPropertyChangeListener*)this);

		m_xExternalViewController = NULL;
		m_xExternalDisplayedForm = NULL;
		m_xExtViewTriggerController = NULL;

		InvalidateSlot( SID_FM_VIEW_AS_GRID, sal_False );
	}
}

//------------------------------------------------------------------------------
void SAL_CALL FmXFormShell::propertyChange(const PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException)
{
    if ( impl_checkDisposed() )
        return;

	if (evt.PropertyName == FM_PROP_ROWCOUNT)
	{
		// Das gleich folgenden Update erzwingt ein Neu-Painten der entsprechenden Slots. Wenn ich mich aber hier nicht
		// in dem HauptThread der Applikation befinde (weil zum Beispiel ein Cursor gerade Datensaetze zaehlt und mir dabei
		// immer diese PropertyChanges beschert), kann sich das mit en normalen Paints im HauptThread der Applikation beissen.
		// (Solche Paints passieren zum Beispiel, wenn man einfach nur eine andere Applikation ueber das Office legt und wieder
		// zurueckschaltet).
		// Deshalb die Benutzung des SolarMutex, der sichert das ab.
		::vos::IMutex& rSolarSafety = Application::GetSolarMutex();
		if (rSolarSafety.tryToAcquire())
		{
			m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_RECORD_TOTAL , sal_True, sal_False);
			m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Update(SID_FM_RECORD_TOTAL);
			rSolarSafety.release();
		}
		else
		{
			// with the following the slot is invalidated asynchron
			LockSlotInvalidation(sal_True);
			InvalidateSlot(SID_FM_RECORD_TOTAL, sal_False);
			LockSlotInvalidation(sal_False);
		}
	}

	// this may be called from a non-main-thread so invalidate the shell asynchronously
	LockSlotInvalidation(sal_True);
	InvalidateSlot(0, 0);		// special meaning : invalidate m_pShell
	LockSlotInvalidation(sal_False);
}

//------------------------------------------------------------------------------
void FmXFormShell::invalidateFeatures( const ::std::vector< sal_Int32 >& _rFeatures )
{
    if ( impl_checkDisposed() )
        return;

    OSL_ENSURE( _rFeatures.size() > 0, "FmXFormShell::invalidateFeatures: invalid arguments!" );

    if ( m_pShell->GetViewShell() && m_pShell->GetViewShell()->GetViewFrame() )
    {
        // unfortunately, SFX requires sal_uInt16
        ::std::vector< sal_uInt16 > aSlotIds;
        aSlotIds.reserve( _rFeatures.size() );
        ::std::copy( _rFeatures.begin(),
            _rFeatures.end(),
            ::std::insert_iterator< ::std::vector< sal_uInt16 > >( aSlotIds, aSlotIds.begin() )
        );

        // furthermore, SFX wants a terminating 0
        aSlotIds.push_back( 0 );

        // and, last but not least, SFX wants the ids to be sorted
        ::std::sort( aSlotIds.begin(), aSlotIds.end() - 1 );

        sal_uInt16 *pSlotIds = aSlotIds.empty() ? 0 : &(aSlotIds[0]);
        m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate( pSlotIds );
    }
}

//------------------------------------------------------------------------------
void SAL_CALL FmXFormShell::formActivated(const EventObject& rEvent) throw( RuntimeException )
{
    if ( impl_checkDisposed() )
        return;

    Reference< runtime::XFormController > xController( rEvent.Source, UNO_QUERY_THROW );
    m_pTextShell->formActivated( xController );
    setActiveController( xController );
}

//------------------------------------------------------------------------------
void SAL_CALL FmXFormShell::formDeactivated(const EventObject& rEvent) throw( RuntimeException )
{
    if ( impl_checkDisposed() )
        return;

    Reference< runtime::XFormController > xController( rEvent.Source, UNO_QUERY_THROW );
    m_pTextShell->formDeactivated( xController );
}

//------------------------------------------------------------------------------
void FmXFormShell::disposing()
{
    impl_checkDisposed();

	FmXFormShell_BASE::disposing();

	if ( m_pShell && !m_pShell->IsDesignMode() )
		setActiveController( NULL, sal_True );
		// do NOT save the content of the old form (the second parameter tells this)
		// if we're here, then we expect that PrepareClose has been called, and thus the user
		// got a chance to commit or reject any changes. So in case we're here and there
		// are still uncommitted changes, the user explicitly wanted this.
		// 2002-11-11 - 104702 - fs@openoffice.org

    m_pTextShell->dispose();

	m_xAttachedFrame = NULL;

	CloseExternalFormViewer();

	while ( m_aLoadingPages.size() )
	{
		Application::RemoveUserEvent( m_aLoadingPages.front().nEventId );
		m_aLoadingPages.pop();
	}

	{
		::osl::MutexGuard aGuard(m_aInvalidationSafety);
		if (m_nInvalidationEvent)
		{
			Application::RemoveUserEvent(m_nInvalidationEvent);
			m_nInvalidationEvent = 0;
		}
        if ( m_nActivationEvent )
        {
            Application::RemoveUserEvent( m_nActivationEvent );
            m_nActivationEvent = 0;
        }
	}

	{
		::osl::ClearableMutexGuard aGuard(m_aAsyncSafety);
		aGuard.clear();

		DBG_ASSERT(!m_nInvalidationEvent, "FmXFormShell::~FmXFormShell : still have an invalidation event !");
			// should habe been deleted while beeing disposed

		m_aMarkTimer.Stop();
	}

    DisableNotification();

    RemoveElement( m_xForms );
	m_xForms.clear();

    impl_switchActiveControllerListening( false );
	m_xActiveController 		= NULL;
	m_xActiveForm				= NULL;

    m_pShell					= NULL;
	m_xNavigationController 	= NULL;
	m_xCurrentForm              = NULL;
	m_xLastGridFound			= NULL;
	m_xAttachedFrame			= NULL;
	m_xExternalViewController	= NULL;
	m_xExtViewTriggerController = NULL;
	m_xExternalDisplayedForm	= NULL;
	m_xLastGridFound			= NULL;

    InterfaceBag aEmpty;
    m_aCurrentSelection.swap( aEmpty );

    m_aActiveControllerFeatures.dispose();
    m_aNavControllerFeatures.dispose();
}

//------------------------------------------------------------------------------
void FmXFormShell::UpdateSlot( sal_Int16 _nId )
{
    if ( impl_checkDisposed() )
        return;

    ::osl::MutexGuard aGuard(m_aInvalidationSafety);

    if ( m_nLockSlotInvalidation )
    {
        OSL_ENSURE( sal_False, "FmXFormShell::UpdateSlot: cannot update if invalidation is currently locked!" );
        InvalidateSlot( _nId, sal_False );
    }
    else
    {
        OSL_ENSURE( _nId, "FmXFormShell::UpdateSlot: can't update the complete shell!" );
		m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate( _nId, sal_True, sal_True );
		m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Update( _nId );
    }
}

//------------------------------------------------------------------------------
void FmXFormShell::InvalidateSlot( sal_Int16 nId, sal_Bool bWithId )
{
    if ( impl_checkDisposed() )
        return;

	::osl::MutexGuard aGuard(m_aInvalidationSafety);
	if (m_nLockSlotInvalidation)
	{
		m_arrInvalidSlots.Insert(nId, m_arrInvalidSlots.Count());
		sal_uInt8 nFlags = ( bWithId ? 0x01 : 0 );
		m_arrInvalidSlots_Flags.push_back(nFlags);
	}
	else
		if (nId)
			m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(nId, sal_True, bWithId);
		else
			m_pShell->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell);
}

//------------------------------------------------------------------------------
void FmXFormShell::LockSlotInvalidation(sal_Bool bLock)
{
    if ( impl_checkDisposed() )
        return;

	::osl::MutexGuard aGuard(m_aInvalidationSafety);
	DBG_ASSERT(bLock || m_nLockSlotInvalidation>0, "FmXFormShell::LockSlotInvalidation : invalid call !");

	if (bLock)
		++m_nLockSlotInvalidation;
	else if (!--m_nLockSlotInvalidation)
	{
		// alles, was sich waehrend der gelockten Phase angesammelt hat, (asynchron) invalidieren
		if (!m_nInvalidationEvent)
			m_nInvalidationEvent = Application::PostUserEvent(LINK(this, FmXFormShell, OnInvalidateSlots));
	}
}

//------------------------------------------------------------------------------
IMPL_LINK(FmXFormShell, OnInvalidateSlots, void*, EMPTYARG)
{
    if ( impl_checkDisposed() )
        return 0L;

    ::osl::MutexGuard aGuard(m_aInvalidationSafety);
	m_nInvalidationEvent = 0;

	DBG_ASSERT(m_arrInvalidSlots.Count() == m_arrInvalidSlots_Flags.size(),
		"FmXFormShell::OnInvalidateSlots : inconsistent slot arrays !");
	sal_uInt8 nFlags;
	for (sal_Int16 i=0; i<m_arrInvalidSlots.Count(); ++i)
	{
		nFlags = m_arrInvalidSlots_Flags[i];

		if (m_arrInvalidSlots[i])
			m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(m_arrInvalidSlots[i], sal_True, (nFlags & 0x01));
		else
			m_pShell->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell);
	}

	m_arrInvalidSlots.Remove(0, m_arrInvalidSlots.Count());
	m_arrInvalidSlots_Flags.clear();
	return 0L;
}

//------------------------------------------------------------------------------
void FmXFormShell::ForceUpdateSelection(sal_Bool bAllowInvalidation)
{
    if ( impl_checkDisposed() )
        return;

    if (IsSelectionUpdatePending())
	{
		m_aMarkTimer.Stop();

		// die Invalidierung der Slots, die implizit von SetSelection besorgt wird, eventuell abschalten
		if (!bAllowInvalidation)
			LockSlotInvalidation(sal_True);

		SetSelection(m_pShell->GetFormView()->GetMarkedObjectList());

		if (!bAllowInvalidation)
			LockSlotInvalidation(sal_False);
	}
}

//------------------------------------------------------------------------------
PopupMenu* FmXFormShell::GetConversionMenu()
{
	const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
	sal_Bool bIsHiContrastMode	= rSettings.GetHighContrastMode();

	PopupMenu* pNewMenu = new PopupMenu(SVX_RES( RID_FMSHELL_CONVERSIONMENU ));

	ImageList aImageList( SVX_RES( bIsHiContrastMode ? RID_SVXIMGLIST_FMEXPL_HC : RID_SVXIMGLIST_FMEXPL) );
	for ( size_t i = 0; i < sizeof( nConvertSlots ) / sizeof( nConvertSlots[0] ); ++i )
	{
		// das entsprechende Image dran
		pNewMenu->SetItemImage(nConvertSlots[i], aImageList.GetImage(nCreateSlots[i]));
	}

	return pNewMenu;
}

//------------------------------------------------------------------------------
bool FmXFormShell::isControlConversionSlot( sal_uInt16 nSlotId )
{
	for ( size_t i = 0; i < sizeof( nConvertSlots ) / sizeof( nConvertSlots[0] ); ++i )
		if (nConvertSlots[i] == nSlotId)
			return true;
	return false;
}

//------------------------------------------------------------------------------
bool FmXFormShell::executeControlConversionSlot( sal_uInt16 _nSlotId )
{
    OSL_PRECOND( canConvertCurrentSelectionToControl( _nSlotId ), "FmXFormShell::executeControlConversionSlot: illegal call!" );
    InterfaceBag::const_iterator aSelectedElement = m_aCurrentSelection.begin();
    if ( aSelectedElement == m_aCurrentSelection.end() )
        return false;

    return executeControlConversionSlot( Reference< XFormComponent >( *aSelectedElement, UNO_QUERY ), _nSlotId );
}

//------------------------------------------------------------------------------
bool FmXFormShell::executeControlConversionSlot( const Reference< XFormComponent >& _rxObject, sal_uInt16 _nSlotId )
{
    if ( impl_checkDisposed() )
        return false;

    OSL_ENSURE( _rxObject.is(), "FmXFormShell::executeControlConversionSlot: invalid object!" );
    if ( !_rxObject.is() )
        return false;

    SdrPage* pPage = m_pShell->GetCurPage();
    FmFormPage* pFormPage = pPage ? dynamic_cast< FmFormPage* >( pPage ) : NULL;
    OSL_ENSURE( pFormPage, "FmXFormShell::executeControlConversionSlot: no current (form) page!" );
    if ( !pFormPage )
        return false;

    OSL_ENSURE( isSolelySelected( _rxObject ),
        "FmXFormShell::executeControlConversionSlot: hmm ... shouldn't this parameter be redundant?" );

	for ( size_t lookupSlot = 0; lookupSlot < sizeof( nConvertSlots ) / sizeof( nConvertSlots[0] ); ++lookupSlot )
	{
		if (nConvertSlots[lookupSlot] == _nSlotId)
        {
            Reference< XInterface > xNormalizedObject( _rxObject, UNO_QUERY );

            FmFormObj* pFormObject = NULL;
            SdrObjListIter aPageIter( *pFormPage );
            while ( aPageIter.IsMore() )
            {
                SdrObject* pCurrent = aPageIter.Next();
                pFormObject = FmFormObj::GetFormObject( pCurrent );
                if ( !pFormObject )
                    continue;

                Reference< XInterface > xCurrentNormalized( pFormObject->GetUnoControlModel(), UNO_QUERY );
                if ( xCurrentNormalized.get() == xNormalizedObject.get() )
                    break;

                pFormObject = NULL;
            }

            if ( !pFormObject )
                return false;

            ::rtl::OUString sNewName( getServiceNameByControlType( nObjectTypes[ lookupSlot ] ) );
	        Reference< XControlModel> xNewModel( ::comphelper::getProcessServiceFactory()->createInstance( sNewName ), UNO_QUERY );
	        if (!xNewModel.is())
		        return false;

	        Reference< XControlModel> xOldModel( pFormObject->GetUnoControlModel() );
	        Reference< XServiceInfo> xModelInfo(xOldModel, UNO_QUERY);

	        // Properties uebertragen
	        Reference< XPropertySet> xOldSet(xOldModel, UNO_QUERY);
	        Reference< XPropertySet> xNewSet(xNewModel, UNO_QUERY);


	        Locale aNewLanguage = Application::GetSettings().GetUILocale();
	        TransferFormComponentProperties(xOldSet, xNewSet, aNewLanguage);

	        Sequence< ::com::sun::star::script::ScriptEventDescriptor> aOldScripts;
	        Reference< XChild> xChild(xOldModel, UNO_QUERY);
	        if (xChild.is())
	        {
		        Reference< XIndexAccess> xParent(xChild->getParent(), UNO_QUERY);

		        // remember old script events
		        Reference< ::com::sun::star::script::XEventAttacherManager> xEvManager(xChild->getParent(), UNO_QUERY);
		        if (xParent.is() && xEvManager.is())
		        {
			        sal_Int32 nIndex = getElementPos(xParent, xOldModel);
			        if (nIndex>=0 && nIndex<xParent->getCount())
				        aOldScripts = xEvManager->getScriptEvents(nIndex);
		        }

		        // replace the mdoel within the parent container
		        Reference< XIndexContainer> xIndexParent(xChild->getParent(), UNO_QUERY);   //Modified by BerryJia for fixing Bug102516 Time(China):2002-9-5 16:00
		        if (xIndexParent.is())
		        {
			        // the form container works with FormComponents
			        Reference< XFormComponent> xComponent(xNewModel, UNO_QUERY);
			        DBG_ASSERT(xComponent.is(), "FmXFormShell::executeControlConversionSlot: the new model is no form component !");
			        Any aNewModel(makeAny(xComponent));
			        try
			        {
				        //Modified by BerryJia for fixing Bug102516 Time(China):2002-9-5 16:00
				        sal_Int32 nIndex = getElementPos(xParent, xOldModel);
				        if (nIndex>=0 && nIndex<xParent->getCount())
					        xIndexParent->replaceByIndex(nIndex, aNewModel);
				        else
				        {
					        DBG_ERROR("FmXFormShell::executeControlConversionSlot: could not replace the model !");
					        Reference< ::com::sun::star::lang::XComponent> xNewComponent(xNewModel, UNO_QUERY);
					        if (xNewComponent.is())
						        xNewComponent->dispose();
					        return false;
				        }
			        }
			        catch(Exception&)
			        {
				        DBG_ERROR("FmXFormShell::executeControlConversionSlot: could not replace the model !");
				        Reference< ::com::sun::star::lang::XComponent> xNewComponent(xNewModel, UNO_QUERY);
				        if (xNewComponent.is())
					        xNewComponent->dispose();
				        return false;
			        }

		        }
	        }

	        // special handling for the LabelControl-property : can only be set when the model is placed
	        // within the forms hierarchy
	        if (::comphelper::hasProperty(FM_PROP_CONTROLLABEL, xOldSet) && ::comphelper::hasProperty(FM_PROP_CONTROLLABEL, xNewSet))
	        {
		        try
		        {
			        xNewSet->setPropertyValue(FM_PROP_CONTROLLABEL, xOldSet->getPropertyValue(FM_PROP_CONTROLLABEL));
		        }
		        catch(Exception&)
		        {
		        }

	        }

	        // neues Model setzen
	        pFormObject->SetChanged();
	        pFormObject->SetUnoControlModel(xNewModel);

	        // transfer script events
	        // (do this _after_ SetUnoControlModel as we need the new (implicitly created) control)
	        if (aOldScripts.getLength())
	        {
		        // das Control zum Model suchen
                Reference< XControlContainer > xControlContainer( getControlContainerForView() );

		        Sequence< Reference< XControl> > aControls( xControlContainer->getControls() );
		        const Reference< XControl>* pControls = aControls.getConstArray();

		        sal_uInt32 nLen = aControls.getLength();
		        Reference< XControl> xControl;
		        for (sal_uInt32 i=0 ; i<nLen; ++i)
		        {
			        if (pControls[i]->getModel() == xNewModel)
			        {
				        xControl = pControls[i];
				        break;
			        }
		        }
		        TransferEventScripts(xNewModel, xControl, aOldScripts);
	        }

            // transfer value bindings, if possible
            {
	            Reference< XBindableValue > xOldBindable( xOldModel, UNO_QUERY );
	            Reference< XBindableValue > xNewBindable( xNewModel, UNO_QUERY );
                if ( xOldBindable.is() )
                {
                    try
                    {
                        if ( xNewBindable.is() )
                            xNewBindable->setValueBinding( xOldBindable->getValueBinding() );
                        xOldBindable->setValueBinding( NULL );
                    }
		            catch(const Exception&)
                    {
                        DBG_UNHANDLED_EXCEPTION();
                    }
                }
            }
            // same for list entry sources
            {
                Reference< XListEntrySink > xOldSink( xOldModel, UNO_QUERY );
                Reference< XListEntrySink > xNewSink( xNewModel, UNO_QUERY );
                if ( xOldSink.is() )
                {
                    try
                    {
                        if ( xNewSink.is() )
                            xNewSink->setListEntrySource( xOldSink->getListEntrySource() );
                        xOldSink->setListEntrySource( NULL );
                    }
		            catch(const Exception&)
		            {
                        DBG_UNHANDLED_EXCEPTION();
		            }
                }
            }

            // create an undo action
	        FmFormModel* pModel = m_pShell->GetFormModel();
	        DBG_ASSERT(pModel != NULL, "FmXFormShell::executeControlConversionSlot: my shell has no model !");
	        if (pModel && pModel->IsUndoEnabled() )
			{
		        pModel->AddUndo(new FmUndoModelReplaceAction(*pModel, pFormObject, xOldModel));
			}
			else
			{
				FmUndoModelReplaceAction::DisposeElement( xOldModel );
			}

	        return true;
        }
	}
	return false;
}

//------------------------------------------------------------------------------
bool FmXFormShell::canConvertCurrentSelectionToControl( sal_Int16 nConversionSlot )
{
    if ( m_aCurrentSelection.empty() )
        return false;

    InterfaceBag::const_iterator aCheck = m_aCurrentSelection.begin();
    Reference< XServiceInfo > xElementInfo( *aCheck, UNO_QUERY );
    if ( !xElementInfo.is() )
        // no service info -> cannot determine this
        return false;

    if (  ++aCheck != m_aCurrentSelection.end() )
        // more than one element
        return false;

    if ( Reference< XForm >::query( xElementInfo ).is() )
        // it's a form
        return false;

	sal_Int16 nObjectType = getControlTypeByObject( xElementInfo );

	if (  ( OBJ_FM_HIDDEN == nObjectType )
       || ( OBJ_FM_CONTROL == nObjectType )
       || ( OBJ_FM_GRID == nObjectType )
       )
        return false;   // those types cannot be converted

	DBG_ASSERT(sizeof(nConvertSlots)/sizeof(nConvertSlots[0]) == sizeof(nObjectTypes)/sizeof(nObjectTypes[0]),
		"FmXFormShell::canConvertCurrentSelectionToControl: nConvertSlots & nObjectTypes must have the same size !");

	for ( size_t i = 0; i < sizeof( nConvertSlots ) / sizeof( nConvertSlots[0] ); ++i )
		if (nConvertSlots[i] == nConversionSlot)
			return nObjectTypes[i] != nObjectType;

	return sal_True;	// all other slots: assume "yes"
}

//------------------------------------------------------------------------------
void FmXFormShell::checkControlConversionSlotsForCurrentSelection( Menu& rMenu )
{
	for (sal_Int16 i=0; i<rMenu.GetItemCount(); ++i)
		// der Context ist schon von einem Typ, der dem Eitnrag entspricht -> disable
		rMenu.EnableItem( rMenu.GetItemId(i), canConvertCurrentSelectionToControl( rMenu.GetItemId( i ) ) );
}

//------------------------------------------------------------------------------
void FmXFormShell::LoopGrids(sal_Int16 nWhat)
{
    if ( impl_checkDisposed() )
        return;

	Reference< XIndexContainer> xControlModels(m_xActiveForm, UNO_QUERY);
	if (xControlModels.is())
    {
		for (sal_Int16 i=0; i<xControlModels->getCount(); ++i)
		{
			Reference< XPropertySet> xModelSet;
			xControlModels->getByIndex(i) >>= xModelSet;
			if (!xModelSet.is())
				continue;

			if (!::comphelper::hasProperty(FM_PROP_CLASSID, xModelSet))
				continue;
			sal_Int16 nClassId = ::comphelper::getINT16(xModelSet->getPropertyValue(FM_PROP_CLASSID));
			if (FormComponentType::GRIDCONTROL != nClassId)
				continue;

			if (!::comphelper::hasProperty(FM_PROP_CURSORCOLOR, xModelSet) || !::comphelper::hasProperty(FM_PROP_ALWAYSSHOWCURSOR, xModelSet) || !::comphelper::hasProperty(FM_PROP_DISPLAYSYNCHRON, xModelSet))
				continue;

			switch (nWhat & GA_SYNC_MASK)
			{
				case GA_DISABLE_SYNC:
					{
						sal_Bool bB(sal_False);
						xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, Any(&bB,getBooleanCppuType()));
					}
					break;
				case GA_FORCE_SYNC:
				{
					Any aOldVal( xModelSet->getPropertyValue(FM_PROP_DISPLAYSYNCHRON) );
					sal_Bool bB(sal_True);
					xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, Any(&bB,getBooleanCppuType()));
					xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, aOldVal);
				}
				break;
				case GA_ENABLE_SYNC:
					{
						sal_Bool bB(sal_True);
						xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, Any(&bB,getBooleanCppuType()));
					}
					break;
			}

			if (nWhat & GA_DISABLE_ROCTRLR)
			{
				sal_Bool bB(sal_False);
				xModelSet->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR, Any(&bB,getBooleanCppuType()));
				Reference< XPropertyState> xModelPropState(xModelSet, UNO_QUERY);
				if (xModelPropState.is())
					xModelPropState->setPropertyToDefault(FM_PROP_CURSORCOLOR);
				else
					xModelSet->setPropertyValue(FM_PROP_CURSORCOLOR, Any());		// this should be the default
			}
			else if (nWhat & GA_ENABLE_ROCTRLR)
			{
				sal_Bool bB(sal_True);
				xModelSet->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR, Any(&bB,getBooleanCppuType()));
				xModelSet->setPropertyValue(FM_PROP_CURSORCOLOR, makeAny(sal_Int32(COL_LIGHTRED)));
			}
		}
    }
}

//------------------------------------------------------------------------------
Reference< XControlContainer > FmXFormShell::getControlContainerForView()
{
    if ( impl_checkDisposed() )
        return NULL;

    SdrPageView* pPageView = NULL;
    if ( m_pShell && m_pShell->GetFormView() )
	    pPageView = m_pShell->GetFormView()->GetSdrPageView();

    Reference< XControlContainer> xControlContainer;
    if ( pPageView )
	    xControlContainer = pPageView->GetPageWindow(0)->GetControlContainer();

    return xControlContainer;
}

//------------------------------------------------------------------------------
void FmXFormShell::ExecuteTabOrderDialog( const Reference< XTabControllerModel >& _rxForForm )
{
    if ( impl_checkDisposed() )
        return;

    OSL_PRECOND( _rxForForm.is(), "FmXFormShell::ExecuteTabOrderDialog: invalid tabbing model!" );
    if ( !_rxForForm.is() )
        return;

    try
    {
        Sequence< Any > aDialogArgs( 3 );
        aDialogArgs[0] <<= NamedValue(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TabbingModel" ) ),
            makeAny( _rxForForm )
        );
        aDialogArgs[1] <<= NamedValue(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlContext" ) ),
            makeAny( getControlContainerForView() )
        );

        Reference< XWindow > xParentWindow;
        if ( m_pShell->GetViewShell() && m_pShell->GetViewShell()->GetViewFrame() )
            xParentWindow = VCLUnoHelper::GetInterface ( &m_pShell->GetViewShell()->GetViewFrame()->GetWindow() );
        aDialogArgs[2] <<= NamedValue(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ),
            makeAny( xParentWindow )
        );

        Reference< dialogs::XExecutableDialog > xDialog(
            ::comphelper::getProcessServiceFactory()->createInstanceWithArguments(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.ui.TabOrderDialog" ) ),
                aDialogArgs
            ),
            UNO_QUERY
        );
        OSL_ENSURE( xDialog.is(), "FmXFormShell::ExecuteTabOrderDialog: could not create the dialog!" );

        if ( xDialog.is() )
            xDialog->execute();
    }
    catch( const Exception& )
    {
    	OSL_ENSURE( sal_False, "FmXFormShell::ExecuteTabOrderDialog: caught an exception!" );
    }
}

//------------------------------------------------------------------------------
void FmXFormShell::ExecuteSearch()
{
    if ( impl_checkDisposed() )
        return;

	// eine Sammlung aller (logischen) Formulare
    FmFormArray aEmpty;
    m_aSearchForms.swap( aEmpty );
    ::std::vector< String > aContextNames;
    impl_collectFormSearchContexts_nothrow( m_pShell->GetCurPage()->GetForms(), ::rtl::OUString(), m_aSearchForms, aContextNames );
    OSL_POSTCOND( m_aSearchForms.size() == aContextNames.size(),
        "FmXFormShell::ExecuteSearch: nonsense!" );
    if ( m_aSearchForms.size() != aContextNames.size() )
        return;

	// filter out the forms which do not contain valid controls at all
    {
        FmFormArray aValidForms;
        ::std::vector< String > aValidContexts;
	    FmFormArray::const_iterator form = m_aSearchForms.begin();
        ::std::vector< String >::const_iterator contextName = aContextNames.begin();
        for ( ; form != m_aSearchForms.end(); ++form, ++contextName )
        {
		    FmSearchContext aTestContext;
		    aTestContext.nContext = static_cast< sal_Int16 >( form - m_aSearchForms.begin() );
		    sal_uInt32 nValidControls = OnSearchContextRequest( &aTestContext );
		    if ( nValidControls > 0 )
		    {
                aValidForms.push_back( *form );
                aValidContexts.push_back( *contextName );
		    }
        }

        m_aSearchForms.swap( aValidForms );
        aContextNames.swap( aValidContexts );
    }

	if (m_aSearchForms.empty() )
	{	// es gibt keine Controls, die alle Bedingungen fuer eine Suche erfuellen
		ErrorBox(NULL, WB_OK, SVX_RESSTR(RID_STR_NODATACONTROLS)).Execute();
		return;
	}

	// jetzt brauche ich noch einen 'initial context'
	sal_Int16 nInitialContext = 0;
	Reference< XForm> xActiveForm( getActiveForm());
	for ( size_t i=0; i<m_aSearchForms.size(); ++i )
	{
		if (m_aSearchForms.at(i) == xActiveForm)
		{
			nInitialContext = (sal_Int16)i;
			break;
		}
	}

	// wenn der Dialog initial den Text des aktiven Controls anbieten soll, muss dieses ein XTextComponent-Interface habe,
	// ausserdem macht das nur Sinn, wenn das aktuelle Feld auch an ein Tabellen- (oder was-auch-immer-)Feld gebunden ist
	UniString strActiveField;
	UniString strInitialText;
	// ... das bekomme ich von meinem FormController
	DBG_ASSERT(m_xActiveController.is(), "FmXFormShell::ExecuteSearch : no active controller !");
	Reference< XControl> xActiveControl( m_xActiveController->getCurrentControl());
	if (xActiveControl.is())
	{
		// das Control kann mir sein Model sagen ...
		Reference< XControlModel> xActiveModel( xActiveControl->getModel());
		DBG_ASSERT(xActiveModel.is(), "FmXFormShell::ExecuteSearch : active control has no model !");

		// das Model frage ich nach der ControlSource-Eigenschaft ...
		Reference< XPropertySet> xProperties(xActiveControl->getModel(), UNO_QUERY);
		if (::comphelper::hasProperty(FM_PROP_CONTROLSOURCE, xProperties) && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xProperties))
		{
			Reference< XPropertySet> xField;
			xProperties->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
			if (xField.is())	// (nur wenn das Ding wirklich gebunden ist)
			{
				// und das Control selber nach einem TextComponent-Interface (damit ich mir dort den Text abholen kann)
				Reference< XTextComponent> xText(xActiveControl, UNO_QUERY);
				if (xText.is())
				{
					strActiveField = getLabelName(xProperties).getStr();
					strInitialText = xText->getText().getStr();
				}
			}
		}
		else
		{
			// das Control selber hat keine ControlSource, aber vielleicht ist es ein GridControl
			Reference< XGrid> xGrid(xActiveControl, UNO_QUERY);
			if (xGrid.is())
			{
				// fuer strActiveField brauche ich die die ControlSource der Column, dafuer den Columns-Container, dafuer die
				// GridPeer
				Reference< XGridPeer> xGridPeer(xActiveControl->getPeer(), UNO_QUERY);
				Reference< XIndexAccess> xColumns;
				if (xGridPeer.is())
					xColumns = Reference< XIndexAccess>(xGridPeer->getColumns(),UNO_QUERY);

				sal_Int16 nViewCol = xGrid->getCurrentColumnPosition();
				sal_Int16 nModelCol = GridView2ModelPos(xColumns, nViewCol);
				Reference< XPropertySet> xCurrentCol;
				if(xColumns.is())
					xColumns->getByIndex(nModelCol) >>= xCurrentCol;
				if (xCurrentCol.is())
					strActiveField = ::comphelper::getString(xCurrentCol->getPropertyValue(FM_PROP_LABEL)).getStr();

				// the text fo the current column
				Reference< XIndexAccess> xColControls(xGridPeer, UNO_QUERY);
				Reference< XInterface> xCurControl;
				xColControls->getByIndex(nViewCol) >>= xCurControl;
				::rtl::OUString sInitialText;
				if (IsSearchableControl(xCurControl, &sInitialText))
					strInitialText = sInitialText.getStr();
			}
		}
	}

	// um eventuelle GridControls, die ich kenne, kuemmern
	LoopGrids(GA_DISABLE_SYNC /*| GA_ENABLE_ROCTRLR*/);

	// jetzt bin ich reif fuer den Dialog
	// wenn die potentiellen Deadlocks, die durch die Benutzung des Solar-Mutex in MTs VCLX...-Klasen entstehen, irgendwann mal
	// ausgeraeumt sind, sollte hier ein SM_USETHREAD rein, denn die Suche in einem eigenen Thread ist doch etwas fluessiger
	// sollte allerdings irgendwie von dem unterliegenden Cursor abhaengig gemacht werden, DAO zum Beispiel ist nicht thread-sicher
	SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
    AbstractFmSearchDialog* pDialog = NULL;
    if ( pFact )
	    pDialog = pFact->CreateFmSearchDialog( &m_pShell->GetViewShell()->GetViewFrame()->GetWindow(), strInitialText, aContextNames, nInitialContext, LINK( this, FmXFormShell, OnSearchContextRequest ) );
    DBG_ASSERT( pDialog, "FmXFormShell::ExecuteSearch: could not create the search dialog!" );
    if ( pDialog )
    {
	    pDialog->SetActiveField( strActiveField );
	    pDialog->SetFoundHandler( LINK( this, FmXFormShell, OnFoundData ) );
	    pDialog->SetCanceledNotFoundHdl( LINK( this, FmXFormShell, OnCanceledNotFound ) );
	    pDialog->Execute();
	    delete pDialog;
    }

	// GridControls wieder restaurieren
	LoopGrids(GA_ENABLE_SYNC | GA_DISABLE_ROCTRLR);

	m_pShell->GetFormView()->UnMarkAll(m_pShell->GetFormView()->GetSdrPageView());
		// da ich in OnFoundData (fals ich dort war) Controls markiert habe
}

//------------------------------------------------------------------------------
sal_Bool FmXFormShell::GetY2KState(sal_uInt16& n)
{
    if ( impl_checkDisposed() )
        return sal_False;

	if (m_pShell->IsDesignMode())
		// im Design-Modus (ohne aktive Controls) soll sich das Haupt-Dokument darum kuemmern
		return sal_False;

	Reference< XForm> xForm( getActiveForm());
	if (!xForm.is())
		// kein aktuelles Formular (also insbesondere kein aktuelles Control) -> das Haupt-Dokument soll sich kuemmern
		return sal_False;

	Reference< XRowSet> xDB(xForm, UNO_QUERY);
	DBG_ASSERT(xDB.is(), "FmXFormShell::GetY2KState : current form has no dbform-interface !");

	Reference< XNumberFormatsSupplier> xSupplier( getNumberFormats(OStaticDataAccessTools().getRowSetConnection(xDB), sal_False));
	if (xSupplier.is())
	{
		Reference< XPropertySet> xSet(xSupplier->getNumberFormatSettings());
		if (xSet.is())
		{
			try
			{
				Any aVal( xSet->getPropertyValue(::rtl::OUString::createFromAscii("TwoDigitDateStart")) );
				aVal >>= n;
				return sal_True;
			}
			catch(Exception&)
			{
			}

		}
	}
	return sal_False;
}

//------------------------------------------------------------------------------
void FmXFormShell::SetY2KState(sal_uInt16 n)
{
    if ( impl_checkDisposed() )
        return;

	Reference< XForm > xActiveForm( getActiveForm());
	Reference< XRowSet > xActiveRowSet( xActiveForm, UNO_QUERY );
	if ( xActiveRowSet.is() )
	{
		Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( getRowSetConnection( xActiveRowSet ), sal_False ) );
		if (xSupplier.is())
		{
			Reference< XPropertySet> xSet(xSupplier->getNumberFormatSettings());
			if (xSet.is())
			{
				try
				{
					Any aVal;
					aVal <<= n;
					xSet->setPropertyValue(::rtl::OUString::createFromAscii("TwoDigitDateStart"), aVal);
				}
				catch(Exception&)
				{
					DBG_ERROR("FmXFormShell::SetY2KState: Exception occured!");
				}

			}
			return;
		}
	}

	// kein aktives Formular gefunden -> alle aktuell vorhandenen Formulare durchiterieren
	Reference< XIndexAccess> xCurrentForms( m_xForms);
	if (!xCurrentForms.is())
	{	// im alive-Modus sind meine Forms nicht gesetzt, wohl aber die an der Page
		if (m_pShell->GetCurPage())
			xCurrentForms = Reference< XIndexAccess>( m_pShell->GetCurPage()->GetForms( false ), UNO_QUERY );
	}
	if (!xCurrentForms.is())
		return;

	::comphelper::IndexAccessIterator aIter(xCurrentForms);
	Reference< XInterface> xCurrentElement( aIter.Next());
	while (xCurrentElement.is())
	{
		// ist das aktuelle Element eine DatabaseForm ?
		Reference< XRowSet> xElementAsRowSet( xCurrentElement, UNO_QUERY );
		if ( xElementAsRowSet.is() )
		{
			Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( getRowSetConnection( xElementAsRowSet ), sal_False ) );
			if (!xSupplier.is())
				continue;

			Reference< XPropertySet> xSet(xSupplier->getNumberFormatSettings());
			if (xSet.is())
			{
				try
				{
					Any aVal;
					aVal <<= n;
					xSet->setPropertyValue(::rtl::OUString::createFromAscii("TwoDigitDateStart"), aVal);
				}
				catch(Exception&)
				{
					DBG_ERROR("FmXFormShell::SetY2KState: Exception occured!");
				}

			}
		}
		xCurrentElement = aIter.Next();
	}
}

//------------------------------------------------------------------------------
void FmXFormShell::CloseExternalFormViewer()
{
    if ( impl_checkDisposed() )
        return;

	if (!m_xExternalViewController.is())
		return;

	Reference< ::com::sun::star::frame::XFrame> xExternalViewFrame( m_xExternalViewController->getFrame());
	Reference< ::com::sun::star::frame::XDispatchProvider> xCommLink(xExternalViewFrame, UNO_QUERY);
	if (!xCommLink.is())
		return;

	xExternalViewFrame->setComponent(NULL,NULL);
	::comphelper::disposeComponent(xExternalViewFrame);
	m_xExternalViewController	= NULL;
	m_xExtViewTriggerController = NULL;
	m_xExternalDisplayedForm	= NULL;
}

//------------------------------------------------------------------------------
Reference< XResultSet> FmXFormShell::getInternalForm(const Reference< XResultSet>& _xForm) const
{
    if ( impl_checkDisposed() )
        return NULL;

	Reference< runtime::XFormController> xExternalCtrlr(m_xExternalViewController, UNO_QUERY);
	if (xExternalCtrlr.is() && (_xForm == xExternalCtrlr->getModel()))
	{
		DBG_ASSERT(m_xExternalDisplayedForm.is(), "FmXFormShell::getInternalForm : invalid external form !");
		return m_xExternalDisplayedForm;
	}
	return _xForm;
}

//------------------------------------------------------------------------------
Reference< XForm> FmXFormShell::getInternalForm(const Reference< XForm>& _xForm) const
{
    if ( impl_checkDisposed() )
        return NULL;

	Reference< runtime::XFormController > xExternalCtrlr(m_xExternalViewController, UNO_QUERY);
	if (xExternalCtrlr.is() && (_xForm == xExternalCtrlr->getModel()))
	{
		DBG_ASSERT(m_xExternalDisplayedForm.is(), "FmXFormShell::getInternalForm : invalid external form !");
		return Reference< XForm>(m_xExternalDisplayedForm, UNO_QUERY);
	}
	return _xForm;
}

//------------------------------------------------------------------------
namespace
{
    static bool lcl_isNavigationRelevant( sal_Int32 _nWhich )
    {
	    return  ( _nWhich == SID_FM_RECORD_FIRST )
	        ||  ( _nWhich == SID_FM_RECORD_PREV )
            ||  ( _nWhich == SID_FM_RECORD_NEXT ) 
	        ||  ( _nWhich == SID_FM_RECORD_LAST )
	        ||  ( _nWhich == SID_FM_RECORD_NEW );
    }
}

//------------------------------------------------------------------------------
bool FmXFormShell::IsFormSlotEnabled( sal_Int32 _nSlot, FeatureState* _pCompleteState )
{
    const ::svx::ControllerFeatures& rController =
            lcl_isNavigationRelevant( _nSlot )
        ?   getNavControllerFeatures()
        :   getActiveControllerFeatures();

    if ( !_pCompleteState )
        return rController->isEnabled( _nSlot );

    rController->getState( _nSlot, *_pCompleteState );
    return _pCompleteState->Enabled;
}

//------------------------------------------------------------------------------
void FmXFormShell::ExecuteFormSlot( sal_Int32 _nSlot )
{
    const ::svx::ControllerFeatures& rController =
            lcl_isNavigationRelevant( _nSlot )
        ?   getNavControllerFeatures()
        :   getActiveControllerFeatures();

    rController->execute( _nSlot );

    if ( _nSlot == SID_FM_RECORD_UNDO )
    {
        // if we're doing an UNDO, *and* if the affected form is the form which we also display
        // as external view, then we need to reset the controls of the external form, too
		if ( getInternalForm( getActiveForm() ) == m_xExternalDisplayedForm )
        {
	        Reference< XIndexAccess > xContainer( m_xExternalDisplayedForm, UNO_QUERY );
		    if ( xContainer.is() )
		    {
			    Reference< XReset > xReset;
			    for ( sal_Int32 i = 0; i < xContainer->getCount(); ++i )
			    {
				    if ( ( xContainer->getByIndex( i ) >>= xReset ) && xReset.is() )
				    {
                        // no resets on sub forms
					    Reference< XForm > xAsForm( xReset, UNO_QUERY );
					    if ( !xAsForm.is() )
						    xReset->reset();
				    }
			    }
		    }
		}
	}
}

//------------------------------------------------------------------------------
void FmXFormShell::impl_switchActiveControllerListening( const bool _bListen )
{
    Reference< XComponent> xComp( m_xActiveController, UNO_QUERY );
    if ( !xComp.is() )
        return;

    if ( _bListen )
        xComp->addEventListener( (XFormControllerListener*)this );
    else
        xComp->removeEventListener( (XFormControllerListener*)this );
}

//------------------------------------------------------------------------------
void FmXFormShell::setActiveController( const Reference< runtime::XFormController >& xController, sal_Bool _bNoSaveOldContent )
{
    if ( impl_checkDisposed() )
        return;

	if (m_bChangingDesignMode)
		return;
	DBG_ASSERT(!m_pShell->IsDesignMode(), "nur im alive mode verwenden");

	// Ist die Routine ein zweites Mal gerufen worden,
	// dann sollte der Focus nicht mehr umgesetzt werden
	if (m_bInActivate)
	{
		m_bSetFocus = xController != m_xActiveController;
		return;
	}

	if (xController != m_xActiveController)
	{
		::osl::ClearableMutexGuard aGuard(m_aAsyncSafety);
		// switch all nav dispatchers belonging to the form of the current nav controller to 'non active'
		Reference< XResultSet> xNavigationForm;
		if (m_xNavigationController.is())
			xNavigationForm = Reference< XResultSet>(m_xNavigationController->getModel(), UNO_QUERY);
		aGuard.clear();

		m_bInActivate = sal_True;

		// check if the 2 controllers serve different forms
		Reference< XResultSet> xOldForm;
		if (m_xActiveController.is())
			xOldForm = Reference< XResultSet>(m_xActiveController->getModel(), UNO_QUERY);
		Reference< XResultSet> xNewForm;
		if (xController.is())
			xNewForm = Reference< XResultSet>(xController->getModel(), UNO_QUERY);
		xOldForm = getInternalForm(xOldForm);
		xNewForm = getInternalForm(xNewForm);

		sal_Bool bDifferentForm = ( xOldForm.get() != xNewForm.get() );
		sal_Bool bNeedSave = bDifferentForm && !_bNoSaveOldContent;
			// we save the content of the old form if we move to a new form, and saving old content is allowed

		if ( m_xActiveController.is() && bNeedSave )
		{
			// beim Wechsel des Controllers den Inhalt speichern, ein Commit
			// wurde bereits ausgefuehrt
            if ( m_aActiveControllerFeatures->commitCurrentControl() )
			{
				m_bSetFocus = sal_True;
                if ( m_aActiveControllerFeatures->isModifiedRow() )
                {
                    sal_Bool bIsNew = m_aActiveControllerFeatures->isInsertionRow();
                    sal_Bool bResult = m_aActiveControllerFeatures->commitCurrentRecord();
                    if ( !bResult && m_bSetFocus )
                    {
                        // if we couldn't save the current record, set the focus back to the
                        // current control
						Reference< XWindow > xWindow( m_xActiveController->getCurrentControl(), UNO_QUERY );
                        if ( xWindow.is() )
						    xWindow->setFocus();
						m_bInActivate = sal_False;
						return;
					}
                    else if ( bResult && bIsNew )
					{
                        Reference< XResultSet > xCursor( m_aActiveControllerFeatures->getCursor().get() );
                        if ( xCursor.is() )
                        {
						    DO_SAFE( xCursor->last(); );
                        }
					}
				}
			}
		}

		stopListening();

        impl_switchActiveControllerListening( false );        

        m_aActiveControllerFeatures.dispose();
		m_xActiveController = xController;
        if ( m_xActiveController.is() )
            m_aActiveControllerFeatures.assign( m_xActiveController );

        impl_switchActiveControllerListening( true );

        if ( m_xActiveController.is() )
			m_xActiveForm = getInternalForm( Reference< XForm >( m_xActiveController->getModel(), UNO_QUERY ) );
		else
			m_xActiveForm = NULL;

		startListening();

		// activate all dispatchers belonging to form of the new navigation controller
		xNavigationForm = NULL;
		if (m_xNavigationController.is())
			xNavigationForm = Reference< XResultSet>(m_xNavigationController->getModel(), UNO_QUERY);

		m_bInActivate = sal_False;

		m_pShell->UIFeatureChanged();
		m_pShell->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell);

		InvalidateSlot(SID_FM_FILTER_NAVIGATOR_CONTROL, sal_True);
	}
}

//------------------------------------------------------------------------------
void FmXFormShell::getCurrentSelection( InterfaceBag& /* [out] */ _rSelection ) const
{
    _rSelection = m_aCurrentSelection;
}

//------------------------------------------------------------------------------
bool FmXFormShell::setCurrentSelectionFromMark( const SdrMarkList& _rMarkList )
{
    m_aLastKnownMarkedControls.clear();

    if ( ( _rMarkList.GetMarkCount() > 0 ) && isControlList( _rMarkList ) )
        collectInterfacesFromMarkList( _rMarkList, m_aLastKnownMarkedControls );

    return setCurrentSelection( m_aLastKnownMarkedControls );
}

//------------------------------------------------------------------------------
bool FmXFormShell::selectLastMarkedControls()
{
    return setCurrentSelection( m_aLastKnownMarkedControls );
}

//------------------------------------------------------------------------------
bool FmXFormShell::setCurrentSelection( const InterfaceBag& _rSelection )
{
    if ( impl_checkDisposed() )
        return false;

    DBG_ASSERT( m_pShell->IsDesignMode(), "FmXFormShell::setCurrentSelection: only to be used in design mode!" );

    if ( _rSelection.empty() && m_aCurrentSelection.empty() )
        // nothing to do
        return false;

    if ( _rSelection.size() == m_aCurrentSelection.size() )
    {
        InterfaceBag::const_iterator aNew = _rSelection.begin();
        InterfaceBag::const_iterator aOld = m_aCurrentSelection.begin();
        for ( ; aNew != _rSelection.end(); ++aNew, ++aOld )
        {
            OSL_ENSURE( Reference< XInterface >( *aNew, UNO_QUERY ).get() == aNew->get(), "FmXFormShell::setCurrentSelection: new interface not normalized!" );
            OSL_ENSURE( Reference< XInterface >( *aOld, UNO_QUERY ).get() == aOld->get(), "FmXFormShell::setCurrentSelection: old interface not normalized!" );

            if ( aNew->get() != aOld->get() )
                break;
        }

        if ( aNew == _rSelection.end() )
            // both bags equal
            return false;
    }

    // the following is some strange code to ensure that when you have two grid controls in a document,
    // only one of them can have a selected column.
    // TODO: this should happen elsewhere, but not here - shouldn't it?
    if ( !m_aCurrentSelection.empty() )
    {
		Reference< XChild > xCur; if ( m_aCurrentSelection.size() == 1 ) xCur = xCur.query( *m_aCurrentSelection.begin() );
		Reference< XChild > xNew; if ( _rSelection.size() == 1 ) xNew = xNew.query( *_rSelection.begin() );

        // is there nothing to be selected, or the parents differ, and the parent of the current object
        // is a selection supplier, then deselect
		if ( xCur.is() && ( !xNew.is() || ( xCur->getParent() != xNew->getParent() ) ) )
        {
			Reference< XSelectionSupplier > xSel( xCur->getParent(), UNO_QUERY );
			if ( xSel.is() )
				xSel->select( Any() );
		}
	}

    m_aCurrentSelection = _rSelection;

    // determine the form which all the selected obj�cts belong to, if any
    Reference< XForm > xNewCurrentForm;
    for ( InterfaceBag::const_iterator loop = m_aCurrentSelection.begin();
          loop != m_aCurrentSelection.end();
          ++loop
        )
    {
        Reference< XForm > xThisRoundsForm( GetForm( *loop ) );
        OSL_ENSURE( xThisRoundsForm.is(), "FmXFormShell::setCurrentSelection: *everything* should belong to a form!" );

        if ( !xNewCurrentForm.is() )
        {   // the first form we encounterd
            xNewCurrentForm = xThisRoundsForm;
        }
        else if ( xNewCurrentForm != xThisRoundsForm )
        {   // different forms -> no "current form" at all
            xNewCurrentForm.clear();
            break;
        }
    }

    if ( !m_aCurrentSelection.empty() )
        impl_updateCurrentForm( xNewCurrentForm );

    // ensure some slots are updated
	for ( size_t i = 0; i < sizeof( SelObjectSlotMap ) / sizeof( SelObjectSlotMap[0] ); ++i )
		InvalidateSlot( SelObjectSlotMap[i], sal_False);

    return true;
}

//------------------------------------------------------------------------------
bool FmXFormShell::isSolelySelected( const Reference< XInterface >& _rxObject )
{
    return ( m_aCurrentSelection.size() == 1 ) && ( *m_aCurrentSelection.begin() == _rxObject );
}

//------------------------------------------------------------------------------
void FmXFormShell::forgetCurrentForm()
{
    if ( !m_xCurrentForm.is() )
        return;

    // reset ...
    impl_updateCurrentForm( NULL );

    // ... and try finding a new current form
    // #i88186# / 2008-04-12 / frank.schoenheit@sun.com
    impl_defaultCurrentForm_nothrow();
}

//------------------------------------------------------------------------------
void FmXFormShell::impl_updateCurrentForm( const Reference< XForm >& _rxNewCurForm )
{
    if ( impl_checkDisposed() )
        return;

    m_xCurrentForm = _rxNewCurForm;

    // propagate to the FormPage(Impl)
    FmFormPage* pPage = m_pShell->GetCurPage();
	if ( pPage )
		pPage->GetImpl().setCurForm( m_xCurrentForm );

    // ensure the UI which depends on the current form is up-to-date
    for ( size_t i = 0; i < sizeof( DlgSlotMap ) / sizeof( DlgSlotMap[0] ); ++i )
		InvalidateSlot( DlgSlotMap[i], sal_False );
}

//------------------------------------------------------------------------------
void FmXFormShell::startListening()
{
    if ( impl_checkDisposed() )
        return;

	Reference< XRowSet> xDatabaseForm(m_xActiveForm, UNO_QUERY);
	if (xDatabaseForm.is() && getRowSetConnection(xDatabaseForm).is())
	{
		Reference< XPropertySet> xActiveFormSet(m_xActiveForm, UNO_QUERY);
		if (xActiveFormSet.is())
		{
			// wenn es eine Datenquelle gibt, dann den Listener aufbauen
            // TODO: this is strange - shouldn't this depend on a isLoaded instead of
            // a "has command value"? Finally, the command value only means that it was
            // intended to be loaded, not that it actually *is* loaded
			::rtl::OUString aSource = ::comphelper::getString(xActiveFormSet->getPropertyValue(FM_PROP_COMMAND));
			if (aSource.getLength())
			{
				m_bDatabaseBar = sal_True;

				xActiveFormSet->getPropertyValue(FM_PROP_NAVIGATION) >>= m_eNavigate;

				switch (m_eNavigate)
				{
					case NavigationBarMode_PARENT:
					{
						// suchen des Controllers, ueber den eine Navigation moeglich ist
						Reference< XChild> xChild(m_xActiveController, UNO_QUERY);
						Reference< runtime::XFormController > xParent;
						while (xChild.is())
						{
							xChild = Reference< XChild>(xChild->getParent(), UNO_QUERY);
							xParent  = Reference< runtime::XFormController >(xChild, UNO_QUERY);
							Reference< XPropertySet> xParentSet;
							if (xParent.is())
								xParentSet = Reference< XPropertySet>(xParent->getModel(), UNO_QUERY);
							if (xParentSet.is())
							{
								xParentSet->getPropertyValue(FM_PROP_NAVIGATION) >>= m_eNavigate;
								if (m_eNavigate == NavigationBarMode_CURRENT)
									break;
							}
						}
						m_xNavigationController = xParent;
					}
                    break;

					case NavigationBarMode_CURRENT:
						m_xNavigationController = m_xActiveController;
						break;

					default:
						m_xNavigationController = NULL;
						m_bDatabaseBar = sal_False;
				}

                m_aNavControllerFeatures.dispose();
                if ( m_xNavigationController.is() && ( m_xNavigationController != m_xActiveController ) )
                    m_aNavControllerFeatures.assign( m_xNavigationController );

				// an dem Controller, der die Navigation regelt, wg. RecordCount lauschen
				Reference< XPropertySet> xNavigationSet;
				if (m_xNavigationController.is())
				{
					xNavigationSet = Reference< XPropertySet>(m_xNavigationController->getModel(), UNO_QUERY);
					if (xNavigationSet.is())
						xNavigationSet->addPropertyChangeListener(FM_PROP_ROWCOUNT,this);
				}
				return;
			}
		}
	}

	m_eNavigate  = NavigationBarMode_NONE;
	m_bDatabaseBar = sal_False;
	m_xNavigationController = NULL;
}

//------------------------------------------------------------------------------
void FmXFormShell::stopListening()
{
    if ( impl_checkDisposed() )
        return;

	Reference< XRowSet> xDatabaseForm(m_xActiveForm, UNO_QUERY);
	if ( xDatabaseForm.is() )
	{
		if (m_xNavigationController.is())
		{
			Reference< XPropertySet> xSet(m_xNavigationController->getModel(), UNO_QUERY);
			if (xSet.is())
				xSet->removePropertyChangeListener(FM_PROP_ROWCOUNT, this);

		}
	}

	m_bDatabaseBar = sal_False;
	m_eNavigate  = NavigationBarMode_NONE;
	m_xNavigationController = NULL;
}

//------------------------------------------------------------------------------
void FmXFormShell::ShowSelectionProperties( sal_Bool bShow )
{
    if ( impl_checkDisposed() )
        return;

	// if the window is already visible, only update the state
	sal_Bool bHasChild = m_pShell->GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_SHOW_PROPERTIES );
	if ( bHasChild && bShow )
		UpdateSlot( SID_FM_PROPERTY_CONTROL );

	// else toggle state
	else
		m_pShell->GetViewShell()->GetViewFrame()->ToggleChildWindow(SID_FM_SHOW_PROPERTIES);

	InvalidateSlot( SID_FM_PROPERTIES, sal_False );
	InvalidateSlot( SID_FM_CTL_PROPERTIES, sal_False );
}

//------------------------------------------------------------------------------
IMPL_LINK(FmXFormShell, OnFoundData, FmFoundRecordInformation*, pfriWhere)
{
    if ( impl_checkDisposed() )
        return 0;

	DBG_ASSERT((pfriWhere->nContext >= 0) && (pfriWhere->nContext < (sal_Int16)m_aSearchForms.size()),
		"FmXFormShell::OnFoundData : ungueltiger Kontext !");
	Reference< XForm> xForm( m_aSearchForms.at(pfriWhere->nContext));
	DBG_ASSERT(xForm.is(), "FmXFormShell::OnFoundData : ungueltige Form !");

	Reference< XRowLocate> xCursor(xForm, UNO_QUERY);
	if (!xCursor.is())
		return 0;		// was soll ich da machen ?

	// zum Datensatz
	try
	{
		xCursor->moveToBookmark(pfriWhere->aPosition);
	}
	catch(const SQLException&)
	{
		OSL_ENSURE(0,"Can position on bookmark!");
	}

	LoopGrids(GA_FORCE_SYNC);

	// und zum Feld (dazu habe ich vor dem Start des Suchens die XVclComponent-Interfaces eingesammelt)
	DBG_ASSERT(pfriWhere->nFieldPos < m_arrSearchedControls.Count(), "FmXFormShell::OnFoundData : ungueltige Daten uebergeben !");
	SdrObject* pObject = m_arrSearchedControls.GetObject(pfriWhere->nFieldPos);
	DBG_ASSERT(pObject != NULL, "FmXFormShell::OnFoundData : unerwartet : ungueltiges VclControl-Interface");

	m_pShell->GetFormView()->UnMarkAll(m_pShell->GetFormView()->GetSdrPageView());
	m_pShell->GetFormView()->MarkObj(pObject, m_pShell->GetFormView()->GetSdrPageView());

    FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
    Reference< XControlModel > xControlModel( pFormObject ? pFormObject->GetUnoControlModel() : Reference< XControlModel >() );
	DBG_ASSERT( xControlModel.is(), "FmXFormShell::OnFoundData: invalid control!" );
    if ( !xControlModel.is() )
        return 0;

	// disable the permanent cursor for the last grid we found a record
	if (m_xLastGridFound.is() && (m_xLastGridFound != xControlModel))
	{
		Reference< XPropertySet> xOldSet(m_xLastGridFound, UNO_QUERY);
		xOldSet->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR, makeAny( (sal_Bool)sal_False ) );
		Reference< XPropertyState> xOldSetState(xOldSet, UNO_QUERY);
		if (xOldSetState.is())
			xOldSetState->setPropertyToDefault(FM_PROP_CURSORCOLOR);
		else
			xOldSet->setPropertyValue(FM_PROP_CURSORCOLOR, Any());
	}

	// wenn das Feld sich in einem GridControl befindet, muss ich dort noch in die entsprechende Spalte gehen
	sal_Int32 nGridColumn = m_arrRelativeGridColumn.GetObject(pfriWhere->nFieldPos);
	if (nGridColumn != -1)
	{	// dummer weise muss ich mir das Control erst wieder besorgen
		Reference< XControl> xControl( impl_getControl( xControlModel, *pFormObject ) );
		Reference< XGrid> xGrid(xControl, UNO_QUERY);
		DBG_ASSERT(xGrid.is(), "FmXFormShell::OnFoundData : ungueltiges Control !");
		// wenn eine der Asserts anschlaegt, habe ich beim Aufbauen von m_arrSearchedControls wohl was falsch gemacht

		// enable a permanent cursor for the grid so we can see the found text
		Reference< XPropertySet> xModelSet(xControlModel, UNO_QUERY);
		DBG_ASSERT(xModelSet.is(), "FmXFormShell::OnFoundData : invalid control model (no property set) !");
		xModelSet->setPropertyValue( FM_PROP_ALWAYSSHOWCURSOR, makeAny( (sal_Bool)sal_True ) );
		xModelSet->setPropertyValue( FM_PROP_CURSORCOLOR, makeAny( sal_Int32( COL_LIGHTRED ) ) );
		m_xLastGridFound = xControlModel;

        if ( xGrid.is() )
		    xGrid->setCurrentColumnPosition((sal_Int16)nGridColumn);
	}

	// als der Cursor neu positioniert wurde, habe ich (in positioned) meine Formularleisten-Slots invalidiert, aber das greift
	// hier dummerweise nicht, da i.A. ja der (modale) Suchdialog oben ist ... also Gewalt ...
	sal_uInt16 nPos = 0;
	while (DatabaseSlotMap[nPos])
		m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Update(DatabaseSlotMap[nPos++]);
		// leider geht das Update im Gegensatz zum Invalidate nur mit einzelnen Slots)

	return 0;
}

//------------------------------------------------------------------------------
IMPL_LINK(FmXFormShell, OnCanceledNotFound, FmFoundRecordInformation*, pfriWhere)
{
    if ( impl_checkDisposed() )
        return 0;

	DBG_ASSERT((pfriWhere->nContext >= 0) && (pfriWhere->nContext < (sal_Int16)m_aSearchForms.size()),
		"FmXFormShell::OnCanceledNotFound : ungueltiger Kontext !");
	Reference< XForm> xForm( m_aSearchForms.at(pfriWhere->nContext));
	DBG_ASSERT(xForm.is(), "FmXFormShell::OnCanceledNotFound : ungueltige Form !");

	Reference< XRowLocate> xCursor(xForm, UNO_QUERY);
	if (!xCursor.is())
		return 0;		// was soll ich da machen ?

	// zum Datensatz
	try
	{
		xCursor->moveToBookmark(pfriWhere->aPosition);
	}
	catch(const SQLException&)
	{
		OSL_ENSURE(0,"Can position on bookmark!");
	}


	m_pShell->GetFormView()->UnMarkAll(m_pShell->GetFormView()->GetSdrPageView());
	return 0L;
}

//------------------------------------------------------------------------------
IMPL_LINK(FmXFormShell, OnSearchContextRequest, FmSearchContext*, pfmscContextInfo)
{
    if ( impl_checkDisposed() )
        return 0;

	DBG_ASSERT(pfmscContextInfo->nContext < (sal_Int16)m_aSearchForms.size(), "FmXFormShell::OnSearchContextRequest : invalid parameter !");
	Reference< XForm> xForm( m_aSearchForms.at(pfmscContextInfo->nContext));
	DBG_ASSERT(xForm.is(), "FmXFormShell::OnSearchContextRequest : unexpected : invalid context !");

	Reference< XResultSet> xIter(xForm, UNO_QUERY);
	DBG_ASSERT(xIter.is(), "FmXFormShell::OnSearchContextRequest : unexpected : context has no iterator !");

	// --------------------------------------------------------------------------------------------
	// die Liste der zu involvierenden Felder zusammenstellen (sind die ControlSources aller Felder, die eine solche Eigenschaft habe)
	UniString strFieldList, sFieldDisplayNames;
	m_arrSearchedControls.Remove(0, m_arrSearchedControls.Count());
	m_arrRelativeGridColumn.Remove(0, m_arrRelativeGridColumn.Count());

	// folgendes kleines Problem : Ich brauche, um gefundene Felder zu markieren, SdrObjekte. Um hier festzustellen, welche Controls
	// ich in die Suche einbeziehen soll, brauche ich Controls (also XControl-Interfaces). Ich muss also ueber eines von beiden
	// iterieren und mir das jeweils andere besorgen. Dummerweise gibt es keine direkte Verbindung zwischen beiden Welten (abgesehen
	// von einem GetUnoControl an SdrUnoObject, das aber ein OutputDevice verlangt, womit ich nichts anfangen kann).
	// Allerdings komme ich sowohl von einem Control als auch von einem SdrObject zum Model, und damit ist mir mit einer doppelten
	// Schleife die Zuordnung SdrObject<->Control moeglich.
	// Die Alternative zu dieser (unschoenen und sicher auch nicht ganz fixen) Loesung waere, auf das Cachen der SdrObjects zu
	// verzichten, was dann aber in OnFoundData zu wesentlicher Mehrarbeit fuehren wuerde (da ich mir dort jedesmal das SdrObject
	// erst besorgen muesste). Da aber OnFoundData i.d.R. oefter aufgerufen wird als ExecuteSearch, erledige ich das hier.

	Reference< XNameAccess> xValidFormFields;
	Reference< XColumnsSupplier> xSupplyCols(xIter, UNO_QUERY);
	DBG_ASSERT(xSupplyCols.is(), "FmXFormShell::OnSearchContextRequest : invalid cursor : no columns supplier !");
	if (xSupplyCols.is())
		xValidFormFields = xSupplyCols->getColumns();
	DBG_ASSERT(xValidFormFields.is(), "FmXFormShell::OnSearchContextRequest : form has no fields !");

	// aktuelle(r) Page/Controller
	FmFormPage* pCurrentPage = m_pShell->GetCurPage();
	DBG_ASSERT(pCurrentPage!=NULL, "FmXFormShell::OnSearchContextRequest : no page !");
	// alle Sdr-Controls dieser Seite durchsuchen ...
	::rtl::OUString sControlSource, aName;

    SdrObjListIter aPageIter( *pCurrentPage );
    while ( aPageIter.IsMore() )
    {
        SdrObject* pCurrent = aPageIter.Next();
        FmFormObj* pFormObject = FmFormObj::GetFormObject( pCurrent );
            // note that in case pCurrent is a virtual object, pFormObject points to the referenced object

        if ( !pFormObject )
            continue;

        // the current object's model, in different tastes
        Reference< XControlModel> xControlModel( pFormObject->GetUnoControlModel() );
        Reference< XFormComponent > xCurrentFormComponent( xControlModel, UNO_QUERY );
        DBG_ASSERT( xCurrentFormComponent.is(), "FmXFormShell::OnSearchContextRequest: invalid objects!" );
        if ( !xCurrentFormComponent.is() )
            continue;

        // does the component belong to the form which we're interested in?
        if ( xCurrentFormComponent->getParent() != xForm )
            continue;

        // ... nach der ControlSource-Eigenschaft fragen
        SearchableControlIterator iter( xCurrentFormComponent );
        Reference< XControl> xControl;
            // das Control, das als Model xControlModel hat
            // (das folgende while kann mehrmals durchlaufen werden, ohne dass das Control sich aendert, dann muss
            // ich nicht jedesmal neu suchen)

        Reference< XInterface > xSearchable( iter.Next() );
        while ( xSearchable.is() )
        {
            sControlSource = iter.getCurrentValue();
            if ( sControlSource.getLength() == 0 )
            {	// das aktuelle Element hat keine ControlSource, also ist es ein GridControl (das ist das einzige, was
                // der SearchableControlIterator noch zulaesst)
                xControl = impl_getControl( xControlModel, *pFormObject );
                DBG_ASSERT(xControl.is(), "FmXFormShell::OnSearchContextRequest : didn't ::std::find a control with requested model !");

                Reference< XGridPeer> xGridPeer;
                if ( xControl.is() )
                    xGridPeer.set( xControl->getPeer(), UNO_QUERY );
                do
                {
                    if (!xGridPeer.is())
                        break;

                    Reference< XIndexAccess> xPeerContainer(xGridPeer, UNO_QUERY);
                    if (!xPeerContainer.is())
                        break;

                    Reference< XIndexAccess> xModelColumns(xGridPeer->getColumns(), UNO_QUERY);
                    DBG_ASSERT(xModelColumns.is(), "FmXFormShell::OnSearchContextRequest : there is a grid control without columns !");
                        // the case 'no columns' should be indicated with an empty container, I think ...
                    DBG_ASSERT(xModelColumns->getCount() >= xPeerContainer->getCount(), "FmXFormShell::OnSearchContextRequest : impossible : have more view than model columns !");

                    Reference< XInterface> xCurrentColumn;
                    for (sal_Int16 nViewPos=0; nViewPos<xPeerContainer->getCount(); ++nViewPos)
                    {
                        xPeerContainer->getByIndex(nViewPos) >>= xCurrentColumn;
                        if (!xCurrentColumn.is())
                            continue;

                        // can we use this column control fo searching ?
                        if (!IsSearchableControl(xCurrentColumn))
                            continue;

                        sal_Int16 nModelPos = GridView2ModelPos(xModelColumns, nViewPos);
                        Reference< XPropertySet> xCurrentColModel;
                        xModelColumns->getByIndex(nModelPos) >>= xCurrentColModel;
                        aName = ::comphelper::getString(xCurrentColModel->getPropertyValue(FM_PROP_CONTROLSOURCE));
                        // the cursor has a field matching the control source ?
                        if (xValidFormFields->hasByName(aName))
                        {
                            strFieldList += aName.getStr();
                            strFieldList += ';';

                            sFieldDisplayNames += ::comphelper::getString(xCurrentColModel->getPropertyValue(FM_PROP_LABEL)).getStr();
                            sFieldDisplayNames += ';';

                            pfmscContextInfo->arrFields.push_back(xCurrentColumn);

                            // und das SdrObjekt zum Feld
                            m_arrSearchedControls.C40_INSERT(SdrObject, pCurrent, m_arrSearchedControls.Count());
                            // die Nummer der Spalte
                            m_arrRelativeGridColumn.Insert(nViewPos, m_arrRelativeGridColumn.Count());
                        }
                    }
                } while (sal_False);
            }
            else
            {
                if (sControlSource.getLength() && xValidFormFields->hasByName(sControlSource))
                {
                    // jetzt brauche ich das Control zum SdrObject
                    if (!xControl.is())
                    {
                        xControl = impl_getControl( xControlModel, *pFormObject );
                        DBG_ASSERT(xControl.is(), "FmXFormShell::OnSearchContextRequest : didn't ::std::find a control with requested model !");
                    }

                    if (IsSearchableControl(xControl))
                    {	// alle Tests ueberstanden -> in die Liste mit aufnehmen
                        strFieldList += sControlSource.getStr();
                        strFieldList += ';';

                        // the label which should appear for the control :
                        sFieldDisplayNames += getLabelName(Reference< XPropertySet>(xControlModel, UNO_QUERY)).getStr();
                        sFieldDisplayNames += ';';

                        // das SdrObjekt merken (beschleunigt die Behandlung in OnFoundData)
                        m_arrSearchedControls.C40_INSERT(SdrObject, pCurrent, m_arrSearchedControls.Count());

                        // die Nummer der Spalte (hier ein Dummy, nur fuer GridControls interesant)
                        m_arrRelativeGridColumn.Insert(-1, m_arrRelativeGridColumn.Count());

                        // und fuer die formatierte Suche ...
                        pfmscContextInfo->arrFields.push_back(Reference< XInterface>(xControl, UNO_QUERY));
                    }
                }
            }

            xSearchable = iter.Next();
        }
    }

	strFieldList.EraseTrailingChars(';');
	sFieldDisplayNames.EraseTrailingChars(';');

	if (pfmscContextInfo->arrFields.empty())
	{
		pfmscContextInfo->arrFields.clear();
		pfmscContextInfo->xCursor = NULL;
		pfmscContextInfo->strUsedFields.Erase();
		return 0L;
	}

	pfmscContextInfo->xCursor = xIter;
	pfmscContextInfo->strUsedFields = strFieldList;
	pfmscContextInfo->sFieldDisplayNames = sFieldDisplayNames;

	// 66463 - 31.05.99 - FS
	// wenn der Cursor sich in einem anderen RecordMode als STANDARD befindet, ruecksetzen
	Reference< XPropertySet> xCursorSet(pfmscContextInfo->xCursor, UNO_QUERY);
	Reference< XResultSetUpdate> xUpdateCursor(pfmscContextInfo->xCursor, UNO_QUERY);
	if (xUpdateCursor.is() && xCursorSet.is() && xCursorSet.is())
	{
		if (::comphelper::getBOOL(xCursorSet->getPropertyValue(FM_PROP_ISNEW)))
			xUpdateCursor->moveToCurrentRow();
		else if (::comphelper::getBOOL(xCursorSet->getPropertyValue(FM_PROP_ISMODIFIED)))
			xUpdateCursor->cancelRowUpdates();
	}

	return pfmscContextInfo->arrFields.size();
}

  // XContainerListener
//------------------------------------------------------------------------------
void FmXFormShell::elementInserted(const ContainerEvent& evt) throw(::com::sun::star::uno::RuntimeException)
{
    if ( impl_checkDisposed() )
        return;

	// neues Object zum lauschen
	Reference< XInterface> xTemp;
	evt.Element >>= xTemp;
	AddElement(xTemp);
	m_pShell->DetermineForms(sal_True);
}

//------------------------------------------------------------------------------
void FmXFormShell::elementReplaced(const ContainerEvent& evt) throw(::com::sun::star::uno::RuntimeException)
{
    if ( impl_checkDisposed() )
        return;

	Reference< XInterface> xTemp;
	evt.ReplacedElement >>= xTemp;
	RemoveElement(xTemp);
	evt.Element >>= xTemp;
	AddElement(xTemp);
}

//------------------------------------------------------------------------------
void FmXFormShell::elementRemoved(const ContainerEvent& evt) throw(::com::sun::star::uno::RuntimeException)
{
    if ( impl_checkDisposed() )
        return;

	Reference< XInterface> xTemp;
	evt.Element >>= xTemp;
	RemoveElement(xTemp);
    m_pShell->DetermineForms(sal_True);
}

//------------------------------------------------------------------------------
void FmXFormShell::UpdateForms( sal_Bool _bInvalidate )
{
    if ( impl_checkDisposed() )
        return;

    Reference< XIndexAccess > xForms;

    FmFormPage* pPage = m_pShell->GetCurPage();
    if ( pPage )
    {
        if ( m_pShell->m_bDesignMode )
            xForms = xForms.query( pPage->GetForms( false ) );
    }

    if ( m_xForms != xForms )
    {
	    RemoveElement( m_xForms );
	    m_xForms = xForms;
	    AddElement( m_xForms );
    }

    m_pShell->DetermineForms( _bInvalidate );
}

//------------------------------------------------------------------------------
void FmXFormShell::AddElement(const Reference< XInterface>& _xElement)
{
    if ( impl_checkDisposed() )
        return;
    impl_AddElement_nothrow(_xElement);
}
// -----------------------------------------------------------------------------
void FmXFormShell::impl_AddElement_nothrow(const Reference< XInterface>& Element)
{
	// am Container horchen
	const Reference< XIndexContainer> xContainer(Element, UNO_QUERY);
	if (xContainer.is())
	{
		const sal_uInt32 nCount = xContainer->getCount();
		Reference< XInterface> xElement;
		for (sal_uInt32 i = 0; i < nCount; ++i)
		{
			xElement.set(xContainer->getByIndex(i),UNO_QUERY);
			impl_AddElement_nothrow(xElement);
		}

		const Reference< XContainer> xCont(Element, UNO_QUERY);
		if (xCont.is())
			xCont->addContainerListener(this);
	}

	const Reference< ::com::sun::star::view::XSelectionSupplier> xSelSupplier(Element, UNO_QUERY);
	if (xSelSupplier.is())
		xSelSupplier->addSelectionChangeListener(this);
}

//------------------------------------------------------------------------------
void FmXFormShell::RemoveElement(const Reference< XInterface>& Element)
{
    if ( impl_checkDisposed() )
        return;
    impl_RemoveElement_nothrow(Element);
}
//------------------------------------------------------------------------------
void FmXFormShell::impl_RemoveElement_nothrow(const Reference< XInterface>& Element)
{
	const Reference< ::com::sun::star::view::XSelectionSupplier> xSelSupplier(Element, UNO_QUERY);
	if (xSelSupplier.is())
		xSelSupplier->removeSelectionChangeListener(this);

	// Verbindung zu Kindern aufheben
	const Reference< XIndexContainer> xContainer(Element, UNO_QUERY);
	if (xContainer.is())
	{
		const Reference< XContainer> xCont(Element, UNO_QUERY);
		if (xCont.is())
			xCont->removeContainerListener(this);

		const sal_uInt32 nCount = xContainer->getCount();
		Reference< XInterface> xElement;
		for (sal_uInt32 i = 0; i < nCount; i++)
		{
			xElement.set(xContainer->getByIndex(i),UNO_QUERY);
			impl_RemoveElement_nothrow(xElement);
		}
	}

    InterfaceBag::iterator wasSelectedPos = m_aCurrentSelection.find( Element );
	if ( wasSelectedPos != m_aCurrentSelection.end() )
        m_aCurrentSelection.erase( wasSelectedPos );
}

//------------------------------------------------------------------------------
void FmXFormShell::selectionChanged(const EventObject& rEvent) throw(::com::sun::star::uno::RuntimeException)
{
    if ( impl_checkDisposed() )
        return;

    Reference< XSelectionSupplier > xSupplier( rEvent.Source, UNO_QUERY );
	Reference< XInterface > xSelObj( xSupplier->getSelection(), UNO_QUERY );
	// es wurde eine Selektion weggenommen, dieses kann nur durch die Shell vorgenommen werden
	if ( !xSelObj.is() )
		return;

	EnableTrackProperties(sal_False);

	sal_Bool bMarkChanged = m_pShell->GetFormView()->checkUnMarkAll(rEvent.Source);
	Reference< XForm > xNewForm( GetForm( rEvent.Source ) );

    InterfaceBag aNewSelection;
    aNewSelection.insert( Reference< XInterface >( xSelObj, UNO_QUERY ) );

	if ( setCurrentSelection( aNewSelection ) && IsPropBrwOpen() )
		ShowSelectionProperties( sal_True );

	EnableTrackProperties(sal_True);

    if ( bMarkChanged )
		m_pShell->NotifyMarkListChanged( m_pShell->GetFormView() );
}

//------------------------------------------------------------------------------
IMPL_LINK(FmXFormShell, OnTimeOut, void*, /*EMPTYTAG*/)
{
    if ( impl_checkDisposed() )
        return 0;

	if (m_pShell->IsDesignMode() && m_pShell->GetFormView())
		SetSelection(m_pShell->GetFormView()->GetMarkedObjectList());

	return 0;
}

//------------------------------------------------------------------------
void FmXFormShell::SetSelectionDelayed()
{
    if ( impl_checkDisposed() )
        return;

	if (m_pShell->IsDesignMode() && IsTrackPropertiesEnabled() && !m_aMarkTimer.IsActive())
		m_aMarkTimer.Start();
}

//------------------------------------------------------------------------
void FmXFormShell::SetSelection(const SdrMarkList& rMarkList)
{
    if ( impl_checkDisposed() )
        return;

	DetermineSelection(rMarkList);
	m_pShell->NotifyMarkListChanged(m_pShell->GetFormView());
}

//------------------------------------------------------------------------
void FmXFormShell::DetermineSelection(const SdrMarkList& rMarkList)
{
	if ( setCurrentSelectionFromMark( rMarkList ) && IsPropBrwOpen() )
		ShowSelectionProperties( sal_True );
}

//------------------------------------------------------------------------------
sal_Bool FmXFormShell::IsPropBrwOpen() const
{
    if ( impl_checkDisposed() )
        return sal_False;

	return( ( m_pShell->GetViewShell() && m_pShell->GetViewShell()->GetViewFrame() ) ?
			m_pShell->GetViewShell()->GetViewFrame()->HasChildWindow(SID_FM_SHOW_PROPERTIES) : sal_False );
}

//------------------------------------------------------------------------------
class FmXFormShell::SuspendPropertyTracking
{
private:
	FmXFormShell&   m_rShell;
	sal_Bool		m_bEnabled;

public:
	SuspendPropertyTracking( FmXFormShell& _rShell )
		:m_rShell( _rShell )
		,m_bEnabled( sal_False )
	{
		if ( m_rShell.IsTrackPropertiesEnabled() )
		{
			m_rShell.EnableTrackProperties( sal_False );
			m_bEnabled = sal_True;
		}
	}

	~SuspendPropertyTracking( )
	{
		if ( m_bEnabled )	// note that ( sal_False != m_bEnabled ) implies ( NULL != m_pShell )
			m_rShell.EnableTrackProperties( sal_True );
	}
};

//------------------------------------------------------------------------------
void FmXFormShell::SetDesignMode(sal_Bool bDesign)
{
    if ( impl_checkDisposed() )
        return;

	DBG_ASSERT(m_pShell->GetFormView(), "FmXFormShell::SetDesignMode : invalid call (have no shell or no view) !");
	m_bChangingDesignMode = sal_True;

	// 67506 - 15.07.99 - FS
	// if we're switching off the design mode we have to force the property browser to be closed
	// so it can commit it's changes _before_ we load the forms
	if (!bDesign)
	{
		m_bHadPropertyBrowserInDesignMode = m_pShell->GetViewShell()->GetViewFrame()->HasChildWindow(SID_FM_SHOW_PROPERTIES);
		if (m_bHadPropertyBrowserInDesignMode)
			m_pShell->GetViewShell()->GetViewFrame()->ToggleChildWindow(SID_FM_SHOW_PROPERTIES);
	}

	FmFormView* pFormView = m_pShell->GetFormView();
	if (bDesign)
	{
		// we are currently filtering, so stop filtering
		if (m_bFilterMode)
			stopFiltering(sal_False);

		// an den Objekten meiner MarkList als Listener abmelden
		pFormView->GetImpl()->stopMarkListWatching();
	}
	else
	{
		m_aMarkTimer.Stop();

		SuspendPropertyTracking aSuspend( *this );
		pFormView->GetImpl()->saveMarkList( sal_True );
	}

	if (bDesign && m_xExternalViewController.is())
		CloseExternalFormViewer();

	pFormView->ChangeDesignMode(bDesign);

	// Listener benachrichtigen
	FmDesignModeChangedHint aChangedHint( bDesign );
	m_pShell->Broadcast(aChangedHint);

	m_pShell->m_bDesignMode = bDesign;
    UpdateForms( sal_False );

    m_pTextShell->designModeChanged( m_pShell->m_bDesignMode );

	if (bDesign)
	{
		SdrMarkList aList;
		{
			// during changing the mark list, don't track the selected objects in the property browser
			SuspendPropertyTracking aSuspend( *this );
			// restore the marks
			pFormView->GetImpl()->restoreMarkList( aList );
		}

		// synchronize with the restored mark list
		if ( aList.GetMarkCount() )
			SetSelection( aList );
	}
	else
	{
		// am Model der View als Listener anmelden (damit ich mitbekomme, wenn jemand waehrend des Alive-Modus
		// Controls loescht, die ich eigentlich mit saveMarkList gespeichert habe) (60343)
		pFormView->GetImpl()->startMarkListWatching();
	}

	m_pShell->UIFeatureChanged();

	// 67506 - 15.07.99 - FS
	if (bDesign && m_bHadPropertyBrowserInDesignMode)
	{
		// The UIFeatureChanged performes an update (a check of the available features) asynchronously.
		// So we can't call ShowSelectionProperties directly as the according feature isn't enabled yet.
		// That's why we use an asynchron execution on the dispatcher.
		// (And that's why this has to be done AFTER the UIFeatureChanged.)
		m_pShell->GetViewShell()->GetViewFrame()->GetDispatcher()->Execute( SID_FM_SHOW_PROPERTY_BROWSER, SFX_CALLMODE_ASYNCHRON );
	}
	m_bChangingDesignMode = sal_False;
}

//------------------------------------------------------------------------------
Reference< XControl> FmXFormShell::impl_getControl( const Reference< XControlModel >& i_rxModel, const FmFormObj& i_rKnownFormObj )
{
    if ( impl_checkDisposed() )
        return NULL;

    Reference< XControl > xControl;
    try
    {
        Reference< XControlContainer> xControlContainer( getControlContainerForView(), UNO_SET_THROW );

        Sequence< Reference< XControl > > seqControls( xControlContainer->getControls() );
	    const Reference< XControl >* pControls = seqControls.getArray();
	    // ... die ich dann durchsuchen kann
	    for (sal_Int32 i=0; i<seqControls.getLength(); ++i)
	    {
            xControl.set( pControls[i], UNO_SET_THROW );
		    Reference< XControlModel > xCurrentModel( xControl->getModel() );
            if ( xCurrentModel == i_rxModel )
                break;
            xControl.clear();
	    }

        if ( !xControl.is() )
        {
            // fallabck (some controls might not have been created, yet, since they were never visible so far)
            Reference< XControl > xContainerControl( xControlContainer, UNO_QUERY_THROW );
            const Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerControl->getPeer() );
            ENSURE_OR_THROW( pContainerWindow, "unexpected control container implementation" );

            const SdrView* pSdrView = m_pShell ? m_pShell->GetFormView() : NULL;
            ENSURE_OR_THROW( pSdrView, "no current view" );

            xControl.set( i_rKnownFormObj.GetUnoControl( *pSdrView, *pContainerWindow ), UNO_QUERY_THROW );
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }

    OSL_ENSURE( xControl.is(), "FmXFormShell::impl_getControl: no control found!" );
    return xControl;
}

//------------------------------------------------------------------------------
void FmXFormShell::impl_collectFormSearchContexts_nothrow( const Reference< XInterface>& _rxStartingPoint,
    const ::rtl::OUString& _rCurrentLevelPrefix, FmFormArray& _out_rForms, ::std::vector< String >& _out_rNames )
{
    try
    {
	    Reference< XIndexAccess> xContainer( _rxStartingPoint, UNO_QUERY );
        if ( !xContainer.is() )
            return;

        sal_Int32 nCount( xContainer->getCount() );
        if ( nCount == 0 )
            return;

        ::rtl::OUString sCurrentFormName;
        ::rtl::OUStringBuffer aNextLevelPrefix;
		for ( sal_Int32 i=0; i<nCount; ++i )
		{
			// is the current child a form?
		    Reference< XForm > xCurrentAsForm( xContainer->getByIndex(i), UNO_QUERY );
            if ( !xCurrentAsForm.is() )
                continue;

            Reference< XNamed > xNamed( xCurrentAsForm, UNO_QUERY_THROW );
            sCurrentFormName = xNamed->getName();

            // the name of the current form
            ::rtl::OUStringBuffer sCompleteCurrentName( sCurrentFormName );
            if ( _rCurrentLevelPrefix.getLength() )
			{
                sCompleteCurrentName.appendAscii( " (" );
				sCompleteCurrentName.append     ( _rCurrentLevelPrefix );
                sCompleteCurrentName.appendAscii( ")" );
			}

			// the prefix for the next level
            aNextLevelPrefix = _rCurrentLevelPrefix;
			if ( _rCurrentLevelPrefix.getLength() )
				aNextLevelPrefix.append( (sal_Unicode)'/' );
            aNextLevelPrefix.append( sCurrentFormName );

			// remember both the form and it's "display name"
			_out_rForms.push_back( xCurrentAsForm );
            _out_rNames.push_back( sCompleteCurrentName.makeStringAndClear() );

			// und absteigen
			impl_collectFormSearchContexts_nothrow( xCurrentAsForm, aNextLevelPrefix.makeStringAndClear(), _out_rForms, _out_rNames );
	    }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------------
void FmXFormShell::startFiltering()
{
    if ( impl_checkDisposed() )
        return;

	// setting all forms in filter mode
	FmXFormView* pXView = m_pShell->GetFormView()->GetImpl();

	// if the active controller is our external one we have to use the trigger controller
	Reference< XControlContainer> xContainer;
	if (getActiveController() == m_xExternalViewController)
	{
		DBG_ASSERT(m_xExtViewTriggerController.is(), "FmXFormShell::startFiltering : inconsistent : active external controller, but noone triggered this !");
		xContainer = m_xExtViewTriggerController->getContainer();
	}
	else
		xContainer = getActiveController()->getContainer();

	PFormViewPageWindowAdapter pAdapter = pXView->findWindow( xContainer );
	if ( pAdapter.is() )
	{
		const ::std::vector< Reference< runtime::XFormController> >& rControllerList = pAdapter->GetList();
		for (   ::std::vector< Reference< runtime::XFormController> >::const_iterator j = rControllerList.begin();
			    j != rControllerList.end();
                ++j
            )
		{
			Reference< XModeSelector> xModeSelector(*j, UNO_QUERY);
			if (xModeSelector.is())
				xModeSelector->setMode( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterMode" ) ) );
		}
	}

	m_bFilterMode = sal_True;

	m_pShell->UIFeatureChanged();
    SfxViewFrame* pViewFrame = m_pShell->GetViewShell()->GetViewFrame();
	pViewFrame->GetBindings().InvalidateShell( *m_pShell );

	if  (   pViewFrame->KnowsChildWindow( SID_FM_FILTER_NAVIGATOR )
        &&  !pViewFrame->HasChildWindow( SID_FM_FILTER_NAVIGATOR )
        )
	{
		pViewFrame->ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
	}
}

//------------------------------------------------------------------------------
void saveFilter(const Reference< runtime::XFormController >& _rxController)
{
	Reference< XPropertySet> xFormAsSet(_rxController->getModel(), UNO_QUERY);
	Reference< XPropertySet> xControllerAsSet(_rxController, UNO_QUERY);
	Reference< XIndexAccess> xControllerAsIndex(_rxController, UNO_QUERY);

	// call the subcontroller
	Reference< runtime::XFormController > xController;
	for (sal_Int32 i = 0, nCount = xControllerAsIndex->getCount(); i < nCount; ++i)
	{
		xControllerAsIndex->getByIndex(i) >>= xController;
		saveFilter(xController);
	}

	try
	{

		xFormAsSet->setPropertyValue(FM_PROP_FILTER, xControllerAsSet->getPropertyValue(FM_PROP_FILTER));
		xFormAsSet->setPropertyValue(FM_PROP_APPLYFILTER, makeAny( (sal_Bool)sal_True ) );
	}
	catch (const Exception& )
	{
		DBG_UNHANDLED_EXCEPTION();
	}

}

//------------------------------------------------------------------------------
void FmXFormShell::stopFiltering(sal_Bool bSave)
{
    if ( impl_checkDisposed() )
        return;

	m_bFilterMode = sal_False;

	FmXFormView* pXView = m_pShell->GetFormView()->GetImpl();

	// if the active controller is our external one we have to use the trigger controller
	Reference< XControlContainer> xContainer;
	if (getActiveController() == m_xExternalViewController)
	{
		DBG_ASSERT(m_xExtViewTriggerController.is(), "FmXFormShell::stopFiltering : inconsistent : active external controller, but noone triggered this !");
		xContainer = m_xExtViewTriggerController->getContainer();
	}
	else
		xContainer = getActiveController()->getContainer();

	PFormViewPageWindowAdapter pAdapter = pXView->findWindow(xContainer);
	if ( pAdapter.is() )
	{
		const ::std::vector< Reference< runtime::XFormController > >& rControllerList = pAdapter->GetList();
		::std::vector < ::rtl::OUString >	aOriginalFilters;
		::std::vector < sal_Bool >			aOriginalApplyFlags;

		if (bSave)
		{
			for (::std::vector< Reference< runtime::XFormController > > ::const_iterator j = rControllerList.begin();
				 j != rControllerList.end(); ++j)
			{
				if (bSave)
				{	// remember the current filter settings in case we're goin to reload the forms below (which may fail)
					try
					{
						Reference< XPropertySet > xFormAsSet((*j)->getModel(), UNO_QUERY);
						aOriginalFilters.push_back(::comphelper::getString(xFormAsSet->getPropertyValue(FM_PROP_FILTER)));
						aOriginalApplyFlags.push_back(::comphelper::getBOOL(xFormAsSet->getPropertyValue(FM_PROP_APPLYFILTER)));
					}
					catch(Exception&)
					{
						DBG_ERROR("FmXFormShell::stopFiltering : could not get the original filter !");
						// put dummies into the arrays so the they have the right size

						if (aOriginalFilters.size() == aOriginalApplyFlags.size())
							// the first getPropertyValue failed -> use two dummies
							aOriginalFilters.push_back( ::rtl::OUString() );
						aOriginalApplyFlags.push_back( sal_False );
					}
				}
				saveFilter(*j);
			}
		}
		for (::std::vector< Reference< runtime::XFormController > > ::const_iterator j = rControllerList.begin();
			 j != rControllerList.end(); ++j)
		{

			Reference< XModeSelector> xModeSelector(*j, UNO_QUERY);
			if (xModeSelector.is())
				xModeSelector->setMode( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) ) );
		}
		if (bSave)	// execute the filter
		{
			const ::std::vector< Reference< runtime::XFormController > > & rControllers = pAdapter->GetList();
			for (::std::vector< Reference< runtime::XFormController > > ::const_iterator j = rControllers.begin();
				 j != rControllers.end(); ++j)
			{
				Reference< XLoadable> xReload((*j)->getModel(), UNO_QUERY);
				if (!xReload.is())
					continue;
				Reference< XPropertySet > xFormSet(xReload, UNO_QUERY);

				try
				{
					xReload->reload();
				}
				catch(Exception&)
				{
					DBG_ERROR("FmXFormShell::stopFiltering: Exception occured!");
				}

				if (!isRowSetAlive(xFormSet))
				{	// something went wrong -> restore the original state
					::rtl::OUString sOriginalFilter = aOriginalFilters[ j - rControllers.begin() ];
					sal_Bool bOriginalApplyFlag = aOriginalApplyFlags[ j - rControllers.begin() ];
					try
					{
						xFormSet->setPropertyValue(FM_PROP_FILTER, makeAny(sOriginalFilter));
						xFormSet->setPropertyValue(FM_PROP_APPLYFILTER, makeAny(bOriginalApplyFlag));
						xReload->reload();
					}
					catch(const Exception&)
					{
						DBG_UNHANDLED_EXCEPTION();
					}
				}
			}
		}
	}

	m_pShell->UIFeatureChanged();
	m_pShell->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell);
}

//------------------------------------------------------------------------------
void clearFilter(const Reference< runtime::XFormController >& _rxController)
{
	Reference< XPropertySet> xControllerAsSet(_rxController, UNO_QUERY);
	Reference< XIndexAccess> xControllerAsIndex(_rxController, UNO_QUERY);

	// call the subcontroller
	Reference< runtime::XFormController > xController;
	for (sal_Int32 i = 0, nCount = xControllerAsIndex->getCount();
		 i < nCount; i++)
	{
		xControllerAsIndex->getByIndex(i) >>= xController;
		clearFilter(xController);
	}

	// clear the filter
	Reference< XIndexContainer> xContainer;
	xControllerAsSet->getPropertyValue(FM_PROP_FILTERSUPPLIER) >>= xContainer;
	if (xContainer.is())
	{
		// clear the current filter
		Sequence< PropertyValue> aCondition;

		// as there is always an empty row, if we have a filter:
		if (xContainer->getCount())
		{
			xControllerAsSet->setPropertyValue(FM_PROP_CURRENTFILTER, makeAny(sal_Int32(xContainer->getCount() - 1)));
			while (xContainer->getCount() > 1)
				xContainer->removeByIndex(0);
		}
	}
}

//------------------------------------------------------------------------------
void FmXFormShell::clearFilter()
{
    if ( impl_checkDisposed() )
        return;

	FmXFormView* pXView = m_pShell->GetFormView()->GetImpl();

	// if the active controller is our external one we have to use the trigger controller
	Reference< XControlContainer> xContainer;
	if (getActiveController() == m_xExternalViewController)
	{
		DBG_ASSERT(m_xExtViewTriggerController.is(), "FmXFormShell::clearFilter : inconsistent : active external controller, but noone triggered this !");
		xContainer = m_xExtViewTriggerController->getContainer();
	}
	else
		xContainer = getActiveController()->getContainer();

	PFormViewPageWindowAdapter pAdapter = pXView->findWindow(xContainer);
	if ( pAdapter.is() )
	{
		const ::std::vector< Reference< runtime::XFormController > > & rControllerList = pAdapter->GetList();
		for (   ::std::vector< Reference< runtime::XFormController > > ::const_iterator j = rControllerList.begin();
			    j != rControllerList.end();
                ++j
            )
		{
			::clearFilter(*j);
		}
	}
}

//------------------------------------------------------------------------------
void FmXFormShell::CreateExternalView()
{
    if ( impl_checkDisposed() )
        return;

	DBG_ASSERT(m_xAttachedFrame.is(), "FmXFormShell::CreateExternalView : no frame !");

	// the frame the external view is displayed in
	sal_Bool bAlreadyExistent = m_xExternalViewController.is();
	Reference< ::com::sun::star::frame::XFrame> xExternalViewFrame;
	::rtl::OUString sFrameName = ::rtl::OUString::createFromAscii("_beamer");
	sal_Int32 nSearchFlags = ::com::sun::star::frame::FrameSearchFlag::CHILDREN | ::com::sun::star::frame::FrameSearchFlag::CREATE;

	Reference< runtime::XFormController > xCurrentNavController( getNavController());
		// the creation of the "partwindow" may cause a deactivate of the document which will result in our nav controller to be set to NULL

	// _first_ check if we have any valid fields we can use for the grid view
	// FS - 21.10.99 - 69219
    {
	    FmXBoundFormFieldIterator aModelIterator(xCurrentNavController->getModel());
	    Reference< XPropertySet> xCurrentModelSet;
	    sal_Bool bHaveUsableControls = sal_False;
	    while ((xCurrentModelSet = Reference< XPropertySet>(aModelIterator.Next(), UNO_QUERY)).is())
	    {
		    // the FmXBoundFormFieldIterator only supplies controls with a valid control source
		    // so we just have to check the field type
		    sal_Int16 nClassId = ::comphelper::getINT16(xCurrentModelSet->getPropertyValue(FM_PROP_CLASSID));
		    switch (nClassId)
		    {
			    case FormComponentType::IMAGECONTROL:
			    case FormComponentType::CONTROL:
				    continue;
		    }
		    bHaveUsableControls = sal_True;
		    break;
	    }

	    if (!bHaveUsableControls)
	    {
		    ErrorBox(NULL, WB_OK, SVX_RESSTR(RID_STR_NOCONTROLS_FOR_EXTERNALDISPLAY)).Execute();
		    return;
	    }
    }

	// load the component for external form views
	if (!bAlreadyExistent)
	{
		URL aWantToDispatch;
		aWantToDispatch.Complete = FMURL_COMPONENT_FORMGRIDVIEW;

		Reference< ::com::sun::star::frame::XDispatchProvider> xProv(m_xAttachedFrame, UNO_QUERY);
		Reference< ::com::sun::star::frame::XDispatch> xDisp;
		if (xProv.is())
			xDisp = xProv->queryDispatch(aWantToDispatch, sFrameName, nSearchFlags);
		if (xDisp.is())
		{
			xDisp->dispatch(aWantToDispatch, Sequence< PropertyValue>());
		}

		// with this the component should be loaded, now search the frame where it resides in
		xExternalViewFrame = m_xAttachedFrame->findFrame(sFrameName, ::com::sun::star::frame::FrameSearchFlag::CHILDREN);
		if (xExternalViewFrame.is())
		{
			m_xExternalViewController = xExternalViewFrame->getController();
			Reference< ::com::sun::star::lang::XComponent> xComp(m_xExternalViewController, UNO_QUERY);
			if (xComp.is())
				xComp->addEventListener((XEventListener*)(XPropertyChangeListener*)this);
		}
	}
	else
	{
		xExternalViewFrame = m_xExternalViewController->getFrame();
		Reference< ::com::sun::star::frame::XDispatchProvider> xCommLink(xExternalViewFrame, UNO_QUERY);

		// if we display the active form we interpret the slot as "remove it"
		Reference< XForm> xCurrentModel(xCurrentNavController->getModel(), UNO_QUERY);
		if ((xCurrentModel == m_xExternalDisplayedForm) || (getInternalForm(xCurrentModel) == m_xExternalDisplayedForm))
		{
			if ( m_xExternalViewController == getActiveController() )
            {
                Reference< runtime::XFormController > xAsFormController( m_xExternalViewController, UNO_QUERY );
                ControllerFeatures aHelper( ::comphelper::getProcessServiceFactory(), xAsFormController, NULL );
                aHelper->commitCurrentControl();
            }

			Reference< runtime::XFormController > xNewController(m_xExtViewTriggerController);
			CloseExternalFormViewer();
			setActiveController(xNewController);
			return;
		}

		URL aClearURL;
		aClearURL.Complete = FMURL_GRIDVIEW_CLEARVIEW;

		Reference< ::com::sun::star::frame::XDispatch> xClear( xCommLink->queryDispatch(aClearURL, ::rtl::OUString::createFromAscii(""), 0));
		if (xClear.is())
			xClear->dispatch(aClearURL, Sequence< PropertyValue>());
	}

    // TODO: We need an interceptor at the xSupplier, which forwards all queryDispatch requests to the FormController
    // instance for which this "external view" was triggered

	// get the dispatch interface of the frame so we can communicate (interceptable) with the controller
	Reference< ::com::sun::star::frame::XDispatchProvider> xCommLink(xExternalViewFrame, UNO_QUERY);

	if (m_xExternalViewController.is())
	{
		DBG_ASSERT(xCommLink.is(), "FmXFormShell::CreateExternalView : the component doesn't have the necessary interfaces !");
		// collect the dispatchers we will need
		URL aAddColumnURL;
		aAddColumnURL.Complete = FMURL_GRIDVIEW_ADDCOLUMN;
		Reference< ::com::sun::star::frame::XDispatch> xAddColumnDispatch( xCommLink->queryDispatch(aAddColumnURL, ::rtl::OUString::createFromAscii(""), 0));
		URL aAttachURL;
		aAttachURL.Complete = FMURL_GRIDVIEW_ATTACHTOFORM;
		Reference< ::com::sun::star::frame::XDispatch> xAttachDispatch( xCommLink->queryDispatch(aAttachURL, ::rtl::OUString::createFromAscii(""), 0));

		if (xAddColumnDispatch.is() && xAttachDispatch.is())
		{
			DBG_ASSERT(xCurrentNavController.is(), "FmXFormShell::CreateExternalView : invalid call : have no nav controller !");
			// first : dispatch the descriptions for the columns to add
			Sequence< Reference< XControl> > aCurrentControls(xCurrentNavController->getControls());

			sal_Int16 nAddedColumns = 0;

			// for radio buttons we need some special structures
			DECLARE_STL_USTRINGACCESS_MAP(Sequence< ::rtl::OUString>, MapUString2UstringSeq);
			DECLARE_STL_ITERATORS(MapUString2UstringSeq);
			DECLARE_STL_USTRINGACCESS_MAP(::rtl::OUString, FmMapUString2UString);
			DECLARE_STL_USTRINGACCESS_MAP(sal_Int16, FmMapUString2Int16);
			DECLARE_STL_ITERATORS(FmMapUString2Int16);

			MapUString2UstringSeq	aRadioValueLists;
			MapUString2UstringSeq	aRadioListSources;
			FmMapUString2UString	aRadioControlSources;
			FmMapUString2Int16		aRadioPositions;

			FmXBoundFormFieldIterator aModelIterator(xCurrentNavController->getModel());
			Reference< XPropertySet> xCurrentModelSet;
			Any aCurrentBoundField;
			::rtl::OUString sColumnType,aGroupName,sControlSource;
			Sequence< Property> aProps;
			Reference< XPropertySet> xCurrentBoundField;
			while ((xCurrentModelSet = Reference< XPropertySet>(aModelIterator.Next(), UNO_QUERY)).is())
			{
				xCurrentModelSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xCurrentBoundField;
				OSL_ENSURE(xCurrentModelSet.is(),"xCurrentModelSet is null!");
				// create a description of the column to be created
				// first : determine it's type

				sal_Int16 nClassId = ::comphelper::getINT16(xCurrentModelSet->getPropertyValue(FM_PROP_CLASSID));
				switch (nClassId)
				{
					case FormComponentType::RADIOBUTTON:
					{
						// get the label of the button (this is the access key for our structures)
						aGroupName = getLabelName(xCurrentModelSet);

						// add the reference value of the radio button to the list source sequence
						Sequence< ::rtl::OUString>& aThisGroupLabels = aRadioListSources[aGroupName];
						sal_Int32 nNewSizeL = aThisGroupLabels.getLength() + 1;
						aThisGroupLabels.realloc(nNewSizeL);
						aThisGroupLabels.getArray()[nNewSizeL - 1] = ::comphelper::getString(xCurrentModelSet->getPropertyValue(FM_PROP_REFVALUE));

						// add the label to the value list sequence
						Sequence< ::rtl::OUString>& aThisGroupControlSources = aRadioValueLists[aGroupName];
						sal_Int32 nNewSizeC = aThisGroupControlSources.getLength() + 1;
						aThisGroupControlSources.realloc(nNewSizeC);
						aThisGroupControlSources.getArray()[nNewSizeC - 1] = ::comphelper::getString(xCurrentModelSet->getPropertyValue(FM_PROP_LABEL));

						// remember the controls source of the radio group
						sControlSource = ::comphelper::getString(xCurrentModelSet->getPropertyValue(FM_PROP_CONTROLSOURCE));
						if (aRadioControlSources.find(aGroupName) == aRadioControlSources.end())
							aRadioControlSources[aGroupName] = sControlSource;
#ifdef DBG_UTIL
						else
							DBG_ASSERT(aRadioControlSources[aGroupName] == sControlSource,
							"FmXFormShell::CreateExternalView : inconsistent radio buttons detected !");
							// (radio buttons with the same name should have the same control source)
#endif
						// remember the position within the columns
						if (aRadioPositions.find(aGroupName) == aRadioPositions.end())
							aRadioPositions[aGroupName] = (sal_Int16)nAddedColumns;

						// any further handling is done below
					}
					continue;

					case FormComponentType::IMAGECONTROL:
					case FormComponentType::CONTROL:
						// no grid columns for these types (though they have a control source)
						continue;
					case FormComponentType::CHECKBOX:
						sColumnType = FM_COL_CHECKBOX; break;
					case FormComponentType::LISTBOX:
						sColumnType = FM_COL_LISTBOX; break;
					case FormComponentType::COMBOBOX:
						sColumnType = FM_COL_COMBOBOX; break;
					case FormComponentType::DATEFIELD:
						sColumnType = FM_COL_DATEFIELD; break;
					case FormComponentType::TIMEFIELD:
						sColumnType = FM_COL_TIMEFIELD; break;
					case FormComponentType::NUMERICFIELD:
						sColumnType = FM_COL_NUMERICFIELD; break;
					case FormComponentType::CURRENCYFIELD:
						sColumnType = FM_COL_CURRENCYFIELD; break;
					case FormComponentType::PATTERNFIELD:
						sColumnType = FM_COL_PATTERNFIELD; break;

					case FormComponentType::TEXTFIELD:
						{
							sColumnType = FM_COL_TEXTFIELD;
							// we know at least two different controls which are TextFields : the basic edit field and the formatted
							// field. we distinguish them by their service name
							Reference< XServiceInfo> xInfo(xCurrentModelSet, UNO_QUERY);
							if (xInfo.is())
							{
								sal_Int16 nObjectType = getControlTypeByObject(xInfo);
								if (OBJ_FM_FORMATTEDFIELD == nObjectType)
									sColumnType = FM_COL_FORMATTEDFIELD;
							}
						}
						break;
					default:
						sColumnType = FM_COL_TEXTFIELD; break;
				}

				const sal_Int16 nDispatchArgs = 3;
				Sequence< PropertyValue> aDispatchArgs(nDispatchArgs);
				PropertyValue* pDispatchArgs = aDispatchArgs.getArray();

				// properties describing "meta data" about the column
				// the type
				pDispatchArgs->Name = FMARG_ADDCOL_COLUMNTYPE;
				pDispatchArgs->Value <<= sColumnType;
				++pDispatchArgs;

				// the pos : append the col
				pDispatchArgs->Name = FMARG_ADDCOL_COLUMNPOS;
				pDispatchArgs->Value <<= nAddedColumns;
				++pDispatchArgs;

				// the properties to forward to the new column
				Sequence< PropertyValue> aColumnProps(1);
				PropertyValue* pColumnProps = aColumnProps.getArray();

				// the label
				pColumnProps->Name = FM_PROP_LABEL;
				pColumnProps->Value <<= getLabelName(xCurrentModelSet);
				++pColumnProps;

				// for all other props : transfer them
				Reference< XPropertySetInfo> xControlModelInfo( xCurrentModelSet->getPropertySetInfo());
				DBG_ASSERT(xControlModelInfo.is(), "FmXFormShell::CreateExternalView : the control model has no property info ! This will crash !");
				aProps = xControlModelInfo->getProperties();
				const Property* pProps = aProps.getConstArray();

				// realloc the control description sequence
				sal_Int32 nExistentDescs = pColumnProps - aColumnProps.getArray();
				aColumnProps.realloc(nExistentDescs + aProps.getLength());
				pColumnProps = aColumnProps.getArray() + nExistentDescs;

				for (sal_Int32 i=0; i<aProps.getLength(); ++i, ++pProps)
				{
					if (pProps->Name.equals(FM_PROP_LABEL))
						// already set
						continue;
					if (pProps->Name.equals(FM_PROP_DEFAULTCONTROL))
						// allow the column's own "default control"
						continue;
					if (pProps->Attributes & PropertyAttribute::READONLY)
						// assume that properties which are readonly for the control are ro for the column to be created, too
						continue;

					pColumnProps->Name = pProps->Name;
					pColumnProps->Value = xCurrentModelSet->getPropertyValue(pProps->Name);
					++pColumnProps;
				}
				aColumnProps.realloc(pColumnProps - aColumnProps.getArray());

				// columns props are a dispatch argument
				pDispatchArgs->Name = ::rtl::OUString::createFromAscii("ColumnProperties"); // TODO : fmurl.*
				pDispatchArgs->Value = makeAny(aColumnProps);
				++pDispatchArgs;
				DBG_ASSERT(nDispatchArgs == (pDispatchArgs - aDispatchArgs.getConstArray()),
					"FmXFormShell::CreateExternalView : forgot to adjust nDispatchArgs ?");

				// dispatch the "add column"
				xAddColumnDispatch->dispatch(aAddColumnURL, aDispatchArgs);
				++nAddedColumns;
			}

			// now for the radio button handling
			sal_Int16 nOffset(0);
			// properties describing the "direct" column properties
			const sal_Int16 nListBoxDescription = 6;
			Sequence< PropertyValue> aListBoxDescription(nListBoxDescription);
			for (	ConstFmMapUString2UStringIterator aCtrlSource = aRadioControlSources.begin();
					aCtrlSource != aRadioControlSources.end();
					++aCtrlSource, ++nOffset
				)
			{

				PropertyValue* pListBoxDescription = aListBoxDescription.getArray();
				// label
				pListBoxDescription->Name = FM_PROP_LABEL;
				pListBoxDescription->Value <<= (*aCtrlSource).first;
				++pListBoxDescription;

				// control source
				pListBoxDescription->Name = FM_PROP_CONTROLSOURCE;
				pListBoxDescription->Value <<= (*aCtrlSource).second;
				++pListBoxDescription;

				// bound column
				pListBoxDescription->Name = FM_PROP_BOUNDCOLUMN;
				pListBoxDescription->Value <<= (sal_Int16)1;
				++pListBoxDescription;

				// content type
				pListBoxDescription->Name = FM_PROP_LISTSOURCETYPE;
				 ListSourceType eType = ListSourceType_VALUELIST;
				 pListBoxDescription->Value = makeAny(eType);
				++pListBoxDescription;

				// list source
				MapUString2UstringSeq::const_iterator aCurrentListSource = aRadioListSources.find((*aCtrlSource).first);
				DBG_ASSERT(aCurrentListSource != aRadioListSources.end(),
					"FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
				pListBoxDescription->Name = FM_PROP_LISTSOURCE;
				pListBoxDescription->Value = makeAny((*aCurrentListSource).second);
				++pListBoxDescription;

				// value list
				MapUString2UstringSeq::const_iterator aCurrentValueList = aRadioValueLists.find((*aCtrlSource).first);
				DBG_ASSERT(aCurrentValueList != aRadioValueLists.end(),
					"FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
				pListBoxDescription->Name = FM_PROP_STRINGITEMLIST;
				pListBoxDescription->Value = makeAny(((*aCurrentValueList).second));
				++pListBoxDescription;

				DBG_ASSERT(nListBoxDescription == (pListBoxDescription - aListBoxDescription.getConstArray()),
					"FmXFormShell::CreateExternalView : forgot to adjust nListBoxDescription ?");

				// properties describing the column "meta data"
				const sal_Int16 nDispatchArgs = 3;
				Sequence< PropertyValue> aDispatchArgs(nDispatchArgs);
				PropertyValue* pDispatchArgs = aDispatchArgs.getArray();

				// column type : listbox
				pDispatchArgs->Name = FMARG_ADDCOL_COLUMNTYPE;
				::rtl::OUString fColName = FM_COL_LISTBOX;
				pDispatchArgs->Value <<= fColName;
//				pDispatchArgs->Value <<= (::rtl::OUString)FM_COL_LISTBOX;
				++pDispatchArgs;

				// column position
				pDispatchArgs->Name = FMARG_ADDCOL_COLUMNPOS;
				FmMapUString2Int16::const_iterator aOffset = aRadioPositions.find((*aCtrlSource).first);
				DBG_ASSERT(aOffset != aRadioPositions.end(),
					"FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
				sal_Int16 nPosition = (*aOffset).second;
				nPosition = nPosition + nOffset;
					// we alread inserted nOffset additinal columns ....
				pDispatchArgs->Value <<= nPosition;
				++pDispatchArgs;

				// the
				pDispatchArgs->Name = ::rtl::OUString::createFromAscii("ColumnProperties"); // TODO : fmurl.*
				pDispatchArgs->Value = makeAny(aListBoxDescription);
				++pDispatchArgs;
				DBG_ASSERT(nDispatchArgs == (pDispatchArgs - aDispatchArgs.getConstArray()),
					"FmXFormShell::CreateExternalView : forgot to adjust nDispatchArgs ?");

				// dispatch the "add column"
				xAddColumnDispatch->dispatch(aAddColumnURL, aDispatchArgs);
				++nAddedColumns;
			}


			DBG_ASSERT(nAddedColumns > 0, "FmXFormShell::CreateExternalView : no controls (inconsistent) !");
				// we should have checked if we have any usable controls (see above).

			// "load" the "form" of the external view
			PropertyValue aArg;
			aArg.Name = FMARG_ATTACHTO_MASTERFORM;
			Reference< XResultSet> xForm(xCurrentNavController->getModel(), UNO_QUERY);
			aArg.Value <<= xForm;

			m_xExternalDisplayedForm = Reference< XResultSet>(xForm, UNO_QUERY);
				// do this before dispatching the "attach" command, as the atach may result in a call to our queryDispatch (for the FormSlots)
				// whichs needs the m_xExternalDisplayedForm

			xAttachDispatch->dispatch(aAttachURL, Sequence< PropertyValue>(&aArg, 1));

			m_xExtViewTriggerController = xCurrentNavController;

			// we want to know modifications done in the external view
			// if the external controller is a XFormController we can use all our default handlings for it
			Reference< runtime::XFormController > xFormController( m_xExternalViewController, UNO_QUERY );
            OSL_ENSURE( xFormController.is(), "FmXFormShell::CreateExternalView:: invalid external view controller!" );
			if (xFormController.is())
				xFormController->addActivateListener((XFormControllerListener*)this);
		}
	}
#ifdef DBG_UTIL
	else
	{
		DBG_ERROR("FmXFormShell::CreateExternalView : could not create the external form view !");
	}
#endif
	InvalidateSlot( SID_FM_VIEW_AS_GRID, sal_False );
}

//------------------------------------------------------------------------
void FmXFormShell::implAdjustConfigCache()
{
	// get (cache) the wizard usage flag
	Sequence< ::rtl::OUString > aNames(1);
	aNames[0] = ::rtl::OUString::createFromAscii("FormControlPilotsEnabled");
	Sequence< Any > aFlags = GetProperties(aNames);
	if (1 == aFlags.getLength())
		m_bUseWizards = ::cppu::any2bool(aFlags[0]);
}

//------------------------------------------------------------------------
void FmXFormShell::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& _rPropertyNames)
{
    if ( impl_checkDisposed() )
        return;

    const ::rtl::OUString* pSearch = _rPropertyNames.getConstArray();
	const ::rtl::OUString* pSearchTil = pSearch + _rPropertyNames.getLength();
	for (;pSearch < pSearchTil; ++pSearch)
		if (0 == pSearch->compareToAscii("FormControlPilotsEnabled"))
		{
			implAdjustConfigCache();
			InvalidateSlot( SID_FM_USE_WIZARDS, sal_True );
		}
}

void FmXFormShell::Commit()
{
}

//------------------------------------------------------------------------
void FmXFormShell::SetWizardUsing(sal_Bool _bUseThem)
{
	m_bUseWizards = _bUseThem;

	Sequence< ::rtl::OUString > aNames(1);
	aNames[0] = ::rtl::OUString::createFromAscii("FormControlPilotsEnabled");
	Sequence< Any > aValues(1);
	aValues[0] = ::cppu::bool2any(m_bUseWizards);
	PutProperties(aNames, aValues);
}

//------------------------------------------------------------------------
void FmXFormShell::viewDeactivated( FmFormView& _rCurrentView, sal_Bool _bDeactivateController /* = sal_True */ )
{

	if ( _rCurrentView.GetImpl() && !_rCurrentView.IsDesignMode() )
	{
		_rCurrentView.GetImpl()->Deactivate( _bDeactivateController );
	}

	// if we have an async load operation pending for the 0-th page for this view,
	// we need to cancel this
	// 103727 - 2002-09-26 - fs@openoffice.org
    FmFormPage* pPage = _rCurrentView.GetCurPage();
	if ( pPage )
	{
		// move all events from our queue to a new one, omit the events for the deactivated
		// page
		::std::queue< FmLoadAction > aNewEvents;
		while ( !m_aLoadingPages.empty() )
		{
			FmLoadAction aAction = m_aLoadingPages.front();
			m_aLoadingPages.pop();
			if ( pPage != aAction.pPage )
			{
				aNewEvents.push( aAction );
			}
			else
			{
				Application::RemoveUserEvent( aAction.nEventId );
			}
		}
		m_aLoadingPages = aNewEvents;
	}

    // remove callbacks at the page
    if ( pPage )
    {
        pPage->GetImpl().SetFormsCreationHdl( Link() );
    }
    UpdateForms( sal_True );
}

//------------------------------------------------------------------------
IMPL_LINK( FmXFormShell, OnFirstTimeActivation, void*, /*NOTINTERESTEDIN*/ )
{
    if ( impl_checkDisposed() )
        return 0L;

    m_nActivationEvent = 0;
    SfxObjectShell* pDocument = m_pShell->GetObjectShell();

    if  ( pDocument && !pDocument->HasName() )
    {
        if ( isEnhancedForm() )
        {
            // show the data navigator
	        if ( !m_pShell->GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_SHOW_DATANAVIGATOR ) )
		        m_pShell->GetViewShell()->GetViewFrame()->ToggleChildWindow( SID_FM_SHOW_DATANAVIGATOR );
        }
    }

    return 0L;
}

//------------------------------------------------------------------------
IMPL_LINK( FmXFormShell, OnFormsCreated, FmFormPage*, /*_pPage*/ )
{
    UpdateForms( sal_True );
    return 0L;
}

//------------------------------------------------------------------------
void FmXFormShell::viewActivated( FmFormView& _rCurrentView, sal_Bool _bSyncAction /* = sal_False */ )
{

    FmFormPage* pPage = _rCurrentView.GetCurPage();

    // activate our view if we are activated ourself
	// FS - 30.06.99 - 67308
	if ( _rCurrentView.GetImpl() && !_rCurrentView.IsDesignMode() )
	{
		// load forms for the page the current view belongs to
		if ( pPage )
		{
			if ( !pPage->GetImpl().hasEverBeenActivated() )
				loadForms( pPage, FORMS_LOAD | ( _bSyncAction ? FORMS_SYNC : FORMS_ASYNC ) );
			pPage->GetImpl().setHasBeenActivated( );
		}

		// first-time initializations for the views
		if ( !_rCurrentView.GetImpl()->hasEverBeenActivated( ) )
		{
			_rCurrentView.GetImpl()->onFirstViewActivation( PTR_CAST( FmFormModel, _rCurrentView.GetModel() ) );
			_rCurrentView.GetImpl()->setHasBeenActivated( );
		}

		// activate the current view
		_rCurrentView.GetImpl()->Activate( _bSyncAction );
	}

    // set callbacks at the page
    if ( pPage )
    {
        pPage->GetImpl().SetFormsCreationHdl( LINK( this, FmXFormShell, OnFormsCreated ) );
    }

    UpdateForms( sal_True );

    if ( !hasEverBeenActivated() )
    {
        m_nActivationEvent = Application::PostUserEvent( LINK( this, FmXFormShell, OnFirstTimeActivation ) );
        setHasBeenActivated();
    }

    // find a default "current form", if there is none, yet
    // #i88186# / 2008-04-12 / frank.schoenheit@sun.com
    impl_defaultCurrentForm_nothrow();
}

//------------------------------------------------------------------------------
void FmXFormShell::impl_defaultCurrentForm_nothrow()
{
    if ( impl_checkDisposed() )
        return;

    if ( m_xCurrentForm.is() )
        // no action required
        return;

    FmFormView* pFormView = m_pShell->GetFormView();
    FmFormPage* pPage = pFormView ? pFormView->GetCurPage() : NULL;
    if ( !pPage )
        return;

    try
    {
        Reference< XIndexAccess > xForms( pPage->GetForms( false ), UNO_QUERY );
        if ( !xForms.is() || !xForms->hasElements() )
            return;

        Reference< XForm > xNewCurrentForm( xForms->getByIndex(0), UNO_QUERY_THROW );
        impl_updateCurrentForm( xNewCurrentForm );
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------------
void FmXFormShell::smartControlReset( const Reference< XIndexAccess >& _rxModels )
{
	if (!_rxModels.is())
	{
		DBG_ERROR("FmXFormShell::smartControlReset: invalid container!");
		return;
	}

	static const ::rtl::OUString sClassIdPropertyName = FM_PROP_CLASSID;
	static const ::rtl::OUString sBoundFieldPropertyName = FM_PROP_BOUNDFIELD;
	sal_Int32 nCount = _rxModels->getCount();
	Reference< XPropertySet > xCurrent;
	Reference< XPropertySetInfo > xCurrentInfo;
	Reference< XPropertySet > xBoundField;

	for (sal_Int32 i=0; i<nCount; ++i)
	{
		_rxModels->getByIndex(i) >>= xCurrent;
		if (xCurrent.is())
			xCurrentInfo = xCurrent->getPropertySetInfo();
		else
			xCurrentInfo.clear();
		if (!xCurrentInfo.is())
			continue;

		if (xCurrentInfo->hasPropertyByName(sClassIdPropertyName))
		{	// it's a control model

			// check if this control is bound to a living database field
			if (xCurrentInfo->hasPropertyByName(sBoundFieldPropertyName))
				xCurrent->getPropertyValue(sBoundFieldPropertyName) >>= xBoundField;
			else
				xBoundField.clear();

            // reset only if it's *not* bound
            bool bReset = !xBoundField.is();

            // and additionally, check if it has an external value binding
            Reference< XBindableValue > xBindable( xCurrent, UNO_QUERY );
            if ( xBindable.is() && xBindable->getValueBinding().is() )
                bReset = false;

			if ( bReset )
			{
				Reference< XReset > xControlReset( xCurrent, UNO_QUERY );
				if ( xControlReset.is() )
					xControlReset->reset();
			}
		}
		else
		{
			Reference< XIndexAccess > xContainer(xCurrent, UNO_QUERY);
			if (xContainer.is())
				smartControlReset(xContainer);
		}
	}
}

//------------------------------------------------------------------------
IMPL_LINK( FmXFormShell, OnLoadForms, FmFormPage*, /*_pPage*/ )
{
	FmLoadAction aAction = m_aLoadingPages.front();
	m_aLoadingPages.pop();

	loadForms( aAction.pPage, aAction.nFlags & ~FORMS_ASYNC );
	return 0L;
}

//------------------------------------------------------------------------------
namespace
{
    sal_Bool lcl_isLoadable( const Reference< XInterface >& _rxLoadable )
    {
	    // determines whether a form should be loaded or not
	    // if there is no datasource or connection there is no reason to load a form
	    Reference< XPropertySet > xSet( _rxLoadable, UNO_QUERY );
	    if ( !xSet.is() )
            return sal_False;
	    try
	    {
		    Reference< XConnection > xConn;
            if ( OStaticDataAccessTools().isEmbeddedInDatabase( _rxLoadable.get(), xConn ) )
                return sal_True;

		    // is there already a active connection
		    xSet->getPropertyValue(FM_PROP_ACTIVE_CONNECTION) >>= xConn;
            if ( xConn.is() )
                return sal_True;

            ::rtl::OUString sPropertyValue;
            OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DATASOURCE ) >>= sPropertyValue );
            if ( sPropertyValue.getLength() )
                return sal_True;

            OSL_VERIFY( xSet->getPropertyValue( FM_PROP_URL ) >>= sPropertyValue );
            if ( sPropertyValue.getLength() )
                return sal_True;
	    }
	    catch(const Exception&)
	    {
            DBG_UNHANDLED_EXCEPTION();
	    }
	    return sal_False;
    }
}

//------------------------------------------------------------------------
void FmXFormShell::loadForms( FmFormPage* _pPage, const sal_uInt16 _nBehaviour /* FORMS_LOAD | FORMS_SYNC */ )
{
	DBG_ASSERT( ( _nBehaviour & ( FORMS_ASYNC | FORMS_UNLOAD ) )  != ( FORMS_ASYNC | FORMS_UNLOAD ),
		"FmXFormShell::loadForms: async loading not supported - this will heavily fail!" );

	if ( _nBehaviour & FORMS_ASYNC )
	{
		m_aLoadingPages.push( FmLoadAction(
			_pPage,
			_nBehaviour,
			Application::PostUserEvent( LINK( this, FmXFormShell, OnLoadForms ), _pPage )
		) );
		return;
	}

	DBG_ASSERT( _pPage, "FmXFormShell::loadForms: invalid page!" );
	if ( _pPage )
	{
		// lock the undo env so the forms can change non-transient properties while loading
		// (without this my doc's modified flag would be set)
		FmFormModel* pModel = PTR_CAST( FmFormModel, _pPage->GetModel() );
		DBG_ASSERT( pModel, "FmXFormShell::loadForms: invalid model!" );
		if ( pModel )
			pModel->GetUndoEnv().Lock();

		// load all forms
		Reference< XIndexAccess >  xForms;
		xForms = xForms.query( _pPage->GetForms( false ) );

		if ( xForms.is() )
		{
			Reference< XLoadable >  xForm;
            sal_Bool                bFormWasLoaded = sal_False;
			for ( sal_Int32 j = 0, nCount = xForms->getCount(); j < nCount; ++j )
			{
				xForms->getByIndex( j ) >>= xForm;
                bFormWasLoaded = sal_False;
				// a database form must be loaded for
                try
                {
				    if ( 0 == ( _nBehaviour & FORMS_UNLOAD ) )
				    {
					    if ( lcl_isLoadable( xForm ) && !xForm->isLoaded() )
						    xForm->load();
				    }
				    else
				    {
					    if ( xForm->isLoaded() )
                        {
                            bFormWasLoaded = sal_True;
						    xForm->unload();
                        }
				    }
                }
                catch( const Exception& )
                {
                	DBG_UNHANDLED_EXCEPTION();
                }

                // reset the form if it was loaded
                if ( bFormWasLoaded )
				{
					Reference< XIndexAccess > xContainer( xForm, UNO_QUERY );
					DBG_ASSERT( xContainer.is(), "FmXFormShell::loadForms: the form is no container!" );
					if ( xContainer.is() )
						smartControlReset( xContainer );
				}
			}
		}

		if ( pModel )
			// unlock the environment
			pModel->GetUndoEnv().UnLock();
	}
}

//------------------------------------------------------------------------
void FmXFormShell::ExecuteTextAttribute( SfxRequest& _rReq )
{
    m_pTextShell->ExecuteTextAttribute( _rReq );
}

//------------------------------------------------------------------------
void FmXFormShell::GetTextAttributeState( SfxItemSet& _rSet )
{
    m_pTextShell->GetTextAttributeState( _rSet );
}

//------------------------------------------------------------------------
bool FmXFormShell::IsActiveControl( bool _bCountRichTextOnly ) const
{
    return m_pTextShell->IsActiveControl( _bCountRichTextOnly );
}

//------------------------------------------------------------------------
void FmXFormShell::ForgetActiveControl()
{
    m_pTextShell->ForgetActiveControl();
}

//------------------------------------------------------------------------
void FmXFormShell::SetControlActivationHandler( const Link& _rHdl )
{
    m_pTextShell->SetControlActivationHandler( _rHdl );
}
//------------------------------------------------------------------------
void FmXFormShell::handleShowPropertiesRequest()
{
    if ( onlyControlsAreMarked() )
        ShowSelectionProperties( sal_True );
}

//------------------------------------------------------------------------
void FmXFormShell::handleMouseButtonDown( const SdrViewEvent& _rViewEvent )
{
    // catch simple double clicks
    if ( ( _rViewEvent.nMouseClicks == 2 ) && ( _rViewEvent.nMouseCode == MOUSE_LEFT ) )
    {
        if ( _rViewEvent.eHit == SDRHIT_MARKEDOBJECT )
        {
            if ( onlyControlsAreMarked() )
                ShowSelectionProperties( sal_True );
        }
    }
}

//------------------------------------------------------------------------------
bool FmXFormShell::HasControlFocus() const
{
    bool bHasControlFocus = false;

    try
    {
        Reference< XFormController > xController( getActiveController() );
        Reference< XControl > xCurrentControl;
        if ( xController.is() )
            xCurrentControl.set( xController->getCurrentControl() );
        if ( xCurrentControl.is() )
        {
            Reference< XWindow2 > xPeerWindow( xCurrentControl->getPeer(), UNO_QUERY_THROW );
            bHasControlFocus = xPeerWindow->hasFocus();
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }

    return bHasControlFocus;
}

//==============================================================================
//==============================================================================
SearchableControlIterator::SearchableControlIterator(Reference< XInterface> xStartingPoint)
	:IndexAccessIterator(xStartingPoint)
{
}

//------------------------------------------------------------------------------
sal_Bool SearchableControlIterator::ShouldHandleElement(const Reference< XInterface>& xElement)
{
	// wenn das Ding eine ControlSource und einen BoundField-Property hat
	Reference< XPropertySet> xProperties(xElement, UNO_QUERY);
	if (::comphelper::hasProperty(FM_PROP_CONTROLSOURCE, xProperties) && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xProperties))
	{
		// und das BoundField gueltig ist
		Reference< XPropertySet> xField;
		xProperties->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
		if (xField.is())
		{
			// nehmen wir's
			m_sCurrentValue = ::comphelper::getString(xProperties->getPropertyValue(FM_PROP_CONTROLSOURCE));
			return sal_True;
		}
	}

	// wenn es ein Grid-Control ist
	if (::comphelper::hasProperty(FM_PROP_CLASSID, xProperties))
	{
		Any aClassId( xProperties->getPropertyValue(FM_PROP_CLASSID) );
		if (::comphelper::getINT16(aClassId) == FormComponentType::GRIDCONTROL)
		{
			m_sCurrentValue = ::rtl::OUString();
			return sal_True;
		}
	}

	return sal_False;
}

//------------------------------------------------------------------------------
sal_Bool SearchableControlIterator::ShouldStepInto(const Reference< XInterface>& /*xContainer*/) const
{
	return sal_True;
}

//==============================================================================
//==============================================================================

SV_IMPL_PTRARR(StatusForwarderArray, SfxStatusForwarder*)

SFX_IMPL_MENU_CONTROL(ControlConversionMenuController, SfxBoolItem);

//------------------------------------------------------------------------------
ControlConversionMenuController::ControlConversionMenuController( sal_uInt16 _nId, Menu& _rMenu, SfxBindings& _rBindings )
	:SfxMenuControl( _nId, _rBindings )
	,m_pMainMenu( &_rMenu )
	,m_pConversionMenu( NULL )
{
	if ( _nId == SID_FM_CHANGECONTROLTYPE )
	{
		m_pConversionMenu = FmXFormShell::GetConversionMenu();
		_rMenu.SetPopupMenu( _nId, m_pConversionMenu );

		for (sal_Int16 i=0; i<m_pConversionMenu->GetItemCount(); ++i)
		{
			_rBindings.Invalidate(m_pConversionMenu->GetItemId(i));
			SfxStatusForwarder* pForwarder = new SfxStatusForwarder(m_pConversionMenu->GetItemId(i), *this);
			m_aStatusForwarders.C40_INSERT(SfxStatusForwarder, pForwarder, m_aStatusForwarders.Count());
		}
	}
}

//------------------------------------------------------------------------------
ControlConversionMenuController::~ControlConversionMenuController()
{
	m_pMainMenu->SetPopupMenu(SID_FM_CHANGECONTROLTYPE, NULL);
	delete m_pConversionMenu;
}

//------------------------------------------------------------------------------
void ControlConversionMenuController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
{
	if (nSID == GetId())
		SfxMenuControl::StateChanged(nSID, eState, pState);
	else if (FmXFormShell::isControlConversionSlot(nSID))
	{
		if ((m_pConversionMenu->GetItemPos(nSID) != MENU_ITEM_NOTFOUND) && (eState == SFX_ITEM_DISABLED))
		{
			m_pConversionMenu->RemoveItem(m_pConversionMenu->GetItemPos(nSID));
		}
		else if ((m_pConversionMenu->GetItemPos(nSID) == MENU_ITEM_NOTFOUND) && (eState != SFX_ITEM_DISABLED))
		{
			// We can't simply re-insert the item because we have a clear order for all the our items.
			// So first we have to determine the position of the item to insert.
			PopupMenu* pSource = FmXFormShell::GetConversionMenu();
			sal_uInt16 nSourcePos = pSource->GetItemPos(nSID);
			DBG_ASSERT(nSourcePos != MENU_ITEM_NOTFOUND, "ControlConversionMenuController::StateChanged : FmXFormShell supplied an invalid menu !");
			sal_uInt16 nPrevInSource = nSourcePos;
			sal_uInt16 nPrevInConversion = MENU_ITEM_NOTFOUND;
			while (nPrevInSource>0)
			{
				sal_Int16 nPrevId = pSource->GetItemId(--nPrevInSource);

				// do we have the source's predecessor in our conversion menu, too ?
				nPrevInConversion = m_pConversionMenu->GetItemPos(nPrevId);
				if (nPrevInConversion != MENU_ITEM_NOTFOUND)
					break;
			}
			if (MENU_ITEM_NOTFOUND == nPrevInConversion)
				// none of the items which precede the nSID-slot in the source menu are present in our conversion menu
				nPrevInConversion = sal::static_int_cast< sal_uInt16 >(-1);	// put the item at the first position
			m_pConversionMenu->InsertItem(nSID, pSource->GetItemText(nSID), pSource->GetItemBits(nSID), ++nPrevInConversion);
			m_pConversionMenu->SetItemImage(nSID, pSource->GetItemImage(nSID));
			m_pConversionMenu->SetHelpId(nSID, pSource->GetHelpId(nSID));

			delete pSource;
		}
		m_pMainMenu->EnableItem(SID_FM_CHANGECONTROLTYPE, m_pConversionMenu->GetItemCount() > 0);
	}
	else
	{
		DBG_ERROR("ControlConversionMenuController::StateChanged : unknown id !");
	}
}

//==============================================================================
