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