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 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 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 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 165 void ScTabView::FakeButtonUp( ScSplitPos eWhich ) 166 { 167 if (pGridWin[eWhich]) 168 pGridWin[eWhich]->FakeButtonUp(); 169 } 170 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 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 198 void ScTabView::HideCursor() 199 { 200 pGridWin[aViewData.GetActivePart()]->HideCursor(); 201 } 202 203 void ScTabView::ShowCursor() 204 { 205 pGridWin[aViewData.GetActivePart()]->ShowCursor(); 206 207 // #114409# 208 pGridWin[aViewData.GetActivePart()]->CursorChanged(); 209 } 210 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 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 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 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 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 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 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 593 void ScTabView::RemoveHintWindow() 594 { 595 DELETEZ(pInputHintWindow); 596 } 597 598 599 // find window that should not be over the cursor 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1529 void ScTabView::SetMarkData( const ScMarkData& rNew ) 1530 { 1531 DoneBlockMode(); 1532 InitOwnBlockMode(); 1533 aViewData.GetMarkData() = rNew; 1534 1535 MarkDataChanged(); 1536 } 1537 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 2718 void ScTabView::HideListBox() 2719 { 2720 for (sal_uInt16 i=0; i<4; i++) 2721 if (pGridWin[i]) 2722 pGridWin[i]->ClickExtern(); 2723 } 2724 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 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 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 2754 void ScTabView::UpdateInputLine() 2755 { 2756 SC_MOD()->InputEnterHandler(); 2757 } 2758 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 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