/**************************************************************
 * 
 * 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 <svx/dialmgr.hxx>
#include <svx/fmshell.hxx>
#include <svx/fmmodel.hxx>
#include <svx/fmpage.hxx>
#include <svx/svdpagv.hxx>
#include "svx/svditer.hxx"

#include "fmhelp.hrc"
#include "fmexpl.hrc"
#include "fmexpl.hxx"
#include "svx/fmresids.hrc"
#include "fmshimp.hxx"
#include "fmservs.hxx"
#include "fmundo.hxx"
#include "fmpgeimp.hxx"
#include "fmitems.hxx"
#include "fmobj.hxx"
#include "fmprop.hrc"
#include <vcl/wrkwin.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/property.hxx>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/script/XEventAttacherManager.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <svx/sdrpaintwindow.hxx>

#include <svx/svxdlg.hxx> //CHINA001
#include <svx/dialogs.hrc> //CHINA001
#include <rtl/logfile.hxx>
//............................................................................
namespace svxform
{
//............................................................................

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

	#define EXPLORER_SYNC_DELAY                 200
		// dieser Betrag an Millisekunden wird gewartet, ehe der Explorer nach einem Select oder Deselect die ::com::sun::star::sdbcx::View synchronisiert

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::form;
	using namespace ::com::sun::star::awt;
	using namespace ::com::sun::star::container;
	using namespace ::com::sun::star::script;
	using namespace ::com::sun::star::datatransfer;
	using namespace ::com::sun::star::datatransfer::clipboard;
	using namespace ::com::sun::star::sdb;

	//========================================================================
	// helper
	//========================================================================

	typedef ::std::map< Reference< XInterface >, SdrObject*, ::comphelper::OInterfaceCompare< XInterface > >
			MapModelToShape;
	typedef MapModelToShape::value_type ModelShapePair;

	//------------------------------------------------------------------------
	void	collectShapeModelMapping( SdrPage* _pPage, MapModelToShape& _rMapping )
	{
		OSL_ENSURE( _pPage, "collectShapeModelMapping: invalid arg!" );

		_rMapping.clear();

		SdrObjListIter aIter( *_pPage );
		while ( aIter.IsMore() )
		{
			SdrObject* pSdrObject = aIter.Next();
            FmFormObj* pFormObject = FmFormObj::GetFormObject( pSdrObject );
            if ( !pFormObject )
                continue;

			Reference< XInterface > xNormalizedModel( pFormObject->GetUnoControlModel(), UNO_QUERY );
				// note that this is normalized (i.e. queried for XInterface explicitly)

#ifdef DBG_UTIL
			::std::pair< MapModelToShape::iterator, bool > aPos =
#endif
			_rMapping.insert( ModelShapePair( xNormalizedModel, pSdrObject ) );
			DBG_ASSERT( aPos.second, "collectShapeModelMapping: model was already existent!" );
				// if this asserts, this would mean we have 2 shapes pointing to the same model
		}
	}

	//------------------------------------------------------------------------
	sal_Bool isModelShapeMarked( FmEntryData* _pEntry, const MapModelToShape& _rModelMap, SdrMarkView* _pView )
	{
		DBG_ASSERT( _pEntry && _pView, "isModelShapeMarked: invalid arguments!" );
		if ( !_pEntry || !_pView )
			return sal_False;

		DBG_ASSERT( _pEntry->GetElement().get() == Reference< XInterface >( _pEntry->GetElement(), UNO_QUERY ).get(),
			"isModelShapeMarked: element of the FmEntryData is not normalized!" );
			// normalization of the XInterface is a prerequisite for properly finding it in the map

		sal_Bool bIsMarked = sal_False;

		MapModelToShape::const_iterator aPos = _rModelMap.find( _pEntry->GetElement() );
		if ( _rModelMap.end() != aPos )
		{	// there is a shape for this model ....
			bIsMarked = _pView->IsObjMarked( aPos->second );
			if ( !bIsMarked )
			{
				// IsObjMarked does not step down grouped objects, so the sal_False we
				// have is not really reliable (while a sal_True would have been)
				// Okay, travel the mark list, and see if there is a group marked, and our shape
				// is a part of this group
				sal_uInt32 nMarked = _pView->GetMarkedObjectList().GetMarkCount();
				for ( sal_uInt32 i = 0; (i<nMarked ) && !bIsMarked; ++i )
				{
					SdrMark* pMark = _pView->GetMarkedObjectList().GetMark( i );
					SdrObject* pObj = pMark ? pMark->GetMarkedSdrObj() : NULL;
					if ( pObj && pObj->IsGroupObject() )
					{	// the i-th marked shape is a group shape
						SdrObjListIter aIter( *pObj );
						while ( aIter.IsMore() )
						{
							if ( aIter.Next() == aPos->second )
							{
								bIsMarked = sal_True;
								break;
							}
						}
					}
				}
			}
		}

		return bIsMarked;
	}

	//========================================================================
	// class NavigatorTree
	//========================================================================

	//------------------------------------------------------------------------
	NavigatorTree::NavigatorTree( const Reference< XMultiServiceFactory >& _xORB,
                           Window* pParent )
        :SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HSCROLL ) // #100258# OJ WB_HSCROLL added
        ,m_aControlExchange(this)
        ,m_xORB(_xORB)
        ,m_pNavModel( NULL )
        ,m_pRootEntry(NULL)
        ,m_pEditEntry(NULL)
        ,nEditEvent(0)
        ,m_sdiState(SDI_DIRTY)
        ,m_aTimerTriggered(-1,-1)
        ,m_aDropActionType( DA_SCROLLUP )
        ,m_nSelectLock(0)
        ,m_nFormsSelected(0)
        ,m_nControlsSelected(0)
        ,m_nHiddenControls(0)
        ,m_aTimerCounter( DROP_ACTION_TIMER_INITIAL_TICKS )
        ,m_bDragDataDirty(sal_False)
        ,m_bPrevSelectionMixed(sal_False)
        ,m_bMarkingObjects(sal_False)
        ,m_bRootSelected(sal_False)
        ,m_bInitialUpdate(sal_True)
        ,m_bKeyboardCut( sal_False )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::NavigatorTree" );
		SetHelpId( HID_FORM_NAVIGATOR );

		m_aNavigatorImages = ImageList( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
		m_aNavigatorImagesHC = ImageList( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );

		SetNodeBitmaps(
			m_aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
			m_aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
			BMP_COLOR_NORMAL
		);
		SetNodeBitmaps(
			m_aNavigatorImagesHC.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
			m_aNavigatorImagesHC.GetImage( RID_SVXIMG_EXPANDEDNODE ),
			BMP_COLOR_HIGHCONTRAST
		);

		SetDragDropMode(0xFFFF);
		EnableInplaceEditing( sal_True );
		SetSelectionMode(MULTIPLE_SELECTION);

		m_pNavModel = new NavigatorTreeModel( m_aNavigatorImages, m_aNavigatorImagesHC );
		Clear();

		StartListening( *m_pNavModel );

		m_aDropActionTimer.SetTimeoutHdl(LINK(this, NavigatorTree, OnDropActionTimer));

		m_aSynchronizeTimer.SetTimeoutHdl(LINK(this, NavigatorTree, OnSynchronizeTimer));
		SetSelectHdl(LINK(this, NavigatorTree, OnEntrySelDesel));
		SetDeselectHdl(LINK(this, NavigatorTree, OnEntrySelDesel));
	}

	//------------------------------------------------------------------------
	NavigatorTree::~NavigatorTree()
	{
		if( nEditEvent )
			Application::RemoveUserEvent( nEditEvent );

		if (m_aSynchronizeTimer.IsActive())
			m_aSynchronizeTimer.Stop();

		DBG_ASSERT(GetNavModel() != NULL, "NavigatorTree::~NavigatorTree : unerwartet : kein ExplorerModel");
		EndListening( *m_pNavModel );
		Clear();
		delete m_pNavModel;
	}

	//------------------------------------------------------------------------
	void NavigatorTree::Clear()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::Clear" );
		m_pNavModel->Clear();
	}

	//------------------------------------------------------------------------
	void NavigatorTree::UpdateContent( FmFormShell* pFormShell )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::UpdateContent" );
		if (m_bInitialUpdate)
		{
			GrabFocus();
			m_bInitialUpdate = sal_False;
		}

		FmFormShell* pOldShell = GetNavModel()->GetFormShell();
		FmFormPage* pOldPage = GetNavModel()->GetFormPage();
		FmFormPage* pNewPage = pFormShell ? pFormShell->GetCurPage() : NULL;

		if ((pOldShell != pFormShell) || (pOldPage != pNewPage))
		{
			// neue Shell, waehrend ich gerade editiere ?
			if (IsEditingActive())
				CancelTextEditing();

			m_bDragDataDirty = sal_True;    // sicherheitshalber, auch wenn ich gar nicht dragge
		}
		GetNavModel()->UpdateContent( pFormShell );

		// wenn es eine Form gibt, die Root expandieren
		if (m_pRootEntry && !IsExpanded(m_pRootEntry))
			Expand(m_pRootEntry);
		// wenn es GENAU eine Form gibt, auch diese expandieren
		if (m_pRootEntry)
		{
			SvLBoxEntry* pFirst = FirstChild(m_pRootEntry);
			if (pFirst && !NextSibling(pFirst))
				Expand(pFirst);
		}
	}

	//------------------------------------------------------------------------------
	sal_Bool NavigatorTree::implAllowExchange( sal_Int8 _nAction, sal_Bool* _pHasNonHidden )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::implAllowExchange" );
		SvLBoxEntry* pCurEntry = GetCurEntry();
		if (!pCurEntry)
			return sal_False;

		// die Informationen fuer das AcceptDrop und ExecuteDrop
		CollectSelectionData(SDI_ALL);
		if (!m_arrCurrentSelection.Count())
			// nothing to do
			return sal_False;

		// testen, ob es sich vielleicht ausschliesslich um hidden controls handelt (dann koennte ich pCtrlExch noch ein
		// zusaetzliches Format geben)
		sal_Bool bHasNonHidden = sal_False;
		for (sal_Int32 i=0; i<m_arrCurrentSelection.Count(); i++)
		{
			FmEntryData* pCurrent = static_cast< FmEntryData* >( m_arrCurrentSelection[(sal_uInt16)i]->GetUserData() );
			if ( IsHiddenControl( pCurrent ) )
				continue;
			bHasNonHidden = sal_True;
			break;
		}

		if ( bHasNonHidden && ( 0 == ( _nAction & DND_ACTION_MOVE ) ) )
			// non-hidden controls need to be moved
			return sal_False;

		if ( _pHasNonHidden )
			*_pHasNonHidden = bHasNonHidden;

		return sal_True;
	}

	//------------------------------------------------------------------------------
	sal_Bool NavigatorTree::implPrepareExchange( sal_Int8 _nAction )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::implPrepareExchange" );
		sal_Int32 i;

		EndSelection();

		sal_Bool bHasNonHidden = sal_False;
		if ( !implAllowExchange( _nAction, &bHasNonHidden ) )
			return sal_False;

		m_aControlExchange.prepareDrag();
		m_aControlExchange->setFocusEntry( GetCurEntry() );

		for ( i = 0; i < m_arrCurrentSelection.Count(); ++i )
			m_aControlExchange->addSelectedEntry(m_arrCurrentSelection[(sal_uInt16)i]);

		m_aControlExchange->setFormsRoot( GetNavModel()->GetFormPage()->GetForms() );
		m_aControlExchange->buildPathFormat( this, m_pRootEntry );

		if (!bHasNonHidden)
		{
			// eine entsprechende Sequenz aufbauen
			Sequence< Reference< XInterface > > seqIFaces(m_arrCurrentSelection.Count());
			Reference< XInterface >* pArray = seqIFaces.getArray();
			for (i=0; i<m_arrCurrentSelection.Count(); ++i, ++pArray)
				*pArray = static_cast< FmEntryData* >( m_arrCurrentSelection[(sal_uInt16)i]->GetUserData() )->GetElement();

			// und das neue Format
			m_aControlExchange->addHiddenControlsFormat(seqIFaces);
		}

		m_bDragDataDirty = sal_False;
		return sal_True;
	}

	//------------------------------------------------------------------------------
	void NavigatorTree::StartDrag( sal_Int8 /*nAction*/, const ::Point& /*rPosPixel*/ )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::StartDrag" );
		EndSelection();

		if ( !implPrepareExchange( DND_ACTION_COPYMOVE ) )
			// nothing to do or something went wrong
			return;

		// jetzt haben wir alle in der aktuelle Situation moeglichen Formate eingesammelt, es kann also losgehen ...
		m_aControlExchange.startDrag( DND_ACTION_COPYMOVE );
	}

	//------------------------------------------------------------------------------
	void NavigatorTree::Command( const CommandEvent& rEvt )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::Command" );
		sal_Bool bHandled = sal_False;
		switch( rEvt.GetCommand() )
		{
			case COMMAND_CONTEXTMENU:
			{
				// die Stelle, an der geklickt wurde
				::Point ptWhere;
				if (rEvt.IsMouseEvent())
				{
					ptWhere = rEvt.GetMousePosPixel();
					SvLBoxEntry* ptClickedOn = GetEntry(ptWhere);
					if (ptClickedOn == NULL)
						break;
					if ( !IsSelected(ptClickedOn) )
					{
						SelectAll(sal_False);
						Select(ptClickedOn, sal_True);
						SetCurEntry(ptClickedOn);
					}
				}
				else
				{
					if (m_arrCurrentSelection.Count() == 0) // kann nur bei Kontextmenue ueber Tastatur passieren
						break;

					SvLBoxEntry* pCurrent = GetCurEntry();
					if (!pCurrent)
						break;
					ptWhere = GetEntryPosition(pCurrent);
				}

				// meine Selektionsdaten auf den aktuellen Stand
				CollectSelectionData(SDI_ALL);

				// wenn mindestens ein Nicht-Root-Eintrag selektiert ist und die Root auch, dann nehme ich letztere aus der Selektion
				// fix wieder raus
				if ( (m_arrCurrentSelection.Count() > 1) && m_bRootSelected )
				{
					Select( m_pRootEntry, sal_False );
					SetCursor( m_arrCurrentSelection.GetObject(0), sal_True);
				}
				sal_Bool bSingleSelection = (m_arrCurrentSelection.Count() == 1);


				DBG_ASSERT( (m_arrCurrentSelection.Count() > 0) || m_bRootSelected, "keine Eintraege selektiert" );
					// solte nicht passieren, da ich oben bei der IsSelected-Abfrage auf jeden Fall einen selektiert haette,
					// wenn das vorher nicht der Fall gewesen waere


				// das Menue zusammenbasteln
				FmFormShell* pFormShell = GetNavModel()->GetFormShell();
				FmFormModel* pFormModel = pFormShell ? pFormShell->GetFormModel() : NULL;
				if( pFormShell && pFormModel )
				{
					PopupMenu aContextMenu(SVX_RES(RID_FMEXPLORER_POPUPMENU));
					PopupMenu* pSubMenuNew = aContextMenu.GetPopupMenu( SID_FM_NEW );

					// das 'Neu'-Untermenue gibt es nur, wenn genau die Root oder genau ein Formular selektiert sind
					aContextMenu.EnableItem( SID_FM_NEW, bSingleSelection && (m_nFormsSelected || m_bRootSelected) );

					// 'Neu'\'Formular' unter genau den selben Bedingungen
					pSubMenuNew->EnableItem( SID_FM_NEW_FORM, bSingleSelection && (m_nFormsSelected || m_bRootSelected) );
					pSubMenuNew->SetItemImage(SID_FM_NEW_FORM, m_aNavigatorImages.GetImage(RID_SVXIMG_FORM));
					pSubMenuNew->SetItemImage(SID_FM_NEW_HIDDEN, m_aNavigatorImages.GetImage(RID_SVXIMG_HIDDEN));

					// 'Neu'\'verstecktes...', wenn genau ein Formular selektiert ist
					pSubMenuNew->EnableItem( SID_FM_NEW_HIDDEN, bSingleSelection && m_nFormsSelected );

					// 'Delete': everything which is not root can be removed
					aContextMenu.EnableItem( SID_FM_DELETE, !m_bRootSelected );

					// 'Cut', 'Copy' and 'Paste'
					aContextMenu.EnableItem( SID_CUT, !m_bRootSelected && implAllowExchange( DND_ACTION_MOVE ) );
					aContextMenu.EnableItem( SID_COPY, !m_bRootSelected && implAllowExchange( DND_ACTION_COPY ) );
					aContextMenu.EnableItem( SID_PASTE, implAcceptPaste( ) );

					// der TabDialog, wenn es genau ein Formular ist ...
					aContextMenu.EnableItem( SID_FM_TAB_DIALOG, bSingleSelection && m_nFormsSelected );

                    // in XML forms, we don't allow for the properties of a form
                    // #i36484# / 2004-11-04 /- fs@openoffice.org
                    if ( pFormShell->GetImpl()->isEnhancedForm() && !m_nControlsSelected )
                        aContextMenu.RemoveItem( aContextMenu.GetItemPos( SID_FM_SHOW_PROPERTY_BROWSER ) );

                    // if the property browser is already open, we don't allow for the properties, too
					if( pFormShell->GetImpl()->IsPropBrwOpen() )
						aContextMenu.RemoveItem( aContextMenu.GetItemPos( SID_FM_SHOW_PROPERTY_BROWSER ) );
                    // and finally, if there's a mixed selection of forms and controls, disable the entry, too
					else
						aContextMenu.EnableItem( SID_FM_SHOW_PROPERTY_BROWSER,
							(m_nControlsSelected && !m_nFormsSelected) || (!m_nControlsSelected && m_nFormsSelected) );

					// Umbenennen gdw wenn ein Element und nicht die Root
					aContextMenu.EnableItem( SID_FM_RENAME_OBJECT, bSingleSelection && !m_bRootSelected );

					// der Reandonly-Eintrag ist nur auf der Root erlaubt
					aContextMenu.EnableItem( SID_FM_OPEN_READONLY, m_bRootSelected );
					// the same for automatic control focus
					aContextMenu.EnableItem( SID_FM_AUTOCONTROLFOCUS, m_bRootSelected );

					// die ConvertTo-Slots sind enabled, wenn genau ein Control selektiert ist, der
					// dem Control entsprechende Slot ist disabled
					if (!m_bRootSelected && !m_nFormsSelected && (m_nControlsSelected == 1))
					{
						aContextMenu.SetPopupMenu( SID_FM_CHANGECONTROLTYPE, FmXFormShell::GetConversionMenu() );
#if OSL_DEBUG_LEVEL > 0
						FmControlData* pCurrent = (FmControlData*)(m_arrCurrentSelection[0]->GetUserData());
                        OSL_ENSURE( pFormShell->GetImpl()->isSolelySelected( pCurrent->GetFormComponent() ),
                            "NavigatorTree::Command: inconsistency between the navigator selection, and the selection as the shell knows it!" );
#endif

                        pFormShell->GetImpl()->checkControlConversionSlotsForCurrentSelection( *aContextMenu.GetPopupMenu( SID_FM_CHANGECONTROLTYPE ) );
					}
					else
						aContextMenu.EnableItem( SID_FM_CHANGECONTROLTYPE, sal_False );

					// jetzt alles, was disabled wurde, wech
					aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
					//////////////////////////////////////////////////////////
					// OpenReadOnly setzen

					aContextMenu.CheckItem( SID_FM_OPEN_READONLY, pFormModel->GetOpenInDesignMode() );
					aContextMenu.CheckItem( SID_FM_AUTOCONTROLFOCUS, pFormModel->GetAutoControlFocus() );

					sal_uInt16 nSlotId = aContextMenu.Execute( this, ptWhere );
					switch( nSlotId )
					{
						case SID_FM_NEW_FORM:
						{
							XubString aStr(SVX_RES(RID_STR_FORM));
							XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
							aUndoStr.SearchAndReplace('#', aStr);

							pFormModel->BegUndo(aUndoStr);
							// der Slot war nur verfuegbar, wenn es genau einen selektierten Eintrag gibt und dieser die Root
							// oder ein Formular ist
							NewForm( m_arrCurrentSelection.GetObject(0) );
							pFormModel->EndUndo();

						}   break;
						case SID_FM_NEW_HIDDEN:
						{
							XubString aStr(SVX_RES(RID_STR_CONTROL));
							XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
							aUndoStr.SearchAndReplace('#', aStr);

							pFormModel->BegUndo(aUndoStr);
							// dieser Slot war guletig bei (genau) einem selektierten Formular
							rtl::OUString fControlName = FM_COMPONENT_HIDDEN;
							NewControl( fControlName, m_arrCurrentSelection.GetObject(0) );
							pFormModel->EndUndo();

						}   break;

						case SID_CUT:
							doCut();
							break;

						case SID_COPY:
							doCopy();
							break;

						case SID_PASTE:
							doPaste();
							break;

						case SID_FM_DELETE:
						{
							DeleteSelection();
						}
						break;
						case SID_FM_TAB_DIALOG:
						{
							// dieser Slot galt bei genau einem selektierten Formular
							SvLBoxEntry* pSelectedForm = m_arrCurrentSelection.GetObject(0);
							DBG_ASSERT( IsFormEntry(pSelectedForm), "NavigatorTree::Command: Dieser Eintrag muss ein FormEntry sein." );

							FmFormData* pFormData = (FmFormData*)pSelectedForm->GetUserData();
							Reference< XForm >  xForm(  pFormData->GetFormIface());

							Reference< XTabControllerModel >  xTabController(xForm, UNO_QUERY);
							if( !xTabController.is() )
                                break;
                            GetNavModel()->GetFormShell()->GetImpl()->ExecuteTabOrderDialog( xTabController );
						}
						break;

						case SID_FM_SHOW_PROPERTY_BROWSER:
						{
							ShowSelectionProperties(sal_True);
						}
						break;
						case SID_FM_RENAME_OBJECT:
						{
							// das war bei genau einem Nicht-Root-Eintrag erlaubt
							EditEntry( m_arrCurrentSelection.GetObject(0) );
						}
						break;
						case SID_FM_OPEN_READONLY:
						{
							pFormModel->SetOpenInDesignMode( !pFormModel->GetOpenInDesignMode() );
							pFormShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_OPEN_READONLY);
						}
						break;
						case SID_FM_AUTOCONTROLFOCUS:
						{
							pFormModel->SetAutoControlFocus( !pFormModel->GetAutoControlFocus() );
							pFormShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_AUTOCONTROLFOCUS);
						}
						break;
						default:
							if (pFormShell->GetImpl()->isControlConversionSlot(nSlotId))
							{
								FmControlData* pCurrent = (FmControlData*)(m_arrCurrentSelection[0]->GetUserData());
								if ( pFormShell->GetImpl()->executeControlConversionSlot( pCurrent->GetFormComponent(), nSlotId ) )
									ShowSelectionProperties();
							}
					}
				}
				bHandled = sal_True;
			} break;
		}

		if (!bHandled)
			SvTreeListBox::Command( rEvt );
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::IsDeleteAllowed()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::IsDeleteAllowed" );
		//////////////////////////////////////////////////////////////////////
		// Haben wir eine Form...
		SvLBoxEntry* pCurEntry = GetCurEntry();
		sal_uInt32 nCurEntryPos = GetModel()->GetAbsPos( pCurEntry );

		if( nCurEntryPos==0 )           // Root kann nicht geloescht werden
			return sal_False;
		else
			return IsFormEntry(pCurEntry) || IsFormComponentEntry(pCurEntry);
	}

	//------------------------------------------------------------------------
	SvLBoxEntry* NavigatorTree::FindEntry( FmEntryData* pEntryData )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::FindEntry" );
		if( !pEntryData ) return NULL;
		SvLBoxEntry* pCurEntry = First();
		FmEntryData* pCurEntryData;
		while( pCurEntry )
		{
			pCurEntryData = (FmEntryData*)pCurEntry->GetUserData();
			if( pCurEntryData && pCurEntryData->IsEqualWithoutChilds(pEntryData) )
				return pCurEntry;

			pCurEntry = Next( pCurEntry );
		}

		return NULL;
	}

	//------------------------------------------------------------------------
	void NavigatorTree::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::Notify" );
		if( rHint.ISA(FmNavRemovedHint) )
		{
			FmNavRemovedHint* pRemovedHint = (FmNavRemovedHint*)&rHint;
			FmEntryData* pEntryData = pRemovedHint->GetEntryData();
			Remove( pEntryData );
		}

		else if( rHint.ISA(FmNavInsertedHint) )
		{
			FmNavInsertedHint* pInsertedHint = (FmNavInsertedHint*)&rHint;
			FmEntryData* pEntryData = pInsertedHint->GetEntryData();
			sal_uInt32 nRelPos = pInsertedHint->GetRelPos();
			Insert( pEntryData, nRelPos );
		}

		else if( rHint.ISA(FmNavModelReplacedHint) )
		{
			FmEntryData* pData = ((FmNavModelReplacedHint*)&rHint)->GetEntryData();
			SvLBoxEntry* pEntry = FindEntry( pData );
			if (pEntry)
			{   // das Image neu setzen
				SetCollapsedEntryBmp( pEntry, pData->GetNormalImage(), BMP_COLOR_NORMAL );
				SetExpandedEntryBmp( pEntry, pData->GetNormalImage(), BMP_COLOR_NORMAL );

				SetCollapsedEntryBmp( pEntry, pData->GetHCImage(), BMP_COLOR_HIGHCONTRAST );
				SetExpandedEntryBmp( pEntry, pData->GetHCImage(), BMP_COLOR_HIGHCONTRAST );
			}
		}

		else if( rHint.ISA(FmNavNameChangedHint) )
		{
			FmNavNameChangedHint* pNameChangedHint = (FmNavNameChangedHint*)&rHint;
			SvLBoxEntry* pEntry = FindEntry( pNameChangedHint->GetEntryData() );
			SetEntryText( pEntry, pNameChangedHint->GetNewName() );
		}

		else if( rHint.ISA(FmNavClearedHint) )
		{
			SvTreeListBox::Clear();

			//////////////////////////////////////////////////////////////////////
			// Default-Eintrag "Formulare"
			Image aRootImage( m_aNavigatorImages.GetImage( RID_SVXIMG_FORMS ) );
			m_pRootEntry = InsertEntry( SVX_RES(RID_STR_FORMS), aRootImage, aRootImage,
				NULL, sal_False, 0, NULL );

			if ( m_pRootEntry )
			{
				Image aHCRootImage( m_aNavigatorImagesHC.GetImage( RID_SVXIMG_FORMS ) );
				SetExpandedEntryBmp( m_pRootEntry, aHCRootImage, BMP_COLOR_HIGHCONTRAST );
				SetCollapsedEntryBmp( m_pRootEntry, aHCRootImage, BMP_COLOR_HIGHCONTRAST );
			}
		}
		else if (!m_bMarkingObjects && rHint.ISA(FmNavRequestSelectHint))
		{   // wenn m_bMarkingObjects sal_True ist, markiere ich gerade selber Objekte, und da der ganze Mechanismus dahinter synchron ist,
			// ist das genau der Hint, der durch mein Markieren ausgeloest wird, also kann ich ihn ignorieren
			FmNavRequestSelectHint* pershHint = (FmNavRequestSelectHint*)&rHint;
			FmEntryDataArray& arredToSelect = pershHint->GetItems();
			SynchronizeSelection(arredToSelect);

			if (pershHint->IsMixedSelection())
				// in diesem Fall habe ich alles deselektiert, obwohl die View u.U. eine gemischte Markierung hatte
				// ich muss also im naechsten Select den Navigator an die View anpassen
				m_bPrevSelectionMixed = sal_True;
		}
	}

	//------------------------------------------------------------------------
	SvLBoxEntry* NavigatorTree::Insert( FmEntryData* pEntryData, sal_uIntPtr nRelPos )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::Insert" );
		//////////////////////////////////////////////////////////////////////
		// Aktuellen Eintrag einfuegen
		SvLBoxEntry* pParentEntry = FindEntry( pEntryData->GetParent() );
		SvLBoxEntry* pNewEntry;

		if( !pParentEntry )
			pNewEntry = InsertEntry( pEntryData->GetText(),
				pEntryData->GetNormalImage(), pEntryData->GetNormalImage(),
				m_pRootEntry, sal_False, nRelPos, pEntryData );

		else
			pNewEntry = InsertEntry( pEntryData->GetText(),
				pEntryData->GetNormalImage(), pEntryData->GetNormalImage(),
				pParentEntry, sal_False, nRelPos, pEntryData );

		if ( pNewEntry )
		{
			SetExpandedEntryBmp( pNewEntry, pEntryData->GetHCImage(), BMP_COLOR_HIGHCONTRAST );
			SetCollapsedEntryBmp( pNewEntry, pEntryData->GetHCImage(), BMP_COLOR_HIGHCONTRAST );
		}

		//////////////////////////////////////////////////////////////////////
		// Wenn Root-Eintrag Root expandieren
		if( !pParentEntry )
			Expand( m_pRootEntry );

		//////////////////////////////////////////////////////////////////////
		// Childs einfuegen
		FmEntryDataList* pChildList = pEntryData->GetChildList();
		sal_uInt32 nChildCount = pChildList->Count();
		FmEntryData* pChildData;
		for( sal_uInt32 i=0; i<nChildCount; i++ )
		{
			pChildData = pChildList->GetObject(i);
			Insert( pChildData, LIST_APPEND );
		}

		return pNewEntry;
	}

	//------------------------------------------------------------------------
	void NavigatorTree::Remove( FmEntryData* pEntryData )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::Remove" );
		if( !pEntryData )
			return;

		// der Entry zu den Daten
		SvLBoxEntry* pEntry = FindEntry( pEntryData );
		if (!pEntry)
			return;

		// Eintrag aus TreeListBox entfernen
		// ich darf das Select, das ich ausloese, nicht behandeln :
		// Select aendert die MarkList der View, wenn das gerade auch jemand anders macht und dabei ein Remove
		// triggert, haben wir mit ziemlicher Sicherheit ein Problem - Paradebeispiel war das Gruppieren von Controls mit
		// offenem Navigator ...)
		LockSelectionHandling();

		// ein kleines Problem : ich merke mir meine selektierten Daten, wenn mir jetzt jemand einen selektierten Eintrag
		// unter dem Hintern wegschiesst, werde ich inkonsistent ... was schlecht waere
		Select(pEntry, sal_False);

		// beim eigentlichen Entfernen kann die Selection geaendert werden, da ich aber das SelectionHandling abgeschaltet
		// habe, muss ich mich hinterher darum kuemmern
		sal_uIntPtr nExpectedSelectionCount = GetSelectionCount();

		if( pEntry )
			GetModel()->Remove( pEntry );

		if (nExpectedSelectionCount != GetSelectionCount())
			SynchronizeSelection();

		// und standardmaessig behandle ich das Select natuerlich
		UnlockSelectionHandling();
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::IsFormEntry( SvLBoxEntry* pEntry )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::IsFormEntry" );
		FmEntryData* pEntryData = (FmEntryData*)pEntry->GetUserData();
		return !pEntryData || pEntryData->ISA(FmFormData);
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::IsFormComponentEntry( SvLBoxEntry* pEntry )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::IsFormComponentEntry" );
		FmEntryData* pEntryData = (FmEntryData*)pEntry->GetUserData();
		return pEntryData && pEntryData->ISA(FmControlData);
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::implAcceptPaste( )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::implAcceptPaste" );
		SvLBoxEntry* pFirstSelected = FirstSelected();
		if ( !pFirstSelected || NextSelected( pFirstSelected ) )
			// no selected entry, or at least two selected entries
			return sal_False;

		// get the clipboard
		TransferableDataHelper aClipboardContent( TransferableDataHelper::CreateFromSystemClipboard( this ) );

		sal_Int8 nAction = m_aControlExchange.isClipboardOwner() && doingKeyboardCut( ) ? DND_ACTION_MOVE : DND_ACTION_COPY;
		return ( nAction == implAcceptDataTransfer( aClipboardContent.GetDataFlavorExVector(), nAction, pFirstSelected, sal_False ) );
	}

	//------------------------------------------------------------------------
	sal_Int8 NavigatorTree::implAcceptDataTransfer( const DataFlavorExVector& _rFlavors, sal_Int8 _nAction, const ::Point& _rDropPos, sal_Bool _bDnD )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::implAcceptDataTransfer" );
		return implAcceptDataTransfer( _rFlavors, _nAction, GetEntry( _rDropPos ), _bDnD );
	}

	//------------------------------------------------------------------------
	sal_Int8 NavigatorTree::implAcceptDataTransfer( const DataFlavorExVector& _rFlavors, sal_Int8 _nAction, SvLBoxEntry* _pTargetEntry, sal_Bool _bDnD )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::implAcceptDataTransfer" );
		// no target -> no drop
		if (!_pTargetEntry)
			return DND_ACTION_NONE;

		// format check
		sal_Bool bHasDefControlFormat = OControlExchange::hasFieldExchangeFormat( _rFlavors );
		sal_Bool bHasControlPathFormat = OControlExchange::hasControlPathFormat( _rFlavors );
		sal_Bool bHasHiddenControlsFormat = OControlExchange::hasHiddenControlModelsFormat( _rFlavors );
		if (!bHasDefControlFormat && !bHasControlPathFormat && !bHasHiddenControlsFormat)
			return DND_ACTION_NONE;

		sal_Bool bSelfSource = _bDnD ? m_aControlExchange.isDragSource() : m_aControlExchange.isClipboardOwner();

		if ( bHasHiddenControlsFormat )
		{	// bHasHiddenControlsFormat means that only hidden controls are part of the data

			// hidden controls can be copied to a form only
			if ( !_pTargetEntry || ( _pTargetEntry == m_pRootEntry ) || !IsFormEntry( _pTargetEntry ) )
				return DND_ACTION_NONE;

			return bSelfSource ? ( DND_ACTION_COPYMOVE & _nAction ) : DND_ACTION_COPY;
		}

		if	( !bSelfSource )
		{
			// DnD or CnP crossing navigator boundaries
			// The main problem here is that the current API does not allow us to sneak into the content which
			// is to be inserted. So we have to allow it for the moment, but maybe reject later on (in the real drop).

			// TODO: this smart behaviour later on ... at the moment, we disallow data transfer crossing navigator
			// boundaries.

			return DND_ACTION_NONE;
		}

		DBG_ASSERT( _bDnD ? m_aControlExchange.isDragSource() : m_aControlExchange.isClipboardOwner(),
			"NavigatorTree::implAcceptDataTransfer: here only with source=dest!" );
			// somebody changed the logic of this method ...

		// from here on, I can work with m_aControlExchange instead of _rData!

		sal_Bool bForeignCollection = m_aControlExchange->getFormsRoot().get() != GetNavModel()->GetFormPage()->GetForms().get();
		if ( bForeignCollection )
		{
			// crossing shell/page boundaries, we can exchange hidden controls only
			// But if we survived the checks above, we do not have hidden controls.
			// -> no data transfer
			DBG_ASSERT( !bHasHiddenControlsFormat, "NavigatorTree::implAcceptDataTransfer: still hidden controls format!" );
				// somebody changed the logic of this method ...

			return DND_ACTION_COPY;
		}

		if (DND_ACTION_MOVE != _nAction) // 'normal' controls within a shell are moved only (never copied)
			return DND_ACTION_NONE;

		if ( m_bDragDataDirty || !bHasDefControlFormat )
		{
			if (!bHasControlPathFormat)
				// ich befinde mich zwar in der Shell/Page, aus der die Controls stammen, habe aber kein Format, das den stattgefundenen
				// Shell-Wechsel ueberlebt hat (SVX_FM_CONTROLS_AS_PATH)
				return DND_ACTION_NONE;

			// da die Shell waehrend des Draggens umgeschaltet wude, muss ich die Liste des ExchangeObjektes wieder neu aufbauen
			// (dort stehen SvLBoxEntries drin, und die sind bei der Umschaltung floeten gegangen)
			m_aControlExchange->buildListFromPath(this, m_pRootEntry);
			m_bDragDataDirty = sal_False;
		}

		// die Liste der gedroppten Eintraege aus dem DragServer
        const ListBoxEntrySet& aDropped = m_aControlExchange->selected();
		DBG_ASSERT(aDropped.size() >= 1, "NavigatorTree::implAcceptDataTransfer: keine Eintraege !");

		sal_Bool bDropTargetIsComponent = IsFormComponentEntry( _pTargetEntry );
		//SvLBoxEntry* pDropTargetParent = GetParent( _pTargetEntry );

		// conditions to disallow the drop
		// 0) the root entry is part of the list (can't DnD the root!)
		// 1) one of the draged entries is to be dropped onto it's own parent
		// 2) -               "       - is to be dropped onto itself
		// 3) -               "       - is a Form and to be dropped onto one of it's descendants
		// 4) one of the entries is a control and to be dropped onto the root
		// 5) a control or form will be dropped onto a control which is _not_ a sibling (dropping onto a sibling
		//      means moving the control)

		// collect the ancestors of the drop targte (speeds up 3)
		SvLBoxEntrySortedArray arrDropAnchestors;
		SvLBoxEntry* pLoop = _pTargetEntry;
		while (pLoop)
		{
			arrDropAnchestors.Insert(pLoop);
			pLoop = GetParent(pLoop);
		}

        for (   ListBoxEntrySet::const_iterator dropped = aDropped.begin();
                dropped != aDropped.end();
                ++dropped
            )
		{
			SvLBoxEntry* pCurrent = *dropped;
			SvLBoxEntry* pCurrentParent = GetParent(pCurrent);

			// test for 0)
			if (pCurrent == m_pRootEntry)
				return DND_ACTION_NONE;

			// test for 1)
			if ( _pTargetEntry == pCurrentParent )
				return DND_ACTION_NONE;

			// test for 2)
			if (pCurrent == _pTargetEntry)
				return DND_ACTION_NONE;

			// test for 5)
	//      if ( bDropTargetIsComponent && (pDropTargetParent != pCurrentParent) )
				if ( bDropTargetIsComponent )   // TODO : die obige Zeile wieder rein, dann muss aber ExecuteDrop das Vertauschen auch beherrschen
					return DND_ACTION_NONE;

			// test for 3)
			if ( IsFormEntry(pCurrent) )
			{
				sal_uInt16 nPosition;
				if ( arrDropAnchestors.Seek_Entry(pCurrent, &nPosition) )
					return DND_ACTION_NONE;
			} else if ( IsFormComponentEntry(pCurrent) )
			{
				// test for 4)
				if (_pTargetEntry == m_pRootEntry)
					return DND_ACTION_NONE;
			}
		}

		return DND_ACTION_MOVE;
	}

	//------------------------------------------------------------------------
	sal_Int8 NavigatorTree::AcceptDrop( const AcceptDropEvent& rEvt )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::AcceptDrop" );
		::Point aDropPos = rEvt.maPosPixel;

		// kuemmern wir uns erst mal um moeglich DropActions (Scrollen und Aufklappen)
		if (rEvt.mbLeaving)
		{
			if (m_aDropActionTimer.IsActive())
				m_aDropActionTimer.Stop();
		} else
		{
			sal_Bool bNeedTrigger = sal_False;
			// auf dem ersten Eintrag ?
			if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
			{
				m_aDropActionType = DA_SCROLLUP;
				bNeedTrigger = sal_True;
			} else
				// auf dem letzten (bzw. in dem Bereich, den ein Eintrag einnehmen wuerde, wenn er unten genau buendig
				// abschliessen wuerde) ?
				if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
				{
					m_aDropActionType = DA_SCROLLDOWN;
					bNeedTrigger = sal_True;
				} else
				{   // auf einem Entry mit Childs, der nicht aufgeklappt ist ?
					SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
					if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
					{
						// -> aufklappen
						m_aDropActionType = DA_EXPANDNODE;
						bNeedTrigger = sal_True;
					}
				}

			if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
			{
				// neu anfangen zu zaehlen
				m_aTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
				// die Pos merken, da ich auch AcceptDrops bekomme, wenn sich die Maus gar nicht bewegt hat
				m_aTimerTriggered = aDropPos;
				// und den Timer los
				if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
				{
					m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
					m_aDropActionTimer.Start();
				}
			} else if (!bNeedTrigger)
				m_aDropActionTimer.Stop();
		}

		return implAcceptDataTransfer( GetDataFlavorExVector(), rEvt.mnAction, aDropPos, sal_True );
	}

	//------------------------------------------------------------------------
	sal_Int8 NavigatorTree::implExecuteDataTransfer( const OControlTransferData& _rData, sal_Int8 _nAction, const ::Point& _rDropPos, sal_Bool _bDnD )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::implExecuteDataTransfer" );
		return implExecuteDataTransfer( _rData, _nAction, GetEntry( _rDropPos ), _bDnD );
	}

	//------------------------------------------------------------------------
	sal_Int8 NavigatorTree::implExecuteDataTransfer( const OControlTransferData& _rData, sal_Int8 _nAction, SvLBoxEntry* _pTargetEntry, sal_Bool _bDnD )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::implExecuteDataTransfer" );
		const DataFlavorExVector& rDataFlavors = _rData.GetDataFlavorExVector();

		if ( DND_ACTION_NONE == implAcceptDataTransfer( rDataFlavors, _nAction, _pTargetEntry, _bDnD ) )
			// under some platforms, it may happen that ExecuteDrop is called though AcceptDrop returned DND_ACTION_NONE
			return DND_ACTION_NONE;

		// ware schlecht, wenn nach dem Droppen noch gescrollt wird ...
		if (m_aDropActionTimer.IsActive())
			m_aDropActionTimer.Stop();

		if (!_pTargetEntry)
			// no target -> no drop
			return DND_ACTION_NONE;

		// format checks
#ifdef DBG_UTIL
		sal_Bool bHasHiddenControlsFormat = OControlExchange::hasHiddenControlModelsFormat( rDataFlavors );
		sal_Bool bForeignCollection = _rData.getFormsRoot().get() != GetNavModel()->GetFormPage()->GetForms().get();
		DBG_ASSERT(!bForeignCollection || bHasHiddenControlsFormat, "NavigatorTree::implExecuteDataTransfer: invalid format (AcceptDrop shouldn't have let this pass) !");
		DBG_ASSERT(bForeignCollection || !m_bDragDataDirty, "NavigatorTree::implExecuteDataTransfer: invalid state (shell changed since last exchange resync) !");
			// das sollte in AcceptDrop erledigt worden sein : dort wird in _rData die Liste der Controls aufgebaut und m_bDragDataDirty
			// zurueckgesetzt
#endif

		if ( DND_ACTION_COPY == _nAction )
		{	// bHasHiddenControlsFormat means that only hidden controls are part of the data
			DBG_ASSERT( bHasHiddenControlsFormat, "NavigatorTree::implExecuteDataTransfer: copy allowed for hidden controls only!" );
			DBG_ASSERT( _pTargetEntry && ( _pTargetEntry != m_pRootEntry ) && IsFormEntry( _pTargetEntry ),
				"NavigatorTree::implExecuteDataTransfer: should not be here!" );
				// implAcceptDataTransfer should have caught both cases

			DBG_ASSERT(bHasHiddenControlsFormat, "NavigatorTree::implExecuteDataTransfer: only copying of hidden controls is supported !");
				// das sollte das AcceptDrop abgefangen haben

			// da ich gleich die Zielobjekte alle selektieren will (und nur die)
			SelectAll(sal_False);

			Sequence< Reference< XInterface > > aControls = _rData.hiddenControls();
			sal_Int32 nCount = aControls.getLength();
			const Reference< XInterface >* pControls = aControls.getConstArray();

			FmFormShell* pFormShell = GetNavModel()->GetFormShell();
			FmFormModel* pFormModel = pFormShell ? pFormShell->GetFormModel() : NULL;

			// innerhalb eines Undo ...
			if (pFormModel)
			{
				XubString aStr(SVX_RES(RID_STR_CONTROL));
				XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
				aUndoStr.SearchAndReplace('#', aStr);
				pFormModel->BegUndo(aUndoStr);
			}

			// die Conrtols kopieren
			for (sal_Int32 i=0; i<nCount; ++i)
			{
				// neues Control anlegen
				rtl::OUString fControlName = FM_COMPONENT_HIDDEN;
				FmControlData* pNewControlData = NewControl( fControlName, _pTargetEntry, sal_False);
				Reference< XPropertySet >  xNewPropSet( pNewControlData->GetPropertySet() );

				// und die Properties des alten in das neue kopieren
				Reference< XPropertySet >  xCurrent(pControls[i], UNO_QUERY);
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
				// nur mal eben sehen, ob das Ding tatsaechlich ein hidden control ist
				sal_Int16 nClassId = ::comphelper::getINT16(xCurrent->getPropertyValue(FM_PROP_CLASSID));
				OSL_ENSURE(nClassId == FormComponentType::HIDDENCONTROL, "NavigatorTree::implExecuteDataTransfer: invalid control in drop list !");
					// wenn das SVX_FM_HIDDEN_CONTROLS-Format vorhanden ist, dann sollten wirklich nur hidden controls in der Sequenz
					// stecken
#endif // (OSL_DEBUG_LEVEL > 1) || DBG_UTIL
				Reference< XPropertySetInfo >  xPropInfo( xCurrent->getPropertySetInfo());
				Sequence< Property> seqAllCurrentProps = xPropInfo->getProperties();
				Property* pAllCurrentProps = seqAllCurrentProps.getArray();
				for (sal_Int32 j=0; j<seqAllCurrentProps.getLength(); ++j)
				{
					::rtl::OUString sCurrentProp = pAllCurrentProps[j].Name;
					if (((pAllCurrentProps[j].Attributes & PropertyAttribute::READONLY) == 0) && (sCurrentProp != FM_PROP_NAME))
					{   // (read-only attribs werden natuerlich nicht gesetzt, dito der Name, den hat das NewControl schon eindeutig
						// festgelegt)
						xNewPropSet->setPropertyValue(sCurrentProp, xCurrent->getPropertyValue(sCurrentProp));
					}
				}

				SvLBoxEntry* pToSelect = FindEntry(pNewControlData);
				Select(pToSelect, sal_True);
				if (i == 0)
					SetCurEntry(pToSelect);
			}

			if (pFormModel)
				pFormModel->EndUndo();

			return _nAction;
		}

		if ( !OControlExchange::hasFieldExchangeFormat( _rData.GetDataFlavorExVector() ) )
		{
			// can't do anything without the internal format here ... usually happens when doing DnD or CnP
			// over navigator boundaries
			return DND_ACTION_NONE;
		}

		// some data for the target
		sal_Bool bDropTargetIsForm = IsFormEntry(_pTargetEntry);
		FmFormData* pTargetData = bDropTargetIsForm ? (FmFormData*)_pTargetEntry->GetUserData() : NULL;

		DBG_ASSERT( DND_ACTION_COPY != _nAction, "NavigatorTree::implExecuteDataTransfer: somebody changed the logics!" );

		// die Liste der gedraggten Eintraege
		ListBoxEntrySet aDropped = _rData.selected();
		DBG_ASSERT(aDropped.size() >= 1, "NavigatorTree::implExecuteDataTransfer: no entries!");

		// die Shell und das Model
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		FmFormModel* pFormModel = pFormShell ? pFormShell->GetFormModel() : NULL;
		if (!pFormModel)
			return DND_ACTION_NONE;

		// fuer's Undo
		const bool bUndo = pFormModel->IsUndoEnabled();

		if( bUndo )
		{
			XubString strUndoDescription(SVX_RES(RID_STR_UNDO_CONTAINER_REPLACE));
			pFormModel->BegUndo(strUndoDescription);
		}

		// ich nehme vor dem Einfuegen eines Eintrages seine Selection raus, damit die Markierung dabei nicht flackert
		// -> das Handeln des Select locken
		LockSelectionHandling();

		// jetzt durch alle gedroppten Eintraege ...
        for (   ListBoxEntrySet::const_iterator dropped = aDropped.begin();
                dropped != aDropped.end();
                ++dropped
            )
		{
			// ein paar Daten zum aktuellen Element
			SvLBoxEntry* pCurrent = *dropped;
			DBG_ASSERT(pCurrent != NULL, "NavigatorTree::implExecuteDataTransfer: ungueltiger Eintrag");
			DBG_ASSERT(GetParent(pCurrent) != NULL, "NavigatorTree::implExecuteDataTransfer: ungueltiger Eintrag");
				// die Root darf nicht gedraggt werden

			FmEntryData* pCurrentUserData = (FmEntryData*)pCurrent->GetUserData();

			Reference< XChild >  xCurrentChild(pCurrentUserData->GetChildIFace(), UNO_QUERY);
			Reference< XIndexContainer >  xContainer(xCurrentChild->getParent(), UNO_QUERY);

			FmFormData* pCurrentParentUserData = (FmFormData*)pCurrentUserData->GetParent();
			DBG_ASSERT(pCurrentParentUserData == NULL || pCurrentParentUserData->ISA(FmFormData), "NavigatorTree::implExecuteDataTransfer: ungueltiges Parent");

			// beim Vater austragen
			if (pCurrentParentUserData)
				pCurrentParentUserData->GetChildList()->Remove(pCurrentUserData);
			else
				GetNavModel()->GetRootList()->Remove(pCurrentUserData);

			// aus dem Container entfernen
			sal_Int32 nIndex = getElementPos(Reference< XIndexAccess > (xContainer, UNO_QUERY), xCurrentChild);
			GetNavModel()->m_pPropChangeList->Lock();
			// die Undo-Action fuer das Rausnehmen
			if ( bUndo && GetNavModel()->m_pPropChangeList->CanUndo())
			{
				pFormModel->AddUndo(new FmUndoContainerAction(*pFormModel, FmUndoContainerAction::Removed,
															xContainer, xCurrentChild, nIndex));
			}
			else if( !GetNavModel()->m_pPropChangeList->CanUndo() )
			{
				FmUndoContainerAction::DisposeElement( xCurrentChild );
			}

			// Events mitkopieren
			Reference< XEventAttacherManager >  xManager(xContainer, UNO_QUERY);
			Sequence< ScriptEventDescriptor > aEvts;

			if (xManager.is() && nIndex >= 0)
				aEvts = xManager->getScriptEvents(nIndex);
			xContainer->removeByIndex(nIndex);

			// die Selection raus
			Select(pCurrent, sal_False);
			// und weg
			Remove(pCurrentUserData);

			// die Stelle innerhalb des DropParents, an der ich die gedroppten Eintraege einfuegen muss
			if (pTargetData)
				xContainer = Reference< XIndexContainer > (pTargetData->GetElement(), UNO_QUERY);
			else
				xContainer = Reference< XIndexContainer > (GetNavModel()->GetForms(), UNO_QUERY);

			// immer ganz hinten einfuegen
			nIndex = xContainer->getCount();

			// UndoAction fuer das Einfuegen
			if ( bUndo && GetNavModel()->m_pPropChangeList->CanUndo())
				pFormModel->AddUndo(new FmUndoContainerAction(*pFormModel, FmUndoContainerAction::Inserted,
														 xContainer, xCurrentChild, nIndex));

			// einfuegen im neuen Container
			if (pTargetData)
			{
				 // es wird in eine Form eingefuegt, dann brauche ich eine FormComponent
				xContainer->insertByIndex( nIndex,
					makeAny( Reference< XFormComponent >( xCurrentChild, UNO_QUERY ) ) );
			}
			else
			{
				xContainer->insertByIndex( nIndex,
					makeAny( Reference< XForm >( xCurrentChild, UNO_QUERY ) ) );
			}

			if (aEvts.getLength())
			{
				xManager = Reference< XEventAttacherManager > (xContainer, UNO_QUERY);
				if (xManager.is())
					xManager->registerScriptEvents(nIndex, aEvts);
			}

			GetNavModel()->m_pPropChangeList->UnLock();

			// zuerst dem Eintrag das neue Parent
			pCurrentUserData->SetParent(pTargetData);

			// dann dem Parent das neue Child
			if (pTargetData)
				pTargetData->GetChildList()->Insert(pCurrentUserData, nIndex);
			else
				GetNavModel()->GetRootList()->Insert(pCurrentUserData, nIndex);

			// dann bei mir selber bekanntgeben und neu selektieren
			SvLBoxEntry* pNew = Insert( pCurrentUserData, nIndex );
			if ( ( aDropped.begin() == dropped ) && pNew )
			{
				SvLBoxEntry* pParent = GetParent( pNew );
				if ( pParent )
					Expand( pParent );
			}
		}

		UnlockSelectionHandling();

		if( bUndo )
			pFormModel->EndUndo();

		// During the move, the markings of the underlying view did not change (because the view is not affected by the logical
		// hierarchy of the form/control models. But my selection changed - which means I have to adjust it according to the
		// view marks, again.
		SynchronizeSelection();

		// in addition, with the move of controls such things as "the current form" may have changed - force the shell
		// to update itself accordingly
		if( pFormShell && pFormShell->GetImpl() && pFormShell->GetFormView() )
			pFormShell->GetImpl()->DetermineSelection( pFormShell->GetFormView()->GetMarkedObjectList() );

		if ( m_aControlExchange.isClipboardOwner() && ( DND_ACTION_MOVE == _nAction ) )
			m_aControlExchange->clear();

		return _nAction;
	}

	//------------------------------------------------------------------------
	sal_Int8 NavigatorTree::ExecuteDrop( const ExecuteDropEvent& rEvt )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::ExecuteDrop" );
		sal_Int8 nResult( DND_ACTION_NONE );

		if ( m_aControlExchange.isDragSource() )
			nResult = implExecuteDataTransfer( *m_aControlExchange, rEvt.mnAction, rEvt.maPosPixel, sal_True );
		else
		{
			OControlTransferData aDroppedData( rEvt.maDropEvent.Transferable );
			nResult = implExecuteDataTransfer( aDroppedData, rEvt.mnAction, rEvt.maPosPixel, sal_True );
		}

		return nResult;
	}

	//------------------------------------------------------------------------
	void NavigatorTree::doPaste()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::doPaste" );
   		try
    	{
			if ( m_aControlExchange.isClipboardOwner() )
			{
				implExecuteDataTransfer( *m_aControlExchange, doingKeyboardCut( ) ? DND_ACTION_MOVE : DND_ACTION_COPY, FirstSelected(), sal_False );
			}
			else
			{
				// the clipboard content
				Reference< XClipboard >	xClipboard( GetClipboard() );
				Reference< XTransferable > xTransferable;
				if ( xClipboard.is() )
	    			xTransferable = xClipboard->getContents();

				OControlTransferData aClipboardContent( xTransferable );
				implExecuteDataTransfer( aClipboardContent, DND_ACTION_COPY, FirstSelected(), sal_False );
			}
		}
		catch( const Exception& )
		{
			DBG_ERROR( "NavigatorTree::doPaste: caught an exception!" );
		}
	}

	//------------------------------------------------------------------------
	void NavigatorTree::doCopy()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::doCopy" );
		if ( implPrepareExchange( DND_ACTION_COPY ) )
		{
			m_aControlExchange.setClipboardListener( LINK( this, NavigatorTree, OnClipboardAction ) );
			m_aControlExchange.copyToClipboard( );
		}
	}

	//------------------------------------------------------------------------
	void NavigatorTree::ModelHasRemoved( SvListEntry* _pEntry )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::ModelHasRemoved" );
        SvLBoxEntry* pTypedEntry = static_cast< SvLBoxEntry* >( _pEntry );
        if ( doingKeyboardCut() )
            m_aCutEntries.erase( pTypedEntry );

        if ( m_aControlExchange.isDataExchangeActive() )
        {
            if ( 0 == m_aControlExchange->onEntryRemoved( pTypedEntry ) )
            {
                // last of the entries which we put into the clipboard has been deleted from the tree.
                // Give up the clipboard ownership.
                m_aControlExchange.clear();
            }
        }
	}

	//------------------------------------------------------------------------
	void NavigatorTree::doCut()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::doCut" );
		if ( implPrepareExchange( DND_ACTION_MOVE ) )
		{
			m_aControlExchange.setClipboardListener( LINK( this, NavigatorTree, OnClipboardAction ) );
			m_aControlExchange.copyToClipboard( );
			m_bKeyboardCut = sal_True;

			// mark all the entries we just "cut" into the clipboard as "nearly moved"
			for ( sal_Int32 i=0; i<m_arrCurrentSelection.Count(); ++i )
			{
				SvLBoxEntry* pEntry = m_arrCurrentSelection[ (sal_uInt16)i ];
				if ( pEntry )
				{
					m_aCutEntries.insert( pEntry );
					pEntry->SetFlags( pEntry->GetFlags() | SV_ENTRYFLAG_SEMITRANSPARENT );
					InvalidateEntry( pEntry );
				}
			}
		}
	}

	//------------------------------------------------------------------------
	void NavigatorTree::KeyInput(const ::KeyEvent& rKEvt)
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::KeyInput" );
		const KeyCode& rCode = rKEvt.GetKeyCode();

		// delete?
		if (rKEvt.GetKeyCode().GetCode() == KEY_DELETE && !rKEvt.GetKeyCode().GetModifier())
		{
			DeleteSelection();
			return;
		}

		// copy'n'paste?
		switch ( rCode.GetFunction() )
		{
			case KEYFUNC_CUT:
				doCut();
				break;

			case KEYFUNC_PASTE:
				if ( implAcceptPaste() )
					doPaste();
				break;

			case KEYFUNC_COPY:
				doCopy();
				break;

            default:
                break;
		}

		SvTreeListBox::KeyInput(rKEvt);
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::EditingEntry( SvLBoxEntry* pEntry, Selection& rSelection )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::EditingEntry" );
		if (!SvTreeListBox::EditingEntry( pEntry, rSelection ))
			return sal_False;

		return (pEntry && (pEntry->GetUserData() != NULL));
			// die Wurzel, die ich nicht umbenennen darf, hat als UserData NULL
	}

	//------------------------------------------------------------------------
	void NavigatorTree::NewForm( SvLBoxEntry* pParentEntry )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::NewForm" );
		//////////////////////////////////////////////////////////////////////
		// ParentFormData holen
		if( !IsFormEntry(pParentEntry) )
			return;

		FmFormData* pParentFormData = (FmFormData*)pParentEntry->GetUserData();

		//////////////////////////////////////////////////////////////////////
		// Neue Form erzeugen
		Reference< XForm >  xNewForm(m_xORB->createInstance(FM_SUN_COMPONENT_FORM), UNO_QUERY);
		if (!xNewForm.is())
			return;

		FmFormData* pNewFormData = new FmFormData( xNewForm, m_aNavigatorImages, m_aNavigatorImagesHC, pParentFormData );

		//////////////////////////////////////////////////////////////////////
		// Namen setzen
		::rtl::OUString aName = GenerateName(pNewFormData);
		pNewFormData->SetText(aName);

		Reference< XPropertySet >  xPropertySet(xNewForm, UNO_QUERY);
		if (!xPropertySet.is())
			return;
		try
		{
			xPropertySet->setPropertyValue( FM_PROP_NAME, makeAny(aName) );
			// a form should always have the command type table as default
			xPropertySet->setPropertyValue( FM_PROP_COMMANDTYPE, makeAny(sal_Int32(CommandType::TABLE)));
		}
		catch ( const Exception& )
		{
			DBG_ERROR("NavigatorTree::NewForm : could not set esssential properties !");
		}


		//////////////////////////////////////////////////////////////////////
		// Form einfuegen
		GetNavModel()->Insert( pNewFormData, LIST_APPEND, sal_True );

		//////////////////////////////////////////////////////////////////////
		// Neue Form als aktive Form setzen
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if( pFormShell )
		{
            InterfaceBag aSelection;
            aSelection.insert( Reference< XInterface >( xNewForm, UNO_QUERY ) );
			pFormShell->GetImpl()->setCurrentSelection( aSelection );

			pFormShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_PROPERTIES,sal_True,sal_True);
		}
		GetNavModel()->SetModified();

		//////////////////////////////////////////////////////////////////////
		// In EditMode schalten
		SvLBoxEntry* pNewEntry = FindEntry( pNewFormData );
		EditEntry( pNewEntry );
	}

	//------------------------------------------------------------------------
	FmControlData* NavigatorTree::NewControl( const ::rtl::OUString& rServiceName, SvLBoxEntry* pParentEntry, sal_Bool bEditName )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::NewControl" );
		//////////////////////////////////////////////////////////////////////
		// ParentForm holen
		if (!GetNavModel()->GetFormShell())
			return NULL;
		if (!IsFormEntry(pParentEntry))
			return NULL;

		FmFormData* pParentFormData = (FmFormData*)pParentEntry->GetUserData();;
		Reference< XForm >  xParentForm( pParentFormData->GetFormIface());

		//////////////////////////////////////////////////////////////////////
		// Neue Component erzeugen
		Reference< XFormComponent >  xNewComponent(::comphelper::getProcessServiceFactory()->createInstance(rServiceName), UNO_QUERY);
		if (!xNewComponent.is())
			return NULL;

		FmControlData* pNewFormControlData = new FmControlData( xNewComponent, m_aNavigatorImages, m_aNavigatorImagesHC, pParentFormData );

		//////////////////////////////////////////////////////////////////////
		// Namen setzen
		FmFormView*     pFormView       = GetNavModel()->GetFormShell()->GetFormView();
		SdrPageView*    pPageView       = pFormView->GetSdrPageView();
		FmFormPage*     pPage           = (FmFormPage*)pPageView->GetPage();

		::rtl::OUString sName = pPage->GetImpl().setUniqueName( xNewComponent, xParentForm );

		pNewFormControlData->SetText( sName );

		//////////////////////////////////////////////////////////////////////
		// FormComponent einfuegen
		GetNavModel()->Insert( pNewFormControlData, LIST_APPEND, sal_True );
		GetNavModel()->SetModified();

		if (bEditName)
		{
			//////////////////////////////////////////////////////////////////////
			// In EditMode schalten
			SvLBoxEntry* pNewEntry = FindEntry( pNewFormControlData );
			Select( pNewEntry, sal_True );
			EditEntry( pNewEntry );
		}

		return pNewFormControlData;
	}

	//------------------------------------------------------------------------
	::rtl::OUString NavigatorTree::GenerateName( FmEntryData* pEntryData )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::GenerateName" );
		const sal_uInt16 nMaxCount = 99;
		::rtl::OUString aNewName;

		//////////////////////////////////////////////////////////////////////
		// BasisNamen erzeugen
		UniString aBaseName;
		if( pEntryData->ISA(FmFormData) )
			aBaseName = SVX_RES( RID_STR_STDFORMNAME );

		else if( pEntryData->ISA(FmControlData) )
			aBaseName = SVX_RES( RID_STR_CONTROL );

		//////////////////////////////////////////////////////////////////////
		// Neuen Namen erstellen
		FmFormData* pFormParentData = (FmFormData*)pEntryData->GetParent();

		for( sal_Int32 i=0; i<nMaxCount; i++ )
		{
			aNewName = aBaseName;
			if( i>0 )
			{
				aNewName += ::rtl::OUString::createFromAscii(" ");
				aNewName += ::rtl::OUString::valueOf(i).getStr();
			}

			if( GetNavModel()->FindData(aNewName, pFormParentData,sal_False) == NULL )
				break;
		}

		return aNewName;
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::EditedEntry" );
		if (EditingCanceled())
			return sal_True;

		GrabFocus();
		FmEntryData* pEntryData = (FmEntryData*)pEntry->GetUserData();
		sal_Bool bRes = GetNavModel()->Rename( pEntryData, rNewText);
		if( !bRes )
		{
			m_pEditEntry = pEntry;
			nEditEvent = Application::PostUserEvent( LINK(this, NavigatorTree, OnEdit) );
		} else
			SetCursor(pEntry, sal_True);

		return bRes;
	}

	//------------------------------------------------------------------------
	IMPL_LINK( NavigatorTree, OnEdit, void*, EMPTYARG )
	{
		nEditEvent = 0;
		EditEntry( m_pEditEntry );
		m_pEditEntry = NULL;

		return 0L;
	}

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

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

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

        case DA_SCROLLUP :
			ScrollOutputArea( 1 );
			m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
			break;

		case DA_SCROLLDOWN :
			ScrollOutputArea( -1 );
			m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
			break;

		}

		return 0L;
	}

	//------------------------------------------------------------------------
	IMPL_LINK(NavigatorTree, OnEntrySelDesel, NavigatorTree*, /*pThis*/)
	{
		m_sdiState = SDI_DIRTY;

		if (IsSelectionHandlingLocked())
			return 0L;

		if (m_aSynchronizeTimer.IsActive())
			m_aSynchronizeTimer.Stop();

		m_aSynchronizeTimer.SetTimeout(EXPLORER_SYNC_DELAY);
		m_aSynchronizeTimer.Start();

		return 0L;
	}

	//------------------------------------------------------------------------
	IMPL_LINK(NavigatorTree, OnSynchronizeTimer, void*, EMPTYARG)
	{
		SynchronizeMarkList();
		return 0L;
	}


	//------------------------------------------------------------------------
	IMPL_LINK( NavigatorTree, OnClipboardAction, void*, EMPTYARG )
	{
		if ( !m_aControlExchange.isClipboardOwner() )
		{
			if ( doingKeyboardCut() )
			{
                for (   ListBoxEntrySet::const_iterator i = m_aCutEntries.begin();
                        i != m_aCutEntries.end();
                        ++i
                    )
				{
                    SvLBoxEntry* pEntry = *i;
					if ( !pEntry )
                        continue;

                    pEntry->SetFlags( pEntry->GetFlags() & ~SV_ENTRYFLAG_SEMITRANSPARENT );
					InvalidateEntry( pEntry );
				}
                ListBoxEntrySet aEmpty;
				m_aCutEntries.swap( aEmpty );

				m_bKeyboardCut = sal_False;
			}
		}
		return 0L;
	}

	//------------------------------------------------------------------------
	void NavigatorTree::ShowSelectionProperties(sal_Bool bForce)
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::ShowSelectionProperties" );
		// zuerst brauche ich die FormShell
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if (!pFormShell)
			// keine Shell -> ich koennte kein curObject setzen -> raus
			return;

		CollectSelectionData(SDI_ALL);
		DBG_ASSERT( m_nFormsSelected + m_nControlsSelected + (m_bRootSelected ? 1 : 0) == m_arrCurrentSelection.Count(),
			"NavigatorTree::ShowSelectionProperties : selection meta data invalid !");


        InterfaceBag aSelection;
        sal_Bool bSetSelectionAsMarkList = sal_False;

		if (m_bRootSelected)
			;                                   // no properties for the root, neither for single nor for multi selection
		else if ( m_nFormsSelected + m_nControlsSelected == 0 )   // none of the two should be less 0
			;                                   // no selection -> no properties
		else if ( m_nFormsSelected * m_nControlsSelected != 0 )
			;                                   // mixed selection -> no properties
		else
		{   // either only forms, or only controls are selected
            if (m_arrCurrentSelection.Count() == 1)
			{
				if (m_nFormsSelected > 0)
				{   // es ist genau eine Form selektiert
					FmFormData* pFormData = (FmFormData*)m_arrCurrentSelection.GetObject(0)->GetUserData();
                    aSelection.insert( Reference< XInterface >( pFormData->GetFormIface(), UNO_QUERY ) );
				}
                else
				{   // es ist genau ein Control selektiert (egal ob hidden oder normal)
					FmEntryData* pEntryData = (FmEntryData*)m_arrCurrentSelection.GetObject(0)->GetUserData();

                    aSelection.insert( Reference< XInterface >( pEntryData->GetElement(), UNO_QUERY ) );
				}
			}
            else
			{   // wir haben eine MultiSelection, also muessen wir ein MultiSet dafuer aufbauen
				if (m_nFormsSelected > 0)
				{   // ... nur Forms
					// erstmal die PropertySet-Interfaces der Forms einsammeln
					for ( sal_Int32 i = 0; i < m_nFormsSelected; ++i )
					{
						FmFormData* pFormData = (FmFormData*)m_arrCurrentSelection.GetObject((sal_uInt16)i)->GetUserData();
                        aSelection.insert( pFormData->GetPropertySet().get() );
					}
				}
				else
				{   // ... nur Controls
					if (m_nHiddenControls == m_nControlsSelected)
					{   // ein MultiSet fuer die Properties der hidden controls
						for ( sal_Int32 i = 0; i < m_nHiddenControls; ++i )
						{
							FmEntryData* pEntryData = (FmEntryData*)m_arrCurrentSelection.GetObject((sal_uInt16)i)->GetUserData();
                            aSelection.insert( pEntryData->GetPropertySet().get() );
						}
					}
					else if (m_nHiddenControls == 0)
					{   // nur normale Controls
                        bSetSelectionAsMarkList = sal_True;
					}
				}
			}

		}

        // und dann meine Form und mein SelObject
        if ( bSetSelectionAsMarkList )
            pFormShell->GetImpl()->setCurrentSelectionFromMark( pFormShell->GetFormView()->GetMarkedObjectList() );
        else
		    pFormShell->GetImpl()->setCurrentSelection( aSelection );

		if ( pFormShell->GetImpl()->IsPropBrwOpen() || bForce )
		{
			// und jetzt kann ich das Ganze dem PropertyBrowser uebergeben
			pFormShell->GetViewShell()->GetViewFrame()->GetDispatcher()->Execute( SID_FM_SHOW_PROPERTY_BROWSER, SFX_CALLMODE_ASYNCHRON );
		}
	}

	//------------------------------------------------------------------------
	void NavigatorTree::DeleteSelection()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::DeleteSelection" );
		// die Root darf ich natuerlich nicht mitloeschen
		sal_Bool bRootSelected = IsSelected(m_pRootEntry);
		sal_uIntPtr nSelectedEntries = GetSelectionCount();
		if (bRootSelected && (nSelectedEntries > 1))     // die Root plus andere Elemente ?
			Select(m_pRootEntry, sal_False);                // ja -> die Root raus

		if ((nSelectedEntries == 0) || bRootSelected)    // immer noch die Root ?
			return;                                     // -> sie ist das einzige selektierte -> raus

		DBG_ASSERT(!m_bPrevSelectionMixed, "NavigatorTree::DeleteSelection() : loeschen nicht erlaubt wenn Markierung und Selektion nciht konsistent");

		// ich brauche unten das FormModel ...
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if (!pFormShell)
			return;
		FmFormModel* pFormModel = pFormShell ? pFormShell->GetFormModel() : NULL;
		if (!pFormModel)
			return;

		// jetzt muss ich noch die DeleteList etwas absichern : wenn man ein Formular und ein abhaengiges
		// Element loescht - und zwar in dieser Reihenfolge - dann ist der SvLBoxEntryPtr des abhaengigen Elementes
		// natuerlich schon ungueltig, wenn es geloescht werden soll ... diesen GPF, den es dann mit Sicherheit gibt,
		// gilt es zu verhindern, also die 'normalisierte' Liste
		CollectSelectionData( SDI_NORMALIZED );

        // see below for why we need this mapping from models to shapes
		FmFormView*		pFormView		= pFormShell->GetFormView();
		SdrPageView*	pPageView		= pFormView ? pFormView->GetSdrPageView() : NULL;
		SdrPage*		pPage			= pPageView ? pPageView->GetPage() : NULL;
		DBG_ASSERT( pPage, "NavigatorTree::DeleteSelection: invalid form page!" );

		MapModelToShape aModelShapes;
		if ( pPage )
			collectShapeModelMapping( pPage, aModelShapes );

        // problem: we have to use ExplorerModel::Remove, since only this one properly deletes Form objects.
        // But, the controls themself must be deleted via DeleteMarked (else, the Writer has some problems
        // somewhere). In case I'd first delete the structure, then the controls, the UNDO would not work
        // (since UNDO then would mean to first restore the controls, then the structure, means their parent
        // form). The other way round, the EntryDatas would be invalid, if I'd first delete the controls and
        // then go on to the strucure. This means I have to delete the forms *after* the normal controls, so
        // that during UNDO, they're restored in the proper order.
		pFormShell->GetImpl()->EnableTrackProperties(sal_False);
		sal_uInt16 i;
		for (i = m_arrCurrentSelection.Count(); i>0; --i)
		{
			FmEntryData* pCurrent = (FmEntryData*)(m_arrCurrentSelection.GetObject(i - 1)->GetUserData());

			// eine Form ?
			sal_Bool bIsForm = pCurrent->ISA(FmFormData);

			// da ich das Loeschen im folgenden der View ueberlasse und dabei auf deren MarkList aufbaue, im Normalfall aber bei
			// einem makierten Formular nur die direkt, nicht die indirekt abhaengigen Controls markiert werden, muss ich das hier
			// noch nachholen
			if (bIsForm)
				MarkViewObj((FmFormData*)pCurrent, sal_True, sal_True);     // das zweite sal_True heisst "deep"

			// ein hidden control ?
			sal_Bool bIsHidden = IsHiddenControl(pCurrent);

			// Forms und hidden Controls muss ich behalten, alles andere nicht
			if (!bIsForm && !bIsHidden)
			{
				// well, no form and no hidden control -> we can remove it from m_arrCurrentSelection, as it will
				// be deleted automatically. This is because for every model (except forms and hidden control models)
				// there exist a shape, which is marked _if_and_only_if_ the model is selected in our tree.
                if ( aModelShapes.find( pCurrent->GetElement() ) != aModelShapes.end() )
                {
                    // if there's a shape for the current entry, then either it is marked or it is in a
                    // hidden layer (#i28502#), or something like this.
                    // In the first case, it will be deleted below, in the second case, we currently don't
                    // delete it, as there's no real (working!) API for this, neither in UNO nor in non-UNO.
                    m_arrCurrentSelection.Remove( i - 1, 1 );
                }
                // In case there is no shape for the current entry, we keep the entry in m_arrCurrentSelection,
                // since then we can definately remove it.
                // #103597#
			}
		}
		pFormShell->GetImpl()->EnableTrackProperties(sal_True);

		// let the view delete the marked controls
		pFormShell->GetFormView()->DeleteMarked();

        // start UNDO at this point. Unfortunately, this results in 2 UNDO actions, since DeleteMarked is
        // creating an own one. However, if we'd move it before DeleteMarked, Writer does not really like
        // this ... :(
        // 2004-07-05 - #i31038# - fs@openoffice.org
        {
            // ---------------
		    // initialize UNDO
            String aUndoStr;
		    if ( m_arrCurrentSelection.Count() == 1 )
		    {
			    aUndoStr = SVX_RES(RID_STR_UNDO_CONTAINER_REMOVE);
			    if (m_nFormsSelected)
				    aUndoStr.SearchAndReplaceAscii( "#", SVX_RES( RID_STR_FORM ) );
			    else
				    // it must be a control (else the root would be selected, but it cannot be deleted)
				    aUndoStr.SearchAndReplaceAscii( "#", SVX_RES( RID_STR_CONTROL ) );
		    }
		    else
		    {
			    aUndoStr = SVX_RES(RID_STR_UNDO_CONTAINER_REMOVE_MULTIPLE);
                aUndoStr.SearchAndReplaceAscii( "#", String::CreateFromInt32( m_arrCurrentSelection.Count() ) );
		    }
            pFormModel->BegUndo(aUndoStr);
        }

        // remove remaining structure
		for (i=0; i<m_arrCurrentSelection.Count(); ++i)
		{
			FmEntryData* pCurrent = (FmEntryData*)(m_arrCurrentSelection.GetObject(i)->GetUserData());

            // if the entry still has children, we skipped deletion of one of those children.
            // This may for instance be because the shape is in a hidden layer, where we're unable
            // to remove it
            if ( pCurrent->GetChildList()->Count() )
                continue;

			// noch ein kleines Problem, bevor ich das ganz loesche : wenn es eine Form ist und die Shell diese als CurrentObject
			// kennt, dann muss ich ihr das natuerlich ausreden
			if (pCurrent->ISA(FmFormData))
			{
				Reference< XForm >  xCurrentForm( static_cast< FmFormData* >( pCurrent )->GetFormIface() );
				if ( pFormShell->GetImpl()->getCurrentForm() == xCurrentForm )  // die Shell kennt die zu loeschende Form ?
					pFormShell->GetImpl()->forgetCurrentForm();                 // -> wegnehmen ...
			}
			GetNavModel()->Remove(pCurrent, sal_True);
		}
		pFormModel->EndUndo();
	}

	//------------------------------------------------------------------------
	void NavigatorTree::CollectSelectionData(SELDATA_ITEMS sdiHow)
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::CollectSelectionData" );
		DBG_ASSERT(sdiHow != SDI_DIRTY, "NavigatorTree::CollectSelectionData : ever thought about your parameter ? DIRTY ?");
		if (sdiHow == m_sdiState)
			return;

		m_arrCurrentSelection.Remove((sal_uInt16)0, m_arrCurrentSelection.Count());
		m_nFormsSelected = m_nControlsSelected = m_nHiddenControls = 0;
		m_bRootSelected = sal_False;

		SvLBoxEntry* pSelectionLoop = FirstSelected();
		while (pSelectionLoop)
		{
			// erst mal die Zaehlung der verschiedenen Elemente
			if (pSelectionLoop == m_pRootEntry)
				m_bRootSelected = sal_True;
			else
			{
				if (IsFormEntry(pSelectionLoop))
					++m_nFormsSelected;
				else
				{
					++m_nControlsSelected;
					if (IsHiddenControl((FmEntryData*)(pSelectionLoop->GetUserData())))
						++m_nHiddenControls;
				}
			}

			if (sdiHow == SDI_NORMALIZED)
			{
				// alles, was schon einen selektierten Vorfahr hat, nicht mitnehmen
				if (pSelectionLoop == m_pRootEntry)
					m_arrCurrentSelection.Insert(pSelectionLoop);
				else
				{
					SvLBoxEntry* pParentLoop = GetParent(pSelectionLoop);
					while (pParentLoop)
					{
						// eigentlich muesste ich testen, ob das Parent in der m_arrCurrentSelection steht ...
						// Aber wenn es selektiert ist, dann steht es in m_arrCurrentSelection, oder wenigstens einer seiner Vorfahren,
						// wenn der auch schon selektiert war. In beiden Faellen reicht also die Abfrage IsSelected
						if (IsSelected(pParentLoop))
							break;
						else
						{
							if (m_pRootEntry == pParentLoop)
							{
								// bis (exclusive) zur Root gab es kein selektiertes Parent -> der Eintrag gehoert in die normalisierte Liste
								m_arrCurrentSelection.Insert(pSelectionLoop);
								break;
							}
							else
								pParentLoop = GetParent(pParentLoop);
						}
					}
				}
			}
			else if (sdiHow == SDI_NORMALIZED_FORMARK)
			{
				SvLBoxEntry* pParent = GetParent(pSelectionLoop);
				if (!pParent || !IsSelected(pParent) || IsFormEntry(pSelectionLoop))
					m_arrCurrentSelection.Insert(pSelectionLoop);
			}
			else
				m_arrCurrentSelection.Insert(pSelectionLoop);


			pSelectionLoop = NextSelected(pSelectionLoop);
		}

		m_sdiState = sdiHow;
	}

	//------------------------------------------------------------------------
	void NavigatorTree::SynchronizeSelection(FmEntryDataArray& arredToSelect)
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::SynchronizeSelection" );
		LockSelectionHandling();
		if (arredToSelect.Count() == 0)
		{
			SelectAll(sal_False);
		}
		else
		{
			// erst mal gleiche ich meine aktuelle Selektion mit der geforderten SelectList ab
			SvLBoxEntry* pSelection = FirstSelected();
			while (pSelection)
			{
				FmEntryData* pCurrent = (FmEntryData*)pSelection->GetUserData();
				if (pCurrent != NULL)
				{
					sal_uInt16 nPosition;
					if ( arredToSelect.Seek_Entry(pCurrent, &nPosition) )
					{   // der Entry ist schon selektiert, steht aber auch in der SelectList -> er kann aus letzterer
						// raus
						arredToSelect.Remove(nPosition, 1);
					} else
					{   // der Entry ist selektiert, aber steht nicht in der SelectList -> Selektion rausnehmen
						Select(pSelection, sal_False);
						// und sichtbar machen (kann ja sein, dass das die einzige Modifikation ist, die ich hier in dem
						// ganzen Handler mache, dann sollte das zu sehen sein)
						MakeVisible(pSelection);
					}
				}
				else
					Select(pSelection, sal_False);

				pSelection = NextSelected(pSelection);
			}

			// jetzt habe ich in der SelectList genau die Eintraege, die noch selektiert werden muessen
			// zwei Moeglichkeiten : 1) ich gehe durch die SelectList, besorge mir zu jedem Eintrag meinen SvLBoxEntry
			// und selektiere diesen (waere irgendwie intuitiver ;)) 2) ich gehe durch alle meine SvLBoxEntries und selektiere
			// genau die, die ich in der SelectList finde
			// 1) braucht O(k*n) (k=Laenge der SelectList, n=Anzahl meiner Entries), plus den Fakt, dass FindEntry nicht den
			// Pointer auf die UserDaten vergleicht, sondern ein aufwendigeres IsEqualWithoutChilds durchfuehrt
			// 2) braucht O(n*log k), dupliziert aber etwas Code (naemlich den aus FindEntry)
			// da das hier eine relativ oft aufgerufenen Stelle sein koennte (bei jeder Aenderung in der Markierung in der View !),
			// nehme ich doch lieber letzteres
			SvLBoxEntry* pLoop = First();
			while( pLoop )
			{
				FmEntryData* pCurEntryData = (FmEntryData*)pLoop->GetUserData();
				sal_uInt16 nPosition;
				if ( arredToSelect.Seek_Entry(pCurEntryData, &nPosition) )
				{
					Select(pLoop, sal_True);
					MakeVisible(pLoop);
					SetCursor(pLoop, sal_True);
				}

				pLoop = Next( pLoop );
			}
		}
		UnlockSelectionHandling();
	}

	//------------------------------------------------------------------------
	void NavigatorTree::SynchronizeSelection()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::SynchronizeSelection" );
		// Shell und View
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if(!pFormShell) return;

		FmFormView* pFormView = pFormShell->GetFormView();
		if (!pFormView) return;

		GetNavModel()->BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
	}

	//------------------------------------------------------------------------
	void NavigatorTree::SynchronizeMarkList()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::SynchronizeMarkList" );
		// die Shell werde ich brauchen ...
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if (!pFormShell) return;

		CollectSelectionData(SDI_NORMALIZED_FORMARK);

		// Die View soll jetzt kein Notify bei einer Aenderung der MarkList rauslassen
		pFormShell->GetImpl()->EnableTrackProperties(sal_False);

		UnmarkAllViewObj();

		for (sal_uInt32 i=0; i<m_arrCurrentSelection.Count(); ++i)
		{
			SvLBoxEntry* pSelectionLoop = m_arrCurrentSelection.GetObject((sal_uInt16)i);
			// Bei Formselektion alle Controls dieser Form markieren
			if (IsFormEntry(pSelectionLoop) && (pSelectionLoop != m_pRootEntry))
				MarkViewObj((FmFormData*)pSelectionLoop->GetUserData(), sal_True, sal_False);

			// Bei Controlselektion Control-SdrObjects markieren
			else if (IsFormComponentEntry(pSelectionLoop))
			{
				FmControlData* pControlData = (FmControlData*)pSelectionLoop->GetUserData();
				if (pControlData)
				{
					/////////////////////////////////////////////////////////////////
					// Beim HiddenControl kann kein Object selektiert werden
					Reference< XFormComponent >  xFormComponent( pControlData->GetFormComponent());
					if (!xFormComponent.is())
						continue;
					Reference< XPropertySet >  xSet(xFormComponent, UNO_QUERY);
					if (!xSet.is())
						continue;

					sal_uInt16 nClassId = ::comphelper::getINT16(xSet->getPropertyValue(FM_PROP_CLASSID));
					if (nClassId != FormComponentType::HIDDENCONTROL)
						MarkViewObj(pControlData, sal_True, sal_True);
				}
			}
		}

		// wenn der PropertyBrowser offen ist, muss ich den entsprechend meiner Selektion anpassen
		// (NICHT entsprechend der MarkList der View : wenn ich ein Formular selektiert habe, sind in der
		// View alle zugehoerigen Controls markiert, trotzdem moechte ich natuerlich die Formular-Eigenschaften
		// sehen)
		ShowSelectionProperties(sal_False);

		// Flag an View wieder zuruecksetzen
		pFormShell->GetImpl()->EnableTrackProperties(sal_True);

		// wenn jetzt genau eine Form selektiert ist, sollte die Shell das als CurrentForm mitbekommen
		// (wenn SelectionHandling nicht locked ist, kuemmert sich die View eigentlich in MarkListHasChanged drum,
		// aber der Mechanismus greift zum Beispiel nicht, wenn die Form leer ist)
		if ((m_arrCurrentSelection.Count() == 1) && (m_nFormsSelected == 1))
		{
			FmFormData* pSingleSelectionData = PTR_CAST( FmFormData, static_cast< FmEntryData* >( FirstSelected()->GetUserData() ) );
			DBG_ASSERT( pSingleSelectionData, "NavigatorTree::SynchronizeMarkList: invalid selected form!" );
			if ( pSingleSelectionData )
            {
                InterfaceBag aSelection;
                aSelection.insert( Reference< XInterface >( pSingleSelectionData->GetFormIface(), UNO_QUERY ) );
				pFormShell->GetImpl()->setCurrentSelection( aSelection );
            }
		}
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::IsHiddenControl(FmEntryData* pEntryData)
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::IsHiddenControl" );
		if (pEntryData == NULL) return sal_False;

		Reference< XPropertySet > xProperties( pEntryData->GetPropertySet() );
		if (::comphelper::hasProperty(FM_PROP_CLASSID, xProperties))
		{
			Any aClassID = xProperties->getPropertyValue( FM_PROP_CLASSID );
			return (::comphelper::getINT16(aClassID) == FormComponentType::HIDDENCONTROL);
		}
		return sal_False;
	}

	//------------------------------------------------------------------------
	sal_Bool NavigatorTree::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::Select" );
		if (bSelect == IsSelected(pEntry))  // das passiert manchmal, ich glaube, die Basisklasse geht zu sehr auf Nummer sicher ;)
			return sal_True;

		return SvTreeListBox::Select(pEntry, bSelect );
	}

	//------------------------------------------------------------------------
    void NavigatorTree::UnmarkAllViewObj()
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::UnmarkAllViewObj" );
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if( !pFormShell )
			return;
		FmFormView* pFormView = pFormShell->GetFormView();
		pFormView->UnMarkAll();
	}
    //------------------------------------------------------------------------
    void NavigatorTree::MarkViewObj(FmFormData* pFormData, sal_Bool bMark, sal_Bool bDeep )
    {
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::MarkViewObjects" );
        FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if( !pFormShell ) 
            return;
        
        // first collect all sdrobjects
        ::std::set< Reference< XFormComponent > > aObjects;
        CollectObjects(pFormData,bDeep,aObjects);

		//////////////////////////////////////////////////////////////////////
        // In der Page das entsprechende SdrObj finden und selektieren
        FmFormView*     pFormView       = pFormShell->GetFormView();
        SdrPageView*    pPageView       = pFormView->GetSdrPageView();
        SdrPage*        pPage           = pPageView->GetPage();
        //FmFormPage*     pFormPage       = dynamic_cast< FmFormPage* >( pPage );

        SdrObjListIter aIter( *pPage );
        while ( aIter.IsMore() )
        {
            SdrObject* pSdrObject = aIter.Next();
            FmFormObj* pFormObject = FmFormObj::GetFormObject( pSdrObject );
            if ( !pFormObject )
                continue;

            Reference< XFormComponent > xControlModel( pFormObject->GetUnoControlModel(),UNO_QUERY );
            if ( xControlModel.is() && aObjects.find(xControlModel) != aObjects.end() && bMark != pFormView->IsObjMarked( pSdrObject ) )
            {
                // unfortunately, the writer doesn't like marking an already-marked object, again, so reset the mark first
                pFormView->MarkObj( pSdrObject, pPageView, !bMark, sal_False );
            }            
        } // while ( aIter.IsMore() )
        if ( bMark )
        {
            // make the mark visible
            ::Rectangle aMarkRect( pFormView->GetAllMarkedRect());
            for ( sal_uInt32 i = 0; i < pFormView->PaintWindowCount(); ++i )
            {
                SdrPaintWindow* pPaintWindow = pFormView->GetPaintWindow( i );
                OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
                if ( ( OUTDEV_WINDOW == rOutDev.GetOutDevType() ) && !aMarkRect.IsEmpty() )
                {
                    pFormView->MakeVisible( aMarkRect, (Window&)rOutDev );
                }
            } // for ( sal_uInt32 i = 0; i < pFormView->PaintWindowCount(); ++i )
        }
    }
    //------------------------------------------------------------------------
    void NavigatorTree::CollectObjects(FmFormData* pFormData, sal_Bool bDeep, ::std::set< Reference< XFormComponent > >& _rObjects)
    {
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::MarkViewObjects" );
        FmEntryDataList* pChildList = pFormData->GetChildList();
        FmEntryData* pEntryData;
		FmControlData* pControlData;
	    for( sal_uInt32 i=0; i < pChildList->Count(); ++i )
	    {
		    pEntryData = pChildList->GetObject(i);
		    if( pEntryData->ISA(FmControlData) )
		    {
			    pControlData = (FmControlData*)pEntryData;
                _rObjects.insert(pControlData->GetFormComponent());
		    } // if( pEntryData->ISA(FmControlData) ) 
            else if (bDeep && (pEntryData->ISA(FmFormData)))
                CollectObjects((FmFormData*)pEntryData,bDeep,_rObjects);
	    } // for( sal_uInt32 i=0; i<pChildList->Count(); i++ )
    }
	//------------------------------------------------------------------------
	void NavigatorTree::MarkViewObj( FmControlData* pControlData, sal_Bool bMarkHandles, sal_Bool bMark)
	{
        RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTree::MarkViewObj" );
		if( !pControlData ) 
            return;
		FmFormShell* pFormShell = GetNavModel()->GetFormShell();
		if( !pFormShell ) 
            return;

		//////////////////////////////////////////////////////////////////////
        // In der Page das entsprechende SdrObj finden und selektieren
        FmFormView*     pFormView       = pFormShell->GetFormView();
        Reference< XFormComponent >  xFormComponent( pControlData->GetFormComponent());
        SdrPageView*    pPageView       = pFormView->GetSdrPageView();
        SdrPage*        pPage           = pPageView->GetPage();

        bool bPaint = false;
        SdrObjListIter aIter( *pPage );
        while ( aIter.IsMore() )
        {
            SdrObject* pSdrObject = aIter.Next();
            FmFormObj* pFormObject = FmFormObj::GetFormObject( pSdrObject );
            if ( !pFormObject )
                continue;

            Reference< XInterface > xControlModel( pFormObject->GetUnoControlModel() );
            if ( xControlModel != xFormComponent )
                continue;

            // mark the object
            if ( bMark != pFormView->IsObjMarked( pSdrObject ) )
                // unfortunately, the writer doesn't like marking an already-marked object, again, so reset the mark first
                pFormView->MarkObj( pSdrObject, pPageView, !bMark, sal_False );

            if ( !bMarkHandles || !bMark )
                continue;

            bPaint = true;
            
        } // while ( aIter.IsMore() )
        if ( bPaint )
        {
            // make the mark visible
            ::Rectangle aMarkRect( pFormView->GetAllMarkedRect());
            for ( sal_uInt32 i = 0; i < pFormView->PaintWindowCount(); ++i )
            {
                SdrPaintWindow* pPaintWindow = pFormView->GetPaintWindow( i );
                OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
                if ( OUTDEV_WINDOW == rOutDev.GetOutDevType() )
                {
                    pFormView->MakeVisible( aMarkRect, (Window&)rOutDev );
                }
            } // for ( sal_uInt32 i = 0; i < pFormView->PaintWindowCount(); ++i )
        }
    }

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


