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