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 "scitems.hxx"
22 : #include <editeng/eeitem.hxx>
23 :
24 : #include <editeng/brushitem.hxx>
25 : #include <editeng/editview.hxx>
26 : #include <svx/fmshell.hxx>
27 : #include <svx/svdoole2.hxx>
28 : #include <sfx2/bindings.hxx>
29 : #include <sfx2/viewfrm.hxx>
30 : #include <vcl/cursor.hxx>
31 :
32 : #include "tabview.hxx"
33 : #include "tabvwsh.hxx"
34 : #include "docsh.hxx"
35 : #include "gridwin.hxx"
36 : #include "olinewin.hxx"
37 : #include "colrowba.hxx"
38 : #include "tabcont.hxx"
39 : #include "scmod.hxx"
40 : #include "uiitems.hxx"
41 : #include "sc.hrc"
42 : #include "viewutil.hxx"
43 : #include "editutil.hxx"
44 : #include "inputhdl.hxx"
45 : #include "inputwin.hxx"
46 : #include "validat.hxx"
47 : #include "hintwin.hxx"
48 : #include "inputopt.hxx"
49 : #include "rfindlst.hxx"
50 : #include "hiranges.hxx"
51 : #include "viewuno.hxx"
52 : #include "chartarr.hxx"
53 : #include "anyrefdg.hxx"
54 : #include "dpobject.hxx"
55 : #include "patattr.hxx"
56 : #include "dociter.hxx"
57 : #include "seltrans.hxx"
58 : #include "fillinfo.hxx"
59 : #include "AccessibilityHints.hxx"
60 : #include "rangeutl.hxx"
61 : #include "client.hxx"
62 : #include "tabprotection.hxx"
63 : #include "markdata.hxx"
64 : #include <formula/FormulaCompiler.hxx>
65 :
66 : #include <com/sun/star/chart2/data/HighlightedRange.hpp>
67 :
68 : namespace
69 : {
70 :
71 0 : ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
72 : {
73 0 : ScAddress aResult( rRange.aStart );
74 :
75 0 : SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
76 0 : SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
77 0 : SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
78 0 : if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
79 : {
80 : // row by row from first to last sheet
81 0 : sal_Int32 nArea = nWidth * nHeight;
82 0 : aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
83 0 : aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
84 0 : aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
85 0 : if( !rRange.In( aResult ) )
86 0 : aResult = rRange.aStart;
87 : }
88 :
89 0 : return ScRange( aResult );
90 : }
91 :
92 : } // anonymous namespace
93 :
94 : using namespace com::sun::star;
95 :
96 : // --- Public-Funktionen
97 :
98 0 : void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, bool bControl )
99 : {
100 0 : ScDocument* pDoc = aViewData.GetDocument();
101 0 : SCTAB nTab = aViewData.GetTabNo();
102 0 : pDoc->SkipOverlapped(nPosX, nPosY, nTab);
103 :
104 0 : bool bRefMode = SC_MOD()->IsFormulaMode();
105 :
106 0 : if ( bRefMode )
107 : {
108 0 : DoneRefMode( false );
109 :
110 0 : if (bControl)
111 0 : SC_MOD()->AddRefEntry();
112 :
113 0 : InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
114 : }
115 : else
116 : {
117 0 : DoneBlockMode( bControl );
118 0 : aViewData.ResetOldCursor();
119 0 : SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
120 : }
121 0 : }
122 :
123 3950 : void ScTabView::UpdateAutoFillMark()
124 : {
125 : // single selection or cursor
126 3950 : ScRange aMarkRange;
127 3950 : bool bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
128 :
129 : sal_uInt16 i;
130 19750 : for (i=0; i<4; i++)
131 15800 : if (pGridWin[i] && pGridWin[i]->IsVisible())
132 3416 : pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
133 :
134 11850 : for (i=0; i<2; i++)
135 : {
136 7900 : if (pColBar[i] && pColBar[i]->IsVisible())
137 3954 : pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
138 7900 : if (pRowBar[i] && pRowBar[i]->IsVisible())
139 3956 : pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
140 : }
141 :
142 : // selection transfer object is checked together with AutoFill marks,
143 : // because it has the same requirement of a single continuous block.
144 3950 : CheckSelectionTransfer(); // update selection transfer object
145 3950 : }
146 :
147 0 : void ScTabView::FakeButtonUp( ScSplitPos eWhich )
148 : {
149 0 : if (pGridWin[eWhich])
150 0 : pGridWin[eWhich]->FakeButtonUp();
151 0 : }
152 :
153 1892 : void ScTabView::HideAllCursors()
154 : {
155 9460 : for (sal_uInt16 i=0; i<4; i++)
156 7568 : if (pGridWin[i])
157 1982 : if (pGridWin[i]->IsVisible())
158 : {
159 1904 : vcl::Cursor* pCur = pGridWin[i]->GetCursor();
160 1904 : if (pCur)
161 0 : if (pCur->IsVisible())
162 0 : pCur->Hide();
163 1904 : pGridWin[i]->HideCursor();
164 : }
165 1892 : }
166 :
167 1350 : void ScTabView::ShowAllCursors()
168 : {
169 6750 : for (sal_uInt16 i=0; i<4; i++)
170 5400 : if (pGridWin[i])
171 1434 : if (pGridWin[i]->IsVisible())
172 : {
173 1362 : pGridWin[i]->ShowCursor();
174 :
175 : // #114409#
176 1362 : pGridWin[i]->CursorChanged();
177 : }
178 1350 : }
179 :
180 0 : void ScTabView::ShowCursor()
181 : {
182 0 : pGridWin[aViewData.GetActivePart()]->ShowCursor();
183 :
184 : // #114409#
185 0 : pGridWin[aViewData.GetActivePart()]->CursorChanged();
186 0 : }
187 :
188 1202 : void ScTabView::InvalidateAttribs()
189 : {
190 1202 : SfxBindings& rBindings = aViewData.GetBindings();
191 :
192 1202 : rBindings.Invalidate( SID_STYLE_APPLY );
193 1202 : rBindings.Invalidate( SID_STYLE_FAMILY2 );
194 : // StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen
195 :
196 1202 : rBindings.Invalidate( SID_ATTR_CHAR_FONT );
197 1202 : rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
198 1202 : rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
199 :
200 1202 : rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
201 1202 : rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
202 1202 : rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
203 1202 : rBindings.Invalidate( SID_ULINE_VAL_NONE );
204 1202 : rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
205 1202 : rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
206 1202 : rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
207 :
208 1202 : rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
209 :
210 1202 : rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
211 1202 : rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
212 1202 : rBindings.Invalidate( SID_SET_SUB_SCRIPT );
213 1202 : rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
214 1202 : rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );
215 :
216 1202 : rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
217 1202 : rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
218 1202 : rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
219 1202 : rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
220 1202 : rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT);
221 :
222 1202 : rBindings.Invalidate( SID_ALIGNLEFT );
223 1202 : rBindings.Invalidate( SID_ALIGNRIGHT );
224 1202 : rBindings.Invalidate( SID_ALIGNBLOCK );
225 1202 : rBindings.Invalidate( SID_ALIGNCENTERHOR );
226 :
227 1202 : rBindings.Invalidate( SID_ALIGNTOP );
228 1202 : rBindings.Invalidate( SID_ALIGNBOTTOM );
229 1202 : rBindings.Invalidate( SID_ALIGNCENTERVER );
230 :
231 : // stuff for sidebar panels
232 : {
233 1202 : rBindings.Invalidate( SID_H_ALIGNCELL );
234 1202 : rBindings.Invalidate( SID_V_ALIGNCELL );
235 1202 : rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
236 1202 : rBindings.Invalidate( SID_FRAME_LINECOLOR );
237 1202 : rBindings.Invalidate( SID_FRAME_LINESTYLE );
238 1202 : rBindings.Invalidate( SID_ATTR_BORDER_OUTER );
239 1202 : rBindings.Invalidate( SID_ATTR_BORDER_INNER );
240 1202 : rBindings.Invalidate( SID_ATTR_BORDER_DIAG_TLBR );
241 1202 : rBindings.Invalidate( SID_ATTR_BORDER_DIAG_BLTR );
242 1202 : rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT );
243 : }
244 :
245 1202 : rBindings.Invalidate( SID_BACKGROUND_COLOR );
246 :
247 1202 : rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
248 1202 : rBindings.Invalidate( SID_NUMBER_FORMAT );
249 :
250 1202 : rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
251 1202 : rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
252 1202 : rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
253 1202 : rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
254 :
255 : // pseudo slots for Format menu
256 1202 : rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
257 1202 : rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
258 1202 : rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
259 1202 : rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
260 1202 : rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
261 1202 : rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
262 1202 : rBindings.Invalidate( SID_ALIGN_ANY_TOP );
263 1202 : rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
264 1202 : rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
265 :
266 1202 : rBindings.Invalidate( SID_NUMBER_CURRENCY );
267 1202 : rBindings.Invalidate( SID_NUMBER_SCIENTIFIC );
268 1202 : rBindings.Invalidate( SID_NUMBER_DATE );
269 1202 : rBindings.Invalidate( SID_NUMBER_CURRENCY );
270 1202 : rBindings.Invalidate( SID_NUMBER_PERCENT );
271 1202 : rBindings.Invalidate( SID_NUMBER_TIME );
272 1202 : }
273 :
274 : // SetCursor - Cursor setzen, zeichnen, InputWin updaten
275 : // oder Referenz verschicken
276 : // ohne Optimierung wegen BugId 29307
277 :
278 922 : void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, bool bNew )
279 : {
280 922 : SCCOL nOldX = aViewData.GetCurX();
281 922 : SCROW nOldY = aViewData.GetCurY();
282 :
283 : // DeactivateIP nur noch bei MarkListHasChanged
284 :
285 922 : if ( nPosX != nOldX || nPosY != nOldY || bNew )
286 : {
287 890 : ScTabViewShell* pViewShell = aViewData.GetViewShell();
288 890 : bool bRefMode = pViewShell && pViewShell->IsRefInputMode();
289 890 : if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 oder so
290 : {
291 0 : UpdateInputLine();
292 : }
293 :
294 890 : HideAllCursors();
295 :
296 890 : aViewData.SetCurX( nPosX );
297 890 : aViewData.SetCurY( nPosY );
298 :
299 890 : ShowAllCursors();
300 :
301 890 : CursorPosChanged();
302 : }
303 922 : }
304 :
305 4510 : void ScTabView::CheckSelectionTransfer()
306 : {
307 4510 : if ( aViewData.IsActive() ) // only for active view
308 : {
309 4502 : ScModule* pScMod = SC_MOD();
310 4502 : ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
311 4502 : if ( pOld && pOld->GetView() == this && pOld->StillValid() )
312 : {
313 : // selection not changed - nothing to do
314 : }
315 : else
316 : {
317 4502 : ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
318 4502 : if ( pNew )
319 : {
320 : // create new selection
321 :
322 360 : if (pOld)
323 6 : pOld->ForgetView();
324 :
325 360 : uno::Reference<datatransfer::XTransferable> xRef( pNew );
326 360 : pScMod->SetSelectionTransfer( pNew );
327 360 : pNew->CopyToSelection( GetActiveWin() ); // may delete pOld
328 : }
329 4142 : else if ( pOld && pOld->GetView() == this )
330 : {
331 : // remove own selection
332 :
333 32 : pOld->ForgetView();
334 32 : pScMod->SetSelectionTransfer( NULL );
335 32 : TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
336 : }
337 : // else: selection from outside: leave unchanged
338 : }
339 : }
340 4510 : }
341 :
342 : // Eingabezeile / Menues updaten
343 : // CursorPosChanged ruft SelectionChanged
344 : // SelectionChanged ruft CellContentChanged
345 :
346 1202 : void ScTabView::CellContentChanged()
347 : {
348 1202 : SfxBindings& rBindings = aViewData.GetBindings();
349 :
350 1202 : rBindings.Invalidate( SID_ATTR_SIZE ); // -> Fehlermeldungen anzeigen
351 1202 : rBindings.Invalidate( SID_THESAURUS );
352 1202 : rBindings.Invalidate( SID_HYPERLINK_GETLINK );
353 1202 : rBindings.Invalidate( SID_ROWCOL_SELCOUNT );
354 :
355 1202 : InvalidateAttribs(); // Attribut-Updates
356 :
357 1202 : aViewData.GetViewShell()->UpdateInputHandler();
358 1202 : }
359 :
360 1172 : void ScTabView::SelectionChanged()
361 : {
362 1172 : SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
363 1172 : if (pViewFrame)
364 : {
365 1172 : uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
366 1172 : if (xController.is())
367 : {
368 1172 : ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
369 1172 : if (pImp)
370 1172 : pImp->SelectionChanged();
371 1172 : }
372 : }
373 :
374 1172 : UpdateAutoFillMark(); // also calls CheckSelectionTransfer
375 :
376 1172 : SfxBindings& rBindings = aViewData.GetBindings();
377 :
378 1172 : rBindings.Invalidate( SID_CURRENTCELL ); // -> Navigator
379 1172 : rBindings.Invalidate( SID_AUTO_FILTER ); // -> Menue
380 1172 : rBindings.Invalidate( FID_NOTE_VISIBLE );
381 1172 : rBindings.Invalidate( FID_SHOW_NOTE );
382 1172 : rBindings.Invalidate( FID_HIDE_NOTE );
383 1172 : rBindings.Invalidate( SID_DELETE_NOTE );
384 1172 : rBindings.Invalidate( SID_ROWCOL_SELCOUNT );
385 :
386 : // Funktionen, die evtl disabled werden muessen
387 :
388 1172 : rBindings.Invalidate( FID_INS_ROWBRK );
389 1172 : rBindings.Invalidate( FID_INS_COLBRK );
390 1172 : rBindings.Invalidate( FID_DEL_ROWBRK );
391 1172 : rBindings.Invalidate( FID_DEL_COLBRK );
392 1172 : rBindings.Invalidate( FID_MERGE_ON );
393 1172 : rBindings.Invalidate( FID_MERGE_OFF );
394 1172 : rBindings.Invalidate( FID_MERGE_TOGGLE );
395 1172 : rBindings.Invalidate( SID_AUTOFILTER_HIDE );
396 1172 : rBindings.Invalidate( SID_UNFILTER );
397 1172 : rBindings.Invalidate( SID_REIMPORT_DATA );
398 1172 : rBindings.Invalidate( SID_REFRESH_DBAREA );
399 1172 : rBindings.Invalidate( SID_OUTLINE_SHOW );
400 1172 : rBindings.Invalidate( SID_OUTLINE_HIDE );
401 1172 : rBindings.Invalidate( SID_OUTLINE_REMOVE );
402 1172 : rBindings.Invalidate( FID_FILL_TO_BOTTOM );
403 1172 : rBindings.Invalidate( FID_FILL_TO_RIGHT );
404 1172 : rBindings.Invalidate( FID_FILL_TO_TOP );
405 1172 : rBindings.Invalidate( FID_FILL_TO_LEFT );
406 1172 : rBindings.Invalidate( FID_FILL_SERIES );
407 1172 : rBindings.Invalidate( SID_SCENARIOS );
408 1172 : rBindings.Invalidate( SID_AUTOFORMAT );
409 1172 : rBindings.Invalidate( SID_OPENDLG_TABOP );
410 1172 : rBindings.Invalidate( SID_DATA_SELECT );
411 :
412 1172 : rBindings.Invalidate( SID_CUT );
413 1172 : rBindings.Invalidate( SID_COPY );
414 1172 : rBindings.Invalidate( SID_PASTE );
415 1172 : rBindings.Invalidate( SID_PASTE_SPECIAL );
416 :
417 1172 : rBindings.Invalidate( FID_INS_ROW );
418 1172 : rBindings.Invalidate( FID_INS_COLUMN );
419 1172 : rBindings.Invalidate( FID_INS_CELL );
420 1172 : rBindings.Invalidate( FID_INS_CELLSDOWN );
421 1172 : rBindings.Invalidate( FID_INS_CELLSRIGHT );
422 :
423 1172 : rBindings.Invalidate( FID_CHG_COMMENT );
424 :
425 : // nur wegen Zellschutz:
426 :
427 1172 : rBindings.Invalidate( SID_CELL_FORMAT_RESET );
428 1172 : rBindings.Invalidate( SID_DELETE );
429 1172 : rBindings.Invalidate( SID_DELETE_CONTENTS );
430 1172 : rBindings.Invalidate( FID_DELETE_CELL );
431 1172 : rBindings.Invalidate( FID_CELL_FORMAT );
432 1172 : rBindings.Invalidate( SID_ENABLE_HYPHENATION );
433 1172 : rBindings.Invalidate( SID_INSERT_POSTIT );
434 1172 : rBindings.Invalidate( SID_CHARMAP );
435 1172 : rBindings.Invalidate( SID_OPENDLG_FUNCTION );
436 1172 : rBindings.Invalidate( FID_VALIDATION );
437 1172 : rBindings.Invalidate( SID_EXTERNAL_SOURCE );
438 1172 : rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
439 1172 : rBindings.Invalidate( SID_SORT_ASCENDING );
440 1172 : rBindings.Invalidate( SID_SORT_DESCENDING );
441 :
442 1172 : if (aViewData.GetViewShell()->HasAccessibilityObjects())
443 2 : aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_CURSORCHANGED));
444 :
445 1172 : CellContentChanged();
446 1172 : }
447 :
448 890 : void ScTabView::CursorPosChanged()
449 : {
450 890 : bool bRefMode = SC_MOD()->IsFormulaMode();
451 890 : if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
452 890 : aViewData.GetDocShell()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
453 :
454 : // Broadcast, damit andere Views des Dokuments auch umschalten
455 :
456 890 : ScDocument* pDoc = aViewData.GetDocument();
457 : bool bDP = NULL != pDoc->GetDPAtCursor(
458 890 : aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
459 890 : aViewData.GetViewShell()->SetPivotShell(bDP);
460 :
461 : // UpdateInputHandler jetzt in CellContentChanged
462 :
463 890 : SelectionChanged();
464 :
465 890 : aViewData.SetTabStartCol( SC_TABSTART_NONE );
466 890 : }
467 :
468 : namespace {
469 :
470 0 : Point calcHintWindowPosition(
471 : const Point& rCellPos, const Size& rCellSize, const Size& rFrameWndSize, const Size& rHintWndSize)
472 : {
473 0 : const long nMargin = 20;
474 :
475 0 : long nMLeft = rCellPos.X();
476 0 : long nMRight = rFrameWndSize.Width() - rCellPos.X() - rCellSize.Width();
477 0 : long nMTop = rCellPos.Y();
478 0 : long nMBottom = rFrameWndSize.Height() - rCellPos.Y() - rCellSize.Height();
479 :
480 : // First, see if we can fit the entire hint window in the visible region.
481 :
482 0 : if (nMRight - nMargin >= rHintWndSize.Width())
483 : {
484 : // Right margin is wide enough.
485 0 : if (rFrameWndSize.Height() >= rHintWndSize.Height())
486 : {
487 : // The frame has enough height. Take it.
488 0 : Point aPos = rCellPos;
489 0 : aPos.X() += rCellSize.Width() + nMargin;
490 0 : if (aPos.Y() + rHintWndSize.Height() > rFrameWndSize.Height())
491 : {
492 : // Push the hint window up a bit to make it fit.
493 0 : aPos.Y() = rFrameWndSize.Height() - rHintWndSize.Height();
494 : }
495 0 : return aPos;
496 : }
497 : }
498 :
499 0 : if (nMBottom - nMargin >= rHintWndSize.Height())
500 : {
501 : // Bottom margin is high enough.
502 0 : if (rFrameWndSize.Width() >= rHintWndSize.Width())
503 : {
504 : // The frame has enough width. Take it.
505 0 : Point aPos = rCellPos;
506 0 : aPos.Y() += rCellSize.Height() + nMargin;
507 0 : if (aPos.X() + rHintWndSize.Width() > rFrameWndSize.Width())
508 : {
509 : // Move the hint window to the left to make it fit.
510 0 : aPos.X() = rFrameWndSize.Width() - rHintWndSize.Width();
511 : }
512 0 : return aPos;
513 : }
514 : }
515 :
516 0 : if (nMLeft - nMargin >= rHintWndSize.Width())
517 : {
518 : // Left margin is wide enough.
519 0 : if (rFrameWndSize.Height() >= rHintWndSize.Height())
520 : {
521 : // The frame is high enough. Take it.
522 0 : Point aPos = rCellPos;
523 0 : aPos.X() -= rHintWndSize.Width() + nMargin;
524 0 : if (aPos.Y() + rHintWndSize.Height() > rFrameWndSize.Height())
525 : {
526 : // Push the hint window up a bit to make it fit.
527 0 : aPos.Y() = rFrameWndSize.Height() - rHintWndSize.Height();
528 : }
529 0 : return aPos;
530 : }
531 : }
532 :
533 0 : if (nMTop - nMargin >= rHintWndSize.Height())
534 : {
535 : // Top margin is high enough.
536 0 : if (rFrameWndSize.Width() >= rHintWndSize.Width())
537 : {
538 : // The frame is wide enough. Take it.
539 0 : Point aPos = rCellPos;
540 0 : aPos.Y() -= rHintWndSize.Height() + nMargin;
541 0 : if (aPos.X() + rHintWndSize.Width() > rFrameWndSize.Width())
542 : {
543 : // Move the hint window to the left to make it fit.
544 0 : aPos.X() = rFrameWndSize.Width() - rHintWndSize.Width();
545 : }
546 0 : return aPos;
547 : }
548 : }
549 :
550 : // The popup doesn't fit in any direction in its entirety. Do our best.
551 :
552 0 : if (nMRight - nMargin >= rHintWndSize.Width())
553 : {
554 : // Right margin is good enough.
555 0 : Point aPos = rCellPos;
556 0 : aPos.X() += nMargin + rCellSize.Width();
557 0 : aPos.Y() = 0;
558 0 : return aPos;
559 : }
560 :
561 0 : if (nMBottom - nMargin >= rHintWndSize.Height())
562 : {
563 : // Bottom margin is good enough.
564 0 : Point aPos = rCellPos;
565 0 : aPos.Y() += nMargin + rCellSize.Height();
566 0 : aPos.X() = 0;
567 0 : return aPos;
568 : }
569 :
570 0 : if (nMLeft - nMargin >= rHintWndSize.Width())
571 : {
572 : // Left margin is good enough.
573 0 : Point aPos = rCellPos;
574 0 : aPos.X() -= rHintWndSize.Width() + nMargin;
575 0 : aPos.Y() = 0;
576 0 : return aPos;
577 : }
578 :
579 0 : if (nMTop - nMargin >= rHintWndSize.Height())
580 : {
581 : // Top margin is good enough.
582 0 : Point aPos = rCellPos;
583 0 : aPos.Y() -= rHintWndSize.Height() + nMargin;
584 0 : aPos.X() = 0;
585 0 : return aPos;
586 : }
587 :
588 : // None of the above. Hopeless. At least try not to cover the current
589 : // cell.
590 0 : Point aPos = rCellPos;
591 0 : aPos.X() += rCellSize.Width();
592 0 : return aPos;
593 : }
594 :
595 : }
596 :
597 1222 : void ScTabView::TestHintWindow()
598 : {
599 : // show input help window and list drop-down button for validity
600 :
601 1222 : bool bListValButton = false;
602 1222 : ScAddress aListValPos;
603 :
604 1222 : ScDocument* pDoc = aViewData.GetDocument();
605 : const SfxUInt32Item* pItem = static_cast<const SfxUInt32Item*>(
606 1222 : pDoc->GetAttr( aViewData.GetCurX(),
607 : aViewData.GetCurY(),
608 1222 : aViewData.GetTabNo(),
609 2444 : ATTR_VALIDDATA ));
610 1222 : if ( pItem->GetValue() )
611 : {
612 0 : const ScValidationData* pData = pDoc->GetValidationEntry( pItem->GetValue() );
613 : OSL_ENSURE(pData,"ValidationData nicht gefunden");
614 0 : OUString aTitle, aMessage;
615 0 : if ( pData && pData->GetInput( aTitle, aMessage ) && !aMessage.isEmpty() )
616 : {
617 : //! Abfrage, ob an gleicher Stelle !!!!
618 :
619 0 : mpInputHintWindow.reset();
620 :
621 0 : ScSplitPos eWhich = aViewData.GetActivePart();
622 0 : ScGridWindow* pWin = pGridWin[eWhich];
623 0 : SCCOL nCol = aViewData.GetCurX();
624 0 : SCROW nRow = aViewData.GetCurY();
625 0 : Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
626 0 : Size aWinSize = pWin->GetOutputSizePixel();
627 : // Cursor sichtbar?
628 0 : if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
629 0 : nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
630 0 : aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
631 : {
632 : // HintWindow anlegen, bestimmt seine Groesse selbst
633 0 : mpInputHintWindow.reset(new ScHintWindow(pWin, aTitle, aMessage));
634 0 : Size aHintWndSize = mpInputHintWindow->GetSizePixel();
635 0 : long nCellSizeX = 0;
636 0 : long nCellSizeY = 0;
637 0 : aViewData.GetMergeSizePixel(nCol, nRow, nCellSizeX, nCellSizeY);
638 :
639 : Point aHintPos = calcHintWindowPosition(
640 0 : aPos, Size(nCellSizeX,nCellSizeY), aWinSize, aHintWndSize);
641 :
642 0 : mpInputHintWindow->SetPosPixel( aHintPos );
643 0 : mpInputHintWindow->ToTop();
644 0 : mpInputHintWindow->Show();
645 : }
646 : }
647 : else
648 0 : mpInputHintWindow.reset();
649 :
650 : // list drop-down button
651 0 : if ( pData && pData->HasSelectionList() )
652 : {
653 0 : aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
654 0 : bListValButton = true;
655 0 : }
656 : }
657 : else
658 1222 : mpInputHintWindow.reset();
659 :
660 6110 : for ( sal_uInt16 i=0; i<4; i++ )
661 4888 : if ( pGridWin[i] && pGridWin[i]->IsVisible() )
662 688 : pGridWin[i]->UpdateListValPos( bListValButton, aListValPos );
663 1222 : }
664 :
665 3054 : bool ScTabView::HasHintWindow() const
666 : {
667 3054 : return mpInputHintWindow.get() != NULL;
668 : }
669 :
670 0 : void ScTabView::RemoveHintWindow()
671 : {
672 0 : mpInputHintWindow.reset();
673 0 : }
674 :
675 : // find window that should not be over the cursor
676 160 : static vcl::Window* lcl_GetCareWin(SfxViewFrame* pViewFrm)
677 : {
678 : //! auch Spelling ??? (dann beim Aufruf Membervariable setzen)
679 :
680 : // Suchen & Ersetzen
681 160 : if ( pViewFrm->HasChildWindow(SID_SEARCH_DLG) )
682 : {
683 0 : SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
684 0 : if (pChild)
685 : {
686 0 : vcl::Window* pWin = pChild->GetWindow();
687 0 : if (pWin && pWin->IsVisible())
688 0 : return pWin;
689 : }
690 : }
691 :
692 : // Aenderungen uebernehmen
693 160 : if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
694 : {
695 0 : SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
696 0 : if (pChild)
697 : {
698 0 : vcl::Window* pWin = pChild->GetWindow();
699 0 : if (pWin && pWin->IsVisible())
700 0 : return pWin;
701 : }
702 : }
703 :
704 160 : return NULL;
705 : }
706 :
707 : // Bildschirm an Cursorposition anpassen
708 :
709 196 : void ScTabView::AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
710 : const ScSplitPos* pWhich )
711 : {
712 :
713 : // aktiven Teil umschalten jetzt hier
714 :
715 196 : ScSplitPos eActive = aViewData.GetActivePart();
716 196 : ScHSplitPos eActiveX = WhichH(eActive);
717 196 : ScVSplitPos eActiveY = WhichV(eActive);
718 196 : bool bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
719 196 : bool bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
720 196 : if (bHFix)
721 2 : if (eActiveX == SC_SPLIT_LEFT && nCurX >= (SCsCOL)aViewData.GetFixPosX())
722 : {
723 0 : ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
724 0 : eActiveX = SC_SPLIT_RIGHT;
725 : }
726 196 : if (bVFix)
727 4 : if (eActiveY == SC_SPLIT_TOP && nCurY >= (SCsROW)aViewData.GetFixPosY())
728 : {
729 0 : ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
730 0 : eActiveY = SC_SPLIT_BOTTOM;
731 : }
732 :
733 : // eigentliches Align
734 :
735 196 : if ( eMode != SC_FOLLOW_NONE )
736 : {
737 : ScSplitPos eAlign;
738 166 : if (pWhich)
739 0 : eAlign = *pWhich;
740 : else
741 166 : eAlign = aViewData.GetActivePart();
742 166 : ScHSplitPos eAlignX = WhichH(eAlign);
743 166 : ScVSplitPos eAlignY = WhichV(eAlign);
744 :
745 166 : SCsCOL nDeltaX = (SCsCOL) aViewData.GetPosX(eAlignX);
746 166 : SCsROW nDeltaY = (SCsROW) aViewData.GetPosY(eAlignY);
747 166 : SCsCOL nSizeX = (SCsCOL) aViewData.VisibleCellsX(eAlignX);
748 166 : SCsROW nSizeY = (SCsROW) aViewData.VisibleCellsY(eAlignY);
749 :
750 : long nCellSizeX;
751 : long nCellSizeY;
752 166 : if ( nCurX >= 0 && nCurY >= 0 )
753 166 : aViewData.GetMergeSizePixel( (SCCOL)nCurX, (SCROW)nCurY, nCellSizeX, nCellSizeY );
754 : else
755 0 : nCellSizeX = nCellSizeY = 0;
756 166 : Size aScrSize = aViewData.GetScrSize();
757 166 : long nSpaceX = ( aScrSize.Width() - nCellSizeX ) / 2;
758 166 : long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
759 : // nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
760 :
761 166 : bool bForceNew = false; // force new calculation of JUMP position (vertical only)
762 :
763 : // VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
764 :
765 : // falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
766 : // wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs
767 :
768 : //! nicht, wenn schon komplett sichtbar
769 :
770 166 : if ( eMode == SC_FOLLOW_JUMP )
771 : {
772 160 : vcl::Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
773 160 : if (pCare)
774 : {
775 0 : bool bLimit = false;
776 0 : Rectangle aDlgPixel;
777 0 : Size aWinSize;
778 0 : vcl::Window* pWin = GetActiveWin();
779 0 : if (pWin)
780 : {
781 0 : aDlgPixel = pCare->GetWindowExtentsRelative( pWin );
782 0 : aWinSize = pWin->GetOutputSizePixel();
783 : // ueberdeckt der Dialog das GridWin?
784 0 : if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
785 : {
786 0 : if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
787 0 : nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
788 0 : bLimit = true; // es wird sowieso gescrollt
789 : else
790 : {
791 : // Cursor ist auf dem Bildschirm
792 0 : Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
793 : long nCSX, nCSY;
794 0 : aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
795 0 : Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
796 0 : if ( aCursor.IsOver( aDlgPixel ) )
797 0 : bLimit = true; // Zelle vom Dialog ueberdeckt
798 : }
799 : }
800 : }
801 :
802 0 : if (bLimit)
803 : {
804 0 : bool bBottom = false;
805 0 : long nTopSpace = aDlgPixel.Top();
806 0 : long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
807 0 : if ( nBotSpace > 0 && nBotSpace > nTopSpace )
808 : {
809 0 : long nDlgBot = aDlgPixel.Bottom();
810 : SCsCOL nWPosX;
811 : SCsROW nWPosY;
812 0 : aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
813 0 : ++nWPosY; // unter der letzten betroffenen Zelle
814 :
815 0 : SCsROW nDiff = nWPosY - nDeltaY;
816 0 : if ( nCurY >= nDiff ) // Pos. kann nicht negativ werden
817 : {
818 0 : nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
819 0 : bBottom = true;
820 0 : bForceNew = true;
821 : }
822 : }
823 0 : if ( !bBottom && nTopSpace > 0 )
824 : {
825 0 : nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
826 0 : bForceNew = true;
827 : }
828 : }
829 : }
830 : }
831 :
832 166 : SCsCOL nNewDeltaX = nDeltaX;
833 166 : SCsROW nNewDeltaY = nDeltaY;
834 166 : bool bDoLine = false;
835 :
836 166 : switch (eMode)
837 : {
838 : case SC_FOLLOW_JUMP:
839 160 : if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
840 : {
841 16 : nNewDeltaX = nCurX - static_cast<SCsCOL>(aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<sal_uInt16>(nSpaceX) ));
842 16 : if (nNewDeltaX < 0) nNewDeltaX = 0;
843 16 : nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
844 : }
845 160 : if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
846 : {
847 40 : nNewDeltaY = nCurY - static_cast<SCsROW>(aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<sal_uInt16>(nSpaceY) ));
848 40 : if (nNewDeltaY < 0) nNewDeltaY = 0;
849 40 : nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
850 : }
851 160 : bDoLine = true;
852 160 : break;
853 :
854 : case SC_FOLLOW_LINE:
855 6 : bDoLine = true;
856 6 : break;
857 :
858 : case SC_FOLLOW_FIX:
859 0 : if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
860 : {
861 0 : nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
862 0 : if (nNewDeltaX < 0) nNewDeltaX = 0;
863 0 : nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
864 : }
865 0 : if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
866 : {
867 0 : nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
868 0 : if (nNewDeltaY < 0) nNewDeltaY = 0;
869 0 : nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
870 : }
871 :
872 : // like old version of SC_FOLLOW_JUMP:
873 :
874 0 : if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
875 : {
876 0 : nNewDeltaX = nCurX - (nSizeX / 2);
877 0 : if (nNewDeltaX < 0) nNewDeltaX = 0;
878 0 : nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
879 : }
880 0 : if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
881 : {
882 0 : nNewDeltaY = nCurY - (nSizeY / 2);
883 0 : if (nNewDeltaY < 0) nNewDeltaY = 0;
884 0 : nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
885 : }
886 :
887 0 : bDoLine = true;
888 0 : break;
889 :
890 : case SC_FOLLOW_NONE:
891 0 : break;
892 : default:
893 : OSL_FAIL("Falscher Cursormodus");
894 0 : break;
895 : }
896 :
897 166 : if (bDoLine)
898 : {
899 336 : while ( nCurX >= nNewDeltaX+nSizeX )
900 : {
901 4 : nNewDeltaX = nCurX-nSizeX+1;
902 4 : ScDocument* pDoc = aViewData.GetDocument();
903 4 : SCTAB nTab = aViewData.GetTabNo();
904 8 : while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
905 0 : ++nNewDeltaX;
906 4 : nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
907 : }
908 332 : while ( nCurY >= nNewDeltaY+nSizeY )
909 : {
910 0 : nNewDeltaY = nCurY-nSizeY+1;
911 0 : ScDocument* pDoc = aViewData.GetDocument();
912 0 : SCTAB nTab = aViewData.GetTabNo();
913 0 : while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
914 0 : ++nNewDeltaY;
915 0 : nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
916 : }
917 166 : if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
918 166 : if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
919 : }
920 :
921 166 : if ( nNewDeltaX != nDeltaX )
922 18 : nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
923 166 : if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
924 166 : if (nNewDeltaX < 0) nNewDeltaX = 0;
925 :
926 166 : if ( nNewDeltaY != nDeltaY )
927 40 : nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
928 166 : if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
929 166 : if (nNewDeltaY < 0) nNewDeltaY = 0;
930 :
931 166 : if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
932 166 : if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
933 : }
934 :
935 : // nochmal aktiven Teil umschalten
936 :
937 196 : if (bHFix)
938 2 : if (eActiveX == SC_SPLIT_RIGHT && nCurX < (SCsCOL)aViewData.GetFixPosX())
939 : {
940 0 : ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
941 0 : eActiveX = SC_SPLIT_LEFT;
942 : }
943 196 : if (bVFix)
944 4 : if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (SCsROW)aViewData.GetFixPosY())
945 : {
946 0 : ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
947 0 : eActiveY = SC_SPLIT_TOP;
948 : }
949 196 : }
950 :
951 0 : bool ScTabView::SelMouseButtonDown( const MouseEvent& rMEvt )
952 : {
953 0 : bool bRet = false;
954 :
955 : // #i3875# *Hack*
956 0 : bool bMod1Locked = aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1 ? true : false;
957 0 : aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );
958 :
959 0 : if ( pSelEngine )
960 : {
961 0 : bMoveIsShift = rMEvt.IsShift();
962 0 : bRet = pSelEngine->SelMouseButtonDown( rMEvt );
963 0 : bMoveIsShift = false;
964 : }
965 :
966 0 : aViewData.SetSelCtrlMouseClick( false ); // #i3875# *Hack*
967 :
968 0 : return bRet;
969 : }
970 :
971 : // MoveCursor - mit Anpassung des Bildausschnitts
972 :
973 28 : void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
974 : bool bShift, bool bControl, bool bKeepOld, bool bKeepSel )
975 : {
976 28 : if (!bKeepOld)
977 2 : aViewData.ResetOldCursor();
978 :
979 : // #i123629#
980 28 : if( aViewData.GetViewShell()->GetForceFocusOnCurCell() )
981 0 : aViewData.GetViewShell()->SetForceFocusOnCurCell( !ValidColRow(nCurX, nCurY) );
982 :
983 28 : if (nCurX < 0) nCurX = 0;
984 28 : if (nCurY < 0) nCurY = 0;
985 28 : if (nCurX > MAXCOL) nCurX = MAXCOL;
986 28 : if (nCurY > MAXROW) nCurY = MAXROW;
987 :
988 28 : HideAllCursors();
989 :
990 : // aktiven Teil umschalten jetzt in AlignToCursor
991 :
992 28 : AlignToCursor( nCurX, nCurY, eMode );
993 : //! auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
994 :
995 28 : if (bKeepSel)
996 : {
997 0 : SetCursor( nCurX, nCurY ); // Markierung stehenlassen
998 :
999 : // If the cursor is in existing selection, it's a cursor movement by
1000 : // ENTER or TAB. If not, then it's a new selection during ADD
1001 : // selection mode.
1002 :
1003 0 : const ScMarkData& rMark = aViewData.GetMarkData();
1004 0 : ScRangeList aSelList;
1005 0 : rMark.FillRangeListWithMarks(&aSelList, false);
1006 0 : if (!aSelList.In(ScRange(nCurX, nCurY, aViewData.GetTabNo())))
1007 : // Cursor not in existing selection. Start a new selection.
1008 0 : DoneBlockMode(true);
1009 : }
1010 : else
1011 : {
1012 28 : if (!bShift)
1013 : {
1014 : // Remove all marked data on cursor movement unless the Shift is locked.
1015 28 : ScMarkData& rMark = aViewData.GetMarkData();
1016 28 : bool bMarked = rMark.IsMarked() || rMark.IsMultiMarked();
1017 28 : if (bMarked)
1018 : {
1019 24 : rMark.ResetMark();
1020 24 : DoneBlockMode();
1021 24 : InitOwnBlockMode();
1022 24 : MarkDataChanged();
1023 : }
1024 : }
1025 :
1026 28 : bool bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
1027 28 : bMoveIsShift = bShift;
1028 28 : pSelEngine->CursorPosChanging( bShift, bControl );
1029 28 : bMoveIsShift = false;
1030 28 : aFunctionSet.SetCursorAtCell( nCurX, nCurY, false );
1031 :
1032 : // Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
1033 : // Aufheben der Selektion hier einzeln passieren:
1034 28 : if (bSame)
1035 2 : SelectionChanged();
1036 : }
1037 :
1038 28 : ShowAllCursors();
1039 28 : TestHintWindow();
1040 28 : }
1041 :
1042 22 : void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
1043 : bool bShift, bool bKeepSel )
1044 : {
1045 22 : ScDocument* pDoc = aViewData.GetDocument();
1046 22 : SCTAB nTab = aViewData.GetTabNo();
1047 :
1048 22 : bool bSkipProtected = false, bSkipUnprotected = false;
1049 22 : ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
1050 22 : if ( pProtect && pProtect->isProtected() )
1051 : {
1052 0 : bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
1053 0 : bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
1054 : }
1055 :
1056 22 : if ( bSkipProtected && bSkipUnprotected )
1057 22 : return;
1058 :
1059 : SCsCOL nOldX;
1060 : SCsROW nOldY;
1061 : SCsCOL nCurX;
1062 : SCsROW nCurY;
1063 22 : if ( aViewData.IsRefMode() )
1064 : {
1065 0 : nOldX = (SCsCOL) aViewData.GetRefEndX();
1066 0 : nOldY = (SCsROW) aViewData.GetRefEndY();
1067 0 : nCurX = nOldX + nMovX;
1068 0 : nCurY = nOldY + nMovY;
1069 : }
1070 : else
1071 : {
1072 22 : nOldX = (SCsCOL) aViewData.GetCurX();
1073 22 : nOldY = (SCsROW) aViewData.GetCurY();
1074 22 : nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
1075 22 : nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
1076 : }
1077 :
1078 22 : aViewData.ResetOldCursor();
1079 :
1080 22 : if (nMovX != 0 && ValidColRow(nCurX,nCurY))
1081 12 : SkipCursorHorizontal(nCurX, nCurY, nOldX, nMovX);
1082 :
1083 22 : if (nMovY != 0 && ValidColRow(nCurX,nCurY))
1084 10 : SkipCursorVertical(nCurX, nCurY, nOldY, nMovY);
1085 :
1086 22 : MoveCursorAbs( nCurX, nCurY, eMode, bShift, false, true, bKeepSel );
1087 : }
1088 :
1089 0 : void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1090 : {
1091 : SCsCOL nPageX;
1092 : SCsROW nPageY;
1093 0 : GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
1094 0 : MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
1095 0 : }
1096 :
1097 22 : void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1098 : {
1099 : SCsCOL nNewX;
1100 : SCsROW nNewY;
1101 22 : GetAreaMoveEndPosition(nMovX, nMovY, eMode, nNewX, nNewY, eMode);
1102 22 : MoveCursorRel(nNewX, nNewY, eMode, bShift, bKeepSel);
1103 22 : }
1104 :
1105 0 : void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1106 : {
1107 0 : ScDocument* pDoc = aViewData.GetDocument();
1108 0 : SCTAB nTab = aViewData.GetTabNo();
1109 :
1110 : SCCOL nCurX;
1111 : SCROW nCurY;
1112 0 : aViewData.GetMoveCursor( nCurX,nCurY );
1113 0 : SCCOL nNewX = nCurX;
1114 0 : SCROW nNewY = nCurY;
1115 :
1116 0 : SCCOL nUsedX = 0;
1117 0 : SCROW nUsedY = 0;
1118 0 : if ( nMovX > 0 || nMovY > 0 )
1119 0 : pDoc->GetPrintArea( nTab, nUsedX, nUsedY ); // Ende holen
1120 :
1121 0 : if (nMovX<0)
1122 0 : nNewX=0;
1123 0 : else if (nMovX>0)
1124 0 : nNewX=nUsedX; // letzter benutzter Bereich
1125 :
1126 0 : if (nMovY<0)
1127 0 : nNewY=0;
1128 0 : else if (nMovY>0)
1129 0 : nNewY=nUsedY;
1130 :
1131 0 : aViewData.ResetOldCursor();
1132 0 : MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
1133 0 : }
1134 :
1135 0 : void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift )
1136 : {
1137 0 : ScDocument* pDoc = aViewData.GetDocument();
1138 0 : SCTAB nTab = aViewData.GetTabNo();
1139 :
1140 : SCCOL nCurX;
1141 : SCROW nCurY;
1142 0 : aViewData.GetMoveCursor( nCurX,nCurY );
1143 0 : SCCOL nNewX = nCurX;
1144 0 : SCROW nNewY = nCurY;
1145 :
1146 0 : ScSplitPos eWhich = aViewData.GetActivePart();
1147 0 : SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
1148 0 : SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );
1149 :
1150 0 : SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
1151 0 : if (nAddX != 0)
1152 0 : --nAddX;
1153 0 : SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
1154 0 : if (nAddY != 0)
1155 0 : --nAddY;
1156 :
1157 0 : if (nMovX<0)
1158 0 : nNewX=nPosX;
1159 0 : else if (nMovX>0)
1160 0 : nNewX=nPosX+nAddX;
1161 :
1162 0 : if (nMovY<0)
1163 0 : nNewY=nPosY;
1164 0 : else if (nMovY>0)
1165 0 : nNewY=nPosY+nAddY;
1166 :
1167 0 : aViewData.SetOldCursor( nNewX,nNewY );
1168 0 : pDoc->SkipOverlapped(nNewX, nNewY, nTab);
1169 0 : MoveCursorAbs( nNewX, nNewY, eMode, bShift, false, true );
1170 0 : }
1171 :
1172 0 : void ScTabView::MoveCursorEnter( bool bShift ) // bShift -> hoch/runter
1173 : {
1174 0 : const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
1175 0 : if (!rOpt.GetMoveSelection())
1176 : {
1177 0 : aViewData.UpdateInputHandler(true);
1178 0 : return;
1179 : }
1180 :
1181 0 : SCsCOL nMoveX = 0;
1182 0 : SCsROW nMoveY = 0;
1183 0 : switch ((ScDirection)rOpt.GetMoveDir())
1184 : {
1185 : case DIR_BOTTOM:
1186 0 : nMoveY = bShift ? -1 : 1;
1187 0 : break;
1188 : case DIR_RIGHT:
1189 0 : nMoveX = bShift ? -1 : 1;
1190 0 : break;
1191 : case DIR_TOP:
1192 0 : nMoveY = bShift ? 1 : -1;
1193 0 : break;
1194 : case DIR_LEFT:
1195 0 : nMoveX = bShift ? 1 : -1;
1196 0 : break;
1197 : }
1198 :
1199 0 : ScMarkData& rMark = aViewData.GetMarkData();
1200 0 : if (rMark.IsMarked() || rMark.IsMultiMarked())
1201 : {
1202 : SCCOL nCurX;
1203 : SCROW nCurY;
1204 0 : aViewData.GetMoveCursor( nCurX,nCurY );
1205 0 : SCCOL nNewX = nCurX;
1206 0 : SCROW nNewY = nCurY;
1207 0 : SCTAB nTab = aViewData.GetTabNo();
1208 :
1209 0 : ScDocument* pDoc = aViewData.GetDocument();
1210 0 : pDoc->GetNextPos( nNewX,nNewY, nTab, nMoveX,nMoveY, true, false, rMark );
1211 :
1212 : MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1213 0 : SC_FOLLOW_LINE, false, true );
1214 :
1215 : // update input line even if cursor was not moved
1216 0 : if ( nNewX == nCurX && nNewY == nCurY )
1217 0 : aViewData.UpdateInputHandler(true);
1218 : }
1219 : else
1220 : {
1221 0 : if ( nMoveY != 0 && !nMoveX )
1222 : {
1223 : // nach Tab und Enter wieder zur Ausgangsspalte
1224 0 : SCCOL nTabCol = aViewData.GetTabStartCol();
1225 0 : if (nTabCol != SC_TABSTART_NONE)
1226 : {
1227 : SCCOL nCurX;
1228 : SCROW nCurY;
1229 0 : aViewData.GetMoveCursor( nCurX,nCurY );
1230 0 : nMoveX = ((SCsCOL)nTabCol)-(SCsCOL)nCurX;
1231 : }
1232 : }
1233 :
1234 0 : MoveCursorRel( nMoveX,nMoveY, SC_FOLLOW_LINE, false );
1235 : }
1236 : }
1237 :
1238 0 : bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
1239 : {
1240 0 : const vcl::KeyCode& rKCode = rKeyEvent.GetKeyCode();
1241 :
1242 : enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
1243 0 : rKCode.IsMod1() ?
1244 0 : (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
1245 0 : (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
1246 :
1247 0 : bool bSel = rKCode.IsShift();
1248 0 : sal_uInt16 nCode = rKCode.GetCode();
1249 :
1250 : // CURSOR keys
1251 0 : SCsCOL nDX = 0;
1252 0 : SCsROW nDY = 0;
1253 0 : switch( nCode )
1254 : {
1255 0 : case KEY_LEFT: nDX = -1; break;
1256 0 : case KEY_RIGHT: nDX = 1; break;
1257 0 : case KEY_UP: nDY = -1; break;
1258 0 : case KEY_DOWN: nDY = 1; break;
1259 : }
1260 0 : if( nDX != 0 || nDY != 0 )
1261 : {
1262 0 : switch( eModifier )
1263 : {
1264 0 : case MOD_NONE: MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel ); break;
1265 0 : case MOD_CTRL: MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel ); break;
1266 : default:
1267 : {
1268 : // added to avoid warnings
1269 : }
1270 : }
1271 : // always true to suppress changes of col/row size (ALT+CURSOR)
1272 0 : return true;
1273 : }
1274 :
1275 : // PAGEUP/PAGEDOWN
1276 0 : if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
1277 : {
1278 0 : nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
1279 0 : switch( eModifier )
1280 : {
1281 0 : case MOD_NONE: MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel ); break;
1282 0 : case MOD_ALT: MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel ); break;
1283 0 : case MOD_CTRL: SelectNextTab( nDX ); break;
1284 : default:
1285 : {
1286 : // added to avoid warnings
1287 : }
1288 : }
1289 0 : return true;
1290 : }
1291 :
1292 : // HOME/END
1293 0 : if( (nCode == KEY_HOME) || (nCode == KEY_END) )
1294 : {
1295 0 : nDX = (nCode == KEY_HOME) ? -1 : 1;
1296 0 : ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
1297 0 : switch( eModifier )
1298 : {
1299 0 : case MOD_NONE: MoveCursorEnd( nDX, 0, eMode, bSel ); break;
1300 0 : case MOD_CTRL: MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
1301 : default:
1302 : {
1303 : // added to avoid warnings
1304 : }
1305 : }
1306 0 : return true;
1307 : }
1308 :
1309 0 : return false;
1310 : }
1311 :
1312 : // naechste/vorherige nicht geschuetzte Zelle
1313 0 : void ScTabView::FindNextUnprot( bool bShift, bool bInSelection )
1314 : {
1315 0 : short nMove = bShift ? -1 : 1;
1316 :
1317 0 : ScMarkData& rMark = aViewData.GetMarkData();
1318 0 : bool bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
1319 :
1320 : SCCOL nCurX;
1321 : SCROW nCurY;
1322 0 : aViewData.GetMoveCursor( nCurX,nCurY );
1323 0 : SCCOL nNewX = nCurX;
1324 0 : SCROW nNewY = nCurY;
1325 0 : SCTAB nTab = aViewData.GetTabNo();
1326 :
1327 0 : ScDocument* pDoc = aViewData.GetDocument();
1328 0 : pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked, true, rMark );
1329 :
1330 0 : SCCOL nTabCol = aViewData.GetTabStartCol();
1331 0 : if ( nTabCol == SC_TABSTART_NONE )
1332 0 : nTabCol = nCurX; // auf diese Spalte zurueck bei Enter
1333 :
1334 : MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1335 0 : SC_FOLLOW_LINE, false, true );
1336 :
1337 : // in MoveCursorRel wird die TabCol zurueckgesetzt...
1338 0 : aViewData.SetTabStartCol( nTabCol );
1339 0 : }
1340 :
1341 0 : void ScTabView::MarkColumns()
1342 : {
1343 : SCCOL nStartCol;
1344 : SCCOL nEndCol;
1345 :
1346 0 : ScMarkData& rMark = aViewData.GetMarkData();
1347 0 : if (rMark.IsMarked())
1348 : {
1349 0 : ScRange aMarkRange;
1350 0 : rMark.GetMarkArea( aMarkRange );
1351 0 : nStartCol = aMarkRange.aStart.Col();
1352 0 : nEndCol = aMarkRange.aEnd.Col();
1353 : }
1354 : else
1355 : {
1356 : SCROW nDummy;
1357 0 : aViewData.GetMoveCursor( nStartCol, nDummy );
1358 0 : nEndCol=nStartCol;
1359 : }
1360 :
1361 0 : SCTAB nTab = aViewData.GetTabNo();
1362 0 : DoneBlockMode();
1363 0 : InitBlockMode( nStartCol,0, nTab );
1364 0 : MarkCursor( nEndCol,MAXROW, nTab );
1365 0 : SelectionChanged();
1366 0 : }
1367 :
1368 0 : void ScTabView::MarkRows()
1369 : {
1370 : SCROW nStartRow;
1371 : SCROW nEndRow;
1372 :
1373 0 : ScMarkData& rMark = aViewData.GetMarkData();
1374 0 : if (rMark.IsMarked())
1375 : {
1376 0 : ScRange aMarkRange;
1377 0 : rMark.GetMarkArea( aMarkRange );
1378 0 : nStartRow = aMarkRange.aStart.Row();
1379 0 : nEndRow = aMarkRange.aEnd.Row();
1380 : }
1381 : else
1382 : {
1383 : SCCOL nDummy;
1384 0 : aViewData.GetMoveCursor( nDummy, nStartRow );
1385 0 : nEndRow=nStartRow;
1386 : }
1387 :
1388 0 : SCTAB nTab = aViewData.GetTabNo();
1389 0 : DoneBlockMode();
1390 0 : InitBlockMode( 0,nStartRow, nTab );
1391 0 : MarkCursor( MAXCOL,nEndRow, nTab );
1392 0 : SelectionChanged();
1393 0 : }
1394 :
1395 0 : void ScTabView::MarkDataArea( bool bIncludeCursor )
1396 : {
1397 0 : ScDocument* pDoc = aViewData.GetDocument();
1398 0 : SCTAB nTab = aViewData.GetTabNo();
1399 0 : SCCOL nStartCol = aViewData.GetCurX();
1400 0 : SCROW nStartRow = aViewData.GetCurY();
1401 0 : SCCOL nEndCol = nStartCol;
1402 0 : SCROW nEndRow = nStartRow;
1403 :
1404 0 : pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );
1405 :
1406 0 : HideAllCursors();
1407 0 : DoneBlockMode();
1408 0 : InitBlockMode( nStartCol, nStartRow, nTab );
1409 0 : MarkCursor( nEndCol, nEndRow, nTab );
1410 0 : ShowAllCursors();
1411 :
1412 0 : SelectionChanged();
1413 0 : }
1414 :
1415 0 : void ScTabView::MarkMatrixFormula()
1416 : {
1417 0 : ScDocument* pDoc = aViewData.GetDocument();
1418 0 : ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
1419 0 : ScRange aMatrix;
1420 0 : if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
1421 : {
1422 0 : MarkRange( aMatrix, false ); // cursor is already within the range
1423 : }
1424 0 : }
1425 :
1426 132 : void ScTabView::MarkRange( const ScRange& rRange, bool bSetCursor, bool bContinue )
1427 : {
1428 132 : SCTAB nTab = rRange.aStart.Tab();
1429 132 : SetTabNo( nTab );
1430 :
1431 132 : HideAllCursors();
1432 132 : DoneBlockMode( bContinue ); // bContinue==true -> clear old mark
1433 132 : if (bSetCursor) // Wenn Cursor gesetzt wird, immer auch alignen
1434 : {
1435 132 : SCCOL nAlignX = rRange.aStart.Col();
1436 132 : SCROW nAlignY = rRange.aStart.Row();
1437 132 : bool bCol = ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL ) && !aViewData.GetDocument()->IsInVBAMode();
1438 132 : bool bRow = ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW );
1439 132 : if ( bCol )
1440 0 : nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
1441 132 : if ( bRow )
1442 0 : nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
1443 132 : AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
1444 : }
1445 132 : InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
1446 132 : MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
1447 132 : if (bSetCursor)
1448 : {
1449 132 : SCCOL nPosX = rRange.aStart.Col();
1450 132 : SCROW nPosY = rRange.aStart.Row();
1451 132 : ScDocument* pDoc = aViewData.GetDocument();
1452 132 : pDoc->SkipOverlapped(nPosX, nPosY, nTab);
1453 :
1454 132 : aViewData.ResetOldCursor();
1455 132 : SetCursor( nPosX, nPosY );
1456 : }
1457 132 : ShowAllCursors();
1458 :
1459 132 : SelectionChanged();
1460 132 : }
1461 :
1462 8 : void ScTabView::Unmark()
1463 : {
1464 8 : ScMarkData& rMark = aViewData.GetMarkData();
1465 8 : if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1466 : {
1467 : SCCOL nCurX;
1468 : SCROW nCurY;
1469 0 : aViewData.GetMoveCursor( nCurX,nCurY );
1470 0 : MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, false, false );
1471 :
1472 0 : SelectionChanged();
1473 : }
1474 8 : }
1475 :
1476 0 : void ScTabView::SetMarkData( const ScMarkData& rNew )
1477 : {
1478 0 : DoneBlockMode();
1479 0 : InitOwnBlockMode();
1480 0 : aViewData.GetMarkData() = rNew;
1481 :
1482 0 : MarkDataChanged();
1483 0 : }
1484 :
1485 62 : void ScTabView::MarkDataChanged()
1486 : {
1487 : // has to be called after making direct changes to mark data (not via MarkCursor etc)
1488 :
1489 62 : UpdateSelectionOverlay();
1490 62 : }
1491 :
1492 0 : void ScTabView::SelectNextTab( short nDir, bool bExtendSelection )
1493 : {
1494 0 : if (!nDir) return;
1495 : OSL_ENSURE( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");
1496 :
1497 0 : ScDocument* pDoc = aViewData.GetDocument();
1498 0 : SCTAB nTab = aViewData.GetTabNo();
1499 0 : if (nDir<0)
1500 : {
1501 0 : if (!nTab) return;
1502 0 : --nTab;
1503 0 : while (!pDoc->IsVisible(nTab))
1504 : {
1505 0 : if (!nTab) return;
1506 0 : --nTab;
1507 : }
1508 : }
1509 : else
1510 : {
1511 0 : SCTAB nCount = pDoc->GetTableCount();
1512 0 : ++nTab;
1513 0 : if (nTab >= nCount) return;
1514 0 : while (!pDoc->IsVisible(nTab))
1515 : {
1516 0 : ++nTab;
1517 0 : if (nTab >= nCount) return;
1518 : }
1519 : }
1520 :
1521 0 : SetTabNo( nTab, false, bExtendSelection );
1522 0 : PaintExtras();
1523 : }
1524 :
1525 : // SetTabNo - angezeigte Tabelle
1526 :
1527 906 : void ScTabView::SetTabNo( SCTAB nTab, bool bNew, bool bExtendSelection, bool bSameTabButMoved )
1528 : {
1529 906 : if ( !ValidTab(nTab) )
1530 : {
1531 : OSL_FAIL("SetTabNo: falsche Tabelle");
1532 0 : return;
1533 : }
1534 :
1535 906 : if ( nTab != aViewData.GetTabNo() || bNew )
1536 : {
1537 : // Die FormShell moechte vor dem Umschalten benachrichtigt werden
1538 752 : FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
1539 752 : if (pFormSh)
1540 : {
1541 752 : bool bAllowed = pFormSh->PrepareClose(true);
1542 752 : if (!bAllowed)
1543 : {
1544 : //! Fehlermeldung? oder macht das die FormShell selber?
1545 : //! Fehler-Flag zurueckgeben und Aktionen abbrechen
1546 :
1547 0 : return; // Die FormShell sagt, es kann nicht umgeschaltet werden
1548 : }
1549 : }
1550 :
1551 : // nicht InputEnterHandler wegen Referenzeingabe !
1552 :
1553 752 : ScDocument* pDoc = aViewData.GetDocument();
1554 :
1555 752 : pDoc->MakeTable( nTab );
1556 :
1557 : // Update pending row heights before switching the sheet, so Reschedule from the progress bar
1558 : // doesn't paint the new sheet with old heights
1559 752 : aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
1560 :
1561 752 : SCTAB nTabCount = pDoc->GetTableCount();
1562 752 : SCTAB nOldPos = nTab;
1563 1506 : while (!pDoc->IsVisible(nTab)) // naechste sichtbare suchen
1564 : {
1565 2 : bool bUp = (nTab>=nOldPos);
1566 2 : if (bUp)
1567 : {
1568 2 : ++nTab;
1569 2 : if (nTab>=nTabCount)
1570 : {
1571 2 : nTab = nOldPos;
1572 2 : bUp = false;
1573 : }
1574 : }
1575 :
1576 2 : if (!bUp)
1577 : {
1578 2 : if (nTab != 0)
1579 2 : --nTab;
1580 : else
1581 : {
1582 : OSL_FAIL("keine sichtbare Tabelle");
1583 0 : pDoc->SetVisible( 0, true );
1584 : }
1585 : }
1586 : }
1587 :
1588 : // #i71490# Deselect drawing objects before changing the sheet number in view data,
1589 : // so the handling of notes still has the sheet selected on which the notes are.
1590 752 : DrawDeselectAll();
1591 :
1592 752 : ScModule* pScMod = SC_MOD();
1593 752 : bool bRefMode = pScMod->IsFormulaMode();
1594 752 : if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
1595 : {
1596 752 : DoneBlockMode();
1597 752 : pSelEngine->Reset(); // reset all flags, including locked modifiers
1598 752 : aViewData.SetRefTabNo( nTab );
1599 : }
1600 :
1601 752 : ScSplitPos eOldActive = aViewData.GetActivePart(); // before switching
1602 752 : bool bFocus = pGridWin[eOldActive]->HasFocus();
1603 :
1604 752 : aViewData.SetTabNo( nTab );
1605 : // UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
1606 : // Fenster findet (wird aus SetCursor gerufen)
1607 752 : UpdateShow();
1608 752 : aViewData.ResetOldCursor();
1609 :
1610 752 : SfxBindings& rBindings = aViewData.GetBindings();
1611 752 : ScMarkData& rMark = aViewData.GetMarkData();
1612 :
1613 752 : bool bAllSelected = true;
1614 1750 : for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
1615 : {
1616 1164 : if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
1617 : {
1618 718 : if (nTab == nSelTab)
1619 : // This tab is already in selection. Keep the current
1620 : // selection.
1621 610 : bExtendSelection = true;
1622 : }
1623 : else
1624 : {
1625 446 : bAllSelected = false;
1626 446 : if (bExtendSelection)
1627 : // We got what we need. No need to stay in the loop.
1628 166 : break;
1629 : }
1630 : }
1631 752 : if (bAllSelected && !bNew)
1632 : // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
1633 : // (not if called with bNew to update settings)
1634 0 : bExtendSelection = false;
1635 :
1636 752 : if (bExtendSelection)
1637 610 : rMark.SelectTable( nTab, true );
1638 : else
1639 : {
1640 142 : rMark.SelectOneTable( nTab );
1641 142 : rBindings.Invalidate( FID_FILL_TAB );
1642 142 : rBindings.Invalidate( FID_TAB_DESELECTALL );
1643 : }
1644 :
1645 752 : SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), true );
1646 752 : bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
1647 :
1648 : // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
1649 752 : RefreshZoom();
1650 752 : UpdateVarZoom();
1651 :
1652 752 : if ( bRefMode ) // hide EditView if necessary (after aViewData.SetTabNo !)
1653 : {
1654 0 : for (sal_uInt16 i = 0; i < 4; ++i)
1655 0 : if (pGridWin[i] && pGridWin[i]->IsVisible())
1656 0 : pGridWin[i]->UpdateEditViewPos();
1657 : }
1658 :
1659 752 : TabChanged(bSameTabButMoved); // DrawView
1660 752 : UpdateVisibleRange();
1661 :
1662 752 : aViewData.GetViewShell()->WindowChanged(); // falls das aktive Fenster anders ist
1663 752 : if ( !bUnoRefDialog )
1664 752 : aViewData.GetViewShell()->DisconnectAllClients(); // important for floating frames
1665 : else
1666 : {
1667 : // hide / show inplace client
1668 :
1669 0 : ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
1670 0 : if ( pClient && pClient->IsObjectInPlaceActive() )
1671 : {
1672 0 : Rectangle aObjArea = pClient->GetObjArea();
1673 0 : if ( nTab == aViewData.GetRefTabNo() )
1674 : {
1675 : // move to its original position
1676 :
1677 0 : SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
1678 0 : if ( pDrawObj )
1679 : {
1680 0 : Rectangle aRect = pDrawObj->GetLogicRect();
1681 0 : MapMode aMapMode( MAP_100TH_MM );
1682 0 : Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
1683 0 : aRect.SetSize( aOleSize );
1684 0 : aObjArea = aRect;
1685 : }
1686 : }
1687 : else
1688 : {
1689 : // move to an invisible position
1690 :
1691 0 : aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
1692 : }
1693 0 : pClient->SetObjArea( aObjArea );
1694 : }
1695 : }
1696 :
1697 752 : if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
1698 0 : ActiveGrabFocus(); // grab focus to the pane that's active now
1699 :
1700 : // Fixierungen
1701 :
1702 752 : bool bResize = false;
1703 752 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1704 0 : if (aViewData.UpdateFixX())
1705 0 : bResize = true;
1706 752 : if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1707 0 : if (aViewData.UpdateFixY())
1708 0 : bResize = true;
1709 752 : if (bResize)
1710 0 : RepeatResize();
1711 752 : InvalidateSplit();
1712 :
1713 752 : if ( aViewData.IsPagebreakMode() )
1714 0 : UpdatePageBreakData(); //! asynchron ??
1715 :
1716 : // Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle kennen
1717 : // dafuer muss hier schon der MapMode stimmen
1718 3760 : for (sal_uInt16 i=0; i<4; i++)
1719 3008 : if (pGridWin[i])
1720 752 : pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1721 752 : SetNewVisArea();
1722 :
1723 752 : PaintGrid();
1724 752 : PaintTop();
1725 752 : PaintLeft();
1726 752 : PaintExtras();
1727 :
1728 752 : DoResize( aBorderPos, aFrameSize );
1729 752 : rBindings.Invalidate( SID_DELETE_PRINTAREA ); // Menue
1730 752 : rBindings.Invalidate( FID_DEL_MANUALBREAKS );
1731 752 : rBindings.Invalidate( FID_RESET_PRINTZOOM );
1732 752 : rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
1733 752 : rBindings.Invalidate( SID_ROWCOL_SELCOUNT ); // Statusbar
1734 752 : rBindings.Invalidate( SID_STATUS_PAGESTYLE ); // Statusbar
1735 752 : rBindings.Invalidate( SID_CURRENTTAB ); // Navigator
1736 752 : rBindings.Invalidate( SID_STYLE_FAMILY2 ); // Gestalter
1737 752 : rBindings.Invalidate( SID_STYLE_FAMILY4 ); // Gestalter
1738 752 : rBindings.Invalidate( SID_TABLES_COUNT );
1739 :
1740 752 : if(pScMod->IsRefDialogOpen())
1741 : {
1742 0 : sal_uInt16 nCurRefDlgId=pScMod->GetCurRefDlgId();
1743 0 : SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
1744 0 : SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
1745 0 : IAnyRefDialog* pRefDlg = pChildWnd ? dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow()) : NULL;
1746 0 : if (pRefDlg)
1747 : {
1748 0 : pRefDlg->ViewShellChanged();
1749 : }
1750 : }
1751 : }
1752 : }
1753 :
1754 : // Paint-Funktionen - nur fuer diese View
1755 :
1756 0 : void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
1757 : {
1758 0 : DrawDeselectAll();
1759 :
1760 0 : if (pDrawView)
1761 0 : DrawEnableAnim( false );
1762 :
1763 0 : EditView* pSpellingView = aViewData.GetSpellingView();
1764 :
1765 0 : for (sal_uInt16 i=0; i<4; i++)
1766 0 : if (pGridWin[i])
1767 0 : if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
1768 : {
1769 0 : ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1770 0 : ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1771 0 : SCCOL nScrX = aViewData.GetPosX( eHWhich );
1772 0 : SCROW nScrY = aViewData.GetPosY( eVWhich );
1773 :
1774 : bool bPosVisible =
1775 0 : ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
1776 0 : nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
1777 :
1778 : // for the active part, create edit view even if outside the visible area,
1779 : // so input isn't lost (and the edit view may be scrolled into the visible area)
1780 :
1781 : // #i26433# during spelling, the spelling view must be active
1782 0 : if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
1783 0 : ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
1784 : {
1785 0 : pGridWin[i]->HideCursor();
1786 :
1787 0 : pGridWin[i]->DeleteCursorOverlay();
1788 0 : pGridWin[i]->DeleteAutoFillOverlay();
1789 0 : pGridWin[i]->DeleteCopySourceOverlay();
1790 :
1791 : // flush OverlayManager before changing MapMode to text edit
1792 0 : pGridWin[i]->flushOverlayManager();
1793 :
1794 : // MapMode must be set after HideCursor
1795 0 : pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
1796 :
1797 0 : aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );
1798 :
1799 0 : if ( !bPosVisible )
1800 : {
1801 : // move the edit view area to the real (possibly negative) position,
1802 : // or hide if completely above or left of the window
1803 0 : pGridWin[i]->UpdateEditViewPos();
1804 : }
1805 : }
1806 : }
1807 :
1808 0 : if (aViewData.GetViewShell()->HasAccessibilityObjects())
1809 0 : aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_ENTEREDITMODE));
1810 0 : }
1811 :
1812 0 : void ScTabView::UpdateEditView()
1813 : {
1814 0 : ScSplitPos eActive = aViewData.GetActivePart();
1815 0 : for (sal_uInt16 i=0; i<4; i++)
1816 0 : if (aViewData.HasEditView( (ScSplitPos) i ))
1817 : {
1818 0 : EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
1819 : aViewData.SetEditEngine( (ScSplitPos) i,
1820 0 : static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
1821 0 : pGridWin[i], GetViewData().GetCurX(), GetViewData().GetCurY() );
1822 0 : if ( (ScSplitPos)i == eActive )
1823 0 : pEditView->ShowCursor( false );
1824 : }
1825 0 : }
1826 :
1827 3484 : void ScTabView::KillEditView( bool bNoPaint )
1828 : {
1829 : sal_uInt16 i;
1830 3484 : SCCOL nCol1 = aViewData.GetEditStartCol();
1831 3484 : SCROW nRow1 = aViewData.GetEditStartRow();
1832 3484 : SCCOL nCol2 = aViewData.GetEditEndCol();
1833 3484 : SCROW nRow2 = aViewData.GetEditEndRow();
1834 : bool bPaint[4];
1835 3484 : bool bNotifyAcc = false;
1836 :
1837 3484 : bool bExtended = nRow1 != nRow2; // Col wird sowieso bis zum Ende gezeichnet
1838 6968 : bool bAtCursor = nCol1 <= aViewData.GetCurX() &&
1839 6100 : nCol2 >= aViewData.GetCurX() &&
1840 6100 : nRow1 == aViewData.GetCurY();
1841 17420 : for (i=0; i<4; i++)
1842 : {
1843 13936 : bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
1844 13936 : if (bPaint[i])
1845 0 : bNotifyAcc = true;
1846 : }
1847 :
1848 : // #108931#; notify accessibility before all things happen
1849 3484 : if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
1850 0 : aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
1851 :
1852 3484 : aViewData.ResetEditView();
1853 17420 : for (i=0; i<4; i++)
1854 13936 : if (pGridWin[i] && bPaint[i])
1855 0 : if (pGridWin[i]->IsVisible())
1856 : {
1857 0 : pGridWin[i]->ShowCursor();
1858 :
1859 0 : pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
1860 :
1861 : // #i73567# the cell still has to be repainted
1862 0 : if (bExtended || ( bAtCursor && !bNoPaint ))
1863 : {
1864 0 : pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
1865 0 : pGridWin[i]->UpdateSelectionOverlay();
1866 : }
1867 : }
1868 :
1869 3484 : if (pDrawView)
1870 3484 : DrawEnableAnim( true );
1871 :
1872 : // GrabFocus immer dann, wenn diese View aktiv ist und
1873 : // die Eingabezeile den Focus hat
1874 :
1875 3484 : bool bGrabFocus = false;
1876 3484 : if (aViewData.IsActive())
1877 : {
1878 3366 : ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
1879 3366 : if ( pInputHdl )
1880 : {
1881 2834 : ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
1882 2834 : if (pInputWin && pInputWin->IsInputActive())
1883 0 : bGrabFocus = true;
1884 : }
1885 : }
1886 :
1887 3484 : if (bGrabFocus)
1888 : {
1889 : // So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
1890 : //! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1891 : // deshalb erstmal so:
1892 0 : GetActiveWin()->GrabFocus();
1893 : }
1894 :
1895 : // Cursor-Abfrage erst nach GrabFocus
1896 :
1897 17420 : for (i=0; i<4; i++)
1898 13936 : if (pGridWin[i] && pGridWin[i]->IsVisible())
1899 : {
1900 3484 : vcl::Cursor* pCur = pGridWin[i]->GetCursor();
1901 3484 : if (pCur && pCur->IsVisible())
1902 0 : pCur->Hide();
1903 :
1904 3484 : if(bPaint[i])
1905 : {
1906 0 : pGridWin[i]->UpdateCursorOverlay();
1907 0 : pGridWin[i]->UpdateAutoFillOverlay();
1908 : }
1909 : }
1910 3484 : }
1911 :
1912 14800 : void ScTabView::UpdateFormulas()
1913 : {
1914 14800 : if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
1915 14800 : return ;
1916 :
1917 : sal_uInt16 i;
1918 74000 : for (i=0; i<4; i++)
1919 59200 : if (pGridWin[i])
1920 14836 : if (pGridWin[i]->IsVisible())
1921 14808 : pGridWin[i]->UpdateFormulas();
1922 :
1923 14800 : if ( aViewData.IsPagebreakMode() )
1924 0 : UpdatePageBreakData(); //! asynchron
1925 :
1926 14800 : UpdateHeaderWidth();
1927 :
1928 : // if in edit mode, adjust edit view area because widths/heights may have changed
1929 14800 : if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
1930 0 : UpdateEditView();
1931 : }
1932 :
1933 : // PaintArea -Block neu zeichnen
1934 :
1935 14930 : void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1936 : ScUpdateMode eMode )
1937 : {
1938 : SCCOL nCol1;
1939 : SCROW nRow1;
1940 : SCCOL nCol2;
1941 : SCROW nRow2;
1942 :
1943 14930 : PutInOrder( nStartCol, nEndCol );
1944 14930 : PutInOrder( nStartRow, nEndRow );
1945 :
1946 74650 : for (size_t i = 0; i < 4; ++i)
1947 : {
1948 59720 : if (!pGridWin[i] || !pGridWin[i]->IsVisible())
1949 44790 : continue;
1950 :
1951 14930 : ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1952 14930 : ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1953 14930 : bool bOut = false;
1954 :
1955 14930 : nCol1 = nStartCol;
1956 14930 : nRow1 = nStartRow;
1957 14930 : nCol2 = nEndCol;
1958 14930 : nRow2 = nEndRow;
1959 :
1960 14930 : SCCOL nScrX = aViewData.GetPosX( eHWhich );
1961 14930 : SCROW nScrY = aViewData.GetPosY( eVWhich );
1962 14930 : if (nCol1 < nScrX) nCol1 = nScrX;
1963 14930 : if (nCol2 < nScrX)
1964 : {
1965 2 : if ( eMode == SC_UPDATE_ALL ) // for UPDATE_ALL, paint anyway
1966 2 : nCol2 = nScrX; // (because of extending strings to the right)
1967 : else
1968 0 : bOut = true; // completely outside the window
1969 : }
1970 14930 : if (nRow1 < nScrY) nRow1 = nScrY;
1971 14930 : if (nRow2 < nScrY) bOut = true;
1972 :
1973 14930 : SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
1974 14930 : SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
1975 14930 : if (nCol1 > nLastX) bOut = true;
1976 14930 : if (nCol2 > nLastX) nCol2 = nLastX;
1977 14930 : if (nRow1 > nLastY) bOut = true;
1978 14930 : if (nRow2 > nLastY) nRow2 = nLastY;
1979 :
1980 14930 : if (bOut)
1981 7140 : continue;
1982 :
1983 7790 : if ( eMode == SC_UPDATE_CHANGED )
1984 0 : pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
1985 : else // ALL oder MARKS
1986 : {
1987 7790 : bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1988 7790 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1989 :
1990 7790 : Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
1991 7790 : Point aEnd = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
1992 7790 : if ( eMode == SC_UPDATE_ALL )
1993 7780 : aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
1994 7790 : aEnd.X() -= nLayoutSign;
1995 7790 : aEnd.Y() -= 1;
1996 :
1997 : // #i85232# include area below cells (could be done in GetScrPos?)
1998 7790 : if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
1999 0 : aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();
2000 :
2001 7790 : aStart.X() -= nLayoutSign; // include change marks
2002 7790 : aStart.Y() -= 1;
2003 :
2004 7790 : bool bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
2005 7790 : if (bMarkClipped)
2006 : {
2007 : // dazu muesste ScColumn::IsEmptyBlock optimiert werden
2008 : // (auf Search() umstellen)
2009 : //!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
2010 : //! aViewData.GetTabNo(),
2011 : //! 0, nRow1, nCol1-1, nRow2 ) )
2012 : {
2013 7790 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
2014 7790 : aStart.X() -= nMarkPixel * nLayoutSign;
2015 : }
2016 : }
2017 :
2018 7790 : pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
2019 : }
2020 : }
2021 :
2022 : // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
2023 : // with a wrong MapMode if editing in a cell (reference input).
2024 : // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
2025 : // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
2026 : // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
2027 : // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
2028 : // is set (width or height changed).
2029 14930 : }
2030 :
2031 0 : void ScTabView::PaintRangeFinderEntry (ScRangeFindData* pData, const SCTAB nTab)
2032 : {
2033 0 : ScRange aRef = pData->aRef;
2034 0 : aRef.Justify(); // Justify fuer die Abfragen unten
2035 :
2036 0 : if ( aRef.aStart == aRef.aEnd ) //! Tab ignorieren?
2037 0 : aViewData.GetDocument()->ExtendMerge(aRef);
2038 :
2039 0 : if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
2040 : {
2041 0 : SCCOL nCol1 = aRef.aStart.Col();
2042 0 : SCROW nRow1 = aRef.aStart.Row();
2043 0 : SCCOL nCol2 = aRef.aEnd.Col();
2044 0 : SCROW nRow2 = aRef.aEnd.Row();
2045 :
2046 : // wegnehmen -> Repaint
2047 : // SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende
2048 :
2049 0 : bool bHiddenEdge = false;
2050 : SCROW nTmp;
2051 0 : ScDocument* pDoc = aViewData.GetDocument();
2052 0 : while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab) )
2053 : {
2054 0 : --nCol1;
2055 0 : bHiddenEdge = true;
2056 : }
2057 0 : while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab) )
2058 : {
2059 0 : ++nCol2;
2060 0 : bHiddenEdge = true;
2061 : }
2062 0 : nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
2063 0 : if (!ValidRow(nTmp))
2064 0 : nTmp = 0;
2065 0 : if (nTmp < nRow1)
2066 : {
2067 0 : nRow1 = nTmp;
2068 0 : bHiddenEdge = true;
2069 : }
2070 0 : nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
2071 0 : if (!ValidRow(nTmp))
2072 0 : nTmp = MAXROW;
2073 0 : if (nTmp > nRow2)
2074 : {
2075 0 : nRow2 = nTmp;
2076 0 : bHiddenEdge = true;
2077 : }
2078 :
2079 0 : if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
2080 : {
2081 : // nur an den Raendern entlang
2082 0 : PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
2083 0 : PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
2084 0 : PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
2085 0 : PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
2086 : }
2087 : else // alles am Stueck
2088 0 : PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
2089 : }
2090 0 : }
2091 :
2092 0 : void ScTabView::PaintRangeFinder( long nNumber )
2093 : {
2094 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
2095 0 : if (pHdl)
2096 : {
2097 0 : ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
2098 0 : if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
2099 : {
2100 0 : SCTAB nTab = aViewData.GetTabNo();
2101 0 : sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
2102 :
2103 0 : if (nNumber < 0)
2104 : {
2105 0 : for (sal_uInt16 i=0; i<nCount; i++)
2106 0 : PaintRangeFinderEntry(pRangeFinder->GetObject(i),nTab);
2107 : }
2108 : else
2109 : {
2110 0 : sal_uInt16 idx = nNumber;
2111 0 : if (idx < nCount)
2112 0 : PaintRangeFinderEntry(pRangeFinder->GetObject(idx),nTab);
2113 : }
2114 : }
2115 : }
2116 0 : }
2117 :
2118 : // fuer Chart-Daten-Markierung
2119 :
2120 0 : void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
2121 : {
2122 0 : maHighlightRanges.push_back( ScHighlightEntry( rRange, rColor ) );
2123 :
2124 0 : SCTAB nTab = aViewData.GetTabNo();
2125 0 : if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
2126 0 : PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
2127 0 : rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
2128 0 : }
2129 :
2130 0 : void ScTabView::ClearHighlightRanges()
2131 : {
2132 0 : SCTAB nTab = aViewData.GetTabNo();
2133 0 : std::vector<ScHighlightEntry>::const_iterator pIter;
2134 0 : for ( pIter = maHighlightRanges.begin(); pIter != maHighlightRanges.end(); ++pIter)
2135 : {
2136 0 : ScRange aRange = pIter->aRef;
2137 0 : if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
2138 0 : PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
2139 0 : aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
2140 : }
2141 :
2142 0 : maHighlightRanges.clear();
2143 0 : }
2144 :
2145 0 : void ScTabView::DoChartSelection(
2146 : const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
2147 : {
2148 0 : ClearHighlightRanges();
2149 0 : const sal_Unicode sep = ::formula::FormulaCompiler::GetNativeSymbolChar(ocSep);
2150 :
2151 0 : for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
2152 : {
2153 0 : Color aSelColor( rHilightRanges[i].PreferredColor );
2154 0 : ScRangeList aRangeList;
2155 0 : ScDocument& rDoc = aViewData.GetDocShell()->GetDocument();
2156 0 : if( ScRangeStringConverter::GetRangeListFromString(
2157 0 : aRangeList, rHilightRanges[i].RangeRepresentation, &rDoc, rDoc.GetAddressConvention(), sep ))
2158 : {
2159 0 : size_t nListSize = aRangeList.size();
2160 0 : for ( size_t j = 0; j < nListSize; ++j )
2161 : {
2162 0 : ScRange* p = aRangeList[j];
2163 0 : if( rHilightRanges[i].Index == - 1 )
2164 0 : AddHighlightRange( *p, aSelColor );
2165 : else
2166 0 : AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
2167 : }
2168 : }
2169 0 : }
2170 0 : }
2171 :
2172 : // PaintGrid - Datenbereiche neu zeichnen
2173 :
2174 866 : void ScTabView::PaintGrid()
2175 : {
2176 : sal_uInt16 i;
2177 4330 : for (i=0; i<4; i++)
2178 3464 : if (pGridWin[i])
2179 1096 : if (pGridWin[i]->IsVisible())
2180 930 : pGridWin[i]->Invalidate();
2181 866 : }
2182 :
2183 : // PaintTop - obere Kontrollelemente neu zeichnen
2184 :
2185 842 : void ScTabView::PaintTop()
2186 : {
2187 : sal_uInt16 i;
2188 2526 : for (i=0; i<2; i++)
2189 : {
2190 1684 : if (pColBar[i])
2191 896 : pColBar[i]->Invalidate();
2192 1684 : if (pColOutline[i])
2193 2 : pColOutline[i]->Invalidate();
2194 : }
2195 842 : }
2196 :
2197 0 : void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
2198 : {
2199 : sal_uInt16 i;
2200 :
2201 0 : for(i=0; i<4; i++)
2202 : {
2203 0 : if(pGridWin[i])
2204 : {
2205 0 : if(pGridWin[i]->IsVisible())
2206 : {
2207 0 : pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
2208 : }
2209 : }
2210 : }
2211 0 : }
2212 :
2213 228 : void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
2214 : {
2215 : // Pixel-Position der linken Kante
2216 :
2217 402 : if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
2218 174 : nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
2219 54 : aViewData.RecalcPixPos();
2220 :
2221 : // Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
2222 :
2223 228 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
2224 0 : if (aViewData.UpdateFixX())
2225 0 : RepeatResize();
2226 :
2227 : // zeichnen
2228 :
2229 228 : if (nStartCol>0)
2230 6 : --nStartCol; //! allgemeiner ?
2231 :
2232 228 : bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2233 228 : long nLayoutSign = bLayoutRTL ? -1 : 1;
2234 :
2235 684 : for (sal_uInt16 i=0; i<2; i++)
2236 : {
2237 456 : ScHSplitPos eWhich = (ScHSplitPos) i;
2238 456 : if (pColBar[eWhich])
2239 : {
2240 228 : Size aWinSize = pColBar[eWhich]->GetSizePixel();
2241 228 : long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
2242 : long nEndX;
2243 228 : if (nEndCol >= MAXCOL)
2244 226 : nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
2245 : else
2246 2 : nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
2247 684 : pColBar[eWhich]->Invalidate(
2248 912 : Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
2249 : }
2250 456 : if (pColOutline[eWhich])
2251 48 : pColOutline[eWhich]->Invalidate();
2252 : }
2253 228 : }
2254 :
2255 : // PaintLeft - linke Kontrollelemente neu zeichnen
2256 :
2257 846 : void ScTabView::PaintLeft()
2258 : {
2259 : sal_uInt16 i;
2260 2538 : for (i=0; i<2; i++)
2261 : {
2262 1692 : if (pRowBar[i])
2263 904 : pRowBar[i]->Invalidate();
2264 1692 : if (pRowOutline[i])
2265 6 : pRowOutline[i]->Invalidate();
2266 : }
2267 846 : }
2268 :
2269 400 : void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
2270 : {
2271 : // Pixel-Position der oberen Kante
2272 :
2273 800 : if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
2274 400 : nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
2275 32 : aViewData.RecalcPixPos();
2276 :
2277 : // Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
2278 :
2279 400 : if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
2280 0 : if (aViewData.UpdateFixY())
2281 0 : RepeatResize();
2282 :
2283 : // zeichnen
2284 :
2285 400 : if (nStartRow>0)
2286 130 : --nStartRow;
2287 :
2288 1200 : for (sal_uInt16 i=0; i<2; i++)
2289 : {
2290 800 : ScVSplitPos eWhich = (ScVSplitPos) i;
2291 800 : if (pRowBar[eWhich])
2292 : {
2293 400 : Size aWinSize = pRowBar[eWhich]->GetSizePixel();
2294 400 : long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
2295 : long nEndY;
2296 400 : if (nEndRow >= MAXROW)
2297 400 : nEndY = aWinSize.Height()-1;
2298 : else
2299 0 : nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
2300 1200 : pRowBar[eWhich]->Invalidate(
2301 1600 : Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
2302 : }
2303 800 : if (pRowOutline[eWhich])
2304 96 : pRowOutline[eWhich]->Invalidate();
2305 : }
2306 400 : }
2307 :
2308 4938 : bool ScTabView::PaintExtras()
2309 : {
2310 4938 : bool bRet = false;
2311 4938 : ScDocument* pDoc = aViewData.GetDocument();
2312 4938 : SCTAB nTab = aViewData.GetTabNo();
2313 4938 : if (!pDoc->HasTable(nTab)) // Tabelle geloescht ?
2314 : {
2315 0 : SCTAB nCount = pDoc->GetTableCount();
2316 0 : aViewData.SetTabNo(nCount-1);
2317 0 : bRet = true;
2318 : }
2319 4938 : pTabControl->UpdateStatus(); // true = active
2320 4938 : return bRet;
2321 : }
2322 :
2323 40 : void ScTabView::RecalcPPT()
2324 : {
2325 : // called after changes that require the PPT values to be recalculated
2326 : // (currently from detective operations)
2327 :
2328 40 : double nOldX = aViewData.GetPPTX();
2329 40 : double nOldY = aViewData.GetPPTY();
2330 :
2331 40 : aViewData.RefreshZoom(); // pre-calculate new PPT values
2332 :
2333 40 : bool bChangedX = ( aViewData.GetPPTX() != nOldX );
2334 40 : bool bChangedY = ( aViewData.GetPPTY() != nOldY );
2335 40 : if ( bChangedX || bChangedY )
2336 : {
2337 : // call view SetZoom (including draw scale, split update etc)
2338 : // and paint only if values changed
2339 :
2340 0 : Fraction aZoomX = aViewData.GetZoomX();
2341 0 : Fraction aZoomY = aViewData.GetZoomY();
2342 0 : SetZoom( aZoomX, aZoomY, false );
2343 :
2344 0 : PaintGrid();
2345 0 : if (bChangedX)
2346 0 : PaintTop();
2347 0 : if (bChangedY)
2348 0 : PaintLeft();
2349 : }
2350 40 : }
2351 :
2352 1084 : void ScTabView::ActivateView( bool bActivate, bool bFirst )
2353 : {
2354 1084 : if ( bActivate == aViewData.IsActive() && !bFirst )
2355 : {
2356 : // keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
2357 : // auf ein anderes Dokument umgeschaltet wurde
2358 1084 : return;
2359 : }
2360 :
2361 : // wird nur bei MDI-(De)Activate gerufen
2362 : // aViewData.Activate hinten wegen Cursor-Show bei KillEditView
2363 : // Markierung nicht mehr loeschen - wenn an der ViewData Activate(false) gesetzt ist,
2364 : // wird die Markierung nicht ausgegeben
2365 :
2366 1084 : if (!bActivate)
2367 : {
2368 542 : ScModule* pScMod = SC_MOD();
2369 542 : bool bRefMode = pScMod->IsFormulaMode();
2370 :
2371 : // Referenzeingabe nicht abbrechen, um Referenzen auf
2372 : // andere Dokumente zuzulassen
2373 :
2374 542 : if (!bRefMode)
2375 : {
2376 : // pass view to GetInputHdl, this view may not be current anymore
2377 542 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2378 542 : if (pHdl)
2379 542 : pHdl->EnterHandler();
2380 : }
2381 : }
2382 :
2383 1084 : PaintExtras();
2384 :
2385 1084 : aViewData.Activate(bActivate);
2386 :
2387 1084 : PaintBlock(false); // Repaint, Markierung je nach Active-Status
2388 :
2389 1084 : if (!bActivate)
2390 542 : HideAllCursors(); // Cursor
2391 542 : else if (!bFirst)
2392 0 : ShowAllCursors();
2393 :
2394 1084 : if (bActivate)
2395 : {
2396 542 : if ( bFirst )
2397 : {
2398 542 : ScSplitPos eWin = aViewData.GetActivePart();
2399 : OSL_ENSURE( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
2400 542 : if ( !pGridWin[eWin] )
2401 : {
2402 0 : eWin = SC_SPLIT_BOTTOMLEFT;
2403 0 : if ( !pGridWin[eWin] )
2404 : {
2405 : short i;
2406 0 : for ( i=0; i<4; i++ )
2407 : {
2408 0 : if ( pGridWin[i] )
2409 : {
2410 0 : eWin = (ScSplitPos) i;
2411 0 : break; // for
2412 : }
2413 : }
2414 : OSL_ENSURE( i<4, "und BUMM" );
2415 : }
2416 0 : aViewData.SetActivePart( eWin );
2417 : }
2418 : }
2419 : // hier nicht mehr selber GrabFocus rufen!
2420 : // Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
2421 : // Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)
2422 :
2423 542 : UpdateInputContext();
2424 : }
2425 : else
2426 542 : pGridWin[aViewData.GetActivePart()]->ClickExtern();
2427 : }
2428 :
2429 32 : void ScTabView::ActivatePart( ScSplitPos eWhich )
2430 : {
2431 32 : ScSplitPos eOld = aViewData.GetActivePart();
2432 32 : if ( eOld != eWhich )
2433 : {
2434 20 : bInActivatePart = true;
2435 :
2436 20 : bool bRefMode = SC_MOD()->IsFormulaMode();
2437 :
2438 : // the HasEditView call during SetCursor would fail otherwise
2439 20 : if ( aViewData.HasEditView(eOld) && !bRefMode )
2440 0 : UpdateInputLine();
2441 :
2442 20 : ScHSplitPos eOldH = WhichH(eOld);
2443 20 : ScVSplitPos eOldV = WhichV(eOld);
2444 20 : ScHSplitPos eNewH = WhichH(eWhich);
2445 20 : ScVSplitPos eNewV = WhichV(eWhich);
2446 20 : bool bTopCap = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
2447 20 : bool bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
2448 :
2449 20 : bool bFocus = pGridWin[eOld]->HasFocus();
2450 20 : bool bCapture = pGridWin[eOld]->IsMouseCaptured();
2451 20 : if (bCapture)
2452 0 : pGridWin[eOld]->ReleaseMouse();
2453 20 : pGridWin[eOld]->ClickExtern();
2454 20 : pGridWin[eOld]->HideCursor();
2455 20 : pGridWin[eWhich]->HideCursor();
2456 20 : aViewData.SetActivePart( eWhich );
2457 :
2458 20 : ScTabViewShell* pShell = aViewData.GetViewShell();
2459 20 : pShell->WindowChanged();
2460 :
2461 20 : pSelEngine->SetWindow(pGridWin[eWhich]);
2462 20 : pSelEngine->SetWhich(eWhich);
2463 20 : pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
2464 :
2465 20 : pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
2466 :
2467 20 : if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
2468 : {
2469 : // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
2470 : // (SelectionEngine ruft CaptureMouse beim SetWindow)
2471 : //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
2472 0 : pGridWin[eWhich]->ReleaseMouse();
2473 0 : pGridWin[eWhich]->StartTracking();
2474 : }
2475 :
2476 20 : if ( bTopCap && pColBar[eNewH] )
2477 : {
2478 0 : pColBar[eOldH]->SetIgnoreMove(true);
2479 0 : pColBar[eNewH]->SetIgnoreMove(false);
2480 0 : pHdrSelEng->SetWindow( pColBar[eNewH] );
2481 0 : long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
2482 0 : pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
2483 0 : pColBar[eNewH]->CaptureMouse();
2484 : }
2485 20 : if ( bLeftCap && pRowBar[eNewV] )
2486 : {
2487 0 : pRowBar[eOldV]->SetIgnoreMove(true);
2488 0 : pRowBar[eNewV]->SetIgnoreMove(false);
2489 0 : pHdrSelEng->SetWindow( pRowBar[eNewV] );
2490 0 : long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
2491 0 : pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
2492 0 : pRowBar[eNewV]->CaptureMouse();
2493 : }
2494 20 : aHdrFunc.SetWhich(eWhich);
2495 :
2496 20 : pGridWin[eOld]->ShowCursor();
2497 20 : pGridWin[eWhich]->ShowCursor();
2498 :
2499 20 : SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
2500 20 : bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
2501 :
2502 : // don't switch ViewShell's active window during RefInput, because the focus
2503 : // might change, and subsequent SetReference calls wouldn't find the right EditView
2504 20 : if ( !bRefMode && !bOleActive )
2505 20 : aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
2506 :
2507 20 : if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
2508 : {
2509 : // GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
2510 : // (z.B. wegen Suchen & Ersetzen)
2511 20 : pGridWin[eWhich]->GrabFocus();
2512 : }
2513 :
2514 20 : bInActivatePart = false;
2515 : }
2516 32 : }
2517 :
2518 3314 : void ScTabView::HideListBox()
2519 : {
2520 16570 : for (sal_uInt16 i=0; i<4; i++)
2521 13256 : if (pGridWin[i])
2522 3560 : pGridWin[i]->ClickExtern();
2523 3314 : }
2524 :
2525 1314 : void ScTabView::UpdateInputContext()
2526 : {
2527 1314 : ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2528 1314 : if (pWin)
2529 1314 : pWin->UpdateInputContext();
2530 :
2531 1314 : if (pTabControl)
2532 1314 : pTabControl->UpdateInputContext();
2533 1314 : }
2534 :
2535 : // GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)
2536 :
2537 86790 : long ScTabView::GetGridWidth( ScHSplitPos eWhich )
2538 : {
2539 86790 : ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2540 86790 : if (pGridWin[eGridWhich])
2541 86790 : return pGridWin[eGridWhich]->GetSizePixel().Width();
2542 : else
2543 0 : return 0;
2544 : }
2545 :
2546 : // GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)
2547 :
2548 103517 : long ScTabView::GetGridHeight( ScVSplitPos eWhich )
2549 : {
2550 103517 : ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2551 103517 : if (pGridWin[eGridWhich])
2552 103517 : return pGridWin[eGridWhich]->GetSizePixel().Height();
2553 : else
2554 0 : return 0;
2555 : }
2556 :
2557 152 : void ScTabView::UpdateInputLine()
2558 : {
2559 152 : SC_MOD()->InputEnterHandler();
2560 152 : }
2561 :
2562 1852 : void ScTabView::ZoomChanged()
2563 : {
2564 1852 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2565 1852 : if (pHdl)
2566 1852 : pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
2567 :
2568 1852 : UpdateFixPos();
2569 :
2570 1852 : UpdateScrollBars();
2571 :
2572 : // VisArea...
2573 : // AW: Discussed with NN if there is a reason that new map mode was only set for one window,
2574 : // but is not. Setting only on one window causes the first repaint to have the old mapMode
2575 : // in three of four views, so the overlay will save the wrong content e.g. when zooming out.
2576 : // Changing to setting map mode at all windows.
2577 : sal_uInt32 a;
2578 :
2579 9260 : for(a = 0L; a < 4L; a++)
2580 : {
2581 7408 : if(pGridWin[a])
2582 : {
2583 1876 : pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
2584 : }
2585 : }
2586 :
2587 1852 : SetNewVisArea();
2588 :
2589 1852 : InterpretVisible(); // have everything calculated before painting
2590 :
2591 1852 : SfxBindings& rBindings = aViewData.GetBindings();
2592 1852 : rBindings.Invalidate( SID_ATTR_ZOOM );
2593 1852 : rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
2594 :
2595 1852 : HideNoteMarker();
2596 :
2597 : // AW: To not change too much, use pWin here
2598 1852 : ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2599 :
2600 1852 : if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
2601 : {
2602 : // flush OverlayManager before changing the MapMode
2603 0 : pWin->flushOverlayManager();
2604 :
2605 : // make sure the EditView's position and size are updated
2606 : // with the right (logic, not drawing) MapMode
2607 0 : pWin->SetMapMode( aViewData.GetLogicMode() );
2608 0 : UpdateEditView();
2609 : }
2610 1852 : }
2611 :
2612 3616 : void ScTabView::CheckNeedsRepaint()
2613 : {
2614 : sal_uInt16 i;
2615 18080 : for (i=0; i<4; i++)
2616 14464 : if ( pGridWin[i] && pGridWin[i]->IsVisible() )
2617 3114 : pGridWin[i]->CheckNeedsRepaint();
2618 3616 : }
2619 :
2620 0 : bool ScTabView::NeedsRepaint()
2621 : {
2622 0 : for (size_t i = 0; i < 4; i++)
2623 0 : if (pGridWin[i] && pGridWin[i]->IsVisible() && pGridWin[i]->NeedsRepaint())
2624 0 : return true;
2625 0 : return false;
2626 228 : }
2627 :
2628 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|