/**************************************************************
 * 
 * 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/app.hxx>
#include <sfx2/viewsh.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/mnemonic.hxx>
#include <tools/shl.hxx>
#include <svtools/taskbar.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>


#define ANYREFDG_CXX
#include "anyrefdg.hxx"
#undef ANYREFDG_CXX

#include "sc.hrc"
#include "inputhdl.hxx"
#include "scmod.hxx"
#include "scresid.hxx"
#include "inputwin.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "rfindlst.hxx"
#include "compiler.hxx"
#include "cell.hxx"
#include "global.hxx"
#include "inputopt.hxx"
#include "rangeutl.hxx"
    

ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings) 
 : m_pDlg(_pDlg)
 , pRefEdit (NULL)
 , m_pWindow(NULL)
 , m_pBindings(_pBindings)
 , pAccel( NULL )
 , pHiddenMarks(NULL)
 , nRefTab(0)
 , bHighLightRef( sal_False )
 , bAccInserted( sal_False )
{
    ScInputOptions aInputOption=SC_MOD()->GetInputOptions();
	bEnableColorRef=aInputOption.GetRangeFinder();
}
// -----------------------------------------------------------------------------
ScFormulaReferenceHelper::~ScFormulaReferenceHelper()
{
    if (bAccInserted)
		Application::RemoveAccel( pAccel.get() );

    // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here

    HideReference();
    enableInput( sal_True );

    ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
    if ( pInputHdl )
        pInputHdl->ResetDelayTimer();   // stop the timer for disabling the input line
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::enableInput( sal_Bool bEnable )
{
    ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(_IsObjectShell< ScDocShell >);
    while( pDocShell )
    {
	    SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
	    while( pFrame )
	    {
		    //	#71577# enable everything except InPlace, including bean frames
            if ( !pFrame->GetFrame().IsInPlace() )
		    {
			    SfxViewShell* p = pFrame->GetViewShell();
			    ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell* >( p);
			    if(pViewSh!=NULL)
			    {
				    Window *pWin=pViewSh->GetWindow();
				    if(pWin)
				    {
					    Window *pParent=pWin->GetParent();
					    if(pParent)
					    {
						    pParent->EnableInput(bEnable,sal_True /* sal_False */);
						    if(sal_True /*bChilds*/)
							    pViewSh->EnableRefInput(bEnable);
					    }
				    }
			    }
		    }
		    pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
	    }

	    pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, _IsObjectShell< ScDocShell >);
    }
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::ShowSimpleReference( const XubString& rStr )
{
    if( /*!pRefEdit &&*/ bEnableColorRef )
	{
		bHighLightRef=sal_True;
		ScViewData* pViewData=ScDocShell::GetViewData();
		if ( pViewData )
		{
			ScDocument* pDoc=pViewData->GetDocument();
			ScTabViewShell*	pTabViewShell=pViewData->GetViewShell();

			ScRangeList aRangeList;

			pTabViewShell->DoneRefMode( sal_False );
			pTabViewShell->ClearHighlightRanges();

			if( ParseWithNames( aRangeList, rStr, pDoc ) )
			{
				ScRange* pRangeEntry = aRangeList.First();

				sal_uInt16 nIndex=0;
				while(pRangeEntry != NULL)
				{
					ColorData aColName = ScRangeFindList::GetColorName(nIndex++);
					pTabViewShell->AddHighlightRange(*pRangeEntry, aColName);

					pRangeEntry = aRangeList.Next();
				}
			}
		}
	}
}
// -----------------------------------------------------------------------------
bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
{
    bool bError = false;
    rRanges.RemoveAll();

    ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
    ScRangeUtil aRangeUtil;
    xub_StrLen nTokenCnt = rStr.GetTokenCount();
    for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
    {
        ScRange aRange;
        String aRangeStr( rStr.GetToken( nToken ) );

        sal_uInt16 nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails );
        if ( nFlags & SCA_VALID )
        {
            if ( (nFlags & SCA_TAB_3D) == 0 )
                aRange.aStart.SetTab( nRefTab );
            if ( (nFlags & SCA_TAB2_3D) == 0 )
                aRange.aEnd.SetTab( aRange.aStart.Tab() );
            rRanges.Append( aRange );
        }
        else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) )
            rRanges.Append( aRange );
        else
            bError = true;        
    }

    return !bError;
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::ShowFormulaReference( const XubString& rStr )
{
    if( /*!pRefEdit &&*/ bEnableColorRef)
	{
		bHighLightRef=sal_True;
		ScViewData* pViewData=ScDocShell::GetViewData();
		if ( pViewData && pRefComp.get() )
		{
			ScTabViewShell*	pTabViewShell=pViewData->GetViewShell();
			SCCOL nCol = pViewData->GetCurX();
			SCROW nRow = pViewData->GetCurY();
			SCTAB nTab = pViewData->GetTabNo();
			ScAddress aPos( nCol, nRow, nTab );

			ScTokenArray* pScTokA=pRefComp->CompileString(rStr);
			//pRefComp->CompileTokenArray();

			if(pTabViewShell!=NULL && pScTokA!=NULL)
			{
				pTabViewShell->DoneRefMode( sal_False );
				pTabViewShell->ClearHighlightRanges();

				pScTokA->Reset();
				const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());

				sal_uInt16 nIndex=0;

				while(pToken!=NULL)
				{
					sal_Bool bDoubleRef=(pToken->GetType()==formula::svDoubleRef);


					if(pToken->GetType()==formula::svSingleRef || bDoubleRef)
					{
						ScRange aRange;
						if(bDoubleRef)
						{
							ScComplexRefData aRef( pToken->GetDoubleRef() );
							aRef.CalcAbsIfRel( aPos );
							aRange.aStart.Set( aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab );
							aRange.aEnd.Set( aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab );
						}
						else
						{
							ScSingleRefData aRef( pToken->GetSingleRef() );
							aRef.CalcAbsIfRel( aPos );
							aRange.aStart.Set( aRef.nCol, aRef.nRow, aRef.nTab );
							aRange.aEnd = aRange.aStart;
						}
						ColorData aColName=ScRangeFindList::GetColorName(nIndex++);
						pTabViewShell->AddHighlightRange(aRange, aColName);
					}

					pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
				}
			}
			if(pScTokA!=NULL) delete pScTokA;
		}
	}
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::HideReference( sal_Bool bDoneRefMode )
{
	ScViewData* pViewData=ScDocShell::GetViewData();

    if( pViewData && /*!pRefEdit &&*/ bHighLightRef && bEnableColorRef)
	{
		ScTabViewShell*	pTabViewShell=pViewData->GetViewShell();

		if(pTabViewShell!=NULL)
		{
			//	bDoneRefMode is sal_False when called from before SetReference.
			//	In that case, RefMode was just started and must not be ended now.

			if ( bDoneRefMode )
				pTabViewShell->DoneRefMode( sal_False );
			pTabViewShell->ClearHighlightRanges();
		}
		bHighLightRef=sal_False;
	}
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::ShowReference( const XubString& rStr )
{
    if( /*!pRefEdit &&*/ bEnableColorRef )
	{
		if(	rStr.Search('(')!=STRING_NOTFOUND ||
			rStr.Search('+')!=STRING_NOTFOUND ||
			rStr.Search('*')!=STRING_NOTFOUND ||
			rStr.Search('-')!=STRING_NOTFOUND ||
			rStr.Search('/')!=STRING_NOTFOUND ||
			rStr.Search('&')!=STRING_NOTFOUND ||
			rStr.Search('<')!=STRING_NOTFOUND ||
			rStr.Search('>')!=STRING_NOTFOUND ||
			rStr.Search('=')!=STRING_NOTFOUND ||
			rStr.Search('^')!=STRING_NOTFOUND)
		{
			ShowFormulaReference(rStr);
		}
		else
		{
			ShowSimpleReference(rStr);
		}
	}
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
    if( !pRefEdit && pEdit )
    {
        m_pDlg->RefInputStart( pEdit, pButton );
//        if( pRefEdit )
//            pRefEdit->SilentGrabFocus();
    }

    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    if( pViewShell )
    {
        pViewShell->ActiveGrabFocus();
        if( pRefEdit )
        {
            const ScViewData* pViewData = pViewShell->GetViewData();
            ScDocument* pDoc = pViewData->GetDocument();
			ScRangeList aRangeList;
            if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) )
			{
                const ScRange* pRange = aRangeList.GetObject( 0 );
                if( pRange )
                {
                    pViewShell->SetTabNo( pRange->aStart.Tab() );
                    pViewShell->MoveCursorAbs(  pRange->aStart.Col(),
                        pRange->aStart.Row(), SC_FOLLOW_JUMP, sal_False, sal_False );
                    pViewShell->MoveCursorAbs( pRange->aEnd.Col(),
                        pRange->aEnd.Row(), SC_FOLLOW_JUMP, sal_True, sal_False );
                    m_pDlg->SetReference( *pRange, pDoc );
                }
            }
        }
    }
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::Init()
{
    ScViewData* pViewData=ScDocShell::GetViewData();    //! use pScViewShell?
	if ( pViewData )
	{
		ScDocument* pDoc = pViewData->GetDocument();
		SCCOL nCol = pViewData->GetCurX();
		SCROW nRow = pViewData->GetCurY();
		SCTAB nTab = pViewData->GetTabNo();
		ScAddress aCursorPos( nCol, nRow, nTab );

		String rStrExp;
		pRefCell.reset( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) );
		pRefComp.reset( new ScCompiler( pDoc, aCursorPos) );
        pRefComp->SetGrammar( pDoc->GetGrammar() );
		pRefComp->SetCompileForFAP(sal_True);

        nRefTab = nTab;
	} // if ( pViewData )
}
// -----------------------------------------------------------------------------
IMPL_LINK( ScFormulaReferenceHelper, AccelSelectHdl, Accelerator *, pSelAccel )
{
    if ( !pSelAccel )
		return 0;

    switch ( pSelAccel->GetCurKeyCode().GetCode() )
	{
		case KEY_RETURN:
		case KEY_ESCAPE:
            if( pRefEdit )
                pRefEdit->GrabFocus();
            m_pDlg->RefInputDone( sal_True );
        break;
	}
	return sal_True;
}
//----------------------------------------------------------------------------
void ScFormulaReferenceHelper::RefInputDone( sal_Bool bForced )
{
	//<!--Modified by PengYunQuan for Validity Cell Range Picker
	//if (pRefEdit && (bForced || !pRefBtn))
	if ( CanInputDone( bForced ) )//if (pRefEdit && (bForced || !pRefBtn))
	//-->Modified by PengYunQuan for Validity Cell Range Picker
	{
		if (bAccInserted)			// Accelerator wieder abschalten
		{
			Application::RemoveAccel( pAccel.get() );
			bAccInserted = sal_False;
		}

		// Fenstertitel anpassen
		m_pWindow->SetText(sOldDialogText);

		// Fenster wieder gross
		m_pWindow->SetOutputSizePixel(aOldDialogSize);

		// pEditCell an alte Position
		pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize);

        // set button position and image
        if( pRefBtn )
        {
            pRefBtn->SetPosPixel( aOldButtonPos );
            pRefBtn->SetStartImage();
        }

		// Alle anderen: Show();
		sal_uInt16 nChildren = m_pWindow->GetChildCount();
		for ( sal_uInt16 i = 0; i < nChildren; i++ )
			if (pHiddenMarks[i])
			{
				m_pWindow->GetChild(i)->GetWindow( WINDOW_CLIENT )->Show();
			}
		delete [] pHiddenMarks;

		pRefEdit = NULL;
        pRefBtn = NULL;
	}
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
	if (!pRefEdit)
	{
		pRefEdit = pEdit;
		pRefBtn  = pButton;

		// Neuen Fenstertitel basteln
		String sNewDialogText;
		sOldDialogText = m_pWindow->GetText();
		sNewDialogText  = sOldDialogText;
		sNewDialogText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));

		// Alle Elemente ausser EditCell und Button verstecken
		sal_uInt16 nChildren = m_pWindow->GetChildCount();
		pHiddenMarks = new sal_Bool [nChildren];
		for (sal_uInt16 i = 0; i < nChildren; i++)
		{
			pHiddenMarks[i] = sal_False;
			Window* pWin = m_pWindow->GetChild(i);
			pWin = pWin->GetWindow( WINDOW_CLIENT );
			if (pWin == (Window*)pRefEdit)
			{
				sNewDialogText += m_pWindow->GetChild(i-1)->GetWindow( WINDOW_CLIENT )->GetText();
			}
			else if (pWin == (Window*)pRefBtn)
				;	// do nothing
			else if (pWin->IsVisible())
			{
				pHiddenMarks[i] = sal_True;
				pWin->Hide();
			}
		}

		// Alte Daten merken
		aOldDialogSize = m_pWindow->GetOutputSizePixel();
		aOldEditPos = pRefEdit->GetPosPixel();
		aOldEditSize = pRefEdit->GetSizePixel();
		if (pRefBtn)
			aOldButtonPos = pRefBtn->GetPosPixel();

		// Edit-Feld verschieben und anpassen
		Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height());
		Size aNewEditSize(aNewDlgSize);
        long nOffset = 0;
		if (pRefBtn)
		{
			aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width();
			aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width());

            long nHeight = pRefBtn->GetSizePixel().Height();
            if ( nHeight > aOldEditSize.Height() )
            {
                aNewDlgSize.Height() = nHeight;
                nOffset = (nHeight-aOldEditSize.Height()) / 2;
            }
            aNewEditSize.Width() -= nOffset;
		}
		pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize);

        // set button position and image
        if( pRefBtn )
        {
            pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) );
            pRefBtn->SetEndImage();
        }

		// Fenster verkleinern
		m_pWindow->SetOutputSizePixel(aNewDlgSize);

		// Fenstertitel anpassen
		m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) );

//        if ( pButton )      // ueber den Button: Enter und Escape abfangen
//        {
			if (!pAccel.get())
			{
				pAccel.reset( new Accelerator );
				pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) );
				pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) );
				pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) );
			}
			Application::InsertAccel( pAccel.get() );
			bAccInserted = sal_True;
//        }
	}
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
    if( pEdit )
    {
        if( pRefEdit == pEdit )                 // is this the active ref edit field?
        {
            pRefEdit->GrabFocus();              // before RefInputDone()
            m_pDlg->RefInputDone( sal_True );               // finish ref input
        }
        else
        {
            m_pDlg->RefInputDone( sal_True );               // another active ref edit?
            m_pDlg->RefInputStart( pEdit, pButton );    // start ref input
            // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
            if( pRefEdit )
                pRefEdit->GrabFocus();
        }
    }
}
// -----------------------------------------------------------------------------
sal_Bool ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )
{
	SfxApplication* pSfxApp = SFX_APP();

	SetDispatcherLock( sal_False );			//! here and in dtor ?

	SfxViewFrame* pViewFrm = SfxViewFrame::Current();
	if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) )
	{
		//	Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch
		//	per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow),
		//	damit die Buttons auch wieder enabled gezeichnet werden.
		SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS);
		if (pChild)
		{
			ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
			pWin->Enable();
		}
	}

	// find parent view frame to close dialog
	SfxViewFrame* pMyViewFrm = NULL;
	if ( m_pBindings )
	{
		SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher();
		if (pMyDisp)
			pMyViewFrm = pMyDisp->GetFrame();
	}
	SC_MOD()->SetRefDialog( nId, sal_False, pMyViewFrm );

	pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );

    ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
	if ( pScViewShell )
		pScViewShell->UpdateInputHandler(sal_True);

	return sal_True;
}
void ScFormulaReferenceHelper::SetDispatcherLock( sal_Bool bLock )
{
	//	lock / unlock only the dispatchers of Calc documents
	ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(_IsObjectShell< ScDocShell >);
	while( pDocShell )
	{
		SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
		while( pFrame )
		{
			SfxDispatcher* pDisp = pFrame->GetDispatcher();
			if (pDisp)
				pDisp->Lock( bLock );

			pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
		}
		pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, _IsObjectShell< ScDocShell >);
	}

	//	if a new view is created while the dialog is open,
	//	that view's dispatcher is locked when trying to create the dialog
	//	for that view (ScTabViewShell::CreateRefDialog)
}
// -----------------------------------------------------------------------------
void ScFormulaReferenceHelper::ViewShellChanged(ScTabViewShell* /* pScViewShell */)
{
	enableInput( sal_False );

	EnableSpreadsheets();
}
void ScFormulaReferenceHelper::EnableSpreadsheets(sal_Bool bFlag, sal_Bool bChilds)
{
	ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(_IsObjectShell< ScDocShell >);
	while( pDocShell )
	{
		SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
		while( pFrame )
		{
			//	#71577# enable everything except InPlace, including bean frames
            if ( !pFrame->GetFrame().IsInPlace() )
			{
				SfxViewShell* p = pFrame->GetViewShell();
				ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell* >( p);
				if(pViewSh!=NULL)
				{
					Window *pWin=pViewSh->GetWindow();
					if(pWin)
					{
						Window *pParent=pWin->GetParent();
						if(pParent)
						{
							pParent->EnableInput(bFlag,sal_False);
							if(bChilds)
								pViewSh->EnableRefInput(bFlag);
						}
					}
				}
			}
			pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
		}

		pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, _IsObjectShell< ScDocShell >);
	}
}

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



void lcl_InvalidateWindows()
{
	ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(_IsObjectShell< ScDocShell >);
	while( pDocShell )
	{
		SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
		while( pFrame )
		{
			//	#71577# enable everything except InPlace, including bean frames
            if ( !pFrame->GetFrame().IsInPlace() )
			{
				SfxViewShell* p = pFrame->GetViewShell();
				ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell* >( p);
				if(pViewSh!=NULL)
				{
					Window *pWin=pViewSh->GetWindow();
					if(pWin)
					{
						Window *pParent=pWin->GetParent();
						if(pParent)
							pParent->Invalidate();
					}
				}
			}
			pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
		}

		pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, _IsObjectShell< ScDocShell >);
	}
}
//----------------------------------------------------------------------------

void lcl_HideAllReferences()
{
	SfxViewShell* pSh = SfxViewShell::GetFirst( _IsSfxViewShell< ScTabViewShell > );
	while ( pSh )
	{
		((ScTabViewShell*)pSh)->ClearHighlightRanges();
		pSh = SfxViewShell::GetNext( *pSh, _IsSfxViewShell< ScTabViewShell > );
	}
}

//============================================================================
//The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
//	class ScRefHandler
//----------------------------------------------------------------------------

ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB/*, SfxChildWindow* pCW,
						  Window* pParent, sal_uInt16 nResId*/, bool bBindRef )
	:	//SfxModelessDialog ( pB, pCW, pParent, ScResId( nResId ) ),
		m_rWindow( rWindow ),
		m_bInRefMode( false ),
        m_aHelper(this,pB),
		pMyBindings( pB ),
        pActiveWin(NULL)
{
	m_aHelper.SetWindow(/*this*/&m_rWindow);
	if(m_rWindow.GetHelpId().getLength()==0)				//Hack, da im SfxModelessDialog die HelpId
		m_rWindow.SetHelpId(m_rWindow.GetUniqueId());	//fuer einen ModelessDialog entfernt und
									//in eine UniqueId gewandelt wird, machen
									//wir das an dieser Stelle rueckgaengig.
	aTimer.SetTimeout(200);
	aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl));

	if( bBindRef ) EnterRefMode();
}

bool ScRefHandler::EnterRefMode()
{
	if( m_bInRefMode ) return false;

	SC_MOD()->InputEnterHandler();
//    ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();

    ScTabViewShell* pScViewShell = NULL;

	// title has to be from the view that opened the dialog,
	// even if it's not the current view

	SfxObjectShell* pParentDoc = NULL;
	if ( pMyBindings )
	{
		SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher();
		if (pMyDisp)
		{
			SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
			if (pMyViewFrm)
            {
                pScViewShell = dynamic_cast< ScTabViewShell* >( pMyViewFrm->GetViewShell() );
                if( pScViewShell )
		            pScViewShell->UpdateInputHandler(sal_True);
				pParentDoc = pMyViewFrm->GetObjectShell();
            }
		}
	}
	if ( !pParentDoc && pScViewShell )					// use current only if above fails
		pParentDoc = pScViewShell->GetObjectShell();
	if ( pParentDoc )
		aDocName = pParentDoc->GetTitle();

    ScInputHandler*	pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);

	DBG_ASSERT( pInputHdl, "Missing input handler :-/" );

	if ( pInputHdl )
		pInputHdl->NotifyChange( NULL );

	m_aHelper.enableInput( sal_False );

	m_aHelper.EnableSpreadsheets();

    m_aHelper.Init();

	m_aHelper.SetDispatcherLock( sal_True );
	//@Test
	//SFX_APPWINDOW->Disable(sal_True);	  //@BugID 54702
	
	return m_bInRefMode = true;
}

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

ScRefHandler::~ScRefHandler()
{
	LeaveRefMode();
}

bool ScRefHandler::LeaveRefMode()
{
	if( !m_bInRefMode ) return false;

	lcl_HideAllReferences();

	if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) )
		pDlg->SetModalInputMode(sal_False);
	SetDispatcherLock( sal_False );			//! here and in DoClose ?

    ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
    if( pScViewShell )
		pScViewShell->UpdateInputHandler(sal_True);

	//SFX_APPWINDOW->Enable(sal_True,sal_True);
	lcl_InvalidateWindows();

	m_bInRefMode = false;
	return true;
}

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

//SfxBindings& ScRefHandler::GetBindings()
//{
//	//!	SfxModelessDialog should allow access to pBindings pointer
//
//	return *pMyBindings;
//}

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

void ScRefHandler::SwitchToDocument()
{
	ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell();
	if (pCurrent)
	{
		SfxObjectShell* pObjSh = pCurrent->GetObjectShell();
		if ( pObjSh && pObjSh->GetTitle() == aDocName )
		{
			//	right document already visible -> nothing to do
			return;
		}
	}

	SfxViewShell* pSh = SfxViewShell::GetFirst( _IsSfxViewShell< ScTabViewShell > );
	while ( pSh )
	{
		SfxObjectShell* pObjSh = pSh->GetObjectShell();
		if ( pObjSh && pObjSh->GetTitle() == aDocName )
		{
			//	switch to first TabViewShell for document
			((ScTabViewShell*)pSh)->SetActive();
			return;
		}
		pSh = SfxViewShell::GetNext( *pSh, _IsSfxViewShell< ScTabViewShell > );
	}
}

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

sal_Bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const	// pDocSh may be 0
{
	//	default: allow only same document (overridden in function dialog)
	String aCmpName;
	if ( pDocSh )
		aCmpName = pDocSh->GetTitle();

	//	if aDocName isn't initialized, allow
	return ( aDocName.Len() == 0 || aDocName == aCmpName );
}

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

sal_Bool __EXPORT ScRefHandler::IsRefInputMode() const
{
	return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen
}

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

sal_Bool __EXPORT ScRefHandler::DoClose( sal_uInt16 nId )
{
    m_aHelper.DoClose(nId);
	return sal_True;
}

void ScRefHandler::SetDispatcherLock( sal_Bool bLock )
{
	m_aHelper.SetDispatcherLock( bLock );
}

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

void ScRefHandler::ViewShellChanged(ScTabViewShell*  pScViewShell )
{
	m_aHelper.ViewShellChanged(pScViewShell);
}

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

void ScRefHandler::AddRefEntry()
{
	//	wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen
}

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

sal_Bool __EXPORT ScRefHandler::IsTableLocked() const
{
	// per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden

	return sal_False;
}

//----------------------------------------------------------------------------
//
//	RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld
//	(per Button oder Bewegung)
//
//----------------------------------------------------------------------------

void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
    m_aHelper.RefInputStart( pEdit, pButton );
}


void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
    m_aHelper.ToggleCollapsed( pEdit, pButton );
}

//The two following function is commentted out by PengYunQuan for Validity Cell Range Picker
//long ScAnyRefDlg::PreNotify( NotifyEvent& rNEvt )
//{
//	sal_uInt16 nSwitch=rNEvt.GetType();
//	if(nSwitch==EVENT_GETFOCUS)
//	{
//		pActiveWin=rNEvt.GetWindow();
//	}
//	return SfxModelessDialog::PreNotify(rNEvt);
//}
//
//void ScAnyRefDlg::StateChanged( StateChangedType nStateChange )
//{
//	SfxModelessDialog::StateChanged( nStateChange );
//
//	if(nStateChange == STATE_CHANGE_VISIBLE)
//	{
//		if(IsVisible())
//		{
//			m_aHelper.enableInput( sal_False );
//			m_aHelper.EnableSpreadsheets();
//			m_aHelper.SetDispatcherLock( sal_True );
//			aTimer.Start();
//		}
//		else
//		{
//			m_aHelper.enableInput( sal_True );
//			m_aHelper.SetDispatcherLock( sal_False );			//! here and in DoClose ?
//		}
//	}
//}

#if defined( _MSC_VER )
#define INTRODUCE_TEMPLATE
#else
#define INTRODUCE_TEMPLATE	template <>
#endif

#define IMPL_TWINDOW_PRENOTIFY( TWindow,bBindRef )	\
INTRODUCE_TEMPLATE long ScRefHdlrImplBase<TWindow,bBindRef>::PreNotify( NotifyEvent& rNEvt )\
{\
	if( bBindRef || m_bInRefMode )\
	{\
		sal_uInt16 nSwitch=rNEvt.GetType();\
		if(nSwitch==EVENT_GETFOCUS)\
		{\
			pActiveWin=rNEvt.GetWindow();\
		}\
	}\
	return TWindow::PreNotify(rNEvt);\
}

#define IMPL_TWINDOW_STATECHANGED( TWindow,bBindRef )	\
INTRODUCE_TEMPLATE void ScRefHdlrImplBase<TWindow,bBindRef>::StateChanged( StateChangedType nStateChange )\
{\
	TWindow::StateChanged( nStateChange );\
\
	if( !bBindRef && !m_bInRefMode ) return;\
	\
	if(nStateChange == STATE_CHANGE_VISIBLE)\
	{\
		if(m_rWindow.IsVisible())\
		{\
			m_aHelper.enableInput( sal_False );\
			m_aHelper.EnableSpreadsheets();\
			m_aHelper.SetDispatcherLock( sal_True );\
			aTimer.Start();\
		}\
		else\
		{\
			m_aHelper.enableInput( sal_True );\
			m_aHelper.SetDispatcherLock( sal_False );			/*//! here and in DoClose ?*/\
		}\
	}\
}

IMPL_TWINDOW_PRENOTIFY( SfxModelessDialog, true )
IMPL_TWINDOW_PRENOTIFY( SfxTabDialog, false )
IMPL_TWINDOW_STATECHANGED( SfxModelessDialog, true )
IMPL_TWINDOW_STATECHANGED( SfxTabDialog, false )

IMPL_LINK( ScRefHandler, UpdateFocusHdl, Timer*, EMPTYARG )
{
	if (pActiveWin)
	{
		pActiveWin->GrabFocus();
	}
	return 0;
}
// -----------------------------------------------------------------------------
bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
{
    return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
}
// -----------------------------------------------------------------------------
void ScRefHandler::HideReference( sal_Bool bDoneRefMode )
{
    m_aHelper.HideReference( bDoneRefMode );
}
// -----------------------------------------------------------------------------
void ScRefHandler::ShowReference( const XubString& rStr )
{
    m_aHelper.ShowReference( rStr );
}
// -----------------------------------------------------------------------------
void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
    m_aHelper.ReleaseFocus( pEdit,pButton );
}
//----------------------------------------------------------------------------
void ScRefHandler::RefInputDone( sal_Bool bForced )
{
    m_aHelper.RefInputDone( bForced );
}

