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