/**************************************************************
 * 
 * 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"



//----------------------------------------------------------------------------
#include <rangelst.hxx>

#include <sfx2/dispatch.hxx>
#include <svl/stritem.hxx>
#include <vcl/msgbox.hxx>
#include <unotools/charclass.hxx>
#include <stdlib.h>

#define _AREASDLG_CXX
#include "areasdlg.hxx"
#undef _AREASDLG_CXX

#include "scresid.hxx"
#include "rangenam.hxx"
#include "reffact.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "globstr.hrc"
#include "pagedlg.hrc"
#include "compiler.hxx"

// STATIC DATA ---------------------------------------------------------------

// List box positions for print range (PR)
const sal_uInt16 SC_AREASDLG_PR_NONE    = 0;
const sal_uInt16 SC_AREASDLG_PR_ENTIRE  = 1;
const sal_uInt16 SC_AREASDLG_PR_USER    = 2;
const sal_uInt16 SC_AREASDLG_PR_SELECT  = 3;
const sal_uInt16 SC_AREASDLG_PR_OFFSET  = 4;

// List box positions for repeat ranges (RR)
const sal_uInt16 SC_AREASDLG_RR_NONE    = 0;
const sal_uInt16 SC_AREASDLG_RR_USER    = 1;
const sal_uInt16 SC_AREASDLG_RR_OFFSET  = 2;

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

#define HDL(hdl)			LINK( this, ScPrintAreasDlg, hdl )
#define ERRORBOX(nId)		ErrorBox( this, WinBits(WB_OK|WB_DEF_OK), \
							ScGlobal::GetRscString( nId ) ).Execute()
#define SWAP(x1,x2)			{ int n=x1; x1=x2; x2=n; }

// globale Funktionen (->am Ende der Datei):

bool    lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange );
void	lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr );

#if 0
static void printAddressFlags(sal_uInt16 nFlag)
{
    if ((nFlag & SCA_COL_ABSOLUTE  ) == SCA_COL_ABSOLUTE  )  printf("SCA_COL_ABSOLUTE \n");
    if ((nFlag & SCA_ROW_ABSOLUTE  ) == SCA_ROW_ABSOLUTE  )  printf("SCA_ROW_ABSOLUTE \n");
    if ((nFlag & SCA_TAB_ABSOLUTE  ) == SCA_TAB_ABSOLUTE  )  printf("SCA_TAB_ABSOLUTE \n");
    if ((nFlag & SCA_TAB_3D        ) == SCA_TAB_3D        )  printf("SCA_TAB_3D       \n");
    if ((nFlag & SCA_COL2_ABSOLUTE ) == SCA_COL2_ABSOLUTE )  printf("SCA_COL2_ABSOLUTE\n");
    if ((nFlag & SCA_ROW2_ABSOLUTE ) == SCA_ROW2_ABSOLUTE )  printf("SCA_ROW2_ABSOLUTE\n");
    if ((nFlag & SCA_TAB2_ABSOLUTE ) == SCA_TAB2_ABSOLUTE )  printf("SCA_TAB2_ABSOLUTE\n");
    if ((nFlag & SCA_TAB2_3D       ) == SCA_TAB2_3D       )  printf("SCA_TAB2_3D      \n");
    if ((nFlag & SCA_VALID_ROW     ) == SCA_VALID_ROW     )  printf("SCA_VALID_ROW    \n");
    if ((nFlag & SCA_VALID_COL     ) == SCA_VALID_COL     )  printf("SCA_VALID_COL    \n");
    if ((nFlag & SCA_VALID_TAB     ) == SCA_VALID_TAB     )  printf("SCA_VALID_TAB    \n");
    if ((nFlag & SCA_FORCE_DOC     ) == SCA_FORCE_DOC     )  printf("SCA_FORCE_DOC    \n");
    if ((nFlag & SCA_VALID_ROW2    ) == SCA_VALID_ROW2    )  printf("SCA_VALID_ROW2   \n");
    if ((nFlag & SCA_VALID_COL2    ) == SCA_VALID_COL2    )  printf("SCA_VALID_COL2   \n");
    if ((nFlag & SCA_VALID_TAB2    ) == SCA_VALID_TAB2    )  printf("SCA_VALID_TAB2   \n");
    if ((nFlag & SCA_VALID         ) == SCA_VALID         )  printf("SCA_VALID        \n");
    if ((nFlag & SCA_ABS           ) == SCA_ABS           )  printf("SCA_ABS          \n");
    if ((nFlag & SCR_ABS           ) == SCR_ABS           )  printf("SCR_ABS          \n");
    if ((nFlag & SCA_ABS_3D        ) == SCA_ABS_3D        )  printf("SCA_ABS_3D       \n");
    if ((nFlag & SCR_ABS_3D        ) == SCR_ABS_3D        )  printf("SCR_ABS_3D       \n");
}
#endif

//============================================================================
//	class ScPrintAreasDlg

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

ScPrintAreasDlg::ScPrintAreasDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent )
	:	ScAnyRefDlg		( pB, pCW, pParent, RID_SCDLG_AREAS),
		//
		aFlPrintArea    ( this, ScResId( FL_PRINTAREA ) ),
		aLbPrintArea	( this, ScResId( LB_PRINTAREA ) ),
        aEdPrintArea    ( this, this, ScResId( ED_PRINTAREA ) ),
		aRbPrintArea	( this, ScResId( RB_PRINTAREA ), &aEdPrintArea, this ),
		//
		aFlRepeatRow    ( this, ScResId( FL_REPEATROW ) ),
		aLbRepeatRow	( this, ScResId( LB_REPEATROW ) ),
        aEdRepeatRow    ( this, this, ScResId( ED_REPEATROW ) ),
		aRbRepeatRow	( this, ScResId( RB_REPEATROW ), &aEdRepeatRow, this ),
		//
		aFlRepeatCol    ( this, ScResId( FL_REPEATCOL ) ),
		aLbRepeatCol	( this, ScResId( LB_REPEATCOL ) ),
        aEdRepeatCol    ( this, this, ScResId( ED_REPEATCOL ) ),
		aRbRepeatCol	( this, ScResId( RB_REPEATCOL ), &aEdRepeatCol, this ),
		//
		aBtnOk			( this, ScResId( BTN_OK ) ),
		aBtnCancel		( this, ScResId( BTN_CANCEL ) ),
		aBtnHelp		( this, ScResId( BTN_HELP ) ),
		//
		bDlgLostFocus	( sal_False ),
		pRefInputEdit	( &aEdPrintArea ),
		pDoc			( NULL ),
		pViewData		( NULL ),
		nCurTab 		( 0 )
{
	ScTabViewShell* pScViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
	ScDocShell*		pScDocSh  = PTR_CAST( ScDocShell,     SfxObjectShell::Current() );

	DBG_ASSERT( pScDocSh, "Current DocumentShell not found :-(" );

	pDoc = pScDocSh->GetDocument();

	if ( pScViewSh )
	{
		pViewData = pScViewSh->GetViewData();
		nCurTab   = pViewData->GetTabNo();
	}

	Impl_Reset();

	//@BugID 54702 Enablen/Disablen nur noch in Basisklasse
	//SFX_APPWINDOW->Enable();

	FreeResource();
}


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

ScPrintAreasDlg::~ScPrintAreasDlg()
{
	// Extra-Data an ListBox-Entries abraeumen
	ListBox* pLb[3] = { &aLbPrintArea, &aLbRepeatRow, &aLbRepeatCol };

	for ( sal_uInt16 i=0; i<3; i++ )
	{
		sal_uInt16 nCount = pLb[i]->GetEntryCount();
		for ( sal_uInt16 j=0; j<nCount; j++ )
			delete (String*)pLb[i]->GetEntryData(j);
	}
}


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

sal_Bool ScPrintAreasDlg::Close()
{
	return DoClose( ScPrintAreasDlgWrapper::GetChildWindowId() );
}


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

sal_Bool ScPrintAreasDlg::IsTableLocked() const
{
	//	Druckbereiche gelten pro Tabelle, darum macht es keinen Sinn,
	//	bei der Eingabe die Tabelle umzuschalten

	return sal_True;
}


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

void ScPrintAreasDlg::SetReference( const ScRange& rRef, ScDocument* /* pDoc */ )
{
	if ( pRefInputEdit )
	{
		if ( rRef.aStart != rRef.aEnd )
			RefInputStart( pRefInputEdit );

		String	aStr;
        const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

		if ( &aEdPrintArea == pRefInputEdit )
		{
			rRef.Format( aStr, SCR_ABS, pDoc, eConv );

//			aEdPrintArea.ReplaceSelected( aStr );

			String aVal = aEdPrintArea.GetText();
			Selection aSel = aEdPrintArea.GetSelection();
            aSel.Justify();
			aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
			aVal.Insert( aStr, (xub_StrLen)aSel.Min() );
			Selection aNewSel( aSel.Min(), aSel.Min()+aStr.Len() );
			aEdPrintArea.SetRefString( aVal );
			aEdPrintArea.SetSelection( aNewSel );
		}
		else
		{
			sal_Bool bRow = ( &aEdRepeatRow == pRefInputEdit );
            lcl_GetRepeatRangeString(&rRef, pDoc, bRow, aStr);
			pRefInputEdit->SetRefString( aStr );
		}
	}

	Impl_ModifyHdl( pRefInputEdit );
}


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

void ScPrintAreasDlg::AddRefEntry()
{
	if ( pRefInputEdit == &aEdPrintArea )
	{
        const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
		String aVal = aEdPrintArea.GetText();
		aVal += sep;
		aEdPrintArea.SetText(aVal);

		xub_StrLen nLen = aVal.Len();
		aEdPrintArea.SetSelection( Selection( nLen, nLen ) );

		Impl_ModifyHdl( &aEdPrintArea );
	}
}


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

void ScPrintAreasDlg::Deactivate()
{
	bDlgLostFocus = sal_True;
}


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

void ScPrintAreasDlg::SetActive()
{
	if ( bDlgLostFocus )
	{
		bDlgLostFocus = sal_False;

		if ( pRefInputEdit )
		{
			pRefInputEdit->GrabFocus();
			Impl_ModifyHdl( pRefInputEdit );
		}
	}
	else
		GrabFocus();

	RefInputDone();
}


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

void ScPrintAreasDlg::Impl_Reset()
{
	String			aStrRange;
	const ScRange*	pRepeatColRange = pDoc->GetRepeatColRange( nCurTab );
	const ScRange*	pRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab );

	aEdPrintArea.SetModifyHdl	( HDL(Impl_ModifyHdl) );
	aEdRepeatRow.SetModifyHdl	( HDL(Impl_ModifyHdl) );
	aEdRepeatCol.SetModifyHdl	( HDL(Impl_ModifyHdl) );
	aEdPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
	aEdRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
	aEdRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
	aLbPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
	aLbRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
	aLbRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
	aLbPrintArea.SetSelectHdl	( HDL(Impl_SelectHdl) );
	aLbRepeatRow.SetSelectHdl	( HDL(Impl_SelectHdl) );
	aLbRepeatCol.SetSelectHdl	( HDL(Impl_SelectHdl) );
	aBtnOk		.SetClickHdl 	( HDL(Impl_BtnHdl)    );
	aBtnCancel	.SetClickHdl 	( HDL(Impl_BtnHdl)    );

	Impl_FillLists();

	//-------------------------
	// Druckbereich
	//-------------------------
	aStrRange.Erase();
    String aOne;
    const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
    const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    sal_uInt16 nRangeCount = pDoc->GetPrintRangeCount( nCurTab );
    for (sal_uInt16 i=0; i<nRangeCount; i++)
    {
        const ScRange* pPrintRange = pDoc->GetPrintRange( nCurTab, i );
        if (pPrintRange)
        {
            if ( aStrRange.Len() )
                aStrRange += sep;
            pPrintRange->Format( aOne, SCR_ABS, pDoc, eConv );
            aStrRange += aOne;
        }
    }
    aEdPrintArea.SetText( aStrRange );

	//-------------------------------
	// Wiederholungszeile
	//-------------------------------
    lcl_GetRepeatRangeString(pRepeatRowRange, pDoc, true, aStrRange);
	aEdRepeatRow.SetText( aStrRange );

	//--------------------------------
	// Wiederholungsspalte
	//--------------------------------
    lcl_GetRepeatRangeString(pRepeatColRange, pDoc, false, aStrRange);
	aEdRepeatCol.SetText( aStrRange );

	Impl_ModifyHdl( &aEdPrintArea );
	Impl_ModifyHdl( &aEdRepeatRow );
	Impl_ModifyHdl( &aEdRepeatCol );
    if( pDoc->IsPrintEntireSheet( nCurTab ) )
        aLbPrintArea.SelectEntryPos( SC_AREASDLG_PR_ENTIRE );

	aEdPrintArea.SaveValue();	// fuer FillItemSet() merken:
	aEdRepeatRow.SaveValue();
	aEdRepeatCol.SaveValue();
}


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

sal_Bool ScPrintAreasDlg::Impl_GetItem( Edit* pEd, SfxStringItem& rItem )
{
	String	aRangeStr = pEd->GetText();
	sal_Bool	bDataChanged = (pEd->GetSavedValue() != aRangeStr);

	if ( (aRangeStr.Len() > 0) && &aEdPrintArea != pEd )
	{
		ScRange aRange;
        const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
        lcl_CheckRepeatString(aRangeStr, pDoc, &aEdRepeatRow == pEd, &aRange);
		aRange.Format(aRangeStr, SCR_ABS, pDoc, eConv);
	}

	rItem.SetValue( aRangeStr );

	return bDataChanged;
}


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

sal_Bool ScPrintAreasDlg::Impl_CheckRefStrings()
{
	sal_Bool		bOk = sal_False;
	String		aStrPrintArea	= aEdPrintArea.GetText();
	String		aStrRepeatRow	= aEdRepeatRow.GetText();
	String		aStrRepeatCol	= aEdRepeatCol.GetText();

	sal_Bool bPrintAreaOk = sal_True;
	if ( aStrPrintArea.Len() )
	{
        const sal_uInt16 nValidAddr  = SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
        const sal_uInt16 nValidRange = nValidAddr | SCA_VALID_ROW2 | SCA_VALID_COL2;
        const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
        const sal_Unicode sep  = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
        // const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);

        ScAddress aAddr;
		ScRange aRange;
		xub_StrLen nSepCount = aStrPrintArea.GetTokenCount(sep);
		for ( xub_StrLen i = 0; i < nSepCount && bPrintAreaOk; ++i )
		{
			String aOne = aStrPrintArea.GetToken(i, sep);
            sal_uInt16 nResult = aRange.Parse( aOne, pDoc, eConv );
            if ((nResult & nValidRange) != nValidRange)
            {
                sal_uInt16 nAddrResult = aAddr.Parse( aOne, pDoc, eConv );
                if ((nAddrResult & nValidAddr) != nValidAddr)
                    bPrintAreaOk = sal_False;
            }
		}
	}

	sal_Bool bRepeatRowOk = (aStrRepeatRow.Len() == 0);
	if ( !bRepeatRowOk )
        bRepeatRowOk = lcl_CheckRepeatString(aStrRepeatRow, pDoc, true, NULL);

	sal_Bool bRepeatColOk = (aStrRepeatCol.Len() == 0);
	if ( !bRepeatColOk )
        bRepeatColOk = lcl_CheckRepeatString(aStrRepeatCol, pDoc, false, NULL);

	// Fehlermeldungen

	bOk = (bPrintAreaOk && bRepeatRowOk && bRepeatColOk);

	if ( !bOk )
	{
		Edit* pEd = NULL;

			 if ( !bPrintAreaOk ) pEd = &aEdPrintArea;
		else if ( !bRepeatRowOk ) pEd = &aEdRepeatRow;
		else if ( !bRepeatColOk ) pEd = &aEdRepeatCol;

		ERRORBOX( STR_INVALID_TABREF );
		pEd->GrabFocus();
	}

	return bOk;
}


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

void ScPrintAreasDlg::Impl_FillLists()
{
	//------------------------------------------------------
	// Selektion holen und String in PrintArea-ListBox merken
	//------------------------------------------------------
	ScRange	aRange;
	String	aStrRange;
	sal_Bool bSimple = sal_True;

	if ( pViewData )
		bSimple = (pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE);

    formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

	if ( bSimple )
		aRange.Format( aStrRange, SCR_ABS, pDoc, eConv );
	else
	{
		ScRangeListRef aList( new ScRangeList );
		pViewData->GetMarkData().FillRangeListWithMarks( aList, sal_False );
		aList->Format( aStrRange, SCR_ABS, pDoc, eConv );
	}

    aLbPrintArea.SetEntryData( SC_AREASDLG_PR_SELECT, new String( aStrRange ) );

	//------------------------------------------------------
	// Ranges holen und in ListBoxen merken
	//------------------------------------------------------
	ScRangeName*	pRangeNames = pDoc->GetRangeName();
	const sal_uInt16	nCount		= pRangeNames ? pRangeNames->GetCount() : 0;

	if ( nCount > 0 )
	{
		String			aName;
		String			aSymbol;
//        ScRange         aRange;
		ScRangeData*	pData = NULL;

		for ( sal_uInt16 i=0; i<nCount; i++ )
		{
			pData = (ScRangeData*)(pRangeNames->At( i ));
			if ( pData )
			{
				if (   pData->HasType( RT_ABSAREA )
					|| pData->HasType( RT_REFAREA )
					|| pData->HasType( RT_ABSPOS ) )
				{
					pData->GetName( aName );
					pData->GetSymbol( aSymbol );
					if ( aRange.ParseAny( aSymbol, pDoc, eConv ) & SCA_VALID )
					{
						if ( pData->HasType( RT_PRINTAREA ) )
						{
							aRange.Format( aSymbol, SCR_ABS, pDoc, eConv );
							aLbPrintArea.SetEntryData(
								aLbPrintArea.InsertEntry( aName ),
								new String( aSymbol ) );
						}

						if ( pData->HasType( RT_ROWHEADER ) )
						{
                            lcl_GetRepeatRangeString(&aRange, pDoc, true, aSymbol);
							aLbRepeatRow.SetEntryData(
								aLbRepeatRow.InsertEntry( aName ),
								new String( aSymbol ) );
						}

						if ( pData->HasType( RT_COLHEADER ) )
						{
                            lcl_GetRepeatRangeString(&aRange, pDoc, false, aSymbol);
							aLbRepeatCol.SetEntryData(
								aLbRepeatCol.InsertEntry( aName ),
								new String( aSymbol ) );
						}
					}
				}
			}
		}
	}
}


//----------------------------------------------------------------------------
// Handler:
//----------------------------------------------------------------------------

IMPL_LINK( ScPrintAreasDlg, Impl_BtnHdl, PushButton*, pBtn )
{
	if ( &aBtnOk == pBtn )
	{
		if ( Impl_CheckRefStrings() )
		{
			sal_Bool			bDataChanged = sal_False;
			String			aStr;
			SfxStringItem	aPrintArea( SID_CHANGE_PRINTAREA, aStr );
			SfxStringItem	aRepeatRow( FN_PARAM_2, aStr );
			SfxStringItem 	aRepeatCol( FN_PARAM_3, aStr );

			//-------------------------
			// Druckbereich veraendert?
			//-------------------------

            // first try the list box, if "Entite sheet" is selected
            sal_Bool bEntireSheet = (aLbPrintArea.GetSelectEntryPos() == SC_AREASDLG_PR_ENTIRE);
            SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );

            bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
            if( !bEntireSheet )
            {
                // if new list box selection is not "Entire sheet", get the edit field contents
                bDataChanged |= Impl_GetItem( &aEdPrintArea, aPrintArea );
            }

			//-------------------------------
			// Wiederholungszeile veraendert?
			//-------------------------------
			bDataChanged |= Impl_GetItem( &aEdRepeatRow, aRepeatRow );

			//--------------------------------
			// Wiederholungsspalte veraendert?
			//--------------------------------
			bDataChanged |= Impl_GetItem( &aEdRepeatCol, aRepeatCol );

			if ( bDataChanged )
			{
				SetDispatcherLock( sal_False );
				SwitchToDocument();
				GetBindings().GetDispatcher()->Execute( SID_CHANGE_PRINTAREA,
										  SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
                                          &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet, 0L );
			}

			Close();
		}
	}
	else if ( &aBtnCancel == pBtn )
		Close();

	return 0;
}


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

IMPL_LINK( ScPrintAreasDlg, Impl_GetFocusHdl, Control*, pCtr )
{
	if ( pCtr ==(Control *) &aEdPrintArea ||
		 pCtr ==(Control *) &aEdRepeatRow ||
		 pCtr ==(Control *) &aEdRepeatCol)
	{
		 pRefInputEdit = (formula::RefEdit*) pCtr;
	}
	else if ( pCtr ==(Control *) &aLbPrintArea)
	{
		pRefInputEdit = &aEdPrintArea;
	}
	else if ( pCtr ==(Control *) &aLbRepeatRow)
	{
		pRefInputEdit = &aEdRepeatRow;
	}
	else if ( pCtr ==(Control *) &aLbRepeatCol)
	{
		pRefInputEdit = &aEdRepeatCol;
	}

	return 0;
}


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

IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, ListBox*, pLb )
{
    sal_uInt16 nSelPos = pLb->GetSelectEntryPos();
    Edit* pEd = NULL;

    // list box positions of specific entries, default to "repeat row/column" list boxes
    sal_uInt16 nAllSheetPos = SC_AREASDLG_RR_NONE;
    sal_uInt16 nUserDefPos = SC_AREASDLG_RR_USER;
    sal_uInt16 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;

    // find edit field for list box, and list box positions
    if( pLb == &aLbPrintArea )
    {
        pEd = &aEdPrintArea;
        nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
        nUserDefPos = SC_AREASDLG_PR_USER;
        nFirstCustomPos = SC_AREASDLG_PR_SELECT;    // "Selection" and following
    }
    else if( pLb == &aLbRepeatCol )
        pEd = &aEdRepeatCol;
    else if( pLb == &aLbRepeatRow )
        pEd = &aEdRepeatRow;
    else
        return 0;

    // fill edit field according to list box selection
    if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
        pEd->SetText( EMPTY_STRING );
    else if( nSelPos == nUserDefPos && !pLb->IsTravelSelect() && pEd->GetText().Len() == 0 )
        pLb->SelectEntryPos( 0 );
    else if( nSelPos >= nFirstCustomPos )
        pEd->SetText( *static_cast< String* >( pLb->GetEntryData( nSelPos ) ) );

    return 0;
}


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

IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit*, pEd )
{
    ListBox* pLb = NULL;

    // list box positions of specific entries, default to "repeat row/column" list boxes
    sal_uInt16 nUserDefPos = SC_AREASDLG_RR_USER;
    sal_uInt16 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;

    if( pEd == &aEdPrintArea )
    {
        pLb = &aLbPrintArea;
        nUserDefPos = SC_AREASDLG_PR_USER;
        nFirstCustomPos = SC_AREASDLG_PR_SELECT;    // "Selection" and following
    }
    else if( pEd == &aEdRepeatCol )
		pLb = &aLbRepeatCol;
    else if( pEd == &aEdRepeatRow )
		pLb = &aLbRepeatRow;
    else
        return 0;

    // set list box selection according to edit field
	sal_uInt16	nEntryCount = pLb->GetEntryCount();
	String	aStrEd( pEd->GetText() );
	String	aEdUpper = aStrEd;
	aEdUpper.ToUpperAscii();

    if ( (nEntryCount > nFirstCustomPos) && aStrEd.Len() > 0 )
	{
		sal_Bool	bFound	= sal_False;
		String* pSymbol	= NULL;
		sal_uInt16 i;

        for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
		{
			pSymbol = (String*)pLb->GetEntryData( i );
			bFound  = ( (*pSymbol == aStrEd) || (*pSymbol == aEdUpper) );
		}

        pLb->SelectEntryPos( bFound ? i-1 : nUserDefPos );
	}
	else
        pLb->SelectEntryPos( aStrEd.Len() ? nUserDefPos : 0 );

	return 0;
}


//============================================================================
// globale Funktionen:

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

// TODO: It might make sense to move these functions to address.?xx. -kohei

bool lcl_CheckOne_OOO( const String& rStr, bool bIsRow, SCCOLROW& rVal )
{
	// Zulaessige Syntax fuer rStr:
	// Row: [$]1-MAXTAB
	// Col: [$]A-IV

	String	aStr	= rStr;
	xub_StrLen nLen = aStr.Len();
	SCCOLROW	nNum	= 0;
	sal_Bool	bStrOk  = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );

	if ( bStrOk )
	{
		if ( '$' == aStr.GetChar(0) )
			aStr.Erase( 0, 1 );

		if ( bIsRow )
		{
			bStrOk = CharClass::isAsciiNumeric(aStr);

			if ( bStrOk )
			{
				sal_Int32 n = aStr.ToInt32();

                if ( ( bStrOk = (n > 0) && ( n <= MAXROWCOUNT ) ) != sal_False )
					nNum = static_cast<SCCOLROW>(n - 1);
			}
		}
		else
		{
            SCCOL nCol = 0;
			bStrOk = ::AlphaToCol( nCol, aStr);
            nNum = nCol;
		}
	}

	if ( bStrOk )
		rVal = nNum;

	return bStrOk;
}

bool lcl_CheckOne_XL_A1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
{
    // XL A1 style is identical to OOO one for print range formats.
    return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
}

bool lcl_CheckOne_XL_R1C1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
{
    xub_StrLen nLen = rStr.Len();
    if (nLen <= 1)
        // There must be at least two characters.
        return false;

    const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
    const sal_Unicode preLower = bIsRow ? 'r' : 'c';
    if (rStr.GetChar(0) != preUpper && rStr.GetChar(0) != preLower)
        return false;

    String aNumStr = rStr.Copy(1);
    if (!CharClass::isAsciiNumeric(aNumStr))
        return false;

    sal_Int32 nNum = aNumStr.ToInt32();

    if (nNum <= 0)
        return false;

    if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT))
        return false;

    rVal = static_cast<SCCOLROW>(nNum-1);
    return true;
}

bool lcl_CheckRepeatOne( const String& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal )
{
    switch (eConv)
    {
        case formula::FormulaGrammar::CONV_OOO:
            return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
        case formula::FormulaGrammar::CONV_XL_A1:
            return lcl_CheckOne_XL_A1(rStr, bIsRow, rVal);
        case formula::FormulaGrammar::CONV_XL_R1C1:
            return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal);
        default:
        {
            // added to avoid warnings
        }
    }
    return false;
}

bool lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange )
{
    // Row: [valid row] rsep [valid row]
    // Col: [valid col] rsep [valid col]

    const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
    const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);

    if (pRange)
    {
        // initialize the range value.
        pRange->aStart.SetCol(0);
        pRange->aStart.SetRow(0);
        pRange->aEnd.SetCol(0);
        pRange->aEnd.SetRow(0);
    }

    String aBuf;
    SCCOLROW nVal = 0;
    xub_StrLen nLen = rStr.Len();
    bool bEndPos = false;
    for (xub_StrLen i = 0; i < nLen; ++i)
    {
        const sal_Unicode c = rStr.GetChar(i);
        if (c == rsep)
        {
            if (bEndPos)
                // We aren't supposed to have more than one range separator.
                return false;

            // range separator
            if (aBuf.Len() == 0)
                return false;

            bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
            if (!bRes)
                return false;

            if (pRange)
            {
                if (bIsRow)
                {
                    pRange->aStart.SetRow(static_cast<SCROW>(nVal));
                    pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
                }
                else
                {
                    pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
                    pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
                }
            }

            aBuf.Erase();
            bEndPos = true;
        }
        else
            aBuf.Append(c);
    }

    if (aBuf.Len() > 0)
    {
        bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
        if (!bRes)
            return false;

        if (pRange)
        {
            if (bIsRow)
            {
                if (!bEndPos)
                    pRange->aStart.SetRow(static_cast<SCROW>(nVal));
                pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
            }
            else
            {
                if (!bEndPos)
                    pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
                pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
            }
        }
    }

    return true;
}

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

void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr )
{
    rStr.Erase();
    if (!pRange)
        return;

    const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
    const ScAddress& rStart = pRange->aStart;
    const ScAddress& rEnd   = pRange->aEnd;

    const sal_uInt16 nFmt = bIsRow ? (SCA_VALID_ROW | SCA_ROW_ABSOLUTE) : (SCA_VALID_COL | SCA_COL_ABSOLUTE);
    String aTmpStr;
    rStart.Format(aTmpStr, nFmt, pDoc, eConv);
    rStr += aTmpStr;
    if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col()))
    {
        rStr += ScCompiler::GetNativeSymbol(ocRange);
        rEnd.Format(aTmpStr, nFmt, pDoc, eConv);
        rStr += aTmpStr;
    }
}

