xref: /trunk/main/sc/source/ui/miscdlgs/anyrefdg.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 
33 //----------------------------------------------------------------------------
34 
35 #include "rangelst.hxx"
36 #include <sfx2/app.hxx>
37 #include <sfx2/viewsh.hxx>
38 #include <vcl/wrkwin.hxx>
39 #include <vcl/mnemonic.hxx>
40 #include <tools/shl.hxx>
41 #include <svtools/taskbar.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/dispatch.hxx>
44 
45 
46 #define ANYREFDG_CXX
47 #include "anyrefdg.hxx"
48 #undef ANYREFDG_CXX
49 
50 #include "sc.hrc"
51 #include "inputhdl.hxx"
52 #include "scmod.hxx"
53 #include "scresid.hxx"
54 #include "inputwin.hxx"
55 #include "tabvwsh.hxx"
56 #include "docsh.hxx"
57 #include "rfindlst.hxx"
58 #include "compiler.hxx"
59 #include "cell.hxx"
60 #include "global.hxx"
61 #include "inputopt.hxx"
62 #include "rangeutl.hxx"
63 
64 
65 ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings)
66  : m_pDlg(_pDlg)
67  , pRefEdit (NULL)
68  , m_pWindow(NULL)
69  , m_pBindings(_pBindings)
70  , pAccel( NULL )
71  , pHiddenMarks(NULL)
72  , nRefTab(0)
73  , bHighLightRef( sal_False )
74  , bAccInserted( sal_False )
75 {
76     ScInputOptions aInputOption=SC_MOD()->GetInputOptions();
77     bEnableColorRef=aInputOption.GetRangeFinder();
78 }
79 // -----------------------------------------------------------------------------
80 ScFormulaReferenceHelper::~ScFormulaReferenceHelper()
81 {
82     if (bAccInserted)
83         Application::RemoveAccel( pAccel.get() );
84 
85     // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
86 
87     HideReference();
88     enableInput( sal_True );
89 
90     ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
91     if ( pInputHdl )
92         pInputHdl->ResetDelayTimer();   // stop the timer for disabling the input line
93 }
94 // -----------------------------------------------------------------------------
95 void ScFormulaReferenceHelper::enableInput( sal_Bool bEnable )
96 {
97     TypeId aType(TYPE(ScDocShell));
98     ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
99     while( pDocShell )
100     {
101         SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
102         while( pFrame )
103         {
104             //  #71577# enable everything except InPlace, including bean frames
105             if ( !pFrame->GetFrame().IsInPlace() )
106             {
107                 SfxViewShell* p = pFrame->GetViewShell();
108                 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
109                 if(pViewSh!=NULL)
110                 {
111                     Window *pWin=pViewSh->GetWindow();
112                     if(pWin)
113                     {
114                         Window *pParent=pWin->GetParent();
115                         if(pParent)
116                         {
117                             pParent->EnableInput(bEnable,sal_True /* sal_False */);
118                             if(sal_True /*bChilds*/)
119                                 pViewSh->EnableRefInput(bEnable);
120                         }
121                     }
122                 }
123             }
124             pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
125         }
126 
127         pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
128     }
129 }
130 // -----------------------------------------------------------------------------
131 void ScFormulaReferenceHelper::ShowSimpleReference( const XubString& rStr )
132 {
133     if( /*!pRefEdit &&*/ bEnableColorRef )
134     {
135         bHighLightRef=sal_True;
136         ScViewData* pViewData=ScDocShell::GetViewData();
137         if ( pViewData )
138         {
139             ScDocument* pDoc=pViewData->GetDocument();
140             ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
141 
142             ScRangeList aRangeList;
143 
144             pTabViewShell->DoneRefMode( sal_False );
145             pTabViewShell->ClearHighlightRanges();
146 
147             if( ParseWithNames( aRangeList, rStr, pDoc ) )
148             {
149                 ScRange* pRangeEntry = aRangeList.First();
150 
151                 sal_uInt16 nIndex=0;
152                 while(pRangeEntry != NULL)
153                 {
154                     ColorData aColName = ScRangeFindList::GetColorName(nIndex++);
155                     pTabViewShell->AddHighlightRange(*pRangeEntry, aColName);
156 
157                     pRangeEntry = aRangeList.Next();
158                 }
159             }
160         }
161     }
162 }
163 // -----------------------------------------------------------------------------
164 bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
165 {
166     bool bError = false;
167     rRanges.RemoveAll();
168 
169     ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
170     ScRangeUtil aRangeUtil;
171     xub_StrLen nTokenCnt = rStr.GetTokenCount();
172     for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
173     {
174         ScRange aRange;
175         String aRangeStr( rStr.GetToken( nToken ) );
176 
177         sal_uInt16 nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails );
178         if ( nFlags & SCA_VALID )
179         {
180             if ( (nFlags & SCA_TAB_3D) == 0 )
181                 aRange.aStart.SetTab( nRefTab );
182             if ( (nFlags & SCA_TAB2_3D) == 0 )
183                 aRange.aEnd.SetTab( aRange.aStart.Tab() );
184             rRanges.Append( aRange );
185         }
186         else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) )
187             rRanges.Append( aRange );
188         else
189             bError = true;
190     }
191 
192     return !bError;
193 }
194 // -----------------------------------------------------------------------------
195 void ScFormulaReferenceHelper::ShowFormulaReference( const XubString& rStr )
196 {
197     if( /*!pRefEdit &&*/ bEnableColorRef)
198     {
199         bHighLightRef=sal_True;
200         ScViewData* pViewData=ScDocShell::GetViewData();
201         if ( pViewData && pRefComp.get() )
202         {
203             ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
204             SCCOL nCol = pViewData->GetCurX();
205             SCROW nRow = pViewData->GetCurY();
206             SCTAB nTab = pViewData->GetTabNo();
207             ScAddress aPos( nCol, nRow, nTab );
208 
209             ScTokenArray* pScTokA=pRefComp->CompileString(rStr);
210             //pRefComp->CompileTokenArray();
211 
212             if(pTabViewShell!=NULL && pScTokA!=NULL)
213             {
214                 pTabViewShell->DoneRefMode( sal_False );
215                 pTabViewShell->ClearHighlightRanges();
216 
217                 pScTokA->Reset();
218                 const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
219 
220                 sal_uInt16 nIndex=0;
221 
222                 while(pToken!=NULL)
223                 {
224                     sal_Bool bDoubleRef=(pToken->GetType()==formula::svDoubleRef);
225 
226 
227                     if(pToken->GetType()==formula::svSingleRef || bDoubleRef)
228                     {
229                         ScRange aRange;
230                         if(bDoubleRef)
231                         {
232                             ScComplexRefData aRef( pToken->GetDoubleRef() );
233                             aRef.CalcAbsIfRel( aPos );
234                             aRange.aStart.Set( aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab );
235                             aRange.aEnd.Set( aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab );
236                         }
237                         else
238                         {
239                             ScSingleRefData aRef( pToken->GetSingleRef() );
240                             aRef.CalcAbsIfRel( aPos );
241                             aRange.aStart.Set( aRef.nCol, aRef.nRow, aRef.nTab );
242                             aRange.aEnd = aRange.aStart;
243                         }
244                         ColorData aColName=ScRangeFindList::GetColorName(nIndex++);
245                         pTabViewShell->AddHighlightRange(aRange, aColName);
246                     }
247 
248                     pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
249                 }
250             }
251             if(pScTokA!=NULL) delete pScTokA;
252         }
253     }
254 }
255 // -----------------------------------------------------------------------------
256 void ScFormulaReferenceHelper::HideReference( sal_Bool bDoneRefMode )
257 {
258     ScViewData* pViewData=ScDocShell::GetViewData();
259 
260     if( pViewData && /*!pRefEdit &&*/ bHighLightRef && bEnableColorRef)
261     {
262         ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
263 
264         if(pTabViewShell!=NULL)
265         {
266             //  bDoneRefMode is sal_False when called from before SetReference.
267             //  In that case, RefMode was just started and must not be ended now.
268 
269             if ( bDoneRefMode )
270                 pTabViewShell->DoneRefMode( sal_False );
271             pTabViewShell->ClearHighlightRanges();
272         }
273         bHighLightRef=sal_False;
274     }
275 }
276 // -----------------------------------------------------------------------------
277 void ScFormulaReferenceHelper::ShowReference( const XubString& rStr )
278 {
279     if( /*!pRefEdit &&*/ bEnableColorRef )
280     {
281         if( rStr.Search('(')!=STRING_NOTFOUND ||
282             rStr.Search('+')!=STRING_NOTFOUND ||
283             rStr.Search('*')!=STRING_NOTFOUND ||
284             rStr.Search('-')!=STRING_NOTFOUND ||
285             rStr.Search('/')!=STRING_NOTFOUND ||
286             rStr.Search('&')!=STRING_NOTFOUND ||
287             rStr.Search('<')!=STRING_NOTFOUND ||
288             rStr.Search('>')!=STRING_NOTFOUND ||
289             rStr.Search('=')!=STRING_NOTFOUND ||
290             rStr.Search('^')!=STRING_NOTFOUND)
291         {
292             ShowFormulaReference(rStr);
293         }
294         else
295         {
296             ShowSimpleReference(rStr);
297         }
298     }
299 }
300 // -----------------------------------------------------------------------------
301 void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
302 {
303     if( !pRefEdit && pEdit )
304     {
305         m_pDlg->RefInputStart( pEdit, pButton );
306 //        if( pRefEdit )
307 //            pRefEdit->SilentGrabFocus();
308     }
309 
310     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
311     if( pViewShell )
312     {
313         pViewShell->ActiveGrabFocus();
314         if( pRefEdit )
315         {
316             const ScViewData* pViewData = pViewShell->GetViewData();
317             ScDocument* pDoc = pViewData->GetDocument();
318             ScRangeList aRangeList;
319             if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) )
320             {
321                 const ScRange* pRange = aRangeList.GetObject( 0 );
322                 if( pRange )
323                 {
324                     pViewShell->SetTabNo( pRange->aStart.Tab() );
325                     pViewShell->MoveCursorAbs(  pRange->aStart.Col(),
326                         pRange->aStart.Row(), SC_FOLLOW_JUMP, sal_False, sal_False );
327                     pViewShell->MoveCursorAbs( pRange->aEnd.Col(),
328                         pRange->aEnd.Row(), SC_FOLLOW_JUMP, sal_True, sal_False );
329                     m_pDlg->SetReference( *pRange, pDoc );
330                 }
331             }
332         }
333     }
334 }
335 // -----------------------------------------------------------------------------
336 void ScFormulaReferenceHelper::Init()
337 {
338     ScViewData* pViewData=ScDocShell::GetViewData();    //! use pScViewShell?
339     if ( pViewData )
340     {
341         ScDocument* pDoc = pViewData->GetDocument();
342         SCCOL nCol = pViewData->GetCurX();
343         SCROW nRow = pViewData->GetCurY();
344         SCTAB nTab = pViewData->GetTabNo();
345         ScAddress aCursorPos( nCol, nRow, nTab );
346 
347         String rStrExp;
348         pRefCell.reset( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) );
349         pRefComp.reset( new ScCompiler( pDoc, aCursorPos) );
350         pRefComp->SetGrammar( pDoc->GetGrammar() );
351         pRefComp->SetCompileForFAP(sal_True);
352 
353         nRefTab = nTab;
354     } // if ( pViewData )
355 }
356 // -----------------------------------------------------------------------------
357 IMPL_LINK( ScFormulaReferenceHelper, AccelSelectHdl, Accelerator *, pSelAccel )
358 {
359     if ( !pSelAccel )
360         return 0;
361 
362     switch ( pSelAccel->GetCurKeyCode().GetCode() )
363     {
364         case KEY_RETURN:
365         case KEY_ESCAPE:
366             if( pRefEdit )
367                 pRefEdit->GrabFocus();
368             m_pDlg->RefInputDone( sal_True );
369         break;
370     }
371     return sal_True;
372 }
373 //----------------------------------------------------------------------------
374 void ScFormulaReferenceHelper::RefInputDone( sal_Bool bForced )
375 {
376     //<!--Modified by PengYunQuan for Validity Cell Range Picker
377     //if (pRefEdit && (bForced || !pRefBtn))
378     if ( CanInputDone( bForced ) )//if (pRefEdit && (bForced || !pRefBtn))
379     //-->Modified by PengYunQuan for Validity Cell Range Picker
380     {
381         if (bAccInserted)           // Accelerator wieder abschalten
382         {
383             Application::RemoveAccel( pAccel.get() );
384             bAccInserted = sal_False;
385         }
386 
387         // Fenstertitel anpassen
388         m_pWindow->SetText(sOldDialogText);
389 
390         // Fenster wieder gross
391         m_pWindow->SetOutputSizePixel(aOldDialogSize);
392 
393         // pEditCell an alte Position
394         pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize);
395 
396         // set button position and image
397         if( pRefBtn )
398         {
399             pRefBtn->SetPosPixel( aOldButtonPos );
400             pRefBtn->SetStartImage();
401         }
402 
403         // Alle anderen: Show();
404         sal_uInt16 nChildren = m_pWindow->GetChildCount();
405         for ( sal_uInt16 i = 0; i < nChildren; i++ )
406             if (pHiddenMarks[i])
407             {
408                 m_pWindow->GetChild(i)->GetWindow( WINDOW_CLIENT )->Show();
409             }
410         delete [] pHiddenMarks;
411 
412         pRefEdit = NULL;
413         pRefBtn = NULL;
414     }
415 }
416 // -----------------------------------------------------------------------------
417 void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
418 {
419     if (!pRefEdit)
420     {
421         pRefEdit = pEdit;
422         pRefBtn  = pButton;
423 
424         // Neuen Fenstertitel basteln
425         String sNewDialogText;
426         sOldDialogText = m_pWindow->GetText();
427         sNewDialogText  = sOldDialogText;
428         sNewDialogText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
429 
430         // Alle Elemente ausser EditCell und Button verstecken
431         sal_uInt16 nChildren = m_pWindow->GetChildCount();
432         pHiddenMarks = new sal_Bool [nChildren];
433         for (sal_uInt16 i = 0; i < nChildren; i++)
434         {
435             pHiddenMarks[i] = sal_False;
436             Window* pWin = m_pWindow->GetChild(i);
437             pWin = pWin->GetWindow( WINDOW_CLIENT );
438             if (pWin == (Window*)pRefEdit)
439             {
440                 sNewDialogText += m_pWindow->GetChild(i-1)->GetWindow( WINDOW_CLIENT )->GetText();
441             }
442             else if (pWin == (Window*)pRefBtn)
443                 ;   // do nothing
444             else if (pWin->IsVisible())
445             {
446                 pHiddenMarks[i] = sal_True;
447                 pWin->Hide();
448             }
449         }
450 
451         // Alte Daten merken
452         aOldDialogSize = m_pWindow->GetOutputSizePixel();
453         aOldEditPos = pRefEdit->GetPosPixel();
454         aOldEditSize = pRefEdit->GetSizePixel();
455         if (pRefBtn)
456             aOldButtonPos = pRefBtn->GetPosPixel();
457 
458         // Edit-Feld verschieben und anpassen
459         Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height());
460         Size aNewEditSize(aNewDlgSize);
461         long nOffset = 0;
462         if (pRefBtn)
463         {
464             aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width();
465             aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width());
466 
467             long nHeight = pRefBtn->GetSizePixel().Height();
468             if ( nHeight > aOldEditSize.Height() )
469             {
470                 aNewDlgSize.Height() = nHeight;
471                 nOffset = (nHeight-aOldEditSize.Height()) / 2;
472             }
473             aNewEditSize.Width() -= nOffset;
474         }
475         pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize);
476 
477         // set button position and image
478         if( pRefBtn )
479         {
480             pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) );
481             pRefBtn->SetEndImage();
482         }
483 
484         // Fenster verkleinern
485         m_pWindow->SetOutputSizePixel(aNewDlgSize);
486 
487         // Fenstertitel anpassen
488         m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) );
489 
490 //        if ( pButton )      // ueber den Button: Enter und Escape abfangen
491 //        {
492             if (!pAccel.get())
493             {
494                 pAccel.reset( new Accelerator );
495                 pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) );
496                 pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) );
497                 pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) );
498             }
499             Application::InsertAccel( pAccel.get() );
500             bAccInserted = sal_True;
501 //        }
502     }
503 }
504 // -----------------------------------------------------------------------------
505 void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
506 {
507     if( pEdit )
508     {
509         if( pRefEdit == pEdit )                 // is this the active ref edit field?
510         {
511             pRefEdit->GrabFocus();              // before RefInputDone()
512             m_pDlg->RefInputDone( sal_True );               // finish ref input
513         }
514         else
515         {
516             m_pDlg->RefInputDone( sal_True );               // another active ref edit?
517             m_pDlg->RefInputStart( pEdit, pButton );    // start ref input
518             // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
519             if( pRefEdit )
520                 pRefEdit->GrabFocus();
521         }
522     }
523 }
524 // -----------------------------------------------------------------------------
525 sal_Bool ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )
526 {
527     SfxApplication* pSfxApp = SFX_APP();
528 
529     SetDispatcherLock( sal_False );         //! here and in dtor ?
530 
531     SfxViewFrame* pViewFrm = SfxViewFrame::Current();
532     if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) )
533     {
534         //  Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch
535         //  per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow),
536         //  damit die Buttons auch wieder enabled gezeichnet werden.
537         SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS);
538         if (pChild)
539         {
540             ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
541             pWin->Enable();
542         }
543     }
544 
545     // find parent view frame to close dialog
546     SfxViewFrame* pMyViewFrm = NULL;
547     if ( m_pBindings )
548     {
549         SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher();
550         if (pMyDisp)
551             pMyViewFrm = pMyDisp->GetFrame();
552     }
553     SC_MOD()->SetRefDialog( nId, sal_False, pMyViewFrm );
554 
555     pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
556 
557     ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
558     if ( pScViewShell )
559         pScViewShell->UpdateInputHandler(sal_True);
560 
561     return sal_True;
562 }
563 void ScFormulaReferenceHelper::SetDispatcherLock( sal_Bool bLock )
564 {
565     //  lock / unlock only the dispatchers of Calc documents
566 
567     TypeId aType(TYPE(ScDocShell));
568     ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
569     while( pDocShell )
570     {
571         SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
572         while( pFrame )
573         {
574             SfxDispatcher* pDisp = pFrame->GetDispatcher();
575             if (pDisp)
576                 pDisp->Lock( bLock );
577 
578             pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
579         }
580         pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
581     }
582 
583     //  if a new view is created while the dialog is open,
584     //  that view's dispatcher is locked when trying to create the dialog
585     //  for that view (ScTabViewShell::CreateRefDialog)
586 }
587 // -----------------------------------------------------------------------------
588 void ScFormulaReferenceHelper::ViewShellChanged(ScTabViewShell* /* pScViewShell */)
589 {
590     enableInput( sal_False );
591 
592     EnableSpreadsheets();
593 }
594 void ScFormulaReferenceHelper::EnableSpreadsheets(sal_Bool bFlag, sal_Bool bChilds)
595 {
596     TypeId aType(TYPE(ScDocShell));
597     ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
598     while( pDocShell )
599     {
600         SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
601         while( pFrame )
602         {
603             //  #71577# enable everything except InPlace, including bean frames
604             if ( !pFrame->GetFrame().IsInPlace() )
605             {
606                 SfxViewShell* p = pFrame->GetViewShell();
607                 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
608                 if(pViewSh!=NULL)
609                 {
610                     Window *pWin=pViewSh->GetWindow();
611                     if(pWin)
612                     {
613                         Window *pParent=pWin->GetParent();
614                         if(pParent)
615                         {
616                             pParent->EnableInput(bFlag,sal_False);
617                             if(bChilds)
618                                 pViewSh->EnableRefInput(bFlag);
619                         }
620                     }
621                 }
622             }
623             pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
624         }
625 
626         pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
627     }
628 }
629 
630 //----------------------------------------------------------------------------
631 
632 
633 
634 void lcl_InvalidateWindows()
635 {
636     TypeId aType(TYPE(ScDocShell));
637     ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
638     while( pDocShell )
639     {
640         SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
641         while( pFrame )
642         {
643             //  #71577# enable everything except InPlace, including bean frames
644             if ( !pFrame->GetFrame().IsInPlace() )
645             {
646                 SfxViewShell* p = pFrame->GetViewShell();
647                 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
648                 if(pViewSh!=NULL)
649                 {
650                     Window *pWin=pViewSh->GetWindow();
651                     if(pWin)
652                     {
653                         Window *pParent=pWin->GetParent();
654                         if(pParent)
655                             pParent->Invalidate();
656                     }
657                 }
658             }
659             pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
660         }
661 
662         pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
663     }
664 }
665 //----------------------------------------------------------------------------
666 
667 void lcl_HideAllReferences()
668 {
669     TypeId aScType = TYPE(ScTabViewShell);
670     SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
671     while ( pSh )
672     {
673         ((ScTabViewShell*)pSh)->ClearHighlightRanges();
674         pSh = SfxViewShell::GetNext( *pSh, &aScType );
675     }
676 }
677 
678 //============================================================================
679 //The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
680 //  class ScRefHandler
681 //----------------------------------------------------------------------------
682 
683 ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB/*, SfxChildWindow* pCW,
684                           Window* pParent, sal_uInt16 nResId*/, bool bBindRef )
685     :   //SfxModelessDialog ( pB, pCW, pParent, ScResId( nResId ) ),
686         m_rWindow( rWindow ),
687         m_bInRefMode( false ),
688         m_aHelper(this,pB),
689         pMyBindings( pB ),
690         pActiveWin(NULL)
691 {
692     m_aHelper.SetWindow(/*this*/&m_rWindow);
693     if(m_rWindow.GetHelpId().getLength()==0)                //Hack, da im SfxModelessDialog die HelpId
694         m_rWindow.SetHelpId(m_rWindow.GetUniqueId());   //fuer einen ModelessDialog entfernt und
695                                     //in eine UniqueId gewandelt wird, machen
696                                     //wir das an dieser Stelle rueckgaengig.
697     aTimer.SetTimeout(200);
698     aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl));
699 
700     if( bBindRef ) EnterRefMode();
701 }
702 
703 bool ScRefHandler::EnterRefMode()
704 {
705     if( m_bInRefMode ) return false;
706 
707     SC_MOD()->InputEnterHandler();
708 //    ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
709 
710     ScTabViewShell* pScViewShell = NULL;
711 
712     // title has to be from the view that opened the dialog,
713     // even if it's not the current view
714 
715     SfxObjectShell* pParentDoc = NULL;
716     if ( pMyBindings )
717     {
718         SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher();
719         if (pMyDisp)
720         {
721             SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
722             if (pMyViewFrm)
723             {
724                 pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
725                 if( pScViewShell )
726                     pScViewShell->UpdateInputHandler(sal_True);
727                 pParentDoc = pMyViewFrm->GetObjectShell();
728             }
729         }
730     }
731     if ( !pParentDoc && pScViewShell )                  // use current only if above fails
732         pParentDoc = pScViewShell->GetObjectShell();
733     if ( pParentDoc )
734         aDocName = pParentDoc->GetTitle();
735 
736     ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
737 
738     DBG_ASSERT( pInputHdl, "Missing input handler :-/" );
739 
740     if ( pInputHdl )
741         pInputHdl->NotifyChange( NULL );
742 
743     m_aHelper.enableInput( sal_False );
744 
745     m_aHelper.EnableSpreadsheets();
746 
747     m_aHelper.Init();
748 
749     m_aHelper.SetDispatcherLock( sal_True );
750     //@Test
751     //SFX_APPWINDOW->Disable(sal_True);   //@BugID 54702
752 
753     return m_bInRefMode = true;
754 }
755 
756 //----------------------------------------------------------------------------
757 
758 ScRefHandler::~ScRefHandler()
759 {
760     LeaveRefMode();
761 }
762 
763 bool ScRefHandler::LeaveRefMode()
764 {
765     if( !m_bInRefMode ) return false;
766 
767     lcl_HideAllReferences();
768 
769     if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) )
770         pDlg->SetModalInputMode(sal_False);
771     SetDispatcherLock( sal_False );         //! here and in DoClose ?
772 
773     ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
774     if( pScViewShell )
775         pScViewShell->UpdateInputHandler(sal_True);
776 
777     //SFX_APPWINDOW->Enable(sal_True,sal_True);
778     lcl_InvalidateWindows();
779 
780     m_bInRefMode = false;
781     return true;
782 }
783 
784 //----------------------------------------------------------------------------
785 
786 //SfxBindings& ScRefHandler::GetBindings()
787 //{
788 //  //! SfxModelessDialog should allow access to pBindings pointer
789 //
790 //  return *pMyBindings;
791 //}
792 
793 //----------------------------------------------------------------------------
794 
795 void ScRefHandler::SwitchToDocument()
796 {
797     ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell();
798     if (pCurrent)
799     {
800         SfxObjectShell* pObjSh = pCurrent->GetObjectShell();
801         if ( pObjSh && pObjSh->GetTitle() == aDocName )
802         {
803             //  right document already visible -> nothing to do
804             return;
805         }
806     }
807 
808     TypeId aScType = TYPE(ScTabViewShell);
809     SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
810     while ( pSh )
811     {
812         SfxObjectShell* pObjSh = pSh->GetObjectShell();
813         if ( pObjSh && pObjSh->GetTitle() == aDocName )
814         {
815             //  switch to first TabViewShell for document
816             ((ScTabViewShell*)pSh)->SetActive();
817             return;
818         }
819         pSh = SfxViewShell::GetNext( *pSh, &aScType );
820     }
821 }
822 
823 //----------------------------------------------------------------------------
824 
825 sal_Bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const   // pDocSh may be 0
826 {
827     //  default: allow only same document (overridden in function dialog)
828     String aCmpName;
829     if ( pDocSh )
830         aCmpName = pDocSh->GetTitle();
831 
832     //  if aDocName isn't initialized, allow
833     return ( aDocName.Len() == 0 || aDocName == aCmpName );
834 }
835 
836 //----------------------------------------------------------------------------
837 
838 sal_Bool __EXPORT ScRefHandler::IsRefInputMode() const
839 {
840     return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen
841 }
842 
843 //----------------------------------------------------------------------------
844 
845 sal_Bool __EXPORT ScRefHandler::DoClose( sal_uInt16 nId )
846 {
847     m_aHelper.DoClose(nId);
848     return sal_True;
849 }
850 
851 void ScRefHandler::SetDispatcherLock( sal_Bool bLock )
852 {
853     m_aHelper.SetDispatcherLock( bLock );
854 }
855 
856 //----------------------------------------------------------------------------
857 
858 void ScRefHandler::ViewShellChanged(ScTabViewShell*  pScViewShell )
859 {
860     m_aHelper.ViewShellChanged(pScViewShell);
861 }
862 
863 //----------------------------------------------------------------------------
864 
865 void ScRefHandler::AddRefEntry()
866 {
867     //  wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen
868 }
869 
870 //----------------------------------------------------------------------------
871 
872 sal_Bool __EXPORT ScRefHandler::IsTableLocked() const
873 {
874     // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
875 
876     return sal_False;
877 }
878 
879 //----------------------------------------------------------------------------
880 //
881 //  RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld
882 //  (per Button oder Bewegung)
883 //
884 //----------------------------------------------------------------------------
885 
886 void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
887 {
888     m_aHelper.RefInputStart( pEdit, pButton );
889 }
890 
891 
892 void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
893 {
894     m_aHelper.ToggleCollapsed( pEdit, pButton );
895 }
896 
897 //The two following function is commentted out by PengYunQuan for Validity Cell Range Picker
898 //long ScAnyRefDlg::PreNotify( NotifyEvent& rNEvt )
899 //{
900 //  sal_uInt16 nSwitch=rNEvt.GetType();
901 //  if(nSwitch==EVENT_GETFOCUS)
902 //  {
903 //      pActiveWin=rNEvt.GetWindow();
904 //  }
905 //  return SfxModelessDialog::PreNotify(rNEvt);
906 //}
907 //
908 //void ScAnyRefDlg::StateChanged( StateChangedType nStateChange )
909 //{
910 //  SfxModelessDialog::StateChanged( nStateChange );
911 //
912 //  if(nStateChange == STATE_CHANGE_VISIBLE)
913 //  {
914 //      if(IsVisible())
915 //      {
916 //          m_aHelper.enableInput( sal_False );
917 //          m_aHelper.EnableSpreadsheets();
918 //          m_aHelper.SetDispatcherLock( sal_True );
919 //          aTimer.Start();
920 //      }
921 //      else
922 //      {
923 //          m_aHelper.enableInput( sal_True );
924 //          m_aHelper.SetDispatcherLock( sal_False );           //! here and in DoClose ?
925 //      }
926 //  }
927 //}
928 
929 #if defined( _MSC_VER )
930 #define INTRODUCE_TEMPLATE
931 #else
932 #define INTRODUCE_TEMPLATE  template <>
933 #endif
934 
935 #define IMPL_TWINDOW_PRENOTIFY( TWindow,bBindRef )  \
936 INTRODUCE_TEMPLATE long ScRefHdlrImplBase<TWindow,bBindRef>::PreNotify( NotifyEvent& rNEvt )\
937 {\
938     if( bBindRef || m_bInRefMode )\
939     {\
940         sal_uInt16 nSwitch=rNEvt.GetType();\
941         if(nSwitch==EVENT_GETFOCUS)\
942         {\
943             pActiveWin=rNEvt.GetWindow();\
944         }\
945     }\
946     return TWindow::PreNotify(rNEvt);\
947 }
948 
949 #define IMPL_TWINDOW_STATECHANGED( TWindow,bBindRef )   \
950 INTRODUCE_TEMPLATE void ScRefHdlrImplBase<TWindow,bBindRef>::StateChanged( StateChangedType nStateChange )\
951 {\
952     TWindow::StateChanged( nStateChange );\
953 \
954     if( !bBindRef && !m_bInRefMode ) return;\
955     \
956     if(nStateChange == STATE_CHANGE_VISIBLE)\
957     {\
958         if(m_rWindow.IsVisible())\
959         {\
960             m_aHelper.enableInput( sal_False );\
961             m_aHelper.EnableSpreadsheets();\
962             m_aHelper.SetDispatcherLock( sal_True );\
963             aTimer.Start();\
964         }\
965         else\
966         {\
967             m_aHelper.enableInput( sal_True );\
968             m_aHelper.SetDispatcherLock( sal_False );           /*//! here and in DoClose ?*/\
969         }\
970     }\
971 }
972 
973 IMPL_TWINDOW_PRENOTIFY( SfxModelessDialog, true )
974 IMPL_TWINDOW_PRENOTIFY( SfxTabDialog, false )
975 IMPL_TWINDOW_STATECHANGED( SfxModelessDialog, true )
976 IMPL_TWINDOW_STATECHANGED( SfxTabDialog, false )
977 
978 IMPL_LINK( ScRefHandler, UpdateFocusHdl, Timer*, EMPTYARG )
979 {
980     if (pActiveWin)
981     {
982         pActiveWin->GrabFocus();
983     }
984     return 0;
985 }
986 // -----------------------------------------------------------------------------
987 bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
988 {
989     return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
990 }
991 // -----------------------------------------------------------------------------
992 void ScRefHandler::HideReference( sal_Bool bDoneRefMode )
993 {
994     m_aHelper.HideReference( bDoneRefMode );
995 }
996 // -----------------------------------------------------------------------------
997 void ScRefHandler::ShowReference( const XubString& rStr )
998 {
999     m_aHelper.ShowReference( rStr );
1000 }
1001 // -----------------------------------------------------------------------------
1002 void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
1003 {
1004     m_aHelper.ReleaseFocus( pEdit,pButton );
1005 }
1006 //----------------------------------------------------------------------------
1007 void ScRefHandler::RefInputDone( sal_Bool bForced )
1008 {
1009     m_aHelper.RefInputDone( bForced );
1010 }
1011 
1012