LibreOffice Module sc (master)  1
gridwin4.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <scitems.hxx>
22 #include <editeng/eeitem.hxx>
23 
24 #include <svtools/colorcfg.hxx>
25 #include <editeng/colritem.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/fhgtitem.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/printer.hxx>
30 #include <vcl/cursor.hxx>
31 #include <vcl/settings.hxx>
32 #include <o3tl/unit_conversion.hxx>
33 #include <osl/diagnose.h>
34 
35 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
36 #include <comphelper/lok.hxx>
37 #include <sfx2/lokhelper.hxx>
38 
39 #include <svx/svdview.hxx>
40 #include <svx/svdpagv.hxx>
41 #include <svx/sdrpagewindow.hxx>
45 #include <tabvwsh.hxx>
46 
47 #include <gridwin.hxx>
48 #include <viewdata.hxx>
49 #include <output.hxx>
50 #include <document.hxx>
51 #include <attrib.hxx>
52 #include <patattr.hxx>
53 #include <dbdata.hxx>
54 #include <docoptio.hxx>
55 #include <notemark.hxx>
56 #include <dbfunc.hxx>
57 #include <scmod.hxx>
58 #include <inputhdl.hxx>
59 #include <rfindlst.hxx>
60 #include <hiranges.hxx>
61 #include <pagedata.hxx>
62 #include <docpool.hxx>
63 #include <globstr.hrc>
64 #include <scresid.hxx>
65 #include <docsh.hxx>
66 #include <cbutton.hxx>
67 #include <invmerge.hxx>
68 #include <editutil.hxx>
69 #include <inputopt.hxx>
70 #include <fillinfo.hxx>
71 #include <dpcontrol.hxx>
72 #include <queryparam.hxx>
73 #include <queryentry.hxx>
74 #include <markdata.hxx>
75 #include <sc.hrc>
76 #include <vcl/virdev.hxx>
77 #include <svx/sdrpaintwindow.hxx>
78 #include <drwlayer.hxx>
79 
80 static void lcl_LimitRect( tools::Rectangle& rRect, const tools::Rectangle& rVisible )
81 {
82  if ( rRect.Top() < rVisible.Top()-1 ) rRect.SetTop( rVisible.Top()-1 );
83  if ( rRect.Bottom() > rVisible.Bottom()+1 ) rRect.SetBottom( rVisible.Bottom()+1 );
84 
85  // The header row must be drawn also when the inner rectangle is not visible,
86  // that is why there is no return value anymore.
87  // When it is far away, then lcl_DrawOneFrame is not even called.
88 }
89 
90 static void lcl_DrawOneFrame( vcl::RenderContext* pDev, const tools::Rectangle& rInnerPixel,
91  const OUString& rTitle, const Color& rColor, bool bTextBelow,
92  double nPPTX, double nPPTY, const Fraction& rZoomY,
93  ScDocument& rDoc, ScViewData& rButtonViewData, bool bLayoutRTL )
94 {
95  // rButtonViewData is only used to set the button size,
96 
97  tools::Rectangle aInner = rInnerPixel;
98  if ( bLayoutRTL )
99  {
100  aInner.SetLeft( rInnerPixel.Right() );
101  aInner.SetRight( rInnerPixel.Left() );
102  }
103 
104  tools::Rectangle aVisible( Point(0,0), pDev->GetOutputSizePixel() );
105  lcl_LimitRect( aInner, aVisible );
106 
107  tools::Rectangle aOuter = aInner;
108  tools::Long nHor = static_cast<tools::Long>( SC_SCENARIO_HSPACE * nPPTX );
109  tools::Long nVer = static_cast<tools::Long>( SC_SCENARIO_VSPACE * nPPTY );
110  aOuter.AdjustLeft( -nHor );
111  aOuter.AdjustRight(nHor );
112  aOuter.AdjustTop( -nVer );
113  aOuter.AdjustBottom(nVer );
114 
115  // use ScPatternAttr::GetFont only for font size
116  vcl::Font aAttrFont;
118  GetFont(aAttrFont,SC_AUTOCOL_BLACK,pDev,&rZoomY);
119 
120  // everything else from application font
121  vcl::Font aAppFont = pDev->GetSettings().GetStyleSettings().GetAppFont();
122  aAppFont.SetFontSize( aAttrFont.GetFontSize() );
123 
124  aAppFont.SetAlignment( ALIGN_TOP );
125  pDev->SetFont( aAppFont );
126 
127  Size aTextSize( pDev->GetTextWidth( rTitle ), pDev->GetTextHeight() );
128 
129  if ( bTextBelow )
130  aOuter.AdjustBottom(aTextSize.Height() );
131  else
132  aOuter.AdjustTop( -(aTextSize.Height()) );
133 
134  pDev->SetLineColor();
135  pDev->SetFillColor( rColor );
136  // left, top, right, bottom
137  pDev->DrawRect( tools::Rectangle( aOuter.Left(), aOuter.Top(), aInner.Left(), aOuter.Bottom() ) );
138  pDev->DrawRect( tools::Rectangle( aOuter.Left(), aOuter.Top(), aOuter.Right(), aInner.Top() ) );
139  pDev->DrawRect( tools::Rectangle( aInner.Right(), aOuter.Top(), aOuter.Right(), aOuter.Bottom() ) );
140  pDev->DrawRect( tools::Rectangle( aOuter.Left(), aInner.Bottom(), aOuter.Right(), aOuter.Bottom() ) );
141 
142  tools::Long nButtonY = bTextBelow ? aInner.Bottom() : aOuter.Top();
143 
144  ScDDComboBoxButton aComboButton(pDev);
145  aComboButton.SetOptSizePixel();
146  tools::Long nBWidth = tools::Long(aComboButton.GetSizePixel().Width() * rZoomY);
147  tools::Long nBHeight = nVer + aTextSize.Height() + 1;
148  Size aButSize( nBWidth, nBHeight );
149  tools::Long nButtonPos = bLayoutRTL ? aOuter.Left() : aOuter.Right()-nBWidth+1;
150  aComboButton.Draw( Point(nButtonPos, nButtonY), aButSize );
151  rButtonViewData.SetScenButSize( aButSize );
152 
153  tools::Long nTextStart = bLayoutRTL ? aInner.Right() - aTextSize.Width() + 1 : aInner.Left();
154 
155  bool bWasClip = false;
156  vcl::Region aOldClip;
157  bool bClip = ( aTextSize.Width() > aOuter.Right() - nBWidth - aInner.Left() );
158  if ( bClip )
159  {
160  if (pDev->IsClipRegion())
161  {
162  bWasClip = true;
163  aOldClip = pDev->GetActiveClipRegion();
164  }
165  tools::Long nClipStartX = bLayoutRTL ? aOuter.Left() + nBWidth : aInner.Left();
166  tools::Long nClipEndX = bLayoutRTL ? aInner.Right() : aOuter.Right() - nBWidth;
167  pDev->SetClipRegion( vcl::Region(tools::Rectangle( nClipStartX, nButtonY + nVer/2,
168  nClipEndX, nButtonY + nVer/2 + aTextSize.Height())) );
169  }
170 
171  pDev->DrawText( Point( nTextStart, nButtonY + nVer/2 ), rTitle );
172 
173  if ( bClip )
174  {
175  if ( bWasClip )
176  pDev->SetClipRegion(aOldClip);
177  else
178  pDev->SetClipRegion();
179  }
180 
181  pDev->SetFillColor();
182  pDev->SetLineColor( COL_BLACK );
183  pDev->DrawRect( aInner );
184  pDev->DrawRect( aOuter );
185 }
186 
187 static void lcl_DrawScenarioFrames( OutputDevice* pDev, ScViewData& rViewData, ScSplitPos eWhich,
188  SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
189 {
190  ScDocument& rDoc = rViewData.GetDocument();
191  SCTAB nTab = rViewData.GetTabNo();
192  SCTAB nTabCount = rDoc.GetTableCount();
193  if ( nTab+1 >= nTabCount || !rDoc.IsScenario(nTab+1) || rDoc.IsScenario(nTab) )
194  return;
195 
196  if ( nX1 > 0 ) --nX1;
197  if ( nY1>=2 ) nY1 -= 2; // Hack: Header row affects two cells
198  else if ( nY1 > 0 ) --nY1;
199  if ( nX2 < rDoc.MaxCol() ) ++nX2;
200  if ( nY2 < rDoc.MaxRow()-1 ) nY2 += 2; // Hack: Header row affects two cells
201  else if ( nY2 < rDoc.MaxRow() ) ++nY2;
202  ScRange aViewRange( nX1,nY1,nTab, nX2,nY2,nTab );
203 
205 
206  ScMarkData aMarks(rDoc.GetSheetLimits());
207  for (SCTAB i=nTab+1; i<nTabCount && rDoc.IsScenario(i); i++)
208  rDoc.MarkScenario( i, nTab, aMarks, false, ScScenarioFlags::ShowFrame );
209  ScRangeListRef xRanges = new ScRangeList;
210  aMarks.FillRangeListWithMarks( xRanges.get(), false );
211 
212  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
213  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
214 
215  for (size_t j = 0, n = xRanges->size(); j < n; ++j)
216  {
217  ScRange aRange = (*xRanges)[j];
218  // Always extend scenario frame to merged cells where no new non-covered cells
219  // are framed
220  rDoc.ExtendTotalMerge( aRange );
221 
223 
224  if ( aRange.Intersects( aViewRange ) )
225  {
226  Point aStartPos = rViewData.GetScrPos(
227  aRange.aStart.Col(), aRange.aStart.Row(), eWhich, true );
228  Point aEndPos = rViewData.GetScrPos(
229  aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich, true );
230  // on the grid:
231  aStartPos.AdjustX( -nLayoutSign );
232  aStartPos.AdjustY( -1 );
233  aEndPos.AdjustX( -nLayoutSign );
234  aEndPos.AdjustY( -1 );
235 
236  bool bTextBelow = ( aRange.aStart.Row() == 0 );
237 
238  OUString aCurrent;
239  Color aColor( COL_LIGHTGRAY );
240  for (SCTAB nAct=nTab+1; nAct<nTabCount && rDoc.IsScenario(nAct); nAct++)
241  if ( rDoc.IsActiveScenario(nAct) && rDoc.HasScenarioRange(nAct,aRange) )
242  {
243  OUString aDummyComment;
244  ScScenarioFlags nDummyFlags;
245  rDoc.GetName( nAct, aCurrent );
246  rDoc.GetScenarioData( nAct, aDummyComment, aColor, nDummyFlags );
247  }
248 
249  if (aCurrent.isEmpty())
250  aCurrent = ScResId( STR_EMPTYDATA );
251 
253 
254  lcl_DrawOneFrame( pDev, tools::Rectangle( aStartPos, aEndPos ),
255  aCurrent, aColor, bTextBelow,
256  rViewData.GetPPTX(), rViewData.GetPPTY(), rViewData.GetZoomY(),
257  rDoc, rViewData, bLayoutRTL );
258  }
259  }
260 }
261 
262 static void lcl_DrawHighlight( ScOutputData& rOutputData, const ScViewData& rViewData,
263  const std::vector<ScHighlightEntry>& rHighlightRanges )
264 {
265  SCTAB nTab = rViewData.GetTabNo();
266  for ( const auto& rHighlightRange : rHighlightRanges)
267  {
268  ScRange aRange = rHighlightRange.aRef;
269  if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
270  {
271  rOutputData.DrawRefMark(
272  aRange.aStart.Col(), aRange.aStart.Row(),
273  aRange.aEnd.Col(), aRange.aEnd.Row(),
274  rHighlightRange.aColor, false );
275  }
276  }
277 }
278 
279 // Calculates top-left offset to be applied based on margins and indent.
280 static void lcl_GetEditAreaTLOffset(tools::Long& nOffsetX, tools::Long& nOffsetY, const ScAddress& rAddr,
281  const ScViewData& rViewData, ScDocument& rDoc)
282 {
285  tools::Long nIndent = 0;
286  tools::Long nDummy = 0;
287  ScEditUtil aEUtil(&rDoc, rAddr.Col(), rAddr.Row(), rAddr.Tab(),
288  Point(0, 0), nullptr, rViewData.GetPPTX(),
289  rViewData.GetPPTY(), Fraction(1.0), Fraction(1.0),
290  false /* bPrintTwips */);
291  const ScPatternAttr* pPattern = rDoc.GetPattern(rAddr);
292  nIndent = aEUtil.GetIndent(pPattern);
293  aEUtil.GetMargins(pPattern, nLeftMargin, nTopMargin, nDummy, nDummy);
294  nOffsetX = nIndent + nLeftMargin;
295  nOffsetY = nTopMargin;
296 }
297 
299 {
300  if ( rPixel == aInvertRect )
301  aInvertRect = tools::Rectangle(); // Cancel
302  else
303  {
304  OSL_ENSURE( aInvertRect.IsEmpty(), "DoInvertRect no pairs" );
305 
306  aInvertRect = rPixel; // Mark new rectangle
307  }
308 
309  UpdateHeaderOverlay(); // uses aInvertRect
310 }
311 
313 {
314  // forward PrePaint to DrawingLayer
315  ScTabViewShell* pTabViewShell = mrViewData.GetViewShell();
316 
317  if(pTabViewShell)
318  {
319  SdrView* pDrawView = pTabViewShell->GetScDrawView();
320 
321  if (pDrawView)
322  {
323  pDrawView->PrePaint();
324  }
325  }
326 }
327 
329  const Fraction aScaleX, const Fraction aScaleY)
330 {
331  // Don't see the need for a map as there will be only a few zoom levels
332  // and as of now X and Y zooms in online are the same.
333  for (auto& rEntry : maLOKLastCursor)
334  {
335  if (aScaleX == rEntry.aScaleX && aScaleY == rEntry.aScaleY)
336  {
337  if (rCursorRect == rEntry.aRect)
338  return false; // No change
339 
340  // Update and allow invalidate.
341  rEntry.aRect = rCursorRect;
342  return true;
343  }
344  }
345 
346  maLOKLastCursor.push_back(LOKCursorEntry{aScaleX, aScaleY, rCursorRect});
347  return true;
348 }
349 
351  const Fraction aScaleX, const Fraction aScaleY)
352 {
353  if (!NeedLOKCursorInvalidation(rCursorRect, aScaleX, aScaleY))
354  return;
355 
356  ScTabViewShell* pThisViewShell = mrViewData.GetViewShell();
357  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
358 
359  while (pViewShell)
360  {
361  if (pViewShell != pThisViewShell && pViewShell->GetDocId() == pThisViewShell->GetDocId())
362  {
363  ScTabViewShell* pOtherViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
364  if (pOtherViewShell)
365  {
366  ScViewData& rOtherViewData = pOtherViewShell->GetViewData();
367  Fraction aZoomX = rOtherViewData.GetZoomX();
368  Fraction aZoomY = rOtherViewData.GetZoomY();
369  if (aZoomX == aScaleX && aZoomY == aScaleY)
370  {
371  SfxLokHelper::notifyOtherView(pThisViewShell, pOtherViewShell,
372  LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", rCursorRect.toString());
373  }
374  }
375  }
376 
377  pViewShell = SfxViewShell::GetNext(*pViewShell);
378  }
379 }
380 
381 void ScGridWindow::Paint( vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rRect )
382 {
384  if ( rDoc.IsInInterpreter() )
385  {
386  // Via Reschedule, interpreted cells do not trigger Invalidate again,
387  // otherwise for instance an error box would never appear (bug 36381).
388  // Later, through bNeedsRepaint everything is painted again.
389  if ( bNeedsRepaint )
390  {
392  aRepaintPixel = tools::Rectangle(); // multiple -> paint all
393  }
394  else
395  {
396  bNeedsRepaint = true;
397  aRepaintPixel = LogicToPixel(rRect); // only affected ranges
398  }
399  return;
400  }
401 
402  // #i117893# If GetSizePixel needs to call the resize handler, the resulting nested Paint call
403  // (possibly for a larger rectangle) has to be allowed. Call GetSizePixel before setting bIsInPaint.
404  GetSizePixel();
405 
406  if (bIsInPaint)
407  return;
408 
409  bIsInPaint = true;
410 
411  tools::Rectangle aPixRect = LogicToPixel( rRect );
412 
415 
416  SCTAB nTab = mrViewData.GetTabNo();
417 
418  double nPPTX = mrViewData.GetPPTX();
419  double nPPTY = mrViewData.GetPPTY();
420 
421  tools::Rectangle aMirroredPixel = aPixRect;
422  if ( rDoc.IsLayoutRTL( nTab ) )
423  {
424  // mirror and swap
425  tools::Long nWidth = GetSizePixel().Width();
426  aMirroredPixel.SetLeft( nWidth - 1 - aPixRect.Right() );
427  aMirroredPixel.SetRight( nWidth - 1 - aPixRect.Left() );
428  }
429 
430  tools::Long nScrX = ScViewData::ToPixel( rDoc.GetColWidth( nX1, nTab ), nPPTX );
431  while ( nScrX <= aMirroredPixel.Left() && nX1 < rDoc.MaxCol() )
432  {
433  ++nX1;
434  nScrX += ScViewData::ToPixel( rDoc.GetColWidth( nX1, nTab ), nPPTX );
435  }
436  SCCOL nX2 = nX1;
437  while ( nScrX <= aMirroredPixel.Right() && nX2 < rDoc.MaxCol() )
438  {
439  ++nX2;
440  nScrX += ScViewData::ToPixel( rDoc.GetColWidth( nX2, nTab ), nPPTX );
441  }
442 
443  tools::Long nScrY = 0;
444  ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, rDoc.MaxRow(), nPPTY, &rDoc, nTab);
445  SCROW nY2 = nY1;
446  if (nScrY <= aPixRect.Bottom() && nY2 < rDoc.MaxRow())
447  {
448  ++nY2;
449  ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, rDoc.MaxRow(), nPPTY, &rDoc, nTab);
450  }
451 
452  Draw( nX1,nY1,nX2,nY2, ScUpdateMode::Marks ); // don't continue with painting
453 
454  bIsInPaint = false;
455 }
456 
457 void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMode eMode )
458 {
460 
461  // let's ignore the normal Draw() attempts when doing the tiled rendering,
462  // all the rendering should go through PaintTile() in that case.
463  // TODO revisit if we can actually turn this into an assert(), and clean
464  // up the callers
466  return;
467 
468  ScModule* pScMod = SC_MOD();
469  bool bTextWysiwyg = pScMod->GetInputOptions().GetTextWysiwyg();
470 
471  if (mrViewData.IsMinimized())
472  return;
473 
474  PutInOrder( nX1, nX2 );
475  PutInOrder( nY1, nY2 );
476 
477  OSL_ENSURE( rDoc.ValidCol(nX2) && rDoc.ValidRow(nY2), "GridWin Draw area too big" );
478 
480 
481  if (nX2 < maVisibleRange.mnCol1 || nY2 < maVisibleRange.mnRow1)
482  return;
483  // invisible
484  if (nX1 < maVisibleRange.mnCol1)
485  nX1 = maVisibleRange.mnCol1;
486  if (nY1 < maVisibleRange.mnRow1)
487  nY1 = maVisibleRange.mnRow1;
488 
489  if (nX1 > maVisibleRange.mnCol2 || nY1 > maVisibleRange.mnRow2)
490  return;
491 
492  if (nX2 > maVisibleRange.mnCol2)
493  nX2 = maVisibleRange.mnCol2;
494  if (nY2 > maVisibleRange.mnRow2)
495  nY2 = maVisibleRange.mnRow2;
496 
497  if ( eMode != ScUpdateMode::Marks && nX2 < maVisibleRange.mnCol2)
498  nX2 = maVisibleRange.mnCol2; // to continue painting
499 
500  // point of no return
501 
502  ++nPaintCount; // mark that painting is in progress
503 
504  SCTAB nTab = mrViewData.GetTabNo();
505  rDoc.ExtendHidden( nX1, nY1, nX2, nY2, nTab );
506 
507  Point aScrPos = mrViewData.GetScrPos( nX1, nY1, eWhich );
508  tools::Long nMirrorWidth = GetSizePixel().Width();
509  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
510  if ( bLayoutRTL )
511  {
512  tools::Long nEndPixel = mrViewData.GetScrPos( nX2+1, maVisibleRange.mnRow1, eWhich ).X();
513  nMirrorWidth = aScrPos.X() - nEndPixel;
514  aScrPos.setX( nEndPixel + 1 );
515  }
516 
517  tools::Long nScrX = aScrPos.X();
518  tools::Long nScrY = aScrPos.Y();
519 
520  SCCOL nCurX = mrViewData.GetCurX();
521  SCROW nCurY = mrViewData.GetCurY();
522  SCCOL nCurEndX = nCurX;
523  SCROW nCurEndY = nCurY;
524  rDoc.ExtendMerge( nCurX, nCurY, nCurEndX, nCurEndY, nTab );
525  bool bCurVis = nCursorHideCount==0 &&
526  ( nCurEndX+1 >= nX1 && nCurX <= nX2+1 && nCurEndY+1 >= nY1 && nCurY <= nY2+1 );
527 
528  // AutoFill Handles
529  if ( !bCurVis && nCursorHideCount==0 && bAutoMarkVisible && aAutoMarkPos.Tab() == nTab &&
530  ( aAutoMarkPos.Col() != nCurX || aAutoMarkPos.Row() != nCurY ) )
531  {
532  SCCOL nHdlX = aAutoMarkPos.Col();
533  SCROW nHdlY = aAutoMarkPos.Row();
534  rDoc.ExtendMerge( nHdlX, nHdlY, nHdlX, nHdlY, nTab );
535  // left and top is unaffected
536 
538  }
539 
540  double nPPTX = mrViewData.GetPPTX();
541  double nPPTY = mrViewData.GetPPTY();
542 
543  const ScViewOptions& rOpts = mrViewData.GetOptions();
544 
545  // data block
546 
547  ScTableInfo aTabInfo;
548  rDoc.FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
549  nPPTX, nPPTY, false, rOpts.GetOption(VOPT_FORMULAS),
550  &mrViewData.GetMarkData() );
551 
552  Fraction aZoomX = mrViewData.GetZoomX();
553  Fraction aZoomY = mrViewData.GetZoomY();
554  ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, &rDoc, nTab,
555  nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
556  &aZoomX, &aZoomY );
557 
558  aOutputData.SetMirrorWidth( nMirrorWidth ); // needed for RTL
559  aOutputData.SetSpellCheckContext(mpSpellCheckCxt.get());
560 
561  ScopedVclPtr< VirtualDevice > xFmtVirtDev;
562  bool bLogicText = bTextWysiwyg; // call DrawStrings in logic MapMode?
563 
564  if ( bTextWysiwyg )
565  {
566  // use printer for text formatting
567 
568  OutputDevice* pFmtDev = rDoc.GetPrinter();
570  aOutputData.SetFmtDevice( pFmtDev );
571  }
572  else if ( aZoomX != aZoomY && mrViewData.IsOle() )
573  {
574  // #i45033# For OLE inplace editing with different zoom factors,
575  // use a virtual device with 1/100th mm as text formatting reference
576 
578  xFmtVirtDev->SetMapMode(MapMode(MapUnit::Map100thMM));
579  aOutputData.SetFmtDevice( xFmtVirtDev.get() );
580 
581  bLogicText = true; // use logic MapMode
582  }
583 
584  DrawContent(*this, aTabInfo, aOutputData, bLogicText);
585 
586  // If something was inverted during the Paint (selection changed from Basic Macro)
587  // then this is now mixed up and has to be repainted
588  OSL_ENSURE(nPaintCount, "Wrong nPaintCount");
589  --nPaintCount;
590  if (!nPaintCount)
592 
593  // Flag drawn formula cells "unchanged".
594  rDoc.ResetChanged(ScRange(nX1, nY1, nTab, nX2, nY2, nTab));
595  rDoc.PrepareFormulaCalc();
596 }
597 
598 namespace {
599 
600 class SuppressEditViewMessagesGuard
601 {
602 public:
603  SuppressEditViewMessagesGuard(EditView& rEditView) :
604  mrEditView(rEditView),
605  mbOrigSuppressFlag(rEditView.IsSuppressLOKMessages())
606  {
607  if (!mbOrigSuppressFlag)
608  mrEditView.SuppressLOKMessages(true);
609  }
610 
611  ~SuppressEditViewMessagesGuard()
612  {
613  if (mrEditView.IsSuppressLOKMessages() != mbOrigSuppressFlag)
614  mrEditView.SuppressLOKMessages(mbOrigSuppressFlag);
615  }
616 
617 private:
618  EditView& mrEditView;
619  const bool mbOrigSuppressFlag;
620 };
621 
622 }
623 
624 void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableInfo, ScOutputData& aOutputData,
625  bool bLogicText)
626 {
627  ScModule* pScMod = SC_MOD();
629  const ScViewOptions& rOpts = mrViewData.GetOptions();
630  bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
631  bool bNoBackgroundAndGrid = bIsTiledRendering
633  comphelper::LibreOfficeKit::Compat::scNoGridBackground);
634 
635  SCTAB nTab = aOutputData.nTab;
636  SCCOL nX1 = aOutputData.nX1;
637  SCROW nY1 = aOutputData.nY1;
638  SCCOL nX2 = aOutputData.nX2;
639  SCROW nY2 = aOutputData.nY2;
640  tools::Long nScrX = aOutputData.nScrX;
641  tools::Long nScrY = aOutputData.nScrY;
642 
643  const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
644  Color aGridColor( rColorCfg.GetColorValue( svtools::CALCGRID, false ).nColor );
645  if ( aGridColor == COL_TRANSPARENT )
646  {
647  // use view options' grid color only if color config has "automatic" color
648  aGridColor = rOpts.GetGridColor();
649  }
650 
651  aOutputData.SetSyntaxMode ( mrViewData.IsSyntaxMode() );
652  aOutputData.SetGridColor ( aGridColor );
653  aOutputData.SetShowNullValues ( rOpts.GetOption( VOPT_NULLVALS ) );
654  aOutputData.SetShowFormulas ( rOpts.GetOption( VOPT_FORMULAS ) );
655  aOutputData.SetShowSpellErrors ( rDoc.GetDocOptions().IsAutoSpell() );
656  aOutputData.SetMarkClipped ( rOpts.GetOption( VOPT_CLIPMARKS ) );
657 
658  aOutputData.SetUseStyleColor( true ); // always set in table view
659 
660  aOutputData.SetViewShell( mrViewData.GetViewShell() );
661 
662  bool bGrid = rOpts.GetOption( VOPT_GRID ) && mrViewData.GetShowGrid();
663  bool bGridFirst = !rOpts.GetOption( VOPT_GRID_ONTOP );
664 
665  bool bPage = rOpts.GetOption( VOPT_PAGEBREAKS ) && !bIsTiledRendering;
666 
667  bool bPageMode = mrViewData.IsPagebreakMode();
668  if (bPageMode) // after FindChanged
669  {
670  // SetPagebreakMode also initializes bPrinted Flags
672  }
673 
674  EditView* pEditView = nullptr;
675  bool bEditMode = mrViewData.HasEditView(eWhich);
676  if ( bEditMode && mrViewData.GetRefTabNo() == nTab )
677  {
678  SCCOL nEditCol;
679  SCROW nEditRow;
680  mrViewData.GetEditView( eWhich, pEditView, nEditCol, nEditRow );
681  SCCOL nEditEndCol = mrViewData.GetEditEndCol();
682  SCROW nEditEndRow = mrViewData.GetEditEndRow();
683 
684  if ( nEditEndCol >= nX1 && nEditCol <= nX2 && nEditEndRow >= nY1 && nEditRow <= nY2 )
685  aOutputData.SetEditCell( nEditCol, nEditRow );
686  else
687  bEditMode = false;
688  }
689 
690  const MapMode aOriginalMode = rDevice.GetMapMode();
691 
692  // define drawing layer map mode and paint rectangle
693  MapMode aDrawMode = GetDrawMapMode();
694  if (bIsTiledRendering)
695  {
696  // FIXME this shouldn't be necessary once we change the entire Calc to
697  // work in the logic coordinates (ideally 100ths of mm - so that it is
698  // the same as editeng and drawinglayer), and get rid of all the
699  // SetMapMode's and other unnecessary fun we have with pixels
700  // See also ScGridWindow::GetDrawMapMode() for the rest of this hack
701  aDrawMode.SetOrigin(PixelToLogic(Point(nScrX, nScrY), aDrawMode));
702  }
703  tools::Rectangle aDrawingRectLogic;
704  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
705 
706  {
707  // get drawing pixel rect
708  tools::Rectangle aDrawingRectPixel(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
709 
710  // correct for border (left/right)
711  if(rDoc.MaxCol() == nX2)
712  {
713  if(bLayoutRTL)
714  {
715  aDrawingRectPixel.SetLeft( 0 );
716  }
717  else
718  {
719  aDrawingRectPixel.SetRight( GetOutputSizePixel().getWidth() );
720  }
721  }
722 
723  // correct for border (bottom)
724  if(rDoc.MaxRow() == nY2)
725  {
726  aDrawingRectPixel.SetBottom( GetOutputSizePixel().getHeight() );
727  }
728 
729  // get logic positions
730  aDrawingRectLogic = PixelToLogic(aDrawingRectPixel, aDrawMode);
731  }
732 
733  bool bInPlaceEditing = bEditMode && (mrViewData.GetRefTabNo() == mrViewData.GetTabNo());
734  vcl::Cursor* pInPlaceCrsr = nullptr;
735  bool bInPlaceVisCursor = false;
736  if (bInPlaceEditing)
737  {
738  // toggle the cursor off if its on to ensure the cursor invert
739  // background logic remains valid after the background is cleared on
740  // the next cursor flash
741  pInPlaceCrsr = pEditView->GetCursor();
742  bInPlaceVisCursor = pInPlaceCrsr && pInPlaceCrsr->IsVisible();
743  if (bInPlaceVisCursor)
744  pInPlaceCrsr->Hide();
745  }
746 
747  OutputDevice* pContentDev = &rDevice; // device for document content, used by overlay manager
748  SdrPaintWindow* pTargetPaintWindow = nullptr; // #i74769# work with SdrPaintWindow directly
749 
750  {
751  // init redraw
752  ScTabViewShell* pTabViewShell = mrViewData.GetViewShell();
753 
754  if(pTabViewShell)
755  {
756  MapMode aCurrentMapMode(pContentDev->GetMapMode());
757  pContentDev->SetMapMode(aDrawMode);
758  SdrView* pDrawView = pTabViewShell->GetScDrawView();
759 
760  if(pDrawView)
761  {
762  // #i74769# Use new BeginDrawLayers() interface
763  vcl::Region aDrawingRegion(aDrawingRectLogic);
764  pTargetPaintWindow = pDrawView->BeginDrawLayers(pContentDev, aDrawingRegion);
765  OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
766 
767  if (!bIsTiledRendering)
768  {
769  // #i74769# get target device from SdrPaintWindow, this may be the prerender
770  // device now, too.
771  pContentDev = &(pTargetPaintWindow->GetTargetOutputDevice());
772  aOutputData.SetContentDevice(pContentDev);
773  }
774  }
775 
776  pContentDev->SetMapMode(aCurrentMapMode);
777  }
778  }
779 
780  // edge (area) (Pixel)
781  if ( nX2==rDoc.MaxCol() || nY2==rDoc.MaxRow() )
782  {
783  // save MapMode and set to pixel
784  MapMode aCurrentMapMode(pContentDev->GetMapMode());
785  pContentDev->SetMapMode(MapMode(MapUnit::MapPixel));
786 
787  tools::Rectangle aPixRect( Point(), GetOutputSizePixel() );
788  pContentDev->SetFillColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
789  pContentDev->SetLineColor();
790  if ( nX2==rDoc.MaxCol() )
791  {
792  tools::Rectangle aDrawRect( aPixRect );
793  if ( bLayoutRTL )
794  aDrawRect.SetRight( nScrX - 1 );
795  else
796  aDrawRect.SetLeft( nScrX + aOutputData.GetScrW() );
797  if (aDrawRect.Right() >= aDrawRect.Left())
798  pContentDev->DrawRect( aDrawRect );
799  }
800  if ( nY2==rDoc.MaxRow() )
801  {
802  tools::Rectangle aDrawRect( aPixRect );
803  aDrawRect.SetTop( nScrY + aOutputData.GetScrH() );
804  if ( nX2==rDoc.MaxCol() )
805  {
806  // no double painting of the corner
807  if ( bLayoutRTL )
808  aDrawRect.SetLeft( nScrX );
809  else
810  aDrawRect.SetRight( nScrX + aOutputData.GetScrW() - 1 );
811  }
812  if (aDrawRect.Bottom() >= aDrawRect.Top())
813  pContentDev->DrawRect( aDrawRect );
814  }
815 
816  // restore MapMode
817  pContentDev->SetMapMode(aCurrentMapMode);
818  }
819 
820  if ( rDoc.HasBackgroundDraw( nTab, aDrawingRectLogic ) )
821  {
822  pContentDev->SetMapMode(MapMode(MapUnit::MapPixel));
823  aOutputData.DrawClear();
824 
825  // drawing background
826 
827  pContentDev->SetMapMode(aDrawMode);
828  DrawRedraw( aOutputData, SC_LAYER_BACK );
829  }
830  else
831  aOutputData.SetSolidBackground(!bNoBackgroundAndGrid);
832 
833  aOutputData.DrawDocumentBackground();
834 
835  if (bGridFirst && (bGrid || bPage))
836  {
837  // Draw lines in background color cover over lok client grid lines in merged cell areas if bNoBackgroundAndGrid is set.
838  if (bNoBackgroundAndGrid)
839  aOutputData.DrawGrid(*pContentDev, false /* bGrid */, false /* bPage */, true /* bMergeCover */);
840  else
841  aOutputData.DrawGrid(*pContentDev, bGrid, bPage);
842  }
843 
844  aOutputData.DrawBackground(*pContentDev);
845 
846  if (!bGridFirst && (bGrid || bPage) && !bNoBackgroundAndGrid)
847  aOutputData.DrawGrid(*pContentDev, bGrid, bPage);
848 
849  pContentDev->SetMapMode(MapMode(MapUnit::MapPixel));
850 
851  if ( bPageMode )
852  {
853  // DrawPagePreview draws complete lines/page numbers, must always be clipped
854  if ( aOutputData.SetChangedClip() )
855  {
856  DrawPagePreview(nX1,nY1,nX2,nY2, *pContentDev);
857  pContentDev->SetClipRegion();
858  }
859  }
860 
861  aOutputData.DrawShadow();
862  aOutputData.DrawFrame(*pContentDev);
863 
864  // Show Note Mark
865  if ( rOpts.GetOption( VOPT_NOTES ) )
866  aOutputData.DrawNoteMarks(*pContentDev);
867 
868  if ( !bLogicText )
869  aOutputData.DrawStrings(); // in pixel MapMode
870 
871  // edit cells and printer-metrics text must be before the buttons
872  // (DataPilot buttons contain labels in UI font)
873 
874  pContentDev->SetMapMode(mrViewData.GetLogicMode(eWhich));
875  if ( bLogicText )
876  aOutputData.DrawStrings(true); // in logic MapMode if bLogicText is set
877  aOutputData.DrawEdit(true);
878 
879  // the buttons are painted in absolute coordinates
880  if (bIsTiledRendering)
881  {
882  // Tiled offset nScrX, nScrY
883  MapMode aMap( MapUnit::MapPixel );
884  Point aOrigin = aOriginalMode.GetOrigin();
885  aOrigin.setX(o3tl::convert(aOrigin.getX(), o3tl::Length::twip, o3tl::Length::px) + nScrX);
886  aOrigin.setY(o3tl::convert(aOrigin.getY(), o3tl::Length::twip, o3tl::Length::px) + nScrY);
887  aMap.SetOrigin(aOrigin);
888  pContentDev->SetMapMode(aMap);
889  }
890  else
891  pContentDev->SetMapMode(MapMode(MapUnit::MapPixel));
892 
893  // Autofilter- and Pivot-Buttons
894 
895  DrawButtons(nX1, nX2, rTableInfo, pContentDev); // Pixel
896 
897  pContentDev->SetMapMode(MapMode(MapUnit::MapPixel));
898 
899  aOutputData.DrawClipMarks();
900 
901  // In any case, Scenario / ChangeTracking must happen after DrawGrid, also for !bGridFirst
902 
905 
906  SCTAB nTabCount = rDoc.GetTableCount();
907  const std::vector<ScHighlightEntry> &rHigh = mrViewData.GetView()->GetHighlightRanges();
908  bool bHasScenario = ( nTab+1<nTabCount && rDoc.IsScenario(nTab+1) && !rDoc.IsScenario(nTab) );
909  bool bHasChange = ( rDoc.GetChangeTrack() != nullptr );
910 
911  if ( bHasChange || bHasScenario || !rHigh.empty() )
912  {
914 
915  if ( bHasChange )
916  aOutputData.DrawChangeTrack();
917 
918  if ( bHasScenario )
919  lcl_DrawScenarioFrames( pContentDev, mrViewData, eWhich, nX1,nY1,nX2,nY2 );
920 
921  lcl_DrawHighlight( aOutputData, mrViewData, rHigh );
922  }
923 
924  // Drawing foreground
925 
926  pContentDev->SetMapMode(aDrawMode);
927 
928  // Bitmaps and buttons are in absolute pixel coordinates.
929  const MapMode aOrig = pContentDev->GetMapMode();
930  if (bIsTiledRendering)
931  {
932  Point aOrigin = aOriginalMode.GetOrigin();
933  Size aPixelOffset(o3tl::convert(aOrigin.getX(), o3tl::Length::twip, o3tl::Length::px),
935  pContentDev->SetPixelOffset(aPixelOffset);
937  }
938 
939  DrawRedraw( aOutputData, SC_LAYER_FRONT );
940  DrawRedraw( aOutputData, SC_LAYER_INTERN );
941  DrawSdrGrid( aDrawingRectLogic, pContentDev );
942 
943  if (bIsTiledRendering)
944  {
945  pContentDev->SetPixelOffset(Size());
946  pContentDev->SetMapMode(aOrig);
947  }
948 
949  pContentDev->SetMapMode(MapMode(MapUnit::MapPixel));
950 
951  if ( mrViewData.IsRefMode() && nTab >= mrViewData.GetRefStartZ() && nTab <= mrViewData.GetRefEndZ() )
952  {
953  Color aRefColor( rColorCfg.GetColorValue(svtools::CALCREFERENCE).nColor );
956  aRefColor, false );
957  }
958 
959  // range finder
960 
961  ScInputHandler* pHdl = pScMod->GetInputHdl( mrViewData.GetViewShell() );
962  if (pHdl)
963  {
964  ScDocShell* pDocSh = mrViewData.GetDocShell();
965  ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
966  if ( pRangeFinder && !pRangeFinder->IsHidden() &&
967  pRangeFinder->GetDocName() == pDocSh->GetTitle() )
968  {
969  sal_uInt16 nCount = static_cast<sal_uInt16>(pRangeFinder->Count());
970  for (sal_uInt16 i=0; i<nCount; i++)
971  {
972  ScRangeFindData& rData = pRangeFinder->GetObject(i);
973 
974  ScRange aRef = rData.aRef;
975  aRef.PutInOrder();
976  if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
977  aOutputData.DrawRefMark( aRef.aStart.Col(), aRef.aStart.Row(),
978  aRef.aEnd.Col(), aRef.aEnd.Row(),
979  rData.nColor,
980  true );
981  }
982  }
983  }
984 
985  {
986  // end redraw
987  ScTabViewShell* pTabViewShell = mrViewData.GetViewShell();
988 
989  if(pTabViewShell)
990  {
991  MapMode aCurrentMapMode(pContentDev->GetMapMode());
992  pContentDev->SetMapMode(aDrawMode);
993 
994  if (bIsTiledRendering)
995  {
996  Point aOrigin = aOriginalMode.GetOrigin();
997  aOrigin.setX(o3tl::convert(aOrigin.getX(), o3tl::Length::twip, o3tl::Length::px)
998  + aOutputData.nScrX);
999  aOrigin.setY(o3tl::convert(aOrigin.getY(), o3tl::Length::twip, o3tl::Length::px)
1000  + aOutputData.nScrY);
1001  const double twipFactor = 15 * 1.76388889; // 26.45833335
1002  aOrigin = Point(aOrigin.getX() * twipFactor,
1003  aOrigin.getY() * twipFactor);
1004  MapMode aNew = rDevice.GetMapMode();
1005  aNew.SetOrigin(aOrigin);
1006  rDevice.SetMapMode(aNew);
1007  }
1008 
1009  SdrView* pDrawView = pTabViewShell->GetScDrawView();
1010 
1011  if(pDrawView)
1012  {
1013  // #i74769# work with SdrPaintWindow directly
1014  pDrawView->EndDrawLayers(*pTargetPaintWindow, true);
1015  }
1016 
1017  pContentDev->SetMapMode(aCurrentMapMode);
1018  }
1019  }
1020 
1021  // paint in-place editing on other views
1022  if (bIsTiledRendering)
1023  {
1024  ScTabViewShell* pThisViewShell = mrViewData.GetViewShell();
1025  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1026 
1027  while (pViewShell)
1028  {
1029  if (pViewShell != pThisViewShell && pViewShell->GetDocId() == pThisViewShell->GetDocId())
1030  {
1031  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
1032  if (pTabViewShell)
1033  {
1034  ScViewData& rOtherViewData = pTabViewShell->GetViewData();
1035  ScSplitPos eOtherWhich = rOtherViewData.GetEditActivePart();
1036 
1037  bool bOtherEditMode = rOtherViewData.HasEditView(eOtherWhich);
1038  SCCOL nCol1 = rOtherViewData.GetEditStartCol();
1039  SCROW nRow1 = rOtherViewData.GetEditStartRow();
1040  SCCOL nCol2 = rOtherViewData.GetEditEndCol();
1041  SCROW nRow2 = rOtherViewData.GetEditEndRow();
1042  bOtherEditMode = bOtherEditMode
1043  && ( nCol2 >= nX1 && nCol1 <= nX2 && nRow2 >= nY1 && nRow1 <= nY2 );
1044  if (bOtherEditMode && rOtherViewData.GetRefTabNo() == nTab)
1045  {
1046  EditView* pOtherEditView = rOtherViewData.GetEditView(eOtherWhich);
1047  if (pOtherEditView)
1048  {
1049  tools::Long nScreenX = aOutputData.nScrX;
1050  tools::Long nScreenY = aOutputData.nScrY;
1051 
1052  rDevice.SetLineColor();
1053  rDevice.SetFillColor(pOtherEditView->GetBackgroundColor());
1054  Point aStart = mrViewData.GetScrPos( nCol1, nRow1, eOtherWhich );
1055  Point aEnd = mrViewData.GetScrPos( nCol2+1, nRow2+1, eOtherWhich );
1056 
1057  // don't overwrite grid
1058  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1059  aEnd.AdjustX( -(2 * nLayoutSign) );
1060  aEnd.AdjustY( -2 );
1061 
1062  tools::Rectangle aBackground(aStart, aEnd);
1063 
1064  // Need to draw the background in absolute coords.
1065  Point aOrigin = aOriginalMode.GetOrigin();
1066  aOrigin.setX(
1068  + nScreenX);
1069  aOrigin.setY(
1071  + nScreenY);
1072  aBackground += aOrigin;
1073  rDevice.SetMapMode(aDrawMode);
1074 
1075  static const double twipFactor = 15 * 1.76388889; // 26.45833335
1076  // keep into account the zoom factor
1077  aOrigin = Point((aOrigin.getX() * twipFactor) / static_cast<double>(aDrawMode.GetScaleX()),
1078  (aOrigin.getY() * twipFactor) / static_cast<double>(aDrawMode.GetScaleY()));
1079 
1080  MapMode aNew = rDevice.GetMapMode();
1081  aNew.SetOrigin(aOrigin);
1082  rDevice.SetMapMode(aNew);
1083 
1084  // paint the background
1085  rDevice.DrawRect(rDevice.PixelToLogic(aBackground));
1086 
1087  tools::Rectangle aEditRect(aBackground);
1088  tools::Long nOffsetX = 0, nOffsetY = 0;
1089  // Get top-left offset because of margin and indent.
1090  lcl_GetEditAreaTLOffset(nOffsetX, nOffsetY, ScAddress(nCol1, nRow1, nTab), mrViewData, rDoc);
1091  aEditRect.AdjustLeft(nOffsetX + 1);
1092  aEditRect.AdjustTop(nOffsetY + 1);
1093 
1094  // EditView has an 'output area' which is used to clip the 'paint area' we provide below.
1095  // So they need to be in the same coordinates/units. This is tied to the mapmode of the gridwin
1096  // attached to the EditView, so we have to change its mapmode too (temporarily). We save the
1097  // original mapmode and 'output area' and roll them back when we finish painting to rDevice.
1098  OutputDevice& rOtherWin = pOtherEditView->GetOutputDevice();
1099  const tools::Rectangle aOrigOutputArea(pOtherEditView->GetOutputArea()); // Not in pixels.
1100  const MapMode aOrigMapMode = rOtherWin.GetMapMode();
1101  rOtherWin.SetMapMode(rDevice.GetMapMode());
1102 
1103  // Avoid sending wrong cursor/selection messages by the 'other' view, as the output-area is going
1104  // to be tweaked temporarily to match the current view's zoom.
1105  SuppressEditViewMessagesGuard aGuard(*pOtherEditView);
1106 
1107  pOtherEditView->SetOutputArea(rDevice.PixelToLogic(aEditRect));
1108  pOtherEditView->Paint(rDevice.PixelToLogic(aEditRect), &rDevice);
1109 
1110  // Rollback the mapmode and 'output area'.
1111  rOtherWin.SetMapMode(aOrigMapMode);
1112  pOtherEditView->SetOutputArea(aOrigOutputArea);
1113  rDevice.SetMapMode(MapMode(MapUnit::MapPixel));
1114  }
1115  }
1116  }
1117  }
1118 
1119  pViewShell = SfxViewShell::GetNext(*pViewShell);
1120  }
1121 
1122  }
1123 
1124  // In-place editing - when the user is typing, we need to paint the text
1125  // using the editeng.
1126  // It's being done after EndDrawLayers() to get it outside the overlay
1127  // buffer and on top of everything.
1128  if (bInPlaceEditing)
1129  {
1130  // get the coordinates of the area we need to clear (overpaint by
1131  // the background)
1132  SCCOL nCol1 = mrViewData.GetEditStartCol();
1133  SCROW nRow1 = mrViewData.GetEditStartRow();
1134  SCCOL nCol2 = mrViewData.GetEditEndCol();
1135  SCROW nRow2 = mrViewData.GetEditEndRow();
1136  rDevice.SetLineColor();
1137  rDevice.SetFillColor(pEditView->GetBackgroundColor());
1138  Point aStart = mrViewData.GetScrPos( nCol1, nRow1, eWhich );
1139  Point aEnd = mrViewData.GetScrPos( nCol2+1, nRow2+1, eWhich );
1140 
1141  // don't overwrite grid
1142  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1143  aEnd.AdjustX( -(2 * nLayoutSign) );
1144  aEnd.AdjustY( -2 );
1145 
1146  // set the correct mapmode
1147  tools::Rectangle aBackground(aStart, aEnd);
1148  tools::Rectangle aBGAbs(aStart, aEnd);
1149 
1150  if (bIsTiledRendering)
1151  {
1152  // Need to draw the background in absolute coords.
1153  Point aOrigin = aOriginalMode.GetOrigin();
1154  aOrigin.setX(o3tl::convert(aOrigin.getX(), o3tl::Length::twip, o3tl::Length::px)
1155  + nScrX);
1156  aOrigin.setY(o3tl::convert(aOrigin.getY(), o3tl::Length::twip, o3tl::Length::px)
1157  + nScrY);
1158  aBackground += aOrigin;
1159  rDevice.SetMapMode(aDrawMode);
1160  }
1161  else
1162  rDevice.SetMapMode(mrViewData.GetLogicMode());
1163 
1164  if (bIsTiledRendering)
1165  {
1166  Point aOrigin = aOriginalMode.GetOrigin();
1167  aOrigin.setX(o3tl::convert(aOrigin.getX(), o3tl::Length::twip, o3tl::Length::px)
1168  + nScrX);
1169  aOrigin.setY(o3tl::convert(aOrigin.getY(), o3tl::Length::twip, o3tl::Length::px)
1170  + nScrY);
1171  static const double twipFactor = 15 * 1.76388889; // 26.45833335
1172  // keep into account the zoom factor
1173  aOrigin = Point((aOrigin.getX() * twipFactor) / static_cast<double>(aDrawMode.GetScaleX()),
1174  (aOrigin.getY() * twipFactor) / static_cast<double>(aDrawMode.GetScaleY()));
1175  MapMode aNew = rDevice.GetMapMode();
1176  aNew.SetOrigin(aOrigin);
1177  rDevice.SetMapMode(aNew);
1178  }
1179 
1180  // paint the background
1181  tools::Rectangle aLogicRect(rDevice.PixelToLogic(aBackground));
1182  //tdf#100925, rhbz#1283420, Draw some text here, to get
1183  //X11CairoTextRender::getCairoContext called, so that the forced read
1184  //from the underlying X Drawable gets it to sync.
1185  rDevice.DrawText(aLogicRect.BottomLeft(), " ");
1186  rDevice.DrawRect(aLogicRect);
1187 
1188  // paint the editeng text
1189  if (bIsTiledRendering)
1190  {
1191  tools::Rectangle aEditRect(aBackground);
1192  tools::Long nOffsetX = 0, nOffsetY = 0;
1193  // Get top-left offset because of margin and indent.
1194  lcl_GetEditAreaTLOffset(nOffsetX, nOffsetY, ScAddress(nCol1, nRow1, mrViewData.GetTabNo()), mrViewData, rDoc);
1195  aEditRect.AdjustLeft(nOffsetX + 1);
1196  aEditRect.AdjustTop(nOffsetY + 1);
1197 
1198  // EditView has an 'output area' which is used to clip the paint area we provide below.
1199  // So they need to be in the same coordinates/units. This is tied to the mapmode of the gridwin
1200  // attached to the EditView, so we have to change its mapmode too (temporarily). We save the
1201  // original mapmode and 'output area' and roll them back when we finish painting to rDevice.
1202  const tools::Rectangle aOrigOutputArea(pEditView->GetOutputArea()); // Not in pixels.
1203  const MapMode aOrigMapMode = GetMapMode();
1204  SetMapMode(rDevice.GetMapMode());
1205 
1206  // Avoid sending wrong cursor/selection messages by the current view, as the output-area is going
1207  // to be tweaked temporarily to match other view's zoom. (This does not affect the manual
1208  // cursor-messaging done in the non print-twips mode)
1209  SuppressEditViewMessagesGuard aGuard(*pEditView);
1210 
1211  pEditView->SetOutputArea(rDevice.PixelToLogic(aEditRect));
1212  pEditView->Paint(rDevice.PixelToLogic(aEditRect), &rDevice);
1213 
1214  // EditView will do the cursor notifications correctly if we're in
1215  // print-twips messaging mode.
1216  if (!comphelper::LibreOfficeKit::isCompatFlagSet(
1217  comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs))
1218  {
1219  // Now we need to get relative cursor position within the editview.
1220  // This is for sending the pixel-aligned twips position of the cursor to the specific views with
1221  // the same given zoom level.
1222  tools::Rectangle aCursorRect = pEditView->GetEditCursor();
1223  Point aCursPos = OutputDevice::LogicToLogic(aCursorRect.TopLeft(),
1224  MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip));
1225 
1226  const MapMode& rDevMM = rDevice.GetMapMode();
1227  MapMode aMM(MapUnit::MapTwip);
1228  aMM.SetScaleX(rDevMM.GetScaleX());
1229  aMM.SetScaleY(rDevMM.GetScaleY());
1230 
1231  aBGAbs.AdjustLeft(1);
1232  aBGAbs.AdjustTop(1);
1233  aCursorRect = OutputDevice::PixelToLogic(aBGAbs, aMM);
1234  aCursorRect.setWidth(0);
1235  aCursorRect.Move(aCursPos.getX(), 0);
1236  // Sends view cursor position to views of all matching zooms if needed (avoids duplicates).
1237  InvalidateLOKViewCursor(aCursorRect, aMM.GetScaleX(), aMM.GetScaleY());
1238  }
1239 
1240  // Rollback the mapmode and 'output area'.
1241  SetMapMode(aOrigMapMode);
1242  pEditView->SetOutputArea(aOrigOutputArea);
1243  }
1244  else
1245  {
1246  tools::Rectangle aEditRect(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
1247  pEditView->Paint(rDevice.PixelToLogic(aEditRect), &rDevice);
1248  }
1249 
1250  rDevice.SetMapMode(MapMode(MapUnit::MapPixel));
1251 
1252  // restore the cursor it was originally visible
1253  if (bInPlaceVisCursor)
1254  pInPlaceCrsr->Show();
1255  }
1256 
1258  {
1259  // flush OverlayManager before changing the MapMode
1261 
1262  // set MapMode for text edit
1263  rDevice.SetMapMode(mrViewData.GetLogicMode());
1264  }
1265  else
1266  rDevice.SetMapMode(aDrawMode);
1267 
1268  if (mpNoteMarker)
1269  mpNoteMarker->Draw(); // Above the cursor, in drawing map mode
1270 }
1271 
1272 namespace
1273 {
1274  template<typename IndexType>
1275  void lcl_getBoundingRowColumnforTile(ScViewData& rViewData,
1276  tools::Long nTileStartPosPx, tools::Long nTileEndPosPx,
1277  sal_Int32& nTopLeftTileOffset, sal_Int32& nTopLeftTileOrigin,
1278  sal_Int32& nTopLeftTileIndex, sal_Int32& nBottomRightTileIndex)
1279  {
1280  const bool bColumnHeader = std::is_same<IndexType, SCCOL>::value;
1281 
1282  SCTAB nTab = rViewData.GetTabNo();
1283 
1284  IndexType nStartIndex = -1;
1285  IndexType nEndIndex = -1;
1286  tools::Long nStartPosPx = 0;
1287  tools::Long nEndPosPx = 0;
1288 
1289  ScPositionHelper& rPositionHelper =
1290  bColumnHeader ? rViewData.GetLOKWidthHelper() : rViewData.GetLOKHeightHelper();
1291  const auto& rStartNearest = rPositionHelper.getNearestByPosition(nTileStartPosPx);
1292  const auto& rEndNearest = rPositionHelper.getNearestByPosition(nTileEndPosPx);
1293 
1294  ScBoundsProvider aBoundsProvider(rViewData, nTab, bColumnHeader);
1295  aBoundsProvider.Compute(rStartNearest, rEndNearest, nTileStartPosPx, nTileEndPosPx);
1296  aBoundsProvider.GetStartIndexAndPosition(nStartIndex, nStartPosPx); ++nStartIndex;
1297  aBoundsProvider.GetEndIndexAndPosition(nEndIndex, nEndPosPx);
1298 
1299  nTopLeftTileOffset = nTileStartPosPx - nStartPosPx;
1300  nTopLeftTileOrigin = nStartPosPx;
1301  nTopLeftTileIndex = nStartIndex;
1302  nBottomRightTileIndex = nEndIndex;
1303  }
1304 
1305  class ScLOKProxyObjectContact final : public sdr::contact::ObjectContactOfPageView
1306  {
1307  private:
1308  sdr::contact::ObjectContact& mrRealObjectContact;
1309 
1310  public:
1311  explicit ScLOKProxyObjectContact(
1312  sdr::contact::ObjectContact& rRealOC,
1313  SdrPageWindow& rPageWindow,
1314  const char* pDebugName) :
1315  ObjectContactOfPageView(rPageWindow, pDebugName),
1316  mrRealObjectContact(rRealOC)
1317  {
1318  }
1319 
1320  virtual bool supportsGridOffsets() const override { return true; }
1321 
1323  basegfx::B2DVector& rTarget,
1324  const sdr::contact::ViewObjectContact& rClient) const override
1325  {
1326  SdrObject* pTargetSdrObject(rClient.GetViewContact().TryToGetSdrObject());
1327  if (pTargetSdrObject)
1328  rTarget = pTargetSdrObject->GetViewContact().GetViewObjectContact(mrRealObjectContact).getGridOffset();
1329  }
1330  };
1331 
1332  class ScLOKDrawView : public FmFormView
1333  {
1334  public:
1335  ScLOKDrawView(OutputDevice* pOut, ScViewData& rData) :
1336  FmFormView(*rData.GetDocument().GetDrawLayer(), pOut),
1337  pScDrawView(rData.GetScDrawView())
1338  {
1339  }
1340 
1342  SdrPageWindow& rPageWindow, const char* pDebugName) const override
1343  {
1344  if (!pScDrawView)
1345  return SdrView::createViewSpecificObjectContact(rPageWindow, pDebugName);
1346 
1347  SdrPageView* pPageView(pScDrawView->GetSdrPageView());
1348  if (!pPageView)
1349  return SdrView::createViewSpecificObjectContact(rPageWindow, pDebugName);
1350 
1351  SdrPageWindow* pSdrPageWindow = pPageView->GetPageWindow(0);
1352  if (!pSdrPageWindow)
1353  return SdrView::createViewSpecificObjectContact(rPageWindow, pDebugName);
1354 
1355  return new ScLOKProxyObjectContact(pSdrPageWindow->GetObjectContact(), rPageWindow, pDebugName);
1356  }
1357 
1358  private:
1359  ScDrawView* pScDrawView;
1360  };
1361 } // anonymous namespace
1362 
1364  int nOutputWidth, int nOutputHeight,
1365  int nTilePosX, int nTilePosY,
1366  tools::Long nTileWidth, tools::Long nTileHeight )
1367 {
1368  Fraction origZoomX = mrViewData.GetZoomX();
1369  Fraction origZoomY = mrViewData.GetZoomY();
1370 
1371  // Output size is in pixels while tile position and size are in logical units (twips).
1372 
1373  // Assumption: always paint the whole sheet i.e. "visible" range is always
1374  // from (0,0) to last data position.
1375 
1376  // Tile geometry is independent of the zoom level, but the output size is
1377  // dependent of the zoom level. Determine the correct zoom level before
1378  // we start.
1379 
1380  // FIXME the painting works using a mixture of drawing with coordinates in
1381  // pixels and in logic coordinates; it should be cleaned up to use logic
1382  // coords only, and avoid all the SetMapMode()'s.
1383  // Similarly to Writer, we should set the mapmode once on the rDevice, and
1384  // not care about any zoom settings.
1385 
1386  Fraction aFracX(o3tl::convert(nOutputWidth, o3tl::Length::px, o3tl::Length::twip), nTileWidth);
1387  Fraction aFracY(o3tl::convert(nOutputHeight, o3tl::Length::px, o3tl::Length::twip), nTileHeight);
1388 
1389  const bool bChangeZoom = (aFracX != origZoomX || aFracY != origZoomY);
1390 
1391  // page break zoom, and aLogicMode in ScViewData
1392  // FIXME: there are issues when SetZoom is called conditionally.
1393  mrViewData.SetZoom(aFracX, aFracY, true);
1394  if (bChangeZoom)
1395  {
1396  if (ScDrawView* pDrawView = mrViewData.GetScDrawView())
1397  pDrawView->resetGridOffsetsForAllSdrPageViews();
1398  }
1399 
1400  const double fTilePosXPixel = static_cast<double>(nTilePosX) * nOutputWidth / nTileWidth;
1401  const double fTilePosYPixel = static_cast<double>(nTilePosY) * nOutputHeight / nTileHeight;
1402  const double fTileBottomPixel = static_cast<double>(nTilePosY + nTileHeight) * nOutputHeight / nTileHeight;
1403  const double fTileRightPixel = static_cast<double>(nTilePosX + nTileWidth) * nOutputWidth / nTileWidth;
1404 
1405  SCTAB nTab = mrViewData.GetTabNo();
1406  ScDocument& rDoc = mrViewData.GetDocument();
1407 
1408  const double fPPTX = mrViewData.GetPPTX();
1409  const double fPPTY = mrViewData.GetPPTY();
1410 
1411  // find approximate col/row offsets of nearby.
1412  sal_Int32 nTopLeftTileRowOffset = 0;
1413  sal_Int32 nTopLeftTileColOffset = 0;
1414  sal_Int32 nTopLeftTileRowOrigin = 0;
1415  sal_Int32 nTopLeftTileColOrigin = 0;
1416 
1417  sal_Int32 nTopLeftTileRow = 0;
1418  sal_Int32 nTopLeftTileCol = 0;
1419  sal_Int32 nBottomRightTileRow = 0;
1420  sal_Int32 nBottomRightTileCol = 0;
1421 
1422  lcl_getBoundingRowColumnforTile<SCROW>(mrViewData,
1423  fTilePosYPixel, fTileBottomPixel,
1424  nTopLeftTileRowOffset, nTopLeftTileRowOrigin,
1425  nTopLeftTileRow, nBottomRightTileRow);
1426 
1427  lcl_getBoundingRowColumnforTile<SCCOL>(mrViewData,
1428  fTilePosXPixel, fTileRightPixel,
1429  nTopLeftTileColOffset, nTopLeftTileColOrigin,
1430  nTopLeftTileCol, nBottomRightTileCol);
1431 
1432  // Enlarge
1433  nBottomRightTileCol++;
1434  nBottomRightTileRow++;
1435 
1436  if (nBottomRightTileCol > rDoc.MaxCol())
1437  nBottomRightTileCol = rDoc.MaxCol();
1438 
1439  if (nBottomRightTileRow > MAXTILEDROW)
1440  nBottomRightTileRow = MAXTILEDROW;
1441 
1442  // size of the document including drawings, charts, etc.
1443  SCCOL nEndCol = 0;
1444  SCROW nEndRow = 0;
1445  rDoc.GetTiledRenderingArea(nTab, nEndCol, nEndRow);
1446 
1447  if (nEndCol < nBottomRightTileCol)
1448  nEndCol = nBottomRightTileCol;
1449 
1450  if (nEndRow < nBottomRightTileRow)
1451  nEndRow = nBottomRightTileRow;
1452 
1453  nTopLeftTileCol = std::max<sal_Int32>(nTopLeftTileCol, 0);
1454  nTopLeftTileRow = std::max<sal_Int32>(nTopLeftTileRow, 0);
1455  nTopLeftTileColOrigin = o3tl::convert(nTopLeftTileColOrigin, o3tl::Length::px, o3tl::Length::twip);
1456  nTopLeftTileRowOrigin = o3tl::convert(nTopLeftTileRowOrigin, o3tl::Length::px, o3tl::Length::twip);
1457 
1458  // Checkout -> 'rDoc.ExtendMerge' ... if we miss merged cells.
1459 
1460  // Origin must be the offset of the first col and row
1461  // containing our top-left pixel.
1462  const MapMode aOriginalMode = rDevice.GetMapMode();
1463  MapMode aAbsMode = aOriginalMode;
1464  const Point aOrigin(-nTopLeftTileColOrigin, -nTopLeftTileRowOrigin);
1465  aAbsMode.SetOrigin(aOrigin);
1466  rDevice.SetMapMode(aAbsMode);
1467 
1468  ScTableInfo aTabInfo(nEndRow + 3);
1469  rDoc.FillInfo(aTabInfo, nTopLeftTileCol, nTopLeftTileRow,
1470  nBottomRightTileCol, nBottomRightTileRow,
1471  nTab, fPPTX, fPPTY, false, false);
1472 
1473 // FIXME: is this called some
1474 // Point aScrPos = mrViewData.GetScrPos( nX1, nY1, eWhich );
1475 
1476  ScOutputData aOutputData(&rDevice, OUTTYPE_WINDOW, aTabInfo, &rDoc, nTab,
1477  -nTopLeftTileColOffset,
1478  -nTopLeftTileRowOffset,
1479  nTopLeftTileCol, nTopLeftTileRow,
1480  nBottomRightTileCol, nBottomRightTileRow,
1481  fPPTX, fPPTY, nullptr, nullptr);
1482 
1483  // setup the SdrPage so that drawinglayer works correctly
1484  ScDrawLayer* pModel = rDoc.GetDrawLayer();
1485  if (pModel)
1486  {
1487  bool bPrintTwipsMsgs = comphelper::LibreOfficeKit::isCompatFlagSet(
1488  comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
1489  mpLOKDrawView.reset(bPrintTwipsMsgs ?
1490  new ScLOKDrawView(
1491  &rDevice,
1492  mrViewData) :
1493  new FmFormView(
1494  *pModel,
1495  &rDevice));
1496  mpLOKDrawView->ShowSdrPage(mpLOKDrawView->GetModel()->GetPage(nTab));
1497  aOutputData.SetDrawView(mpLOKDrawView.get());
1498  aOutputData.SetSpellCheckContext(mpSpellCheckCxt.get());
1499  }
1500 
1501  // draw the content
1502  DrawContent(rDevice, aTabInfo, aOutputData, true);
1503  rDevice.SetMapMode(aOriginalMode);
1504 
1505  // Flag drawn formula cells "unchanged".
1506  rDoc.ResetChanged(ScRange(nTopLeftTileCol, nTopLeftTileRow, nTab, nBottomRightTileCol, nBottomRightTileRow, nTab));
1507  rDoc.PrepareFormulaCalc();
1508 
1509  mrViewData.SetZoom(origZoomX, origZoomY, true);
1510  if (bChangeZoom)
1511  {
1512  if (ScDrawView* pDrawView = mrViewData.GetScDrawView())
1513  pDrawView->resetGridOffsetsForAllSdrPageViews();
1514  }
1515 }
1516 
1518 {
1519  OString sRectangle;
1520  if (!pRectangle)
1521  sRectangle = "EMPTY";
1522  else
1523  {
1524  tools::Rectangle aRectangle(*pRectangle);
1525  // When dragging shapes the map mode is disabled.
1526  if (IsMapModeEnabled())
1527  {
1528  if (GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
1529  aRectangle = OutputDevice::LogicToLogic(aRectangle, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip));
1530  }
1531  else
1532  aRectangle = PixelToLogic(aRectangle, MapMode(MapUnit::MapTwip));
1533  sRectangle = aRectangle.toString();
1534  }
1535 
1536  ScTabViewShell* pViewShell = mrViewData.GetViewShell();
1537  SfxLokHelper::notifyInvalidation(pViewShell, sRectangle);
1538 }
1539 
1540 void ScGridWindow::SetCellSelectionPixel(int nType, int nPixelX, int nPixelY)
1541 {
1542  ScTabView* pTabView = mrViewData.GetView();
1543  ScTabViewShell* pViewShell = mrViewData.GetViewShell();
1544  ScInputHandler* pInputHandler = SC_MOD()->GetInputHdl(pViewShell);
1545 
1546  if (pInputHandler && pInputHandler->IsInputMode())
1547  {
1548  // we need to switch off the editeng
1550  pViewShell->UpdateInputHandler();
1551  }
1552 
1553  if (nType == LOK_SETTEXTSELECTION_RESET)
1554  {
1555  pTabView->DoneBlockMode();
1556  return;
1557  }
1558 
1559  // obtain the current selection
1561 
1562  SCCOL nCol1, nCol2;
1563  SCROW nRow1, nRow2;
1564  SCTAB nTab1, nTab2;
1565 
1566  bool bWasEmpty = false;
1567  if (aRangeList.empty())
1568  {
1569  nCol1 = nCol2 = mrViewData.GetCurX();
1570  nRow1 = nRow2 = mrViewData.GetCurY();
1571  bWasEmpty = true;
1572  }
1573  else
1574  aRangeList.Combine().GetVars(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
1575 
1576  // convert the coordinates to column/row
1577  SCCOL nNewPosX;
1578  SCROW nNewPosY;
1579  SCTAB nTab = mrViewData.GetTabNo();
1580  mrViewData.GetPosFromPixel(nPixelX, nPixelY, eWhich, nNewPosX, nNewPosY);
1581 
1582  // change the selection
1583  switch (nType)
1584  {
1585  case LOK_SETTEXTSELECTION_START:
1586  if (nNewPosX != nCol1 || nNewPosY != nRow1 || bWasEmpty)
1587  {
1588  pTabView->SetCursor(nNewPosX, nNewPosY);
1589  pTabView->DoneBlockMode();
1590  pTabView->InitBlockMode(nNewPosX, nNewPosY, nTab, true);
1591  pTabView->MarkCursor(nCol2, nRow2, nTab);
1592  }
1593  break;
1594  case LOK_SETTEXTSELECTION_END:
1595  if (nNewPosX != nCol2 || nNewPosY != nRow2 || bWasEmpty)
1596  {
1597  pTabView->SetCursor(nCol1, nRow1);
1598  pTabView->DoneBlockMode();
1599  pTabView->InitBlockMode(nCol1, nRow1, nTab, true);
1600  pTabView->MarkCursor(nNewPosX, nNewPosY, nTab);
1601  }
1602  break;
1603  default:
1604  assert(false);
1605  break;
1606  }
1607 }
1608 
1610 {
1611  // called at the end of painting, and from timer after background text width calculation
1612 
1613  if (!bNeedsRepaint)
1614  return;
1615 
1616  bNeedsRepaint = false;
1617  if (aRepaintPixel.IsEmpty())
1618  Invalidate();
1619  else
1622 
1623  // selection function in status bar might also be invalid
1624  SfxBindings& rBindings = mrViewData.GetBindings();
1625  rBindings.Invalidate( SID_STATUS_SUM );
1626  rBindings.Invalidate( SID_ATTR_SIZE );
1627  rBindings.Invalidate( SID_TABLE_CELL );
1628 }
1629 
1630 void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, vcl::RenderContext& rRenderContext)
1631 {
1633  if (!pPageData)
1634  return;
1635 
1636  ScDocument& rDoc = mrViewData.GetDocument();
1637  SCTAB nTab = mrViewData.GetTabNo();
1638  Size aWinSize = GetOutputSizePixel();
1639  const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
1641  Color aAutomatic( rColorCfg.GetColorValue(svtools::CALCPAGEBREAK).nColor );
1642 
1643  OUString aPageStr = ScResId( STR_PGNUM );
1644  if ( nPageScript == SvtScriptType::NONE )
1645  {
1646  // get script type of translated "Page" string only once
1647  nPageScript = rDoc.GetStringScriptType( aPageStr );
1648  if (nPageScript == SvtScriptType::NONE)
1650  }
1651 
1652  vcl::Font aFont;
1653  std::unique_ptr<ScEditEngineDefaulter> pEditEng;
1654  const ScPatternAttr& rDefPattern = rDoc.GetPool()->GetDefaultItem(ATTR_PATTERN);
1655  if ( nPageScript == SvtScriptType::LATIN )
1656  {
1657  // use single font and call DrawText directly
1658  rDefPattern.GetFont( aFont, SC_AUTOCOL_BLACK );
1659  aFont.SetColor( COL_LIGHTGRAY );
1660  // font size is set as needed
1661  }
1662  else
1663  {
1664  // use EditEngine to draw mixed-script string
1665  pEditEng.reset(new ScEditEngineDefaulter( EditEngine::CreatePool(), true ));
1666  pEditEng->SetRefMapMode(rRenderContext.GetMapMode());
1667  auto pEditDefaults = std::make_unique<SfxItemSet>( pEditEng->GetEmptyItemSet() );
1668  rDefPattern.FillEditItemSet( pEditDefaults.get() );
1669  pEditDefaults->Put( SvxColorItem( COL_LIGHTGRAY, EE_CHAR_COLOR ) );
1670  pEditEng->SetDefaults( std::move(pEditDefaults) );
1671  }
1672 
1673  sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
1674  for (sal_uInt16 nPos=0; nPos<nCount; nPos++)
1675  {
1676  ScPrintRangeData& rData = pPageData->GetData(nPos);
1677  ScRange aRange = rData.GetPrintRange();
1678  if ( aRange.aStart.Col() <= nX2+1 && aRange.aEnd.Col()+1 >= nX1 &&
1679  aRange.aStart.Row() <= nY2+1 && aRange.aEnd.Row()+1 >= nY1 )
1680  {
1681  // 3 pixel frame around the print area
1682  // (middle pixel on the grid lines)
1683 
1684  rRenderContext.SetLineColor();
1685  if (rData.IsAutomatic())
1686  rRenderContext.SetFillColor( aAutomatic );
1687  else
1688  rRenderContext.SetFillColor( aManual );
1689 
1690  Point aStart = mrViewData.GetScrPos(
1691  aRange.aStart.Col(), aRange.aStart.Row(), eWhich, true );
1692  Point aEnd = mrViewData.GetScrPos(
1693  aRange.aEnd.Col() + 1, aRange.aEnd.Row() + 1, eWhich, true );
1694  aStart.AdjustX( -2 );
1695  aStart.AdjustY( -2 );
1696 
1697  // Prevent overflows:
1698  if ( aStart.X() < -10 ) aStart.setX( -10 );
1699  if ( aStart.Y() < -10 ) aStart.setY( -10 );
1700  if ( aEnd.X() > aWinSize.Width() + 10 )
1701  aEnd.setX( aWinSize.Width() + 10 );
1702  if ( aEnd.Y() > aWinSize.Height() + 10 )
1703  aEnd.setY( aWinSize.Height() + 10 );
1704 
1705  rRenderContext.DrawRect( tools::Rectangle( aStart, Point(aEnd.X(),aStart.Y()+2) ) );
1706  rRenderContext.DrawRect( tools::Rectangle( aStart, Point(aStart.X()+2,aEnd.Y()) ) );
1707  rRenderContext.DrawRect( tools::Rectangle( Point(aStart.X(),aEnd.Y()-2), aEnd ) );
1708  rRenderContext.DrawRect( tools::Rectangle( Point(aEnd.X()-2,aStart.Y()), aEnd ) );
1709 
1710  // Page breaks
1712 
1713  size_t nColBreaks = rData.GetPagesX();
1714  const SCCOL* pColEnd = rData.GetPageEndX();
1715  size_t nColPos;
1716  for (nColPos=0; nColPos+1<nColBreaks; nColPos++)
1717  {
1718  SCCOL nBreak = pColEnd[nColPos]+1;
1719  if ( nBreak >= nX1 && nBreak <= nX2+1 )
1720  {
1722  if (rDoc.HasColBreak(nBreak, nTab) & ScBreakType::Manual)
1723  rRenderContext.SetFillColor( aManual );
1724  else
1725  rRenderContext.SetFillColor( aAutomatic );
1726  Point aBreak = mrViewData.GetScrPos(
1727  nBreak, aRange.aStart.Row(), eWhich, true );
1728  rRenderContext.DrawRect( tools::Rectangle( aBreak.X()-1, aStart.Y(), aBreak.X(), aEnd.Y() ) );
1729  }
1730  }
1731 
1732  size_t nRowBreaks = rData.GetPagesY();
1733  const SCROW* pRowEnd = rData.GetPageEndY();
1734  size_t nRowPos;
1735  for (nRowPos=0; nRowPos+1<nRowBreaks; nRowPos++)
1736  {
1737  SCROW nBreak = pRowEnd[nRowPos]+1;
1738  if ( nBreak >= nY1 && nBreak <= nY2+1 )
1739  {
1741  if (rDoc.HasRowBreak(nBreak, nTab) & ScBreakType::Manual)
1742  rRenderContext.SetFillColor( aManual );
1743  else
1744  rRenderContext.SetFillColor( aAutomatic );
1745  Point aBreak = mrViewData.GetScrPos(
1746  aRange.aStart.Col(), nBreak, eWhich, true );
1747  rRenderContext.DrawRect( tools::Rectangle( aStart.X(), aBreak.Y()-1, aEnd.X(), aBreak.Y() ) );
1748  }
1749  }
1750 
1751  // Page numbers
1752 
1753  SCROW nPrStartY = aRange.aStart.Row();
1754  for (nRowPos=0; nRowPos<nRowBreaks; nRowPos++)
1755  {
1756  SCROW nPrEndY = pRowEnd[nRowPos];
1757  if ( nPrEndY >= nY1 && nPrStartY <= nY2 )
1758  {
1759  SCCOL nPrStartX = aRange.aStart.Col();
1760  for (nColPos=0; nColPos<nColBreaks; nColPos++)
1761  {
1762  SCCOL nPrEndX = pColEnd[nColPos];
1763  if ( nPrEndX >= nX1 && nPrStartX <= nX2 )
1764  {
1765  Point aPageStart = mrViewData.GetScrPos(
1766  nPrStartX, nPrStartY, eWhich, true );
1767  Point aPageEnd = mrViewData.GetScrPos(
1768  nPrEndX+1,nPrEndY+1, eWhich, true );
1769 
1770  tools::Long nPageNo = rData.GetFirstPage();
1771  if ( rData.IsTopDown() )
1772  nPageNo += static_cast<tools::Long>(nColPos)*nRowBreaks+nRowPos;
1773  else
1774  nPageNo += static_cast<tools::Long>(nRowPos)*nColBreaks+nColPos;
1775 
1776  OUString aThisPageStr = aPageStr.replaceFirst("%1", OUString::number(nPageNo));
1777 
1778  if ( pEditEng )
1779  {
1780  // find right font size with EditEngine
1781  tools::Long nHeight = 100;
1782  pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
1783  pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1784  pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1785  pEditEng->SetTextCurrentDefaults( aThisPageStr );
1786  Size aSize100( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
1787 
1788  // 40% of width or 60% of height
1789  tools::Long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
1790  tools::Long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
1791  nHeight = std::min(nSizeX,nSizeY);
1792  pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
1793  pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1794  pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1795 
1796  // centered output with EditEngine
1797  Size aTextSize( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
1798  Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
1799  (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
1800  pEditEng->Draw( &rRenderContext, aPos );
1801  }
1802  else
1803  {
1804  // find right font size for DrawText
1805  aFont.SetFontSize( Size( 0,100 ) );
1806  rRenderContext.SetFont( aFont );
1807  Size aSize100(rRenderContext.GetTextWidth( aThisPageStr ), rRenderContext.GetTextHeight() );
1808 
1809  // 40% of width or 60% of height
1810  tools::Long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
1811  tools::Long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
1812  aFont.SetFontSize( Size( 0,std::min(nSizeX,nSizeY) ) );
1813  rRenderContext.SetFont( aFont );
1814 
1815  // centered output with DrawText
1816  Size aTextSize(rRenderContext.GetTextWidth( aThisPageStr ), rRenderContext.GetTextHeight() );
1817  Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
1818  (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
1819  rRenderContext.DrawText( aPos, aThisPageStr );
1820  }
1821  }
1822  nPrStartX = nPrEndX + 1;
1823  }
1824  }
1825  nPrStartY = nPrEndY + 1;
1826  }
1827  }
1828  }
1829 }
1830 
1831 void ScGridWindow::DrawButtons(SCCOL nX1, SCCOL nX2, const ScTableInfo& rTabInfo, OutputDevice* pContentDev)
1832 {
1833  aComboButton.SetOutputDevice( pContentDev );
1834 
1835  ScDocument& rDoc = mrViewData.GetDocument();
1836  ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &mrViewData.GetZoomY(), &rDoc);
1837 
1838  SCCOL nCol;
1839  SCROW nRow;
1840  SCSIZE nArrY;
1841  SCSIZE nQuery;
1842  SCTAB nTab = mrViewData.GetTabNo();
1843  ScDBData* pDBData = nullptr;
1844  std::unique_ptr<ScQueryParam> pQueryParam;
1845 
1846  RowInfo* pRowInfo = rTabInfo.mpRowInfo.get();
1847  sal_uInt16 nArrCount = rTabInfo.mnArrCount;
1848 
1849  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
1850 
1851  Point aOldPos = aComboButton.GetPosPixel(); // store state for MouseDown/Up
1852  Size aOldSize = aComboButton.GetSizePixel();
1853 
1854  for (nArrY=1; nArrY+1<nArrCount; nArrY++)
1855  {
1856  if ( pRowInfo[nArrY].bAutoFilter && pRowInfo[nArrY].bChanged )
1857  {
1858  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1859 
1860  nRow = pThisRowInfo->nRowNo;
1861 
1862  for (nCol=nX1; nCol<=nX2; nCol++)
1863  {
1864  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
1865  //if several columns merged on a row, there should be only one auto button at the end of the columns.
1866  //if several rows merged on a column, the button may be in the middle, so "!pInfo->bVOverlapped" should not be used
1867  if ( pInfo->bAutoFilter && !pInfo->bHOverlapped )
1868  {
1869  if (!pQueryParam)
1870  pQueryParam.reset(new ScQueryParam);
1871 
1872  bool bNewData = true;
1873  if (pDBData)
1874  {
1875  SCCOL nStartCol;
1876  SCROW nStartRow;
1877  SCCOL nEndCol;
1878  SCROW nEndRow;
1879  SCTAB nAreaTab;
1880  pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
1881  if ( nCol >= nStartCol && nCol <= nEndCol &&
1882  nRow >= nStartRow && nRow <= nEndRow )
1883  bNewData = false;
1884  }
1885  if (bNewData)
1886  {
1887  pDBData = rDoc.GetDBAtCursor( nCol, nRow, nTab, ScDBDataPortion::AREA );
1888  if (pDBData)
1889  pDBData->GetQueryParam( *pQueryParam );
1890  else
1891  {
1892  // can also be part of DataPilot table
1893  }
1894  }
1895 
1896  // pQueryParam can only include MAXQUERY entries
1897 
1898  bool bSimpleQuery = true;
1899  bool bColumnFound = false;
1900  if (!pQueryParam->bInplace)
1901  bSimpleQuery = false;
1902  SCSIZE nCount = pQueryParam->GetEntryCount();
1903  for (nQuery = 0; nQuery < nCount && bSimpleQuery; ++nQuery)
1904  if (pQueryParam->GetEntry(nQuery).bDoQuery)
1905  {
1906  // Do no restrict to EQUAL here
1907  // (Column head should become blue also when ">1")
1908 
1909  if (pQueryParam->GetEntry(nQuery).nField == nCol)
1910  bColumnFound = true;
1911  if (nQuery > 0)
1912  if (pQueryParam->GetEntry(nQuery).eConnect != SC_AND)
1913  bSimpleQuery = false;
1914  }
1915 
1916  bool bArrowState = bSimpleQuery && bColumnFound;
1917  tools::Long nSizeX;
1918  tools::Long nSizeY;
1919  SCCOL nStartCol= nCol;
1920  SCROW nStartRow = nRow;
1921  //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.
1922  //should first get the start pos of the merge area, then get the nSizeX through the start pos.
1923  rDoc.ExtendOverlapped(nStartCol, nStartRow,nCol, nRow, nTab);//get nStartCol,nStartRow
1924  mrViewData.GetMergeSizePixel( nStartCol, nStartRow, nSizeX, nSizeY );//get nSizeX
1925  nSizeY = ScViewData::ToPixel(rDoc.GetRowHeight(nRow, nTab), mrViewData.GetPPTY());
1926  Point aScrPos = mrViewData.GetScrPos( nCol, nRow, eWhich );
1927 
1928  aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1), bLayoutRTL);
1929  aCellBtn.setPopupLeft(bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL
1930  aCellBtn.setDrawBaseButton(false);
1931  aCellBtn.setDrawPopupButton(true);
1932  aCellBtn.setHasHiddenMember(bArrowState);
1933  aCellBtn.draw();
1934  }
1935  }
1936  }
1937 
1938  if ( pRowInfo[nArrY].bPivotButton && pRowInfo[nArrY].bChanged )
1939  {
1940  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1941  nRow = pThisRowInfo->nRowNo;
1942  for (nCol=nX1; nCol<=nX2; nCol++)
1943  {
1944  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
1945  if (pInfo->bHOverlapped || pInfo->bVOverlapped)
1946  continue;
1947 
1948  Point aScrPos = mrViewData.GetScrPos( nCol, nRow, eWhich );
1949  tools::Long nSizeX;
1950  tools::Long nSizeY;
1951  mrViewData.GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
1952  tools::Long nPosX = aScrPos.X();
1953  tools::Long nPosY = aScrPos.Y();
1954  // bLayoutRTL is handled in setBoundingBox
1955 
1956  OUString aStr = rDoc.GetString(nCol, nRow, nTab);
1957  aCellBtn.setText(aStr);
1958  aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL);
1959  aCellBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
1960  aCellBtn.setDrawBaseButton(pInfo->bPivotButton);
1961  aCellBtn.setDrawPopupButton(pInfo->bPivotPopupButton);
1962  aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
1963  aCellBtn.draw();
1964  }
1965  }
1966 
1967  if ( !comphelper::LibreOfficeKit::isActive() && bListValButton && pRowInfo[nArrY].nRowNo == aListValPos.Row() && pRowInfo[nArrY].bChanged )
1968  {
1970  aComboButton.SetPosPixel( aRect.TopLeft() );
1971  aComboButton.SetSizePixel( aRect.GetSize() );
1972  pContentDev->SetClipRegion(vcl::Region(aRect));
1973  aComboButton.Draw();
1974  pContentDev->SetClipRegion(); // always called from Draw() without clip region
1975  aComboButton.SetPosPixel( aOldPos ); // restore old state
1976  aComboButton.SetSizePixel( aOldSize ); // for MouseUp/Down (AutoFilter)
1977  }
1978  }
1979 
1980  pQueryParam.reset();
1981  aComboButton.SetOutputDevice( this );
1982 }
1983 
1985 {
1986  ScDocument& rDoc = mrViewData.GetDocument();
1987  SCTAB nTab = mrViewData.GetTabNo();
1988  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
1989  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1990 
1991  ScDDComboBoxButton aButton( this ); // for optimal size
1992  Size aBtnSize = aButton.GetSizePixel();
1993 
1994  SCCOL nCol = rButtonPos.Col();
1995  SCROW nRow = rButtonPos.Row();
1996 
1997  tools::Long nCellSizeX; // width of this cell, including merged
1998  tools::Long nDummy;
1999  mrViewData.GetMergeSizePixel( nCol, nRow, nCellSizeX, nDummy );
2000 
2001  // for height, only the cell's row is used, excluding merged cells
2002  tools::Long nCellSizeY = ScViewData::ToPixel( rDoc.GetRowHeight( nRow, nTab ), mrViewData.GetPPTY() );
2003  tools::Long nAvailable = nCellSizeX;
2004 
2005  // left edge of next cell if there is a non-hidden next column
2006  SCCOL nNextCol = nCol + 1;
2007  const ScMergeAttr* pMerge = rDoc.GetAttr( nCol,nRow,nTab, ATTR_MERGE );
2008  if ( pMerge->GetColMerge() > 1 )
2009  nNextCol = nCol + pMerge->GetColMerge(); // next cell after the merged area
2010  while ( nNextCol <= rDoc.MaxCol() && rDoc.ColHidden(nNextCol, nTab) )
2011  ++nNextCol;
2012  bool bNextCell = ( nNextCol <= rDoc.MaxCol() );
2013  if ( bNextCell )
2014  nAvailable = ScViewData::ToPixel( rDoc.GetColWidth( nNextCol, nTab ), mrViewData.GetPPTX() );
2015 
2016  if ( nAvailable < aBtnSize.Width() )
2017  aBtnSize.setWidth( nAvailable );
2018  if ( nCellSizeY < aBtnSize.Height() )
2019  aBtnSize.setHeight( nCellSizeY );
2020 
2021  Point aPos = mrViewData.GetScrPos( nCol, nRow, eWhich, true );
2022  aPos.AdjustX(nCellSizeX * nLayoutSign ); // start of next cell
2023  if (!bNextCell)
2024  aPos.AdjustX( -(aBtnSize.Width() * nLayoutSign) ); // right edge of cell if next cell not available
2025  aPos.AdjustY(nCellSizeY - aBtnSize.Height() );
2026  // X remains at the left edge
2027 
2028  if ( bLayoutRTL )
2029  aPos.AdjustX( -(aBtnSize.Width()-1) ); // align right edge of button with cell border
2030 
2031  return tools::Rectangle( aPos, aBtnSize );
2032 }
2033 
2035 {
2036  ScDocument& rDoc = mrViewData.GetDocument();
2037  ScDBData* pDBData = rDoc.GetDBAtCursor( nCol, nRow, nTab, ScDBDataPortion::AREA );
2038  ScQueryParam aQueryParam;
2039 
2040  if ( pDBData )
2041  pDBData->GetQueryParam( aQueryParam );
2042  else
2043  {
2044  OSL_FAIL("Auto filter button without DBData");
2045  }
2046 
2047  bool bSimpleQuery = true;
2048  bool bColumnFound = false;
2049  SCSIZE nQuery;
2050 
2051  if ( !aQueryParam.bInplace )
2052  bSimpleQuery = false;
2053 
2054  // aQueryParam can only include MAXQUERY entries
2055 
2056  SCSIZE nCount = aQueryParam.GetEntryCount();
2057  for (nQuery = 0; nQuery < nCount && bSimpleQuery; ++nQuery)
2058  if ( aQueryParam.GetEntry(nQuery).bDoQuery )
2059  {
2060  if (aQueryParam.GetEntry(nQuery).nField == nCol)
2061  bColumnFound = true;
2062 
2063  if (nQuery > 0)
2064  if (aQueryParam.GetEntry(nQuery).eConnect != SC_AND)
2065  bSimpleQuery = false;
2066  }
2067 
2068  return ( bSimpleQuery && bColumnFound );
2069 }
2070 
2071 void ScGridWindow::GetSelectionRects( ::std::vector< tools::Rectangle >& rPixelRects ) const
2072 {
2073  GetPixelRectsFor( mrViewData.GetMarkData(), rPixelRects );
2074 }
2075 
2076 void ScGridWindow::GetSelectionRectsPrintTwips(::std::vector< tools::Rectangle >& rRects) const
2077 {
2078  GetRectsAnyFor(mrViewData.GetMarkData(), rRects, true);
2079 }
2080 
2083  ::std::vector< tools::Rectangle >& rPixelRects ) const
2084 {
2085  GetRectsAnyFor(rMarkData, rPixelRects, false);
2086 }
2087 
2089  ::std::vector< tools::Rectangle >& rRects,
2090  bool bInPrintTwips) const
2091 {
2092  ScMarkData aMultiMark( rMarkData );
2093  aMultiMark.SetMarking( false );
2094  aMultiMark.MarkToMulti();
2095  ScDocument& rDoc = mrViewData.GetDocument();
2096  SCTAB nTab = mrViewData.GetTabNo();
2097 
2098  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
2099  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2100  if ( !aMultiMark.IsMultiMarked() )
2101  return;
2102  ScRange aMultiRange;
2103  aMultiMark.GetMultiMarkArea( aMultiRange );
2104  SCCOL nX1 = aMultiRange.aStart.Col();
2105  SCROW nY1 = aMultiRange.aStart.Row();
2106  SCCOL nX2 = aMultiRange.aEnd.Col();
2107  SCROW nY2 = aMultiRange.aEnd.Row();
2108 
2109  PutInOrder( nX1, nX2 );
2110  PutInOrder( nY1, nY2 );
2111 
2112  SCCOL nTestX2 = nX2;
2113  SCROW nTestY2 = nY2;
2114 
2115  rDoc.ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
2116 
2117  SCCOL nPosX = mrViewData.GetPosX( eHWhich );
2118  SCROW nPosY = mrViewData.GetPosY( eVWhich );
2119  // is the selection visible at all?
2120  if (nTestX2 < nPosX || nTestY2 < nPosY)
2121  return;
2122  SCCOL nRealX1 = nX1;
2123  if (nX1 < nPosX)
2124  nX1 = nPosX;
2125  if (nY1 < nPosY)
2126  nY1 = nPosY;
2127 
2129  {
2130  // limit the selection to only what is visible on the screen
2131  SCCOL nXRight = nPosX + mrViewData.VisibleCellsX(eHWhich);
2132  if (nXRight > rDoc.MaxCol())
2133  nXRight = rDoc.MaxCol();
2134 
2135  SCROW nYBottom = nPosY + mrViewData.VisibleCellsY(eVWhich);
2136  if (nYBottom > rDoc.MaxRow())
2137  nYBottom = rDoc.MaxRow();
2138 
2139  // is the selection visible at all?
2140  if (nX1 > nXRight || nY1 > nYBottom)
2141  return;
2142 
2143  if (nX2 > nXRight)
2144  nX2 = nXRight;
2145  if (nY2 > nYBottom)
2146  nY2 = nYBottom;
2147  }
2148  else
2149  {
2150  SCCOL nMaxTiledCol;
2151  SCROW nMaxTiledRow;
2152  rDoc.GetTiledRenderingArea(nTab, nMaxTiledCol, nMaxTiledRow);
2153 
2154  if (nX2 > nMaxTiledCol)
2155  nX2 = nMaxTiledCol;
2156  if (nY2 > nMaxTiledRow)
2157  nY2 = nMaxTiledRow;
2158  }
2159 
2160  double nPPTX = mrViewData.GetPPTX();
2161  double nPPTY = mrViewData.GetPPTY();
2162 
2163  ScInvertMerger aInvert( &rRects );
2164 
2165  Point aScrPos = bInPrintTwips ? mrViewData.GetPrintTwipsPos(nX1, nY1) :
2166  mrViewData.GetScrPos(nX1, nY1, eWhich);
2167  tools::Long nScrY = aScrPos.Y();
2168  bool bWasHidden = false;
2169  for (SCROW nY=nY1; nY<=nY2; nY++)
2170  {
2171  bool bFirstRow = ( nY == nPosY ); // first visible row?
2172  bool bDoHidden = false; // repeat hidden ?
2173  sal_uInt16 nHeightTwips = rDoc.GetRowHeight( nY,nTab );
2174  bool bDoRow = ( nHeightTwips != 0 );
2175  if (bDoRow)
2176  {
2177  if (bWasHidden) // test hidden merge
2178  {
2179  bDoHidden = true;
2180  bDoRow = true;
2181  }
2182 
2183  bWasHidden = false;
2184  }
2185  else
2186  {
2187  bWasHidden = true;
2188  if (nY==nY2)
2189  bDoRow = true; // last cell of the block
2190  }
2191 
2192  if ( bDoRow )
2193  {
2194  SCCOL nLoopEndX = nX2;
2195  if (nX2 < nX1) // the rest of the merge
2196  {
2197  SCCOL nStartX = nX1;
2198  while ( rDoc.GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG)->IsHorOverlapped() )
2199  --nStartX;
2200  if (nStartX <= nX2)
2201  nLoopEndX = nX1;
2202  }
2203 
2204  const tools::Long nHeight = bInPrintTwips ?
2205  nHeightTwips : ScViewData::ToPixel(nHeightTwips, nPPTY);
2206  tools::Long nEndY = nScrY + nHeight - 1;
2207  tools::Long nScrX = aScrPos.X();
2208  for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
2209  {
2210  tools::Long nWidth = rDoc.GetColWidth(nX, nTab);
2211  if (!bInPrintTwips)
2212  nWidth = ScViewData::ToPixel(nWidth, nPPTX);
2213 
2214  if ( nWidth > 0 )
2215  {
2216  tools::Long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
2217 
2218  SCROW nThisY = nY;
2219  const ScPatternAttr* pPattern = rDoc.GetPattern( nX, nY, nTab );
2220  const ScMergeFlagAttr* pMergeFlag = &pPattern->GetItem(ATTR_MERGE_FLAG);
2221  if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
2222  {
2223  while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
2224  (rDoc.RowHidden(nThisY-1, nTab) || bFirstRow) )
2225  {
2226  --nThisY;
2227  pPattern = rDoc.GetPattern( nX, nThisY, nTab );
2228  pMergeFlag = &pPattern->GetItem(ATTR_MERGE_FLAG);
2229  }
2230  }
2231 
2232  // only the rest of the merged is seen ?
2233  SCCOL nThisX = nX;
2234  if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
2235  {
2236  while ( pMergeFlag->IsHorOverlapped() )
2237  {
2238  --nThisX;
2239  pPattern = rDoc.GetPattern( nThisX, nThisY, nTab );
2240  pMergeFlag = &pPattern->GetItem(ATTR_MERGE_FLAG);
2241  }
2242  }
2243 
2244  if ( aMultiMark.IsCellMarked( nThisX, nThisY, true ) )
2245  {
2246  if ( !pMergeFlag->IsOverlapped() )
2247  {
2248  const ScMergeAttr* pMerge = &pPattern->GetItem(ATTR_MERGE);
2249  if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
2250  {
2251  const SCCOL nEndColMerge = nThisX + pMerge->GetColMerge();
2252  const SCROW nEndRowMerge = nThisY + pMerge->GetRowMerge();
2253  Point aEndPos = bInPrintTwips ?
2254  mrViewData.GetPrintTwipsPos(nEndColMerge, nEndRowMerge) :
2255  mrViewData.GetScrPos(nEndColMerge, nEndRowMerge, eWhich);
2256  if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
2257  {
2258  aInvert.AddRect( tools::Rectangle( nScrX,nScrY,
2259  aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
2260  }
2261  }
2262  else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
2263  {
2264  aInvert.AddRect( tools::Rectangle( nScrX,nScrY,nEndX,nEndY ) );
2265  }
2266  }
2267  }
2268 
2269  nScrX = nEndX + nLayoutSign;
2270  }
2271  }
2272  nScrY = nEndY + 1;
2273  }
2274  }
2275 }
2276 
2278 {
2279  Window::DataChanged(rDCEvt);
2280 
2281  if ( !((rDCEvt.GetType() == DataChangedEventType::PRINTER) ||
2282  (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
2283  (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
2284  (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
2285  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2286  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))) )
2287  return;
2288 
2289  if ( rDCEvt.GetType() == DataChangedEventType::FONTS && eWhich == mrViewData.GetActivePart() )
2291 
2292  if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2293  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
2294  {
2295  if ( eWhich == mrViewData.GetActivePart() ) // only once for the view
2296  {
2297  ScTabView* pView = mrViewData.GetView();
2298 
2299  pView->RecalcPPT();
2300 
2301  // RepeatResize in case scroll bar sizes have changed
2302  pView->RepeatResize();
2303  pView->UpdateAllOverlays();
2304 
2305  // invalidate cell attribs in input handler, in case the
2306  // EditEngine BackgroundColor has to be changed
2307  if ( mrViewData.IsActive() )
2308  {
2309  ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
2310  if (pHdl)
2311  pHdl->ForgetLastPattern();
2312  }
2313  }
2314  }
2315 
2316  Invalidate();
2317 }
2318 
2319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
tools::Long nScrY
Definition: output.hxx:185
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3047
Point TopLeft() const
void SetClipRegion()
const Fraction & GetScaleX() const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, MetricVector *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
void SetSyntaxMode(bool bNewMode)
Definition: output.cxx:279
void InvalidateLOKViewCursor(const tools::Rectangle &rCursorRect, const Fraction aScaleX, const Fraction aScaleY)
Definition: gridwin4.cxx:350
std::unique_ptr< RowInfo[]> mpRowInfo
Definition: fillinfo.hxx:194
bool IsHidden() const
Definition: rfindlst.hxx:58
void FillInfo(ScTableInfo &rTabInfo, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, double fColScale, double fRowScale, bool bPageMode, bool bFormulaMode, const ScMarkData *pMarkData=nullptr)
Definition: fillinfo.cxx:347
constexpr double nPPTY
SCCOL GetColMerge() const
Definition: attrib.hxx:68
void SetOutputDevice(OutputDevice *pOutputDevice)
Definition: cbuttonw.cxx:38
void DrawButtons(SCCOL nX1, SCCOL nX2, const ScTableInfo &rTabInfo, OutputDevice *pContentDev)
Definition: gridwin4.cxx:1831
void SetPixelOffset(const Size &rOffset)
std::unique_ptr< ScNoteMarker, o3tl::default_delete< ScNoteMarker > > mpNoteMarker
Definition: gridwin.hxx:152
OutputDevice & GetOutputDevice() const
void ExtendHidden(SCCOL &rX1, SCROW &rY1, SCCOL &rX2, SCROW &rY2, SCTAB nTab)
Definition: document.cxx:4698
void SetFontSize(const Size &)
bool HasScenarioRange(SCTAB nTab, const ScRange &rRange) const
Definition: documen3.cxx:864
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:353
ScAddress aStart
Definition: address.hxx:499
void DrawFrame(vcl::RenderContext &rRenderContext)
Definition: output.cxx:1383
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:42
SCROW GetRefEndY() const
Definition: viewdata.hxx:518
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)
void SetShowNullValues(bool bSet)
Definition: output.cxx:247
bool bPivotButton
Definition: fillinfo.hxx:162
bool IsInInterpreter() const
Definition: document.hxx:2313
ScDDComboBoxButton aComboButton
Definition: gridwin.hxx:189
This class takes care of physically drawing field button controls inside data pilot tables...
Definition: dpcontrol.hxx:35
void flushOverlayManager()
Definition: gridwin.cxx:6597
static void lcl_DrawScenarioFrames(OutputDevice *pDev, ScViewData &rViewData, ScSplitPos eWhich, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2)
Definition: gridwin4.cxx:187
void EndDrawLayers(SdrPaintWindow &rPaintWindow, bool bPaintFormLayer)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
MapMode GetDrawMapMode(bool bForce=false)
MapMode for the drawinglayer objects.
Definition: gridwin3.cxx:252
SCROW Row() const
Definition: address.hxx:261
void setWidth(tools::Long nWidth)
void SetUseStyleColor(bool bSet)
Definition: output.hxx:323
OUString GetTitle(sal_uInt16 nMaxLen=0) const
void GetRectsAnyFor(const ScMarkData &rMarkData,::std::vector< tools::Rectangle > &rRects, bool bInPrintTwips) const
Definition: gridwin4.cxx:2088
void MarkToMulti()
Definition: markdata.cxx:224
tools::Rectangle GetListValButtonRect(const ScAddress &rButtonPos)
Definition: gridwin4.cxx:1984
void DrawClipMarks()
Definition: output.cxx:2475
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
const Fraction & GetZoomX() const
Definition: viewdata.hxx:458
void LogicInvalidate(const tools::Rectangle *pRectangle) override
Definition: gridwin4.cxx:1517
virtual SdrObject * TryToGetSdrObject() const
std::vector< LOKCursorEntry > maLOKLastCursor
Definition: gridwin.hxx:143
SC_DLLPUBLIC bool IsActiveScenario(SCTAB nTab) const
Definition: documen3.cxx:877
const std::vector< ScHighlightEntry > & GetHighlightRanges() const
Definition: tabview.hxx:329
bool bHOverlapped
Definition: fillinfo.hxx:159
ScScenarioFlags
Definition: global.hxx:235
tools::Long const nLeftMargin
SCCOL nX1
Definition: output.hxx:189
bool IsInputMode() const
Definition: inputhdl.hxx:184
Point GetPrintTwipsPos(SCCOL nCol, SCROW nRow) const
returns the position (top-left corner) of the requested cell in print twips coordinates.
Definition: viewdata.cxx:2466
SC_DLLPUBLIC bool Intersects(const ScRange &rRange) const
Definition: address.cxx:1558
SCROW GetRefStartY() const
Definition: viewdata.hxx:515
void RepeatResize(bool bUpdateFix=true)
Definition: tabview.cxx:772
std::unique_ptr< FmFormView > mpLOKDrawView
LibreOfficeKit needs a persistent FmFormView for tiled rendering, otherwise the invalidations from dr...
Definition: gridwin.hxx:111
long Long
virtual void calculateGridOffsetForViewOjectContact(basegfx::B2DVector &rTarget, const ViewObjectContact &rClient) const
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
const SCCOL * GetPageEndX() const
Definition: pagedata.hxx:50
const StyleSettings & GetStyleSettings() const
SCROW GetCurY() const
Definition: viewdata.hxx:401
svtools::ColorConfig & GetColorConfig()
Definition: scmod.cxx:816
bool IsOverlapped() const
Definition: attrib.hxx:101
void DrawRefMark(SCCOL nRefStartX, SCROW nRefStartY, SCCOL nRefEndX, SCROW nRefEndY, const Color &rColor, bool bHandle)
Draws reference mark and returns its properties.
Definition: output.cxx:2012
SCSIZE mnArrCount
Definition: fillinfo.hxx:195
bool IsMapModeEnabled() const
#define SC_SCENARIO_VSPACE
Definition: output.hxx:55
sal_Int64 n
ScViewData & mrViewData
Definition: gridwin.hxx:147
ViewShellDocId GetDocId() const override
virtual Size GetSizePixel() const
void DrawChangeTrack()
Definition: output.cxx:2257
void AddRect(const tools::Rectangle &rRect)
Definition: invmerge.cxx:123
ScPrintRangeData & GetData(size_t i)
Definition: pagedata.cxx:60
const ContentProperties & rData
double GetPPTX() const
Definition: viewdata.hxx:467
bool HasEditView(ScSplitPos eWhich) const
Definition: viewdata.hxx:563
const MapMode & GetMapMode() const
void SetOptSizePixel()
Definition: cbuttonw.cxx:43
SCTAB GetTabNo() const
Definition: viewdata.hxx:394
constexpr SdrLayerID SC_LAYER_BACK(1)
static void lcl_GetEditAreaTLOffset(tools::Long &nOffsetX, tools::Long &nOffsetY, const ScAddress &rAddr, const ScViewData &rViewData, ScDocument &rDoc)
Definition: gridwin4.cxx:280
bool IsSyntaxMode() const
Definition: viewdata.hxx:540
SCCOLROW nField
Definition: queryentry.hxx:51
ScRange Combine() const
Definition: rangelst.cxx:1112
DataChangedEventType GetType() const
ScAddress aEnd
Definition: address.hxx:500
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:397
static void UpdateInputLine()
Definition: tabview3.cxx:3003
void SetSolidBackground(bool bSet)
Definition: output.hxx:322
ScDocument & GetDocument() const
Definition: viewdata.hxx:379
void SetShowFormulas(bool bSet)
Definition: output.cxx:252
void SetCellSelectionPixel(int nType, int nPixelX, int nPixelY)
Update the cell selection according to what handles have been dragged.
Definition: gridwin4.cxx:1540
const tools::Rectangle & GetOutputArea() const
void UpdateAllOverlays()
Definition: tabview2.cxx:1000
void SetMarkClipped(bool bSet)
Definition: output.cxx:242
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
void SetSizePixel(const Size &rNewSize)
Definition: cbutton.hxx:45
void Invalidate(sal_uInt16 nId)
SC_DLLPUBLIC void SetCursor(SCCOL nPosX, SCROW nPosY, bool bNew=false)
Definition: tabview3.cxx:361
SCCOL GetPosX(ScHSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1342
void SetMapMode()
SCROW GetEditEndRow() const
Definition: viewdata.hxx:589
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
void SetRight(tools::Long v)
SCROW nRowNo
Definition: fillinfo.hxx:181
SC_DLLPUBLIC SvtScriptType GetStringScriptType(const OUString &rString)
Definition: documen6.cxx:76
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4351
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4153
void SetContentDevice(OutputDevice *pContentDev)
Definition: output.cxx:221
SCROW nY2
Definition: output.hxx:192
ScSplitPos
Definition: viewdata.hxx:44
void DrawPagePreview(SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, vcl::RenderContext &rRenderContext)
Definition: gridwin4.cxx:1630
bool IsCellMarked(SCCOL nCol, SCROW nRow, bool bNoSimple=false) const
Definition: markdata.cxx:285
bool bIsInPaint
Definition: gridwin.hxx:209
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6048
bool IsEmpty() const
constexpr tools::Long Width() const
HashMap_OWString_Interface aMap
const SCROW * GetPageEndY() const
Definition: pagedata.hxx:52
SfxPrinter * GetPrinter(bool bCreateIfNotExist=true)
Definition: documen8.cxx:113
tools::Rectangle aInvertRect
Definition: gridwin.hxx:199
void disposeAndReset(VirtualDevice *pBody)
static tools::Long ToPixel(sal_uInt16 nTwips, double nFactor)
Definition: viewdata.hxx:681
bool IsOle() const
Definition: viewdata.cxx:3902
void DrawSdrGrid(const tools::Rectangle &rDrawingRect, OutputDevice *pContentDev)
Definition: gridwin3.cxx:234
bool IsAutoFilterActive(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: gridwin4.cxx:2034
ScPageBreakData * GetPageBreakData()
Definition: tabview.hxx:328
tools::Long Left() const
void SetLeft(tools::Long v)
void SetFmtDevice(OutputDevice *pRDev)
Definition: output.hxx:317
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:871
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const Fraction & GetScaleY() const
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:313
vcl::Cursor * GetCursor() const
OutputDevice & GetTargetOutputDevice()
void Draw(SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMode eMode)
Definition: gridwin4.cxx:457
SCCOL VisibleCellsX(ScHSplitPos eWhichX) const
Definition: viewdata.cxx:2622
bool IsMultiMarked() const
Definition: markdata.hxx:82
void DrawContent(OutputDevice &rDevice, const ScTableInfo &rTableInfo, ScOutputData &aOutputData, bool bLogicText)
Draw content of the gridwindow; shared between the desktop and the tiled rendering.
Definition: gridwin4.cxx:624
int nCount
static SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
SC_DLLPUBLIC SCSIZE GetEntryCount() const
Definition: queryparam.cxx:119
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3478
AllSettingsFlags GetFlags() const
tools::Long Bottom() const
bool isCompatFlagSet(Compat flag)
SC_DLLPUBLIC const ScQueryEntry & GetEntry(SCSIZE n) const
Definition: queryparam.cxx:124
void CheckNeedsRepaint()
Definition: gridwin4.cxx:1609
void UpdateInputHandler(bool bForce=false, bool bStopEditing=true)
Definition: tabvwsha.cxx:653
SCTAB Tab() const
Definition: address.hxx:270
void SetDrawView(FmFormView *pNew)
Definition: output.hxx:320
void GetSelectionRectsPrintTwips(::std::vector< tools::Rectangle > &rRects) const
Definition: gridwin4.cxx:2076
void RecalcPPT()
Definition: tabview3.cxx:2768
void DoneBlockMode(bool bContinue=false)
Definition: tabview2.cxx:409
void PrepareFormulaCalc()
Call this before any operations that might trigger one or more formula cells to get calculated...
Definition: document.cxx:2440
SCROW GetPosY(ScVSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1356
size_t GetCount() const
Definition: pagedata.hxx:73
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
const Fraction & GetZoomY() const
Definition: viewdata.hxx:459
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4727
ScDrawView * GetScDrawView()
Definition: viewdata.cxx:3075
ScViewData & GetViewData()
Definition: tabview.hxx:333
ScAddress aListValPos
Definition: gridwin.hxx:197
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2395
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4706
ScVSplitPos eVWhich
Definition: gridwin.hxx:150
void DrawRect(const tools::Rectangle &rRect)
bool GetTextWysiwyg() const
Definition: inputopt.hxx:65
constexpr auto convert(N n, sal_Int64 mul, sal_Int64 div)
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:70
SCROW VisibleCellsY(ScVSplitPos eWhichY) const
Definition: viewdata.cxx:2627
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:953
bool empty() const
Definition: rangelst.hxx:88
void SetEditCell(SCCOL nCol, SCROW nRow)
Definition: output.cxx:267
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1939
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:356
bool bAutoFilter
Definition: fillinfo.hxx:161
constexpr double nPPTX
void SetAlignment(FontAlign)
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1057
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:870
void SetLineColor()
T * get() const
bool IsVerOverlapped() const
Definition: attrib.hxx:100
virtual void PrePaint(vcl::RenderContext &rRenderContext) override
Definition: gridwin4.cxx:312
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4437
void SetScaleX(const Fraction &rScaleX)
static void GetFont(vcl::Font &rFont, const SfxItemSet &rItemSet, ScAutoFontColorMode eAutoMode, const OutputDevice *pOutDev=nullptr, const Fraction *pScale=nullptr, const SfxItemSet *pCondSet=nullptr, SvtScriptType nScript=SvtScriptType::NONE, const Color *pBackConfigColor=nullptr, const Color *pTextConfigColor=nullptr)
Static helper function to fill a font object from the passed item set.
Definition: patattr.cxx:214
SdrPaintWindow * BeginDrawLayers(OutputDevice *pOut, const vcl::Region &rReg, bool bDisableIntersect=false)
SCCOL nX2
Definition: output.hxx:191
SCTAB GetRefEndZ() const
Definition: viewdata.hxx:519
int i
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2314
bool IsClipRegion() const
bool bChanged
Definition: fillinfo.hxx:187
bool bFilterActive
Definition: fillinfo.hxx:164
tools::Long GetFirstPage() const
Definition: pagedata.hxx:55
SfxBindings & GetBindings()
Definition: viewdata.cxx:3035
void GetPosFromPixel(tools::Long nClickX, tools::Long nClickY, ScSplitPos eWhich, SCCOL &rPosX, SCROW &rPosY, bool bTestMerge=true, bool bRepair=false, SCTAB nForTab=-1)
Definition: viewdata.cxx:2695
sal_Int16 SCCOL
Definition: types.hxx:21
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:873
bool HasBackgroundDraw(SCTAB nTab, const tools::Rectangle &rMMRect) const
Definition: documen9.cxx:343
#define SC_MOD()
Definition: scmod.hxx:249
ScSplitPos GetEditActivePart() const
Definition: viewdata.hxx:583
SC_DLLPUBLIC void GetTiledRenderingArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow) const
Return the number of columns / rows that should be visible for the tiled rendering.
Definition: documen2.cxx:666
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:872
void SetOrigin(const Point &rOrigin)
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: gridwin4.cxx:381
bool SetChangedClip()
Definition: output.cxx:1775
const ScRange & GetPrintRange() const
Definition: pagedata.hxx:44
void SetFillColor()
size_t size() const
Definition: rangelst.hxx:89
void setLocalRendering(bool bLocalRendering=true)
void DrawBackground(vcl::RenderContext &rRenderContext)
Definition: output.cxx:1019
void MarkScenario(SCTAB nSrcTab, SCTAB nDestTab, ScMarkData &rDestMark, bool bResetMark=true, ScScenarioFlags nNeededBits=ScScenarioFlags::NONE) const
Definition: documen3.cxx:852
OUString ScResId(const char *pId)
Definition: scdll.cxx:89
bool IsActive() const
Definition: viewdata.hxx:381
void DrawDocumentBackground()
Definition: output.cxx:834
bool GetOption(ScViewOption eOpt) const
Definition: viewopti.hxx:87
void SetScaleY(const Fraction &rScaleY)
const Size & GetFontSize() const
bool bVOverlapped
Definition: fillinfo.hxx:160
void DrawStrings(bool bPixelToLogic=false)
Definition: output2.cxx:1481
SCROW nY1
Definition: output.hxx:190
void SetTop(tools::Long v)
sal_uInt16 nCursorHideCount
Definition: gridwin.hxx:161
void SetBottom(tools::Long v)
const AllSettings & GetSettings() const
Size GetOutputSizePixel() const
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: gridwin4.cxx:2277
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
Definition: address.hxx:692
void ResetChanged(const ScRange &rRange)
Definition: document.cxx:4063
sal_uInt16 nPaintCount
Definition: gridwin.hxx:193
void GetPixelRectsFor(const ScMarkData &rMarkData,::std::vector< tools::Rectangle > &rPixelRects) const
convert rMarkData into pixel rectangles for this view
Definition: gridwin4.cxx:2082
SCCOL GetRefEndX() const
Definition: viewdata.hxx:517
tools::Long Top() const
const sdr::contact::ObjectContact & GetObjectContact() const
static SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
bool UpdateVisibleRange()
Definition: gridwin2.cxx:618
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
Definition: dbdata.cxx:300
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5555
tools::Long nScrX
Definition: output.hxx:184
void DrawClear()
Definition: output.cxx:1323
void SetGridColor(const Color &rColor)
Definition: output.cxx:237
Size GetSize() const
ScSplitPos eWhich
Definition: gridwin.hxx:148
SCCOL Col() const
Definition: address.hxx:266
bool bNeedsRepaint
Definition: gridwin.hxx:210
SCTAB nTab
Definition: output.hxx:183
void SetColor(const Color &)
ScDBFunc * GetView() const
Definition: viewdata.cxx:853
virtual sdr::contact::ObjectContact * createViewSpecificObjectContact(SdrPageWindow &rPageWindow, const char *pDebugName) const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
static SfxItemPool * CreatePool()
SCCOL GetRefStartX() const
Definition: viewdata.hxx:514
MapUnit GetMapUnit()
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
void PaintTile(VirtualDevice &rDevice, int nOutputWidth, int nOutputHeight, int nTilePosX, int nTilePosY, tools::Long nTileWidth, tools::Long nTileHeight)
Definition: gridwin4.cxx:1363
SC_DLLPUBLIC void GetScenarioData(SCTAB nTab, OUString &rComment, Color &rColor, ScScenarioFlags &rFlags) const
Definition: documen3.cxx:468
bool IsHorOverlapped() const
Definition: attrib.hxx:99
void SetPosPixel(const Point &rNewPos)
Definition: cbutton.hxx:42
sal_uLong Count() const
Definition: rfindlst.hxx:50
SCTAB GetRefStartZ() const
Definition: viewdata.hxx:516
ScRange aRef
Definition: rfindlst.hxx:30
void DrawGrid(vcl::RenderContext &rRenderContext, bool bGrid, bool bPage, bool bMergeCover=false)
Definition: output.cxx:291
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
void DrawRedraw(ScOutputData &rOutputData, SdrLayerID nLayer)
Definition: gridwin3.cxx:209
sal_Int32 SCROW
Definition: types.hxx:17
ALIGN_TOP
SC_DLLPUBLIC void PutInOrder()
Definition: address.cxx:1582
static SC_DLLPUBLIC SvtScriptType GetDefaultScriptType()
Definition: global.cxx:849
VisibleRange maVisibleRange
Definition: gridwin.hxx:132
void SetShowSpellErrors(bool bSet)
Definition: output.cxx:257
double GetPPTY() const
Definition: viewdata.hxx:468
bool ValidRow(SCROW nRow) const
Definition: document.hxx:874
tools::Long const nTopMargin
const Point & GetPosPixel() const
Definition: cbutton.hxx:43
bool bPivotPopupButton
Definition: fillinfo.hxx:163
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
void Draw(const Point &rAt, const Size &rSize)
Definition: cbuttonw.cxx:49
SC_DLLPUBLIC bool IsScenario(SCTAB nTab) const
Definition: documen3.cxx:432
ScDrawView * GetScDrawView()
Definition: tabview.hxx:341
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CTL(EE_CHAR_START+20)
ScUpdateMode
Definition: viewutil.hxx:39
void PrePaint()
bool IsAutomatic() const
Definition: pagedata.hxx:59
constexpr tools::Long Height() const
SCCOL GetEditStartCol() const
Definition: viewdata.hxx:586
void setWidth(tools::Long n)
void SetFont(const vcl::Font &rNewFont)
static void lcl_LimitRect(tools::Rectangle &rRect, const tools::Rectangle &rVisible)
Definition: gridwin4.cxx:80
bool GetShowGrid() const
Definition: viewdata.hxx:462
virtual vcl::Region GetActiveClipRegion() const
constexpr SdrLayerID SC_LAYER_FRONT(0)
tools::Long GetTextHeight() const
SC_DLLPUBLIC ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4366
SvtScriptType nPageScript
Definition: gridwin.hxx:181
constexpr TypedWhichId< SvxColorItem > EE_CHAR_COLOR(EE_CHAR_START+0)
constexpr SdrLayerID SC_LAYER_INTERN(2)
virtual bool supportsGridOffsets() const
void SetViewShell(ScTabViewShell *pSh)
Definition: output.hxx:318
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
void SetSpellCheckContext(const sc::SpellCheckContext *pCxt)
Definition: output.cxx:216
const ScViewOptions & GetOptions() const
Definition: viewdata.hxx:536
const value_type & getNearestByPosition(tools::Long nPos) const
Definition: viewdata.cxx:219
void Paint(const tools::Rectangle &rRect, OutputDevice *pTargetDevice=nullptr)
SCCOL GetEditEndCol() const
Definition: viewdata.hxx:588
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:400
SC_DLLPUBLIC const ScInputOptions & GetInputOptions()
Definition: scmod.cxx:776
static void lcl_DrawOneFrame(vcl::RenderContext *pDev, const tools::Rectangle &rInnerPixel, const OUString &rTitle, const Color &rColor, bool bTextBelow, double nPPTX, double nPPTY, const Fraction &rZoomY, ScDocument &rDoc, ScViewData &rButtonViewData, bool bLayoutRTL)
Definition: gridwin4.cxx:90
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
bool IsAutoSpell() const
Definition: docoptio.hxx:53
bool GetMergeSizePixel(SCCOL nX, SCROW nY, tools::Long &rSizeXPix, tools::Long &rSizeYPix) const
Definition: viewdata.cxx:2642
SC_DLLPUBLIC void GetQueryParam(ScQueryParam &rQueryParam) const
Definition: dbdata.cxx:409
const Point & GetOrigin() const
size_t GetPagesX() const
Definition: pagedata.hxx:49
const SCROW MAXTILEDROW
Definition: address.hxx:75
ScQueryConnect eConnect
Definition: queryentry.hxx:53
static void AddPixelsWhile(tools::Long &rScrY, tools::Long nEndPixels, SCROW &rPosY, SCROW nEndRow, double nPPTY, const ScDocument *pDoc, SCTAB nTabNo)
while (rScrY <= nEndPixels && rPosY <= nEndRow) add pixels of row heights converted with nPPTY to rSc...
Definition: viewdata.cxx:4023
SC_DLLPUBLIC void ExtendTotalMerge(ScRange &rRange) const
Definition: document.cxx:5605
ScPositionHelper & GetLOKWidthHelper()
Definition: viewdata.hxx:409
void DrawNoteMarks(vcl::RenderContext &rRenderContext)
Definition: output.cxx:2322
CALCPAGEBREAKMANUAL
const Size & GetSizePixel() const
Definition: cbutton.hxx:46
bool IsTopDown() const
Definition: pagedata.hxx:57
tools::Long GetScrH() const
Definition: output.hxx:335
void SetMarking(bool bFlag)
Definition: markdata.hxx:102
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:985
Color const & GetGridColor(OUString *pStrName=nullptr) const
Definition: viewopti.cxx:117
bool IsVisible() const
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4421
const vcl::Font & GetAppFont() const
void SetOutputArea(const tools::Rectangle &rRect)
void setHeight(tools::Long nHeight)
ScAddress aAutoMarkPos
Definition: gridwin.hxx:196
void SetZoom(const Fraction &rNewX, const Fraction &rNewY, std::vector< SCTAB > &tabs)
Definition: viewdata.cxx:1025
tools::Long GetScrW() const
Definition: output.hxx:334
ViewContact & GetViewContact() const
void SetMirrorWidth(tools::Long nNew)
Definition: output.cxx:232
void UpdateFontList()
Definition: docsh3.cxx:455
ScRangeFindData & GetObject(sal_uLong nIndex)
Definition: rfindlst.hxx:53
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
SCTAB GetRefTabNo() const
Definition: viewdata.hxx:391
tools::Rectangle GetEditCursor() const
VirtualDevice * get() const
ScRangeList GetMarkedRanges() const
Definition: markdata.cxx:465
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CJK(EE_CHAR_START+19)
SCROW GetRowMerge() const
Definition: attrib.hxx:69
void GetMultiMarkArea(ScRange &rRange) const
Definition: markdata.cxx:117
ScInputHandler * GetInputHdl(ScTabViewShell *pViewSh=nullptr, bool bUseRef=true)
Input-Handler.
Definition: scmod.cxx:1304
void DoInvertRect(const tools::Rectangle &rPixel)
Definition: gridwin4.cxx:298
const MapMode & GetLogicMode(ScSplitPos eWhich)
Definition: viewdata.cxx:2921
CellInfo * pCellInfo
Definition: fillinfo.hxx:178
tools::Rectangle aRepaintPixel
Definition: gridwin.hxx:194
const OUString & GetDocName() const
Definition: rfindlst.hxx:57
ScPositionHelper & GetLOKHeightHelper()
Definition: viewdata.hxx:410
void DrawEdit(bool bPixelToLogic)
Definition: output2.cxx:4290
const ScDBData * GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const
Definition: documen3.cxx:322
void DrawShadow()
Definition: output.cxx:1177
void SetScenButSize(const Size &rNew)
Definition: viewdata.hxx:647
ScRangeFindList * GetRangeFindList()
Definition: inputhdl.hxx:251
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5465
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4112
bool IsPagebreakMode() const
Definition: viewdata.hxx:424
bool NeedLOKCursorInvalidation(const tools::Rectangle &rCursorRect, const Fraction aScaleX, const Fraction aScaleY)
Definition: gridwin4.cxx:328
void MarkCursor(SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, bool bCols=false, bool bRows=false, bool bCellSelection=false)
Definition: tabview2.cxx:449
size_t GetPagesY() const
Definition: pagedata.hxx:51
rtl::OString toString() const
ScHSplitPos eHWhich
Definition: gridwin.hxx:149
bool IsRefMode() const
Definition: viewdata.hxx:512
void GetSelectionRects(::std::vector< tools::Rectangle > &rPixelRects) const
Definition: gridwin4.cxx:2071
bool bListValButton
Definition: gridwin.hxx:212
aStr
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:212
bool bAutoMarkVisible
Definition: gridwin.hxx:211
static void notifyInvalidation(SfxViewShell const *pThisView, std::string_view rPayload)
tools::Long Right() const
Color const & GetBackgroundColor() const
void GetEditView(ScSplitPos eWhich, EditView *&rViewPtr, SCCOL &rCol, SCROW &rRow)
Definition: viewdata.cxx:2220
bool IsMinimized() const
Definition: viewdata.cxx:3081
void UpdateHeaderOverlay()
Definition: gridwin.cxx:6471
void InitBlockMode(SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, bool bTestNeg=false, bool bCols=false, bool bRows=false, bool bForceNeg=false)
Definition: tabview2.cxx:353
std::shared_ptr< sc::SpellCheckContext > mpSpellCheckCxt
Definition: gridwin.hxx:145
void ForgetLastPattern()
Definition: inputhdl.cxx:2242
sal_uInt16 nPos
static void notifyOtherView(const SfxViewShell *pThisView, SfxViewShell const *pOtherView, int nType, std::string_view rKey, const OString &rPayload)
sal_Int16 SCTAB
Definition: types.hxx:22
void SetPagebreakMode(ScPageBreakData *pPageData)
Definition: output.cxx:605
SCCOL GetCurX() const
Definition: viewdata.hxx:400
SCROW GetEditStartRow() const
Definition: viewdata.hxx:587
void FillEditItemSet(SfxItemSet *pEditSet, const SfxItemSet *pCondSet=nullptr) const
Converts all Calc items contained in the own item set to edit engine items and puts them into pEditSe...
Definition: patattr.cxx:774
#define SC_SCENARIO_HSPACE
Definition: output.hxx:54
static void lcl_DrawHighlight(ScOutputData &rOutputData, const ScViewData &rViewData, const std::vector< ScHighlightEntry > &rHighlightRanges)
Definition: gridwin4.cxx:262