bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / miscdlgs / anyrefdg.cxx
blobab3b534bf93cda15e8b58fb395d2aa21b4e48608
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 "formulacell.hxx"
41 #include "global.hxx"
42 #include "inputopt.hxx"
43 #include "rangeutl.hxx"
44 #include "tokenarray.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 , nRefTab(0)
53 , mnOldEditWidthReq( -1 )
54 , mpOldEditParent( NULL )
55 , mbOldDlgLayoutEnabled( false )
56 , mbOldEditParentLayoutEnabled( false )
57 , bHighLightRef( false )
58 , bAccInserted( false )
60 ScInputOptions aInputOption=SC_MOD()->GetInputOptions();
61 bEnableColorRef=aInputOption.GetRangeFinder();
63 // -----------------------------------------------------------------------------
64 ScFormulaReferenceHelper::~ScFormulaReferenceHelper()
66 if (bAccInserted)
67 Application::RemoveAccel( pAccel.get() );
69 // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
71 HideReference();
72 enableInput( true );
74 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
75 if ( pInputHdl )
76 pInputHdl->ResetDelayTimer(); // stop the timer for disabling the input line
78 // -----------------------------------------------------------------------------
79 void ScFormulaReferenceHelper::enableInput( bool bEnable )
81 TypeId aType(TYPE(ScDocShell));
82 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
83 while( pDocShell )
85 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
86 while( pFrame )
88 // enable everything except InPlace, including bean frames
89 if ( !pFrame->GetFrame().IsInPlace() )
91 SfxViewShell* p = pFrame->GetViewShell();
92 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
93 if(pViewSh!=NULL)
95 Window *pWin=pViewSh->GetWindow();
96 if(pWin)
98 Window *pParent=pWin->GetParent();
99 if(pParent)
101 pParent->EnableInput(bEnable,true);
102 if(true)
103 pViewSh->EnableRefInput(bEnable);
108 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
111 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
114 // -----------------------------------------------------------------------------
115 void ScFormulaReferenceHelper::ShowSimpleReference( const XubString& rStr )
117 if( bEnableColorRef )
119 bHighLightRef=true;
120 ScViewData* pViewData=ScDocShell::GetViewData();
121 if ( pViewData )
123 ScDocument* pDoc=pViewData->GetDocument();
124 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
126 ScRangeList aRangeList;
128 pTabViewShell->DoneRefMode( false );
129 pTabViewShell->ClearHighlightRanges();
131 if( ParseWithNames( aRangeList, rStr, pDoc ) )
133 for ( size_t i = 0, nRanges = aRangeList.size(); i < nRanges; ++i )
135 ScRange* pRangeEntry = aRangeList[ i ];
136 ColorData aColName = ScRangeFindList::GetColorName( i );
137 pTabViewShell->AddHighlightRange( *pRangeEntry, aColName );
143 // -----------------------------------------------------------------------------
144 bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
146 bool bError = false;
147 rRanges.RemoveAll();
149 ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
150 ScRangeUtil aRangeUtil;
151 xub_StrLen nTokenCnt = comphelper::string::getTokenCount(rStr, ';');
152 for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
154 ScRange aRange;
155 String aRangeStr( rStr.GetToken( nToken ) );
157 sal_uInt16 nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails );
158 if ( nFlags & SCA_VALID )
160 if ( (nFlags & SCA_TAB_3D) == 0 )
161 aRange.aStart.SetTab( nRefTab );
162 if ( (nFlags & SCA_TAB2_3D) == 0 )
163 aRange.aEnd.SetTab( aRange.aStart.Tab() );
164 rRanges.Append( aRange );
166 else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) )
167 rRanges.Append( aRange );
168 else
169 bError = true;
172 return !bError;
174 // -----------------------------------------------------------------------------
175 void ScFormulaReferenceHelper::ShowFormulaReference( const XubString& rStr )
177 if( bEnableColorRef)
179 bHighLightRef=true;
180 ScViewData* pViewData=ScDocShell::GetViewData();
181 if ( pViewData && pRefComp.get() )
183 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
184 SCCOL nCol = pViewData->GetCurX();
185 SCROW nRow = pViewData->GetCurY();
186 SCTAB nTab = pViewData->GetTabNo();
187 ScAddress aPos( nCol, nRow, nTab );
189 ScTokenArray* pScTokA=pRefComp->CompileString(rStr);
190 //pRefComp->CompileTokenArray();
192 if(pTabViewShell!=NULL && pScTokA!=NULL)
194 pTabViewShell->DoneRefMode( false );
195 pTabViewShell->ClearHighlightRanges();
197 pScTokA->Reset();
198 const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
200 sal_uInt16 nIndex=0;
202 while(pToken!=NULL)
204 bool bDoubleRef=(pToken->GetType()==formula::svDoubleRef);
207 if(pToken->GetType()==formula::svSingleRef || bDoubleRef)
209 ScRange aRange;
210 if(bDoubleRef)
212 ScComplexRefData aRef( pToken->GetDoubleRef() );
213 aRef.CalcAbsIfRel( aPos );
214 aRange.aStart.Set( aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab );
215 aRange.aEnd.Set( aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab );
217 else
219 ScSingleRefData aRef( pToken->GetSingleRef() );
220 aRef.CalcAbsIfRel( aPos );
221 aRange.aStart.Set( aRef.nCol, aRef.nRow, aRef.nTab );
222 aRange.aEnd = aRange.aStart;
224 ColorData aColName=ScRangeFindList::GetColorName(nIndex++);
225 pTabViewShell->AddHighlightRange(aRange, aColName);
228 pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
231 if(pScTokA!=NULL) delete pScTokA;
235 // -----------------------------------------------------------------------------
236 void ScFormulaReferenceHelper::HideReference( bool bDoneRefMode )
238 ScViewData* pViewData=ScDocShell::GetViewData();
240 if( pViewData && bHighLightRef && bEnableColorRef)
242 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
244 if(pTabViewShell!=NULL)
246 // bDoneRefMode is sal_False when called from before SetReference.
247 // In that case, RefMode was just started and must not be ended now.
249 if ( bDoneRefMode )
250 pTabViewShell->DoneRefMode( false );
251 pTabViewShell->ClearHighlightRanges();
253 bHighLightRef=false;
256 // -----------------------------------------------------------------------------
257 void ScFormulaReferenceHelper::ShowReference( const XubString& rStr )
259 if( bEnableColorRef )
261 if( 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 ||
269 rStr.Search('=')!=STRING_NOTFOUND ||
270 rStr.Search('^')!=STRING_NOTFOUND)
272 ShowFormulaReference(rStr);
274 else
276 ShowSimpleReference(rStr);
280 // -----------------------------------------------------------------------------
281 void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
283 if( !pRefEdit && pEdit )
285 m_pDlg->RefInputStart( pEdit, pButton );
288 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
289 if( pViewShell )
291 pViewShell->ActiveGrabFocus();
292 if( pRefEdit )
294 const ScViewData* pViewData = pViewShell->GetViewData();
295 ScDocument* pDoc = pViewData->GetDocument();
296 ScRangeList aRangeList;
297 if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) )
299 if ( !aRangeList.empty() )
301 const ScRange* pRange = aRangeList.front();
302 pViewShell->SetTabNo( pRange->aStart.Tab() );
303 pViewShell->MoveCursorAbs( pRange->aStart.Col(),
304 pRange->aStart.Row(), SC_FOLLOW_JUMP, false, false );
305 pViewShell->MoveCursorAbs( pRange->aEnd.Col(),
306 pRange->aEnd.Row(), SC_FOLLOW_JUMP, true, false );
307 m_pDlg->SetReference( *pRange, pDoc );
313 // -----------------------------------------------------------------------------
314 void ScFormulaReferenceHelper::Init()
316 ScViewData* pViewData=ScDocShell::GetViewData(); //! use pScViewShell?
317 if ( pViewData )
319 ScDocument* pDoc = pViewData->GetDocument();
320 SCCOL nCol = pViewData->GetCurX();
321 SCROW nRow = pViewData->GetCurY();
322 SCTAB nTab = pViewData->GetTabNo();
323 ScAddress aCursorPos( nCol, nRow, nTab );
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;
350 typedef std::vector<Window*> winvec;
352 void ScFormulaReferenceHelper::RefInputDone( bool bForced )
354 if ( CanInputDone( bForced ) )
356 if (bAccInserted) // Accelerator wieder abschalten
358 Application::RemoveAccel( pAccel.get() );
359 bAccInserted = false;
362 //get rid of all this junk when we can
363 if (!mbOldDlgLayoutEnabled)
365 m_pWindow->SetOutputSizePixel(aOldDialogSize);
367 // restore the parent of the edit field
368 pRefEdit->SetParent(mpOldEditParent);
370 // Fenster wieder gross
371 m_pWindow->SetOutputSizePixel(aOldDialogSize);
373 // set button parent
374 if( pRefBtn )
376 pRefBtn->SetParent(m_pWindow);
380 if (!mbOldEditParentLayoutEnabled)
382 // pEditCell an alte Position
383 pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize);
385 // set button position
386 if( pRefBtn )
388 pRefBtn->SetPosPixel( aOldButtonPos );
392 // Fenstertitel anpassen
393 m_pWindow->SetText(sOldDialogText);
395 // set button image
396 if( pRefBtn )
397 pRefBtn->SetStartImage();
399 // Alle anderen: Show();
400 for (winvec::iterator aI = m_aHiddenWidgets.begin(); aI != m_aHiddenWidgets.end(); ++aI)
402 Window *pWindow = *aI;
403 pWindow->Show();
405 m_aHiddenWidgets.clear();
407 if (mbOldDlgLayoutEnabled)
409 pRefEdit->set_width_request(mnOldEditWidthReq);
410 Dialog* pResizeDialog = pRefEdit->GetParentDialog();
411 pResizeDialog->set_border_width(m_nOldBorderWidth);
412 if (Window *pActionArea = pResizeDialog->get_action_area())
413 pActionArea->Show();
414 pResizeDialog->setOptimalLayoutSize();
417 pRefEdit = NULL;
418 pRefBtn = NULL;
422 typedef std::set<Window*> winset;
424 namespace
426 void hideUnless(Window *pTop, const winset& rVisibleWidgets,
427 winvec &rWasVisibleWidgets)
429 for (Window* pChild = pTop->GetWindow(WINDOW_FIRSTCHILD); pChild;
430 pChild = pChild->GetWindow(WINDOW_NEXT))
432 if (!pChild->IsVisible())
433 continue;
434 if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
436 rWasVisibleWidgets.push_back(pChild);
437 pChild->Hide();
439 else if (isContainerWindow(pChild))
441 hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
447 // -----------------------------------------------------------------------------
448 void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
450 if (!pRefEdit)
452 pRefEdit = pEdit;
453 pRefBtn = pButton;
455 mbOldDlgLayoutEnabled = isLayoutEnabled(m_pWindow);
456 aOldEditSize = pRefEdit->GetSizePixel();
457 mnOldEditWidthReq = pRefEdit->get_width_request();
458 mpOldEditParent = pRefEdit->GetParent();
459 mbOldEditParentLayoutEnabled = isContainerWindow(mpOldEditParent);
461 //get rid of all the !mbOldDlgLayoutEnabled and
462 //mbOldEditParentLayoutEnabled junk when we can after the last user of
463 //this is widget-layout-ified
464 if (!mbOldEditParentLayoutEnabled)
466 // Alte Daten merken
467 aOldDialogSize = m_pWindow->GetOutputSizePixel();
468 aOldEditPos = pRefEdit->GetPosPixel();
469 if (pRefBtn)
470 aOldButtonPos = pRefBtn->GetPosPixel();
473 if (!mbOldDlgLayoutEnabled)
475 pRefEdit->SetParent(m_pWindow);
476 if(pRefBtn)
477 pRefBtn->SetParent(m_pWindow);
480 // Fenstertitel anpassen
481 sOldDialogText = m_pWindow->GetText();
482 if (Window *pLabel = pRefEdit->GetLabelWidgetForShrinkMode())
484 OUString sLabel = pLabel->GetText();
485 if (!sLabel.isEmpty())
487 String sNewDialogText = sOldDialogText;
488 sNewDialogText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
489 sNewDialogText += sLabel;
490 m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) );
494 Dialog* pResizeDialog = NULL;
496 if (!mbOldDlgLayoutEnabled)
498 for (Window* pChild = m_pWindow->GetWindow(WINDOW_FIRSTCHILD); pChild;
499 pChild = pChild->GetWindow(WINDOW_NEXT))
501 Window *pWin = pChild->GetWindow(WINDOW_CLIENT);
502 if (pWin == (Window*)pRefEdit || pWin == (Window*)pRefBtn)
503 continue; // do nothing
504 else if (pWin->IsVisible())
506 m_aHiddenWidgets.push_back(pChild);
507 pChild->Hide();
511 else
513 //We want just pRefBtn and pRefEdit to be shown
514 //mark widgets we want to be visible, starting with pRefEdit
515 //and all its direct parents.
516 winset m_aVisibleWidgets;
517 pResizeDialog = pRefEdit->GetParentDialog();
518 Window *pContentArea = pResizeDialog->get_content_area();
519 for (Window *pCandidate = pRefEdit;
520 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
521 pCandidate = pCandidate->GetWindow(WINDOW_REALPARENT))
523 m_aVisibleWidgets.insert(pCandidate);
525 //same again with pRefBtn, except stop if there's a
526 //shared parent in the existing widgets
527 for (Window *pCandidate = pRefBtn;
528 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
529 pCandidate = pCandidate->GetWindow(WINDOW_REALPARENT))
531 if (m_aVisibleWidgets.insert(pCandidate).second)
532 break;
535 //hide everything except the m_aVisibleWidgets
536 hideUnless(pContentArea, m_aVisibleWidgets, m_aHiddenWidgets);
539 if (!mbOldDlgLayoutEnabled)
541 // Edit-Feld verschieben und anpassen
542 Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height());
543 Size aNewEditSize(aNewDlgSize);
544 long nOffset = 0;
545 if (pRefBtn)
547 aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width();
548 aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width());
550 long nHeight = pRefBtn->GetSizePixel().Height();
551 if ( nHeight > aOldEditSize.Height() )
553 aNewDlgSize.Height() = nHeight;
554 nOffset = (nHeight-aOldEditSize.Height()) / 2;
556 aNewEditSize.Width() -= nOffset;
558 pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize);
560 // set button position
561 if( pRefBtn )
562 pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) );
564 // Fenster verkleinern
565 m_pWindow->SetOutputSizePixel(aNewDlgSize);
568 // set button image
569 if( pRefBtn )
570 pRefBtn->SetEndImage();
572 if (!pAccel.get())
574 pAccel.reset( new Accelerator );
575 pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) );
576 pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) );
577 pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) );
579 Application::InsertAccel( pAccel.get() );
580 bAccInserted = true;
582 if (mbOldDlgLayoutEnabled)
584 pRefEdit->set_width_request(aOldEditSize.Width());
585 m_nOldBorderWidth = pResizeDialog->get_border_width();
586 pResizeDialog->set_border_width(0);
587 if (Window *pActionArea = pResizeDialog->get_action_area())
588 pActionArea->Hide();
589 pResizeDialog->setOptimalLayoutSize();
593 // -----------------------------------------------------------------------------
594 void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
596 if( pEdit )
598 if( pRefEdit == pEdit ) // is this the active ref edit field?
600 pRefEdit->GrabFocus(); // before RefInputDone()
601 m_pDlg->RefInputDone( true ); // finish ref input
603 else
605 m_pDlg->RefInputDone( true ); // another active ref edit?
606 m_pDlg->RefInputStart( pEdit, pButton ); // start ref input
607 // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
608 if( pRefEdit )
609 pRefEdit->GrabFocus();
613 // -----------------------------------------------------------------------------
614 bool ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )
616 SfxApplication* pSfxApp = SFX_APP();
618 SetDispatcherLock( false ); //! here and in dtor ?
620 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
621 if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) )
623 // Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch
624 // per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow),
625 // damit die Buttons auch wieder enabled gezeichnet werden.
626 SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS);
627 if (pChild)
629 ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
630 pWin->Enable();
634 // find parent view frame to close dialog
635 SfxViewFrame* pMyViewFrm = NULL;
636 if ( m_pBindings )
638 SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher();
639 if (pMyDisp)
640 pMyViewFrm = pMyDisp->GetFrame();
642 SC_MOD()->SetRefDialog( nId, false, pMyViewFrm );
644 pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
646 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
647 if ( pScViewShell )
648 pScViewShell->UpdateInputHandler(true);
650 return true;
652 void ScFormulaReferenceHelper::SetDispatcherLock( bool bLock )
654 // lock / unlock only the dispatchers of Calc documents
656 TypeId aType(TYPE(ScDocShell));
657 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
658 while( pDocShell )
660 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
661 while( pFrame )
663 SfxDispatcher* pDisp = pFrame->GetDispatcher();
664 if (pDisp)
665 pDisp->Lock( bLock );
667 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
669 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
672 // if a new view is created while the dialog is open,
673 // that view's dispatcher is locked when trying to create the dialog
674 // for that view (ScTabViewShell::CreateRefDialog)
676 // -----------------------------------------------------------------------------
677 void ScFormulaReferenceHelper::ViewShellChanged()
679 enableInput( false );
681 EnableSpreadsheets();
683 void ScFormulaReferenceHelper::EnableSpreadsheets(bool bFlag, bool bChildren)
685 TypeId aType(TYPE(ScDocShell));
686 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
687 while( pDocShell )
689 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
690 while( pFrame )
692 // enable everything except InPlace, including bean frames
693 if ( !pFrame->GetFrame().IsInPlace() )
695 SfxViewShell* p = pFrame->GetViewShell();
696 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
697 if(pViewSh!=NULL)
699 Window *pWin=pViewSh->GetWindow();
700 if(pWin)
702 Window *pParent=pWin->GetParent();
703 if(pParent)
705 pParent->EnableInput(bFlag,false);
706 if(bChildren)
707 pViewSh->EnableRefInput(bFlag);
712 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
715 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
719 //----------------------------------------------------------------------------
723 static void lcl_InvalidateWindows()
725 TypeId aType(TYPE(ScDocShell));
726 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
727 while( pDocShell )
729 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
730 while( pFrame )
732 // enable everything except InPlace, including bean frames
733 if ( !pFrame->GetFrame().IsInPlace() )
735 SfxViewShell* p = pFrame->GetViewShell();
736 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
737 if(pViewSh!=NULL)
739 Window *pWin=pViewSh->GetWindow();
740 if(pWin)
742 Window *pParent=pWin->GetParent();
743 if(pParent)
744 pParent->Invalidate();
748 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
751 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
754 //----------------------------------------------------------------------------
756 static void lcl_HideAllReferences()
758 TypeId aScType = TYPE(ScTabViewShell);
759 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
760 while ( pSh )
762 ((ScTabViewShell*)pSh)->ClearHighlightRanges();
763 pSh = SfxViewShell::GetNext( *pSh, &aScType );
767 //============================================================================
768 //The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
769 // class ScRefHandler
770 //----------------------------------------------------------------------------
772 ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB, bool bBindRef ):
773 m_rWindow( rWindow ),
774 m_bInRefMode( false ),
775 m_aHelper(this,pB),
776 pMyBindings( pB ),
777 pActiveWin(NULL)
779 m_aHelper.SetWindow(&m_rWindow);
780 reverseUniqueHelpIdHack(m_rWindow);
781 aTimer.SetTimeout(200);
782 aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl));
784 if( bBindRef ) EnterRefMode();
787 bool ScRefHandler::EnterRefMode()
789 if( m_bInRefMode ) return false;
791 SC_MOD()->InputEnterHandler();
793 ScTabViewShell* pScViewShell = NULL;
795 // title has to be from the view that opened the dialog,
796 // even if it's not the current view
798 SfxObjectShell* pParentDoc = NULL;
799 if ( pMyBindings )
801 SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher();
802 if (pMyDisp)
804 SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
805 if (pMyViewFrm)
807 pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
808 if( pScViewShell )
809 pScViewShell->UpdateInputHandler(sal_True);
810 pParentDoc = pMyViewFrm->GetObjectShell();
814 if ( !pParentDoc && pScViewShell ) // use current only if above fails
815 pParentDoc = pScViewShell->GetObjectShell();
816 if ( pParentDoc )
817 aDocName = pParentDoc->GetTitle();
819 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
821 OSL_ENSURE( pInputHdl, "Missing input handler :-/" );
823 if ( pInputHdl )
824 pInputHdl->NotifyChange( NULL );
826 m_aHelper.enableInput( false );
828 m_aHelper.EnableSpreadsheets();
830 m_aHelper.Init();
832 m_aHelper.SetDispatcherLock( true );
834 return m_bInRefMode = true;
837 //----------------------------------------------------------------------------
839 ScRefHandler::~ScRefHandler()
841 LeaveRefMode();
844 bool ScRefHandler::LeaveRefMode()
846 if( !m_bInRefMode ) return false;
848 lcl_HideAllReferences();
850 if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) )
851 pDlg->SetModalInputMode(false);
852 SetDispatcherLock( false ); //! here and in DoClose ?
854 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
855 if( pScViewShell )
856 pScViewShell->UpdateInputHandler(sal_True);
858 lcl_InvalidateWindows();
860 m_bInRefMode = false;
861 return true;
864 //----------------------------------------------------------------------------
866 void ScRefHandler::SwitchToDocument()
868 ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell();
869 if (pCurrent)
871 SfxObjectShell* pObjSh = pCurrent->GetObjectShell();
872 if ( pObjSh && pObjSh->GetTitle() == aDocName )
874 // right document already visible -> nothing to do
875 return;
879 TypeId aScType = TYPE(ScTabViewShell);
880 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
881 while ( pSh )
883 SfxObjectShell* pObjSh = pSh->GetObjectShell();
884 if ( pObjSh && pObjSh->GetTitle() == aDocName )
886 // switch to first TabViewShell for document
887 ((ScTabViewShell*)pSh)->SetActive();
888 return;
890 pSh = SfxViewShell::GetNext( *pSh, &aScType );
894 //----------------------------------------------------------------------------
896 sal_Bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const // pDocSh may be 0
898 // default: allow only same document (overridden in function dialog)
899 String aCmpName;
900 if ( pDocSh )
901 aCmpName = pDocSh->GetTitle();
903 // if aDocName isn't initialized, allow
904 return ( aDocName.Len() == 0 || aDocName == aCmpName );
907 //----------------------------------------------------------------------------
909 sal_Bool ScRefHandler::IsRefInputMode() const
911 return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen
914 //----------------------------------------------------------------------------
916 sal_Bool ScRefHandler::DoClose( sal_uInt16 nId )
918 m_aHelper.DoClose(nId);
919 return sal_True;
922 void ScRefHandler::SetDispatcherLock( bool bLock )
924 m_aHelper.SetDispatcherLock( bLock );
927 //----------------------------------------------------------------------------
929 void ScRefHandler::ViewShellChanged()
931 m_aHelper.ViewShellChanged();
934 //----------------------------------------------------------------------------
936 void ScRefHandler::AddRefEntry()
938 // wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen
941 //----------------------------------------------------------------------------
943 sal_Bool ScRefHandler::IsTableLocked() const
945 // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
947 return false;
950 //----------------------------------------------------------------------------
952 // RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld
953 // (per Button oder Bewegung)
955 //----------------------------------------------------------------------------
957 void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
959 m_aHelper.RefInputStart( pEdit, pButton );
963 void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
965 m_aHelper.ToggleCollapsed( pEdit, pButton );
968 void ScRefHandler::preNotify(const NotifyEvent& rNEvt, const bool bBindRef)
970 if( bBindRef || m_bInRefMode )
972 sal_uInt16 nSwitch=rNEvt.GetType();
973 if(nSwitch==EVENT_GETFOCUS)
975 pActiveWin=rNEvt.GetWindow();
980 void ScRefHandler::stateChanged(const StateChangedType nStateChange, const bool bBindRef)
982 if( !bBindRef && !m_bInRefMode ) return;
984 if(nStateChange == STATE_CHANGE_VISIBLE)
986 if(m_rWindow.IsVisible())
988 m_aHelper.enableInput( false );
989 m_aHelper.EnableSpreadsheets();
990 m_aHelper.SetDispatcherLock( sal_True );
991 aTimer.Start();
993 else
995 m_aHelper.enableInput( sal_True );
996 m_aHelper.SetDispatcherLock( false ); /*//! here and in DoClose ?*/
1001 IMPL_LINK_NOARG(ScRefHandler, UpdateFocusHdl)
1003 if (pActiveWin)
1005 pActiveWin->GrabFocus();
1007 return 0;
1009 // -----------------------------------------------------------------------------
1010 bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
1012 return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
1014 // -----------------------------------------------------------------------------
1015 void ScRefHandler::HideReference( sal_Bool bDoneRefMode )
1017 m_aHelper.HideReference( bDoneRefMode );
1019 // -----------------------------------------------------------------------------
1020 void ScRefHandler::ShowReference( const XubString& rStr )
1022 m_aHelper.ShowReference( rStr );
1024 // -----------------------------------------------------------------------------
1025 void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
1027 m_aHelper.ReleaseFocus( pEdit,pButton );
1029 //----------------------------------------------------------------------------
1030 void ScRefHandler::RefInputDone( sal_Bool bForced )
1032 m_aHelper.RefInputDone( bForced );
1035 //-------------------------------------------------------------------------------
1037 ScRefHdlModalImpl::ScRefHdlModalImpl( Window* pParent, ResId& rResId ):
1038 ModalDialog( pParent, rResId ),
1039 ScRefHandler(dynamic_cast<Window&>(*this), NULL, true) {}
1041 long ScRefHdlModalImpl::PreNotify( NotifyEvent& rNEvt )
1043 ScRefHandler::preNotify( rNEvt, true );
1044 return ModalDialog::PreNotify( rNEvt );
1047 void ScRefHdlModalImpl::StateChanged( StateChangedType nStateChange )
1049 ModalDialog::StateChanged( nStateChange );
1050 ScRefHandler::stateChanged( nStateChange, true );
1053 ScAnyRefModalDlg::ScAnyRefModalDlg( Window* pParent, ResId aResId ):
1054 ScRefHdlModalImpl( pParent, aResId ) {}
1056 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */