1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: hdrcont.cxx,v $
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"
45 #include "tabvwsh.hxx"
46 #include "hdrcont.hxx"
47 #include "scmod.hxx" // Optionen
48 #include "inputopt.hxx" // Optionen
49 #include "gridmerg.hxx"
50 #include "document.hxx"
52 // -----------------------------------------------------------------------
57 // (selection left/right must be first because the continuous lines
58 // are partly overwritten later)
60 #define SC_HDRPAINT_SEL_RIGHT 0
61 #define SC_HDRPAINT_SEL_LEFT 1
62 #define SC_HDRPAINT_TOP 2
63 #define SC_HDRPAINT_SEL_TOP 3
64 #define SC_HDRPAINT_SEL_BOTTOM 4
65 #define SC_HDRPAINT_BOTTOM 5
66 #define SC_HDRPAINT_TEXT 6
67 #define SC_HDRPAINT_COUNT 7
69 //==================================================================
71 ScHeaderControl::ScHeaderControl( Window
* pParent
, SelectionEngine
* pSelectionEngine
,
72 SCCOLROW nNewSize
, USHORT nNewFlags
) :
74 pSelEngine ( pSelectionEngine
),
76 bVertical ( (nNewFlags
& HDR_VERTICAL
) != 0 ),
84 // --- RTL --- no default mirroring for this window, the spreadsheet itself
85 // is also not mirrored
86 // #107811# mirror the vertical window for correct border drawing
87 // #106948# table layout depends on sheet format, not UI setting, so the
88 // borders of the vertical window have to be handled manually, too.
91 aNormFont
= GetFont();
92 aNormFont
.SetTransparent( TRUE
); //! WEIGHT_NORMAL hart setzen ???
93 aBoldFont
= aNormFont
;
94 aBoldFont
.SetWeight( WEIGHT_BOLD
);
99 Size aSize
= LogicToPixel( Size(
100 GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888")) ),
102 aSize
.Width() += 4; // Platz fuer hervorgehobene Umrandung
104 SetSizePixel( aSize
);
106 nWidth
= nSmallWidth
= aSize
.Width();
107 nBigWidth
= LogicToPixel( Size( GetTextWidth(
108 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888888")) ), 0 ) ).Width() + 5;
110 SetBackground(); // sonst Probleme auf OS/2 !?!?!
113 void ScHeaderControl::SetWidth( long nNew
)
115 DBG_ASSERT( bVertical
, "SetDigits nur fuer Zeilenkoepfe erlaubt" );
116 if ( nNew
!= nWidth
)
118 Size
aSize( nNew
, GetSizePixel().Height() ); // Hoehe nicht aendern
119 SetSizePixel( aSize
);
123 Invalidate(); // neu zentrieren
127 __EXPORT
ScHeaderControl::~ScHeaderControl()
131 void ScHeaderControl::DoPaint( SCCOLROW nStart
, SCCOLROW nEnd
)
133 BOOL bLayoutRTL
= IsLayoutRTL();
134 long nLayoutSign
= bLayoutRTL
? -1 : 1;
136 Rectangle
aRect( Point(0,0), GetOutputSizePixel() );
139 aRect
.Top() = GetScrPos( nStart
)-nLayoutSign
; // extra pixel for line at top of selection
140 aRect
.Bottom() = GetScrPos( nEnd
+1 )-nLayoutSign
;
144 aRect
.Left() = GetScrPos( nStart
)-nLayoutSign
; // extra pixel for line left of selection
145 aRect
.Right() = GetScrPos( nEnd
+1 )-nLayoutSign
;
150 void ScHeaderControl::SetMark( BOOL bNewSet
, SCCOLROW nNewStart
, SCCOLROW nNewEnd
)
152 BOOL bEnabled
= SC_MOD()->GetInputOptions().GetMarkHeader(); //! cachen?
158 BOOL bOldSet
= bMarkRange
;
159 SCCOLROW nOldStart
= nMarkStart
;
160 SCCOLROW nOldEnd
= nMarkEnd
;
161 PutInOrder( nNewStart
, nNewEnd
);
162 bMarkRange
= bNewSet
;
163 nMarkStart
= nNewStart
;
172 if ( nNewStart
== nOldStart
)
174 if ( nNewEnd
!= nOldEnd
)
175 DoPaint( Min( nNewEnd
, nOldEnd
) + 1, Max( nNewEnd
, nOldEnd
) );
178 else if ( nNewEnd
== nOldEnd
)
179 DoPaint( Min( nNewStart
, nOldStart
), Max( nNewStart
, nOldStart
) - 1 );
180 else if ( nNewStart
> nOldEnd
|| nNewEnd
< nOldStart
)
183 DoPaint( nOldStart
, nOldEnd
);
184 DoPaint( nNewStart
, nNewEnd
);
186 else // irgendwie ueberlappend... (kommt eh nicht oft vor)
187 DoPaint( Min( nNewStart
, nOldStart
), Max( nNewEnd
, nOldEnd
) );
190 DoPaint( nNewStart
, nNewEnd
); // komplett neu
193 DoPaint( nOldStart
, nOldEnd
); // komplett aufheben
195 // sonst war nix, is nix
198 long ScHeaderControl::GetScrPos( SCCOLROW nEntryNo
)
202 long nMax
= ( bVertical
? GetOutputSizePixel().Height() : GetOutputSizePixel().Width() ) + 1;
203 if (nEntryNo
>= nSize
)
208 for (SCCOLROW i
=GetPos(); i
<nEntryNo
&& nScrPos
<nMax
; i
++)
210 USHORT nAdd
= GetEntrySize(i
);
215 SCCOLROW nHidden
= GetHiddenCount(i
);
223 nScrPos
= nMax
- nScrPos
- 2;
228 // draw a rectangle across the window's width/height, with the outer part in a lighter color
230 void ScHeaderControl::DrawShadedRect( long nStart
, long nEnd
, const Color
& rBaseColor
)
232 Color
aWhite( COL_WHITE
);
234 Color
aInner( rBaseColor
); // highlight color, unchanged
235 Color
aCenter( rBaseColor
);
236 aCenter
.Merge( aWhite
, 0xd0 ); // lighten up a bit
237 Color
aOuter( rBaseColor
);
238 aOuter
.Merge( aWhite
, 0xa0 ); // lighten up more
241 std::swap( aInner
, aOuter
); // just swap colors instead of positions
243 Size aWinSize
= GetSizePixel();
244 long nBarSize
= bVertical
? aWinSize
.Width() : aWinSize
.Height();
245 long nCenterPos
= (nBarSize
/ 2) - 1;
248 SetFillColor( aOuter
);
250 DrawRect( Rectangle( 0, nStart
, nCenterPos
-1, nEnd
) );
252 DrawRect( Rectangle( nStart
, 0, nEnd
, nCenterPos
-1 ) );
253 SetFillColor( aCenter
);
255 DrawRect( Rectangle( nCenterPos
, nStart
, nCenterPos
, nEnd
) );
257 DrawRect( Rectangle( nStart
, nCenterPos
, nEnd
, nCenterPos
) );
258 SetFillColor( aInner
);
260 DrawRect( Rectangle( nCenterPos
+1, nStart
, nBarSize
-1, nEnd
) );
262 DrawRect( Rectangle( nStart
, nCenterPos
+1, nEnd
, nBarSize
-1 ) );
269 void __EXPORT
ScHeaderControl::Paint( const Rectangle
& rRect
)
271 // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren
272 // Linien zusammengefasst
274 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
275 BOOL bHighContrast
= rStyleSettings
.GetHighContrastMode();
276 BOOL bDark
= rStyleSettings
.GetFaceColor().IsDark();
277 // Use the same distinction for bDark as in Window::DrawSelectionBackground
279 Color aTextColor
= rStyleSettings
.GetButtonTextColor();
280 Color aSelTextColor
= rStyleSettings
.GetHighlightTextColor();
281 aNormFont
.SetColor( aTextColor
);
283 aBoldFont
.SetColor( aTextColor
);
285 aBoldFont
.SetColor( aSelTextColor
);
286 SetTextColor( ( bBoldSet
&& !bHighContrast
) ? aSelTextColor
: aTextColor
);
288 Color
aBlack( COL_BLACK
);
289 Color aSelLineColor
= rStyleSettings
.GetHighlightColor();
290 aSelLineColor
.Merge( aBlack
, 0xe0 ); // darken just a little bit
292 BOOL bLayoutRTL
= IsLayoutRTL();
293 long nLayoutSign
= bLayoutRTL
? -1 : 1;
294 BOOL bMirrored
= IsMirrored();
296 // const FunctionSet* pFuncSet = pSelEngine->GetFunctionSet();
301 // Size aSize = GetOutputSizePixel();
304 nBarSize
= (USHORT
) GetSizePixel().Width();
306 nBarSize
= (USHORT
) GetSizePixel().Height();
308 SCCOLROW nPos
= GetPos();
310 long nPStart
= bVertical
? rRect
.Top() : rRect
.Left();
311 long nPEnd
= bVertical
? rRect
.Bottom() : rRect
.Right();
313 long nTransStart
= nPEnd
+ 1;
316 long nInitScrPos
= 0;
319 long nTemp
= nPStart
; // swap nPStart / nPEnd
322 nTemp
= nTransStart
; // swap nTransStart / nTransEnd
323 nTransStart
= nTransEnd
;
325 if ( bVertical
) // start loops from the end
326 nInitScrPos
= GetSizePixel().Height() - 1;
328 nInitScrPos
= GetSizePixel().Width() - 1;
331 // aeussere Linien komplett durchzeichnen
332 // Zuerst Ende der letzten Zelle finden
334 // long nLineEnd = -1;
335 long nLineEnd
= nInitScrPos
- nLayoutSign
;
337 for (SCCOLROW i
=nPos
; i
<nSize
; i
++)
339 USHORT nSizePix
= GetEntrySize( i
);
342 nLineEnd
+= nSizePix
* nLayoutSign
;
344 if ( bMarkRange
&& i
>= nMarkStart
&& i
<= nMarkEnd
)
346 long nLineStart
= nLineEnd
- ( nSizePix
- 1 ) * nLayoutSign
;
347 if ( nLineStart
* nLayoutSign
< nTransStart
* nLayoutSign
)
348 nTransStart
= nLineStart
;
349 if ( nLineEnd
* nLayoutSign
> nTransEnd
* nLayoutSign
)
350 nTransEnd
= nLineEnd
;
353 if ( nLineEnd
* nLayoutSign
> nPEnd
* nLayoutSign
)
361 SCCOLROW nHidden
= GetHiddenCount(i
);
367 // background is different for entry area and behind the entries
372 if ( nLineEnd
* nLayoutSign
>= nInitScrPos
* nLayoutSign
)
376 // high contrast: single-color background
377 SetFillColor( rStyleSettings
.GetFaceColor() );
379 aFillRect
= Rectangle( 0, nInitScrPos
, nBarSize
-1, nLineEnd
);
381 aFillRect
= Rectangle( nInitScrPos
, 0, nLineEnd
, nBarSize
-1 );
382 DrawRect( aFillRect
);
386 // normal: 3-part background
387 DrawShadedRect( nInitScrPos
, nLineEnd
, rStyleSettings
.GetFaceColor() );
391 if ( nLineEnd
* nLayoutSign
< nPEnd
* nLayoutSign
)
393 SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND
).nColor
);
395 aFillRect
= Rectangle( 0, nLineEnd
+nLayoutSign
, nBarSize
-1, nPEnd
);
397 aFillRect
= Rectangle( nLineEnd
+nLayoutSign
, 0, nPEnd
, nBarSize
-1 );
398 DrawRect( aFillRect
);
401 if ( nLineEnd
* nLayoutSign
>= nPStart
* nLayoutSign
)
403 if ( nTransEnd
* nLayoutSign
>= nTransStart
* nLayoutSign
)
409 // solid grey background for dark face color is drawn before lines
412 SetFillColor( COL_LIGHTGRAY
);
414 DrawRect( Rectangle( 0, nTransStart
, nBarSize
-1, nTransEnd
) );
416 DrawRect( Rectangle( nTransStart
, 0, nTransEnd
, nBarSize
-1 ) );
421 // background for selection
423 DrawShadedRect( nTransStart
, nTransEnd
, rStyleSettings
.GetHighlightColor() );
428 // 3D border is no longer used
429 SetLineColor( rStyleSettings
.GetLightColor() );
431 DrawLine( Point( 0, nPStart
), Point( 0, nLineEnd
) );
433 DrawLine( Point( nPStart
, 0 ), Point( nLineEnd
, 0 ) );
436 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
439 long nDarkPos
= bMirrored
? 0 : nBarSize
-1;
440 DrawLine( Point( nDarkPos
, nPStart
), Point( nDarkPos
, nLineEnd
) );
443 DrawLine( Point( nPStart
, nBarSize
-1 ), Point( nLineEnd
, nBarSize
-1 ) );
445 // line in different color for selection
446 if ( nTransEnd
* nLayoutSign
>= nTransStart
* nLayoutSign
&& !bHighContrast
)
448 SetLineColor( aSelLineColor
);
451 long nDarkPos
= bMirrored
? 0 : nBarSize
-1;
452 DrawLine( Point( nDarkPos
, nTransStart
), Point( nDarkPos
, nTransEnd
) );
455 DrawLine( Point( nTransStart
, nBarSize
-1 ), Point( nTransEnd
, nBarSize
-1 ) );
460 // loop through entries several times to avoid changing the line color too often
461 // and to allow merging of lines
464 ScGridMerger
aGrid( this, 1, 1 );
466 // start at SC_HDRPAINT_BOTTOM instead of 0 - selection doesn't get different
467 // borders, light border at top isn't used anymore
468 // use SC_HDRPAINT_SEL_BOTTOM for different color
470 for (USHORT nPass
= SC_HDRPAINT_SEL_BOTTOM
; nPass
< SC_HDRPAINT_COUNT
; nPass
++)
472 // set line color etc. before entry loop
475 case SC_HDRPAINT_SEL_BOTTOM
:
476 // same as non-selected for high contrast
477 SetLineColor( bHighContrast
? rStyleSettings
.GetDarkShadowColor() : aSelLineColor
);
479 case SC_HDRPAINT_BOTTOM
:
480 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
482 case SC_HDRPAINT_TEXT
:
483 // DrawSelectionBackground is used only for high contrast on light background
484 if ( nTransEnd
* nLayoutSign
>= nTransStart
* nLayoutSign
&& bHighContrast
&& !bDark
)
486 // Transparent selection background is drawn after lines, before text.
487 // #109814# Use DrawSelectionBackground to make sure there is a visible
488 // difference. The case of a dark face color, where DrawSelectionBackground
489 // would just paint over the lines, is handled separately (bDark).
490 // Otherwise, GetHighlightColor is used with 80% transparency.
491 // The window's background color (SetBackground) has to be the background
492 // of the cell area, for the contrast comparison in DrawSelectionBackground.
494 Rectangle aTransRect
;
496 aTransRect
= Rectangle( 0, nTransStart
, nBarSize
-1, nTransEnd
);
498 aTransRect
= Rectangle( nTransStart
, 0, nTransEnd
, nBarSize
-1 );
499 SetBackground( Color( rStyleSettings
.GetFaceColor() ) );
500 DrawSelectionBackground( aTransRect
, 0, TRUE
, FALSE
, FALSE
);
507 long nScrPos
=nInitScrPos
;
511 aScrPos
= Point( 0, nScrPos
);
513 aScrPos
= Point( nScrPos
, 0 );
515 SCCOLROW nEntryNo
= nCount
+ nPos
;
516 if ( nEntryNo
>= nSize
) // MAXCOL/MAXROW
517 nScrPos
= nPEnd
+ nLayoutSign
; // beyond nPEnd -> stop
520 USHORT nSizePix
= GetEntrySize( nEntryNo
);
524 SCCOLROW nHidden
= GetHiddenCount(nEntryNo
);
526 nCount
+= nHidden
- 1;
528 else if ((nScrPos
+nSizePix
*nLayoutSign
)*nLayoutSign
>= nPStart
*nLayoutSign
)
530 Point
aEndPos(aScrPos
);
532 aEndPos
= Point( aScrPos
.X()+nBarSize
-1, aScrPos
.Y()+(nSizePix
-1)*nLayoutSign
);
534 aEndPos
= Point( aScrPos
.X()+(nSizePix
-1)*nLayoutSign
, aScrPos
.Y()+nBarSize
-1 );
536 BOOL bMark
= bMarkRange
&& nEntryNo
>= nMarkStart
&& nEntryNo
<= nMarkEnd
;
537 BOOL bNextToMark
= bMarkRange
&& nEntryNo
+ 1 >= nMarkStart
&& nEntryNo
<= nMarkEnd
;
541 case SC_HDRPAINT_SEL_BOTTOM
:
542 case SC_HDRPAINT_BOTTOM
:
543 if ( nPass
== ( bNextToMark
? SC_HDRPAINT_SEL_BOTTOM
: SC_HDRPAINT_BOTTOM
) )
546 aGrid
.AddHorLine( aScrPos
.X(), aEndPos
.X(), aEndPos
.Y() );
548 aGrid
.AddVerLine( aEndPos
.X(), aScrPos
.Y(), aEndPos
.Y() );
550 // thick bottom for hidden rows
551 // (drawn directly, without aGrid)
552 if ( nEntryNo
+1 < nSize
)
553 if ( GetEntrySize(nEntryNo
+1)==0 )
556 DrawLine( Point(aScrPos
.X(),aEndPos
.Y()-nLayoutSign
),
557 Point(aEndPos
.X(),aEndPos
.Y()-nLayoutSign
) );
559 DrawLine( Point(aEndPos
.X()-nLayoutSign
,aScrPos
.Y()),
560 Point(aEndPos
.X()-nLayoutSign
,aEndPos
.Y()) );
565 case SC_HDRPAINT_TEXT
:
566 if ( nSizePix
> 1 ) // minimal check for small columns/rows
568 if ( bMark
!= bBoldSet
)
576 aString
= GetEntryText( nEntryNo
);
577 aTextSize
.Width() = GetTextWidth( aString
);
578 aTextSize
.Height() = GetTextHeight();
580 Point
aTxtPos(aScrPos
);
583 aTxtPos
.X() += (nBarSize
-aTextSize
.Width())/2;
584 aTxtPos
.Y() += (nSizePix
*nLayoutSign
-aTextSize
.Height())/2;
586 aTxtPos
.X() += 1; // dark border is left instead of right
590 aTxtPos
.X() += (nSizePix
*nLayoutSign
-aTextSize
.Width()+1)/2;
591 aTxtPos
.Y() += (nBarSize
-aTextSize
.Height())/2;
593 DrawText( aTxtPos
, aString
);
598 // bei Selektion der ganzen Zeile/Spalte:
599 // InvertRect( Rectangle( aScrPos, aEndPos ) );
601 nScrPos
+= nSizePix
* nLayoutSign
; // also if before the visible area
605 while ( nScrPos
* nLayoutSign
<= nPEnd
* nLayoutSign
);
615 SCCOLROW
ScHeaderControl::GetMousePos( const MouseEvent
& rMEvt
, BOOL
& rBorder
)
619 SCCOLROW nPos
= GetPos();
620 SCCOLROW nHitNo
= nPos
;
622 long nMousePos
= bVertical
? rMEvt
.GetPosPixel().Y() : rMEvt
.GetPosPixel().X();
624 Size aSize
= GetOutputSizePixel();
625 long nWinSize
= bVertical
? aSize
.Height() : aSize
.Width();
627 BOOL bLayoutRTL
= IsLayoutRTL();
628 long nLayoutSign
= bLayoutRTL
? -1 : 1;
629 long nEndPos
= bLayoutRTL
? -1 : nWinSize
;
631 nScrPos
= GetScrPos( nPos
) - nLayoutSign
;
634 SCCOLROW nEntryNo
= nCount
+ nPos
;
636 // nScrPos = GetScrPos( nEntryNo ) - 1;
638 if (nEntryNo
> nSize
)
639 nScrPos
= nEndPos
+ nLayoutSign
;
641 nScrPos
+= GetEntrySize( nEntryNo
- 1 ) * nLayoutSign
; //! GetHiddenCount() ??
643 nDif
= nMousePos
- nScrPos
;
644 if (nDif
>= -2 && nDif
<= 2 && nCount
> 0)
649 else if (nDif
* nLayoutSign
>= 0 && nEntryNo
< nSize
)
653 while ( nScrPos
* nLayoutSign
< nEndPos
* nLayoutSign
&& nDif
* nLayoutSign
> 0 );
659 bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos
) const
661 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>(SfxViewShell::Current());
665 ScViewData
* pViewData
= pViewSh
->GetViewData();
666 USHORT nTab
= pViewData
->GetTabNo();
667 ScDocument
* pDoc
= pViewData
->GetDocument();
668 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
669 bool bSelectAllowed
= true;
670 if ( pProtect
&& pProtect
->isProtected() )
672 // This sheet is protected. Check if a context menu is allowed on this cell.
673 bool bCellsProtected
= false;
676 bCellsProtected
= pDoc
->HasAttrib(0, nPos
, nTab
, MAXCOL
, nPos
, nTab
, HASATTR_PROTECTED
);
679 bCellsProtected
= pDoc
->HasAttrib(nPos
, 0, nTab
, nPos
, MAXROW
, nTab
, HASATTR_PROTECTED
);
681 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
682 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
685 bSelectAllowed
= bSelProtected
;
687 bSelectAllowed
= bSelUnprotected
;
689 return bSelectAllowed
;
692 void __EXPORT
ScHeaderControl::MouseButtonDown( const MouseEvent
& rMEvt
)
701 SCCOLROW nHitNo
= GetMousePos( rMEvt
, bFound
);
702 if (!IsSelectionAllowed(nHitNo
))
705 if ( bFound
&& rMEvt
.IsLeft() && ResizeAllowed() )
708 USHORT nClicks
= rMEvt
.GetClicks();
709 if ( nClicks
&& nClicks
%2==0 )
711 SetEntrySize( nDragNo
, HDR_SIZE_OPTIMUM
);
712 SetPointer( Pointer( POINTER_ARROW
) );
717 nDragStart
= rMEvt
.GetPosPixel().Y();
719 nDragStart
= rMEvt
.GetPosPixel().X();
720 nDragPos
= nDragStart
;
722 DrawInvert( nDragPos
);
730 else if (rMEvt
.IsLeft())
732 pSelEngine
->SetWindow( this );
734 Rectangle
aVis( aPoint
,GetOutputSizePixel() );
736 aVis
.Left() = LONG_MIN
, aVis
.Right() = LONG_MAX
;
738 aVis
.Top() = LONG_MIN
, aVis
.Bottom() = LONG_MAX
;
739 pSelEngine
->SetVisibleArea( aVis
);
741 SetMarking( TRUE
); // muss vor SelMouseButtonDown sein
742 pSelEngine
->SelMouseButtonDown( rMEvt
);
744 // #74215# In column/row headers a simple click already is a selection.
745 // -> Call SelMouseMove to ensure CreateAnchor is called (and DestroyAnchor
746 // if the next click is somewhere else with Control key).
747 pSelEngine
->SelMouseMove( rMEvt
);
749 if (IsMouseCaptured())
751 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
752 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
759 void __EXPORT
ScHeaderControl::MouseButtonUp( const MouseEvent
& rMEvt
)
767 // SCCOLROW nHitNo = GetMousePos( rMEvt, bFound );
771 DrawInvert( nDragPos
);
775 long nScrPos
= GetScrPos( nDragNo
);
776 long nMousePos
= bVertical
? rMEvt
.GetPosPixel().Y() : rMEvt
.GetPosPixel().X();
777 BOOL bLayoutRTL
= IsLayoutRTL();
778 long nNewWidth
= bLayoutRTL
? ( nScrPos
- nMousePos
+ 1 )
779 : ( nMousePos
+ 2 - nScrPos
);
781 if ( nNewWidth
< 0 /* && !IsSelected(nDragNo) */ )
784 SCCOLROW nEnd
= nDragNo
;
785 while (nNewWidth
< 0)
791 nNewWidth
+= GetEntrySize( nDragNo
); //! GetHiddenCount() ???
796 HideEntries( nStart
, nEnd
);
800 if (nNewWidth
<0) nNewWidth
=0;
802 SetEntrySize( nDragNo
, (USHORT
) nNewWidth
);
807 pSelEngine
->SelMouseButtonUp( rMEvt
);
812 void __EXPORT
ScHeaderControl::MouseMove( const MouseEvent
& rMEvt
)
816 SetPointer( Pointer( POINTER_ARROW
) );
821 (void)GetMousePos( rMEvt
, bFound
);
825 long nNewPos
= bVertical
? rMEvt
.GetPosPixel().Y() : rMEvt
.GetPosPixel().X();
826 if ( nNewPos
!= nDragPos
)
828 DrawInvert( nDragPos
);
831 DrawInvert( nDragPos
);
833 if (nDragPos
<= nDragStart
-SC_DRAG_MIN
|| nDragPos
>= nDragStart
+SC_DRAG_MIN
)
839 if ( bFound
&& rMEvt
.GetButtons()==0 && ResizeAllowed() )
840 SetPointer( Pointer( bVertical
? POINTER_VSIZEBAR
: POINTER_HSIZEBAR
) );
842 SetPointer( Pointer( POINTER_ARROW
) );
845 pSelEngine
->SelMouseMove( rMEvt
);
849 void ScHeaderControl::Tracking( const TrackingEvent
& rTEvt
)
851 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
852 // die verschiedenen MouseHandler verteilen...
854 if ( rTEvt
.IsTrackingCanceled() )
856 else if ( rTEvt
.IsTrackingEnded() )
857 MouseButtonUp( rTEvt
.GetMouseEvent() );
859 MouseMove( rTEvt
.GetMouseEvent() );
862 void __EXPORT
ScHeaderControl::Command( const CommandEvent
& rCEvt
)
864 USHORT nCmd
= rCEvt
.GetCommand();
865 if ( nCmd
== COMMAND_CONTEXTMENU
)
867 StopMarking(); // Selektion / Dragging beenden
871 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
,
872 SfxViewShell::Current() );
875 if ( rCEvt
.IsMouseEvent() )
877 // #i18735# select the column/row under the mouse pointer
878 ScViewData
* pViewData
= pViewSh
->GetViewData();
880 SelectWindow(); // also deselects drawing objects, stops draw text edit
881 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
882 SC_MOD()->InputEnterHandler(); // always end edit mode
884 MouseEvent
aMEvt( rCEvt
.GetMousePosPixel() );
886 SCCOLROW nPos
= GetMousePos( aMEvt
, bBorder
);
887 if (!IsSelectionAllowed(nPos
))
888 // Selecting this cell is not allowed, neither is context menu.
891 SCTAB nTab
= pViewData
->GetTabNo();
894 aNewRange
= ScRange( 0, sal::static_int_cast
<SCROW
>(nPos
), nTab
,
895 MAXCOL
, sal::static_int_cast
<SCROW
>(nPos
), nTab
);
897 aNewRange
= ScRange( sal::static_int_cast
<SCCOL
>(nPos
), 0, nTab
,
898 sal::static_int_cast
<SCCOL
>(nPos
), MAXROW
, nTab
);
900 // see if any part of the range is already selected
901 BOOL bSelected
= FALSE
;
903 pViewData
->GetMarkData().FillRangeListWithMarks( &aRanges
, FALSE
);
904 ULONG nRangeCount
= aRanges
.Count();
905 for (ULONG i
=0; i
<nRangeCount
&& !bSelected
; i
++)
906 if ( aRanges
.GetObject(i
)->Intersects( aNewRange
) )
909 // select the range if no part of it was selected
911 pViewSh
->MarkRange( aNewRange
);
914 ScResId
aResId( bVertical
? RID_POPUP_ROWHEADER
: RID_POPUP_COLHEADER
);
915 pViewSh
->GetDispatcher()->ExecutePopup( aResId
);
918 else if ( nCmd
== COMMAND_STARTDRAG
)
920 pSelEngine
->Command( rCEvt
);
924 void ScHeaderControl::StopMarking()
928 DrawInvert( nDragPos
);
935 // #86260# don't call pSelEngine->Reset, so selection across the parts of
936 // a split/frozen view is possible
941 void ScHeaderControl::ShowDragHelp()
943 if (Help::IsQuickHelpEnabled())
945 long nScrPos
= GetScrPos( nDragNo
);
946 BOOL bLayoutRTL
= IsLayoutRTL();
947 long nVal
= bLayoutRTL
? ( nScrPos
- nDragPos
+ 1 )
948 : ( nDragPos
+ 2 - nScrPos
);
950 String aHelpStr
= GetDragHelp( nVal
);
951 Point aPos
= OutputToScreenPixel( Point(0,0) );
952 Size aSize
= GetSizePixel();
954 Point aMousePos
= OutputToScreenPixel(GetPointerPosPixel());
961 aRect
.Left() = aMousePos
.X();
962 aRect
.Top() = aPos
.Y() - 4;
963 nAlign
= QUICKHELP_BOTTOM
|QUICKHELP_CENTER
;
968 aRect
.Left() = aPos
.X() + aSize
.Width() + 8;
969 aRect
.Top() = aMousePos
.Y() - 2;
970 nAlign
= QUICKHELP_LEFT
|QUICKHELP_BOTTOM
;
973 aRect
.Right() = aRect
.Left();
974 aRect
.Bottom() = aRect
.Top();
976 Help::ShowQuickHelp(this, aRect
, aHelpStr
, nAlign
);
980 void __EXPORT
ScHeaderControl::RequestHelp( const HelpEvent
& rHEvt
)
982 // Wenn eigene QuickHelp angezeigt wird, nicht durch RequestHelp
983 // wieder wegnehmen lassen
985 BOOL bOwn
= bDragging
&& Help::IsQuickHelpEnabled();
987 Window::RequestHelp(rHEvt
);
990 // -----------------------------------------------------------------------
991 // Dummys fuer virtuelle Methoden
992 // -----------------------------------------------------------------------
994 SCCOLROW
ScHeaderControl::GetHiddenCount( SCCOLROW nEntryNo
)
996 SCCOLROW nHidden
= 0;
997 while ( nEntryNo
< nSize
&& GetEntrySize( nEntryNo
) == 0 )
1005 BOOL
ScHeaderControl::IsLayoutRTL()
1010 BOOL
ScHeaderControl::IsMirrored()
1015 BOOL
ScHeaderControl::IsDisabled()
1020 BOOL
ScHeaderControl::ResizeAllowed()
1025 void ScHeaderControl::SelectWindow()
1029 void ScHeaderControl::DrawInvert( long /* nDragPos */ )
1033 String
ScHeaderControl::GetDragHelp( long /* nVal */ )
1035 return EMPTY_STRING
;
1038 void ScHeaderControl::SetMarking( BOOL
/* bSet */ )