/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: imapdlg.cxx,v $
 * $Revision: 1.36 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#define _SDR_NOITEMS
#define _SDR_NOTOUCH
#define _SDR_NOTRANSFORM
#define _SDR_NOOBJECTS
#define _SDR_NOVIEWMARKER
#define _SDR_NODRAGMETHODS
#define _SDR_NOUNDO
#define _SDR_NOXOUTDEV

#include <stdlib.h>
#include <tools/shl.hxx>
#ifndef _EINF_HXX
#include <tools/errinf.hxx>
#endif
#include <tools/urlobj.hxx>
#ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX
#include <unotools/ucbstreamhelper.hxx>
#endif
#include <vcl/msgbox.hxx>
#include <vcl/group.hxx>
#include <vcl/lstbox.hxx>
#include <svtools/eitem.hxx>
#include <svtools/pathoptions.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/module.hxx>
#include <sfx2/filedlghelper.hxx>
#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
#include <svtools/urihelper.hxx>
#include <svtools/miscopt.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/docfile.hxx>
#include <unotools/localedatawrapper.hxx>
#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif

#define _IMAPDLG_PRIVATE
#include "imapdlg.hxx"

#include <svx/dialmgr.hxx>
#include <svx/dialogs.hrc>
#include <svx/svxids.hrc>
#include "imapdlg.hrc"
#include "imapwnd.hxx"
#include "imapimp.hxx"
#include "dlgutil.hxx"
#include <svx/svdtrans.hxx>
#include <svx/svdopath.hxx>
#include <vcl/svapp.hxx>

#define SELF_TARGET			"_self"
#define	IMAP_ALL_FILTER		"<Alle>"
#define	IMAP_CERN_FILTER	"MAP - CERN"
#define	IMAP_NCSA_FILTER	"MAP - NCSA"
#define	IMAP_BINARY_FILTER	"SIP - StarView ImageMap"
#define IMAP_ALL_TYPE		"*.*"
#define IMAP_BINARY_TYPE	"*.sip"
#define IMAP_CERN_TYPE		"*.map"
#define IMAP_NCSA_TYPE		"*.map"
#define	IMAP_BINARY_EXT		"sip"
#define	IMAP_CERN_EXT		"map"
#define	IMAP_NCSA_EXT		"map"

/******************************************************************************/

SFX_IMPL_MODELESSDIALOG( SvxIMapDlgChildWindow, SID_IMAP );

/******************************************************************************/

inline String GetUnitString( long nVal_100, FieldUnit eFieldUnit, sal_Unicode cSep )
{
	String aVal = UniString::CreateFromInt64( MetricField::ConvertValue( nVal_100, 2, MAP_100TH_MM, eFieldUnit ) );

	while( aVal.Len() < 3 )
		aVal.Insert( sal_Unicode('0'), 0 );

	aVal.Insert( cSep, aVal.Len() - 2 );
	aVal += sal_Unicode(' ');
	aVal += SdrFormatter::GetUnitStr( eFieldUnit );

	return aVal;
}

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

SvxIMapDlgItem::SvxIMapDlgItem( USHORT _nId, SvxIMapDlg& rIMapDlg, SfxBindings& rBindings ) :
            SfxControllerItem   ( _nId, rBindings ),
			rIMap				( rIMapDlg )
{
}

/*************************************************************************
|*
|* StateChanged-Methode
|*
\************************************************************************/

void SvxIMapDlgItem::StateChanged( USHORT nSID, SfxItemState /*eState*/,
								   const SfxPoolItem* pItem )
{
	if ( ( nSID == SID_IMAP_EXEC ) && pItem )
	{
		const SfxBoolItem* pStateItem = PTR_CAST( SfxBoolItem, pItem );

		DBG_ASSERT( pStateItem || pItem == 0, "SfxBoolItem erwartet");

		// Float ggf. disablen
		rIMap.SetExecState( !pStateItem->GetValue() );
	}
}

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

SvxIMapDlgChildWindow::SvxIMapDlgChildWindow( Window* _pParent, USHORT nId,
											  SfxBindings* pBindings,
											  SfxChildWinInfo* pInfo ) :
            SfxChildWindow( _pParent, nId )
{
    pWindow = new SvxIMapDlg( pBindings, this, _pParent, SVX_RES( RID_SVXDLG_IMAP ) );
	SvxIMapDlg* pDlg = (SvxIMapDlg*) pWindow;

	if ( pInfo->nFlags & SFX_CHILDWIN_ZOOMIN )
		pDlg->RollUp();

	eChildAlignment = SFX_ALIGN_NOALIGNMENT;

    pDlg->Initialize( pInfo );
}


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

void SvxIMapDlgChildWindow::UpdateIMapDlg( const Graphic& rGraphic, const ImageMap* pImageMap,
										   const TargetList* pTargetList, void* pEditingObj )
{
	if ( SfxViewFrame::Current() &&
		 SfxViewFrame::Current()->HasChildWindow( SvxIMapDlgChildWindow::GetChildWindowId() ) )
		SVXIMAPDLG()->Update( rGraphic, pImageMap, pTargetList, pEditingObj );
}


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

SvxIMapDlg::SvxIMapDlg( SfxBindings *_pBindings, SfxChildWindow *pCW,
                        Window* _pParent, const ResId& rResId ) :
        SfxModelessDialog   ( _pBindings, pCW, _pParent, rResId ),
        
        aTbxIMapDlg1        ( this, SVX_RES( TBX_IMAPDLG1 ) ),
        aFtURL              ( this, SVX_RES( FT_URL ) ),
        maURLBox            ( this, SVX_RES( CBB_URL ) ),
        aFtText             ( this, SVX_RES( FT_TEXT ) ),
        aEdtText            ( this, SVX_RES( EDT_TEXT ) ),
        maFtTarget          ( this, SVX_RES( RID_SVXCTL_FT_TARGET ) ),
        maCbbTarget         ( this, SVX_RES( RID_SVXCTL_CBB_TARGET ) ),
        aStbStatus          ( this, WB_BORDER | WB_3DLOOK | WB_LEFT ),
        maImageList         ( SVX_RES( IL_IMAPDLG ) ),
        maImageListH        ( SVX_RES( ILH_IMAPDLG ) ),
        pCheckObj           ( NULL ),
        aIMapItem           ( SID_IMAP_EXEC, *this, *_pBindings )
{
	pIMapWnd = new IMapWindow( this, SVX_RES( RID_SVXCTL_IMAP ), _pBindings->GetActiveFrame() );

    ApplyImageList();

	FreeResource();

	pOwnData = new IMapOwnData( this );

	pIMapWnd->SetInfoLink( LINK( this, SvxIMapDlg, InfoHdl ) );
	pIMapWnd->SetMousePosLink( LINK( this, SvxIMapDlg, MousePosHdl ) );
	pIMapWnd->SetGraphSizeLink( LINK( this, SvxIMapDlg, GraphSizeHdl ) );
	pIMapWnd->SetUpdateLink( LINK( this, SvxIMapDlg, StateHdl ) );

	maURLBox.SetModifyHdl( LINK( this, SvxIMapDlg, URLModifyHdl ) );
	maURLBox.SetSelectHdl( LINK( this, SvxIMapDlg, URLModifyHdl ) );
	maURLBox.SetLoseFocusHdl( LINK( this, SvxIMapDlg, URLLoseFocusHdl ) );
	aEdtText.SetModifyHdl( LINK( this, SvxIMapDlg, URLModifyHdl ) );
	maCbbTarget.SetLoseFocusHdl( LINK( this, SvxIMapDlg, URLLoseFocusHdl ) );

   	SvtMiscOptions aMiscOptions;
    aMiscOptions.AddListener( LINK( this, SvxIMapDlg, MiscHdl ) );

    aTbxIMapDlg1.SetOutStyle( aMiscOptions.GetToolboxStyle() );
	aTbxIMapDlg1.SetSizePixel( aTbxIMapDlg1.CalcWindowSizePixel() );
	aTbxIMapDlg1.SetSelectHdl( LINK( this, SvxIMapDlg, TbxClickHdl ) );
	aTbxIMapDlg1.CheckItem( TBI_SELECT, TRUE );
	TbxClickHdl( &aTbxIMapDlg1 );

	SetMinOutputSizePixel( aLastSize = GetOutputSizePixel() );

	aStbStatus.InsertItem( 1, 130, SIB_LEFT | SIB_IN | SIB_AUTOSIZE );
	aStbStatus.InsertItem( 2, 10 + GetTextWidth( DEFINE_CONST_UNICODE( " 9999,99 cm / 9999,99 cm ") ), SIB_CENTER | SIB_IN );
	aStbStatus.InsertItem( 3, 10 + GetTextWidth( DEFINE_CONST_UNICODE( " 9999,99 cm x 9999,99 cm ") ), SIB_CENTER | SIB_IN );

	aFtURL.Disable();
	maURLBox.Disable();
	aFtText.Disable();
	aEdtText.Disable();
	maFtTarget.Disable();
	maCbbTarget.Disable();
	pOwnData->bExecState = FALSE;

	Resize();

	pOwnData->aTimer.SetTimeout( 100 );
	pOwnData->aTimer.SetTimeoutHdl( LINK( this, SvxIMapDlg, UpdateHdl ) );

	aTbxIMapDlg1.EnableItem( TBI_ACTIVE, FALSE );
	aTbxIMapDlg1.EnableItem( TBI_MACRO, FALSE );
	aTbxIMapDlg1.EnableItem( TBI_PROPERTY, FALSE );
}


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

SvxIMapDlg::~SvxIMapDlg()
{
	// URL-Liste loeschen
	delete pIMapWnd;
	delete pOwnData;
}


/*************************************************************************
|*
|* Resize-Methode
|*
\************************************************************************/

void SvxIMapDlg::Resize()
{
	SfxModelessDialog::Resize();

	Size aMinSize( GetMinOutputSizePixel() );
	Size aNewSize( GetOutputSizePixel() );

	if ( aNewSize.Height() >= aMinSize.Height() )
	{
        Size    _aSize( aStbStatus.GetSizePixel() );
        Point   aPoint( 0, aNewSize.Height() - _aSize.Height() );

		// StatusBar positionieren
        aStbStatus.SetPosSizePixel( aPoint, Size( aNewSize.Width(), _aSize.Height() ) );
		aStbStatus.Show();

		// EditWindow positionieren
        _aSize.Width() = aNewSize.Width() - 18;
        _aSize.Height() = aPoint.Y() - pIMapWnd->GetPosPixel().Y() - 6;
        pIMapWnd->SetSizePixel( _aSize );

		aLastSize = aNewSize;
	}
}


/*************************************************************************
|*
|* Close-Methode
|*
\************************************************************************/

BOOL SvxIMapDlg::Close()
{
	BOOL bRet = TRUE;

	if ( aTbxIMapDlg1.IsItemEnabled( TBI_APPLY ) )
	{
		QueryBox	aQBox( this, WB_YES_NO_CANCEL | WB_DEF_YES,
						   String( SVX_RES( STR_IMAPDLG_MODIFY ) ) );
		const long	nRet = aQBox.Execute();

		if( nRet == RET_YES )
		{
			SfxBoolItem aBoolItem( SID_IMAP_EXEC, TRUE );
			GetBindings().GetDispatcher()->Execute(
				SID_IMAP_EXEC, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD, &aBoolItem, 0L );
		}
		else if( nRet == RET_CANCEL )
			bRet = FALSE;
	}
	else if( pIMapWnd->IsChanged() )
	{
		QueryBox	aQBox( this, WB_YES_NO_CANCEL | WB_DEF_YES,
						   String( SVX_RES( STR_IMAPDLG_SAVE ) ) );
		const long	nRet = aQBox.Execute();

		if( nRet == RET_YES )
			bRet = DoSave();
		else if( nRet == RET_CANCEL )
			bRet = FALSE;
	}

	return( bRet ? SfxModelessDialog::Close() : FALSE );
}


/*************************************************************************
|*
|* Enabled oder disabled alle Controls
|*
\************************************************************************/

void SvxIMapDlg::SetExecState( BOOL bEnable )
{
	pOwnData->bExecState = bEnable;
}


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

void SvxIMapDlg::SetGraphic( const Graphic& rGraphic )
{
	pIMapWnd->SetGraphic( rGraphic );
}


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

void SvxIMapDlg::SetImageMap( const ImageMap& rImageMap )
{
	pIMapWnd->SetImageMap( rImageMap );
}


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

const ImageMap& SvxIMapDlg::GetImageMap() const
{
	return pIMapWnd->GetImageMap();
}


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

void SvxIMapDlg::SetTargetList( const TargetList& rTargetList )
{
	TargetList	aNewList( rTargetList );

	pIMapWnd->SetTargetList( aNewList );

	maCbbTarget.Clear();

	for( String* pStr = aNewList.First(); pStr; pStr = aNewList.Next() )
		maCbbTarget.InsertEntry( *pStr );
}


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

const TargetList& SvxIMapDlg::GetTargetList() const
{
	return pIMapWnd->GetTargetList();
}


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

void SvxIMapDlg::Update( const Graphic& rGraphic, const ImageMap* pImageMap,
						 const TargetList* pTargetList, void* pEditingObj )
{
	pOwnData->aUpdateGraphic = rGraphic;

	if ( pImageMap )
		pOwnData->aUpdateImageMap = *pImageMap;
	else
		pOwnData->aUpdateImageMap.ClearImageMap();

	pOwnData->pUpdateEditingObject = pEditingObj;

	// UpdateTargetList loeschen, da diese Methode
	// vor dem Zuschlagen des Update-Timers noch
	// mehrmals gerufen werden kann( #46540 )
	for( String* pStr = pOwnData->aUpdateTargetList.First(); pStr; pStr = pOwnData->aUpdateTargetList.Next() )
		delete pStr;
	pOwnData->aUpdateTargetList.Clear();

	// TargetListe muss kopiert werden, da sie im
	// Besitz des Aufrufers ist und von ihm nach diesem
	// Aufruf sofort geloescht werden kann;
	// die kopierte Liste wird im Handler wieder geloescht
	if( pTargetList )
	{
		TargetList aTargetList( *pTargetList );

		for( String* pStr = aTargetList.First(); pStr; pStr = aTargetList.Next() )
			pOwnData->aUpdateTargetList.Insert( new String( *pStr ) );
	}

	pOwnData->aTimer.Start();
}


void SvxIMapDlg::KeyInput( const KeyEvent& rKEvt )
{
		SfxModelessDialog::KeyInput( rKEvt );
}

/*************************************************************************
|*
|* Click-Hdl fuer ToolBox
|*
\************************************************************************/

IMPL_LINK( SvxIMapDlg, TbxClickHdl, ToolBox*, pTbx )
{
	USHORT nNewItemId = pTbx->GetCurItemId();

	switch( pTbx->GetCurItemId() )
	{
		case( TBI_APPLY ):
		{
        	URLLoseFocusHdl( NULL );
			SfxBoolItem aBoolItem( SID_IMAP_EXEC, TRUE );
			GetBindings().GetDispatcher()->Execute(
				SID_IMAP_EXEC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aBoolItem, 0L );
		}
		break;

		case( TBI_OPEN ):
			DoOpen();
		break;

		case( TBI_SAVEAS ):
			DoSave();
		break;

		case( TBI_SELECT ):
		{
			pTbx->CheckItem( nNewItemId, TRUE );
			pIMapWnd->SetEditMode( TRUE );
			if( pTbx->IsKeyEvent() )
			{
				if((pTbx->GetKeyModifier() & KEY_MOD1) != 0)
					pIMapWnd->SelectFirstObject();
				else
					pIMapWnd->GrabFocus();
			}
		}
		break;

		case( TBI_RECT ):
		{
			pTbx->CheckItem( nNewItemId, TRUE );
			pIMapWnd->SetObjKind( OBJ_RECT );
			if( pTbx->IsKeyEvent() && ((pTbx->GetKeyModifier() & KEY_MOD1) != 0) )
			{
				pIMapWnd->CreateDefaultObject();
				pIMapWnd->GrabFocus();
			}
		}
		break;

		case( TBI_CIRCLE ):
		{
			pTbx->CheckItem( nNewItemId, TRUE );
			pIMapWnd->SetObjKind( OBJ_CIRC );
			if( pTbx->IsKeyEvent() && ((pTbx->GetKeyModifier() & KEY_MOD1) != 0) )
			{
				pIMapWnd->CreateDefaultObject();
				pIMapWnd->GrabFocus();
			}
		}
		break;

		case( TBI_POLY ):
		{
			pTbx->CheckItem( nNewItemId, TRUE );
			pIMapWnd->SetObjKind( OBJ_POLY );
			if( pTbx->IsKeyEvent() && ((pTbx->GetKeyModifier() & KEY_MOD1) != 0) )
			{
				pIMapWnd->CreateDefaultObject();
				pIMapWnd->GrabFocus();
			}
		}
		break;

		case( TBI_FREEPOLY ):
		{
			pTbx->CheckItem( nNewItemId, TRUE );
			pIMapWnd->SetObjKind( OBJ_FREEFILL );
			if( pTbx->IsKeyEvent() && ((pTbx->GetKeyModifier() & KEY_MOD1) != 0) )
			{
				pIMapWnd->CreateDefaultObject();
				pIMapWnd->GrabFocus();
			}
		}
		break;

		case( TBI_ACTIVE ):
		{
        	URLLoseFocusHdl( NULL );
            BOOL bNewState = !pTbx->IsItemChecked( TBI_ACTIVE );
			pTbx->CheckItem( TBI_ACTIVE, bNewState );
			pIMapWnd->SetCurrentObjState( !bNewState );
		}
		break;

		case( TBI_MACRO ):
			pIMapWnd->DoMacroAssign();
		break;

		case( TBI_PROPERTY ):
			pIMapWnd->DoPropertyDialog();
		break;

		case( TBI_POLYEDIT ):
			pIMapWnd->SetPolyEditMode( pTbx->IsItemChecked( TBI_POLYEDIT ) ? SID_BEZIER_MOVE : 0 );
			if( pTbx->IsKeyEvent() && pTbx->IsItemChecked( TBI_POLYEDIT ) )
				pIMapWnd->StartPolyEdit();
		break;

		case( TBI_POLYMOVE ):
			pIMapWnd->SetPolyEditMode( SID_BEZIER_MOVE );
		break;

		case( TBI_POLYINSERT ):
			pIMapWnd->SetPolyEditMode( SID_BEZIER_INSERT );
		break;

		case( TBI_POLYDELETE ):
			pIMapWnd->GetSdrView()->DeleteMarkedPoints();
		break;

		case( TBI_UNDO ):
        {
        	URLLoseFocusHdl( NULL );
			pIMapWnd->GetSdrModel()->Undo();
        }
		break;

		case( TBI_REDO ):
        {
        	URLLoseFocusHdl( NULL );
			pIMapWnd->GetSdrModel()->Redo();
        }
		break;

		default:
		break;
	}

	return 0;
}


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

void SvxIMapDlg::DoOpen()
{
   	::sfx2::FileDialogHelper aDlg(
        com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 );

	ImageMap		aLoadIMap;
	const String	aFilter( DEFINE_CONST_UNICODE( IMAP_ALL_FILTER ) );

	aDlg.AddFilter( aFilter, DEFINE_CONST_UNICODE( IMAP_ALL_TYPE ) );
	aDlg.AddFilter( DEFINE_CONST_UNICODE( IMAP_CERN_FILTER ), DEFINE_CONST_UNICODE( IMAP_CERN_TYPE ) );
	aDlg.AddFilter( DEFINE_CONST_UNICODE( IMAP_NCSA_FILTER ), DEFINE_CONST_UNICODE( IMAP_NCSA_TYPE ) );
	aDlg.AddFilter( DEFINE_CONST_UNICODE( IMAP_BINARY_FILTER ), DEFINE_CONST_UNICODE( IMAP_BINARY_TYPE ) );

	aDlg.SetCurrentFilter( aFilter );
	aDlg.SetDisplayDirectory( SvtPathOptions().GetWorkPath() );

	if( aDlg.Execute() == ERRCODE_NONE )
	{
		INetURLObject aURL( aDlg.GetPath() );
		DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
		SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );

		if( pIStm )
		{
            aLoadIMap.Read( *pIStm, IMAP_FORMAT_DETECT, String() );

			if( pIStm->GetError() )
				ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
			else
				pIMapWnd->SetImageMap( aLoadIMap );

			delete pIStm;
		}

		pIMapWnd->Invalidate();
	}
}


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

BOOL SvxIMapDlg::DoSave()
{
   	::sfx2::FileDialogHelper aDlg(
        com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, 0 );

	const String	aBinFilter( DEFINE_CONST_UNICODE( IMAP_BINARY_FILTER ) );
	const String	aCERNFilter( DEFINE_CONST_UNICODE( IMAP_CERN_FILTER ) );
	const String	aNCSAFilter( DEFINE_CONST_UNICODE( IMAP_NCSA_FILTER ) );
	SdrModel*		pModel = pIMapWnd->GetSdrModel();
	const sal_Bool bChanged = pModel->IsChanged();
	BOOL			bRet = false;

	aDlg.AddFilter( aCERNFilter, DEFINE_CONST_UNICODE( IMAP_CERN_TYPE ) );
	aDlg.AddFilter( aNCSAFilter, DEFINE_CONST_UNICODE( IMAP_NCSA_TYPE ) );
	aDlg.AddFilter( aBinFilter, DEFINE_CONST_UNICODE( IMAP_BINARY_TYPE ) );

	aDlg.SetCurrentFilter( aCERNFilter );
	aDlg.SetDisplayDirectory( SvtPathOptions().GetWorkPath() );

	if( aDlg.Execute() == ERRCODE_NONE )
	{
		const String	aFilter( aDlg.GetCurrentFilter() );
		String			aExt;
		ULONG			nFormat;

		if ( aFilter == aBinFilter )
		{
			nFormat = IMAP_FORMAT_BIN;
			aExt = DEFINE_CONST_UNICODE( IMAP_BINARY_EXT );
		}
		else if ( aFilter == aCERNFilter )
		{
			nFormat = IMAP_FORMAT_CERN;
			aExt = DEFINE_CONST_UNICODE( IMAP_CERN_EXT );
		}
		else if ( aFilter == aNCSAFilter )
		{
			nFormat = IMAP_FORMAT_NCSA;
			aExt = DEFINE_CONST_UNICODE( IMAP_NCSA_EXT );
		}
		else
		{
			return FALSE;
		}

		INetURLObject aURL( aDlg.GetPath() );

		if( aURL.GetProtocol() == INET_PROT_NOT_VALID )
		{
			DBG_ERROR( "invalid URL" );
		}
		else
		{
			if( !aURL.getExtension().getLength() )
				aURL.setExtension( aExt );

			SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_TRUNC );
			if( pOStm )
			{
                pIMapWnd->GetImageMap().Write( *pOStm, nFormat, String() );

				if( pOStm->GetError() )
					ErrorHandler::HandleError( ERRCODE_IO_GENERAL );

				delete pOStm;
				pModel->SetChanged( bChanged );
				bRet = TRUE;
			}
		}
	}

	return bRet;
}


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

IMPL_LINK( SvxIMapDlg, InfoHdl, IMapWindow*, pWnd )
{
	String				aStr;
	const NotifyInfo&	rInfo = pWnd->GetInfo();

	if ( rInfo.bNewObj )
	{
		if( rInfo.aMarkURL.Len() && ( maURLBox.GetEntryPos( rInfo.aMarkURL ) == LISTBOX_ENTRY_NOTFOUND ) )
			maURLBox.InsertEntry( rInfo.aMarkURL );

		maURLBox.SetText( rInfo.aMarkURL );
		aEdtText.SetText( rInfo.aMarkAltText );

		if ( !rInfo.aMarkTarget.Len() )
			maCbbTarget.SetText( DEFINE_CONST_UNICODE( SELF_TARGET ) );
		else
			maCbbTarget.SetText( rInfo.aMarkTarget );
	}

	if ( !rInfo.bOneMarked )
	{
		aTbxIMapDlg1.CheckItem( TBI_ACTIVE, FALSE );
		aTbxIMapDlg1.EnableItem( TBI_ACTIVE, FALSE );
		aTbxIMapDlg1.EnableItem( TBI_MACRO, FALSE );
		aTbxIMapDlg1.EnableItem( TBI_PROPERTY, FALSE );
		aStbStatus.SetItemText( 1, aStr );

		aFtURL.Disable();
		maURLBox.Disable();
		aFtText.Disable();
		aEdtText.Disable();
		maFtTarget.Disable();
		maCbbTarget.Disable();

		maURLBox.SetText( String() );
		aEdtText.SetText( String() );
	}
	else
	{
		aTbxIMapDlg1.EnableItem( TBI_ACTIVE, TRUE );
		aTbxIMapDlg1.CheckItem( TBI_ACTIVE, !rInfo.bActivated );
		aTbxIMapDlg1.EnableItem( TBI_MACRO, TRUE );
		aTbxIMapDlg1.EnableItem( TBI_PROPERTY, TRUE );

		aFtURL.Enable();
		maURLBox.Enable();
		aFtText.Enable();
		aEdtText.Enable();
		maFtTarget.Enable();
		maCbbTarget.Enable();

		aStbStatus.SetItemText( 1, rInfo.aMarkURL );

		if ( maURLBox.GetText() != rInfo.aMarkURL )
			maURLBox.SetText( rInfo.aMarkURL );

		if ( aEdtText.GetText() != rInfo.aMarkAltText )
			aEdtText.SetText( rInfo.aMarkAltText );

		if ( !rInfo.aMarkTarget.Len() )
			maCbbTarget.SetText( DEFINE_CONST_UNICODE( SELF_TARGET ) );
		else
			maCbbTarget.SetText(  rInfo.aMarkTarget );
	}

	return 0;
}

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

IMPL_LINK( SvxIMapDlg, MousePosHdl, IMapWindow*, pWnd )
{
	String aStr;
	const FieldUnit eFieldUnit = GetModuleFieldUnit();
	const Point& rMousePos = pWnd->GetMousePos();
	LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
	const sal_Unicode cSep = aLocaleWrapper.getNumDecimalSep().GetChar(0);

	aStr.Assign( GetUnitString( rMousePos.X(), eFieldUnit, cSep ) );
	aStr.Append( DEFINE_CONST_UNICODE( " / " ) );
	aStr.Append( GetUnitString( rMousePos.Y(), eFieldUnit, cSep ) );

	aStbStatus.SetItemText( 2, aStr );

	return 0L;
}

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

IMPL_LINK( SvxIMapDlg, GraphSizeHdl, IMapWindow*, pWnd )
{
	String aStr;
	const FieldUnit eFieldUnit = GetModuleFieldUnit();
	const Size&	rSize = pWnd->GetGraphicSize();
	LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
	const sal_Unicode cSep = aLocaleWrapper.getNumDecimalSep().GetChar(0);

	aStr.Assign( GetUnitString( rSize.Width(), eFieldUnit, cSep ) );
	aStr.Append( DEFINE_CONST_UNICODE( " x " ) );
	aStr.Append( GetUnitString( rSize.Height(), eFieldUnit, cSep ) );

	aStbStatus.SetItemText( 3, aStr );

	return 0L;
}

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

IMPL_LINK( SvxIMapDlg, URLModifyHdl, void*, EMPTYARG )
{
	NotifyInfo	aNewInfo;

	aNewInfo.aMarkURL = maURLBox.GetText();
	aNewInfo.aMarkAltText = aEdtText.GetText();
	aNewInfo.aMarkTarget = maCbbTarget.GetText();

	pIMapWnd->ReplaceActualIMapInfo( aNewInfo );

	return 0;
}


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

IMPL_LINK( SvxIMapDlg, URLLoseFocusHdl, void*, EMPTYARG )
{
	NotifyInfo		aNewInfo;
	const String	aURLText( maURLBox.GetText() );
	const String	aTargetText( maCbbTarget.GetText() );

	if ( aURLText.Len() )
	{
        String aBase = GetBindings().GetDispatcher()->GetFrame()->GetObjectShell()->GetMedium()->GetBaseURL();
        aNewInfo.aMarkURL = ::URIHelper::SmartRel2Abs( INetURLObject(aBase), aURLText, URIHelper::GetMaybeFileHdl(), true, false,
														INetURLObject::WAS_ENCODED,
														INetURLObject::DECODE_UNAMBIGUOUS );
	}
	else
		aNewInfo.aMarkURL = aURLText;

	aNewInfo.aMarkAltText = aEdtText.GetText();

	if ( !aTargetText.Len() )
		aNewInfo.aMarkTarget = DEFINE_CONST_UNICODE( SELF_TARGET );
	else
		aNewInfo.aMarkTarget = aTargetText;

	pIMapWnd->ReplaceActualIMapInfo( aNewInfo );

	return 0;
}


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

IMPL_LINK( SvxIMapDlg, UpdateHdl, Timer*, EMPTYARG )
{
	pOwnData->aTimer.Stop();

	if ( pOwnData->pUpdateEditingObject != pCheckObj )
	{
		if ( pIMapWnd->IsChanged() &&
			 ( QueryBox( this, WB_YES_NO | WB_DEF_YES,
			 String( SVX_RES( STR_IMAPDLG_SAVE ) ) ).Execute() == RET_YES ) )
		{
			DoSave();
		}

		SetGraphic( pOwnData->aUpdateGraphic );
		SetImageMap( pOwnData->aUpdateImageMap );
		SetTargetList( pOwnData->aUpdateTargetList );
		SetEditingObject( pOwnData->pUpdateEditingObject );

		// Nach Wechsel => default Selektion
		aTbxIMapDlg1.CheckItem( TBI_SELECT, TRUE );
		pIMapWnd->SetEditMode( TRUE );
	}

	// die in der Update-Methode kopierte Liste wieder loeschen
	for( String* pStr = pOwnData->aUpdateTargetList.First(); pStr; pStr = pOwnData->aUpdateTargetList.Next() )
		delete pStr;

	pOwnData->aUpdateTargetList.Clear();

	GetBindings().Invalidate( SID_IMAP_EXEC );

	return 0L;
}


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

IMPL_LINK( SvxIMapDlg, StateHdl, IMapWindow*, pWnd )
{
	const SdrObject*	pObj = pWnd->GetSelectedSdrObject();
	const SdrModel*		pModel = pWnd->GetSdrModel();
	const SdrView*		pView = pWnd->GetSdrView();
	const BOOL			bPolyEdit = ( pObj != NULL ) && pObj->ISA( SdrPathObj );
	const BOOL			bDrawEnabled = !( bPolyEdit && aTbxIMapDlg1.IsItemChecked( TBI_POLYEDIT ) );

	aTbxIMapDlg1.EnableItem( TBI_APPLY, pOwnData->bExecState && pWnd->IsChanged() );

	aTbxIMapDlg1.EnableItem( TBI_SELECT, bDrawEnabled );
	aTbxIMapDlg1.EnableItem( TBI_RECT, bDrawEnabled );
	aTbxIMapDlg1.EnableItem( TBI_CIRCLE, bDrawEnabled );
	aTbxIMapDlg1.EnableItem( TBI_POLY, bDrawEnabled );
	aTbxIMapDlg1.EnableItem( TBI_FREEPOLY, bDrawEnabled );

	// BezierEditor-Stati
	aTbxIMapDlg1.EnableItem( TBI_POLYEDIT, bPolyEdit );
	aTbxIMapDlg1.EnableItem( TBI_POLYMOVE, !bDrawEnabled );
	aTbxIMapDlg1.EnableItem( TBI_POLYINSERT, !bDrawEnabled );
	aTbxIMapDlg1.EnableItem( TBI_POLYDELETE, !bDrawEnabled && pView->IsDeleteMarkedPointsPossible() );

	// Undo/Redo
	aTbxIMapDlg1.EnableItem( TBI_UNDO, pModel->GetUndoActionCount() > 0 );
	aTbxIMapDlg1.EnableItem( TBI_REDO, pModel->GetRedoActionCount() > 0 );

	if ( bPolyEdit )
	{
		USHORT nId = 0;

		switch( pWnd->GetPolyEditMode() )
		{
			case( SID_BEZIER_MOVE ): nId = TBI_POLYMOVE; break;
			case( SID_BEZIER_INSERT ): nId = TBI_POLYINSERT; break;

			default:
			break;
		}

		aTbxIMapDlg1.CheckItem( nId, TRUE );
	}
	else
	{
		aTbxIMapDlg1.CheckItem( TBI_POLYEDIT, FALSE );
		aTbxIMapDlg1.CheckItem( TBI_POLYMOVE, TRUE );
		aTbxIMapDlg1.CheckItem( TBI_POLYINSERT, FALSE );
		pWnd->SetPolyEditMode( 0 );
	}

	return 0L;
}

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

IMPL_LINK( SvxIMapDlg, MiscHdl, void*, EMPTYARG )
{
   	SvtMiscOptions aMiscOptions;
    aTbxIMapDlg1.SetOutStyle( aMiscOptions.GetToolboxStyle() );

    return 0L;
}

void SvxIMapDlg::ApplyImageList()
{
	bool bHighContrast = GetDisplayBackground().GetColor().IsDark() != 0;

    ImageList& rImgLst = bHighContrast ? maImageListH : maImageList;

	aTbxIMapDlg1.SetImageList( rImgLst );
}

void SvxIMapDlg::DataChanged( const DataChangedEvent& rDCEvt )
{
    SfxModelessDialog::DataChanged( rDCEvt );

	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
            ApplyImageList();
}
