Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "view/SlsLayouter.hxx"
21 : #include "model/SlideSorterModel.hxx"
22 : #include "model/SlsPageDescriptor.hxx"
23 : #include "Window.hxx"
24 : #include <rtl/math.hxx>
25 : #include <basegfx/numeric/ftools.hxx>
26 :
27 : namespace sd { namespace slidesorter { namespace view {
28 :
29 : class Layouter::Implementation
30 : {
31 : public:
32 : VclPtr<sd::Window> mpWindow;
33 : sal_Int32 mnRequestedLeftBorder;
34 : sal_Int32 mnRequestedRightBorder;
35 : sal_Int32 mnRequestedTopBorder;
36 : sal_Int32 mnRequestedBottomBorder;
37 : sal_Int32 mnLeftBorder;
38 : sal_Int32 mnRightBorder;
39 : sal_Int32 mnTopBorder;
40 : sal_Int32 mnBottomBorder;
41 : sal_Int32 mnVerticalGap;
42 : sal_Int32 mnHorizontalGap;
43 : Size maMinimalSize;
44 : Size maPreferredSize;
45 : Size maMaximalSize;
46 : sal_Int32 mnMinimalColumnCount;
47 : sal_Int32 mnMaximalColumnCount;
48 : sal_Int32 mnPageCount;
49 : sal_Int32 mnColumnCount;
50 : sal_Int32 mnRowCount;
51 : /// The maximum number of columns. Can only be larger than the current
52 : /// number of columns when there are not enough pages to fill all
53 : /// available columns.
54 : sal_Int32 mnMaxColumnCount;
55 : /// The maximum number of rows. Can only be larger than the current
56 : /// number of rows when there are not enough pages to fill all available
57 : /// rows.
58 : sal_Int32 mnMaxRowCount;
59 : Size maPageObjectSize;
60 : ::boost::shared_ptr<PageObjectLayouter> mpPageObjectLayouter;
61 : ::boost::shared_ptr<view::Theme> mpTheme;
62 :
63 : /** Specify how the gap between two page objects is associated with the
64 : page objects.
65 : */
66 : enum GapMembership {
67 : GM_NONE, // Gap is not associated with any page object.
68 : GM_PREVIOUS, // The whole gap is associated with the previous page
69 : // object (left or above the gap.)
70 : GM_BOTH, // Half of the gap is associated with previous, half
71 : // with the next page object.
72 : GM_NEXT, // The whole gap is associated with the next page
73 : // object (right or below the gap.)
74 : GM_PAGE_BORDER
75 : };
76 :
77 : static Implementation* Create (
78 : const Implementation& rImplementation,
79 : const Layouter::Orientation eOrientation);
80 :
81 : virtual Layouter::Orientation GetOrientation() const = 0;
82 :
83 : bool Rearrange (
84 : const Size& rWindowSize,
85 : const Size& rPreviewModelSize,
86 : const sal_uInt32 nPageCount);
87 :
88 : /** Calculate the row that the point with the given vertical coordinate
89 : is over. The horizontal component is ignored.
90 : @param nYPosition
91 : Vertical position in model coordinates.
92 : @param bIncludeBordersAndGaps
93 : When this flag is <TRUE/> then the area of borders and gaps are
94 : interpreted as belonging to one of the rows.
95 : @param eGapMembership
96 : Specifies to what row the gap areas belong. Here GM_NONE
97 : corresponds to bIncludeBordersAndGaps being <FALSE/>. When
98 : GM_BOTH is given then the upper half is associated to the row
99 : above and the lower half to the row below. Values of
100 : GM_PREVIOUS and GM_NEXT associate the whole gap area with the
101 : row above or below respectively.
102 : */
103 : sal_Int32 GetRowAtPosition (
104 : sal_Int32 nYPosition,
105 : bool bIncludeBordersAndGaps,
106 : GapMembership eGapMembership = GM_NONE) const;
107 :
108 : /** Calculate the column that the point with the given horizontal
109 : coordinate is over. The vertical component is ignored.
110 : @param nXPosition
111 : Horizontal position in model coordinates.
112 : @param bIncludeBordersAndGaps
113 : When this flag is <TRUE/> then the area of borders and gaps are
114 : interpreted as belonging to one of the columns.
115 : @param eGapMembership
116 : Specifies to what column the gap areas belong.
117 : */
118 : sal_Int32 GetColumnAtPosition (
119 : sal_Int32 nXPosition,
120 : bool bIncludeBordersAndGaps,
121 : GapMembership eGapMembership = GM_NONE) const;
122 :
123 : /** This method is typically called from GetRowAtPosition() and
124 : GetColumnAtPosition() to handle a position that lies inside the gap
125 : between two adjacent rows or columns.
126 : @param nDistanceIntoGap
127 : Vertical distance from the bottom of the upper row down into the
128 : gap or horizontal distance from the right edge right into the
129 : gap.
130 : @param eGapMemberhship
131 : This value decides what areas in the gap belong to which (or no)
132 : row or column.
133 : @param nIndex
134 : The row index of the upper row or the column index of the left
135 : column.
136 : @param nGap
137 : Width or height of the gap in model coordiantes between the
138 : page borders.
139 : @return
140 : Returns either the index of the upper row (as given as nRow), the
141 : index of the lower row (nRow+1) or -1 to indicate that the
142 : position belongs to no row.
143 : */
144 : static sal_Int32 ResolvePositionInGap (
145 : sal_Int32 nDistanceIntoGap,
146 : GapMembership eGapMembership,
147 : sal_Int32 nIndex,
148 : sal_Int32 nGap);
149 :
150 : /** Calculate the logical part of the insert position, i.e. the page
151 : after whicht to insert.
152 : */
153 : virtual void CalculateLogicalInsertPosition (
154 : const Point& rModelPosition,
155 : InsertPosition& rPosition) const = 0;
156 :
157 : /** Calculate the geometrical part of the insert position, i.e. the
158 : location of where to display the insertion indicator and the
159 : distances about which the leading and trailing pages have to be
160 : moved to make room for the indicator.
161 : */
162 : void CalculateGeometricPosition (
163 : InsertPosition& rPosition,
164 : const Size& rIndicatorSize,
165 : const bool bIsVertical,
166 : model::SlideSorterModel& rModel) const;
167 :
168 : /** Return the bounding box of the preview or, when selected, of the page
169 : object. Thus, it returns something like a visual bounding box.
170 : */
171 : Rectangle GetInnerBoundingBox (
172 : model::SlideSorterModel& rModel,
173 : const sal_Int32 nIndex) const;
174 :
175 : Range GetValidHorizontalSizeRange() const;
176 : Range GetValidVerticalSizeRange() const;
177 :
178 : Range GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const;
179 : sal_Int32 GetIndex (
180 : const sal_Int32 nRow,
181 : const sal_Int32 nColumn,
182 : const bool bClampToValidRange) const;
183 :
184 : Rectangle GetPageObjectBox (
185 : const sal_Int32 nIndex,
186 : const bool bIncludeBorderAndGap = false) const;
187 :
188 : Rectangle GetPageObjectBox (
189 : const sal_Int32 nRow,
190 : const sal_Int32 nColumn) const;
191 :
192 : Rectangle AddBorderAndGap (
193 : const Rectangle& rBoundingBox,
194 : const sal_Int32 nRow,
195 : const sal_Int32 nColumn) const;
196 :
197 : Rectangle GetTotalBoundingBox() const;
198 :
199 : virtual ~Implementation();
200 :
201 : protected:
202 : Implementation (
203 : sd::Window *pWindow,
204 : const ::boost::shared_ptr<view::Theme>& rpTheme);
205 : Implementation (const Implementation& rImplementation);
206 :
207 : virtual void CalculateRowAndColumnCount (const Size& rWindowSize) = 0;
208 : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) = 0;
209 : virtual Size CalculateTargetSize (
210 : const Size& rWindowSize,
211 : const Size& rPreviewModelSize) const = 0;
212 : Size GetTargetSize (
213 : const Size& rWindowSize,
214 : const Size& rPreviewModelSize,
215 : const bool bCalculateWidth,
216 : const bool bCalculateHeight) const;
217 : void CalculateVerticalLogicalInsertPosition (
218 : const Point& rModelPosition,
219 : InsertPosition& rPosition) const;
220 : };
221 :
222 : /** The vertical layouter has one column and as many rows as there are
223 : pages.
224 : */
225 132 : class VerticalImplementation : public Layouter::Implementation
226 : {
227 : public:
228 : VerticalImplementation (const Implementation& rImplementation);
229 :
230 : virtual Layouter::Orientation GetOrientation() const SAL_OVERRIDE;
231 :
232 : void CalculateLogicalInsertPosition (
233 : const Point& rModelPosition,
234 : InsertPosition& rPosition) const SAL_OVERRIDE;
235 :
236 : protected:
237 : virtual void CalculateRowAndColumnCount (const Size& rWindowSize) SAL_OVERRIDE;
238 : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) SAL_OVERRIDE;
239 : virtual Size CalculateTargetSize (
240 : const Size& rWindowSize,
241 : const Size& rPreviewModelSize) const SAL_OVERRIDE;
242 : };
243 :
244 : /** The horizontal layouter has one row and as many columns as there are
245 : pages.
246 : */
247 0 : class HorizontalImplementation : public Layouter::Implementation
248 : {
249 : public:
250 : HorizontalImplementation (const Implementation& rImplementation);
251 :
252 : virtual Layouter::Orientation GetOrientation() const SAL_OVERRIDE;
253 :
254 : void CalculateLogicalInsertPosition (
255 : const Point& rModelPosition,
256 : InsertPosition& rPosition) const SAL_OVERRIDE;
257 :
258 : protected:
259 : virtual void CalculateRowAndColumnCount (const Size& rWindowSize) SAL_OVERRIDE;
260 : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) SAL_OVERRIDE;
261 : virtual Size CalculateTargetSize (
262 : const Size& rWindowSize,
263 : const Size& rPreviewModelSize) const SAL_OVERRIDE;
264 : };
265 :
266 : /** The number of columns of the grid layouter is defined via a control in
267 : the slide sorter tool bar. The number of rows is calculated from the
268 : number of columns and the number of pages.
269 : */
270 260 : class GridImplementation : public Layouter::Implementation
271 : {
272 : public:
273 : GridImplementation (
274 : sd::Window *pWindow,
275 : const ::boost::shared_ptr<view::Theme>& rpTheme);
276 : GridImplementation (const Implementation& rImplementation);
277 :
278 : virtual Layouter::Orientation GetOrientation() const SAL_OVERRIDE;
279 :
280 : void CalculateLogicalInsertPosition (
281 : const Point& rModelPosition,
282 : InsertPosition& rPosition) const SAL_OVERRIDE;
283 :
284 : protected:
285 : virtual void CalculateRowAndColumnCount (const Size& rWindowSize) SAL_OVERRIDE;
286 : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) SAL_OVERRIDE;
287 : virtual Size CalculateTargetSize (
288 : const Size& rWindowSize,
289 : const Size& rPreviewModelSize) const SAL_OVERRIDE;
290 : };
291 :
292 : //===== Layouter ==============================================================
293 :
294 64 : Layouter::Layouter (
295 : sd::Window *pWindow,
296 : const ::boost::shared_ptr<Theme>& rpTheme)
297 64 : : mpImplementation(new GridImplementation(pWindow, rpTheme)),
298 128 : mpWindow(pWindow)
299 : {
300 64 : }
301 :
302 64 : Layouter::~Layouter()
303 : {
304 64 : }
305 :
306 962 : ::boost::shared_ptr<PageObjectLayouter> Layouter::GetPageObjectLayouter() const
307 : {
308 962 : return mpImplementation->mpPageObjectLayouter;
309 : }
310 :
311 0 : void Layouter::SetColumnCount (
312 : sal_Int32 nMinimalColumnCount,
313 : sal_Int32 nMaximalColumnCount)
314 : {
315 0 : if (nMinimalColumnCount <= nMaximalColumnCount)
316 : {
317 0 : mpImplementation->mnMinimalColumnCount = nMinimalColumnCount;
318 0 : mpImplementation->mnMaximalColumnCount = nMaximalColumnCount;
319 : }
320 0 : }
321 :
322 326 : bool Layouter::Rearrange (
323 : const Orientation eOrientation,
324 : const Size& rWindowSize,
325 : const Size& rPageSize,
326 : const sal_uInt32 nPageCount)
327 : {
328 : OSL_ASSERT(mpWindow);
329 :
330 326 : if (eOrientation != mpImplementation->GetOrientation())
331 132 : mpImplementation.reset(Implementation::Create(*mpImplementation, eOrientation));
332 :
333 326 : return mpImplementation->Rearrange(rWindowSize, rPageSize, nPageCount);
334 : }
335 :
336 192 : sal_Int32 Layouter::GetColumnCount() const
337 : {
338 192 : return mpImplementation->mnColumnCount;
339 : }
340 :
341 0 : sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const
342 : {
343 0 : return mpImplementation->GetIndex(nRow,nColumn,true);
344 : }
345 :
346 64 : Size Layouter::GetPageObjectSize() const
347 : {
348 64 : return mpImplementation->maPageObjectSize;
349 : }
350 :
351 433 : Rectangle Layouter::GetPageObjectBox (
352 : const sal_Int32 nIndex,
353 : const bool bIncludeBorderAndGap) const
354 : {
355 433 : return mpImplementation->GetPageObjectBox(nIndex, bIncludeBorderAndGap);
356 : }
357 :
358 875 : Rectangle Layouter::GetTotalBoundingBox() const
359 : {
360 875 : return mpImplementation->GetTotalBoundingBox();
361 : }
362 :
363 0 : InsertPosition Layouter::GetInsertPosition (
364 : const Point& rModelPosition,
365 : const Size& rIndicatorSize,
366 : model::SlideSorterModel& rModel) const
367 : {
368 0 : InsertPosition aPosition;
369 0 : mpImplementation->CalculateLogicalInsertPosition(
370 : rModelPosition,
371 0 : aPosition);
372 : mpImplementation->CalculateGeometricPosition(
373 : aPosition,
374 : rIndicatorSize,
375 0 : GetColumnCount()==1,
376 0 : rModel);
377 0 : return aPosition;
378 : }
379 :
380 66 : Range Layouter::GetValidHorizontalSizeRange() const
381 : {
382 66 : return mpImplementation->GetValidHorizontalSizeRange();
383 : }
384 :
385 0 : Range Layouter::GetValidVerticalSizeRange() const
386 : {
387 0 : return mpImplementation->GetValidVerticalSizeRange();
388 : }
389 :
390 383 : Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const
391 : {
392 383 : return mpImplementation->GetRangeOfVisiblePageObjects(aVisibleArea);
393 : }
394 :
395 68 : sal_Int32 Layouter::GetIndexAtPoint (
396 : const Point& rPosition,
397 : const bool bIncludePageBorders,
398 : const bool bClampToValidRange) const
399 : {
400 : const sal_Int32 nRow (
401 : mpImplementation->GetRowAtPosition (
402 68 : rPosition.Y(),
403 : bIncludePageBorders,
404 136 : bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE));
405 : const sal_Int32 nColumn (
406 : mpImplementation->GetColumnAtPosition (
407 68 : rPosition.X(),
408 : bIncludePageBorders,
409 136 : bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE));
410 :
411 68 : return mpImplementation->GetIndex(nRow,nColumn,bClampToValidRange);
412 : }
413 :
414 : //===== Layouter::Implementation ==============================================
415 :
416 132 : Layouter::Implementation* Layouter::Implementation::Create (
417 : const Implementation& rImplementation,
418 : const Layouter::Orientation eOrientation)
419 : {
420 132 : switch (eOrientation)
421 : {
422 0 : case HORIZONTAL: return new HorizontalImplementation(rImplementation);
423 66 : case VERTICAL: return new VerticalImplementation(rImplementation);
424 : case GRID:
425 66 : default: return new GridImplementation(rImplementation);
426 : }
427 : }
428 :
429 64 : Layouter::Implementation::Implementation (
430 : sd::Window *pWindow,
431 : const ::boost::shared_ptr<view::Theme>& rpTheme)
432 : : mpWindow(pWindow),
433 : mnRequestedLeftBorder(5),
434 : mnRequestedRightBorder(5),
435 : mnRequestedTopBorder(5),
436 : mnRequestedBottomBorder(5),
437 : mnLeftBorder(5),
438 : mnRightBorder(5),
439 : mnTopBorder(5),
440 : mnBottomBorder(5),
441 : mnVerticalGap (10 - 2*Theme_FocusIndicatorWidth),
442 : mnHorizontalGap(10 - 2*Theme_FocusIndicatorWidth),
443 : maMinimalSize(132,98),
444 : maPreferredSize(200,150),
445 : maMaximalSize(600,400),
446 : mnMinimalColumnCount(1),
447 : mnMaximalColumnCount(15),
448 : mnPageCount(0),
449 : mnColumnCount(1),
450 : mnRowCount(0),
451 : mnMaxColumnCount(0),
452 : mnMaxRowCount(0),
453 : maPageObjectSize(1,1),
454 : mpPageObjectLayouter(),
455 64 : mpTheme(rpTheme)
456 : {
457 64 : }
458 :
459 132 : Layouter::Implementation::Implementation (const Implementation& rImplementation)
460 : : mpWindow(rImplementation.mpWindow),
461 : mnRequestedLeftBorder(rImplementation.mnRequestedLeftBorder),
462 : mnRequestedRightBorder(rImplementation.mnRequestedRightBorder),
463 : mnRequestedTopBorder(rImplementation.mnRequestedTopBorder),
464 : mnRequestedBottomBorder(rImplementation.mnRequestedBottomBorder),
465 : mnLeftBorder(rImplementation.mnLeftBorder),
466 : mnRightBorder(rImplementation.mnRightBorder),
467 : mnTopBorder(rImplementation.mnTopBorder),
468 : mnBottomBorder(rImplementation.mnBottomBorder),
469 : mnVerticalGap(rImplementation.mnVerticalGap),
470 : mnHorizontalGap(rImplementation.mnHorizontalGap),
471 : maMinimalSize(rImplementation.maMinimalSize),
472 : maPreferredSize(rImplementation.maPreferredSize),
473 : maMaximalSize(rImplementation.maMaximalSize),
474 : mnMinimalColumnCount(rImplementation.mnMinimalColumnCount),
475 : mnMaximalColumnCount(rImplementation.mnMaximalColumnCount),
476 : mnPageCount(rImplementation.mnPageCount),
477 : mnColumnCount(rImplementation.mnColumnCount),
478 : mnRowCount(rImplementation.mnRowCount),
479 : mnMaxColumnCount(rImplementation.mnMaxColumnCount),
480 : mnMaxRowCount(rImplementation.mnMaxRowCount),
481 : maPageObjectSize(rImplementation.maPageObjectSize),
482 : mpPageObjectLayouter(),
483 132 : mpTheme(rImplementation.mpTheme)
484 : {
485 132 : }
486 :
487 196 : Layouter::Implementation::~Implementation()
488 : {
489 196 : }
490 :
491 326 : bool Layouter::Implementation::Rearrange (
492 : const Size& rWindowSize,
493 : const Size& rPreviewModelSize,
494 : const sal_uInt32 nPageCount)
495 : {
496 326 : mnPageCount = nPageCount;
497 :
498 : // Return early when the window or the model have not yet been initialized.
499 326 : if (rWindowSize.Width()<=0 || rWindowSize.Height()<=0)
500 0 : return false;
501 326 : if (rPreviewModelSize.Width()<=0 || rPreviewModelSize.Height()<=0)
502 0 : return false;
503 :
504 326 : CalculateRowAndColumnCount(rWindowSize);
505 :
506 : // Update the border values.
507 326 : mnLeftBorder = mnRequestedLeftBorder;
508 326 : mnTopBorder = mnRequestedTopBorder;
509 326 : mnRightBorder = mnRequestedRightBorder;
510 326 : mnBottomBorder = mnRequestedBottomBorder;
511 326 : if (mnColumnCount > 1)
512 : {
513 0 : int nMinimumBorderWidth = mnHorizontalGap/2;
514 0 : if (mnLeftBorder < nMinimumBorderWidth)
515 0 : mnLeftBorder = nMinimumBorderWidth;
516 0 : if (mnRightBorder < nMinimumBorderWidth)
517 0 : mnRightBorder = nMinimumBorderWidth;
518 : }
519 : else
520 : {
521 326 : int nMinimumBorderHeight = mnVerticalGap/2;
522 326 : if (mnTopBorder < nMinimumBorderHeight)
523 0 : mnTopBorder = nMinimumBorderHeight;
524 326 : if (mnBottomBorder < nMinimumBorderHeight)
525 0 : mnBottomBorder = nMinimumBorderHeight;
526 : }
527 :
528 : mpPageObjectLayouter.reset(
529 : new PageObjectLayouter(
530 326 : CalculateTargetSize(rWindowSize, rPreviewModelSize),
531 : rPreviewModelSize,
532 : mpWindow,
533 326 : mnPageCount));
534 :
535 : maPageObjectSize = mpPageObjectLayouter->GetGridMaxSize(
536 326 : PageObjectLayouter::WindowCoordinateSystem);
537 :
538 326 : CalculateMaxRowAndColumnCount(rWindowSize);
539 :
540 326 : return true;
541 : }
542 :
543 834 : sal_Int32 Layouter::Implementation::GetRowAtPosition (
544 : sal_Int32 nYPosition,
545 : bool bIncludeBordersAndGaps,
546 : GapMembership eGapMembership) const
547 : {
548 834 : sal_Int32 nRow = -1;
549 :
550 834 : const sal_Int32 nY = nYPosition - mnTopBorder;
551 834 : if (nY >= 0)
552 : {
553 : // Vertical distance from one row to the next.
554 511 : const sal_Int32 nRowOffset (maPageObjectSize.Height() + mnVerticalGap);
555 :
556 : // Calculate row consisting of page objects and gap below.
557 511 : nRow = nY / nRowOffset;
558 :
559 511 : const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height());
560 : // When inside the gap below then nYPosition is not over a page
561 : // object.
562 511 : if (nDistanceIntoGap > 0)
563 : {
564 : sal_Int32 nResolvedRow = ResolvePositionInGap(
565 : nDistanceIntoGap,
566 : eGapMembership,
567 : nRow,
568 0 : mnVerticalGap);
569 0 : if (!bIncludeBordersAndGaps || nResolvedRow != -1)
570 0 : nRow = nResolvedRow;
571 : }
572 : }
573 323 : else if (bIncludeBordersAndGaps)
574 : {
575 : // We are in the top border area. Set nRow to the first row when
576 : // the top border shall be considered to belong to the first row.
577 255 : nRow = 0;
578 : }
579 :
580 834 : return nRow;
581 : }
582 :
583 834 : sal_Int32 Layouter::Implementation::GetColumnAtPosition (
584 : sal_Int32 nXPosition,
585 : bool bIncludeBordersAndGaps,
586 : GapMembership eGapMembership) const
587 : {
588 834 : sal_Int32 nColumn = -1;
589 :
590 834 : sal_Int32 nX = nXPosition - mnLeftBorder;
591 834 : if (nX >= 0)
592 : {
593 : // Horizontal distance from one column to the next.
594 511 : const sal_Int32 nColumnOffset (maPageObjectSize.Width() + mnHorizontalGap);
595 :
596 : // Calculate row consisting of page objects and gap below.
597 511 : nColumn = nX / nColumnOffset;
598 511 : if (nColumn < 0)
599 0 : nColumn = 0;
600 511 : else if (nColumn >= mnColumnCount)
601 255 : nColumn = mnColumnCount-1;
602 :
603 511 : const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width());
604 : // When inside the gap at the right then nXPosition is not over a
605 : // page object.
606 511 : if (nDistanceIntoGap > 0)
607 : {
608 : sal_Int32 nResolvedColumn = ResolvePositionInGap(
609 : nDistanceIntoGap,
610 : eGapMembership,
611 : nColumn,
612 255 : mnHorizontalGap);
613 255 : if (!bIncludeBordersAndGaps || nResolvedColumn != -1)
614 255 : nColumn = nResolvedColumn;
615 : }
616 : }
617 323 : else if (bIncludeBordersAndGaps)
618 : {
619 : // We are in the left border area. Set nColumn to the first column
620 : // when the left border shall be considered to belong to the first
621 : // column.
622 255 : nColumn = 0;
623 : }
624 834 : return nColumn;
625 : }
626 :
627 255 : sal_Int32 Layouter::Implementation::ResolvePositionInGap (
628 : sal_Int32 nDistanceIntoGap,
629 : GapMembership eGapMembership,
630 : sal_Int32 nIndex,
631 : sal_Int32 nGap)
632 : {
633 255 : switch (eGapMembership)
634 : {
635 : case GM_NONE:
636 : // The gap is no man's land.
637 0 : nIndex = -1;
638 0 : break;
639 :
640 : case GM_BOTH:
641 : {
642 : // The lower half of the gap belongs to the next row or column.
643 0 : sal_Int32 nFirstHalfGapWidth = nGap / 2;
644 0 : if (nDistanceIntoGap > nFirstHalfGapWidth)
645 0 : nIndex ++;
646 0 : break;
647 : }
648 :
649 : case GM_PREVIOUS:
650 : // Row or column already at correct value.
651 255 : break;
652 :
653 : case GM_NEXT:
654 : // The complete gap belongs to the next row or column.
655 0 : nIndex ++;
656 0 : break;
657 :
658 : case GM_PAGE_BORDER:
659 0 : if (nDistanceIntoGap > 0)
660 : {
661 0 : if (nDistanceIntoGap > nGap)
662 : {
663 : // Inside the border of the next row or column.
664 0 : nIndex ++;
665 : }
666 : else
667 : {
668 : // Inside the gap between the page borders.
669 0 : nIndex = -1;
670 : }
671 : }
672 0 : break;
673 :
674 : default:
675 0 : nIndex = -1;
676 : }
677 :
678 255 : return nIndex;
679 : }
680 :
681 0 : void Layouter::Implementation::CalculateGeometricPosition (
682 : InsertPosition& rPosition,
683 : const Size& rIndicatorSize,
684 : const bool bIsVertical,
685 : model::SlideSorterModel& rModel) const
686 : {
687 : // 1. Determine right/bottom of the leading page and the left/top of the
688 : // trailing page object and how to distribute the missing space.
689 0 : sal_Int32 nLeadingLocation (0);
690 0 : sal_Int32 nTrailingLocation (0);
691 0 : bool bIsLeadingFixed (false);
692 0 : bool bIsTrailingFixed (false);
693 0 : sal_Int32 nSecondaryLocation (0);
694 0 : const sal_Int32 nIndex (rPosition.GetIndex());
695 :
696 0 : if (rPosition.IsAtRunStart())
697 : {
698 : // Place indicator at the top of the column.
699 0 : const Rectangle aOuterBox (GetPageObjectBox(nIndex));
700 0 : const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex));
701 0 : if (bIsVertical)
702 : {
703 0 : nLeadingLocation = aOuterBox.Top();
704 0 : nTrailingLocation = aInnerBox.Top();
705 0 : nSecondaryLocation = aInnerBox.Center().X();
706 : }
707 : else
708 : {
709 0 : nLeadingLocation = aOuterBox.Left();
710 0 : nTrailingLocation = aInnerBox.Left();
711 0 : nSecondaryLocation = aInnerBox.Center().Y();
712 : }
713 0 : bIsLeadingFixed = true;
714 : }
715 0 : else if (rPosition.IsAtRunEnd())
716 : {
717 : // Place indicator at the bottom/right of the column/row.
718 :
719 0 : const Rectangle aOuterBox (GetPageObjectBox(nIndex-1));
720 0 : const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex-1));
721 0 : if (bIsVertical)
722 : {
723 0 : nLeadingLocation = aInnerBox.Bottom();
724 0 : nTrailingLocation = aOuterBox.Bottom();
725 0 : nSecondaryLocation = aInnerBox.Center().X();
726 : }
727 : else
728 : {
729 0 : nLeadingLocation = aInnerBox.Right();
730 0 : nTrailingLocation = aOuterBox.Right();
731 0 : nSecondaryLocation = aInnerBox.Center().Y();
732 : }
733 0 : bIsTrailingFixed = true;
734 0 : if ( ! rPosition.IsExtraSpaceNeeded())
735 0 : bIsLeadingFixed = true;
736 : }
737 : else
738 : {
739 : // Place indicator between two rows/columns.
740 0 : const Rectangle aBox1 (GetInnerBoundingBox(rModel, nIndex-1));
741 0 : const Rectangle aBox2 (GetInnerBoundingBox(rModel, nIndex));
742 0 : if (bIsVertical)
743 : {
744 0 : nLeadingLocation = aBox1.Bottom();
745 0 : nTrailingLocation = aBox2.Top();
746 0 : nSecondaryLocation = (aBox1.Center().X() + aBox2.Center().X()) / 2;
747 : }
748 : else
749 : {
750 0 : nLeadingLocation = aBox1.Right();
751 0 : nTrailingLocation = aBox2.Left();
752 0 : nSecondaryLocation = (aBox1.Center().Y() + aBox2.Center().Y()) / 2;
753 : }
754 : }
755 :
756 : // 2. Calculate the location of the insert indicator and the offsets of
757 : // leading and trailing pages.
758 0 : const sal_Int32 nAvailableSpace (nTrailingLocation - nLeadingLocation);
759 0 : const sal_Int32 nRequiredSpace (bIsVertical ? rIndicatorSize.Height():rIndicatorSize.Width());
760 0 : const sal_Int32 nMissingSpace (::std::max(sal_Int32(0), nRequiredSpace - nAvailableSpace));
761 0 : sal_Int32 nPrimaryLocation (0);
762 0 : sal_Int32 nLeadingOffset (0);
763 0 : sal_Int32 nTrailingOffset (0);
764 0 : if (bIsLeadingFixed)
765 : {
766 0 : nPrimaryLocation = nLeadingLocation + nRequiredSpace/2;
767 0 : if ( ! bIsTrailingFixed)
768 0 : nTrailingOffset = nMissingSpace;
769 : }
770 0 : else if (bIsTrailingFixed)
771 : {
772 0 : nPrimaryLocation = nTrailingLocation - nRequiredSpace/2;
773 0 : nLeadingOffset = -nMissingSpace;
774 : }
775 : else
776 : {
777 0 : nPrimaryLocation = (nLeadingLocation + nTrailingLocation) /2;
778 0 : nLeadingOffset = -nMissingSpace/2;
779 0 : nTrailingOffset = nMissingSpace + nLeadingOffset;
780 : }
781 :
782 0 : if (bIsVertical)
783 : {
784 : rPosition.SetGeometricalPosition(
785 : Point(nSecondaryLocation, nPrimaryLocation),
786 : Point(0, nLeadingOffset),
787 0 : Point(0, nTrailingOffset));
788 : }
789 : else
790 : {
791 : rPosition.SetGeometricalPosition(
792 : Point(nPrimaryLocation, nSecondaryLocation),
793 : Point(nLeadingOffset, 0),
794 0 : Point(nTrailingOffset, 0));
795 : }
796 0 : }
797 :
798 0 : Rectangle Layouter::Implementation::GetInnerBoundingBox (
799 : model::SlideSorterModel& rModel,
800 : const sal_Int32 nIndex) const
801 : {
802 0 : model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex));
803 0 : if ( ! pDescriptor)
804 0 : return Rectangle();
805 :
806 0 : PageObjectLayouter::Part ePart = PageObjectLayouter::Preview;
807 :
808 0 : if (pDescriptor->HasState(model::PageDescriptor::ST_Selected))
809 0 : ePart = PageObjectLayouter::PageObject;
810 :
811 : return mpPageObjectLayouter->GetBoundingBox(
812 : pDescriptor, ePart,
813 0 : PageObjectLayouter::ModelCoordinateSystem, true);
814 : }
815 :
816 66 : Range Layouter::Implementation::GetValidHorizontalSizeRange() const
817 : {
818 : return Range(
819 66 : mnLeftBorder + maMinimalSize.Width() + mnRightBorder,
820 132 : mnLeftBorder + maMaximalSize.Width() + mnRightBorder);
821 : }
822 :
823 0 : Range Layouter::Implementation::GetValidVerticalSizeRange() const
824 : {
825 : return Range(
826 0 : mnTopBorder + maMinimalSize.Height() + mnBottomBorder,
827 0 : mnTopBorder + maMaximalSize.Height() + mnBottomBorder);
828 : }
829 :
830 383 : Range Layouter::Implementation::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const
831 : {
832 383 : const sal_Int32 nRow0 (GetRowAtPosition(aVisibleArea.Top(), true, GM_NEXT));
833 383 : const sal_Int32 nCol0 (GetColumnAtPosition(aVisibleArea.Left(),true, GM_NEXT));
834 383 : const sal_Int32 nRow1 (GetRowAtPosition(aVisibleArea.Bottom(), true, GM_PREVIOUS));
835 383 : const sal_Int32 nCol1 (GetColumnAtPosition(aVisibleArea.Right(), true, GM_PREVIOUS));
836 :
837 : // When start and end lie in different rows then the range may include
838 : // slides outside (left or right of) the given area.
839 383 : return Range(GetIndex(nRow0,nCol0,true), GetIndex(nRow1,nCol1,true));
840 : }
841 :
842 326 : Size Layouter::Implementation::GetTargetSize (
843 : const Size& rWindowSize,
844 : const Size& rPreviewModelSize,
845 : const bool bCalculateWidth,
846 : const bool bCalculateHeight) const
847 : {
848 : (void)rPreviewModelSize;
849 :
850 326 : if (mnColumnCount<=0 || mnRowCount<=0)
851 0 : return maPreferredSize;
852 326 : if ( ! (bCalculateWidth || bCalculateHeight))
853 : {
854 : OSL_ASSERT(bCalculateWidth || bCalculateHeight);
855 0 : return maPreferredSize;
856 : }
857 :
858 : // Calculate the width of each page object.
859 326 : Size aTargetSize (0,0);
860 326 : if (bCalculateWidth)
861 : aTargetSize.setWidth(
862 326 : (rWindowSize.Width() - mnLeftBorder - mnRightBorder
863 326 : - (mnColumnCount-1) * mnHorizontalGap)
864 326 : / mnColumnCount);
865 0 : else if (bCalculateHeight)
866 : aTargetSize.setHeight(
867 0 : (rWindowSize.Height() - mnTopBorder - mnBottomBorder
868 0 : - (mnRowCount-1) * mnVerticalGap)
869 0 : / mnRowCount);
870 :
871 326 : if (bCalculateWidth)
872 : {
873 326 : if (aTargetSize.Width() < maMinimalSize.Width())
874 0 : aTargetSize.setWidth(maMinimalSize.Width());
875 326 : else if (aTargetSize.Width() > maMaximalSize.Width())
876 0 : aTargetSize.setWidth(maMaximalSize.Width());
877 : }
878 0 : else if (bCalculateHeight)
879 : {
880 0 : if (aTargetSize.Height() < maMinimalSize.Height())
881 0 : aTargetSize.setHeight(maMinimalSize.Height());
882 0 : else if (aTargetSize.Height() > maMaximalSize.Height())
883 0 : aTargetSize.setHeight(maMaximalSize.Height());
884 : }
885 :
886 326 : return aTargetSize;
887 : }
888 :
889 834 : sal_Int32 Layouter::Implementation::GetIndex (
890 : const sal_Int32 nRow,
891 : const sal_Int32 nColumn,
892 : const bool bClampToValidRange) const
893 : {
894 834 : if (nRow >= 0 && nColumn >= 0)
895 : {
896 766 : const sal_Int32 nIndex (nRow * mnColumnCount + nColumn);
897 766 : if (nIndex >= mnPageCount)
898 253 : if (bClampToValidRange)
899 253 : return mnPageCount-1;
900 : else
901 0 : return -1;
902 : else
903 513 : return nIndex;
904 : }
905 68 : else if (bClampToValidRange)
906 0 : return 0;
907 : else
908 68 : return -1;
909 : }
910 :
911 433 : Rectangle Layouter::Implementation::GetPageObjectBox (
912 : const sal_Int32 nIndex,
913 : const bool bIncludeBorderAndGap) const
914 : {
915 433 : const sal_Int32 nRow (nIndex / mnColumnCount);
916 433 : const sal_Int32 nColumn (nIndex % mnColumnCount);
917 :
918 433 : const Rectangle aBoundingBox (GetPageObjectBox(nRow,nColumn));
919 433 : if (bIncludeBorderAndGap)
920 237 : return AddBorderAndGap(aBoundingBox, nRow, nColumn);
921 : else
922 196 : return aBoundingBox;
923 : }
924 :
925 433 : Rectangle Layouter::Implementation::GetPageObjectBox (
926 : const sal_Int32 nRow,
927 : const sal_Int32 nColumn) const
928 : {
929 : return Rectangle(
930 : Point (mnLeftBorder
931 433 : + nColumn * maPageObjectSize.Width()
932 433 : + (nColumn>0 ? nColumn : 0) * mnHorizontalGap,
933 : mnTopBorder
934 433 : + nRow * maPageObjectSize.Height()
935 433 : + (nRow>0 ? nRow : 0) * mnVerticalGap),
936 1299 : maPageObjectSize);
937 : }
938 :
939 237 : Rectangle Layouter::Implementation::AddBorderAndGap (
940 : const Rectangle& rBoundingBox,
941 : const sal_Int32 nRow,
942 : const sal_Int32 nColumn) const
943 : {
944 237 : Rectangle aBoundingBox (rBoundingBox);
945 :
946 237 : if (nColumn == 0)
947 237 : aBoundingBox.Left() = 0;
948 : else
949 0 : aBoundingBox.Left() -= mnHorizontalGap/2;
950 237 : if (nColumn == mnColumnCount-1)
951 237 : aBoundingBox.Right() += mnRightBorder;
952 : else
953 0 : aBoundingBox.Right() += mnHorizontalGap/2;
954 237 : if (nRow == 0)
955 222 : aBoundingBox.Top() = 0;
956 : else
957 15 : aBoundingBox.Top() -= mnVerticalGap/2;
958 237 : if (nRow == mnRowCount-1)
959 144 : aBoundingBox.Bottom() += mnBottomBorder;
960 : else
961 93 : aBoundingBox.Bottom() += mnVerticalGap/2;
962 237 : return aBoundingBox;
963 : }
964 :
965 875 : Rectangle Layouter::Implementation::GetTotalBoundingBox() const
966 : {
967 875 : sal_Int32 nHorizontalSize = 0;
968 875 : sal_Int32 nVerticalSize = 0;
969 875 : if (mnColumnCount > 0)
970 : {
971 875 : sal_Int32 nRowCount = (mnPageCount+mnColumnCount-1) / mnColumnCount;
972 : nHorizontalSize =
973 : mnLeftBorder
974 875 : + mnRightBorder
975 875 : + mnColumnCount * maPageObjectSize.Width();
976 875 : if (mnColumnCount > 1)
977 0 : nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap;
978 : nVerticalSize =
979 : mnTopBorder
980 875 : + mnBottomBorder
981 875 : + nRowCount * maPageObjectSize.Height();
982 875 : if (nRowCount > 1)
983 134 : nVerticalSize += (nRowCount-1) * mnVerticalGap;
984 : }
985 :
986 : return Rectangle (
987 : Point(0,0),
988 : Size (nHorizontalSize, nVerticalSize)
989 875 : );
990 : }
991 :
992 0 : void Layouter::Implementation::CalculateVerticalLogicalInsertPosition (
993 : const Point& rModelPosition,
994 : InsertPosition& rPosition) const
995 : {
996 0 : const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2;
997 0 : const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap);
998 0 : const sal_Int32 nRow (::std::min(mnPageCount, nY / nRowHeight));
999 : rPosition.SetLogicalPosition (
1000 : nRow,
1001 : 0,
1002 : nRow,
1003 : (nRow == 0),
1004 : (nRow == mnRowCount),
1005 0 : (nRow >= mnMaxRowCount));
1006 0 : }
1007 :
1008 : //===== HorizontalImplementation ================================================
1009 :
1010 0 : HorizontalImplementation::HorizontalImplementation (const Implementation& rImplementation)
1011 0 : : Implementation(rImplementation)
1012 : {
1013 0 : }
1014 :
1015 0 : Layouter::Orientation HorizontalImplementation::GetOrientation() const
1016 : {
1017 0 : return Layouter::HORIZONTAL;
1018 : }
1019 :
1020 0 : void HorizontalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize)
1021 : {
1022 : (void)rWindowSize;
1023 :
1024 : // Row and column count are fixed (for a given page count.)
1025 0 : mnColumnCount = mnPageCount;
1026 0 : mnRowCount = 1;
1027 0 : }
1028 :
1029 0 : void HorizontalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize)
1030 : {
1031 0 : mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
1032 0 : / (maPageObjectSize.Width() + mnHorizontalGap);
1033 0 : mnMaxRowCount = 1;
1034 0 : }
1035 :
1036 0 : Size HorizontalImplementation::CalculateTargetSize (
1037 : const Size& rWindowSize,
1038 : const Size& rPreviewModelSize) const
1039 : {
1040 0 : return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, false, true);
1041 : }
1042 :
1043 0 : void HorizontalImplementation::CalculateLogicalInsertPosition (
1044 : const Point& rModelPosition,
1045 : InsertPosition& rPosition) const
1046 : {
1047 0 : const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2;
1048 0 : const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap);
1049 0 : const sal_Int32 nColumn (::std::min(mnPageCount, nX / nColumnWidth));
1050 : rPosition.SetLogicalPosition (
1051 : 0,
1052 : nColumn,
1053 : nColumn,
1054 : (nColumn == 0),
1055 : (nColumn == mnColumnCount),
1056 0 : (nColumn >= mnMaxColumnCount));
1057 0 : }
1058 :
1059 : //===== VerticalImplementation ================================================
1060 :
1061 66 : VerticalImplementation::VerticalImplementation (const Implementation& rImplementation)
1062 66 : : Implementation(rImplementation)
1063 : {
1064 66 : }
1065 :
1066 188 : Layouter::Orientation VerticalImplementation::GetOrientation() const
1067 : {
1068 188 : return Layouter::VERTICAL;
1069 : }
1070 :
1071 188 : void VerticalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize)
1072 : {
1073 : (void)rWindowSize;
1074 :
1075 : // Row and column count are fixed (for a given page count.)
1076 188 : mnRowCount = mnPageCount;
1077 188 : mnColumnCount = 1;
1078 :
1079 188 : }
1080 :
1081 188 : void VerticalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize)
1082 : {
1083 188 : mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder)
1084 188 : / (maPageObjectSize.Height() + mnVerticalGap);
1085 188 : mnMaxColumnCount = 1;
1086 188 : }
1087 :
1088 188 : Size VerticalImplementation::CalculateTargetSize (
1089 : const Size& rWindowSize,
1090 : const Size& rPreviewModelSize) const
1091 : {
1092 188 : return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, false);
1093 : }
1094 :
1095 0 : void VerticalImplementation::CalculateLogicalInsertPosition (
1096 : const Point& rModelPosition,
1097 : InsertPosition& rPosition) const
1098 : {
1099 0 : return CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition);
1100 : }
1101 :
1102 : //===== GridImplementation ================================================
1103 :
1104 64 : GridImplementation::GridImplementation (
1105 : sd::Window *pWindow,
1106 : const ::boost::shared_ptr<view::Theme>& rpTheme)
1107 64 : : Implementation(pWindow, rpTheme)
1108 : {
1109 64 : }
1110 :
1111 66 : GridImplementation::GridImplementation (const Implementation& rImplementation)
1112 66 : : Implementation(rImplementation)
1113 : {
1114 66 : }
1115 :
1116 138 : Layouter::Orientation GridImplementation::GetOrientation() const
1117 : {
1118 138 : return Layouter::GRID;
1119 : }
1120 :
1121 138 : void GridImplementation::CalculateRowAndColumnCount (const Size& rWindowSize)
1122 : {
1123 : // Calculate the column count.
1124 : mnColumnCount
1125 138 : = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder)
1126 138 : / (maPreferredSize.Width() + mnHorizontalGap);
1127 138 : if (mnColumnCount < mnMinimalColumnCount)
1128 138 : mnColumnCount = mnMinimalColumnCount;
1129 138 : if (mnColumnCount > mnMaximalColumnCount)
1130 0 : mnColumnCount = mnMaximalColumnCount;
1131 138 : mnRowCount = (mnPageCount + mnColumnCount-1)/mnColumnCount;
1132 138 : }
1133 :
1134 138 : void GridImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize)
1135 : {
1136 138 : mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
1137 138 : / (maPageObjectSize.Width() + mnHorizontalGap);
1138 138 : mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder)
1139 138 : / (maPageObjectSize.Height() + mnVerticalGap);
1140 138 : }
1141 :
1142 138 : Size GridImplementation::CalculateTargetSize (
1143 : const Size& rWindowSize,
1144 : const Size& rPreviewModelSize) const
1145 : {
1146 138 : return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, true);
1147 : }
1148 :
1149 0 : void GridImplementation::CalculateLogicalInsertPosition (
1150 : const Point& rModelPosition,
1151 : InsertPosition& rPosition) const
1152 : {
1153 0 : if (mnColumnCount == 1)
1154 : {
1155 0 : CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition);
1156 : }
1157 : else
1158 : {
1159 : // Handle the general case of more than one column.
1160 : sal_Int32 nRow (::std::min(
1161 0 : mnRowCount-1,
1162 0 : GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH)));
1163 0 : const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2;
1164 0 : const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap);
1165 0 : sal_Int32 nColumn (::std::min(mnColumnCount, nX / nColumnWidth));
1166 0 : sal_Int32 nIndex (nRow * mnColumnCount + nColumn);
1167 0 : bool bIsAtRunEnd (nColumn == mnColumnCount);
1168 :
1169 0 : if (nIndex >= mnPageCount)
1170 : {
1171 0 : nIndex = mnPageCount;
1172 0 : nRow = mnRowCount-1;
1173 0 : nColumn = ::std::min(::std::min(mnPageCount, mnColumnCount), nColumn);
1174 0 : bIsAtRunEnd = true;
1175 : }
1176 :
1177 : rPosition.SetLogicalPosition (
1178 : nRow,
1179 : nColumn,
1180 : nIndex,
1181 : (nColumn == 0),
1182 : bIsAtRunEnd,
1183 0 : (nColumn >= mnMaxColumnCount));
1184 : }
1185 0 : }
1186 :
1187 : //===== InsertPosition ========================================================
1188 :
1189 64 : InsertPosition::InsertPosition()
1190 : : mnRow(-1),
1191 : mnColumn(-1),
1192 : mnIndex(-1),
1193 : mbIsAtRunStart(false),
1194 : mbIsAtRunEnd(false),
1195 : mbIsExtraSpaceNeeded(false),
1196 : maLocation(0,0),
1197 : maLeadingOffset(0,0),
1198 64 : maTrailingOffset(0,0)
1199 : {
1200 64 : }
1201 :
1202 0 : InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition)
1203 : {
1204 0 : if (this != &rInsertPosition)
1205 : {
1206 0 : mnRow = rInsertPosition.mnRow;
1207 0 : mnColumn = rInsertPosition.mnColumn;
1208 0 : mnIndex = rInsertPosition.mnIndex;
1209 0 : mbIsAtRunStart = rInsertPosition.mbIsAtRunStart;
1210 0 : mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd;
1211 0 : mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded;
1212 0 : maLocation = rInsertPosition.maLocation;
1213 0 : maLeadingOffset = rInsertPosition.maLeadingOffset;
1214 0 : maTrailingOffset = rInsertPosition.maTrailingOffset;
1215 : }
1216 0 : return *this;
1217 : }
1218 :
1219 0 : bool InsertPosition::operator== (const InsertPosition& rInsertPosition) const
1220 : {
1221 : // Do not compare the geometrical information (maLocation).
1222 0 : return mnRow==rInsertPosition.mnRow
1223 0 : && mnColumn==rInsertPosition.mnColumn
1224 0 : && mnIndex==rInsertPosition.mnIndex
1225 0 : && mbIsAtRunStart==rInsertPosition.mbIsAtRunStart
1226 0 : && mbIsAtRunEnd==rInsertPosition.mbIsAtRunEnd
1227 0 : && mbIsExtraSpaceNeeded==rInsertPosition.mbIsExtraSpaceNeeded;
1228 : }
1229 :
1230 0 : bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const
1231 : {
1232 0 : return !operator==(rInsertPosition);
1233 : }
1234 :
1235 0 : void InsertPosition::SetLogicalPosition (
1236 : const sal_Int32 nRow,
1237 : const sal_Int32 nColumn,
1238 : const sal_Int32 nIndex,
1239 : const bool bIsAtRunStart,
1240 : const bool bIsAtRunEnd,
1241 : const bool bIsExtraSpaceNeeded)
1242 : {
1243 0 : mnRow = nRow;
1244 0 : mnColumn = nColumn;
1245 0 : mnIndex = nIndex;
1246 0 : mbIsAtRunStart = bIsAtRunStart;
1247 0 : mbIsAtRunEnd = bIsAtRunEnd;
1248 0 : mbIsExtraSpaceNeeded = bIsExtraSpaceNeeded;
1249 0 : }
1250 :
1251 0 : void InsertPosition::SetGeometricalPosition(
1252 : const Point& rLocation,
1253 : const Point& rLeadingOffset,
1254 : const Point& rTrailingOffset)
1255 : {
1256 0 : maLocation = rLocation;
1257 0 : maLeadingOffset = rLeadingOffset;
1258 0 : maTrailingOffset = rTrailingOffset;
1259 0 : }
1260 :
1261 : } } } // end of namespace ::sd::slidesorter::namespace
1262 :
1263 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|