/**************************************************************
 * 
 * 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 && _pView->areSdrObjectsSelected())
			{
				// 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
				const SdrObjectVector aSelection(_pView->getSelectedSdrObjectVectorFromSdrMarkView());

				for ( sal_uInt32 i(0); (i < aSelection.size()) && !bIsMarked; ++i )
				{
					SdrObject* pObj = aSelection[i];

					if ( pObj->getChildrenOfSdrObject() )
    				{
						// 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" );
	    const FmNavRemovedHint* pFmNavRemovedHint = dynamic_cast< const FmNavRemovedHint* >(&rHint);

		if( pFmNavRemovedHint )
		{
			FmEntryData* pEntryData = pFmNavRemovedHint->GetEntryData();
			Remove( pEntryData );
		}
		else 
		{
		    const FmNavInsertedHint* pFmNavInsertedHint = dynamic_cast< const FmNavInsertedHint* >(&rHint);

			if( pFmNavInsertedHint )
    		{
				FmEntryData* pEntryData = pFmNavInsertedHint->GetEntryData();
				sal_uInt32 nRelPos = pFmNavInsertedHint->GetRelPos();
			    Insert( pEntryData, nRelPos );
		    }
			else 
			{
			    const FmNavModelReplacedHint* pFmNavModelReplacedHint = dynamic_cast< const FmNavModelReplacedHint* >(&rHint);

				if( pFmNavModelReplacedHint )
        		{
					FmEntryData* pData = pFmNavModelReplacedHint->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
				{
				    const FmNavNameChangedHint* pFmNavNameChangedHint = dynamic_cast< const FmNavNameChangedHint* >(&rHint);

					if( pFmNavNameChangedHint )
            		{
						SvLBoxEntry* pEntry = FindEntry( pFmNavNameChangedHint->GetEntryData() );
						SetEntryText( pEntry, pFmNavNameChangedHint->GetNewName() );
            		}
					else
					{
					    const FmNavClearedHint* pFmNavClearedHint = dynamic_cast< const FmNavClearedHint* >(&rHint);

						if( pFmNavClearedHint )
                		{
			                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 )
						{
						    FmNavRequestSelectHint* pFmNavRequestSelectHint = dynamic_cast< FmNavRequestSelectHint* >(& const_cast< SfxHint& >(rHint));
							
							if( pFmNavRequestSelectHint )
		                    {   // 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
								FmEntryDataArray& arredToSelect = pFmNavRequestSelectHint->GetItems();
                    			SynchronizeSelection(arredToSelect);

								if (pFmNavRequestSelectHint->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 || dynamic_cast< FmFormData* >(pEntryData);
	}

	//------------------------------------------------------------------------
	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 && dynamic_cast< FmControlData* >(pEntryData);
	}

	//------------------------------------------------------------------------
	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 || dynamic_cast< FmFormData* >(pCurrentParentUserData), 
				"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()->getSelectedSdrObjectVectorFromSdrMarkView() );

		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();

		if(pPageView)
		{
			FmFormPage* pPage = dynamic_cast< FmFormPage* >(&pPageView->getSdrPageFromSdrPageView());
		    ::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( dynamic_cast< FmFormData* >(pEntryData) )
			aBaseName = SVX_RES( RID_STR_STDFORMNAME );

		else if( dynamic_cast< FmControlData* >(pEntryData) )
			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()->setCurrentSelectionFromSdrObjectVector( pFormShell->GetFormView()->getSelectedSdrObjectVectorFromSdrMarkView() );
        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->getSdrPageFromSdrPageView() : 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 = 0 != dynamic_cast< FmFormData* >(pCurrent);

			// 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 definitely 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
			FmFormData* pFmFormData = dynamic_cast< FmFormData* >(pCurrent);
			
			if (pFmFormData)
			{
				Reference< XForm >  xCurrentForm( pFmFormData->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->getSelectedSdrObjectVectorFromSdrMarkView());
	}

	//------------------------------------------------------------------------
	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 = dynamic_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->UnmarkAllObj();
	}
    //------------------------------------------------------------------------
    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();

		if(pPageView)
		{
			SdrPage* pPage = &pPageView->getSdrPageFromSdrPageView();
        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 != (sal_Bool)pFormView->IsObjMarked( *pSdrObject ) )
            {
                // unfortunately, the writer doesn't like marking an already-marked object, again, so reset the mark first
					pFormView->MarkObj( *pSdrObject, !bMark );
            }            
        } // while ( aIter.IsMore() )
        if ( bMark )
        {
            // make the mark visible
				const basegfx::B2DRange aMarkRange( pFormView->getMarkedObjectSnapRange());

            for ( sal_uInt32 i = 0; i < pFormView->PaintWindowCount(); ++i )
            {
                SdrPaintWindow* pPaintWindow = pFormView->GetPaintWindow( i );
                OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
                
					if ( ( OUTDEV_WINDOW == rOutDev.GetOutDevType() ) && !aMarkRange.isEmpty() )
                {
						pFormView->MakeVisibleAtView( aMarkRange, (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();
        
	    for( sal_uInt32 i=0; i < pChildList->Count(); ++i )
	    {
			FmEntryData* pEntryData = pChildList->GetObject(i);
			FmControlData* pControlData = dynamic_cast< FmControlData* >(pEntryData);

			if( pControlData )
		    {
                _rObjects.insert(pControlData->GetFormComponent());
		    } // if( dynamic_cast< FmControlData* >(pEntryData) ) 
            else if (bDeep)
			{
				FmFormData* pFmFormData = dynamic_cast< FmFormData* >(pEntryData);
	            
				if (pFmFormData)
				{
	                CollectObjects(pFmFormData,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();

		if(pPageView)
		{
			SdrPage* pPage = &pPageView->getSdrPageFromSdrPageView();
            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 != (sal_Bool)pFormView->IsObjMarked( *pSdrObject ) )
                    // unfortunately, the writer doesn't like marking an already-marked object, again, so reset the mark first
					pFormView->MarkObj( *pSdrObject, !bMark );

                if ( !bMarkHandles || !bMark )
                    continue;

                bPaint = true;
            
            } // while ( aIter.IsMore() )
            if ( bPaint )
            {
                // make the mark visible
			    const basegfx::B2DRange aMarkRange( pFormView->getMarkedObjectSnapRange());

                for ( sal_uInt32 i = 0; i < pFormView->PaintWindowCount(); ++i )
                {
                    SdrPaintWindow* pPaintWindow = pFormView->GetPaintWindow( i );
                    OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
                    if ( OUTDEV_WINDOW == rOutDev.GetOutDevType() )
                    {
						    pFormView->MakeVisibleAtView( aMarkRange, (Window&)rOutDev );
                    }
                } // for ( sal_uInt32 i = 0; i < pFormView->PaintWindowCount(); ++i )
            }
        }
    }

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


