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