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