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