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 "formulacell.hxx"
41 : #include "global.hxx"
42 : #include "inputopt.hxx"
43 : #include "rangeutl.hxx"
44 : #include "tokenarray.hxx"
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 : , nRefTab(0)
53 : , mnOldEditWidthReq( -1 )
54 : , mpOldEditParent( NULL )
55 : , mbOldDlgLayoutEnabled( false )
56 : , mbOldEditParentLayoutEnabled( false )
57 : , bHighLightRef( false )
58 0 : , bAccInserted( false )
59 : {
60 0 : ScInputOptions aInputOption=SC_MOD()->GetInputOptions();
61 0 : bEnableColorRef=aInputOption.GetRangeFinder();
62 0 : }
63 : // -----------------------------------------------------------------------------
64 0 : ScFormulaReferenceHelper::~ScFormulaReferenceHelper()
65 : {
66 0 : if (bAccInserted)
67 0 : Application::RemoveAccel( pAccel.get() );
68 :
69 : // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
70 :
71 0 : HideReference();
72 0 : enableInput( true );
73 :
74 0 : ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
75 0 : if ( pInputHdl )
76 0 : pInputHdl->ResetDelayTimer(); // stop the timer for disabling the input line
77 0 : }
78 : // -----------------------------------------------------------------------------
79 0 : void ScFormulaReferenceHelper::enableInput( bool bEnable )
80 : {
81 0 : TypeId aType(TYPE(ScDocShell));
82 0 : ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
83 0 : while( pDocShell )
84 : {
85 0 : SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
86 0 : while( pFrame )
87 : {
88 : // enable everything except InPlace, including bean frames
89 0 : if ( !pFrame->GetFrame().IsInPlace() )
90 : {
91 0 : SfxViewShell* p = pFrame->GetViewShell();
92 0 : ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
93 0 : if(pViewSh!=NULL)
94 : {
95 0 : Window *pWin=pViewSh->GetWindow();
96 0 : if(pWin)
97 : {
98 0 : Window *pParent=pWin->GetParent();
99 0 : if(pParent)
100 : {
101 0 : pParent->EnableInput(bEnable,true);
102 : if(true)
103 0 : pViewSh->EnableRefInput(bEnable);
104 : }
105 : }
106 : }
107 : }
108 0 : pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
109 : }
110 :
111 0 : pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
112 : }
113 0 : }
114 : // -----------------------------------------------------------------------------
115 0 : void ScFormulaReferenceHelper::ShowSimpleReference( const XubString& rStr )
116 : {
117 0 : if( bEnableColorRef )
118 : {
119 0 : bHighLightRef=true;
120 0 : ScViewData* pViewData=ScDocShell::GetViewData();
121 0 : if ( pViewData )
122 : {
123 0 : ScDocument* pDoc=pViewData->GetDocument();
124 0 : ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
125 :
126 0 : ScRangeList aRangeList;
127 :
128 0 : pTabViewShell->DoneRefMode( false );
129 0 : pTabViewShell->ClearHighlightRanges();
130 :
131 0 : if( ParseWithNames( aRangeList, rStr, pDoc ) )
132 : {
133 0 : for ( size_t i = 0, nRanges = aRangeList.size(); i < nRanges; ++i )
134 : {
135 0 : ScRange* pRangeEntry = aRangeList[ i ];
136 0 : ColorData aColName = ScRangeFindList::GetColorName( i );
137 0 : pTabViewShell->AddHighlightRange( *pRangeEntry, aColName );
138 : }
139 0 : }
140 : }
141 : }
142 0 : }
143 : // -----------------------------------------------------------------------------
144 0 : bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
145 : {
146 0 : bool bError = false;
147 0 : rRanges.RemoveAll();
148 :
149 0 : ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
150 0 : ScRangeUtil aRangeUtil;
151 0 : xub_StrLen nTokenCnt = comphelper::string::getTokenCount(rStr, ';');
152 0 : for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
153 : {
154 0 : ScRange aRange;
155 0 : String aRangeStr( rStr.GetToken( nToken ) );
156 :
157 0 : sal_uInt16 nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails );
158 0 : if ( nFlags & SCA_VALID )
159 : {
160 0 : if ( (nFlags & SCA_TAB_3D) == 0 )
161 0 : aRange.aStart.SetTab( nRefTab );
162 0 : if ( (nFlags & SCA_TAB2_3D) == 0 )
163 0 : aRange.aEnd.SetTab( aRange.aStart.Tab() );
164 0 : rRanges.Append( aRange );
165 : }
166 0 : else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) )
167 0 : rRanges.Append( aRange );
168 : else
169 0 : bError = true;
170 0 : }
171 :
172 0 : return !bError;
173 : }
174 : // -----------------------------------------------------------------------------
175 0 : void ScFormulaReferenceHelper::ShowFormulaReference( const XubString& rStr )
176 : {
177 0 : if( bEnableColorRef)
178 : {
179 0 : bHighLightRef=true;
180 0 : ScViewData* pViewData=ScDocShell::GetViewData();
181 0 : if ( pViewData && pRefComp.get() )
182 : {
183 0 : ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
184 0 : SCCOL nCol = pViewData->GetCurX();
185 0 : SCROW nRow = pViewData->GetCurY();
186 0 : SCTAB nTab = pViewData->GetTabNo();
187 0 : ScAddress aPos( nCol, nRow, nTab );
188 :
189 0 : ScTokenArray* pScTokA=pRefComp->CompileString(rStr);
190 : //pRefComp->CompileTokenArray();
191 :
192 0 : if(pTabViewShell!=NULL && pScTokA!=NULL)
193 : {
194 0 : pTabViewShell->DoneRefMode( false );
195 0 : pTabViewShell->ClearHighlightRanges();
196 :
197 0 : pScTokA->Reset();
198 0 : const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
199 :
200 0 : sal_uInt16 nIndex=0;
201 :
202 0 : while(pToken!=NULL)
203 : {
204 0 : bool bDoubleRef=(pToken->GetType()==formula::svDoubleRef);
205 :
206 :
207 0 : if(pToken->GetType()==formula::svSingleRef || bDoubleRef)
208 : {
209 0 : ScRange aRange;
210 0 : if(bDoubleRef)
211 : {
212 0 : ScComplexRefData aRef( pToken->GetDoubleRef() );
213 0 : aRef.CalcAbsIfRel( aPos );
214 0 : aRange.aStart.Set( aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab );
215 0 : aRange.aEnd.Set( aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab );
216 : }
217 : else
218 : {
219 0 : ScSingleRefData aRef( pToken->GetSingleRef() );
220 0 : aRef.CalcAbsIfRel( aPos );
221 0 : aRange.aStart.Set( aRef.nCol, aRef.nRow, aRef.nTab );
222 0 : aRange.aEnd = aRange.aStart;
223 : }
224 0 : ColorData aColName=ScRangeFindList::GetColorName(nIndex++);
225 0 : pTabViewShell->AddHighlightRange(aRange, aColName);
226 : }
227 :
228 0 : pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
229 : }
230 : }
231 0 : if(pScTokA!=NULL) delete pScTokA;
232 : }
233 : }
234 0 : }
235 : // -----------------------------------------------------------------------------
236 0 : void ScFormulaReferenceHelper::HideReference( bool bDoneRefMode )
237 : {
238 0 : ScViewData* pViewData=ScDocShell::GetViewData();
239 :
240 0 : if( pViewData && bHighLightRef && bEnableColorRef)
241 : {
242 0 : ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
243 :
244 0 : if(pTabViewShell!=NULL)
245 : {
246 : // bDoneRefMode is sal_False when called from before SetReference.
247 : // In that case, RefMode was just started and must not be ended now.
248 :
249 0 : if ( bDoneRefMode )
250 0 : pTabViewShell->DoneRefMode( false );
251 0 : pTabViewShell->ClearHighlightRanges();
252 : }
253 0 : bHighLightRef=false;
254 : }
255 0 : }
256 : // -----------------------------------------------------------------------------
257 0 : void ScFormulaReferenceHelper::ShowReference( const XubString& rStr )
258 : {
259 0 : if( bEnableColorRef )
260 : {
261 0 : if( 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 0 : rStr.Search('=')!=STRING_NOTFOUND ||
270 0 : rStr.Search('^')!=STRING_NOTFOUND)
271 : {
272 0 : ShowFormulaReference(rStr);
273 : }
274 : else
275 : {
276 0 : ShowSimpleReference(rStr);
277 : }
278 : }
279 0 : }
280 : // -----------------------------------------------------------------------------
281 0 : void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
282 : {
283 0 : if( !pRefEdit && pEdit )
284 : {
285 0 : m_pDlg->RefInputStart( pEdit, pButton );
286 : }
287 :
288 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
289 0 : if( pViewShell )
290 : {
291 0 : pViewShell->ActiveGrabFocus();
292 0 : if( pRefEdit )
293 : {
294 0 : const ScViewData* pViewData = pViewShell->GetViewData();
295 0 : ScDocument* pDoc = pViewData->GetDocument();
296 0 : ScRangeList aRangeList;
297 0 : if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) )
298 : {
299 0 : if ( !aRangeList.empty() )
300 : {
301 0 : const ScRange* pRange = aRangeList.front();
302 0 : pViewShell->SetTabNo( pRange->aStart.Tab() );
303 0 : pViewShell->MoveCursorAbs( pRange->aStart.Col(),
304 0 : pRange->aStart.Row(), SC_FOLLOW_JUMP, false, false );
305 0 : pViewShell->MoveCursorAbs( pRange->aEnd.Col(),
306 0 : pRange->aEnd.Row(), SC_FOLLOW_JUMP, true, false );
307 0 : m_pDlg->SetReference( *pRange, pDoc );
308 : }
309 0 : }
310 : }
311 : }
312 0 : }
313 : // -----------------------------------------------------------------------------
314 0 : void ScFormulaReferenceHelper::Init()
315 : {
316 0 : ScViewData* pViewData=ScDocShell::GetViewData(); //! use pScViewShell?
317 0 : if ( pViewData )
318 : {
319 0 : ScDocument* pDoc = pViewData->GetDocument();
320 0 : SCCOL nCol = pViewData->GetCurX();
321 0 : SCROW nRow = pViewData->GetCurY();
322 0 : SCTAB nTab = pViewData->GetTabNo();
323 0 : ScAddress aCursorPos( nCol, nRow, nTab );
324 :
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 : typedef std::vector<Window*> winvec;
351 :
352 0 : void ScFormulaReferenceHelper::RefInputDone( bool bForced )
353 : {
354 0 : if ( CanInputDone( bForced ) )
355 : {
356 0 : if (bAccInserted) // Accelerator wieder abschalten
357 : {
358 0 : Application::RemoveAccel( pAccel.get() );
359 0 : bAccInserted = false;
360 : }
361 :
362 : //get rid of all this junk when we can
363 0 : if (!mbOldDlgLayoutEnabled)
364 : {
365 0 : m_pWindow->SetOutputSizePixel(aOldDialogSize);
366 :
367 : // restore the parent of the edit field
368 0 : pRefEdit->SetParent(mpOldEditParent);
369 :
370 : // Fenster wieder gross
371 0 : m_pWindow->SetOutputSizePixel(aOldDialogSize);
372 :
373 : // set button parent
374 0 : if( pRefBtn )
375 : {
376 0 : pRefBtn->SetParent(m_pWindow);
377 : }
378 : }
379 :
380 0 : if (!mbOldEditParentLayoutEnabled)
381 : {
382 : // pEditCell an alte Position
383 0 : pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize);
384 :
385 : // set button position
386 0 : if( pRefBtn )
387 : {
388 0 : pRefBtn->SetPosPixel( aOldButtonPos );
389 : }
390 : }
391 :
392 : // Fenstertitel anpassen
393 0 : m_pWindow->SetText(sOldDialogText);
394 :
395 : // set button image
396 0 : if( pRefBtn )
397 0 : pRefBtn->SetStartImage();
398 :
399 : // Alle anderen: Show();
400 0 : for (winvec::iterator aI = m_aHiddenWidgets.begin(); aI != m_aHiddenWidgets.end(); ++aI)
401 : {
402 0 : Window *pWindow = *aI;
403 0 : pWindow->Show();
404 : }
405 0 : m_aHiddenWidgets.clear();
406 :
407 0 : if (mbOldDlgLayoutEnabled)
408 : {
409 0 : pRefEdit->set_width_request(mnOldEditWidthReq);
410 0 : Dialog* pResizeDialog = pRefEdit->GetParentDialog();
411 0 : pResizeDialog->set_border_width(m_nOldBorderWidth);
412 0 : if (Window *pActionArea = pResizeDialog->get_action_area())
413 0 : pActionArea->Show();
414 0 : pResizeDialog->setOptimalLayoutSize();
415 : }
416 :
417 0 : pRefEdit = NULL;
418 0 : pRefBtn = NULL;
419 : }
420 0 : }
421 :
422 : typedef std::set<Window*> winset;
423 :
424 : namespace
425 : {
426 0 : void hideUnless(Window *pTop, const winset& rVisibleWidgets,
427 : winvec &rWasVisibleWidgets)
428 : {
429 0 : for (Window* pChild = pTop->GetWindow(WINDOW_FIRSTCHILD); pChild;
430 0 : pChild = pChild->GetWindow(WINDOW_NEXT))
431 : {
432 0 : if (!pChild->IsVisible())
433 0 : continue;
434 0 : if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
435 : {
436 0 : rWasVisibleWidgets.push_back(pChild);
437 0 : pChild->Hide();
438 : }
439 0 : else if (isContainerWindow(pChild))
440 : {
441 0 : hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
442 : }
443 : }
444 0 : }
445 : }
446 :
447 : // -----------------------------------------------------------------------------
448 0 : void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
449 : {
450 0 : if (!pRefEdit)
451 : {
452 0 : pRefEdit = pEdit;
453 0 : pRefBtn = pButton;
454 :
455 0 : mbOldDlgLayoutEnabled = isLayoutEnabled(m_pWindow);
456 0 : aOldEditSize = pRefEdit->GetSizePixel();
457 0 : mnOldEditWidthReq = pRefEdit->get_width_request();
458 0 : mpOldEditParent = pRefEdit->GetParent();
459 0 : mbOldEditParentLayoutEnabled = isContainerWindow(mpOldEditParent);
460 :
461 : //get rid of all the !mbOldDlgLayoutEnabled and
462 : //mbOldEditParentLayoutEnabled junk when we can after the last user of
463 : //this is widget-layout-ified
464 0 : if (!mbOldEditParentLayoutEnabled)
465 : {
466 : // Alte Daten merken
467 0 : aOldDialogSize = m_pWindow->GetOutputSizePixel();
468 0 : aOldEditPos = pRefEdit->GetPosPixel();
469 0 : if (pRefBtn)
470 0 : aOldButtonPos = pRefBtn->GetPosPixel();
471 : }
472 :
473 0 : if (!mbOldDlgLayoutEnabled)
474 : {
475 0 : pRefEdit->SetParent(m_pWindow);
476 0 : if(pRefBtn)
477 0 : pRefBtn->SetParent(m_pWindow);
478 : }
479 :
480 : // Fenstertitel anpassen
481 0 : sOldDialogText = m_pWindow->GetText();
482 0 : if (Window *pLabel = pRefEdit->GetLabelWidgetForShrinkMode())
483 : {
484 0 : OUString sLabel = pLabel->GetText();
485 0 : if (!sLabel.isEmpty())
486 : {
487 0 : String sNewDialogText = sOldDialogText;
488 0 : sNewDialogText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
489 0 : sNewDialogText += sLabel;
490 0 : m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) );
491 0 : }
492 : }
493 :
494 0 : Dialog* pResizeDialog = NULL;
495 :
496 0 : if (!mbOldDlgLayoutEnabled)
497 : {
498 0 : for (Window* pChild = m_pWindow->GetWindow(WINDOW_FIRSTCHILD); pChild;
499 0 : pChild = pChild->GetWindow(WINDOW_NEXT))
500 : {
501 0 : Window *pWin = pChild->GetWindow(WINDOW_CLIENT);
502 0 : if (pWin == (Window*)pRefEdit || pWin == (Window*)pRefBtn)
503 0 : continue; // do nothing
504 0 : else if (pWin->IsVisible())
505 : {
506 0 : m_aHiddenWidgets.push_back(pChild);
507 0 : pChild->Hide();
508 : }
509 : }
510 : }
511 : else
512 : {
513 : //We want just pRefBtn and pRefEdit to be shown
514 : //mark widgets we want to be visible, starting with pRefEdit
515 : //and all its direct parents.
516 0 : winset m_aVisibleWidgets;
517 0 : pResizeDialog = pRefEdit->GetParentDialog();
518 0 : Window *pContentArea = pResizeDialog->get_content_area();
519 0 : for (Window *pCandidate = pRefEdit;
520 0 : pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
521 0 : pCandidate = pCandidate->GetWindow(WINDOW_REALPARENT))
522 : {
523 0 : m_aVisibleWidgets.insert(pCandidate);
524 : }
525 : //same again with pRefBtn, except stop if there's a
526 : //shared parent in the existing widgets
527 0 : for (Window *pCandidate = pRefBtn;
528 0 : pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
529 0 : pCandidate = pCandidate->GetWindow(WINDOW_REALPARENT))
530 : {
531 0 : if (m_aVisibleWidgets.insert(pCandidate).second)
532 0 : break;
533 : }
534 :
535 : //hide everything except the m_aVisibleWidgets
536 0 : hideUnless(pContentArea, m_aVisibleWidgets, m_aHiddenWidgets);
537 : }
538 :
539 0 : if (!mbOldDlgLayoutEnabled)
540 : {
541 : // Edit-Feld verschieben und anpassen
542 0 : Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height());
543 0 : Size aNewEditSize(aNewDlgSize);
544 0 : long nOffset = 0;
545 0 : if (pRefBtn)
546 : {
547 0 : aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width();
548 0 : aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width());
549 :
550 0 : long nHeight = pRefBtn->GetSizePixel().Height();
551 0 : if ( nHeight > aOldEditSize.Height() )
552 : {
553 0 : aNewDlgSize.Height() = nHeight;
554 0 : nOffset = (nHeight-aOldEditSize.Height()) / 2;
555 : }
556 0 : aNewEditSize.Width() -= nOffset;
557 : }
558 0 : pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize);
559 :
560 : // set button position
561 0 : if( pRefBtn )
562 0 : pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) );
563 :
564 : // Fenster verkleinern
565 0 : m_pWindow->SetOutputSizePixel(aNewDlgSize);
566 : }
567 :
568 : // set button image
569 0 : if( pRefBtn )
570 0 : pRefBtn->SetEndImage();
571 :
572 0 : if (!pAccel.get())
573 : {
574 0 : pAccel.reset( new Accelerator );
575 0 : pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) );
576 0 : pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) );
577 0 : pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) );
578 : }
579 0 : Application::InsertAccel( pAccel.get() );
580 0 : bAccInserted = true;
581 :
582 0 : if (mbOldDlgLayoutEnabled)
583 : {
584 0 : pRefEdit->set_width_request(aOldEditSize.Width());
585 0 : m_nOldBorderWidth = pResizeDialog->get_border_width();
586 0 : pResizeDialog->set_border_width(0);
587 0 : if (Window *pActionArea = pResizeDialog->get_action_area())
588 0 : pActionArea->Hide();
589 0 : pResizeDialog->setOptimalLayoutSize();
590 : }
591 : }
592 0 : }
593 : // -----------------------------------------------------------------------------
594 0 : void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
595 : {
596 0 : if( pEdit )
597 : {
598 0 : if( pRefEdit == pEdit ) // is this the active ref edit field?
599 : {
600 0 : pRefEdit->GrabFocus(); // before RefInputDone()
601 0 : m_pDlg->RefInputDone( true ); // finish ref input
602 : }
603 : else
604 : {
605 0 : m_pDlg->RefInputDone( true ); // another active ref edit?
606 0 : m_pDlg->RefInputStart( pEdit, pButton ); // start ref input
607 : // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
608 0 : if( pRefEdit )
609 0 : pRefEdit->GrabFocus();
610 : }
611 : }
612 0 : }
613 : // -----------------------------------------------------------------------------
614 0 : bool ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )
615 : {
616 0 : SfxApplication* pSfxApp = SFX_APP();
617 :
618 0 : SetDispatcherLock( false ); //! here and in dtor ?
619 :
620 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
621 0 : if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) )
622 : {
623 : // Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch
624 : // per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow),
625 : // damit die Buttons auch wieder enabled gezeichnet werden.
626 0 : SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS);
627 0 : if (pChild)
628 : {
629 0 : ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
630 0 : pWin->Enable();
631 : }
632 : }
633 :
634 : // find parent view frame to close dialog
635 0 : SfxViewFrame* pMyViewFrm = NULL;
636 0 : if ( m_pBindings )
637 : {
638 0 : SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher();
639 0 : if (pMyDisp)
640 0 : pMyViewFrm = pMyDisp->GetFrame();
641 : }
642 0 : SC_MOD()->SetRefDialog( nId, false, pMyViewFrm );
643 :
644 0 : pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
645 :
646 0 : ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
647 0 : if ( pScViewShell )
648 0 : pScViewShell->UpdateInputHandler(true);
649 :
650 0 : return true;
651 : }
652 0 : void ScFormulaReferenceHelper::SetDispatcherLock( bool bLock )
653 : {
654 : // lock / unlock only the dispatchers of Calc documents
655 :
656 0 : TypeId aType(TYPE(ScDocShell));
657 0 : ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
658 0 : while( pDocShell )
659 : {
660 0 : SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
661 0 : while( pFrame )
662 : {
663 0 : SfxDispatcher* pDisp = pFrame->GetDispatcher();
664 0 : if (pDisp)
665 0 : pDisp->Lock( bLock );
666 :
667 0 : pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
668 : }
669 0 : pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
670 : }
671 :
672 : // if a new view is created while the dialog is open,
673 : // that view's dispatcher is locked when trying to create the dialog
674 : // for that view (ScTabViewShell::CreateRefDialog)
675 0 : }
676 : // -----------------------------------------------------------------------------
677 0 : void ScFormulaReferenceHelper::ViewShellChanged()
678 : {
679 0 : enableInput( false );
680 :
681 0 : EnableSpreadsheets();
682 0 : }
683 0 : void ScFormulaReferenceHelper::EnableSpreadsheets(bool bFlag, bool bChildren)
684 : {
685 0 : TypeId aType(TYPE(ScDocShell));
686 0 : ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
687 0 : while( pDocShell )
688 : {
689 0 : SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
690 0 : while( pFrame )
691 : {
692 : // enable everything except InPlace, including bean frames
693 0 : if ( !pFrame->GetFrame().IsInPlace() )
694 : {
695 0 : SfxViewShell* p = pFrame->GetViewShell();
696 0 : ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
697 0 : if(pViewSh!=NULL)
698 : {
699 0 : Window *pWin=pViewSh->GetWindow();
700 0 : if(pWin)
701 : {
702 0 : Window *pParent=pWin->GetParent();
703 0 : if(pParent)
704 : {
705 0 : pParent->EnableInput(bFlag,false);
706 0 : if(bChildren)
707 0 : pViewSh->EnableRefInput(bFlag);
708 : }
709 : }
710 : }
711 : }
712 0 : pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
713 : }
714 :
715 0 : pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
716 : }
717 0 : }
718 :
719 : //----------------------------------------------------------------------------
720 :
721 :
722 :
723 0 : static void lcl_InvalidateWindows()
724 : {
725 0 : TypeId aType(TYPE(ScDocShell));
726 0 : ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
727 0 : while( pDocShell )
728 : {
729 0 : SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
730 0 : while( pFrame )
731 : {
732 : // enable everything except InPlace, including bean frames
733 0 : if ( !pFrame->GetFrame().IsInPlace() )
734 : {
735 0 : SfxViewShell* p = pFrame->GetViewShell();
736 0 : ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
737 0 : if(pViewSh!=NULL)
738 : {
739 0 : Window *pWin=pViewSh->GetWindow();
740 0 : if(pWin)
741 : {
742 0 : Window *pParent=pWin->GetParent();
743 0 : if(pParent)
744 0 : pParent->Invalidate();
745 : }
746 : }
747 : }
748 0 : pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
749 : }
750 :
751 0 : pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
752 : }
753 0 : }
754 : //----------------------------------------------------------------------------
755 :
756 0 : static void lcl_HideAllReferences()
757 : {
758 0 : TypeId aScType = TYPE(ScTabViewShell);
759 0 : SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
760 0 : while ( pSh )
761 : {
762 0 : ((ScTabViewShell*)pSh)->ClearHighlightRanges();
763 0 : pSh = SfxViewShell::GetNext( *pSh, &aScType );
764 : }
765 0 : }
766 :
767 : //============================================================================
768 : //The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
769 : // class ScRefHandler
770 : //----------------------------------------------------------------------------
771 :
772 0 : ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB, bool bBindRef ):
773 : m_rWindow( rWindow ),
774 : m_bInRefMode( false ),
775 : m_aHelper(this,pB),
776 : pMyBindings( pB ),
777 0 : pActiveWin(NULL)
778 : {
779 0 : m_aHelper.SetWindow(&m_rWindow);
780 0 : reverseUniqueHelpIdHack(m_rWindow);
781 0 : aTimer.SetTimeout(200);
782 0 : aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl));
783 :
784 0 : if( bBindRef ) EnterRefMode();
785 0 : }
786 :
787 0 : bool ScRefHandler::EnterRefMode()
788 : {
789 0 : if( m_bInRefMode ) return false;
790 :
791 0 : SC_MOD()->InputEnterHandler();
792 :
793 0 : ScTabViewShell* pScViewShell = NULL;
794 :
795 : // title has to be from the view that opened the dialog,
796 : // even if it's not the current view
797 :
798 0 : SfxObjectShell* pParentDoc = NULL;
799 0 : if ( pMyBindings )
800 : {
801 0 : SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher();
802 0 : if (pMyDisp)
803 : {
804 0 : SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
805 0 : if (pMyViewFrm)
806 : {
807 0 : pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
808 0 : if( pScViewShell )
809 0 : pScViewShell->UpdateInputHandler(sal_True);
810 0 : pParentDoc = pMyViewFrm->GetObjectShell();
811 : }
812 : }
813 : }
814 0 : if ( !pParentDoc && pScViewShell ) // use current only if above fails
815 0 : pParentDoc = pScViewShell->GetObjectShell();
816 0 : if ( pParentDoc )
817 0 : aDocName = pParentDoc->GetTitle();
818 :
819 0 : ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
820 :
821 : OSL_ENSURE( pInputHdl, "Missing input handler :-/" );
822 :
823 0 : if ( pInputHdl )
824 0 : pInputHdl->NotifyChange( NULL );
825 :
826 0 : m_aHelper.enableInput( false );
827 :
828 0 : m_aHelper.EnableSpreadsheets();
829 :
830 0 : m_aHelper.Init();
831 :
832 0 : m_aHelper.SetDispatcherLock( true );
833 :
834 0 : return m_bInRefMode = true;
835 : }
836 :
837 : //----------------------------------------------------------------------------
838 :
839 0 : ScRefHandler::~ScRefHandler()
840 : {
841 0 : LeaveRefMode();
842 0 : }
843 :
844 0 : bool ScRefHandler::LeaveRefMode()
845 : {
846 0 : if( !m_bInRefMode ) return false;
847 :
848 0 : lcl_HideAllReferences();
849 :
850 0 : if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) )
851 0 : pDlg->SetModalInputMode(false);
852 0 : SetDispatcherLock( false ); //! here and in DoClose ?
853 :
854 0 : ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
855 0 : if( pScViewShell )
856 0 : pScViewShell->UpdateInputHandler(sal_True);
857 :
858 0 : lcl_InvalidateWindows();
859 :
860 0 : m_bInRefMode = false;
861 0 : return true;
862 : }
863 :
864 : //----------------------------------------------------------------------------
865 :
866 0 : void ScRefHandler::SwitchToDocument()
867 : {
868 0 : ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell();
869 0 : if (pCurrent)
870 : {
871 0 : SfxObjectShell* pObjSh = pCurrent->GetObjectShell();
872 0 : if ( pObjSh && pObjSh->GetTitle() == aDocName )
873 : {
874 : // right document already visible -> nothing to do
875 0 : return;
876 : }
877 : }
878 :
879 0 : TypeId aScType = TYPE(ScTabViewShell);
880 0 : SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
881 0 : while ( pSh )
882 : {
883 0 : SfxObjectShell* pObjSh = pSh->GetObjectShell();
884 0 : if ( pObjSh && pObjSh->GetTitle() == aDocName )
885 : {
886 : // switch to first TabViewShell for document
887 0 : ((ScTabViewShell*)pSh)->SetActive();
888 0 : return;
889 : }
890 0 : pSh = SfxViewShell::GetNext( *pSh, &aScType );
891 : }
892 : }
893 :
894 : //----------------------------------------------------------------------------
895 :
896 0 : sal_Bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const // pDocSh may be 0
897 : {
898 : // default: allow only same document (overridden in function dialog)
899 0 : String aCmpName;
900 0 : if ( pDocSh )
901 0 : aCmpName = pDocSh->GetTitle();
902 :
903 : // if aDocName isn't initialized, allow
904 0 : return ( aDocName.Len() == 0 || aDocName == aCmpName );
905 : }
906 :
907 : //----------------------------------------------------------------------------
908 :
909 0 : sal_Bool ScRefHandler::IsRefInputMode() const
910 : {
911 0 : return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen
912 : }
913 :
914 : //----------------------------------------------------------------------------
915 :
916 0 : sal_Bool ScRefHandler::DoClose( sal_uInt16 nId )
917 : {
918 0 : m_aHelper.DoClose(nId);
919 0 : return sal_True;
920 : }
921 :
922 0 : void ScRefHandler::SetDispatcherLock( bool bLock )
923 : {
924 0 : m_aHelper.SetDispatcherLock( bLock );
925 0 : }
926 :
927 : //----------------------------------------------------------------------------
928 :
929 0 : void ScRefHandler::ViewShellChanged()
930 : {
931 0 : m_aHelper.ViewShellChanged();
932 0 : }
933 :
934 : //----------------------------------------------------------------------------
935 :
936 0 : void ScRefHandler::AddRefEntry()
937 : {
938 : // wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen
939 0 : }
940 :
941 : //----------------------------------------------------------------------------
942 :
943 0 : sal_Bool ScRefHandler::IsTableLocked() const
944 : {
945 : // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
946 :
947 0 : return false;
948 : }
949 :
950 : //----------------------------------------------------------------------------
951 : //
952 : // RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld
953 : // (per Button oder Bewegung)
954 : //
955 : //----------------------------------------------------------------------------
956 :
957 0 : void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
958 : {
959 0 : m_aHelper.RefInputStart( pEdit, pButton );
960 0 : }
961 :
962 :
963 0 : void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
964 : {
965 0 : m_aHelper.ToggleCollapsed( pEdit, pButton );
966 0 : }
967 :
968 0 : void ScRefHandler::preNotify(const NotifyEvent& rNEvt, const bool bBindRef)
969 : {
970 0 : if( bBindRef || m_bInRefMode )
971 : {
972 0 : sal_uInt16 nSwitch=rNEvt.GetType();
973 0 : if(nSwitch==EVENT_GETFOCUS)
974 : {
975 0 : pActiveWin=rNEvt.GetWindow();
976 : }
977 : }
978 0 : }
979 :
980 0 : void ScRefHandler::stateChanged(const StateChangedType nStateChange, const bool bBindRef)
981 : {
982 0 : if( !bBindRef && !m_bInRefMode ) return;
983 :
984 0 : if(nStateChange == STATE_CHANGE_VISIBLE)
985 : {
986 0 : if(m_rWindow.IsVisible())
987 : {
988 0 : m_aHelper.enableInput( false );
989 0 : m_aHelper.EnableSpreadsheets();
990 0 : m_aHelper.SetDispatcherLock( sal_True );
991 0 : aTimer.Start();
992 : }
993 : else
994 : {
995 0 : m_aHelper.enableInput( sal_True );
996 0 : m_aHelper.SetDispatcherLock( false ); /*//! here and in DoClose ?*/
997 : }
998 : }
999 : }
1000 :
1001 0 : IMPL_LINK_NOARG(ScRefHandler, UpdateFocusHdl)
1002 : {
1003 0 : if (pActiveWin)
1004 : {
1005 0 : pActiveWin->GrabFocus();
1006 : }
1007 0 : return 0;
1008 : }
1009 : // -----------------------------------------------------------------------------
1010 0 : bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
1011 : {
1012 0 : return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
1013 : }
1014 : // -----------------------------------------------------------------------------
1015 0 : void ScRefHandler::HideReference( sal_Bool bDoneRefMode )
1016 : {
1017 0 : m_aHelper.HideReference( bDoneRefMode );
1018 0 : }
1019 : // -----------------------------------------------------------------------------
1020 0 : void ScRefHandler::ShowReference( const XubString& rStr )
1021 : {
1022 0 : m_aHelper.ShowReference( rStr );
1023 0 : }
1024 : // -----------------------------------------------------------------------------
1025 0 : void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
1026 : {
1027 0 : m_aHelper.ReleaseFocus( pEdit,pButton );
1028 0 : }
1029 : //----------------------------------------------------------------------------
1030 0 : void ScRefHandler::RefInputDone( sal_Bool bForced )
1031 : {
1032 0 : m_aHelper.RefInputDone( bForced );
1033 0 : }
1034 :
1035 : //-------------------------------------------------------------------------------
1036 :
1037 0 : ScRefHdlModalImpl::ScRefHdlModalImpl( Window* pParent, ResId& rResId ):
1038 : ModalDialog( pParent, rResId ),
1039 0 : ScRefHandler(dynamic_cast<Window&>(*this), NULL, true) {}
1040 :
1041 0 : long ScRefHdlModalImpl::PreNotify( NotifyEvent& rNEvt )
1042 : {
1043 0 : ScRefHandler::preNotify( rNEvt, true );
1044 0 : return ModalDialog::PreNotify( rNEvt );
1045 : }
1046 :
1047 0 : void ScRefHdlModalImpl::StateChanged( StateChangedType nStateChange )
1048 : {
1049 0 : ModalDialog::StateChanged( nStateChange );
1050 0 : ScRefHandler::stateChanged( nStateChange, true );
1051 0 : }
1052 :
1053 0 : ScAnyRefModalDlg::ScAnyRefModalDlg( Window* pParent, ResId aResId ):
1054 93 : ScRefHdlModalImpl( pParent, aResId ) {}
1055 :
1056 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|