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 <vcl/svapp.hxx>
21 :
22 : #include <pagepreviewlayout.hxx>
23 : #include <prevwpage.hxx>
24 :
25 : #include <algorithm>
26 : #include <tools/fract.hxx>
27 : #include <vcl/window.hxx>
28 : #include <vcl/settings.hxx>
29 :
30 : #include <rootfrm.hxx>
31 : #include <pagefrm.hxx>
32 : #include <viewsh.hxx>
33 : #include <viewimp.hxx>
34 : #include <viewopt.hxx>
35 : #include <swregion.hxx>
36 : #include <comcore.hrc>
37 : #include <frmtool.hxx>
38 : #include <sfx2/zoomitem.hxx>
39 : #include <printdata.hxx>
40 : #include <paintfrm.hxx>
41 :
42 : #include <IDocumentDeviceAccess.hxx>
43 :
44 : // methods to initialize page preview layout
45 :
46 0 : SwPagePreviewLayout::SwPagePreviewLayout( SwViewShell& _rParentViewShell,
47 : const SwRootFrm& _rLayoutRootFrm )
48 : : mnXFree ( 4*142 ),
49 : mnYFree ( 4*142 ),
50 : mrParentViewShell( _rParentViewShell ),
51 0 : mrLayoutRootFrm ( _rLayoutRootFrm )
52 : {
53 0 : _Clear();
54 :
55 : // OD 2004-03-05 #i18143#
56 0 : mbBookPreview = false;
57 0 : mbBookPreviewModeToggled = false;
58 :
59 0 : mbPrintEmptyPages = mrParentViewShell.getIDocumentDeviceAccess()->getPrintData().IsPrintEmptyPages();
60 0 : }
61 :
62 0 : void SwPagePreviewLayout::_Clear()
63 : {
64 0 : mbLayoutInfoValid = mbLayoutSizesValid = mbPaintInfoValid = false;
65 :
66 0 : maWinSize.Width() = 0;
67 0 : maWinSize.Height() = 0;
68 0 : mnCols = mnRows = 0;
69 :
70 0 : _ClearPreviewLayoutSizes();
71 :
72 0 : mbDoesLayoutRowsFitIntoWindow = false;
73 0 : mbDoesLayoutColsFitIntoWindow = false;
74 :
75 0 : mnPaintPhyStartPageNum = 0;
76 0 : mnPaintStartCol = mnPaintStartRow = 0;
77 0 : mbNoPageVisible = false;
78 0 : maPaintStartPageOffset.X() = 0;
79 0 : maPaintStartPageOffset.Y() = 0;
80 0 : maPaintPreviewDocOffset.X() = 0;
81 0 : maPaintPreviewDocOffset.Y() = 0;
82 0 : maAdditionalPaintOffset.X() = 0;
83 0 : maAdditionalPaintOffset.Y() = 0;
84 0 : maPaintedPreviewDocRect.Left() = 0;
85 0 : maPaintedPreviewDocRect.Top() = 0;
86 0 : maPaintedPreviewDocRect.Right() = 0;
87 0 : maPaintedPreviewDocRect.Bottom() = 0;
88 0 : mnSelectedPageNum = 0;
89 0 : _ClearPreviewPageData();
90 :
91 : // OD 07.11.2003 #i22014#
92 0 : mbInPaint = false;
93 0 : mbNewLayoutDuringPaint = false;
94 0 : }
95 :
96 0 : void SwPagePreviewLayout::_ClearPreviewLayoutSizes()
97 : {
98 0 : mnPages = 0;
99 :
100 0 : maMaxPageSize.Width() = 0;
101 0 : maMaxPageSize.Height() = 0;
102 0 : maPreviewDocRect.Left() = maPreviewDocRect.Top() = 0;
103 0 : maPreviewDocRect.Right() = maPreviewDocRect.Bottom() = 0;
104 0 : mnColWidth = mnRowHeight = 0;
105 0 : mnPreviewLayoutWidth = mnPreviewLayoutHeight = 0;
106 0 : }
107 :
108 0 : void SwPagePreviewLayout::_ClearPreviewPageData()
109 : {
110 0 : for ( std::vector<PreviewPage*>::iterator aPageDelIter = maPreviewPages.begin();
111 0 : aPageDelIter != maPreviewPages.end();
112 : ++aPageDelIter )
113 : {
114 0 : delete (*aPageDelIter);
115 : }
116 0 : maPreviewPages.clear();
117 0 : }
118 :
119 : /** calculate page preview layout sizes
120 :
121 : OD 18.12.2002 #103492#
122 : */
123 0 : void SwPagePreviewLayout::_CalcPreviewLayoutSizes()
124 : {
125 : // calculate maximal page size; calculate also number of pages
126 :
127 0 : const SwPageFrm* pPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower());
128 0 : while ( pPage )
129 : {
130 0 : if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() )
131 : {
132 0 : pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
133 0 : continue;
134 : }
135 :
136 0 : ++mnPages;
137 0 : pPage->Calc();
138 0 : const Size& rPageSize = pPage->Frm().SSize();
139 0 : if ( rPageSize.Width() > maMaxPageSize.Width() )
140 0 : maMaxPageSize.Width() = rPageSize.Width();
141 0 : if ( rPageSize.Height() > maMaxPageSize.Height() )
142 0 : maMaxPageSize.Height() = rPageSize.Height();
143 0 : pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
144 : }
145 : // calculate and set column width and row height
146 0 : mnColWidth = maMaxPageSize.Width() + mnXFree;
147 0 : mnRowHeight = maMaxPageSize.Height() + mnYFree;
148 :
149 : // calculate and set preview layout width and height
150 0 : mnPreviewLayoutWidth = mnCols * mnColWidth + mnXFree;
151 0 : mnPreviewLayoutHeight = mnRows * mnRowHeight + mnYFree;
152 :
153 : // calculate document rectangle in preview layout
154 : {
155 0 : Size aDocSize;
156 : // document width
157 0 : aDocSize.Width() = mnPreviewLayoutWidth;
158 :
159 : // document height
160 : // determine number of rows needed for <nPages> in preview layout
161 : // OD 19.02.2003 #107369# - use method <GetRowOfPage(..)>.
162 0 : const sal_uInt16 nDocRows = GetRowOfPage( mnPages );
163 0 : aDocSize.Height() = nDocRows * maMaxPageSize.Height() +
164 0 : (nDocRows+1) * mnYFree;
165 0 : maPreviewDocRect.SetPos( Point( 0, 0 ) );
166 0 : maPreviewDocRect.SetSize( aDocSize );
167 : }
168 0 : }
169 :
170 : /** init page preview layout
171 :
172 : OD 11.12.2002 #103492#
173 : initialize the page preview settings for a given layout.
174 :
175 : side effects:
176 : (1) If parameter <_bCalcScale> is true, mapping mode with calculated
177 : scaling is set at the output device and the zoom at the view options of
178 : the given view shell is set with the calculated scaling.
179 : */
180 0 : bool SwPagePreviewLayout::Init( const sal_uInt16 _nCols,
181 : const sal_uInt16 _nRows,
182 : const Size& _rPxWinSize,
183 : const bool _bCalcScale
184 : )
185 : {
186 : // check environment and parameters
187 : {
188 0 : bool bColsRowsValid = (_nCols != 0) && (_nRows != 0);
189 : OSL_ENSURE( bColsRowsValid, "preview layout parameters not correct - preview layout can *not* be initialized" );
190 0 : if ( !bColsRowsValid )
191 0 : return false;
192 :
193 0 : bool bPxWinSizeValid = (_rPxWinSize.Width() >= 0) &&
194 0 : (_rPxWinSize.Height() >= 0);
195 : OSL_ENSURE( bPxWinSizeValid, "no window size - preview layout can *not* be initialized" );
196 0 : if ( !bPxWinSizeValid )
197 0 : return false;
198 : }
199 :
200 : // environment and parameters ok
201 :
202 : // clear existing preview settings
203 0 : _Clear();
204 :
205 : // set layout information columns and rows
206 0 : mnCols = _nCols;
207 0 : mnRows = _nRows;
208 :
209 0 : _CalcPreviewLayoutSizes();
210 :
211 : // validate layout information
212 0 : mbLayoutInfoValid = true;
213 :
214 0 : if ( _bCalcScale )
215 : {
216 : // calculate scaling
217 0 : MapMode aMapMode( MAP_TWIP );
218 0 : Size aWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize, aMapMode );
219 0 : Fraction aXScale( aWinSize.Width(), mnPreviewLayoutWidth );
220 0 : Fraction aYScale( aWinSize.Height(), mnPreviewLayoutHeight );
221 0 : if( aXScale < aYScale )
222 0 : aYScale = aXScale;
223 : {
224 : // adjust scaling for Drawing layer.
225 0 : aYScale *= Fraction( 1000, 1 );
226 0 : long nNewNuminator = aYScale.operator long();
227 0 : if( nNewNuminator < 1 )
228 0 : nNewNuminator = 1;
229 0 : aYScale = Fraction( nNewNuminator, 1000 );
230 : // propagate scaling as zoom percentage to view options for font cache
231 0 : _ApplyNewZoomAtViewShell( static_cast<sal_uInt8>(nNewNuminator/10) );
232 : }
233 0 : aMapMode.SetScaleY( aYScale );
234 0 : aMapMode.SetScaleX( aYScale );
235 : // set created mapping mode with calculated scaling at output device.
236 0 : mrParentViewShell.GetOut()->SetMapMode( aMapMode );
237 : // OD 20.02.2003 #107369# - update statics for paint.
238 0 : ::SwCalcPixStatics( mrParentViewShell.GetOut() );
239 : }
240 :
241 : // set window size in twips
242 0 : maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize );
243 : // validate layout sizes
244 0 : mbLayoutSizesValid = true;
245 :
246 0 : return true;
247 : }
248 :
249 : /** apply new zoom at given view shell */
250 0 : void SwPagePreviewLayout::_ApplyNewZoomAtViewShell( sal_uInt8 _aNewZoom )
251 : {
252 0 : SwViewOption aNewViewOptions = *(mrParentViewShell.GetViewOptions());
253 0 : if ( aNewViewOptions.GetZoom() != _aNewZoom )
254 : {
255 0 : aNewViewOptions.SetZoom( _aNewZoom );
256 : //#i19975# - consider zoom type.
257 0 : SvxZoomType eZoomType = SvxZoomType::PERCENT;
258 0 : aNewViewOptions.SetZoomType( eZoomType );
259 0 : mrParentViewShell.ApplyViewOptions( aNewViewOptions );
260 0 : }
261 0 : }
262 :
263 : /** method to adjust page preview layout to document changes
264 :
265 : OD 18.12.2002 #103492#
266 : */
267 0 : bool SwPagePreviewLayout::ReInit()
268 : {
269 : // check environment and parameters
270 : {
271 0 : bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid;
272 : OSL_ENSURE( bLayoutSettingsValid,
273 : "no valid preview layout info/sizes - no re-init of page preview layout");
274 0 : if ( !bLayoutSettingsValid )
275 0 : return false;
276 : }
277 :
278 0 : _ClearPreviewLayoutSizes();
279 0 : _CalcPreviewLayoutSizes();
280 :
281 0 : return true;
282 : }
283 :
284 : // methods to prepare paint of page preview
285 :
286 : /** prepare paint of page preview
287 :
288 : OD 12.12.2002 #103492#
289 : OD 21.03.2003 #108282# - delete parameter _onStartPageVirtNum
290 :
291 : @note _nProposedStartPageNum, _onStartPageNum are absolute
292 : */
293 0 : bool SwPagePreviewLayout::Prepare( const sal_uInt16 _nProposedStartPageNum,
294 : const Point& rProposedStartPos,
295 : const Size& _rPxWinSize,
296 : sal_uInt16& _onStartPageNum,
297 : Rectangle& _orDocPreviewPaintRect,
298 : const bool _bStartWithPageAtFirstCol
299 : )
300 : {
301 0 : sal_uInt16 nProposedStartPageNum = ConvertAbsoluteToRelativePageNum( _nProposedStartPageNum );
302 : // check environment and parameters
303 : {
304 0 : bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid;
305 : OSL_ENSURE( bLayoutSettingsValid,
306 : "no valid preview layout info/sizes - no prepare of preview paint");
307 0 : if ( !bLayoutSettingsValid )
308 0 : return false;
309 :
310 0 : bool bStartPageRangeValid = nProposedStartPageNum <= mnPages;
311 : OSL_ENSURE( bStartPageRangeValid,
312 : "proposed start page not existing - no prepare of preview paint");
313 0 : if ( !bStartPageRangeValid )
314 0 : return false;
315 :
316 : bool bStartPosRangeValid =
317 0 : rProposedStartPos.X() >= 0 && rProposedStartPos.Y() >= 0 &&
318 0 : rProposedStartPos.X() <= maPreviewDocRect.Right() &&
319 0 : rProposedStartPos.Y() <= maPreviewDocRect.Bottom();
320 : OSL_ENSURE( bStartPosRangeValid,
321 : "proposed start position out of range - no prepare of preview paint");
322 0 : if ( !bStartPosRangeValid )
323 0 : return false;
324 :
325 0 : bool bWinSizeValid = _rPxWinSize.Width() != 0 && _rPxWinSize.Height() != 0;
326 : OSL_ENSURE( bWinSizeValid, "no window size - no prepare of preview paint");
327 0 : if ( !bWinSizeValid )
328 0 : return false;
329 :
330 0 : bool bStartInfoValid = _nProposedStartPageNum > 0 ||
331 0 : rProposedStartPos != Point(0,0);
332 0 : if ( !bStartInfoValid )
333 0 : nProposedStartPageNum = 1;
334 : }
335 :
336 : // environment and parameter ok
337 :
338 : // update window size at preview setting data
339 0 : maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize );
340 :
341 0 : mbNoPageVisible = false;
342 0 : if ( nProposedStartPageNum > 0 )
343 : {
344 : // determine column and row of proposed start page in virtual preview layout
345 0 : const sal_uInt16 nColOfProposed = GetColOfPage( nProposedStartPageNum );
346 0 : const sal_uInt16 nRowOfProposed = GetRowOfPage( nProposedStartPageNum );
347 : // determine start page
348 0 : if ( _bStartWithPageAtFirstCol )
349 : {
350 : // OD 19.02.2003 #107369# - leaving left-top-corner blank is
351 : // controlled by <mbBookPreview>.
352 0 : if ( mbBookPreview &&
353 0 : ( nProposedStartPageNum == 1 || nRowOfProposed == 1 )
354 : )
355 0 : mnPaintPhyStartPageNum = 1;
356 : else
357 0 : mnPaintPhyStartPageNum = nProposedStartPageNum - (nColOfProposed-1);
358 : }
359 : else
360 0 : mnPaintPhyStartPageNum = nProposedStartPageNum;
361 :
362 0 : mnPaintPhyStartPageNum = ConvertRelativeToAbsolutePageNum( mnPaintPhyStartPageNum );
363 :
364 : // set starting column
365 0 : if ( _bStartWithPageAtFirstCol )
366 0 : mnPaintStartCol = 1;
367 : else
368 0 : mnPaintStartCol = nColOfProposed;
369 : // set starting row
370 0 : mnPaintStartRow = nRowOfProposed;
371 : // page offset == (-1,-1), indicating no offset and paint of free space.
372 0 : maPaintStartPageOffset.X() = -1;
373 0 : maPaintStartPageOffset.Y() = -1;
374 : // virtual preview document offset.
375 0 : if ( _bStartWithPageAtFirstCol )
376 0 : maPaintPreviewDocOffset.X() = 0;
377 : else
378 0 : maPaintPreviewDocOffset.X() = (nColOfProposed-1) * mnColWidth;
379 0 : maPaintPreviewDocOffset.Y() = (nRowOfProposed-1) * mnRowHeight;
380 : }
381 : else
382 : {
383 : // determine column and row of proposed start position.
384 : // Note: paint starts at point (0,0)
385 : const sal_uInt16 nColOfProposed =
386 0 : static_cast<sal_uInt16>(rProposedStartPos.X() / mnColWidth) + 1;
387 : const sal_uInt16 nRowOfProposed =
388 0 : static_cast<sal_uInt16>(rProposedStartPos.Y() / mnRowHeight) + 1;
389 : // determine start page == page at proposed start position
390 : // OD 19.02.2003 #107369# - leaving left-top-corner blank is
391 : // controlled by <mbBookPreview>.
392 0 : if ( mbBookPreview &&
393 0 : ( nRowOfProposed == 1 && nColOfProposed == 1 )
394 : )
395 0 : mnPaintPhyStartPageNum = 1;
396 : else
397 : {
398 : // OD 19.02.2003 #107369# - leaving left-top-corner blank is
399 : // controlled by <mbBookPreview>.
400 0 : mnPaintPhyStartPageNum = (nRowOfProposed-1) * mnCols + nColOfProposed;
401 0 : if ( mbBookPreview )
402 0 : --mnPaintPhyStartPageNum;
403 0 : if ( mnPaintPhyStartPageNum > mnPages )
404 : {
405 : // no page will be visible, because shown part of document
406 : // preview is the last row to the right of the last page
407 0 : mnPaintPhyStartPageNum = mnPages;
408 0 : mbNoPageVisible = true;
409 : }
410 : }
411 : // set starting column and starting row
412 0 : mnPaintStartCol = nColOfProposed;
413 0 : mnPaintStartRow = nRowOfProposed;
414 : // page offset
415 0 : maPaintStartPageOffset.X() =
416 0 : (rProposedStartPos.X() % mnColWidth) - mnXFree;
417 0 : maPaintStartPageOffset.Y() =
418 0 : (rProposedStartPos.Y() % mnRowHeight) - mnYFree;
419 : // virtual preview document offset.
420 0 : maPaintPreviewDocOffset = rProposedStartPos;
421 : }
422 :
423 : // determine additional paint offset, if preview layout fits into window.
424 0 : _CalcAdditionalPaintOffset();
425 :
426 : // determine rectangle to be painted from document preview
427 0 : _CalcDocPreviewPaintRect();
428 0 : _orDocPreviewPaintRect = maPaintedPreviewDocRect;
429 :
430 : // OD 20.01.2003 #103492# - shift visible preview document area to the left,
431 : // if on the right is an area left blank.
432 0 : if ( !mbDoesLayoutColsFitIntoWindow &&
433 0 : maPaintedPreviewDocRect.GetWidth() < maWinSize.Width() )
434 : {
435 : maPaintedPreviewDocRect.Move(
436 0 : -(maWinSize.Width() - maPaintedPreviewDocRect.GetWidth()), 0 );
437 0 : Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
438 : _rPxWinSize, _onStartPageNum,
439 0 : _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
440 : }
441 :
442 : // OD 20.01.2003 #103492# - shift visible preview document area to the top,
443 : // if on the botton is an area left blank.
444 0 : if ( mbBookPreviewModeToggled &&
445 0 : maPaintedPreviewDocRect.Bottom() == maPreviewDocRect.Bottom() &&
446 0 : maPaintedPreviewDocRect.GetHeight() < maWinSize.Height() )
447 : {
448 0 : if ( mbDoesLayoutRowsFitIntoWindow )
449 : {
450 0 : if ( maPaintedPreviewDocRect.GetHeight() < mnPreviewLayoutHeight)
451 : {
452 : maPaintedPreviewDocRect.Move(
453 0 : 0, -(mnPreviewLayoutHeight - maPaintedPreviewDocRect.GetHeight()) );
454 0 : Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
455 : _rPxWinSize, _onStartPageNum,
456 0 : _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
457 : }
458 : }
459 : else
460 : {
461 : maPaintedPreviewDocRect.Move(
462 0 : 0, -(maWinSize.Height() - maPaintedPreviewDocRect.GetHeight()) );
463 0 : Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
464 : _rPxWinSize, _onStartPageNum,
465 0 : _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
466 : }
467 : }
468 :
469 : // determine preview pages - visible pages with needed data for paint and
470 : // accessible pages with needed data.
471 0 : _CalcPreviewPages();
472 :
473 : // OD 07.11.2003 #i22014# - indicate new layout, if print preview is in paint
474 0 : if ( mbInPaint )
475 : {
476 0 : mbNewLayoutDuringPaint = true;
477 : }
478 :
479 : // validate paint data
480 0 : mbPaintInfoValid = true;
481 :
482 : // return start page
483 0 : _onStartPageNum = mnPaintPhyStartPageNum;
484 :
485 0 : return true;
486 : }
487 :
488 : /** calculate additional paint offset
489 :
490 : OD 12.12.2002 #103492#
491 : */
492 0 : void SwPagePreviewLayout::_CalcAdditionalPaintOffset()
493 : {
494 0 : if ( mnPreviewLayoutWidth <= maWinSize.Width() &&
495 0 : maPaintStartPageOffset.X() <= 0 )
496 : {
497 0 : mbDoesLayoutColsFitIntoWindow = true;
498 0 : maAdditionalPaintOffset.X() = (maWinSize.Width() - mnPreviewLayoutWidth) / 2;
499 : }
500 : else
501 : {
502 0 : mbDoesLayoutColsFitIntoWindow = false;
503 0 : maAdditionalPaintOffset.X() = 0;
504 : }
505 :
506 0 : if ( mnPreviewLayoutHeight <= maWinSize.Height() &&
507 0 : maPaintStartPageOffset.Y() <= 0 )
508 : {
509 0 : mbDoesLayoutRowsFitIntoWindow = true;
510 0 : maAdditionalPaintOffset.Y() = (maWinSize.Height() - mnPreviewLayoutHeight) / 2;
511 : }
512 : else
513 : {
514 0 : mbDoesLayoutRowsFitIntoWindow = false;
515 0 : maAdditionalPaintOffset.Y() = 0;
516 : }
517 0 : }
518 :
519 : /** calculate painted preview document rectangle
520 :
521 : OD 12.12.2002 #103492#
522 : */
523 0 : void SwPagePreviewLayout::_CalcDocPreviewPaintRect()
524 : {
525 0 : Point aTopLeftPos = maPaintPreviewDocOffset;
526 0 : maPaintedPreviewDocRect.SetPos( aTopLeftPos );
527 :
528 0 : Size aSize;
529 0 : if ( mbDoesLayoutColsFitIntoWindow )
530 0 : aSize.Width() = std::min( mnPreviewLayoutWidth,
531 0 : maPreviewDocRect.GetWidth() - aTopLeftPos.X() );
532 : else
533 0 : aSize.Width() = std::min( maPreviewDocRect.GetWidth() - aTopLeftPos.X(),
534 0 : maWinSize.Width() - maAdditionalPaintOffset.X() );
535 0 : if ( mbDoesLayoutRowsFitIntoWindow )
536 0 : aSize.Height() = std::min( mnPreviewLayoutHeight,
537 0 : maPreviewDocRect.GetHeight() - aTopLeftPos.Y() );
538 : else
539 0 : aSize.Height() = std::min( maPreviewDocRect.GetHeight() - aTopLeftPos.Y(),
540 0 : maWinSize.Height() - maAdditionalPaintOffset.Y() );
541 0 : maPaintedPreviewDocRect.SetSize( aSize );
542 0 : }
543 :
544 : /** calculate preview pages
545 :
546 : OD 12.12.2002 #103492#
547 : */
548 0 : void SwPagePreviewLayout::_CalcPreviewPages()
549 : {
550 0 : _ClearPreviewPageData();
551 :
552 0 : if ( mbNoPageVisible )
553 0 : return;
554 :
555 : // determine start page frame
556 0 : const SwPageFrm* pStartPage = mrLayoutRootFrm.GetPageByPageNum( mnPaintPhyStartPageNum );
557 :
558 : // calculate initial paint offset
559 0 : Point aInitialPaintOffset;
560 : /// check whether RTL interface or not
561 0 : if(!AllSettings::GetLayoutRTL()){
562 0 : if ( maPaintStartPageOffset != Point( -1, -1 ) )
563 0 : aInitialPaintOffset = Point(0,0) - maPaintStartPageOffset;
564 : else
565 0 : aInitialPaintOffset = Point( mnXFree, mnYFree );
566 : }
567 : else {
568 0 : if ( maPaintStartPageOffset != Point( -1, -1 ) )
569 0 : aInitialPaintOffset = Point(0 + ((SwPagePreviewLayout::mnCols-1)*mnColWidth),0) - maPaintStartPageOffset;
570 : else
571 0 : aInitialPaintOffset = Point( mnXFree + ((SwPagePreviewLayout::mnCols-1)*mnColWidth), mnYFree );
572 : }
573 0 : aInitialPaintOffset += maAdditionalPaintOffset;
574 :
575 : // prepare loop data
576 0 : const SwPageFrm* pPage = pStartPage;
577 0 : sal_uInt16 nCurrCol = mnPaintStartCol;
578 0 : sal_uInt16 nConsideredRows = 0;
579 0 : Point aCurrPaintOffset = aInitialPaintOffset;
580 : // loop on pages to determine preview background retangles
581 0 : while ( pPage &&
582 0 : (!mbDoesLayoutRowsFitIntoWindow || nConsideredRows < mnRows) &&
583 0 : aCurrPaintOffset.Y() < maWinSize.Height()
584 : )
585 : {
586 0 : if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() )
587 : {
588 0 : pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
589 0 : continue;
590 : }
591 :
592 0 : pPage->Calc();
593 :
594 : // consider only pages, which have to be painted.
595 0 : if ( nCurrCol < mnPaintStartCol )
596 : {
597 : // calculate data of unvisible page needed for accessibility
598 0 : PreviewPage* pPreviewPage = new PreviewPage;
599 : Point aCurrAccOffset = aCurrPaintOffset -
600 0 : Point( (mnPaintStartCol-nCurrCol) * mnColWidth, 0 );
601 0 : _CalcPreviewDataForPage( *(pPage), aCurrAccOffset, pPreviewPage );
602 0 : pPreviewPage->bVisible = false;
603 0 : maPreviewPages.push_back( pPreviewPage );
604 : // continue with next page and next column
605 0 : pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
606 0 : ++nCurrCol;
607 0 : continue;
608 : }
609 0 : if ( aCurrPaintOffset.X() < maWinSize.Width() )
610 : {
611 : // OD 19.02.2003 #107369# - leaving left-top-corner blank is
612 : // controlled by <mbBookPreview>.
613 0 : if ( mbBookPreview && pPage->GetPhyPageNum() == 1 && mnCols != 1 && nCurrCol == 1
614 : )
615 : {
616 : // first page in 2nd column
617 : // --> continue with increased paint offset and next column
618 : /// check whether RTL interface or not
619 0 : if(!AllSettings::GetLayoutRTL())
620 0 : aCurrPaintOffset.X() += mnColWidth;
621 0 : else aCurrPaintOffset.X() -= mnColWidth;
622 0 : ++nCurrCol;
623 0 : continue;
624 : }
625 :
626 : // calculate data of visible page
627 0 : PreviewPage* pPreviewPage = new PreviewPage;
628 0 : _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPreviewPage );
629 0 : pPreviewPage->bVisible = true;
630 0 : maPreviewPages.push_back( pPreviewPage );
631 : }
632 : else
633 : {
634 : // calculate data of unvisible page needed for accessibility
635 0 : PreviewPage* pPreviewPage = new PreviewPage;
636 0 : _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPreviewPage );
637 0 : pPreviewPage->bVisible = false;
638 0 : maPreviewPages.push_back( pPreviewPage );
639 : }
640 :
641 : // prepare data for next loop
642 0 : pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
643 :
644 : /// check whether RTL interface or not
645 0 : if(!AllSettings::GetLayoutRTL())
646 0 : aCurrPaintOffset.X() += mnColWidth;
647 0 : else aCurrPaintOffset.X() -= mnColWidth;
648 0 : ++nCurrCol;
649 0 : if ( nCurrCol > mnCols )
650 : {
651 0 : ++nConsideredRows;
652 0 : aCurrPaintOffset.X() = aInitialPaintOffset.X();
653 0 : nCurrCol = 1;
654 0 : aCurrPaintOffset.Y() += mnRowHeight;
655 : }
656 : }
657 : }
658 :
659 : /** determines preview data for a given page and a given preview offset
660 :
661 : OD 13.12.2002 #103492#
662 : */
663 0 : bool SwPagePreviewLayout::_CalcPreviewDataForPage( const SwPageFrm& _rPage,
664 : const Point& _rPreviewOffset,
665 : PreviewPage* _opPreviewPage )
666 : {
667 : // page frame
668 0 : _opPreviewPage->pPage = &_rPage;
669 : // size of page frame
670 0 : if ( _rPage.IsEmptyPage() )
671 : {
672 0 : if ( _rPage.GetPhyPageNum() % 2 == 0 )
673 0 : _opPreviewPage->aPageSize = _rPage.GetPrev()->Frm().SSize();
674 : else
675 0 : _opPreviewPage->aPageSize = _rPage.GetNext()->Frm().SSize();
676 : }
677 : else
678 0 : _opPreviewPage->aPageSize = _rPage.Frm().SSize();
679 : // position of page in preview window
680 0 : Point aPreviewWinOffset( _rPreviewOffset );
681 0 : if ( _opPreviewPage->aPageSize.Width() < maMaxPageSize.Width() )
682 0 : aPreviewWinOffset.X() += ( maMaxPageSize.Width() - _opPreviewPage->aPageSize.Width() ) / 2;
683 0 : if ( _opPreviewPage->aPageSize.Height() < maMaxPageSize.Height() )
684 0 : aPreviewWinOffset.Y() += ( maMaxPageSize.Height() - _opPreviewPage->aPageSize.Height() ) / 2;
685 0 : _opPreviewPage->aPreviewWinPos = aPreviewWinOffset;
686 : // logic position of page and mapping offset for paint
687 0 : if ( _rPage.IsEmptyPage() )
688 : {
689 0 : _opPreviewPage->aLogicPos = _opPreviewPage->aPreviewWinPos;
690 0 : _opPreviewPage->aMapOffset = Point( 0, 0 );
691 : }
692 : else
693 : {
694 0 : _opPreviewPage->aLogicPos = _rPage.Frm().Pos();
695 0 : _opPreviewPage->aMapOffset = _opPreviewPage->aPreviewWinPos - _opPreviewPage->aLogicPos;
696 : }
697 :
698 0 : return true;
699 : }
700 :
701 : /** enable/disable book preview
702 :
703 : OD 2004-03-04 #i18143#
704 : */
705 0 : bool SwPagePreviewLayout::SetBookPreviewMode( const bool _bEnableBookPreview,
706 : sal_uInt16& _onStartPageNum,
707 : Rectangle& _orDocPreviewPaintRect )
708 : {
709 0 : if ( mbBookPreview != _bEnableBookPreview)
710 : {
711 0 : mbBookPreview = _bEnableBookPreview;
712 : // re-initialize page preview layout
713 0 : ReInit();
714 : // re-prepare page preview layout
715 : {
716 0 : mbBookPreviewModeToggled = true;
717 0 : Point aProposedStartPos( maPaintPreviewDocOffset );
718 : // if proposed start position is below virtual preview document
719 : // bottom, adjust it to the virtual preview document bottom
720 0 : if ( aProposedStartPos.Y() > maPreviewDocRect.Bottom() )
721 : {
722 0 : aProposedStartPos.Y() = maPreviewDocRect.Bottom();
723 : }
724 : Prepare( 0, aProposedStartPos,
725 0 : mrParentViewShell.GetOut()->LogicToPixel( maWinSize ),
726 0 : _onStartPageNum, _orDocPreviewPaintRect );
727 0 : mbBookPreviewModeToggled = false;
728 : }
729 :
730 0 : return true;
731 : }
732 :
733 0 : return false;
734 : }
735 :
736 : // methods to determine new data for changing the current shown part of the
737 : // document preview.
738 :
739 : /** calculate start position for new scale
740 :
741 : OD 12.12.2002 #103492#
742 : */
743 0 : Point SwPagePreviewLayout::GetPreviewStartPosForNewScale(
744 : const Fraction& _aNewScale,
745 : const Fraction& _aOldScale,
746 : const Size& _aNewWinSize ) const
747 : {
748 0 : Point aNewPaintStartPos = maPaintedPreviewDocRect.TopLeft();
749 0 : if ( _aNewScale < _aOldScale )
750 : {
751 : // increase paint width by moving start point to left.
752 0 : if ( mnPreviewLayoutWidth < _aNewWinSize.Width() )
753 0 : aNewPaintStartPos.X() = 0;
754 0 : else if ( maPaintedPreviewDocRect.GetWidth() < _aNewWinSize.Width() )
755 : {
756 0 : aNewPaintStartPos.X() -=
757 0 : (_aNewWinSize.Width() - maPaintedPreviewDocRect.GetWidth()) / 2;
758 0 : if ( aNewPaintStartPos.X() < 0)
759 0 : aNewPaintStartPos.X() = 0;
760 : }
761 :
762 0 : if ( !mbDoesLayoutRowsFitIntoWindow )
763 : {
764 : // increase paint height by moving start point to top.
765 0 : if ( mnPreviewLayoutHeight < _aNewWinSize.Height() )
766 : {
767 0 : aNewPaintStartPos.Y() =
768 0 : ( (mnPaintStartRow - 1) * mnRowHeight );
769 : }
770 0 : else if ( maPaintedPreviewDocRect.GetHeight() < _aNewWinSize.Height() )
771 : {
772 0 : aNewPaintStartPos.Y() -=
773 0 : (_aNewWinSize.Height() - maPaintedPreviewDocRect.GetHeight()) / 2;
774 0 : if ( aNewPaintStartPos.Y() < 0)
775 0 : aNewPaintStartPos.Y() = 0;
776 : }
777 : }
778 : }
779 : else
780 : {
781 : // decrease paint width by moving start point to right
782 0 : if ( maPaintedPreviewDocRect.GetWidth() > _aNewWinSize.Width() )
783 0 : aNewPaintStartPos.X() +=
784 0 : (maPaintedPreviewDocRect.GetWidth() - _aNewWinSize.Width()) / 2;
785 : // decrease paint height by moving start point to bottom
786 0 : if ( maPaintedPreviewDocRect.GetHeight() > _aNewWinSize.Height() )
787 : {
788 0 : aNewPaintStartPos.Y() +=
789 0 : (maPaintedPreviewDocRect.GetHeight() - _aNewWinSize.Height()) / 2;
790 : // check, if new y-position is outside document preview
791 0 : if ( aNewPaintStartPos.Y() > maPreviewDocRect.Bottom() )
792 0 : aNewPaintStartPos.Y() =
793 0 : std::max( 0L, maPreviewDocRect.Bottom() - mnPreviewLayoutHeight );
794 : }
795 : }
796 :
797 0 : return aNewPaintStartPos;
798 : }
799 :
800 : /** determines, if page with given page number is visible in preview
801 :
802 : @note _nPageNum is absolut!
803 : */
804 0 : bool SwPagePreviewLayout::IsPageVisible( const sal_uInt16 _nPageNum ) const
805 : {
806 0 : const PreviewPage* pPreviewPage = _GetPreviewPageByPageNum( _nPageNum );
807 0 : return pPreviewPage && pPreviewPage->bVisible;
808 : }
809 :
810 : /** calculate data to bring new selected page into view.
811 :
812 : @note IN/OUT parameters are absolute page numbers!!!
813 : */
814 0 : bool SwPagePreviewLayout::CalcStartValuesForSelectedPageMove(
815 : const sal_Int16 _nHoriMove,
816 : const sal_Int16 _nVertMove,
817 : sal_uInt16& _orNewSelectedPage,
818 : sal_uInt16& _orNewStartPage,
819 : Point& _orNewStartPos ) const
820 : {
821 : // determine position of current selected page
822 0 : sal_uInt16 nTmpRelSelPageNum = ConvertAbsoluteToRelativePageNum( mnSelectedPageNum );
823 0 : sal_uInt16 nNewRelSelectedPageNum = nTmpRelSelPageNum;
824 :
825 0 : const sal_uInt16 nCurrRow = GetRowOfPage(nTmpRelSelPageNum);
826 :
827 : // determine new selected page number
828 : {
829 0 : if ( _nHoriMove != 0 )
830 : {
831 0 : if ( (nNewRelSelectedPageNum + _nHoriMove) < 1 )
832 0 : nNewRelSelectedPageNum = 1;
833 0 : else if ( (nNewRelSelectedPageNum + _nHoriMove) > mnPages )
834 0 : nNewRelSelectedPageNum = mnPages;
835 : else
836 0 : nNewRelSelectedPageNum = nNewRelSelectedPageNum + _nHoriMove;
837 : }
838 0 : if ( _nVertMove != 0 )
839 : {
840 0 : if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) < 1 )
841 0 : nNewRelSelectedPageNum = 1;
842 0 : else if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) > mnPages )
843 0 : nNewRelSelectedPageNum = mnPages;
844 : else
845 0 : nNewRelSelectedPageNum += ( _nVertMove * mnCols );
846 : }
847 : }
848 :
849 0 : sal_uInt16 nNewStartPage = mnPaintPhyStartPageNum;
850 0 : Point aNewStartPos = Point(0,0);
851 :
852 0 : const sal_uInt16 nNewAbsSelectedPageNum = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum );
853 0 : if ( !IsPageVisible( nNewAbsSelectedPageNum ) )
854 : {
855 0 : if ( _nHoriMove != 0 && _nVertMove != 0 )
856 : {
857 : OSL_FAIL( "missing implementation for moving preview selected page horizontal AND vertical");
858 0 : return false;
859 : }
860 :
861 : // new selected page has to be brought into view considering current
862 : // visible preview.
863 0 : const sal_uInt16 nTotalRows = GetRowOfPage( mnPages );
864 0 : if ( (_nHoriMove > 0 || _nVertMove > 0) &&
865 0 : mbDoesLayoutRowsFitIntoWindow &&
866 0 : mbDoesLayoutColsFitIntoWindow &&
867 0 : nCurrRow > nTotalRows - mnRows )
868 : {
869 : // new proposed start page = left-top-corner of last possible
870 : // preview page.
871 0 : nNewStartPage = (nTotalRows - mnRows) * mnCols + 1;
872 : // leaving left-top-corner blank is controlled
873 : // by <mbBookPreview>.
874 0 : if ( mbBookPreview )
875 : {
876 : // Note: decrease new proposed start page number by one,
877 : // because of blank left-top-corner
878 0 : --nNewStartPage;
879 : }
880 0 : nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewStartPage );
881 : }
882 : else
883 : {
884 : // new proposed start page = new selected page.
885 0 : nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum );
886 : }
887 : }
888 :
889 0 : _orNewSelectedPage = nNewAbsSelectedPageNum;
890 0 : _orNewStartPage = nNewStartPage;
891 0 : _orNewStartPos = aNewStartPos;
892 :
893 0 : return true;
894 : }
895 :
896 : /** checks, if given position is inside a shown document page */
897 : struct PreviewPosInsidePagePred
898 : {
899 : const Point mnPreviewPos;
900 0 : explicit PreviewPosInsidePagePred(const Point& rPreviewPos)
901 0 : : mnPreviewPos( rPreviewPos )
902 0 : {}
903 0 : bool operator() ( const PreviewPage* _pPreviewPage )
904 : {
905 0 : if ( _pPreviewPage->bVisible )
906 : {
907 0 : Rectangle aPreviewPageRect( _pPreviewPage->aPreviewWinPos, _pPreviewPage->aPageSize );
908 0 : return aPreviewPageRect.IsInside( mnPreviewPos );
909 : }
910 0 : return false;
911 : }
912 : };
913 :
914 0 : bool SwPagePreviewLayout::IsPreviewPosInDocPreviewPage( const Point& rPreviewPos,
915 : Point& _orDocPos,
916 : bool& _obPosInEmptyPage,
917 : sal_uInt16& _onPageNum ) const
918 : {
919 : // initialize variable parameter values.
920 0 : _orDocPos.X() = 0;
921 0 : _orDocPos.Y() = 0;
922 0 : _obPosInEmptyPage = false;
923 0 : _onPageNum = 0;
924 :
925 : std::vector<PreviewPage*>::const_iterator aFoundPreviewPageIter =
926 : std::find_if( maPreviewPages.begin(), maPreviewPages.end(),
927 0 : PreviewPosInsidePagePred( rPreviewPos ) );
928 :
929 0 : if ( aFoundPreviewPageIter != maPreviewPages.end() )
930 : {
931 : // given preview position is inside a document page.
932 0 : _onPageNum = (*aFoundPreviewPageIter)->pPage->GetPhyPageNum();
933 0 : _obPosInEmptyPage = (*aFoundPreviewPageIter)->pPage->IsEmptyPage();
934 0 : if ( !_obPosInEmptyPage )
935 : {
936 : // given preview position inside a normal page
937 0 : _orDocPos = rPreviewPos -
938 0 : (*aFoundPreviewPageIter)->aPreviewWinPos +
939 0 : (*aFoundPreviewPageIter)->aLogicPos;
940 0 : return true;
941 : }
942 : }
943 :
944 0 : return false;
945 : }
946 :
947 : /** determine window page scroll amount */
948 0 : SwTwips SwPagePreviewLayout::GetWinPagesScrollAmount(
949 : const sal_Int16 _nWinPagesToScroll ) const
950 : {
951 : SwTwips nScrollAmount;
952 0 : if ( mbDoesLayoutRowsFitIntoWindow )
953 : {
954 0 : nScrollAmount = (mnPreviewLayoutHeight - mnYFree) * _nWinPagesToScroll;
955 : }
956 : else
957 0 : nScrollAmount = _nWinPagesToScroll * maPaintedPreviewDocRect.GetHeight();
958 :
959 : // check, if preview layout size values are valid.
960 : // If not, the checks for an adjustment of the scroll amount aren't useful.
961 0 : if ( mbLayoutSizesValid )
962 : {
963 0 : if ( (maPaintedPreviewDocRect.Top() + nScrollAmount) <= 0 )
964 0 : nScrollAmount = -maPaintedPreviewDocRect.Top();
965 :
966 : // correct scroll amount
967 0 : if ( nScrollAmount > 0 &&
968 0 : maPaintedPreviewDocRect.Bottom() == maPreviewDocRect.Bottom()
969 : )
970 : {
971 0 : nScrollAmount = 0;
972 : }
973 : else
974 : {
975 0 : while ( (maPaintedPreviewDocRect.Top() + nScrollAmount + mnYFree) >= maPreviewDocRect.GetHeight() )
976 : {
977 0 : nScrollAmount -= mnRowHeight;
978 : }
979 : }
980 : }
981 :
982 0 : return nScrollAmount;
983 : }
984 :
985 : // methods to paint page preview layout
986 :
987 : /** paint prepared preview
988 :
989 : OD 12.12.2002 #103492#
990 : */
991 0 : bool SwPagePreviewLayout::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rOutRect) const
992 : {
993 : // check environment and parameters
994 : {
995 0 : if (!mrParentViewShell.GetWin() && !mrParentViewShell.GetOut()->GetConnectMetaFile())
996 : {
997 0 : return false;
998 : }
999 :
1000 : OSL_ENSURE(mbPaintInfoValid, "invalid preview settings - no paint of preview");
1001 0 : if (!mbPaintInfoValid)
1002 0 : return false;
1003 : }
1004 :
1005 : // OD 17.11.2003 #i22014# - no paint, if <superfluous> flag is set at layout
1006 0 : if (mrLayoutRootFrm.IsSuperfluous())
1007 : {
1008 0 : return true;
1009 : }
1010 :
1011 : // environment and parameter ok
1012 :
1013 : // OD 07.11.2003 #i22014#
1014 0 : if (mbInPaint)
1015 : {
1016 0 : return false;
1017 : }
1018 0 : mbInPaint = true;
1019 :
1020 0 : OutputDevice* pOutputDev = &rRenderContext;
1021 :
1022 : // prepare paint
1023 0 : if ( maPreviewPages.size() > 0 )
1024 : {
1025 0 : mrParentViewShell.Imp()->bFirstPageInvalid = false;
1026 0 : mrParentViewShell.Imp()->pFirstVisPage =
1027 0 : const_cast<SwPageFrm*>(maPreviewPages[0]->pPage);
1028 : }
1029 :
1030 : // paint preview background
1031 : {
1032 0 : SwRegionRects aPreviewBackgrdRegion(rOutRect);
1033 : // calculate preview background rectangles
1034 0 : for ( std::vector<PreviewPage*>::const_iterator aPageIter = maPreviewPages.begin();
1035 0 : aPageIter != maPreviewPages.end();
1036 : ++aPageIter )
1037 : {
1038 0 : if ( (*aPageIter)->bVisible )
1039 : {
1040 0 : aPreviewBackgrdRegion -=
1041 0 : SwRect( (*aPageIter)->aPreviewWinPos, (*aPageIter)->aPageSize );
1042 : }
1043 : }
1044 : // paint preview background rectangles
1045 0 : mrParentViewShell._PaintDesktop(rRenderContext, aPreviewBackgrdRegion);
1046 : }
1047 :
1048 : // prepare data for paint of pages
1049 0 : const Rectangle aPxOutRect( pOutputDev->LogicToPixel(rOutRect) );
1050 :
1051 0 : MapMode aMapMode( pOutputDev->GetMapMode() );
1052 0 : MapMode aSavedMapMode = aMapMode;
1053 :
1054 0 : const vcl::Font& rEmptyPgFont = SwPageFrm::GetEmptyPageFont();
1055 :
1056 0 : for ( std::vector<PreviewPage*>::const_iterator aPageIter = maPreviewPages.begin();
1057 0 : aPageIter != maPreviewPages.end();
1058 : ++aPageIter )
1059 : {
1060 0 : if ( !(*aPageIter)->bVisible )
1061 0 : continue;
1062 :
1063 0 : Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize );
1064 0 : aMapMode.SetOrigin( (*aPageIter)->aMapOffset );
1065 0 : pOutputDev->SetMapMode( aMapMode );
1066 0 : Rectangle aPxPaintRect = pOutputDev->LogicToPixel( aPageRect );
1067 0 : if ( aPxOutRect.IsOver( aPxPaintRect) )
1068 : {
1069 0 : if ( (*aPageIter)->pPage->IsEmptyPage() )
1070 : {
1071 0 : const Color aRetouche( mrParentViewShell.Imp()->GetRetoucheColor() );
1072 0 : if( pOutputDev->GetFillColor() != aRetouche )
1073 0 : pOutputDev->SetFillColor( aRetouche );
1074 0 : pOutputDev->SetLineColor(); // OD 20.02.2003 #107369# - no line color
1075 : // OD 20.02.2003 #107369# - use aligned page rectangle
1076 : {
1077 0 : SwRect aTmpPageRect( aPageRect );
1078 0 : ::SwAlignRect( aTmpPageRect, &mrParentViewShell);
1079 0 : aPageRect = aTmpPageRect.SVRect();
1080 : }
1081 0 : pOutputDev->DrawRect( aPageRect );
1082 :
1083 : // paint empty page text
1084 0 : vcl::Font aOldFont( pOutputDev->GetFont() );
1085 0 : pOutputDev->SetFont( rEmptyPgFont );
1086 : pOutputDev->DrawText( aPageRect, SW_RESSTR( STR_EMPTYPAGE ),
1087 : DrawTextFlags::VCenter |
1088 0 : DrawTextFlags::Center |
1089 0 : DrawTextFlags::Clip );
1090 0 : pOutputDev->SetFont( aOldFont );
1091 : // paint shadow and border for empty page
1092 : // OD 19.02.2003 #107369# - use new method to paint page border and shadow
1093 0 : SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, false, true );
1094 : }
1095 : else
1096 : {
1097 0 : mrParentViewShell.maVisArea = aPageRect;
1098 0 : aPxPaintRect.Intersection( aPxOutRect );
1099 0 : Rectangle aPaintRect = pOutputDev->PixelToLogic( aPxPaintRect );
1100 0 : mrParentViewShell.Paint(rRenderContext, aPaintRect);
1101 : // --> OD 2007-08-15 #i80691#
1102 : // paint page border and shadow
1103 : {
1104 0 : SwRect aPageBorderRect;
1105 : SwPageFrm::GetBorderAndShadowBoundRect( SwRect( aPageRect ), &mrParentViewShell, aPageBorderRect,
1106 0 : (*aPageIter)->pPage->IsLeftShadowNeeded(), (*aPageIter)->pPage->IsRightShadowNeeded(), true );
1107 0 : const vcl::Region aDLRegion(aPageBorderRect.SVRect());
1108 0 : mrParentViewShell.DLPrePaint2(aDLRegion);
1109 0 : SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, false, true );
1110 0 : mrParentViewShell.DLPostPaint2(true);
1111 : }
1112 : // <--
1113 : }
1114 : // OD 07.11.2003 #i22014# - stop painting, because new print
1115 : // preview layout is created during paint.
1116 0 : if ( mbNewLayoutDuringPaint )
1117 : {
1118 0 : break;
1119 : }
1120 :
1121 0 : if ( (*aPageIter)->pPage->GetPhyPageNum() == mnSelectedPageNum )
1122 : {
1123 0 : _PaintSelectMarkAtPage( (*aPageIter) );
1124 : }
1125 :
1126 : }
1127 : }
1128 :
1129 : // OD 17.11.2003 #i22014# - no update of accessible preview, if a new
1130 : // print preview layout is created during paint.
1131 0 : if ( !mbNewLayoutDuringPaint )
1132 : {
1133 : // update at accessiblilty interface
1134 : mrParentViewShell.Imp()->UpdateAccessiblePreview(
1135 : maPreviewPages,
1136 0 : aMapMode.GetScaleX(),
1137 0 : mrLayoutRootFrm.GetPageByPageNum( mnSelectedPageNum ),
1138 0 : maWinSize );
1139 : }
1140 :
1141 0 : pOutputDev->SetMapMode( aSavedMapMode );
1142 0 : mrParentViewShell.maVisArea.Clear();
1143 :
1144 : // OD 07.11.2003 #i22014#
1145 0 : mbInPaint = false;
1146 0 : mbNewLayoutDuringPaint = false;
1147 :
1148 0 : return true;
1149 : }
1150 :
1151 : /** repaint pages on page preview
1152 :
1153 : OD 18.12.2002 #103492#
1154 : */
1155 0 : void SwPagePreviewLayout::Repaint( const Rectangle& rInvalidCoreRect ) const
1156 : {
1157 : // check environment and parameters
1158 : {
1159 0 : if ( !mrParentViewShell.GetWin() &&
1160 0 : !mrParentViewShell.GetOut()->GetConnectMetaFile() )
1161 0 : return;
1162 :
1163 : OSL_ENSURE( mbPaintInfoValid,
1164 : "invalid preview settings - no paint of preview" );
1165 0 : if ( !mbPaintInfoValid )
1166 0 : return;
1167 : }
1168 :
1169 : // environment and parameter ok
1170 :
1171 : // prepare paint
1172 0 : if ( maPreviewPages.size() > 0 )
1173 : {
1174 0 : mrParentViewShell.Imp()->bFirstPageInvalid = false;
1175 0 : mrParentViewShell.Imp()->pFirstVisPage =
1176 0 : const_cast<SwPageFrm*>(maPreviewPages[0]->pPage);
1177 : }
1178 :
1179 : // invalidate visible pages, which overlap the invalid core rectangle
1180 0 : for ( std::vector<PreviewPage*>::const_iterator aPageIter = maPreviewPages.begin();
1181 0 : aPageIter != maPreviewPages.end();
1182 : ++aPageIter )
1183 : {
1184 0 : if ( !(*aPageIter)->bVisible )
1185 0 : continue;
1186 :
1187 0 : Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize );
1188 0 : if ( rInvalidCoreRect.IsOver( aPageRect ) )
1189 : {
1190 0 : aPageRect.Intersection(rInvalidCoreRect);
1191 0 : Rectangle aInvalidPreviewRect = aPageRect;
1192 0 : aInvalidPreviewRect.SetPos( aInvalidPreviewRect.TopLeft() -
1193 0 : (*aPageIter)->aLogicPos +
1194 0 : (*aPageIter)->aPreviewWinPos );
1195 0 : mrParentViewShell.GetWin()->Invalidate( aInvalidPreviewRect );
1196 : }
1197 : }
1198 : }
1199 :
1200 : /** paint selection mark at page
1201 :
1202 : OD 17.12.2002 #103492#
1203 : */
1204 0 : void SwPagePreviewLayout::_PaintSelectMarkAtPage(
1205 : const PreviewPage* _aSelectedPreviewPage ) const
1206 : {
1207 0 : OutputDevice* pOutputDev = mrParentViewShell.GetOut();
1208 0 : MapMode aMapMode( pOutputDev->GetMapMode() );
1209 : // save mapping mode of output device
1210 0 : MapMode aSavedMapMode = aMapMode;
1211 : // save fill and line color of output device
1212 0 : Color aFill( pOutputDev->GetFillColor() );
1213 0 : Color aLine( pOutputDev->GetLineColor() );
1214 :
1215 : // determine selection mark color
1216 0 : Color aSelPgLineColor(COL_LIGHTBLUE);
1217 : const StyleSettings& rSettings =
1218 0 : mrParentViewShell.GetWin()->GetSettings().GetStyleSettings();
1219 0 : if ( rSettings.GetHighContrastMode() )
1220 0 : aSelPgLineColor = rSettings.GetHighlightTextColor();
1221 :
1222 : // set needed mapping mode at output device
1223 0 : aMapMode.SetOrigin( _aSelectedPreviewPage->aMapOffset );
1224 0 : pOutputDev->SetMapMode( aMapMode );
1225 :
1226 : // calculate page rectangle in pixel coordinates
1227 : SwRect aPageRect( _aSelectedPreviewPage->aLogicPos,
1228 0 : _aSelectedPreviewPage->aPageSize );
1229 : // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for
1230 : // page border and shadow paint - see <SwPageFrm::PaintBorderAndShadow(..)>
1231 0 : ::SwAlignRect( aPageRect, &mrParentViewShell);
1232 0 : Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() );
1233 :
1234 : // draw two rectangle
1235 : // OD 19.02.2003 #107369# - adjust position of select mark rectangle
1236 0 : Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(),
1237 0 : aPxPageRect.Right(), aPxPageRect.Bottom() );
1238 0 : aRect = pOutputDev->PixelToLogic( aRect );
1239 0 : pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color
1240 0 : pOutputDev->SetLineColor( aSelPgLineColor );
1241 0 : pOutputDev->DrawRect( aRect );
1242 : // OD 19.02.2003 #107369# - adjust position of select mark rectangle
1243 0 : aRect = Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1,
1244 0 : aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 );
1245 0 : aRect = pOutputDev->PixelToLogic( aRect );
1246 0 : pOutputDev->DrawRect( aRect );
1247 :
1248 : // reset fill and line color of output device
1249 0 : pOutputDev->SetFillColor( aFill );
1250 0 : pOutputDev->SetLineColor( aLine );
1251 :
1252 : // reset mapping mode of output device
1253 0 : pOutputDev->SetMapMode( aSavedMapMode );
1254 0 : }
1255 :
1256 : /** paint to mark new selected page
1257 :
1258 : OD 17.12.2002 #103492#
1259 : Perform paint for current selected page in order to unmark it.
1260 : Set new selected page and perform paint to mark this page.
1261 :
1262 : @note _nSelectedPage, mnSelectedPage are absolut
1263 : */
1264 0 : void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage )
1265 : {
1266 0 : const sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum;
1267 0 : mnSelectedPageNum = _nSelectedPage;
1268 :
1269 : // re-paint for current selected page in order to umark it.
1270 0 : const PreviewPage* pOldSelectedPreviewPage = _GetPreviewPageByPageNum( nOldSelectedPageNum );
1271 0 : if ( pOldSelectedPreviewPage && pOldSelectedPreviewPage->bVisible )
1272 : {
1273 : // OD 20.02.2003 #107369# - invalidate only areas of selection mark.
1274 : SwRect aPageRect( pOldSelectedPreviewPage->aPreviewWinPos,
1275 0 : pOldSelectedPreviewPage->aPageSize );
1276 0 : ::SwAlignRect( aPageRect, &mrParentViewShell);
1277 0 : OutputDevice* pOutputDev = mrParentViewShell.GetOut();
1278 0 : Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() );
1279 : // invalidate top mark line
1280 0 : Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(),
1281 0 : aPxPageRect.Right(), aPxPageRect.Top()+1 );
1282 0 : mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1283 : // invalidate right mark line
1284 0 : aInvalPxRect = Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(),
1285 0 : aPxPageRect.Right(), aPxPageRect.Bottom() );
1286 0 : mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1287 : // invalidate bottom mark line
1288 0 : aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1,
1289 0 : aPxPageRect.Right(), aPxPageRect.Bottom() );
1290 0 : mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1291 : // invalidate left mark line
1292 0 : aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Top(),
1293 0 : aPxPageRect.Left()+1, aPxPageRect.Bottom() );
1294 0 : mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1295 : }
1296 :
1297 : // re-paint for new selected page in order to mark it.
1298 0 : const PreviewPage* pNewSelectedPreviewPage = _GetPreviewPageByPageNum( _nSelectedPage );
1299 0 : if ( pNewSelectedPreviewPage && pNewSelectedPreviewPage->bVisible )
1300 0 : _PaintSelectMarkAtPage( pNewSelectedPreviewPage );
1301 0 : }
1302 :
1303 : // helper methods
1304 :
1305 : /** get preview page by physical page number
1306 :
1307 : OD 17.12.2002 #103492#
1308 : */
1309 : struct EqualsPageNumPred
1310 : {
1311 : const sal_uInt16 mnPageNum;
1312 0 : explicit EqualsPageNumPred(const sal_uInt16 _nPageNum)
1313 0 : : mnPageNum( _nPageNum )
1314 0 : {}
1315 0 : bool operator() ( const PreviewPage* _pPreviewPage )
1316 : {
1317 0 : return _pPreviewPage->pPage->GetPhyPageNum() == mnPageNum;
1318 : }
1319 : };
1320 :
1321 0 : const PreviewPage* SwPagePreviewLayout::_GetPreviewPageByPageNum( const sal_uInt16 _nPageNum ) const
1322 : {
1323 : std::vector<PreviewPage*>::const_iterator aFoundPreviewPageIter =
1324 : std::find_if( maPreviewPages.begin(), maPreviewPages.end(),
1325 0 : EqualsPageNumPred( _nPageNum ) );
1326 :
1327 0 : if ( aFoundPreviewPageIter == maPreviewPages.end() )
1328 0 : return 0;
1329 :
1330 0 : return (*aFoundPreviewPageIter);
1331 : }
1332 :
1333 : /** determine row the page with the given number is in
1334 :
1335 : OD 17.01.2003 #103492#
1336 :
1337 : @note _nPageNum is relative
1338 : */
1339 0 : sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const
1340 : {
1341 : // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
1342 : // by <mbBookPreview>.
1343 0 : if ( mbBookPreview )
1344 : {
1345 : // Note: increase given physical page number by one, because left-top-corner
1346 : // in the preview layout is left blank.
1347 0 : ++_nPageNum;
1348 : }
1349 :
1350 0 : return _nPageNum / mnCols + ((_nPageNum % mnCols)>0 ? 1 : 0);
1351 : }
1352 :
1353 : /** determine column the page with the given number is in
1354 :
1355 : OD 17.01.2003 #103492#
1356 :
1357 : @note _nPageNum is relative
1358 : */
1359 0 : sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const
1360 : {
1361 : // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
1362 : // by <mbBookPreview>.
1363 0 : if ( mbBookPreview )
1364 : {
1365 : // Note: increase given physical page number by one, because left-top-corner
1366 : // in the preview layout is left blank.
1367 0 : ++_nPageNum;
1368 : }
1369 :
1370 0 : const sal_uInt16 nCol = _nPageNum % mnCols;
1371 0 : return nCol ? nCol : mnCols;
1372 : }
1373 :
1374 0 : Size SwPagePreviewLayout::GetPreviewDocSize() const
1375 : {
1376 : OSL_ENSURE( PreviewLayoutValid(), "PagePreviewLayout not valid" );
1377 0 : return maPreviewDocRect.GetSize();
1378 : }
1379 :
1380 : /** get size of a preview page by its physical page number
1381 :
1382 : OD 15.01.2003 #103492#
1383 : */
1384 0 : Size SwPagePreviewLayout::GetPreviewPageSizeByPageNum( sal_uInt16 _nPageNum ) const
1385 : {
1386 0 : const PreviewPage* pPreviewPage = _GetPreviewPageByPageNum( _nPageNum );
1387 0 : if ( pPreviewPage )
1388 : {
1389 0 : return pPreviewPage->aPageSize;
1390 : }
1391 0 : return Size( 0, 0 );
1392 : }
1393 :
1394 : /** get virtual page number by its physical page number
1395 :
1396 : OD 21.03.2003 #108282#
1397 : */
1398 0 : sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const
1399 : {
1400 0 : const PreviewPage* pPreviewPage = _GetPreviewPageByPageNum( _nPageNum );
1401 0 : if ( pPreviewPage )
1402 : {
1403 0 : return pPreviewPage->pPage->GetVirtPageNum();
1404 : }
1405 0 : return 0;
1406 : }
1407 :
1408 : /** Convert absolute to relative page numbers (see PrintEmptyPages) */
1409 0 : sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const
1410 : {
1411 0 : if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum )
1412 : {
1413 0 : return _nAbsPageNum;
1414 : }
1415 :
1416 0 : const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower());
1417 :
1418 0 : sal_uInt16 nRet = 1;
1419 :
1420 0 : while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum )
1421 : {
1422 0 : if ( !pTmpPage->IsEmptyPage() )
1423 0 : ++nRet;
1424 :
1425 0 : pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() );
1426 : }
1427 :
1428 0 : return nRet;
1429 : }
1430 :
1431 : /** Convert relative to absolute page numbers (see PrintEmptyPages) */
1432 0 : sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const
1433 : {
1434 0 : if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum )
1435 : {
1436 0 : return _nRelPageNum;
1437 : }
1438 :
1439 0 : const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower());
1440 0 : const SwPageFrm* pRet = 0;
1441 :
1442 0 : sal_uInt16 i = 0;
1443 0 : while( pTmpPage && i != _nRelPageNum )
1444 : {
1445 0 : if ( !pTmpPage->IsEmptyPage() )
1446 0 : ++i;
1447 :
1448 0 : pRet = pTmpPage;
1449 0 : pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() );
1450 : }
1451 :
1452 0 : return pRet->GetPhyPageNum();
1453 177 : }
1454 :
1455 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|