/**************************************************************
 * 
 * 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 <tools/urlobj.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/help.hxx>
#include <sfx2/sfxsids.hrc>		// SID_ATTR_MACROITEM
#define _ANIMATION
#include <svtools/imaprect.hxx>
#include <svtools/imapcirc.hxx>
#include <svtools/imappoly.hxx>
#include <svl/urlbmk.hxx>

#include <svx/xoutbmp.hxx>
#include <svx/dialmgr.hxx>
#include <svx/dialogs.hrc>
#include <svx/svxids.hrc>
#include <imapdlg.hrc>
#include <imapwnd.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdorect.hxx>
#include <svx/svdocirc.hxx>
#include <svx/svdopath.hxx>
#include <svx/xfltrit.hxx>
#include <svx/svdpagv.hxx>
#include <svl/urihelper.hxx>
#include <svx/xfillit.hxx>
#include <svx/xlineit.hxx>
#include <sfx2/evntconf.hxx>

#include <sot/formats.hxx>

#include <svx/svxdlg.hxx>
#include <svx/dialogs.hrc>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>

using ::com::sun::star::frame::XFrame;
using ::com::sun::star::uno::Reference;

#define TRANSCOL Color( COL_WHITE )

/*************************************************************************
|*
|*
|*
\************************************************************************/

IMapWindow::IMapWindow( Window* pParent, const ResId& rResId, const Reference< XFrame >& rxDocumentFrame ) :
			GraphCtrl( pParent, rResId ),
			DropTargetHelper( this ),
            mxDocumentFrame( rxDocumentFrame )
{
	SetWinStyle( WB_SDRMODE );

	pItemInfo = new SfxItemInfo[ 1 ];
	memset( pItemInfo, 0, sizeof( SfxItemInfo ) );
	pIMapPool = new SfxItemPool( String::CreateFromAscii( "IMapItemPool" ),
								 SID_ATTR_MACROITEM, SID_ATTR_MACROITEM, pItemInfo );
	pIMapPool->FreezeIdRanges();
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

IMapWindow::~IMapWindow()
{
	// Liste loeschen
	for( String* pStr = aTargetList.First(); pStr; pStr = aTargetList.Next() )
		delete pStr;

    SfxItemPool::Free(pIMapPool);
	delete[] pItemInfo;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::SetImageMap( const ImageMap& rImageMap )
{
	ReplaceImageMap( rImageMap, sal_False );
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::ReplaceImageMap( const ImageMap& rImageMap, sal_Bool /*bScaleToGraphic*/ )
{
	SdrPage* pPage = 0;
	aIMap = rImageMap;

	if(GetSdrModel())
	{
		// try to access page
		pPage = GetSdrModel()->GetPage(0L);
	}

	if(pPage)
	{
		// clear all draw objects
		pPage->Clear();
	}

	if(GetSdrView())
	{
		// #i63762# reset selection at view
		GetSdrView()->UnmarkAllObj();
	}

	// create new drawing objects
	const sal_uInt16 nCount(rImageMap.GetIMapObjectCount());

	for ( sal_uInt16 i(nCount); i > 0; i-- )
	{
		SdrObject* pNewObj = CreateObj( rImageMap.GetIMapObject( i - 1 ) );

		if ( pNewObj )
		{
			pPage->InsertObject( pNewObj );
		}
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

sal_Bool IMapWindow::ReplaceActualIMapInfo( const NotifyInfo& rNewInfo )
{
	const SdrObject*	pSdrObj = GetSelectedSdrObject();
	IMapObject*			pIMapObj;
	sal_Bool				bRet = sal_False;

	if ( pSdrObj && ( ( pIMapObj = GetIMapObj( pSdrObj ) ) != NULL ) )
	{
		pIMapObj->SetURL( rNewInfo.aMarkURL );
		pIMapObj->SetAltText( rNewInfo.aMarkAltText );
		pIMapObj->SetTarget( rNewInfo.aMarkTarget );
		pModel->SetChanged( sal_True );
		UpdateInfo( sal_False );

		bRet = sal_True;
	}

	return bRet;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

const ImageMap& IMapWindow::GetImageMap()
{
	if ( pModel->IsChanged() )
	{
		SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 );

		if ( pPage )
		{
			const long nCount = pPage->GetObjCount();

			aIMap.ClearImageMap();

			for ( long i = nCount - 1; i > -1; i-- )
				aIMap.InsertIMapObject( *( ( (IMapUserData*) pPage->GetObj( i )->GetUserData( 0 ) )->GetObject() ) );
		}

		pModel->SetChanged( sal_False );
	}

	return aIMap;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::SetTargetList( TargetList& rTargetList )
{
	String* pStr;

	// alte Liste loeschen
	for( pStr = aTargetList.First(); pStr; pStr = aTargetList.Next() )
		delete pStr;

	aTargetList.Clear();

	// mit uebergebener Liste fuellen
	for( pStr = rTargetList.First(); pStr; pStr = rTargetList.Next() )
		aTargetList.Insert( new String( *pStr ) );

	pModel->SetChanged( sal_False );
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

SdrObject* IMapWindow::CreateObj( const IMapObject* pIMapObj )
{
	Point 		aPoint;
	Rectangle 	aClipRect( aPoint, GetGraphicSize() );
	SdrObject*	pSdrObj = NULL;
	IMapObjectPtr pCloneIMapObj;

	switch( pIMapObj->GetType() )
	{
		case( IMAP_OBJ_RECTANGLE ):
		{
			IMapRectangleObject*	pIMapRectObj = (IMapRectangleObject*) pIMapObj;
			Rectangle				aDrawRect( pIMapRectObj->GetRectangle( sal_False ) );

			// auf Zeichenflaeche clippen
			aDrawRect.Intersection( aClipRect );

			pSdrObj = (SdrObject*) new SdrRectObj( aDrawRect );
			pCloneIMapObj.reset((IMapObject*) new IMapRectangleObject( *pIMapRectObj ));
		}
		break;

		case( IMAP_OBJ_CIRCLE ):
		{
			IMapCircleObject*	pIMapCircleObj = (IMapCircleObject*) pIMapObj;
			const Point			aCenter( pIMapCircleObj->GetCenter( sal_False ) );
			const long			nRadius = pIMapCircleObj->GetRadius( sal_False );
			const Point			aOffset( nRadius, nRadius );
			Rectangle			aCircle( aCenter - aOffset, aCenter + aOffset );

			// auf Zeichenflaeche begrenzen
			aCircle.Intersection( aClipRect );

			pSdrObj = (SdrObject*) new SdrCircObj( OBJ_CIRC, aCircle, 0, 36000 );
			pCloneIMapObj.reset((IMapObject*) new IMapCircleObject( *pIMapCircleObj ));
		}
		break;

		case( IMAP_OBJ_POLYGON ):
		{
			IMapPolygonObject*	pIMapPolyObj = (IMapPolygonObject*) pIMapObj;

			// Falls wir eigentlich eine Ellipse sind,
			// erzeugen wir auch wieder eine Ellipse
			if ( pIMapPolyObj->HasExtraEllipse() )
			{
				Rectangle aDrawRect( pIMapPolyObj->GetExtraEllipse() );

				// auf Zeichenflaeche clippen
				aDrawRect.Intersection( aClipRect );

				pSdrObj = (SdrObject*) new SdrCircObj( OBJ_CIRC, aDrawRect, 0, 36000 );
			}
			else
			{
				const Polygon& 	rPoly = pIMapPolyObj->GetPolygon( sal_False );
                Polygon         aDrawPoly( rPoly );

				// auf Zeichenflaeche clippen
				aDrawPoly.Clip( aClipRect );

				basegfx::B2DPolygon aPolygon;
				aPolygon.append(aDrawPoly.getB2DPolygon());
				pSdrObj = (SdrObject*)new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aPolygon));
			}

			pCloneIMapObj.reset((IMapObject*) new IMapPolygonObject( *pIMapPolyObj ));
		}
		break;

		default:
		break;
	}

	if ( pSdrObj )
	{
		SfxItemSet aSet( pModel->GetItemPool() );

		aSet.Put( XFillStyleItem( XFILL_SOLID ) );
		aSet.Put( XFillColorItem( String(), TRANSCOL ) );

		if ( !pIMapObj->IsActive() )
		{
			aSet.Put( XFillTransparenceItem( 100 ) );
			aSet.Put( XLineColorItem( String(), Color( COL_RED ) ) );
		}
		else
		{
			aSet.Put( XFillTransparenceItem( 50 ) );
			aSet.Put( XLineColorItem( String(), Color( COL_BLACK ) ) );
		}

		//pSdrObj->SetItemSetAndBroadcast(aSet);
		pSdrObj->SetMergedItemSetAndBroadcast(aSet);

		pSdrObj->InsertUserData( new IMapUserData( pCloneIMapObj ) );
		pSdrObj->SetUserCall( GetSdrUserCall() );
	}

	return pSdrObj;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::InitSdrModel()
{
	GraphCtrl::InitSdrModel();

	SfxItemSet aSet( pModel->GetItemPool() );

	aSet.Put( XFillColorItem( String(), TRANSCOL ) );
	aSet.Put( XFillTransparenceItem( 50 ) );
	pView->SetAttributes( aSet );
	pView->SetFrameDragSingles( sal_True );
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::SdrObjCreated( const SdrObject& rObj )
{
	switch( rObj.GetObjIdentifier() )
	{
		case( OBJ_RECT ):
		{
			SdrRectObj*			 pRectObj = (SdrRectObj*) &rObj;
			IMapRectangleObject* pObj = new IMapRectangleObject( pRectObj->GetLogicRect(),
				String(), String(), String(), String(), String(), sal_True, sal_False );

			pRectObj->InsertUserData( new IMapUserData( IMapObjectPtr(pObj) ) );
		}
		break;

		case( OBJ_CIRC ):
		{
			SdrCircObj* pCircObj = (SdrCircObj*) &rObj;
			SdrPathObj* pPathObj = (SdrPathObj*) pCircObj->ConvertToPolyObj( sal_False, sal_False );
			Polygon aPoly(pPathObj->GetPathPoly().getB2DPolygon(0L));
			delete pPathObj;

			IMapPolygonObject* pObj = new IMapPolygonObject( Polygon(aPoly), String(), String(), String(), String(), String(),  sal_True, sal_False );
			pObj->SetExtraEllipse( aPoly.GetBoundRect() );
			pCircObj->InsertUserData( new IMapUserData( IMapObjectPtr(pObj) ) );
		}
		break;

		case( OBJ_POLY ):
		case( OBJ_FREEFILL ):
		case( OBJ_PATHPOLY ):
		case( OBJ_PATHFILL ):
		{
			SdrPathObj* pPathObj = (SdrPathObj*) &rObj;
			const basegfx::B2DPolyPolygon& rXPolyPoly = pPathObj->GetPathPoly();

			if ( rXPolyPoly.count() )
			{
				Polygon aPoly(rXPolyPoly.getB2DPolygon(0L));
				IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, String(), String(), String(), String(), String(),  sal_True, sal_False );
				pPathObj->InsertUserData( new IMapUserData( IMapObjectPtr(pObj) ) );
			}
		}
		break;

		default:
		break;
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::SdrObjChanged( const SdrObject& rObj )
{
	IMapUserData* pUserData = (IMapUserData*) rObj.GetUserData( 0 );

	if ( pUserData )
	{
		String			aURL;
		String			aAltText;
		String			aDesc;
		String			aTarget;
		IMapObjectPtr	pIMapObj = pUserData->GetObject();
		sal_Bool			bActive = sal_True;

		if ( pIMapObj.get() )
		{
			aURL = pIMapObj->GetURL();
			aAltText = pIMapObj->GetAltText();
			aDesc = pIMapObj->GetDesc();
			aTarget = pIMapObj->GetTarget();
			bActive = pIMapObj->IsActive();
		}

		switch( rObj.GetObjIdentifier() )
		{
			case( OBJ_RECT ):
			{
				pUserData->ReplaceObject( IMapObjectPtr(new IMapRectangleObject( ( (const SdrRectObj&) rObj ).GetLogicRect(),
						  aURL, aAltText, aDesc, aTarget, String(), bActive, sal_False ) ) );
			}
			break;

			case( OBJ_CIRC ):
			{
				const SdrCircObj& rCircObj = (const SdrCircObj&) rObj;
				SdrPathObj* pPathObj = (SdrPathObj*) rCircObj.ConvertToPolyObj( sal_False, sal_False );
				Polygon aPoly(pPathObj->GetPathPoly().getB2DPolygon(0L));

				IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, aURL, aAltText, aDesc, aTarget, String(), bActive, sal_False );
				pObj->SetExtraEllipse( aPoly.GetBoundRect() );

				// wurde von uns nur temporaer angelegt
				delete pPathObj;
				pUserData->ReplaceObject( IMapObjectPtr(pObj) );
			}
			break;

			case( OBJ_POLY ):
			case( OBJ_FREEFILL ):
			case( OBJ_PATHPOLY ):
			case( OBJ_PATHFILL ):
			{
				const SdrPathObj& rPathObj = (const SdrPathObj&) rObj;
				const basegfx::B2DPolyPolygon& rXPolyPoly = rPathObj.GetPathPoly();

				if ( rXPolyPoly.count() )
				{
					Polygon aPoly(rPathObj.GetPathPoly().getB2DPolygon(0L));
					IMapPolygonObject*	pObj = new IMapPolygonObject( aPoly, aURL, aAltText, aDesc, aTarget, String(), bActive, sal_False );
					pUserData->ReplaceObject( IMapObjectPtr(pObj) );
				}
			}
			break;

			default:
			break;
		}
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::MouseButtonUp(const MouseEvent& rMEvt)
{
	GraphCtrl::MouseButtonUp( rMEvt );
	UpdateInfo( sal_True );
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::MarkListHasChanged()
{
	GraphCtrl::MarkListHasChanged();
	UpdateInfo( sal_False );
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

SdrObject* IMapWindow::GetHitSdrObj( const Point& rPosPixel ) const
{
	SdrObject*	pObj = NULL;
	Point		aPt = PixelToLogic( rPosPixel );

	if ( Rectangle( Point(), GetGraphicSize() ).IsInside( aPt ) )
	{
		SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 );
		sal_uIntPtr	 nCount;

		if ( pPage && ( ( nCount = pPage->GetObjCount() ) > 0 ) )
		{
			for ( long i = nCount - 1; i >= 0; i-- )
			{
				SdrObject*	pTestObj = pPage->GetObj( i );
				IMapObject*	pIMapObj = GetIMapObj( pTestObj );

				if ( pIMapObj && pIMapObj->IsHit( aPt ) )
				{
					pObj = pTestObj;
					break;
				}
			}
		}
	}

	return pObj;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

IMapObject* IMapWindow::GetIMapObj( const SdrObject* pSdrObj ) const
{
	IMapObject*	pIMapObj = NULL;

	if ( pSdrObj )
	{
		IMapUserData* pUserData = (IMapUserData*) pSdrObj->GetUserData( 0 );

		if ( pUserData )
			pIMapObj = pUserData->GetObject().get();
	}

	return pIMapObj;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

SdrObject* IMapWindow::GetSdrObj( const IMapObject* pIMapObj ) const
{
	SdrObject*	pSdrObj = NULL;
	SdrPage*	pPage = (SdrPage*) pModel->GetPage( 0 );
	sal_uIntPtr		nCount;

	if ( pPage && ( ( nCount = pPage->GetObjCount() ) > 0 ) )
	{
		for ( sal_uIntPtr i = 0; i < nCount; i++ )
		{
			SdrObject* pTestObj = pPage->GetObj( i );

			if ( pIMapObj == GetIMapObj( pTestObj ) )
			{
				pSdrObj = pTestObj;
				break;
			}
		}
	}

	return pSdrObj;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::Command(const CommandEvent& rCEvt)
{
	Region  aRegion;

	if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
	{
		PopupMenu			aMenu( SVX_RES( RID_SVXMN_IMAP ) );
		const SdrMarkList&	rMarkList = pView->GetMarkedObjectList();
		sal_uIntPtr				nMarked = rMarkList.GetMarkCount();

		aMenu.EnableItem( MN_URL, sal_False );
		aMenu.EnableItem( MN_ACTIVATE, sal_False );
		aMenu.EnableItem( MN_MACRO, sal_False );
		aMenu.EnableItem( MN_MARK_ALL, pModel->GetPage( 0 )->GetObjCount() != pView->GetMarkedObjectCount() );

		if ( !nMarked )
		{
			aMenu.EnableItem( MN_POSITION, sal_False );
			aMenu.EnableItem( MN_FRAME_TO_TOP, sal_False );
			aMenu.EnableItem( MN_MOREFRONT, sal_False );
			aMenu.EnableItem( MN_MOREBACK, sal_False );
			aMenu.EnableItem( MN_FRAME_TO_BOTTOM, sal_False );
            aMenu.EnableItem( MN_DELETE1, sal_False );
		}
		else
		{
			if ( nMarked == 1 )
			{
				SdrObject*	pSdrObj = GetSelectedSdrObject();

				aMenu.EnableItem( MN_URL, sal_True );
				aMenu.EnableItem( MN_ACTIVATE, sal_True );
				aMenu.EnableItem( MN_MACRO, sal_True );
				aMenu.CheckItem( MN_ACTIVATE, GetIMapObj( pSdrObj )->IsActive() );
			}

			aMenu.EnableItem( MN_POSITION, sal_True );
			aMenu.EnableItem( MN_FRAME_TO_TOP, sal_True );
			aMenu.EnableItem( MN_MOREFRONT, sal_True );
			aMenu.EnableItem( MN_MOREBACK, sal_True );
			aMenu.EnableItem( MN_FRAME_TO_BOTTOM, sal_True );
            aMenu.EnableItem( MN_DELETE1, sal_True );
		}

		aMenu.SetSelectHdl( LINK( this, IMapWindow, MenuSelectHdl ) );
		aMenu.Execute( this, rCEvt.GetMousePosPixel() );
	}
	else
		Window::Command(rCEvt);
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

sal_Int8 IMapWindow::AcceptDrop( const AcceptDropEvent& rEvt )
{
	return( ( GetHitSdrObj( rEvt.maPosPixel ) != NULL ) ? rEvt.mnAction : DND_ACTION_NONE );
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

sal_Int8 IMapWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
	sal_Int8 nRet = DND_ACTION_NONE;

	if( IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
	{
		const String	aString;
		INetBookmark	aBookMark( aString, aString );
		SdrObject*		pSdrObj = GetHitSdrObj( rEvt.maPosPixel );

		if( pSdrObj && TransferableDataHelper( rEvt.maDropEvent.Transferable ).GetINetBookmark( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, aBookMark ) )
		{
			IMapObject* pIMapObj = GetIMapObj( pSdrObj );

			pIMapObj->SetURL( aBookMark.GetURL() );
			pIMapObj->SetAltText( aBookMark.GetDescription() );
			pModel->SetChanged( sal_True );
			pView->UnmarkAll();
			pView->MarkObj( pSdrObj, pView->GetSdrPageView() );
			UpdateInfo( sal_True );
			nRet =  rEvt.mnAction;
		}
	}

	return nRet;
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::RequestHelp( const HelpEvent& rHEvt )
{
	SdrObject*			pSdrObj = NULL;
	SdrPageView*		pPageView = NULL;
	Point				aPos = PixelToLogic( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );

	if ( Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled() )
	{
		if ( pView->PickObj( aPos, pView->getHitTolLog(), pSdrObj, pPageView ) )
		{
			const IMapObject*	pIMapObj = GetIMapObj( pSdrObj );
			String				aStr;

			if ( pIMapObj && ( aStr = pIMapObj->GetURL() ).Len() )
			{
				String		aDescr( pIMapObj->GetAltText() );
				Rectangle	aLogicPix( LogicToPixel( Rectangle( Point(), GetGraphicSize() ) ) );
				Rectangle	aScreenRect( OutputToScreenPixel( aLogicPix.TopLeft() ),
										 OutputToScreenPixel( aLogicPix.BottomRight() ) );

				if ( Help::IsBalloonHelpEnabled() )
					Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aScreenRect, aStr );
				else if ( Help::IsQuickHelpEnabled() )
					Help::ShowQuickHelp( this, aScreenRect, aStr );
			}
		}
		else
			Window::RequestHelp( rHEvt );
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::SetCurrentObjState( sal_Bool bActive )
{
	SdrObject* pObj = GetSelectedSdrObject();

	if ( pObj )
	{
		SfxItemSet aSet( pModel->GetItemPool() );

		GetIMapObj( pObj )->SetActive( bActive );

		aSet.Put( XFillColorItem( String(), TRANSCOL ) );

		if ( !bActive )
		{
			aSet.Put( XFillTransparenceItem( 100 ) );
			aSet.Put( XLineColorItem( String(), Color( COL_RED ) ) );
		}
		else
		{
			aSet.Put( XFillTransparenceItem( 50 ) );
			aSet.Put( XLineColorItem( String(), Color( COL_BLACK ) ) );
		}

		pView->SetAttributes( aSet, sal_False );
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::UpdateInfo( sal_Bool bNewObj )
{
	if ( aInfoLink.IsSet() )
	{
		const SdrObject*	pSdrObj = GetSelectedSdrObject();
		const IMapObject*	pIMapObj = pSdrObj ? GetIMapObj( pSdrObj ) : NULL;

		aInfo.bNewObj = bNewObj;

		if ( pIMapObj )
		{
			aInfo.bOneMarked = sal_True;
			aInfo.aMarkURL = pIMapObj->GetURL();
			aInfo.aMarkAltText = pIMapObj->GetAltText();
			aInfo.aMarkTarget = pIMapObj->GetTarget();
			aInfo.bActivated = pIMapObj->IsActive();
			aInfoLink.Call( this );
		}
		else
		{
			aInfo.aMarkURL = aInfo.aMarkAltText = aInfo.aMarkTarget = String();
			aInfo.bOneMarked = sal_False;
			aInfo.bActivated = sal_False;
		}

		aInfoLink.Call( this );
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::DoMacroAssign()
{
	SdrObject*	pSdrObj = GetSelectedSdrObject();

	if ( pSdrObj )
	{
		SfxItemSet		aSet( *pIMapPool, SID_ATTR_MACROITEM, SID_ATTR_MACROITEM, SID_EVENTCONFIG, SID_EVENTCONFIG, 0 );

		SfxEventNamesItem aNamesItem(SID_EVENTCONFIG);
		aNamesItem.AddEvent( String::CreateFromAscii( "MouseOver" ), String(), SFX_EVENT_MOUSEOVER_OBJECT );
		aNamesItem.AddEvent( String::CreateFromAscii( "MouseOut" ), String(), SFX_EVENT_MOUSEOUT_OBJECT );
		aSet.Put( aNamesItem );
		
        SvxMacroItem    aMacroItem(SID_ATTR_MACROITEM);
		IMapObject*		pIMapObj = GetIMapObj( pSdrObj );
		aMacroItem.SetMacroTable( pIMapObj->GetMacroTable() );
		aSet.Put( aMacroItem, SID_ATTR_MACROITEM );

		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
		SfxAbstractDialog* pMacroDlg = pFact->CreateSfxDialog( this, aSet, mxDocumentFrame, SID_EVENTCONFIG );

		if ( pMacroDlg && pMacroDlg->Execute() == RET_OK )
		{
			const SfxItemSet* pOutSet = pMacroDlg->GetOutputItemSet();
			pIMapObj->SetMacroTable( ((const SvxMacroItem& )pOutSet->Get( SID_ATTR_MACROITEM )).GetMacroTable() );
    		pModel->SetChanged( sal_True );
	        UpdateInfo( sal_False );
		}

		delete pMacroDlg;
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void IMapWindow::DoPropertyDialog()
{
	SdrObject*	pSdrObj = GetSelectedSdrObject();

	if ( pSdrObj )
	{
		IMapObject* pIMapObj = GetIMapObj( pSdrObj );
		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
		if(pFact)
		{
			AbstractURLDlg* aDlg = pFact->CreateURLDialog( this, pIMapObj->GetURL(), pIMapObj->GetAltText(), pIMapObj->GetDesc(),
											pIMapObj->GetTarget(), pIMapObj->GetName(), aTargetList );
			DBG_ASSERT(aDlg, "Dialogdiet fail!");
			if ( aDlg->Execute() == RET_OK )
			{
				const String aURLText( aDlg->GetURL() );

				if ( aURLText.Len() )
				{
                    INetURLObject aObj( aURLText, INET_PROT_FILE );
                    DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL" );
                    pIMapObj->SetURL( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
				}
				else
					pIMapObj->SetURL( aURLText );

				pIMapObj->SetAltText( aDlg->GetAltText() );
				pIMapObj->SetDesc( aDlg->GetDesc() );
				pIMapObj->SetTarget( aDlg->GetTarget() );
				pIMapObj->SetName( aDlg->GetName() );
				pModel->SetChanged( sal_True );
				UpdateInfo( sal_True );
			}
			delete aDlg; //add by CHINA001
		}
	}
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

IMPL_LINK( IMapWindow, MenuSelectHdl, Menu*, pMenu )
{
	if (pMenu)
	{
		sal_uInt16  nId = pMenu->GetCurItemId();

		switch(nId)
		{
			case( MN_URL ):
				DoPropertyDialog();
			break;

			case( MN_MACRO ):
				DoMacroAssign();
			break;

			case( MN_ACTIVATE ):
			{
				const sal_Bool bNewState = !pMenu->IsItemChecked( MN_ACTIVATE );

				pMenu->CheckItem( MN_ACTIVATE, bNewState );
				SetCurrentObjState( bNewState );
				UpdateInfo( sal_False );
			}

			case( MN_FRAME_TO_TOP ):
				pView->PutMarkedToTop();
			break;

			case( MN_MOREFRONT ):
				pView->MovMarkedToTop();
			break;

			case( MN_MOREBACK ):
				pView->MovMarkedToBtm();
			break;

			case( MN_FRAME_TO_BOTTOM ):
				pView->PutMarkedToBtm();
			break;

			case( MN_MARK_ALL ):
				pView->MarkAll();
			break;

            case( MN_DELETE1 ):
				pView->DeleteMarked();

			default :
			break;
		}
	}

	return 0;
}

void IMapWindow::CreateDefaultObject()
{
	SdrPageView* pPageView = pView->GetSdrPageView();

	if(pPageView)
	{
		// calc position and size
		Point aPagePos(0, 0); // = pPageView->GetOffset();
		Size aPageSize = pPageView->GetPage()->GetSize();
		sal_uInt32 nDefaultObjectSizeWidth = aPageSize.Width() / 4;
		sal_uInt32 nDefaultObjectSizeHeight = aPageSize.Height() / 4;
		aPagePos.X() += (aPageSize.Width() / 2) - (nDefaultObjectSizeWidth / 2);
		aPagePos.Y() += (aPageSize.Height() / 2) - (nDefaultObjectSizeHeight / 2);
		Rectangle aNewObjectRectangle(aPagePos, Size(nDefaultObjectSizeWidth, nDefaultObjectSizeHeight));

		SdrObject* pObj = SdrObjFactory::MakeNewObject(	pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(), 0L, pModel);
		pObj->SetLogicRect(aNewObjectRectangle);

		switch( pObj->GetObjIdentifier() )
		{
		case OBJ_POLY:
		case OBJ_PATHPOLY:
			{
				basegfx::B2DPolygon aInnerPoly;
				aInnerPoly.append(basegfx::B2DPoint(aNewObjectRectangle.BottomLeft().X(), aNewObjectRectangle.BottomLeft().Y()));
				aInnerPoly.append(basegfx::B2DPoint(aNewObjectRectangle.TopLeft().X(), aNewObjectRectangle.TopLeft().Y()));
				aInnerPoly.append(basegfx::B2DPoint(aNewObjectRectangle.TopCenter().X(), aNewObjectRectangle.TopCenter().Y()));
				aInnerPoly.append(basegfx::B2DPoint(aNewObjectRectangle.Center().X(), aNewObjectRectangle.Center().Y()));
				aInnerPoly.append(basegfx::B2DPoint(aNewObjectRectangle.RightCenter().X(), aNewObjectRectangle.RightCenter().Y()));
				aInnerPoly.append(basegfx::B2DPoint(aNewObjectRectangle.BottomRight().X(), aNewObjectRectangle.BottomRight().Y()));
				aInnerPoly.setClosed(true);
				((SdrPathObj*)pObj)->SetPathPoly(basegfx::B2DPolyPolygon(aInnerPoly));
				break;
			}
		case OBJ_FREEFILL:
		case OBJ_PATHFILL:
			{
				sal_Int32 nWdt(aNewObjectRectangle.GetWidth() / 2);
				sal_Int32 nHgt(aNewObjectRectangle.GetHeight() / 2);
				basegfx::B2DPolygon aInnerPoly(XPolygon(aNewObjectRectangle.Center(), nWdt, nHgt).getB2DPolygon());
				((SdrPathObj*)pObj)->SetPathPoly(basegfx::B2DPolyPolygon(aInnerPoly));
				break;
			}

		}

		pView->InsertObjectAtView(pObj, *pPageView);
		SdrObjCreated( *pObj );
		SetCurrentObjState( true );
		pView->MarkObj( pObj, pPageView );
	}
}

void IMapWindow::KeyInput( const KeyEvent& rKEvt )
{
	KeyCode aCode = rKEvt.GetKeyCode();

/*
	switch(aCode.GetCode())
	{
		case KEY_ESCAPE:
		{
			if ( pView->IsAction() )
			{
				pView->BrkAction();
				return;
			}
			else if ( pView->AreObjectsMarked() )
			{
				const SdrHdlList& rHdlList = pView->GetHdlList();
				SdrHdl* pHdl = rHdlList.GetFocusHdl();

				if(pHdl)
				{
					((SdrHdlList&)rHdlList).ResetFocusHdl();
				}
				else
				{
					pView->UnmarkAllObj();
					((Dialog*)GetParent())->GrabFocusToFirstControl();
				}

				return;
			}
		}
		break;

	}
*/
	GraphCtrl::KeyInput( rKEvt );
}

void IMapWindow::SelectFirstObject()
{
	SdrPage*	pPage = (SdrPage*) pModel->GetPage( 0 );
	if( pPage->GetObjCount() != 0 )
	{
		GrabFocus();
		pView->UnmarkAllObj();
		pView->MarkNextObj(sal_True);
	}
}

void IMapWindow::StartPolyEdit()
{
	GrabFocus();

	if( !pView->AreObjectsMarked() )
		pView->MarkNextObj(sal_True);

	const SdrHdlList& rHdlList = pView->GetHdlList();
	SdrHdl* pHdl = rHdlList.GetFocusHdl();

	if(!pHdl)
	{
		((SdrHdlList&)rHdlList).TravelFocusHdl(true);
	}
}
