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>
31 #include <svx/svdview.hxx>
32 #include "tabvwsh.hxx"
34 #include "gridwin.hxx"
35 #include "viewdata.hxx"
37 #include "document.hxx"
39 #include "patattr.hxx" // InvertSimple
41 #include "docoptio.hxx"
42 #include "notemark.hxx"
43 #include "dbfunc.hxx" // oder GetPageBreakData an die ViewData
45 #include "inputhdl.hxx"
46 #include "rfindlst.hxx"
47 #include "hiranges.hxx"
48 #include "pagedata.hxx"
49 #include "docpool.hxx"
50 #include "globstr.hrc"
51 #include "docsh.hxx" // oder GetSfxInPlaceObject
52 #include "cbutton.hxx"
53 #include "invmerge.hxx"
54 #include "editutil.hxx"
55 #include "inputopt.hxx"
56 #include "fillinfo.hxx"
57 #include "dpcontrol.hxx"
58 #include "queryparam.hxx"
59 #include "queryentry.hxx"
60 #include "markdata.hxx"
62 #include <vcl/virdev.hxx>
65 #include <svx/sdrpaintwindow.hxx>
67 //------------------------------------------------------------------------
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( OutputDevice
* pDev
, const Rectangle
& rInnerPixel
,
80 const String
& rTitle
, const Color
& rColor
, sal_Bool bTextBelow
,
81 double nPPTX
, double nPPTY
, const Fraction
& rZoomY
,
82 ScDocument
* pDoc
, ScViewData
* pButtonViewData
, sal_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 ((const ScPatternAttr
&)pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
)).
108 GetFont(aAttrFont
,SC_AUTOCOL_BLACK
,pDev
,&rZoomY
);
110 // everything else from application font
111 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((Window
*)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 sal_Bool bWasClip
= false;
149 sal_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( 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 sal_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
, sal_True
);
219 Point aEndPos
= pViewData
->GetScrPos(
220 aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
, sal_True
);
222 aStartPos
.X() -= nLayoutSign
;
224 aEndPos
.X() -= nLayoutSign
;
227 sal_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 //------------------------------------------------------------------------
256 static void lcl_DrawHighlight( ScOutputData
& rOutputData
, ScViewData
* pViewData
,
257 const std::vector
<ScHighlightEntry
>& rHighlightRanges
)
259 SCTAB nTab
= pViewData
->GetTabNo();
260 std::vector
<ScHighlightEntry
>::const_iterator pIter
;
261 for ( pIter
= rHighlightRanges
.begin(); pIter
!= rHighlightRanges
.end(); ++pIter
)
263 ScRange aRange
= pIter
->aRef
;
264 if ( nTab
>= aRange
.aStart
.Tab() && nTab
<= aRange
.aEnd
.Tab() )
266 rOutputData
.DrawRefMark(
267 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
268 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
269 pIter
->aColor
, false );
274 //------------------------------------------------------------------------
276 void ScGridWindow::DoInvertRect( const Rectangle
& rPixel
)
278 if ( rPixel
== aInvertRect
)
279 aInvertRect
= Rectangle(); // aufheben
282 OSL_ENSURE( aInvertRect
.IsEmpty(), "DoInvertRect nicht paarig" );
284 aInvertRect
= rPixel
; // neues Rechteck merken
287 UpdateHeaderOverlay(); // uses aInvertRect
290 //------------------------------------------------------------------------
292 void ScGridWindow::PrePaint()
294 // forward PrePaint to DrawingLayer
295 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
299 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
303 pDrawView
->PrePaint();
308 //------------------------------------------------------------------------
310 void ScGridWindow::Paint( const Rectangle
& rRect
)
312 ScDocument
* pDoc
= pViewData
->GetDocument();
313 if ( pDoc
->IsInInterpreter() )
315 // via Reschedule, interpretierende Zellen nicht nochmal anstossen
316 // hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe
317 // (Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt.
321 //! Rechtecke zusammenfassen?
322 aRepaintPixel
= Rectangle(); // mehrfach -> alles painten
326 bNeedsRepaint
= true;
327 aRepaintPixel
= LogicToPixel(rRect
); // nur betroffenen Bereich
332 // #i117893# If GetSizePixel needs to call the resize handler, the resulting nested Paint call
333 // (possibly for a larger rectangle) has to be allowed. Call GetSizePixel before setting bIsInPaint.
341 Rectangle aPixRect
= LogicToPixel( rRect
);
343 SCCOL nX1
= pViewData
->GetPosX(eHWhich
);
344 SCROW nY1
= pViewData
->GetPosY(eVWhich
);
346 SCTAB nTab
= pViewData
->GetTabNo();
348 double nPPTX
= pViewData
->GetPPTX();
349 double nPPTY
= pViewData
->GetPPTY();
351 Rectangle aMirroredPixel
= aPixRect
;
352 if ( pDoc
->IsLayoutRTL( nTab
) )
355 long nWidth
= GetSizePixel().Width();
356 aMirroredPixel
.Left() = nWidth
- 1 - aPixRect
.Right();
357 aMirroredPixel
.Right() = nWidth
- 1 - aPixRect
.Left();
360 long nScrX
= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
361 while ( nScrX
<= aMirroredPixel
.Left() && nX1
< MAXCOL
)
364 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
367 while ( nScrX
<= aMirroredPixel
.Right() && nX2
< MAXCOL
)
370 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX2
, nTab
), nPPTX
);
374 ScViewData::AddPixelsWhile( nScrY
, aPixRect
.Top(), nY1
, MAXROW
, nPPTY
, pDoc
, nTab
);
376 if (nScrY
<= aPixRect
.Bottom() && nY2
< MAXROW
)
379 ScViewData::AddPixelsWhile( nScrY
, aPixRect
.Bottom(), nY2
, MAXROW
, nPPTY
, pDoc
, nTab
);
382 Draw( nX1
,nY1
,nX2
,nY2
, SC_UPDATE_MARKS
); // nicht weiterzeichnen
388 // Draw ----------------------------------------------------------------
391 void ScGridWindow::Draw( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, ScUpdateMode eMode
)
393 ScModule
* pScMod
= SC_MOD();
394 sal_Bool bTextWysiwyg
= pScMod
->GetInputOptions().GetTextWysiwyg();
396 if (pViewData
->IsMinimized())
399 PutInOrder( nX1
, nX2
);
400 PutInOrder( nY1
, nY2
);
402 OSL_ENSURE( ValidCol(nX2
) && ValidRow(nY2
), "GridWin Draw Bereich zu gross" );
404 UpdateVisibleRange();
406 if (nX2
< maVisibleRange
.mnCol1
|| nY2
< maVisibleRange
.mnRow1
)
409 if (nX1
< maVisibleRange
.mnCol1
)
410 nX1
= maVisibleRange
.mnCol1
;
411 if (nY1
< maVisibleRange
.mnRow1
)
412 nY1
= maVisibleRange
.mnRow1
;
414 if (nX1
> maVisibleRange
.mnCol2
|| nY1
> maVisibleRange
.mnRow2
)
417 if (nX2
> maVisibleRange
.mnCol2
)
418 nX2
= maVisibleRange
.mnCol2
;
419 if (nY2
> maVisibleRange
.mnRow2
)
420 nY2
= maVisibleRange
.mnRow2
;
422 if ( eMode
!= SC_UPDATE_MARKS
&& nX2
< maVisibleRange
.mnCol2
)
423 nX2
= maVisibleRange
.mnCol2
; // zum Weiterzeichnen
425 // ab hier kein return mehr
427 ++nPaintCount
; // merken, dass gemalt wird (wichtig beim Invertieren)
429 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
430 ScDocument
* pDoc
= pDocSh
->GetDocument();
431 SCTAB nTab
= pViewData
->GetTabNo();
433 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
435 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
436 long nMirrorWidth
= GetSizePixel().Width();
437 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
438 long nLayoutSign
= bLayoutRTL
? -1 : 1;
441 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, maVisibleRange
.mnRow1
, eWhich
).X();
442 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
443 aScrPos
.X() = nEndPixel
+ 1;
446 long nScrX
= aScrPos
.X();
447 long nScrY
= aScrPos
.Y();
449 SCCOL nCurX
= pViewData
->GetCurX();
450 SCROW nCurY
= pViewData
->GetCurY();
451 SCCOL nCurEndX
= nCurX
;
452 SCROW nCurEndY
= nCurY
;
453 pDoc
->ExtendMerge( nCurX
, nCurY
, nCurEndX
, nCurEndY
, nTab
);
454 sal_Bool bCurVis
= nCursorHideCount
==0 &&
455 ( nCurEndX
+1 >= nX1
&& nCurX
<= nX2
+1 && nCurEndY
+1 >= nY1
&& nCurY
<= nY2
+1 );
458 if ( !bCurVis
&& nCursorHideCount
==0 && bAutoMarkVisible
&& aAutoMarkPos
.Tab() == nTab
&&
459 ( aAutoMarkPos
.Col() != nCurX
|| aAutoMarkPos
.Row() != nCurY
) )
461 SCCOL nHdlX
= aAutoMarkPos
.Col();
462 SCROW nHdlY
= aAutoMarkPos
.Row();
463 pDoc
->ExtendMerge( nHdlX
, nHdlY
, nHdlX
, nHdlY
, nTab
);
464 bCurVis
= ( nHdlX
+1 >= nX1
&& nHdlX
<= nX2
&& nHdlY
+1 >= nY1
&& nHdlY
<= nY2
);
465 // links und oben ist nicht betroffen
467 //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
470 double nPPTX
= pViewData
->GetPPTX();
471 double nPPTY
= pViewData
->GetPPTY();
473 const ScViewOptions
& rOpts
= pViewData
->GetOptions();
474 sal_Bool bFormulaMode
= rOpts
.GetOption( VOPT_FORMULAS
);
475 sal_Bool bMarkClipped
= rOpts
.GetOption( VOPT_CLIPMARKS
);
479 ScTableInfo aTabInfo
;
480 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
,
481 nPPTX
, nPPTY
, false, bFormulaMode
,
482 &pViewData
->GetMarkData() );
484 //--------------------------------------------------------------------
486 Fraction aZoomX
= pViewData
->GetZoomX();
487 Fraction aZoomY
= pViewData
->GetZoomY();
488 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
489 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
492 aOutputData
.SetMirrorWidth( nMirrorWidth
); // needed for RTL
494 std::auto_ptr
< VirtualDevice
> xFmtVirtDev
;
495 sal_Bool bLogicText
= bTextWysiwyg
; // call DrawStrings in logic MapMode?
499 // use printer for text formatting
501 OutputDevice
* pFmtDev
= pDoc
->GetPrinter();
502 pFmtDev
->SetMapMode( pViewData
->GetLogicMode(eWhich
) );
503 aOutputData
.SetFmtDevice( pFmtDev
);
505 else if ( aZoomX
!= aZoomY
&& pViewData
->IsOle() )
507 // #i45033# For OLE inplace editing with different zoom factors,
508 // use a virtual device with 1/100th mm as text formatting reference
510 xFmtVirtDev
.reset( new VirtualDevice
);
511 xFmtVirtDev
->SetMapMode( MAP_100TH_MM
);
512 aOutputData
.SetFmtDevice( xFmtVirtDev
.get() );
514 bLogicText
= sal_True
; // use logic MapMode
517 const svtools::ColorConfig
& rColorCfg
= pScMod
->GetColorConfig();
518 Color
aGridColor( rColorCfg
.GetColorValue( svtools::CALCGRID
, false ).nColor
);
519 if ( aGridColor
.GetColor() == COL_TRANSPARENT
)
521 // use view options' grid color only if color config has "automatic" color
522 aGridColor
= rOpts
.GetGridColor();
525 aOutputData
.SetSyntaxMode ( pViewData
->IsSyntaxMode() );
526 aOutputData
.SetGridColor ( aGridColor
);
527 aOutputData
.SetShowNullValues ( rOpts
.GetOption( VOPT_NULLVALS
) );
528 aOutputData
.SetShowFormulas ( bFormulaMode
);
529 aOutputData
.SetShowSpellErrors ( pDoc
->GetDocOptions().IsAutoSpell() );
530 aOutputData
.SetMarkClipped ( bMarkClipped
);
532 aOutputData
.SetUseStyleColor( true ); // always set in table view
534 aOutputData
.SetEditObject( GetEditObject() );
535 aOutputData
.SetViewShell( pViewData
->GetViewShell() );
537 sal_Bool bGrid
= rOpts
.GetOption( VOPT_GRID
) && pViewData
->GetShowGrid();
538 sal_Bool bGridFirst
= !rOpts
.GetOption( VOPT_GRID_ONTOP
);
540 sal_Bool bPage
= rOpts
.GetOption( VOPT_PAGEBREAKS
);
542 if ( eMode
== SC_UPDATE_CHANGED
)
544 aOutputData
.FindChanged();
545 aOutputData
.SetSingleGrid(sal_True
);
548 sal_Bool bPageMode
= pViewData
->IsPagebreakMode();
549 if (bPageMode
) // nach FindChanged
551 // SetPagebreakMode initialisiert auch bPrinted Flags
552 aOutputData
.SetPagebreakMode( pViewData
->GetView()->GetPageBreakData() );
555 EditView
* pEditView
= NULL
;
556 sal_Bool bEditMode
= pViewData
->HasEditView(eWhich
);
557 if ( bEditMode
&& pViewData
->GetRefTabNo() == nTab
)
561 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
562 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
563 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
565 if ( nEditEndCol
>= nX1
&& nEditCol
<= nX2
&& nEditEndRow
>= nY1
&& nEditRow
<= nY2
)
566 aOutputData
.SetEditCell( nEditCol
, nEditRow
);
571 // define drawing layer map mode and paint rectangle
572 const MapMode aDrawMode
= GetDrawMapMode();
573 Rectangle aDrawingRectLogic
;
576 // get drawing pixel rect
577 Rectangle
aDrawingRectPixel(Point(nScrX
, nScrY
), Size(aOutputData
.GetScrW(), aOutputData
.GetScrH()));
579 // correct for border (left/right)
584 aDrawingRectPixel
.Left() = 0L;
588 aDrawingRectPixel
.Right() = GetOutputSizePixel().getWidth();
592 // correct for border (bottom)
595 aDrawingRectPixel
.Bottom() = GetOutputSizePixel().getHeight();
598 // get logic positions
599 aDrawingRectLogic
= PixelToLogic(aDrawingRectPixel
, aDrawMode
);
602 OutputDevice
* pContentDev
= this; // device for document content, used by overlay manager
603 SdrPaintWindow
* pTargetPaintWindow
= 0; // #i74769# work with SdrPaintWindow directly
607 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
611 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
612 pContentDev
->SetMapMode(aDrawMode
);
613 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
617 // #i74769# Use new BeginDrawLayers() interface
618 Region
aDrawingRegion(aDrawingRectLogic
);
619 pTargetPaintWindow
= pDrawView
->BeginDrawLayers(this, aDrawingRegion
);
620 OSL_ENSURE(pTargetPaintWindow
, "BeginDrawLayers: Got no SdrPaintWindow (!)");
622 // #i74769# get target device from SdrPaintWindow, this may be the prerender
624 pContentDev
= &(pTargetPaintWindow
->GetTargetOutputDevice());
625 aOutputData
.SetContentDevice( pContentDev
);
628 pContentDev
->SetMapMode(aCurrentMapMode
);
632 // Rand (Wiese) (Pixel)
633 if ( nX2
==MAXCOL
|| nY2
==MAXROW
)
635 // save MapMode and set to pixel
636 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
637 pContentDev
->SetMapMode(MAP_PIXEL
);
639 Rectangle aPixRect
= Rectangle( Point(), GetOutputSizePixel() );
640 pContentDev
->SetFillColor( rColorCfg
.GetColorValue(svtools::APPBACKGROUND
).nColor
);
641 pContentDev
->SetLineColor();
644 Rectangle
aDrawRect( aPixRect
);
646 aDrawRect
.Right() = nScrX
- 1;
648 aDrawRect
.Left() = nScrX
+ aOutputData
.GetScrW();
649 if (aDrawRect
.Right() >= aDrawRect
.Left())
650 pContentDev
->DrawRect( aDrawRect
);
654 Rectangle
aDrawRect( aPixRect
);
655 aDrawRect
.Top() = nScrY
+ aOutputData
.GetScrH();
658 // no double painting of the corner
660 aDrawRect
.Left() = nScrX
;
662 aDrawRect
.Right() = nScrX
+ aOutputData
.GetScrW() - 1;
664 if (aDrawRect
.Bottom() >= aDrawRect
.Top())
665 pContentDev
->DrawRect( aDrawRect
);
669 pContentDev
->SetMapMode(aCurrentMapMode
);
672 if ( pDoc
->HasBackgroundDraw( nTab
, aDrawingRectLogic
) )
674 pContentDev
->SetMapMode(MAP_PIXEL
);
675 aOutputData
.DrawClear();
677 // Drawing Hintergrund
679 pContentDev
->SetMapMode(aDrawMode
);
680 DrawRedraw( aOutputData
, eMode
, SC_LAYER_BACK
);
683 aOutputData
.SetSolidBackground(sal_True
);
685 pContentDev
->SetMapMode(MAP_PIXEL
);
686 aOutputData
.DrawDocumentBackground();
688 if ( bGridFirst
&& ( bGrid
|| bPage
) )
689 aOutputData
.DrawGrid( bGrid
, bPage
);
691 aOutputData
.DrawBackground();
693 if ( !bGridFirst
&& ( bGrid
|| bPage
) )
694 aOutputData
.DrawGrid( bGrid
, bPage
);
698 // DrawPagePreview draws complete lines/page numbers, must always be clipped
699 if ( aOutputData
.SetChangedClip() )
701 DrawPagePreview(nX1
,nY1
,nX2
,nY2
, pContentDev
);
702 pContentDev
->SetClipRegion();
706 aOutputData
.DrawShadow();
707 aOutputData
.DrawFrame();
709 aOutputData
.DrawStrings(false); // in pixel MapMode
711 // edit cells and printer-metrics text must be before the buttons
712 // (DataPilot buttons contain labels in UI font)
714 pContentDev
->SetMapMode(pViewData
->GetLogicMode(eWhich
));
716 aOutputData
.DrawStrings(sal_True
); // in logic MapMode if bTextWysiwyg is set
717 aOutputData
.DrawEdit(sal_True
);
718 pContentDev
->SetMapMode(MAP_PIXEL
);
720 // Autofilter- und Pivot-Buttons
722 DrawButtons( nX1
, nX2
, aTabInfo
, pContentDev
); // Pixel
726 if ( rOpts
.GetOption( VOPT_NOTES
) )
727 aOutputData
.DrawNoteMarks();
729 aOutputData
.DrawClipMarks();
731 // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
733 //! Test, ob ChangeTrack-Anzeige aktiv ist
734 //! Szenario-Rahmen per View-Optionen abschaltbar?
736 SCTAB nTabCount
= pDoc
->GetTableCount();
737 const std::vector
<ScHighlightEntry
> &rHigh
= pViewData
->GetView()->GetHighlightRanges();
738 sal_Bool bHasScenario
= ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) );
739 sal_Bool bHasChange
= ( pDoc
->GetChangeTrack() != NULL
);
741 if ( bHasChange
|| bHasScenario
|| !rHigh
.empty() )
744 //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
746 sal_Bool bAny
= sal_True
;
747 if (eMode
== SC_UPDATE_CHANGED
)
748 bAny
= aOutputData
.SetChangedClip();
752 aOutputData
.DrawChangeTrack();
755 lcl_DrawScenarioFrames( pContentDev
, pViewData
, eWhich
, nX1
,nY1
,nX2
,nY2
);
757 lcl_DrawHighlight( aOutputData
, pViewData
, rHigh
);
759 if (eMode
== SC_UPDATE_CHANGED
)
760 pContentDev
->SetClipRegion();
764 // Drawing Vordergrund
766 pContentDev
->SetMapMode(aDrawMode
);
768 DrawRedraw( aOutputData
, eMode
, SC_LAYER_FRONT
);
769 DrawRedraw( aOutputData
, eMode
, SC_LAYER_INTERN
);
770 DrawSdrGrid( aDrawingRectLogic
, pContentDev
);
772 if (!bIsInScroll
) // Drawing Markierungen
774 if(eMode
== SC_UPDATE_CHANGED
&& aOutputData
.SetChangedClip())
776 pContentDev
->SetClipRegion();
780 pContentDev
->SetMapMode(MAP_PIXEL
);
782 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() )
784 Color
aRefColor( rColorCfg
.GetColorValue(svtools::CALCREFERENCE
).nColor
);
785 aOutputData
.DrawRefMark( pViewData
->GetRefStartX(), pViewData
->GetRefStartY(),
786 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(),
792 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
795 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
796 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
797 pRangeFinder
->GetDocName() == pDocSh
->GetTitle() )
799 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
800 for (sal_uInt16 i
=0; i
<nCount
; i
++)
802 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
804 ScRange aRef
= pData
->aRef
;
806 if ( aRef
.aStart
.Tab() >= nTab
&& aRef
.aEnd
.Tab() <= nTab
)
807 aOutputData
.DrawRefMark( aRef
.aStart
.Col(), aRef
.aStart
.Row(),
808 aRef
.aEnd
.Col(), aRef
.aEnd
.Row(),
809 Color( ScRangeFindList::GetColorName( i
) ),
817 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
821 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
822 pContentDev
->SetMapMode(aDrawMode
);
823 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
827 // #i74769# work with SdrPaintWindow directly
828 pDrawView
->EndDrawLayers(*pTargetPaintWindow
, true);
831 pContentDev
->SetMapMode(aCurrentMapMode
);
836 // moved after EndDrawLayers() to get it outside the overlay buffer and
837 // on top of everything
838 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
840 //! use pContentDev for EditView?
841 SetMapMode(MAP_PIXEL
);
842 SCCOL nCol1
= pViewData
->GetEditStartCol();
843 SCROW nRow1
= pViewData
->GetEditStartRow();
844 SCCOL nCol2
= pViewData
->GetEditEndCol();
845 SCROW nRow2
= pViewData
->GetEditEndRow();
847 SetFillColor( pEditView
->GetBackgroundColor() );
848 Point aStart
= pViewData
->GetScrPos( nCol1
, nRow1
, eWhich
);
849 Point aEnd
= pViewData
->GetScrPos( nCol2
+1, nRow2
+1, eWhich
);
850 aEnd
.X() -= 2 * nLayoutSign
; // don't overwrite grid
852 DrawRect( Rectangle( aStart
,aEnd
) );
854 SetMapMode(pViewData
->GetLogicMode());
855 pEditView
->Paint( PixelToLogic( Rectangle( Point( nScrX
, nScrY
),
856 Size( aOutputData
.GetScrW(), aOutputData
.GetScrH() ) ) ) );
857 SetMapMode(MAP_PIXEL
);
860 if (pViewData
->HasEditView(eWhich
))
862 // flush OverlayManager before changing the MapMode
863 flushOverlayManager();
865 // set MapMode for text edit
866 SetMapMode(pViewData
->GetLogicMode());
869 SetMapMode(aDrawMode
);
872 pNoteMarker
->Draw(); // ueber den Cursor, im Drawing-MapMode
875 // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
876 // ist das jetzt durcheinandergekommen und es muss neu gemalt werden
879 OSL_ENSURE(nPaintCount
, "nPaintCount falsch");
884 // Flag drawn formula cells "unchanged".
885 pDoc
->ResetChanged(ScRange(nX1
,nY1
,nTab
,nX2
,nY2
,nTab
));
888 void ScGridWindow::CheckNeedsRepaint()
890 // called at the end of painting, and from timer after background text width calculation
894 bNeedsRepaint
= false;
895 if (aRepaintPixel
.IsEmpty())
898 Invalidate(PixelToLogic(aRepaintPixel
));
899 aRepaintPixel
= Rectangle();
901 // selection function in status bar might also be invalid
902 SfxBindings
& rBindings
= pViewData
->GetBindings();
903 rBindings
.Invalidate( SID_STATUS_SUM
);
904 rBindings
.Invalidate( SID_ATTR_SIZE
);
905 rBindings
.Invalidate( SID_TABLE_CELL
);
909 void ScGridWindow::DrawPagePreview( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, OutputDevice
* pContentDev
)
911 ScPageBreakData
* pPageData
= pViewData
->GetView()->GetPageBreakData();
914 ScDocument
* pDoc
= pViewData
->GetDocument();
915 SCTAB nTab
= pViewData
->GetTabNo();
916 Size aWinSize
= GetOutputSizePixel();
917 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
918 Color
aManual( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
919 Color
aAutomatic( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAK
).nColor
);
921 String aPageStr
= ScGlobal::GetRscString( STR_PGNUM
);
922 if ( nPageScript
== 0 )
924 // get script type of translated "Page" string only once
925 nPageScript
= pDoc
->GetStringScriptType( aPageStr
);
926 if (nPageScript
== 0)
927 nPageScript
= ScGlobal::GetDefaultScriptType();
931 ScEditEngineDefaulter
* pEditEng
= NULL
;
932 const ScPatternAttr
& rDefPattern
= ((const ScPatternAttr
&)pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
));
933 if ( nPageScript
== SCRIPTTYPE_LATIN
)
935 // use single font and call DrawText directly
936 rDefPattern
.GetFont( aFont
, SC_AUTOCOL_BLACK
);
937 aFont
.SetColor( Color( COL_LIGHTGRAY
) );
938 // font size is set as needed
942 // use EditEngine to draw mixed-script string
943 pEditEng
= new ScEditEngineDefaulter( EditEngine::CreatePool(), sal_True
);
944 pEditEng
->SetRefMapMode( pContentDev
->GetMapMode() );
945 SfxItemSet
* pEditDefaults
= new SfxItemSet( pEditEng
->GetEmptyItemSet() );
946 rDefPattern
.FillEditItemSet( pEditDefaults
);
947 pEditDefaults
->Put( SvxColorItem( Color( COL_LIGHTGRAY
), EE_CHAR_COLOR
) );
948 pEditEng
->SetDefaults( pEditDefaults
);
951 sal_uInt16 nCount
= sal::static_int_cast
<sal_uInt16
>( pPageData
->GetCount() );
952 for (sal_uInt16 nPos
=0; nPos
<nCount
; nPos
++)
954 ScPrintRangeData
& rData
= pPageData
->GetData(nPos
);
955 ScRange aRange
= rData
.GetPrintRange();
956 if ( aRange
.aStart
.Col() <= nX2
+1 && aRange
.aEnd
.Col()+1 >= nX1
&&
957 aRange
.aStart
.Row() <= nY2
+1 && aRange
.aEnd
.Row()+1 >= nY1
)
959 // 3 Pixel Rahmen um den Druckbereich
960 // (mittlerer Pixel auf den Gitterlinien)
962 pContentDev
->SetLineColor();
963 if (rData
.IsAutomatic())
964 pContentDev
->SetFillColor( aAutomatic
);
966 pContentDev
->SetFillColor( aManual
);
968 Point aStart
= pViewData
->GetScrPos(
969 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, sal_True
);
970 Point aEnd
= pViewData
->GetScrPos(
971 aRange
.aEnd
.Col() + 1, aRange
.aEnd
.Row() + 1, eWhich
, sal_True
);
975 // Ueberlaeufe verhindern:
976 if ( aStart
.X() < -10 ) aStart
.X() = -10;
977 if ( aStart
.Y() < -10 ) aStart
.Y() = -10;
978 if ( aEnd
.X() > aWinSize
.Width() + 10 )
979 aEnd
.X() = aWinSize
.Width() + 10;
980 if ( aEnd
.Y() > aWinSize
.Height() + 10 )
981 aEnd
.Y() = aWinSize
.Height() + 10;
983 pContentDev
->DrawRect( Rectangle( aStart
, Point(aEnd
.X(),aStart
.Y()+2) ) );
984 pContentDev
->DrawRect( Rectangle( aStart
, Point(aStart
.X()+2,aEnd
.Y()) ) );
985 pContentDev
->DrawRect( Rectangle( Point(aStart
.X(),aEnd
.Y()-2), aEnd
) );
986 pContentDev
->DrawRect( Rectangle( Point(aEnd
.X()-2,aStart
.Y()), aEnd
) );
989 //! anders darstellen (gestrichelt ????)
991 size_t nColBreaks
= rData
.GetPagesX();
992 const SCCOL
* pColEnd
= rData
.GetPageEndX();
994 for (nColPos
=0; nColPos
+1<nColBreaks
; nColPos
++)
996 SCCOL nBreak
= pColEnd
[nColPos
]+1;
997 if ( nBreak
>= nX1
&& nBreak
<= nX2
+1 )
1000 if (pDoc
->HasColBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1001 pContentDev
->SetFillColor( aManual
);
1003 pContentDev
->SetFillColor( aAutomatic
);
1004 Point aBreak
= pViewData
->GetScrPos(
1005 nBreak
, aRange
.aStart
.Row(), eWhich
, sal_True
);
1006 pContentDev
->DrawRect( Rectangle( aBreak
.X()-1, aStart
.Y(), aBreak
.X(), aEnd
.Y() ) );
1010 size_t nRowBreaks
= rData
.GetPagesY();
1011 const SCROW
* pRowEnd
= rData
.GetPageEndY();
1013 for (nRowPos
=0; nRowPos
+1<nRowBreaks
; nRowPos
++)
1015 SCROW nBreak
= pRowEnd
[nRowPos
]+1;
1016 if ( nBreak
>= nY1
&& nBreak
<= nY2
+1 )
1019 if (pDoc
->HasRowBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1020 pContentDev
->SetFillColor( aManual
);
1022 pContentDev
->SetFillColor( aAutomatic
);
1023 Point aBreak
= pViewData
->GetScrPos(
1024 aRange
.aStart
.Col(), nBreak
, eWhich
, sal_True
);
1025 pContentDev
->DrawRect( Rectangle( aStart
.X(), aBreak
.Y()-1, aEnd
.X(), aBreak
.Y() ) );
1031 SCROW nPrStartY
= aRange
.aStart
.Row();
1032 for (nRowPos
=0; nRowPos
<nRowBreaks
; nRowPos
++)
1034 SCROW nPrEndY
= pRowEnd
[nRowPos
];
1035 if ( nPrEndY
>= nY1
&& nPrStartY
<= nY2
)
1037 SCCOL nPrStartX
= aRange
.aStart
.Col();
1038 for (nColPos
=0; nColPos
<nColBreaks
; nColPos
++)
1040 SCCOL nPrEndX
= pColEnd
[nColPos
];
1041 if ( nPrEndX
>= nX1
&& nPrStartX
<= nX2
)
1043 Point aPageStart
= pViewData
->GetScrPos(
1044 nPrStartX
, nPrStartY
, eWhich
, sal_True
);
1045 Point aPageEnd
= pViewData
->GetScrPos(
1046 nPrEndX
+1,nPrEndY
+1, eWhich
, sal_True
);
1048 long nPageNo
= rData
.GetFirstPage();
1049 if ( rData
.IsTopDown() )
1050 nPageNo
+= ((long)nColPos
)*nRowBreaks
+nRowPos
;
1052 nPageNo
+= ((long)nRowPos
)*nColBreaks
+nColPos
;
1054 OUString aThisPageStr
= OUString(aPageStr
).replaceFirst("%1", OUString::number(nPageNo
));
1058 // find right font size with EditEngine
1060 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1061 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1062 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1063 pEditEng
->SetText( aThisPageStr
);
1064 Size
aSize100( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1066 // 40% of width or 60% of height
1067 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1068 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1069 nHeight
= std::min(nSizeX
,nSizeY
);
1070 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1071 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1072 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1074 // centered output with EditEngine
1075 Size
aTextSize( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1076 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1077 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1078 pEditEng
->Draw( pContentDev
, aPos
);
1082 // find right font size for DrawText
1083 aFont
.SetSize( Size( 0,100 ) );
1084 pContentDev
->SetFont( aFont
);
1085 Size
aSize100( pContentDev
->GetTextWidth( aThisPageStr
), pContentDev
->GetTextHeight() );
1087 // 40% of width or 60% of height
1088 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1089 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1090 aFont
.SetSize( Size( 0,std::min(nSizeX
,nSizeY
) ) );
1091 pContentDev
->SetFont( aFont
);
1093 // centered output with DrawText
1094 Size
aTextSize( pContentDev
->GetTextWidth( aThisPageStr
), pContentDev
->GetTextHeight() );
1095 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1096 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1097 pContentDev
->DrawText( aPos
, aThisPageStr
);
1100 nPrStartX
= nPrEndX
+ 1;
1103 nPrStartY
= nPrEndY
+ 1;
1112 void ScGridWindow::DrawButtons( SCCOL nX1
, SCCOL nX2
, ScTableInfo
& rTabInfo
, OutputDevice
* pContentDev
)
1114 aComboButton
.SetOutputDevice( pContentDev
);
1116 ScDocument
* pDoc
= pViewData
->GetDocument();
1117 ScDPFieldButton
aCellBtn(pContentDev
, &GetSettings().GetStyleSettings(), &pViewData
->GetZoomX(), &pViewData
->GetZoomY(), pDoc
);
1123 SCTAB nTab
= pViewData
->GetTabNo();
1124 ScDBData
* pDBData
= NULL
;
1125 ScQueryParam
* pQueryParam
= NULL
;
1127 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
1128 sal_uInt16 nArrCount
= rTabInfo
.mnArrCount
;
1130 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1132 Point aOldPos
= aComboButton
.GetPosPixel(); // Zustand fuer MouseDown/Up
1133 Size aOldSize
= aComboButton
.GetSizePixel(); // merken
1135 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1137 if ( pRowInfo
[nArrY
].bAutoFilter
&& pRowInfo
[nArrY
].bChanged
)
1139 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1141 nRow
= pThisRowInfo
->nRowNo
;
1144 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1146 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1147 //if several columns merged on a row, there should be only one auto button at the end of the columns.
1148 //if several rows merged on a column, the button may be in the middle, so "!pInfo->bVOverlapped" should not be used
1149 if ( pInfo
->bAutoFilter
&& !pInfo
->bHOverlapped
)
1152 pQueryParam
= new ScQueryParam
;
1154 sal_Bool bNewData
= sal_True
;
1162 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1163 if ( nCol
>= nStartCol
&& nCol
<= nEndCol
&&
1164 nRow
>= nStartRow
&& nRow
<= nEndRow
)
1169 pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1171 pDBData
->GetQueryParam( *pQueryParam
);
1174 // can also be part of DataPilot table
1175 // OSL_FAIL("Auto-Filter-Button ohne DBData");
1179 // pQueryParam kann nur MAXQUERY Eintraege enthalten
1181 sal_Bool bSimpleQuery
= sal_True
;
1182 sal_Bool bColumnFound
= false;
1183 if (!pQueryParam
->bInplace
)
1184 bSimpleQuery
= false;
1185 SCSIZE nCount
= pQueryParam
->GetEntryCount();
1186 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1187 if (pQueryParam
->GetEntry(nQuery
).bDoQuery
)
1189 // hier nicht auf EQUAL beschraenken
1190 // (auch bei ">1" soll der Spaltenkopf blau werden)
1192 if (pQueryParam
->GetEntry(nQuery
).nField
== nCol
)
1193 bColumnFound
= sal_True
;
1195 if (pQueryParam
->GetEntry(nQuery
).eConnect
!= SC_AND
)
1196 bSimpleQuery
= false;
1199 bool bArrowState
= bSimpleQuery
&& bColumnFound
;
1202 SCCOL nStartCol
= nCol
;
1203 SCROW nStartRow
= nRow
;
1204 //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.
1205 //should first get the start pos of the merge area, then get the nSizeX through the start pos.
1206 pDoc
->ExtendOverlapped(nStartCol
, nStartRow
,nCol
, nRow
, nTab
);//get nStartCol,nStartRow
1207 pViewData
->GetMergeSizePixel( nStartCol
, nStartRow
, nSizeX
, nSizeY
);//get nSizeX
1208 nSizeY
= pViewData
->ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
1209 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1211 aCellBtn
.setBoundingBox(aScrPos
, Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1212 aCellBtn
.setPopupLeft(bLayoutRTL
); // #i114944# AutoFilter button is left-aligned in RTL
1213 aCellBtn
.setDrawBaseButton(false);
1214 aCellBtn
.setDrawPopupButton(true);
1215 aCellBtn
.setHasHiddenMember(bArrowState
);
1221 if ( pRowInfo
[nArrY
].bPivotButton
&& pRowInfo
[nArrY
].bChanged
)
1223 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1224 nRow
= pThisRowInfo
->nRowNo
;
1225 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1227 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1228 if (pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
1231 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1234 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1235 long nPosX
= aScrPos
.X();
1236 long nPosY
= aScrPos
.Y();
1237 // bLayoutRTL is handled in setBoundingBox
1239 OUString aStr
= pDoc
->GetString(nCol
, nRow
, nTab
);
1240 aCellBtn
.setText(aStr
);
1241 aCellBtn
.setBoundingBox(Point(nPosX
, nPosY
), Size(nSizeX
-1, nSizeY
-1), bLayoutRTL
);
1242 aCellBtn
.setPopupLeft(false); // DataPilot popup is always right-aligned for now
1243 aCellBtn
.setDrawBaseButton(pInfo
->bPivotButton
);
1244 aCellBtn
.setDrawPopupButton(pInfo
->bPivotPopupButton
);
1245 aCellBtn
.setHasHiddenMember(pInfo
->bFilterActive
);
1250 if ( bListValButton
&& pRowInfo
[nArrY
].nRowNo
== aListValPos
.Row() && pRowInfo
[nArrY
].bChanged
)
1252 Rectangle aRect
= GetListValButtonRect( aListValPos
);
1253 aComboButton
.SetPosPixel( aRect
.TopLeft() );
1254 aComboButton
.SetSizePixel( aRect
.GetSize() );
1255 pContentDev
->SetClipRegion(Region(aRect
));
1256 aComboButton
.Draw( false, false );
1257 pContentDev
->SetClipRegion(); // always called from Draw() without clip region
1258 aComboButton
.SetPosPixel( aOldPos
); // restore old state
1259 aComboButton
.SetSizePixel( aOldSize
); // for MouseUp/Down (AutoFilter)
1264 aComboButton
.SetOutputDevice( this );
1267 Rectangle
ScGridWindow::GetListValButtonRect( const ScAddress
& rButtonPos
)
1269 ScDocument
* pDoc
= pViewData
->GetDocument();
1270 SCTAB nTab
= pViewData
->GetTabNo();
1271 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1272 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1274 ScDDComboBoxButton
aButton( this ); // for optimal size
1275 Size aBtnSize
= aButton
.GetSizePixel();
1277 SCCOL nCol
= rButtonPos
.Col();
1278 SCROW nRow
= rButtonPos
.Row();
1280 long nCellSizeX
; // width of this cell, including merged
1282 pViewData
->GetMergeSizePixel( nCol
, nRow
, nCellSizeX
, nDummy
);
1284 // for height, only the cell's row is used, excluding merged cells
1285 long nCellSizeY
= ScViewData::ToPixel( pDoc
->GetRowHeight( nRow
, nTab
), pViewData
->GetPPTY() );
1286 long nAvailable
= nCellSizeX
;
1288 // left edge of next cell if there is a non-hidden next column
1289 SCCOL nNextCol
= nCol
+ 1;
1290 const ScMergeAttr
* pMerge
= static_cast<const ScMergeAttr
*>(pDoc
->GetAttr( nCol
,nRow
,nTab
, ATTR_MERGE
));
1291 if ( pMerge
->GetColMerge() > 1 )
1292 nNextCol
= nCol
+ pMerge
->GetColMerge(); // next cell after the merged area
1293 while ( nNextCol
<= MAXCOL
&& pDoc
->ColHidden(nNextCol
, nTab
) )
1295 sal_Bool bNextCell
= ( nNextCol
<= MAXCOL
);
1297 nAvailable
= ScViewData::ToPixel( pDoc
->GetColWidth( nNextCol
, nTab
), pViewData
->GetPPTX() );
1299 if ( nAvailable
< aBtnSize
.Width() )
1300 aBtnSize
.Width() = nAvailable
;
1301 if ( nCellSizeY
< aBtnSize
.Height() )
1302 aBtnSize
.Height() = nCellSizeY
;
1304 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
, sal_True
);
1305 aPos
.X() += nCellSizeX
* nLayoutSign
; // start of next cell
1307 aPos
.X() -= aBtnSize
.Width() * nLayoutSign
; // right edge of cell if next cell not available
1308 aPos
.Y() += nCellSizeY
- aBtnSize
.Height();
1309 // X remains at the left edge
1312 aPos
.X() -= aBtnSize
.Width()-1; // align right edge of button with cell border
1314 return Rectangle( aPos
, aBtnSize
);
1317 bool ScGridWindow::IsAutoFilterActive( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1319 ScDocument
* pDoc
= pViewData
->GetDocument();
1320 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1321 ScQueryParam aQueryParam
;
1324 pDBData
->GetQueryParam( aQueryParam
);
1327 OSL_FAIL("Auto-Filter-Button ohne DBData");
1330 bool bSimpleQuery
= true;
1331 bool bColumnFound
= false;
1334 if ( !aQueryParam
.bInplace
)
1335 bSimpleQuery
= false;
1337 // aQueryParam kann nur MAXQUERY Eintraege enthalten
1339 SCSIZE nCount
= aQueryParam
.GetEntryCount();
1340 for (nQuery
= 0; nQuery
< nCount
&& bSimpleQuery
; ++nQuery
)
1341 if ( aQueryParam
.GetEntry(nQuery
).bDoQuery
)
1343 if (aQueryParam
.GetEntry(nQuery
).nField
== nCol
)
1344 bColumnFound
= sal_True
;
1347 if (aQueryParam
.GetEntry(nQuery
).eConnect
!= SC_AND
)
1348 bSimpleQuery
= false;
1351 return ( bSimpleQuery
&& bColumnFound
);
1354 void ScGridWindow::GetSelectionRects( ::std::vector
< Rectangle
>& rPixelRects
)
1356 ScMarkData
aMultiMark( pViewData
->GetMarkData() );
1357 aMultiMark
.SetMarking( false );
1358 aMultiMark
.MarkToMulti();
1360 ScDocument
* pDoc
= pViewData
->GetDocument();
1361 SCTAB nTab
= pViewData
->GetTabNo();
1363 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1364 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1366 if ( !aMultiMark
.IsMultiMarked() )
1369 ScRange aMultiRange
;
1370 aMultiMark
.GetMultiMarkArea( aMultiRange
);
1371 SCCOL nX1
= aMultiRange
.aStart
.Col();
1372 SCROW nY1
= aMultiRange
.aStart
.Row();
1373 SCCOL nX2
= aMultiRange
.aEnd
.Col();
1374 SCROW nY2
= aMultiRange
.aEnd
.Row();
1376 PutInOrder( nX1
, nX2
);
1377 PutInOrder( nY1
, nY2
);
1379 sal_Bool bTestMerge
= sal_True
;
1380 bool bRepeat
= true;
1382 SCCOL nTestX2
= nX2
;
1383 SCROW nTestY2
= nY2
;
1385 pDoc
->ExtendMerge( nX1
,nY1
, nTestX2
,nTestY2
, nTab
);
1387 SCCOL nPosX
= pViewData
->GetPosX( eHWhich
);
1388 SCROW nPosY
= pViewData
->GetPosY( eVWhich
);
1389 if (nTestX2
< nPosX
|| nTestY2
< nPosY
)
1390 return; // unsichtbar
1391 SCCOL nRealX1
= nX1
;
1397 SCCOL nXRight
= nPosX
+ pViewData
->VisibleCellsX(eHWhich
);
1398 if (nXRight
> MAXCOL
) nXRight
= MAXCOL
;
1399 SCROW nYBottom
= nPosY
+ pViewData
->VisibleCellsY(eVWhich
);
1400 if (nYBottom
> MAXROW
) nYBottom
= MAXROW
;
1402 if (nX1
> nXRight
|| nY1
> nYBottom
)
1403 return; // unsichtbar
1404 if (nX2
> nXRight
) nX2
= nXRight
;
1405 if (nY2
> nYBottom
) nY2
= nYBottom
;
1407 double nPPTX
= pViewData
->GetPPTX();
1408 double nPPTY
= pViewData
->GetPPTY();
1410 ScInvertMerger
aInvert( &rPixelRects
);
1412 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
1413 long nScrY
= aScrPos
.Y();
1414 sal_Bool bWasHidden
= false;
1415 for (SCROW nY
=nY1
; nY
<=nY2
; nY
++)
1417 sal_Bool bFirstRow
= ( nY
== nPosY
); // first visible row?
1418 sal_Bool bDoHidden
= false; // versteckte nachholen ?
1419 sal_uInt16 nHeightTwips
= pDoc
->GetRowHeight( nY
,nTab
);
1420 sal_Bool bDoRow
= ( nHeightTwips
!= 0 );
1424 if (bWasHidden
) // auf versteckte zusammengefasste testen
1426 bDoHidden
= sal_True
;
1434 bWasHidden
= sal_True
;
1437 bDoRow
= sal_True
; // letzte Zeile aus Block
1442 SCCOL nLoopEndX
= nX2
;
1443 if (nX2
< nX1
) // Rest von zusammengefasst
1445 SCCOL nStartX
= nX1
;
1446 while ( ((const ScMergeFlagAttr
*)pDoc
->
1447 GetAttr(nStartX
,nY
,nTab
,ATTR_MERGE_FLAG
))->IsHorOverlapped() )
1453 long nEndY
= nScrY
+ ScViewData::ToPixel( nHeightTwips
, nPPTY
) - 1;
1454 long nScrX
= aScrPos
.X();
1455 for (SCCOL nX
=nX1
; nX
<=nLoopEndX
; nX
++)
1457 long nWidth
= ScViewData::ToPixel( pDoc
->GetColWidth( nX
,nTab
), nPPTX
);
1460 long nEndX
= nScrX
+ ( nWidth
- 1 ) * nLayoutSign
;
1464 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1465 const ScMergeFlagAttr
* pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->
1466 GetItem(ATTR_MERGE_FLAG
);
1467 if ( pMergeFlag
->IsVerOverlapped() && ( bDoHidden
|| bFirstRow
) )
1469 while ( pMergeFlag
->IsVerOverlapped() && nThisY
> 0 &&
1470 (pDoc
->RowHidden(nThisY
-1, nTab
) || bFirstRow
) )
1473 pPattern
= pDoc
->GetPattern( nX
, nThisY
, nTab
);
1474 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1478 // nur Rest von zusammengefasster zu sehen ?
1480 if ( pMergeFlag
->IsHorOverlapped() && nX
== nPosX
&& nX
> nRealX1
)
1482 while ( pMergeFlag
->IsHorOverlapped() )
1485 pPattern
= pDoc
->GetPattern( nThisX
, nThisY
, nTab
);
1486 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1490 if ( aMultiMark
.IsCellMarked( nThisX
, nThisY
, sal_True
) == bRepeat
)
1492 if ( !pMergeFlag
->IsOverlapped() )
1494 ScMergeAttr
* pMerge
= (ScMergeAttr
*)&pPattern
->GetItem(ATTR_MERGE
);
1495 if (pMerge
->GetColMerge() > 0 || pMerge
->GetRowMerge() > 0)
1497 Point aEndPos
= pViewData
->GetScrPos(
1498 nThisX
+ pMerge
->GetColMerge(),
1499 nThisY
+ pMerge
->GetRowMerge(), eWhich
);
1500 if ( aEndPos
.X() * nLayoutSign
> nScrX
* nLayoutSign
&& aEndPos
.Y() > nScrY
)
1502 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,
1503 aEndPos
.X()-nLayoutSign
,aEndPos
.Y()-1 ) );
1506 else if ( nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1508 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1515 if ( aMultiMark
.IsCellMarked( nX
, nY
, sal_True
) == bRepeat
&&
1516 nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1518 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1522 nScrX
= nEndX
+ nLayoutSign
;
1530 // -------------------------------------------------------------------------
1532 void ScGridWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
1534 Window::DataChanged(rDCEvt
);
1536 if ( (rDCEvt
.GetType() == DATACHANGED_PRINTER
) ||
1537 (rDCEvt
.GetType() == DATACHANGED_DISPLAY
) ||
1538 (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
1539 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
1540 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1541 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
1543 if ( rDCEvt
.GetType() == DATACHANGED_FONTS
&& eWhich
== pViewData
->GetActivePart() )
1544 pViewData
->GetDocShell()->UpdateFontList();
1546 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1547 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
1549 if ( eWhich
== pViewData
->GetActivePart() ) // only once for the view
1551 ScTabView
* pView
= pViewData
->GetView();
1553 // update scale in case the UI ScreenZoom has changed
1554 ScGlobal::UpdatePPT(this);
1557 // RepeatResize in case scroll bar sizes have changed
1558 pView
->RepeatResize();
1559 pView
->UpdateAllOverlays();
1561 // invalidate cell attribs in input handler, in case the
1562 // EditEngine BackgroundColor has to be changed
1563 if ( pViewData
->IsActive() )
1565 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1567 pHdl
->ForgetLastPattern();
1576 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */