1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/dispatch.hxx>
21 #include <vcl/help.hxx>
22 #include <vcl/settings.hxx>
23 #include <tools/poly.hxx>
24 #include <svtools/colorcfg.hxx>
26 #include "scresid.hxx"
28 #include "tabvwsh.hxx"
29 #include "hdrcont.hxx"
31 #include "inputopt.hxx"
32 #include "gridmerg.hxx"
33 #include "document.hxx"
34 #include "markdata.hxx"
39 // (selection left/right must be first because the continuous lines
40 // are partly overwritten later)
42 #define SC_HDRPAINT_SEL_BOTTOM 4
43 #define SC_HDRPAINT_BOTTOM 5
44 #define SC_HDRPAINT_TEXT 6
45 #define SC_HDRPAINT_COUNT 7
47 ScHeaderControl::ScHeaderControl( vcl::Window
* pParent
, SelectionEngine
* pSelectionEngine
,
48 SCCOLROW nNewSize
, bool bNewVertical
) :
50 pSelEngine ( pSelectionEngine
),
51 bVertical ( bNewVertical
),
63 // --- RTL --- no default mirroring for this window, the spreadsheet itself
64 // is also not mirrored
65 // mirror the vertical window for correct border drawing
66 // table layout depends on sheet format, not UI setting, so the
67 // borders of the vertical window have to be handled manually, too.
70 aNormFont
= GetFont();
71 aNormFont
.SetTransparent( true ); //! WEIGHT_NORMAL hart setzen ???
72 aBoldFont
= aNormFont
;
73 aBoldFont
.SetWeight( WEIGHT_BOLD
);
78 Size aSize
= LogicToPixel( Size(
79 GetTextWidth(OUString("8888")),
81 aSize
.Width() += 4; // place for highlight border
83 SetSizePixel( aSize
);
85 nWidth
= nSmallWidth
= aSize
.Width();
86 nBigWidth
= LogicToPixel( Size( GetTextWidth(OUString("8888888")), 0 ) ).Width() + 5;
88 SetBackground(); // sonst Probleme auf OS/2 !?!?!
91 void ScHeaderControl::SetWidth( long nNew
)
93 OSL_ENSURE( bVertical
, "SetWidth works only on row headers" );
96 Size
aSize( nNew
, GetSizePixel().Height() );
97 SetSizePixel( aSize
);
105 ScHeaderControl::~ScHeaderControl()
109 void ScHeaderControl::DoPaint( SCCOLROW nStart
, SCCOLROW nEnd
)
111 bool bLayoutRTL
= IsLayoutRTL();
112 long nLayoutSign
= bLayoutRTL
? -1 : 1;
114 Rectangle
aRect( Point(0,0), GetOutputSizePixel() );
117 aRect
.Top() = GetScrPos( nStart
)-nLayoutSign
; // extra pixel for line at top of selection
118 aRect
.Bottom() = GetScrPos( nEnd
+1 )-nLayoutSign
;
122 aRect
.Left() = GetScrPos( nStart
)-nLayoutSign
; // extra pixel for line left of selection
123 aRect
.Right() = GetScrPos( nEnd
+1 )-nLayoutSign
;
128 void ScHeaderControl::SetMark( bool bNewSet
, SCCOLROW nNewStart
, SCCOLROW nNewEnd
)
130 bool bEnabled
= SC_MOD()->GetInputOptions().GetMarkHeader(); //! cachen?
134 bool bOldSet
= bMarkRange
;
135 SCCOLROW nOldStart
= nMarkStart
;
136 SCCOLROW nOldEnd
= nMarkEnd
;
137 PutInOrder( nNewStart
, nNewEnd
);
138 bMarkRange
= bNewSet
;
139 nMarkStart
= nNewStart
;
148 if ( nNewStart
== nOldStart
)
150 if ( nNewEnd
!= nOldEnd
)
151 DoPaint( std::min( nNewEnd
, nOldEnd
) + 1, std::max( nNewEnd
, nOldEnd
) );
153 else if ( nNewEnd
== nOldEnd
)
154 DoPaint( std::min( nNewStart
, nOldStart
), std::max( nNewStart
, nOldStart
) - 1 );
155 else if ( nNewStart
> nOldEnd
|| nNewEnd
< nOldStart
)
158 DoPaint( nOldStart
, nOldEnd
);
159 DoPaint( nNewStart
, nNewEnd
);
161 else // somehow overlapping... (it is not often)
162 DoPaint( std::min( nNewStart
, nOldStart
), std::max( nNewEnd
, nOldEnd
) );
165 DoPaint( nNewStart
, nNewEnd
); // completely new selection
168 DoPaint( nOldStart
, nOldEnd
); // cancel selection
171 long ScHeaderControl::GetScrPos( SCCOLROW nEntryNo
) const
175 long nMax
= ( bVertical
? GetOutputSizePixel().Height() : GetOutputSizePixel().Width() ) + 1;
176 if (nEntryNo
>= nSize
)
181 for (SCCOLROW i
=GetPos(); i
<nEntryNo
&& nScrPos
<nMax
; i
++)
183 sal_uInt16 nAdd
= GetEntrySize(i
);
188 SCCOLROW nHidden
= GetHiddenCount(i
);
196 nScrPos
= nMax
- nScrPos
- 2;
201 // draw a rectangle across the window's width/height, with the outer part in a lighter color
203 void ScHeaderControl::DrawShadedRect( long nStart
, long nEnd
, const Color
& rBaseColor
)
205 Color
aWhite( COL_WHITE
);
207 Color
aInner( rBaseColor
); // highlight color, unchanged
208 Color
aCenter( rBaseColor
);
209 aCenter
.Merge( aWhite
, 0xd0 ); // lighten up a bit
210 Color
aOuter( rBaseColor
);
211 aOuter
.Merge( aWhite
, 0xa0 ); // lighten up more
214 std::swap( aInner
, aOuter
); // just swap colors instead of positions
216 Size aWinSize
= GetSizePixel();
217 long nBarSize
= bVertical
? aWinSize
.Width() : aWinSize
.Height();
218 long nCenterPos
= (nBarSize
/ 2) - 1;
221 SetFillColor( aOuter
);
223 DrawRect( Rectangle( 0, nStart
, nCenterPos
-1, nEnd
) );
225 DrawRect( Rectangle( nStart
, 0, nEnd
, nCenterPos
-1 ) );
226 SetFillColor( aCenter
);
228 DrawRect( Rectangle( nCenterPos
, nStart
, nCenterPos
, nEnd
) );
230 DrawRect( Rectangle( nStart
, nCenterPos
, nEnd
, nCenterPos
) );
231 SetFillColor( aInner
);
233 DrawRect( Rectangle( nCenterPos
+1, nStart
, nBarSize
-1, nEnd
) );
235 DrawRect( Rectangle( nStart
, nCenterPos
+1, nEnd
, nBarSize
-1 ) );
238 void ScHeaderControl::Paint( vcl::RenderContext
& /*rRenderContext*/, const Rectangle
& rRect
)
240 // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren
241 // Linien zusammengefasst
243 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
244 bool bHighContrast
= rStyleSettings
.GetHighContrastMode();
245 bool bDark
= rStyleSettings
.GetFaceColor().IsDark();
246 // Use the same distinction for bDark as in Window::DrawSelectionBackground
248 Color aTextColor
= rStyleSettings
.GetButtonTextColor();
249 Color aSelTextColor
= rStyleSettings
.GetHighlightTextColor();
250 aNormFont
.SetColor( aTextColor
);
252 aBoldFont
.SetColor( aTextColor
);
254 aBoldFont
.SetColor( aSelTextColor
);
255 SetTextColor( ( bBoldSet
&& !bHighContrast
) ? aSelTextColor
: aTextColor
);
257 Color
aBlack( COL_BLACK
);
258 Color aSelLineColor
= rStyleSettings
.GetHighlightColor();
259 aSelLineColor
.Merge( aBlack
, 0xe0 ); // darken just a little bit
261 bool bLayoutRTL
= IsLayoutRTL();
262 long nLayoutSign
= bLayoutRTL
? -1 : 1;
263 bool bMirrored
= IsMirrored();
271 nBarSize
= (sal_uInt16
) GetSizePixel().Width();
273 nBarSize
= (sal_uInt16
) GetSizePixel().Height();
275 SCCOLROW nPos
= GetPos();
277 long nPStart
= bVertical
? rRect
.Top() : rRect
.Left();
278 long nPEnd
= bVertical
? rRect
.Bottom() : rRect
.Right();
280 long nTransStart
= nPEnd
+ 1;
283 long nInitScrPos
= 0;
286 long nTemp
= nPStart
; // swap nPStart / nPEnd
289 nTemp
= nTransStart
; // swap nTransStart / nTransEnd
290 nTransStart
= nTransEnd
;
292 if ( bVertical
) // start loops from the end
293 nInitScrPos
= GetSizePixel().Height() - 1;
295 nInitScrPos
= GetSizePixel().Width() - 1;
298 // aeussere Linien komplett durchzeichnen
299 // Zuerst Ende der letzten Zelle finden
301 long nLineEnd
= nInitScrPos
- nLayoutSign
;
303 for (SCCOLROW i
=nPos
; i
<nSize
; i
++)
305 sal_uInt16 nSizePix
= GetEntrySize( i
);
308 nLineEnd
+= nSizePix
* nLayoutSign
;
310 if ( bMarkRange
&& i
>= nMarkStart
&& i
<= nMarkEnd
)
312 long nLineStart
= nLineEnd
- ( nSizePix
- 1 ) * nLayoutSign
;
313 if ( nLineStart
* nLayoutSign
< nTransStart
* nLayoutSign
)
314 nTransStart
= nLineStart
;
315 if ( nLineEnd
* nLayoutSign
> nTransEnd
* nLayoutSign
)
316 nTransEnd
= nLineEnd
;
319 if ( nLineEnd
* nLayoutSign
> nPEnd
* nLayoutSign
)
327 SCCOLROW nHidden
= GetHiddenCount(i
);
333 // background is different for entry area and behind the entries
338 if ( nLineEnd
* nLayoutSign
>= nInitScrPos
* nLayoutSign
)
342 // high contrast: single-color background
343 SetFillColor( rStyleSettings
.GetFaceColor() );
345 aFillRect
= Rectangle( 0, nInitScrPos
, nBarSize
-1, nLineEnd
);
347 aFillRect
= Rectangle( nInitScrPos
, 0, nLineEnd
, nBarSize
-1 );
348 DrawRect( aFillRect
);
352 // normal: 3-part background
353 DrawShadedRect( nInitScrPos
, nLineEnd
, rStyleSettings
.GetFaceColor() );
357 if ( nLineEnd
* nLayoutSign
< nPEnd
* nLayoutSign
)
359 SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND
).nColor
);
361 aFillRect
= Rectangle( 0, nLineEnd
+nLayoutSign
, nBarSize
-1, nPEnd
);
363 aFillRect
= Rectangle( nLineEnd
+nLayoutSign
, 0, nPEnd
, nBarSize
-1 );
364 DrawRect( aFillRect
);
367 if ( nLineEnd
* nLayoutSign
>= nPStart
* nLayoutSign
)
369 if ( nTransEnd
* nLayoutSign
>= nTransStart
* nLayoutSign
)
375 // solid grey background for dark face color is drawn before lines
378 SetFillColor( COL_LIGHTGRAY
);
380 DrawRect( Rectangle( 0, nTransStart
, nBarSize
-1, nTransEnd
) );
382 DrawRect( Rectangle( nTransStart
, 0, nTransEnd
, nBarSize
-1 ) );
387 // background for selection
389 DrawShadedRect( nTransStart
, nTransEnd
, rStyleSettings
.GetHighlightColor() );
393 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
396 long nDarkPos
= bMirrored
? 0 : nBarSize
-1;
397 DrawLine( Point( nDarkPos
, nPStart
), Point( nDarkPos
, nLineEnd
) );
400 DrawLine( Point( nPStart
, nBarSize
-1 ), Point( nLineEnd
, nBarSize
-1 ) );
402 // line in different color for selection
403 if ( nTransEnd
* nLayoutSign
>= nTransStart
* nLayoutSign
&& !bHighContrast
)
405 SetLineColor( aSelLineColor
);
408 long nDarkPos
= bMirrored
? 0 : nBarSize
-1;
409 DrawLine( Point( nDarkPos
, nTransStart
), Point( nDarkPos
, nTransEnd
) );
412 DrawLine( Point( nTransStart
, nBarSize
-1 ), Point( nTransEnd
, nBarSize
-1 ) );
416 // loop through entries several times to avoid changing the line color too often
417 // and to allow merging of lines
419 ScGridMerger
aGrid( this, 1, 1 );
421 // start at SC_HDRPAINT_BOTTOM instead of 0 - selection doesn't get different
422 // borders, light border at top isn't used anymore
423 // use SC_HDRPAINT_SEL_BOTTOM for different color
425 for (sal_uInt16 nPass
= SC_HDRPAINT_SEL_BOTTOM
; nPass
< SC_HDRPAINT_COUNT
; nPass
++)
427 // set line color etc. before entry loop
430 case SC_HDRPAINT_SEL_BOTTOM
:
431 // same as non-selected for high contrast
432 SetLineColor( bHighContrast
? rStyleSettings
.GetDarkShadowColor() : aSelLineColor
);
434 case SC_HDRPAINT_BOTTOM
:
435 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
437 case SC_HDRPAINT_TEXT
:
438 // DrawSelectionBackground is used only for high contrast on light background
439 if ( nTransEnd
* nLayoutSign
>= nTransStart
* nLayoutSign
&& bHighContrast
&& !bDark
)
441 // Transparent selection background is drawn after lines, before text.
442 // Use DrawSelectionBackground to make sure there is a visible
443 // difference. The case of a dark face color, where DrawSelectionBackground
444 // would just paint over the lines, is handled separately (bDark).
445 // Otherwise, GetHighlightColor is used with 80% transparency.
446 // The window's background color (SetBackground) has to be the background
447 // of the cell area, for the contrast comparison in DrawSelectionBackground.
449 Rectangle aTransRect
;
451 aTransRect
= Rectangle( 0, nTransStart
, nBarSize
-1, nTransEnd
);
453 aTransRect
= Rectangle( nTransStart
, 0, nTransEnd
, nBarSize
-1 );
454 SetBackground( Color( rStyleSettings
.GetFaceColor() ) );
455 DrawSelectionBackground( aTransRect
, 0, true, false, false );
462 long nScrPos
=nInitScrPos
;
466 aScrPos
= Point( 0, nScrPos
);
468 aScrPos
= Point( nScrPos
, 0 );
470 SCCOLROW nEntryNo
= nCount
+ nPos
;
471 if ( nEntryNo
>= nSize
) // MAXCOL/MAXROW
472 nScrPos
= nPEnd
+ nLayoutSign
; // beyond nPEnd -> stop
475 sal_uInt16 nSizePix
= GetEntrySize( nEntryNo
);
479 SCCOLROW nHidden
= GetHiddenCount(nEntryNo
);
481 nCount
+= nHidden
- 1;
483 else if ((nScrPos
+nSizePix
*nLayoutSign
)*nLayoutSign
>= nPStart
*nLayoutSign
)
485 Point
aEndPos(aScrPos
);
487 aEndPos
= Point( aScrPos
.X()+nBarSize
-1, aScrPos
.Y()+(nSizePix
-1)*nLayoutSign
);
489 aEndPos
= Point( aScrPos
.X()+(nSizePix
-1)*nLayoutSign
, aScrPos
.Y()+nBarSize
-1 );
491 bool bMark
= bMarkRange
&& nEntryNo
>= nMarkStart
&& nEntryNo
<= nMarkEnd
;
492 bool bNextToMark
= bMarkRange
&& nEntryNo
+ 1 >= nMarkStart
&& nEntryNo
<= nMarkEnd
;
496 case SC_HDRPAINT_SEL_BOTTOM
:
497 case SC_HDRPAINT_BOTTOM
:
498 if ( nPass
== ( bNextToMark
? SC_HDRPAINT_SEL_BOTTOM
: SC_HDRPAINT_BOTTOM
) )
501 aGrid
.AddHorLine( aScrPos
.X(), aEndPos
.X(), aEndPos
.Y() );
503 aGrid
.AddVerLine( aEndPos
.X(), aScrPos
.Y(), aEndPos
.Y() );
505 // thick bottom for hidden rows
506 // (drawn directly, without aGrid)
507 if ( nEntryNo
+1 < nSize
)
508 if ( GetEntrySize(nEntryNo
+1)==0 )
511 DrawLine( Point(aScrPos
.X(),aEndPos
.Y()-nLayoutSign
),
512 Point(aEndPos
.X(),aEndPos
.Y()-nLayoutSign
) );
514 DrawLine( Point(aEndPos
.X()-nLayoutSign
,aScrPos
.Y()),
515 Point(aEndPos
.X()-nLayoutSign
,aEndPos
.Y()) );
520 case SC_HDRPAINT_TEXT
:
521 if ( nSizePix
> 1 ) // minimal check for small columns/rows
523 if ( bMark
!= bBoldSet
)
531 aString
= GetEntryText( nEntryNo
);
532 aTextSize
.Width() = GetTextWidth( aString
);
533 aTextSize
.Height() = GetTextHeight();
535 Point
aTxtPos(aScrPos
);
538 aTxtPos
.X() += (nBarSize
-aTextSize
.Width())/2;
539 aTxtPos
.Y() += (nSizePix
*nLayoutSign
-aTextSize
.Height())/2;
541 aTxtPos
.X() += 1; // dark border is left instead of right
545 aTxtPos
.X() += (nSizePix
*nLayoutSign
-aTextSize
.Width()+1)/2;
546 aTxtPos
.Y() += (nBarSize
-aTextSize
.Height())/2;
548 DrawText( aTxtPos
, aString
);
553 // bei Selektion der ganzen Zeile/Spalte:
554 // InvertRect( Rectangle( aScrPos, aEndPos ) );
556 nScrPos
+= nSizePix
* nLayoutSign
; // also if before the visible area
560 while ( nScrPos
* nLayoutSign
<= nPEnd
* nLayoutSign
);
566 SCCOLROW
ScHeaderControl::GetMousePos( const MouseEvent
& rMEvt
, bool& rBorder
) const
569 SCCOLROW nPos
= GetPos();
570 SCCOLROW nHitNo
= nPos
;
571 SCCOLROW nEntryNo
= 1 + nPos
;
573 long nMousePos
= bVertical
? rMEvt
.GetPosPixel().Y() : rMEvt
.GetPosPixel().X();
575 Size aSize
= GetOutputSizePixel();
576 long nWinSize
= bVertical
? aSize
.Height() : aSize
.Width();
578 bool bLayoutRTL
= IsLayoutRTL();
579 long nLayoutSign
= bLayoutRTL
? -1 : 1;
580 long nEndPos
= bLayoutRTL
? -1 : nWinSize
;
582 nScrPos
= GetScrPos( nPos
) - nLayoutSign
;
585 if (nEntryNo
> nSize
)
586 nScrPos
= nEndPos
+ nLayoutSign
;
588 nScrPos
+= GetEntrySize( nEntryNo
- 1 ) * nLayoutSign
; //! GetHiddenCount() ??
590 nDif
= nMousePos
- nScrPos
;
591 if (nDif
>= -2 && nDif
<= 2)
596 else if (nDif
* nLayoutSign
>= 0 && nEntryNo
< nSize
)
600 while ( nScrPos
* nLayoutSign
< nEndPos
* nLayoutSign
&& nDif
* nLayoutSign
> 0 );
606 bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos
) const
608 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>(SfxViewShell::Current());
612 ScViewData
& rViewData
= pViewSh
->GetViewData();
613 sal_uInt16 nTab
= rViewData
.GetTabNo();
614 ScDocument
* pDoc
= rViewData
.GetDocument();
615 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
616 bool bSelectAllowed
= true;
617 if ( pProtect
&& pProtect
->isProtected() )
619 // This sheet is protected. Check if a context menu is allowed on this cell.
620 bool bCellsProtected
= false;
624 SCROW nRPos
= static_cast<SCROW
>(nPos
);
625 bCellsProtected
= pDoc
->HasAttrib(0, nRPos
, nTab
, MAXCOL
, nRPos
, nTab
, HASATTR_PROTECTED
);
630 SCCOL nCPos
= static_cast<SCCOL
>(nPos
);
631 bCellsProtected
= pDoc
->HasAttrib(nCPos
, 0, nTab
, nCPos
, MAXROW
, nTab
, HASATTR_PROTECTED
);
634 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
635 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
638 bSelectAllowed
= bSelProtected
;
640 bSelectAllowed
= bSelUnprotected
;
642 return bSelectAllowed
;
645 void ScHeaderControl::MouseButtonDown( const MouseEvent
& rMEvt
)
654 SCCOLROW nHitNo
= GetMousePos( rMEvt
, bIsBorder
);
655 if (!IsSelectionAllowed(nHitNo
))
657 if ( ! rMEvt
.IsLeft() )
659 if ( bIsBorder
&& ResizeAllowed() )
662 sal_uInt16 nClicks
= rMEvt
.GetClicks();
663 if ( nClicks
&& nClicks
%2==0 )
665 SetEntrySize( nDragNo
, HDR_SIZE_OPTIMUM
);
666 SetPointer( Pointer( PointerStyle::Arrow
) );
671 nDragStart
= rMEvt
.GetPosPixel().Y();
673 nDragStart
= rMEvt
.GetPosPixel().X();
674 nDragPos
= nDragStart
;
676 DrawInvert( nDragPos
);
685 pSelEngine
->SetWindow( this );
687 Rectangle
aVis( aPoint
,GetOutputSizePixel() );
689 aVis
.Left() = LONG_MIN
, aVis
.Right() = LONG_MAX
;
691 aVis
.Top() = LONG_MIN
, aVis
.Bottom() = LONG_MAX
;
692 pSelEngine
->SetVisibleArea( aVis
);
694 SetMarking( true ); // must precede SelMouseButtonDown
695 pSelEngine
->SelMouseButtonDown( rMEvt
);
697 // In column/row headers a simple click already is a selection.
698 // -> Call SelMouseMove to ensure CreateAnchor is called (and DestroyAnchor
699 // if the next click is somewhere else with Control key).
700 pSelEngine
->SelMouseMove( rMEvt
);
702 if (IsMouseCaptured())
704 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
705 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
712 void ScHeaderControl::MouseButtonUp( const MouseEvent
& rMEvt
)
722 DrawInvert( nDragPos
);
726 long nScrPos
= GetScrPos( nDragNo
);
727 long nMousePos
= bVertical
? rMEvt
.GetPosPixel().Y() : rMEvt
.GetPosPixel().X();
728 bool bLayoutRTL
= IsLayoutRTL();
729 long nNewWidth
= bLayoutRTL
? ( nScrPos
- nMousePos
+ 1 )
730 : ( nMousePos
+ 2 - nScrPos
);
732 if ( nNewWidth
< 0 /* && !IsSelected(nDragNo) */ )
735 SCCOLROW nEnd
= nDragNo
;
736 while (nNewWidth
< 0)
742 nNewWidth
+= GetEntrySize( nDragNo
); //! GetHiddenCount() ???
747 HideEntries( nStart
, nEnd
);
752 SetEntrySize( nDragNo
, (sal_uInt16
) nNewWidth
);
757 pSelEngine
->SelMouseButtonUp( rMEvt
);
762 void ScHeaderControl::MouseMove( const MouseEvent
& rMEvt
)
766 SetPointer( Pointer( PointerStyle::Arrow
) );
772 long nNewPos
= bVertical
? rMEvt
.GetPosPixel().Y() : rMEvt
.GetPosPixel().X();
773 if ( nNewPos
!= nDragPos
)
775 DrawInvert( nDragPos
);
778 DrawInvert( nDragPos
);
780 if (nDragPos
<= nDragStart
-SC_DRAG_MIN
|| nDragPos
>= nDragStart
+SC_DRAG_MIN
)
787 (void)GetMousePos( rMEvt
, bIsBorder
);
789 if ( bIsBorder
&& rMEvt
.GetButtons()==0 && ResizeAllowed() )
790 SetPointer( Pointer( bVertical
? PointerStyle::VSizeBar
: PointerStyle::HSizeBar
) );
792 SetPointer( Pointer( PointerStyle::Arrow
) );
795 pSelEngine
->SelMouseMove( rMEvt
);
799 void ScHeaderControl::Tracking( const TrackingEvent
& rTEvt
)
801 // Distribute the tracking events to the various MouseEvents, because
802 // SelectionEngine does not know anything about Tracking
804 if ( rTEvt
.IsTrackingCanceled() )
806 else if ( rTEvt
.IsTrackingEnded() )
807 MouseButtonUp( rTEvt
.GetMouseEvent() );
809 MouseMove( rTEvt
.GetMouseEvent() );
812 void ScHeaderControl::Command( const CommandEvent
& rCEvt
)
814 CommandEventId nCmd
= rCEvt
.GetCommand();
815 if ( nCmd
== CommandEventId::ContextMenu
)
817 StopMarking(); // finish selection / dragging
819 // execute popup menu
821 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
,
822 SfxViewShell::Current() );
825 if ( rCEvt
.IsMouseEvent() )
827 // #i18735# select the column/row under the mouse pointer
828 ScViewData
& rViewData
= pViewSh
->GetViewData();
830 SelectWindow(); // also deselects drawing objects, stops draw text edit
831 if ( rViewData
.HasEditView( rViewData
.GetActivePart() ) )
832 SC_MOD()->InputEnterHandler(); // always end edit mode
834 MouseEvent
aMEvt( rCEvt
.GetMousePosPixel() );
836 SCCOLROW nPos
= GetMousePos( aMEvt
, bBorder
);
837 if (!IsSelectionAllowed(nPos
))
838 // Selecting this cell is not allowed, neither is context menu.
841 SCTAB nTab
= rViewData
.GetTabNo();
844 aNewRange
= ScRange( 0, sal::static_int_cast
<SCROW
>(nPos
), nTab
,
845 MAXCOL
, sal::static_int_cast
<SCROW
>(nPos
), nTab
);
847 aNewRange
= ScRange( sal::static_int_cast
<SCCOL
>(nPos
), 0, nTab
,
848 sal::static_int_cast
<SCCOL
>(nPos
), MAXROW
, nTab
);
850 // see if any part of the range is already selected
852 rViewData
.GetMarkData().FillRangeListWithMarks( &aRanges
, false );
853 bool bSelected
= aRanges
.Intersects(aNewRange
);
855 // select the range if no part of it was selected
857 pViewSh
->MarkRange( aNewRange
);
860 ScResId
aResId( bVertical
? RID_POPUP_ROWHEADER
: RID_POPUP_COLHEADER
);
861 pViewSh
->GetDispatcher()->ExecutePopup( aResId
);
864 else if ( nCmd
== CommandEventId::StartDrag
)
866 pSelEngine
->Command( rCEvt
);
870 void ScHeaderControl::StopMarking()
874 DrawInvert( nDragPos
);
881 // don't call pSelEngine->Reset, so selection across the parts of
882 // a split/frozen view is possible
887 void ScHeaderControl::ShowDragHelp()
889 if (Help::IsQuickHelpEnabled())
891 long nScrPos
= GetScrPos( nDragNo
);
892 bool bLayoutRTL
= IsLayoutRTL();
893 long nVal
= bLayoutRTL
? ( nScrPos
- nDragPos
+ 1 )
894 : ( nDragPos
+ 2 - nScrPos
);
896 OUString aHelpStr
= GetDragHelp( nVal
);
897 Point aPos
= OutputToScreenPixel( Point(0,0) );
898 Size aSize
= GetSizePixel();
900 Point aMousePos
= OutputToScreenPixel(GetPointerPosPixel());
903 QuickHelpFlags nAlign
;
907 aRect
.Left() = aMousePos
.X();
908 aRect
.Top() = aPos
.Y() - 4;
909 nAlign
= QuickHelpFlags::Bottom
|QuickHelpFlags::Center
;
914 aRect
.Left() = aPos
.X() + aSize
.Width() + 8;
915 aRect
.Top() = aMousePos
.Y() - 2;
916 nAlign
= QuickHelpFlags::Left
|QuickHelpFlags::Bottom
;
919 aRect
.Right() = aRect
.Left();
920 aRect
.Bottom() = aRect
.Top();
922 Help::ShowQuickHelp(this, aRect
, aHelpStr
, nAlign
);
926 void ScHeaderControl::RequestHelp( const HelpEvent
& rHEvt
)
928 // If the own QuickHelp is displayed, don't let RequestHelp remove it
930 bool bOwn
= bDragging
&& Help::IsQuickHelpEnabled();
932 Window::RequestHelp(rHEvt
);
935 // Dummys fuer virtuelle Methoden
937 SCCOLROW
ScHeaderControl::GetHiddenCount( SCCOLROW nEntryNo
) const
939 SCCOLROW nHidden
= 0;
940 while ( nEntryNo
< nSize
&& GetEntrySize( nEntryNo
) == 0 )
948 bool ScHeaderControl::IsLayoutRTL() const
953 bool ScHeaderControl::IsMirrored() const
958 bool ScHeaderControl::IsDisabled() const
963 bool ScHeaderControl::ResizeAllowed() const
968 void ScHeaderControl::SelectWindow()
972 void ScHeaderControl::DrawInvert( long /* nDragPos */ )
976 OUString
ScHeaderControl::GetDragHelp( long /* nVal */ )
978 return EMPTY_OUSTRING
;
981 void ScHeaderControl::SetMarking( bool /* bSet */ )
985 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */