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