/**************************************************************
 *
 * 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;
}



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