xref: /aoo42x/main/sc/source/ui/view/gridwin4.cxx (revision 51b45b88)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 // INCLUDE ---------------------------------------------------------------
30 
31 #include "scitems.hxx"
32 #include <editeng/eeitem.hxx>
33 
34 
35 #include <svtools/colorcfg.hxx>
36 #include <editeng/colritem.hxx>
37 #include <editeng/editview.hxx>
38 #include <editeng/fhgtitem.hxx>
39 #include <editeng/scripttypeitem.hxx>
40 #include <sfx2/bindings.hxx>
41 #include <sfx2/printer.hxx>
42 
43 #include <svx/svdview.hxx>
44 #include "tabvwsh.hxx"
45 
46 #include "gridwin.hxx"
47 #include "viewdata.hxx"
48 #include "output.hxx"
49 #include "document.hxx"
50 #include "attrib.hxx"
51 #include "patattr.hxx"			// InvertSimple
52 #include "dbcolect.hxx"
53 #include "docoptio.hxx"
54 #include "notemark.hxx"
55 #include "dbfunc.hxx"			// oder GetPageBreakData an die ViewData
56 #include "scmod.hxx"
57 #include "inputhdl.hxx"
58 #include "rfindlst.hxx"
59 #include "hiranges.hxx"
60 #include "pagedata.hxx"
61 #include "docpool.hxx"
62 #include "globstr.hrc"
63 #include "docsh.hxx"			// oder GetSfxInPlaceObject
64 #include "cbutton.hxx"
65 #include "invmerge.hxx"
66 #include "editutil.hxx"
67 #include "inputopt.hxx"
68 #include "fillinfo.hxx"
69 #include "dpcontrol.hxx"
70 #include "queryparam.hxx"
71 #include "sc.hrc"
72 #include <vcl/virdev.hxx>
73 
74 // #i74769#
75 #include <svx/sdrpaintwindow.hxx>
76 
77 //#include "tabvwsh.hxx"			//! Test !!!!
78 
79 //------------------------------------------------------------------------
80 
lcl_LimitRect(Rectangle & rRect,const Rectangle & rVisible)81 void lcl_LimitRect( Rectangle& rRect, const Rectangle& rVisible )
82 {
83 	if ( rRect.Top()    < rVisible.Top()-1 )    rRect.Top()    = rVisible.Top()-1;
84 //	if ( rRect.Left()   < rVisible.Left()-1 )   rRect.Left()   = rVisible.Left()-1;
85 	if ( rRect.Bottom() > rVisible.Bottom()+1 ) rRect.Bottom() = rVisible.Bottom()+1;
86 //	if ( rRect.Right()  > rVisible.Right()+1 )  rRect.Right()  = rVisible.Right()+1;
87 
88 	// #51122# auch wenn das inner-Rectangle nicht sichtbar ist, muss evtl.
89 	// die Titelzeile gezeichnet werden, darum kein Rueckgabewert mehr.
90 	// Wenn's weit daneben liegt, wird lcl_DrawOneFrame erst gar nicht gerufen.
91 }
92 
lcl_DrawOneFrame(OutputDevice * pDev,const Rectangle & rInnerPixel,const String & rTitle,const Color & rColor,sal_Bool bTextBelow,double nPPTX,double nPPTY,const Fraction & rZoomY,ScDocument * pDoc,ScViewData * pButtonViewData,sal_Bool bLayoutRTL)93 void lcl_DrawOneFrame( OutputDevice* pDev, const Rectangle& rInnerPixel,
94 						const String& rTitle, const Color& rColor, sal_Bool bTextBelow,
95 						double nPPTX, double nPPTY, const Fraction& rZoomY,
96 						ScDocument* pDoc, ScViewData* pButtonViewData, sal_Bool bLayoutRTL )
97 {
98 	//	pButtonViewData wird nur benutzt, um die Button-Groesse zu setzen,
99 	//	darf ansonsten NULL sein!
100 
101 	Rectangle aInner = rInnerPixel;
102 	if ( bLayoutRTL )
103 	{
104 		aInner.Left() = rInnerPixel.Right();
105 		aInner.Right() = rInnerPixel.Left();
106 	}
107 
108 	Rectangle aVisible( Point(0,0), pDev->GetOutputSizePixel() );
109 	lcl_LimitRect( aInner, aVisible );
110 
111 	Rectangle aOuter = aInner;
112 	long nHor = (long) ( SC_SCENARIO_HSPACE * nPPTX );
113 	long nVer = (long) ( SC_SCENARIO_VSPACE * nPPTY );
114 	aOuter.Left()	-= nHor;
115 	aOuter.Right()	+= nHor;
116 	aOuter.Top()	-= nVer;
117 	aOuter.Bottom()	+= nVer;
118 
119 	//	use ScPatternAttr::GetFont only for font size
120 	Font aAttrFont;
121 	((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
122 									GetFont(aAttrFont,SC_AUTOCOL_BLACK,pDev,&rZoomY);
123 
124 	//	everything else from application font
125 	Font aAppFont = pDev->GetSettings().GetStyleSettings().GetAppFont();
126 	aAppFont.SetSize( aAttrFont.GetSize() );
127 
128 	aAppFont.SetAlign( ALIGN_TOP );
129 	pDev->SetFont( aAppFont );
130 
131 	Size aTextSize( pDev->GetTextWidth( rTitle ), pDev->GetTextHeight() );
132 
133 	if ( bTextBelow )
134 		aOuter.Bottom() += aTextSize.Height();
135 	else
136 		aOuter.Top()    -= aTextSize.Height();
137 
138 	pDev->SetLineColor();
139 	pDev->SetFillColor( rColor );
140 	//	links, oben, rechts, unten
141 	pDev->DrawRect( Rectangle( aOuter.Left(),  aOuter.Top(),    aInner.Left(),  aOuter.Bottom() ) );
142 	pDev->DrawRect( Rectangle( aOuter.Left(),  aOuter.Top(),    aOuter.Right(), aInner.Top()    ) );
143 	pDev->DrawRect( Rectangle( aInner.Right(), aOuter.Top(),    aOuter.Right(), aOuter.Bottom() ) );
144 	pDev->DrawRect( Rectangle( aOuter.Left(),  aInner.Bottom(), aOuter.Right(), aOuter.Bottom() ) );
145 
146 	long nButtonY = bTextBelow ? aInner.Bottom() : aOuter.Top();
147 
148 	ScDDComboBoxButton aComboButton((Window*)pDev);
149 	aComboButton.SetOptSizePixel();
150 	long nBWidth  = ( aComboButton.GetSizePixel().Width() * rZoomY.GetNumerator() )
151 						/ rZoomY.GetDenominator();
152 	long nBHeight = nVer + aTextSize.Height() + 1;
153 	Size aButSize( nBWidth, nBHeight );
154     long nButtonPos = bLayoutRTL ? aOuter.Left() : aOuter.Right()-nBWidth+1;
155     aComboButton.Draw( Point(nButtonPos, nButtonY), aButSize, sal_False );
156 	if (pButtonViewData)
157 		pButtonViewData->SetScenButSize( aButSize );
158 
159 	long nTextStart = bLayoutRTL ? aInner.Right() - aTextSize.Width() + 1 : aInner.Left();
160 
161 	sal_Bool bWasClip = sal_False;
162 	Region aOldClip;
163 	sal_Bool bClip = ( aTextSize.Width() > aOuter.Right() - nBWidth - aInner.Left() );
164 	if ( bClip )
165 	{
166 		if (pDev->IsClipRegion())
167 		{
168 			bWasClip = sal_True;
169 			aOldClip = pDev->GetActiveClipRegion();
170 		}
171 		long nClipStartX = bLayoutRTL ? aOuter.Left() + nBWidth : aInner.Left();
172 		long nClipEndX = bLayoutRTL ? aInner.Right() : aOuter.Right() - nBWidth;
173 		pDev->SetClipRegion( Rectangle( nClipStartX, nButtonY + nVer/2,
174 								nClipEndX, nButtonY + nVer/2 + aTextSize.Height() ) );
175 	}
176 
177 	pDev->DrawText( Point( nTextStart, nButtonY + nVer/2 ), rTitle );
178 
179 	if ( bClip )
180 	{
181 		if ( bWasClip )
182 			pDev->SetClipRegion(aOldClip);
183 		else
184 			pDev->SetClipRegion();
185 	}
186 
187 	pDev->SetFillColor();
188 	pDev->SetLineColor( COL_BLACK );
189 	pDev->DrawRect( aInner );
190 	pDev->DrawRect( aOuter );
191 }
192 
lcl_DrawScenarioFrames(OutputDevice * pDev,ScViewData * pViewData,ScSplitPos eWhich,SCCOL nX1,SCROW nY1,SCCOL nX2,SCROW nY2)193 void lcl_DrawScenarioFrames( OutputDevice* pDev, ScViewData* pViewData, ScSplitPos eWhich,
194 							SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
195 {
196 	ScDocument* pDoc = pViewData->GetDocument();
197 	SCTAB nTab = pViewData->GetTabNo();
198 	SCTAB nTabCount = pDoc->GetTableCount();
199 	if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
200 	{
201 		if ( nX1 > 0 ) --nX1;
202 		if ( nY1>=2 ) nY1 -= 2;				// Hack: Titelzeile beruehrt zwei Zellen
203 		else if ( nY1 > 0 ) --nY1;
204 		if ( nX2 < MAXCOL ) ++nX2;
205 		if ( nY2 < MAXROW-1 ) nY2 += 2;		// Hack: Titelzeile beruehrt zwei Zellen
206 		else if ( nY2 < MAXROW ) ++nY2;
207 		ScRange aViewRange( nX1,nY1,nTab, nX2,nY2,nTab );
208 
209 		//!	Ranges an der Table cachen!!!!
210 
211 		ScMarkData aMarks;
212 		for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
213 			pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
214 		ScRangeListRef xRanges = new ScRangeList;
215 		aMarks.FillRangeListWithMarks( xRanges, sal_False );
216 
217 		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
218 		long nLayoutSign = bLayoutRTL ? -1 : 1;
219 
220 		sal_uInt16 nRangeCount = (sal_uInt16)xRanges->Count();
221 		for (sal_uInt16 j=0; j<nRangeCount; j++)
222 		{
223 			ScRange aRange = *xRanges->GetObject(j);
224 			//	Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
225 			//	dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
226 			pDoc->ExtendTotalMerge( aRange );
227 
228 			//!	-> Repaint beim Zusammenfassen erweitern !!!
229 
230 			if ( aRange.Intersects( aViewRange ) )			//! Platz fuer Text/Button?
231 			{
232 				Point aStartPos = pViewData->GetScrPos(
233 									aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True );
234 				Point aEndPos = pViewData->GetScrPos(
235 									aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich, sal_True );
236 				//	on the grid:
237 				aStartPos.X() -= nLayoutSign;
238 				aStartPos.Y() -= 1;
239 				aEndPos.X() -= nLayoutSign;
240 				aEndPos.Y() -= 1;
241 
242 				sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
243 
244 				String aCurrent;
245 				Color aColor( COL_LIGHTGRAY );
246 				for (SCTAB nAct=nTab+1; nAct<nTabCount && pDoc->IsScenario(nAct); nAct++)
247 					if ( pDoc->IsActiveScenario(nAct) && pDoc->HasScenarioRange(nAct,aRange) )
248 					{
249 						String aDummyComment;
250 						sal_uInt16 nDummyFlags;
251 						pDoc->GetName( nAct, aCurrent );
252 						pDoc->GetScenarioData( nAct, aDummyComment, aColor, nDummyFlags );
253 					}
254 
255 				if (!aCurrent.Len())
256 					aCurrent = ScGlobal::GetRscString( STR_EMPTYDATA );
257 
258 				//!	eigener Text "(keins)" statt "(leer)" ???
259 
260 				lcl_DrawOneFrame( pDev, Rectangle( aStartPos, aEndPos ),
261 									aCurrent, aColor, bTextBelow,
262 									pViewData->GetPPTX(), pViewData->GetPPTY(), pViewData->GetZoomY(),
263 									pDoc, pViewData, bLayoutRTL );
264 			}
265 		}
266 	}
267 }
268 
269 //------------------------------------------------------------------------
270 
lcl_DrawHighlight(ScOutputData & rOutputData,ScViewData * pViewData,ScHighlightRanges & rHighlightRanges)271 void lcl_DrawHighlight( ScOutputData& rOutputData, ScViewData* pViewData,
272 						ScHighlightRanges& rHighlightRanges )
273 {
274 	SCTAB nTab = pViewData->GetTabNo();
275 	sal_uLong nCount = rHighlightRanges.Count();
276 	for (sal_uLong i=0; i<nCount; i++)
277 	{
278 		ScHighlightEntry* pEntry = rHighlightRanges.GetObject( i );
279 		if (pEntry)
280 		{
281 			ScRange aRange = pEntry->aRef;
282 			if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
283 			{
284 				rOutputData.DrawRefMark(
285 									aRange.aStart.Col(), aRange.aStart.Row(),
286 									aRange.aEnd.Col(), aRange.aEnd.Row(),
287 									pEntry->aColor, sal_False );
288 			}
289 		}
290 	}
291 }
292 
293 //------------------------------------------------------------------------
294 
DoInvertRect(const Rectangle & rPixel)295 void ScGridWindow::DoInvertRect( const Rectangle& rPixel )
296 {
297 //	Invert( PixelToLogic(rPixel) );
298 
299 	if ( rPixel == aInvertRect )
300 		aInvertRect = Rectangle();		// aufheben
301 	else
302 	{
303 		DBG_ASSERT( aInvertRect.IsEmpty(), "DoInvertRect nicht paarig" );
304 
305 		aInvertRect = rPixel;			// neues Rechteck merken
306 	}
307 
308     UpdateHeaderOverlay();      // uses aInvertRect
309 }
310 
311 //------------------------------------------------------------------------
312 
PrePaint()313 void __EXPORT ScGridWindow::PrePaint()
314 {
315 	// forward PrePaint to DrawingLayer
316 	ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
317 
318 	if(pTabViewShell)
319 	{
320 		SdrView* pDrawView = pTabViewShell->GetSdrView();
321 
322 		if(pDrawView)
323 		{
324             pDrawView->PrePaint();
325         }
326     }
327 }
328 
329 //------------------------------------------------------------------------
330 
Paint(const Rectangle & rRect)331 void __EXPORT ScGridWindow::Paint( const Rectangle& rRect )
332 {
333     //TODO/LATER: how to get environment? Do we need that?!
334     /*
335 	ScDocShell* pDocSh = pViewData->GetDocShell();
336 	SvInPlaceEnvironment* pEnv = pDocSh->GetIPEnv();
337 	if (pEnv && pEnv->GetRectsChangedLockCount())
338 	{
339 		Invalidate(rRect);
340 		return;
341     }*/
342 
343 	ScDocument* pDoc = pViewData->GetDocument();
344 	if ( pDoc->IsInInterpreter() )
345 	{
346 		//	via Reschedule, interpretierende Zellen nicht nochmal anstossen
347 		//	hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe
348 		//	(Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt.
349 
350 		if ( bNeedsRepaint )
351 		{
352 			//!	Rechtecke zusammenfassen?
353 			aRepaintPixel = Rectangle();			// mehrfach -> alles painten
354 		}
355 		else
356 		{
357 			bNeedsRepaint = sal_True;
358 			aRepaintPixel = LogicToPixel(rRect);	// nur betroffenen Bereich
359 		}
360 		return;
361 	}
362 
363     // #i117893# If GetSizePixel needs to call the resize handler, the resulting nested Paint call
364     // (possibly for a larger rectangle) has to be allowed. Call GetSizePixel before setting bIsInPaint.
365     GetSizePixel();
366 
367 	if (bIsInPaint)
368 		return;
369 
370 	bIsInPaint = sal_True;
371 
372 	Rectangle aPixRect = LogicToPixel( rRect );
373 
374 	SCCOL nX1 = pViewData->GetPosX(eHWhich);
375 	SCROW nY1 = pViewData->GetPosY(eVWhich);
376 
377 	SCTAB nTab = pViewData->GetTabNo();
378 
379 	double nPPTX = pViewData->GetPPTX();
380 	double nPPTY = pViewData->GetPPTY();
381 
382 	Rectangle aMirroredPixel = aPixRect;
383 	if ( pDoc->IsLayoutRTL( nTab ) )
384 	{
385 		//	mirror and swap
386 		long nWidth = GetSizePixel().Width();
387 		aMirroredPixel.Left()  = nWidth - 1 - aPixRect.Right();
388 		aMirroredPixel.Right() = nWidth - 1 - aPixRect.Left();
389 	}
390 
391 	long nScrX = ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
392 	while ( nScrX <= aMirroredPixel.Left() && nX1 < MAXCOL )
393 	{
394 		++nX1;
395 		nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
396 	}
397 	SCCOL nX2 = nX1;
398 	while ( nScrX <= aMirroredPixel.Right() && nX2 < MAXCOL )
399 	{
400 		++nX2;
401 		nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX2, nTab ), nPPTX );
402 	}
403 
404 	long nScrY = 0;
405     ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, MAXROW, nPPTY, pDoc, nTab);
406 	SCROW nY2 = nY1;
407     if (nScrY <= aPixRect.Bottom() && nY2 < MAXROW)
408     {
409         ++nY2;
410         ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, MAXROW, nPPTY, pDoc, nTab);
411     }
412 
413 	Draw( nX1,nY1,nX2,nY2, SC_UPDATE_MARKS );			// nicht weiterzeichnen
414 
415 	bIsInPaint = sal_False;
416 }
417 
418 //
419 // 	Draw  ----------------------------------------------------------------
420 //
421 
Draw(SCCOL nX1,SCROW nY1,SCCOL nX2,SCROW nY2,ScUpdateMode eMode)422 void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMode eMode )
423 {
424 	ScModule* pScMod = SC_MOD();
425 	sal_Bool bTextWysiwyg = pScMod->GetInputOptions().GetTextWysiwyg();
426 	sal_Bool bGridFirst = sal_True;		//! entscheiden!!!
427 
428 	if (pViewData->IsMinimized())
429 		return;
430 
431 	PutInOrder( nX1, nX2 );
432 	PutInOrder( nY1, nY2 );
433 
434 	DBG_ASSERT( ValidCol(nX2) && ValidRow(nY2), "GridWin Draw Bereich zu gross" );
435 
436 	SCCOL nPosX = pViewData->GetPosX( eHWhich );
437 	SCROW nPosY = pViewData->GetPosY( eVWhich );
438 	if (nX2 < nPosX || nY2 < nPosY)
439 		return;											// unsichtbar
440 	if (nX1 < nPosX) nX1 = nPosX;
441 	if (nY1 < nPosY) nY1 = nPosY;
442 
443 	SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
444 	if (nXRight > MAXCOL) nXRight = MAXCOL;
445 	SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
446 	if (nYBottom > MAXROW) nYBottom = MAXROW;
447 
448     // Store the current visible range.
449     maVisibleRange.mnCol1 = nPosX;
450     maVisibleRange.mnCol2 = nXRight;
451     maVisibleRange.mnRow1 = nPosY;
452     maVisibleRange.mnRow2 = nYBottom;
453 
454 	if (nX1 > nXRight || nY1 > nYBottom)
455 		return;											// unsichtbar
456 	if (nX2 > nXRight) nX2 = nXRight;
457 	if (nY2 > nYBottom) nY2 = nYBottom;
458 
459 	if ( eMode != SC_UPDATE_MARKS )
460 		if (nX2 < nXRight)
461 			nX2 = nXRight;								// zum Weiterzeichnen
462 
463 		//	ab hier kein return mehr
464 
465 	++nPaintCount;					// merken, dass gemalt wird (wichtig beim Invertieren)
466 
467 	ScDocShell* pDocSh = pViewData->GetDocShell();
468 	ScDocument* pDoc = pDocSh->GetDocument();
469 	SCTAB nTab = pViewData->GetTabNo();
470 
471 	pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
472 
473 	Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
474 	long nMirrorWidth = GetSizePixel().Width();
475 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
476 	long nLayoutSign = bLayoutRTL ? -1 : 1;
477 	if ( bLayoutRTL )
478 	{
479 		long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
480 		nMirrorWidth = aScrPos.X() - nEndPixel;
481 		aScrPos.X() = nEndPixel + 1;
482 	}
483 
484 	long nScrX = aScrPos.X();
485 	long nScrY = aScrPos.Y();
486 
487 	SCCOL nCurX = pViewData->GetCurX();
488 	SCROW nCurY = pViewData->GetCurY();
489 	SCCOL nCurEndX = nCurX;
490 	SCROW nCurEndY = nCurY;
491 	pDoc->ExtendMerge( nCurX, nCurY, nCurEndX, nCurEndY, nTab );
492 	sal_Bool bCurVis = nCursorHideCount==0 &&
493 					( nCurEndX+1 >= nX1 && nCurX <= nX2+1 && nCurEndY+1 >= nY1 && nCurY <= nY2+1 );
494 
495 	//	AutoFill-Anfasser
496 	if ( !bCurVis && nCursorHideCount==0 && bAutoMarkVisible && aAutoMarkPos.Tab() == nTab &&
497 			( aAutoMarkPos.Col() != nCurX || aAutoMarkPos.Row() != nCurY ) )
498 	{
499 		SCCOL nHdlX = aAutoMarkPos.Col();
500 		SCROW nHdlY = aAutoMarkPos.Row();
501 		pDoc->ExtendMerge( nHdlX, nHdlY, nHdlX, nHdlY, nTab );
502 		bCurVis = ( nHdlX+1 >= nX1 && nHdlX <= nX2 && nHdlY+1 >= nY1 && nHdlY <= nY2 );
503 		//	links und oben ist nicht betroffen
504 
505 		//!	AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
506 	}
507 
508 	double nPPTX = pViewData->GetPPTX();
509 	double nPPTY = pViewData->GetPPTY();
510 
511 	const ScViewOptions& rOpts = pViewData->GetOptions();
512 	sal_Bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
513 	sal_Bool bMarkClipped = rOpts.GetOption( VOPT_CLIPMARKS );
514 
515 		// Datenblock
516 
517     ScTableInfo aTabInfo;
518     pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
519 										nPPTX, nPPTY, sal_False, bFormulaMode,
520 										&pViewData->GetMarkData() );
521 
522 	//--------------------------------------------------------------------
523 
524 	Fraction aZoomX = pViewData->GetZoomX();
525 	Fraction aZoomY = pViewData->GetZoomY();
526     ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
527 								nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
528 								&aZoomX, &aZoomY );
529 
530 	aOutputData.SetMirrorWidth( nMirrorWidth );			// needed for RTL
531 
532     std::auto_ptr< VirtualDevice > xFmtVirtDev;
533     sal_Bool bLogicText = bTextWysiwyg;                     // call DrawStrings in logic MapMode?
534 
535 	if ( bTextWysiwyg )
536 	{
537 		//	use printer for text formatting
538 
539 		OutputDevice* pFmtDev = pDoc->GetPrinter();
540 		pFmtDev->SetMapMode( pViewData->GetLogicMode(eWhich) );
541 		aOutputData.SetFmtDevice( pFmtDev );
542 	}
543     else if ( aZoomX != aZoomY && pViewData->IsOle() )
544     {
545         //  #i45033# For OLE inplace editing with different zoom factors,
546         //  use a virtual device with 1/100th mm as text formatting reference
547 
548         xFmtVirtDev.reset( new VirtualDevice );
549         xFmtVirtDev->SetMapMode( MAP_100TH_MM );
550         aOutputData.SetFmtDevice( xFmtVirtDev.get() );
551 
552         bLogicText = sal_True;                      // use logic MapMode
553     }
554 
555     const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
556     Color aGridColor( rColorCfg.GetColorValue( svtools::CALCGRID, sal_False ).nColor );
557 	if ( aGridColor.GetColor() == COL_TRANSPARENT )
558 	{
559 		//	use view options' grid color only if color config has "automatic" color
560 		aGridColor = rOpts.GetGridColor();
561 	}
562 
563 	aOutputData.SetSyntaxMode		( pViewData->IsSyntaxMode() );
564 	aOutputData.SetGridColor		( aGridColor );
565 	aOutputData.SetShowNullValues	( rOpts.GetOption( VOPT_NULLVALS ) );
566 	aOutputData.SetShowFormulas		( bFormulaMode );
567     aOutputData.SetShowSpellErrors  ( pDoc->GetDocOptions().IsAutoSpell() );
568 	aOutputData.SetMarkClipped		( bMarkClipped );
569 
570 	aOutputData.SetUseStyleColor( sal_True );		// always set in table view
571 
572 	aOutputData.SetEditObject( GetEditObject() );
573 	aOutputData.SetViewShell( pViewData->GetViewShell() );
574 
575 	sal_Bool bGrid = rOpts.GetOption( VOPT_GRID );
576 	sal_Bool bPage = rOpts.GetOption( VOPT_PAGEBREAKS );
577 
578 	if ( eMode == SC_UPDATE_CHANGED )
579 	{
580 		aOutputData.FindChanged();
581 		aOutputData.SetSingleGrid(sal_True);
582 	}
583 
584 	sal_Bool bPageMode = pViewData->IsPagebreakMode();
585 	if (bPageMode)										// nach FindChanged
586 	{
587 		// SetPagebreakMode initialisiert auch bPrinted Flags
588 		aOutputData.SetPagebreakMode( pViewData->GetView()->GetPageBreakData() );
589 	}
590 
591 	EditView*	pEditView = NULL;
592 	sal_Bool		bEditMode = pViewData->HasEditView(eWhich);
593 	if ( bEditMode && pViewData->GetRefTabNo() == nTab )
594 	{
595 		SCCOL nEditCol;
596 		SCROW nEditRow;
597 		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
598 		SCCOL nEditEndCol = pViewData->GetEditEndCol();
599 		SCROW nEditEndRow = pViewData->GetEditEndRow();
600 
601 		if ( nEditEndCol >= nX1 && nEditCol <= nX2 && nEditEndRow >= nY1 && nEditRow <= nY2 )
602 			aOutputData.SetEditCell( nEditCol, nEditRow );
603 		else
604 			bEditMode = sal_False;
605 
606 		//	nur Edit-Area zu zeichnen?
607 		//!	dann muss trotzdem noch der Rand / das Gitter gemalt werden!
608 
609 //		if ( nEditCol <= nX1 && nEditEndCol >= nX2 && nEditRow <= nY1 && nEditEndRow >= nY2 )
610 //			bOnlyEdit = sal_True;
611 	}
612 
613 	// define drawing layer map mode and paint rectangle
614 	const MapMode aDrawMode = GetDrawMapMode();
615 	Rectangle aDrawingRectLogic;
616 
617 	{
618 		// get drawing pixel rect
619 		Rectangle aDrawingRectPixel(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
620 
621 		// correct for border (left/right)
622 		if(MAXCOL == nX2)
623 		{
624 			if(bLayoutRTL)
625 			{
626 				aDrawingRectPixel.Left() = 0L;
627 			}
628 			else
629 			{
630 				aDrawingRectPixel.Right() = GetOutputSizePixel().getWidth();
631 			}
632 		}
633 
634 		// correct for border (bottom)
635 		if(MAXROW == nY2)
636 		{
637 			aDrawingRectPixel.Bottom() = GetOutputSizePixel().getHeight();
638 		}
639 
640 		// get logic positions
641 		aDrawingRectLogic = PixelToLogic(aDrawingRectPixel, aDrawMode);
642 	}
643 
644 // not necessary with overlay
645 //	if (bCurVis)
646 //		HideCursor();
647 
648     OutputDevice* pContentDev = this;       // device for document content, used by overlay manager
649 	SdrPaintWindow* pTargetPaintWindow = 0;	// #i74769# work with SdrPaintWindow directly
650 
651 	{
652 		// init redraw
653 		ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
654 
655 		if(pTabViewShell)
656 		{
657 			MapMode aCurrentMapMode(pContentDev->GetMapMode());
658 			pContentDev->SetMapMode(aDrawMode);
659 			SdrView* pDrawView = pTabViewShell->GetSdrView();
660 
661 			if(pDrawView)
662 			{
663 				// #i74769# Use new BeginDrawLayers() interface
664 				Region aDrawingRegion(aDrawingRectLogic);
665 				pTargetPaintWindow = pDrawView->BeginDrawLayers(this, aDrawingRegion);
666 				OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
667 
668 				// #i74769# get target device from SdrPaintWindow, this may be the prerender
669 				// device now, too.
670 				pContentDev = &(pTargetPaintWindow->GetTargetOutputDevice());
671                 aOutputData.SetContentDevice( pContentDev );
672 			}
673 
674 			pContentDev->SetMapMode(aCurrentMapMode);
675 		}
676 	}
677 
678 	//	Rand (Wiese) (Pixel)
679 	if ( nX2==MAXCOL || nY2==MAXROW )
680 	{
681 		// save MapMode and set to pixel
682 		MapMode aCurrentMapMode(pContentDev->GetMapMode());
683 		pContentDev->SetMapMode(MAP_PIXEL);
684 
685 		Rectangle aPixRect = Rectangle( Point(), GetOutputSizePixel() );
686         pContentDev->SetFillColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
687 		pContentDev->SetLineColor();
688 		if ( nX2==MAXCOL )
689 		{
690 			Rectangle aDrawRect( aPixRect );
691 			if ( bLayoutRTL )
692 				aDrawRect.Right() = nScrX - 1;
693 			else
694 				aDrawRect.Left() = nScrX + aOutputData.GetScrW();
695 			if (aDrawRect.Right() >= aDrawRect.Left())
696 				pContentDev->DrawRect( aDrawRect );
697 		}
698 		if ( nY2==MAXROW )
699 		{
700 			Rectangle aDrawRect( aPixRect );
701 			aDrawRect.Top() = nScrY + aOutputData.GetScrH();
702 			if ( nX2==MAXCOL )
703 			{
704 				// no double painting of the corner
705 				if ( bLayoutRTL )
706 					aDrawRect.Left() = nScrX;
707 				else
708 					aDrawRect.Right() = nScrX + aOutputData.GetScrW() - 1;
709 			}
710 			if (aDrawRect.Bottom() >= aDrawRect.Top())
711 				pContentDev->DrawRect( aDrawRect );
712 		}
713 
714 		// restore MapMode
715 		pContentDev->SetMapMode(aCurrentMapMode);
716 	}
717 
718 	if ( pDoc->HasBackgroundDraw( nTab, aDrawingRectLogic ) )
719 	{
720 		pContentDev->SetMapMode(MAP_PIXEL);
721 		aOutputData.DrawClear();
722 
723 			// Drawing Hintergrund
724 
725 		pContentDev->SetMapMode(aDrawMode);
726 		DrawRedraw( aOutputData, eMode, SC_LAYER_BACK );
727 	}
728 	else
729 		aOutputData.SetSolidBackground(sal_True);
730 
731 	pContentDev->SetMapMode(MAP_PIXEL);
732 	aOutputData.DrawBackground();
733 	if ( bGridFirst && ( bGrid || bPage ) )
734 		aOutputData.DrawGrid( bGrid, bPage );
735 	if ( bPageMode )
736 	{
737 		// #87655# DrawPagePreview draws complete lines/page numbers, must always be clipped
738 		if ( aOutputData.SetChangedClip() )
739 		{
740             DrawPagePreview(nX1,nY1,nX2,nY2, pContentDev);
741 			pContentDev->SetClipRegion();
742 		}
743 	}
744 	aOutputData.DrawShadow();
745 	aOutputData.DrawFrame();
746 	if ( !bLogicText )
747 		aOutputData.DrawStrings(sal_False);		// in pixel MapMode
748 
749     // edit cells and printer-metrics text must be before the buttons
750     // (DataPilot buttons contain labels in UI font)
751 
752     pContentDev->SetMapMode(pViewData->GetLogicMode(eWhich));
753     if ( bLogicText )
754         aOutputData.DrawStrings(sal_True);      // in logic MapMode if bTextWysiwyg is set
755     aOutputData.DrawEdit(sal_True);
756     pContentDev->SetMapMode(MAP_PIXEL);
757 
758 		// Autofilter- und Pivot-Buttons
759 
760     DrawButtons( nX1, nY1, nX2, nY2, aTabInfo, pContentDev );          // Pixel
761 
762 		// Notiz-Anzeiger
763 
764 	if ( rOpts.GetOption( VOPT_NOTES ) )
765 		aOutputData.DrawNoteMarks();
766 
767 	if ( !bGridFirst && ( bGrid || bPage ) )
768 	{
769 		aOutputData.DrawGrid( bGrid, bPage );
770 	}
771 	aOutputData.DrawClipMarks();
772 
773 	//	Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
774 
775 	//!	Test, ob ChangeTrack-Anzeige aktiv ist
776 	//!	Szenario-Rahmen per View-Optionen abschaltbar?
777 
778 	SCTAB nTabCount = pDoc->GetTableCount();
779 	ScHighlightRanges* pHigh = pViewData->GetView()->GetHighlightRanges();
780 	sal_Bool bHasScenario = ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) );
781 	sal_Bool bHasChange = ( pDoc->GetChangeTrack() != NULL );
782 
783 	if ( bHasChange || bHasScenario || pHigh != NULL )
784 	{
785 
786 		//! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
787 
788 		sal_Bool bAny = sal_True;
789 		if (eMode == SC_UPDATE_CHANGED)
790 			bAny = aOutputData.SetChangedClip();
791 		if (bAny)
792 		{
793 			if ( bHasChange )
794 				aOutputData.DrawChangeTrack();
795 
796 			if ( bHasScenario )
797 				lcl_DrawScenarioFrames( pContentDev, pViewData, eWhich, nX1,nY1,nX2,nY2 );
798 
799 			if ( pHigh )
800 				lcl_DrawHighlight( aOutputData, pViewData, *pHigh );
801 
802 			if (eMode == SC_UPDATE_CHANGED)
803 				pContentDev->SetClipRegion();
804 		}
805 	}
806 
807 		// Drawing Vordergrund
808 
809 	pContentDev->SetMapMode(aDrawMode);
810 
811 	DrawRedraw( aOutputData, eMode, SC_LAYER_FRONT );
812 	DrawRedraw( aOutputData, eMode, SC_LAYER_INTERN );
813     DrawSdrGrid( aDrawingRectLogic, pContentDev );
814 
815 	if (!bIsInScroll)								// Drawing Markierungen
816 	{
817 		if(eMode == SC_UPDATE_CHANGED && aOutputData.SetChangedClip())
818 		{
819 			pContentDev->SetClipRegion();
820 		}
821 
822 		//sal_Bool bDraw = sal_True;
823 		//if (eMode == SC_UPDATE_CHANGED)
824 		//	bDraw = NeedDrawMarks() && aOutputData.SetChangedClip();
825 		//if (bDraw)
826 		//{
827 		//	DrawMarks();
828 		//	if (eMode == SC_UPDATE_CHANGED)
829 		//		pContentDev->SetClipRegion();
830 		//}
831 	}
832 
833 	pContentDev->SetMapMode(MAP_PIXEL);
834 
835 #ifdef OLD_SELECTION_PAINT
836 	if (pViewData->IsActive())
837 		aOutputData.DrawMark( this );
838 #endif
839 
840 	if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() )
841 	{
842         // The AutoFill shrink area has an own overlay now
843 #if 0
844 		//	Schraffur beim Loeschen per AutoFill
845 		if ( pViewData->GetRefType() == SC_REFTYPE_FILL )
846 		{
847 			ScRange aRange;
848 			if ( pViewData->GetDelMark( aRange ) )
849 			{
850 				if ( aRange.aStart.Col() < nX1 ) aRange.aStart.SetCol(nX1);
851 				if ( aRange.aEnd.Col() > nX2 )	 aRange.aEnd.SetCol(nX2);
852 				if ( aRange.aStart.Row() < nY1 ) aRange.aStart.SetRow(nY1);
853 				if ( aRange.aEnd.Row() > nY2 )	 aRange.aEnd.SetRow(nY2);
854 				if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
855 					 aRange.aStart.Row() <= aRange.aEnd.Row() )
856 				{
857 					Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
858 														 aRange.aStart.Row(), eWhich );
859 					Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
860 													   aRange.aEnd.Row()+1, eWhich );
861 					aEnd.X() -= 1;
862 					aEnd.Y() -= 1;
863 
864 					//	Markierung aufheben - roter Rahmen bleibt stehen
865 					Rectangle aRect( aStart,aEnd );
866 					Invert( aRect, INVERT_HIGHLIGHT );
867 
868 					//!	Delete-Bereich extra kennzeichnen?!?!?
869 				}
870 			}
871 		}
872 #endif
873 
874         Color aRefColor( rColorCfg.GetColorValue(svtools::CALCREFERENCE).nColor );
875 		aOutputData.DrawRefMark( pViewData->GetRefStartX(), pViewData->GetRefStartY(),
876 								 pViewData->GetRefEndX(), pViewData->GetRefEndY(),
877 								 aRefColor, sal_False );
878 	}
879 
880 		//	Range-Finder
881 
882 	ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
883 	if (pHdl)
884 	{
885 		ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
886 		if ( pRangeFinder && !pRangeFinder->IsHidden() &&
887 				pRangeFinder->GetDocName() == pDocSh->GetTitle() )
888 		{
889 			sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
890 			for (sal_uInt16 i=0; i<nCount; i++)
891 			{
892 				ScRangeFindData* pData = pRangeFinder->GetObject(i);
893 				if (pData)
894 				{
895 					ScRange aRef = pData->aRef;
896 					aRef.Justify();
897 					if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
898 						aOutputData.DrawRefMark( aRef.aStart.Col(), aRef.aStart.Row(),
899 												aRef.aEnd.Col(), aRef.aEnd.Row(),
900 												Color( ScRangeFindList::GetColorName( i ) ),
901 												sal_True );
902 				}
903 			}
904 		}
905 	}
906 
907 	{
908 		// end redraw
909 		ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
910 
911 		if(pTabViewShell)
912 		{
913 			MapMode aCurrentMapMode(pContentDev->GetMapMode());
914 			pContentDev->SetMapMode(aDrawMode);
915 			SdrView* pDrawView = pTabViewShell->GetSdrView();
916 
917 			if(pDrawView)
918 			{
919 				// #i74769# work with SdrPaintWindow directly
920 				pDrawView->EndDrawLayers(*pTargetPaintWindow, true);
921 			}
922 
923 			pContentDev->SetMapMode(aCurrentMapMode);
924 		}
925 	}
926 
927 	//	InPlace Edit-View
928 	// moved after EndDrawLayers() to get it outside the overlay buffer and
929 	// on top of everything
930 	if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
931 	{
932         //! use pContentDev for EditView?
933         SetMapMode(MAP_PIXEL);
934 		SCCOL nCol1 = pViewData->GetEditStartCol();
935 		SCROW nRow1 = pViewData->GetEditStartRow();
936 		SCCOL nCol2 = pViewData->GetEditEndCol();
937 		SCROW nRow2 = pViewData->GetEditEndRow();
938 		SetLineColor();
939 		SetFillColor( pEditView->GetBackgroundColor() );
940 		Point aStart = pViewData->GetScrPos( nCol1, nRow1, eWhich );
941 		Point aEnd = pViewData->GetScrPos( nCol2+1, nRow2+1, eWhich );
942 		aEnd.X() -= 2 * nLayoutSign;		// don't overwrite grid
943 		aEnd.Y() -= 2;
944 		DrawRect( Rectangle( aStart,aEnd ) );
945 
946 		SetMapMode(pViewData->GetLogicMode());
947 		pEditView->Paint( PixelToLogic( Rectangle( Point( nScrX, nScrY ),
948 							Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ) );
949 		SetMapMode(MAP_PIXEL);
950 	}
951 
952 	if (pViewData->HasEditView(eWhich))
953 	{
954 		// flush OverlayManager before changing the MapMode
955 		flushOverlayManager();
956 
957 		// set MapMode for text edit
958 		SetMapMode(pViewData->GetLogicMode());
959 	}
960 	else
961 		SetMapMode(aDrawMode);
962 
963 	if ( pNoteMarker )
964 		pNoteMarker->Draw();		// ueber den Cursor, im Drawing-MapMode
965 
966 	//DrawStartTimer();				// fuer bunte Handles ohne System-Clipping
967 
968 	//
969 	//	Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
970 	//	ist das jetzt durcheinandergekommen und es muss neu gemalt werden
971 	//
972 
973 	DBG_ASSERT(nPaintCount, "nPaintCount falsch");
974 	--nPaintCount;
975 	if (!nPaintCount)
976 		CheckNeedsRepaint();
977 }
978 
CheckNeedsRepaint()979 void ScGridWindow::CheckNeedsRepaint()
980 {
981 	//	called at the end of painting, and from timer after background text width calculation
982 
983 	if (bNeedsRepaint)
984 	{
985 		bNeedsRepaint = sal_False;
986 		if (aRepaintPixel.IsEmpty())
987 			Invalidate();
988 		else
989 			Invalidate(PixelToLogic(aRepaintPixel));
990 		aRepaintPixel = Rectangle();
991 
992         // selection function in status bar might also be invalid
993         SfxBindings& rBindings = pViewData->GetBindings();
994         rBindings.Invalidate( SID_STATUS_SUM );
995         rBindings.Invalidate( SID_ATTR_SIZE );
996         rBindings.Invalidate( SID_TABLE_CELL );
997 	}
998 }
999 
DrawPagePreview(SCCOL nX1,SCROW nY1,SCCOL nX2,SCROW nY2,OutputDevice * pContentDev)1000 void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, OutputDevice* pContentDev )
1001 {
1002 	ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData();
1003 	if (pPageData)
1004 	{
1005 		ScDocument* pDoc = pViewData->GetDocument();
1006 		SCTAB nTab = pViewData->GetTabNo();
1007 		Size aWinSize = GetOutputSizePixel();
1008         const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
1009         Color aManual( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
1010         Color aAutomatic( rColorCfg.GetColorValue(svtools::CALCPAGEBREAK).nColor );
1011 
1012 		String aPageText = ScGlobal::GetRscString( STR_PAGE );
1013 		if ( nPageScript == 0 )
1014 		{
1015 			//	get script type of translated "Page" string only once
1016 			nPageScript = pDoc->GetStringScriptType( aPageText );
1017 			if (nPageScript == 0)
1018 				nPageScript = ScGlobal::GetDefaultScriptType();
1019 		}
1020 		aPageText += ' ';
1021 
1022 		Font aFont;
1023 		ScEditEngineDefaulter* pEditEng = NULL;
1024 		const ScPatternAttr& rDefPattern = ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
1025 		if ( nPageScript == SCRIPTTYPE_LATIN )
1026 		{
1027 			//	use single font and call DrawText directly
1028 			rDefPattern.GetFont( aFont, SC_AUTOCOL_BLACK );
1029 			aFont.SetColor( Color( COL_LIGHTGRAY ) );
1030 			//	font size is set as needed
1031 		}
1032 		else
1033 		{
1034 			//	use EditEngine to draw mixed-script string
1035 			pEditEng = new ScEditEngineDefaulter( EditEngine::CreatePool(), sal_True );
1036 			pEditEng->SetRefMapMode( pContentDev->GetMapMode() );
1037 			SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() );
1038 			rDefPattern.FillEditItemSet( pEditDefaults );
1039 			pEditDefaults->Put( SvxColorItem( Color( COL_LIGHTGRAY ), EE_CHAR_COLOR ) );
1040 			pEditEng->SetDefaults( pEditDefaults );
1041 		}
1042 
1043         sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
1044 		for (sal_uInt16 nPos=0; nPos<nCount; nPos++)
1045 		{
1046 			ScPrintRangeData& rData = pPageData->GetData(nPos);
1047 			ScRange aRange = rData.GetPrintRange();
1048 			if ( aRange.aStart.Col() <= nX2+1  && aRange.aEnd.Col()+1 >= nX1 &&
1049 				 aRange.aStart.Row() <= nY2+1 && aRange.aEnd.Row()+1 >= nY1 )
1050 			{
1051 				//	3 Pixel Rahmen um den Druckbereich
1052 				//	(mittlerer Pixel auf den Gitterlinien)
1053 
1054 				pContentDev->SetLineColor();
1055 				if (rData.IsAutomatic())
1056 					pContentDev->SetFillColor( aAutomatic );
1057 				else
1058 					pContentDev->SetFillColor( aManual );
1059 
1060 				Point aStart = pViewData->GetScrPos(
1061 									aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True );
1062 				Point aEnd = pViewData->GetScrPos(
1063 									aRange.aEnd.Col() + 1, aRange.aEnd.Row() + 1, eWhich, sal_True );
1064 				aStart.X() -= 2;
1065 				aStart.Y() -= 2;
1066 
1067 				//	Ueberlaeufe verhindern:
1068 				if ( aStart.X() < -10 )	aStart.X() = -10;
1069 				if ( aStart.Y() < -10 )	aStart.Y() = -10;
1070 				if ( aEnd.X() > aWinSize.Width() + 10 )
1071 					aEnd.X() = aWinSize.Width() + 10;
1072 				if ( aEnd.Y() > aWinSize.Height() + 10 )
1073 					aEnd.Y() = aWinSize.Height() + 10;
1074 
1075 				pContentDev->DrawRect( Rectangle( aStart, Point(aEnd.X(),aStart.Y()+2) ) );
1076 				pContentDev->DrawRect( Rectangle( aStart, Point(aStart.X()+2,aEnd.Y()) ) );
1077 				pContentDev->DrawRect( Rectangle( Point(aStart.X(),aEnd.Y()-2), aEnd ) );
1078 				pContentDev->DrawRect( Rectangle( Point(aEnd.X()-2,aStart.Y()), aEnd ) );
1079 
1080 				//	Seitenumbrueche
1081 				//!	anders darstellen (gestrichelt ????)
1082 
1083 				size_t nColBreaks = rData.GetPagesX();
1084 				const SCCOL* pColEnd = rData.GetPageEndX();
1085 				size_t nColPos;
1086 				for (nColPos=0; nColPos+1<nColBreaks; nColPos++)
1087 				{
1088 					SCCOL nBreak = pColEnd[nColPos]+1;
1089 					if ( nBreak >= nX1 && nBreak <= nX2+1 )
1090 					{
1091 						//! hidden suchen
1092                         if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL)
1093 							pContentDev->SetFillColor( aManual );
1094 						else
1095 							pContentDev->SetFillColor( aAutomatic );
1096 						Point aBreak = pViewData->GetScrPos(
1097 										nBreak, aRange.aStart.Row(), eWhich, sal_True );
1098 						pContentDev->DrawRect( Rectangle( aBreak.X()-1, aStart.Y(), aBreak.X(), aEnd.Y() ) );
1099 					}
1100 				}
1101 
1102 				size_t nRowBreaks = rData.GetPagesY();
1103 				const SCROW* pRowEnd = rData.GetPageEndY();
1104 				size_t nRowPos;
1105 				for (nRowPos=0; nRowPos+1<nRowBreaks; nRowPos++)
1106 				{
1107 					SCROW nBreak = pRowEnd[nRowPos]+1;
1108 					if ( nBreak >= nY1 && nBreak <= nY2+1 )
1109 					{
1110 						//! hidden suchen
1111                         if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL)
1112 							pContentDev->SetFillColor( aManual );
1113 						else
1114 							pContentDev->SetFillColor( aAutomatic );
1115 						Point aBreak = pViewData->GetScrPos(
1116 										aRange.aStart.Col(), nBreak, eWhich, sal_True );
1117 						pContentDev->DrawRect( Rectangle( aStart.X(), aBreak.Y()-1, aEnd.X(), aBreak.Y() ) );
1118 					}
1119 				}
1120 
1121 				//	Seitenzahlen
1122 
1123 				SCROW nPrStartY = aRange.aStart.Row();
1124 				for (nRowPos=0; nRowPos<nRowBreaks; nRowPos++)
1125 				{
1126 					SCROW nPrEndY = pRowEnd[nRowPos];
1127 					if ( nPrEndY >= nY1 && nPrStartY <= nY2 )
1128 					{
1129 						SCCOL nPrStartX = aRange.aStart.Col();
1130 						for (nColPos=0; nColPos<nColBreaks; nColPos++)
1131 						{
1132 							SCCOL nPrEndX = pColEnd[nColPos];
1133 							if ( nPrEndX >= nX1 && nPrStartX <= nX2 )
1134 							{
1135 								Point aPageStart = pViewData->GetScrPos(
1136 														nPrStartX, nPrStartY, eWhich, sal_True );
1137 								Point aPageEnd = pViewData->GetScrPos(
1138 														nPrEndX+1,nPrEndY+1, eWhich, sal_True );
1139 
1140 								long nPageNo = rData.GetFirstPage();
1141 								if ( rData.IsTopDown() )
1142 									nPageNo += ((long)nColPos)*nRowBreaks+nRowPos;
1143 								else
1144 									nPageNo += ((long)nRowPos)*nColBreaks+nColPos;
1145 								String aPageStr = aPageText;
1146 								aPageStr += String::CreateFromInt32(nPageNo);
1147 
1148 								if ( pEditEng )
1149 								{
1150 									//	find right font size with EditEngine
1151 									long nHeight = 100;
1152 									pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
1153 									pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1154 									pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1155 									pEditEng->SetText( aPageStr );
1156 									Size aSize100( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
1157 
1158 									//	40% of width or 60% of height
1159 									long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
1160 									long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
1161 									nHeight = Min(nSizeX,nSizeY);
1162 									pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
1163 									pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1164 									pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1165 
1166 									//	centered output with EditEngine
1167 									Size aTextSize( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
1168 									Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
1169 												(aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
1170 									pEditEng->Draw( pContentDev, aPos );
1171 								}
1172 								else
1173 								{
1174 									//	find right font size for DrawText
1175 									aFont.SetSize( Size( 0,100 ) );
1176 									pContentDev->SetFont( aFont );
1177 									Size aSize100( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() );
1178 
1179 									//	40% of width or 60% of height
1180 									long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
1181 									long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
1182 									aFont.SetSize( Size( 0,Min(nSizeX,nSizeY) ) );
1183 									pContentDev->SetFont( aFont );
1184 
1185 									//	centered output with DrawText
1186 									Size aTextSize( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() );
1187 									Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
1188 												(aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
1189 									pContentDev->DrawText( aPos, aPageStr );
1190 								}
1191 							}
1192 							nPrStartX = nPrEndX + 1;
1193 						}
1194 					}
1195 					nPrStartY = nPrEndY + 1;
1196 				}
1197 			}
1198 		}
1199 
1200 		delete pEditEng;
1201 	}
1202 }
1203 
DrawButtons(SCCOL nX1,SCROW,SCCOL nX2,SCROW,ScTableInfo & rTabInfo,OutputDevice * pContentDev)1204 void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2*/, ScTableInfo& rTabInfo, OutputDevice* pContentDev )
1205 {
1206     aComboButton.SetOutputDevice( pContentDev );
1207 
1208     ScDocument* pDoc = pViewData->GetDocument();
1209     ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY(), pDoc);
1210 
1211 	SCCOL nCol;
1212 	SCROW nRow;
1213 	SCSIZE nArrY;
1214 	SCSIZE nQuery;
1215 	SCTAB			nTab = pViewData->GetTabNo();
1216 	ScDBData*		pDBData = NULL;
1217 	ScQueryParam*	pQueryParam = NULL;
1218 
1219     RowInfo*        pRowInfo = rTabInfo.mpRowInfo;
1220     sal_uInt16          nArrCount = rTabInfo.mnArrCount;
1221 
1222 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1223 
1224 	Point aOldPos  = aComboButton.GetPosPixel();	// Zustand fuer MouseDown/Up
1225 	Size  aOldSize = aComboButton.GetSizePixel();   // merken
1226 
1227 	for (nArrY=1; nArrY+1<nArrCount; nArrY++)
1228 	{
1229 		if ( pRowInfo[nArrY].bAutoFilter && pRowInfo[nArrY].bChanged )
1230 		{
1231 			RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1232 
1233 			nRow = pThisRowInfo->nRowNo;
1234 
1235 
1236 			for (nCol=nX1; nCol<=nX2; nCol++)
1237 			{
1238 				CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
1239 				//if several columns merged on a row, there should be only one auto button at the end of the columns.
1240 				//if several rows merged on a column, the button may be in the middle, so "!pInfo->bVOverlapped" should not be used
1241 				if ( pInfo->bAutoFilter && !pInfo->bHOverlapped )
1242 				{
1243 					if (!pQueryParam)
1244 						pQueryParam = new ScQueryParam;
1245 
1246 					sal_Bool bNewData = sal_True;
1247 					if (pDBData)
1248 					{
1249 						SCCOL nStartCol;
1250 						SCROW nStartRow;
1251 						SCCOL nEndCol;
1252 						SCROW nEndRow;
1253 						SCTAB nAreaTab;
1254 						pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
1255 						if ( nCol >= nStartCol && nCol <= nEndCol &&
1256 							 nRow >= nStartRow && nRow <= nEndRow )
1257 							bNewData = sal_False;
1258 					}
1259 					if (bNewData)
1260 					{
1261 						pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1262 						if (pDBData)
1263 							pDBData->GetQueryParam( *pQueryParam );
1264 						else
1265 						{
1266 							// can also be part of DataPilot table
1267 							// DBG_ERROR("Auto-Filter-Button ohne DBData");
1268 						}
1269 					}
1270 
1271 					//	pQueryParam kann nur MAXQUERY Eintraege enthalten
1272 
1273 					sal_Bool bSimpleQuery = sal_True;
1274 					sal_Bool bColumnFound = sal_False;
1275 					if (!pQueryParam->bInplace)
1276 						bSimpleQuery = sal_False;
1277 					for (nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++)
1278 						if (pQueryParam->GetEntry(nQuery).bDoQuery)
1279 						{
1280 							//	hier nicht auf EQUAL beschraenken
1281 							//	(auch bei ">1" soll der Spaltenkopf blau werden)
1282 
1283 							if (pQueryParam->GetEntry(nQuery).nField == nCol)
1284 								bColumnFound = sal_True;
1285 							if (nQuery > 0)
1286 								if (pQueryParam->GetEntry(nQuery).eConnect != SC_AND)
1287 									bSimpleQuery = sal_False;
1288 						}
1289 
1290                     bool bArrowState = bSimpleQuery && bColumnFound;
1291 					long	nSizeX;
1292 					long	nSizeY;
1293 					SCCOL nStartCol= nCol;
1294 					SCROW nStartRow = nRow;
1295 					//if address(nCol,nRow) is not the start pos of the merge area, the value of the nSizeX will be incorrect, it will be the length of the cell.
1296 					//should first get the start pos of the merge area, then get the nSizeX through the start pos.
1297 					pDoc->ExtendOverlapped(nStartCol, nStartRow,nCol, nRow, nTab);//get nStartCol,nStartRow
1298 					pViewData->GetMergeSizePixel( nStartCol, nStartRow, nSizeX, nSizeY );//get nSizeX
1299 					nSizeY = pViewData->ToPixel(pDoc->GetRowHeight(nRow, nTab), pViewData->GetPPTY());
1300 					Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
1301 
1302                     aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1), bLayoutRTL);
1303                     aCellBtn.setPopupLeft(bLayoutRTL);   // #i114944# AutoFilter button is left-aligned in RTL
1304                     aCellBtn.setDrawBaseButton(false);
1305                     aCellBtn.setDrawPopupButton(true);
1306                     aCellBtn.setHasHiddenMember(bArrowState);
1307                     aCellBtn.draw();
1308 				}
1309 			}
1310 		}
1311 
1312 		if ( pRowInfo[nArrY].bPushButton && pRowInfo[nArrY].bChanged )
1313 		{
1314 			RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1315 			nRow = pThisRowInfo->nRowNo;
1316 			for (nCol=nX1; nCol<=nX2; nCol++)
1317 			{
1318 				CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
1319 				if ( pInfo->bPushButton && !pInfo->bHOverlapped && !pInfo->bVOverlapped )
1320 				{
1321 					Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
1322 					long nSizeX;
1323 					long nSizeY;
1324 					pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
1325 					long nPosX = aScrPos.X();
1326 					long nPosY = aScrPos.Y();
1327 					// bLayoutRTL is handled in setBoundingBox
1328 
1329                     String aStr;
1330                     pDoc->GetString(nCol, nRow, nTab, aStr);
1331                     aCellBtn.setText(aStr);
1332                     aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL);
1333                     aCellBtn.setPopupLeft(false);   // DataPilot popup is always right-aligned for now
1334                     aCellBtn.setDrawBaseButton(true);
1335                     aCellBtn.setDrawPopupButton(pInfo->bPopupButton);
1336                     aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
1337                     aCellBtn.draw();
1338 				}
1339 			}
1340 		}
1341 
1342         if ( bListValButton && pRowInfo[nArrY].nRowNo == aListValPos.Row() && pRowInfo[nArrY].bChanged )
1343         {
1344             Rectangle aRect = GetListValButtonRect( aListValPos );
1345             aComboButton.SetPosPixel( aRect.TopLeft() );
1346             aComboButton.SetSizePixel( aRect.GetSize() );
1347             pContentDev->SetClipRegion( aRect );
1348             aComboButton.Draw( sal_False, sal_False );
1349             pContentDev->SetClipRegion();           // always called from Draw() without clip region
1350             aComboButton.SetPosPixel( aOldPos );    // restore old state
1351             aComboButton.SetSizePixel( aOldSize );  // for MouseUp/Down (AutoFilter)
1352         }
1353 	}
1354 
1355 	delete pQueryParam;
1356     aComboButton.SetOutputDevice( this );
1357 }
1358 
GetListValButtonRect(const ScAddress & rButtonPos)1359 Rectangle ScGridWindow::GetListValButtonRect( const ScAddress& rButtonPos )
1360 {
1361     ScDocument* pDoc = pViewData->GetDocument();
1362     SCTAB nTab = pViewData->GetTabNo();
1363     sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1364     long nLayoutSign = bLayoutRTL ? -1 : 1;
1365 
1366     ScDDComboBoxButton aButton( this );             // for optimal size
1367     Size aBtnSize = aButton.GetSizePixel();
1368 
1369     SCCOL nCol = rButtonPos.Col();
1370     SCROW nRow = rButtonPos.Row();
1371 
1372     long nCellSizeX;    // width of this cell, including merged
1373     long nDummy;
1374     pViewData->GetMergeSizePixel( nCol, nRow, nCellSizeX, nDummy );
1375 
1376     // for height, only the cell's row is used, excluding merged cells
1377     long nCellSizeY = ScViewData::ToPixel( pDoc->GetRowHeight( nRow, nTab ), pViewData->GetPPTY() );
1378     long nAvailable = nCellSizeX;
1379 
1380     //  left edge of next cell if there is a non-hidden next column
1381     SCCOL nNextCol = nCol + 1;
1382     const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(pDoc->GetAttr( nCol,nRow,nTab, ATTR_MERGE ));
1383     if ( pMerge->GetColMerge() > 1 )
1384         nNextCol = nCol + pMerge->GetColMerge();    // next cell after the merged area
1385     while ( nNextCol <= MAXCOL && pDoc->ColHidden(nNextCol, nTab) )
1386         ++nNextCol;
1387     sal_Bool bNextCell = ( nNextCol <= MAXCOL );
1388     if ( bNextCell )
1389         nAvailable = ScViewData::ToPixel( pDoc->GetColWidth( nNextCol, nTab ), pViewData->GetPPTX() );
1390 
1391     if ( nAvailable < aBtnSize.Width() )
1392         aBtnSize.Width() = nAvailable;
1393     if ( nCellSizeY < aBtnSize.Height() )
1394         aBtnSize.Height() = nCellSizeY;
1395 
1396     Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich, sal_True );
1397     aPos.X() += nCellSizeX * nLayoutSign;               // start of next cell
1398     if (!bNextCell)
1399         aPos.X() -= aBtnSize.Width() * nLayoutSign;     // right edge of cell if next cell not available
1400     aPos.Y() += nCellSizeY - aBtnSize.Height();
1401     // X remains at the left edge
1402 
1403     if ( bLayoutRTL )
1404         aPos.X() -= aBtnSize.Width()-1;     // align right edge of button with cell border
1405 
1406     return Rectangle( aPos, aBtnSize );
1407 }
1408 
IsAutoFilterActive(SCCOL nCol,SCROW nRow,SCTAB nTab)1409 sal_Bool ScGridWindow::IsAutoFilterActive( SCCOL nCol, SCROW nRow, SCTAB nTab )
1410 {
1411 	ScDocument*		pDoc	= pViewData->GetDocument();
1412 	ScDBData*		pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1413 	ScQueryParam	aQueryParam;
1414 
1415 	if ( pDBData )
1416 		pDBData->GetQueryParam( aQueryParam );
1417 	else
1418 	{
1419 		DBG_ERROR("Auto-Filter-Button ohne DBData");
1420 	}
1421 
1422 	sal_Bool	bSimpleQuery = sal_True;
1423 	sal_Bool	bColumnFound = sal_False;
1424 	SCSIZE	nQuery;
1425 
1426 	if ( !aQueryParam.bInplace )
1427 		bSimpleQuery = sal_False;
1428 
1429 	//	aQueryParam kann nur MAXQUERY Eintraege enthalten
1430 
1431 	for ( nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++ )
1432 		if ( aQueryParam.GetEntry(nQuery).bDoQuery )
1433 		{
1434 			if (aQueryParam.GetEntry(nQuery).nField == nCol)
1435 				bColumnFound = sal_True;
1436 
1437 			if (nQuery > 0)
1438 				if (aQueryParam.GetEntry(nQuery).eConnect != SC_AND)
1439 					bSimpleQuery = sal_False;
1440 		}
1441 
1442 	return ( bSimpleQuery && bColumnFound );
1443 }
1444 
DrawComboButton(const Point & rCellPos,long nCellSizeX,long nCellSizeY,sal_Bool bArrowState,sal_Bool bBtnIn)1445 void ScGridWindow::DrawComboButton( const Point&	rCellPos,
1446 									long			nCellSizeX,
1447 									long			nCellSizeY,
1448                                     sal_Bool            bArrowState,
1449 									sal_Bool			bBtnIn )
1450 {
1451 	Point	aScrPos	 = rCellPos;
1452 	Size	aBtnSize = aComboButton.GetSizePixel();
1453 
1454 	if ( nCellSizeX < aBtnSize.Width() || nCellSizeY < aBtnSize.Height() )
1455 	{
1456 		if ( nCellSizeX < aBtnSize.Width() )
1457 			aBtnSize.Width() = nCellSizeX;
1458 
1459 		if ( nCellSizeY < aBtnSize.Height() )
1460 			aBtnSize.Height() = nCellSizeY;
1461 
1462 		aComboButton.SetSizePixel( aBtnSize );
1463 	}
1464 
1465 	sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
1466 
1467 	if ( bLayoutRTL )
1468 		aScrPos.X() -= nCellSizeX - 1;
1469 	else
1470 		aScrPos.X() += nCellSizeX - aBtnSize.Width();
1471 	aScrPos.Y() += nCellSizeY - aBtnSize.Height();
1472 
1473 	aComboButton.SetPosPixel( aScrPos );
1474 
1475 	HideCursor();
1476     aComboButton.Draw( bArrowState, bBtnIn );
1477 	ShowCursor();
1478 }
1479 
InvertSimple(SCCOL nX1,SCROW nY1,SCCOL nX2,SCROW nY2,sal_Bool bTestMerge,sal_Bool bRepeat)1480 void ScGridWindow::InvertSimple( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1481 									sal_Bool bTestMerge, sal_Bool bRepeat )
1482 {
1483 	//!	if INVERT_HIGHLIGHT swaps foreground and background (like on Mac),
1484 	//!	use INVERT_HIGHLIGHT only for cells that have no background color set
1485 	//!	(here and in ScOutputData::DrawMark)
1486 
1487 	PutInOrder( nX1, nX2 );
1488 	PutInOrder( nY1, nY2 );
1489 
1490 	ScMarkData& rMark = pViewData->GetMarkData();
1491 	ScDocument* pDoc = pViewData->GetDocument();
1492 	SCTAB nTab = pViewData->GetTabNo();
1493 
1494 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1495 	long nLayoutSign = bLayoutRTL ? -1 : 1;
1496 
1497 	SCCOL nTestX2 = nX2;
1498 	SCROW nTestY2 = nY2;
1499 	if (bTestMerge)
1500 		pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
1501 
1502 	SCCOL nPosX = pViewData->GetPosX( eHWhich );
1503 	SCROW nPosY = pViewData->GetPosY( eVWhich );
1504 	if (nTestX2 < nPosX || nTestY2 < nPosY)
1505 		return;											// unsichtbar
1506 	SCCOL nRealX1 = nX1;
1507 	if (nX1 < nPosX)
1508 		nX1 = nPosX;
1509 	if (nY1 < nPosY)
1510 		nY1 = nPosY;
1511 
1512 	SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
1513 	if (nXRight > MAXCOL) nXRight = MAXCOL;
1514 	SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
1515 	if (nYBottom > MAXROW) nYBottom = MAXROW;
1516 
1517 	if (nX1 > nXRight || nY1 > nYBottom)
1518 		return;											// unsichtbar
1519 	if (nX2 > nXRight) nX2 = nXRight;
1520 	if (nY2 > nYBottom) nY2 = nYBottom;
1521 
1522 	MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);		// erst nach den return's !!!
1523 
1524 	double nPPTX = pViewData->GetPPTX();
1525 	double nPPTY = pViewData->GetPPTY();
1526 
1527 	ScInvertMerger aInvert( this );
1528 
1529 	Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
1530 	long nScrY = aScrPos.Y();
1531 	sal_Bool bWasHidden = sal_False;
1532 	for (SCROW nY=nY1; nY<=nY2; nY++)
1533 	{
1534 		sal_Bool bFirstRow = ( nY == nPosY );						// first visible row?
1535 		sal_Bool bDoHidden = sal_False;									// versteckte nachholen ?
1536 		sal_uInt16 nHeightTwips = pDoc->GetRowHeight( nY,nTab );
1537 		sal_Bool bDoRow = ( nHeightTwips != 0 );
1538 		if (bDoRow)
1539 		{
1540 			if (bTestMerge)
1541 				if (bWasHidden)					// auf versteckte zusammengefasste testen
1542 				{
1543 //					--nY;						// nY geaendert -> vorherige zeichnen
1544 					bDoHidden = sal_True;
1545 					bDoRow = sal_True;
1546 				}
1547 
1548 			bWasHidden = sal_False;
1549 		}
1550 		else
1551 		{
1552 			bWasHidden = sal_True;
1553 			if (bTestMerge)
1554 				if (nY==nY2)
1555 					bDoRow = sal_True;				// letzte Zeile aus Block
1556 		}
1557 
1558 		if ( bDoRow )
1559 		{
1560 			SCCOL nLoopEndX = nX2;
1561 			if (nX2 < nX1)						// Rest von zusammengefasst
1562 			{
1563 				SCCOL nStartX = nX1;
1564 				while ( ((const ScMergeFlagAttr*)pDoc->
1565 							GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() )
1566 					--nStartX;
1567 				if (nStartX <= nX2)
1568 					nLoopEndX = nX1;
1569 			}
1570 
1571 			long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1;
1572 			long nScrX = aScrPos.X();
1573 			for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
1574 			{
1575 				long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX );
1576 				if ( nWidth > 0 )
1577 				{
1578 					long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
1579 					if (bTestMerge)
1580 					{
1581 						SCROW nThisY = nY;
1582 						const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
1583 						const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->
1584 																		GetItem(ATTR_MERGE_FLAG);
1585 						if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
1586 						{
1587 							while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
1588                                     (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) )
1589 							{
1590 								--nThisY;
1591 								pPattern = pDoc->GetPattern( nX, nThisY, nTab );
1592 								pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1593 							}
1594 						}
1595 
1596 						// nur Rest von zusammengefasster zu sehen ?
1597 						SCCOL nThisX = nX;
1598 						if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
1599 						{
1600 							while ( pMergeFlag->IsHorOverlapped() )
1601 							{
1602 								--nThisX;
1603 								pPattern = pDoc->GetPattern( nThisX, nThisY, nTab );
1604 								pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1605 							}
1606 						}
1607 
1608 						if ( rMark.IsCellMarked( nThisX, nThisY, sal_True ) == bRepeat )
1609 						{
1610 							if ( !pMergeFlag->IsOverlapped() )
1611 							{
1612 								ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
1613 								if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
1614 								{
1615 									Point aEndPos = pViewData->GetScrPos(
1616 											nThisX + pMerge->GetColMerge(),
1617 											nThisY + pMerge->GetRowMerge(), eWhich );
1618 									if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
1619 									{
1620 										aInvert.AddRect( Rectangle( nScrX,nScrY,
1621 													aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
1622 									}
1623 								}
1624 								else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
1625 								{
1626 									aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
1627 								}
1628 							}
1629 						}
1630 					}
1631 					else		// !bTestMerge
1632 					{
1633 						if ( rMark.IsCellMarked( nX, nY, sal_True ) == bRepeat &&
1634 												nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
1635 						{
1636 							aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
1637 						}
1638 					}
1639 
1640 					nScrX = nEndX + nLayoutSign;
1641 				}
1642 			}
1643 			nScrY = nEndY + 1;
1644 		}
1645 	}
1646 
1647 	aInvert.Flush();		// before restoring MapMode
1648 
1649 	SetMapMode(aOld);
1650 
1651 	CheckInverted();
1652 }
1653 
GetSelectionRects(::std::vector<Rectangle> & rPixelRects)1654 void ScGridWindow::GetSelectionRects( ::std::vector< Rectangle >& rPixelRects )
1655 {
1656     // transformed from ScGridWindow::InvertSimple
1657 
1658 //  ScMarkData& rMark = pViewData->GetMarkData();
1659     ScMarkData aMultiMark( pViewData->GetMarkData() );
1660     aMultiMark.SetMarking( sal_False );
1661     aMultiMark.MarkToMulti();
1662 
1663 	ScDocument* pDoc = pViewData->GetDocument();
1664 	SCTAB nTab = pViewData->GetTabNo();
1665 
1666 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1667 	long nLayoutSign = bLayoutRTL ? -1 : 1;
1668 
1669     if ( !aMultiMark.IsMultiMarked() )
1670         return;
1671 
1672     ScRange aMultiRange;
1673     aMultiMark.GetMultiMarkArea( aMultiRange );
1674     SCCOL nX1 = aMultiRange.aStart.Col();
1675     SCROW nY1 = aMultiRange.aStart.Row();
1676     SCCOL nX2 = aMultiRange.aEnd.Col();
1677     SCROW nY2 = aMultiRange.aEnd.Row();
1678 
1679 	PutInOrder( nX1, nX2 );
1680 	PutInOrder( nY1, nY2 );
1681 
1682     sal_Bool bTestMerge = sal_True;
1683     sal_Bool bRepeat = sal_True;
1684 
1685 	SCCOL nTestX2 = nX2;
1686 	SCROW nTestY2 = nY2;
1687 	if (bTestMerge)
1688 		pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
1689 
1690 	SCCOL nPosX = pViewData->GetPosX( eHWhich );
1691 	SCROW nPosY = pViewData->GetPosY( eVWhich );
1692 	if (nTestX2 < nPosX || nTestY2 < nPosY)
1693 		return;											// unsichtbar
1694 	SCCOL nRealX1 = nX1;
1695 	if (nX1 < nPosX)
1696 		nX1 = nPosX;
1697 	if (nY1 < nPosY)
1698 		nY1 = nPosY;
1699 
1700 	SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
1701 	if (nXRight > MAXCOL) nXRight = MAXCOL;
1702 	SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
1703 	if (nYBottom > MAXROW) nYBottom = MAXROW;
1704 
1705 	if (nX1 > nXRight || nY1 > nYBottom)
1706 		return;											// unsichtbar
1707 	if (nX2 > nXRight) nX2 = nXRight;
1708 	if (nY2 > nYBottom) nY2 = nYBottom;
1709 
1710 //	MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);		// erst nach den return's !!!
1711 
1712 	double nPPTX = pViewData->GetPPTX();
1713 	double nPPTY = pViewData->GetPPTY();
1714 
1715     ScInvertMerger aInvert( &rPixelRects );
1716 
1717 	Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
1718 	long nScrY = aScrPos.Y();
1719 	sal_Bool bWasHidden = sal_False;
1720 	for (SCROW nY=nY1; nY<=nY2; nY++)
1721 	{
1722 		sal_Bool bFirstRow = ( nY == nPosY );						// first visible row?
1723 		sal_Bool bDoHidden = sal_False;									// versteckte nachholen ?
1724 		sal_uInt16 nHeightTwips = pDoc->GetRowHeight( nY,nTab );
1725 		sal_Bool bDoRow = ( nHeightTwips != 0 );
1726 		if (bDoRow)
1727 		{
1728 			if (bTestMerge)
1729 				if (bWasHidden)					// auf versteckte zusammengefasste testen
1730 				{
1731 					bDoHidden = sal_True;
1732 					bDoRow = sal_True;
1733 				}
1734 
1735 			bWasHidden = sal_False;
1736 		}
1737 		else
1738 		{
1739 			bWasHidden = sal_True;
1740 			if (bTestMerge)
1741 				if (nY==nY2)
1742 					bDoRow = sal_True;				// letzte Zeile aus Block
1743 		}
1744 
1745 		if ( bDoRow )
1746 		{
1747 			SCCOL nLoopEndX = nX2;
1748 			if (nX2 < nX1)						// Rest von zusammengefasst
1749 			{
1750 				SCCOL nStartX = nX1;
1751 				while ( ((const ScMergeFlagAttr*)pDoc->
1752 							GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() )
1753 					--nStartX;
1754 				if (nStartX <= nX2)
1755 					nLoopEndX = nX1;
1756 			}
1757 
1758 			long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1;
1759 			long nScrX = aScrPos.X();
1760 			for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
1761 			{
1762 				long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX );
1763 				if ( nWidth > 0 )
1764 				{
1765 					long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
1766 					if (bTestMerge)
1767 					{
1768 						SCROW nThisY = nY;
1769 						const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
1770 						const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->
1771 																		GetItem(ATTR_MERGE_FLAG);
1772 						if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
1773 						{
1774 							while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
1775                                     (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) )
1776 							{
1777 								--nThisY;
1778 								pPattern = pDoc->GetPattern( nX, nThisY, nTab );
1779 								pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1780 							}
1781 						}
1782 
1783 						// nur Rest von zusammengefasster zu sehen ?
1784 						SCCOL nThisX = nX;
1785 						if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
1786 						{
1787 							while ( pMergeFlag->IsHorOverlapped() )
1788 							{
1789 								--nThisX;
1790 								pPattern = pDoc->GetPattern( nThisX, nThisY, nTab );
1791 								pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1792 							}
1793 						}
1794 
1795 						if ( aMultiMark.IsCellMarked( nThisX, nThisY, sal_True ) == bRepeat )
1796 						{
1797 							if ( !pMergeFlag->IsOverlapped() )
1798 							{
1799 								ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
1800 								if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
1801 								{
1802 									Point aEndPos = pViewData->GetScrPos(
1803 											nThisX + pMerge->GetColMerge(),
1804 											nThisY + pMerge->GetRowMerge(), eWhich );
1805 									if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
1806 									{
1807 										aInvert.AddRect( Rectangle( nScrX,nScrY,
1808 													aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
1809 									}
1810 								}
1811 								else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
1812 								{
1813 									aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
1814 								}
1815 							}
1816 						}
1817 					}
1818 					else		// !bTestMerge
1819 					{
1820 						if ( aMultiMark.IsCellMarked( nX, nY, sal_True ) == bRepeat &&
1821 												nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
1822 						{
1823 							aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
1824 						}
1825 					}
1826 
1827 					nScrX = nEndX + nLayoutSign;
1828 				}
1829 			}
1830 			nScrY = nEndY + 1;
1831 		}
1832 	}
1833 
1834 //	aInvert.Flush();		// before restoring MapMode
1835 }
1836 
1837 // -------------------------------------------------------------------------
1838 
1839 //UNUSED2008-05  void ScGridWindow::DrawDragRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
1840 //UNUSED2008-05  {
1841 //UNUSED2008-05      if ( nX2 < pViewData->GetPosX(eHWhich) || nY2 < pViewData->GetPosY(eVWhich) )
1842 //UNUSED2008-05          return;
1843 //UNUSED2008-05
1844 //UNUSED2008-05      Update();           // wegen XOR
1845 //UNUSED2008-05
1846 //UNUSED2008-05      MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
1847 //UNUSED2008-05
1848 //UNUSED2008-05      SCTAB nTab = pViewData->GetTabNo();
1849 //UNUSED2008-05
1850 //UNUSED2008-05      SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
1851 //UNUSED2008-05      SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
1852 //UNUSED2008-05      if (nX1 < nPosX) nX1 = nPosX;
1853 //UNUSED2008-05      if (nX2 < nPosX) nX2 = nPosX;
1854 //UNUSED2008-05      if (nY1 < nPosY) nY1 = nPosY;
1855 //UNUSED2008-05      if (nY2 < nPosY) nY2 = nPosY;
1856 //UNUSED2008-05
1857 //UNUSED2008-05      Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
1858 //UNUSED2008-05
1859 //UNUSED2008-05      long nSizeXPix=0;
1860 //UNUSED2008-05      long nSizeYPix=0;
1861 //UNUSED2008-05      ScDocument* pDoc = pViewData->GetDocument();
1862 //UNUSED2008-05      double nPPTX = pViewData->GetPPTX();
1863 //UNUSED2008-05      double nPPTY = pViewData->GetPPTY();
1864 //UNUSED2008-05      SCCOLROW i;
1865 //UNUSED2008-05
1866 //UNUSED2008-05      sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1867 //UNUSED2008-05      long nLayoutSign = bLayoutRTL ? -1 : 1;
1868 //UNUSED2008-05
1869 //UNUSED2008-05      if (ValidCol(nX2) && nX2>=nX1)
1870 //UNUSED2008-05          for (i=nX1; i<=nX2; i++)
1871 //UNUSED2008-05              nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
1872 //UNUSED2008-05      else
1873 //UNUSED2008-05      {
1874 //UNUSED2008-05          aScrPos.X() -= nLayoutSign;
1875 //UNUSED2008-05          nSizeXPix   += 2;
1876 //UNUSED2008-05      }
1877 //UNUSED2008-05
1878 //UNUSED2008-05      if (ValidRow(nY2) && nY2>=nY1)
1879 //UNUSED2008-05          for (i=nY1; i<=nY2; i++)
1880 //UNUSED2008-05              nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
1881 //UNUSED2008-05      else
1882 //UNUSED2008-05      {
1883 //UNUSED2008-05          aScrPos.Y() -= 1;
1884 //UNUSED2008-05          nSizeYPix   += 2;
1885 //UNUSED2008-05      }
1886 //UNUSED2008-05
1887 //UNUSED2008-05      aScrPos.X() -= 2 * nLayoutSign;
1888 //UNUSED2008-05      aScrPos.Y() -= 2;
1889 //UNUSED2008-05  //	Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
1890 //UNUSED2008-05      Rectangle aRect( aScrPos.X(), aScrPos.Y(),
1891 //UNUSED2008-05                       aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
1892 //UNUSED2008-05      if ( bLayoutRTL )
1893 //UNUSED2008-05      {
1894 //UNUSED2008-05          aRect.Left() = aRect.Right();   // end position is left
1895 //UNUSED2008-05          aRect.Right() = aScrPos.X();
1896 //UNUSED2008-05      }
1897 //UNUSED2008-05
1898 //UNUSED2008-05      Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
1899 //UNUSED2008-05      Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
1900 //UNUSED2008-05      Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
1901 //UNUSED2008-05      Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
1902 //UNUSED2008-05
1903 //UNUSED2008-05      SetMapMode(aOld);
1904 //UNUSED2008-05  }
1905 
1906 // -------------------------------------------------------------------------
1907 
DrawCursor()1908 void ScGridWindow::DrawCursor()
1909 {
1910 // #114409#
1911 //	SCTAB nTab = pViewData->GetTabNo();
1912 //	SCCOL nX = pViewData->GetCurX();
1913 //	SCROW nY = pViewData->GetCurY();
1914 //
1915 //	//	in verdeckten Zellen nicht zeichnen
1916 //
1917 //	ScDocument* pDoc = pViewData->GetDocument();
1918 //	const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
1919 //	const ScMergeFlagAttr& rMerge = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
1920 //	if (rMerge.IsOverlapped())
1921 //		return;
1922 //
1923 //	//	links/oben ausserhalb des Bildschirms ?
1924 //
1925 //	sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
1926 //	if (!bVis)
1927 //	{
1928 //		SCCOL nEndX = nX;
1929 //		SCROW nEndY = nY;
1930 //		ScDocument* pDoc = pViewData->GetDocument();
1931 //		const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
1932 //		if (rMerge.GetColMerge() > 1)
1933 //			nEndX += rMerge.GetColMerge()-1;
1934 //		if (rMerge.GetRowMerge() > 1)
1935 //			nEndY += rMerge.GetRowMerge()-1;
1936 //		bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
1937 //	}
1938 //
1939 //	if ( bVis )
1940 //	{
1941 //		//	hier kein Update, da aus Paint gerufen und laut Zaehler Cursor schon da
1942 //		//	wenn Update noetig, dann bei Hide/Showcursor vor dem Hoch-/Runterzaehlen
1943 //
1944 //		MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
1945 //
1946 //		Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
1947 //		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1948 //
1949 //		//	completely right of/below the screen?
1950 //		//	(test with logical start position in aScrPos)
1951 //		sal_Bool bMaybeVisible;
1952 //		if ( bLayoutRTL )
1953 //			bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
1954 //		else
1955 //		{
1956 //			Size aOutSize = GetOutputSizePixel();
1957 //			bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
1958 //		}
1959 //		if ( bMaybeVisible )
1960 //		{
1961 //			long nSizeXPix;
1962 //			long nSizeYPix;
1963 //			pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
1964 //
1965 //			if ( bLayoutRTL )
1966 //				aScrPos.X() -= nSizeXPix - 2;		// move instead of mirroring
1967 //
1968 //			sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
1969 //							pViewData->GetVSplitMode() == SC_SPLIT_FIX );
1970 //			if ( pViewData->GetActivePart()==eWhich || bFix )
1971 //			{
1972 //				//	old UNX version with two Invert calls causes flicker.
1973 //				//	if optimization is needed, a new flag should be added
1974 //				//	to InvertTracking
1975 //
1976 //				aScrPos.X() -= 2;
1977 //				aScrPos.Y() -= 2;
1978 //				Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
1979 //
1980 //				Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
1981 //				Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
1982 //				Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
1983 //				Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
1984 //			}
1985 //			else
1986 //			{
1987 //				Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
1988 //				Invert( aRect );
1989 //			}
1990 //		}
1991 //
1992 //		SetMapMode(aOld);
1993 //	}
1994 }
1995 
1996 	//	AutoFill-Anfasser:
1997 
DrawAutoFillMark()1998 void ScGridWindow::DrawAutoFillMark()
1999 {
2000 // #114409#
2001 //	if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() )
2002 //	{
2003 //		SCCOL nX = aAutoMarkPos.Col();
2004 //		SCROW nY = aAutoMarkPos.Row();
2005 //		SCTAB nTab = pViewData->GetTabNo();
2006 //		ScDocument* pDoc = pViewData->GetDocument();
2007 //		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
2008 //
2009 //		Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
2010 //		long nSizeXPix;
2011 //		long nSizeYPix;
2012 //		pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
2013 //		if ( bLayoutRTL )
2014 //			aFillPos.X() -= nSizeXPix + 3;
2015 //		else
2016 //			aFillPos.X() += nSizeXPix - 2;
2017 //
2018 //		aFillPos.Y() += nSizeYPix;
2019 //		aFillPos.Y() -= 2;
2020 //		Rectangle aFillRect( aFillPos, Size(6,6) );
2021 //		//	Anfasser von Zeichenobjekten sind 7*7
2022 //
2023 //		MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
2024 //		Invert( aFillRect );
2025 //		SetMapMode(aOld);
2026 //	}
2027 }
2028 
2029 // -------------------------------------------------------------------------
2030 
DataChanged(const DataChangedEvent & rDCEvt)2031 void ScGridWindow::DataChanged( const DataChangedEvent& rDCEvt )
2032 {
2033 	Window::DataChanged(rDCEvt);
2034 
2035 	if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
2036 		 (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
2037 		 (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2038 		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2039 		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2040 		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2041 	{
2042 		if ( rDCEvt.GetType() == DATACHANGED_FONTS && eWhich == pViewData->GetActivePart() )
2043 			pViewData->GetDocShell()->UpdateFontList();
2044 
2045 		if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2046 			 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2047 		{
2048 			if ( eWhich == pViewData->GetActivePart() )		// only once for the view
2049 			{
2050 				ScTabView* pView = pViewData->GetView();
2051 
2052 				//	update scale in case the UI ScreenZoom has changed
2053 				ScGlobal::UpdatePPT(this);
2054 				pView->RecalcPPT();
2055 
2056 				//	RepeatResize in case scroll bar sizes have changed
2057 				pView->RepeatResize();
2058                 pView->UpdateAllOverlays();
2059 
2060 				//	invalidate cell attribs in input handler, in case the
2061 				//	EditEngine BackgroundColor has to be changed
2062 				if ( pViewData->IsActive() )
2063 				{
2064 					ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
2065 					if (pHdl)
2066 						pHdl->ForgetLastPattern();
2067 				}
2068 			}
2069 		}
2070 
2071 		Invalidate();
2072 	}
2073 }
2074 
2075 
2076 
2077 
2078