1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
32 #include "inputhdl.hxx"
34 #include "scresid.hxx"
35 #include "inputwin.hxx"
36 #include "tabvwsh.hxx"
38 #include "rfindlst.hxx"
39 #include "compiler.hxx"
40 #include "formulacell.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
)
52 , m_pBindings(_pBindings
)
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()
69 Application::RemoveAccel( pAccel
.get() );
71 // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
76 ScInputHandler
* pInputHdl
= SC_MOD()->GetInputHdl();
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
);
87 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
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
);
97 Window
*pWin
=pViewSh
->GetWindow();
100 Window
*pParent
=pWin
->GetParent();
103 pParent
->EnableInput(bEnable
,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
)
122 ScViewData
* pViewData
=ScDocShell::GetViewData();
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
)
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
)
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
);
176 // -----------------------------------------------------------------------------
177 void ScFormulaReferenceHelper::ShowFormulaReference(const OUString
& rStr
)
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();
199 const ScToken
* pToken
= static_cast<const ScToken
*>(pScTokA
->GetNextReference());
205 bool bDoubleRef
=(pToken
->GetType()==formula::svDoubleRef
);
208 if(pToken
->GetType()==formula::svSingleRef
|| bDoubleRef
)
213 ScComplexRefData
aRef( pToken
->GetDoubleRef() );
214 aRange
= aRef
.toAbs(aPos
);
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.
247 pTabViewShell
->DoneRefMode( false );
248 pTabViewShell
->ClearHighlightRanges();
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
);
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();
288 pViewShell
->ActiveGrabFocus();
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?
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);
329 // -----------------------------------------------------------------------------
330 IMPL_LINK( ScFormulaReferenceHelper
, AccelSelectHdl
, Accelerator
*, pSelAccel
)
335 switch ( pSelAccel
->GetCurKeyCode().GetCode() )
340 pRefEdit
->GrabFocus();
341 m_pDlg
->RefInputDone( 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
);
373 pRefBtn
->SetParent(m_pWindow
);
377 if (!mbOldEditParentLayoutEnabled
)
379 // pEditCell an alte Position
380 pRefEdit
->SetPosSizePixel(aOldEditPos
, aOldEditSize
);
382 // set button position
385 pRefBtn
->SetPosPixel( aOldButtonPos
);
389 // Fenstertitel anpassen
390 m_pWindow
->SetText(sOldDialogText
);
394 pRefBtn
->SetStartImage();
396 // Alle anderen: Show();
397 for (winvec::iterator aI
= m_aHiddenWidgets
.begin(); aI
!= m_aHiddenWidgets
.end(); ++aI
)
399 Window
*pWindow
= *aI
;
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())
411 pResizeDialog
->setOptimalLayoutSize();
419 typedef std::set
<Window
*> winset
;
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())
431 if (rVisibleWidgets
.find(pChild
) == rVisibleWidgets
.end())
433 rWasVisibleWidgets
.push_back(pChild
);
436 else if (isContainerWindow(pChild
))
438 hideUnless(pChild
, rVisibleWidgets
, rWasVisibleWidgets
);
444 // -----------------------------------------------------------------------------
445 void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit
* pEdit
, formula::RefButton
* 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
)
464 aOldDialogSize
= m_pWindow
->GetOutputSizePixel();
465 aOldEditPos
= pRefEdit
->GetPosPixel();
467 aOldButtonPos
= pRefBtn
->GetPosPixel();
470 if (!mbOldDlgLayoutEnabled
)
472 pRefEdit
->SetParent(m_pWindow
);
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
);
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
)
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
);
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
559 pRefBtn
->SetPosPixel( Point( aOldDialogSize
.Width() - pRefBtn
->GetSizePixel().Width(), 0 ) );
561 // Fenster verkleinern
562 m_pWindow
->SetOutputSizePixel(aNewDlgSize
);
567 pRefBtn
->SetEndImage();
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() );
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())
586 pResizeDialog
->setOptimalLayoutSize();
590 // -----------------------------------------------------------------------------
591 void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit
* pEdit
, formula::RefButton
* pButton
)
595 if( pRefEdit
== pEdit
) // is this the active ref edit field?
597 pRefEdit
->GrabFocus(); // before RefInputDone()
598 m_pDlg
->RefInputDone( true ); // finish ref input
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)
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
);
626 ScInputWindow
* pWin
= (ScInputWindow
*)pChild
->GetWindow();
631 // find parent view frame to close dialog
632 SfxViewFrame
* pMyViewFrm
= NULL
;
635 SfxDispatcher
* pMyDisp
= m_pBindings
->GetDispatcher();
637 pMyViewFrm
= pMyDisp
->GetFrame();
639 SC_MOD()->SetRefDialog( nId
, false, pMyViewFrm
);
641 pSfxApp
->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW
) );
643 ScTabViewShell
* pScViewShell
= ScTabViewShell::GetActiveViewShell();
645 pScViewShell
->UpdateInputHandler(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
);
657 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
660 SfxDispatcher
* pDisp
= pFrame
->GetDispatcher();
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
);
686 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
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
);
696 Window
*pWin
=pViewSh
->GetWindow();
699 Window
*pParent
=pWin
->GetParent();
702 pParent
->EnableInput(bFlag
,false);
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
);
726 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
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
);
736 Window
*pWin
=pViewSh
->GetWindow();
739 Window
*pParent
=pWin
->GetParent();
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
);
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 ),
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
;
798 SfxDispatcher
* pMyDisp
= pMyBindings
->GetDispatcher();
801 SfxViewFrame
* pMyViewFrm
= pMyDisp
->GetFrame();
804 pScViewShell
= PTR_CAST( ScTabViewShell
, pMyViewFrm
->GetViewShell() );
806 pScViewShell
->UpdateInputHandler(sal_True
);
807 pParentDoc
= pMyViewFrm
->GetObjectShell();
811 if ( !pParentDoc
&& pScViewShell
) // use current only if above fails
812 pParentDoc
= pScViewShell
->GetObjectShell();
814 aDocName
= pParentDoc
->GetTitle();
816 ScInputHandler
* pInputHdl
= SC_MOD()->GetInputHdl(pScViewShell
);
818 OSL_ENSURE( pInputHdl
, "Missing input handler :-/" );
821 pInputHdl
->NotifyChange( NULL
);
823 m_aHelper
.enableInput( false );
825 m_aHelper
.EnableSpreadsheets();
829 m_aHelper
.SetDispatcherLock( true );
831 return m_bInRefMode
= true;
834 //----------------------------------------------------------------------------
836 ScRefHandler::~ScRefHandler()
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();
853 pScViewShell
->UpdateInputHandler(sal_True
);
855 lcl_InvalidateWindows();
857 m_bInRefMode
= false;
861 //----------------------------------------------------------------------------
863 void ScRefHandler::SwitchToDocument()
865 ScTabViewShell
* pCurrent
= ScTabViewShell::GetActiveViewShell();
868 SfxObjectShell
* pObjSh
= pCurrent
->GetObjectShell();
869 if ( pObjSh
&& pObjSh
->GetTitle() == aDocName
)
871 // right document already visible -> nothing to do
876 TypeId aScType
= TYPE(ScTabViewShell
);
877 SfxViewShell
* pSh
= SfxViewShell::GetFirst( &aScType
);
880 SfxObjectShell
* pObjSh
= pSh
->GetObjectShell();
881 if ( pObjSh
&& pObjSh
->GetTitle() == aDocName
)
883 // switch to first TabViewShell for document
884 ((ScTabViewShell
*)pSh
)->SetActive();
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)
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
);
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
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
);
992 m_aHelper
.enableInput( sal_True
);
993 m_aHelper
.SetDispatcherLock( false ); /*//! here and in DoClose ?*/
998 IMPL_LINK_NOARG(ScRefHandler
, UpdateFocusHdl
)
1002 pActiveWin
->GrabFocus();
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: */