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 #define LOK_USE_UNSTABLE_API
33 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
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 // auch wenn das inner-Rectangle nicht sichtbar ist, muss evtl.
75 // die Titelzeile gezeichnet werden, darum kein Rueckgabewert mehr.
76 // Wenn's weit daneben liegt, wird lcl_DrawOneFrame erst gar nicht gerufen.
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 wird nur benutzt, um die Button-Groesse zu setzen,
85 // darf ansonsten NULL sein!
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
.SetSize( aAttrFont
.GetSize() );
114 aAppFont
.SetAlign( 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 // links, oben, rechts, unten
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
, false );
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: Titelzeile beruehrt zwei Zellen
189 else if ( nY1
> 0 ) --nY1
;
190 if ( nX2
< MAXCOL
) ++nX2
;
191 if ( nY2
< MAXROW
-1 ) nY2
+= 2; // Hack: Titelzeile beruehrt zwei Zellen
192 else if ( nY2
< MAXROW
) ++nY2
;
193 ScRange
aViewRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
195 //! Ranges an der Table cachen!!!!
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 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
210 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
211 pDoc
->ExtendTotalMerge( aRange
);
213 //! -> Repaint beim Zusammenfassen erweitern !!!
215 if ( aRange
.Intersects( aViewRange
) ) //! Platz fuer 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 //! eigener Text "(keins)" statt "(leer)" ???
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(); // aufheben
278 OSL_ENSURE( aInvertRect
.IsEmpty(), "DoInvertRect nicht paarig" );
280 aInvertRect
= rPixel
; // neues Rechteck merken
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, interpretierende Zellen nicht nochmal anstossen
308 // hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe
309 // (Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt.
313 //! Rechtecke zusammenfassen?
314 aRepaintPixel
= Rectangle(); // mehrfach -> alles painten
318 bNeedsRepaint
= true;
319 aRepaintPixel
= LogicToPixel(rRect
); // nur betroffenen Bereich
324 // #i117893# If GetSizePixel needs to call the resize handler, the resulting nested Paint call
325 // (possibly for a larger rectangle) has to be allowed. Call GetSizePixel before setting bIsInPaint.
333 Rectangle aPixRect
= LogicToPixel( rRect
);
335 SCCOL nX1
= pViewData
->GetPosX(eHWhich
);
336 SCROW nY1
= pViewData
->GetPosY(eVWhich
);
338 SCTAB nTab
= pViewData
->GetTabNo();
340 double nPPTX
= pViewData
->GetPPTX();
341 double nPPTY
= pViewData
->GetPPTY();
343 Rectangle aMirroredPixel
= aPixRect
;
344 if ( pDoc
->IsLayoutRTL( nTab
) )
347 long nWidth
= GetSizePixel().Width();
348 aMirroredPixel
.Left() = nWidth
- 1 - aPixRect
.Right();
349 aMirroredPixel
.Right() = nWidth
- 1 - aPixRect
.Left();
352 long nScrX
= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
353 while ( nScrX
<= aMirroredPixel
.Left() && nX1
< MAXCOL
)
356 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
359 while ( nScrX
<= aMirroredPixel
.Right() && nX2
< MAXCOL
)
362 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX2
, nTab
), nPPTX
);
366 ScViewData::AddPixelsWhile( nScrY
, aPixRect
.Top(), nY1
, MAXROW
, nPPTY
, pDoc
, nTab
);
368 if (nScrY
<= aPixRect
.Bottom() && nY2
< MAXROW
)
371 ScViewData::AddPixelsWhile( nScrY
, aPixRect
.Bottom(), nY2
, MAXROW
, nPPTY
, pDoc
, nTab
);
374 Draw( nX1
,nY1
,nX2
,nY2
, SC_UPDATE_MARKS
); // don't continue with painting
379 void ScGridWindow::Draw( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, ScUpdateMode eMode
)
381 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
382 ScDocument
& rDoc
= pDocSh
->GetDocument();
384 // let's ignore the normal Draw() attempts when doing the tiled rendering,
385 // all the rendering should go through PaintTile() in that case.
386 // TODO revisit if we can actually turn this into an assert(), and clean
388 if (rDoc
.GetDrawLayer()->isTiledRendering())
391 ScModule
* pScMod
= SC_MOD();
392 bool bTextWysiwyg
= pScMod
->GetInputOptions().GetTextWysiwyg();
394 if (pViewData
->IsMinimized())
397 PutInOrder( nX1
, nX2
);
398 PutInOrder( nY1
, nY2
);
400 OSL_ENSURE( ValidCol(nX2
) && ValidRow(nY2
), "GridWin Draw area too big" );
402 UpdateVisibleRange();
404 if (nX2
< maVisibleRange
.mnCol1
|| nY2
< maVisibleRange
.mnRow1
)
407 if (nX1
< maVisibleRange
.mnCol1
)
408 nX1
= maVisibleRange
.mnCol1
;
409 if (nY1
< maVisibleRange
.mnRow1
)
410 nY1
= maVisibleRange
.mnRow1
;
412 if (nX1
> maVisibleRange
.mnCol2
|| nY1
> maVisibleRange
.mnRow2
)
415 if (nX2
> maVisibleRange
.mnCol2
)
416 nX2
= maVisibleRange
.mnCol2
;
417 if (nY2
> maVisibleRange
.mnRow2
)
418 nY2
= maVisibleRange
.mnRow2
;
420 if ( eMode
!= SC_UPDATE_MARKS
&& nX2
< maVisibleRange
.mnCol2
)
421 nX2
= maVisibleRange
.mnCol2
; // zum Weiterzeichnen
423 // point of no return
425 ++nPaintCount
; // mark that painting is in progress
427 SCTAB nTab
= pViewData
->GetTabNo();
428 rDoc
.ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
430 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
431 long nMirrorWidth
= GetSizePixel().Width();
432 bool bLayoutRTL
= rDoc
.IsLayoutRTL( nTab
);
435 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, maVisibleRange
.mnRow1
, eWhich
).X();
436 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
437 aScrPos
.X() = nEndPixel
+ 1;
440 long nScrX
= aScrPos
.X();
441 long nScrY
= aScrPos
.Y();
443 SCCOL nCurX
= pViewData
->GetCurX();
444 SCROW nCurY
= pViewData
->GetCurY();
445 SCCOL nCurEndX
= nCurX
;
446 SCROW nCurEndY
= nCurY
;
447 rDoc
.ExtendMerge( nCurX
, nCurY
, nCurEndX
, nCurEndY
, nTab
);
448 bool bCurVis
= nCursorHideCount
==0 &&
449 ( nCurEndX
+1 >= nX1
&& nCurX
<= nX2
+1 && nCurEndY
+1 >= nY1
&& nCurY
<= nY2
+1 );
452 if ( !bCurVis
&& nCursorHideCount
==0 && bAutoMarkVisible
&& aAutoMarkPos
.Tab() == nTab
&&
453 ( aAutoMarkPos
.Col() != nCurX
|| aAutoMarkPos
.Row() != nCurY
) )
455 SCCOL nHdlX
= aAutoMarkPos
.Col();
456 SCROW nHdlY
= aAutoMarkPos
.Row();
457 rDoc
.ExtendMerge( nHdlX
, nHdlY
, nHdlX
, nHdlY
, nTab
);
458 bCurVis
= ( nHdlX
+1 >= nX1
&& nHdlX
<= nX2
&& nHdlY
+1 >= nY1
&& nHdlY
<= nY2
);
459 // left and top is unaffected
461 //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
464 double nPPTX
= pViewData
->GetPPTX();
465 double nPPTY
= pViewData
->GetPPTY();
467 const ScViewOptions
& rOpts
= pViewData
->GetOptions();
471 ScTableInfo aTabInfo
;
472 rDoc
.FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
,
473 nPPTX
, nPPTY
, false, rOpts
.GetOption(VOPT_FORMULAS
),
474 &pViewData
->GetMarkData() );
476 Fraction aZoomX
= pViewData
->GetZoomX();
477 Fraction aZoomY
= pViewData
->GetZoomY();
478 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, &rDoc
, nTab
,
479 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
482 aOutputData
.SetMirrorWidth( nMirrorWidth
); // needed for RTL
483 aOutputData
.SetSpellCheckContext(mpSpellCheckCxt
.get());
485 ScopedVclPtr
< VirtualDevice
> xFmtVirtDev
;
486 bool bLogicText
= bTextWysiwyg
; // call DrawStrings in logic MapMode?
490 // use printer for text formatting
492 OutputDevice
* pFmtDev
= rDoc
.GetPrinter();
493 pFmtDev
->SetMapMode( pViewData
->GetLogicMode(eWhich
) );
494 aOutputData
.SetFmtDevice( pFmtDev
);
496 else if ( aZoomX
!= aZoomY
&& pViewData
->IsOle() )
498 // #i45033# For OLE inplace editing with different zoom factors,
499 // use a virtual device with 1/100th mm as text formatting reference
501 xFmtVirtDev
.reset( VclPtr
<VirtualDevice
>::Create() );
502 xFmtVirtDev
->SetMapMode( MAP_100TH_MM
);
503 aOutputData
.SetFmtDevice( xFmtVirtDev
.get() );
505 bLogicText
= true; // use logic MapMode
508 DrawContent(*this, aTabInfo
, aOutputData
, bLogicText
, eMode
);
510 // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
511 // ist das jetzt durcheinandergekommen und es muss neu gemalt werden
513 OSL_ENSURE(nPaintCount
, "nPaintCount falsch");
518 // Flag drawn formula cells "unchanged".
519 rDoc
.ResetChanged(ScRange(nX1
, nY1
, nTab
, nX2
, nY2
, nTab
));
520 rDoc
.ClearFormulaContext();
523 void ScGridWindow::DrawContent(OutputDevice
&rDevice
, const ScTableInfo
& rTableInfo
, ScOutputData
& aOutputData
,
524 bool bLogicText
, ScUpdateMode eMode
)
526 ScModule
* pScMod
= SC_MOD();
527 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
528 ScDocument
& rDoc
= pDocSh
->GetDocument();
529 const ScViewOptions
& rOpts
= pViewData
->GetOptions();
530 bool bIsTiledRendering
= rDoc
.GetDrawLayer()->isTiledRendering();
532 SCTAB nTab
= aOutputData
.nTab
;
533 SCCOL nX1
= aOutputData
.nX1
;
534 SCROW nY1
= aOutputData
.nY1
;
535 SCCOL nX2
= aOutputData
.nX2
;
536 SCROW nY2
= aOutputData
.nY2
;
537 long nScrX
= aOutputData
.nScrX
;
538 long nScrY
= aOutputData
.nScrY
;
540 const svtools::ColorConfig
& rColorCfg
= pScMod
->GetColorConfig();
541 Color
aGridColor( rColorCfg
.GetColorValue( svtools::CALCGRID
, false ).nColor
);
542 if ( aGridColor
.GetColor() == COL_TRANSPARENT
)
544 // use view options' grid color only if color config has "automatic" color
545 aGridColor
= rOpts
.GetGridColor();
548 aOutputData
.SetSyntaxMode ( pViewData
->IsSyntaxMode() );
549 aOutputData
.SetGridColor ( aGridColor
);
550 aOutputData
.SetShowNullValues ( rOpts
.GetOption( VOPT_NULLVALS
) );
551 aOutputData
.SetShowFormulas ( rOpts
.GetOption( VOPT_FORMULAS
) );
552 aOutputData
.SetShowSpellErrors ( rDoc
.GetDocOptions().IsAutoSpell() );
553 aOutputData
.SetMarkClipped ( rOpts
.GetOption( VOPT_CLIPMARKS
) );
555 aOutputData
.SetUseStyleColor( true ); // always set in table view
557 aOutputData
.SetEditObject( GetEditObject() );
558 aOutputData
.SetViewShell( pViewData
->GetViewShell() );
560 bool bGrid
= rOpts
.GetOption( VOPT_GRID
) && pViewData
->GetShowGrid();
561 bool bGridFirst
= !rOpts
.GetOption( VOPT_GRID_ONTOP
);
563 bool bPage
= rOpts
.GetOption( VOPT_PAGEBREAKS
);
565 if ( eMode
== SC_UPDATE_CHANGED
)
567 aOutputData
.FindChanged();
568 aOutputData
.SetSingleGrid(true);
571 bool bPageMode
= pViewData
->IsPagebreakMode();
572 if (bPageMode
) // nach FindChanged
574 // SetPagebreakMode initialisiert auch bPrinted Flags
575 aOutputData
.SetPagebreakMode( pViewData
->GetView()->GetPageBreakData() );
578 EditView
* pEditView
= NULL
;
579 bool bEditMode
= pViewData
->HasEditView(eWhich
);
580 if ( bEditMode
&& pViewData
->GetRefTabNo() == nTab
)
584 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
585 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
586 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
588 if ( nEditEndCol
>= nX1
&& nEditCol
<= nX2
&& nEditEndRow
>= nY1
&& nEditRow
<= nY2
)
589 aOutputData
.SetEditCell( nEditCol
, nEditRow
);
594 // define drawing layer map mode and paint rectangle
595 MapMode aDrawMode
= GetDrawMapMode();
596 if (bIsTiledRendering
)
598 // FIXME this shouldn't be necessary once we change the entire Calc to
599 // work in the logic coordinates (ideally 100ths of mm - so that it is
600 // the same as editeng and drawinglayer), and get rid of all the
601 // SetMapMode's and other unneccessary fun we have with pixels
602 // See also ScGridWindow::GetDrawMapMode() for the rest of this hack
603 aDrawMode
.SetOrigin(PixelToLogic(Point(nScrX
, nScrY
), aDrawMode
));
605 Rectangle aDrawingRectLogic
;
606 bool bLayoutRTL
= rDoc
.IsLayoutRTL( nTab
);
609 // get drawing pixel rect
610 Rectangle
aDrawingRectPixel(Point(nScrX
, nScrY
), Size(aOutputData
.GetScrW(), aOutputData
.GetScrH()));
612 // correct for border (left/right)
617 aDrawingRectPixel
.Left() = 0L;
621 aDrawingRectPixel
.Right() = GetOutputSizePixel().getWidth();
625 // correct for border (bottom)
628 aDrawingRectPixel
.Bottom() = GetOutputSizePixel().getHeight();
631 // get logic positions
632 aDrawingRectLogic
= PixelToLogic(aDrawingRectPixel
, aDrawMode
);
635 OutputDevice
* pContentDev
= &rDevice
; // device for document content, used by overlay manager
636 SdrPaintWindow
* pTargetPaintWindow
= 0; // #i74769# work with SdrPaintWindow directly
640 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
644 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
645 pContentDev
->SetMapMode(aDrawMode
);
646 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
650 // #i74769# Use new BeginDrawLayers() interface
651 vcl::Region
aDrawingRegion(aDrawingRectLogic
);
652 pTargetPaintWindow
= pDrawView
->BeginDrawLayers(pContentDev
, aDrawingRegion
);
653 OSL_ENSURE(pTargetPaintWindow
, "BeginDrawLayers: Got no SdrPaintWindow (!)");
655 if (!bIsTiledRendering
)
657 // #i74769# get target device from SdrPaintWindow, this may be the prerender
659 pContentDev
= &(pTargetPaintWindow
->GetTargetOutputDevice());
660 aOutputData
.SetContentDevice(pContentDev
);
664 pContentDev
->SetMapMode(aCurrentMapMode
);
668 // Rand (Wiese) (Pixel)
669 if ( nX2
==MAXCOL
|| nY2
==MAXROW
)
671 // save MapMode and set to pixel
672 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
673 pContentDev
->SetMapMode(MAP_PIXEL
);
675 Rectangle aPixRect
= Rectangle( Point(), GetOutputSizePixel() );
676 pContentDev
->SetFillColor( rColorCfg
.GetColorValue(svtools::APPBACKGROUND
).nColor
);
677 pContentDev
->SetLineColor();
680 Rectangle
aDrawRect( aPixRect
);
682 aDrawRect
.Right() = nScrX
- 1;
684 aDrawRect
.Left() = nScrX
+ aOutputData
.GetScrW();
685 if (aDrawRect
.Right() >= aDrawRect
.Left())
686 pContentDev
->DrawRect( aDrawRect
);
690 Rectangle
aDrawRect( aPixRect
);
691 aDrawRect
.Top() = nScrY
+ aOutputData
.GetScrH();
694 // no double painting of the corner
696 aDrawRect
.Left() = nScrX
;
698 aDrawRect
.Right() = nScrX
+ aOutputData
.GetScrW() - 1;
700 if (aDrawRect
.Bottom() >= aDrawRect
.Top())
701 pContentDev
->DrawRect( aDrawRect
);
705 pContentDev
->SetMapMode(aCurrentMapMode
);
708 if ( rDoc
.HasBackgroundDraw( nTab
, aDrawingRectLogic
) )
710 pContentDev
->SetMapMode(MAP_PIXEL
);
711 aOutputData
.DrawClear();
713 // Drawing Hintergrund
715 pContentDev
->SetMapMode(aDrawMode
);
716 DrawRedraw( aOutputData
, eMode
, SC_LAYER_BACK
);
719 aOutputData
.SetSolidBackground(true);
721 pContentDev
->SetMapMode(MAP_PIXEL
);
722 aOutputData
.DrawDocumentBackground();
724 if ( bGridFirst
&& ( bGrid
|| bPage
) )
725 aOutputData
.DrawGrid( bGrid
, bPage
);
727 aOutputData
.DrawBackground();
729 if ( !bGridFirst
&& ( bGrid
|| bPage
) )
730 aOutputData
.DrawGrid( bGrid
, bPage
);
734 // DrawPagePreview draws complete lines/page numbers, must always be clipped
735 if ( aOutputData
.SetChangedClip() )
737 DrawPagePreview(nX1
,nY1
,nX2
,nY2
, pContentDev
);
738 pContentDev
->SetClipRegion();
742 aOutputData
.DrawShadow();
743 aOutputData
.DrawFrame();
746 if ( rOpts
.GetOption( VOPT_NOTES
) )
747 aOutputData
.DrawNoteMarks();
750 aOutputData
.DrawStrings(false); // in pixel MapMode
752 // edit cells and printer-metrics text must be before the buttons
753 // (DataPilot buttons contain labels in UI font)
755 pContentDev
->SetMapMode(pViewData
->GetLogicMode(eWhich
));
757 aOutputData
.DrawStrings(true); // in logic MapMode if bLogicText is set
758 aOutputData
.DrawEdit(true);
760 // the buttons are painted in absolute coordinates
761 if (bIsTiledRendering
)
763 // Tiled offset nScrX, nScrY
764 MapMode
aMap( MAP_PIXEL
);
765 aMap
.SetOrigin(Point(nScrX
, nScrY
));
766 pContentDev
->SetMapMode(aMap
);
769 pContentDev
->SetMapMode(MAP_PIXEL
);
771 // Autofilter- und Pivot-Buttons
773 DrawButtons(nX1
, nX2
, rTableInfo
, pContentDev
); // Pixel
775 pContentDev
->SetMapMode(MAP_PIXEL
);
777 aOutputData
.DrawClipMarks();
779 // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
781 //! Test, ob ChangeTrack-Anzeige aktiv ist
782 //! Szenario-Rahmen per View-Optionen abschaltbar?
784 SCTAB nTabCount
= rDoc
.GetTableCount();
785 const std::vector
<ScHighlightEntry
> &rHigh
= pViewData
->GetView()->GetHighlightRanges();
786 bool bHasScenario
= ( nTab
+1<nTabCount
&& rDoc
.IsScenario(nTab
+1) && !rDoc
.IsScenario(nTab
) );
787 bool bHasChange
= ( rDoc
.GetChangeTrack() != NULL
);
789 if ( bHasChange
|| bHasScenario
|| !rHigh
.empty() )
792 //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
795 if (eMode
== SC_UPDATE_CHANGED
)
796 bAny
= aOutputData
.SetChangedClip();
800 aOutputData
.DrawChangeTrack();
803 lcl_DrawScenarioFrames( pContentDev
, pViewData
, eWhich
, nX1
,nY1
,nX2
,nY2
);
805 lcl_DrawHighlight( aOutputData
, pViewData
, rHigh
);
807 if (eMode
== SC_UPDATE_CHANGED
)
808 pContentDev
->SetClipRegion();
812 // Drawing Vordergrund
814 pContentDev
->SetMapMode(aDrawMode
);
816 DrawRedraw( aOutputData
, eMode
, SC_LAYER_FRONT
);
817 DrawRedraw( aOutputData
, eMode
, SC_LAYER_INTERN
);
818 DrawSdrGrid( aDrawingRectLogic
, pContentDev
);
820 if (!bIsInScroll
) // Drawing Markierungen
822 if(eMode
== SC_UPDATE_CHANGED
&& aOutputData
.SetChangedClip())
824 pContentDev
->SetClipRegion();
828 pContentDev
->SetMapMode(MAP_PIXEL
);
830 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() )
832 Color
aRefColor( rColorCfg
.GetColorValue(svtools::CALCREFERENCE
).nColor
);
833 aOutputData
.DrawRefMark( pViewData
->GetRefStartX(), pViewData
->GetRefStartY(),
834 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(),
840 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
843 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
844 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
845 pRangeFinder
->GetDocName() == pDocSh
->GetTitle() )
847 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
848 for (sal_uInt16 i
=0; i
<nCount
; i
++)
850 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
852 ScRange aRef
= pData
->aRef
;
854 if ( aRef
.aStart
.Tab() >= nTab
&& aRef
.aEnd
.Tab() <= nTab
)
855 aOutputData
.DrawRefMark( aRef
.aStart
.Col(), aRef
.aStart
.Row(),
856 aRef
.aEnd
.Col(), aRef
.aEnd
.Row(),
857 Color( pData
->nColorData
),
865 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
869 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
870 pContentDev
->SetMapMode(aDrawMode
);
871 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
875 // #i74769# work with SdrPaintWindow directly
876 pDrawView
->EndDrawLayers(*pTargetPaintWindow
, true);
879 pContentDev
->SetMapMode(aCurrentMapMode
);
883 // In-place editing - when the user is typing, we need to paint the text
884 // using the editeng.
885 // It's being done after EndDrawLayers() to get it outside the overlay
886 // buffer and on top of everything.
887 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
889 // get the coordinates of the area we need to clear (overpaint by
891 SCCOL nCol1
= pViewData
->GetEditStartCol();
892 SCROW nRow1
= pViewData
->GetEditStartRow();
893 SCCOL nCol2
= pViewData
->GetEditEndCol();
894 SCROW nRow2
= pViewData
->GetEditEndRow();
895 rDevice
.SetLineColor();
896 rDevice
.SetFillColor(pEditView
->GetBackgroundColor());
897 Point aStart
= pViewData
->GetScrPos( nCol1
, nRow1
, eWhich
);
898 Point aEnd
= pViewData
->GetScrPos( nCol2
+1, nRow2
+1, eWhich
);
900 // don't overwrite grid
901 long nLayoutSign
= bLayoutRTL
? -1 : 1;
902 aEnd
.X() -= 2 * nLayoutSign
;
905 // set the correct mapmode
906 Rectangle
aBackground(aStart
, aEnd
);
907 if (bIsTiledRendering
)
909 aBackground
+= Point(nScrX
, nScrY
);
910 rDevice
.SetMapMode(aDrawMode
);
913 rDevice
.SetMapMode(pViewData
->GetLogicMode());
915 // paint the background
916 rDevice
.DrawRect(rDevice
.PixelToLogic(aBackground
));
918 // paint the editeng text
919 pEditView
->Paint(rDevice
.PixelToLogic(Rectangle(Point(nScrX
, nScrY
), Size(aOutputData
.GetScrW(), aOutputData
.GetScrH()))), &rDevice
);
920 rDevice
.SetMapMode(MAP_PIXEL
);
923 if (pViewData
->HasEditView(eWhich
))
925 // flush OverlayManager before changing the MapMode
926 flushOverlayManager();
928 // set MapMode for text edit
929 rDevice
.SetMapMode(pViewData
->GetLogicMode());
932 rDevice
.SetMapMode(aDrawMode
);
935 mpNoteMarker
->Draw(); // ueber den Cursor, im Drawing-MapMode
938 void ScGridWindow::PaintTile( VirtualDevice
& rDevice
,
939 int nOutputWidth
, int nOutputHeight
,
940 int nTilePosX
, int nTilePosY
,
941 long nTileWidth
, long nTileHeight
)
943 // Output size is in pixels while tile position and size are in logical units (twips).
945 // Assumption: always paint the whole sheet i.e. "visible" range is always
946 // from (0,0) to last data position.
948 // Tile geometry is independent of the zoom level, but the output size is
949 // dependent of the zoom level. Determine the correct zoom level before
952 // FIXME the painting works using a mixture of drawing with coordinates in
953 // pixels and in logic coordinates; it should be cleaned up to use logic
954 // coords only, and avoid all the SetMapMode()'s.
955 // Similarly to Writer, we should set the mapmode once on the rDevice, and
956 // not care about any zoom settings.
958 Fraction
aFracX(long(nOutputWidth
* TWIPS_PER_PIXEL
), nTileWidth
);
959 Fraction
aFracY(long(nOutputHeight
* TWIPS_PER_PIXEL
), nTileHeight
);
961 // page break zoom, and aLogicMode in ScViewData
962 pViewData
->SetZoom(aFracX
, aFracY
, true);
964 double fTilePosXPixel
= static_cast<double>(nTilePosX
) * nOutputWidth
/ nTileWidth
;
965 double fTilePosYPixel
= static_cast<double>(nTilePosY
) * nOutputHeight
/ nTileHeight
;
967 SCTAB nTab
= pViewData
->GetTabNo();
968 ScDocument
* pDoc
= pViewData
->GetDocument();
970 SCCOL nStartCol
= 0, nEndCol
= 0;
971 SCROW nStartRow
= 0, nEndRow
= 0;
973 // size of the document including drawings, charts, etc.
974 pDoc
->GetTiledRenderingArea(nTab
, nEndCol
, nEndRow
);
976 double fPPTX
= pViewData
->GetPPTX();
977 double fPPTY
= pViewData
->GetPPTY();
979 ScTableInfo aTabInfo
;
980 pDoc
->FillInfo(aTabInfo
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
, fPPTX
, fPPTY
, false, false, NULL
);
982 ScOutputData
aOutputData(&rDevice
, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
983 -fTilePosXPixel
, -fTilePosYPixel
, nStartCol
, nStartRow
, nEndCol
, nEndRow
,
986 // setup the SdrPage so that drawinglayer works correctly
987 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
988 boost::scoped_ptr
<FmFormView
> pDrawView
;
991 pDrawView
.reset(new FmFormView(pModel
, &rDevice
));
992 pDrawView
->ShowSdrPage(pDrawView
->GetModel()->GetPage(nTab
));
993 aOutputData
.SetDrawView( pDrawView
.get() );
997 DrawContent(rDevice
, aTabInfo
, aOutputData
, true, SC_UPDATE_ALL
);
1000 void ScGridWindow::LogicInvalidate(const Rectangle
* pRectangle
)
1004 sRectangle
= "EMPTY";
1007 Rectangle
aRectangle(*pRectangle
);
1008 // When dragging shapes the map mode is disabled.
1009 if (IsMapModeEnabled())
1011 if (GetMapMode().GetMapUnit() == MAP_100TH_MM
)
1012 aRectangle
= OutputDevice::LogicToLogic(aRectangle
, MAP_100TH_MM
, MAP_TWIP
);
1015 aRectangle
= PixelToLogic(aRectangle
, MapMode(MAP_TWIP
));
1016 sRectangle
= aRectangle
.toString();
1019 pViewData
->GetDocument()->GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES
, sRectangle
.getStr());
1022 void ScGridWindow::SetCellSelectionPixel(int nType
, int nPixelX
, int nPixelY
)
1024 ScTabView
* pTabView
= pViewData
->GetView();
1025 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
1026 ScInputHandler
* pInputHandler
= SC_MOD()->GetInputHdl(pViewShell
);
1028 if (pInputHandler
&& pInputHandler
->IsInputMode())
1030 // we need to switch off the editeng
1031 ScTabView::UpdateInputLine();
1032 pViewShell
->UpdateInputHandler();
1035 if (nType
== LOK_SETTEXTSELECTION_RESET
)
1037 pTabView
->DoneBlockMode();
1041 // obtain the current selection
1042 ScRangeList aRangeList
= pViewData
->GetMarkData().GetMarkedRanges();
1048 bool bWasEmpty
= false;
1049 if (aRangeList
.empty())
1051 nCol1
= nCol2
= pViewData
->GetCurX();
1052 nRow1
= nRow2
= pViewData
->GetCurY();
1056 aRangeList
.Combine().GetVars(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1058 // convert the coordinates to column/row
1061 SCTAB nTab
= pViewData
->GetTabNo();
1062 pViewData
->GetPosFromPixel(nPixelX
, nPixelY
, eWhich
, nNewPosX
, nNewPosY
);
1064 // change the selection
1067 case LOK_SETTEXTSELECTION_START
:
1068 if (nNewPosX
!= nCol1
|| nNewPosY
!= nRow1
|| bWasEmpty
)
1070 pTabView
->SetCursor(nNewPosX
, nNewPosY
);
1071 pTabView
->DoneBlockMode();
1072 pTabView
->InitBlockMode(nNewPosX
, nNewPosY
, nTab
, true);
1073 pTabView
->MarkCursor(nCol2
, nRow2
, nTab
);
1076 case LOK_SETTEXTSELECTION_END
:
1077 if (nNewPosX
!= nCol2
|| nNewPosY
!= nRow2
|| bWasEmpty
)
1079 pTabView
->SetCursor(nCol1
, nRow1
);
1080 pTabView
->DoneBlockMode();
1081 pTabView
->InitBlockMode(nCol1
, nRow1
, nTab
, true);
1082 pTabView
->MarkCursor(nNewPosX
, nNewPosY
, nTab
);
1091 void ScGridWindow::CheckNeedsRepaint()
1093 // called at the end of painting, and from timer after background text width calculation
1097 bNeedsRepaint
= false;
1098 if (aRepaintPixel
.IsEmpty())
1101 Invalidate(PixelToLogic(aRepaintPixel
));
1102 aRepaintPixel
= Rectangle();
1104 // selection function in status bar might also be invalid
1105 SfxBindings
& rBindings
= pViewData
->GetBindings();
1106 rBindings
.Invalidate( SID_STATUS_SUM
);
1107 rBindings
.Invalidate( SID_ATTR_SIZE
);
1108 rBindings
.Invalidate( SID_TABLE_CELL
);
1112 void ScGridWindow::DrawPagePreview( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, OutputDevice
* pContentDev
)
1114 ScPageBreakData
* pPageData
= pViewData
->GetView()->GetPageBreakData();
1117 ScDocument
* pDoc
= pViewData
->GetDocument();
1118 SCTAB nTab
= pViewData
->GetTabNo();
1119 Size aWinSize
= GetOutputSizePixel();
1120 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
1121 Color
aManual( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
1122 Color
aAutomatic( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAK
).nColor
);
1124 OUString aPageStr
= ScGlobal::GetRscString( STR_PGNUM
);
1125 if ( nPageScript
== SvtScriptType::NONE
)
1127 // get script type of translated "Page" string only once
1128 nPageScript
= pDoc
->GetStringScriptType( aPageStr
);
1129 if (nPageScript
== SvtScriptType::NONE
)
1130 nPageScript
= ScGlobal::GetDefaultScriptType();
1134 std::unique_ptr
<ScEditEngineDefaulter
> pEditEng
;
1135 const ScPatternAttr
& rDefPattern
= static_cast<const ScPatternAttr
&>(pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
));
1136 if ( nPageScript
== SvtScriptType::LATIN
)
1138 // use single font and call DrawText directly
1139 rDefPattern
.GetFont( aFont
, SC_AUTOCOL_BLACK
);
1140 aFont
.SetColor( Color( COL_LIGHTGRAY
) );
1141 // font size is set as needed
1145 // use EditEngine to draw mixed-script string
1146 pEditEng
.reset(new ScEditEngineDefaulter( EditEngine::CreatePool(), true ));
1147 pEditEng
->SetRefMapMode( pContentDev
->GetMapMode() );
1148 SfxItemSet
* pEditDefaults
= new SfxItemSet( pEditEng
->GetEmptyItemSet() );
1149 rDefPattern
.FillEditItemSet( pEditDefaults
);
1150 pEditDefaults
->Put( SvxColorItem( Color( COL_LIGHTGRAY
), EE_CHAR_COLOR
) );
1151 pEditEng
->SetDefaults( pEditDefaults
);
1154 sal_uInt16 nCount
= sal::static_int_cast
<sal_uInt16
>( pPageData
->GetCount() );
1155 for (sal_uInt16 nPos
=0; nPos
<nCount
; nPos
++)
1157 ScPrintRangeData
& rData
= pPageData
->GetData(nPos
);
1158 ScRange aRange
= rData
.GetPrintRange();
1159 if ( aRange
.aStart
.Col() <= nX2
+1 && aRange
.aEnd
.Col()+1 >= nX1
&&
1160 aRange
.aStart
.Row() <= nY2
+1 && aRange
.aEnd
.Row()+1 >= nY1
)
1162 // 3 Pixel Rahmen um den Druckbereich
1163 // (mittlerer Pixel auf den Gitterlinien)
1165 pContentDev
->SetLineColor();
1166 if (rData
.IsAutomatic())
1167 pContentDev
->SetFillColor( aAutomatic
);
1169 pContentDev
->SetFillColor( aManual
);
1171 Point aStart
= pViewData
->GetScrPos(
1172 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, true );
1173 Point aEnd
= pViewData
->GetScrPos(
1174 aRange
.aEnd
.Col() + 1, aRange
.aEnd
.Row() + 1, eWhich
, true );
1178 // Ueberlaeufe verhindern:
1179 if ( aStart
.X() < -10 ) aStart
.X() = -10;
1180 if ( aStart
.Y() < -10 ) aStart
.Y() = -10;
1181 if ( aEnd
.X() > aWinSize
.Width() + 10 )
1182 aEnd
.X() = aWinSize
.Width() + 10;
1183 if ( aEnd
.Y() > aWinSize
.Height() + 10 )
1184 aEnd
.Y() = aWinSize
.Height() + 10;
1186 pContentDev
->DrawRect( Rectangle( aStart
, Point(aEnd
.X(),aStart
.Y()+2) ) );
1187 pContentDev
->DrawRect( Rectangle( aStart
, Point(aStart
.X()+2,aEnd
.Y()) ) );
1188 pContentDev
->DrawRect( Rectangle( Point(aStart
.X(),aEnd
.Y()-2), aEnd
) );
1189 pContentDev
->DrawRect( Rectangle( Point(aEnd
.X()-2,aStart
.Y()), aEnd
) );
1192 //! anders darstellen (gestrichelt ????)
1194 size_t nColBreaks
= rData
.GetPagesX();
1195 const SCCOL
* pColEnd
= rData
.GetPageEndX();
1197 for (nColPos
=0; nColPos
+1<nColBreaks
; nColPos
++)
1199 SCCOL nBreak
= pColEnd
[nColPos
]+1;
1200 if ( nBreak
>= nX1
&& nBreak
<= nX2
+1 )
1203 if (pDoc
->HasColBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1204 pContentDev
->SetFillColor( aManual
);
1206 pContentDev
->SetFillColor( aAutomatic
);
1207 Point aBreak
= pViewData
->GetScrPos(
1208 nBreak
, aRange
.aStart
.Row(), eWhich
, true );
1209 pContentDev
->DrawRect( Rectangle( aBreak
.X()-1, aStart
.Y(), aBreak
.X(), aEnd
.Y() ) );
1213 size_t nRowBreaks
= rData
.GetPagesY();
1214 const SCROW
* pRowEnd
= rData
.GetPageEndY();
1216 for (nRowPos
=0; nRowPos
+1<nRowBreaks
; nRowPos
++)
1218 SCROW nBreak
= pRowEnd
[nRowPos
]+1;
1219 if ( nBreak
>= nY1
&& nBreak
<= nY2
+1 )
1222 if (pDoc
->HasRowBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1223 pContentDev
->SetFillColor( aManual
);
1225 pContentDev
->SetFillColor( aAutomatic
);
1226 Point aBreak
= pViewData
->GetScrPos(
1227 aRange
.aStart
.Col(), nBreak
, eWhich
, true );
1228 pContentDev
->DrawRect( Rectangle( aStart
.X(), aBreak
.Y()-1, aEnd
.X(), aBreak
.Y() ) );
1234 SCROW nPrStartY
= aRange
.aStart
.Row();
1235 for (nRowPos
=0; nRowPos
<nRowBreaks
; nRowPos
++)
1237 SCROW nPrEndY
= pRowEnd
[nRowPos
];
1238 if ( nPrEndY
>= nY1
&& nPrStartY
<= nY2
)
1240 SCCOL nPrStartX
= aRange
.aStart
.Col();
1241 for (nColPos
=0; nColPos
<nColBreaks
; nColPos
++)
1243 SCCOL nPrEndX
= pColEnd
[nColPos
];
1244 if ( nPrEndX
>= nX1
&& nPrStartX
<= nX2
)
1246 Point aPageStart
= pViewData
->GetScrPos(
1247 nPrStartX
, nPrStartY
, eWhich
, true );
1248 Point aPageEnd
= pViewData
->GetScrPos(
1249 nPrEndX
+1,nPrEndY
+1, eWhich
, true );
1251 long nPageNo
= rData
.GetFirstPage();
1252 if ( rData
.IsTopDown() )
1253 nPageNo
+= ((long)nColPos
)*nRowBreaks
+nRowPos
;
1255 nPageNo
+= ((long)nRowPos
)*nColBreaks
+nColPos
;
1257 OUString aThisPageStr
= OUString(aPageStr
).replaceFirst("%1", OUString::number(nPageNo
));
1261 // find right font size with EditEngine
1263 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1264 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1265 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1266 pEditEng
->SetText( aThisPageStr
);
1267 Size
aSize100( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1269 // 40% of width or 60% of height
1270 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1271 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1272 nHeight
= std::min(nSizeX
,nSizeY
);
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
) );
1277 // centered output with EditEngine
1278 Size
aTextSize( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1279 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1280 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1281 pEditEng
->Draw( pContentDev
, aPos
);
1285 // find right font size for DrawText
1286 aFont
.SetSize( Size( 0,100 ) );
1287 pContentDev
->SetFont( aFont
);
1288 Size
aSize100( pContentDev
->GetTextWidth( aThisPageStr
), pContentDev
->GetTextHeight() );
1290 // 40% of width or 60% of height
1291 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1292 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1293 aFont
.SetSize( Size( 0,std::min(nSizeX
,nSizeY
) ) );
1294 pContentDev
->SetFont( aFont
);
1296 // centered output with DrawText
1297 Size
aTextSize( pContentDev
->GetTextWidth( aThisPageStr
), pContentDev
->GetTextHeight() );
1298 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1299 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1300 pContentDev
->DrawText( aPos
, aThisPageStr
);
1303 nPrStartX
= nPrEndX
+ 1;
1306 nPrStartY
= nPrEndY
+ 1;
1313 void ScGridWindow::DrawButtons(SCCOL nX1
, SCCOL nX2
, const ScTableInfo
& rTabInfo
, OutputDevice
* pContentDev
)
1315 aComboButton
.SetOutputDevice( pContentDev
);
1317 ScDocument
* pDoc
= pViewData
->GetDocument();
1318 ScDPFieldButton
aCellBtn(pContentDev
, &GetSettings().GetStyleSettings(), &pViewData
->GetZoomX(), &pViewData
->GetZoomY(), pDoc
);
1324 SCTAB nTab
= pViewData
->GetTabNo();
1325 ScDBData
* pDBData
= NULL
;
1326 std::unique_ptr
<ScQueryParam
> pQueryParam
;
1328 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
1329 sal_uInt16 nArrCount
= rTabInfo
.mnArrCount
;
1331 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1333 Point aOldPos
= aComboButton
.GetPosPixel(); // Zustand fuer MouseDown/Up
1334 Size aOldSize
= aComboButton
.GetSizePixel(); // merken
1336 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1338 if ( pRowInfo
[nArrY
].bAutoFilter
&& pRowInfo
[nArrY
].bChanged
)
1340 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1342 nRow
= pThisRowInfo
->nRowNo
;
1344 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1346 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1347 //if several columns merged on a row, there should be only one auto button at the end of the columns.
1348 //if several rows merged on a column, the button may be in the middle, so "!pInfo->bVOverlapped" should not be used
1349 if ( pInfo
->bAutoFilter
&& !pInfo
->bHOverlapped
)
1352 pQueryParam
.reset(new ScQueryParam
);
1354 bool bNewData
= true;
1362 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1363 if ( nCol
>= nStartCol
&& nCol
<= nEndCol
&&
1364 nRow
>= nStartRow
&& nRow
<= nEndRow
)
1369 pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1371 pDBData
->GetQueryParam( *pQueryParam
);
1374 // can also be part of DataPilot table
1375 // OSL_FAIL("Auto-Filter-Button ohne DBData");
1379 // pQueryParam kann nur MAXQUERY Eintraege enthalten
1381 bool bSimpleQuery
= true;
1382 bool bColumnFound
= false;
1383 if (!pQueryParam
->bInplace
)
1384 bSimpleQuery
= false;
1385 SCSIZE nCount
= pQueryParam
->GetEntryCount();
1386 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1387 if (pQueryParam
->GetEntry(nQuery
).bDoQuery
)
1389 // hier nicht auf EQUAL beschraenken
1390 // (auch bei ">1" soll der Spaltenkopf blau werden)
1392 if (pQueryParam
->GetEntry(nQuery
).nField
== nCol
)
1393 bColumnFound
= true;
1395 if (pQueryParam
->GetEntry(nQuery
).eConnect
!= SC_AND
)
1396 bSimpleQuery
= false;
1399 bool bArrowState
= bSimpleQuery
&& bColumnFound
;
1402 SCCOL nStartCol
= nCol
;
1403 SCROW nStartRow
= nRow
;
1404 //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.
1405 //should first get the start pos of the merge area, then get the nSizeX through the start pos.
1406 pDoc
->ExtendOverlapped(nStartCol
, nStartRow
,nCol
, nRow
, nTab
);//get nStartCol,nStartRow
1407 pViewData
->GetMergeSizePixel( nStartCol
, nStartRow
, nSizeX
, nSizeY
);//get nSizeX
1408 nSizeY
= ScViewData::ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
1409 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1411 aCellBtn
.setBoundingBox(aScrPos
, Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1412 aCellBtn
.setPopupLeft(bLayoutRTL
); // #i114944# AutoFilter button is left-aligned in RTL
1413 aCellBtn
.setDrawBaseButton(false);
1414 aCellBtn
.setDrawPopupButton(true);
1415 aCellBtn
.setHasHiddenMember(bArrowState
);
1421 if ( pRowInfo
[nArrY
].bPivotButton
&& pRowInfo
[nArrY
].bChanged
)
1423 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1424 nRow
= pThisRowInfo
->nRowNo
;
1425 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1427 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1428 if (pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
1431 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1434 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1435 long nPosX
= aScrPos
.X();
1436 long nPosY
= aScrPos
.Y();
1437 // bLayoutRTL is handled in setBoundingBox
1439 OUString aStr
= pDoc
->GetString(nCol
, nRow
, nTab
);
1440 aCellBtn
.setText(aStr
);
1441 aCellBtn
.setBoundingBox(Point(nPosX
, nPosY
), Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1442 aCellBtn
.setPopupLeft(false); // DataPilot popup is always right-aligned for now
1443 aCellBtn
.setDrawBaseButton(pInfo
->bPivotButton
);
1444 aCellBtn
.setDrawPopupButton(pInfo
->bPivotPopupButton
);
1445 aCellBtn
.setHasHiddenMember(pInfo
->bFilterActive
);
1450 if ( bListValButton
&& pRowInfo
[nArrY
].nRowNo
== aListValPos
.Row() && pRowInfo
[nArrY
].bChanged
)
1452 Rectangle aRect
= GetListValButtonRect( aListValPos
);
1453 aComboButton
.SetPosPixel( aRect
.TopLeft() );
1454 aComboButton
.SetSizePixel( aRect
.GetSize() );
1455 pContentDev
->SetClipRegion(vcl::Region(aRect
));
1456 aComboButton
.Draw( false, false );
1457 pContentDev
->SetClipRegion(); // always called from Draw() without clip region
1458 aComboButton
.SetPosPixel( aOldPos
); // restore old state
1459 aComboButton
.SetSizePixel( aOldSize
); // for MouseUp/Down (AutoFilter)
1463 pQueryParam
.reset();
1464 aComboButton
.SetOutputDevice( this );
1467 Rectangle
ScGridWindow::GetListValButtonRect( const ScAddress
& rButtonPos
)
1469 ScDocument
* pDoc
= pViewData
->GetDocument();
1470 SCTAB nTab
= pViewData
->GetTabNo();
1471 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1472 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1474 ScDDComboBoxButton
aButton( this ); // for optimal size
1475 Size aBtnSize
= aButton
.GetSizePixel();
1477 SCCOL nCol
= rButtonPos
.Col();
1478 SCROW nRow
= rButtonPos
.Row();
1480 long nCellSizeX
; // width of this cell, including merged
1482 pViewData
->GetMergeSizePixel( nCol
, nRow
, nCellSizeX
, nDummy
);
1484 // for height, only the cell's row is used, excluding merged cells
1485 long nCellSizeY
= ScViewData::ToPixel( pDoc
->GetRowHeight( nRow
, nTab
), pViewData
->GetPPTY() );
1486 long nAvailable
= nCellSizeX
;
1488 // left edge of next cell if there is a non-hidden next column
1489 SCCOL nNextCol
= nCol
+ 1;
1490 const ScMergeAttr
* pMerge
= static_cast<const ScMergeAttr
*>(pDoc
->GetAttr( nCol
,nRow
,nTab
, ATTR_MERGE
));
1491 if ( pMerge
->GetColMerge() > 1 )
1492 nNextCol
= nCol
+ pMerge
->GetColMerge(); // next cell after the merged area
1493 while ( nNextCol
<= MAXCOL
&& pDoc
->ColHidden(nNextCol
, nTab
) )
1495 bool bNextCell
= ( nNextCol
<= MAXCOL
);
1497 nAvailable
= ScViewData::ToPixel( pDoc
->GetColWidth( nNextCol
, nTab
), pViewData
->GetPPTX() );
1499 if ( nAvailable
< aBtnSize
.Width() )
1500 aBtnSize
.Width() = nAvailable
;
1501 if ( nCellSizeY
< aBtnSize
.Height() )
1502 aBtnSize
.Height() = nCellSizeY
;
1504 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
, true );
1505 aPos
.X() += nCellSizeX
* nLayoutSign
; // start of next cell
1507 aPos
.X() -= aBtnSize
.Width() * nLayoutSign
; // right edge of cell if next cell not available
1508 aPos
.Y() += nCellSizeY
- aBtnSize
.Height();
1509 // X remains at the left edge
1512 aPos
.X() -= aBtnSize
.Width()-1; // align right edge of button with cell border
1514 return Rectangle( aPos
, aBtnSize
);
1517 bool ScGridWindow::IsAutoFilterActive( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1519 ScDocument
* pDoc
= pViewData
->GetDocument();
1520 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1521 ScQueryParam aQueryParam
;
1524 pDBData
->GetQueryParam( aQueryParam
);
1527 OSL_FAIL("Auto-Filter-Button ohne DBData");
1530 bool bSimpleQuery
= true;
1531 bool bColumnFound
= false;
1534 if ( !aQueryParam
.bInplace
)
1535 bSimpleQuery
= false;
1537 // aQueryParam kann nur MAXQUERY Eintraege enthalten
1539 SCSIZE nCount
= aQueryParam
.GetEntryCount();
1540 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1541 if ( aQueryParam
.GetEntry(nQuery
).bDoQuery
)
1543 if (aQueryParam
.GetEntry(nQuery
).nField
== nCol
)
1544 bColumnFound
= true;
1547 if (aQueryParam
.GetEntry(nQuery
).eConnect
!= SC_AND
)
1548 bSimpleQuery
= false;
1551 return ( bSimpleQuery
&& bColumnFound
);
1554 void ScGridWindow::GetSelectionRects( ::std::vector
< Rectangle
>& rPixelRects
)
1556 ScMarkData
aMultiMark( pViewData
->GetMarkData() );
1557 aMultiMark
.SetMarking( false );
1558 aMultiMark
.MarkToMulti();
1559 ScDocument
* pDoc
= pViewData
->GetDocument();
1560 SCTAB nTab
= pViewData
->GetTabNo();
1562 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1563 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1564 if ( !aMultiMark
.IsMultiMarked() )
1566 ScRange aMultiRange
;
1567 aMultiMark
.GetMultiMarkArea( aMultiRange
);
1568 SCCOL nX1
= aMultiRange
.aStart
.Col();
1569 SCROW nY1
= aMultiRange
.aStart
.Row();
1570 SCCOL nX2
= aMultiRange
.aEnd
.Col();
1571 SCROW nY2
= aMultiRange
.aEnd
.Row();
1573 PutInOrder( nX1
, nX2
);
1574 PutInOrder( nY1
, nY2
);
1576 bool bTestMerge
= true;
1577 bool bRepeat
= true;
1579 SCCOL nTestX2
= nX2
;
1580 SCROW nTestY2
= nY2
;
1582 pDoc
->ExtendMerge( nX1
,nY1
, nTestX2
,nTestY2
, nTab
);
1584 SCCOL nPosX
= pViewData
->GetPosX( eHWhich
);
1585 SCROW nPosY
= pViewData
->GetPosY( eVWhich
);
1586 // is the selection visible at all?
1587 if (nTestX2
< nPosX
|| nTestY2
< nPosY
)
1589 SCCOL nRealX1
= nX1
;
1595 if (!pDoc
->GetDrawLayer()->isTiledRendering())
1597 // limit the selection to only what is visible on the screen
1598 SCCOL nXRight
= nPosX
+ pViewData
->VisibleCellsX(eHWhich
);
1599 if (nXRight
> MAXCOL
)
1602 SCROW nYBottom
= nPosY
+ pViewData
->VisibleCellsY(eVWhich
);
1603 if (nYBottom
> MAXROW
)
1606 // is the selection visible at all?
1607 if (nX1
> nXRight
|| nY1
> nYBottom
)
1616 double nPPTX
= pViewData
->GetPPTX();
1617 double nPPTY
= pViewData
->GetPPTY();
1619 ScInvertMerger
aInvert( &rPixelRects
);
1621 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
1622 long nScrY
= aScrPos
.Y();
1623 bool bWasHidden
= false;
1624 for (SCROW nY
=nY1
; nY
<=nY2
; nY
++)
1626 bool bFirstRow
= ( nY
== nPosY
); // first visible row?
1627 bool bDoHidden
= false; // versteckte nachholen ?
1628 sal_uInt16 nHeightTwips
= pDoc
->GetRowHeight( nY
,nTab
);
1629 bool bDoRow
= ( nHeightTwips
!= 0 );
1633 if (bWasHidden
) // auf versteckte zusammengefasste testen
1646 bDoRow
= true; // letzte Zeile aus Block
1651 SCCOL nLoopEndX
= nX2
;
1652 if (nX2
< nX1
) // Rest von zusammengefasst
1654 SCCOL nStartX
= nX1
;
1655 while ( static_cast<const ScMergeFlagAttr
*>(pDoc
->
1656 GetAttr(nStartX
,nY
,nTab
,ATTR_MERGE_FLAG
))->IsHorOverlapped() )
1662 long nEndY
= nScrY
+ ScViewData::ToPixel( nHeightTwips
, nPPTY
) - 1;
1663 long nScrX
= aScrPos
.X();
1664 for (SCCOL nX
=nX1
; nX
<=nLoopEndX
; nX
++)
1666 long nWidth
= ScViewData::ToPixel( pDoc
->GetColWidth( nX
,nTab
), nPPTX
);
1669 long nEndX
= nScrX
+ ( nWidth
- 1 ) * nLayoutSign
;
1673 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1674 const ScMergeFlagAttr
* pMergeFlag
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->
1675 GetItem(ATTR_MERGE_FLAG
) );
1676 if ( pMergeFlag
->IsVerOverlapped() && ( bDoHidden
|| bFirstRow
) )
1678 while ( pMergeFlag
->IsVerOverlapped() && nThisY
> 0 &&
1679 (pDoc
->RowHidden(nThisY
-1, nTab
) || bFirstRow
) )
1682 pPattern
= pDoc
->GetPattern( nX
, nThisY
, nTab
);
1683 pMergeFlag
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->GetItem(ATTR_MERGE_FLAG
) );
1687 // nur Rest von zusammengefasster zu sehen ?
1689 if ( pMergeFlag
->IsHorOverlapped() && nX
== nPosX
&& nX
> nRealX1
)
1691 while ( pMergeFlag
->IsHorOverlapped() )
1694 pPattern
= pDoc
->GetPattern( nThisX
, nThisY
, nTab
);
1695 pMergeFlag
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->GetItem(ATTR_MERGE_FLAG
) );
1699 if ( aMultiMark
.IsCellMarked( nThisX
, nThisY
, true ) == bRepeat
)
1701 if ( !pMergeFlag
->IsOverlapped() )
1703 const ScMergeAttr
* pMerge
= static_cast<const ScMergeAttr
*>(&pPattern
->GetItem(ATTR_MERGE
));
1704 if (pMerge
->GetColMerge() > 0 || pMerge
->GetRowMerge() > 0)
1706 Point aEndPos
= pViewData
->GetScrPos(
1707 nThisX
+ pMerge
->GetColMerge(),
1708 nThisY
+ pMerge
->GetRowMerge(), eWhich
);
1709 if ( aEndPos
.X() * nLayoutSign
> nScrX
* nLayoutSign
&& aEndPos
.Y() > nScrY
)
1711 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,
1712 aEndPos
.X()-nLayoutSign
,aEndPos
.Y()-1 ) );
1715 else if ( nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1717 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1724 if ( aMultiMark
.IsCellMarked( nX
, nY
, true ) == bRepeat
&&
1725 nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1727 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1731 nScrX
= nEndX
+ nLayoutSign
;
1739 void ScGridWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
1741 Window::DataChanged(rDCEvt
);
1743 if ( (rDCEvt
.GetType() == DataChangedEventType::PRINTER
) ||
1744 (rDCEvt
.GetType() == DataChangedEventType::DISPLAY
) ||
1745 (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
1746 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
1747 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1748 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
1750 if ( rDCEvt
.GetType() == DataChangedEventType::FONTS
&& eWhich
== pViewData
->GetActivePart() )
1751 pViewData
->GetDocShell()->UpdateFontList();
1753 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1754 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1756 if ( eWhich
== pViewData
->GetActivePart() ) // only once for the view
1758 ScTabView
* pView
= pViewData
->GetView();
1760 // update scale in case the UI ScreenZoom has changed
1761 ScGlobal::UpdatePPT(this);
1764 // RepeatResize in case scroll bar sizes have changed
1765 pView
->RepeatResize();
1766 pView
->UpdateAllOverlays();
1768 // invalidate cell attribs in input handler, in case the
1769 // EditEngine BackgroundColor has to be changed
1770 if ( pViewData
->IsActive() )
1772 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1774 pHdl
->ForgetLastPattern();
1783 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */