Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / miscdlgs / anyrefdg.cxx
blob17560892932e22b317422e02c1ed613ed983c70d
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 #include <boost/scoped_ptr.hpp>
48 ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings)
49 : m_pDlg(_pDlg)
50 , pRefEdit (NULL)
51 , m_pWindow(NULL)
52 , m_pBindings(_pBindings)
53 , pAccel( NULL )
54 , nRefTab(0)
55 , mnOldEditWidthReq( -1 )
56 , mpOldEditParent( NULL )
57 , mbOldDlgLayoutEnabled( false )
58 , mbOldEditParentLayoutEnabled( false )
59 , bHighlightRef( false )
60 , bAccInserted( false )
62 ScInputOptions aInputOption=SC_MOD()->GetInputOptions();
63 bEnableColorRef=aInputOption.GetRangeFinder();
65 // -----------------------------------------------------------------------------
66 ScFormulaReferenceHelper::~ScFormulaReferenceHelper()
68 if (bAccInserted)
69 Application::RemoveAccel( pAccel.get() );
71 // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
73 HideReference();
74 enableInput( true );
76 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
77 if ( pInputHdl )
78 pInputHdl->ResetDelayTimer(); // stop the timer for disabling the input line
80 // -----------------------------------------------------------------------------
81 void ScFormulaReferenceHelper::enableInput( bool bEnable )
83 TypeId aType(TYPE(ScDocShell));
84 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
85 while( pDocShell )
87 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
88 while( pFrame )
90 // enable everything except InPlace, including bean frames
91 if ( !pFrame->GetFrame().IsInPlace() )
93 SfxViewShell* p = pFrame->GetViewShell();
94 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
95 if(pViewSh!=NULL)
97 Window *pWin=pViewSh->GetWindow();
98 if(pWin)
100 Window *pParent=pWin->GetParent();
101 if(pParent)
103 pParent->EnableInput(bEnable,true);
104 if(true)
105 pViewSh->EnableRefInput(bEnable);
110 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
113 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
116 // -----------------------------------------------------------------------------
117 void ScFormulaReferenceHelper::ShowSimpleReference(const OUString& rStr)
119 if( bEnableColorRef )
121 bHighlightRef=true;
122 ScViewData* pViewData=ScDocShell::GetViewData();
123 if ( pViewData )
125 ScDocument* pDoc=pViewData->GetDocument();
126 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
128 ScRangeList aRangeList;
130 pTabViewShell->DoneRefMode( false );
131 pTabViewShell->ClearHighlightRanges();
133 if( ParseWithNames( aRangeList, rStr, pDoc ) )
135 for ( size_t i = 0, nRanges = aRangeList.size(); i < nRanges; ++i )
137 ScRange* pRangeEntry = aRangeList[ i ];
138 ColorData aColName = ScRangeFindList::GetColorName( i );
139 pTabViewShell->AddHighlightRange( *pRangeEntry, aColName );
145 // -----------------------------------------------------------------------------
146 bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const OUString& rStr, ScDocument* pDoc )
148 bool bError = false;
149 rRanges.RemoveAll();
151 ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
152 ScRangeUtil aRangeUtil;
153 sal_Int32 nTokenCnt = comphelper::string::getTokenCount(rStr, ';');
154 for( sal_Int32 nToken = 0; nToken < nTokenCnt; ++nToken )
156 ScRange aRange;
157 OUString aRangeStr( rStr.getToken( nToken, ';' ) );
159 sal_uInt16 nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails );
160 if ( nFlags & SCA_VALID )
162 if ( (nFlags & SCA_TAB_3D) == 0 )
163 aRange.aStart.SetTab( nRefTab );
164 if ( (nFlags & SCA_TAB2_3D) == 0 )
165 aRange.aEnd.SetTab( aRange.aStart.Tab() );
166 rRanges.Append( aRange );
168 else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) )
169 rRanges.Append( aRange );
170 else
171 bError = true;
174 return !bError;
176 // -----------------------------------------------------------------------------
177 void ScFormulaReferenceHelper::ShowFormulaReference(const OUString& rStr)
179 if( bEnableColorRef)
181 bHighlightRef=true;
182 ScViewData* pViewData=ScDocShell::GetViewData();
183 if ( pViewData && pRefComp.get() )
185 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
186 SCCOL nCol = pViewData->GetCurX();
187 SCROW nRow = pViewData->GetCurY();
188 SCTAB nTab = pViewData->GetTabNo();
189 ScAddress aPos( nCol, nRow, nTab );
191 boost::scoped_ptr<ScTokenArray> pScTokA(pRefComp->CompileString(rStr));
193 if (pTabViewShell && pScTokA)
195 pTabViewShell->DoneRefMode( false );
196 pTabViewShell->ClearHighlightRanges();
198 pScTokA->Reset();
199 const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
201 sal_uInt16 nIndex=0;
203 while(pToken!=NULL)
205 bool bDoubleRef=(pToken->GetType()==formula::svDoubleRef);
208 if(pToken->GetType()==formula::svSingleRef || bDoubleRef)
210 ScRange aRange;
211 if(bDoubleRef)
213 ScComplexRefData aRef( pToken->GetDoubleRef() );
214 aRange = aRef.toAbs(aPos);
216 else
218 ScSingleRefData aRef( pToken->GetSingleRef() );
219 aRange.aStart = aRef.toAbs(aPos);
220 aRange.aEnd = aRange.aStart;
222 ColorData aColName=ScRangeFindList::GetColorName(nIndex++);
223 pTabViewShell->AddHighlightRange(aRange, aColName);
226 pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
232 // -----------------------------------------------------------------------------
233 void ScFormulaReferenceHelper::HideReference( bool bDoneRefMode )
235 ScViewData* pViewData=ScDocShell::GetViewData();
237 if( pViewData && bHighlightRef && bEnableColorRef)
239 ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
241 if(pTabViewShell!=NULL)
243 // bDoneRefMode is sal_False when called from before SetReference.
244 // In that case, RefMode was just started and must not be ended now.
246 if ( bDoneRefMode )
247 pTabViewShell->DoneRefMode( false );
248 pTabViewShell->ClearHighlightRanges();
250 bHighlightRef=false;
253 // -----------------------------------------------------------------------------
254 void ScFormulaReferenceHelper::ShowReference(const OUString& rStr)
256 if( bEnableColorRef )
258 if( rStr.indexOf('(') != -1 ||
259 rStr.indexOf('+') != -1 ||
260 rStr.indexOf('*') != -1 ||
261 rStr.indexOf('-') != -1 ||
262 rStr.indexOf('/') != -1 ||
263 rStr.indexOf('&') != -1 ||
264 rStr.indexOf('<') != -1 ||
265 rStr.indexOf('>') != -1 ||
266 rStr.indexOf('=') != -1 ||
267 rStr.indexOf('^') != -1 )
269 ShowFormulaReference(rStr);
271 else
273 ShowSimpleReference(rStr);
277 // -----------------------------------------------------------------------------
278 void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
280 if( !pRefEdit && pEdit )
282 m_pDlg->RefInputStart( pEdit, pButton );
285 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
286 if( pViewShell )
288 pViewShell->ActiveGrabFocus();
289 if( pRefEdit )
291 const ScViewData* pViewData = pViewShell->GetViewData();
292 ScDocument* pDoc = pViewData->GetDocument();
293 ScRangeList aRangeList;
294 if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) )
296 if ( !aRangeList.empty() )
298 const ScRange* pRange = aRangeList.front();
299 pViewShell->SetTabNo( pRange->aStart.Tab() );
300 pViewShell->MoveCursorAbs( pRange->aStart.Col(),
301 pRange->aStart.Row(), SC_FOLLOW_JUMP, false, false );
302 pViewShell->MoveCursorAbs( pRange->aEnd.Col(),
303 pRange->aEnd.Row(), SC_FOLLOW_JUMP, true, false );
304 m_pDlg->SetReference( *pRange, pDoc );
310 // -----------------------------------------------------------------------------
311 void ScFormulaReferenceHelper::Init()
313 ScViewData* pViewData=ScDocShell::GetViewData(); //! use pScViewShell?
314 if ( pViewData )
316 ScDocument* pDoc = pViewData->GetDocument();
317 SCCOL nCol = pViewData->GetCurX();
318 SCROW nRow = pViewData->GetCurY();
319 SCTAB nTab = pViewData->GetTabNo();
320 ScAddress aCursorPos( nCol, nRow, nTab );
322 pRefComp.reset( new ScCompiler( pDoc, aCursorPos) );
323 pRefComp->SetGrammar( pDoc->GetGrammar() );
324 pRefComp->SetCompileForFAP(true);
326 nRefTab = nTab;
329 // -----------------------------------------------------------------------------
330 IMPL_LINK( ScFormulaReferenceHelper, AccelSelectHdl, Accelerator *, pSelAccel )
332 if ( !pSelAccel )
333 return 0;
335 switch ( pSelAccel->GetCurKeyCode().GetCode() )
337 case KEY_RETURN:
338 case KEY_ESCAPE:
339 if( pRefEdit )
340 pRefEdit->GrabFocus();
341 m_pDlg->RefInputDone( true );
342 break;
344 return true;
347 typedef std::vector<Window*> winvec;
349 void ScFormulaReferenceHelper::RefInputDone( bool bForced )
351 if ( CanInputDone( bForced ) )
353 if (bAccInserted) // Accelerator wieder abschalten
355 Application::RemoveAccel( pAccel.get() );
356 bAccInserted = false;
359 //get rid of all this junk when we can
360 if (!mbOldDlgLayoutEnabled)
362 m_pWindow->SetOutputSizePixel(aOldDialogSize);
364 // restore the parent of the edit field
365 pRefEdit->SetParent(mpOldEditParent);
367 // Fenster wieder gross
368 m_pWindow->SetOutputSizePixel(aOldDialogSize);
370 // set button parent
371 if( pRefBtn )
373 pRefBtn->SetParent(m_pWindow);
377 if (!mbOldEditParentLayoutEnabled)
379 // pEditCell an alte Position
380 pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize);
382 // set button position
383 if( pRefBtn )
385 pRefBtn->SetPosPixel( aOldButtonPos );
389 // Fenstertitel anpassen
390 m_pWindow->SetText(sOldDialogText);
392 // set button image
393 if( pRefBtn )
394 pRefBtn->SetStartImage();
396 // Alle anderen: Show();
397 for (winvec::iterator aI = m_aHiddenWidgets.begin(); aI != m_aHiddenWidgets.end(); ++aI)
399 Window *pWindow = *aI;
400 pWindow->Show();
402 m_aHiddenWidgets.clear();
404 if (mbOldDlgLayoutEnabled)
406 pRefEdit->set_width_request(mnOldEditWidthReq);
407 Dialog* pResizeDialog = pRefEdit->GetParentDialog();
408 pResizeDialog->set_border_width(m_nOldBorderWidth);
409 if (Window *pActionArea = pResizeDialog->get_action_area())
410 pActionArea->Show();
411 pResizeDialog->setOptimalLayoutSize();
414 pRefEdit = NULL;
415 pRefBtn = NULL;
419 typedef std::set<Window*> winset;
421 namespace
423 void hideUnless(Window *pTop, const winset& rVisibleWidgets,
424 winvec &rWasVisibleWidgets)
426 for (Window* pChild = pTop->GetWindow(WINDOW_FIRSTCHILD); pChild;
427 pChild = pChild->GetWindow(WINDOW_NEXT))
429 if (!pChild->IsVisible())
430 continue;
431 if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
433 rWasVisibleWidgets.push_back(pChild);
434 pChild->Hide();
436 else if (isContainerWindow(pChild))
438 hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
444 // -----------------------------------------------------------------------------
445 void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
447 if (!pRefEdit)
449 pRefEdit = pEdit;
450 pRefBtn = pButton;
452 mbOldDlgLayoutEnabled = isLayoutEnabled(m_pWindow);
453 aOldEditSize = pRefEdit->GetSizePixel();
454 mnOldEditWidthReq = pRefEdit->get_width_request();
455 mpOldEditParent = pRefEdit->GetParent();
456 mbOldEditParentLayoutEnabled = isContainerWindow(mpOldEditParent);
458 //get rid of all the !mbOldDlgLayoutEnabled and
459 //mbOldEditParentLayoutEnabled junk when we can after the last user of
460 //this is widget-layout-ified
461 if (!mbOldEditParentLayoutEnabled)
463 // Alte Daten merken
464 aOldDialogSize = m_pWindow->GetOutputSizePixel();
465 aOldEditPos = pRefEdit->GetPosPixel();
466 if (pRefBtn)
467 aOldButtonPos = pRefBtn->GetPosPixel();
470 if (!mbOldDlgLayoutEnabled)
472 pRefEdit->SetParent(m_pWindow);
473 if(pRefBtn)
474 pRefBtn->SetParent(m_pWindow);
477 // Fenstertitel anpassen
478 sOldDialogText = m_pWindow->GetText();
479 if (Window *pLabel = pRefEdit->GetLabelWidgetForShrinkMode())
481 OUString sLabel = pLabel->GetText();
482 if (!sLabel.isEmpty())
484 OUString sNewDialogText = sOldDialogText;
485 sNewDialogText += ": ";
486 sNewDialogText += comphelper::string::stripEnd(sLabel, ':');
487 m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) );
491 Dialog* pResizeDialog = NULL;
493 if (!mbOldDlgLayoutEnabled)
495 for (Window* pChild = m_pWindow->GetWindow(WINDOW_FIRSTCHILD); pChild;
496 pChild = pChild->GetWindow(WINDOW_NEXT))
498 Window *pWin = pChild->GetWindow(WINDOW_CLIENT);
499 if (pWin == (Window*)pRefEdit || pWin == (Window*)pRefBtn)
500 continue; // do nothing
501 else if (pWin->IsVisible())
503 m_aHiddenWidgets.push_back(pChild);
504 pChild->Hide();
508 else
510 //We want just pRefBtn and pRefEdit to be shown
511 //mark widgets we want to be visible, starting with pRefEdit
512 //and all its direct parents.
513 winset m_aVisibleWidgets;
514 pResizeDialog = pRefEdit->GetParentDialog();
515 Window *pContentArea = pResizeDialog->get_content_area();
516 for (Window *pCandidate = pRefEdit;
517 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
518 pCandidate = pCandidate->GetWindow(WINDOW_REALPARENT))
520 m_aVisibleWidgets.insert(pCandidate);
522 //same again with pRefBtn, except stop if there's a
523 //shared parent in the existing widgets
524 for (Window *pCandidate = pRefBtn;
525 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
526 pCandidate = pCandidate->GetWindow(WINDOW_REALPARENT))
528 if (m_aVisibleWidgets.insert(pCandidate).second)
529 break;
532 //hide everything except the m_aVisibleWidgets
533 hideUnless(pContentArea, m_aVisibleWidgets, m_aHiddenWidgets);
536 if (!mbOldDlgLayoutEnabled)
538 // Edit-Feld verschieben und anpassen
539 Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height());
540 Size aNewEditSize(aNewDlgSize);
541 long nOffset = 0;
542 if (pRefBtn)
544 aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width();
545 aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width());
547 long nHeight = pRefBtn->GetSizePixel().Height();
548 if ( nHeight > aOldEditSize.Height() )
550 aNewDlgSize.Height() = nHeight;
551 nOffset = (nHeight-aOldEditSize.Height()) / 2;
553 aNewEditSize.Width() -= nOffset;
555 pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize);
557 // set button position
558 if( pRefBtn )
559 pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) );
561 // Fenster verkleinern
562 m_pWindow->SetOutputSizePixel(aNewDlgSize);
565 // set button image
566 if( pRefBtn )
567 pRefBtn->SetEndImage();
569 if (!pAccel.get())
571 pAccel.reset( new Accelerator );
572 pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) );
573 pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) );
574 pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) );
576 Application::InsertAccel( pAccel.get() );
577 bAccInserted = true;
579 if (mbOldDlgLayoutEnabled)
581 pRefEdit->set_width_request(aOldEditSize.Width());
582 m_nOldBorderWidth = pResizeDialog->get_border_width();
583 pResizeDialog->set_border_width(0);
584 if (Window *pActionArea = pResizeDialog->get_action_area())
585 pActionArea->Hide();
586 pResizeDialog->setOptimalLayoutSize();
590 // -----------------------------------------------------------------------------
591 void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
593 if( pEdit )
595 if( pRefEdit == pEdit ) // is this the active ref edit field?
597 pRefEdit->GrabFocus(); // before RefInputDone()
598 m_pDlg->RefInputDone( true ); // finish ref input
600 else
602 m_pDlg->RefInputDone( true ); // another active ref edit?
603 m_pDlg->RefInputStart( pEdit, pButton ); // start ref input
604 // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
605 if( pRefEdit )
606 pRefEdit->GrabFocus();
610 // -----------------------------------------------------------------------------
611 bool ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )
613 SfxApplication* pSfxApp = SFX_APP();
615 SetDispatcherLock( false ); //! here and in dtor ?
617 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
618 if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) )
620 // Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch
621 // per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow),
622 // damit die Buttons auch wieder enabled gezeichnet werden.
623 SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS);
624 if (pChild)
626 ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
627 pWin->Enable();
631 // find parent view frame to close dialog
632 SfxViewFrame* pMyViewFrm = NULL;
633 if ( m_pBindings )
635 SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher();
636 if (pMyDisp)
637 pMyViewFrm = pMyDisp->GetFrame();
639 SC_MOD()->SetRefDialog( nId, false, pMyViewFrm );
641 pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
643 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
644 if ( pScViewShell )
645 pScViewShell->UpdateInputHandler(true);
647 return true;
649 void ScFormulaReferenceHelper::SetDispatcherLock( bool bLock )
651 // lock / unlock only the dispatchers of Calc documents
653 TypeId aType(TYPE(ScDocShell));
654 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
655 while( pDocShell )
657 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
658 while( pFrame )
660 SfxDispatcher* pDisp = pFrame->GetDispatcher();
661 if (pDisp)
662 pDisp->Lock( bLock );
664 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
666 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
669 // if a new view is created while the dialog is open,
670 // that view's dispatcher is locked when trying to create the dialog
671 // for that view (ScTabViewShell::CreateRefDialog)
673 // -----------------------------------------------------------------------------
674 void ScFormulaReferenceHelper::ViewShellChanged()
676 enableInput( false );
678 EnableSpreadsheets();
680 void ScFormulaReferenceHelper::EnableSpreadsheets(bool bFlag, bool bChildren)
682 TypeId aType(TYPE(ScDocShell));
683 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
684 while( pDocShell )
686 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
687 while( pFrame )
689 // enable everything except InPlace, including bean frames
690 if ( !pFrame->GetFrame().IsInPlace() )
692 SfxViewShell* p = pFrame->GetViewShell();
693 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
694 if(pViewSh!=NULL)
696 Window *pWin=pViewSh->GetWindow();
697 if(pWin)
699 Window *pParent=pWin->GetParent();
700 if(pParent)
702 pParent->EnableInput(bFlag,false);
703 if(bChildren)
704 pViewSh->EnableRefInput(bFlag);
709 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
712 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
716 //----------------------------------------------------------------------------
720 static void lcl_InvalidateWindows()
722 TypeId aType(TYPE(ScDocShell));
723 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
724 while( pDocShell )
726 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
727 while( pFrame )
729 // enable everything except InPlace, including bean frames
730 if ( !pFrame->GetFrame().IsInPlace() )
732 SfxViewShell* p = pFrame->GetViewShell();
733 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
734 if(pViewSh!=NULL)
736 Window *pWin=pViewSh->GetWindow();
737 if(pWin)
739 Window *pParent=pWin->GetParent();
740 if(pParent)
741 pParent->Invalidate();
745 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
748 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
751 //----------------------------------------------------------------------------
753 static void lcl_HideAllReferences()
755 TypeId aScType = TYPE(ScTabViewShell);
756 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
757 while ( pSh )
759 ((ScTabViewShell*)pSh)->ClearHighlightRanges();
760 pSh = SfxViewShell::GetNext( *pSh, &aScType );
764 //============================================================================
765 //The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
766 // class ScRefHandler
767 //----------------------------------------------------------------------------
769 ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB, bool bBindRef ):
770 m_rWindow( rWindow ),
771 m_bInRefMode( false ),
772 m_aHelper(this,pB),
773 pMyBindings( pB ),
774 pActiveWin(NULL)
776 m_aHelper.SetWindow(&m_rWindow);
777 reverseUniqueHelpIdHack(m_rWindow);
778 aTimer.SetTimeout(200);
779 aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl));
781 if( bBindRef ) EnterRefMode();
784 bool ScRefHandler::EnterRefMode()
786 if( m_bInRefMode ) return false;
788 SC_MOD()->InputEnterHandler();
790 ScTabViewShell* pScViewShell = NULL;
792 // title has to be from the view that opened the dialog,
793 // even if it's not the current view
795 SfxObjectShell* pParentDoc = NULL;
796 if ( pMyBindings )
798 SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher();
799 if (pMyDisp)
801 SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
802 if (pMyViewFrm)
804 pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
805 if( pScViewShell )
806 pScViewShell->UpdateInputHandler(sal_True);
807 pParentDoc = pMyViewFrm->GetObjectShell();
811 if ( !pParentDoc && pScViewShell ) // use current only if above fails
812 pParentDoc = pScViewShell->GetObjectShell();
813 if ( pParentDoc )
814 aDocName = pParentDoc->GetTitle();
816 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
818 OSL_ENSURE( pInputHdl, "Missing input handler :-/" );
820 if ( pInputHdl )
821 pInputHdl->NotifyChange( NULL );
823 m_aHelper.enableInput( false );
825 m_aHelper.EnableSpreadsheets();
827 m_aHelper.Init();
829 m_aHelper.SetDispatcherLock( true );
831 return m_bInRefMode = true;
834 //----------------------------------------------------------------------------
836 ScRefHandler::~ScRefHandler()
838 LeaveRefMode();
841 bool ScRefHandler::LeaveRefMode()
843 if( !m_bInRefMode ) return false;
845 lcl_HideAllReferences();
847 if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) )
848 pDlg->SetModalInputMode(false);
849 SetDispatcherLock( false ); //! here and in DoClose ?
851 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
852 if( pScViewShell )
853 pScViewShell->UpdateInputHandler(sal_True);
855 lcl_InvalidateWindows();
857 m_bInRefMode = false;
858 return true;
861 //----------------------------------------------------------------------------
863 void ScRefHandler::SwitchToDocument()
865 ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell();
866 if (pCurrent)
868 SfxObjectShell* pObjSh = pCurrent->GetObjectShell();
869 if ( pObjSh && pObjSh->GetTitle() == aDocName )
871 // right document already visible -> nothing to do
872 return;
876 TypeId aScType = TYPE(ScTabViewShell);
877 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
878 while ( pSh )
880 SfxObjectShell* pObjSh = pSh->GetObjectShell();
881 if ( pObjSh && pObjSh->GetTitle() == aDocName )
883 // switch to first TabViewShell for document
884 ((ScTabViewShell*)pSh)->SetActive();
885 return;
887 pSh = SfxViewShell::GetNext( *pSh, &aScType );
891 //----------------------------------------------------------------------------
893 sal_Bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const // pDocSh may be 0
895 // default: allow only same document (overridden in function dialog)
896 OUString aCmpName;
897 if ( pDocSh )
898 aCmpName = pDocSh->GetTitle();
900 // if aDocName isn't initialized, allow
901 return ( aDocName.isEmpty() || aDocName == aCmpName );
904 //----------------------------------------------------------------------------
906 sal_Bool ScRefHandler::IsRefInputMode() const
908 return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen
911 //----------------------------------------------------------------------------
913 sal_Bool ScRefHandler::DoClose( sal_uInt16 nId )
915 m_aHelper.DoClose(nId);
916 return sal_True;
919 void ScRefHandler::SetDispatcherLock( bool bLock )
921 m_aHelper.SetDispatcherLock( bLock );
924 //----------------------------------------------------------------------------
926 void ScRefHandler::ViewShellChanged()
928 m_aHelper.ViewShellChanged();
931 //----------------------------------------------------------------------------
933 void ScRefHandler::AddRefEntry()
935 // wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen
938 //----------------------------------------------------------------------------
940 sal_Bool ScRefHandler::IsTableLocked() const
942 // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
944 return false;
947 //----------------------------------------------------------------------------
949 // RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld
950 // (per Button oder Bewegung)
952 //----------------------------------------------------------------------------
954 void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
956 m_aHelper.RefInputStart( pEdit, pButton );
960 void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
962 m_aHelper.ToggleCollapsed( pEdit, pButton );
965 void ScRefHandler::preNotify(const NotifyEvent& rNEvt, const bool bBindRef)
967 if( bBindRef || m_bInRefMode )
969 sal_uInt16 nSwitch=rNEvt.GetType();
970 if(nSwitch==EVENT_GETFOCUS)
972 pActiveWin=rNEvt.GetWindow();
977 void ScRefHandler::stateChanged(const StateChangedType nStateChange, const bool bBindRef)
979 if( !bBindRef && !m_bInRefMode ) return;
981 if(nStateChange == STATE_CHANGE_VISIBLE)
983 if(m_rWindow.IsVisible())
985 m_aHelper.enableInput( false );
986 m_aHelper.EnableSpreadsheets();
987 m_aHelper.SetDispatcherLock( sal_True );
988 aTimer.Start();
990 else
992 m_aHelper.enableInput( sal_True );
993 m_aHelper.SetDispatcherLock( false ); /*//! here and in DoClose ?*/
998 IMPL_LINK_NOARG(ScRefHandler, UpdateFocusHdl)
1000 if (pActiveWin)
1002 pActiveWin->GrabFocus();
1004 return 0;
1006 // -----------------------------------------------------------------------------
1007 bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const OUString& rStr, ScDocument* pDoc )
1009 return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
1011 // -----------------------------------------------------------------------------
1012 void ScRefHandler::HideReference( sal_Bool bDoneRefMode )
1014 m_aHelper.HideReference( bDoneRefMode );
1016 // -----------------------------------------------------------------------------
1017 void ScRefHandler::ShowReference(const OUString& rStr)
1019 m_aHelper.ShowReference(rStr);
1021 // -----------------------------------------------------------------------------
1022 void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
1024 m_aHelper.ReleaseFocus( pEdit,pButton );
1026 //----------------------------------------------------------------------------
1027 void ScRefHandler::RefInputDone( sal_Bool bForced )
1029 m_aHelper.RefInputDone( bForced );
1032 //-------------------------------------------------------------------------------
1034 ScRefHdlModalImpl::ScRefHdlModalImpl( Window* pParent, const ResId& rResId )
1035 : ModalDialog( pParent, rResId ),
1036 ScRefHandler(dynamic_cast<Window&>(*this), NULL, true) {}
1038 long ScRefHdlModalImpl::PreNotify( NotifyEvent& rNEvt )
1040 ScRefHandler::preNotify( rNEvt, true );
1041 return ModalDialog::PreNotify( rNEvt );
1044 void ScRefHdlModalImpl::StateChanged( StateChangedType nStateChange )
1046 ModalDialog::StateChanged( nStateChange );
1047 ScRefHandler::stateChanged( nStateChange, true );
1050 ScAnyRefModalDlg::ScAnyRefModalDlg( Window* pParent, const ResId &rResId ):
1051 ScRefHdlModalImpl( pParent, rResId ) {}
1053 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */