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 ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog
* _pDlg
,SfxBindings
* _pBindings
)
50 , m_pBindings(_pBindings
)
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()
67 Application::RemoveAccel( pAccel
.get() );
69 // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
74 ScInputHandler
* pInputHdl
= SC_MOD()->GetInputHdl();
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
);
85 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
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
);
95 Window
*pWin
=pViewSh
->GetWindow();
98 Window
*pParent
=pWin
->GetParent();
101 pParent
->EnableInput(bEnable
,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
)
120 ScViewData
* pViewData
=ScDocShell::GetViewData();
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
)
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
)
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
);
174 // -----------------------------------------------------------------------------
175 void ScFormulaReferenceHelper::ShowFormulaReference( const XubString
& rStr
)
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();
198 const ScToken
* pToken
= static_cast<const ScToken
*>(pScTokA
->GetNextReference());
204 bool bDoubleRef
=(pToken
->GetType()==formula::svDoubleRef
);
207 if(pToken
->GetType()==formula::svSingleRef
|| 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
);
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.
250 pTabViewShell
->DoneRefMode( false );
251 pTabViewShell
->ClearHighlightRanges();
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
);
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();
291 pViewShell
->ActiveGrabFocus();
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?
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);
332 // -----------------------------------------------------------------------------
333 IMPL_LINK( ScFormulaReferenceHelper
, AccelSelectHdl
, Accelerator
*, pSelAccel
)
338 switch ( pSelAccel
->GetCurKeyCode().GetCode() )
343 pRefEdit
->GrabFocus();
344 m_pDlg
->RefInputDone( 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
);
376 pRefBtn
->SetParent(m_pWindow
);
380 if (!mbOldEditParentLayoutEnabled
)
382 // pEditCell an alte Position
383 pRefEdit
->SetPosSizePixel(aOldEditPos
, aOldEditSize
);
385 // set button position
388 pRefBtn
->SetPosPixel( aOldButtonPos
);
392 // Fenstertitel anpassen
393 m_pWindow
->SetText(sOldDialogText
);
397 pRefBtn
->SetStartImage();
399 // Alle anderen: Show();
400 for (winvec::iterator aI
= m_aHiddenWidgets
.begin(); aI
!= m_aHiddenWidgets
.end(); ++aI
)
402 Window
*pWindow
= *aI
;
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())
414 pResizeDialog
->setOptimalLayoutSize();
422 typedef std::set
<Window
*> winset
;
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())
434 if (rVisibleWidgets
.find(pChild
) == rVisibleWidgets
.end())
436 rWasVisibleWidgets
.push_back(pChild
);
439 else if (isContainerWindow(pChild
))
441 hideUnless(pChild
, rVisibleWidgets
, rWasVisibleWidgets
);
447 // -----------------------------------------------------------------------------
448 void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit
* pEdit
, formula::RefButton
* 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
)
467 aOldDialogSize
= m_pWindow
->GetOutputSizePixel();
468 aOldEditPos
= pRefEdit
->GetPosPixel();
470 aOldButtonPos
= pRefBtn
->GetPosPixel();
473 if (!mbOldDlgLayoutEnabled
)
475 pRefEdit
->SetParent(m_pWindow
);
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
);
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
)
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
);
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
562 pRefBtn
->SetPosPixel( Point( aOldDialogSize
.Width() - pRefBtn
->GetSizePixel().Width(), 0 ) );
564 // Fenster verkleinern
565 m_pWindow
->SetOutputSizePixel(aNewDlgSize
);
570 pRefBtn
->SetEndImage();
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() );
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())
589 pResizeDialog
->setOptimalLayoutSize();
593 // -----------------------------------------------------------------------------
594 void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit
* pEdit
, formula::RefButton
* pButton
)
598 if( pRefEdit
== pEdit
) // is this the active ref edit field?
600 pRefEdit
->GrabFocus(); // before RefInputDone()
601 m_pDlg
->RefInputDone( true ); // finish ref input
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)
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
);
629 ScInputWindow
* pWin
= (ScInputWindow
*)pChild
->GetWindow();
634 // find parent view frame to close dialog
635 SfxViewFrame
* pMyViewFrm
= NULL
;
638 SfxDispatcher
* pMyDisp
= m_pBindings
->GetDispatcher();
640 pMyViewFrm
= pMyDisp
->GetFrame();
642 SC_MOD()->SetRefDialog( nId
, false, pMyViewFrm
);
644 pSfxApp
->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW
) );
646 ScTabViewShell
* pScViewShell
= ScTabViewShell::GetActiveViewShell();
648 pScViewShell
->UpdateInputHandler(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
);
660 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
663 SfxDispatcher
* pDisp
= pFrame
->GetDispatcher();
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
);
689 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
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
);
699 Window
*pWin
=pViewSh
->GetWindow();
702 Window
*pParent
=pWin
->GetParent();
705 pParent
->EnableInput(bFlag
,false);
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
);
729 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
);
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
);
739 Window
*pWin
=pViewSh
->GetWindow();
742 Window
*pParent
=pWin
->GetParent();
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
);
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 ),
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
;
801 SfxDispatcher
* pMyDisp
= pMyBindings
->GetDispatcher();
804 SfxViewFrame
* pMyViewFrm
= pMyDisp
->GetFrame();
807 pScViewShell
= PTR_CAST( ScTabViewShell
, pMyViewFrm
->GetViewShell() );
809 pScViewShell
->UpdateInputHandler(sal_True
);
810 pParentDoc
= pMyViewFrm
->GetObjectShell();
814 if ( !pParentDoc
&& pScViewShell
) // use current only if above fails
815 pParentDoc
= pScViewShell
->GetObjectShell();
817 aDocName
= pParentDoc
->GetTitle();
819 ScInputHandler
* pInputHdl
= SC_MOD()->GetInputHdl(pScViewShell
);
821 OSL_ENSURE( pInputHdl
, "Missing input handler :-/" );
824 pInputHdl
->NotifyChange( NULL
);
826 m_aHelper
.enableInput( false );
828 m_aHelper
.EnableSpreadsheets();
832 m_aHelper
.SetDispatcherLock( true );
834 return m_bInRefMode
= true;
837 //----------------------------------------------------------------------------
839 ScRefHandler::~ScRefHandler()
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();
856 pScViewShell
->UpdateInputHandler(sal_True
);
858 lcl_InvalidateWindows();
860 m_bInRefMode
= false;
864 //----------------------------------------------------------------------------
866 void ScRefHandler::SwitchToDocument()
868 ScTabViewShell
* pCurrent
= ScTabViewShell::GetActiveViewShell();
871 SfxObjectShell
* pObjSh
= pCurrent
->GetObjectShell();
872 if ( pObjSh
&& pObjSh
->GetTitle() == aDocName
)
874 // right document already visible -> nothing to do
879 TypeId aScType
= TYPE(ScTabViewShell
);
880 SfxViewShell
* pSh
= SfxViewShell::GetFirst( &aScType
);
883 SfxObjectShell
* pObjSh
= pSh
->GetObjectShell();
884 if ( pObjSh
&& pObjSh
->GetTitle() == aDocName
)
886 // switch to first TabViewShell for document
887 ((ScTabViewShell
*)pSh
)->SetActive();
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)
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
);
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
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
);
995 m_aHelper
.enableInput( sal_True
);
996 m_aHelper
.SetDispatcherLock( false ); /*//! here and in DoClose ?*/
1001 IMPL_LINK_NOARG(ScRefHandler
, UpdateFocusHdl
)
1005 pActiveWin
->GrabFocus();
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: */