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 <svx/svdview.hxx>
33 #include "tabvwsh.hxx"
35 #include "gridwin.hxx"
36 #include "viewdata.hxx"
38 #include "document.hxx"
40 #include "patattr.hxx"
42 #include "docoptio.hxx"
43 #include "notemark.hxx"
46 #include "inputhdl.hxx"
47 #include "rfindlst.hxx"
48 #include "hiranges.hxx"
49 #include "pagedata.hxx"
50 #include "docpool.hxx"
51 #include "globstr.hrc"
53 #include "cbutton.hxx"
54 #include "invmerge.hxx"
55 #include "editutil.hxx"
56 #include "inputopt.hxx"
57 #include "fillinfo.hxx"
58 #include "dpcontrol.hxx"
59 #include "queryparam.hxx"
60 #include "queryentry.hxx"
61 #include "markdata.hxx"
63 #include <vcl/virdev.hxx>
64 #include <svx/sdrpaintwindow.hxx>
66 #include <boost/scoped_ptr.hpp>
68 static void lcl_LimitRect( Rectangle
& rRect
, const Rectangle
& rVisible
)
70 if ( rRect
.Top() < rVisible
.Top()-1 ) rRect
.Top() = rVisible
.Top()-1;
71 if ( rRect
.Bottom() > rVisible
.Bottom()+1 ) rRect
.Bottom() = rVisible
.Bottom()+1;
73 // auch wenn das inner-Rectangle nicht sichtbar ist, muss evtl.
74 // die Titelzeile gezeichnet werden, darum kein Rueckgabewert mehr.
75 // Wenn's weit daneben liegt, wird lcl_DrawOneFrame erst gar nicht gerufen.
78 static void lcl_DrawOneFrame( OutputDevice
* pDev
, const Rectangle
& rInnerPixel
,
79 const OUString
& rTitle
, const Color
& rColor
, bool bTextBelow
,
80 double nPPTX
, double nPPTY
, const Fraction
& rZoomY
,
81 ScDocument
* pDoc
, ScViewData
* pButtonViewData
, bool bLayoutRTL
)
83 // pButtonViewData wird nur benutzt, um die Button-Groesse zu setzen,
84 // darf ansonsten NULL sein!
86 Rectangle aInner
= rInnerPixel
;
89 aInner
.Left() = rInnerPixel
.Right();
90 aInner
.Right() = rInnerPixel
.Left();
93 Rectangle
aVisible( Point(0,0), pDev
->GetOutputSizePixel() );
94 lcl_LimitRect( aInner
, aVisible
);
96 Rectangle aOuter
= aInner
;
97 long nHor
= (long) ( SC_SCENARIO_HSPACE
* nPPTX
);
98 long nVer
= (long) ( SC_SCENARIO_VSPACE
* nPPTY
);
99 aOuter
.Left() -= nHor
;
100 aOuter
.Right() += nHor
;
101 aOuter
.Top() -= nVer
;
102 aOuter
.Bottom() += nVer
;
104 // use ScPatternAttr::GetFont only for font size
106 ((const ScPatternAttr
&)pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
)).
107 GetFont(aAttrFont
,SC_AUTOCOL_BLACK
,pDev
,&rZoomY
);
109 // everything else from application font
110 Font aAppFont
= pDev
->GetSettings().GetStyleSettings().GetAppFont();
111 aAppFont
.SetSize( aAttrFont
.GetSize() );
113 aAppFont
.SetAlign( ALIGN_TOP
);
114 pDev
->SetFont( aAppFont
);
116 Size
aTextSize( pDev
->GetTextWidth( rTitle
), pDev
->GetTextHeight() );
119 aOuter
.Bottom() += aTextSize
.Height();
121 aOuter
.Top() -= aTextSize
.Height();
123 pDev
->SetLineColor();
124 pDev
->SetFillColor( rColor
);
125 // links, oben, rechts, unten
126 pDev
->DrawRect( Rectangle( aOuter
.Left(), aOuter
.Top(), aInner
.Left(), aOuter
.Bottom() ) );
127 pDev
->DrawRect( Rectangle( aOuter
.Left(), aOuter
.Top(), aOuter
.Right(), aInner
.Top() ) );
128 pDev
->DrawRect( Rectangle( aInner
.Right(), aOuter
.Top(), aOuter
.Right(), aOuter
.Bottom() ) );
129 pDev
->DrawRect( Rectangle( aOuter
.Left(), aInner
.Bottom(), aOuter
.Right(), aOuter
.Bottom() ) );
131 long nButtonY
= bTextBelow
? aInner
.Bottom() : aOuter
.Top();
133 ScDDComboBoxButton
aComboButton((Window
*)pDev
);
134 aComboButton
.SetOptSizePixel();
135 long nBWidth
= ( aComboButton
.GetSizePixel().Width() * rZoomY
.GetNumerator() )
136 / rZoomY
.GetDenominator();
137 long nBHeight
= nVer
+ aTextSize
.Height() + 1;
138 Size
aButSize( nBWidth
, nBHeight
);
139 long nButtonPos
= bLayoutRTL
? aOuter
.Left() : aOuter
.Right()-nBWidth
+1;
140 aComboButton
.Draw( Point(nButtonPos
, nButtonY
), aButSize
, false );
142 pButtonViewData
->SetScenButSize( aButSize
);
144 long nTextStart
= bLayoutRTL
? aInner
.Right() - aTextSize
.Width() + 1 : aInner
.Left();
146 bool bWasClip
= false;
148 bool bClip
= ( aTextSize
.Width() > aOuter
.Right() - nBWidth
- aInner
.Left() );
151 if (pDev
->IsClipRegion())
154 aOldClip
= pDev
->GetActiveClipRegion();
156 long nClipStartX
= bLayoutRTL
? aOuter
.Left() + nBWidth
: aInner
.Left();
157 long nClipEndX
= bLayoutRTL
? aInner
.Right() : aOuter
.Right() - nBWidth
;
158 pDev
->SetClipRegion( Region(Rectangle( nClipStartX
, nButtonY
+ nVer
/2,
159 nClipEndX
, nButtonY
+ nVer
/2 + aTextSize
.Height())) );
162 pDev
->DrawText( Point( nTextStart
, nButtonY
+ nVer
/2 ), rTitle
);
167 pDev
->SetClipRegion(aOldClip
);
169 pDev
->SetClipRegion();
172 pDev
->SetFillColor();
173 pDev
->SetLineColor( COL_BLACK
);
174 pDev
->DrawRect( aInner
);
175 pDev
->DrawRect( aOuter
);
178 static void lcl_DrawScenarioFrames( OutputDevice
* pDev
, ScViewData
* pViewData
, ScSplitPos eWhich
,
179 SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
)
181 ScDocument
* pDoc
= pViewData
->GetDocument();
182 SCTAB nTab
= pViewData
->GetTabNo();
183 SCTAB nTabCount
= pDoc
->GetTableCount();
184 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
186 if ( nX1
> 0 ) --nX1
;
187 if ( nY1
>=2 ) nY1
-= 2; // Hack: Titelzeile beruehrt zwei Zellen
188 else if ( nY1
> 0 ) --nY1
;
189 if ( nX2
< MAXCOL
) ++nX2
;
190 if ( nY2
< MAXROW
-1 ) nY2
+= 2; // Hack: Titelzeile beruehrt zwei Zellen
191 else if ( nY2
< MAXROW
) ++nY2
;
192 ScRange
aViewRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
194 //! Ranges an der Table cachen!!!!
197 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
198 pDoc
->MarkScenario( i
, nTab
, aMarks
, false, SC_SCENARIO_SHOWFRAME
);
199 ScRangeListRef xRanges
= new ScRangeList
;
200 aMarks
.FillRangeListWithMarks( xRanges
, false );
202 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
203 long nLayoutSign
= bLayoutRTL
? -1 : 1;
205 for (size_t j
= 0, n
= xRanges
->size(); j
< n
; ++j
)
207 ScRange aRange
= *(*xRanges
)[j
];
208 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
209 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
210 pDoc
->ExtendTotalMerge( aRange
);
212 //! -> Repaint beim Zusammenfassen erweitern !!!
214 if ( aRange
.Intersects( aViewRange
) ) //! Platz fuer Text/Button?
216 Point aStartPos
= pViewData
->GetScrPos(
217 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, true );
218 Point aEndPos
= pViewData
->GetScrPos(
219 aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
, true );
221 aStartPos
.X() -= nLayoutSign
;
223 aEndPos
.X() -= nLayoutSign
;
226 bool bTextBelow
= ( aRange
.aStart
.Row() == 0 );
229 Color
aColor( COL_LIGHTGRAY
);
230 for (SCTAB nAct
=nTab
+1; nAct
<nTabCount
&& pDoc
->IsScenario(nAct
); nAct
++)
231 if ( pDoc
->IsActiveScenario(nAct
) && pDoc
->HasScenarioRange(nAct
,aRange
) )
233 OUString aDummyComment
;
234 sal_uInt16 nDummyFlags
;
235 pDoc
->GetName( nAct
, aCurrent
);
236 pDoc
->GetScenarioData( nAct
, aDummyComment
, aColor
, nDummyFlags
);
239 if (aCurrent
.isEmpty())
240 aCurrent
= ScGlobal::GetRscString( STR_EMPTYDATA
);
242 //! eigener Text "(keins)" statt "(leer)" ???
244 lcl_DrawOneFrame( pDev
, Rectangle( aStartPos
, aEndPos
),
245 aCurrent
, aColor
, bTextBelow
,
246 pViewData
->GetPPTX(), pViewData
->GetPPTY(), pViewData
->GetZoomY(),
247 pDoc
, pViewData
, bLayoutRTL
);
253 static void lcl_DrawHighlight( ScOutputData
& rOutputData
, ScViewData
* pViewData
,
254 const std::vector
<ScHighlightEntry
>& rHighlightRanges
)
256 SCTAB nTab
= pViewData
->GetTabNo();
257 std::vector
<ScHighlightEntry
>::const_iterator pIter
;
258 for ( pIter
= rHighlightRanges
.begin(); pIter
!= rHighlightRanges
.end(); ++pIter
)
260 ScRange aRange
= pIter
->aRef
;
261 if ( nTab
>= aRange
.aStart
.Tab() && nTab
<= aRange
.aEnd
.Tab() )
263 rOutputData
.DrawRefMark(
264 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
265 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
266 pIter
->aColor
, false );
271 void ScGridWindow::DoInvertRect( const Rectangle
& rPixel
)
273 if ( rPixel
== aInvertRect
)
274 aInvertRect
= Rectangle(); // aufheben
277 OSL_ENSURE( aInvertRect
.IsEmpty(), "DoInvertRect nicht paarig" );
279 aInvertRect
= rPixel
; // neues Rechteck merken
282 UpdateHeaderOverlay(); // uses aInvertRect
285 void ScGridWindow::PrePaint()
287 // forward PrePaint to DrawingLayer
288 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
292 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
296 pDrawView
->PrePaint();
301 void ScGridWindow::Paint( const Rectangle
& rRect
)
303 ScDocument
* pDoc
= pViewData
->GetDocument();
304 if ( pDoc
->IsInInterpreter() )
306 // via Reschedule, interpretierende Zellen nicht nochmal anstossen
307 // hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe
308 // (Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt.
312 //! Rechtecke zusammenfassen?
313 aRepaintPixel
= Rectangle(); // mehrfach -> alles painten
317 bNeedsRepaint
= true;
318 aRepaintPixel
= LogicToPixel(rRect
); // nur betroffenen Bereich
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
); // nicht weiterzeichnen
379 // Draw ----------------------------------------------------------------
382 void ScGridWindow::Draw( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, ScUpdateMode eMode
)
384 ScModule
* pScMod
= SC_MOD();
385 bool bTextWysiwyg
= pScMod
->GetInputOptions().GetTextWysiwyg();
387 if (pViewData
->IsMinimized())
390 PutInOrder( nX1
, nX2
);
391 PutInOrder( nY1
, nY2
);
393 OSL_ENSURE( ValidCol(nX2
) && ValidRow(nY2
), "GridWin Draw Bereich zu gross" );
395 if (nX2
< maVisibleRange
.mnCol1
|| nY2
< maVisibleRange
.mnRow1
)
398 if (nX1
< maVisibleRange
.mnCol1
)
399 nX1
= maVisibleRange
.mnCol1
;
400 if (nY1
< maVisibleRange
.mnRow1
)
401 nY1
= maVisibleRange
.mnRow1
;
403 if (nX1
> maVisibleRange
.mnCol2
|| nY1
> maVisibleRange
.mnRow2
)
406 if (nX2
> maVisibleRange
.mnCol2
)
407 nX2
= maVisibleRange
.mnCol2
;
408 if (nY2
> maVisibleRange
.mnRow2
)
409 nY2
= maVisibleRange
.mnRow2
;
411 if ( eMode
!= SC_UPDATE_MARKS
&& nX2
< maVisibleRange
.mnCol2
)
412 nX2
= maVisibleRange
.mnCol2
; // zum Weiterzeichnen
414 // ab hier kein return mehr
416 ++nPaintCount
; // merken, dass gemalt wird (wichtig beim Invertieren)
418 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
419 ScDocument
* pDoc
= pDocSh
->GetDocument();
420 SCTAB nTab
= pViewData
->GetTabNo();
422 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
424 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
425 long nMirrorWidth
= GetSizePixel().Width();
426 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
427 long nLayoutSign
= bLayoutRTL
? -1 : 1;
430 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, maVisibleRange
.mnRow1
, eWhich
).X();
431 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
432 aScrPos
.X() = nEndPixel
+ 1;
435 long nScrX
= aScrPos
.X();
436 long nScrY
= aScrPos
.Y();
438 SCCOL nCurX
= pViewData
->GetCurX();
439 SCROW nCurY
= pViewData
->GetCurY();
440 SCCOL nCurEndX
= nCurX
;
441 SCROW nCurEndY
= nCurY
;
442 pDoc
->ExtendMerge( nCurX
, nCurY
, nCurEndX
, nCurEndY
, nTab
);
443 bool bCurVis
= nCursorHideCount
==0 &&
444 ( nCurEndX
+1 >= nX1
&& nCurX
<= nX2
+1 && nCurEndY
+1 >= nY1
&& nCurY
<= nY2
+1 );
447 if ( !bCurVis
&& nCursorHideCount
==0 && bAutoMarkVisible
&& aAutoMarkPos
.Tab() == nTab
&&
448 ( aAutoMarkPos
.Col() != nCurX
|| aAutoMarkPos
.Row() != nCurY
) )
450 SCCOL nHdlX
= aAutoMarkPos
.Col();
451 SCROW nHdlY
= aAutoMarkPos
.Row();
452 pDoc
->ExtendMerge( nHdlX
, nHdlY
, nHdlX
, nHdlY
, nTab
);
453 bCurVis
= ( nHdlX
+1 >= nX1
&& nHdlX
<= nX2
&& nHdlY
+1 >= nY1
&& nHdlY
<= nY2
);
454 // links und oben ist nicht betroffen
456 //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
459 double nPPTX
= pViewData
->GetPPTX();
460 double nPPTY
= pViewData
->GetPPTY();
462 const ScViewOptions
& rOpts
= pViewData
->GetOptions();
463 bool bFormulaMode
= rOpts
.GetOption( VOPT_FORMULAS
);
464 bool bMarkClipped
= rOpts
.GetOption( VOPT_CLIPMARKS
);
468 ScTableInfo aTabInfo
;
469 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
,
470 nPPTX
, nPPTY
, false, bFormulaMode
,
471 &pViewData
->GetMarkData() );
473 Fraction aZoomX
= pViewData
->GetZoomX();
474 Fraction aZoomY
= pViewData
->GetZoomY();
475 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
476 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
479 aOutputData
.SetMirrorWidth( nMirrorWidth
); // needed for RTL
480 aOutputData
.SetSpellCheckContext(mpSpellCheckCxt
.get());
482 boost::scoped_ptr
< VirtualDevice
> xFmtVirtDev
;
483 bool bLogicText
= bTextWysiwyg
; // call DrawStrings in logic MapMode?
487 // use printer for text formatting
489 OutputDevice
* pFmtDev
= pDoc
->GetPrinter();
490 pFmtDev
->SetMapMode( pViewData
->GetLogicMode(eWhich
) );
491 aOutputData
.SetFmtDevice( pFmtDev
);
493 else if ( aZoomX
!= aZoomY
&& pViewData
->IsOle() )
495 // #i45033# For OLE inplace editing with different zoom factors,
496 // use a virtual device with 1/100th mm as text formatting reference
498 xFmtVirtDev
.reset( new VirtualDevice
);
499 xFmtVirtDev
->SetMapMode( MAP_100TH_MM
);
500 aOutputData
.SetFmtDevice( xFmtVirtDev
.get() );
502 bLogicText
= true; // use logic MapMode
505 const svtools::ColorConfig
& rColorCfg
= pScMod
->GetColorConfig();
506 Color
aGridColor( rColorCfg
.GetColorValue( svtools::CALCGRID
, false ).nColor
);
507 if ( aGridColor
.GetColor() == COL_TRANSPARENT
)
509 // use view options' grid color only if color config has "automatic" color
510 aGridColor
= rOpts
.GetGridColor();
513 aOutputData
.SetSyntaxMode ( pViewData
->IsSyntaxMode() );
514 aOutputData
.SetGridColor ( aGridColor
);
515 aOutputData
.SetShowNullValues ( rOpts
.GetOption( VOPT_NULLVALS
) );
516 aOutputData
.SetShowFormulas ( bFormulaMode
);
517 aOutputData
.SetShowSpellErrors ( pDoc
->GetDocOptions().IsAutoSpell() );
518 aOutputData
.SetMarkClipped ( bMarkClipped
);
520 aOutputData
.SetUseStyleColor( true ); // always set in table view
522 aOutputData
.SetEditObject( GetEditObject() );
523 aOutputData
.SetViewShell( pViewData
->GetViewShell() );
525 bool bGrid
= rOpts
.GetOption( VOPT_GRID
) && pViewData
->GetShowGrid();
526 bool bGridFirst
= !rOpts
.GetOption( VOPT_GRID_ONTOP
);
528 bool bPage
= rOpts
.GetOption( VOPT_PAGEBREAKS
);
530 if ( eMode
== SC_UPDATE_CHANGED
)
532 aOutputData
.FindChanged();
533 aOutputData
.SetSingleGrid(true);
536 bool bPageMode
= pViewData
->IsPagebreakMode();
537 if (bPageMode
) // nach FindChanged
539 // SetPagebreakMode initialisiert auch bPrinted Flags
540 aOutputData
.SetPagebreakMode( pViewData
->GetView()->GetPageBreakData() );
543 EditView
* pEditView
= NULL
;
544 bool bEditMode
= pViewData
->HasEditView(eWhich
);
545 if ( bEditMode
&& pViewData
->GetRefTabNo() == nTab
)
549 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
550 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
551 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
553 if ( nEditEndCol
>= nX1
&& nEditCol
<= nX2
&& nEditEndRow
>= nY1
&& nEditRow
<= nY2
)
554 aOutputData
.SetEditCell( nEditCol
, nEditRow
);
559 // define drawing layer map mode and paint rectangle
560 const MapMode aDrawMode
= GetDrawMapMode();
561 Rectangle aDrawingRectLogic
;
564 // get drawing pixel rect
565 Rectangle
aDrawingRectPixel(Point(nScrX
, nScrY
), Size(aOutputData
.GetScrW(), aOutputData
.GetScrH()));
567 // correct for border (left/right)
572 aDrawingRectPixel
.Left() = 0L;
576 aDrawingRectPixel
.Right() = GetOutputSizePixel().getWidth();
580 // correct for border (bottom)
583 aDrawingRectPixel
.Bottom() = GetOutputSizePixel().getHeight();
586 // get logic positions
587 aDrawingRectLogic
= PixelToLogic(aDrawingRectPixel
, aDrawMode
);
590 OutputDevice
* pContentDev
= this; // device for document content, used by overlay manager
591 SdrPaintWindow
* pTargetPaintWindow
= 0; // #i74769# work with SdrPaintWindow directly
595 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
599 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
600 pContentDev
->SetMapMode(aDrawMode
);
601 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
605 // #i74769# Use new BeginDrawLayers() interface
606 Region
aDrawingRegion(aDrawingRectLogic
);
607 pTargetPaintWindow
= pDrawView
->BeginDrawLayers(this, aDrawingRegion
);
608 OSL_ENSURE(pTargetPaintWindow
, "BeginDrawLayers: Got no SdrPaintWindow (!)");
610 // #i74769# get target device from SdrPaintWindow, this may be the prerender
612 pContentDev
= &(pTargetPaintWindow
->GetTargetOutputDevice());
613 aOutputData
.SetContentDevice( pContentDev
);
616 pContentDev
->SetMapMode(aCurrentMapMode
);
620 // Rand (Wiese) (Pixel)
621 if ( nX2
==MAXCOL
|| nY2
==MAXROW
)
623 // save MapMode and set to pixel
624 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
625 pContentDev
->SetMapMode(MAP_PIXEL
);
627 Rectangle aPixRect
= Rectangle( Point(), GetOutputSizePixel() );
628 pContentDev
->SetFillColor( rColorCfg
.GetColorValue(svtools::APPBACKGROUND
).nColor
);
629 pContentDev
->SetLineColor();
632 Rectangle
aDrawRect( aPixRect
);
634 aDrawRect
.Right() = nScrX
- 1;
636 aDrawRect
.Left() = nScrX
+ aOutputData
.GetScrW();
637 if (aDrawRect
.Right() >= aDrawRect
.Left())
638 pContentDev
->DrawRect( aDrawRect
);
642 Rectangle
aDrawRect( aPixRect
);
643 aDrawRect
.Top() = nScrY
+ aOutputData
.GetScrH();
646 // no double painting of the corner
648 aDrawRect
.Left() = nScrX
;
650 aDrawRect
.Right() = nScrX
+ aOutputData
.GetScrW() - 1;
652 if (aDrawRect
.Bottom() >= aDrawRect
.Top())
653 pContentDev
->DrawRect( aDrawRect
);
657 pContentDev
->SetMapMode(aCurrentMapMode
);
660 if ( pDoc
->HasBackgroundDraw( nTab
, aDrawingRectLogic
) )
662 pContentDev
->SetMapMode(MAP_PIXEL
);
663 aOutputData
.DrawClear();
665 // Drawing Hintergrund
667 pContentDev
->SetMapMode(aDrawMode
);
668 DrawRedraw( aOutputData
, eMode
, SC_LAYER_BACK
);
671 aOutputData
.SetSolidBackground(true);
673 pContentDev
->SetMapMode(MAP_PIXEL
);
674 aOutputData
.DrawDocumentBackground();
676 if ( bGridFirst
&& ( bGrid
|| bPage
) )
677 aOutputData
.DrawGrid( bGrid
, bPage
);
679 aOutputData
.DrawBackground();
681 if ( !bGridFirst
&& ( bGrid
|| bPage
) )
682 aOutputData
.DrawGrid( bGrid
, bPage
);
686 // DrawPagePreview draws complete lines/page numbers, must always be clipped
687 if ( aOutputData
.SetChangedClip() )
689 DrawPagePreview(nX1
,nY1
,nX2
,nY2
, pContentDev
);
690 pContentDev
->SetClipRegion();
694 aOutputData
.DrawShadow();
695 aOutputData
.DrawFrame();
697 aOutputData
.DrawStrings(false); // in pixel MapMode
699 // edit cells and printer-metrics text must be before the buttons
700 // (DataPilot buttons contain labels in UI font)
702 pContentDev
->SetMapMode(pViewData
->GetLogicMode(eWhich
));
704 aOutputData
.DrawStrings(true); // in logic MapMode if bTextWysiwyg is set
705 aOutputData
.DrawEdit(true);
706 pContentDev
->SetMapMode(MAP_PIXEL
);
708 // Autofilter- und Pivot-Buttons
710 DrawButtons( nX1
, nX2
, aTabInfo
, pContentDev
); // Pixel
714 if ( rOpts
.GetOption( VOPT_NOTES
) )
715 aOutputData
.DrawNoteMarks();
717 aOutputData
.DrawClipMarks();
719 // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
721 //! Test, ob ChangeTrack-Anzeige aktiv ist
722 //! Szenario-Rahmen per View-Optionen abschaltbar?
724 SCTAB nTabCount
= pDoc
->GetTableCount();
725 const std::vector
<ScHighlightEntry
> &rHigh
= pViewData
->GetView()->GetHighlightRanges();
726 bool bHasScenario
= ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) );
727 bool bHasChange
= ( pDoc
->GetChangeTrack() != NULL
);
729 if ( bHasChange
|| bHasScenario
|| !rHigh
.empty() )
732 //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
735 if (eMode
== SC_UPDATE_CHANGED
)
736 bAny
= aOutputData
.SetChangedClip();
740 aOutputData
.DrawChangeTrack();
743 lcl_DrawScenarioFrames( pContentDev
, pViewData
, eWhich
, nX1
,nY1
,nX2
,nY2
);
745 lcl_DrawHighlight( aOutputData
, pViewData
, rHigh
);
747 if (eMode
== SC_UPDATE_CHANGED
)
748 pContentDev
->SetClipRegion();
752 // Drawing Vordergrund
754 pContentDev
->SetMapMode(aDrawMode
);
756 DrawRedraw( aOutputData
, eMode
, SC_LAYER_FRONT
);
757 DrawRedraw( aOutputData
, eMode
, SC_LAYER_INTERN
);
758 DrawSdrGrid( aDrawingRectLogic
, pContentDev
);
760 if (!bIsInScroll
) // Drawing Markierungen
762 if(eMode
== SC_UPDATE_CHANGED
&& aOutputData
.SetChangedClip())
764 pContentDev
->SetClipRegion();
768 pContentDev
->SetMapMode(MAP_PIXEL
);
770 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() )
772 Color
aRefColor( rColorCfg
.GetColorValue(svtools::CALCREFERENCE
).nColor
);
773 aOutputData
.DrawRefMark( pViewData
->GetRefStartX(), pViewData
->GetRefStartY(),
774 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(),
780 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
783 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
784 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
785 pRangeFinder
->GetDocName() == pDocSh
->GetTitle() )
787 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
788 for (sal_uInt16 i
=0; i
<nCount
; i
++)
790 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
792 ScRange aRef
= pData
->aRef
;
794 if ( aRef
.aStart
.Tab() >= nTab
&& aRef
.aEnd
.Tab() <= nTab
)
795 aOutputData
.DrawRefMark( aRef
.aStart
.Col(), aRef
.aStart
.Row(),
796 aRef
.aEnd
.Col(), aRef
.aEnd
.Row(),
797 Color( pData
->nColorData
),
805 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
809 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
810 pContentDev
->SetMapMode(aDrawMode
);
811 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
815 // #i74769# work with SdrPaintWindow directly
816 pDrawView
->EndDrawLayers(*pTargetPaintWindow
, true);
819 pContentDev
->SetMapMode(aCurrentMapMode
);
824 // moved after EndDrawLayers() to get it outside the overlay buffer and
825 // on top of everything
826 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
828 //! use pContentDev for EditView?
829 SetMapMode(MAP_PIXEL
);
830 SCCOL nCol1
= pViewData
->GetEditStartCol();
831 SCROW nRow1
= pViewData
->GetEditStartRow();
832 SCCOL nCol2
= pViewData
->GetEditEndCol();
833 SCROW nRow2
= pViewData
->GetEditEndRow();
835 SetFillColor( pEditView
->GetBackgroundColor() );
836 Point aStart
= pViewData
->GetScrPos( nCol1
, nRow1
, eWhich
);
837 Point aEnd
= pViewData
->GetScrPos( nCol2
+1, nRow2
+1, eWhich
);
838 aEnd
.X() -= 2 * nLayoutSign
; // don't overwrite grid
840 DrawRect( Rectangle( aStart
,aEnd
) );
842 SetMapMode(pViewData
->GetLogicMode());
843 pEditView
->Paint( PixelToLogic( Rectangle( Point( nScrX
, nScrY
),
844 Size( aOutputData
.GetScrW(), aOutputData
.GetScrH() ) ) ) );
845 SetMapMode(MAP_PIXEL
);
848 if (pViewData
->HasEditView(eWhich
))
850 // flush OverlayManager before changing the MapMode
851 flushOverlayManager();
853 // set MapMode for text edit
854 SetMapMode(pViewData
->GetLogicMode());
857 SetMapMode(aDrawMode
);
860 pNoteMarker
->Draw(); // ueber den Cursor, im Drawing-MapMode
863 // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
864 // ist das jetzt durcheinandergekommen und es muss neu gemalt werden
867 OSL_ENSURE(nPaintCount
, "nPaintCount falsch");
872 // Flag drawn formula cells "unchanged".
873 pDoc
->ResetChanged(ScRange(nX1
,nY1
,nTab
,nX2
,nY2
,nTab
));
874 pDoc
->ClearFormulaContext();
877 void ScGridWindow::CheckNeedsRepaint()
879 // called at the end of painting, and from timer after background text width calculation
883 bNeedsRepaint
= false;
884 if (aRepaintPixel
.IsEmpty())
887 Invalidate(PixelToLogic(aRepaintPixel
));
888 aRepaintPixel
= Rectangle();
890 // selection function in status bar might also be invalid
891 SfxBindings
& rBindings
= pViewData
->GetBindings();
892 rBindings
.Invalidate( SID_STATUS_SUM
);
893 rBindings
.Invalidate( SID_ATTR_SIZE
);
894 rBindings
.Invalidate( SID_TABLE_CELL
);
898 void ScGridWindow::DrawPagePreview( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, OutputDevice
* pContentDev
)
900 ScPageBreakData
* pPageData
= pViewData
->GetView()->GetPageBreakData();
903 ScDocument
* pDoc
= pViewData
->GetDocument();
904 SCTAB nTab
= pViewData
->GetTabNo();
905 Size aWinSize
= GetOutputSizePixel();
906 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
907 Color
aManual( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
908 Color
aAutomatic( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAK
).nColor
);
910 OUString aPageStr
= ScGlobal::GetRscString( STR_PGNUM
);
911 if ( nPageScript
== 0 )
913 // get script type of translated "Page" string only once
914 nPageScript
= pDoc
->GetStringScriptType( aPageStr
);
915 if (nPageScript
== 0)
916 nPageScript
= ScGlobal::GetDefaultScriptType();
920 boost::scoped_ptr
<ScEditEngineDefaulter
> pEditEng
;
921 const ScPatternAttr
& rDefPattern
= ((const ScPatternAttr
&)pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
));
922 if ( nPageScript
== SCRIPTTYPE_LATIN
)
924 // use single font and call DrawText directly
925 rDefPattern
.GetFont( aFont
, SC_AUTOCOL_BLACK
);
926 aFont
.SetColor( Color( COL_LIGHTGRAY
) );
927 // font size is set as needed
931 // use EditEngine to draw mixed-script string
932 pEditEng
.reset(new ScEditEngineDefaulter( EditEngine::CreatePool(), true ));
933 pEditEng
->SetRefMapMode( pContentDev
->GetMapMode() );
934 SfxItemSet
* pEditDefaults
= new SfxItemSet( pEditEng
->GetEmptyItemSet() );
935 rDefPattern
.FillEditItemSet( pEditDefaults
);
936 pEditDefaults
->Put( SvxColorItem( Color( COL_LIGHTGRAY
), EE_CHAR_COLOR
) );
937 pEditEng
->SetDefaults( pEditDefaults
);
940 sal_uInt16 nCount
= sal::static_int_cast
<sal_uInt16
>( pPageData
->GetCount() );
941 for (sal_uInt16 nPos
=0; nPos
<nCount
; nPos
++)
943 ScPrintRangeData
& rData
= pPageData
->GetData(nPos
);
944 ScRange aRange
= rData
.GetPrintRange();
945 if ( aRange
.aStart
.Col() <= nX2
+1 && aRange
.aEnd
.Col()+1 >= nX1
&&
946 aRange
.aStart
.Row() <= nY2
+1 && aRange
.aEnd
.Row()+1 >= nY1
)
948 // 3 Pixel Rahmen um den Druckbereich
949 // (mittlerer Pixel auf den Gitterlinien)
951 pContentDev
->SetLineColor();
952 if (rData
.IsAutomatic())
953 pContentDev
->SetFillColor( aAutomatic
);
955 pContentDev
->SetFillColor( aManual
);
957 Point aStart
= pViewData
->GetScrPos(
958 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, true );
959 Point aEnd
= pViewData
->GetScrPos(
960 aRange
.aEnd
.Col() + 1, aRange
.aEnd
.Row() + 1, eWhich
, true );
964 // Ueberlaeufe verhindern:
965 if ( aStart
.X() < -10 ) aStart
.X() = -10;
966 if ( aStart
.Y() < -10 ) aStart
.Y() = -10;
967 if ( aEnd
.X() > aWinSize
.Width() + 10 )
968 aEnd
.X() = aWinSize
.Width() + 10;
969 if ( aEnd
.Y() > aWinSize
.Height() + 10 )
970 aEnd
.Y() = aWinSize
.Height() + 10;
972 pContentDev
->DrawRect( Rectangle( aStart
, Point(aEnd
.X(),aStart
.Y()+2) ) );
973 pContentDev
->DrawRect( Rectangle( aStart
, Point(aStart
.X()+2,aEnd
.Y()) ) );
974 pContentDev
->DrawRect( Rectangle( Point(aStart
.X(),aEnd
.Y()-2), aEnd
) );
975 pContentDev
->DrawRect( Rectangle( Point(aEnd
.X()-2,aStart
.Y()), aEnd
) );
978 //! anders darstellen (gestrichelt ????)
980 size_t nColBreaks
= rData
.GetPagesX();
981 const SCCOL
* pColEnd
= rData
.GetPageEndX();
983 for (nColPos
=0; nColPos
+1<nColBreaks
; nColPos
++)
985 SCCOL nBreak
= pColEnd
[nColPos
]+1;
986 if ( nBreak
>= nX1
&& nBreak
<= nX2
+1 )
989 if (pDoc
->HasColBreak(nBreak
, nTab
) & BREAK_MANUAL
)
990 pContentDev
->SetFillColor( aManual
);
992 pContentDev
->SetFillColor( aAutomatic
);
993 Point aBreak
= pViewData
->GetScrPos(
994 nBreak
, aRange
.aStart
.Row(), eWhich
, true );
995 pContentDev
->DrawRect( Rectangle( aBreak
.X()-1, aStart
.Y(), aBreak
.X(), aEnd
.Y() ) );
999 size_t nRowBreaks
= rData
.GetPagesY();
1000 const SCROW
* pRowEnd
= rData
.GetPageEndY();
1002 for (nRowPos
=0; nRowPos
+1<nRowBreaks
; nRowPos
++)
1004 SCROW nBreak
= pRowEnd
[nRowPos
]+1;
1005 if ( nBreak
>= nY1
&& nBreak
<= nY2
+1 )
1008 if (pDoc
->HasRowBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1009 pContentDev
->SetFillColor( aManual
);
1011 pContentDev
->SetFillColor( aAutomatic
);
1012 Point aBreak
= pViewData
->GetScrPos(
1013 aRange
.aStart
.Col(), nBreak
, eWhich
, true );
1014 pContentDev
->DrawRect( Rectangle( aStart
.X(), aBreak
.Y()-1, aEnd
.X(), aBreak
.Y() ) );
1020 SCROW nPrStartY
= aRange
.aStart
.Row();
1021 for (nRowPos
=0; nRowPos
<nRowBreaks
; nRowPos
++)
1023 SCROW nPrEndY
= pRowEnd
[nRowPos
];
1024 if ( nPrEndY
>= nY1
&& nPrStartY
<= nY2
)
1026 SCCOL nPrStartX
= aRange
.aStart
.Col();
1027 for (nColPos
=0; nColPos
<nColBreaks
; nColPos
++)
1029 SCCOL nPrEndX
= pColEnd
[nColPos
];
1030 if ( nPrEndX
>= nX1
&& nPrStartX
<= nX2
)
1032 Point aPageStart
= pViewData
->GetScrPos(
1033 nPrStartX
, nPrStartY
, eWhich
, true );
1034 Point aPageEnd
= pViewData
->GetScrPos(
1035 nPrEndX
+1,nPrEndY
+1, eWhich
, true );
1037 long nPageNo
= rData
.GetFirstPage();
1038 if ( rData
.IsTopDown() )
1039 nPageNo
+= ((long)nColPos
)*nRowBreaks
+nRowPos
;
1041 nPageNo
+= ((long)nRowPos
)*nColBreaks
+nColPos
;
1043 OUString aThisPageStr
= OUString(aPageStr
).replaceFirst("%1", OUString::number(nPageNo
));
1047 // find right font size with EditEngine
1049 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1050 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1051 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1052 pEditEng
->SetText( aThisPageStr
);
1053 Size
aSize100( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1055 // 40% of width or 60% of height
1056 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1057 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1058 nHeight
= std::min(nSizeX
,nSizeY
);
1059 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1060 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1061 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1063 // centered output with EditEngine
1064 Size
aTextSize( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1065 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1066 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1067 pEditEng
->Draw( pContentDev
, aPos
);
1071 // find right font size for DrawText
1072 aFont
.SetSize( Size( 0,100 ) );
1073 pContentDev
->SetFont( aFont
);
1074 Size
aSize100( pContentDev
->GetTextWidth( aThisPageStr
), pContentDev
->GetTextHeight() );
1076 // 40% of width or 60% of height
1077 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1078 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1079 aFont
.SetSize( Size( 0,std::min(nSizeX
,nSizeY
) ) );
1080 pContentDev
->SetFont( aFont
);
1082 // centered output with DrawText
1083 Size
aTextSize( pContentDev
->GetTextWidth( aThisPageStr
), pContentDev
->GetTextHeight() );
1084 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1085 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1086 pContentDev
->DrawText( aPos
, aThisPageStr
);
1089 nPrStartX
= nPrEndX
+ 1;
1092 nPrStartY
= nPrEndY
+ 1;
1099 void ScGridWindow::DrawButtons( SCCOL nX1
, SCCOL nX2
, ScTableInfo
& rTabInfo
, OutputDevice
* pContentDev
)
1101 aComboButton
.SetOutputDevice( pContentDev
);
1103 ScDocument
* pDoc
= pViewData
->GetDocument();
1104 ScDPFieldButton
aCellBtn(pContentDev
, &GetSettings().GetStyleSettings(), &pViewData
->GetZoomX(), &pViewData
->GetZoomY(), pDoc
);
1110 SCTAB nTab
= pViewData
->GetTabNo();
1111 ScDBData
* pDBData
= NULL
;
1112 boost::scoped_ptr
<ScQueryParam
> pQueryParam
;
1114 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
1115 sal_uInt16 nArrCount
= rTabInfo
.mnArrCount
;
1117 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1119 Point aOldPos
= aComboButton
.GetPosPixel(); // Zustand fuer MouseDown/Up
1120 Size aOldSize
= aComboButton
.GetSizePixel(); // merken
1122 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1124 if ( pRowInfo
[nArrY
].bAutoFilter
&& pRowInfo
[nArrY
].bChanged
)
1126 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1128 nRow
= pThisRowInfo
->nRowNo
;
1131 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1133 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1134 //if several columns merged on a row, there should be only one auto button at the end of the columns.
1135 //if several rows merged on a column, the button may be in the middle, so "!pInfo->bVOverlapped" should not be used
1136 if ( pInfo
->bAutoFilter
&& !pInfo
->bHOverlapped
)
1139 pQueryParam
.reset(new ScQueryParam
);
1141 bool bNewData
= true;
1149 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1150 if ( nCol
>= nStartCol
&& nCol
<= nEndCol
&&
1151 nRow
>= nStartRow
&& nRow
<= nEndRow
)
1156 pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1158 pDBData
->GetQueryParam( *pQueryParam
);
1161 // can also be part of DataPilot table
1162 // OSL_FAIL("Auto-Filter-Button ohne DBData");
1166 // pQueryParam kann nur MAXQUERY Eintraege enthalten
1168 bool bSimpleQuery
= true;
1169 bool bColumnFound
= false;
1170 if (!pQueryParam
->bInplace
)
1171 bSimpleQuery
= false;
1172 SCSIZE nCount
= pQueryParam
->GetEntryCount();
1173 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1174 if (pQueryParam
->GetEntry(nQuery
).bDoQuery
)
1176 // hier nicht auf EQUAL beschraenken
1177 // (auch bei ">1" soll der Spaltenkopf blau werden)
1179 if (pQueryParam
->GetEntry(nQuery
).nField
== nCol
)
1180 bColumnFound
= true;
1182 if (pQueryParam
->GetEntry(nQuery
).eConnect
!= SC_AND
)
1183 bSimpleQuery
= false;
1186 bool bArrowState
= bSimpleQuery
&& bColumnFound
;
1189 SCCOL nStartCol
= nCol
;
1190 SCROW nStartRow
= nRow
;
1191 //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.
1192 //should first get the start pos of the merge area, then get the nSizeX through the start pos.
1193 pDoc
->ExtendOverlapped(nStartCol
, nStartRow
,nCol
, nRow
, nTab
);//get nStartCol,nStartRow
1194 pViewData
->GetMergeSizePixel( nStartCol
, nStartRow
, nSizeX
, nSizeY
);//get nSizeX
1195 nSizeY
= pViewData
->ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
1196 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1198 aCellBtn
.setBoundingBox(aScrPos
, Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1199 aCellBtn
.setPopupLeft(bLayoutRTL
); // #i114944# AutoFilter button is left-aligned in RTL
1200 aCellBtn
.setDrawBaseButton(false);
1201 aCellBtn
.setDrawPopupButton(true);
1202 aCellBtn
.setHasHiddenMember(bArrowState
);
1208 if ( pRowInfo
[nArrY
].bPivotButton
&& pRowInfo
[nArrY
].bChanged
)
1210 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1211 nRow
= pThisRowInfo
->nRowNo
;
1212 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1214 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1215 if (pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
1218 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1221 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1222 long nPosX
= aScrPos
.X();
1223 long nPosY
= aScrPos
.Y();
1224 // bLayoutRTL is handled in setBoundingBox
1226 OUString aStr
= pDoc
->GetString(nCol
, nRow
, nTab
);
1227 aCellBtn
.setText(aStr
);
1228 aCellBtn
.setBoundingBox(Point(nPosX
, nPosY
), Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1229 aCellBtn
.setPopupLeft(false); // DataPilot popup is always right-aligned for now
1230 aCellBtn
.setDrawBaseButton(pInfo
->bPivotButton
);
1231 aCellBtn
.setDrawPopupButton(pInfo
->bPivotPopupButton
);
1232 aCellBtn
.setHasHiddenMember(pInfo
->bFilterActive
);
1237 if ( bListValButton
&& pRowInfo
[nArrY
].nRowNo
== aListValPos
.Row() && pRowInfo
[nArrY
].bChanged
)
1239 Rectangle aRect
= GetListValButtonRect( aListValPos
);
1240 aComboButton
.SetPosPixel( aRect
.TopLeft() );
1241 aComboButton
.SetSizePixel( aRect
.GetSize() );
1242 pContentDev
->SetClipRegion(Region(aRect
));
1243 aComboButton
.Draw( false, false );
1244 pContentDev
->SetClipRegion(); // always called from Draw() without clip region
1245 aComboButton
.SetPosPixel( aOldPos
); // restore old state
1246 aComboButton
.SetSizePixel( aOldSize
); // for MouseUp/Down (AutoFilter)
1250 pQueryParam
.reset();
1251 aComboButton
.SetOutputDevice( this );
1254 Rectangle
ScGridWindow::GetListValButtonRect( const ScAddress
& rButtonPos
)
1256 ScDocument
* pDoc
= pViewData
->GetDocument();
1257 SCTAB nTab
= pViewData
->GetTabNo();
1258 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1259 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1261 ScDDComboBoxButton
aButton( this ); // for optimal size
1262 Size aBtnSize
= aButton
.GetSizePixel();
1264 SCCOL nCol
= rButtonPos
.Col();
1265 SCROW nRow
= rButtonPos
.Row();
1267 long nCellSizeX
; // width of this cell, including merged
1269 pViewData
->GetMergeSizePixel( nCol
, nRow
, nCellSizeX
, nDummy
);
1271 // for height, only the cell's row is used, excluding merged cells
1272 long nCellSizeY
= ScViewData::ToPixel( pDoc
->GetRowHeight( nRow
, nTab
), pViewData
->GetPPTY() );
1273 long nAvailable
= nCellSizeX
;
1275 // left edge of next cell if there is a non-hidden next column
1276 SCCOL nNextCol
= nCol
+ 1;
1277 const ScMergeAttr
* pMerge
= static_cast<const ScMergeAttr
*>(pDoc
->GetAttr( nCol
,nRow
,nTab
, ATTR_MERGE
));
1278 if ( pMerge
->GetColMerge() > 1 )
1279 nNextCol
= nCol
+ pMerge
->GetColMerge(); // next cell after the merged area
1280 while ( nNextCol
<= MAXCOL
&& pDoc
->ColHidden(nNextCol
, nTab
) )
1282 bool bNextCell
= ( nNextCol
<= MAXCOL
);
1284 nAvailable
= ScViewData::ToPixel( pDoc
->GetColWidth( nNextCol
, nTab
), pViewData
->GetPPTX() );
1286 if ( nAvailable
< aBtnSize
.Width() )
1287 aBtnSize
.Width() = nAvailable
;
1288 if ( nCellSizeY
< aBtnSize
.Height() )
1289 aBtnSize
.Height() = nCellSizeY
;
1291 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
, true );
1292 aPos
.X() += nCellSizeX
* nLayoutSign
; // start of next cell
1294 aPos
.X() -= aBtnSize
.Width() * nLayoutSign
; // right edge of cell if next cell not available
1295 aPos
.Y() += nCellSizeY
- aBtnSize
.Height();
1296 // X remains at the left edge
1299 aPos
.X() -= aBtnSize
.Width()-1; // align right edge of button with cell border
1301 return Rectangle( aPos
, aBtnSize
);
1304 bool ScGridWindow::IsAutoFilterActive( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1306 ScDocument
* pDoc
= pViewData
->GetDocument();
1307 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1308 ScQueryParam aQueryParam
;
1311 pDBData
->GetQueryParam( aQueryParam
);
1314 OSL_FAIL("Auto-Filter-Button ohne DBData");
1317 bool bSimpleQuery
= true;
1318 bool bColumnFound
= false;
1321 if ( !aQueryParam
.bInplace
)
1322 bSimpleQuery
= false;
1324 // aQueryParam kann nur MAXQUERY Eintraege enthalten
1326 SCSIZE nCount
= aQueryParam
.GetEntryCount();
1327 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1328 if ( aQueryParam
.GetEntry(nQuery
).bDoQuery
)
1330 if (aQueryParam
.GetEntry(nQuery
).nField
== nCol
)
1331 bColumnFound
= true;
1334 if (aQueryParam
.GetEntry(nQuery
).eConnect
!= SC_AND
)
1335 bSimpleQuery
= false;
1338 return ( bSimpleQuery
&& bColumnFound
);
1341 void ScGridWindow::GetSelectionRects( ::std::vector
< Rectangle
>& rPixelRects
)
1343 ScMarkData
aMultiMark( pViewData
->GetMarkData() );
1344 aMultiMark
.SetMarking( false );
1345 aMultiMark
.MarkToMulti();
1346 ScDocument
* pDoc
= pViewData
->GetDocument();
1347 SCTAB nTab
= pViewData
->GetTabNo();
1349 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1350 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1351 if ( !aMultiMark
.IsMultiMarked() )
1353 ScRange aMultiRange
;
1354 aMultiMark
.GetMultiMarkArea( aMultiRange
);
1355 SCCOL nX1
= aMultiRange
.aStart
.Col();
1356 SCROW nY1
= aMultiRange
.aStart
.Row();
1357 SCCOL nX2
= aMultiRange
.aEnd
.Col();
1358 SCROW nY2
= aMultiRange
.aEnd
.Row();
1360 PutInOrder( nX1
, nX2
);
1361 PutInOrder( nY1
, nY2
);
1363 bool bTestMerge
= true;
1364 bool bRepeat
= true;
1366 SCCOL nTestX2
= nX2
;
1367 SCROW nTestY2
= nY2
;
1369 pDoc
->ExtendMerge( nX1
,nY1
, nTestX2
,nTestY2
, nTab
);
1371 SCCOL nPosX
= pViewData
->GetPosX( eHWhich
);
1372 SCROW nPosY
= pViewData
->GetPosY( eVWhich
);
1373 if (nTestX2
< nPosX
|| nTestY2
< nPosY
)
1374 return; // unsichtbar
1375 SCCOL nRealX1
= nX1
;
1381 SCCOL nXRight
= nPosX
+ pViewData
->VisibleCellsX(eHWhich
);
1382 if (nXRight
> MAXCOL
) nXRight
= MAXCOL
;
1383 SCROW nYBottom
= nPosY
+ pViewData
->VisibleCellsY(eVWhich
);
1384 if (nYBottom
> MAXROW
) nYBottom
= MAXROW
;
1386 if (nX1
> nXRight
|| nY1
> nYBottom
)
1387 return; // unsichtbar
1388 if (nX2
> nXRight
) nX2
= nXRight
;
1389 if (nY2
> nYBottom
) nY2
= nYBottom
;
1391 double nPPTX
= pViewData
->GetPPTX();
1392 double nPPTY
= pViewData
->GetPPTY();
1394 ScInvertMerger
aInvert( &rPixelRects
);
1396 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
1397 long nScrY
= aScrPos
.Y();
1398 bool bWasHidden
= false;
1399 for (SCROW nY
=nY1
; nY
<=nY2
; nY
++)
1401 bool bFirstRow
= ( nY
== nPosY
); // first visible row?
1402 bool bDoHidden
= false; // versteckte nachholen ?
1403 sal_uInt16 nHeightTwips
= pDoc
->GetRowHeight( nY
,nTab
);
1404 bool bDoRow
= ( nHeightTwips
!= 0 );
1408 if (bWasHidden
) // auf versteckte zusammengefasste testen
1421 bDoRow
= true; // letzte Zeile aus Block
1426 SCCOL nLoopEndX
= nX2
;
1427 if (nX2
< nX1
) // Rest von zusammengefasst
1429 SCCOL nStartX
= nX1
;
1430 while ( ((const ScMergeFlagAttr
*)pDoc
->
1431 GetAttr(nStartX
,nY
,nTab
,ATTR_MERGE_FLAG
))->IsHorOverlapped() )
1437 long nEndY
= nScrY
+ ScViewData::ToPixel( nHeightTwips
, nPPTY
) - 1;
1438 long nScrX
= aScrPos
.X();
1439 for (SCCOL nX
=nX1
; nX
<=nLoopEndX
; nX
++)
1441 long nWidth
= ScViewData::ToPixel( pDoc
->GetColWidth( nX
,nTab
), nPPTX
);
1444 long nEndX
= nScrX
+ ( nWidth
- 1 ) * nLayoutSign
;
1448 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1449 const ScMergeFlagAttr
* pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->
1450 GetItem(ATTR_MERGE_FLAG
);
1451 if ( pMergeFlag
->IsVerOverlapped() && ( bDoHidden
|| bFirstRow
) )
1453 while ( pMergeFlag
->IsVerOverlapped() && nThisY
> 0 &&
1454 (pDoc
->RowHidden(nThisY
-1, nTab
) || bFirstRow
) )
1457 pPattern
= pDoc
->GetPattern( nX
, nThisY
, nTab
);
1458 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1462 // nur Rest von zusammengefasster zu sehen ?
1464 if ( pMergeFlag
->IsHorOverlapped() && nX
== nPosX
&& nX
> nRealX1
)
1466 while ( pMergeFlag
->IsHorOverlapped() )
1469 pPattern
= pDoc
->GetPattern( nThisX
, nThisY
, nTab
);
1470 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1474 if ( aMultiMark
.IsCellMarked( nThisX
, nThisY
, true ) == bRepeat
)
1476 if ( !pMergeFlag
->IsOverlapped() )
1478 ScMergeAttr
* pMerge
= (ScMergeAttr
*)&pPattern
->GetItem(ATTR_MERGE
);
1479 if (pMerge
->GetColMerge() > 0 || pMerge
->GetRowMerge() > 0)
1481 Point aEndPos
= pViewData
->GetScrPos(
1482 nThisX
+ pMerge
->GetColMerge(),
1483 nThisY
+ pMerge
->GetRowMerge(), eWhich
);
1484 if ( aEndPos
.X() * nLayoutSign
> nScrX
* nLayoutSign
&& aEndPos
.Y() > nScrY
)
1486 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,
1487 aEndPos
.X()-nLayoutSign
,aEndPos
.Y()-1 ) );
1490 else if ( nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1492 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1499 if ( aMultiMark
.IsCellMarked( nX
, nY
, true ) == bRepeat
&&
1500 nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1502 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1506 nScrX
= nEndX
+ nLayoutSign
;
1514 void ScGridWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
1516 Window::DataChanged(rDCEvt
);
1518 if ( (rDCEvt
.GetType() == DATACHANGED_PRINTER
) ||
1519 (rDCEvt
.GetType() == DATACHANGED_DISPLAY
) ||
1520 (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
1521 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
1522 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1523 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
1525 if ( rDCEvt
.GetType() == DATACHANGED_FONTS
&& eWhich
== pViewData
->GetActivePart() )
1526 pViewData
->GetDocShell()->UpdateFontList();
1528 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1529 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
1531 if ( eWhich
== pViewData
->GetActivePart() ) // only once for the view
1533 ScTabView
* pView
= pViewData
->GetView();
1535 // update scale in case the UI ScreenZoom has changed
1536 ScGlobal::UpdatePPT(this);
1539 // RepeatResize in case scroll bar sizes have changed
1540 pView
->RepeatResize();
1541 pView
->UpdateAllOverlays();
1543 // invalidate cell attribs in input handler, in case the
1544 // EditEngine BackgroundColor has to be changed
1545 if ( pViewData
->IsActive() )
1547 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1549 pHdl
->ForgetLastPattern();
1558 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */