update dev300-m57
[ooovba.git] / sc / source / ui / view / hdrcont.cxx
blob89e871c12ce183859a2506d405046e627cd9dffe
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: hdrcont.cxx,v $
10 * $Revision: 1.21 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include <sfx2/dispatch.hxx>
39 #include <vcl/help.hxx>
40 #include <tools/poly.hxx>
41 #include <svtools/colorcfg.hxx>
43 #include "scresid.hxx"
44 #include "sc.hrc"
45 #include "tabvwsh.hxx"
46 #include "hdrcont.hxx"
47 #include "scmod.hxx" // Optionen
48 #include "inputopt.hxx" // Optionen
49 #include "gridmerg.hxx"
51 // -----------------------------------------------------------------------
53 #define SC_DRAG_MIN 2
55 // passes in paint
56 // (selection left/right must be first because the continuous lines
57 // are partly overwritten later)
59 #define SC_HDRPAINT_SEL_RIGHT 0
60 #define SC_HDRPAINT_SEL_LEFT 1
61 #define SC_HDRPAINT_TOP 2
62 #define SC_HDRPAINT_SEL_TOP 3
63 #define SC_HDRPAINT_SEL_BOTTOM 4
64 #define SC_HDRPAINT_BOTTOM 5
65 #define SC_HDRPAINT_TEXT 6
66 #define SC_HDRPAINT_COUNT 7
68 //==================================================================
70 ScHeaderControl::ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine,
71 SCCOLROW nNewSize, USHORT nNewFlags ) :
72 Window ( pParent ),
73 pSelEngine ( pSelectionEngine ),
74 nFlags ( nNewFlags ),
75 bVertical ( (nNewFlags & HDR_VERTICAL) != 0 ),
76 nSize ( nNewSize ),
77 nMarkStart ( 0 ),
78 nMarkEnd ( 0 ),
79 bMarkRange ( FALSE ),
80 bDragging ( FALSE ),
81 bIgnoreMove ( FALSE )
83 // --- RTL --- no default mirroring for this window, the spreadsheet itself
84 // is also not mirrored
85 // #107811# mirror the vertical window for correct border drawing
86 // #106948# table layout depends on sheet format, not UI setting, so the
87 // borders of the vertical window have to be handled manually, too.
88 EnableRTL( FALSE );
90 aNormFont = GetFont();
91 aNormFont.SetTransparent( TRUE ); //! WEIGHT_NORMAL hart setzen ???
92 aBoldFont = aNormFont;
93 aBoldFont.SetWeight( WEIGHT_BOLD );
95 SetFont(aBoldFont);
96 bBoldSet = TRUE;
98 Size aSize = LogicToPixel( Size(
99 GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888")) ),
100 GetTextHeight() ) );
101 aSize.Width() += 4; // Platz fuer hervorgehobene Umrandung
102 aSize.Height() += 3;
103 SetSizePixel( aSize );
105 nWidth = nSmallWidth = aSize.Width();
106 nBigWidth = LogicToPixel( Size( GetTextWidth(
107 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888888")) ), 0 ) ).Width() + 5;
109 SetBackground(); // sonst Probleme auf OS/2 !?!?!
112 void ScHeaderControl::SetWidth( long nNew )
114 DBG_ASSERT( bVertical, "SetDigits nur fuer Zeilenkoepfe erlaubt" );
115 if ( nNew != nWidth )
117 Size aSize( nNew, GetSizePixel().Height() ); // Hoehe nicht aendern
118 SetSizePixel( aSize );
120 nWidth = nNew;
122 Invalidate(); // neu zentrieren
126 __EXPORT ScHeaderControl::~ScHeaderControl()
130 void ScHeaderControl::DoPaint( SCCOLROW nStart, SCCOLROW nEnd )
132 BOOL bLayoutRTL = IsLayoutRTL();
133 long nLayoutSign = bLayoutRTL ? -1 : 1;
135 Rectangle aRect( Point(0,0), GetOutputSizePixel() );
136 if ( bVertical )
138 aRect.Top() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line at top of selection
139 aRect.Bottom() = GetScrPos( nEnd+1 )-nLayoutSign;
141 else
143 aRect.Left() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line left of selection
144 aRect.Right() = GetScrPos( nEnd+1 )-nLayoutSign;
146 Invalidate(aRect);
149 void ScHeaderControl::SetMark( BOOL bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd )
151 BOOL bEnabled = SC_MOD()->GetInputOptions().GetMarkHeader(); //! cachen?
152 if (!bEnabled)
153 bNewSet = FALSE;
155 // Variablen setzen
157 BOOL bOldSet = bMarkRange;
158 SCCOLROW nOldStart = nMarkStart;
159 SCCOLROW nOldEnd = nMarkEnd;
160 PutInOrder( nNewStart, nNewEnd );
161 bMarkRange = bNewSet;
162 nMarkStart = nNewStart;
163 nMarkEnd = nNewEnd;
165 // Paint
167 if ( bNewSet )
169 if ( bOldSet )
171 if ( nNewStart == nOldStart )
173 if ( nNewEnd != nOldEnd )
174 DoPaint( Min( nNewEnd, nOldEnd ) + 1, Max( nNewEnd, nOldEnd ) );
175 // sonst nix
177 else if ( nNewEnd == nOldEnd )
178 DoPaint( Min( nNewStart, nOldStart ), Max( nNewStart, nOldStart ) - 1 );
179 else if ( nNewStart > nOldEnd || nNewEnd < nOldStart )
181 // zwei Bereiche...
182 DoPaint( nOldStart, nOldEnd );
183 DoPaint( nNewStart, nNewEnd );
185 else // irgendwie ueberlappend... (kommt eh nicht oft vor)
186 DoPaint( Min( nNewStart, nOldStart ), Max( nNewEnd, nOldEnd ) );
188 else
189 DoPaint( nNewStart, nNewEnd ); // komplett neu
191 else if ( bOldSet )
192 DoPaint( nOldStart, nOldEnd ); // komplett aufheben
194 // sonst war nix, is nix
197 long ScHeaderControl::GetScrPos( SCCOLROW nEntryNo )
199 long nScrPos;
201 long nMax = ( bVertical ? GetOutputSizePixel().Height() : GetOutputSizePixel().Width() ) + 1;
202 if (nEntryNo >= nSize)
203 nScrPos = nMax;
204 else
206 nScrPos = 0;
207 for (SCCOLROW i=GetPos(); i<nEntryNo && nScrPos<nMax; i++)
209 USHORT nAdd = GetEntrySize(i);
210 if (nAdd)
211 nScrPos += nAdd;
212 else
214 SCCOLROW nHidden = GetHiddenCount(i);
215 if (nHidden > 0)
216 i += nHidden - 1;
221 if ( IsLayoutRTL() )
222 nScrPos = nMax - nScrPos - 2;
224 return nScrPos;
227 // draw a rectangle across the window's width/height, with the outer part in a lighter color
229 void ScHeaderControl::DrawShadedRect( long nStart, long nEnd, const Color& rBaseColor )
231 Color aWhite( COL_WHITE );
233 Color aInner( rBaseColor ); // highlight color, unchanged
234 Color aCenter( rBaseColor );
235 aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit
236 Color aOuter( rBaseColor );
237 aOuter.Merge( aWhite, 0xa0 ); // lighten up more
239 if ( IsMirrored() )
240 std::swap( aInner, aOuter ); // just swap colors instead of positions
242 Size aWinSize = GetSizePixel();
243 long nBarSize = bVertical ? aWinSize.Width() : aWinSize.Height();
244 long nCenterPos = (nBarSize / 2) - 1;
246 SetLineColor();
247 SetFillColor( aOuter );
248 if (bVertical)
249 DrawRect( Rectangle( 0, nStart, nCenterPos-1, nEnd ) );
250 else
251 DrawRect( Rectangle( nStart, 0, nEnd, nCenterPos-1 ) );
252 SetFillColor( aCenter );
253 if (bVertical)
254 DrawRect( Rectangle( nCenterPos, nStart, nCenterPos, nEnd ) );
255 else
256 DrawRect( Rectangle( nStart, nCenterPos, nEnd, nCenterPos ) );
257 SetFillColor( aInner );
258 if (bVertical)
259 DrawRect( Rectangle( nCenterPos+1, nStart, nBarSize-1, nEnd ) );
260 else
261 DrawRect( Rectangle( nStart, nCenterPos+1, nEnd, nBarSize-1 ) );
265 // Paint
268 void __EXPORT ScHeaderControl::Paint( const Rectangle& rRect )
270 // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren
271 // Linien zusammengefasst
273 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
274 BOOL bHighContrast = rStyleSettings.GetHighContrastMode();
275 BOOL bDark = rStyleSettings.GetFaceColor().IsDark();
276 // Use the same distinction for bDark as in Window::DrawSelectionBackground
278 Color aTextColor = rStyleSettings.GetButtonTextColor();
279 Color aSelTextColor = rStyleSettings.GetHighlightTextColor();
280 aNormFont.SetColor( aTextColor );
281 if ( bHighContrast )
282 aBoldFont.SetColor( aTextColor );
283 else
284 aBoldFont.SetColor( aSelTextColor );
285 SetTextColor( ( bBoldSet && !bHighContrast ) ? aSelTextColor : aTextColor );
287 Color aBlack( COL_BLACK );
288 Color aSelLineColor = rStyleSettings.GetHighlightColor();
289 aSelLineColor.Merge( aBlack, 0xe0 ); // darken just a little bit
291 BOOL bLayoutRTL = IsLayoutRTL();
292 long nLayoutSign = bLayoutRTL ? -1 : 1;
293 BOOL bMirrored = IsMirrored();
295 // const FunctionSet* pFuncSet = pSelEngine->GetFunctionSet();
296 String aString;
297 USHORT nBarSize;
298 Point aScrPos;
299 Size aTextSize;
300 // Size aSize = GetOutputSizePixel();
302 if (bVertical)
303 nBarSize = (USHORT) GetSizePixel().Width();
304 else
305 nBarSize = (USHORT) GetSizePixel().Height();
307 SCCOLROW nPos = GetPos();
309 long nPStart = bVertical ? rRect.Top() : rRect.Left();
310 long nPEnd = bVertical ? rRect.Bottom() : rRect.Right();
312 long nTransStart = nPEnd + 1;
313 long nTransEnd = 0;
315 long nInitScrPos = 0;
316 if ( bLayoutRTL )
318 long nTemp = nPStart; // swap nPStart / nPEnd
319 nPStart = nPEnd;
320 nPEnd = nTemp;
321 nTemp = nTransStart; // swap nTransStart / nTransEnd
322 nTransStart = nTransEnd;
323 nTransEnd = nTemp;
324 if ( bVertical ) // start loops from the end
325 nInitScrPos = GetSizePixel().Height() - 1;
326 else
327 nInitScrPos = GetSizePixel().Width() - 1;
330 // aeussere Linien komplett durchzeichnen
331 // Zuerst Ende der letzten Zelle finden
333 // long nLineEnd = -1;
334 long nLineEnd = nInitScrPos - nLayoutSign;
336 for (SCCOLROW i=nPos; i<nSize; i++)
338 USHORT nSizePix = GetEntrySize( i );
339 if (nSizePix)
341 nLineEnd += nSizePix * nLayoutSign;
343 if ( bMarkRange && i >= nMarkStart && i <= nMarkEnd )
345 long nLineStart = nLineEnd - ( nSizePix - 1 ) * nLayoutSign;
346 if ( nLineStart * nLayoutSign < nTransStart * nLayoutSign )
347 nTransStart = nLineStart;
348 if ( nLineEnd * nLayoutSign > nTransEnd * nLayoutSign )
349 nTransEnd = nLineEnd;
352 if ( nLineEnd * nLayoutSign > nPEnd * nLayoutSign )
354 nLineEnd = nPEnd;
355 break;
358 else
360 SCCOLROW nHidden = GetHiddenCount(i);
361 if (nHidden > 0)
362 i += nHidden - 1;
366 // background is different for entry area and behind the entries
368 Rectangle aFillRect;
369 SetLineColor();
371 if ( nLineEnd * nLayoutSign >= nInitScrPos * nLayoutSign )
373 if ( bHighContrast )
375 // high contrast: single-color background
376 SetFillColor( rStyleSettings.GetFaceColor() );
377 if ( bVertical )
378 aFillRect = Rectangle( 0, nInitScrPos, nBarSize-1, nLineEnd );
379 else
380 aFillRect = Rectangle( nInitScrPos, 0, nLineEnd, nBarSize-1 );
381 DrawRect( aFillRect );
383 else
385 // normal: 3-part background
386 DrawShadedRect( nInitScrPos, nLineEnd, rStyleSettings.GetFaceColor() );
390 if ( nLineEnd * nLayoutSign < nPEnd * nLayoutSign )
392 SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND).nColor );
393 if ( bVertical )
394 aFillRect = Rectangle( 0, nLineEnd+nLayoutSign, nBarSize-1, nPEnd );
395 else
396 aFillRect = Rectangle( nLineEnd+nLayoutSign, 0, nPEnd, nBarSize-1 );
397 DrawRect( aFillRect );
400 if ( nLineEnd * nLayoutSign >= nPStart * nLayoutSign )
402 if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign )
404 if ( bHighContrast )
406 if ( bDark )
408 // solid grey background for dark face color is drawn before lines
410 SetLineColor();
411 SetFillColor( COL_LIGHTGRAY );
412 if (bVertical)
413 DrawRect( Rectangle( 0, nTransStart, nBarSize-1, nTransEnd ) );
414 else
415 DrawRect( Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 ) );
418 else
420 // background for selection
422 DrawShadedRect( nTransStart, nTransEnd, rStyleSettings.GetHighlightColor() );
426 #if 0
427 // 3D border is no longer used
428 SetLineColor( rStyleSettings.GetLightColor() );
429 if (bVertical)
430 DrawLine( Point( 0, nPStart ), Point( 0, nLineEnd ) );
431 else
432 DrawLine( Point( nPStart, 0 ), Point( nLineEnd, 0 ) );
433 #endif
435 SetLineColor( rStyleSettings.GetDarkShadowColor() );
436 if (bVertical)
438 long nDarkPos = bMirrored ? 0 : nBarSize-1;
439 DrawLine( Point( nDarkPos, nPStart ), Point( nDarkPos, nLineEnd ) );
441 else
442 DrawLine( Point( nPStart, nBarSize-1 ), Point( nLineEnd, nBarSize-1 ) );
444 // line in different color for selection
445 if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && !bHighContrast )
447 SetLineColor( aSelLineColor );
448 if (bVertical)
450 long nDarkPos = bMirrored ? 0 : nBarSize-1;
451 DrawLine( Point( nDarkPos, nTransStart ), Point( nDarkPos, nTransEnd ) );
453 else
454 DrawLine( Point( nTransStart, nBarSize-1 ), Point( nTransEnd, nBarSize-1 ) );
459 // loop through entries several times to avoid changing the line color too often
460 // and to allow merging of lines
463 ScGridMerger aGrid( this, 1, 1 );
465 // start at SC_HDRPAINT_BOTTOM instead of 0 - selection doesn't get different
466 // borders, light border at top isn't used anymore
467 // use SC_HDRPAINT_SEL_BOTTOM for different color
469 for (USHORT nPass = SC_HDRPAINT_SEL_BOTTOM; nPass < SC_HDRPAINT_COUNT; nPass++)
471 // set line color etc. before entry loop
472 switch ( nPass )
474 case SC_HDRPAINT_SEL_BOTTOM:
475 // same as non-selected for high contrast
476 SetLineColor( bHighContrast ? rStyleSettings.GetDarkShadowColor() : aSelLineColor );
477 break;
478 case SC_HDRPAINT_BOTTOM:
479 SetLineColor( rStyleSettings.GetDarkShadowColor() );
480 break;
481 case SC_HDRPAINT_TEXT:
482 // DrawSelectionBackground is used only for high contrast on light background
483 if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && bHighContrast && !bDark )
485 // Transparent selection background is drawn after lines, before text.
486 // #109814# Use DrawSelectionBackground to make sure there is a visible
487 // difference. The case of a dark face color, where DrawSelectionBackground
488 // would just paint over the lines, is handled separately (bDark).
489 // Otherwise, GetHighlightColor is used with 80% transparency.
490 // The window's background color (SetBackground) has to be the background
491 // of the cell area, for the contrast comparison in DrawSelectionBackground.
493 Rectangle aTransRect;
494 if (bVertical)
495 aTransRect = Rectangle( 0, nTransStart, nBarSize-1, nTransEnd );
496 else
497 aTransRect = Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 );
498 SetBackground( Color( rStyleSettings.GetFaceColor() ) );
499 DrawSelectionBackground( aTransRect, 0, TRUE, FALSE, FALSE );
500 SetBackground();
502 break;
505 SCCOLROW nCount=0;
506 long nScrPos=nInitScrPos;
509 if (bVertical)
510 aScrPos = Point( 0, nScrPos );
511 else
512 aScrPos = Point( nScrPos, 0 );
514 SCCOLROW nEntryNo = nCount + nPos;
515 if ( nEntryNo >= nSize ) // MAXCOL/MAXROW
516 nScrPos = nPEnd + nLayoutSign; // beyond nPEnd -> stop
517 else
519 USHORT nSizePix = GetEntrySize( nEntryNo );
521 if (nSizePix == 0)
523 SCCOLROW nHidden = GetHiddenCount(nEntryNo);
524 if (nHidden > 0)
525 nCount += nHidden - 1;
527 else if ((nScrPos+nSizePix*nLayoutSign)*nLayoutSign >= nPStart*nLayoutSign)
529 Point aEndPos(aScrPos);
530 if (bVertical)
531 aEndPos = Point( aScrPos.X()+nBarSize-1, aScrPos.Y()+(nSizePix-1)*nLayoutSign );
532 else
533 aEndPos = Point( aScrPos.X()+(nSizePix-1)*nLayoutSign, aScrPos.Y()+nBarSize-1 );
535 BOOL bMark = bMarkRange && nEntryNo >= nMarkStart && nEntryNo <= nMarkEnd;
536 BOOL bNextToMark = bMarkRange && nEntryNo + 1 >= nMarkStart && nEntryNo <= nMarkEnd;
538 switch ( nPass )
540 case SC_HDRPAINT_SEL_BOTTOM:
541 case SC_HDRPAINT_BOTTOM:
542 if ( nPass == ( bNextToMark ? SC_HDRPAINT_SEL_BOTTOM : SC_HDRPAINT_BOTTOM ) )
544 if (bVertical)
545 aGrid.AddHorLine( aScrPos.X(), aEndPos.X(), aEndPos.Y() );
546 else
547 aGrid.AddVerLine( aEndPos.X(), aScrPos.Y(), aEndPos.Y() );
549 // thick bottom for hidden rows
550 // (drawn directly, without aGrid)
551 if ( nEntryNo+1 < nSize )
552 if ( GetEntrySize(nEntryNo+1)==0 )
554 if (bVertical)
555 DrawLine( Point(aScrPos.X(),aEndPos.Y()-nLayoutSign),
556 Point(aEndPos.X(),aEndPos.Y()-nLayoutSign) );
557 else
558 DrawLine( Point(aEndPos.X()-nLayoutSign,aScrPos.Y()),
559 Point(aEndPos.X()-nLayoutSign,aEndPos.Y()) );
562 break;
564 case SC_HDRPAINT_TEXT:
565 if ( nSizePix > 1 ) // minimal check for small columns/rows
567 if ( bMark != bBoldSet )
569 if (bMark)
570 SetFont(aBoldFont);
571 else
572 SetFont(aNormFont);
573 bBoldSet = bMark;
575 aString = GetEntryText( nEntryNo );
576 aTextSize.Width() = GetTextWidth( aString );
577 aTextSize.Height() = GetTextHeight();
579 Point aTxtPos(aScrPos);
580 if (bVertical)
582 aTxtPos.X() += (nBarSize-aTextSize.Width())/2;
583 aTxtPos.Y() += (nSizePix*nLayoutSign-aTextSize.Height())/2;
584 if ( bMirrored )
585 aTxtPos.X() += 1; // dark border is left instead of right
587 else
589 aTxtPos.X() += (nSizePix*nLayoutSign-aTextSize.Width()+1)/2;
590 aTxtPos.Y() += (nBarSize-aTextSize.Height())/2;
592 DrawText( aTxtPos, aString );
594 break;
597 // bei Selektion der ganzen Zeile/Spalte:
598 // InvertRect( Rectangle( aScrPos, aEndPos ) );
600 nScrPos += nSizePix * nLayoutSign; // also if before the visible area
602 ++nCount;
604 while ( nScrPos * nLayoutSign <= nPEnd * nLayoutSign );
606 aGrid.Flush();
611 // Maus - Handling
614 SCCOLROW ScHeaderControl::GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder )
616 BOOL bFound=FALSE;
617 SCCOLROW nCount = 1;
618 SCCOLROW nPos = GetPos();
619 SCCOLROW nHitNo = nPos;
620 long nScrPos;
621 long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
622 long nDif;
623 Size aSize = GetOutputSizePixel();
624 long nWinSize = bVertical ? aSize.Height() : aSize.Width();
626 BOOL bLayoutRTL = IsLayoutRTL();
627 long nLayoutSign = bLayoutRTL ? -1 : 1;
628 long nEndPos = bLayoutRTL ? -1 : nWinSize;
630 nScrPos = GetScrPos( nPos ) - nLayoutSign;
633 SCCOLROW nEntryNo = nCount + nPos;
635 // nScrPos = GetScrPos( nEntryNo ) - 1;
637 if (nEntryNo > nSize)
638 nScrPos = nEndPos + nLayoutSign;
639 else
640 nScrPos += GetEntrySize( nEntryNo - 1 ) * nLayoutSign; //! GetHiddenCount() ??
642 nDif = nMousePos - nScrPos;
643 if (nDif >= -2 && nDif <= 2 && nCount > 0)
645 bFound=TRUE;
646 nHitNo=nEntryNo-1;
648 else if (nDif * nLayoutSign >= 0 && nEntryNo < nSize)
649 nHitNo = nEntryNo;
650 ++nCount;
652 while ( nScrPos * nLayoutSign < nEndPos * nLayoutSign && nDif * nLayoutSign > 0 );
654 rBorder = bFound;
655 return nHitNo;
658 void __EXPORT ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt )
660 if (IsDisabled())
661 return;
663 bIgnoreMove = FALSE;
664 SelectWindow();
666 BOOL bFound;
667 SCCOLROW nHitNo = GetMousePos( rMEvt, bFound );
669 if ( bFound && rMEvt.IsLeft() && ResizeAllowed() )
671 nDragNo = nHitNo;
672 USHORT nClicks = rMEvt.GetClicks();
673 if ( nClicks && nClicks%2==0 )
675 SetEntrySize( nDragNo, HDR_SIZE_OPTIMUM );
676 SetPointer( Pointer( POINTER_ARROW ) );
678 else
680 if (bVertical)
681 nDragStart = rMEvt.GetPosPixel().Y();
682 else
683 nDragStart = rMEvt.GetPosPixel().X();
684 nDragPos = nDragStart;
685 ShowDragHelp();
686 DrawInvert( nDragPos );
688 // CaptureMouse();
689 StartTracking();
690 bDragging = TRUE;
691 bDragMoved = FALSE;
694 else if (rMEvt.IsLeft())
696 pSelEngine->SetWindow( this );
697 Point aPoint;
698 Rectangle aVis( aPoint,GetOutputSizePixel() );
699 if (bVertical)
700 aVis.Left() = LONG_MIN, aVis.Right() = LONG_MAX;
701 else
702 aVis.Top() = LONG_MIN, aVis.Bottom() = LONG_MAX;
703 pSelEngine->SetVisibleArea( aVis );
705 SetMarking( TRUE ); // muss vor SelMouseButtonDown sein
706 pSelEngine->SelMouseButtonDown( rMEvt );
708 // #74215# In column/row headers a simple click already is a selection.
709 // -> Call SelMouseMove to ensure CreateAnchor is called (and DestroyAnchor
710 // if the next click is somewhere else with Control key).
711 pSelEngine->SelMouseMove( rMEvt );
713 if (IsMouseCaptured())
715 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
716 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
717 ReleaseMouse();
718 StartTracking();
723 void __EXPORT ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt )
725 if ( IsDisabled() )
726 return;
728 SetMarking( FALSE );
729 bIgnoreMove = FALSE;
730 // BOOL bFound;
731 // SCCOLROW nHitNo = GetMousePos( rMEvt, bFound );
733 if ( bDragging )
735 DrawInvert( nDragPos );
736 ReleaseMouse();
737 bDragging = FALSE;
739 long nScrPos = GetScrPos( nDragNo );
740 long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
741 BOOL bLayoutRTL = IsLayoutRTL();
742 long nNewWidth = bLayoutRTL ? ( nScrPos - nMousePos + 1 )
743 : ( nMousePos + 2 - nScrPos );
745 if ( nNewWidth < 0 /* && !IsSelected(nDragNo) */ )
747 SCCOLROW nStart = 0;
748 SCCOLROW nEnd = nDragNo;
749 while (nNewWidth < 0)
751 nStart = nDragNo;
752 if (nDragNo>0)
754 --nDragNo;
755 nNewWidth += GetEntrySize( nDragNo ); //! GetHiddenCount() ???
757 else
758 nNewWidth = 0;
760 HideEntries( nStart, nEnd );
762 else
764 if (nNewWidth<0) nNewWidth=0;
765 if (bDragMoved)
766 SetEntrySize( nDragNo, (USHORT) nNewWidth );
769 else
771 pSelEngine->SelMouseButtonUp( rMEvt );
772 ReleaseMouse();
776 void __EXPORT ScHeaderControl::MouseMove( const MouseEvent& rMEvt )
778 if ( IsDisabled() )
780 SetPointer( Pointer( POINTER_ARROW ) );
781 return;
784 BOOL bFound;
785 (void)GetMousePos( rMEvt, bFound );
787 if ( bDragging )
789 long nNewPos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
790 if ( nNewPos != nDragPos )
792 DrawInvert( nDragPos );
793 nDragPos = nNewPos;
794 ShowDragHelp();
795 DrawInvert( nDragPos );
797 if (nDragPos <= nDragStart-SC_DRAG_MIN || nDragPos >= nDragStart+SC_DRAG_MIN)
798 bDragMoved = TRUE;
801 else
803 if ( bFound && rMEvt.GetButtons()==0 && ResizeAllowed() )
804 SetPointer( Pointer( bVertical ? POINTER_VSIZEBAR : POINTER_HSIZEBAR ) );
805 else
806 SetPointer( Pointer( POINTER_ARROW ) );
808 if (!bIgnoreMove)
809 pSelEngine->SelMouseMove( rMEvt );
813 void ScHeaderControl::Tracking( const TrackingEvent& rTEvt )
815 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
816 // die verschiedenen MouseHandler verteilen...
818 if ( rTEvt.IsTrackingCanceled() )
819 StopMarking();
820 else if ( rTEvt.IsTrackingEnded() )
821 MouseButtonUp( rTEvt.GetMouseEvent() );
822 else
823 MouseMove( rTEvt.GetMouseEvent() );
826 void __EXPORT ScHeaderControl::Command( const CommandEvent& rCEvt )
828 USHORT nCmd = rCEvt.GetCommand();
829 if ( nCmd == COMMAND_CONTEXTMENU )
831 StopMarking(); // Selektion / Dragging beenden
833 // Popup ausfuehren
835 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell,
836 SfxViewShell::Current() );
837 if ( pViewSh )
839 if ( rCEvt.IsMouseEvent() )
841 // #i18735# select the column/row under the mouse pointer
842 ScViewData* pViewData = pViewSh->GetViewData();
844 SelectWindow(); // also deselects drawing objects, stops draw text edit
845 if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
846 SC_MOD()->InputEnterHandler(); // always end edit mode
848 MouseEvent aMEvt( rCEvt.GetMousePosPixel() );
849 BOOL bBorder;
850 SCCOLROW nPos = GetMousePos( aMEvt, bBorder );
851 USHORT nTab = pViewData->GetTabNo();
853 ScRange aNewRange;
854 if ( bVertical )
855 aNewRange = ScRange( 0, sal::static_int_cast<SCROW>(nPos), nTab,
856 MAXCOL, sal::static_int_cast<SCROW>(nPos), nTab );
857 else
858 aNewRange = ScRange( sal::static_int_cast<SCCOL>(nPos), 0, nTab,
859 sal::static_int_cast<SCCOL>(nPos), MAXROW, nTab );
861 // see if any part of the range is already selected
862 BOOL bSelected = FALSE;
863 ScRangeList aRanges;
864 pViewData->GetMarkData().FillRangeListWithMarks( &aRanges, FALSE );
865 ULONG nRangeCount = aRanges.Count();
866 for (ULONG i=0; i<nRangeCount && !bSelected; i++)
867 if ( aRanges.GetObject(i)->Intersects( aNewRange ) )
868 bSelected = TRUE;
870 // select the range if no part of it was selected
871 if ( !bSelected )
872 pViewSh->MarkRange( aNewRange );
875 ScResId aResId( bVertical ? RID_POPUP_ROWHEADER : RID_POPUP_COLHEADER );
876 pViewSh->GetDispatcher()->ExecutePopup( aResId );
879 else if ( nCmd == COMMAND_STARTDRAG )
881 pSelEngine->Command( rCEvt );
885 void ScHeaderControl::StopMarking()
887 if ( bDragging )
889 DrawInvert( nDragPos );
890 bDragging = FALSE;
893 SetMarking( FALSE );
894 bIgnoreMove = TRUE;
896 // #86260# don't call pSelEngine->Reset, so selection across the parts of
897 // a split/frozen view is possible
899 ReleaseMouse();
902 void ScHeaderControl::ShowDragHelp()
904 if (Help::IsQuickHelpEnabled())
906 long nScrPos = GetScrPos( nDragNo );
907 BOOL bLayoutRTL = IsLayoutRTL();
908 long nVal = bLayoutRTL ? ( nScrPos - nDragPos + 1 )
909 : ( nDragPos + 2 - nScrPos );
911 String aHelpStr = GetDragHelp( nVal );
912 Point aPos = OutputToScreenPixel( Point(0,0) );
913 Size aSize = GetSizePixel();
915 Point aMousePos = OutputToScreenPixel(GetPointerPosPixel());
917 Rectangle aRect;
918 USHORT nAlign;
919 if (!bVertical)
921 // oberhalb
922 aRect.Left() = aMousePos.X();
923 aRect.Top() = aPos.Y() - 4;
924 nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
926 else
928 // rechts oben
929 aRect.Left() = aPos.X() + aSize.Width() + 8;
930 aRect.Top() = aMousePos.Y() - 2;
931 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
934 aRect.Right() = aRect.Left();
935 aRect.Bottom() = aRect.Top();
937 Help::ShowQuickHelp(this, aRect, aHelpStr, nAlign);
941 void __EXPORT ScHeaderControl::RequestHelp( const HelpEvent& rHEvt )
943 // Wenn eigene QuickHelp angezeigt wird, nicht durch RequestHelp
944 // wieder wegnehmen lassen
946 BOOL bOwn = bDragging && Help::IsQuickHelpEnabled();
947 if (!bOwn)
948 Window::RequestHelp(rHEvt);
951 // -----------------------------------------------------------------------
952 // Dummys fuer virtuelle Methoden
953 // -----------------------------------------------------------------------
955 SCCOLROW ScHeaderControl::GetHiddenCount( SCCOLROW nEntryNo )
957 SCCOLROW nHidden = 0;
958 while ( nEntryNo < nSize && GetEntrySize( nEntryNo ) == 0 )
960 ++nEntryNo;
961 ++nHidden;
963 return nHidden;
966 BOOL ScHeaderControl::IsLayoutRTL()
968 return FALSE;
971 BOOL ScHeaderControl::IsMirrored()
973 return FALSE;
976 BOOL ScHeaderControl::IsDisabled()
978 return FALSE;
981 BOOL ScHeaderControl::ResizeAllowed()
983 return TRUE;
986 void ScHeaderControl::SelectWindow()
990 void ScHeaderControl::DrawInvert( long /* nDragPos */ )
994 String ScHeaderControl::GetDragHelp( long /* nVal */ )
996 return EMPTY_STRING;
999 void ScHeaderControl::SetMarking( BOOL /* bSet */ )