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