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