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