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