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