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