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 28 //------------------------------------------------------------------ 29 30 #if 0 31 #define _MACRODLG_HXX 32 #define _BIGINT_HXX 33 #define _SVCONTNR_HXX 34 #define BASIC_NODIALOGS 35 #define _SFXMNUITEM_HXX 36 #define _SVDXOUT_HXX 37 #define _SVDATTR_HXX 38 #define _SFXMNUITEM_HXX 39 #define _DLGCFG_HXX 40 #define _SFXMNUMGR_HXX 41 #define _SFXBASIC_HXX 42 #define _MODALDLG_HXX 43 #define _SFX_TEMPLDLG_HXX 44 #define _SFXSTBMGR_HXX 45 #define _SFXTBXMGR_HXX 46 #define _BASE_DLGS_HXX 47 #define _SFXIMGMGR_HXX 48 #define _SFXMNUMGR_HXX 49 #define _SFXSTBITEM_HXX 50 #define _SFXTBXCTRL_HXX 51 #define _PASSWD_HXX 52 //#define _SFXFILEDLG_HXX 53 //#define _SFXREQUEST_HXX 54 #define _SFXOBJFACE_HXX 55 56 #define _SDR_NOTRANSFORM 57 #define _SVDXOUT_HXX 58 #endif 59 #include <vcl/svapp.hxx> 60 61 /////////////////////////////////////////////////////////////////////////// 62 // NODRAW.HXX 63 // Erweiterte Konstanten, um CLOKs mit SVDRAW.HXX zu vermeiden 64 // Die u.a. Aenderungen nehmen vorgeschlagene Konstante vorweg 65 /////////////////////////////////////////////////////////////////////////// 66 67 #if 0 68 #define _SDR_NOTRANSFORM // Transformationen, selten verwendet 69 #define _SDR_NOTOUCH // Hit-Tests, selten verwendet 70 71 #define _SDR_NOUNDO // Undo-Objekte 72 #define _SDR_NOPAGEOBJ // SdrPageObj 73 #define _SDR_NOVIRTOBJ // SdrVirtObj 74 #define _SDR_NOGROUPOBJ // SdrGroupObj 75 #define _SDR_NOTEXTOBJ // SdrTextObj 76 #define _SDR_NOPATHOBJ // SdrPathObj 77 #define _SDR_NOEDGEOBJ // SdrEdgeObj 78 #define _SDR_NORECTOBJ // SdrRectObj 79 #define _SDR_NOCAPTIONOBJ // SdrCaptionObj 80 #define _SDR_NOCIRCLEOBJ // SdrCircleObj 81 #define _SDR_NOGRAFOBJ // SdrGrafObj 82 #define _SDR_NOOLE2OBJ // SdrOle2Obj 83 #endif 84 85 // Dieses define entfernt die VCControls aus SI.HXX 86 87 #define _SI_HXX // VCControls 88 89 ////////////////////// Umsetzen der Standard-Defines ////////////////////// 90 91 //#define _SVDDRAG_HXX // SdrDragStat 92 #define _SVDPAGE_HXX // SdrPage 93 94 #ifdef _SDR_NOSURROGATEOBJ 95 #undef _SDR_NOSURROGATEOBJ 96 #define _SVDSURO_HXX 97 #endif 98 99 #ifdef _SDR_NOPAGEOBJ 100 #undef _SDR_NOPAGEOBJ 101 #define _SVDOPAGE_HXX 102 #endif 103 104 #ifdef _SDR_NOVIRTOBJ 105 #undef _SDR_NOVIRTOBJ 106 #define _SVDOVIRT_HXX 107 #endif 108 109 #ifdef _SDR_NOGROUPOBJ 110 #undef _SDR_NOGROUPOBJ 111 #define _SVDOGRP_HXX 112 #endif 113 114 #ifdef _SDR_NOTEXTOBJ 115 #undef _SDR_NOTEXTOBJ 116 #define _SVDOTEXT_HXX 117 #endif 118 119 #ifdef _SDR_NOPATHOBJ 120 #undef _SDR_NOPATHOBJ 121 #define _SVDOPATH_HXX 122 #endif 123 124 #ifdef _SDR_NOEDGEOBJ 125 #undef _SDR_NOEDGEOBJ 126 #define _SVDOEDGE_HXX 127 #endif 128 129 #ifdef _SDR_NORECTOBJ 130 #undef _SDR_NORECTOBJ 131 #define _SVDORECT_HXX 132 #else 133 #undef _SDVOTEXT_OBJ 134 #endif 135 136 #ifdef _SDR_NOCAPTIONOBJ 137 #undef _SDR_NOCAPTIONOBJ 138 #define _SVDCAPT_HXX 139 #endif 140 141 #ifdef _SDR_NOCIRCLEOBJ 142 #undef _SDR_NOCIRCLEOBJ 143 #define _SVDOCIRC_HXX 144 #endif 145 146 #ifdef _SDR_NOGRAFOBJ 147 #undef _SDR_NOGRAFOBJ 148 #define _SVDOGRAF_HXX 149 #else 150 #undef _SVDOTEXT_HXX 151 #undef _SVDORECT_HXX 152 #endif 153 154 #ifdef _SDR_NOOLE2OBJ 155 #undef _SDR_NOOLE2OBJ 156 #define _SVDOOLE2_HXX 157 #else 158 #undef _SVDOTEXT_HXX 159 #undef _SVDORECT_HXX 160 #endif 161 162 //#ifdef _SDR_NOVIEWS 163 // #define _SVDDRAG_HXX 164 //#endif 165 166 ////////////////////// Ende der SVDRAW-Modifikationen ///////////////////// 167 168 169 // INCLUDE --------------------------------------------------------------- 170 171 #include "scitems.hxx" 172 #include <sfx2/viewfrm.hxx> 173 #include <sfx2/bindings.hxx> 174 #include <vcl/help.hxx> 175 #include <rtl/logfile.hxx> 176 177 #include "tabview.hxx" 178 #include "tabvwsh.hxx" 179 #include "document.hxx" 180 #include "gridwin.hxx" 181 #include "olinewin.hxx" 182 #include "olinetab.hxx" 183 #include "tabsplit.hxx" 184 #include "colrowba.hxx" 185 #include "tabcont.hxx" 186 #include "scmod.hxx" 187 #include "sc.hrc" 188 #include "viewutil.hxx" 189 #include "globstr.hrc" 190 #include "drawview.hxx" 191 #include "docsh.hxx" 192 #include "viewuno.hxx" 193 #include "AccessibilityHints.hxx" 194 #include "appoptio.hxx" 195 196 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> 197 198 #include <string> 199 #include <algorithm> 200 201 #define SPLIT_MARGIN 30 202 #define SC_ICONSIZE 36 203 204 #define SC_SCROLLBAR_MIN 30 205 #define SC_TABBAR_MIN 6 206 207 // fuer Rad-Maus 208 #define SC_DELTA_ZOOM 10 209 210 using namespace ::com::sun::star; 211 212 // STATIC DATA ----------------------------------------------------------- 213 214 215 //================================================================== 216 217 // Corner-Button 218 219 ScCornerButton::ScCornerButton( Window* pParent, ScViewData* pData, sal_Bool bAdditional ) : 220 Window( pParent, WinBits( 0 ) ), 221 pViewData( pData ), 222 bAdd( bAdditional ) 223 { 224 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 225 SetBackground( rStyleSettings.GetFaceColor() ); 226 EnableRTL( sal_False ); 227 } 228 229 __EXPORT ScCornerButton::~ScCornerButton() 230 { 231 } 232 233 void __EXPORT ScCornerButton::Paint( const Rectangle& rRect ) 234 { 235 Size aSize = GetOutputSizePixel(); 236 long nPosX = aSize.Width()-1; 237 long nPosY = aSize.Height()-1; 238 239 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 240 241 Window::Paint(rRect); 242 243 sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() ); 244 long nDarkX = bLayoutRTL ? 0 : nPosX; 245 246 if ( !bAdd && !rStyleSettings.GetHighContrastMode() ) 247 { 248 // match the shaded look of column/row headers 249 250 Color aFace( rStyleSettings.GetFaceColor() ); 251 Color aWhite( COL_WHITE ); 252 Color aCenter( aFace ); 253 aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit 254 Color aOuter( aFace ); 255 aOuter.Merge( aWhite, 0xa0 ); // lighten up more 256 257 long nCenterX = (aSize.Width() / 2) - 1; 258 long nCenterY = (aSize.Height() / 2) - 1; 259 260 SetLineColor(); 261 SetFillColor(aCenter); 262 DrawRect( Rectangle( nCenterX, nCenterY, nCenterX, nPosY ) ); 263 DrawRect( Rectangle( nCenterX, nCenterY, nDarkX, nCenterY ) ); 264 SetFillColor(aOuter); 265 DrawRect( Rectangle( 0, 0, nPosX, nCenterY-1 ) ); 266 if ( bLayoutRTL ) 267 DrawRect( Rectangle( nCenterX+1, nCenterY, nPosX, nPosY ) ); 268 else 269 DrawRect( Rectangle( 0, nCenterY, nCenterX-1, nPosY ) ); 270 } 271 272 // both buttons have the same look now - only dark right/bottom lines 273 SetLineColor( rStyleSettings.GetDarkShadowColor() ); 274 DrawLine( Point(0,nPosY), Point(nPosX,nPosY) ); 275 DrawLine( Point(nDarkX,0), Point(nDarkX,nPosY) ); 276 } 277 278 void ScCornerButton::StateChanged( StateChangedType nType ) 279 { 280 Window::StateChanged( nType ); 281 282 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 283 SetBackground( rStyleSettings.GetFaceColor() ); 284 Invalidate(); 285 } 286 287 // ----------------------------------------------------------------------- 288 289 void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt ) 290 { 291 Window::DataChanged( rDCEvt ); 292 293 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 294 SetBackground( rStyleSettings.GetFaceColor() ); 295 Invalidate(); 296 } 297 298 299 void __EXPORT ScCornerButton::Resize() 300 { 301 Invalidate(); 302 } 303 304 void __EXPORT ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt ) 305 { 306 ScModule* pScMod = SC_MOD(); 307 sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode(); 308 if (!bDisable) 309 { 310 ScTabViewShell* pViewSh = pViewData->GetViewShell(); 311 pViewSh->SetActive(); // Appear und SetViewFrame 312 pViewSh->ActiveGrabFocus(); 313 314 sal_Bool bControl = rMEvt.IsMod1(); 315 pViewSh->SelectAll( bControl ); 316 } 317 } 318 319 //================================================================== 320 321 sal_Bool lcl_HasColOutline( const ScViewData& rViewData ) 322 { 323 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo()); 324 if (pTable) 325 { 326 const ScOutlineArray* pArray = pTable->GetColArray(); 327 if ( pArray->GetDepth() > 0 ) 328 return sal_True; 329 } 330 return sal_False; 331 } 332 333 sal_Bool lcl_HasRowOutline( const ScViewData& rViewData ) 334 { 335 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo()); 336 if (pTable) 337 { 338 const ScOutlineArray* pArray = pTable->GetRowArray(); 339 if ( pArray->GetDepth() > 0 ) 340 return sal_True; 341 } 342 return sal_False; 343 } 344 345 //================================================================== 346 347 // Init und Konstruktoren 348 // ScTabView::Init() in tabview5.cxx wegen out of keys 349 350 351 #define TABVIEW_INIT \ 352 pSelEngine( NULL ), \ 353 aFunctionSet( &aViewData ), \ 354 pHdrSelEng( NULL ), \ 355 aHdrFunc( &aViewData ), \ 356 pDrawView( NULL ), \ 357 bDrawSelMode( sal_False ), \ 358 aVScrollTop( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \ 359 aVScrollBottom( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \ 360 aHScrollLeft( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \ 361 aHScrollRight( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \ 362 aCornerButton( pFrameWin, &aViewData, sal_False ), \ 363 aTopButton( pFrameWin, &aViewData, sal_True ), \ 364 aScrollBarBox( pFrameWin, WB_SIZEABLE ), \ 365 pInputHintWindow( NULL ), \ 366 pPageBreakData( NULL ), \ 367 pHighlightRanges( NULL ), \ 368 pBrushDocument( NULL ), \ 369 pDrawBrushSet( NULL ), \ 370 bLockPaintBrush( sal_False ), \ 371 pTimerWindow( NULL ), \ 372 nTipVisible( 0 ), \ 373 bDragging( sal_False ), \ 374 bIsBlockMode( sal_False ), \ 375 bBlockNeg( sal_False ), \ 376 bBlockCols( sal_False ), \ 377 bBlockRows( sal_False ), \ 378 mfPendingTabBarWidth( -1.0 ), \ 379 bMinimized( sal_False ), \ 380 bInUpdateHeader( sal_False ), \ 381 bInActivatePart( sal_False ), \ 382 bInZoomUpdate( sal_False ), \ 383 bMoveIsShift( sal_False ), \ 384 bNewStartIfMarking( sal_False ) 385 386 387 ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) : 388 pFrameWin( pParent ), 389 aViewData( &rDocSh, pViewShell ), 390 TABVIEW_INIT 391 { 392 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" ); 393 394 Init(); 395 } 396 397 //UNUSED2009-05 ScTabView::ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell ) : 398 //UNUSED2009-05 pFrameWin( pParent ), 399 //UNUSED2009-05 aViewData( rScTabView.aViewData ), 400 //UNUSED2009-05 TABVIEW_INIT 401 //UNUSED2009-05 { 402 //UNUSED2009-05 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" ); 403 //UNUSED2009-05 404 //UNUSED2009-05 aViewData.SetViewShell( pViewShell ); 405 //UNUSED2009-05 Init(); 406 //UNUSED2009-05 407 //UNUSED2009-05 UpdateShow(); 408 //UNUSED2009-05 if ( aViewData.GetActivePart() != SC_SPLIT_BOTTOMLEFT ) 409 //UNUSED2009-05 pGridWin[SC_SPLIT_BOTTOMLEFT]->Show(); 410 //UNUSED2009-05 411 //UNUSED2009-05 InvalidateSplit(); 412 //UNUSED2009-05 } 413 414 void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal ) 415 { 416 rScrollBar.SetRange( Range( 0, nMaxVal ) ); 417 rScrollBar.SetLineSize( 1 ); 418 rScrollBar.SetPageSize( 1 ); // wird getrennt abgefragt 419 rScrollBar.SetVisibleSize( 10 ); // wird bei Resize neu gesetzt 420 421 rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) ); 422 rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) ); 423 } 424 425 // Scroll-Timer 426 427 void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt ) 428 { 429 pTimerWindow = pWin; 430 aTimerMEvt = rMEvt; 431 aScrollTimer.Start(); 432 } 433 434 void ScTabView::ResetTimer() 435 { 436 aScrollTimer.Stop(); 437 pTimerWindow = NULL; 438 } 439 440 IMPL_LINK( ScTabView, TimerHdl, Timer*, EMPTYARG ) 441 { 442 // aScrollTimer.Stop(); 443 if (pTimerWindow) 444 pTimerWindow->MouseMove( aTimerMEvt ); 445 446 return 0; 447 } 448 449 // --- Resize --------------------------------------------------------------------- 450 451 void lcl_SetPosSize( Window& rWindow, const Point& rPos, const Size& rSize, 452 long nTotalWidth, sal_Bool bLayoutRTL ) 453 { 454 Point aNewPos = rPos; 455 if ( bLayoutRTL ) 456 { 457 aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width(); 458 if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() ) 459 { 460 // Document windows are manually painted right-to-left, so they need to 461 // be repainted if the size changes. 462 rWindow.Invalidate(); 463 } 464 } 465 rWindow.SetPosSizePixel( aNewPos, rSize ); 466 } 467 468 void ScTabView::DoResize( const Point& rOffset, const Size& rSize, sal_Bool bInner ) 469 { 470 HideListBox(); 471 472 sal_Bool bHasHint = ( pInputHintWindow != NULL ); 473 if (bHasHint) 474 RemoveHintWindow(); 475 476 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); 477 long nTotalWidth = rSize.Width(); 478 if ( bLayoutRTL ) 479 nTotalWidth += 2*rOffset.X(); 480 481 sal_Bool bVScroll = aViewData.IsVScrollMode(); 482 sal_Bool bHScroll = aViewData.IsHScrollMode(); 483 sal_Bool bTabControl = aViewData.IsTabMode(); 484 sal_Bool bHeaders = aViewData.IsHeaderMode(); 485 sal_Bool bOutlMode = aViewData.IsOutlineMode(); 486 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData); 487 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); 488 489 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden: 490 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode(); 491 if ( eMode == SCROLLING_NO ) 492 bHScroll = bVScroll = sal_False; 493 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ??? 494 bHScroll = bVScroll = sal_True; 495 496 if ( aViewData.GetDocShell()->IsPreview() ) 497 bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = sal_False; 498 499 long nBarX = 0; 500 long nBarY = 0; 501 long nOutlineX = 0; 502 long nOutlineY = 0; 503 long nOutPosX; 504 long nOutPosY; 505 506 long nPosX = rOffset.X(); 507 long nPosY = rOffset.Y(); 508 long nSizeX = rSize.Width(); 509 long nSizeY = rSize.Height(); 510 long nSize1; 511 512 bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE ); 513 if ( bMinimized ) 514 return; 515 516 long nSplitSizeX = SPLIT_HANDLE_SIZE; 517 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) 518 nSplitSizeX = 1; 519 long nSplitSizeY = SPLIT_HANDLE_SIZE; 520 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) 521 nSplitSizeY = 1; 522 523 const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel(); 524 525 aBorderPos = rOffset; 526 aFrameSize = rSize; 527 528 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) 529 if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN ) 530 { 531 aViewData.SetHSplitMode( SC_SPLIT_NONE ); 532 if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT ) 533 ActivatePart( SC_SPLIT_BOTTOMLEFT ); 534 InvalidateSplit(); 535 // UpdateShow(); 536 } 537 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 538 if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN ) 539 { 540 aViewData.SetVSplitMode( SC_SPLIT_NONE ); 541 if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP ) 542 ActivatePart( SC_SPLIT_BOTTOMLEFT ); 543 InvalidateSplit(); 544 // UpdateShow(); 545 } 546 547 UpdateShow(); 548 549 if (bHScroll || bVScroll) // Scrollbars horizontal oder vertikal 550 { 551 long nScrollBarSize = pFrameWin->GetSettings().GetStyleSettings().GetScrollBarSize(); 552 if (bVScroll) 553 { 554 // nBarX = aVScrollBottom.GetSizePixel().Width(); 555 nBarX = nScrollBarSize; 556 nSizeX -= nBarX - nOverlap; 557 } 558 if (bHScroll) 559 { 560 // nBarY = aHScrollLeft.GetSizePixel().Height(); 561 nBarY = nScrollBarSize; 562 nSizeY -= nBarY - nOverlap; 563 } 564 565 // window at the bottom right 566 lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ), 567 nTotalWidth, bLayoutRTL ); 568 569 if (bHScroll) // Scrollbars horizontal 570 { 571 long nSizeLt = 0; // left scroll bar 572 long nSizeRt = 0; // right scroll bar 573 long nSizeSp = 0; // splitter 574 575 switch (aViewData.GetHSplitMode()) 576 { 577 case SC_SPLIT_NONE: 578 nSizeSp = nSplitSizeX; 579 nSizeLt = nSizeX - nSizeSp + nOverlap; // Ecke ueberdecken 580 break; 581 case SC_SPLIT_NORMAL: 582 nSizeSp = nSplitSizeX; 583 nSizeLt = aViewData.GetHSplitPos(); 584 break; 585 case SC_SPLIT_FIX: 586 nSizeSp = 0; 587 nSizeLt = 0; 588 break; 589 } 590 nSizeRt = nSizeX - nSizeLt - nSizeSp; 591 592 long nTabSize = 0; 593 if (bTabControl) 594 { 595 // pending relative tab bar width from extended document options 596 if( mfPendingTabBarWidth >= 0.0 ) 597 { 598 SetRelTabBarWidth( mfPendingTabBarWidth ); 599 mfPendingTabBarWidth = -1.0; 600 } 601 602 nTabSize = pTabControl->GetSizePixel().Width()-nOverlap; 603 604 if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // bei linkem Scrollbar 605 { 606 if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN) nTabSize = nSizeLt-SC_SCROLLBAR_MIN; 607 if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN; 608 nSizeLt -= nTabSize; 609 } 610 else // bei rechtem Scrollbar 611 { 612 if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN) nTabSize = nSizeRt-SC_SCROLLBAR_MIN; 613 if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN; 614 nSizeRt -= nTabSize; 615 } 616 } 617 618 lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY), 619 Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL ); 620 pTabControl->SetSheetLayoutRTL( bLayoutRTL ); 621 622 lcl_SetPosSize( aHScrollLeft, Point(nPosX+nTabSize-nOverlap, nPosY+nSizeY), 623 Size(nSizeLt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL ); 624 lcl_SetPosSize( *pHSplitter, Point( nPosX+nTabSize+nSizeLt, nPosY+nSizeY ), 625 Size( nSizeSp, nBarY ), nTotalWidth, bLayoutRTL ); 626 lcl_SetPosSize( aHScrollRight, Point(nPosX+nTabSize+nSizeLt+nSizeSp-nOverlap, 627 nPosY+nSizeY), 628 Size(nSizeRt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL ); 629 630 // SetDragRectPixel is done below 631 } 632 633 if (bVScroll) // Scrollbars vertikal 634 { 635 long nSizeUp = 0; // upper scroll bar 636 long nSizeSp = 0; // splitter 637 long nSizeDn; // unterer Scrollbar 638 639 switch (aViewData.GetVSplitMode()) 640 { 641 case SC_SPLIT_NONE: 642 nSizeUp = 0; 643 nSizeSp = nSplitSizeY; 644 break; 645 case SC_SPLIT_NORMAL: 646 nSizeUp = aViewData.GetVSplitPos(); 647 nSizeSp = nSplitSizeY; 648 break; 649 case SC_SPLIT_FIX: 650 nSizeUp = 0; 651 nSizeSp = 0; 652 break; 653 } 654 nSizeDn = nSizeY - nSizeUp - nSizeSp; 655 656 lcl_SetPosSize( aVScrollTop, Point(nPosX+nSizeX, nPosY-nOverlap), 657 Size(nBarX,nSizeUp+2*nOverlap), nTotalWidth, bLayoutRTL ); 658 lcl_SetPosSize( *pVSplitter, Point( nPosX+nSizeX, nPosY+nSizeUp ), 659 Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL ); 660 lcl_SetPosSize( aVScrollBottom, Point(nPosX+nSizeX, 661 nPosY+nSizeUp+nSizeSp-nOverlap), 662 Size(nBarX, nSizeDn+2*nOverlap), nTotalWidth, bLayoutRTL ); 663 664 // SetDragRectPixel is done below 665 } 666 } 667 668 // SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist 669 if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE ) 670 pHSplitter->SetDragRectPixel( 671 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin ); 672 if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 673 pVSplitter->SetDragRectPixel( 674 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin ); 675 676 if (bTabControl && ! bHScroll ) 677 { 678 nBarY = aHScrollLeft.GetSizePixel().Height(); 679 nBarX = aVScrollBottom.GetSizePixel().Width(); 680 681 nSize1 = nSizeX + nOverlap; 682 683 long nTabSize = nSize1; 684 if (nTabSize < 0) nTabSize = 0; 685 686 lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY-nBarY), 687 Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL ); 688 nSizeY -= nBarY - nOverlap; 689 lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ), 690 nTotalWidth, bLayoutRTL ); 691 692 if( bVScroll ) 693 { 694 Size aVScrSize = aVScrollBottom.GetSizePixel(); 695 aVScrSize.Height() -= nBarY; 696 aVScrollBottom.SetSizePixel( aVScrSize ); 697 } 698 } 699 700 nOutPosX = nPosX; 701 nOutPosY = nPosY; 702 703 // Outline-Controls 704 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM]) 705 { 706 nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize(); 707 nSizeX -= nOutlineX; 708 nPosX += nOutlineX; 709 } 710 if (bHOutline && pColOutline[SC_SPLIT_LEFT]) 711 { 712 nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize(); 713 nSizeY -= nOutlineY; 714 nPosY += nOutlineY; 715 } 716 717 if (bHeaders) // Spalten/Zeilen-Header 718 { 719 nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); 720 nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); 721 nSizeX -= nBarX; 722 nSizeY -= nBarY; 723 nPosX += nBarX; 724 nPosY += nBarY; 725 } 726 else 727 nBarX = nBarY = 0; 728 729 // 730 // Splitter auswerten 731 // 732 733 long nLeftSize = nSizeX; 734 long nRightSize = 0; 735 long nTopSize = 0; 736 long nBottomSize = nSizeY; 737 long nSplitPosX = nPosX; 738 long nSplitPosY = nPosY; 739 740 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) 741 { 742 long nSplitHeight = rSize.Height(); 743 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) 744 { 745 // Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen 746 if ( bHScroll ) 747 nSplitHeight -= aHScrollLeft.GetSizePixel().Height(); 748 else if ( bTabControl && pTabControl ) 749 nSplitHeight -= pTabControl->GetSizePixel().Height(); 750 } 751 nSplitPosX = aViewData.GetHSplitPos(); 752 lcl_SetPosSize( *pHSplitter, 753 Point( nSplitPosX, nOutPosY ), Size( nSplitSizeX, nSplitHeight ), nTotalWidth, bLayoutRTL ); 754 nLeftSize = nSplitPosX - nPosX; 755 nSplitPosX += nSplitSizeX; 756 nRightSize = nSizeX - nLeftSize - nSplitSizeX; 757 } 758 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 759 { 760 long nSplitWidth = rSize.Width(); 761 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll ) 762 nSplitWidth -= aVScrollBottom.GetSizePixel().Width(); 763 nSplitPosY = aViewData.GetVSplitPos(); 764 lcl_SetPosSize( *pVSplitter, 765 Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL ); 766 nTopSize = nSplitPosY - nPosY; 767 nSplitPosY += nSplitSizeY; 768 nBottomSize = nSizeY - nTopSize - nSplitSizeY; 769 } 770 771 // ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow 772 773 if (bHOutline) // Outline-Controls 774 { 775 if (pColOutline[SC_SPLIT_LEFT]) 776 { 777 pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX ); 778 lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT], 779 Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL ); 780 } 781 if (pColOutline[SC_SPLIT_RIGHT]) 782 { 783 pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag 784 lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT], 785 Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL ); 786 } 787 } 788 if (bVOutline) 789 { 790 if (nTopSize) 791 { 792 if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM]) 793 { 794 pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY ); 795 lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP], 796 Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL ); 797 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 ); 798 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM], 799 Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL ); 800 } 801 } 802 else if (pRowOutline[SC_SPLIT_BOTTOM]) 803 { 804 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY ); 805 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM], 806 Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL ); 807 } 808 } 809 if (bHOutline && bVOutline) 810 { 811 lcl_SetPosSize( aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL ); 812 aTopButton.Show(); 813 } 814 else 815 aTopButton.Hide(); 816 817 if (bHeaders) // Spalten/Zeilen-Header 818 { 819 lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT], 820 Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL ); 821 if (pColBar[SC_SPLIT_RIGHT]) 822 lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT], 823 Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL ); 824 825 if (pRowBar[SC_SPLIT_TOP]) 826 lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP], 827 Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL ); 828 lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM], 829 Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL ); 830 831 lcl_SetPosSize( aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL ); 832 aCornerButton.Show(); 833 pColBar[SC_SPLIT_LEFT]->Show(); 834 pRowBar[SC_SPLIT_BOTTOM]->Show(); 835 } 836 else 837 { 838 aCornerButton.Hide(); 839 pColBar[SC_SPLIT_LEFT]->Hide(); // immer da 840 pRowBar[SC_SPLIT_BOTTOM]->Hide(); 841 } 842 843 844 // Grid-Windows 845 846 if (bInner) 847 { 848 long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX; 849 pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) ); 850 } 851 else 852 { 853 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT], 854 Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL ); 855 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) 856 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT], 857 Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL ); 858 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 859 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT], 860 Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL ); 861 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 862 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT], 863 Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL ); 864 } 865 866 // 867 // Scrollbars updaten 868 // 869 870 if (!bInUpdateHeader) 871 { 872 UpdateScrollBars(); // Scrollbars nicht beim Scrollen neu setzen 873 UpdateHeaderWidth(); 874 875 InterpretVisible(); // #69343# have everything calculated before painting 876 } 877 878 if (bHasHint) 879 TestHintWindow(); // neu positionieren 880 881 UpdateVarZoom(); // update variable zoom types (after resizing GridWindows) 882 883 if (aViewData.GetViewShell()->HasAccessibilityObjects()) 884 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED)); 885 } 886 887 void ScTabView::UpdateVarZoom() 888 { 889 // update variable zoom types 890 891 SvxZoomType eZoomType = GetZoomType(); 892 if ( eZoomType != SVX_ZOOM_PERCENT && !bInZoomUpdate ) 893 { 894 bInZoomUpdate = sal_True; 895 const Fraction& rOldX = GetViewData()->GetZoomX(); 896 const Fraction& rOldY = GetViewData()->GetZoomY(); 897 long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator(); 898 sal_uInt16 nNewZoom = CalcZoom( eZoomType, (sal_uInt16)nOldPercent ); 899 Fraction aNew( nNewZoom, 100 ); 900 901 if ( aNew != rOldX || aNew != rOldY ) 902 { 903 SetZoom( aNew, aNew, sal_False ); // always separately per sheet 904 PaintGrid(); 905 PaintTop(); 906 PaintLeft(); 907 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM ); 908 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER ); 909 } 910 bInZoomUpdate = sal_False; 911 } 912 } 913 914 void ScTabView::UpdateFixPos() 915 { 916 sal_Bool bResize = sal_False; 917 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) 918 if (aViewData.UpdateFixX()) 919 bResize = sal_True; 920 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) 921 if (aViewData.UpdateFixY()) 922 bResize = sal_True; 923 if (bResize) 924 RepeatResize(sal_False); 925 } 926 927 void ScTabView::RepeatResize( sal_Bool bUpdateFix ) 928 { 929 if ( bUpdateFix ) 930 { 931 ScSplitMode eHSplit = aViewData.GetHSplitMode(); 932 ScSplitMode eVSplit = aViewData.GetVSplitMode(); 933 934 // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the 935 // outline windows to be available. So UpdateShow has to be called before 936 // (also called from DoResize). 937 if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX ) 938 UpdateShow(); 939 940 if ( eHSplit == SC_SPLIT_FIX ) 941 aViewData.UpdateFixX(); 942 if ( eVSplit == SC_SPLIT_FIX ) 943 aViewData.UpdateFixY(); 944 } 945 946 DoResize( aBorderPos, aFrameSize ); 947 948 //! Border muss neu gesetzt werden ??? 949 } 950 951 void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ ) 952 { 953 sal_Bool bScrollBars = aViewData.IsVScrollMode(); 954 sal_Bool bHeaders = aViewData.IsHeaderMode(); 955 sal_Bool bOutlMode = aViewData.IsOutlineMode(); 956 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData); 957 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); 958 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); 959 960 rBorder = SvBorder(); 961 962 if (bScrollBars) // Scrollbars horizontal oder vertikal 963 { 964 rBorder.Right() += aVScrollBottom.GetSizePixel().Width(); 965 rBorder.Bottom() += aHScrollLeft.GetSizePixel().Height(); 966 } 967 968 // Outline-Controls 969 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM]) 970 rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize(); 971 if (bHOutline && pColOutline[SC_SPLIT_LEFT]) 972 rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize(); 973 974 if (bHeaders) // Spalten/Zeilen-Header 975 { 976 rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); 977 rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); 978 } 979 980 if ( bLayoutRTL ) 981 ::std::swap( rBorder.Left(), rBorder.Right() ); 982 } 983 984 IMPL_LINK( ScTabView, TabBarResize, void*, EMPTYARG ) 985 { 986 sal_Bool bHScrollMode = aViewData.IsHScrollMode(); 987 988 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden: 989 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode(); 990 if ( eMode == SCROLLING_NO ) 991 bHScrollMode = sal_False; 992 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ??? 993 bHScrollMode = sal_True; 994 995 if( bHScrollMode ) 996 { 997 const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel(); 998 long nSize = pTabControl->GetSplitSize(); 999 1000 if (aViewData.GetHSplitMode() != SC_SPLIT_FIX) 1001 { 1002 long nMax = pHSplitter->GetPosPixel().X(); 1003 if( pTabControl->IsEffectiveRTL() ) 1004 nMax = pFrameWin->GetSizePixel().Width() - nMax; 1005 --nMax; 1006 if (nSize>nMax) nSize = nMax; 1007 } 1008 1009 if ( nSize != pTabControl->GetSizePixel().Width() ) 1010 { 1011 pTabControl->SetSizePixel( Size( nSize+nOverlap, 1012 pTabControl->GetSizePixel().Height() ) ); 1013 RepeatResize(); 1014 } 1015 } 1016 1017 return 0; 1018 } 1019 1020 void ScTabView::SetTabBarWidth( long nNewWidth ) 1021 { 1022 Size aSize = pTabControl->GetSizePixel(); 1023 1024 if ( aSize.Width() != nNewWidth ) 1025 { 1026 aSize.Width() = nNewWidth; 1027 pTabControl->SetSizePixel( aSize ); 1028 } 1029 } 1030 1031 void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth ) 1032 { 1033 if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) ) 1034 if( long nFrameWidth = pFrameWin->GetSizePixel().Width() ) 1035 SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) ); 1036 } 1037 1038 void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth ) 1039 { 1040 mfPendingTabBarWidth = fRelTabBarWidth; 1041 SetRelTabBarWidth( fRelTabBarWidth ); 1042 } 1043 1044 long ScTabView::GetTabBarWidth() const 1045 { 1046 return pTabControl->GetSizePixel().Width(); 1047 } 1048 1049 double ScTabView::GetRelTabBarWidth() const 1050 { 1051 if( long nFrameWidth = pFrameWin->GetSizePixel().Width() ) 1052 return static_cast< double >( GetTabBarWidth() ) / nFrameWidth; 1053 return 0.0; 1054 } 1055 1056 double ScTabView::GetPendingRelTabBarWidth() const 1057 { 1058 return mfPendingTabBarWidth; 1059 } 1060 1061 Window* ScTabView::GetActiveWin() 1062 { 1063 ScSplitPos ePos = aViewData.GetActivePart(); 1064 DBG_ASSERT(pGridWin[ePos],"kein aktives Fenster"); 1065 return pGridWin[ePos]; 1066 } 1067 1068 Window* ScTabView::GetWindowByPos( ScSplitPos ePos ) 1069 { 1070 return pGridWin[ePos]; 1071 } 1072 1073 void ScTabView::SetActivePointer( const Pointer& rPointer ) 1074 { 1075 for (sal_uInt16 i=0; i<4; i++) 1076 if (pGridWin[i]) 1077 pGridWin[i]->SetPointer( rPointer ); 1078 1079 /* ScSplitPos ePos = aViewData.GetActivePart(); 1080 if (pGridWin[ePos]) 1081 pGridWin[ePos]->SetPointer( rPointer ); 1082 */ 1083 } 1084 1085 //UNUSED2008-05 void ScTabView::SetActivePointer( const ResId& ) 1086 //UNUSED2008-05 { 1087 //UNUSED2008-05 DBG_ERRORFILE( "keine Pointer mit ResId!" ); 1088 //UNUSED2008-05 } 1089 1090 void ScTabView::ActiveGrabFocus() 1091 { 1092 ScSplitPos ePos = aViewData.GetActivePart(); 1093 if (pGridWin[ePos]) 1094 pGridWin[ePos]->GrabFocus(); 1095 } 1096 1097 //UNUSED2008-05 void ScTabView::ActiveCaptureMouse() 1098 //UNUSED2008-05 { 1099 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart(); 1100 //UNUSED2008-05 if (pGridWin[ePos]) 1101 //UNUSED2008-05 pGridWin[ePos]->CaptureMouse(); 1102 //UNUSED2008-05 } 1103 //UNUSED2008-05 1104 //UNUSED2008-05 void ScTabView::ActiveReleaseMouse() 1105 //UNUSED2008-05 { 1106 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart(); 1107 //UNUSED2008-05 if (pGridWin[ePos]) 1108 //UNUSED2008-05 pGridWin[ePos]->ReleaseMouse(); 1109 //UNUSED2008-05 } 1110 //UNUSED2008-05 1111 //UNUSED2008-05 Point ScTabView::ActivePixelToLogic( const Point& rDevicePoint ) 1112 //UNUSED2008-05 { 1113 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart(); 1114 //UNUSED2008-05 if (pGridWin[ePos]) 1115 //UNUSED2008-05 return pGridWin[ePos]->PixelToLogic(rDevicePoint); 1116 //UNUSED2008-05 else 1117 //UNUSED2008-05 return Point(); 1118 //UNUSED2008-05 } 1119 1120 ScSplitPos ScTabView::FindWindow( Window* pWindow ) const 1121 { 1122 ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default 1123 for (sal_uInt16 i=0; i<4; i++) 1124 if ( pGridWin[i] == pWindow ) 1125 eVal = (ScSplitPos) i; 1126 1127 return eVal; 1128 } 1129 1130 Point ScTabView::GetGridOffset() const 1131 { 1132 Point aPos; 1133 1134 // Groessen hier wie in DoResize 1135 1136 sal_Bool bHeaders = aViewData.IsHeaderMode(); 1137 sal_Bool bOutlMode = aViewData.IsOutlineMode(); 1138 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData); 1139 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); 1140 1141 // Outline-Controls 1142 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM]) 1143 aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize(); 1144 if (bHOutline && pColOutline[SC_SPLIT_LEFT]) 1145 aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize(); 1146 1147 if (bHeaders) // Spalten/Zeilen-Header 1148 { 1149 if (pRowBar[SC_SPLIT_BOTTOM]) 1150 aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); 1151 if (pColBar[SC_SPLIT_LEFT]) 1152 aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); 1153 } 1154 1155 return aPos; 1156 } 1157 1158 // --- Scroll-Bars -------------------------------------------------------- 1159 1160 sal_Bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos ) 1161 { 1162 HideNoteMarker(); 1163 1164 sal_Bool bDone = sal_False; 1165 const CommandWheelData* pData = rCEvt.GetWheelData(); 1166 if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM ) 1167 { 1168 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) 1169 { 1170 // for ole inplace editing, the scale is defined by the visarea and client size 1171 // and can't be changed directly 1172 1173 const Fraction& rOldY = aViewData.GetZoomY(); 1174 long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator()); 1175 long nNew = nOld; 1176 if ( pData->GetDelta() < 0 ) 1177 nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) ); 1178 else 1179 nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) ); 1180 1181 if ( nNew != nOld ) 1182 { 1183 // scroll wheel doesn't set the AppOptions default 1184 1185 sal_Bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom(); 1186 SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom ); 1187 Fraction aFract( nNew, 100 ); 1188 SetZoom( aFract, aFract, bSyncZoom ); 1189 PaintGrid(); 1190 PaintTop(); 1191 PaintLeft(); 1192 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM ); 1193 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER ); 1194 } 1195 1196 bDone = sal_True; 1197 } 1198 } 1199 else 1200 { 1201 ScHSplitPos eHPos = WhichH(ePos); 1202 ScVSplitPos eVPos = WhichV(ePos); 1203 ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? &aHScrollLeft : &aHScrollRight; 1204 ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? &aVScrollTop : &aVScrollBottom; 1205 if ( pGridWin[ePos] ) 1206 bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll ); 1207 } 1208 return bDone; 1209 } 1210 1211 IMPL_LINK( ScTabView, EndScrollHdl, ScrollBar*, pScroll ) 1212 { 1213 sal_Bool bOnlineScroll = sal_True; //! Optionen 1214 1215 if ( bDragging ) 1216 { 1217 if ( bOnlineScroll ) // nur Ranges aktualisieren 1218 UpdateScrollBars(); 1219 else 1220 { 1221 long nScrollMin = 0; // RangeMin simulieren 1222 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight ) 1223 nScrollMin = aViewData.GetFixPosX(); 1224 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom ) 1225 nScrollMin = aViewData.GetFixPosY(); 1226 1227 if ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight ) 1228 { 1229 sal_Bool bMirror = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) != Application::GetSettings().GetLayoutRTL(); 1230 ScHSplitPos eWhich = (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT; 1231 long nDelta = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin - aViewData.GetPosX(eWhich); 1232 if (nDelta) ScrollX( nDelta, eWhich ); 1233 } 1234 else // VScroll... 1235 { 1236 ScVSplitPos eWhich = (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM; 1237 long nDelta = GetScrollBarPos( *pScroll, sal_False ) + nScrollMin - aViewData.GetPosY(eWhich); 1238 if (nDelta) ScrollY( nDelta, eWhich ); 1239 } 1240 } 1241 bDragging = sal_False; 1242 } 1243 return 0; 1244 } 1245 1246 IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll ) 1247 { 1248 sal_Bool bOnlineScroll = sal_True; //! Optionen 1249 1250 sal_Bool bHoriz = ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight ); 1251 long nViewPos; 1252 if ( bHoriz ) 1253 nViewPos = aViewData.GetPosX( (pScroll == &aHScrollLeft) ? 1254 SC_SPLIT_LEFT : SC_SPLIT_RIGHT ); 1255 else 1256 nViewPos = aViewData.GetPosY( (pScroll == &aVScrollTop) ? 1257 SC_SPLIT_TOP : SC_SPLIT_BOTTOM ); 1258 1259 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); 1260 sal_Bool bMirror = bHoriz && (bLayoutRTL != Application::GetSettings().GetLayoutRTL()); 1261 1262 ScrollType eType = pScroll->GetType(); 1263 if ( eType == SCROLL_DRAG ) 1264 { 1265 if (!bDragging) 1266 { 1267 bDragging = sal_True; 1268 nPrevDragPos = nViewPos; 1269 } 1270 1271 // Scroll-Position anzeigen 1272 // (nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer) 1273 1274 if (Help::IsQuickHelpEnabled()) 1275 { 1276 Size aSize = pScroll->GetSizePixel(); 1277 1278 /* Convert scrollbar mouse position to screen position. If RTL 1279 mode of scrollbar differs from RTL mode of its parent, then the 1280 direct call to Window::OutputToNormalizedScreenPixel() will 1281 give unusable results, because calcualtion of screen position 1282 is based on parent orientation and expects equal orientation of 1283 the child position. Need to mirror mouse position before. */ 1284 Point aMousePos = pScroll->GetPointerPosPixel(); 1285 if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() ) 1286 aMousePos.X() = aSize.Width() - aMousePos.X() - 1; 1287 aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos ); 1288 1289 // convert top-left position of scrollbar to screen position 1290 Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() ); 1291 1292 // get scrollbar scroll position for help text (row number/column name) 1293 long nScrollMin = 0; // RangeMin simulieren 1294 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight ) 1295 nScrollMin = aViewData.GetFixPosX(); 1296 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom ) 1297 nScrollMin = aViewData.GetFixPosY(); 1298 long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin; 1299 1300 String aHelpStr; 1301 Rectangle aRect; 1302 sal_uInt16 nAlign; 1303 if (bHoriz) 1304 { 1305 aHelpStr = ScGlobal::GetRscString(STR_COLUMN); 1306 aHelpStr += ' '; 1307 aHelpStr += ScColToAlpha((SCCOL) nScrollPos); 1308 1309 aRect.Left() = aMousePos.X(); 1310 aRect.Top() = aPos.Y() - 4; 1311 nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER; 1312 } 1313 else 1314 { 1315 aHelpStr = ScGlobal::GetRscString(STR_ROW); 1316 aHelpStr += ' '; 1317 aHelpStr += String::CreateFromInt32(nScrollPos + 1); 1318 1319 // show quicktext always inside sheet area 1320 aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8); 1321 aRect.Top() = aMousePos.Y(); 1322 nAlign = (bLayoutRTL ? QUICKHELP_LEFT : QUICKHELP_RIGHT) | QUICKHELP_VCENTER; 1323 } 1324 aRect.Right() = aRect.Left(); 1325 aRect.Bottom() = aRect.Top(); 1326 1327 Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign); 1328 } 1329 } 1330 1331 if ( bOnlineScroll || eType != SCROLL_DRAG ) 1332 { 1333 if ( bMirror ) 1334 { 1335 // change scroll type so visible/previous cells calculation below remains the same 1336 switch ( eType ) 1337 { 1338 case SCROLL_LINEUP: eType = SCROLL_LINEDOWN; break; 1339 case SCROLL_LINEDOWN: eType = SCROLL_LINEUP; break; 1340 case SCROLL_PAGEUP: eType = SCROLL_PAGEDOWN; break; 1341 case SCROLL_PAGEDOWN: eType = SCROLL_PAGEUP; break; 1342 default: 1343 { 1344 // added to avoid warnings 1345 } 1346 } 1347 } 1348 long nDelta = pScroll->GetDelta(); 1349 switch ( eType ) 1350 { 1351 case SCROLL_LINEUP: 1352 nDelta = -1; 1353 break; 1354 case SCROLL_LINEDOWN: 1355 nDelta = 1; 1356 break; 1357 case SCROLL_PAGEUP: 1358 if ( pScroll == &aHScrollLeft ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT ); 1359 if ( pScroll == &aHScrollRight ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT ); 1360 if ( pScroll == &aVScrollTop ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP ); 1361 if ( pScroll == &aVScrollBottom ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM ); 1362 if (nDelta==0) nDelta=-1; 1363 break; 1364 case SCROLL_PAGEDOWN: 1365 if ( pScroll == &aHScrollLeft ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT ); 1366 if ( pScroll == &aHScrollRight ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT ); 1367 if ( pScroll == &aVScrollTop ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP ); 1368 if ( pScroll == &aVScrollBottom ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM ); 1369 if (nDelta==0) nDelta=1; 1370 break; 1371 case SCROLL_DRAG: 1372 { 1373 // nur in die richtige Richtung scrollen, nicht um ausgeblendete 1374 // Bereiche herumzittern 1375 1376 long nScrollMin = 0; // RangeMin simulieren 1377 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight ) 1378 nScrollMin = aViewData.GetFixPosX(); 1379 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom ) 1380 nScrollMin = aViewData.GetFixPosY(); 1381 1382 long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin; 1383 nDelta = nScrollPos - nViewPos; 1384 if ( nScrollPos > nPrevDragPos ) 1385 { 1386 if (nDelta<0) nDelta=0; 1387 } 1388 else if ( nScrollPos < nPrevDragPos ) 1389 { 1390 if (nDelta>0) nDelta=0; 1391 } 1392 else 1393 nDelta = 0; 1394 nPrevDragPos = nScrollPos; 1395 } 1396 break; 1397 default: 1398 { 1399 // added to avoid warnings 1400 } 1401 } 1402 1403 if (nDelta) 1404 { 1405 sal_Bool bUpdate = ( eType != SCROLL_DRAG ); // bei Drag die Ranges nicht aendern 1406 if ( bHoriz ) 1407 ScrollX( nDelta, (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate ); 1408 else 1409 ScrollY( nDelta, (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate ); 1410 } 1411 } 1412 1413 return 0; 1414 } 1415 1416 void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, sal_Bool bUpdBars ) 1417 { 1418 sal_Bool bHasHint = ( pInputHintWindow != NULL ); 1419 if (bHasHint) 1420 RemoveHintWindow(); 1421 1422 SCCOL nOldX = aViewData.GetPosX(eWhich); 1423 SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX); 1424 if ( nNewX < 0 ) 1425 { 1426 nDeltaX -= nNewX; 1427 nNewX = 0; 1428 } 1429 if ( nNewX > MAXCOL ) 1430 { 1431 nDeltaX -= nNewX - MAXCOL; 1432 nNewX = MAXCOL; 1433 } 1434 1435 SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1; 1436 ScDocument* pDoc = aViewData.GetDocument(); 1437 SCTAB nTab = aViewData.GetTabNo(); 1438 while ( pDoc->ColHidden(nNewX, nTab) && 1439 nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL ) 1440 nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir ); 1441 1442 // Fixierung 1443 1444 if (aViewData.GetHSplitMode() == SC_SPLIT_FIX) 1445 { 1446 if (eWhich == SC_SPLIT_LEFT) 1447 nNewX = static_cast<SCsCOL>(nOldX); // links immer stehenlassen 1448 else 1449 { 1450 SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX()); 1451 if (nNewX < nFixX) 1452 nNewX = nFixX; 1453 } 1454 } 1455 if (nNewX == static_cast<SCsCOL>(nOldX)) 1456 return; 1457 1458 HideAllCursors(); 1459 1460 if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX ) 1461 { 1462 SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) ); 1463 1464 // Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update 1465 // nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl. 1466 // mit schon geaenderter Pos. gepainted werden - 1467 // darum vorher einmal Update am Col-/RowBar 1468 1469 if (pColBar[eWhich]) 1470 pColBar[eWhich]->Update(); 1471 1472 long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X(); 1473 aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) ); 1474 long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos; 1475 1476 if ( eWhich==SC_SPLIT_LEFT ) 1477 { 1478 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 ); 1479 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 1480 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 ); 1481 } 1482 else 1483 { 1484 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 ); 1485 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 1486 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 ); 1487 } 1488 if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); } 1489 if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff ); 1490 if (bUpdBars) 1491 UpdateScrollBars(); 1492 } 1493 1494 if (nDeltaX==1 || nDeltaX==-1) 1495 pGridWin[aViewData.GetActivePart()]->Update(); 1496 1497 ShowAllCursors(); 1498 1499 SetNewVisArea(); // MapMode muss schon gesetzt sein 1500 1501 if (bHasHint) 1502 TestHintWindow(); // neu positionieren 1503 } 1504 1505 void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, sal_Bool bUpdBars ) 1506 { 1507 sal_Bool bHasHint = ( pInputHintWindow != NULL ); 1508 if (bHasHint) 1509 RemoveHintWindow(); 1510 1511 SCROW nOldY = aViewData.GetPosY(eWhich); 1512 SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY); 1513 if ( nNewY < 0 ) 1514 { 1515 nDeltaY -= nNewY; 1516 nNewY = 0; 1517 } 1518 if ( nNewY > MAXROW ) 1519 { 1520 nDeltaY -= nNewY - MAXROW; 1521 nNewY = MAXROW; 1522 } 1523 1524 SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1; 1525 ScDocument* pDoc = aViewData.GetDocument(); 1526 SCTAB nTab = aViewData.GetTabNo(); 1527 while ( pDoc->RowHidden(nNewY, nTab) && 1528 nNewY+nDir >= 0 && nNewY+nDir <= MAXROW ) 1529 nNewY += nDir; 1530 1531 // Fixierung 1532 1533 if (aViewData.GetVSplitMode() == SC_SPLIT_FIX) 1534 { 1535 if (eWhich == SC_SPLIT_TOP) 1536 nNewY = static_cast<SCsROW>(nOldY); // oben immer stehenlassen 1537 else 1538 { 1539 SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY()); 1540 if (nNewY < nFixY) 1541 nNewY = nFixY; 1542 } 1543 } 1544 if (nNewY == static_cast<SCsROW>(nOldY)) 1545 return; 1546 1547 HideAllCursors(); 1548 1549 if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY ) 1550 { 1551 SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) ); 1552 1553 // Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht 1554 // doppelt gepainted werden muss 1555 // PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben 1556 SCROW nUNew = static_cast<SCROW>(nNewY); 1557 UpdateHeaderWidth( &eWhich, &nUNew ); // Zeilenkoepfe anpassen 1558 1559 if (pRowBar[eWhich]) 1560 pRowBar[eWhich]->Update(); 1561 1562 long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y(); 1563 aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) ); 1564 long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos; 1565 1566 if ( eWhich==SC_SPLIT_TOP ) 1567 { 1568 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff ); 1569 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) 1570 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff ); 1571 } 1572 else 1573 { 1574 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff ); 1575 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) 1576 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff ); 1577 } 1578 if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); } 1579 if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff ); 1580 if (bUpdBars) 1581 UpdateScrollBars(); 1582 } 1583 1584 if (nDeltaY==1 || nDeltaY==-1) 1585 pGridWin[aViewData.GetActivePart()]->Update(); 1586 1587 ShowAllCursors(); 1588 1589 SetNewVisArea(); // MapMode muss schon gesetzt sein 1590 1591 if (bHasHint) 1592 TestHintWindow(); // neu positionieren 1593 } 1594 1595 void ScTabView::ScrollLines( long nDeltaX, long nDeltaY ) 1596 { 1597 ScSplitPos eWhich = aViewData.GetActivePart(); 1598 if (nDeltaX) 1599 ScrollX(nDeltaX,WhichH(eWhich)); 1600 if (nDeltaY) 1601 ScrollY(nDeltaY,WhichV(eWhich)); 1602 } 1603 1604 SCROW lcl_LastVisible( ScViewData& rViewData ) 1605 { 1606 // wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?), 1607 // soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden 1608 //! als Member ans Dokument ??? 1609 1610 ScDocument* pDoc = rViewData.GetDocument(); 1611 SCTAB nTab = rViewData.GetTabNo(); 1612 1613 SCROW nVis = MAXROW; 1614 while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 ) 1615 --nVis; 1616 return nVis; 1617 } 1618 1619 void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY ) 1620 { 1621 if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 ) 1622 return; 1623 1624 SCROW nEndPos = MAXROW; 1625 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) 1626 { 1627 // fuer OLE Inplace immer MAXROW 1628 1629 if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY ) 1630 nEndPos = *pPosY; 1631 else 1632 nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM ); 1633 nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE ); // VisibleCellsY 1634 if (nEndPos > MAXROW) 1635 nEndPos = lcl_LastVisible( aViewData ); 1636 1637 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 1638 { 1639 SCROW nTopEnd; 1640 if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY ) 1641 nTopEnd = *pPosY; 1642 else 1643 nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP ); 1644 nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY 1645 if (nTopEnd > MAXROW) 1646 nTopEnd = lcl_LastVisible( aViewData ); 1647 1648 if ( nTopEnd > nEndPos ) 1649 nEndPos = nTopEnd; 1650 } 1651 } 1652 1653 long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth(); 1654 long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth(); 1655 long nDiff = nBig - nSmall; 1656 1657 if (nEndPos>10000) 1658 nEndPos = 10000; 1659 else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible) 1660 nEndPos = 1; 1661 long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000; 1662 1663 if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader ) 1664 { 1665 bInUpdateHeader = sal_True; 1666 1667 pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth ); 1668 if (pRowBar[SC_SPLIT_TOP]) 1669 pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth ); 1670 1671 RepeatResize(); 1672 1673 // auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster) 1674 //aCornerButton.Update(); // der bekommt sonst nie ein Update 1675 1676 bInUpdateHeader = sal_False; 1677 } 1678 } 1679 1680 inline void ShowHide( Window* pWin, sal_Bool bShow ) 1681 { 1682 DBG_ASSERT(pWin || !bShow, "Fenster ist nicht da"); 1683 if (pWin) 1684 pWin->Show(bShow); 1685 } 1686 1687 void ScTabView::UpdateShow() 1688 { 1689 sal_Bool bHScrollMode = aViewData.IsHScrollMode(); 1690 sal_Bool bVScrollMode = aViewData.IsVScrollMode(); 1691 sal_Bool bTabMode = aViewData.IsTabMode(); 1692 sal_Bool bOutlMode = aViewData.IsOutlineMode(); 1693 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData); 1694 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); 1695 sal_Bool bHeader = aViewData.IsHeaderMode(); 1696 1697 sal_Bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ); 1698 sal_Bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ); 1699 1700 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden: 1701 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode(); 1702 if ( eMode == SCROLLING_NO ) 1703 bHScrollMode = bVScrollMode = sal_False; 1704 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ??? 1705 bHScrollMode = bVScrollMode = sal_True; 1706 1707 if ( aViewData.GetDocShell()->IsPreview() ) 1708 bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = sal_False; 1709 1710 // 1711 // Windows anlegen 1712 // 1713 1714 if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT]) 1715 { 1716 pGridWin[SC_SPLIT_BOTTOMRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT ); 1717 DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] ); 1718 } 1719 if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT]) 1720 { 1721 pGridWin[SC_SPLIT_TOPLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT ); 1722 DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] ); 1723 } 1724 if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT]) 1725 { 1726 pGridWin[SC_SPLIT_TOPRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT ); 1727 DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] ); 1728 } 1729 1730 if (bHOutline && !pColOutline[SC_SPLIT_LEFT]) 1731 pColOutline[SC_SPLIT_LEFT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT ); 1732 if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT]) 1733 pColOutline[SC_SPLIT_RIGHT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT ); 1734 1735 if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM]) 1736 pRowOutline[SC_SPLIT_BOTTOM] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT ); 1737 if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP]) 1738 pRowOutline[SC_SPLIT_TOP] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT ); 1739 1740 if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT]) 1741 pColBar[SC_SPLIT_RIGHT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_RIGHT, 1742 &aHdrFunc, pHdrSelEng ); 1743 if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP]) 1744 pRowBar[SC_SPLIT_TOP] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_TOP, 1745 &aHdrFunc, pHdrSelEng ); 1746 1747 // 1748 // Windows anzeigen 1749 // 1750 1751 ShowHide( &aHScrollLeft, bHScrollMode ); 1752 ShowHide( &aHScrollRight, bShowH && bHScrollMode ); 1753 ShowHide( &aVScrollBottom, bVScrollMode ); 1754 ShowHide( &aVScrollTop, bShowV && bVScrollMode ); 1755 ShowHide( &aScrollBarBox, bVScrollMode || bHScrollMode ); 1756 1757 ShowHide( pHSplitter, bHScrollMode || bShowH ); // immer angelegt 1758 ShowHide( pVSplitter, bVScrollMode || bShowV ); 1759 ShowHide( pTabControl, bTabMode ); 1760 1761 // ab hier dynamisch angelegte 1762 1763 ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH ); 1764 ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV ); 1765 ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV ); 1766 1767 ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline ); 1768 ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline ); 1769 1770 ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline ); 1771 ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline ); 1772 1773 ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader ); 1774 ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader ); 1775 1776 1777 //! neue Gridwindows eintragen 1778 } 1779 1780 // --- Splitter -------------------------------------------------------- 1781 1782 IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter ) 1783 { 1784 if ( pSplitter == pHSplitter ) 1785 DoHSplit( pHSplitter->GetSplitPosPixel() ); 1786 else 1787 DoVSplit( pVSplitter->GetSplitPosPixel() ); 1788 1789 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX ) 1790 FreezeSplitters( sal_True ); 1791 1792 DoResize( aBorderPos, aFrameSize ); 1793 1794 return 0; 1795 } 1796 1797 void ScTabView::DoHSplit(long nSplitPos) 1798 { 1799 // nSplitPos is the real pixel position on the frame window, 1800 // mirroring for RTL has to be done here. 1801 1802 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); 1803 if ( bLayoutRTL ) 1804 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1; 1805 1806 long nMinPos; 1807 long nMaxPos; 1808 SCCOL nOldDelta; 1809 SCCOL nNewDelta; 1810 1811 nMinPos = SPLIT_MARGIN; 1812 if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos ) 1813 nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1; 1814 nMaxPos = aFrameSize.Width() - SPLIT_MARGIN; 1815 1816 ScSplitMode aOldMode = aViewData.GetHSplitMode(); 1817 ScSplitMode aNewMode = SC_SPLIT_NORMAL; 1818 1819 aViewData.SetHSplitPos( nSplitPos ); 1820 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos ) 1821 aNewMode = SC_SPLIT_NONE; 1822 1823 aViewData.SetHSplitMode( aNewMode ); 1824 1825 if ( aNewMode != aOldMode ) 1826 { 1827 UpdateShow(); // vor ActivatePart !! 1828 1829 if ( aNewMode == SC_SPLIT_NONE ) 1830 { 1831 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT) 1832 ActivatePart( SC_SPLIT_TOPLEFT ); 1833 if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT) 1834 ActivatePart( SC_SPLIT_BOTTOMLEFT ); 1835 } 1836 else 1837 { 1838 nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT ); 1839 // aViewData.SetPosX( SC_SPLIT_LEFT, nOldDelta ); 1840 long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); 1841 if ( nLeftWidth < 0 ) nLeftWidth = 0; 1842 nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT, 1843 (sal_uInt16) nLeftWidth ); 1844 if ( nNewDelta > MAXCOL ) 1845 nNewDelta = MAXCOL; 1846 aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta ); 1847 if ( nNewDelta > aViewData.GetCurX() ) 1848 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ? 1849 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT ); 1850 else 1851 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ? 1852 SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT ); 1853 } 1854 1855 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen 1856 // dafuer muss hier schon der MapMode stimmen 1857 for (sal_uInt16 i=0; i<4; i++) 1858 if (pGridWin[i]) 1859 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() ); 1860 SetNewVisArea(); 1861 1862 PaintGrid(); 1863 PaintTop(); 1864 1865 InvalidateSplit(); 1866 } 1867 } 1868 1869 void ScTabView::DoVSplit(long nSplitPos) 1870 { 1871 long nMinPos; 1872 long nMaxPos; 1873 SCROW nOldDelta; 1874 SCROW nNewDelta; 1875 1876 nMinPos = SPLIT_MARGIN; 1877 if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos ) 1878 nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1; 1879 nMaxPos = aFrameSize.Height() - SPLIT_MARGIN; 1880 1881 ScSplitMode aOldMode = aViewData.GetVSplitMode(); 1882 ScSplitMode aNewMode = SC_SPLIT_NORMAL; 1883 1884 aViewData.SetVSplitPos( nSplitPos ); 1885 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos ) 1886 aNewMode = SC_SPLIT_NONE; 1887 1888 aViewData.SetVSplitMode( aNewMode ); 1889 1890 if ( aNewMode != aOldMode ) 1891 { 1892 UpdateShow(); // vor ActivatePart !! 1893 1894 if ( aNewMode == SC_SPLIT_NONE ) 1895 { 1896 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP ); 1897 aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta ); 1898 1899 if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT) 1900 ActivatePart( SC_SPLIT_BOTTOMLEFT ); 1901 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT) 1902 ActivatePart( SC_SPLIT_BOTTOMRIGHT ); 1903 } 1904 else 1905 { 1906 if ( aOldMode == SC_SPLIT_NONE ) 1907 nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM ); 1908 else 1909 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP ); 1910 1911 aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta ); 1912 long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); 1913 if ( nTopHeight < 0 ) nTopHeight = 0; 1914 nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP, 1915 (sal_uInt16) nTopHeight ); 1916 if ( nNewDelta > MAXROW ) 1917 nNewDelta = MAXROW; 1918 aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta ); 1919 if ( nNewDelta > aViewData.GetCurY() ) 1920 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ? 1921 SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT ); 1922 else 1923 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ? 1924 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT ); 1925 } 1926 1927 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen 1928 // dafuer muss hier schon der MapMode stimmen 1929 for (sal_uInt16 i=0; i<4; i++) 1930 if (pGridWin[i]) 1931 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() ); 1932 SetNewVisArea(); 1933 1934 PaintGrid(); 1935 PaintLeft(); 1936 1937 InvalidateSplit(); 1938 } 1939 } 1940 1941 Point ScTabView::GetInsertPos() 1942 { 1943 ScDocument* pDoc = aViewData.GetDocument(); 1944 SCCOL nCol = aViewData.GetCurX(); 1945 SCROW nRow = aViewData.GetCurY(); 1946 SCTAB nTab = aViewData.GetTabNo(); 1947 long nPosX = 0; 1948 for (SCCOL i=0; i<nCol; i++) 1949 nPosX += pDoc->GetColWidth(i,nTab); 1950 nPosX = (long)(nPosX * HMM_PER_TWIPS); 1951 if ( pDoc->IsNegativePage( nTab ) ) 1952 nPosX = -nPosX; 1953 long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab); 1954 nPosY = (long)(nPosY * HMM_PER_TWIPS); 1955 return Point(nPosX,nPosY); 1956 } 1957 1958 Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange ) 1959 { 1960 Point aInsertPos; 1961 const long nBorder = 100; // leave 1mm for border 1962 long nNeededWidth = rSize.Width() + 2 * nBorder; 1963 long nNeededHeight = rSize.Height() + 2 * nBorder; 1964 1965 // use the active window, or lower/right if frozen (as in CalcZoom) 1966 ScSplitPos eUsedPart = aViewData.GetActivePart(); 1967 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) 1968 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT; 1969 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) 1970 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT; 1971 1972 ScGridWindow* pWin = pGridWin[eUsedPart]; 1973 DBG_ASSERT( pWin, "Window not found" ); 1974 if (pWin) 1975 { 1976 ActivatePart( eUsedPart ); 1977 1978 // get the visible rectangle in logic units 1979 1980 MapMode aDrawMode = pWin->GetDrawMapMode(); 1981 Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) ); 1982 1983 ScDocument* pDoc = aViewData.GetDocument(); 1984 SCTAB nTab = aViewData.GetTabNo(); 1985 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1986 long nLayoutSign = bLayoutRTL ? -1 : 1; 1987 1988 long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign; 1989 long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS ); 1990 1991 if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign ) 1992 aVisible.Left() = nDocX; 1993 if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign ) 1994 aVisible.Right() = nDocX; 1995 if ( aVisible.Top() > nDocY ) 1996 aVisible.Top() = nDocY; 1997 if ( aVisible.Bottom() > nDocY ) 1998 aVisible.Bottom() = nDocY; 1999 2000 // get the logic position of the selection 2001 2002 Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(), 2003 rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab ); 2004 2005 long nLeftSpace = aSelection.Left() - aVisible.Left(); 2006 long nRightSpace = aVisible.Right() - aSelection.Right(); 2007 long nTopSpace = aSelection.Top() - aVisible.Top(); 2008 long nBottomSpace = aVisible.Bottom() - aSelection.Bottom(); 2009 2010 bool bFitLeft = ( nLeftSpace >= nNeededWidth ); 2011 bool bFitRight = ( nRightSpace >= nNeededWidth ); 2012 2013 if ( bFitLeft || bFitRight ) 2014 { 2015 // first preference: completely left or right of the selection 2016 2017 // if both fit, prefer left in RTL mode, right otherwise 2018 bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight ); 2019 2020 if ( bPutLeft ) 2021 aInsertPos.X() = aSelection.Left() - nNeededWidth; 2022 else 2023 aInsertPos.X() = aSelection.Right() + 1; 2024 2025 // align with top of selection (is moved again if it doesn't fit) 2026 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() ); 2027 } 2028 else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight ) 2029 { 2030 // second preference: completely above or below the selection 2031 2032 if ( nBottomSpace > nNeededHeight ) // bottom is preferred 2033 aInsertPos.Y() = aSelection.Bottom() + 1; 2034 else 2035 aInsertPos.Y() = aSelection.Top() - nNeededHeight; 2036 2037 // align with (logic) left edge of selection (moved again if it doesn't fit) 2038 if ( bLayoutRTL ) 2039 aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1; 2040 else 2041 aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() ); 2042 } 2043 else 2044 { 2045 // place to the (logic) right of the selection and move so it fits 2046 2047 if ( bLayoutRTL ) 2048 aInsertPos.X() = aSelection.Left() - nNeededWidth; 2049 else 2050 aInsertPos.X() = aSelection.Right() + 1; 2051 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() ); 2052 } 2053 2054 // move the position if the object doesn't fit in the screen 2055 2056 Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) ); 2057 if ( aCompareRect.Right() > aVisible.Right() ) 2058 aInsertPos.X() -= aCompareRect.Right() - aVisible.Right(); 2059 if ( aCompareRect.Bottom() > aVisible.Bottom() ) 2060 aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom(); 2061 2062 if ( aInsertPos.X() < aVisible.Left() ) 2063 aInsertPos.X() = aVisible.Left(); 2064 if ( aInsertPos.Y() < aVisible.Top() ) 2065 aInsertPos.Y() = aVisible.Top(); 2066 2067 // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the 2068 // object position, inside the border 2069 2070 aInsertPos.X() += nBorder; 2071 aInsertPos.Y() += nBorder; 2072 } 2073 return aInsertPos; 2074 } 2075 2076 Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart ) 2077 { 2078 // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels. 2079 2080 Point aRet; 2081 2082 // use the active window, or lower/right if frozen (as in CalcZoom) 2083 ScSplitPos eUsedPart = aViewData.GetActivePart(); 2084 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) 2085 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT; 2086 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) 2087 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT; 2088 2089 ScGridWindow* pWin = pGridWin[eUsedPart]; 2090 DBG_ASSERT( pWin, "Window not found" ); 2091 if (pWin) 2092 { 2093 MapMode aDrawMode = pWin->GetDrawMapMode(); 2094 Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode ); 2095 Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ), 2096 pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) ); 2097 2098 Rectangle aDesktop = pWin->GetDesktopRectPixel(); 2099 Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT ); 2100 2101 ScDocument* pDoc = aViewData.GetDocument(); 2102 SCTAB nTab = aViewData.GetTabNo(); 2103 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 2104 2105 bool bCenterHor = false; 2106 2107 if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() ) 2108 { 2109 // first preference: below the chart 2110 2111 aRet.Y() = aObjAbs.Bottom() + aSpace.Height(); 2112 bCenterHor = true; 2113 } 2114 else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() ) 2115 { 2116 // second preference: above the chart 2117 2118 aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height(); 2119 bCenterHor = true; 2120 } 2121 else 2122 { 2123 bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() ); 2124 bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() ); 2125 2126 if ( bFitLeft || bFitRight ) 2127 { 2128 // if both fit, prefer right in RTL mode, left otherwise 2129 bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft ); 2130 if ( bPutRight ) 2131 aRet.X() = aObjAbs.Right() + aSpace.Width(); 2132 else 2133 aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width(); 2134 2135 // center vertically 2136 aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2; 2137 } 2138 else 2139 { 2140 // doesn't fit on any edge - put at the bottom of the screen 2141 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height(); 2142 bCenterHor = true; 2143 } 2144 } 2145 if ( bCenterHor ) 2146 aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2; 2147 2148 // limit to screen (centering might lead to invalid positions) 2149 if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() ) 2150 aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1; 2151 if ( aRet.X() < aDesktop.Left() ) 2152 aRet.X() = aDesktop.Left(); 2153 if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() ) 2154 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1; 2155 if ( aRet.Y() < aDesktop.Top() ) 2156 aRet.Y() = aDesktop.Top(); 2157 } 2158 2159 return aRet; 2160 } 2161 2162 void ScTabView::LockModifiers( sal_uInt16 nModifiers ) 2163 { 2164 pSelEngine->LockModifiers( nModifiers ); 2165 pHdrSelEng->LockModifiers( nModifiers ); 2166 } 2167 2168 sal_uInt16 ScTabView::GetLockedModifiers() const 2169 { 2170 return pSelEngine->GetLockedModifiers(); 2171 } 2172 2173 Point ScTabView::GetMousePosPixel() 2174 { 2175 Point aPos; 2176 ScGridWindow* pWin = (ScGridWindow*)GetActiveWin(); 2177 2178 if ( pWin ) 2179 aPos = pWin->GetMousePosPixel(); 2180 2181 return aPos; 2182 } 2183 2184 sal_Bool lcl_MouseIsOverWin( const Point& rScreenPosPixel, Window* pWin ) 2185 { 2186 if (pWin) 2187 { 2188 // SPLIT_HANDLE_SIZE draufaddieren, damit das Einrasten genau 2189 // auf dem Splitter nicht aussetzt 2190 2191 Point aRel = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel ); 2192 Size aWinSize = pWin->GetOutputSizePixel(); 2193 if ( aRel.X() >= 0 && aRel.X() < aWinSize.Width() + SPLIT_HANDLE_SIZE && 2194 aRel.Y() >= 0 && aRel.Y() < aWinSize.Height() + SPLIT_HANDLE_SIZE ) 2195 return sal_True; 2196 } 2197 return sal_False; 2198 } 2199 2200 void ScTabView::SnapSplitPos( Point& rScreenPosPixel ) 2201 { 2202 sal_Bool bOverWin = sal_False; 2203 sal_uInt16 i; 2204 for (i=0; i<4; i++) 2205 if (lcl_MouseIsOverWin(rScreenPosPixel,pGridWin[i])) 2206 bOverWin = sal_True; 2207 2208 if (!bOverWin) 2209 return; 2210 2211 // #74761# don't snap to cells if the scale will be modified afterwards 2212 if ( GetZoomType() != SVX_ZOOM_PERCENT ) 2213 return; 2214 2215 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT; 2216 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 2217 ePos = SC_SPLIT_TOPLEFT; 2218 2219 Window* pWin = pGridWin[ePos]; 2220 if (!pWin) 2221 { 2222 DBG_ERROR("Window NULL"); 2223 return; 2224 } 2225 2226 Point aMouse = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel ); 2227 SCsCOL nPosX; 2228 SCsROW nPosY; 2229 // #52949# bNextIfLarge=FALSE: nicht auf naechste Zelle, wenn ausserhalb des Fensters 2230 aViewData.GetPosFromPixel( aMouse.X(), aMouse.Y(), ePos, nPosX, nPosY, sal_True, sal_False, sal_False ); 2231 sal_Bool bLeft; 2232 sal_Bool bTop; 2233 aViewData.GetMouseQuadrant( aMouse, ePos, nPosX, nPosY, bLeft, bTop ); 2234 if (!bLeft) 2235 ++nPosX; 2236 if (!bTop) 2237 ++nPosY; 2238 aMouse = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True ); 2239 rScreenPosPixel = pWin->OutputToNormalizedScreenPixel( aMouse ); 2240 } 2241 2242 void ScTabView::FreezeSplitters( sal_Bool bFreeze ) 2243 { 2244 ScSplitMode eOldH = aViewData.GetHSplitMode(); 2245 ScSplitMode eOldV = aViewData.GetVSplitMode(); 2246 2247 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT; 2248 if ( eOldV != SC_SPLIT_NONE ) 2249 ePos = SC_SPLIT_TOPLEFT; 2250 Window* pWin = pGridWin[ePos]; 2251 2252 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); 2253 2254 if ( bFreeze ) 2255 { 2256 Point aWinStart = pWin->GetPosPixel(); 2257 2258 Point aSplit; 2259 SCsCOL nPosX; 2260 SCsROW nPosY; 2261 if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE) 2262 { 2263 if (eOldH != SC_SPLIT_NONE) 2264 { 2265 long nSplitPos = aViewData.GetHSplitPos(); 2266 if ( bLayoutRTL ) 2267 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1; 2268 aSplit.X() = nSplitPos - aWinStart.X(); 2269 } 2270 if (eOldV != SC_SPLIT_NONE) 2271 aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y(); 2272 2273 aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY ); 2274 sal_Bool bLeft; 2275 sal_Bool bTop; 2276 aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop ); 2277 if (!bLeft) 2278 ++nPosX; 2279 if (!bTop) 2280 ++nPosY; 2281 } 2282 else 2283 { 2284 nPosX = static_cast<SCsCOL>( aViewData.GetCurX()); 2285 nPosY = static_cast<SCsROW>( aViewData.GetCurY()); 2286 } 2287 2288 SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT); 2289 SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM); 2290 SCCOL nRightPos = static_cast<SCCOL>(nPosX); 2291 SCROW nBottomPos = static_cast<SCROW>(nPosY); 2292 if (eOldH != SC_SPLIT_NONE) 2293 if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos) 2294 nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT); 2295 if (eOldV != SC_SPLIT_NONE) 2296 { 2297 nTopPos = aViewData.GetPosY(SC_SPLIT_TOP); 2298 if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos) 2299 nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM); 2300 } 2301 2302 aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True ); 2303 if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL 2304 { 2305 long nSplitPos = aSplit.X() + aWinStart.X(); 2306 if ( bLayoutRTL ) 2307 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1; 2308 2309 aViewData.SetHSplitMode( SC_SPLIT_FIX ); 2310 aViewData.SetHSplitPos( nSplitPos ); 2311 aViewData.SetFixPosX( nPosX ); 2312 2313 aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos); 2314 aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos); 2315 } 2316 else 2317 aViewData.SetHSplitMode( SC_SPLIT_NONE ); 2318 if (aSplit.Y() > 0) 2319 { 2320 aViewData.SetVSplitMode( SC_SPLIT_FIX ); 2321 aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() ); 2322 aViewData.SetFixPosY( nPosY ); 2323 2324 aViewData.SetPosY(SC_SPLIT_TOP, nTopPos); 2325 aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos); 2326 } 2327 else 2328 aViewData.SetVSplitMode( SC_SPLIT_NONE ); 2329 } 2330 else // Fixierung aufheben 2331 { 2332 if ( eOldH == SC_SPLIT_FIX ) 2333 aViewData.SetHSplitMode( SC_SPLIT_NORMAL ); 2334 if ( eOldV == SC_SPLIT_FIX ) 2335 aViewData.SetVSplitMode( SC_SPLIT_NORMAL ); 2336 } 2337 2338 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen 2339 // dafuer muss hier schon der MapMode stimmen 2340 for (sal_uInt16 i=0; i<4; i++) 2341 if (pGridWin[i]) 2342 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() ); 2343 SetNewVisArea(); 2344 2345 RepeatResize(sal_False); 2346 2347 UpdateShow(); 2348 PaintLeft(); 2349 PaintTop(); 2350 PaintGrid(); 2351 2352 // SC_FOLLOW_NONE: only update active part 2353 AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE ); 2354 UpdateAutoFillMark(); 2355 2356 InvalidateSplit(); 2357 } 2358 2359 void ScTabView::RemoveSplit() 2360 { 2361 DoHSplit( 0 ); 2362 DoVSplit( 0 ); 2363 RepeatResize(); 2364 } 2365 2366 void ScTabView::SplitAtCursor() 2367 { 2368 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT; 2369 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) 2370 ePos = SC_SPLIT_TOPLEFT; 2371 Window* pWin = pGridWin[ePos]; 2372 Point aWinStart = pWin->GetPosPixel(); 2373 2374 SCCOL nPosX = aViewData.GetCurX(); 2375 SCROW nPosY = aViewData.GetCurY(); 2376 Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, sal_True ); 2377 if ( nPosX > 0 ) 2378 DoHSplit( aSplit.X() + aWinStart.X() ); 2379 else 2380 DoHSplit( 0 ); 2381 if ( nPosY > 0 ) 2382 DoVSplit( aSplit.Y() + aWinStart.Y() ); 2383 else 2384 DoVSplit( 0 ); 2385 RepeatResize(); 2386 } 2387 2388 void ScTabView::SplitAtPixel( const Point& rPixel, sal_Bool bHor, sal_Bool bVer ) // fuer API 2389 { 2390 // Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin 2391 2392 if (bHor) 2393 { 2394 if ( rPixel.X() > 0 ) 2395 DoHSplit( rPixel.X() ); 2396 else 2397 DoHSplit( 0 ); 2398 } 2399 if (bVer) 2400 { 2401 if ( rPixel.Y() > 0 ) 2402 DoVSplit( rPixel.Y() ); 2403 else 2404 DoVSplit( 0 ); 2405 } 2406 RepeatResize(); 2407 } 2408 2409 void ScTabView::InvalidateSplit() 2410 { 2411 SfxBindings& rBindings = aViewData.GetBindings(); 2412 rBindings.Invalidate( SID_WINDOW_SPLIT ); 2413 rBindings.Invalidate( SID_WINDOW_FIX ); 2414 2415 pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX ); 2416 pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX ); 2417 } 2418 2419 void ScTabView::SetNewVisArea() 2420 { 2421 // #63854# fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein 2422 // (auch wenn ansonsten der Edit-MapMode gesetzt ist) 2423 MapMode aOldMode[4]; 2424 MapMode aDrawMode[4]; 2425 sal_uInt16 i; 2426 for (i=0; i<4; i++) 2427 if (pGridWin[i]) 2428 { 2429 aOldMode[i] = pGridWin[i]->GetMapMode(); 2430 aDrawMode[i] = pGridWin[i]->GetDrawMapMode(); 2431 if (aDrawMode[i] != aOldMode[i]) 2432 pGridWin[i]->SetMapMode(aDrawMode[i]); 2433 } 2434 2435 Window* pActive = pGridWin[aViewData.GetActivePart()]; 2436 if (pActive) 2437 aViewData.GetViewShell()->VisAreaChanged( 2438 pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) ); 2439 if (pDrawView) 2440 pDrawView->VisAreaChanged(); // kein Window uebergeben -> alle Fenster 2441 2442 UpdateAllOverlays(); // #i79909# with drawing MapMode set 2443 2444 for (i=0; i<4; i++) 2445 if (pGridWin[i] && aDrawMode[i] != aOldMode[i]) 2446 { 2447 pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode 2448 pGridWin[i]->SetMapMode(aOldMode[i]); 2449 } 2450 2451 SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); 2452 if (pViewFrame) 2453 { 2454 SfxFrame& rFrame = pViewFrame->GetFrame(); 2455 com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController(); 2456 if (xController.is()) 2457 { 2458 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); 2459 if (pImp) 2460 pImp->VisAreaChanged(); 2461 } 2462 } 2463 if (aViewData.GetViewShell()->HasAccessibilityObjects()) 2464 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED)); 2465 } 2466 2467 sal_Bool ScTabView::HasPageFieldDataAtCursor() const 2468 { 2469 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()]; 2470 SCCOL nCol = aViewData.GetCurX(); 2471 SCROW nRow = aViewData.GetCurY(); 2472 if (pWin) 2473 return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE; 2474 2475 return sal_False; 2476 } 2477 2478 void ScTabView::StartDataSelect() 2479 { 2480 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()]; 2481 SCCOL nCol = aViewData.GetCurX(); 2482 SCROW nRow = aViewData.GetCurY(); 2483 2484 if (!pWin) 2485 return; 2486 2487 switch (pWin->GetDPFieldOrientation(nCol, nRow)) 2488 { 2489 case sheet::DataPilotFieldOrientation_PAGE: 2490 // #i36598# If the cursor is on a page field's data cell, 2491 // no meaningful input is possible anyway, so this function 2492 // can be used to select a page field entry. 2493 pWin->LaunchPageFieldMenu( nCol, nRow ); 2494 break; 2495 case sheet::DataPilotFieldOrientation_COLUMN: 2496 case sheet::DataPilotFieldOrientation_ROW: 2497 pWin->LaunchDPFieldMenu( nCol, nRow ); 2498 break; 2499 default: 2500 pWin->DoAutoFilterMenue( nCol, nRow, sal_True ); 2501 } 2502 } 2503 2504 void ScTabView::EnableRefInput(sal_Bool bFlag) 2505 { 2506 aHScrollLeft.EnableInput(bFlag); 2507 aHScrollRight.EnableInput(bFlag); 2508 aVScrollBottom.EnableInput(bFlag); 2509 aVScrollTop.EnableInput(bFlag); 2510 aScrollBarBox.EnableInput(bFlag); 2511 2512 // ab hier dynamisch angelegte 2513 2514 if(pTabControl!=NULL) pTabControl->EnableInput(bFlag,sal_True); 2515 2516 if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=NULL) 2517 pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,sal_False); 2518 if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=NULL) 2519 pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,sal_False); 2520 if(pGridWin[SC_SPLIT_TOPLEFT]!=NULL) 2521 pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,sal_False); 2522 if(pGridWin[SC_SPLIT_TOPRIGHT]!=NULL) 2523 pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,sal_False); 2524 if(pColBar[SC_SPLIT_RIGHT]!=NULL) 2525 pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,sal_False); 2526 if(pRowBar[SC_SPLIT_TOP]!=NULL) 2527 pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,sal_False); 2528 } 2529 2530 2531 2532