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