/**************************************************************
 * 
 * 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_sc.hxx"

// System - Includes ---------------------------------------------------------



// INCLUDE -------------------------------------------------------------------

#include <vcl/msgbox.hxx>
#include <sfx2/app.hxx>

#include "reffact.hxx"
#include "document.hxx"
#include "scresid.hxx"
#include "globstr.hrc"
#include "simpref.hrc"
#include "rangenam.hxx"		// IsNameValid
#include "simpref.hxx"
#include "scmod.hxx"

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

#define ABS_SREF		  SCA_VALID \
						| SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
#define ABS_DREF		  ABS_SREF \
						| SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
#define ABS_SREF3D		ABS_SREF | SCA_TAB_3D
#define ABS_DREF3D		ABS_DREF | SCA_TAB_3D

//----------------------------------------------------------------------------

#define ERRORBOX(s) ErrorBox(this,WinBits(WB_OK|WB_DEF_OK),s).Execute()
#define QUERYBOX(m) QueryBox(this,WinBits(WB_YES_NO|WB_DEF_YES),m).Execute()

//============================================================================
//	class ScSimpleRefDlg

//----------------------------------------------------------------------------
ScSimpleRefDlg::ScSimpleRefDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
						  ScViewData*	ptrViewData )

	:	ScAnyRefDlg	( pB, pCW, pParent, RID_SCDLG_SIMPLEREF ),
		//
		aFtAssign		( this, ScResId( FT_ASSIGN ) ),
        aEdAssign       ( this, this, ScResId( ED_ASSIGN ) ),
		aRbAssign		( this, ScResId( RB_ASSIGN ), &aEdAssign, this ),

		aBtnOk			( this, ScResId( BTN_OK ) ),
		aBtnCancel		( this, ScResId( BTN_CANCEL ) ),
		aBtnHelp		( this, ScResId( BTN_HELP ) ),

		//
		pViewData		( ptrViewData ),
		pDoc			( ptrViewData->GetDocument() ),
		bRefInputMode	( sal_False ),
		bAutoReOpen		( sal_True ),
		bCloseOnButtonUp( sal_False ),
        bSingleCell     ( sal_False ),
        bMultiSelection ( sal_False )
{
	//	damit die Strings in der Resource bei den FixedTexten bleiben koennen:
	Init();
	FreeResource();
	SetDispatcherLock( sal_True ); // Modal-Modus einschalten
}

//----------------------------------------------------------------------------
__EXPORT ScSimpleRefDlg::~ScSimpleRefDlg()
{
	SetDispatcherLock( sal_False ); // Modal-Modus einschalten
}

//----------------------------------------------------------------------------
void ScSimpleRefDlg::FillInfo(SfxChildWinInfo& rWinInfo) const
{
	ScAnyRefDlg::FillInfo(rWinInfo);
	rWinInfo.bVisible=bAutoReOpen;
}

//----------------------------------------------------------------------------
void ScSimpleRefDlg::SetRefString(const String &rStr)
{
	aEdAssign.SetText(rStr);
}

//----------------------------------------------------------------------------
void ScSimpleRefDlg::Init()
{
	aBtnOk.SetClickHdl		( LINK( this, ScSimpleRefDlg, OkBtnHdl ) );
	aBtnCancel.SetClickHdl	( LINK( this, ScSimpleRefDlg, CancelBtnHdl ) );
	bCloseFlag=sal_False;
}

//----------------------------------------------------------------------------
// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
//  neue Selektion im Referenz-Fenster angezeigt wird.
void ScSimpleRefDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
{
	if ( aEdAssign.IsEnabled() )
	{
		if ( rRef.aStart != rRef.aEnd )
			RefInputStart( &aEdAssign );

		theCurArea = rRef;
		String aRefStr;
		if ( bSingleCell )
		{
			ScAddress aAdr = rRef.aStart;
            aAdr.Format( aRefStr, SCA_ABS_3D, pDocP, pDocP->GetAddressConvention() );
		}
		else
            theCurArea.Format( aRefStr, ABS_DREF3D, pDocP, pDocP->GetAddressConvention() );

        if ( bMultiSelection )
        {
            String aVal = aEdAssign.GetText();
            Selection aSel = aEdAssign.GetSelection();
            aSel.Justify();
            aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
            aVal.Insert( aRefStr, (xub_StrLen)aSel.Min() );
            Selection aNewSel( aSel.Min(), aSel.Min()+aRefStr.Len() );
            aEdAssign.SetRefString( aVal );
            aEdAssign.SetSelection( aNewSel );
        }
        else
            aEdAssign.SetRefString( aRefStr );

		aChangeHdl.Call( &aRefStr );
	}
}


//----------------------------------------------------------------------------
sal_Bool __EXPORT ScSimpleRefDlg::Close()
{
	CancelBtnHdl(&aBtnCancel);
	return sal_True;
}

//------------------------------------------------------------------------
void ScSimpleRefDlg::SetActive()
{
	aEdAssign.GrabFocus();

	//	kein NameModifyHdl, weil sonst Bereiche nicht geaendert werden koennen
	//	(nach dem Aufziehen der Referenz wuerde der alte Inhalt wieder angezeigt)
	//	(der ausgewaehlte DB-Name hat sich auch nicht veraendert)

	RefInputDone();
}
//------------------------------------------------------------------------
sal_Bool ScSimpleRefDlg::IsRefInputMode() const
{
	return sal_True;
}

String ScSimpleRefDlg::GetRefString() const
{
	return aEdAssign.GetText();
}

void ScSimpleRefDlg::SetCloseHdl( const Link& rLink )
{
	aCloseHdl=rLink;
}

void ScSimpleRefDlg::SetUnoLinks( const Link& rDone, const Link& rAbort,
									const Link& rChange )
{
	aDoneHdl	= rDone;
	aAbortedHdl	= rAbort;
	aChangeHdl	= rChange;
}

void ScSimpleRefDlg::SetFlags( sal_Bool bSetCloseOnButtonUp, sal_Bool bSetSingleCell, sal_Bool bSetMultiSelection )
{
	bCloseOnButtonUp = bSetCloseOnButtonUp;
	bSingleCell = bSetSingleCell;
	bMultiSelection = bSetMultiSelection;
}

void ScSimpleRefDlg::StartRefInput()
{
    if ( bMultiSelection )
    {
        // initially select the whole string, so it gets replaced by default
        aEdAssign.SetSelection( Selection( 0, aEdAssign.GetText().Len() ) );
    }

	aRbAssign.DoRef();
	bCloseFlag=sal_True;
}

void ScSimpleRefDlg::RefInputDone( sal_Bool bForced)
{
	ScAnyRefDlg::RefInputDone(bForced);
	if ( (bForced || bCloseOnButtonUp) && bCloseFlag )
		OkBtnHdl(&aBtnOk);
}
//------------------------------------------------------------------------
// Handler:
// ========
IMPL_LINK( ScSimpleRefDlg, OkBtnHdl, void *, EMPTYARG )
{
	bAutoReOpen=sal_False;
	String aResult=aEdAssign.GetText();
	aCloseHdl.Call(&aResult);
	Link aUnoLink = aDoneHdl;		// stack var because this is deleted in DoClose
	DoClose( ScSimpleRefDlgWrapper::GetChildWindowId() );
	aUnoLink.Call( &aResult );
	return 0;
}

//------------------------------------------------------------------------
IMPL_LINK( ScSimpleRefDlg, CancelBtnHdl, void *, EMPTYARG )
{
	bAutoReOpen=sal_False;
	String aResult=aEdAssign.GetText();
	aCloseHdl.Call(NULL);
	Link aUnoLink = aAbortedHdl;	// stack var because this is deleted in DoClose
	DoClose( ScSimpleRefDlgWrapper::GetChildWindowId() );
	aUnoLink.Call( &aResult );
	return 0;
}



//------------------------------------------------------------------------

