1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gridwin4.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
42 #include <svtools/colorcfg.hxx>
43 #include <svx/colritem.hxx>
44 #include <svx/editview.hxx>
45 #include <svx/fhgtitem.hxx>
46 #include <svx/scripttypeitem.hxx>
47 #include <sfx2/bindings.hxx>
48 #include <sfx2/printer.hxx>
50 #include <svx/svdview.hxx>
51 #include "tabvwsh.hxx"
53 #include "gridwin.hxx"
54 #include "viewdata.hxx"
56 #include "document.hxx"
58 #include "patattr.hxx" // InvertSimple
59 #include "dbcolect.hxx"
60 #include "docoptio.hxx"
61 #include "notemark.hxx"
62 #include "dbfunc.hxx" // oder GetPageBreakData an die ViewData
64 #include "inputhdl.hxx"
65 #include "rfindlst.hxx"
66 #include "hiranges.hxx"
67 #include "pagedata.hxx"
68 #include "docpool.hxx"
69 #include "globstr.hrc"
70 #include "docsh.hxx" // oder GetSfxInPlaceObject
71 #include "cbutton.hxx"
72 #include "invmerge.hxx"
73 #include "editutil.hxx"
74 #include "inputopt.hxx"
75 #include "fillinfo.hxx"
76 #include "dpcontrol.hxx"
77 #include "queryparam.hxx"
79 #include <vcl/virdev.hxx>
82 #include <svx/sdrpaintwindow.hxx>
84 //#include "tabvwsh.hxx" //! Test !!!!
86 //------------------------------------------------------------------------
88 void lcl_LimitRect( Rectangle
& rRect
, const Rectangle
& rVisible
)
90 if ( rRect
.Top() < rVisible
.Top()-1 ) rRect
.Top() = rVisible
.Top()-1;
91 // if ( rRect.Left() < rVisible.Left()-1 ) rRect.Left() = rVisible.Left()-1;
92 if ( rRect
.Bottom() > rVisible
.Bottom()+1 ) rRect
.Bottom() = rVisible
.Bottom()+1;
93 // if ( rRect.Right() > rVisible.Right()+1 ) rRect.Right() = rVisible.Right()+1;
95 // #51122# auch wenn das inner-Rectangle nicht sichtbar ist, muss evtl.
96 // die Titelzeile gezeichnet werden, darum kein Rueckgabewert mehr.
97 // Wenn's weit daneben liegt, wird lcl_DrawOneFrame erst gar nicht gerufen.
100 void lcl_DrawOneFrame( OutputDevice
* pDev
, const Rectangle
& rInnerPixel
,
101 const String
& rTitle
, const Color
& rColor
, BOOL bTextBelow
,
102 double nPPTX
, double nPPTY
, const Fraction
& rZoomY
,
103 ScDocument
* pDoc
, ScViewData
* pButtonViewData
, BOOL bLayoutRTL
)
105 // pButtonViewData wird nur benutzt, um die Button-Groesse zu setzen,
106 // darf ansonsten NULL sein!
108 Rectangle aInner
= rInnerPixel
;
111 aInner
.Left() = rInnerPixel
.Right();
112 aInner
.Right() = rInnerPixel
.Left();
115 Rectangle
aVisible( Point(0,0), pDev
->GetOutputSizePixel() );
116 lcl_LimitRect( aInner
, aVisible
);
118 Rectangle aOuter
= aInner
;
119 long nHor
= (long) ( SC_SCENARIO_HSPACE
* nPPTX
);
120 long nVer
= (long) ( SC_SCENARIO_VSPACE
* nPPTY
);
121 aOuter
.Left() -= nHor
;
122 aOuter
.Right() += nHor
;
123 aOuter
.Top() -= nVer
;
124 aOuter
.Bottom() += nVer
;
126 // use ScPatternAttr::GetFont only for font size
128 ((const ScPatternAttr
&)pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
)).
129 GetFont(aAttrFont
,SC_AUTOCOL_BLACK
,pDev
,&rZoomY
);
131 // everything else from application font
132 Font aAppFont
= pDev
->GetSettings().GetStyleSettings().GetAppFont();
133 aAppFont
.SetSize( aAttrFont
.GetSize() );
135 aAppFont
.SetAlign( ALIGN_TOP
);
136 pDev
->SetFont( aAppFont
);
138 Size
aTextSize( pDev
->GetTextWidth( rTitle
), pDev
->GetTextHeight() );
141 aOuter
.Bottom() += aTextSize
.Height();
143 aOuter
.Top() -= aTextSize
.Height();
145 pDev
->SetLineColor();
146 pDev
->SetFillColor( rColor
);
147 // links, oben, rechts, unten
148 pDev
->DrawRect( Rectangle( aOuter
.Left(), aOuter
.Top(), aInner
.Left(), aOuter
.Bottom() ) );
149 pDev
->DrawRect( Rectangle( aOuter
.Left(), aOuter
.Top(), aOuter
.Right(), aInner
.Top() ) );
150 pDev
->DrawRect( Rectangle( aInner
.Right(), aOuter
.Top(), aOuter
.Right(), aOuter
.Bottom() ) );
151 pDev
->DrawRect( Rectangle( aOuter
.Left(), aInner
.Bottom(), aOuter
.Right(), aOuter
.Bottom() ) );
153 long nButtonY
= bTextBelow
? aInner
.Bottom() : aOuter
.Top();
155 ScDDComboBoxButton
aComboButton((Window
*)pDev
);
156 aComboButton
.SetOptSizePixel();
157 long nBWidth
= ( aComboButton
.GetSizePixel().Width() * rZoomY
.GetNumerator() )
158 / rZoomY
.GetDenominator();
159 long nBHeight
= nVer
+ aTextSize
.Height() + 1;
160 Size
aButSize( nBWidth
, nBHeight
);
161 long nButtonPos
= bLayoutRTL
? aOuter
.Left() : aOuter
.Right()-nBWidth
+1;
162 aComboButton
.Draw( Point(nButtonPos
, nButtonY
), aButSize
, FALSE
);
164 pButtonViewData
->SetScenButSize( aButSize
);
166 long nTextStart
= bLayoutRTL
? aInner
.Right() - aTextSize
.Width() + 1 : aInner
.Left();
168 BOOL bWasClip
= FALSE
;
170 BOOL bClip
= ( aTextSize
.Width() > aOuter
.Right() - nBWidth
- aInner
.Left() );
173 if (pDev
->IsClipRegion())
176 aOldClip
= pDev
->GetActiveClipRegion();
178 long nClipStartX
= bLayoutRTL
? aOuter
.Left() + nBWidth
: aInner
.Left();
179 long nClipEndX
= bLayoutRTL
? aInner
.Right() : aOuter
.Right() - nBWidth
;
180 pDev
->SetClipRegion( Rectangle( nClipStartX
, nButtonY
+ nVer
/2,
181 nClipEndX
, nButtonY
+ nVer
/2 + aTextSize
.Height() ) );
184 pDev
->DrawText( Point( nTextStart
, nButtonY
+ nVer
/2 ), rTitle
);
189 pDev
->SetClipRegion(aOldClip
);
191 pDev
->SetClipRegion();
194 pDev
->SetFillColor();
195 pDev
->SetLineColor( COL_BLACK
);
196 pDev
->DrawRect( aInner
);
197 pDev
->DrawRect( aOuter
);
200 void lcl_DrawScenarioFrames( OutputDevice
* pDev
, ScViewData
* pViewData
, ScSplitPos eWhich
,
201 SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
)
203 ScDocument
* pDoc
= pViewData
->GetDocument();
204 SCTAB nTab
= pViewData
->GetTabNo();
205 SCTAB nTabCount
= pDoc
->GetTableCount();
206 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
208 if ( nX1
> 0 ) --nX1
;
209 if ( nY1
>=2 ) nY1
-= 2; // Hack: Titelzeile beruehrt zwei Zellen
210 else if ( nY1
> 0 ) --nY1
;
211 if ( nX2
< MAXCOL
) ++nX2
;
212 if ( nY2
< MAXROW
-1 ) nY2
+= 2; // Hack: Titelzeile beruehrt zwei Zellen
213 else if ( nY2
< MAXROW
) ++nY2
;
214 ScRange
aViewRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
216 //! Ranges an der Table cachen!!!!
219 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
220 pDoc
->MarkScenario( i
, nTab
, aMarks
, FALSE
, SC_SCENARIO_SHOWFRAME
);
221 ScRangeListRef xRanges
= new ScRangeList
;
222 aMarks
.FillRangeListWithMarks( xRanges
, FALSE
);
224 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
225 long nLayoutSign
= bLayoutRTL
? -1 : 1;
227 USHORT nRangeCount
= (USHORT
)xRanges
->Count();
228 for (USHORT j
=0; j
<nRangeCount
; j
++)
230 ScRange aRange
= *xRanges
->GetObject(j
);
231 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
232 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
233 pDoc
->ExtendTotalMerge( aRange
);
235 //! -> Repaint beim Zusammenfassen erweitern !!!
237 if ( aRange
.Intersects( aViewRange
) ) //! Platz fuer Text/Button?
239 Point aStartPos
= pViewData
->GetScrPos(
240 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, TRUE
);
241 Point aEndPos
= pViewData
->GetScrPos(
242 aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
, TRUE
);
244 aStartPos
.X() -= nLayoutSign
;
246 aEndPos
.X() -= nLayoutSign
;
249 BOOL bTextBelow
= ( aRange
.aStart
.Row() == 0 );
252 Color
aColor( COL_LIGHTGRAY
);
253 for (SCTAB nAct
=nTab
+1; nAct
<nTabCount
&& pDoc
->IsScenario(nAct
); nAct
++)
254 if ( pDoc
->IsActiveScenario(nAct
) && pDoc
->HasScenarioRange(nAct
,aRange
) )
256 String aDummyComment
;
258 pDoc
->GetName( nAct
, aCurrent
);
259 pDoc
->GetScenarioData( nAct
, aDummyComment
, aColor
, nDummyFlags
);
263 aCurrent
= ScGlobal::GetRscString( STR_EMPTYDATA
);
265 //! eigener Text "(keins)" statt "(leer)" ???
267 lcl_DrawOneFrame( pDev
, Rectangle( aStartPos
, aEndPos
),
268 aCurrent
, aColor
, bTextBelow
,
269 pViewData
->GetPPTX(), pViewData
->GetPPTY(), pViewData
->GetZoomY(),
270 pDoc
, pViewData
, bLayoutRTL
);
276 //------------------------------------------------------------------------
278 void lcl_DrawHighlight( ScOutputData
& rOutputData
, ScViewData
* pViewData
,
279 ScHighlightRanges
& rHighlightRanges
)
281 SCTAB nTab
= pViewData
->GetTabNo();
282 ULONG nCount
= rHighlightRanges
.Count();
283 for (ULONG i
=0; i
<nCount
; i
++)
285 ScHighlightEntry
* pEntry
= rHighlightRanges
.GetObject( i
);
288 ScRange aRange
= pEntry
->aRef
;
289 if ( nTab
>= aRange
.aStart
.Tab() && nTab
<= aRange
.aEnd
.Tab() )
291 rOutputData
.DrawRefMark(
292 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
293 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
294 pEntry
->aColor
, FALSE
);
300 //------------------------------------------------------------------------
302 void ScGridWindow::DoInvertRect( const Rectangle
& rPixel
)
304 // Invert( PixelToLogic(rPixel) );
306 if ( rPixel
== aInvertRect
)
307 aInvertRect
= Rectangle(); // aufheben
310 DBG_ASSERT( aInvertRect
.IsEmpty(), "DoInvertRect nicht paarig" );
312 aInvertRect
= rPixel
; // neues Rechteck merken
315 UpdateHeaderOverlay(); // uses aInvertRect
318 //------------------------------------------------------------------------
320 void __EXPORT
ScGridWindow::PrePaint()
322 // forward PrePaint to DrawingLayer
323 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
327 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
331 pDrawView
->PrePaint();
336 //------------------------------------------------------------------------
338 void __EXPORT
ScGridWindow::Paint( const Rectangle
& rRect
)
340 //TODO/LATER: how to get environment? Do we need that?!
342 ScDocShell* pDocSh = pViewData->GetDocShell();
343 SvInPlaceEnvironment* pEnv = pDocSh->GetIPEnv();
344 if (pEnv && pEnv->GetRectsChangedLockCount())
350 ScDocument
* pDoc
= pViewData
->GetDocument();
351 if ( pDoc
->IsInInterpreter() )
353 // via Reschedule, interpretierende Zellen nicht nochmal anstossen
354 // hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe
355 // (Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt.
359 //! Rechtecke zusammenfassen?
360 aRepaintPixel
= Rectangle(); // mehrfach -> alles painten
364 bNeedsRepaint
= TRUE
;
365 aRepaintPixel
= LogicToPixel(rRect
); // nur betroffenen Bereich
375 Rectangle aPixRect
= LogicToPixel( rRect
);
377 SCCOL nX1
= pViewData
->GetPosX(eHWhich
);
378 SCROW nY1
= pViewData
->GetPosY(eVWhich
);
380 SCTAB nTab
= pViewData
->GetTabNo();
382 double nPPTX
= pViewData
->GetPPTX();
383 double nPPTY
= pViewData
->GetPPTY();
385 Rectangle aMirroredPixel
= aPixRect
;
386 if ( pDoc
->IsLayoutRTL( nTab
) )
389 long nWidth
= GetSizePixel().Width();
390 aMirroredPixel
.Left() = nWidth
- 1 - aPixRect
.Right();
391 aMirroredPixel
.Right() = nWidth
- 1 - aPixRect
.Left();
394 long nScrX
= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
395 while ( nScrX
<= aMirroredPixel
.Left() && nX1
< MAXCOL
)
398 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX1
, nTab
), nPPTX
);
401 while ( nScrX
<= aMirroredPixel
.Right() && nX2
< MAXCOL
)
404 nScrX
+= ScViewData::ToPixel( pDoc
->GetColWidth( nX2
, nTab
), nPPTX
);
407 long nScrY
= ScViewData::ToPixel( pDoc
->GetRowHeight( nY1
, nTab
), nPPTY
);
408 while ( nScrY
<= aPixRect
.Top() && nY1
< MAXROW
)
411 nScrY
+= ScViewData::ToPixel( pDoc
->GetRowHeight( nY1
, nTab
), nPPTY
);
414 while ( nScrY
<= aPixRect
.Bottom() && nY2
< MAXROW
)
417 nScrY
+= ScViewData::ToPixel( pDoc
->GetRowHeight( nY2
, nTab
), nPPTY
);
420 Draw( nX1
,nY1
,nX2
,nY2
, SC_UPDATE_MARKS
); // nicht weiterzeichnen
426 // Draw ----------------------------------------------------------------
429 void ScGridWindow::Draw( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, ScUpdateMode eMode
)
431 ScModule
* pScMod
= SC_MOD();
432 BOOL bTextWysiwyg
= pScMod
->GetInputOptions().GetTextWysiwyg();
433 BOOL bGridFirst
= TRUE
; //! entscheiden!!!
435 if (pViewData
->IsMinimized())
438 PutInOrder( nX1
, nX2
);
439 PutInOrder( nY1
, nY2
);
441 DBG_ASSERT( ValidCol(nX2
) && ValidRow(nY2
), "GridWin Draw Bereich zu gross" );
443 SCCOL nPosX
= pViewData
->GetPosX( eHWhich
);
444 SCROW nPosY
= pViewData
->GetPosY( eVWhich
);
445 if (nX2
< nPosX
|| nY2
< nPosY
)
446 return; // unsichtbar
447 if (nX1
< nPosX
) nX1
= nPosX
;
448 if (nY1
< nPosY
) nY1
= nPosY
;
450 SCCOL nXRight
= nPosX
+ pViewData
->VisibleCellsX(eHWhich
);
451 if (nXRight
> MAXCOL
) nXRight
= MAXCOL
;
452 SCROW nYBottom
= nPosY
+ pViewData
->VisibleCellsY(eVWhich
);
453 if (nYBottom
> MAXROW
) nYBottom
= MAXROW
;
455 // Store the current visible range.
456 maVisibleRange
.mnCol1
= nPosX
;
457 maVisibleRange
.mnCol2
= nXRight
;
458 maVisibleRange
.mnRow1
= nPosY
;
459 maVisibleRange
.mnRow2
= nYBottom
;
461 if (nX1
> nXRight
|| nY1
> nYBottom
)
462 return; // unsichtbar
463 if (nX2
> nXRight
) nX2
= nXRight
;
464 if (nY2
> nYBottom
) nY2
= nYBottom
;
466 if ( eMode
!= SC_UPDATE_MARKS
)
468 nX2
= nXRight
; // zum Weiterzeichnen
470 // ab hier kein return mehr
472 ++nPaintCount
; // merken, dass gemalt wird (wichtig beim Invertieren)
474 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
475 ScDocument
* pDoc
= pDocSh
->GetDocument();
476 SCTAB nTab
= pViewData
->GetTabNo();
478 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
480 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
481 long nMirrorWidth
= GetSizePixel().Width();
482 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
483 long nLayoutSign
= bLayoutRTL
? -1 : 1;
486 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
487 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
488 aScrPos
.X() = nEndPixel
+ 1;
491 long nScrX
= aScrPos
.X();
492 long nScrY
= aScrPos
.Y();
494 SCCOL nCurX
= pViewData
->GetCurX();
495 SCROW nCurY
= pViewData
->GetCurY();
496 SCCOL nCurEndX
= nCurX
;
497 SCROW nCurEndY
= nCurY
;
498 pDoc
->ExtendMerge( nCurX
, nCurY
, nCurEndX
, nCurEndY
, nTab
);
499 BOOL bCurVis
= nCursorHideCount
==0 &&
500 ( nCurEndX
+1 >= nX1
&& nCurX
<= nX2
+1 && nCurEndY
+1 >= nY1
&& nCurY
<= nY2
+1 );
503 if ( !bCurVis
&& nCursorHideCount
==0 && bAutoMarkVisible
&& aAutoMarkPos
.Tab() == nTab
&&
504 ( aAutoMarkPos
.Col() != nCurX
|| aAutoMarkPos
.Row() != nCurY
) )
506 SCCOL nHdlX
= aAutoMarkPos
.Col();
507 SCROW nHdlY
= aAutoMarkPos
.Row();
508 pDoc
->ExtendMerge( nHdlX
, nHdlY
, nHdlX
, nHdlY
, nTab
);
509 bCurVis
= ( nHdlX
+1 >= nX1
&& nHdlX
<= nX2
&& nHdlY
+1 >= nY1
&& nHdlY
<= nY2
);
510 // links und oben ist nicht betroffen
512 //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
515 double nPPTX
= pViewData
->GetPPTX();
516 double nPPTY
= pViewData
->GetPPTY();
518 const ScViewOptions
& rOpts
= pViewData
->GetOptions();
519 BOOL bFormulaMode
= rOpts
.GetOption( VOPT_FORMULAS
);
520 BOOL bMarkClipped
= rOpts
.GetOption( VOPT_CLIPMARKS
);
524 ScTableInfo aTabInfo
;
525 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
,
526 nPPTX
, nPPTY
, FALSE
, bFormulaMode
,
527 &pViewData
->GetMarkData() );
529 //--------------------------------------------------------------------
531 Fraction aZoomX
= pViewData
->GetZoomX();
532 Fraction aZoomY
= pViewData
->GetZoomY();
533 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
534 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
537 aOutputData
.SetMirrorWidth( nMirrorWidth
); // needed for RTL
539 std::auto_ptr
< VirtualDevice
> xFmtVirtDev
;
540 BOOL bLogicText
= bTextWysiwyg
; // call DrawStrings in logic MapMode?
544 // use printer for text formatting
546 OutputDevice
* pFmtDev
= pDoc
->GetPrinter();
547 pFmtDev
->SetMapMode( pViewData
->GetLogicMode(eWhich
) );
548 aOutputData
.SetFmtDevice( pFmtDev
);
550 else if ( aZoomX
!= aZoomY
&& pViewData
->IsOle() )
552 // #i45033# For OLE inplace editing with different zoom factors,
553 // use a virtual device with 1/100th mm as text formatting reference
555 xFmtVirtDev
.reset( new VirtualDevice
);
556 xFmtVirtDev
->SetMapMode( MAP_100TH_MM
);
557 aOutputData
.SetFmtDevice( xFmtVirtDev
.get() );
559 bLogicText
= TRUE
; // use logic MapMode
562 const svtools::ColorConfig
& rColorCfg
= pScMod
->GetColorConfig();
563 Color
aGridColor( rColorCfg
.GetColorValue( svtools::CALCGRID
, FALSE
).nColor
);
564 if ( aGridColor
.GetColor() == COL_TRANSPARENT
)
566 // use view options' grid color only if color config has "automatic" color
567 aGridColor
= rOpts
.GetGridColor();
570 aOutputData
.SetSyntaxMode ( pViewData
->IsSyntaxMode() );
571 aOutputData
.SetGridColor ( aGridColor
);
572 aOutputData
.SetShowNullValues ( rOpts
.GetOption( VOPT_NULLVALS
) );
573 aOutputData
.SetShowFormulas ( bFormulaMode
);
574 aOutputData
.SetShowSpellErrors ( pDoc
->GetDocOptions().IsAutoSpell() );
575 aOutputData
.SetMarkClipped ( bMarkClipped
);
577 aOutputData
.SetUseStyleColor( TRUE
); // always set in table view
579 aOutputData
.SetEditObject( GetEditObject() );
580 aOutputData
.SetViewShell( pViewData
->GetViewShell() );
582 BOOL bGrid
= rOpts
.GetOption( VOPT_GRID
) && pViewData
->GetShowGrid();
584 BOOL bPage
= rOpts
.GetOption( VOPT_PAGEBREAKS
);
586 if ( eMode
== SC_UPDATE_CHANGED
)
588 aOutputData
.FindChanged();
589 aOutputData
.SetSingleGrid(TRUE
);
592 BOOL bPageMode
= pViewData
->IsPagebreakMode();
593 if (bPageMode
) // nach FindChanged
595 // SetPagebreakMode initialisiert auch bPrinted Flags
596 aOutputData
.SetPagebreakMode( pViewData
->GetView()->GetPageBreakData() );
599 EditView
* pEditView
= NULL
;
600 BOOL bEditMode
= pViewData
->HasEditView(eWhich
);
601 if ( bEditMode
&& pViewData
->GetRefTabNo() == nTab
)
605 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
606 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
607 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
609 if ( nEditEndCol
>= nX1
&& nEditCol
<= nX2
&& nEditEndRow
>= nY1
&& nEditRow
<= nY2
)
610 aOutputData
.SetEditCell( nEditCol
, nEditRow
);
614 // nur Edit-Area zu zeichnen?
615 //! dann muss trotzdem noch der Rand / das Gitter gemalt werden!
617 // if ( nEditCol <= nX1 && nEditEndCol >= nX2 && nEditRow <= nY1 && nEditEndRow >= nY2 )
621 // define drawing layer map mode and paint rectangle
622 const MapMode aDrawMode
= GetDrawMapMode();
623 Rectangle aDrawingRectLogic
;
626 // get drawing pixel rect
627 Rectangle
aDrawingRectPixel(Point(nScrX
, nScrY
), Size(aOutputData
.GetScrW(), aOutputData
.GetScrH()));
629 // correct for border (left/right)
634 aDrawingRectPixel
.Left() = 0L;
638 aDrawingRectPixel
.Right() = GetOutputSizePixel().getWidth();
642 // correct for border (bottom)
645 aDrawingRectPixel
.Bottom() = GetOutputSizePixel().getHeight();
648 // get logic positions
649 aDrawingRectLogic
= PixelToLogic(aDrawingRectPixel
, aDrawMode
);
652 // not necessary with overlay
656 OutputDevice
* pContentDev
= this; // device for document content, used by overlay manager
657 SdrPaintWindow
* pTargetPaintWindow
= 0; // #i74769# work with SdrPaintWindow directly
661 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
665 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
666 pContentDev
->SetMapMode(aDrawMode
);
667 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
671 // #i74769# Use new BeginDrawLayers() interface
672 Region
aDrawingRegion(aDrawingRectLogic
);
673 pTargetPaintWindow
= pDrawView
->BeginDrawLayers(this, aDrawingRegion
);
674 OSL_ENSURE(pTargetPaintWindow
, "BeginDrawLayers: Got no SdrPaintWindow (!)");
676 // #i74769# get target device from SdrPaintWindow, this may be the prerender
678 pContentDev
= &(pTargetPaintWindow
->GetTargetOutputDevice());
679 aOutputData
.SetContentDevice( pContentDev
);
682 pContentDev
->SetMapMode(aCurrentMapMode
);
686 // Rand (Wiese) (Pixel)
687 if ( nX2
==MAXCOL
|| nY2
==MAXROW
)
689 // save MapMode and set to pixel
690 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
691 pContentDev
->SetMapMode(MAP_PIXEL
);
693 Rectangle aPixRect
= Rectangle( Point(), GetOutputSizePixel() );
694 pContentDev
->SetFillColor( rColorCfg
.GetColorValue(svtools::APPBACKGROUND
).nColor
);
695 pContentDev
->SetLineColor();
698 Rectangle
aDrawRect( aPixRect
);
700 aDrawRect
.Right() = nScrX
- 1;
702 aDrawRect
.Left() = nScrX
+ aOutputData
.GetScrW();
703 if (aDrawRect
.Right() >= aDrawRect
.Left())
704 pContentDev
->DrawRect( aDrawRect
);
708 Rectangle
aDrawRect( aPixRect
);
709 aDrawRect
.Top() = nScrY
+ aOutputData
.GetScrH();
712 // no double painting of the corner
714 aDrawRect
.Left() = nScrX
;
716 aDrawRect
.Right() = nScrX
+ aOutputData
.GetScrW() - 1;
718 if (aDrawRect
.Bottom() >= aDrawRect
.Top())
719 pContentDev
->DrawRect( aDrawRect
);
723 pContentDev
->SetMapMode(aCurrentMapMode
);
726 if ( pDoc
->HasBackgroundDraw( nTab
, aDrawingRectLogic
) )
728 pContentDev
->SetMapMode(MAP_PIXEL
);
729 aOutputData
.DrawClear();
731 // Drawing Hintergrund
733 pContentDev
->SetMapMode(aDrawMode
);
734 DrawRedraw( aOutputData
, eMode
, SC_LAYER_BACK
);
737 aOutputData
.SetSolidBackground(TRUE
);
739 pContentDev
->SetMapMode(MAP_PIXEL
);
740 aOutputData
.DrawDocumentBackground();
741 if ( bGridFirst
&& ( bGrid
|| bPage
) )
742 aOutputData
.DrawGrid( bGrid
, bPage
);
743 aOutputData
.DrawBackground();
746 // #87655# DrawPagePreview draws complete lines/page numbers, must always be clipped
747 if ( aOutputData
.SetChangedClip() )
749 DrawPagePreview(nX1
,nY1
,nX2
,nY2
, pContentDev
);
750 pContentDev
->SetClipRegion();
753 aOutputData
.DrawShadow();
754 aOutputData
.DrawFrame();
756 aOutputData
.DrawStrings(FALSE
); // in pixel MapMode
758 // Autofilter- und Pivot-Buttons
760 DrawButtons( nX1
, nY1
, nX2
, nY2
, aTabInfo
, pContentDev
); // Pixel
764 if ( rOpts
.GetOption( VOPT_NOTES
) )
765 aOutputData
.DrawNoteMarks();
769 pContentDev
->SetMapMode(pViewData
->GetLogicMode(eWhich
));
771 aOutputData
.DrawStrings(TRUE
); // in logic MapMode if bTextWysiwyg is set
772 aOutputData
.DrawEdit(TRUE
);
774 pContentDev
->SetMapMode(MAP_PIXEL
);
775 if ( !bGridFirst
&& ( bGrid
|| bPage
) )
777 aOutputData
.DrawGrid( bGrid
, bPage
);
779 aOutputData
.DrawClipMarks();
781 // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
783 //! Test, ob ChangeTrack-Anzeige aktiv ist
784 //! Szenario-Rahmen per View-Optionen abschaltbar?
786 SCTAB nTabCount
= pDoc
->GetTableCount();
787 ScHighlightRanges
* pHigh
= pViewData
->GetView()->GetHighlightRanges();
788 BOOL bHasScenario
= ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) );
789 BOOL bHasChange
= ( pDoc
->GetChangeTrack() != NULL
);
791 if ( bHasChange
|| bHasScenario
|| pHigh
!= NULL
)
794 //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
797 if (eMode
== SC_UPDATE_CHANGED
)
798 bAny
= aOutputData
.SetChangedClip();
802 aOutputData
.DrawChangeTrack();
805 lcl_DrawScenarioFrames( pContentDev
, pViewData
, eWhich
, nX1
,nY1
,nX2
,nY2
);
808 lcl_DrawHighlight( aOutputData
, pViewData
, *pHigh
);
810 if (eMode
== SC_UPDATE_CHANGED
)
811 pContentDev
->SetClipRegion();
815 // Drawing Vordergrund
817 pContentDev
->SetMapMode(aDrawMode
);
819 DrawRedraw( aOutputData
, eMode
, SC_LAYER_FRONT
);
820 DrawRedraw( aOutputData
, eMode
, SC_LAYER_INTERN
);
821 DrawSdrGrid( aDrawingRectLogic
, pContentDev
);
823 if (!bIsInScroll
) // Drawing Markierungen
825 if(eMode
== SC_UPDATE_CHANGED
&& aOutputData
.SetChangedClip())
827 pContentDev
->SetClipRegion();
831 //if (eMode == SC_UPDATE_CHANGED)
832 // bDraw = NeedDrawMarks() && aOutputData.SetChangedClip();
836 // if (eMode == SC_UPDATE_CHANGED)
837 // pContentDev->SetClipRegion();
841 pContentDev
->SetMapMode(MAP_PIXEL
);
843 #ifdef OLD_SELECTION_PAINT
844 if (pViewData
->IsActive())
845 aOutputData
.DrawMark( this );
848 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() )
850 // The AutoFill shrink area has an own overlay now
852 // Schraffur beim Loeschen per AutoFill
853 if ( pViewData
->GetRefType() == SC_REFTYPE_FILL
)
856 if ( pViewData
->GetDelMark( aRange
) )
858 if ( aRange
.aStart
.Col() < nX1
) aRange
.aStart
.SetCol(nX1
);
859 if ( aRange
.aEnd
.Col() > nX2
) aRange
.aEnd
.SetCol(nX2
);
860 if ( aRange
.aStart
.Row() < nY1
) aRange
.aStart
.SetRow(nY1
);
861 if ( aRange
.aEnd
.Row() > nY2
) aRange
.aEnd
.SetRow(nY2
);
862 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
863 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
865 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
866 aRange
.aStart
.Row(), eWhich
);
867 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
868 aRange
.aEnd
.Row()+1, eWhich
);
872 // Markierung aufheben - roter Rahmen bleibt stehen
873 Rectangle
aRect( aStart
,aEnd
);
874 Invert( aRect
, INVERT_HIGHLIGHT
);
876 //! Delete-Bereich extra kennzeichnen?!?!?
882 Color
aRefColor( rColorCfg
.GetColorValue(svtools::CALCREFERENCE
).nColor
);
883 aOutputData
.DrawRefMark( pViewData
->GetRefStartX(), pViewData
->GetRefStartY(),
884 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(),
890 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
893 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
894 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
895 pRangeFinder
->GetDocName() == pDocSh
->GetTitle() )
897 USHORT nCount
= (USHORT
)pRangeFinder
->Count();
898 for (USHORT i
=0; i
<nCount
; i
++)
900 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
903 ScRange aRef
= pData
->aRef
;
905 if ( aRef
.aStart
.Tab() >= nTab
&& aRef
.aEnd
.Tab() <= nTab
)
906 aOutputData
.DrawRefMark( aRef
.aStart
.Col(), aRef
.aStart
.Row(),
907 aRef
.aEnd
.Col(), aRef
.aEnd
.Row(),
908 Color( ScRangeFindList::GetColorName( i
) ),
917 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
921 MapMode
aCurrentMapMode(pContentDev
->GetMapMode());
922 pContentDev
->SetMapMode(aDrawMode
);
923 SdrView
* pDrawView
= pTabViewShell
->GetSdrView();
927 // #i74769# work with SdrPaintWindow directly
928 pDrawView
->EndDrawLayers(*pTargetPaintWindow
, true);
931 pContentDev
->SetMapMode(aCurrentMapMode
);
936 // moved after EndDrawLayers() to get it outside the overlay buffer and
937 // on top of everything
938 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
940 //! use pContentDev for EditView?
941 SetMapMode(MAP_PIXEL
);
942 SCCOL nCol1
= pViewData
->GetEditStartCol();
943 SCROW nRow1
= pViewData
->GetEditStartRow();
944 SCCOL nCol2
= pViewData
->GetEditEndCol();
945 SCROW nRow2
= pViewData
->GetEditEndRow();
947 SetFillColor( pEditView
->GetBackgroundColor() );
948 Point aStart
= pViewData
->GetScrPos( nCol1
, nRow1
, eWhich
);
949 Point aEnd
= pViewData
->GetScrPos( nCol2
+1, nRow2
+1, eWhich
);
950 aEnd
.X() -= 2 * nLayoutSign
; // don't overwrite grid
952 DrawRect( Rectangle( aStart
,aEnd
) );
954 SetMapMode(pViewData
->GetLogicMode());
955 pEditView
->Paint( PixelToLogic( Rectangle( Point( nScrX
, nScrY
),
956 Size( aOutputData
.GetScrW(), aOutputData
.GetScrH() ) ) ) );
957 SetMapMode(MAP_PIXEL
);
960 if (pViewData
->HasEditView(eWhich
))
962 // flush OverlayManager before changing the MapMode
963 flushOverlayManager();
965 // set MapMode for text edit
966 SetMapMode(pViewData
->GetLogicMode());
969 SetMapMode(aDrawMode
);
972 pNoteMarker
->Draw(); // ueber den Cursor, im Drawing-MapMode
974 //DrawStartTimer(); // fuer bunte Handles ohne System-Clipping
977 // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
978 // ist das jetzt durcheinandergekommen und es muss neu gemalt werden
981 DBG_ASSERT(nPaintCount
, "nPaintCount falsch");
987 void ScGridWindow::CheckNeedsRepaint()
989 // called at the end of painting, and from timer after background text width calculation
993 bNeedsRepaint
= FALSE
;
994 if (aRepaintPixel
.IsEmpty())
997 Invalidate(PixelToLogic(aRepaintPixel
));
998 aRepaintPixel
= Rectangle();
1000 // selection function in status bar might also be invalid
1001 SfxBindings
& rBindings
= pViewData
->GetBindings();
1002 rBindings
.Invalidate( SID_STATUS_SUM
);
1003 rBindings
.Invalidate( SID_ATTR_SIZE
);
1004 rBindings
.Invalidate( SID_TABLE_CELL
);
1008 void ScGridWindow::DrawPagePreview( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
, OutputDevice
* pContentDev
)
1010 ScPageBreakData
* pPageData
= pViewData
->GetView()->GetPageBreakData();
1013 ScDocument
* pDoc
= pViewData
->GetDocument();
1014 SCTAB nTab
= pViewData
->GetTabNo();
1015 Size aWinSize
= GetOutputSizePixel();
1016 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
1017 Color
aManual( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
1018 Color
aAutomatic( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAK
).nColor
);
1020 String aPageText
= ScGlobal::GetRscString( STR_PAGE
);
1021 if ( nPageScript
== 0 )
1023 // get script type of translated "Page" string only once
1024 nPageScript
= pDoc
->GetStringScriptType( aPageText
);
1025 if (nPageScript
== 0)
1026 nPageScript
= ScGlobal::GetDefaultScriptType();
1031 ScEditEngineDefaulter
* pEditEng
= NULL
;
1032 const ScPatternAttr
& rDefPattern
= ((const ScPatternAttr
&)pDoc
->GetPool()->GetDefaultItem(ATTR_PATTERN
));
1033 if ( nPageScript
== SCRIPTTYPE_LATIN
)
1035 // use single font and call DrawText directly
1036 rDefPattern
.GetFont( aFont
, SC_AUTOCOL_BLACK
);
1037 aFont
.SetColor( Color( COL_LIGHTGRAY
) );
1038 // font size is set as needed
1042 // use EditEngine to draw mixed-script string
1043 pEditEng
= new ScEditEngineDefaulter( EditEngine::CreatePool(), TRUE
);
1044 pEditEng
->SetRefMapMode( pContentDev
->GetMapMode() );
1045 SfxItemSet
* pEditDefaults
= new SfxItemSet( pEditEng
->GetEmptyItemSet() );
1046 rDefPattern
.FillEditItemSet( pEditDefaults
);
1047 pEditDefaults
->Put( SvxColorItem( Color( COL_LIGHTGRAY
), EE_CHAR_COLOR
) );
1048 pEditEng
->SetDefaults( pEditDefaults
);
1051 USHORT nCount
= sal::static_int_cast
<USHORT
>( pPageData
->GetCount() );
1052 for (USHORT nPos
=0; nPos
<nCount
; nPos
++)
1054 ScPrintRangeData
& rData
= pPageData
->GetData(nPos
);
1055 ScRange aRange
= rData
.GetPrintRange();
1056 if ( aRange
.aStart
.Col() <= nX2
+1 && aRange
.aEnd
.Col()+1 >= nX1
&&
1057 aRange
.aStart
.Row() <= nY2
+1 && aRange
.aEnd
.Row()+1 >= nY1
)
1059 // 3 Pixel Rahmen um den Druckbereich
1060 // (mittlerer Pixel auf den Gitterlinien)
1062 pContentDev
->SetLineColor();
1063 if (rData
.IsAutomatic())
1064 pContentDev
->SetFillColor( aAutomatic
);
1066 pContentDev
->SetFillColor( aManual
);
1068 Point aStart
= pViewData
->GetScrPos(
1069 aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
, TRUE
);
1070 Point aEnd
= pViewData
->GetScrPos(
1071 aRange
.aEnd
.Col() + 1, aRange
.aEnd
.Row() + 1, eWhich
, TRUE
);
1075 // Ueberlaeufe verhindern:
1076 if ( aStart
.X() < -10 ) aStart
.X() = -10;
1077 if ( aStart
.Y() < -10 ) aStart
.Y() = -10;
1078 if ( aEnd
.X() > aWinSize
.Width() + 10 )
1079 aEnd
.X() = aWinSize
.Width() + 10;
1080 if ( aEnd
.Y() > aWinSize
.Height() + 10 )
1081 aEnd
.Y() = aWinSize
.Height() + 10;
1083 pContentDev
->DrawRect( Rectangle( aStart
, Point(aEnd
.X(),aStart
.Y()+2) ) );
1084 pContentDev
->DrawRect( Rectangle( aStart
, Point(aStart
.X()+2,aEnd
.Y()) ) );
1085 pContentDev
->DrawRect( Rectangle( Point(aStart
.X(),aEnd
.Y()-2), aEnd
) );
1086 pContentDev
->DrawRect( Rectangle( Point(aEnd
.X()-2,aStart
.Y()), aEnd
) );
1089 //! anders darstellen (gestrichelt ????)
1091 size_t nColBreaks
= rData
.GetPagesX();
1092 const SCCOL
* pColEnd
= rData
.GetPageEndX();
1094 for (nColPos
=0; nColPos
+1<nColBreaks
; nColPos
++)
1096 SCCOL nBreak
= pColEnd
[nColPos
]+1;
1097 if ( nBreak
>= nX1
&& nBreak
<= nX2
+1 )
1100 if (pDoc
->HasColBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1101 pContentDev
->SetFillColor( aManual
);
1103 pContentDev
->SetFillColor( aAutomatic
);
1104 Point aBreak
= pViewData
->GetScrPos(
1105 nBreak
, aRange
.aStart
.Row(), eWhich
, TRUE
);
1106 pContentDev
->DrawRect( Rectangle( aBreak
.X()-1, aStart
.Y(), aBreak
.X(), aEnd
.Y() ) );
1110 size_t nRowBreaks
= rData
.GetPagesY();
1111 const SCROW
* pRowEnd
= rData
.GetPageEndY();
1113 for (nRowPos
=0; nRowPos
+1<nRowBreaks
; nRowPos
++)
1115 SCROW nBreak
= pRowEnd
[nRowPos
]+1;
1116 if ( nBreak
>= nY1
&& nBreak
<= nY2
+1 )
1119 if (pDoc
->HasRowBreak(nBreak
, nTab
) & BREAK_MANUAL
)
1120 pContentDev
->SetFillColor( aManual
);
1122 pContentDev
->SetFillColor( aAutomatic
);
1123 Point aBreak
= pViewData
->GetScrPos(
1124 aRange
.aStart
.Col(), nBreak
, eWhich
, TRUE
);
1125 pContentDev
->DrawRect( Rectangle( aStart
.X(), aBreak
.Y()-1, aEnd
.X(), aBreak
.Y() ) );
1131 SCROW nPrStartY
= aRange
.aStart
.Row();
1132 for (nRowPos
=0; nRowPos
<nRowBreaks
; nRowPos
++)
1134 SCROW nPrEndY
= pRowEnd
[nRowPos
];
1135 if ( nPrEndY
>= nY1
&& nPrStartY
<= nY2
)
1137 SCCOL nPrStartX
= aRange
.aStart
.Col();
1138 for (nColPos
=0; nColPos
<nColBreaks
; nColPos
++)
1140 SCCOL nPrEndX
= pColEnd
[nColPos
];
1141 if ( nPrEndX
>= nX1
&& nPrStartX
<= nX2
)
1143 Point aPageStart
= pViewData
->GetScrPos(
1144 nPrStartX
, nPrStartY
, eWhich
, TRUE
);
1145 Point aPageEnd
= pViewData
->GetScrPos(
1146 nPrEndX
+1,nPrEndY
+1, eWhich
, TRUE
);
1148 long nPageNo
= rData
.GetFirstPage();
1149 if ( rData
.IsTopDown() )
1150 nPageNo
+= ((long)nColPos
)*nRowBreaks
+nRowPos
;
1152 nPageNo
+= ((long)nRowPos
)*nColBreaks
+nColPos
;
1153 String aPageStr
= aPageText
;
1154 aPageStr
+= String::CreateFromInt32(nPageNo
);
1158 // find right font size with EditEngine
1160 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1161 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1162 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1163 pEditEng
->SetText( aPageStr
);
1164 Size
aSize100( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1166 // 40% of width or 60% of height
1167 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1168 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1169 nHeight
= Min(nSizeX
,nSizeY
);
1170 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
1171 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
1172 pEditEng
->SetDefaultItem( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
1174 // centered output with EditEngine
1175 Size
aTextSize( pEditEng
->CalcTextWidth(), pEditEng
->GetTextHeight() );
1176 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1177 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1178 pEditEng
->Draw( pContentDev
, aPos
);
1182 // find right font size for DrawText
1183 aFont
.SetSize( Size( 0,100 ) );
1184 pContentDev
->SetFont( aFont
);
1185 Size
aSize100( pContentDev
->GetTextWidth( aPageStr
), pContentDev
->GetTextHeight() );
1187 // 40% of width or 60% of height
1188 long nSizeX
= 40 * ( aPageEnd
.X() - aPageStart
.X() ) / aSize100
.Width();
1189 long nSizeY
= 60 * ( aPageEnd
.Y() - aPageStart
.Y() ) / aSize100
.Height();
1190 aFont
.SetSize( Size( 0,Min(nSizeX
,nSizeY
) ) );
1191 pContentDev
->SetFont( aFont
);
1193 // centered output with DrawText
1194 Size
aTextSize( pContentDev
->GetTextWidth( aPageStr
), pContentDev
->GetTextHeight() );
1195 Point
aPos( (aPageStart
.X()+aPageEnd
.X()-aTextSize
.Width())/2,
1196 (aPageStart
.Y()+aPageEnd
.Y()-aTextSize
.Height())/2 );
1197 pContentDev
->DrawText( aPos
, aPageStr
);
1200 nPrStartX
= nPrEndX
+ 1;
1203 nPrStartY
= nPrEndY
+ 1;
1212 void ScGridWindow::DrawButtons( SCCOL nX1
, SCROW
/*nY1*/, SCCOL nX2
, SCROW
/*nY2*/, ScTableInfo
& rTabInfo
, OutputDevice
* pContentDev
)
1214 aComboButton
.SetOutputDevice( pContentDev
);
1216 ScDPFieldButton
aCellBtn(pContentDev
, &GetSettings().GetStyleSettings(), &pViewData
->GetZoomX(), &pViewData
->GetZoomY());
1222 SCTAB nTab
= pViewData
->GetTabNo();
1223 ScDocument
* pDoc
= pViewData
->GetDocument();
1224 ScDBData
* pDBData
= NULL
;
1225 ScQueryParam
* pQueryParam
= NULL
;
1227 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
1228 USHORT nArrCount
= rTabInfo
.mnArrCount
;
1230 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1232 Point aOldPos
= aComboButton
.GetPosPixel(); // Zustand fuer MouseDown/Up
1233 Size aOldSize
= aComboButton
.GetSizePixel(); // merken
1235 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1237 if ( pRowInfo
[nArrY
].bAutoFilter
&& pRowInfo
[nArrY
].bChanged
)
1239 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1241 nRow
= pThisRowInfo
->nRowNo
;
1244 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1246 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1247 if ( pInfo
->bAutoFilter
&& !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
1250 pQueryParam
= new ScQueryParam
;
1252 BOOL bNewData
= TRUE
;
1260 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1261 if ( nCol
>= nStartCol
&& nCol
<= nEndCol
&&
1262 nRow
>= nStartRow
&& nRow
<= nEndRow
)
1267 pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1269 pDBData
->GetQueryParam( *pQueryParam
);
1272 // can also be part of DataPilot table
1273 // DBG_ERROR("Auto-Filter-Button ohne DBData");
1277 // pQueryParam kann nur MAXQUERY Eintraege enthalten
1279 BOOL bSimpleQuery
= TRUE
;
1280 BOOL bColumnFound
= FALSE
;
1281 if (!pQueryParam
->bInplace
)
1282 bSimpleQuery
= FALSE
;
1283 for (nQuery
=0; nQuery
<MAXQUERY
&& bSimpleQuery
; nQuery
++)
1284 if (pQueryParam
->GetEntry(nQuery
).bDoQuery
)
1286 // hier nicht auf EQUAL beschraenken
1287 // (auch bei ">1" soll der Spaltenkopf blau werden)
1289 if (pQueryParam
->GetEntry(nQuery
).nField
== nCol
)
1290 bColumnFound
= TRUE
;
1292 if (pQueryParam
->GetEntry(nQuery
).eConnect
!= SC_AND
)
1293 bSimpleQuery
= FALSE
;
1296 bool bArrowState
= bSimpleQuery
&& bColumnFound
;
1299 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1300 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1302 aCellBtn
.setBoundingBox(aScrPos
, Size(nSizeX
-1, nSizeY
-1));
1303 aCellBtn
.setDrawBaseButton(false);
1304 aCellBtn
.setDrawPopupButton(true);
1305 aCellBtn
.setHasHiddenMember(bArrowState
);
1311 if ( pRowInfo
[nArrY
].bPushButton
&& pRowInfo
[nArrY
].bChanged
)
1313 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1314 nRow
= pThisRowInfo
->nRowNo
;
1315 for (nCol
=nX1
; nCol
<=nX2
; nCol
++)
1317 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nCol
+1];
1318 if ( pInfo
->bPushButton
&& !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
1320 Point aScrPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1323 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1324 long nPosX
= aScrPos
.X();
1325 long nPosY
= aScrPos
.Y();
1328 // overwrite the right, not left (visually) grid as long as the
1329 // left/right colors of the button borders aren't mirrored.
1330 nPosX
-= nSizeX
- 2;
1334 pDoc
->GetString(nCol
, nRow
, nTab
, aStr
);
1335 aCellBtn
.setText(aStr
);
1336 aCellBtn
.setBoundingBox(Point(nPosX
, nPosY
), Size(nSizeX
-1, nSizeY
-1));
1337 aCellBtn
.setDrawBaseButton(true);
1338 aCellBtn
.setDrawPopupButton(pInfo
->bPopupButton
);
1339 aCellBtn
.setHasHiddenMember(pInfo
->bFilterActive
);
1345 if ( bListValButton
&& pRowInfo
[nArrY
].nRowNo
== aListValPos
.Row() && pRowInfo
[nArrY
].bChanged
)
1347 Rectangle aRect
= GetListValButtonRect( aListValPos
);
1348 aComboButton
.SetPosPixel( aRect
.TopLeft() );
1349 aComboButton
.SetSizePixel( aRect
.GetSize() );
1350 pContentDev
->SetClipRegion( aRect
);
1351 aComboButton
.Draw( FALSE
, FALSE
);
1352 pContentDev
->SetClipRegion(); // always called from Draw() without clip region
1353 aComboButton
.SetPosPixel( aOldPos
); // restore old state
1354 aComboButton
.SetSizePixel( aOldSize
); // for MouseUp/Down (AutoFilter)
1359 aComboButton
.SetOutputDevice( this );
1362 Rectangle
ScGridWindow::GetListValButtonRect( const ScAddress
& rButtonPos
)
1364 ScDocument
* pDoc
= pViewData
->GetDocument();
1365 SCTAB nTab
= pViewData
->GetTabNo();
1366 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1367 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1369 ScDDComboBoxButton
aButton( this ); // for optimal size
1370 Size aBtnSize
= aButton
.GetSizePixel();
1372 SCCOL nCol
= rButtonPos
.Col();
1373 SCROW nRow
= rButtonPos
.Row();
1375 long nCellSizeX
; // width of this cell, including merged
1377 pViewData
->GetMergeSizePixel( nCol
, nRow
, nCellSizeX
, nDummy
);
1379 // for height, only the cell's row is used, excluding merged cells
1380 long nCellSizeY
= ScViewData::ToPixel( pDoc
->GetRowHeight( nRow
, nTab
), pViewData
->GetPPTY() );
1381 long nAvailable
= nCellSizeX
;
1383 // left edge of next cell if there is a non-hidden next column
1384 SCCOL nNextCol
= nCol
+ 1;
1385 const ScMergeAttr
* pMerge
= static_cast<const ScMergeAttr
*>(pDoc
->GetAttr( nCol
,nRow
,nTab
, ATTR_MERGE
));
1386 if ( pMerge
->GetColMerge() > 1 )
1387 nNextCol
= nCol
+ pMerge
->GetColMerge(); // next cell after the merged area
1388 while ( nNextCol
<= MAXCOL
&& pDoc
->ColHidden(nNextCol
, nTab
) )
1390 BOOL bNextCell
= ( nNextCol
<= MAXCOL
);
1392 nAvailable
= ScViewData::ToPixel( pDoc
->GetColWidth( nNextCol
, nTab
), pViewData
->GetPPTX() );
1394 if ( nAvailable
< aBtnSize
.Width() )
1395 aBtnSize
.Width() = nAvailable
;
1396 if ( nCellSizeY
< aBtnSize
.Height() )
1397 aBtnSize
.Height() = nCellSizeY
;
1399 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
, TRUE
);
1400 aPos
.X() += nCellSizeX
* nLayoutSign
; // start of next cell
1402 aPos
.X() -= aBtnSize
.Width() * nLayoutSign
; // right edge of cell if next cell not available
1403 aPos
.Y() += nCellSizeY
- aBtnSize
.Height();
1404 // X remains at the left edge
1407 aPos
.X() -= aBtnSize
.Width()-1; // align right edge of button with cell border
1409 return Rectangle( aPos
, aBtnSize
);
1412 BOOL
ScGridWindow::IsAutoFilterActive( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1414 ScDocument
* pDoc
= pViewData
->GetDocument();
1415 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1416 ScQueryParam aQueryParam
;
1419 pDBData
->GetQueryParam( aQueryParam
);
1422 DBG_ERROR("Auto-Filter-Button ohne DBData");
1425 BOOL bSimpleQuery
= TRUE
;
1426 BOOL bColumnFound
= FALSE
;
1429 if ( !aQueryParam
.bInplace
)
1430 bSimpleQuery
= FALSE
;
1432 // aQueryParam kann nur MAXQUERY Eintraege enthalten
1434 for ( nQuery
=0; nQuery
<MAXQUERY
&& bSimpleQuery
; nQuery
++ )
1435 if ( aQueryParam
.GetEntry(nQuery
).bDoQuery
)
1437 if (aQueryParam
.GetEntry(nQuery
).nField
== nCol
)
1438 bColumnFound
= TRUE
;
1441 if (aQueryParam
.GetEntry(nQuery
).eConnect
!= SC_AND
)
1442 bSimpleQuery
= FALSE
;
1445 return ( bSimpleQuery
&& bColumnFound
);
1448 void ScGridWindow::DrawComboButton( const Point
& rCellPos
,
1454 Point aScrPos
= rCellPos
;
1455 Size aBtnSize
= aComboButton
.GetSizePixel();
1457 if ( nCellSizeX
< aBtnSize
.Width() || nCellSizeY
< aBtnSize
.Height() )
1459 if ( nCellSizeX
< aBtnSize
.Width() )
1460 aBtnSize
.Width() = nCellSizeX
;
1462 if ( nCellSizeY
< aBtnSize
.Height() )
1463 aBtnSize
.Height() = nCellSizeY
;
1465 aComboButton
.SetSizePixel( aBtnSize
);
1468 BOOL bLayoutRTL
= pViewData
->GetDocument()->IsLayoutRTL( pViewData
->GetTabNo() );
1471 aScrPos
.X() -= nCellSizeX
- 1;
1473 aScrPos
.X() += nCellSizeX
- aBtnSize
.Width();
1474 aScrPos
.Y() += nCellSizeY
- aBtnSize
.Height();
1476 aComboButton
.SetPosPixel( aScrPos
);
1479 aComboButton
.Draw( bArrowState
, bBtnIn
);
1483 void ScGridWindow::InvertSimple( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
,
1484 BOOL bTestMerge
, BOOL bRepeat
)
1486 //! if INVERT_HIGHLIGHT swaps foreground and background (like on Mac),
1487 //! use INVERT_HIGHLIGHT only for cells that have no background color set
1488 //! (here and in ScOutputData::DrawMark)
1490 PutInOrder( nX1
, nX2
);
1491 PutInOrder( nY1
, nY2
);
1493 ScMarkData
& rMark
= pViewData
->GetMarkData();
1494 ScDocument
* pDoc
= pViewData
->GetDocument();
1495 SCTAB nTab
= pViewData
->GetTabNo();
1497 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1498 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1500 SCCOL nTestX2
= nX2
;
1501 SCROW nTestY2
= nY2
;
1503 pDoc
->ExtendMerge( nX1
,nY1
, nTestX2
,nTestY2
, nTab
);
1505 SCCOL nPosX
= pViewData
->GetPosX( eHWhich
);
1506 SCROW nPosY
= pViewData
->GetPosY( eVWhich
);
1507 if (nTestX2
< nPosX
|| nTestY2
< nPosY
)
1508 return; // unsichtbar
1509 SCCOL nRealX1
= nX1
;
1515 SCCOL nXRight
= nPosX
+ pViewData
->VisibleCellsX(eHWhich
);
1516 if (nXRight
> MAXCOL
) nXRight
= MAXCOL
;
1517 SCROW nYBottom
= nPosY
+ pViewData
->VisibleCellsY(eVWhich
);
1518 if (nYBottom
> MAXROW
) nYBottom
= MAXROW
;
1520 if (nX1
> nXRight
|| nY1
> nYBottom
)
1521 return; // unsichtbar
1522 if (nX2
> nXRight
) nX2
= nXRight
;
1523 if (nY2
> nYBottom
) nY2
= nYBottom
;
1525 MapMode aOld
= GetMapMode(); SetMapMode(MAP_PIXEL
); // erst nach den return's !!!
1527 double nPPTX
= pViewData
->GetPPTX();
1528 double nPPTY
= pViewData
->GetPPTY();
1530 ScInvertMerger
aInvert( this );
1532 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
1533 long nScrY
= aScrPos
.Y();
1534 BOOL bWasHidden
= FALSE
;
1535 for (SCROW nY
=nY1
; nY
<=nY2
; nY
++)
1537 BOOL bFirstRow
= ( nY
== nPosY
); // first visible row?
1538 BOOL bDoHidden
= FALSE
; // versteckte nachholen ?
1539 USHORT nHeightTwips
= pDoc
->GetRowHeight( nY
,nTab
);
1540 BOOL bDoRow
= ( nHeightTwips
!= 0 );
1544 if (bWasHidden
) // auf versteckte zusammengefasste testen
1546 // --nY; // nY geaendert -> vorherige zeichnen
1558 bDoRow
= TRUE
; // letzte Zeile aus Block
1563 SCCOL nLoopEndX
= nX2
;
1564 if (nX2
< nX1
) // Rest von zusammengefasst
1566 SCCOL nStartX
= nX1
;
1567 while ( ((const ScMergeFlagAttr
*)pDoc
->
1568 GetAttr(nStartX
,nY
,nTab
,ATTR_MERGE_FLAG
))->IsHorOverlapped() )
1574 long nEndY
= nScrY
+ ScViewData::ToPixel( nHeightTwips
, nPPTY
) - 1;
1575 long nScrX
= aScrPos
.X();
1576 for (SCCOL nX
=nX1
; nX
<=nLoopEndX
; nX
++)
1578 long nWidth
= ScViewData::ToPixel( pDoc
->GetColWidth( nX
,nTab
), nPPTX
);
1581 long nEndX
= nScrX
+ ( nWidth
- 1 ) * nLayoutSign
;
1585 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1586 const ScMergeFlagAttr
* pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->
1587 GetItem(ATTR_MERGE_FLAG
);
1588 if ( pMergeFlag
->IsVerOverlapped() && ( bDoHidden
|| bFirstRow
) )
1590 while ( pMergeFlag
->IsVerOverlapped() && nThisY
> 0 &&
1591 (pDoc
->RowHidden(nThisY
-1, nTab
) || bFirstRow
) )
1594 pPattern
= pDoc
->GetPattern( nX
, nThisY
, nTab
);
1595 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1599 // nur Rest von zusammengefasster zu sehen ?
1601 if ( pMergeFlag
->IsHorOverlapped() && nX
== nPosX
&& nX
> nRealX1
)
1603 while ( pMergeFlag
->IsHorOverlapped() )
1606 pPattern
= pDoc
->GetPattern( nThisX
, nThisY
, nTab
);
1607 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1611 if ( rMark
.IsCellMarked( nThisX
, nThisY
, TRUE
) == bRepeat
)
1613 if ( !pMergeFlag
->IsOverlapped() )
1615 ScMergeAttr
* pMerge
= (ScMergeAttr
*)&pPattern
->GetItem(ATTR_MERGE
);
1616 if (pMerge
->GetColMerge() > 0 || pMerge
->GetRowMerge() > 0)
1618 Point aEndPos
= pViewData
->GetScrPos(
1619 nThisX
+ pMerge
->GetColMerge(),
1620 nThisY
+ pMerge
->GetRowMerge(), eWhich
);
1621 if ( aEndPos
.X() * nLayoutSign
> nScrX
* nLayoutSign
&& aEndPos
.Y() > nScrY
)
1623 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,
1624 aEndPos
.X()-nLayoutSign
,aEndPos
.Y()-1 ) );
1627 else if ( nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1629 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1636 if ( rMark
.IsCellMarked( nX
, nY
, TRUE
) == bRepeat
&&
1637 nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1639 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1643 nScrX
= nEndX
+ nLayoutSign
;
1650 aInvert
.Flush(); // before restoring MapMode
1657 void ScGridWindow::GetSelectionRects( ::std::vector
< Rectangle
>& rPixelRects
)
1659 // transformed from ScGridWindow::InvertSimple
1661 // ScMarkData& rMark = pViewData->GetMarkData();
1662 ScMarkData
aMultiMark( pViewData
->GetMarkData() );
1663 aMultiMark
.SetMarking( FALSE
);
1664 aMultiMark
.MarkToMulti();
1666 ScDocument
* pDoc
= pViewData
->GetDocument();
1667 SCTAB nTab
= pViewData
->GetTabNo();
1669 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1670 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1672 if ( !aMultiMark
.IsMultiMarked() )
1675 ScRange aMultiRange
;
1676 aMultiMark
.GetMultiMarkArea( aMultiRange
);
1677 SCCOL nX1
= aMultiRange
.aStart
.Col();
1678 SCROW nY1
= aMultiRange
.aStart
.Row();
1679 SCCOL nX2
= aMultiRange
.aEnd
.Col();
1680 SCROW nY2
= aMultiRange
.aEnd
.Row();
1682 PutInOrder( nX1
, nX2
);
1683 PutInOrder( nY1
, nY2
);
1685 BOOL bTestMerge
= TRUE
;
1686 BOOL bRepeat
= TRUE
;
1688 SCCOL nTestX2
= nX2
;
1689 SCROW nTestY2
= nY2
;
1691 pDoc
->ExtendMerge( nX1
,nY1
, nTestX2
,nTestY2
, nTab
);
1693 SCCOL nPosX
= pViewData
->GetPosX( eHWhich
);
1694 SCROW nPosY
= pViewData
->GetPosY( eVWhich
);
1695 if (nTestX2
< nPosX
|| nTestY2
< nPosY
)
1696 return; // unsichtbar
1697 SCCOL nRealX1
= nX1
;
1703 SCCOL nXRight
= nPosX
+ pViewData
->VisibleCellsX(eHWhich
);
1704 if (nXRight
> MAXCOL
) nXRight
= MAXCOL
;
1705 SCROW nYBottom
= nPosY
+ pViewData
->VisibleCellsY(eVWhich
);
1706 if (nYBottom
> MAXROW
) nYBottom
= MAXROW
;
1708 if (nX1
> nXRight
|| nY1
> nYBottom
)
1709 return; // unsichtbar
1710 if (nX2
> nXRight
) nX2
= nXRight
;
1711 if (nY2
> nYBottom
) nY2
= nYBottom
;
1713 // MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); // erst nach den return's !!!
1715 double nPPTX
= pViewData
->GetPPTX();
1716 double nPPTY
= pViewData
->GetPPTY();
1718 ScInvertMerger
aInvert( &rPixelRects
);
1720 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
1721 long nScrY
= aScrPos
.Y();
1722 BOOL bWasHidden
= FALSE
;
1723 for (SCROW nY
=nY1
; nY
<=nY2
; nY
++)
1725 BOOL bFirstRow
= ( nY
== nPosY
); // first visible row?
1726 BOOL bDoHidden
= FALSE
; // versteckte nachholen ?
1727 USHORT nHeightTwips
= pDoc
->GetRowHeight( nY
,nTab
);
1728 BOOL bDoRow
= ( nHeightTwips
!= 0 );
1732 if (bWasHidden
) // auf versteckte zusammengefasste testen
1745 bDoRow
= TRUE
; // letzte Zeile aus Block
1750 SCCOL nLoopEndX
= nX2
;
1751 if (nX2
< nX1
) // Rest von zusammengefasst
1753 SCCOL nStartX
= nX1
;
1754 while ( ((const ScMergeFlagAttr
*)pDoc
->
1755 GetAttr(nStartX
,nY
,nTab
,ATTR_MERGE_FLAG
))->IsHorOverlapped() )
1761 long nEndY
= nScrY
+ ScViewData::ToPixel( nHeightTwips
, nPPTY
) - 1;
1762 long nScrX
= aScrPos
.X();
1763 for (SCCOL nX
=nX1
; nX
<=nLoopEndX
; nX
++)
1765 long nWidth
= ScViewData::ToPixel( pDoc
->GetColWidth( nX
,nTab
), nPPTX
);
1768 long nEndX
= nScrX
+ ( nWidth
- 1 ) * nLayoutSign
;
1772 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1773 const ScMergeFlagAttr
* pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->
1774 GetItem(ATTR_MERGE_FLAG
);
1775 if ( pMergeFlag
->IsVerOverlapped() && ( bDoHidden
|| bFirstRow
) )
1777 while ( pMergeFlag
->IsVerOverlapped() && nThisY
> 0 &&
1778 (pDoc
->RowHidden(nThisY
-1, nTab
) || bFirstRow
) )
1781 pPattern
= pDoc
->GetPattern( nX
, nThisY
, nTab
);
1782 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1786 // nur Rest von zusammengefasster zu sehen ?
1788 if ( pMergeFlag
->IsHorOverlapped() && nX
== nPosX
&& nX
> nRealX1
)
1790 while ( pMergeFlag
->IsHorOverlapped() )
1793 pPattern
= pDoc
->GetPattern( nThisX
, nThisY
, nTab
);
1794 pMergeFlag
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1798 if ( aMultiMark
.IsCellMarked( nThisX
, nThisY
, TRUE
) == bRepeat
)
1800 if ( !pMergeFlag
->IsOverlapped() )
1802 ScMergeAttr
* pMerge
= (ScMergeAttr
*)&pPattern
->GetItem(ATTR_MERGE
);
1803 if (pMerge
->GetColMerge() > 0 || pMerge
->GetRowMerge() > 0)
1805 Point aEndPos
= pViewData
->GetScrPos(
1806 nThisX
+ pMerge
->GetColMerge(),
1807 nThisY
+ pMerge
->GetRowMerge(), eWhich
);
1808 if ( aEndPos
.X() * nLayoutSign
> nScrX
* nLayoutSign
&& aEndPos
.Y() > nScrY
)
1810 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,
1811 aEndPos
.X()-nLayoutSign
,aEndPos
.Y()-1 ) );
1814 else if ( nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1816 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1823 if ( aMultiMark
.IsCellMarked( nX
, nY
, TRUE
) == bRepeat
&&
1824 nEndX
* nLayoutSign
>= nScrX
* nLayoutSign
&& nEndY
>= nScrY
)
1826 aInvert
.AddRect( Rectangle( nScrX
,nScrY
,nEndX
,nEndY
) );
1830 nScrX
= nEndX
+ nLayoutSign
;
1837 // aInvert.Flush(); // before restoring MapMode
1840 // -------------------------------------------------------------------------
1842 //UNUSED2008-05 void ScGridWindow::DrawDragRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
1844 //UNUSED2008-05 if ( nX2 < pViewData->GetPosX(eHWhich) || nY2 < pViewData->GetPosY(eVWhich) )
1845 //UNUSED2008-05 return;
1847 //UNUSED2008-05 Update(); // wegen XOR
1849 //UNUSED2008-05 MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
1851 //UNUSED2008-05 SCTAB nTab = pViewData->GetTabNo();
1853 //UNUSED2008-05 SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
1854 //UNUSED2008-05 SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
1855 //UNUSED2008-05 if (nX1 < nPosX) nX1 = nPosX;
1856 //UNUSED2008-05 if (nX2 < nPosX) nX2 = nPosX;
1857 //UNUSED2008-05 if (nY1 < nPosY) nY1 = nPosY;
1858 //UNUSED2008-05 if (nY2 < nPosY) nY2 = nPosY;
1860 //UNUSED2008-05 Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
1862 //UNUSED2008-05 long nSizeXPix=0;
1863 //UNUSED2008-05 long nSizeYPix=0;
1864 //UNUSED2008-05 ScDocument* pDoc = pViewData->GetDocument();
1865 //UNUSED2008-05 double nPPTX = pViewData->GetPPTX();
1866 //UNUSED2008-05 double nPPTY = pViewData->GetPPTY();
1867 //UNUSED2008-05 SCCOLROW i;
1869 //UNUSED2008-05 BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1870 //UNUSED2008-05 long nLayoutSign = bLayoutRTL ? -1 : 1;
1872 //UNUSED2008-05 if (ValidCol(nX2) && nX2>=nX1)
1873 //UNUSED2008-05 for (i=nX1; i<=nX2; i++)
1874 //UNUSED2008-05 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
1875 //UNUSED2008-05 else
1877 //UNUSED2008-05 aScrPos.X() -= nLayoutSign;
1878 //UNUSED2008-05 nSizeXPix += 2;
1881 //UNUSED2008-05 if (ValidRow(nY2) && nY2>=nY1)
1882 //UNUSED2008-05 for (i=nY1; i<=nY2; i++)
1883 //UNUSED2008-05 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
1884 //UNUSED2008-05 else
1886 //UNUSED2008-05 aScrPos.Y() -= 1;
1887 //UNUSED2008-05 nSizeYPix += 2;
1890 //UNUSED2008-05 aScrPos.X() -= 2 * nLayoutSign;
1891 //UNUSED2008-05 aScrPos.Y() -= 2;
1892 //UNUSED2008-05 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
1893 //UNUSED2008-05 Rectangle aRect( aScrPos.X(), aScrPos.Y(),
1894 //UNUSED2008-05 aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
1895 //UNUSED2008-05 if ( bLayoutRTL )
1897 //UNUSED2008-05 aRect.Left() = aRect.Right(); // end position is left
1898 //UNUSED2008-05 aRect.Right() = aScrPos.X();
1901 //UNUSED2008-05 Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
1902 //UNUSED2008-05 Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
1903 //UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
1904 //UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
1906 //UNUSED2008-05 SetMapMode(aOld);
1909 // -------------------------------------------------------------------------
1911 void ScGridWindow::DrawCursor()
1914 // SCTAB nTab = pViewData->GetTabNo();
1915 // SCCOL nX = pViewData->GetCurX();
1916 // SCROW nY = pViewData->GetCurY();
1918 // // in verdeckten Zellen nicht zeichnen
1920 // ScDocument* pDoc = pViewData->GetDocument();
1921 // const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
1922 // const ScMergeFlagAttr& rMerge = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
1923 // if (rMerge.IsOverlapped())
1926 // // links/oben ausserhalb des Bildschirms ?
1928 // BOOL bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
1931 // SCCOL nEndX = nX;
1932 // SCROW nEndY = nY;
1933 // ScDocument* pDoc = pViewData->GetDocument();
1934 // const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
1935 // if (rMerge.GetColMerge() > 1)
1936 // nEndX += rMerge.GetColMerge()-1;
1937 // if (rMerge.GetRowMerge() > 1)
1938 // nEndY += rMerge.GetRowMerge()-1;
1939 // bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
1944 // // hier kein Update, da aus Paint gerufen und laut Zaehler Cursor schon da
1945 // // wenn Update noetig, dann bei Hide/Showcursor vor dem Hoch-/Runterzaehlen
1947 // MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
1949 // Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE );
1950 // BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1952 // // completely right of/below the screen?
1953 // // (test with logical start position in aScrPos)
1954 // BOOL bMaybeVisible;
1955 // if ( bLayoutRTL )
1956 // bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
1959 // Size aOutSize = GetOutputSizePixel();
1960 // bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
1962 // if ( bMaybeVisible )
1966 // pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
1968 // if ( bLayoutRTL )
1969 // aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring
1971 // BOOL bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
1972 // pViewData->GetVSplitMode() == SC_SPLIT_FIX );
1973 // if ( pViewData->GetActivePart()==eWhich || bFix )
1975 // // old UNX version with two Invert calls causes flicker.
1976 // // if optimization is needed, a new flag should be added
1977 // // to InvertTracking
1979 // aScrPos.X() -= 2;
1980 // aScrPos.Y() -= 2;
1981 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
1983 // Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
1984 // Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
1985 // Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
1986 // Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
1990 // Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
1995 // SetMapMode(aOld);
1999 // AutoFill-Anfasser:
2001 void ScGridWindow::DrawAutoFillMark()
2004 // if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() )
2006 // SCCOL nX = aAutoMarkPos.Col();
2007 // SCROW nY = aAutoMarkPos.Row();
2008 // SCTAB nTab = pViewData->GetTabNo();
2009 // ScDocument* pDoc = pViewData->GetDocument();
2010 // BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
2012 // Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE );
2015 // pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
2016 // if ( bLayoutRTL )
2017 // aFillPos.X() -= nSizeXPix + 3;
2019 // aFillPos.X() += nSizeXPix - 2;
2021 // aFillPos.Y() += nSizeYPix;
2022 // aFillPos.Y() -= 2;
2023 // Rectangle aFillRect( aFillPos, Size(6,6) );
2024 // // Anfasser von Zeichenobjekten sind 7*7
2026 // MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
2027 // Invert( aFillRect );
2028 // SetMapMode(aOld);
2032 // -------------------------------------------------------------------------
2034 void ScGridWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
2036 Window::DataChanged(rDCEvt
);
2038 if ( (rDCEvt
.GetType() == DATACHANGED_PRINTER
) ||
2039 (rDCEvt
.GetType() == DATACHANGED_DISPLAY
) ||
2040 (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
2041 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
2042 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
2043 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
2045 if ( rDCEvt
.GetType() == DATACHANGED_FONTS
&& eWhich
== pViewData
->GetActivePart() )
2046 pViewData
->GetDocShell()->UpdateFontList();
2048 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
2049 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
2051 if ( eWhich
== pViewData
->GetActivePart() ) // only once for the view
2053 ScTabView
* pView
= pViewData
->GetView();
2055 // update scale in case the UI ScreenZoom has changed
2056 ScGlobal::UpdatePPT(this);
2059 // RepeatResize in case scroll bar sizes have changed
2060 pView
->RepeatResize();
2061 pView
->UpdateAllOverlays();
2063 // invalidate cell attribs in input handler, in case the
2064 // EditEngine BackgroundColor has to be changed
2065 if ( pViewData
->IsActive() )
2067 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
2069 pHdl
->ForgetLastPattern();