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