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