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