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