| /************************************************************** |
| * |
| * 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 ) |
| { |
| TypeId aType(TYPE(ScDocShell)); |
| ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); |
| 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 = PTR_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, &aType); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| 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 |
| |
| TypeId aType(TYPE(ScDocShell)); |
| ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); |
| 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, &aType); |
| } |
| |
| // 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) |
| { |
| TypeId aType(TYPE(ScDocShell)); |
| ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); |
| 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 = PTR_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, &aType); |
| } |
| } |
| |
| //---------------------------------------------------------------------------- |
| |
| |
| |
| void lcl_InvalidateWindows() |
| { |
| TypeId aType(TYPE(ScDocShell)); |
| ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); |
| 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 = PTR_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, &aType); |
| } |
| } |
| //---------------------------------------------------------------------------- |
| |
| void lcl_HideAllReferences() |
| { |
| TypeId aScType = TYPE(ScTabViewShell); |
| SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType ); |
| while ( pSh ) |
| { |
| ((ScTabViewShell*)pSh)->ClearHighlightRanges(); |
| pSh = SfxViewShell::GetNext( *pSh, &aScType ); |
| } |
| } |
| |
| //============================================================================ |
| //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 = PTR_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; |
| } |
| } |
| |
| TypeId aScType = TYPE(ScTabViewShell); |
| SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType ); |
| 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, &aScType ); |
| } |
| } |
| |
| //---------------------------------------------------------------------------- |
| |
| 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 ); |
| } |
| |