xref: /AOO41X/main/sc/source/ui/view/gridwin4.cxx (revision 51b45b885d34684241bbd5d7074220a670520cb5)
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