Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / sc / source / ui / miscdlgs / anyrefdg.cxx
blob5e2d9c66dd6dcc64e0b4ca78defa449705d02fc3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "rangelst.hxx"
21 #include <comphelper/string.hxx>
22 #include <sfx2/app.hxx>
23 #include <sfx2/viewsh.hxx>
24 #include <vcl/wrkwin.hxx>
25 #include <vcl/mnemonic.hxx>
26 #include <tools/shl.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
30 #include "anyrefdg.hxx"
31 #include "sc.hrc"
32 #include "inputhdl.hxx"
33 #include "scmod.hxx"
34 #include "scresid.hxx"
35 #include "inputwin.hxx"
36 #include "tabvwsh.hxx"
37 #include "docsh.hxx"
38 #include "rfindlst.hxx"
39 #include "compiler.hxx"
40 #include "cell.hxx"
41 #include "global.hxx"
42 #include "inputopt.hxx"
43 #include "rangeutl.hxx"
46 ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings)
47 : m_pDlg(_pDlg)
48 , pRefEdit (NULL)
49 , m_pWindow(NULL)
50 , m_pBindings(_pBindings)
51 , pAccel( NULL )
52 , pHiddenMarks(NULL)
53 , nRefTab(0)
54 , mpOldEditParent( NULL )
55 , bHighLightRef( false )
56 , bAccInserted( false )
58 ScInputOptions aInputOption=SC_MOD()->GetInputOptions();
59 bEnableColorRef=aInputOption.GetRangeFinder();
61 // -----------------------------------------------------------------------------
62 ScFormulaReferenceHelper::~ScFormulaReferenceHelper()
64 if (bAccInserted)
65 Application::RemoveAccel( pAccel.get() );
67 // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
69 HideReference();
70 enableInput( true );
72 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
73 if ( pInputHdl )
74 pInputHdl->ResetDelayTimer(); // stop the timer for disabling the input line
76 // -----------------------------------------------------------------------------
77 void ScFormulaReferenceHelper::enableInput( bool bEnable )
79 TypeId aType(TYPE(ScDocShell));
80 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
81 while( pDocShell )
83 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
84 while( pFrame )
86 // enable everything except InPlace, including bean frames
87 if ( !pFrame->GetFrame().IsInPlace() )
89 SfxViewShell* p = pFrame->GetViewShell();
90 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
91 if(pViewSh!=NULL)
93 Window *pWin=pViewSh->GetWindow();
94 if(pWin)
96 Window *pParent=pWin->GetParent();
97 if(pParent)
99 pParent->EnableInput(bEnable,true);
100 if(true)
101 pViewSh->EnableRefInput(bEnable);
106 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
109 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
112 // -----------------------------------------------------------------------------
113 void ScFormulaReferenceHelper::ShowSimpleReference( const XubString& rStr )
115 if( bEnableColorRef )
117 bHighLightRef=true;
118 ScViewData* pViewData=ScDocShell::GetViewData();
119 if ( pViewData )
121 ScDocument* pDoc=pViewData->GetDocument();
122 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
124 ScRangeList aRangeList;
126 pTabViewShell->DoneRefMode( false );
127 pTabViewShell->ClearHighlightRanges();
129 if( ParseWithNames( aRangeList, rStr, pDoc ) )
131 for ( size_t i = 0, nRanges = aRangeList.size(); i < nRanges; ++i )
133 ScRange* pRangeEntry = aRangeList[ i ];
134 ColorData aColName = ScRangeFindList::GetColorName( i );
135 pTabViewShell->AddHighlightRange( *pRangeEntry, aColName );
141 // -----------------------------------------------------------------------------
142 bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
144 bool bError = false;
145 rRanges.RemoveAll();
147 ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
148 ScRangeUtil aRangeUtil;
149 xub_StrLen nTokenCnt = comphelper::string::getTokenCount(rStr, ';');
150 for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
152 ScRange aRange;
153 String aRangeStr( rStr.GetToken( nToken ) );
155 sal_uInt16 nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails );
156 if ( nFlags & SCA_VALID )
158 if ( (nFlags & SCA_TAB_3D) == 0 )
159 aRange.aStart.SetTab( nRefTab );
160 if ( (nFlags & SCA_TAB2_3D) == 0 )
161 aRange.aEnd.SetTab( aRange.aStart.Tab() );
162 rRanges.Append( aRange );
164 else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) )
165 rRanges.Append( aRange );
166 else
167 bError = true;
170 return !bError;
172 // -----------------------------------------------------------------------------
173 void ScFormulaReferenceHelper::ShowFormulaReference( const XubString& rStr )
175 if( bEnableColorRef)
177 bHighLightRef=true;
178 ScViewData* pViewData=ScDocShell::GetViewData();
179 if ( pViewData && pRefComp.get() )
181 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
182 SCCOL nCol = pViewData->GetCurX();
183 SCROW nRow = pViewData->GetCurY();
184 SCTAB nTab = pViewData->GetTabNo();
185 ScAddress aPos( nCol, nRow, nTab );
187 ScTokenArray* pScTokA=pRefComp->CompileString(rStr);
188 //pRefComp->CompileTokenArray();
190 if(pTabViewShell!=NULL && pScTokA!=NULL)
192 pTabViewShell->DoneRefMode( false );
193 pTabViewShell->ClearHighlightRanges();
195 pScTokA->Reset();
196 const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
198 sal_uInt16 nIndex=0;
200 while(pToken!=NULL)
202 bool bDoubleRef=(pToken->GetType()==formula::svDoubleRef);
205 if(pToken->GetType()==formula::svSingleRef || bDoubleRef)
207 ScRange aRange;
208 if(bDoubleRef)
210 ScComplexRefData aRef( pToken->GetDoubleRef() );
211 aRef.CalcAbsIfRel( aPos );
212 aRange.aStart.Set( aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab );
213 aRange.aEnd.Set( aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab );
215 else
217 ScSingleRefData aRef( pToken->GetSingleRef() );
218 aRef.CalcAbsIfRel( aPos );
219 aRange.aStart.Set( aRef.nCol, aRef.nRow, aRef.nTab );
220 aRange.aEnd = aRange.aStart;
222 ColorData aColName=ScRangeFindList::GetColorName(nIndex++);
223 pTabViewShell->AddHighlightRange(aRange, aColName);
226 pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
229 if(pScTokA!=NULL) delete pScTokA;
233 // -----------------------------------------------------------------------------
234 void ScFormulaReferenceHelper::HideReference( bool bDoneRefMode )
236 ScViewData* pViewData=ScDocShell::GetViewData();
238 if( pViewData && bHighLightRef && bEnableColorRef)
240 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
242 if(pTabViewShell!=NULL)
244 // bDoneRefMode is sal_False when called from before SetReference.
245 // In that case, RefMode was just started and must not be ended now.
247 if ( bDoneRefMode )
248 pTabViewShell->DoneRefMode( false );
249 pTabViewShell->ClearHighlightRanges();
251 bHighLightRef=false;
254 // -----------------------------------------------------------------------------
255 void ScFormulaReferenceHelper::ShowReference( const XubString& rStr )
257 if( bEnableColorRef )
259 if( rStr.Search('(')!=STRING_NOTFOUND ||
260 rStr.Search('+')!=STRING_NOTFOUND ||
261 rStr.Search('*')!=STRING_NOTFOUND ||
262 rStr.Search('-')!=STRING_NOTFOUND ||
263 rStr.Search('/')!=STRING_NOTFOUND ||
264 rStr.Search('&')!=STRING_NOTFOUND ||
265 rStr.Search('<')!=STRING_NOTFOUND ||
266 rStr.Search('>')!=STRING_NOTFOUND ||
267 rStr.Search('=')!=STRING_NOTFOUND ||
268 rStr.Search('^')!=STRING_NOTFOUND)
270 ShowFormulaReference(rStr);
272 else
274 ShowSimpleReference(rStr);
278 // -----------------------------------------------------------------------------
279 void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
281 if( !pRefEdit && pEdit )
283 m_pDlg->RefInputStart( pEdit, pButton );
286 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
287 if( pViewShell )
289 pViewShell->ActiveGrabFocus();
290 if( pRefEdit )
292 const ScViewData* pViewData = pViewShell->GetViewData();
293 ScDocument* pDoc = pViewData->GetDocument();
294 ScRangeList aRangeList;
295 if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) )
297 if ( !aRangeList.empty() )
299 const ScRange* pRange = aRangeList.front();
300 pViewShell->SetTabNo( pRange->aStart.Tab() );
301 pViewShell->MoveCursorAbs( pRange->aStart.Col(),
302 pRange->aStart.Row(), SC_FOLLOW_JUMP, false, false );
303 pViewShell->MoveCursorAbs( pRange->aEnd.Col(),
304 pRange->aEnd.Row(), SC_FOLLOW_JUMP, true, false );
305 m_pDlg->SetReference( *pRange, pDoc );
311 // -----------------------------------------------------------------------------
312 void ScFormulaReferenceHelper::Init()
314 ScViewData* pViewData=ScDocShell::GetViewData(); //! use pScViewShell?
315 if ( pViewData )
317 ScDocument* pDoc = pViewData->GetDocument();
318 SCCOL nCol = pViewData->GetCurX();
319 SCROW nRow = pViewData->GetCurY();
320 SCTAB nTab = pViewData->GetTabNo();
321 ScAddress aCursorPos( nCol, nRow, nTab );
323 String rStrExp;
324 pRefCell.reset( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) );
325 pRefComp.reset( new ScCompiler( pDoc, aCursorPos) );
326 pRefComp->SetGrammar( pDoc->GetGrammar() );
327 pRefComp->SetCompileForFAP(true);
329 nRefTab = nTab;
332 // -----------------------------------------------------------------------------
333 IMPL_LINK( ScFormulaReferenceHelper, AccelSelectHdl, Accelerator *, pSelAccel )
335 if ( !pSelAccel )
336 return 0;
338 switch ( pSelAccel->GetCurKeyCode().GetCode() )
340 case KEY_RETURN:
341 case KEY_ESCAPE:
342 if( pRefEdit )
343 pRefEdit->GrabFocus();
344 m_pDlg->RefInputDone( true );
345 break;
347 return true;
349 //----------------------------------------------------------------------------
350 void ScFormulaReferenceHelper::RefInputDone( bool bForced )
352 if ( CanInputDone( bForced ) )
354 if (bAccInserted) // Accelerator wieder abschalten
356 Application::RemoveAccel( pAccel.get() );
357 bAccInserted = false;
360 // restore the parent of the edit field
361 pRefEdit->SetParent(mpOldEditParent);
363 // Fenstertitel anpassen
364 m_pWindow->SetText(sOldDialogText);
366 // Fenster wieder gross
367 m_pWindow->SetOutputSizePixel(aOldDialogSize);
368 if (aOldMinDialogSize.Height())
370 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_pWindow);
371 pSysWin->SetMinOutputSizePixel(aOldMinDialogSize);
374 // pEditCell an alte Position
375 pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize);
377 // set button position and image
378 if( pRefBtn )
380 pRefBtn->SetParent(m_pWindow);
381 pRefBtn->SetPosPixel( aOldButtonPos );
382 pRefBtn->SetStartImage();
385 // Alle anderen: Show();
386 sal_uInt16 nChildren = m_pWindow->GetChildCount();
387 for ( sal_uInt16 i = 0; i < nChildren; i++ )
388 if (pHiddenMarks[i])
390 m_pWindow->GetChild(i)->GetWindow( WINDOW_CLIENT )->Show();
392 delete [] pHiddenMarks;
394 pRefEdit = NULL;
395 pRefBtn = NULL;
398 // -----------------------------------------------------------------------------
399 void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
401 if (!pRefEdit)
403 pRefEdit = pEdit;
404 pRefBtn = pButton;
406 // Neuen Fenstertitel basteln
407 String sNewDialogText;
408 sOldDialogText = m_pWindow->GetText();
409 sNewDialogText = sOldDialogText;
410 sNewDialogText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
412 mpOldEditParent = pRefEdit->GetParent();
414 // Alte Daten merken
415 aOldDialogSize = m_pWindow->GetOutputSizePixel();
416 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_pWindow);
417 if (pSysWin)
418 aOldMinDialogSize = pSysWin->GetMinOutputSizePixel();
419 aOldEditPos = pRefEdit->GetPosPixel();
420 aOldEditSize = pRefEdit->GetSizePixel();
421 if (pRefBtn)
422 aOldButtonPos = pRefBtn->GetPosPixel();
424 pRefEdit->SetParent(m_pWindow);
425 if(pRefBtn)
426 pRefBtn->SetParent(m_pWindow);
428 // Alle Elemente ausser EditCell und Button verstecken
429 sal_uInt16 nChildren = m_pWindow->GetChildCount();
430 pHiddenMarks = new bool [nChildren];
431 for (sal_uInt16 i = 0; i < nChildren; i++)
433 pHiddenMarks[i] = false;
434 Window* pWin = m_pWindow->GetChild(i);
435 pWin = pWin->GetWindow( WINDOW_CLIENT );
436 if (pWin == (Window*)pRefEdit)
438 sNewDialogText += m_pWindow->GetChild(i-1)->GetWindow( WINDOW_CLIENT )->GetText();
440 else if (pWin == (Window*)pRefBtn)
441 ; // do nothing
442 else if (pWin->IsVisible())
444 pHiddenMarks[i] = true;
445 pWin->Hide();
449 // Edit-Feld verschieben und anpassen
450 Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height());
451 Size aNewEditSize(aNewDlgSize);
452 long nOffset = 0;
453 if (pRefBtn)
455 aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width();
456 aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width());
458 long nHeight = pRefBtn->GetSizePixel().Height();
459 if ( nHeight > aOldEditSize.Height() )
461 aNewDlgSize.Height() = nHeight;
462 nOffset = (nHeight-aOldEditSize.Height()) / 2;
464 aNewEditSize.Width() -= nOffset;
466 pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize);
468 // set button position and image
469 if( pRefBtn )
471 pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) );
472 pRefBtn->SetEndImage();
475 // Fenster verkleinern
476 if (aOldMinDialogSize.Height() && pSysWin)
477 pSysWin->SetMinOutputSizePixel(Size()); //unset min size
478 m_pWindow->SetOutputSizePixel(aNewDlgSize);
480 // Fenstertitel anpassen
481 m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) );
483 if (!pAccel.get())
485 pAccel.reset( new Accelerator );
486 pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) );
487 pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) );
488 pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) );
490 Application::InsertAccel( pAccel.get() );
491 bAccInserted = true;
494 // -----------------------------------------------------------------------------
495 void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
497 if( pEdit )
499 if( pRefEdit == pEdit ) // is this the active ref edit field?
501 pRefEdit->GrabFocus(); // before RefInputDone()
502 m_pDlg->RefInputDone( true ); // finish ref input
504 else
506 m_pDlg->RefInputDone( true ); // another active ref edit?
507 m_pDlg->RefInputStart( pEdit, pButton ); // start ref input
508 // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
509 if( pRefEdit )
510 pRefEdit->GrabFocus();
514 // -----------------------------------------------------------------------------
515 bool ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )
517 SfxApplication* pSfxApp = SFX_APP();
519 SetDispatcherLock( false ); //! here and in dtor ?
521 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
522 if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) )
524 // Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch
525 // per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow),
526 // damit die Buttons auch wieder enabled gezeichnet werden.
527 SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS);
528 if (pChild)
530 ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
531 pWin->Enable();
535 // find parent view frame to close dialog
536 SfxViewFrame* pMyViewFrm = NULL;
537 if ( m_pBindings )
539 SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher();
540 if (pMyDisp)
541 pMyViewFrm = pMyDisp->GetFrame();
543 SC_MOD()->SetRefDialog( nId, false, pMyViewFrm );
545 pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
547 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
548 if ( pScViewShell )
549 pScViewShell->UpdateInputHandler(true);
551 return true;
553 void ScFormulaReferenceHelper::SetDispatcherLock( bool bLock )
555 // lock / unlock only the dispatchers of Calc documents
557 TypeId aType(TYPE(ScDocShell));
558 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
559 while( pDocShell )
561 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
562 while( pFrame )
564 SfxDispatcher* pDisp = pFrame->GetDispatcher();
565 if (pDisp)
566 pDisp->Lock( bLock );
568 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
570 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
573 // if a new view is created while the dialog is open,
574 // that view's dispatcher is locked when trying to create the dialog
575 // for that view (ScTabViewShell::CreateRefDialog)
577 // -----------------------------------------------------------------------------
578 void ScFormulaReferenceHelper::ViewShellChanged()
580 enableInput( false );
582 EnableSpreadsheets();
584 void ScFormulaReferenceHelper::EnableSpreadsheets(bool bFlag, bool bChildren)
586 TypeId aType(TYPE(ScDocShell));
587 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
588 while( pDocShell )
590 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
591 while( pFrame )
593 // enable everything except InPlace, including bean frames
594 if ( !pFrame->GetFrame().IsInPlace() )
596 SfxViewShell* p = pFrame->GetViewShell();
597 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
598 if(pViewSh!=NULL)
600 Window *pWin=pViewSh->GetWindow();
601 if(pWin)
603 Window *pParent=pWin->GetParent();
604 if(pParent)
606 pParent->EnableInput(bFlag,false);
607 if(bChildren)
608 pViewSh->EnableRefInput(bFlag);
613 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
616 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
620 //----------------------------------------------------------------------------
624 static void lcl_InvalidateWindows()
626 TypeId aType(TYPE(ScDocShell));
627 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
628 while( pDocShell )
630 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
631 while( pFrame )
633 // enable everything except InPlace, including bean frames
634 if ( !pFrame->GetFrame().IsInPlace() )
636 SfxViewShell* p = pFrame->GetViewShell();
637 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
638 if(pViewSh!=NULL)
640 Window *pWin=pViewSh->GetWindow();
641 if(pWin)
643 Window *pParent=pWin->GetParent();
644 if(pParent)
645 pParent->Invalidate();
649 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
652 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
655 //----------------------------------------------------------------------------
657 static void lcl_HideAllReferences()
659 TypeId aScType = TYPE(ScTabViewShell);
660 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
661 while ( pSh )
663 ((ScTabViewShell*)pSh)->ClearHighlightRanges();
664 pSh = SfxViewShell::GetNext( *pSh, &aScType );
668 //============================================================================
669 //The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
670 // class ScRefHandler
671 //----------------------------------------------------------------------------
673 ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB, bool bBindRef ):
674 m_rWindow( rWindow ),
675 m_bInRefMode( false ),
676 m_aHelper(this,pB),
677 pMyBindings( pB ),
678 pActiveWin(NULL)
680 m_aHelper.SetWindow(&m_rWindow);
681 if(m_rWindow.GetHelpId().isEmpty()) //Hack, da im SfxModelessDialog die HelpId
682 m_rWindow.SetHelpId(m_rWindow.GetUniqueId()); //fuer einen ModelessDialog entfernt und
683 //in eine UniqueId gewandelt wird, machen
684 //wir das an dieser Stelle rueckgaengig.
685 aTimer.SetTimeout(200);
686 aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl));
688 if( bBindRef ) EnterRefMode();
691 bool ScRefHandler::EnterRefMode()
693 if( m_bInRefMode ) return false;
695 SC_MOD()->InputEnterHandler();
697 ScTabViewShell* pScViewShell = NULL;
699 // title has to be from the view that opened the dialog,
700 // even if it's not the current view
702 SfxObjectShell* pParentDoc = NULL;
703 if ( pMyBindings )
705 SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher();
706 if (pMyDisp)
708 SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
709 if (pMyViewFrm)
711 pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
712 if( pScViewShell )
713 pScViewShell->UpdateInputHandler(sal_True);
714 pParentDoc = pMyViewFrm->GetObjectShell();
718 if ( !pParentDoc && pScViewShell ) // use current only if above fails
719 pParentDoc = pScViewShell->GetObjectShell();
720 if ( pParentDoc )
721 aDocName = pParentDoc->GetTitle();
723 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
725 OSL_ENSURE( pInputHdl, "Missing input handler :-/" );
727 if ( pInputHdl )
728 pInputHdl->NotifyChange( NULL );
730 m_aHelper.enableInput( false );
732 m_aHelper.EnableSpreadsheets();
734 m_aHelper.Init();
736 m_aHelper.SetDispatcherLock( true );
738 return m_bInRefMode = true;
741 //----------------------------------------------------------------------------
743 ScRefHandler::~ScRefHandler()
745 LeaveRefMode();
748 bool ScRefHandler::LeaveRefMode()
750 if( !m_bInRefMode ) return false;
752 lcl_HideAllReferences();
754 if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) )
755 pDlg->SetModalInputMode(false);
756 SetDispatcherLock( false ); //! here and in DoClose ?
758 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
759 if( pScViewShell )
760 pScViewShell->UpdateInputHandler(sal_True);
762 lcl_InvalidateWindows();
764 m_bInRefMode = false;
765 return true;
768 //----------------------------------------------------------------------------
770 void ScRefHandler::SwitchToDocument()
772 ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell();
773 if (pCurrent)
775 SfxObjectShell* pObjSh = pCurrent->GetObjectShell();
776 if ( pObjSh && pObjSh->GetTitle() == aDocName )
778 // right document already visible -> nothing to do
779 return;
783 TypeId aScType = TYPE(ScTabViewShell);
784 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
785 while ( pSh )
787 SfxObjectShell* pObjSh = pSh->GetObjectShell();
788 if ( pObjSh && pObjSh->GetTitle() == aDocName )
790 // switch to first TabViewShell for document
791 ((ScTabViewShell*)pSh)->SetActive();
792 return;
794 pSh = SfxViewShell::GetNext( *pSh, &aScType );
798 //----------------------------------------------------------------------------
800 sal_Bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const // pDocSh may be 0
802 // default: allow only same document (overridden in function dialog)
803 String aCmpName;
804 if ( pDocSh )
805 aCmpName = pDocSh->GetTitle();
807 // if aDocName isn't initialized, allow
808 return ( aDocName.Len() == 0 || aDocName == aCmpName );
811 //----------------------------------------------------------------------------
813 sal_Bool ScRefHandler::IsRefInputMode() const
815 return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen
818 //----------------------------------------------------------------------------
820 sal_Bool ScRefHandler::DoClose( sal_uInt16 nId )
822 m_aHelper.DoClose(nId);
823 return sal_True;
826 void ScRefHandler::SetDispatcherLock( bool bLock )
828 m_aHelper.SetDispatcherLock( bLock );
831 //----------------------------------------------------------------------------
833 void ScRefHandler::ViewShellChanged()
835 m_aHelper.ViewShellChanged();
838 //----------------------------------------------------------------------------
840 void ScRefHandler::AddRefEntry()
842 // wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen
845 //----------------------------------------------------------------------------
847 sal_Bool ScRefHandler::IsTableLocked() const
849 // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
851 return false;
854 //----------------------------------------------------------------------------
856 // RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld
857 // (per Button oder Bewegung)
859 //----------------------------------------------------------------------------
861 void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
863 m_aHelper.RefInputStart( pEdit, pButton );
867 void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
869 m_aHelper.ToggleCollapsed( pEdit, pButton );
872 void ScRefHandler::preNotify(const NotifyEvent& rNEvt, const bool bBindRef)
874 if( bBindRef || m_bInRefMode )
876 sal_uInt16 nSwitch=rNEvt.GetType();
877 if(nSwitch==EVENT_GETFOCUS)
879 pActiveWin=rNEvt.GetWindow();
884 void ScRefHandler::stateChanged(const StateChangedType nStateChange, const bool bBindRef)
886 if( !bBindRef && !m_bInRefMode ) return;
888 if(nStateChange == STATE_CHANGE_VISIBLE)
890 if(m_rWindow.IsVisible())
892 m_aHelper.enableInput( false );
893 m_aHelper.EnableSpreadsheets();
894 m_aHelper.SetDispatcherLock( sal_True );
895 aTimer.Start();
897 else
899 m_aHelper.enableInput( sal_True );
900 m_aHelper.SetDispatcherLock( false ); /*//! here and in DoClose ?*/
905 IMPL_LINK_NOARG(ScRefHandler, UpdateFocusHdl)
907 if (pActiveWin)
909 pActiveWin->GrabFocus();
911 return 0;
913 // -----------------------------------------------------------------------------
914 bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
916 return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
918 // -----------------------------------------------------------------------------
919 void ScRefHandler::HideReference( sal_Bool bDoneRefMode )
921 m_aHelper.HideReference( bDoneRefMode );
923 // -----------------------------------------------------------------------------
924 void ScRefHandler::ShowReference( const XubString& rStr )
926 m_aHelper.ShowReference( rStr );
928 // -----------------------------------------------------------------------------
929 void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
931 m_aHelper.ReleaseFocus( pEdit,pButton );
933 //----------------------------------------------------------------------------
934 void ScRefHandler::RefInputDone( sal_Bool bForced )
936 m_aHelper.RefInputDone( bForced );
939 //-------------------------------------------------------------------------------
941 ScRefHdlModalImpl::ScRefHdlModalImpl( Window* pParent, ResId& rResId ):
942 ModalDialog( pParent, rResId ),
943 ScRefHandler(dynamic_cast<Window&>(*this), NULL, true) {}
945 long ScRefHdlModalImpl::PreNotify( NotifyEvent& rNEvt )
947 ScRefHandler::preNotify( rNEvt, true );
948 return ModalDialog::PreNotify( rNEvt );
951 void ScRefHdlModalImpl::StateChanged( StateChangedType nStateChange )
953 ModalDialog::StateChanged( nStateChange );
954 ScRefHandler::stateChanged( nStateChange, true );
957 ScAnyRefModalDlg::ScAnyRefModalDlg( Window* pParent, ResId aResId ):
958 ScRefHdlModalImpl( pParent, aResId ) {}
960 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */