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