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