1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sc.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir // INCLUDE --------------------------------------------------------------- 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <sfx2/dispatch.hxx> 36*cdf0e10cSrcweir #include <vcl/help.hxx> 37*cdf0e10cSrcweir #include <tools/poly.hxx> 38*cdf0e10cSrcweir #include <svtools/colorcfg.hxx> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include "scresid.hxx" 41*cdf0e10cSrcweir #include "sc.hrc" 42*cdf0e10cSrcweir #include "tabvwsh.hxx" 43*cdf0e10cSrcweir #include "hdrcont.hxx" 44*cdf0e10cSrcweir #include "scmod.hxx" // Optionen 45*cdf0e10cSrcweir #include "inputopt.hxx" // Optionen 46*cdf0e10cSrcweir #include "gridmerg.hxx" 47*cdf0e10cSrcweir #include "document.hxx" 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir // ----------------------------------------------------------------------- 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #define SC_DRAG_MIN 2 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir // passes in paint 54*cdf0e10cSrcweir // (selection left/right must be first because the continuous lines 55*cdf0e10cSrcweir // are partly overwritten later) 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir #define SC_HDRPAINT_SEL_RIGHT 0 58*cdf0e10cSrcweir #define SC_HDRPAINT_SEL_LEFT 1 59*cdf0e10cSrcweir #define SC_HDRPAINT_TOP 2 60*cdf0e10cSrcweir #define SC_HDRPAINT_SEL_TOP 3 61*cdf0e10cSrcweir #define SC_HDRPAINT_SEL_BOTTOM 4 62*cdf0e10cSrcweir #define SC_HDRPAINT_BOTTOM 5 63*cdf0e10cSrcweir #define SC_HDRPAINT_TEXT 6 64*cdf0e10cSrcweir #define SC_HDRPAINT_COUNT 7 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir //================================================================== 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir ScHeaderControl::ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine, 69*cdf0e10cSrcweir SCCOLROW nNewSize, sal_uInt16 nNewFlags ) : 70*cdf0e10cSrcweir Window ( pParent ), 71*cdf0e10cSrcweir pSelEngine ( pSelectionEngine ), 72*cdf0e10cSrcweir nFlags ( nNewFlags ), 73*cdf0e10cSrcweir bVertical ( (nNewFlags & HDR_VERTICAL) != 0 ), 74*cdf0e10cSrcweir nSize ( nNewSize ), 75*cdf0e10cSrcweir nMarkStart ( 0 ), 76*cdf0e10cSrcweir nMarkEnd ( 0 ), 77*cdf0e10cSrcweir bMarkRange ( sal_False ), 78*cdf0e10cSrcweir bDragging ( sal_False ), 79*cdf0e10cSrcweir bIgnoreMove ( sal_False ) 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir // --- RTL --- no default mirroring for this window, the spreadsheet itself 82*cdf0e10cSrcweir // is also not mirrored 83*cdf0e10cSrcweir // #107811# mirror the vertical window for correct border drawing 84*cdf0e10cSrcweir // #106948# table layout depends on sheet format, not UI setting, so the 85*cdf0e10cSrcweir // borders of the vertical window have to be handled manually, too. 86*cdf0e10cSrcweir EnableRTL( sal_False ); 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir aNormFont = GetFont(); 89*cdf0e10cSrcweir aNormFont.SetTransparent( sal_True ); //! WEIGHT_NORMAL hart setzen ??? 90*cdf0e10cSrcweir aBoldFont = aNormFont; 91*cdf0e10cSrcweir aBoldFont.SetWeight( WEIGHT_BOLD ); 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir SetFont(aBoldFont); 94*cdf0e10cSrcweir bBoldSet = sal_True; 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir Size aSize = LogicToPixel( Size( 97*cdf0e10cSrcweir GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888")) ), 98*cdf0e10cSrcweir GetTextHeight() ) ); 99*cdf0e10cSrcweir aSize.Width() += 4; // Platz fuer hervorgehobene Umrandung 100*cdf0e10cSrcweir aSize.Height() += 3; 101*cdf0e10cSrcweir SetSizePixel( aSize ); 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir nWidth = nSmallWidth = aSize.Width(); 104*cdf0e10cSrcweir nBigWidth = LogicToPixel( Size( GetTextWidth( 105*cdf0e10cSrcweir String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888888")) ), 0 ) ).Width() + 5; 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir SetBackground(); // sonst Probleme auf OS/2 !?!?! 108*cdf0e10cSrcweir } 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir void ScHeaderControl::SetWidth( long nNew ) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir DBG_ASSERT( bVertical, "SetDigits nur fuer Zeilenkoepfe erlaubt" ); 113*cdf0e10cSrcweir if ( nNew != nWidth ) 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir Size aSize( nNew, GetSizePixel().Height() ); // Hoehe nicht aendern 116*cdf0e10cSrcweir SetSizePixel( aSize ); 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir nWidth = nNew; 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir Invalidate(); // neu zentrieren 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir } 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir ScHeaderControl::~ScHeaderControl() 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir void ScHeaderControl::DoPaint( SCCOLROW nStart, SCCOLROW nEnd ) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir sal_Bool bLayoutRTL = IsLayoutRTL(); 131*cdf0e10cSrcweir long nLayoutSign = bLayoutRTL ? -1 : 1; 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir Rectangle aRect( Point(0,0), GetOutputSizePixel() ); 134*cdf0e10cSrcweir if ( bVertical ) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir aRect.Top() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line at top of selection 137*cdf0e10cSrcweir aRect.Bottom() = GetScrPos( nEnd+1 )-nLayoutSign; 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir else 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir aRect.Left() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line left of selection 142*cdf0e10cSrcweir aRect.Right() = GetScrPos( nEnd+1 )-nLayoutSign; 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir Invalidate(aRect); 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir void ScHeaderControl::SetMark( sal_Bool bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd ) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir sal_Bool bEnabled = SC_MOD()->GetInputOptions().GetMarkHeader(); //! cachen? 150*cdf0e10cSrcweir if (!bEnabled) 151*cdf0e10cSrcweir bNewSet = sal_False; 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir // Variablen setzen 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir sal_Bool bOldSet = bMarkRange; 156*cdf0e10cSrcweir SCCOLROW nOldStart = nMarkStart; 157*cdf0e10cSrcweir SCCOLROW nOldEnd = nMarkEnd; 158*cdf0e10cSrcweir PutInOrder( nNewStart, nNewEnd ); 159*cdf0e10cSrcweir bMarkRange = bNewSet; 160*cdf0e10cSrcweir nMarkStart = nNewStart; 161*cdf0e10cSrcweir nMarkEnd = nNewEnd; 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir // Paint 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir if ( bNewSet ) 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir if ( bOldSet ) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir if ( nNewStart == nOldStart ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir if ( nNewEnd != nOldEnd ) 172*cdf0e10cSrcweir DoPaint( Min( nNewEnd, nOldEnd ) + 1, Max( nNewEnd, nOldEnd ) ); 173*cdf0e10cSrcweir // sonst nix 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir else if ( nNewEnd == nOldEnd ) 176*cdf0e10cSrcweir DoPaint( Min( nNewStart, nOldStart ), Max( nNewStart, nOldStart ) - 1 ); 177*cdf0e10cSrcweir else if ( nNewStart > nOldEnd || nNewEnd < nOldStart ) 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir // zwei Bereiche... 180*cdf0e10cSrcweir DoPaint( nOldStart, nOldEnd ); 181*cdf0e10cSrcweir DoPaint( nNewStart, nNewEnd ); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir else // irgendwie ueberlappend... (kommt eh nicht oft vor) 184*cdf0e10cSrcweir DoPaint( Min( nNewStart, nOldStart ), Max( nNewEnd, nOldEnd ) ); 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir else 187*cdf0e10cSrcweir DoPaint( nNewStart, nNewEnd ); // komplett neu 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir else if ( bOldSet ) 190*cdf0e10cSrcweir DoPaint( nOldStart, nOldEnd ); // komplett aufheben 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir // sonst war nix, is nix 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir long ScHeaderControl::GetScrPos( SCCOLROW nEntryNo ) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir long nScrPos; 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir long nMax = ( bVertical ? GetOutputSizePixel().Height() : GetOutputSizePixel().Width() ) + 1; 200*cdf0e10cSrcweir if (nEntryNo >= nSize) 201*cdf0e10cSrcweir nScrPos = nMax; 202*cdf0e10cSrcweir else 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir nScrPos = 0; 205*cdf0e10cSrcweir for (SCCOLROW i=GetPos(); i<nEntryNo && nScrPos<nMax; i++) 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir sal_uInt16 nAdd = GetEntrySize(i); 208*cdf0e10cSrcweir if (nAdd) 209*cdf0e10cSrcweir nScrPos += nAdd; 210*cdf0e10cSrcweir else 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir SCCOLROW nHidden = GetHiddenCount(i); 213*cdf0e10cSrcweir if (nHidden > 0) 214*cdf0e10cSrcweir i += nHidden - 1; 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir if ( IsLayoutRTL() ) 220*cdf0e10cSrcweir nScrPos = nMax - nScrPos - 2; 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir return nScrPos; 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir // draw a rectangle across the window's width/height, with the outer part in a lighter color 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir void ScHeaderControl::DrawShadedRect( long nStart, long nEnd, const Color& rBaseColor ) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir Color aWhite( COL_WHITE ); 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir Color aInner( rBaseColor ); // highlight color, unchanged 232*cdf0e10cSrcweir Color aCenter( rBaseColor ); 233*cdf0e10cSrcweir aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit 234*cdf0e10cSrcweir Color aOuter( rBaseColor ); 235*cdf0e10cSrcweir aOuter.Merge( aWhite, 0xa0 ); // lighten up more 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir if ( IsMirrored() ) 238*cdf0e10cSrcweir std::swap( aInner, aOuter ); // just swap colors instead of positions 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir Size aWinSize = GetSizePixel(); 241*cdf0e10cSrcweir long nBarSize = bVertical ? aWinSize.Width() : aWinSize.Height(); 242*cdf0e10cSrcweir long nCenterPos = (nBarSize / 2) - 1; 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir SetLineColor(); 245*cdf0e10cSrcweir SetFillColor( aOuter ); 246*cdf0e10cSrcweir if (bVertical) 247*cdf0e10cSrcweir DrawRect( Rectangle( 0, nStart, nCenterPos-1, nEnd ) ); 248*cdf0e10cSrcweir else 249*cdf0e10cSrcweir DrawRect( Rectangle( nStart, 0, nEnd, nCenterPos-1 ) ); 250*cdf0e10cSrcweir SetFillColor( aCenter ); 251*cdf0e10cSrcweir if (bVertical) 252*cdf0e10cSrcweir DrawRect( Rectangle( nCenterPos, nStart, nCenterPos, nEnd ) ); 253*cdf0e10cSrcweir else 254*cdf0e10cSrcweir DrawRect( Rectangle( nStart, nCenterPos, nEnd, nCenterPos ) ); 255*cdf0e10cSrcweir SetFillColor( aInner ); 256*cdf0e10cSrcweir if (bVertical) 257*cdf0e10cSrcweir DrawRect( Rectangle( nCenterPos+1, nStart, nBarSize-1, nEnd ) ); 258*cdf0e10cSrcweir else 259*cdf0e10cSrcweir DrawRect( Rectangle( nStart, nCenterPos+1, nEnd, nBarSize-1 ) ); 260*cdf0e10cSrcweir } 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir // 263*cdf0e10cSrcweir // Paint 264*cdf0e10cSrcweir // 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir void ScHeaderControl::Paint( const Rectangle& rRect ) 267*cdf0e10cSrcweir { 268*cdf0e10cSrcweir // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren 269*cdf0e10cSrcweir // Linien zusammengefasst 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 272*cdf0e10cSrcweir sal_Bool bHighContrast = rStyleSettings.GetHighContrastMode(); 273*cdf0e10cSrcweir sal_Bool bDark = rStyleSettings.GetFaceColor().IsDark(); 274*cdf0e10cSrcweir // Use the same distinction for bDark as in Window::DrawSelectionBackground 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir Color aTextColor = rStyleSettings.GetButtonTextColor(); 277*cdf0e10cSrcweir Color aSelTextColor = rStyleSettings.GetHighlightTextColor(); 278*cdf0e10cSrcweir aNormFont.SetColor( aTextColor ); 279*cdf0e10cSrcweir if ( bHighContrast ) 280*cdf0e10cSrcweir aBoldFont.SetColor( aTextColor ); 281*cdf0e10cSrcweir else 282*cdf0e10cSrcweir aBoldFont.SetColor( aSelTextColor ); 283*cdf0e10cSrcweir SetTextColor( ( bBoldSet && !bHighContrast ) ? aSelTextColor : aTextColor ); 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir Color aBlack( COL_BLACK ); 286*cdf0e10cSrcweir Color aSelLineColor = rStyleSettings.GetHighlightColor(); 287*cdf0e10cSrcweir aSelLineColor.Merge( aBlack, 0xe0 ); // darken just a little bit 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir sal_Bool bLayoutRTL = IsLayoutRTL(); 290*cdf0e10cSrcweir long nLayoutSign = bLayoutRTL ? -1 : 1; 291*cdf0e10cSrcweir sal_Bool bMirrored = IsMirrored(); 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir // const FunctionSet* pFuncSet = pSelEngine->GetFunctionSet(); 294*cdf0e10cSrcweir String aString; 295*cdf0e10cSrcweir sal_uInt16 nBarSize; 296*cdf0e10cSrcweir Point aScrPos; 297*cdf0e10cSrcweir Size aTextSize; 298*cdf0e10cSrcweir // Size aSize = GetOutputSizePixel(); 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir if (bVertical) 301*cdf0e10cSrcweir nBarSize = (sal_uInt16) GetSizePixel().Width(); 302*cdf0e10cSrcweir else 303*cdf0e10cSrcweir nBarSize = (sal_uInt16) GetSizePixel().Height(); 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir SCCOLROW nPos = GetPos(); 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir long nPStart = bVertical ? rRect.Top() : rRect.Left(); 308*cdf0e10cSrcweir long nPEnd = bVertical ? rRect.Bottom() : rRect.Right(); 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir long nTransStart = nPEnd + 1; 311*cdf0e10cSrcweir long nTransEnd = 0; 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir long nInitScrPos = 0; 314*cdf0e10cSrcweir if ( bLayoutRTL ) 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir long nTemp = nPStart; // swap nPStart / nPEnd 317*cdf0e10cSrcweir nPStart = nPEnd; 318*cdf0e10cSrcweir nPEnd = nTemp; 319*cdf0e10cSrcweir nTemp = nTransStart; // swap nTransStart / nTransEnd 320*cdf0e10cSrcweir nTransStart = nTransEnd; 321*cdf0e10cSrcweir nTransEnd = nTemp; 322*cdf0e10cSrcweir if ( bVertical ) // start loops from the end 323*cdf0e10cSrcweir nInitScrPos = GetSizePixel().Height() - 1; 324*cdf0e10cSrcweir else 325*cdf0e10cSrcweir nInitScrPos = GetSizePixel().Width() - 1; 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir // aeussere Linien komplett durchzeichnen 329*cdf0e10cSrcweir // Zuerst Ende der letzten Zelle finden 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir // long nLineEnd = -1; 332*cdf0e10cSrcweir long nLineEnd = nInitScrPos - nLayoutSign; 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir for (SCCOLROW i=nPos; i<nSize; i++) 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir sal_uInt16 nSizePix = GetEntrySize( i ); 337*cdf0e10cSrcweir if (nSizePix) 338*cdf0e10cSrcweir { 339*cdf0e10cSrcweir nLineEnd += nSizePix * nLayoutSign; 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir if ( bMarkRange && i >= nMarkStart && i <= nMarkEnd ) 342*cdf0e10cSrcweir { 343*cdf0e10cSrcweir long nLineStart = nLineEnd - ( nSizePix - 1 ) * nLayoutSign; 344*cdf0e10cSrcweir if ( nLineStart * nLayoutSign < nTransStart * nLayoutSign ) 345*cdf0e10cSrcweir nTransStart = nLineStart; 346*cdf0e10cSrcweir if ( nLineEnd * nLayoutSign > nTransEnd * nLayoutSign ) 347*cdf0e10cSrcweir nTransEnd = nLineEnd; 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir if ( nLineEnd * nLayoutSign > nPEnd * nLayoutSign ) 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir nLineEnd = nPEnd; 353*cdf0e10cSrcweir break; 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir else 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir SCCOLROW nHidden = GetHiddenCount(i); 359*cdf0e10cSrcweir if (nHidden > 0) 360*cdf0e10cSrcweir i += nHidden - 1; 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir // background is different for entry area and behind the entries 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir Rectangle aFillRect; 367*cdf0e10cSrcweir SetLineColor(); 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir if ( nLineEnd * nLayoutSign >= nInitScrPos * nLayoutSign ) 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir if ( bHighContrast ) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir // high contrast: single-color background 374*cdf0e10cSrcweir SetFillColor( rStyleSettings.GetFaceColor() ); 375*cdf0e10cSrcweir if ( bVertical ) 376*cdf0e10cSrcweir aFillRect = Rectangle( 0, nInitScrPos, nBarSize-1, nLineEnd ); 377*cdf0e10cSrcweir else 378*cdf0e10cSrcweir aFillRect = Rectangle( nInitScrPos, 0, nLineEnd, nBarSize-1 ); 379*cdf0e10cSrcweir DrawRect( aFillRect ); 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir else 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir // normal: 3-part background 384*cdf0e10cSrcweir DrawShadedRect( nInitScrPos, nLineEnd, rStyleSettings.GetFaceColor() ); 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir 388*cdf0e10cSrcweir if ( nLineEnd * nLayoutSign < nPEnd * nLayoutSign ) 389*cdf0e10cSrcweir { 390*cdf0e10cSrcweir SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND).nColor ); 391*cdf0e10cSrcweir if ( bVertical ) 392*cdf0e10cSrcweir aFillRect = Rectangle( 0, nLineEnd+nLayoutSign, nBarSize-1, nPEnd ); 393*cdf0e10cSrcweir else 394*cdf0e10cSrcweir aFillRect = Rectangle( nLineEnd+nLayoutSign, 0, nPEnd, nBarSize-1 ); 395*cdf0e10cSrcweir DrawRect( aFillRect ); 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir if ( nLineEnd * nLayoutSign >= nPStart * nLayoutSign ) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign ) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir if ( bHighContrast ) 403*cdf0e10cSrcweir { 404*cdf0e10cSrcweir if ( bDark ) 405*cdf0e10cSrcweir { 406*cdf0e10cSrcweir // solid grey background for dark face color is drawn before lines 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir SetLineColor(); 409*cdf0e10cSrcweir SetFillColor( COL_LIGHTGRAY ); 410*cdf0e10cSrcweir if (bVertical) 411*cdf0e10cSrcweir DrawRect( Rectangle( 0, nTransStart, nBarSize-1, nTransEnd ) ); 412*cdf0e10cSrcweir else 413*cdf0e10cSrcweir DrawRect( Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 ) ); 414*cdf0e10cSrcweir } 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir else 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir // background for selection 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir DrawShadedRect( nTransStart, nTransEnd, rStyleSettings.GetHighlightColor() ); 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir #if 0 425*cdf0e10cSrcweir // 3D border is no longer used 426*cdf0e10cSrcweir SetLineColor( rStyleSettings.GetLightColor() ); 427*cdf0e10cSrcweir if (bVertical) 428*cdf0e10cSrcweir DrawLine( Point( 0, nPStart ), Point( 0, nLineEnd ) ); 429*cdf0e10cSrcweir else 430*cdf0e10cSrcweir DrawLine( Point( nPStart, 0 ), Point( nLineEnd, 0 ) ); 431*cdf0e10cSrcweir #endif 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir SetLineColor( rStyleSettings.GetDarkShadowColor() ); 434*cdf0e10cSrcweir if (bVertical) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir long nDarkPos = bMirrored ? 0 : nBarSize-1; 437*cdf0e10cSrcweir DrawLine( Point( nDarkPos, nPStart ), Point( nDarkPos, nLineEnd ) ); 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir else 440*cdf0e10cSrcweir DrawLine( Point( nPStart, nBarSize-1 ), Point( nLineEnd, nBarSize-1 ) ); 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir // line in different color for selection 443*cdf0e10cSrcweir if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && !bHighContrast ) 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir SetLineColor( aSelLineColor ); 446*cdf0e10cSrcweir if (bVertical) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir long nDarkPos = bMirrored ? 0 : nBarSize-1; 449*cdf0e10cSrcweir DrawLine( Point( nDarkPos, nTransStart ), Point( nDarkPos, nTransEnd ) ); 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir else 452*cdf0e10cSrcweir DrawLine( Point( nTransStart, nBarSize-1 ), Point( nTransEnd, nBarSize-1 ) ); 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir // 457*cdf0e10cSrcweir // loop through entries several times to avoid changing the line color too often 458*cdf0e10cSrcweir // and to allow merging of lines 459*cdf0e10cSrcweir // 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir ScGridMerger aGrid( this, 1, 1 ); 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir // start at SC_HDRPAINT_BOTTOM instead of 0 - selection doesn't get different 464*cdf0e10cSrcweir // borders, light border at top isn't used anymore 465*cdf0e10cSrcweir // use SC_HDRPAINT_SEL_BOTTOM for different color 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir for (sal_uInt16 nPass = SC_HDRPAINT_SEL_BOTTOM; nPass < SC_HDRPAINT_COUNT; nPass++) 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir // set line color etc. before entry loop 470*cdf0e10cSrcweir switch ( nPass ) 471*cdf0e10cSrcweir { 472*cdf0e10cSrcweir case SC_HDRPAINT_SEL_BOTTOM: 473*cdf0e10cSrcweir // same as non-selected for high contrast 474*cdf0e10cSrcweir SetLineColor( bHighContrast ? rStyleSettings.GetDarkShadowColor() : aSelLineColor ); 475*cdf0e10cSrcweir break; 476*cdf0e10cSrcweir case SC_HDRPAINT_BOTTOM: 477*cdf0e10cSrcweir SetLineColor( rStyleSettings.GetDarkShadowColor() ); 478*cdf0e10cSrcweir break; 479*cdf0e10cSrcweir case SC_HDRPAINT_TEXT: 480*cdf0e10cSrcweir // DrawSelectionBackground is used only for high contrast on light background 481*cdf0e10cSrcweir if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && bHighContrast && !bDark ) 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir // Transparent selection background is drawn after lines, before text. 484*cdf0e10cSrcweir // #109814# Use DrawSelectionBackground to make sure there is a visible 485*cdf0e10cSrcweir // difference. The case of a dark face color, where DrawSelectionBackground 486*cdf0e10cSrcweir // would just paint over the lines, is handled separately (bDark). 487*cdf0e10cSrcweir // Otherwise, GetHighlightColor is used with 80% transparency. 488*cdf0e10cSrcweir // The window's background color (SetBackground) has to be the background 489*cdf0e10cSrcweir // of the cell area, for the contrast comparison in DrawSelectionBackground. 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir Rectangle aTransRect; 492*cdf0e10cSrcweir if (bVertical) 493*cdf0e10cSrcweir aTransRect = Rectangle( 0, nTransStart, nBarSize-1, nTransEnd ); 494*cdf0e10cSrcweir else 495*cdf0e10cSrcweir aTransRect = Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 ); 496*cdf0e10cSrcweir SetBackground( Color( rStyleSettings.GetFaceColor() ) ); 497*cdf0e10cSrcweir DrawSelectionBackground( aTransRect, 0, sal_True, sal_False, sal_False ); 498*cdf0e10cSrcweir SetBackground(); 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir break; 501*cdf0e10cSrcweir } 502*cdf0e10cSrcweir 503*cdf0e10cSrcweir SCCOLROW nCount=0; 504*cdf0e10cSrcweir long nScrPos=nInitScrPos; 505*cdf0e10cSrcweir do 506*cdf0e10cSrcweir { 507*cdf0e10cSrcweir if (bVertical) 508*cdf0e10cSrcweir aScrPos = Point( 0, nScrPos ); 509*cdf0e10cSrcweir else 510*cdf0e10cSrcweir aScrPos = Point( nScrPos, 0 ); 511*cdf0e10cSrcweir 512*cdf0e10cSrcweir SCCOLROW nEntryNo = nCount + nPos; 513*cdf0e10cSrcweir if ( nEntryNo >= nSize ) // MAXCOL/MAXROW 514*cdf0e10cSrcweir nScrPos = nPEnd + nLayoutSign; // beyond nPEnd -> stop 515*cdf0e10cSrcweir else 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir sal_uInt16 nSizePix = GetEntrySize( nEntryNo ); 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir if (nSizePix == 0) 520*cdf0e10cSrcweir { 521*cdf0e10cSrcweir SCCOLROW nHidden = GetHiddenCount(nEntryNo); 522*cdf0e10cSrcweir if (nHidden > 0) 523*cdf0e10cSrcweir nCount += nHidden - 1; 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir else if ((nScrPos+nSizePix*nLayoutSign)*nLayoutSign >= nPStart*nLayoutSign) 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir Point aEndPos(aScrPos); 528*cdf0e10cSrcweir if (bVertical) 529*cdf0e10cSrcweir aEndPos = Point( aScrPos.X()+nBarSize-1, aScrPos.Y()+(nSizePix-1)*nLayoutSign ); 530*cdf0e10cSrcweir else 531*cdf0e10cSrcweir aEndPos = Point( aScrPos.X()+(nSizePix-1)*nLayoutSign, aScrPos.Y()+nBarSize-1 ); 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir sal_Bool bMark = bMarkRange && nEntryNo >= nMarkStart && nEntryNo <= nMarkEnd; 534*cdf0e10cSrcweir sal_Bool bNextToMark = bMarkRange && nEntryNo + 1 >= nMarkStart && nEntryNo <= nMarkEnd; 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir switch ( nPass ) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir case SC_HDRPAINT_SEL_BOTTOM: 539*cdf0e10cSrcweir case SC_HDRPAINT_BOTTOM: 540*cdf0e10cSrcweir if ( nPass == ( bNextToMark ? SC_HDRPAINT_SEL_BOTTOM : SC_HDRPAINT_BOTTOM ) ) 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir if (bVertical) 543*cdf0e10cSrcweir aGrid.AddHorLine( aScrPos.X(), aEndPos.X(), aEndPos.Y() ); 544*cdf0e10cSrcweir else 545*cdf0e10cSrcweir aGrid.AddVerLine( aEndPos.X(), aScrPos.Y(), aEndPos.Y() ); 546*cdf0e10cSrcweir 547*cdf0e10cSrcweir // thick bottom for hidden rows 548*cdf0e10cSrcweir // (drawn directly, without aGrid) 549*cdf0e10cSrcweir if ( nEntryNo+1 < nSize ) 550*cdf0e10cSrcweir if ( GetEntrySize(nEntryNo+1)==0 ) 551*cdf0e10cSrcweir { 552*cdf0e10cSrcweir if (bVertical) 553*cdf0e10cSrcweir DrawLine( Point(aScrPos.X(),aEndPos.Y()-nLayoutSign), 554*cdf0e10cSrcweir Point(aEndPos.X(),aEndPos.Y()-nLayoutSign) ); 555*cdf0e10cSrcweir else 556*cdf0e10cSrcweir DrawLine( Point(aEndPos.X()-nLayoutSign,aScrPos.Y()), 557*cdf0e10cSrcweir Point(aEndPos.X()-nLayoutSign,aEndPos.Y()) ); 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir break; 561*cdf0e10cSrcweir 562*cdf0e10cSrcweir case SC_HDRPAINT_TEXT: 563*cdf0e10cSrcweir if ( nSizePix > 1 ) // minimal check for small columns/rows 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir if ( bMark != bBoldSet ) 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir if (bMark) 568*cdf0e10cSrcweir SetFont(aBoldFont); 569*cdf0e10cSrcweir else 570*cdf0e10cSrcweir SetFont(aNormFont); 571*cdf0e10cSrcweir bBoldSet = bMark; 572*cdf0e10cSrcweir } 573*cdf0e10cSrcweir aString = GetEntryText( nEntryNo ); 574*cdf0e10cSrcweir aTextSize.Width() = GetTextWidth( aString ); 575*cdf0e10cSrcweir aTextSize.Height() = GetTextHeight(); 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir Point aTxtPos(aScrPos); 578*cdf0e10cSrcweir if (bVertical) 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir aTxtPos.X() += (nBarSize-aTextSize.Width())/2; 581*cdf0e10cSrcweir aTxtPos.Y() += (nSizePix*nLayoutSign-aTextSize.Height())/2; 582*cdf0e10cSrcweir if ( bMirrored ) 583*cdf0e10cSrcweir aTxtPos.X() += 1; // dark border is left instead of right 584*cdf0e10cSrcweir } 585*cdf0e10cSrcweir else 586*cdf0e10cSrcweir { 587*cdf0e10cSrcweir aTxtPos.X() += (nSizePix*nLayoutSign-aTextSize.Width()+1)/2; 588*cdf0e10cSrcweir aTxtPos.Y() += (nBarSize-aTextSize.Height())/2; 589*cdf0e10cSrcweir } 590*cdf0e10cSrcweir DrawText( aTxtPos, aString ); 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir break; 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir // bei Selektion der ganzen Zeile/Spalte: 596*cdf0e10cSrcweir // InvertRect( Rectangle( aScrPos, aEndPos ) ); 597*cdf0e10cSrcweir } 598*cdf0e10cSrcweir nScrPos += nSizePix * nLayoutSign; // also if before the visible area 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir ++nCount; 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir while ( nScrPos * nLayoutSign <= nPEnd * nLayoutSign ); 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir aGrid.Flush(); 605*cdf0e10cSrcweir } 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir // 609*cdf0e10cSrcweir // Maus - Handling 610*cdf0e10cSrcweir // 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir SCCOLROW ScHeaderControl::GetMousePos( const MouseEvent& rMEvt, sal_Bool& rBorder ) 613*cdf0e10cSrcweir { 614*cdf0e10cSrcweir sal_Bool bFound=sal_False; 615*cdf0e10cSrcweir SCCOLROW nCount = 1; 616*cdf0e10cSrcweir SCCOLROW nPos = GetPos(); 617*cdf0e10cSrcweir SCCOLROW nHitNo = nPos; 618*cdf0e10cSrcweir long nScrPos; 619*cdf0e10cSrcweir long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X(); 620*cdf0e10cSrcweir long nDif; 621*cdf0e10cSrcweir Size aSize = GetOutputSizePixel(); 622*cdf0e10cSrcweir long nWinSize = bVertical ? aSize.Height() : aSize.Width(); 623*cdf0e10cSrcweir 624*cdf0e10cSrcweir sal_Bool bLayoutRTL = IsLayoutRTL(); 625*cdf0e10cSrcweir long nLayoutSign = bLayoutRTL ? -1 : 1; 626*cdf0e10cSrcweir long nEndPos = bLayoutRTL ? -1 : nWinSize; 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir nScrPos = GetScrPos( nPos ) - nLayoutSign; 629*cdf0e10cSrcweir do 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir SCCOLROW nEntryNo = nCount + nPos; 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir // nScrPos = GetScrPos( nEntryNo ) - 1; 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir if (nEntryNo > nSize) 636*cdf0e10cSrcweir nScrPos = nEndPos + nLayoutSign; 637*cdf0e10cSrcweir else 638*cdf0e10cSrcweir nScrPos += GetEntrySize( nEntryNo - 1 ) * nLayoutSign; //! GetHiddenCount() ?? 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir nDif = nMousePos - nScrPos; 641*cdf0e10cSrcweir if (nDif >= -2 && nDif <= 2 && nCount > 0) 642*cdf0e10cSrcweir { 643*cdf0e10cSrcweir bFound=sal_True; 644*cdf0e10cSrcweir nHitNo=nEntryNo-1; 645*cdf0e10cSrcweir } 646*cdf0e10cSrcweir else if (nDif * nLayoutSign >= 0 && nEntryNo < nSize) 647*cdf0e10cSrcweir nHitNo = nEntryNo; 648*cdf0e10cSrcweir ++nCount; 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir while ( nScrPos * nLayoutSign < nEndPos * nLayoutSign && nDif * nLayoutSign > 0 ); 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir rBorder = bFound; 653*cdf0e10cSrcweir return nHitNo; 654*cdf0e10cSrcweir } 655*cdf0e10cSrcweir 656*cdf0e10cSrcweir bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos) const 657*cdf0e10cSrcweir { 658*cdf0e10cSrcweir ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); 659*cdf0e10cSrcweir if (!pViewSh) 660*cdf0e10cSrcweir return false; 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir ScViewData* pViewData = pViewSh->GetViewData(); 663*cdf0e10cSrcweir sal_uInt16 nTab = pViewData->GetTabNo(); 664*cdf0e10cSrcweir ScDocument* pDoc = pViewData->GetDocument(); 665*cdf0e10cSrcweir const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); 666*cdf0e10cSrcweir bool bSelectAllowed = true; 667*cdf0e10cSrcweir if ( pProtect && pProtect->isProtected() ) 668*cdf0e10cSrcweir { 669*cdf0e10cSrcweir // This sheet is protected. Check if a context menu is allowed on this cell. 670*cdf0e10cSrcweir bool bCellsProtected = false; 671*cdf0e10cSrcweir if (bVertical) 672*cdf0e10cSrcweir { 673*cdf0e10cSrcweir // row header 674*cdf0e10cSrcweir SCROW nRPos = static_cast<SCROW>(nPos); 675*cdf0e10cSrcweir bCellsProtected = pDoc->HasAttrib(0, nRPos, nTab, MAXCOL, nRPos, nTab, HASATTR_PROTECTED); 676*cdf0e10cSrcweir } 677*cdf0e10cSrcweir else 678*cdf0e10cSrcweir { 679*cdf0e10cSrcweir // column header 680*cdf0e10cSrcweir SCCOL nCPos = static_cast<SCCOL>(nPos); 681*cdf0e10cSrcweir bCellsProtected = pDoc->HasAttrib(nCPos, 0, nTab, nCPos, MAXROW, nTab, HASATTR_PROTECTED); 682*cdf0e10cSrcweir } 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); 685*cdf0e10cSrcweir bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir if (bCellsProtected) 688*cdf0e10cSrcweir bSelectAllowed = bSelProtected; 689*cdf0e10cSrcweir else 690*cdf0e10cSrcweir bSelectAllowed = bSelUnprotected; 691*cdf0e10cSrcweir } 692*cdf0e10cSrcweir return bSelectAllowed; 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir void ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) 696*cdf0e10cSrcweir { 697*cdf0e10cSrcweir if (IsDisabled()) 698*cdf0e10cSrcweir return; 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir bIgnoreMove = sal_False; 701*cdf0e10cSrcweir SelectWindow(); 702*cdf0e10cSrcweir 703*cdf0e10cSrcweir sal_Bool bFound; 704*cdf0e10cSrcweir SCCOLROW nHitNo = GetMousePos( rMEvt, bFound ); 705*cdf0e10cSrcweir if (!IsSelectionAllowed(nHitNo)) 706*cdf0e10cSrcweir return; 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir if ( bFound && rMEvt.IsLeft() && ResizeAllowed() ) 709*cdf0e10cSrcweir { 710*cdf0e10cSrcweir nDragNo = nHitNo; 711*cdf0e10cSrcweir sal_uInt16 nClicks = rMEvt.GetClicks(); 712*cdf0e10cSrcweir if ( nClicks && nClicks%2==0 ) 713*cdf0e10cSrcweir { 714*cdf0e10cSrcweir SetEntrySize( nDragNo, HDR_SIZE_OPTIMUM ); 715*cdf0e10cSrcweir SetPointer( Pointer( POINTER_ARROW ) ); 716*cdf0e10cSrcweir } 717*cdf0e10cSrcweir else 718*cdf0e10cSrcweir { 719*cdf0e10cSrcweir if (bVertical) 720*cdf0e10cSrcweir nDragStart = rMEvt.GetPosPixel().Y(); 721*cdf0e10cSrcweir else 722*cdf0e10cSrcweir nDragStart = rMEvt.GetPosPixel().X(); 723*cdf0e10cSrcweir nDragPos = nDragStart; 724*cdf0e10cSrcweir ShowDragHelp(); 725*cdf0e10cSrcweir DrawInvert( nDragPos ); 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir // CaptureMouse(); 728*cdf0e10cSrcweir StartTracking(); 729*cdf0e10cSrcweir bDragging = sal_True; 730*cdf0e10cSrcweir bDragMoved = sal_False; 731*cdf0e10cSrcweir } 732*cdf0e10cSrcweir } 733*cdf0e10cSrcweir else if (rMEvt.IsLeft()) 734*cdf0e10cSrcweir { 735*cdf0e10cSrcweir pSelEngine->SetWindow( this ); 736*cdf0e10cSrcweir Point aPoint; 737*cdf0e10cSrcweir Rectangle aVis( aPoint,GetOutputSizePixel() ); 738*cdf0e10cSrcweir if (bVertical) 739*cdf0e10cSrcweir aVis.Left() = LONG_MIN, aVis.Right() = LONG_MAX; 740*cdf0e10cSrcweir else 741*cdf0e10cSrcweir aVis.Top() = LONG_MIN, aVis.Bottom() = LONG_MAX; 742*cdf0e10cSrcweir pSelEngine->SetVisibleArea( aVis ); 743*cdf0e10cSrcweir 744*cdf0e10cSrcweir SetMarking( sal_True ); // muss vor SelMouseButtonDown sein 745*cdf0e10cSrcweir pSelEngine->SelMouseButtonDown( rMEvt ); 746*cdf0e10cSrcweir 747*cdf0e10cSrcweir // #74215# In column/row headers a simple click already is a selection. 748*cdf0e10cSrcweir // -> Call SelMouseMove to ensure CreateAnchor is called (and DestroyAnchor 749*cdf0e10cSrcweir // if the next click is somewhere else with Control key). 750*cdf0e10cSrcweir pSelEngine->SelMouseMove( rMEvt ); 751*cdf0e10cSrcweir 752*cdf0e10cSrcweir if (IsMouseCaptured()) 753*cdf0e10cSrcweir { 754*cdf0e10cSrcweir // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann 755*cdf0e10cSrcweir //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?! 756*cdf0e10cSrcweir ReleaseMouse(); 757*cdf0e10cSrcweir StartTracking(); 758*cdf0e10cSrcweir } 759*cdf0e10cSrcweir } 760*cdf0e10cSrcweir } 761*cdf0e10cSrcweir 762*cdf0e10cSrcweir void ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt ) 763*cdf0e10cSrcweir { 764*cdf0e10cSrcweir if ( IsDisabled() ) 765*cdf0e10cSrcweir return; 766*cdf0e10cSrcweir 767*cdf0e10cSrcweir SetMarking( sal_False ); 768*cdf0e10cSrcweir bIgnoreMove = sal_False; 769*cdf0e10cSrcweir // sal_Bool bFound; 770*cdf0e10cSrcweir // SCCOLROW nHitNo = GetMousePos( rMEvt, bFound ); 771*cdf0e10cSrcweir 772*cdf0e10cSrcweir if ( bDragging ) 773*cdf0e10cSrcweir { 774*cdf0e10cSrcweir DrawInvert( nDragPos ); 775*cdf0e10cSrcweir ReleaseMouse(); 776*cdf0e10cSrcweir bDragging = sal_False; 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir long nScrPos = GetScrPos( nDragNo ); 779*cdf0e10cSrcweir long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X(); 780*cdf0e10cSrcweir sal_Bool bLayoutRTL = IsLayoutRTL(); 781*cdf0e10cSrcweir long nNewWidth = bLayoutRTL ? ( nScrPos - nMousePos + 1 ) 782*cdf0e10cSrcweir : ( nMousePos + 2 - nScrPos ); 783*cdf0e10cSrcweir 784*cdf0e10cSrcweir if ( nNewWidth < 0 /* && !IsSelected(nDragNo) */ ) 785*cdf0e10cSrcweir { 786*cdf0e10cSrcweir SCCOLROW nStart = 0; 787*cdf0e10cSrcweir SCCOLROW nEnd = nDragNo; 788*cdf0e10cSrcweir while (nNewWidth < 0) 789*cdf0e10cSrcweir { 790*cdf0e10cSrcweir nStart = nDragNo; 791*cdf0e10cSrcweir if (nDragNo>0) 792*cdf0e10cSrcweir { 793*cdf0e10cSrcweir --nDragNo; 794*cdf0e10cSrcweir nNewWidth += GetEntrySize( nDragNo ); //! GetHiddenCount() ??? 795*cdf0e10cSrcweir } 796*cdf0e10cSrcweir else 797*cdf0e10cSrcweir nNewWidth = 0; 798*cdf0e10cSrcweir } 799*cdf0e10cSrcweir HideEntries( nStart, nEnd ); 800*cdf0e10cSrcweir } 801*cdf0e10cSrcweir else 802*cdf0e10cSrcweir { 803*cdf0e10cSrcweir if (nNewWidth<0) nNewWidth=0; 804*cdf0e10cSrcweir if (bDragMoved) 805*cdf0e10cSrcweir SetEntrySize( nDragNo, (sal_uInt16) nNewWidth ); 806*cdf0e10cSrcweir } 807*cdf0e10cSrcweir } 808*cdf0e10cSrcweir else 809*cdf0e10cSrcweir { 810*cdf0e10cSrcweir pSelEngine->SelMouseButtonUp( rMEvt ); 811*cdf0e10cSrcweir ReleaseMouse(); 812*cdf0e10cSrcweir } 813*cdf0e10cSrcweir } 814*cdf0e10cSrcweir 815*cdf0e10cSrcweir void ScHeaderControl::MouseMove( const MouseEvent& rMEvt ) 816*cdf0e10cSrcweir { 817*cdf0e10cSrcweir if ( IsDisabled() ) 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir SetPointer( Pointer( POINTER_ARROW ) ); 820*cdf0e10cSrcweir return; 821*cdf0e10cSrcweir } 822*cdf0e10cSrcweir 823*cdf0e10cSrcweir sal_Bool bFound; 824*cdf0e10cSrcweir (void)GetMousePos( rMEvt, bFound ); 825*cdf0e10cSrcweir 826*cdf0e10cSrcweir if ( bDragging ) 827*cdf0e10cSrcweir { 828*cdf0e10cSrcweir long nNewPos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X(); 829*cdf0e10cSrcweir if ( nNewPos != nDragPos ) 830*cdf0e10cSrcweir { 831*cdf0e10cSrcweir DrawInvert( nDragPos ); 832*cdf0e10cSrcweir nDragPos = nNewPos; 833*cdf0e10cSrcweir ShowDragHelp(); 834*cdf0e10cSrcweir DrawInvert( nDragPos ); 835*cdf0e10cSrcweir 836*cdf0e10cSrcweir if (nDragPos <= nDragStart-SC_DRAG_MIN || nDragPos >= nDragStart+SC_DRAG_MIN) 837*cdf0e10cSrcweir bDragMoved = sal_True; 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir } 840*cdf0e10cSrcweir else 841*cdf0e10cSrcweir { 842*cdf0e10cSrcweir if ( bFound && rMEvt.GetButtons()==0 && ResizeAllowed() ) 843*cdf0e10cSrcweir SetPointer( Pointer( bVertical ? POINTER_VSIZEBAR : POINTER_HSIZEBAR ) ); 844*cdf0e10cSrcweir else 845*cdf0e10cSrcweir SetPointer( Pointer( POINTER_ARROW ) ); 846*cdf0e10cSrcweir 847*cdf0e10cSrcweir if (!bIgnoreMove) 848*cdf0e10cSrcweir pSelEngine->SelMouseMove( rMEvt ); 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir 852*cdf0e10cSrcweir void ScHeaderControl::Tracking( const TrackingEvent& rTEvt ) 853*cdf0e10cSrcweir { 854*cdf0e10cSrcweir // Weil die SelectionEngine kein Tracking kennt, die Events nur auf 855*cdf0e10cSrcweir // die verschiedenen MouseHandler verteilen... 856*cdf0e10cSrcweir 857*cdf0e10cSrcweir if ( rTEvt.IsTrackingCanceled() ) 858*cdf0e10cSrcweir StopMarking(); 859*cdf0e10cSrcweir else if ( rTEvt.IsTrackingEnded() ) 860*cdf0e10cSrcweir MouseButtonUp( rTEvt.GetMouseEvent() ); 861*cdf0e10cSrcweir else 862*cdf0e10cSrcweir MouseMove( rTEvt.GetMouseEvent() ); 863*cdf0e10cSrcweir } 864*cdf0e10cSrcweir 865*cdf0e10cSrcweir void ScHeaderControl::Command( const CommandEvent& rCEvt ) 866*cdf0e10cSrcweir { 867*cdf0e10cSrcweir sal_uInt16 nCmd = rCEvt.GetCommand(); 868*cdf0e10cSrcweir if ( nCmd == COMMAND_CONTEXTMENU ) 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir StopMarking(); // Selektion / Dragging beenden 871*cdf0e10cSrcweir 872*cdf0e10cSrcweir // Popup ausfuehren 873*cdf0e10cSrcweir 874*cdf0e10cSrcweir ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, 875*cdf0e10cSrcweir SfxViewShell::Current() ); 876*cdf0e10cSrcweir if ( pViewSh ) 877*cdf0e10cSrcweir { 878*cdf0e10cSrcweir if ( rCEvt.IsMouseEvent() ) 879*cdf0e10cSrcweir { 880*cdf0e10cSrcweir // #i18735# select the column/row under the mouse pointer 881*cdf0e10cSrcweir ScViewData* pViewData = pViewSh->GetViewData(); 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir SelectWindow(); // also deselects drawing objects, stops draw text edit 884*cdf0e10cSrcweir if ( pViewData->HasEditView( pViewData->GetActivePart() ) ) 885*cdf0e10cSrcweir SC_MOD()->InputEnterHandler(); // always end edit mode 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir MouseEvent aMEvt( rCEvt.GetMousePosPixel() ); 888*cdf0e10cSrcweir sal_Bool bBorder; 889*cdf0e10cSrcweir SCCOLROW nPos = GetMousePos( aMEvt, bBorder ); 890*cdf0e10cSrcweir if (!IsSelectionAllowed(nPos)) 891*cdf0e10cSrcweir // Selecting this cell is not allowed, neither is context menu. 892*cdf0e10cSrcweir return; 893*cdf0e10cSrcweir 894*cdf0e10cSrcweir SCTAB nTab = pViewData->GetTabNo(); 895*cdf0e10cSrcweir ScRange aNewRange; 896*cdf0e10cSrcweir if ( bVertical ) 897*cdf0e10cSrcweir aNewRange = ScRange( 0, sal::static_int_cast<SCROW>(nPos), nTab, 898*cdf0e10cSrcweir MAXCOL, sal::static_int_cast<SCROW>(nPos), nTab ); 899*cdf0e10cSrcweir else 900*cdf0e10cSrcweir aNewRange = ScRange( sal::static_int_cast<SCCOL>(nPos), 0, nTab, 901*cdf0e10cSrcweir sal::static_int_cast<SCCOL>(nPos), MAXROW, nTab ); 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir // see if any part of the range is already selected 904*cdf0e10cSrcweir sal_Bool bSelected = sal_False; 905*cdf0e10cSrcweir ScRangeList aRanges; 906*cdf0e10cSrcweir pViewData->GetMarkData().FillRangeListWithMarks( &aRanges, sal_False ); 907*cdf0e10cSrcweir sal_uLong nRangeCount = aRanges.Count(); 908*cdf0e10cSrcweir for (sal_uLong i=0; i<nRangeCount && !bSelected; i++) 909*cdf0e10cSrcweir if ( aRanges.GetObject(i)->Intersects( aNewRange ) ) 910*cdf0e10cSrcweir bSelected = sal_True; 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir // select the range if no part of it was selected 913*cdf0e10cSrcweir if ( !bSelected ) 914*cdf0e10cSrcweir pViewSh->MarkRange( aNewRange ); 915*cdf0e10cSrcweir } 916*cdf0e10cSrcweir 917*cdf0e10cSrcweir ScResId aResId( bVertical ? RID_POPUP_ROWHEADER : RID_POPUP_COLHEADER ); 918*cdf0e10cSrcweir pViewSh->GetDispatcher()->ExecutePopup( aResId ); 919*cdf0e10cSrcweir } 920*cdf0e10cSrcweir } 921*cdf0e10cSrcweir else if ( nCmd == COMMAND_STARTDRAG ) 922*cdf0e10cSrcweir { 923*cdf0e10cSrcweir pSelEngine->Command( rCEvt ); 924*cdf0e10cSrcweir } 925*cdf0e10cSrcweir } 926*cdf0e10cSrcweir 927*cdf0e10cSrcweir void ScHeaderControl::StopMarking() 928*cdf0e10cSrcweir { 929*cdf0e10cSrcweir if ( bDragging ) 930*cdf0e10cSrcweir { 931*cdf0e10cSrcweir DrawInvert( nDragPos ); 932*cdf0e10cSrcweir bDragging = sal_False; 933*cdf0e10cSrcweir } 934*cdf0e10cSrcweir 935*cdf0e10cSrcweir SetMarking( sal_False ); 936*cdf0e10cSrcweir bIgnoreMove = sal_True; 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir // #86260# don't call pSelEngine->Reset, so selection across the parts of 939*cdf0e10cSrcweir // a split/frozen view is possible 940*cdf0e10cSrcweir 941*cdf0e10cSrcweir ReleaseMouse(); 942*cdf0e10cSrcweir } 943*cdf0e10cSrcweir 944*cdf0e10cSrcweir void ScHeaderControl::ShowDragHelp() 945*cdf0e10cSrcweir { 946*cdf0e10cSrcweir if (Help::IsQuickHelpEnabled()) 947*cdf0e10cSrcweir { 948*cdf0e10cSrcweir long nScrPos = GetScrPos( nDragNo ); 949*cdf0e10cSrcweir sal_Bool bLayoutRTL = IsLayoutRTL(); 950*cdf0e10cSrcweir long nVal = bLayoutRTL ? ( nScrPos - nDragPos + 1 ) 951*cdf0e10cSrcweir : ( nDragPos + 2 - nScrPos ); 952*cdf0e10cSrcweir 953*cdf0e10cSrcweir String aHelpStr = GetDragHelp( nVal ); 954*cdf0e10cSrcweir Point aPos = OutputToScreenPixel( Point(0,0) ); 955*cdf0e10cSrcweir Size aSize = GetSizePixel(); 956*cdf0e10cSrcweir 957*cdf0e10cSrcweir Point aMousePos = OutputToScreenPixel(GetPointerPosPixel()); 958*cdf0e10cSrcweir 959*cdf0e10cSrcweir Rectangle aRect; 960*cdf0e10cSrcweir sal_uInt16 nAlign; 961*cdf0e10cSrcweir if (!bVertical) 962*cdf0e10cSrcweir { 963*cdf0e10cSrcweir // oberhalb 964*cdf0e10cSrcweir aRect.Left() = aMousePos.X(); 965*cdf0e10cSrcweir aRect.Top() = aPos.Y() - 4; 966*cdf0e10cSrcweir nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER; 967*cdf0e10cSrcweir } 968*cdf0e10cSrcweir else 969*cdf0e10cSrcweir { 970*cdf0e10cSrcweir // rechts oben 971*cdf0e10cSrcweir aRect.Left() = aPos.X() + aSize.Width() + 8; 972*cdf0e10cSrcweir aRect.Top() = aMousePos.Y() - 2; 973*cdf0e10cSrcweir nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM; 974*cdf0e10cSrcweir } 975*cdf0e10cSrcweir 976*cdf0e10cSrcweir aRect.Right() = aRect.Left(); 977*cdf0e10cSrcweir aRect.Bottom() = aRect.Top(); 978*cdf0e10cSrcweir 979*cdf0e10cSrcweir Help::ShowQuickHelp(this, aRect, aHelpStr, nAlign); 980*cdf0e10cSrcweir } 981*cdf0e10cSrcweir } 982*cdf0e10cSrcweir 983*cdf0e10cSrcweir void ScHeaderControl::RequestHelp( const HelpEvent& rHEvt ) 984*cdf0e10cSrcweir { 985*cdf0e10cSrcweir // Wenn eigene QuickHelp angezeigt wird, nicht durch RequestHelp 986*cdf0e10cSrcweir // wieder wegnehmen lassen 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir sal_Bool bOwn = bDragging && Help::IsQuickHelpEnabled(); 989*cdf0e10cSrcweir if (!bOwn) 990*cdf0e10cSrcweir Window::RequestHelp(rHEvt); 991*cdf0e10cSrcweir } 992*cdf0e10cSrcweir 993*cdf0e10cSrcweir // ----------------------------------------------------------------------- 994*cdf0e10cSrcweir // Dummys fuer virtuelle Methoden 995*cdf0e10cSrcweir // ----------------------------------------------------------------------- 996*cdf0e10cSrcweir 997*cdf0e10cSrcweir SCCOLROW ScHeaderControl::GetHiddenCount( SCCOLROW nEntryNo ) 998*cdf0e10cSrcweir { 999*cdf0e10cSrcweir SCCOLROW nHidden = 0; 1000*cdf0e10cSrcweir while ( nEntryNo < nSize && GetEntrySize( nEntryNo ) == 0 ) 1001*cdf0e10cSrcweir { 1002*cdf0e10cSrcweir ++nEntryNo; 1003*cdf0e10cSrcweir ++nHidden; 1004*cdf0e10cSrcweir } 1005*cdf0e10cSrcweir return nHidden; 1006*cdf0e10cSrcweir } 1007*cdf0e10cSrcweir 1008*cdf0e10cSrcweir sal_Bool ScHeaderControl::IsLayoutRTL() 1009*cdf0e10cSrcweir { 1010*cdf0e10cSrcweir return sal_False; 1011*cdf0e10cSrcweir } 1012*cdf0e10cSrcweir 1013*cdf0e10cSrcweir sal_Bool ScHeaderControl::IsMirrored() 1014*cdf0e10cSrcweir { 1015*cdf0e10cSrcweir return sal_False; 1016*cdf0e10cSrcweir } 1017*cdf0e10cSrcweir 1018*cdf0e10cSrcweir sal_Bool ScHeaderControl::IsDisabled() 1019*cdf0e10cSrcweir { 1020*cdf0e10cSrcweir return sal_False; 1021*cdf0e10cSrcweir } 1022*cdf0e10cSrcweir 1023*cdf0e10cSrcweir sal_Bool ScHeaderControl::ResizeAllowed() 1024*cdf0e10cSrcweir { 1025*cdf0e10cSrcweir return sal_True; 1026*cdf0e10cSrcweir } 1027*cdf0e10cSrcweir 1028*cdf0e10cSrcweir void ScHeaderControl::SelectWindow() 1029*cdf0e10cSrcweir { 1030*cdf0e10cSrcweir } 1031*cdf0e10cSrcweir 1032*cdf0e10cSrcweir void ScHeaderControl::DrawInvert( long /* nDragPos */ ) 1033*cdf0e10cSrcweir { 1034*cdf0e10cSrcweir } 1035*cdf0e10cSrcweir 1036*cdf0e10cSrcweir String ScHeaderControl::GetDragHelp( long /* nVal */ ) 1037*cdf0e10cSrcweir { 1038*cdf0e10cSrcweir return EMPTY_STRING; 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir void ScHeaderControl::SetMarking( sal_Bool /* bSet */ ) 1042*cdf0e10cSrcweir { 1043*cdf0e10cSrcweir } 1044*cdf0e10cSrcweir 1045*cdf0e10cSrcweir 1046*cdf0e10cSrcweir 1047