/**************************************************************
 * 
 * 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 ---------------------------------------------------------------
#include <tools/list.hxx>
#include "scitems.hxx"
#include <sfx2/bindings.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/dispatch.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/langitem.hxx>
#include <editeng/scripttypeitem.hxx>
#include <svl/itempool.hxx>
#include <svl/itemset.hxx>
#include <svl/cjkoptions.hxx>
#include <svl/ctloptions.hxx>
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/wrkwin.hxx>
#include <sfx2/request.hxx>
#include <sfx2/objsh.hxx>
#include <svl/stritem.hxx>
#include <svl/eitem.hxx>

#include <com/sun/star/i18n/TransliterationModules.hpp>
#include <com/sun/star/i18n/TransliterationModulesExtra.hpp>


#include "viewutil.hxx"
#include "global.hxx"
#include "chgtrack.hxx"
#include "chgviset.hxx"
#include "markdata.hxx"

#include <svx/svxdlg.hxx> //CHINA001
#include <svx/dialogs.hrc> //CHINA001
// STATIC DATA -----------------------------------------------------------

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

//	static
void ScViewUtil::PutItemScript( SfxItemSet& rShellSet, const SfxItemSet& rCoreSet,
								sal_uInt16 nWhichId, sal_uInt16 nScript )
{
	//	take the effective item from rCoreSet according to nScript
	//	and put in rShellSet under the (base) nWhichId

	SfxItemPool& rPool = *rShellSet.GetPool();
	SvxScriptSetItem aSetItem( rPool.GetSlotId(nWhichId), rPool );
	//	use PutExtended with eDefaultAs = SFX_ITEM_SET, so defaults from rCoreSet
	//	(document pool) are read and put into rShellSet (MessagePool)
	aSetItem.GetItemSet().PutExtended( rCoreSet, SFX_ITEM_DONTCARE, SFX_ITEM_SET );
	const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
	if (pI)
		rShellSet.Put( *pI, nWhichId );
	else
		rShellSet.InvalidateItem( nWhichId );
}

//	static
sal_uInt16 ScViewUtil::GetEffLanguage( ScDocument* pDoc, const ScAddress& rPos )
{
	//	used for thesaurus

	sal_uInt8 nScript = pDoc->GetScriptType( rPos.Col(), rPos.Row(), rPos.Tab() );
	sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
					( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : ATTR_FONT_LANGUAGE );
	const SfxPoolItem* pItem = pDoc->GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), nWhich);
	const SvxLanguageItem* pLangIt = dynamic_cast< const SvxLanguageItem* >( pItem );
	LanguageType eLnge;
	if (pLangIt)
	{
		eLnge = (LanguageType) pLangIt->GetValue();
		if (eLnge == LANGUAGE_DONTKNOW)					//! can this happen?
		{
			LanguageType eLatin, eCjk, eCtl;
			pDoc->GetLanguage( eLatin, eCjk, eCtl );
			eLnge = ( nScript == SCRIPTTYPE_ASIAN ) ? eCjk :
					( ( nScript == SCRIPTTYPE_COMPLEX ) ? eCtl : eLatin );
		}
	}
	else
		eLnge = LANGUAGE_ENGLISH_US;
	if ( eLnge == LANGUAGE_SYSTEM )
        eLnge = Application::GetSettings().GetLanguage();   // never use SYSTEM for spelling

	return eLnge;
}

//	static
sal_Int32 ScViewUtil::GetTransliterationType( sal_uInt16 nSlotID )
{
	sal_Int32 nType = 0;
	switch ( nSlotID )
	{
        case SID_TRANSLITERATE_SENTENCE_CASE:
            nType = com::sun::star::i18n::TransliterationModulesExtra::SENTENCE_CASE;
            break;
        case SID_TRANSLITERATE_TITLE_CASE:
            nType = com::sun::star::i18n::TransliterationModulesExtra::TITLE_CASE;
            break;
        case SID_TRANSLITERATE_TOGGLE_CASE:
            nType = com::sun::star::i18n::TransliterationModulesExtra::TOGGLE_CASE;
            break;
        case SID_TRANSLITERATE_UPPER:
			nType = com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE;
			break;
		case SID_TRANSLITERATE_LOWER:
			nType = com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE;
			break;
		case SID_TRANSLITERATE_HALFWIDTH:
			nType = com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH;
			break;
		case SID_TRANSLITERATE_FULLWIDTH:
			nType = com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH;
			break;
		case SID_TRANSLITERATE_HIRAGANA:
			nType = com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA;
			break;
		case SID_TRANSLITERATE_KATAGANA:
			nType = com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA;
			break;
	}
	return nType;
}

//	static
sal_Bool ScViewUtil::IsActionShown( const ScChangeAction& rAction,
								const ScChangeViewSettings& rSettings,
								ScDocument& rDocument )
{
	// abgelehnte werden durch eine invertierende akzeptierte Action dargestellt,
	// die Reihenfolge von ShowRejected/ShowAccepted ist deswegen wichtig

	if ( !rSettings.IsShowRejected() && rAction.IsRejecting() )
		return sal_False;

	if ( !rSettings.IsShowAccepted() && rAction.IsAccepted() && !rAction.IsRejecting() )
		return sal_False;

	if ( rSettings.HasAuthor() )
	{
		if ( rSettings.IsEveryoneButMe() )
		{
			//	GetUser() am ChangeTrack ist der aktuelle Benutzer
			ScChangeTrack* pTrack = rDocument.GetChangeTrack();
			if ( !pTrack || rAction.GetUser() == pTrack->GetUser() )
				return sal_False;
		}
		else if ( rAction.GetUser() != rSettings.GetTheAuthorToShow() )
			return sal_False;
	}

	if ( rSettings.HasComment() )
	{
		String aComStr=rAction.GetComment();
		aComStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
		rAction.GetDescription( aComStr, &rDocument );
		aComStr+=')';

		if(!rSettings.IsValidComment(&aComStr))
			return sal_False;
	}

	if ( rSettings.HasRange() )
		if ( !rSettings.GetTheRangeList().Intersects( rAction.GetBigRange().MakeRange() ) )
			return sal_False;

	if ( rSettings.HasDate() && rSettings.GetTheDateMode() != SCDM_NO_DATEMODE )
	{
		DateTime aDateTime = rAction.GetDateTime();
		const DateTime& rFirst = rSettings.GetTheFirstDateTime();
		const DateTime& rLast  = rSettings.GetTheLastDateTime();
		switch ( rSettings.GetTheDateMode() )
		{	// korrespondiert mit ScHighlightChgDlg::OKBtnHdl
			case SCDM_DATE_BEFORE:
				if ( aDateTime > rFirst )
					return sal_False;
				break;

			case SCDM_DATE_SINCE:
				if ( aDateTime < rFirst )
					return sal_False;
				break;

			case SCDM_DATE_EQUAL:
			case SCDM_DATE_BETWEEN:
				if ( aDateTime < rFirst || aDateTime > rLast )
					return sal_False;
				break;

			case SCDM_DATE_NOTEQUAL:
				if ( aDateTime >= rFirst && aDateTime <= rLast )
					return sal_False;
				break;

			case SCDM_DATE_SAVE:
				{
				ScChangeTrack* pTrack = rDocument.GetChangeTrack();
				if ( !pTrack || pTrack->GetLastSavedActionNumber() >=
						rAction.GetActionNumber() )
					return sal_False;
				}
				break;

            default:
            {
                // added to avoid warnings
            }
		}
	}

    if ( rSettings.HasActionRange() )
    {
        sal_uLong nAction = rAction.GetActionNumber();
        sal_uLong nFirstAction;
        sal_uLong nLastAction;
        rSettings.GetTheActionRange( nFirstAction, nLastAction );
        if ( nAction < nFirstAction || nAction > nLastAction )
        {
            return sal_False;
        }
    }

	return sal_True;
}

// static
void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc )
{
    rMark.MarkToMulti();

    ScRange aMultiArea;
    rMark.GetMultiMarkArea( aMultiArea );
    SCCOL nStartCol = aMultiArea.aStart.Col();
    SCROW nStartRow = aMultiArea.aStart.Row();
    SCCOL nEndCol = aMultiArea.aEnd.Col();
    SCROW nEndRow = aMultiArea.aEnd.Row();

    bool bChanged = false;
    SCTAB nTabCount = pDoc->GetTableCount();
    for (SCTAB nTab=0; nTab<nTabCount; nTab++)
        if ( rMark.GetTableSelect(nTab ) )
        {
            for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
            {
                SCROW nLastRow = nRow;
                if (pDoc->RowFiltered(nRow, nTab, NULL, &nLastRow))
    			{
                    // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns
                    // (visible in repaint for indentation)
                    rMark.SetMultiMarkArea(
                        ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false);
                    bChanged = true;
                    nRow = nLastRow;
    			}
            }
        }

    if ( bChanged && !rMark.HasAnyMultiMarks() )
        rMark.ResetMark();

    rMark.MarkToSimple();
}


// static
bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows )
{
    SCTAB nTab = rRange.aStart.Tab();
    bool bOneTabOnly = (nTab == rRange.aEnd.Tab());
    // Always fit the range on its first sheet.
    DBG_ASSERT( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet");
    SCROW nStartRow = rRange.aStart.Row();
    SCROW nLastRow = pDoc->LastNonFilteredRow(nStartRow, MAXROW, nTab);
    if (ValidRow(nLastRow))
        rRange.aEnd.SetRow(nLastRow);
    SCROW nCount = pDoc->CountNonFilteredRows(nStartRow, MAXROW, nTab);
    return static_cast<size_t>(nCount) == nRows && bOneTabOnly;
}


// static
bool ScViewUtil::HasFiltered( const ScRange& rRange, ScDocument* pDoc )
{
    SCROW nStartRow = rRange.aStart.Row();
    SCROW nEndRow = rRange.aEnd.Row();
    for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++)
    {
        if (pDoc->HasFilteredRows(nStartRow, nEndRow, nTab))
            return true;
    }

    return false;
}

// static
void ScViewUtil::HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, sal_uInt16 nSlotId )
{
    SvtCJKOptions aCJKOptions;
    SvtCTLOptions aCTLOptions;
    bool bEnabled = true;

    switch( nSlotId )
    {
        case SID_CHINESE_CONVERSION:
        case SID_HANGUL_HANJA_CONVERSION:
            bEnabled = aCJKOptions.IsAnyEnabled();
        break;

        case SID_TRANSLITERATE_HALFWIDTH:
        case SID_TRANSLITERATE_FULLWIDTH:
        case SID_TRANSLITERATE_HIRAGANA:
        case SID_TRANSLITERATE_KATAGANA:
            bEnabled = aCJKOptions.IsChangeCaseMapEnabled();
        break;

        case SID_INSERT_RLM:
        case SID_INSERT_LRM:
        case SID_INSERT_ZWNBSP:
        case SID_INSERT_ZWSP:
            bEnabled = aCTLOptions.IsCTLFontEnabled();
        break;

        default:
            DBG_ERRORFILE( "ScViewUtil::HideDisabledSlot - unknown slot ID" );
            return;
    }

    rBindings.SetVisibleState( nSlotId, bEnabled );
    if( !bEnabled )
        rSet.DisableItem( nSlotId );
}

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

sal_Bool ScViewUtil::ExecuteCharMap( const SvxFontItem& rOldFont,
								 SfxViewFrame& rFrame,
								 SvxFontItem& 		rNewFont,
								 String&			rString )
{
	sal_Bool bRet = sal_False;
	SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
	if(pFact)
	{
		SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() );
		aSet.Put( SfxBoolItem( FN_PARAM_1, sal_False ) );
		aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT ) ) );
		SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP );
		if ( pDlg->Execute() == RET_OK )
		{
			SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP );
			SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pFontItem, SvxFontItem, SID_ATTR_CHAR_FONT );
			if ( pItem )
				rString  = pItem->GetValue();
			if ( pFontItem )
				rNewFont = SvxFontItem( pFontItem->GetFamily(), pFontItem->GetFamilyName(), pFontItem->GetStyleName(), pFontItem->GetPitch(), pFontItem->GetCharSet(), rNewFont.Which() );
			bRet = sal_True;
		}
		delete pDlg;
	}
	return bRet;
}

bool ScViewUtil::IsFullScreen( SfxViewShell& rViewShell )
{
    SfxBindings&    rBindings       = rViewShell.GetViewFrame()->GetBindings();
    SfxPoolItem*    pItem           = 0;
    bool            bIsFullScreen   = false;

    if (rBindings.QueryState( SID_WIN_FULLSCREEN, pItem ) >= SFX_ITEM_DEFAULT)
        bIsFullScreen = static_cast< SfxBoolItem* >( pItem )->GetValue();
    return bIsFullScreen;
}

void ScViewUtil::SetFullScreen( SfxViewShell& rViewShell, bool bSet )
{
    if( IsFullScreen( rViewShell ) != bSet )
    {
        SfxBoolItem aItem( SID_WIN_FULLSCREEN, bSet );
        rViewShell.GetDispatcher()->Execute( SID_WIN_FULLSCREEN, SFX_CALLMODE_RECORD, &aItem, 0L );
    }
}

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

ScUpdateRect::ScUpdateRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
{
	PutInOrder( nX1, nX2 );
	PutInOrder( nY1, nY2 );

	nOldStartX = nX1;
	nOldStartY = nY1;
	nOldEndX = nX2;
	nOldEndY = nY2;
}

void ScUpdateRect::SetNew( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
{
	PutInOrder( nX1, nX2 );
	PutInOrder( nY1, nY2 );

	nNewStartX = nX1;
	nNewStartY = nY1;
	nNewEndX = nX2;
	nNewEndY = nY2;
}

sal_Bool ScUpdateRect::GetDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
{
	if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
		 nNewStartY == nOldStartY && nNewEndY == nOldEndY )
	{
		rX1 = nNewStartX;
		rY1 = nNewStartY;
		rX2 = nNewStartX;
		rY2 = nNewStartY;
		return sal_False;
	}

	rX1 = Min(nNewStartX,nOldStartX);
	rY1 = Min(nNewStartY,nOldStartY);
	rX2 = Max(nNewEndX,nOldEndX);
	rY2 = Max(nNewEndY,nOldEndY);

	if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX )
	{
		if ( nNewStartY == nOldStartY )
		{
			rY1 = Min( nNewEndY, nOldEndY );
			rY2 = Max( nNewEndY, nOldEndY );
		}
		else if ( nNewEndY == nOldEndY )
		{
			rY1 = Min( nNewStartY, nOldStartY );
			rY2 = Max( nNewStartY, nOldStartY );
		}
	}
	else if ( nNewStartY == nOldStartY && nNewEndY == nOldEndY )
	{
		if ( nNewStartX == nOldStartX )
		{
			rX1 = Min( nNewEndX, nOldEndX );
			rX2 = Max( nNewEndX, nOldEndX );
		}
		else if ( nNewEndX == nOldEndX )
		{
			rX1 = Min( nNewStartX, nOldStartX );
			rX2 = Max( nNewStartX, nOldStartX );
		}
	}

	return sal_True;
}

#ifdef OLD_SELECTION_PAINT
sal_Bool ScUpdateRect::GetXorDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, sal_Bool& rCont )
{
    rCont = sal_False;

    if (nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
        nNewStartY == nOldStartY && nNewEndY == nOldEndY)
    {
        rX1 = nNewStartX;
        rY1 = nNewStartY;
        rX2 = nNewStartX;
        rY2 = nNewStartY;
        return sal_False;
    }

    rX1 = Min(nNewStartX,nOldStartX);
    rY1 = Min(nNewStartY,nOldStartY);
    rX2 = Max(nNewEndX,nOldEndX);
    rY2 = Max(nNewEndY,nOldEndY);

    if (nNewStartX == nOldStartX && nNewEndX == nOldEndX)             // nur vertikal
    {
        if (nNewStartY == nOldStartY)
        {
            rY1 = Min( nNewEndY, nOldEndY ) + 1;
            rY2 = Max( nNewEndY, nOldEndY );
        }
        else if (nNewEndY == nOldEndY)
        {
            rY1 = Min( nNewStartY, nOldStartY );
            rY2 = Max( nNewStartY, nOldStartY ) - 1;
        }
        else
        {
            rY1 = Min( nNewStartY, nOldStartY );
            rY2 = Max( nNewStartY, nOldStartY ) - 1;
            rCont = sal_True;
            nContY1 = Min( nNewEndY, nOldEndY ) + 1;
            nContY2 = Max( nNewEndY, nOldEndY );
            nContX1 = rX1;
            nContX2 = rX2;
        }
    }
    else if (nNewStartY == nOldStartY && nNewEndY == nOldEndY)        // nur horizontal
    {
        if (nNewStartX == nOldStartX)
        {
            rX1 = Min( nNewEndX, nOldEndX ) + 1;
            rX2 = Max( nNewEndX, nOldEndX );
        }
        else if (nNewEndX == nOldEndX)
        {
            rX1 = Min( nNewStartX, nOldStartX );
            rX2 = Max( nNewStartX, nOldStartX ) - 1;
        }
        else
        {
            rX1 = Min( nNewStartX, nOldStartX );
            rX2 = Max( nNewStartX, nOldStartX ) - 1;
            rCont = sal_True;
            nContX1 = Min( nNewEndX, nOldEndX ) + 1;
            nContX2 = Max( nNewEndX, nOldEndX );
            nContY1 = rY1;
            nContY2 = rY2;
        }
    }
    else if (nNewEndX == nOldEndX && nNewEndY == nOldEndY)            // links oben
    {
        if ((nNewStartX<nOldStartX) == (nNewStartY<nOldStartY))
            rX1 = Min( nNewStartX, nOldStartX );
        else
            rX1 = Max( nNewStartX, nOldStartX );            // Ecke weglassen
        rX2 = nOldEndX;
        rY1 = Min( nNewStartY, nOldStartY );                // oben
        rY2 = Max( nNewStartY, nOldStartY ) - 1;
        rCont = sal_True;
        nContY1 = rY2+1;
        nContY2 = nOldEndY;
        nContX1 = Min( nNewStartX, nOldStartX );            // links
        nContX2 = Max( nNewStartX, nOldStartX ) - 1;
    }
    else if (nNewStartX == nOldStartX && nNewEndY == nOldEndY)        // rechts oben
    {
        if ((nNewEndX<nOldEndX) != (nNewStartY<nOldStartY))
            rX2 = Max( nNewEndX, nOldEndX );
        else
            rX2 = Min( nNewEndX, nOldEndX );                // Ecke weglassen
        rX1 = nOldStartX;
        rY1 = Min( nNewStartY, nOldStartY );                // oben
        rY2 = Max( nNewStartY, nOldStartY ) - 1;
        rCont = sal_True;
        nContY1 = rY2+1;
        nContY2 = nOldEndY;
        nContX1 = Min( nNewEndX, nOldEndX ) + 1;            // rechts
        nContX2 = Max( nNewEndX, nOldEndX );
    }
    else if (nNewEndX == nOldEndX && nNewStartY == nOldStartY)        // links unten
    {
        if ((nNewStartX<nOldStartX) != (nNewEndY<nOldEndY))
            rX1 = Min( nNewStartX, nOldStartX );
        else
            rX1 = Max( nNewStartX, nOldStartX );            // Ecke weglassen
        rX2 = nOldEndX;
        rY1 = Min( nNewEndY, nOldEndY ) + 1;                // unten
        rY2 = Max( nNewEndY, nOldEndY );
        rCont = sal_True;
        nContY1 = nOldStartY;
        nContY2 = rY1-1;
        nContX1 = Min( nNewStartX, nOldStartX );            // links
        nContX2 = Max( nNewStartX, nOldStartX ) - 1;
    }
    else if (nNewStartX == nOldStartX && nNewStartY == nOldStartY)    // rechts unten
    {
        if ((nNewEndX<nOldEndX) == (nNewEndY<nOldEndY))
            rX2 = Max( nNewEndX, nOldEndX );
        else
            rX2 = Min( nNewEndX, nOldEndX );                // Ecke weglassen
        rX1 = nOldStartX;
        rY1 = Min( nNewEndY, nOldEndY ) + 1;                // unten
        rY2 = Max( nNewEndY, nOldEndY );
        rCont = sal_True;
        nContY1 = nOldStartY;
        nContY2 = rY1-1;
        nContX1 = Min( nNewEndX, nOldEndX ) + 1;            // rechts
        nContX2 = Max( nNewEndX, nOldEndX );
    }
    else                                                                // Ueberschlag
    {
        rX1 = nOldStartX;
        rY1 = nOldStartY;
        rX2 = nOldEndX;
        rY2 = nOldEndY;
        rCont = sal_True;
        nContX1 = nNewStartX;
        nContY1 = nNewStartY;
        nContX2 = nNewEndX;
        nContY2 = nNewEndY;
    }

    return sal_True;
}

void ScUpdateRect::GetContDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
{
    rX1 = nContX1;
    rY1 = nContY1;
    rX2 = nContX2;
    rY2 = nContY2;
}
#endif






