Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "scitems.hxx"
21 : #include <editeng/eeitem.hxx>
22 :
23 : #include <svtools/colorcfg.hxx>
24 : #include <editeng/colritem.hxx>
25 : #include <editeng/editview.hxx>
26 : #include <editeng/fhgtitem.hxx>
27 : #include <editeng/scripttypeitem.hxx>
28 : #include <sfx2/bindings.hxx>
29 : #include <sfx2/printer.hxx>
30 :
31 : #include <svx/svdview.hxx>
32 : #include "tabvwsh.hxx"
33 :
34 : #include "gridwin.hxx"
35 : #include "viewdata.hxx"
36 : #include "output.hxx"
37 : #include "document.hxx"
38 : #include "attrib.hxx"
39 : #include "patattr.hxx" // InvertSimple
40 : #include "dbdata.hxx"
41 : #include "docoptio.hxx"
42 : #include "notemark.hxx"
43 : #include "dbfunc.hxx" // oder GetPageBreakData an die ViewData
44 : #include "scmod.hxx"
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"
61 : #include "sc.hrc"
62 : #include <vcl/virdev.hxx>
63 :
64 : // #i74769#
65 : #include <svx/sdrpaintwindow.hxx>
66 :
67 : //------------------------------------------------------------------------
68 :
69 0 : static void lcl_LimitRect( Rectangle& rRect, const Rectangle& rVisible )
70 : {
71 0 : if ( rRect.Top() < rVisible.Top()-1 ) rRect.Top() = rVisible.Top()-1;
72 0 : if ( rRect.Bottom() > rVisible.Bottom()+1 ) rRect.Bottom() = rVisible.Bottom()+1;
73 :
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.
77 0 : }
78 :
79 0 : 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 )
83 : {
84 : // pButtonViewData wird nur benutzt, um die Button-Groesse zu setzen,
85 : // darf ansonsten NULL sein!
86 :
87 0 : Rectangle aInner = rInnerPixel;
88 0 : if ( bLayoutRTL )
89 : {
90 0 : aInner.Left() = rInnerPixel.Right();
91 0 : aInner.Right() = rInnerPixel.Left();
92 : }
93 :
94 0 : Rectangle aVisible( Point(0,0), pDev->GetOutputSizePixel() );
95 0 : lcl_LimitRect( aInner, aVisible );
96 :
97 0 : Rectangle aOuter = aInner;
98 0 : long nHor = (long) ( SC_SCENARIO_HSPACE * nPPTX );
99 0 : long nVer = (long) ( SC_SCENARIO_VSPACE * nPPTY );
100 0 : aOuter.Left() -= nHor;
101 0 : aOuter.Right() += nHor;
102 0 : aOuter.Top() -= nVer;
103 0 : aOuter.Bottom() += nVer;
104 :
105 : // use ScPatternAttr::GetFont only for font size
106 0 : Font aAttrFont;
107 0 : ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
108 0 : GetFont(aAttrFont,SC_AUTOCOL_BLACK,pDev,&rZoomY);
109 :
110 : // everything else from application font
111 0 : Font aAppFont = pDev->GetSettings().GetStyleSettings().GetAppFont();
112 0 : aAppFont.SetSize( aAttrFont.GetSize() );
113 :
114 0 : aAppFont.SetAlign( ALIGN_TOP );
115 0 : pDev->SetFont( aAppFont );
116 :
117 0 : Size aTextSize( pDev->GetTextWidth( rTitle ), pDev->GetTextHeight() );
118 :
119 0 : if ( bTextBelow )
120 0 : aOuter.Bottom() += aTextSize.Height();
121 : else
122 0 : aOuter.Top() -= aTextSize.Height();
123 :
124 0 : pDev->SetLineColor();
125 0 : pDev->SetFillColor( rColor );
126 : // links, oben, rechts, unten
127 0 : pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aInner.Left(), aOuter.Bottom() ) );
128 0 : pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aOuter.Right(), aInner.Top() ) );
129 0 : pDev->DrawRect( Rectangle( aInner.Right(), aOuter.Top(), aOuter.Right(), aOuter.Bottom() ) );
130 0 : pDev->DrawRect( Rectangle( aOuter.Left(), aInner.Bottom(), aOuter.Right(), aOuter.Bottom() ) );
131 :
132 0 : long nButtonY = bTextBelow ? aInner.Bottom() : aOuter.Top();
133 :
134 0 : ScDDComboBoxButton aComboButton((Window*)pDev);
135 0 : aComboButton.SetOptSizePixel();
136 0 : long nBWidth = ( aComboButton.GetSizePixel().Width() * rZoomY.GetNumerator() )
137 0 : / rZoomY.GetDenominator();
138 0 : long nBHeight = nVer + aTextSize.Height() + 1;
139 0 : Size aButSize( nBWidth, nBHeight );
140 0 : long nButtonPos = bLayoutRTL ? aOuter.Left() : aOuter.Right()-nBWidth+1;
141 0 : aComboButton.Draw( Point(nButtonPos, nButtonY), aButSize, false );
142 0 : if (pButtonViewData)
143 0 : pButtonViewData->SetScenButSize( aButSize );
144 :
145 0 : long nTextStart = bLayoutRTL ? aInner.Right() - aTextSize.Width() + 1 : aInner.Left();
146 :
147 0 : sal_Bool bWasClip = false;
148 0 : Region aOldClip;
149 0 : sal_Bool bClip = ( aTextSize.Width() > aOuter.Right() - nBWidth - aInner.Left() );
150 0 : if ( bClip )
151 : {
152 0 : if (pDev->IsClipRegion())
153 : {
154 0 : bWasClip = sal_True;
155 0 : aOldClip = pDev->GetActiveClipRegion();
156 : }
157 0 : long nClipStartX = bLayoutRTL ? aOuter.Left() + nBWidth : aInner.Left();
158 0 : long nClipEndX = bLayoutRTL ? aInner.Right() : aOuter.Right() - nBWidth;
159 : pDev->SetClipRegion( Rectangle( nClipStartX, nButtonY + nVer/2,
160 0 : nClipEndX, nButtonY + nVer/2 + aTextSize.Height() ) );
161 : }
162 :
163 0 : pDev->DrawText( Point( nTextStart, nButtonY + nVer/2 ), rTitle );
164 :
165 0 : if ( bClip )
166 : {
167 0 : if ( bWasClip )
168 0 : pDev->SetClipRegion(aOldClip);
169 : else
170 0 : pDev->SetClipRegion();
171 : }
172 :
173 0 : pDev->SetFillColor();
174 0 : pDev->SetLineColor( COL_BLACK );
175 0 : pDev->DrawRect( aInner );
176 0 : pDev->DrawRect( aOuter );
177 0 : }
178 :
179 0 : static void lcl_DrawScenarioFrames( OutputDevice* pDev, ScViewData* pViewData, ScSplitPos eWhich,
180 : SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
181 : {
182 0 : ScDocument* pDoc = pViewData->GetDocument();
183 0 : SCTAB nTab = pViewData->GetTabNo();
184 0 : SCTAB nTabCount = pDoc->GetTableCount();
185 0 : if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
186 : {
187 0 : if ( nX1 > 0 ) --nX1;
188 0 : if ( nY1>=2 ) nY1 -= 2; // Hack: Titelzeile beruehrt zwei Zellen
189 0 : else if ( nY1 > 0 ) --nY1;
190 0 : if ( nX2 < MAXCOL ) ++nX2;
191 0 : if ( nY2 < MAXROW-1 ) nY2 += 2; // Hack: Titelzeile beruehrt zwei Zellen
192 0 : else if ( nY2 < MAXROW ) ++nY2;
193 0 : ScRange aViewRange( nX1,nY1,nTab, nX2,nY2,nTab );
194 :
195 : //! Ranges an der Table cachen!!!!
196 :
197 0 : ScMarkData aMarks;
198 0 : for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
199 0 : pDoc->MarkScenario( i, nTab, aMarks, false, SC_SCENARIO_SHOWFRAME );
200 0 : ScRangeListRef xRanges = new ScRangeList;
201 0 : aMarks.FillRangeListWithMarks( xRanges, false );
202 :
203 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
204 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
205 :
206 0 : for (size_t j = 0, n = xRanges->size(); j < n; ++j)
207 : {
208 0 : 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 0 : pDoc->ExtendTotalMerge( aRange );
212 :
213 : //! -> Repaint beim Zusammenfassen erweitern !!!
214 :
215 0 : if ( aRange.Intersects( aViewRange ) ) //! Platz fuer Text/Button?
216 : {
217 : Point aStartPos = pViewData->GetScrPos(
218 0 : aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True );
219 : Point aEndPos = pViewData->GetScrPos(
220 0 : aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich, sal_True );
221 : // on the grid:
222 0 : aStartPos.X() -= nLayoutSign;
223 0 : aStartPos.Y() -= 1;
224 0 : aEndPos.X() -= nLayoutSign;
225 0 : aEndPos.Y() -= 1;
226 :
227 0 : sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
228 :
229 0 : rtl::OUString aCurrent;
230 0 : Color aColor( COL_LIGHTGRAY );
231 0 : for (SCTAB nAct=nTab+1; nAct<nTabCount && pDoc->IsScenario(nAct); nAct++)
232 0 : if ( pDoc->IsActiveScenario(nAct) && pDoc->HasScenarioRange(nAct,aRange) )
233 : {
234 0 : rtl::OUString aDummyComment;
235 : sal_uInt16 nDummyFlags;
236 0 : pDoc->GetName( nAct, aCurrent );
237 0 : pDoc->GetScenarioData( nAct, aDummyComment, aColor, nDummyFlags );
238 : }
239 :
240 0 : if (aCurrent.isEmpty())
241 0 : aCurrent = ScGlobal::GetRscString( STR_EMPTYDATA );
242 :
243 : //! eigener Text "(keins)" statt "(leer)" ???
244 :
245 : lcl_DrawOneFrame( pDev, Rectangle( aStartPos, aEndPos ),
246 : aCurrent, aColor, bTextBelow,
247 0 : pViewData->GetPPTX(), pViewData->GetPPTY(), pViewData->GetZoomY(),
248 0 : pDoc, pViewData, bLayoutRTL );
249 : }
250 0 : }
251 : }
252 0 : }
253 :
254 : //------------------------------------------------------------------------
255 :
256 0 : static void lcl_DrawHighlight( ScOutputData& rOutputData, ScViewData* pViewData,
257 : const std::vector<ScHighlightEntry>& rHighlightRanges )
258 : {
259 0 : SCTAB nTab = pViewData->GetTabNo();
260 0 : std::vector<ScHighlightEntry>::const_iterator pIter;
261 0 : for ( pIter = rHighlightRanges.begin(); pIter != rHighlightRanges.end(); ++pIter)
262 : {
263 0 : ScRange aRange = pIter->aRef;
264 0 : if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
265 : {
266 : rOutputData.DrawRefMark(
267 0 : aRange.aStart.Col(), aRange.aStart.Row(),
268 0 : aRange.aEnd.Col(), aRange.aEnd.Row(),
269 0 : pIter->aColor, false );
270 : }
271 : }
272 0 : }
273 :
274 : //------------------------------------------------------------------------
275 :
276 0 : void ScGridWindow::DoInvertRect( const Rectangle& rPixel )
277 : {
278 0 : if ( rPixel == aInvertRect )
279 0 : aInvertRect = Rectangle(); // aufheben
280 : else
281 : {
282 : OSL_ENSURE( aInvertRect.IsEmpty(), "DoInvertRect nicht paarig" );
283 :
284 0 : aInvertRect = rPixel; // neues Rechteck merken
285 : }
286 :
287 0 : UpdateHeaderOverlay(); // uses aInvertRect
288 0 : }
289 :
290 : //------------------------------------------------------------------------
291 :
292 0 : void ScGridWindow::PrePaint()
293 : {
294 : // forward PrePaint to DrawingLayer
295 0 : ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
296 :
297 0 : if(pTabViewShell)
298 : {
299 0 : SdrView* pDrawView = pTabViewShell->GetSdrView();
300 :
301 0 : if(pDrawView)
302 : {
303 0 : pDrawView->PrePaint();
304 : }
305 : }
306 0 : }
307 :
308 : //------------------------------------------------------------------------
309 :
310 0 : void ScGridWindow::Paint( const Rectangle& rRect )
311 : {
312 0 : ScDocument* pDoc = pViewData->GetDocument();
313 0 : if ( pDoc->IsInInterpreter() )
314 : {
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.
318 :
319 0 : if ( bNeedsRepaint )
320 : {
321 : //! Rechtecke zusammenfassen?
322 0 : aRepaintPixel = Rectangle(); // mehrfach -> alles painten
323 : }
324 : else
325 : {
326 0 : bNeedsRepaint = true;
327 0 : aRepaintPixel = LogicToPixel(rRect); // nur betroffenen Bereich
328 : }
329 : return;
330 : }
331 :
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.
334 0 : GetSizePixel();
335 :
336 0 : if (bIsInPaint)
337 : return;
338 :
339 0 : bIsInPaint = true;
340 :
341 0 : Rectangle aPixRect = LogicToPixel( rRect );
342 :
343 0 : SCCOL nX1 = pViewData->GetPosX(eHWhich);
344 0 : SCROW nY1 = pViewData->GetPosY(eVWhich);
345 :
346 0 : SCTAB nTab = pViewData->GetTabNo();
347 :
348 0 : double nPPTX = pViewData->GetPPTX();
349 0 : double nPPTY = pViewData->GetPPTY();
350 :
351 0 : Rectangle aMirroredPixel = aPixRect;
352 0 : if ( pDoc->IsLayoutRTL( nTab ) )
353 : {
354 : // mirror and swap
355 0 : long nWidth = GetSizePixel().Width();
356 0 : aMirroredPixel.Left() = nWidth - 1 - aPixRect.Right();
357 0 : aMirroredPixel.Right() = nWidth - 1 - aPixRect.Left();
358 : }
359 :
360 0 : long nScrX = ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
361 0 : while ( nScrX <= aMirroredPixel.Left() && nX1 < MAXCOL )
362 : {
363 0 : ++nX1;
364 0 : nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
365 : }
366 0 : SCCOL nX2 = nX1;
367 0 : while ( nScrX <= aMirroredPixel.Right() && nX2 < MAXCOL )
368 : {
369 0 : ++nX2;
370 0 : nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX2, nTab ), nPPTX );
371 : }
372 :
373 0 : long nScrY = 0;
374 0 : ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, MAXROW, nPPTY, pDoc, nTab);
375 0 : SCROW nY2 = nY1;
376 0 : if (nScrY <= aPixRect.Bottom() && nY2 < MAXROW)
377 : {
378 0 : ++nY2;
379 0 : ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, MAXROW, nPPTY, pDoc, nTab);
380 : }
381 :
382 0 : Draw( nX1,nY1,nX2,nY2, SC_UPDATE_MARKS ); // nicht weiterzeichnen
383 :
384 0 : bIsInPaint = false;
385 : }
386 :
387 : //
388 : // Draw ----------------------------------------------------------------
389 : //
390 :
391 0 : void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMode eMode )
392 : {
393 0 : ScModule* pScMod = SC_MOD();
394 0 : sal_Bool bTextWysiwyg = pScMod->GetInputOptions().GetTextWysiwyg();
395 :
396 0 : if (pViewData->IsMinimized())
397 : return;
398 :
399 0 : PutInOrder( nX1, nX2 );
400 0 : PutInOrder( nY1, nY2 );
401 :
402 : OSL_ENSURE( ValidCol(nX2) && ValidRow(nY2), "GridWin Draw Bereich zu gross" );
403 :
404 0 : UpdateVisibleRange();
405 :
406 0 : if (nX2 < maVisibleRange.mnCol1 || nY2 < maVisibleRange.mnRow1)
407 : return;
408 : // unsichtbar
409 0 : if (nX1 < maVisibleRange.mnCol1)
410 0 : nX1 = maVisibleRange.mnCol1;
411 0 : if (nY1 < maVisibleRange.mnRow1)
412 0 : nY1 = maVisibleRange.mnRow1;
413 :
414 0 : if (nX1 > maVisibleRange.mnCol2 || nY1 > maVisibleRange.mnRow2)
415 : return;
416 :
417 0 : if (nX2 > maVisibleRange.mnCol2)
418 0 : nX2 = maVisibleRange.mnCol2;
419 0 : if (nY2 > maVisibleRange.mnRow2)
420 0 : nY2 = maVisibleRange.mnRow2;
421 :
422 0 : if ( eMode != SC_UPDATE_MARKS && nX2 < maVisibleRange.mnCol2)
423 0 : nX2 = maVisibleRange.mnCol2; // zum Weiterzeichnen
424 :
425 : // ab hier kein return mehr
426 :
427 0 : ++nPaintCount; // merken, dass gemalt wird (wichtig beim Invertieren)
428 :
429 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
430 0 : ScDocument* pDoc = pDocSh->GetDocument();
431 0 : SCTAB nTab = pViewData->GetTabNo();
432 :
433 0 : pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
434 :
435 0 : Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
436 0 : long nMirrorWidth = GetSizePixel().Width();
437 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
438 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
439 0 : if ( bLayoutRTL )
440 : {
441 0 : long nEndPixel = pViewData->GetScrPos( nX2+1, maVisibleRange.mnRow1, eWhich ).X();
442 0 : nMirrorWidth = aScrPos.X() - nEndPixel;
443 0 : aScrPos.X() = nEndPixel + 1;
444 : }
445 :
446 0 : long nScrX = aScrPos.X();
447 0 : long nScrY = aScrPos.Y();
448 :
449 0 : SCCOL nCurX = pViewData->GetCurX();
450 0 : SCROW nCurY = pViewData->GetCurY();
451 0 : SCCOL nCurEndX = nCurX;
452 0 : SCROW nCurEndY = nCurY;
453 0 : pDoc->ExtendMerge( nCurX, nCurY, nCurEndX, nCurEndY, nTab );
454 : sal_Bool bCurVis = nCursorHideCount==0 &&
455 0 : ( nCurEndX+1 >= nX1 && nCurX <= nX2+1 && nCurEndY+1 >= nY1 && nCurY <= nY2+1 );
456 :
457 : // AutoFill-Anfasser
458 0 : if ( !bCurVis && nCursorHideCount==0 && bAutoMarkVisible && aAutoMarkPos.Tab() == nTab &&
459 0 : ( aAutoMarkPos.Col() != nCurX || aAutoMarkPos.Row() != nCurY ) )
460 : {
461 0 : SCCOL nHdlX = aAutoMarkPos.Col();
462 0 : SCROW nHdlY = aAutoMarkPos.Row();
463 0 : pDoc->ExtendMerge( nHdlX, nHdlY, nHdlX, nHdlY, nTab );
464 0 : bCurVis = ( nHdlX+1 >= nX1 && nHdlX <= nX2 && nHdlY+1 >= nY1 && nHdlY <= nY2 );
465 : // links und oben ist nicht betroffen
466 :
467 : //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
468 : }
469 :
470 0 : double nPPTX = pViewData->GetPPTX();
471 0 : double nPPTY = pViewData->GetPPTY();
472 :
473 0 : const ScViewOptions& rOpts = pViewData->GetOptions();
474 0 : sal_Bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
475 0 : sal_Bool bMarkClipped = rOpts.GetOption( VOPT_CLIPMARKS );
476 :
477 : // Datenblock
478 :
479 0 : ScTableInfo aTabInfo;
480 : pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
481 : nPPTX, nPPTY, false, bFormulaMode,
482 0 : &pViewData->GetMarkData() );
483 :
484 : //--------------------------------------------------------------------
485 :
486 0 : Fraction aZoomX = pViewData->GetZoomX();
487 0 : Fraction aZoomY = pViewData->GetZoomY();
488 : ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
489 : nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
490 0 : &aZoomX, &aZoomY );
491 :
492 0 : aOutputData.SetMirrorWidth( nMirrorWidth ); // needed for RTL
493 :
494 0 : std::auto_ptr< VirtualDevice > xFmtVirtDev;
495 0 : sal_Bool bLogicText = bTextWysiwyg; // call DrawStrings in logic MapMode?
496 :
497 0 : if ( bTextWysiwyg )
498 : {
499 : // use printer for text formatting
500 :
501 0 : OutputDevice* pFmtDev = pDoc->GetPrinter();
502 0 : pFmtDev->SetMapMode( pViewData->GetLogicMode(eWhich) );
503 0 : aOutputData.SetFmtDevice( pFmtDev );
504 : }
505 0 : else if ( aZoomX != aZoomY && pViewData->IsOle() )
506 : {
507 : // #i45033# For OLE inplace editing with different zoom factors,
508 : // use a virtual device with 1/100th mm as text formatting reference
509 :
510 0 : xFmtVirtDev.reset( new VirtualDevice );
511 0 : xFmtVirtDev->SetMapMode( MAP_100TH_MM );
512 0 : aOutputData.SetFmtDevice( xFmtVirtDev.get() );
513 :
514 0 : bLogicText = sal_True; // use logic MapMode
515 : }
516 :
517 0 : const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
518 0 : Color aGridColor( rColorCfg.GetColorValue( svtools::CALCGRID, false ).nColor );
519 0 : if ( aGridColor.GetColor() == COL_TRANSPARENT )
520 : {
521 : // use view options' grid color only if color config has "automatic" color
522 0 : aGridColor = rOpts.GetGridColor();
523 : }
524 :
525 0 : aOutputData.SetSyntaxMode ( pViewData->IsSyntaxMode() );
526 0 : aOutputData.SetGridColor ( aGridColor );
527 0 : aOutputData.SetShowNullValues ( rOpts.GetOption( VOPT_NULLVALS ) );
528 0 : aOutputData.SetShowFormulas ( bFormulaMode );
529 0 : aOutputData.SetShowSpellErrors ( pDoc->GetDocOptions().IsAutoSpell() );
530 0 : aOutputData.SetMarkClipped ( bMarkClipped );
531 :
532 0 : aOutputData.SetUseStyleColor( true ); // always set in table view
533 :
534 0 : aOutputData.SetEditObject( GetEditObject() );
535 0 : aOutputData.SetViewShell( pViewData->GetViewShell() );
536 :
537 0 : sal_Bool bGrid = rOpts.GetOption( VOPT_GRID ) && pViewData->GetShowGrid();
538 0 : sal_Bool bGridFirst = !rOpts.GetOption( VOPT_GRID_ONTOP );
539 :
540 0 : sal_Bool bPage = rOpts.GetOption( VOPT_PAGEBREAKS );
541 :
542 0 : if ( eMode == SC_UPDATE_CHANGED )
543 : {
544 0 : aOutputData.FindChanged();
545 0 : aOutputData.SetSingleGrid(sal_True);
546 : }
547 :
548 0 : sal_Bool bPageMode = pViewData->IsPagebreakMode();
549 0 : if (bPageMode) // nach FindChanged
550 : {
551 : // SetPagebreakMode initialisiert auch bPrinted Flags
552 0 : aOutputData.SetPagebreakMode( pViewData->GetView()->GetPageBreakData() );
553 : }
554 :
555 0 : EditView* pEditView = NULL;
556 0 : sal_Bool bEditMode = pViewData->HasEditView(eWhich);
557 0 : if ( bEditMode && pViewData->GetRefTabNo() == nTab )
558 : {
559 : SCCOL nEditCol;
560 : SCROW nEditRow;
561 0 : pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
562 0 : SCCOL nEditEndCol = pViewData->GetEditEndCol();
563 0 : SCROW nEditEndRow = pViewData->GetEditEndRow();
564 :
565 0 : if ( nEditEndCol >= nX1 && nEditCol <= nX2 && nEditEndRow >= nY1 && nEditRow <= nY2 )
566 0 : aOutputData.SetEditCell( nEditCol, nEditRow );
567 : else
568 0 : bEditMode = false;
569 : }
570 :
571 : // define drawing layer map mode and paint rectangle
572 0 : const MapMode aDrawMode = GetDrawMapMode();
573 0 : Rectangle aDrawingRectLogic;
574 :
575 : {
576 : // get drawing pixel rect
577 0 : Rectangle aDrawingRectPixel(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
578 :
579 : // correct for border (left/right)
580 0 : if(MAXCOL == nX2)
581 : {
582 0 : if(bLayoutRTL)
583 : {
584 0 : aDrawingRectPixel.Left() = 0L;
585 : }
586 : else
587 : {
588 0 : aDrawingRectPixel.Right() = GetOutputSizePixel().getWidth();
589 : }
590 : }
591 :
592 : // correct for border (bottom)
593 0 : if(MAXROW == nY2)
594 : {
595 0 : aDrawingRectPixel.Bottom() = GetOutputSizePixel().getHeight();
596 : }
597 :
598 : // get logic positions
599 0 : aDrawingRectLogic = PixelToLogic(aDrawingRectPixel, aDrawMode);
600 : }
601 :
602 0 : OutputDevice* pContentDev = this; // device for document content, used by overlay manager
603 0 : SdrPaintWindow* pTargetPaintWindow = 0; // #i74769# work with SdrPaintWindow directly
604 :
605 : {
606 : // init redraw
607 0 : ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
608 :
609 0 : if(pTabViewShell)
610 : {
611 0 : MapMode aCurrentMapMode(pContentDev->GetMapMode());
612 0 : pContentDev->SetMapMode(aDrawMode);
613 0 : SdrView* pDrawView = pTabViewShell->GetSdrView();
614 :
615 0 : if(pDrawView)
616 : {
617 : // #i74769# Use new BeginDrawLayers() interface
618 0 : Region aDrawingRegion(aDrawingRectLogic);
619 0 : pTargetPaintWindow = pDrawView->BeginDrawLayers(this, aDrawingRegion);
620 : OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
621 :
622 : // #i74769# get target device from SdrPaintWindow, this may be the prerender
623 : // device now, too.
624 0 : pContentDev = &(pTargetPaintWindow->GetTargetOutputDevice());
625 0 : aOutputData.SetContentDevice( pContentDev );
626 : }
627 :
628 0 : pContentDev->SetMapMode(aCurrentMapMode);
629 : }
630 : }
631 :
632 : // Rand (Wiese) (Pixel)
633 0 : if ( nX2==MAXCOL || nY2==MAXROW )
634 : {
635 : // save MapMode and set to pixel
636 0 : MapMode aCurrentMapMode(pContentDev->GetMapMode());
637 0 : pContentDev->SetMapMode(MAP_PIXEL);
638 :
639 0 : Rectangle aPixRect = Rectangle( Point(), GetOutputSizePixel() );
640 0 : pContentDev->SetFillColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
641 0 : pContentDev->SetLineColor();
642 0 : if ( nX2==MAXCOL )
643 : {
644 0 : Rectangle aDrawRect( aPixRect );
645 0 : if ( bLayoutRTL )
646 0 : aDrawRect.Right() = nScrX - 1;
647 : else
648 0 : aDrawRect.Left() = nScrX + aOutputData.GetScrW();
649 0 : if (aDrawRect.Right() >= aDrawRect.Left())
650 0 : pContentDev->DrawRect( aDrawRect );
651 : }
652 0 : if ( nY2==MAXROW )
653 : {
654 0 : Rectangle aDrawRect( aPixRect );
655 0 : aDrawRect.Top() = nScrY + aOutputData.GetScrH();
656 0 : if ( nX2==MAXCOL )
657 : {
658 : // no double painting of the corner
659 0 : if ( bLayoutRTL )
660 0 : aDrawRect.Left() = nScrX;
661 : else
662 0 : aDrawRect.Right() = nScrX + aOutputData.GetScrW() - 1;
663 : }
664 0 : if (aDrawRect.Bottom() >= aDrawRect.Top())
665 0 : pContentDev->DrawRect( aDrawRect );
666 : }
667 :
668 : // restore MapMode
669 0 : pContentDev->SetMapMode(aCurrentMapMode);
670 : }
671 :
672 0 : if ( pDoc->HasBackgroundDraw( nTab, aDrawingRectLogic ) )
673 : {
674 0 : pContentDev->SetMapMode(MAP_PIXEL);
675 0 : aOutputData.DrawClear();
676 :
677 : // Drawing Hintergrund
678 :
679 0 : pContentDev->SetMapMode(aDrawMode);
680 0 : DrawRedraw( aOutputData, eMode, SC_LAYER_BACK );
681 : }
682 : else
683 0 : aOutputData.SetSolidBackground(sal_True);
684 :
685 0 : pContentDev->SetMapMode(MAP_PIXEL);
686 0 : aOutputData.DrawDocumentBackground();
687 :
688 0 : if ( bGridFirst && ( bGrid || bPage ) )
689 0 : aOutputData.DrawGrid( bGrid, bPage );
690 :
691 0 : aOutputData.DrawBackground();
692 :
693 0 : if ( !bGridFirst && ( bGrid || bPage ) )
694 0 : aOutputData.DrawGrid( bGrid, bPage );
695 :
696 0 : if ( bPageMode )
697 : {
698 : // DrawPagePreview draws complete lines/page numbers, must always be clipped
699 0 : if ( aOutputData.SetChangedClip() )
700 : {
701 0 : DrawPagePreview(nX1,nY1,nX2,nY2, pContentDev);
702 0 : pContentDev->SetClipRegion();
703 : }
704 : }
705 :
706 0 : aOutputData.DrawShadow();
707 0 : aOutputData.DrawFrame();
708 0 : if ( !bLogicText )
709 0 : aOutputData.DrawStrings(false); // in pixel MapMode
710 :
711 : // edit cells and printer-metrics text must be before the buttons
712 : // (DataPilot buttons contain labels in UI font)
713 :
714 0 : pContentDev->SetMapMode(pViewData->GetLogicMode(eWhich));
715 0 : if ( bLogicText )
716 0 : aOutputData.DrawStrings(sal_True); // in logic MapMode if bTextWysiwyg is set
717 0 : aOutputData.DrawEdit(sal_True);
718 0 : pContentDev->SetMapMode(MAP_PIXEL);
719 :
720 : // Autofilter- und Pivot-Buttons
721 :
722 0 : DrawButtons( nX1, nX2, aTabInfo, pContentDev ); // Pixel
723 :
724 : // Notiz-Anzeiger
725 :
726 0 : if ( rOpts.GetOption( VOPT_NOTES ) )
727 0 : aOutputData.DrawNoteMarks();
728 :
729 0 : aOutputData.DrawClipMarks();
730 :
731 : // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
732 :
733 : //! Test, ob ChangeTrack-Anzeige aktiv ist
734 : //! Szenario-Rahmen per View-Optionen abschaltbar?
735 :
736 0 : SCTAB nTabCount = pDoc->GetTableCount();
737 0 : const std::vector<ScHighlightEntry> &rHigh = pViewData->GetView()->GetHighlightRanges();
738 0 : sal_Bool bHasScenario = ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) );
739 0 : sal_Bool bHasChange = ( pDoc->GetChangeTrack() != NULL );
740 :
741 0 : if ( bHasChange || bHasScenario || !rHigh.empty() )
742 : {
743 :
744 : //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
745 :
746 0 : sal_Bool bAny = sal_True;
747 0 : if (eMode == SC_UPDATE_CHANGED)
748 0 : bAny = aOutputData.SetChangedClip();
749 0 : if (bAny)
750 : {
751 0 : if ( bHasChange )
752 0 : aOutputData.DrawChangeTrack();
753 :
754 0 : if ( bHasScenario )
755 0 : lcl_DrawScenarioFrames( pContentDev, pViewData, eWhich, nX1,nY1,nX2,nY2 );
756 :
757 0 : lcl_DrawHighlight( aOutputData, pViewData, rHigh );
758 :
759 0 : if (eMode == SC_UPDATE_CHANGED)
760 0 : pContentDev->SetClipRegion();
761 : }
762 : }
763 :
764 : // Drawing Vordergrund
765 :
766 0 : pContentDev->SetMapMode(aDrawMode);
767 :
768 0 : DrawRedraw( aOutputData, eMode, SC_LAYER_FRONT );
769 0 : DrawRedraw( aOutputData, eMode, SC_LAYER_INTERN );
770 0 : DrawSdrGrid( aDrawingRectLogic, pContentDev );
771 :
772 0 : if (!bIsInScroll) // Drawing Markierungen
773 : {
774 0 : if(eMode == SC_UPDATE_CHANGED && aOutputData.SetChangedClip())
775 : {
776 0 : pContentDev->SetClipRegion();
777 : }
778 : }
779 :
780 0 : pContentDev->SetMapMode(MAP_PIXEL);
781 :
782 0 : if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() )
783 : {
784 0 : Color aRefColor( rColorCfg.GetColorValue(svtools::CALCREFERENCE).nColor );
785 0 : aOutputData.DrawRefMark( pViewData->GetRefStartX(), pViewData->GetRefStartY(),
786 0 : pViewData->GetRefEndX(), pViewData->GetRefEndY(),
787 0 : aRefColor, false );
788 : }
789 :
790 : // Range-Finder
791 :
792 0 : ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
793 0 : if (pHdl)
794 : {
795 0 : ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
796 0 : if ( pRangeFinder && !pRangeFinder->IsHidden() &&
797 0 : pRangeFinder->GetDocName() == pDocSh->GetTitle() )
798 : {
799 0 : sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
800 0 : for (sal_uInt16 i=0; i<nCount; i++)
801 : {
802 0 : ScRangeFindData* pData = pRangeFinder->GetObject(i);
803 :
804 0 : ScRange aRef = pData->aRef;
805 0 : aRef.Justify();
806 0 : if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
807 0 : aOutputData.DrawRefMark( aRef.aStart.Col(), aRef.aStart.Row(),
808 0 : aRef.aEnd.Col(), aRef.aEnd.Row(),
809 : Color( ScRangeFindList::GetColorName( i ) ),
810 0 : sal_True );
811 : }
812 : }
813 : }
814 :
815 : {
816 : // end redraw
817 0 : ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
818 :
819 0 : if(pTabViewShell)
820 : {
821 0 : MapMode aCurrentMapMode(pContentDev->GetMapMode());
822 0 : pContentDev->SetMapMode(aDrawMode);
823 0 : SdrView* pDrawView = pTabViewShell->GetSdrView();
824 :
825 0 : if(pDrawView)
826 : {
827 : // #i74769# work with SdrPaintWindow directly
828 0 : pDrawView->EndDrawLayers(*pTargetPaintWindow, true);
829 : }
830 :
831 0 : pContentDev->SetMapMode(aCurrentMapMode);
832 : }
833 : }
834 :
835 : // InPlace Edit-View
836 : // moved after EndDrawLayers() to get it outside the overlay buffer and
837 : // on top of everything
838 0 : if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
839 : {
840 : //! use pContentDev for EditView?
841 0 : SetMapMode(MAP_PIXEL);
842 0 : SCCOL nCol1 = pViewData->GetEditStartCol();
843 0 : SCROW nRow1 = pViewData->GetEditStartRow();
844 0 : SCCOL nCol2 = pViewData->GetEditEndCol();
845 0 : SCROW nRow2 = pViewData->GetEditEndRow();
846 0 : SetLineColor();
847 0 : SetFillColor( pEditView->GetBackgroundColor() );
848 0 : Point aStart = pViewData->GetScrPos( nCol1, nRow1, eWhich );
849 0 : Point aEnd = pViewData->GetScrPos( nCol2+1, nRow2+1, eWhich );
850 0 : aEnd.X() -= 2 * nLayoutSign; // don't overwrite grid
851 0 : aEnd.Y() -= 2;
852 0 : DrawRect( Rectangle( aStart,aEnd ) );
853 :
854 0 : SetMapMode(pViewData->GetLogicMode());
855 : pEditView->Paint( PixelToLogic( Rectangle( Point( nScrX, nScrY ),
856 0 : Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ) );
857 0 : SetMapMode(MAP_PIXEL);
858 : }
859 :
860 0 : if (pViewData->HasEditView(eWhich))
861 : {
862 : // flush OverlayManager before changing the MapMode
863 0 : flushOverlayManager();
864 :
865 : // set MapMode for text edit
866 0 : SetMapMode(pViewData->GetLogicMode());
867 : }
868 : else
869 0 : SetMapMode(aDrawMode);
870 :
871 0 : if ( pNoteMarker )
872 0 : pNoteMarker->Draw(); // ueber den Cursor, im Drawing-MapMode
873 :
874 : //
875 : // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
876 : // ist das jetzt durcheinandergekommen und es muss neu gemalt werden
877 : //
878 :
879 : OSL_ENSURE(nPaintCount, "nPaintCount falsch");
880 0 : --nPaintCount;
881 0 : if (!nPaintCount)
882 0 : CheckNeedsRepaint();
883 :
884 : // Flag drawn formula cells "unchanged".
885 0 : pDoc->ResetChanged(ScRange(nX1,nY1,nTab,nX2,nY2,nTab));
886 : }
887 :
888 0 : void ScGridWindow::CheckNeedsRepaint()
889 : {
890 : // called at the end of painting, and from timer after background text width calculation
891 :
892 0 : if (bNeedsRepaint)
893 : {
894 0 : bNeedsRepaint = false;
895 0 : if (aRepaintPixel.IsEmpty())
896 0 : Invalidate();
897 : else
898 0 : Invalidate(PixelToLogic(aRepaintPixel));
899 0 : aRepaintPixel = Rectangle();
900 :
901 : // selection function in status bar might also be invalid
902 0 : SfxBindings& rBindings = pViewData->GetBindings();
903 0 : rBindings.Invalidate( SID_STATUS_SUM );
904 0 : rBindings.Invalidate( SID_ATTR_SIZE );
905 0 : rBindings.Invalidate( SID_TABLE_CELL );
906 : }
907 0 : }
908 :
909 0 : void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, OutputDevice* pContentDev )
910 : {
911 0 : ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData();
912 0 : if (pPageData)
913 : {
914 0 : ScDocument* pDoc = pViewData->GetDocument();
915 0 : SCTAB nTab = pViewData->GetTabNo();
916 0 : Size aWinSize = GetOutputSizePixel();
917 0 : const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
918 0 : Color aManual( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
919 0 : Color aAutomatic( rColorCfg.GetColorValue(svtools::CALCPAGEBREAK).nColor );
920 :
921 0 : String aPageStr = ScGlobal::GetRscString( STR_PGNUM );
922 0 : if ( nPageScript == 0 )
923 : {
924 : // get script type of translated "Page" string only once
925 0 : nPageScript = pDoc->GetStringScriptType( aPageStr );
926 0 : if (nPageScript == 0)
927 0 : nPageScript = ScGlobal::GetDefaultScriptType();
928 : }
929 :
930 0 : Font aFont;
931 0 : ScEditEngineDefaulter* pEditEng = NULL;
932 0 : const ScPatternAttr& rDefPattern = ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
933 0 : if ( nPageScript == SCRIPTTYPE_LATIN )
934 : {
935 : // use single font and call DrawText directly
936 0 : rDefPattern.GetFont( aFont, SC_AUTOCOL_BLACK );
937 0 : aFont.SetColor( Color( COL_LIGHTGRAY ) );
938 : // font size is set as needed
939 : }
940 : else
941 : {
942 : // use EditEngine to draw mixed-script string
943 0 : pEditEng = new ScEditEngineDefaulter( EditEngine::CreatePool(), sal_True );
944 0 : pEditEng->SetRefMapMode( pContentDev->GetMapMode() );
945 0 : SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() );
946 0 : rDefPattern.FillEditItemSet( pEditDefaults );
947 0 : pEditDefaults->Put( SvxColorItem( Color( COL_LIGHTGRAY ), EE_CHAR_COLOR ) );
948 0 : pEditEng->SetDefaults( pEditDefaults );
949 : }
950 :
951 0 : sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
952 0 : for (sal_uInt16 nPos=0; nPos<nCount; nPos++)
953 : {
954 0 : ScPrintRangeData& rData = pPageData->GetData(nPos);
955 0 : ScRange aRange = rData.GetPrintRange();
956 0 : if ( aRange.aStart.Col() <= nX2+1 && aRange.aEnd.Col()+1 >= nX1 &&
957 0 : aRange.aStart.Row() <= nY2+1 && aRange.aEnd.Row()+1 >= nY1 )
958 : {
959 : // 3 Pixel Rahmen um den Druckbereich
960 : // (mittlerer Pixel auf den Gitterlinien)
961 :
962 0 : pContentDev->SetLineColor();
963 0 : if (rData.IsAutomatic())
964 0 : pContentDev->SetFillColor( aAutomatic );
965 : else
966 0 : pContentDev->SetFillColor( aManual );
967 :
968 : Point aStart = pViewData->GetScrPos(
969 0 : aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True );
970 : Point aEnd = pViewData->GetScrPos(
971 0 : aRange.aEnd.Col() + 1, aRange.aEnd.Row() + 1, eWhich, sal_True );
972 0 : aStart.X() -= 2;
973 0 : aStart.Y() -= 2;
974 :
975 : // Ueberlaeufe verhindern:
976 0 : if ( aStart.X() < -10 ) aStart.X() = -10;
977 0 : if ( aStart.Y() < -10 ) aStart.Y() = -10;
978 0 : if ( aEnd.X() > aWinSize.Width() + 10 )
979 0 : aEnd.X() = aWinSize.Width() + 10;
980 0 : if ( aEnd.Y() > aWinSize.Height() + 10 )
981 0 : aEnd.Y() = aWinSize.Height() + 10;
982 :
983 0 : pContentDev->DrawRect( Rectangle( aStart, Point(aEnd.X(),aStart.Y()+2) ) );
984 0 : pContentDev->DrawRect( Rectangle( aStart, Point(aStart.X()+2,aEnd.Y()) ) );
985 0 : pContentDev->DrawRect( Rectangle( Point(aStart.X(),aEnd.Y()-2), aEnd ) );
986 0 : pContentDev->DrawRect( Rectangle( Point(aEnd.X()-2,aStart.Y()), aEnd ) );
987 :
988 : // Seitenumbrueche
989 : //! anders darstellen (gestrichelt ????)
990 :
991 0 : size_t nColBreaks = rData.GetPagesX();
992 0 : const SCCOL* pColEnd = rData.GetPageEndX();
993 : size_t nColPos;
994 0 : for (nColPos=0; nColPos+1<nColBreaks; nColPos++)
995 : {
996 0 : SCCOL nBreak = pColEnd[nColPos]+1;
997 0 : if ( nBreak >= nX1 && nBreak <= nX2+1 )
998 : {
999 : //! hidden suchen
1000 0 : if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL)
1001 0 : pContentDev->SetFillColor( aManual );
1002 : else
1003 0 : pContentDev->SetFillColor( aAutomatic );
1004 : Point aBreak = pViewData->GetScrPos(
1005 0 : nBreak, aRange.aStart.Row(), eWhich, sal_True );
1006 0 : pContentDev->DrawRect( Rectangle( aBreak.X()-1, aStart.Y(), aBreak.X(), aEnd.Y() ) );
1007 : }
1008 : }
1009 :
1010 0 : size_t nRowBreaks = rData.GetPagesY();
1011 0 : const SCROW* pRowEnd = rData.GetPageEndY();
1012 : size_t nRowPos;
1013 0 : for (nRowPos=0; nRowPos+1<nRowBreaks; nRowPos++)
1014 : {
1015 0 : SCROW nBreak = pRowEnd[nRowPos]+1;
1016 0 : if ( nBreak >= nY1 && nBreak <= nY2+1 )
1017 : {
1018 : //! hidden suchen
1019 0 : if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL)
1020 0 : pContentDev->SetFillColor( aManual );
1021 : else
1022 0 : pContentDev->SetFillColor( aAutomatic );
1023 : Point aBreak = pViewData->GetScrPos(
1024 0 : aRange.aStart.Col(), nBreak, eWhich, sal_True );
1025 0 : pContentDev->DrawRect( Rectangle( aStart.X(), aBreak.Y()-1, aEnd.X(), aBreak.Y() ) );
1026 : }
1027 : }
1028 :
1029 : // Seitenzahlen
1030 :
1031 0 : SCROW nPrStartY = aRange.aStart.Row();
1032 0 : for (nRowPos=0; nRowPos<nRowBreaks; nRowPos++)
1033 : {
1034 0 : SCROW nPrEndY = pRowEnd[nRowPos];
1035 0 : if ( nPrEndY >= nY1 && nPrStartY <= nY2 )
1036 : {
1037 0 : SCCOL nPrStartX = aRange.aStart.Col();
1038 0 : for (nColPos=0; nColPos<nColBreaks; nColPos++)
1039 : {
1040 0 : SCCOL nPrEndX = pColEnd[nColPos];
1041 0 : if ( nPrEndX >= nX1 && nPrStartX <= nX2 )
1042 : {
1043 : Point aPageStart = pViewData->GetScrPos(
1044 0 : nPrStartX, nPrStartY, eWhich, sal_True );
1045 : Point aPageEnd = pViewData->GetScrPos(
1046 0 : nPrEndX+1,nPrEndY+1, eWhich, sal_True );
1047 :
1048 0 : long nPageNo = rData.GetFirstPage();
1049 0 : if ( rData.IsTopDown() )
1050 0 : nPageNo += ((long)nColPos)*nRowBreaks+nRowPos;
1051 : else
1052 0 : nPageNo += ((long)nRowPos)*nColBreaks+nColPos;
1053 :
1054 0 : String aThisPageStr = aPageStr; // Don't modify the original string.
1055 0 : aThisPageStr.SearchAndReplaceAscii("%1", String::CreateFromInt32(nPageNo));
1056 :
1057 0 : if ( pEditEng )
1058 : {
1059 : // find right font size with EditEngine
1060 0 : long nHeight = 100;
1061 0 : pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
1062 0 : pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1063 0 : pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1064 0 : pEditEng->SetText( aThisPageStr );
1065 0 : Size aSize100( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
1066 :
1067 : // 40% of width or 60% of height
1068 0 : long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
1069 0 : long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
1070 0 : nHeight = Min(nSizeX,nSizeY);
1071 0 : pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
1072 0 : pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1073 0 : pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1074 :
1075 : // centered output with EditEngine
1076 0 : Size aTextSize( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
1077 0 : Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
1078 0 : (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
1079 0 : pEditEng->Draw( pContentDev, aPos );
1080 : }
1081 : else
1082 : {
1083 : // find right font size for DrawText
1084 0 : aFont.SetSize( Size( 0,100 ) );
1085 0 : pContentDev->SetFont( aFont );
1086 0 : Size aSize100( pContentDev->GetTextWidth( aThisPageStr ), pContentDev->GetTextHeight() );
1087 :
1088 : // 40% of width or 60% of height
1089 0 : long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
1090 0 : long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
1091 0 : aFont.SetSize( Size( 0,Min(nSizeX,nSizeY) ) );
1092 0 : pContentDev->SetFont( aFont );
1093 :
1094 : // centered output with DrawText
1095 0 : Size aTextSize( pContentDev->GetTextWidth( aThisPageStr ), pContentDev->GetTextHeight() );
1096 0 : Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
1097 0 : (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
1098 0 : pContentDev->DrawText( aPos, aThisPageStr );
1099 0 : }
1100 : }
1101 0 : nPrStartX = nPrEndX + 1;
1102 : }
1103 : }
1104 0 : nPrStartY = nPrEndY + 1;
1105 : }
1106 : }
1107 : }
1108 :
1109 0 : delete pEditEng;
1110 : }
1111 0 : }
1112 :
1113 0 : void ScGridWindow::DrawButtons( SCCOL nX1, SCCOL nX2, ScTableInfo& rTabInfo, OutputDevice* pContentDev)
1114 : {
1115 0 : aComboButton.SetOutputDevice( pContentDev );
1116 :
1117 0 : ScDocument* pDoc = pViewData->GetDocument();
1118 0 : ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY(), pDoc);
1119 :
1120 : SCCOL nCol;
1121 : SCROW nRow;
1122 : SCSIZE nArrY;
1123 : SCSIZE nQuery;
1124 0 : SCTAB nTab = pViewData->GetTabNo();
1125 0 : ScDBData* pDBData = NULL;
1126 0 : ScQueryParam* pQueryParam = NULL;
1127 :
1128 0 : RowInfo* pRowInfo = rTabInfo.mpRowInfo;
1129 0 : sal_uInt16 nArrCount = rTabInfo.mnArrCount;
1130 :
1131 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1132 :
1133 0 : Point aOldPos = aComboButton.GetPosPixel(); // Zustand fuer MouseDown/Up
1134 0 : Size aOldSize = aComboButton.GetSizePixel(); // merken
1135 :
1136 0 : for (nArrY=1; nArrY+1<nArrCount; nArrY++)
1137 : {
1138 0 : if ( pRowInfo[nArrY].bAutoFilter && pRowInfo[nArrY].bChanged )
1139 : {
1140 0 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1141 :
1142 0 : nRow = pThisRowInfo->nRowNo;
1143 :
1144 :
1145 0 : for (nCol=nX1; nCol<=nX2; nCol++)
1146 : {
1147 0 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
1148 0 : if ( pInfo->bAutoFilter && !pInfo->bHOverlapped && !pInfo->bVOverlapped )
1149 : {
1150 0 : if (!pQueryParam)
1151 0 : pQueryParam = new ScQueryParam;
1152 :
1153 0 : sal_Bool bNewData = sal_True;
1154 0 : if (pDBData)
1155 : {
1156 : SCCOL nStartCol;
1157 : SCROW nStartRow;
1158 : SCCOL nEndCol;
1159 : SCROW nEndRow;
1160 : SCTAB nAreaTab;
1161 0 : pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
1162 0 : if ( nCol >= nStartCol && nCol <= nEndCol &&
1163 : nRow >= nStartRow && nRow <= nEndRow )
1164 0 : bNewData = false;
1165 : }
1166 0 : if (bNewData)
1167 : {
1168 0 : pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1169 0 : if (pDBData)
1170 0 : pDBData->GetQueryParam( *pQueryParam );
1171 : else
1172 : {
1173 : // can also be part of DataPilot table
1174 : // OSL_FAIL("Auto-Filter-Button ohne DBData");
1175 : }
1176 : }
1177 :
1178 : // pQueryParam kann nur MAXQUERY Eintraege enthalten
1179 :
1180 0 : sal_Bool bSimpleQuery = sal_True;
1181 0 : sal_Bool bColumnFound = false;
1182 0 : if (!pQueryParam->bInplace)
1183 0 : bSimpleQuery = false;
1184 0 : SCSIZE nCount = pQueryParam->GetEntryCount();
1185 0 : for (nQuery = 0; nQuery < nCount && bSimpleQuery; ++nQuery)
1186 0 : if (pQueryParam->GetEntry(nQuery).bDoQuery)
1187 : {
1188 : // hier nicht auf EQUAL beschraenken
1189 : // (auch bei ">1" soll der Spaltenkopf blau werden)
1190 :
1191 0 : if (pQueryParam->GetEntry(nQuery).nField == nCol)
1192 0 : bColumnFound = sal_True;
1193 0 : if (nQuery > 0)
1194 0 : if (pQueryParam->GetEntry(nQuery).eConnect != SC_AND)
1195 0 : bSimpleQuery = false;
1196 : }
1197 :
1198 0 : bool bArrowState = bSimpleQuery && bColumnFound;
1199 : long nSizeX;
1200 : long nSizeY;
1201 0 : pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
1202 0 : Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
1203 :
1204 0 : aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1), bLayoutRTL);
1205 0 : aCellBtn.setPopupLeft(bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL
1206 0 : aCellBtn.setDrawBaseButton(false);
1207 0 : aCellBtn.setDrawPopupButton(true);
1208 0 : aCellBtn.setHasHiddenMember(bArrowState);
1209 0 : aCellBtn.draw();
1210 : }
1211 : }
1212 : }
1213 :
1214 0 : if ( pRowInfo[nArrY].bPivotButton && pRowInfo[nArrY].bChanged )
1215 : {
1216 0 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1217 0 : nRow = pThisRowInfo->nRowNo;
1218 0 : for (nCol=nX1; nCol<=nX2; nCol++)
1219 : {
1220 0 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
1221 0 : if (pInfo->bHOverlapped || pInfo->bVOverlapped)
1222 0 : continue;
1223 :
1224 0 : Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
1225 : long nSizeX;
1226 : long nSizeY;
1227 0 : pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
1228 0 : long nPosX = aScrPos.X();
1229 0 : long nPosY = aScrPos.Y();
1230 : // bLayoutRTL is handled in setBoundingBox
1231 :
1232 0 : String aStr;
1233 0 : pDoc->GetString(nCol, nRow, nTab, aStr);
1234 0 : aCellBtn.setText(aStr);
1235 0 : aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL);
1236 0 : aCellBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
1237 0 : aCellBtn.setDrawBaseButton(pInfo->bPivotButton);
1238 0 : aCellBtn.setDrawPopupButton(pInfo->bPivotPopupButton);
1239 0 : aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
1240 0 : aCellBtn.draw();
1241 0 : }
1242 : }
1243 :
1244 0 : if ( bListValButton && pRowInfo[nArrY].nRowNo == aListValPos.Row() && pRowInfo[nArrY].bChanged )
1245 : {
1246 0 : Rectangle aRect = GetListValButtonRect( aListValPos );
1247 0 : aComboButton.SetPosPixel( aRect.TopLeft() );
1248 0 : aComboButton.SetSizePixel( aRect.GetSize() );
1249 0 : pContentDev->SetClipRegion( aRect );
1250 0 : aComboButton.Draw( false, false );
1251 0 : pContentDev->SetClipRegion(); // always called from Draw() without clip region
1252 0 : aComboButton.SetPosPixel( aOldPos ); // restore old state
1253 0 : aComboButton.SetSizePixel( aOldSize ); // for MouseUp/Down (AutoFilter)
1254 : }
1255 : }
1256 :
1257 0 : delete pQueryParam;
1258 0 : aComboButton.SetOutputDevice( this );
1259 0 : }
1260 :
1261 0 : Rectangle ScGridWindow::GetListValButtonRect( const ScAddress& rButtonPos )
1262 : {
1263 0 : ScDocument* pDoc = pViewData->GetDocument();
1264 0 : SCTAB nTab = pViewData->GetTabNo();
1265 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1266 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1267 :
1268 0 : ScDDComboBoxButton aButton( this ); // for optimal size
1269 0 : Size aBtnSize = aButton.GetSizePixel();
1270 :
1271 0 : SCCOL nCol = rButtonPos.Col();
1272 0 : SCROW nRow = rButtonPos.Row();
1273 :
1274 : long nCellSizeX; // width of this cell, including merged
1275 : long nDummy;
1276 0 : pViewData->GetMergeSizePixel( nCol, nRow, nCellSizeX, nDummy );
1277 :
1278 : // for height, only the cell's row is used, excluding merged cells
1279 0 : long nCellSizeY = ScViewData::ToPixel( pDoc->GetRowHeight( nRow, nTab ), pViewData->GetPPTY() );
1280 0 : long nAvailable = nCellSizeX;
1281 :
1282 : // left edge of next cell if there is a non-hidden next column
1283 0 : SCCOL nNextCol = nCol + 1;
1284 0 : const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(pDoc->GetAttr( nCol,nRow,nTab, ATTR_MERGE ));
1285 0 : if ( pMerge->GetColMerge() > 1 )
1286 0 : nNextCol = nCol + pMerge->GetColMerge(); // next cell after the merged area
1287 0 : while ( nNextCol <= MAXCOL && pDoc->ColHidden(nNextCol, nTab) )
1288 0 : ++nNextCol;
1289 0 : sal_Bool bNextCell = ( nNextCol <= MAXCOL );
1290 0 : if ( bNextCell )
1291 0 : nAvailable = ScViewData::ToPixel( pDoc->GetColWidth( nNextCol, nTab ), pViewData->GetPPTX() );
1292 :
1293 0 : if ( nAvailable < aBtnSize.Width() )
1294 0 : aBtnSize.Width() = nAvailable;
1295 0 : if ( nCellSizeY < aBtnSize.Height() )
1296 0 : aBtnSize.Height() = nCellSizeY;
1297 :
1298 0 : Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich, sal_True );
1299 0 : aPos.X() += nCellSizeX * nLayoutSign; // start of next cell
1300 0 : if (!bNextCell)
1301 0 : aPos.X() -= aBtnSize.Width() * nLayoutSign; // right edge of cell if next cell not available
1302 0 : aPos.Y() += nCellSizeY - aBtnSize.Height();
1303 : // X remains at the left edge
1304 :
1305 0 : if ( bLayoutRTL )
1306 0 : aPos.X() -= aBtnSize.Width()-1; // align right edge of button with cell border
1307 :
1308 0 : return Rectangle( aPos, aBtnSize );
1309 : }
1310 :
1311 0 : bool ScGridWindow::IsAutoFilterActive( SCCOL nCol, SCROW nRow, SCTAB nTab )
1312 : {
1313 0 : ScDocument* pDoc = pViewData->GetDocument();
1314 0 : ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1315 0 : ScQueryParam aQueryParam;
1316 :
1317 0 : if ( pDBData )
1318 0 : pDBData->GetQueryParam( aQueryParam );
1319 : else
1320 : {
1321 : OSL_FAIL("Auto-Filter-Button ohne DBData");
1322 : }
1323 :
1324 0 : bool bSimpleQuery = true;
1325 0 : bool bColumnFound = false;
1326 : SCSIZE nQuery;
1327 :
1328 0 : if ( !aQueryParam.bInplace )
1329 0 : bSimpleQuery = false;
1330 :
1331 : // aQueryParam kann nur MAXQUERY Eintraege enthalten
1332 :
1333 0 : SCSIZE nCount = aQueryParam.GetEntryCount();
1334 0 : for (nQuery = 0; nQuery < nCount && bSimpleQuery; ++nQuery)
1335 0 : if ( aQueryParam.GetEntry(nQuery).bDoQuery )
1336 : {
1337 0 : if (aQueryParam.GetEntry(nQuery).nField == nCol)
1338 0 : bColumnFound = sal_True;
1339 :
1340 0 : if (nQuery > 0)
1341 0 : if (aQueryParam.GetEntry(nQuery).eConnect != SC_AND)
1342 0 : bSimpleQuery = false;
1343 : }
1344 :
1345 0 : return ( bSimpleQuery && bColumnFound );
1346 : }
1347 :
1348 0 : void ScGridWindow::GetSelectionRects( ::std::vector< Rectangle >& rPixelRects )
1349 : {
1350 0 : ScMarkData aMultiMark( pViewData->GetMarkData() );
1351 0 : aMultiMark.SetMarking( false );
1352 0 : aMultiMark.MarkToMulti();
1353 :
1354 0 : ScDocument* pDoc = pViewData->GetDocument();
1355 0 : SCTAB nTab = pViewData->GetTabNo();
1356 :
1357 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1358 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1359 :
1360 0 : if ( !aMultiMark.IsMultiMarked() )
1361 : return;
1362 :
1363 0 : ScRange aMultiRange;
1364 0 : aMultiMark.GetMultiMarkArea( aMultiRange );
1365 0 : SCCOL nX1 = aMultiRange.aStart.Col();
1366 0 : SCROW nY1 = aMultiRange.aStart.Row();
1367 0 : SCCOL nX2 = aMultiRange.aEnd.Col();
1368 0 : SCROW nY2 = aMultiRange.aEnd.Row();
1369 :
1370 0 : PutInOrder( nX1, nX2 );
1371 0 : PutInOrder( nY1, nY2 );
1372 :
1373 0 : sal_Bool bTestMerge = sal_True;
1374 0 : bool bRepeat = true;
1375 :
1376 0 : SCCOL nTestX2 = nX2;
1377 0 : SCROW nTestY2 = nY2;
1378 0 : if (bTestMerge)
1379 0 : pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
1380 :
1381 0 : SCCOL nPosX = pViewData->GetPosX( eHWhich );
1382 0 : SCROW nPosY = pViewData->GetPosY( eVWhich );
1383 0 : if (nTestX2 < nPosX || nTestY2 < nPosY)
1384 : return; // unsichtbar
1385 0 : SCCOL nRealX1 = nX1;
1386 0 : if (nX1 < nPosX)
1387 0 : nX1 = nPosX;
1388 0 : if (nY1 < nPosY)
1389 0 : nY1 = nPosY;
1390 :
1391 0 : SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
1392 0 : if (nXRight > MAXCOL) nXRight = MAXCOL;
1393 0 : SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
1394 0 : if (nYBottom > MAXROW) nYBottom = MAXROW;
1395 :
1396 0 : if (nX1 > nXRight || nY1 > nYBottom)
1397 : return; // unsichtbar
1398 0 : if (nX2 > nXRight) nX2 = nXRight;
1399 0 : if (nY2 > nYBottom) nY2 = nYBottom;
1400 :
1401 0 : double nPPTX = pViewData->GetPPTX();
1402 0 : double nPPTY = pViewData->GetPPTY();
1403 :
1404 0 : ScInvertMerger aInvert( &rPixelRects );
1405 :
1406 0 : Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
1407 0 : long nScrY = aScrPos.Y();
1408 0 : sal_Bool bWasHidden = false;
1409 0 : for (SCROW nY=nY1; nY<=nY2; nY++)
1410 : {
1411 0 : sal_Bool bFirstRow = ( nY == nPosY ); // first visible row?
1412 0 : sal_Bool bDoHidden = false; // versteckte nachholen ?
1413 0 : sal_uInt16 nHeightTwips = pDoc->GetRowHeight( nY,nTab );
1414 0 : sal_Bool bDoRow = ( nHeightTwips != 0 );
1415 0 : if (bDoRow)
1416 : {
1417 0 : if (bTestMerge)
1418 0 : if (bWasHidden) // auf versteckte zusammengefasste testen
1419 : {
1420 0 : bDoHidden = sal_True;
1421 0 : bDoRow = sal_True;
1422 : }
1423 :
1424 0 : bWasHidden = false;
1425 : }
1426 : else
1427 : {
1428 0 : bWasHidden = sal_True;
1429 0 : if (bTestMerge)
1430 0 : if (nY==nY2)
1431 0 : bDoRow = sal_True; // letzte Zeile aus Block
1432 : }
1433 :
1434 0 : if ( bDoRow )
1435 : {
1436 0 : SCCOL nLoopEndX = nX2;
1437 0 : if (nX2 < nX1) // Rest von zusammengefasst
1438 : {
1439 0 : SCCOL nStartX = nX1;
1440 0 : while ( ((const ScMergeFlagAttr*)pDoc->
1441 0 : GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() )
1442 0 : --nStartX;
1443 0 : if (nStartX <= nX2)
1444 0 : nLoopEndX = nX1;
1445 : }
1446 :
1447 0 : long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1;
1448 0 : long nScrX = aScrPos.X();
1449 0 : for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
1450 : {
1451 0 : long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX );
1452 0 : if ( nWidth > 0 )
1453 : {
1454 0 : long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
1455 0 : if (bTestMerge)
1456 : {
1457 0 : SCROW nThisY = nY;
1458 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
1459 : const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->
1460 0 : GetItem(ATTR_MERGE_FLAG);
1461 0 : if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
1462 : {
1463 0 : while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
1464 0 : (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) )
1465 : {
1466 0 : --nThisY;
1467 0 : pPattern = pDoc->GetPattern( nX, nThisY, nTab );
1468 0 : pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1469 : }
1470 : }
1471 :
1472 : // nur Rest von zusammengefasster zu sehen ?
1473 0 : SCCOL nThisX = nX;
1474 0 : if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
1475 : {
1476 0 : while ( pMergeFlag->IsHorOverlapped() )
1477 : {
1478 0 : --nThisX;
1479 0 : pPattern = pDoc->GetPattern( nThisX, nThisY, nTab );
1480 0 : pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1481 : }
1482 : }
1483 :
1484 0 : if ( aMultiMark.IsCellMarked( nThisX, nThisY, sal_True ) == bRepeat )
1485 : {
1486 0 : if ( !pMergeFlag->IsOverlapped() )
1487 : {
1488 0 : ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
1489 0 : if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
1490 : {
1491 : Point aEndPos = pViewData->GetScrPos(
1492 0 : nThisX + pMerge->GetColMerge(),
1493 0 : nThisY + pMerge->GetRowMerge(), eWhich );
1494 0 : if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
1495 : {
1496 : aInvert.AddRect( Rectangle( nScrX,nScrY,
1497 0 : aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
1498 : }
1499 : }
1500 0 : else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
1501 : {
1502 0 : aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
1503 : }
1504 : }
1505 : }
1506 : }
1507 : else // !bTestMerge
1508 : {
1509 0 : if ( aMultiMark.IsCellMarked( nX, nY, sal_True ) == bRepeat &&
1510 : nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
1511 : {
1512 0 : aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
1513 : }
1514 : }
1515 :
1516 0 : nScrX = nEndX + nLayoutSign;
1517 : }
1518 : }
1519 0 : nScrY = nEndY + 1;
1520 : }
1521 0 : }
1522 : }
1523 :
1524 : // -------------------------------------------------------------------------
1525 :
1526 0 : void ScGridWindow::DataChanged( const DataChangedEvent& rDCEvt )
1527 : {
1528 0 : Window::DataChanged(rDCEvt);
1529 :
1530 0 : if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
1531 0 : (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
1532 0 : (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1533 0 : (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1534 0 : ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1535 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1536 : {
1537 0 : if ( rDCEvt.GetType() == DATACHANGED_FONTS && eWhich == pViewData->GetActivePart() )
1538 0 : pViewData->GetDocShell()->UpdateFontList();
1539 :
1540 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1541 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1542 : {
1543 0 : if ( eWhich == pViewData->GetActivePart() ) // only once for the view
1544 : {
1545 0 : ScTabView* pView = pViewData->GetView();
1546 :
1547 : // update scale in case the UI ScreenZoom has changed
1548 0 : ScGlobal::UpdatePPT(this);
1549 0 : pView->RecalcPPT();
1550 :
1551 : // RepeatResize in case scroll bar sizes have changed
1552 0 : pView->RepeatResize();
1553 0 : pView->UpdateAllOverlays();
1554 :
1555 : // invalidate cell attribs in input handler, in case the
1556 : // EditEngine BackgroundColor has to be changed
1557 0 : if ( pViewData->IsActive() )
1558 : {
1559 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1560 0 : if (pHdl)
1561 0 : pHdl->ForgetLastPattern();
1562 : }
1563 : }
1564 : }
1565 :
1566 0 : Invalidate();
1567 : }
1568 15 : }
1569 :
1570 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|