1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include <svtools/colorcfg.hxx>
24 #include <editeng/colritem.hxx>
25 #include <editeng/editview.hxx>
26 #include <editeng/fhgtitem.hxx>
27 #include <editeng/scripttypeitem.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/printer.hxx>
30 #include <vcl/settings.hxx>
32 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
33 #include <comphelper/lok.hxx>
35 #include <svx/svdview.hxx>
36 #include "tabvwsh.hxx"
38 #include "gridwin.hxx"
39 #include "viewdata.hxx"
41 #include "document.hxx"
43 #include "patattr.hxx"
45 #include "docoptio.hxx"
46 #include "notemark.hxx"
49 #include "inputhdl.hxx"
50 #include "rfindlst.hxx"
51 #include "hiranges.hxx"
52 #include "pagedata.hxx"
53 #include "docpool.hxx"
54 #include "globstr.hrc"
56 #include "cbutton.hxx"
57 #include "invmerge.hxx"
58 #include "editutil.hxx"
59 #include "inputopt.hxx"
60 #include "fillinfo.hxx"
61 #include "dpcontrol.hxx"
62 #include "queryparam.hxx"
63 #include "queryentry.hxx"
64 #include "markdata.hxx"
66 #include <vcl/virdev.hxx>
67 #include <svx/sdrpaintwindow.hxx>
69 static void lcl_LimitRect( Rectangle
& rRect
, const Rectangle
& rVisible
)
71 if ( rRect
.Top() < rVisible
.Top()-1 ) rRect
.Top() = rVisible
.Top()-1;
72 if ( rRect
.Bottom() > rVisible
.Bottom()+1 ) rRect
.Bottom() = rVisible
.Bottom()+1;
74 // The header row must be drawn also when the inner rectangle is not visible,
75 // that is why there is no return value anymore.
76 // When it is far away, then lcl_DrawOneFrame is not even called.
79 static void lcl_DrawOneFrame( vcl::RenderContext
* pDev
, const Rectangle
& rInnerPixel
,
80 const OUString
& rTitle
, const Color
& rColor
, bool bTextBelow
,
81 double nPPTX
, double nPPTY
, const Fraction
& rZoomY
,
82 ScDocument
* pDoc
, ScViewData
* pButtonViewData
, bool bLayoutRTL
)
84 // pButtonViewData is only used to set the button size,
85 // can otherwise be NULL!
87 Rectangle aInner
= rInnerPixel
;
90 aInner
.Left() = rInnerPixel
.Right();
91 aInner
.Right() = rInnerPixel
.Left();
94 Rectangle
aVisible( Point(0,0), pDev
->GetOutputSizePixel() );
95 lcl_LimitRect( aInner
, aVisible
);
97 Rectangle aOuter
= aInner
;
98 long nHor
= (long) ( SC_SCENARIO_HSPACE
* nPPTX
);
99 long nVer
= (long) ( SC_SCENARIO_VSPACE
* nPPTY
);
100 aOuter
.Left() -= nHor
;
101 aOuter
.Right() += nHor
;
102 aOuter
.Top() -= nVer
;
103 aOuter
.Bottom() += nVer
;
105 // use ScPatternAttr::GetFont only for font size
107 static_cast<const ScPatternAttr
&>(pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
)).
108 GetFont(aAttrFont
,SC_AUTOCOL_BLACK
,pDev
,&rZoomY
);
110 // everything else from application font
111 vcl::Font aAppFont
= pDev
->GetSettings().GetStyleSettings().GetAppFont();
112 aAppFont
.SetFontSize( aAttrFont
.GetFontSize() );
114 aAppFont
.SetAlignment( ALIGN_TOP
);
115 pDev
->SetFont( aAppFont
);
117 Size
aTextSize( pDev
->GetTextWidth( rTitle
), pDev
->GetTextHeight() );
120 aOuter
.Bottom() += aTextSize
.Height();
122 aOuter
.Top() -= aTextSize
.Height();
124 pDev
->SetLineColor();
125 pDev
->SetFillColor( rColor
);
126 // left, top, right, bottom
127 pDev
->DrawRect( Rectangle( aOuter
.Left(), aOuter
.Top(), aInner
.Left(), aOuter
.Bottom() ) );
128 pDev
->DrawRect( Rectangle( aOuter
.Left(), aOuter
.Top(), aOuter
.Right(), aInner
.Top() ) );
129 pDev
->DrawRect( Rectangle( aInner
.Right(), aOuter
.Top(), aOuter
.Right(), aOuter
.Bottom() ) );
130 pDev
->DrawRect( Rectangle( aOuter
.Left(), aInner
.Bottom(), aOuter
.Right(), aOuter
.Bottom() ) );
132 long nButtonY
= bTextBelow
? aInner
.Bottom() : aOuter
.Top();
134 ScDDComboBoxButton
aComboButton(pDev
);
135 aComboButton
.SetOptSizePixel();
136 long nBWidth
= ( aComboButton
.GetSizePixel().Width() * rZoomY
.GetNumerator() )
137 / rZoomY
.GetDenominator();
138 long nBHeight
= nVer
+ aTextSize
.Height() + 1;
139 Size
aButSize( nBWidth
, nBHeight
);
140 long nButtonPos
= bLayoutRTL
? aOuter
.Left() : aOuter
.Right()-nBWidth
+1;
141 aComboButton
.Draw( Point(nButtonPos
, nButtonY
), aButSize
);
143 pButtonViewData
->SetScenButSize( aButSize
);
145 long nTextStart
= bLayoutRTL
? aInner
.Right() - aTextSize
.Width() + 1 : aInner
.Left();
147 bool bWasClip
= false;
148 vcl::Region aOldClip
;
149 bool bClip
= ( aTextSize
.Width() > aOuter
.Right() - nBWidth
- aInner
.Left() );
152 if (pDev
->IsClipRegion())
155 aOldClip
= pDev
->GetActiveClipRegion();
157 long nClipStartX
= bLayoutRTL
? aOuter
.Left() + nBWidth
: aInner
.Left();
158 long nClipEndX
= bLayoutRTL
? aInner
.Right() : aOuter
.Right() - nBWidth
;
159 pDev
->SetClipRegion( vcl::Region(Rectangle( nClipStartX
, nButtonY
+ nVer
/2,
160 nClipEndX
, nButtonY
+ nVer
/2 + aTextSize
.Height())) );
163 pDev
->DrawText( Point( nTextStart
, nButtonY
+ nVer
/2 ), rTitle
);
168 pDev
->SetClipRegion(aOldClip
);
170 pDev
->SetClipRegion();
173 pDev
->SetFillColor();
174 pDev
->SetLineColor( COL_BLACK
);
175 pDev
->DrawRect( aInner
);
176 pDev
->DrawRect( aOuter
);
179 static void lcl_DrawScenarioFrames( OutputDevice
* pDev
, ScViewData
* pViewData
, ScSplitPos eWhich
,
180 SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
)
182 ScDocument
* pDoc
= pViewData
->GetDocument();
183 SCTAB nTab
= pViewData
->GetTabNo();
184 SCTAB nTabCount
= pDoc
->GetTableCount();
185 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
187 if ( nX1
> 0 ) --nX1
;
188 if ( nY1
>=2 ) nY1
-= 2; // Hack: Header row affects two cells
189 else if ( nY1
> 0 ) --nY1
;
190 if ( nX2
< MAXCOL
) ++nX2
;
191 if ( nY2
< MAXROW
-1 ) nY2
+= 2; // Hack: Header row affects two cells
192 else if ( nY2
< MAXROW
) ++nY2
;
193 ScRange
aViewRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
195 //! cache the ranges in table!!!!
198 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
199 pDoc
->MarkScenario( i
, nTab
, aMarks
, false, SC_SCENARIO_SHOWFRAME
);
200 ScRangeListRef xRanges
= new ScRangeList
;
201 aMarks
.FillRangeListWithMarks( xRanges
, false );
203 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
204 long nLayoutSign
= bLayoutRTL
? -1 : 1;
206 for (size_t j
= 0, n
= xRanges
->size(); j
< n
; ++j
)
208 ScRange aRange
= *(*xRanges
)[j
];
209 // Always extend scenario frame to merged cells where no new non-covered cells
211 pDoc
->ExtendTotalMerge( aRange
);
213 //! -> Extend repaint when merging !!!
215 if ( aRange
.Intersects( aViewRange
) ) //! Space for Text/Button?
217 Point aStartPos
= pViewData
->GetScrPos(
218 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, true );
219 Point aEndPos
= pViewData
->GetScrPos(
220 aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
, true );
222 aStartPos
.X() -= nLayoutSign
;
224 aEndPos
.X() -= nLayoutSign
;
227 bool bTextBelow
= ( aRange
.aStart
.Row() == 0 );
230 Color
aColor( COL_LIGHTGRAY
);
231 for (SCTAB nAct
=nTab
+1; nAct
<nTabCount
&& pDoc
->IsScenario(nAct
); nAct
++)
232 if ( pDoc
->IsActiveScenario(nAct
) && pDoc
->HasScenarioRange(nAct
,aRange
) )
234 OUString aDummyComment
;
235 sal_uInt16 nDummyFlags
;
236 pDoc
->GetName( nAct
, aCurrent
);
237 pDoc
->GetScenarioData( nAct
, aDummyComment
, aColor
, nDummyFlags
);
240 if (aCurrent
.isEmpty())
241 aCurrent
= ScGlobal::GetRscString( STR_EMPTYDATA
);
243 //! Own text "(None)" instead of "(Empty)" ???
245 lcl_DrawOneFrame( pDev
, Rectangle( aStartPos
, aEndPos
),
246 aCurrent
, aColor
, bTextBelow
,
247 pViewData
->GetPPTX(), pViewData
->GetPPTY(), pViewData
->GetZoomY(),
248 pDoc
, pViewData
, bLayoutRTL
);
254 static void lcl_DrawHighlight( ScOutputData
& rOutputData
, ScViewData
* pViewData
,
255 const std::vector
<ScHighlightEntry
>& rHighlightRanges
)
257 SCTAB nTab
= pViewData
->GetTabNo();
258 std::vector
<ScHighlightEntry
>::const_iterator pIter
;
259 for ( pIter
= rHighlightRanges
.begin(); pIter
!= rHighlightRanges
.end(); ++pIter
)
261 ScRange aRange
= pIter
->aRef
;
262 if ( nTab
>= aRange
.aStart
.Tab() && nTab
<= aRange
.aEnd
.Tab() )
264 rOutputData
.DrawRefMark(
265 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
266 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
267 pIter
->aColor
, false );
272 void ScGridWindow::DoInvertRect( const Rectangle
& rPixel
)
274 if ( rPixel
== aInvertRect
)
275 aInvertRect
= Rectangle(); // Cancel
278 OSL_ENSURE( aInvertRect
.IsEmpty(), "DoInvertRect no pairs" );
280 aInvertRect
= rPixel
; // Mark new rectangle
283 UpdateHeaderOverlay(); // uses aInvertRect
286 void ScGridWindow::PrePaint(vcl::RenderContext
& /*rRenderContext*/)
288 // forward PrePaint to DrawingLayer
289 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
293 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
297 pDrawView
->PrePaint();
302 void ScGridWindow::Paint( vcl::RenderContext
& /*rRenderContext*/, const Rectangle
& rRect
)
304 ScDocument
* pDoc
= pViewData
->GetDocument();
305 if ( pDoc
->IsInInterpreter() )
307 // Via Reschedule, interpretended cells do not trigger Invalidate again,
308 // otherwise for instance an error box would never appear (bug 36381).
309 // Later, through bNeedsRepaint everything is painted again.
313 aRepaintPixel
= Rectangle(); // multiple -> paint all
317 bNeedsRepaint
= true;
318 aRepaintPixel
= LogicToPixel(rRect
); // only affected ranges
323 // #i117893# If GetSizePixel needs to call the resize handler, the resulting nested Paint call
324 // (possibly for a larger rectangle) has to be allowed. Call GetSizePixel before setting bIsInPaint.
332 Rectangle aPixRect
= LogicToPixel( rRect
);
334 SCCOL nX1
= pViewData
->GetPosX(eHWhich
);
335 SCROW nY1
= pViewData
->GetPosY(eVWhich
);
337 SCTAB nTab
= pViewData
->GetTabNo();
339 double nPPTX
= pViewData
->GetPPTX();
340 double nPPTY
= pViewData
->GetPPTY();
342 Rectangle aMirroredPixel
= aPixRect
;
343 if ( pDoc
->IsLayoutRTL( nTab
) )
346 long nWidth
= GetSizePixel().Width();
347 aMirroredPixel
.Left() = nWidth
- 1 - aPixRect
.Right();
348 aMirroredPixel
.Right() = nWidth
- 1 - aPixRect
.Left();
351 long nScrX
= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
352 while ( nScrX
<= aMirroredPixel
.Left() && nX1
< MAXCOL
)
355 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
358 while ( nScrX
<= aMirroredPixel
.Right() && nX2
< MAXCOL
)
361 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX2
, nTab
), nPPTX
);
365 ScViewData::AddPixelsWhile( nScrY
, aPixRect
.Top(), nY1
, MAXROW
, nPPTY
, pDoc
, nTab
);
367 if (nScrY
<= aPixRect
.Bottom() && nY2
< MAXROW
)
370 ScViewData::AddPixelsWhile( nScrY
, aPixRect
.Bottom(), nY2
, MAXROW
, nPPTY
, pDoc
, nTab
);
373 Draw( nX1
,nY1
,nX2
,nY2
, SC_UPDATE_MARKS
); // don't continue with painting
378 void ScGridWindow::Draw( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, ScUpdateMode eMode
)
380 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
381 ScDocument
& rDoc
= pDocSh
->GetDocument();
383 // let's ignore the normal Draw() attempts when doing the tiled rendering,
384 // all the rendering should go through PaintTile() in that case.
385 // TODO revisit if we can actually turn this into an assert(), and clean
387 if (comphelper::LibreOfficeKit::isActive())
390 ScModule
* pScMod
= SC_MOD();
391 bool bTextWysiwyg
= pScMod
->GetInputOptions().GetTextWysiwyg();
393 if (pViewData
->IsMinimized())
396 PutInOrder( nX1
, nX2
);
397 PutInOrder( nY1
, nY2
);
399 OSL_ENSURE( ValidCol(nX2
) && ValidRow(nY2
), "GridWin Draw area too big" );
401 UpdateVisibleRange();
403 if (nX2
< maVisibleRange
.mnCol1
|| nY2
< maVisibleRange
.mnRow1
)
406 if (nX1
< maVisibleRange
.mnCol1
)
407 nX1
= maVisibleRange
.mnCol1
;
408 if (nY1
< maVisibleRange
.mnRow1
)
409 nY1
= maVisibleRange
.mnRow1
;
411 if (nX1
> maVisibleRange
.mnCol2
|| nY1
> maVisibleRange
.mnRow2
)
414 if (nX2
> maVisibleRange
.mnCol2
)
415 nX2
= maVisibleRange
.mnCol2
;
416 if (nY2
> maVisibleRange
.mnRow2
)
417 nY2
= maVisibleRange
.mnRow2
;
419 if ( eMode
!= SC_UPDATE_MARKS
&& nX2
< maVisibleRange
.mnCol2
)
420 nX2
= maVisibleRange
.mnCol2
; // to continue painting
422 // point of no return
424 ++nPaintCount
; // mark that painting is in progress
426 SCTAB nTab
= pViewData
->GetTabNo();
427 rDoc
.ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
429 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
430 long nMirrorWidth
= GetSizePixel().Width();
431 bool bLayoutRTL
= rDoc
.IsLayoutRTL( nTab
);
434 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, maVisibleRange
.mnRow1
, eWhich
).X();
435 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
436 aScrPos
.X() = nEndPixel
+ 1;
439 long nScrX
= aScrPos
.X();
440 long nScrY
= aScrPos
.Y();
442 SCCOL nCurX
= pViewData
->GetCurX();
443 SCROW nCurY
= pViewData
->GetCurY();
444 SCCOL nCurEndX
= nCurX
;
445 SCROW nCurEndY
= nCurY
;
446 rDoc
.ExtendMerge( nCurX
, nCurY
, nCurEndX
, nCurEndY
, nTab
);
447 bool bCurVis
= nCursorHideCount
==0 &&
448 ( nCurEndX
+1 >= nX1
&& nCurX
<= nX2
+1 && nCurEndY
+1 >= nY1
&& nCurY
<= nY2
+1 );
451 if ( !bCurVis
&& nCursorHideCount
==0 && bAutoMarkVisible
&& aAutoMarkPos
.Tab() == nTab
&&
452 ( aAutoMarkPos
.Col() != nCurX
|| aAutoMarkPos
.Row() != nCurY
) )
454 SCCOL nHdlX
= aAutoMarkPos
.Col();
455 SCROW nHdlY
= aAutoMarkPos
.Row();
456 rDoc
.ExtendMerge( nHdlX
, nHdlY
, nHdlX
, nHdlY
, nTab
);
457 // left and top is unaffected
459 //! Paint AutoFill handles alone (without Cursor) ???
462 double nPPTX
= pViewData
->GetPPTX();
463 double nPPTY
= pViewData
->GetPPTY();
465 const ScViewOptions
& rOpts
= pViewData
->GetOptions();
469 ScTableInfo aTabInfo
;
470 rDoc
.FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
,
471 nPPTX
, nPPTY
, false, rOpts
.GetOption(VOPT_FORMULAS
),
472 &pViewData
->GetMarkData() );
474 Fraction aZoomX
= pViewData
->GetZoomX();
475 Fraction aZoomY
= pViewData
->GetZoomY();
476 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, &rDoc
, nTab
,
477 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
480 aOutputData
.SetMirrorWidth( nMirrorWidth
); // needed for RTL
481 aOutputData
.SetSpellCheckContext(mpSpellCheckCxt
.get());
483 ScopedVclPtr
< VirtualDevice
> xFmtVirtDev
;
484 bool bLogicText
= bTextWysiwyg
; // call DrawStrings in logic MapMode?
488 // use printer for text formatting
490 OutputDevice
* pFmtDev
= rDoc
.GetPrinter();
491 pFmtDev
->SetMapMode( pViewData
->GetLogicMode(eWhich
) );
492 aOutputData
.SetFmtDevice( pFmtDev
);
494 else if ( aZoomX
!= aZoomY
&& pViewData
->IsOle() )
496 // #i45033# For OLE inplace editing with different zoom factors,
497 // use a virtual device with 1/100th mm as text formatting reference
499 xFmtVirtDev
.disposeAndReset( VclPtr
<VirtualDevice
>::Create() );
500 xFmtVirtDev
->SetMapMode( MAP_100TH_MM
);
501 aOutputData
.SetFmtDevice( xFmtVirtDev
.get() );
503 bLogicText
= true; // use logic MapMode
506 DrawContent(*this, aTabInfo
, aOutputData
, bLogicText
, eMode
);
508 // If something was inverted during the Paint (selection changed from Basic Macro)
509 // then this is now mixed up and has to be repainted
510 OSL_ENSURE(nPaintCount
, "Wrong nPaintCount");
515 // Flag drawn formula cells "unchanged".
516 rDoc
.ResetChanged(ScRange(nX1
, nY1
, nTab
, nX2
, nY2
, nTab
));
517 rDoc
.ClearFormulaContext();
520 void ScGridWindow::DrawContent(OutputDevice
&rDevice
, const ScTableInfo
& rTableInfo
, ScOutputData
& aOutputData
,
521 bool bLogicText
, ScUpdateMode eMode
)
523 ScModule
* pScMod
= SC_MOD();
524 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
525 ScDocument
& rDoc
= pDocSh
->GetDocument();
526 const ScViewOptions
& rOpts
= pViewData
->GetOptions();
527 bool bIsTiledRendering
= comphelper::LibreOfficeKit::isActive();
529 SCTAB nTab
= aOutputData
.nTab
;
530 SCCOL nX1
= aOutputData
.nX1
;
531 SCROW nY1
= aOutputData
.nY1
;
532 SCCOL nX2
= aOutputData
.nX2
;
533 SCROW nY2
= aOutputData
.nY2
;
534 long nScrX
= aOutputData
.nScrX
;
535 long nScrY
= aOutputData
.nScrY
;
537 const svtools::ColorConfig
& rColorCfg
= pScMod
->GetColorConfig();
538 Color
aGridColor( rColorCfg
.GetColorValue( svtools::CALCGRID
, false ).nColor
);
539 if ( aGridColor
.GetColor() == COL_TRANSPARENT
)
541 // use view options' grid color only if color config has "automatic" color
542 aGridColor
= rOpts
.GetGridColor();
545 aOutputData
.SetSyntaxMode ( pViewData
->IsSyntaxMode() );
546 aOutputData
.SetGridColor ( aGridColor
);
547 aOutputData
.SetShowNullValues ( rOpts
.GetOption( VOPT_NULLVALS
) );
548 aOutputData
.SetShowFormulas ( rOpts
.GetOption( VOPT_FORMULAS
) );
549 aOutputData
.SetShowSpellErrors ( rDoc
.GetDocOptions().IsAutoSpell() );
550 aOutputData
.SetMarkClipped ( rOpts
.GetOption( VOPT_CLIPMARKS
) );
552 aOutputData
.SetUseStyleColor( true ); // always set in table view
554 aOutputData
.SetEditObject( GetEditObject() );
555 aOutputData
.SetViewShell( pViewData
->GetViewShell() );
557 bool bGrid
= rOpts
.GetOption( VOPT_GRID
) && pViewData
->GetShowGrid();
558 bool bGridFirst
= !rOpts
.GetOption( VOPT_GRID_ONTOP
);
560 bool bPage
= rOpts
.GetOption( VOPT_PAGEBREAKS
);
562 if ( eMode
== SC_UPDATE_CHANGED
)
564 aOutputData
.FindChanged();
565 aOutputData
.SetSingleGrid(true);
568 bool bPageMode
= pViewData
->IsPagebreakMode();
569 if (bPageMode
) // after FindChanged
571 // SetPagebreakMode initialisiert auch bPrinted Flags
572 aOutputData
.SetPagebreakMode( pViewData
->GetView()->GetPageBreakData() );
575 EditView
* pEditView
= nullptr;
576 bool bEditMode
= pViewData
->HasEditView(eWhich
);
577 if ( bEditMode
&& pViewData
->GetRefTabNo() == nTab
)
581 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
582 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
583 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
585 if ( nEditEndCol
>= nX1
&& nEditCol
<= nX2
&& nEditEndRow
>= nY1
&& nEditRow
<= nY2
)
586 aOutputData
.SetEditCell( nEditCol
, nEditRow
);
591 // define drawing layer map mode and paint rectangle
592 MapMode aDrawMode
= GetDrawMapMode();
593 if (bIsTiledRendering
)
595 // FIXME this shouldn't be necessary once we change the entire Calc to
596 // work in the logic coordinates (ideally 100ths of mm - so that it is
597 // the same as editeng and drawinglayer), and get rid of all the
598 // SetMapMode's and other unnecessary fun we have with pixels
599 // See also ScGridWindow::GetDrawMapMode() for the rest of this hack
600 aDrawMode
.SetOrigin(PixelToLogic(Point(nScrX
, nScrY
), aDrawMode
));
602 Rectangle aDrawingRectLogic
;
603 bool bLayoutRTL
= rDoc
.IsLayoutRTL( nTab
);
606 // get drawing pixel rect
607 Rectangle
aDrawingRectPixel(Point(nScrX
, nScrY
), Size(aOutputData
.GetScrW(), aOutputData
.GetScrH()));
609 // correct for border (left/right)
614 aDrawingRectPixel
.Left() = 0L;
618 aDrawingRectPixel
.Right() = GetOutputSizePixel().getWidth();
622 // correct for border (bottom)
625 aDrawingRectPixel
.Bottom() = GetOutputSizePixel().getHeight();
628 // get logic positions
629 aDrawingRectLogic
= PixelToLogic(aDrawingRectPixel
, aDrawMode
);
632 OutputDevice
* pContentDev
= &rDevice
; // device for document content, used by overlay manager
633 SdrPaintWindow
* pTargetPaintWindow
= nullptr; // #i74769# work with SdrPaintWindow directly
637 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
641 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
642 pContentDev
->SetMapMode(aDrawMode
);
643 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
647 // #i74769# Use new BeginDrawLayers() interface
648 vcl::Region
aDrawingRegion(aDrawingRectLogic
);
649 pTargetPaintWindow
= pDrawView
->BeginDrawLayers(pContentDev
, aDrawingRegion
);
650 OSL_ENSURE(pTargetPaintWindow
, "BeginDrawLayers: Got no SdrPaintWindow (!)");
652 if (!bIsTiledRendering
)
654 // #i74769# get target device from SdrPaintWindow, this may be the prerender
656 pContentDev
= &(pTargetPaintWindow
->GetTargetOutputDevice());
657 aOutputData
.SetContentDevice(pContentDev
);
661 pContentDev
->SetMapMode(aCurrentMapMode
);
665 // edge (area) (Pixel)
666 if ( nX2
==MAXCOL
|| nY2
==MAXROW
)
668 // save MapMode and set to pixel
669 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
670 pContentDev
->SetMapMode(MAP_PIXEL
);
672 Rectangle aPixRect
= Rectangle( Point(), GetOutputSizePixel() );
673 pContentDev
->SetFillColor( rColorCfg
.GetColorValue(svtools::APPBACKGROUND
).nColor
);
674 pContentDev
->SetLineColor();
677 Rectangle
aDrawRect( aPixRect
);
679 aDrawRect
.Right() = nScrX
- 1;
681 aDrawRect
.Left() = nScrX
+ aOutputData
.GetScrW();
682 if (aDrawRect
.Right() >= aDrawRect
.Left())
683 pContentDev
->DrawRect( aDrawRect
);
687 Rectangle
aDrawRect( aPixRect
);
688 aDrawRect
.Top() = nScrY
+ aOutputData
.GetScrH();
691 // no double painting of the corner
693 aDrawRect
.Left() = nScrX
;
695 aDrawRect
.Right() = nScrX
+ aOutputData
.GetScrW() - 1;
697 if (aDrawRect
.Bottom() >= aDrawRect
.Top())
698 pContentDev
->DrawRect( aDrawRect
);
702 pContentDev
->SetMapMode(aCurrentMapMode
);
705 if ( rDoc
.HasBackgroundDraw( nTab
, aDrawingRectLogic
) )
707 pContentDev
->SetMapMode(MAP_PIXEL
);
708 aOutputData
.DrawClear();
710 // drawing background
712 pContentDev
->SetMapMode(aDrawMode
);
713 DrawRedraw( aOutputData
, eMode
, SC_LAYER_BACK
);
716 aOutputData
.SetSolidBackground(true);
718 aOutputData
.DrawDocumentBackground();
720 if ( bGridFirst
&& ( bGrid
|| bPage
) )
721 aOutputData
.DrawGrid(*pContentDev
, bGrid
, bPage
);
723 aOutputData
.DrawBackground(*pContentDev
);
725 if ( !bGridFirst
&& ( bGrid
|| bPage
) )
726 aOutputData
.DrawGrid(*pContentDev
, bGrid
, bPage
);
728 pContentDev
->SetMapMode(MAP_PIXEL
);
732 // DrawPagePreview draws complete lines/page numbers, must always be clipped
733 if ( aOutputData
.SetChangedClip() )
735 DrawPagePreview(nX1
,nY1
,nX2
,nY2
, *pContentDev
);
736 pContentDev
->SetClipRegion();
740 aOutputData
.DrawShadow();
741 aOutputData
.DrawFrame(*pContentDev
);
744 if ( rOpts
.GetOption( VOPT_NOTES
) )
745 aOutputData
.DrawNoteMarks(*pContentDev
);
748 aOutputData
.DrawStrings(); // in pixel MapMode
750 // edit cells and printer-metrics text must be before the buttons
751 // (DataPilot buttons contain labels in UI font)
753 pContentDev
->SetMapMode(pViewData
->GetLogicMode(eWhich
));
755 aOutputData
.DrawStrings(true); // in logic MapMode if bLogicText is set
756 aOutputData
.DrawEdit(true);
758 // the buttons are painted in absolute coordinates
759 if (bIsTiledRendering
)
761 // Tiled offset nScrX, nScrY
762 MapMode
aMap( MAP_PIXEL
);
763 aMap
.SetOrigin(Point(nScrX
, nScrY
));
764 pContentDev
->SetMapMode(aMap
);
767 pContentDev
->SetMapMode(MAP_PIXEL
);
769 // Autofilter- and Pivot-Buttons
771 DrawButtons(nX1
, nX2
, rTableInfo
, pContentDev
); // Pixel
773 pContentDev
->SetMapMode(MAP_PIXEL
);
775 aOutputData
.DrawClipMarks();
777 // In any case, Szenario / ChangeTracking must happen after DrawGrid, also for !bGridFirst
779 //! Test, ob ChangeTrack-Anzeige aktiv ist
780 //! Szenario-Rahmen per View-Optionen abschaltbar?
782 SCTAB nTabCount
= rDoc
.GetTableCount();
783 const std::vector
<ScHighlightEntry
> &rHigh
= pViewData
->GetView()->GetHighlightRanges();
784 bool bHasScenario
= ( nTab
+1<nTabCount
&& rDoc
.IsScenario(nTab
+1) && !rDoc
.IsScenario(nTab
) );
785 bool bHasChange
= ( rDoc
.GetChangeTrack() != nullptr );
787 if ( bHasChange
|| bHasScenario
|| !rHigh
.empty() )
790 //! Merge SetChangedClip() with DrawMarks() ?? (different MapMode!)
793 if (eMode
== SC_UPDATE_CHANGED
)
794 bAny
= aOutputData
.SetChangedClip();
798 aOutputData
.DrawChangeTrack();
801 lcl_DrawScenarioFrames( pContentDev
, pViewData
, eWhich
, nX1
,nY1
,nX2
,nY2
);
803 lcl_DrawHighlight( aOutputData
, pViewData
, rHigh
);
805 if (eMode
== SC_UPDATE_CHANGED
)
806 pContentDev
->SetClipRegion();
810 // Drawing foreground
812 pContentDev
->SetMapMode(aDrawMode
);
814 DrawRedraw( aOutputData
, eMode
, SC_LAYER_FRONT
);
815 DrawRedraw( aOutputData
, eMode
, SC_LAYER_INTERN
);
816 DrawSdrGrid( aDrawingRectLogic
, pContentDev
);
818 if (!bIsInScroll
) // Drawing marks
820 if(eMode
== SC_UPDATE_CHANGED
&& aOutputData
.SetChangedClip())
822 pContentDev
->SetClipRegion();
826 pContentDev
->SetMapMode(MAP_PIXEL
);
828 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() )
830 Color
aRefColor( rColorCfg
.GetColorValue(svtools::CALCREFERENCE
).nColor
);
831 aOutputData
.DrawRefMark( pViewData
->GetRefStartX(), pViewData
->GetRefStartY(),
832 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(),
838 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
841 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
842 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
843 pRangeFinder
->GetDocName() == pDocSh
->GetTitle() )
845 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
846 for (sal_uInt16 i
=0; i
<nCount
; i
++)
848 ScRangeFindData
& rData
= pRangeFinder
->GetObject(i
);
850 ScRange aRef
= rData
.aRef
;
852 if ( aRef
.aStart
.Tab() >= nTab
&& aRef
.aEnd
.Tab() <= nTab
)
853 aOutputData
.DrawRefMark( aRef
.aStart
.Col(), aRef
.aStart
.Row(),
854 aRef
.aEnd
.Col(), aRef
.aEnd
.Row(),
855 Color( rData
.nColorData
),
863 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
867 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
868 pContentDev
->SetMapMode(aDrawMode
);
869 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
873 // #i74769# work with SdrPaintWindow directly
874 pDrawView
->EndDrawLayers(*pTargetPaintWindow
, true);
877 pContentDev
->SetMapMode(aCurrentMapMode
);
881 // In-place editing - when the user is typing, we need to paint the text
882 // using the editeng.
883 // It's being done after EndDrawLayers() to get it outside the overlay
884 // buffer and on top of everything.
885 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
887 // get the coordinates of the area we need to clear (overpaint by
889 SCCOL nCol1
= pViewData
->GetEditStartCol();
890 SCROW nRow1
= pViewData
->GetEditStartRow();
891 SCCOL nCol2
= pViewData
->GetEditEndCol();
892 SCROW nRow2
= pViewData
->GetEditEndRow();
893 rDevice
.SetLineColor();
894 rDevice
.SetFillColor(pEditView
->GetBackgroundColor());
895 Point aStart
= pViewData
->GetScrPos( nCol1
, nRow1
, eWhich
);
896 Point aEnd
= pViewData
->GetScrPos( nCol2
+1, nRow2
+1, eWhich
);
898 // don't overwrite grid
899 long nLayoutSign
= bLayoutRTL
? -1 : 1;
900 aEnd
.X() -= 2 * nLayoutSign
;
903 // toggle the cursor off if its on to ensure the cursor invert
904 // background logic remains valid after the background is cleared on
905 // the next cursor flash
906 vcl::Cursor
* pCrsr
= pEditView
->GetCursor();
907 const bool bVisCursor
= pCrsr
&& pCrsr
->IsVisible();
911 // set the correct mapmode
912 Rectangle
aBackground(aStart
, aEnd
);
913 if (bIsTiledRendering
)
915 aBackground
+= Point(nScrX
, nScrY
);
916 rDevice
.SetMapMode(aDrawMode
);
919 rDevice
.SetMapMode(pViewData
->GetLogicMode());
921 // paint the background
922 rDevice
.DrawRect(rDevice
.PixelToLogic(aBackground
));
924 // paint the editeng text
925 pEditView
->Paint(rDevice
.PixelToLogic(Rectangle(Point(nScrX
, nScrY
), Size(aOutputData
.GetScrW(), aOutputData
.GetScrH()))), &rDevice
);
926 rDevice
.SetMapMode(MAP_PIXEL
);
928 // restore the cursor it was originally visible
933 if (pViewData
->HasEditView(eWhich
))
935 // flush OverlayManager before changing the MapMode
936 flushOverlayManager();
938 // set MapMode for text edit
939 rDevice
.SetMapMode(pViewData
->GetLogicMode());
942 rDevice
.SetMapMode(aDrawMode
);
945 mpNoteMarker
->Draw(); // Above the cursor, in drawing map mode
948 void ScGridWindow::PaintTile( VirtualDevice
& rDevice
,
949 int nOutputWidth
, int nOutputHeight
,
950 int nTilePosX
, int nTilePosY
,
951 long nTileWidth
, long nTileHeight
)
953 // Output size is in pixels while tile position and size are in logical units (twips).
955 // Assumption: always paint the whole sheet i.e. "visible" range is always
956 // from (0,0) to last data position.
958 // Tile geometry is independent of the zoom level, but the output size is
959 // dependent of the zoom level. Determine the correct zoom level before
962 // FIXME the painting works using a mixture of drawing with coordinates in
963 // pixels and in logic coordinates; it should be cleaned up to use logic
964 // coords only, and avoid all the SetMapMode()'s.
965 // Similarly to Writer, we should set the mapmode once on the rDevice, and
966 // not care about any zoom settings.
968 Fraction
aFracX(long(nOutputWidth
* TWIPS_PER_PIXEL
), nTileWidth
);
969 Fraction
aFracY(long(nOutputHeight
* TWIPS_PER_PIXEL
), nTileHeight
);
971 // page break zoom, and aLogicMode in ScViewData
972 pViewData
->SetZoom(aFracX
, aFracY
, true);
974 double fTilePosXPixel
= static_cast<double>(nTilePosX
) * nOutputWidth
/ nTileWidth
;
975 double fTilePosYPixel
= static_cast<double>(nTilePosY
) * nOutputHeight
/ nTileHeight
;
977 SCTAB nTab
= pViewData
->GetTabNo();
978 ScDocument
* pDoc
= pViewData
->GetDocument();
980 SCCOL nStartCol
= 0, nEndCol
= 0;
981 SCROW nStartRow
= 0, nEndRow
= 0;
983 // size of the document including drawings, charts, etc.
984 pDoc
->GetTiledRenderingArea(nTab
, nEndCol
, nEndRow
);
986 double fPPTX
= pViewData
->GetPPTX();
987 double fPPTY
= pViewData
->GetPPTY();
989 ScTableInfo aTabInfo
;
990 pDoc
->FillInfo(aTabInfo
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
, fPPTX
, fPPTY
, false, false);
992 ScOutputData
aOutputData(&rDevice
, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
993 -fTilePosXPixel
, -fTilePosYPixel
, nStartCol
, nStartRow
, nEndCol
, nEndRow
,
996 // setup the SdrPage so that drawinglayer works correctly
997 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
998 std::unique_ptr
<FmFormView
> pDrawView
;
1001 pDrawView
.reset(new FmFormView(pModel
, &rDevice
));
1002 pDrawView
->ShowSdrPage(pDrawView
->GetModel()->GetPage(nTab
));
1003 aOutputData
.SetDrawView( pDrawView
.get() );
1007 DrawContent(rDevice
, aTabInfo
, aOutputData
, true, SC_UPDATE_ALL
);
1010 void ScGridWindow::LogicInvalidate(const Rectangle
* pRectangle
)
1014 sRectangle
= "EMPTY";
1017 Rectangle
aRectangle(*pRectangle
);
1018 // When dragging shapes the map mode is disabled.
1019 if (IsMapModeEnabled())
1021 if (GetMapMode().GetMapUnit() == MAP_100TH_MM
)
1022 aRectangle
= OutputDevice::LogicToLogic(aRectangle
, MAP_100TH_MM
, MAP_TWIP
);
1025 aRectangle
= PixelToLogic(aRectangle
, MapMode(MAP_TWIP
));
1026 sRectangle
= aRectangle
.toString();
1029 pViewData
->GetDocument()->GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES
, sRectangle
.getStr());
1032 void ScGridWindow::SetCellSelectionPixel(int nType
, int nPixelX
, int nPixelY
)
1034 ScTabView
* pTabView
= pViewData
->GetView();
1035 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
1036 ScInputHandler
* pInputHandler
= SC_MOD()->GetInputHdl(pViewShell
);
1038 if (pInputHandler
&& pInputHandler
->IsInputMode())
1040 // we need to switch off the editeng
1041 ScTabView::UpdateInputLine();
1042 pViewShell
->UpdateInputHandler();
1045 if (nType
== LOK_SETTEXTSELECTION_RESET
)
1047 pTabView
->DoneBlockMode();
1051 // obtain the current selection
1052 ScRangeList aRangeList
= pViewData
->GetMarkData().GetMarkedRanges();
1058 bool bWasEmpty
= false;
1059 if (aRangeList
.empty())
1061 nCol1
= nCol2
= pViewData
->GetCurX();
1062 nRow1
= nRow2
= pViewData
->GetCurY();
1066 aRangeList
.Combine().GetVars(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1068 // convert the coordinates to column/row
1071 SCTAB nTab
= pViewData
->GetTabNo();
1072 pViewData
->GetPosFromPixel(nPixelX
, nPixelY
, eWhich
, nNewPosX
, nNewPosY
);
1074 // change the selection
1077 case LOK_SETTEXTSELECTION_START
:
1078 if (nNewPosX
!= nCol1
|| nNewPosY
!= nRow1
|| bWasEmpty
)
1080 pTabView
->SetCursor(nNewPosX
, nNewPosY
);
1081 pTabView
->DoneBlockMode();
1082 pTabView
->InitBlockMode(nNewPosX
, nNewPosY
, nTab
, true);
1083 pTabView
->MarkCursor(nCol2
, nRow2
, nTab
);
1086 case LOK_SETTEXTSELECTION_END
:
1087 if (nNewPosX
!= nCol2
|| nNewPosY
!= nRow2
|| bWasEmpty
)
1089 pTabView
->SetCursor(nCol1
, nRow1
);
1090 pTabView
->DoneBlockMode();
1091 pTabView
->InitBlockMode(nCol1
, nRow1
, nTab
, true);
1092 pTabView
->MarkCursor(nNewPosX
, nNewPosY
, nTab
);
1101 void ScGridWindow::CheckNeedsRepaint()
1103 // called at the end of painting, and from timer after background text width calculation
1107 bNeedsRepaint
= false;
1108 if (aRepaintPixel
.IsEmpty())
1111 Invalidate(PixelToLogic(aRepaintPixel
));
1112 aRepaintPixel
= Rectangle();
1114 // selection function in status bar might also be invalid
1115 SfxBindings
& rBindings
= pViewData
->GetBindings();
1116 rBindings
.Invalidate( SID_STATUS_SUM
);
1117 rBindings
.Invalidate( SID_ATTR_SIZE
);
1118 rBindings
.Invalidate( SID_TABLE_CELL
);
1122 void ScGridWindow::DrawPagePreview( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, vcl::RenderContext
& rRenderContext
)
1124 ScPageBreakData
* pPageData
= pViewData
->GetView()->GetPageBreakData();
1127 ScDocument
* pDoc
= pViewData
->GetDocument();
1128 SCTAB nTab
= pViewData
->GetTabNo();
1129 Size aWinSize
= GetOutputSizePixel();
1130 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
1131 Color
aManual( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
1132 Color
aAutomatic( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAK
).nColor
);
1134 OUString aPageStr
= ScGlobal::GetRscString( STR_PGNUM
);
1135 if ( nPageScript
== SvtScriptType::NONE
)
1137 // get script type of translated "Page" string only once
1138 nPageScript
= pDoc
->GetStringScriptType( aPageStr
);
1139 if (nPageScript
== SvtScriptType::NONE
)
1140 nPageScript
= ScGlobal::GetDefaultScriptType();
1144 std::unique_ptr
<ScEditEngineDefaulter
> pEditEng
;
1145 const ScPatternAttr
& rDefPattern
= static_cast<const ScPatternAttr
&>(pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
));
1146 if ( nPageScript
== SvtScriptType::LATIN
)
1148 // use single font and call DrawText directly
1149 rDefPattern
.GetFont( aFont
, SC_AUTOCOL_BLACK
);
1150 aFont
.SetColor( Color( COL_LIGHTGRAY
) );
1151 // font size is set as needed
1155 // use EditEngine to draw mixed-script string
1156 pEditEng
.reset(new ScEditEngineDefaulter( EditEngine::CreatePool(), true ));
1157 pEditEng
->SetRefMapMode(rRenderContext
.GetMapMode());
1158 SfxItemSet
* pEditDefaults
= new SfxItemSet( pEditEng
->GetEmptyItemSet() );
1159 rDefPattern
.FillEditItemSet( pEditDefaults
);
1160 pEditDefaults
->Put( SvxColorItem( Color( COL_LIGHTGRAY
), EE_CHAR_COLOR
) );
1161 pEditEng
->SetDefaults( pEditDefaults
);
1164 sal_uInt16 nCount
= sal::static_int_cast
<sal_uInt16
>( pPageData
->GetCount() );
1165 for (sal_uInt16 nPos
=0; nPos
<nCount
; nPos
++)
1167 ScPrintRangeData
& rData
= pPageData
->GetData(nPos
);
1168 ScRange aRange
= rData
.GetPrintRange();
1169 if ( aRange
.aStart
.Col() <= nX2
+1 && aRange
.aEnd
.Col()+1 >= nX1
&&
1170 aRange
.aStart
.Row() <= nY2
+1 && aRange
.aEnd
.Row()+1 >= nY1
)
1172 // 3 pixel frame around the print area
1173 // (middle pixel on the grid lines)
1175 rRenderContext
.SetLineColor();
1176 if (rData
.IsAutomatic())
1177 rRenderContext
.SetFillColor( aAutomatic
);
1179 rRenderContext
.SetFillColor( aManual
);
1181 Point aStart
= pViewData
->GetScrPos(
1182 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, true );
1183 Point aEnd
= pViewData
->GetScrPos(
1184 aRange
.aEnd
.Col() + 1, aRange
.aEnd
.Row() + 1, eWhich
, true );
1188 // Prevent overflows:
1189 if ( aStart
.X() < -10 ) aStart
.X() = -10;
1190 if ( aStart
.Y() < -10 ) aStart
.Y() = -10;
1191 if ( aEnd
.X() > aWinSize
.Width() + 10 )
1192 aEnd
.X() = aWinSize
.Width() + 10;
1193 if ( aEnd
.Y() > aWinSize
.Height() + 10 )
1194 aEnd
.Y() = aWinSize
.Height() + 10;
1196 rRenderContext
.DrawRect( Rectangle( aStart
, Point(aEnd
.X(),aStart
.Y()+2) ) );
1197 rRenderContext
.DrawRect( Rectangle( aStart
, Point(aStart
.X()+2,aEnd
.Y()) ) );
1198 rRenderContext
.DrawRect( Rectangle( Point(aStart
.X(),aEnd
.Y()-2), aEnd
) );
1199 rRenderContext
.DrawRect( Rectangle( Point(aEnd
.X()-2,aStart
.Y()), aEnd
) );
1202 //! Display differently (dashed ????)
1204 size_t nColBreaks
= rData
.GetPagesX();
1205 const SCCOL
* pColEnd
= rData
.GetPageEndX();
1207 for (nColPos
=0; nColPos
+1<nColBreaks
; nColPos
++)
1209 SCCOL nBreak
= pColEnd
[nColPos
]+1;
1210 if ( nBreak
>= nX1
&& nBreak
<= nX2
+1 )
1212 //! Search for hidden
1213 if (pDoc
->HasColBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1214 rRenderContext
.SetFillColor( aManual
);
1216 rRenderContext
.SetFillColor( aAutomatic
);
1217 Point aBreak
= pViewData
->GetScrPos(
1218 nBreak
, aRange
.aStart
.Row(), eWhich
, true );
1219 rRenderContext
.DrawRect( Rectangle( aBreak
.X()-1, aStart
.Y(), aBreak
.X(), aEnd
.Y() ) );
1223 size_t nRowBreaks
= rData
.GetPagesY();
1224 const SCROW
* pRowEnd
= rData
.GetPageEndY();
1226 for (nRowPos
=0; nRowPos
+1<nRowBreaks
; nRowPos
++)
1228 SCROW nBreak
= pRowEnd
[nRowPos
]+1;
1229 if ( nBreak
>= nY1
&& nBreak
<= nY2
+1 )
1231 //! Search for hidden
1232 if (pDoc
->HasRowBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1233 rRenderContext
.SetFillColor( aManual
);
1235 rRenderContext
.SetFillColor( aAutomatic
);
1236 Point aBreak
= pViewData
->GetScrPos(
1237 aRange
.aStart
.Col(), nBreak
, eWhich
, true );
1238 rRenderContext
.DrawRect( Rectangle( aStart
.X(), aBreak
.Y()-1, aEnd
.X(), aBreak
.Y() ) );
1244 SCROW nPrStartY
= aRange
.aStart
.Row();
1245 for (nRowPos
=0; nRowPos
<nRowBreaks
; nRowPos
++)
1247 SCROW nPrEndY
= pRowEnd
[nRowPos
];
1248 if ( nPrEndY
>= nY1
&& nPrStartY
<= nY2
)
1250 SCCOL nPrStartX
= aRange
.aStart
.Col();
1251 for (nColPos
=0; nColPos
<nColBreaks
; nColPos
++)
1253 SCCOL nPrEndX
= pColEnd
[nColPos
];
1254 if ( nPrEndX
>= nX1
&& nPrStartX
<= nX2
)
1256 Point aPageStart
= pViewData
->GetScrPos(
1257 nPrStartX
, nPrStartY
, eWhich
, true );
1258 Point aPageEnd
= pViewData
->GetScrPos(
1259 nPrEndX
+1,nPrEndY
+1, eWhich
, true );
1261 long nPageNo
= rData
.GetFirstPage();
1262 if ( rData
.IsTopDown() )
1263 nPageNo
+= ((long)nColPos
)*nRowBreaks
+nRowPos
;
1265 nPageNo
+= ((long)nRowPos
)*nColBreaks
+nColPos
;
1267 OUString aThisPageStr
= aPageStr
.replaceFirst("%1", OUString::number(nPageNo
));
1271 // find right font size with EditEngine
1273 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1274 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1275 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1276 pEditEng
->SetText( aThisPageStr
);
1277 Size
aSize100( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1279 // 40% of width or 60% of height
1280 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1281 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1282 nHeight
= std::min(nSizeX
,nSizeY
);
1283 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1284 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1285 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1287 // centered output with EditEngine
1288 Size
aTextSize( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1289 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1290 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1291 pEditEng
->Draw( &rRenderContext
, aPos
);
1295 // find right font size for DrawText
1296 aFont
.SetFontSize( Size( 0,100 ) );
1297 rRenderContext
.SetFont( aFont
);
1298 Size
aSize100(rRenderContext
.GetTextWidth( aThisPageStr
), rRenderContext
.GetTextHeight() );
1300 // 40% of width or 60% of height
1301 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1302 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1303 aFont
.SetFontSize( Size( 0,std::min(nSizeX
,nSizeY
) ) );
1304 rRenderContext
.SetFont( aFont
);
1306 // centered output with DrawText
1307 Size
aTextSize(rRenderContext
.GetTextWidth( aThisPageStr
), rRenderContext
.GetTextHeight() );
1308 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1309 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1310 rRenderContext
.DrawText( aPos
, aThisPageStr
);
1313 nPrStartX
= nPrEndX
+ 1;
1316 nPrStartY
= nPrEndY
+ 1;
1323 void ScGridWindow::DrawButtons(SCCOL nX1
, SCCOL nX2
, const ScTableInfo
& rTabInfo
, OutputDevice
* pContentDev
)
1325 aComboButton
.SetOutputDevice( pContentDev
);
1327 ScDocument
* pDoc
= pViewData
->GetDocument();
1328 ScDPFieldButton
aCellBtn(pContentDev
, &GetSettings().GetStyleSettings(), &pViewData
->GetZoomX(), &pViewData
->GetZoomY(), pDoc
);
1334 SCTAB nTab
= pViewData
->GetTabNo();
1335 ScDBData
* pDBData
= nullptr;
1336 std::unique_ptr
<ScQueryParam
> pQueryParam
;
1338 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
1339 sal_uInt16 nArrCount
= rTabInfo
.mnArrCount
;
1341 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1343 Point aOldPos
= aComboButton
.GetPosPixel(); // store state for MouseDown/Up
1344 Size aOldSize
= aComboButton
.GetSizePixel();
1346 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1348 if ( pRowInfo
[nArrY
].bAutoFilter
&& pRowInfo
[nArrY
].bChanged
)
1350 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1352 nRow
= pThisRowInfo
->nRowNo
;
1354 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1356 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1357 //if several columns merged on a row, there should be only one auto button at the end of the columns.
1358 //if several rows merged on a column, the button may be in the middle, so "!pInfo->bVOverlapped" should not be used
1359 if ( pInfo
->bAutoFilter
&& !pInfo
->bHOverlapped
)
1362 pQueryParam
.reset(new ScQueryParam
);
1364 bool bNewData
= true;
1372 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1373 if ( nCol
>= nStartCol
&& nCol
<= nEndCol
&&
1374 nRow
>= nStartRow
&& nRow
<= nEndRow
)
1379 pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
, ScDBDataPortion::AREA
);
1381 pDBData
->GetQueryParam( *pQueryParam
);
1384 // can also be part of DataPilot table
1388 // pQueryParam can only include MAXQUERY entries
1390 bool bSimpleQuery
= true;
1391 bool bColumnFound
= false;
1392 if (!pQueryParam
->bInplace
)
1393 bSimpleQuery
= false;
1394 SCSIZE nCount
= pQueryParam
->GetEntryCount();
1395 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1396 if (pQueryParam
->GetEntry(nQuery
).bDoQuery
)
1398 // Do no restrict to EQUAL here
1399 // (Column head should become blue also when ">1")
1401 if (pQueryParam
->GetEntry(nQuery
).nField
== nCol
)
1402 bColumnFound
= true;
1404 if (pQueryParam
->GetEntry(nQuery
).eConnect
!= SC_AND
)
1405 bSimpleQuery
= false;
1408 bool bArrowState
= bSimpleQuery
&& bColumnFound
;
1411 SCCOL nStartCol
= nCol
;
1412 SCROW nStartRow
= nRow
;
1413 //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.
1414 //should first get the start pos of the merge area, then get the nSizeX through the start pos.
1415 pDoc
->ExtendOverlapped(nStartCol
, nStartRow
,nCol
, nRow
, nTab
);//get nStartCol,nStartRow
1416 pViewData
->GetMergeSizePixel( nStartCol
, nStartRow
, nSizeX
, nSizeY
);//get nSizeX
1417 nSizeY
= ScViewData::ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
1418 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1420 aCellBtn
.setBoundingBox(aScrPos
, Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1421 aCellBtn
.setPopupLeft(bLayoutRTL
); // #i114944# AutoFilter button is left-aligned in RTL
1422 aCellBtn
.setDrawBaseButton(false);
1423 aCellBtn
.setDrawPopupButton(true);
1424 aCellBtn
.setHasHiddenMember(bArrowState
);
1430 if ( pRowInfo
[nArrY
].bPivotButton
&& pRowInfo
[nArrY
].bChanged
)
1432 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1433 nRow
= pThisRowInfo
->nRowNo
;
1434 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1436 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1437 if (pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
1440 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1443 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1444 long nPosX
= aScrPos
.X();
1445 long nPosY
= aScrPos
.Y();
1446 // bLayoutRTL is handled in setBoundingBox
1448 OUString aStr
= pDoc
->GetString(nCol
, nRow
, nTab
);
1449 aCellBtn
.setText(aStr
);
1450 aCellBtn
.setBoundingBox(Point(nPosX
, nPosY
), Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1451 aCellBtn
.setPopupLeft(false); // DataPilot popup is always right-aligned for now
1452 aCellBtn
.setDrawBaseButton(pInfo
->bPivotButton
);
1453 aCellBtn
.setDrawPopupButton(pInfo
->bPivotPopupButton
);
1454 aCellBtn
.setHasHiddenMember(pInfo
->bFilterActive
);
1459 if ( bListValButton
&& pRowInfo
[nArrY
].nRowNo
== aListValPos
.Row() && pRowInfo
[nArrY
].bChanged
)
1461 Rectangle aRect
= GetListValButtonRect( aListValPos
);
1462 aComboButton
.SetPosPixel( aRect
.TopLeft() );
1463 aComboButton
.SetSizePixel( aRect
.GetSize() );
1464 pContentDev
->SetClipRegion(vcl::Region(aRect
));
1465 aComboButton
.Draw();
1466 pContentDev
->SetClipRegion(); // always called from Draw() without clip region
1467 aComboButton
.SetPosPixel( aOldPos
); // restore old state
1468 aComboButton
.SetSizePixel( aOldSize
); // for MouseUp/Down (AutoFilter)
1472 pQueryParam
.reset();
1473 aComboButton
.SetOutputDevice( this );
1476 Rectangle
ScGridWindow::GetListValButtonRect( const ScAddress
& rButtonPos
)
1478 ScDocument
* pDoc
= pViewData
->GetDocument();
1479 SCTAB nTab
= pViewData
->GetTabNo();
1480 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1481 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1483 ScDDComboBoxButton
aButton( this ); // for optimal size
1484 Size aBtnSize
= aButton
.GetSizePixel();
1486 SCCOL nCol
= rButtonPos
.Col();
1487 SCROW nRow
= rButtonPos
.Row();
1489 long nCellSizeX
; // width of this cell, including merged
1491 pViewData
->GetMergeSizePixel( nCol
, nRow
, nCellSizeX
, nDummy
);
1493 // for height, only the cell's row is used, excluding merged cells
1494 long nCellSizeY
= ScViewData::ToPixel( pDoc
->GetRowHeight( nRow
, nTab
), pViewData
->GetPPTY() );
1495 long nAvailable
= nCellSizeX
;
1497 // left edge of next cell if there is a non-hidden next column
1498 SCCOL nNextCol
= nCol
+ 1;
1499 const ScMergeAttr
* pMerge
= static_cast<const ScMergeAttr
*>(pDoc
->GetAttr( nCol
,nRow
,nTab
, ATTR_MERGE
));
1500 if ( pMerge
->GetColMerge() > 1 )
1501 nNextCol
= nCol
+ pMerge
->GetColMerge(); // next cell after the merged area
1502 while ( nNextCol
<= MAXCOL
&& pDoc
->ColHidden(nNextCol
, nTab
) )
1504 bool bNextCell
= ( nNextCol
<= MAXCOL
);
1506 nAvailable
= ScViewData::ToPixel( pDoc
->GetColWidth( nNextCol
, nTab
), pViewData
->GetPPTX() );
1508 if ( nAvailable
< aBtnSize
.Width() )
1509 aBtnSize
.Width() = nAvailable
;
1510 if ( nCellSizeY
< aBtnSize
.Height() )
1511 aBtnSize
.Height() = nCellSizeY
;
1513 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
, true );
1514 aPos
.X() += nCellSizeX
* nLayoutSign
; // start of next cell
1516 aPos
.X() -= aBtnSize
.Width() * nLayoutSign
; // right edge of cell if next cell not available
1517 aPos
.Y() += nCellSizeY
- aBtnSize
.Height();
1518 // X remains at the left edge
1521 aPos
.X() -= aBtnSize
.Width()-1; // align right edge of button with cell border
1523 return Rectangle( aPos
, aBtnSize
);
1526 bool ScGridWindow::IsAutoFilterActive( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1528 ScDocument
* pDoc
= pViewData
->GetDocument();
1529 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
, ScDBDataPortion::AREA
);
1530 ScQueryParam aQueryParam
;
1533 pDBData
->GetQueryParam( aQueryParam
);
1536 OSL_FAIL("Auto filter button without DBData");
1539 bool bSimpleQuery
= true;
1540 bool bColumnFound
= false;
1543 if ( !aQueryParam
.bInplace
)
1544 bSimpleQuery
= false;
1546 // aQueryParam can only include MAXQUERY entries
1548 SCSIZE nCount
= aQueryParam
.GetEntryCount();
1549 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1550 if ( aQueryParam
.GetEntry(nQuery
).bDoQuery
)
1552 if (aQueryParam
.GetEntry(nQuery
).nField
== nCol
)
1553 bColumnFound
= true;
1556 if (aQueryParam
.GetEntry(nQuery
).eConnect
!= SC_AND
)
1557 bSimpleQuery
= false;
1560 return ( bSimpleQuery
&& bColumnFound
);
1563 void ScGridWindow::GetSelectionRects( ::std::vector
< Rectangle
>& rPixelRects
)
1565 ScMarkData
aMultiMark( pViewData
->GetMarkData() );
1566 aMultiMark
.SetMarking( false );
1567 aMultiMark
.MarkToMulti();
1568 ScDocument
* pDoc
= pViewData
->GetDocument();
1569 SCTAB nTab
= pViewData
->GetTabNo();
1571 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1572 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1573 if ( !aMultiMark
.IsMultiMarked() )
1575 ScRange aMultiRange
;
1576 aMultiMark
.GetMultiMarkArea( aMultiRange
);
1577 SCCOL nX1
= aMultiRange
.aStart
.Col();
1578 SCROW nY1
= aMultiRange
.aStart
.Row();
1579 SCCOL nX2
= aMultiRange
.aEnd
.Col();
1580 SCROW nY2
= aMultiRange
.aEnd
.Row();
1582 PutInOrder( nX1
, nX2
);
1583 PutInOrder( nY1
, nY2
);
1585 bool bTestMerge
= true;
1586 bool bRepeat
= true;
1588 SCCOL nTestX2
= nX2
;
1589 SCROW nTestY2
= nY2
;
1591 pDoc
->ExtendMerge( nX1
,nY1
, nTestX2
,nTestY2
, nTab
);
1593 SCCOL nPosX
= pViewData
->GetPosX( eHWhich
);
1594 SCROW nPosY
= pViewData
->GetPosY( eVWhich
);
1595 // is the selection visible at all?
1596 if (nTestX2
< nPosX
|| nTestY2
< nPosY
)
1598 SCCOL nRealX1
= nX1
;
1604 if (!comphelper::LibreOfficeKit::isActive())
1606 // limit the selection to only what is visible on the screen
1607 SCCOL nXRight
= nPosX
+ pViewData
->VisibleCellsX(eHWhich
);
1608 if (nXRight
> MAXCOL
)
1611 SCROW nYBottom
= nPosY
+ pViewData
->VisibleCellsY(eVWhich
);
1612 if (nYBottom
> MAXROW
)
1615 // is the selection visible at all?
1616 if (nX1
> nXRight
|| nY1
> nYBottom
)
1628 pDoc
->GetTiledRenderingArea(nTab
, nMaxTiledCol
, nMaxTiledRow
);
1630 if (nX2
> nMaxTiledCol
)
1632 if (nY2
> nMaxTiledRow
)
1636 double nPPTX
= pViewData
->GetPPTX();
1637 double nPPTY
= pViewData
->GetPPTY();
1639 ScInvertMerger
aInvert( &rPixelRects
);
1641 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
1642 long nScrY
= aScrPos
.Y();
1643 bool bWasHidden
= false;
1644 for (SCROW nY
=nY1
; nY
<=nY2
; nY
++)
1646 bool bFirstRow
= ( nY
== nPosY
); // first visible row?
1647 bool bDoHidden
= false; // repeat hidden ?
1648 sal_uInt16 nHeightTwips
= pDoc
->GetRowHeight( nY
,nTab
);
1649 bool bDoRow
= ( nHeightTwips
!= 0 );
1653 if (bWasHidden
) // test hidden merge
1666 bDoRow
= true; // last cell of the block
1671 SCCOL nLoopEndX
= nX2
;
1672 if (nX2
< nX1
) // the rest of the merge
1674 SCCOL nStartX
= nX1
;
1675 while ( static_cast<const ScMergeFlagAttr
*>(pDoc
->
1676 GetAttr(nStartX
,nY
,nTab
,ATTR_MERGE_FLAG
))->IsHorOverlapped() )
1682 long nEndY
= nScrY
+ ScViewData::ToPixel( nHeightTwips
, nPPTY
) - 1;
1683 long nScrX
= aScrPos
.X();
1684 for (SCCOL nX
=nX1
; nX
<=nLoopEndX
; nX
++)
1686 long nWidth
= ScViewData::ToPixel( pDoc
->GetColWidth( nX
,nTab
), nPPTX
);
1689 long nEndX
= nScrX
+ ( nWidth
- 1 ) * nLayoutSign
;
1693 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1694 const ScMergeFlagAttr
* pMergeFlag
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->
1695 GetItem(ATTR_MERGE_FLAG
) );
1696 if ( pMergeFlag
->IsVerOverlapped() && ( bDoHidden
|| bFirstRow
) )
1698 while ( pMergeFlag
->IsVerOverlapped() && nThisY
> 0 &&
1699 (pDoc
->RowHidden(nThisY
-1, nTab
) || bFirstRow
) )
1702 pPattern
= pDoc
->GetPattern( nX
, nThisY
, nTab
);
1703 pMergeFlag
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->GetItem(ATTR_MERGE_FLAG
) );
1707 // only the rest of the merged is seen ?
1709 if ( pMergeFlag
->IsHorOverlapped() && nX
== nPosX
&& nX
> nRealX1
)
1711 while ( pMergeFlag
->IsHorOverlapped() )
1714 pPattern
= pDoc
->GetPattern( nThisX
, nThisY
, nTab
);
1715 pMergeFlag
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->GetItem(ATTR_MERGE_FLAG
) );
1719 if ( aMultiMark
.IsCellMarked( nThisX
, nThisY
, true ) == bRepeat
)
1721 if ( !pMergeFlag
->IsOverlapped() )
1723 const ScMergeAttr
* pMerge
= static_cast<const ScMergeAttr
*>(&pPattern
->GetItem(ATTR_MERGE
));
1724 if (pMerge
->GetColMerge() > 0 || pMerge
->GetRowMerge() > 0)
1726 Point aEndPos
= pViewData
->GetScrPos(
1727 nThisX
+ pMerge
->GetColMerge(),
1728 nThisY
+ pMerge
->GetRowMerge(), eWhich
);
1729 if ( aEndPos
.X() * nLayoutSign
> nScrX
* nLayoutSign
&& aEndPos
.Y() > nScrY
)
1731 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,
1732 aEndPos
.X()-nLayoutSign
,aEndPos
.Y()-1 ) );
1735 else if ( nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1737 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1744 if ( aMultiMark
.IsCellMarked( nX
, nY
, true ) == bRepeat
&&
1745 nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1747 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1751 nScrX
= nEndX
+ nLayoutSign
;
1759 void ScGridWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
1761 Window::DataChanged(rDCEvt
);
1763 if ( (rDCEvt
.GetType() == DataChangedEventType::PRINTER
) ||
1764 (rDCEvt
.GetType() == DataChangedEventType::DISPLAY
) ||
1765 (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
1766 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
1767 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1768 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
1770 if ( rDCEvt
.GetType() == DataChangedEventType::FONTS
&& eWhich
== pViewData
->GetActivePart() )
1771 pViewData
->GetDocShell()->UpdateFontList();
1773 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1774 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1776 if ( eWhich
== pViewData
->GetActivePart() ) // only once for the view
1778 ScTabView
* pView
= pViewData
->GetView();
1780 // update scale in case the UI ScreenZoom has changed
1781 ScGlobal::UpdatePPT(this);
1784 // RepeatResize in case scroll bar sizes have changed
1785 pView
->RepeatResize();
1786 pView
->UpdateAllOverlays();
1788 // invalidate cell attribs in input handler, in case the
1789 // EditEngine BackgroundColor has to be changed
1790 if ( pViewData
->IsActive() )
1792 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1794 pHdl
->ForgetLastPattern();
1803 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */