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