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