1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sd.hxx" 29 30 #include "view/SlsLayouter.hxx" 31 #include "model/SlideSorterModel.hxx" 32 #include "model/SlsPageDescriptor.hxx" 33 #include "Window.hxx" 34 #include <rtl/math.hxx> 35 #include <basegfx/numeric/ftools.hxx> 36 37 namespace { 38 sal_Int32 RoundToInt (const double nValue) 39 { 40 return sal_Int32(::rtl::math::round(nValue)); 41 } 42 } 43 44 45 namespace sd { namespace slidesorter { namespace view { 46 47 class Layouter::Implementation 48 { 49 public: 50 SharedSdWindow mpWindow; 51 sal_Int32 mnRequestedLeftBorder; 52 sal_Int32 mnRequestedRightBorder; 53 sal_Int32 mnRequestedTopBorder; 54 sal_Int32 mnRequestedBottomBorder; 55 sal_Int32 mnLeftBorder; 56 sal_Int32 mnRightBorder; 57 sal_Int32 mnTopBorder; 58 sal_Int32 mnBottomBorder; 59 sal_Int32 mnVerticalGap; 60 sal_Int32 mnHorizontalGap; 61 Size maMinimalSize; 62 Size maPreferredSize; 63 Size maMaximalSize; 64 sal_Int32 mnMinimalColumnCount; 65 sal_Int32 mnMaximalColumnCount; 66 sal_Int32 mnPageCount; 67 sal_Int32 mnColumnCount; 68 sal_Int32 mnRowCount; 69 /// The maximum number of columns. Can only be larger than the current 70 /// number of columns when there are not enough pages to fill all 71 /// available columns. 72 sal_Int32 mnMaxColumnCount; 73 /// The maximum number of rows. Can only be larger than the current 74 /// number of rows when there are not enough pages to fill all available 75 /// rows. 76 sal_Int32 mnMaxRowCount; 77 Size maPageObjectSize; 78 ::boost::shared_ptr<PageObjectLayouter> mpPageObjectLayouter; 79 ::boost::shared_ptr<view::Theme> mpTheme; 80 81 /** Specify how the gap between two page objects is associated with the 82 page objects. 83 */ 84 enum GapMembership { 85 GM_NONE, // Gap is not associated with any page object. 86 GM_PREVIOUS, // The whole gap is associated with the previous page 87 // object (left or above the gap.) 88 GM_BOTH, // Half of the gap is associated with previous, half 89 // with the next page object. 90 GM_NEXT, // The whole gap is associated with the next page 91 // object (right or below the gap.) 92 GM_PAGE_BORDER 93 }; 94 95 static Implementation* Create ( 96 const Implementation& rImplementation, 97 const Layouter::Orientation eOrientation); 98 99 virtual Layouter::Orientation GetOrientation (void) const = 0; 100 101 bool Rearrange ( 102 const Size& rWindowSize, 103 const Size& rPreviewModelSize, 104 const sal_uInt32 nPageCount); 105 106 /** Calculate the row that the point with the given vertical coordinate 107 is over. The horizontal component is ignored. 108 @param nYPosition 109 Vertical position in model coordinates. 110 @param bIncludeBordersAndGaps 111 When this flag is <TRUE/> then the area of borders and gaps are 112 interpreted as belonging to one of the rows. 113 @param eGapMembership 114 Specifies to what row the gap areas belong. Here GM_NONE 115 corresponds to bIncludeBordersAndGaps being <FALSE/>. When 116 GM_BOTH is given then the upper half is associated to the row 117 above and the lower half to the row below. Values of 118 GM_PREVIOUS and GM_NEXT associate the whole gap area with the 119 row above or below respectively. 120 */ 121 sal_Int32 GetRowAtPosition ( 122 sal_Int32 nYPosition, 123 bool bIncludeBordersAndGaps, 124 GapMembership eGapMembership = GM_NONE) const; 125 126 /** Calculate the column that the point with the given horizontal 127 coordinate is over. The verical component is ignored. 128 @param nXPosition 129 Horizontal position in model coordinates. 130 @param bIncludeBordersAndGaps 131 When this flag is <TRUE/> then the area of borders and gaps are 132 interpreted as belonging to one of the columns. 133 @param eGapMembership 134 Specifies to what column the gap areas belong. 135 */ 136 sal_Int32 GetColumnAtPosition ( 137 sal_Int32 nXPosition, 138 bool bIncludeBordersAndGaps, 139 GapMembership eGapMembership = GM_NONE) const; 140 141 /** This method is typically called from GetRowAtPosition() and 142 GetColumnAtPosition() to handle a position that lies inside the gap 143 between two adjacent rows or columns. 144 @param nDistanceIntoGap 145 Vertical distance from the bottom of the upper row down into the 146 gap or or horizontal distance from the right edge right into the 147 gap. 148 @param eGapMemberhship 149 This value decides what areas in the gap belong to which (or no) 150 row or column. 151 @param nIndex 152 The row index of the upper row or the column index of the left 153 column. 154 @param nGap 155 Width or height of the gap in model coordiantes between the 156 page borders. 157 @return 158 Returns either the index of the upper row (as given as nRow), the 159 index of the lower row (nRow+1) or -1 to indicate that the 160 position belongs to no row. 161 */ 162 sal_Int32 ResolvePositionInGap ( 163 sal_Int32 nDistanceIntoGap, 164 GapMembership eGapMembership, 165 sal_Int32 nIndex, 166 sal_Int32 nGap) const; 167 168 /** Calculate the logical part of the insert position, i.e. the page 169 after whicht to insert. 170 */ 171 virtual void CalculateLogicalInsertPosition ( 172 const Point& rModelPosition, 173 InsertPosition& rPosition) const = 0; 174 175 /** Calculate the geometrical part of the insert position, i.e. the 176 location of where to display the insertion indicator and the 177 distances about which the leading and trailing pages have to be 178 moved to make room for the indicator. 179 */ 180 void CalculateGeometricPosition ( 181 InsertPosition& rPosition, 182 const Size& rIndicatorSize, 183 const bool bIsVertical, 184 model::SlideSorterModel& rModel) const; 185 186 /** Return the bounding box of the preview or, when selected, of the page 187 object. Thus, it returns something like a visual bounding box. 188 */ 189 Rectangle GetInnerBoundingBox ( 190 model::SlideSorterModel& rModel, 191 const sal_Int32 nIndex) const; 192 193 Range GetValidHorizontalSizeRange (void) const; 194 Range GetValidVerticalSizeRange (void) const; 195 196 Range GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const; 197 sal_Int32 GetIndex ( 198 const sal_Int32 nRow, 199 const sal_Int32 nColumn, 200 const bool bClampToValidRange) const; 201 202 Rectangle GetPageObjectBox ( 203 const sal_Int32 nIndex, 204 const bool bIncludeBorderAndGap = false) const; 205 206 Rectangle GetPageObjectBox ( 207 const sal_Int32 nRow, 208 const sal_Int32 nColumn) const; 209 210 Rectangle AddBorderAndGap ( 211 const Rectangle& rBoundingBox, 212 const sal_Int32 nRow, 213 const sal_Int32 nColumn) const; 214 215 Rectangle GetTotalBoundingBox (void) const; 216 217 virtual ~Implementation (void); 218 219 protected: 220 Implementation ( 221 const SharedSdWindow& rpWindow, 222 const ::boost::shared_ptr<view::Theme>& rpTheme); 223 Implementation (const Implementation& rImplementation); 224 225 virtual void CalculateRowAndColumnCount (const Size& rWindowSize) = 0; 226 virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) = 0; 227 virtual Size CalculateTargetSize ( 228 const Size& rWindowSize, 229 const Size& rPreviewModelSize) const = 0; 230 Size GetTargetSize ( 231 const Size& rWindowSize, 232 const Size& rPreviewModelSize, 233 const bool bCalculateWidth, 234 const bool bCalculateHeight) const; 235 void CalculateVerticalLogicalInsertPosition ( 236 const Point& rModelPosition, 237 InsertPosition& rPosition) const; 238 }; 239 240 241 /** The vertical layouter has one column and as many rows as there are 242 pages. 243 */ 244 class VerticalImplementation : public Layouter::Implementation 245 { 246 public: 247 VerticalImplementation ( 248 const SharedSdWindow& rpWindow, 249 const ::boost::shared_ptr<view::Theme>& rpTheme); 250 VerticalImplementation (const Implementation& rImplementation); 251 252 virtual Layouter::Orientation GetOrientation (void) const; 253 254 void CalculateLogicalInsertPosition ( 255 const Point& rModelPosition, 256 InsertPosition& rPosition) const; 257 258 protected: 259 virtual void CalculateRowAndColumnCount (const Size& rWindowSize); 260 virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); 261 virtual Size CalculateTargetSize ( 262 const Size& rWindowSize, 263 const Size& rPreviewModelSize) const; 264 }; 265 266 267 /** The horizontal layouter has one row and as many columns as there are 268 pages. 269 */ 270 class HorizontalImplementation : public Layouter::Implementation 271 { 272 public: 273 HorizontalImplementation ( 274 const SharedSdWindow& rpWindow, 275 const ::boost::shared_ptr<view::Theme>& rpTheme); 276 HorizontalImplementation (const Implementation& rImplementation); 277 278 virtual Layouter::Orientation GetOrientation (void) const; 279 280 void CalculateLogicalInsertPosition ( 281 const Point& rModelPosition, 282 InsertPosition& rPosition) const; 283 284 protected: 285 virtual void CalculateRowAndColumnCount (const Size& rWindowSize); 286 virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); 287 virtual Size CalculateTargetSize ( 288 const Size& rWindowSize, 289 const Size& rPreviewModelSize) const; 290 }; 291 292 293 /** The number of columns of the grid layouter is defined via a control in 294 the slide sorter tool bar. The number of rows is calculated from the 295 number of columns and the number of pages. 296 */ 297 class GridImplementation : public Layouter::Implementation 298 { 299 public: 300 GridImplementation ( 301 const SharedSdWindow& rpWindow, 302 const ::boost::shared_ptr<view::Theme>& rpTheme); 303 GridImplementation (const Implementation& rImplementation); 304 305 virtual Layouter::Orientation GetOrientation (void) const; 306 307 void CalculateLogicalInsertPosition ( 308 const Point& rModelPosition, 309 InsertPosition& rPosition) const; 310 311 protected: 312 virtual void CalculateRowAndColumnCount (const Size& rWindowSize); 313 virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); 314 virtual Size CalculateTargetSize ( 315 const Size& rWindowSize, 316 const Size& rPreviewModelSize) const; 317 }; 318 319 320 321 322 //===== Layouter ============================================================== 323 324 Layouter::Layouter ( 325 const SharedSdWindow& rpWindow, 326 const ::boost::shared_ptr<Theme>& rpTheme) 327 : mpImplementation(new GridImplementation(rpWindow, rpTheme)), 328 mpWindow(rpWindow) 329 { 330 } 331 332 333 334 335 Layouter::~Layouter (void) 336 { 337 } 338 339 340 341 342 ::boost::shared_ptr<PageObjectLayouter> Layouter::GetPageObjectLayouter (void) const 343 { 344 return mpImplementation->mpPageObjectLayouter; 345 } 346 347 348 349 350 void Layouter::SetBorders ( 351 sal_Int32 nLeftBorder, 352 sal_Int32 nRightBorder, 353 sal_Int32 nTopBorder, 354 sal_Int32 nBottomBorder) 355 { 356 if (nLeftBorder >= 0) 357 mpImplementation->mnRequestedLeftBorder = nLeftBorder; 358 if (nRightBorder >= 0) 359 mpImplementation->mnRequestedRightBorder = nRightBorder; 360 if (nTopBorder >= 0) 361 mpImplementation->mnRequestedTopBorder = nTopBorder; 362 if (nBottomBorder >= 0) 363 mpImplementation->mnRequestedBottomBorder = nBottomBorder; 364 } 365 366 367 368 369 void Layouter::SetColumnCount ( 370 sal_Int32 nMinimalColumnCount, 371 sal_Int32 nMaximalColumnCount) 372 { 373 if (nMinimalColumnCount <= nMaximalColumnCount) 374 { 375 mpImplementation->mnMinimalColumnCount = nMinimalColumnCount; 376 mpImplementation->mnMaximalColumnCount = nMaximalColumnCount; 377 } 378 } 379 380 381 382 383 bool Layouter::Rearrange ( 384 const Orientation eOrientation, 385 const Size& rWindowSize, 386 const Size& rPageSize, 387 const sal_uInt32 nPageCount) 388 { 389 OSL_ASSERT(mpWindow); 390 391 if (eOrientation != mpImplementation->GetOrientation()) 392 mpImplementation.reset(Implementation::Create(*mpImplementation, eOrientation)); 393 394 return mpImplementation->Rearrange(rWindowSize, rPageSize, nPageCount); 395 } 396 397 398 399 400 void Layouter::_SetZoom (double nZoomFactor) 401 { 402 _SetZoom(Fraction(nZoomFactor)); 403 } 404 405 406 407 408 void Layouter::_SetZoom (Fraction nZoomFactor) 409 { 410 OSL_ASSERT(mpWindow); 411 412 MapMode aMapMode (mpWindow->GetMapMode()); 413 aMapMode.SetScaleX (nZoomFactor); 414 aMapMode.SetScaleY (nZoomFactor); 415 mpWindow->SetMapMode (aMapMode); 416 } 417 418 419 420 421 sal_Int32 Layouter::GetColumnCount (void) const 422 { 423 return mpImplementation->mnColumnCount; 424 } 425 426 427 428 429 sal_Int32 Layouter::GetRowCount (void) const 430 { 431 return mpImplementation->mnRowCount; 432 } 433 434 435 436 437 sal_Int32 Layouter::GetRow (const sal_Int32 nIndex) const 438 { 439 return nIndex / mpImplementation->mnColumnCount; 440 } 441 442 443 444 445 sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const 446 { 447 return nIndex % mpImplementation->mnColumnCount; 448 } 449 450 451 452 453 sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const 454 { 455 return mpImplementation->GetIndex(nRow,nColumn,true); 456 } 457 458 459 460 461 Size Layouter::GetPageObjectSize (void) const 462 { 463 return mpImplementation->maPageObjectSize; 464 } 465 466 467 468 469 Rectangle Layouter::GetPageObjectBox ( 470 const sal_Int32 nIndex, 471 const bool bIncludeBorderAndGap) const 472 { 473 return mpImplementation->GetPageObjectBox(nIndex, bIncludeBorderAndGap); 474 } 475 476 477 478 479 Rectangle Layouter::GetTotalBoundingBox (void) const 480 { 481 return mpImplementation->GetTotalBoundingBox(); 482 } 483 484 485 486 487 InsertPosition Layouter::GetInsertPosition ( 488 const Point& rModelPosition, 489 const Size& rIndicatorSize, 490 model::SlideSorterModel& rModel) const 491 { 492 InsertPosition aPosition; 493 mpImplementation->CalculateLogicalInsertPosition( 494 rModelPosition, 495 aPosition); 496 mpImplementation->CalculateGeometricPosition( 497 aPosition, 498 rIndicatorSize, 499 GetColumnCount()==1, 500 rModel); 501 return aPosition; 502 } 503 504 505 506 507 Range Layouter::GetValidHorizontalSizeRange (void) const 508 { 509 return mpImplementation->GetValidHorizontalSizeRange(); 510 } 511 512 513 514 515 Range Layouter::GetValidVerticalSizeRange (void) const 516 { 517 return mpImplementation->GetValidVerticalSizeRange(); 518 } 519 520 521 522 523 Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const 524 { 525 return mpImplementation->GetRangeOfVisiblePageObjects(aVisibleArea); 526 } 527 528 529 530 531 sal_Int32 Layouter::GetIndexAtPoint ( 532 const Point& rPosition, 533 const bool bIncludePageBorders, 534 const bool bClampToValidRange) const 535 { 536 const sal_Int32 nRow ( 537 mpImplementation->GetRowAtPosition ( 538 rPosition.Y(), 539 bIncludePageBorders, 540 bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE)); 541 const sal_Int32 nColumn ( 542 mpImplementation->GetColumnAtPosition ( 543 rPosition.X(), 544 bIncludePageBorders, 545 bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE)); 546 547 return mpImplementation->GetIndex(nRow,nColumn,bClampToValidRange); 548 } 549 550 551 552 553 //===== Layouter::Implementation ============================================== 554 555 Layouter::Implementation* Layouter::Implementation::Create ( 556 const Implementation& rImplementation, 557 const Layouter::Orientation eOrientation) 558 { 559 switch (eOrientation) 560 { 561 case HORIZONTAL: return new HorizontalImplementation(rImplementation); 562 case VERTICAL: return new VerticalImplementation(rImplementation); 563 case GRID: 564 default: return new GridImplementation(rImplementation); 565 } 566 } 567 568 569 570 571 Layouter::Implementation::Implementation ( 572 const SharedSdWindow& rpWindow, 573 const ::boost::shared_ptr<view::Theme>& rpTheme) 574 : mpWindow(rpWindow), 575 mnRequestedLeftBorder(5), 576 mnRequestedRightBorder(5), 577 mnRequestedTopBorder(5), 578 mnRequestedBottomBorder(5), 579 mnLeftBorder(5), 580 mnRightBorder(5), 581 mnTopBorder(5), 582 mnBottomBorder(5), 583 mnVerticalGap (10 - 2*rpTheme->GetIntegerValue(Theme::Integer_FocusIndicatorWidth)), 584 mnHorizontalGap(10 - 2*rpTheme->GetIntegerValue(Theme::Integer_FocusIndicatorWidth)), 585 maMinimalSize(132,98), 586 maPreferredSize(200,150), 587 maMaximalSize(300,200), 588 mnMinimalColumnCount(1), 589 mnMaximalColumnCount(15), 590 mnPageCount(0), 591 mnColumnCount(1), 592 mnRowCount(0), 593 mnMaxColumnCount(0), 594 mnMaxRowCount(0), 595 maPageObjectSize(1,1), 596 mpPageObjectLayouter(), 597 mpTheme(rpTheme) 598 { 599 } 600 601 602 603 604 Layouter::Implementation::Implementation (const Implementation& rImplementation) 605 : mpWindow(rImplementation.mpWindow), 606 mnRequestedLeftBorder(rImplementation.mnRequestedLeftBorder), 607 mnRequestedRightBorder(rImplementation.mnRequestedRightBorder), 608 mnRequestedTopBorder(rImplementation.mnRequestedTopBorder), 609 mnRequestedBottomBorder(rImplementation.mnRequestedBottomBorder), 610 mnLeftBorder(rImplementation.mnLeftBorder), 611 mnRightBorder(rImplementation.mnRightBorder), 612 mnTopBorder(rImplementation.mnTopBorder), 613 mnBottomBorder(rImplementation.mnBottomBorder), 614 mnVerticalGap(rImplementation.mnVerticalGap), 615 mnHorizontalGap(rImplementation.mnHorizontalGap), 616 maMinimalSize(rImplementation.maMinimalSize), 617 maPreferredSize(rImplementation.maPreferredSize), 618 maMaximalSize(rImplementation.maMaximalSize), 619 mnMinimalColumnCount(rImplementation.mnMinimalColumnCount), 620 mnMaximalColumnCount(rImplementation.mnMaximalColumnCount), 621 mnPageCount(rImplementation.mnPageCount), 622 mnColumnCount(rImplementation.mnColumnCount), 623 mnRowCount(rImplementation.mnRowCount), 624 mnMaxColumnCount(rImplementation.mnMaxColumnCount), 625 mnMaxRowCount(rImplementation.mnMaxRowCount), 626 maPageObjectSize(rImplementation.maPageObjectSize), 627 mpPageObjectLayouter(), 628 mpTheme(rImplementation.mpTheme) 629 { 630 } 631 632 633 634 635 Layouter::Implementation::~Implementation (void) 636 { 637 } 638 639 640 641 642 bool Layouter::Implementation::Rearrange ( 643 const Size& rWindowSize, 644 const Size& rPreviewModelSize, 645 const sal_uInt32 nPageCount) 646 { 647 mnPageCount = nPageCount; 648 649 // Return early when the window or the model have not yet been initialized. 650 if (rWindowSize.Width()<=0 || rWindowSize.Height()<=0) 651 return false; 652 if (rPreviewModelSize.Width()<=0 || rPreviewModelSize.Height()<=0) 653 return false; 654 655 CalculateRowAndColumnCount(rWindowSize); 656 657 // Update the border values. 658 mnLeftBorder = mnRequestedLeftBorder; 659 mnTopBorder = mnRequestedTopBorder; 660 mnRightBorder = mnRequestedRightBorder; 661 mnBottomBorder = mnRequestedBottomBorder; 662 if (mnColumnCount > 1) 663 { 664 int nMinimumBorderWidth = mnHorizontalGap/2; 665 if (mnLeftBorder < nMinimumBorderWidth) 666 mnLeftBorder = nMinimumBorderWidth; 667 if (mnRightBorder < nMinimumBorderWidth) 668 mnRightBorder = nMinimumBorderWidth; 669 } 670 else 671 { 672 int nMinimumBorderHeight = mnVerticalGap/2; 673 if (mnTopBorder < nMinimumBorderHeight) 674 mnTopBorder = nMinimumBorderHeight; 675 if (mnBottomBorder < nMinimumBorderHeight) 676 mnBottomBorder = nMinimumBorderHeight; 677 } 678 679 mpPageObjectLayouter.reset( 680 new PageObjectLayouter( 681 mpTheme, 682 CalculateTargetSize(rWindowSize, rPreviewModelSize), 683 rPreviewModelSize, 684 mpWindow, 685 mnPageCount)); 686 maPageObjectSize = mpPageObjectLayouter->GetSize( 687 PageObjectLayouter::FocusIndicator, 688 PageObjectLayouter::WindowCoordinateSystem); 689 690 CalculateMaxRowAndColumnCount(rWindowSize); 691 692 return true; 693 } 694 695 696 697 698 sal_Int32 Layouter::Implementation::GetRowAtPosition ( 699 sal_Int32 nYPosition, 700 bool bIncludeBordersAndGaps, 701 GapMembership eGapMembership) const 702 { 703 sal_Int32 nRow = -1; 704 705 const sal_Int32 nY = nYPosition - mnTopBorder; 706 if (nY >= 0) 707 { 708 // Vertical distance from one row to the next. 709 const sal_Int32 nRowOffset (maPageObjectSize.Height() + mnVerticalGap); 710 711 // Calculate row consisting of page objects and gap below. 712 nRow = nY / nRowOffset; 713 714 const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height()); 715 // When inside the gap below then nYPosition is not over a page 716 // object. 717 if (nDistanceIntoGap > 0) 718 nRow = ResolvePositionInGap ( 719 nDistanceIntoGap, 720 eGapMembership, 721 nRow, 722 mnVerticalGap); 723 } 724 else if (bIncludeBordersAndGaps) 725 { 726 // We are in the top border area. Set nRow to the first row when 727 // the top border shall be considered to belong to the first row. 728 nRow = 0; 729 } 730 731 return nRow; 732 } 733 734 735 736 737 sal_Int32 Layouter::Implementation::GetColumnAtPosition ( 738 sal_Int32 nXPosition, 739 bool bIncludeBordersAndGaps, 740 GapMembership eGapMembership) const 741 { 742 sal_Int32 nColumn = -1; 743 744 sal_Int32 nX = nXPosition - mnLeftBorder; 745 if (nX >= 0) 746 { 747 // Horizontal distance from one column to the next. 748 const sal_Int32 nColumnOffset (maPageObjectSize.Width() + mnHorizontalGap); 749 750 // Calculate row consisting of page objects and gap below. 751 nColumn = nX / nColumnOffset; 752 if (nColumn < 0) 753 nColumn = 0; 754 else if (nColumn >= mnColumnCount) 755 nColumn = mnColumnCount-1; 756 757 const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width()); 758 // When inside the gap at the right then nXPosition is not over a 759 // page object. 760 if (nDistanceIntoGap > 0) 761 nColumn = ResolvePositionInGap ( 762 nDistanceIntoGap, 763 eGapMembership, 764 nColumn, 765 mnHorizontalGap); 766 } 767 else if (bIncludeBordersAndGaps) 768 { 769 // We are in the left border area. Set nColumn to the first column 770 // when the left border shall be considered to belong to the first 771 // column. 772 nColumn = 0; 773 } 774 return nColumn; 775 } 776 777 778 779 780 sal_Int32 Layouter::Implementation::ResolvePositionInGap ( 781 sal_Int32 nDistanceIntoGap, 782 GapMembership eGapMembership, 783 sal_Int32 nIndex, 784 sal_Int32 nGap) const 785 { 786 switch (eGapMembership) 787 { 788 case GM_NONE: 789 // The gap is no man's land. 790 nIndex = -1; 791 break; 792 793 case GM_BOTH: 794 { 795 // The lower half of the gap belongs to the next row or column. 796 sal_Int32 nFirstHalfGapWidth = nGap / 2; 797 if (nDistanceIntoGap > nFirstHalfGapWidth) 798 nIndex ++; 799 break; 800 } 801 802 case GM_PREVIOUS: 803 // Row or column already at correct value. 804 break; 805 806 case GM_NEXT: 807 // The complete gap belongs to the next row or column. 808 nIndex ++; 809 break; 810 811 case GM_PAGE_BORDER: 812 if (nDistanceIntoGap > 0) 813 { 814 if (nDistanceIntoGap > nGap) 815 { 816 // Inside the border of the next row or column. 817 nIndex ++; 818 } 819 else 820 { 821 // Inside the gap between the page borders. 822 nIndex = -1; 823 } 824 } 825 break; 826 827 default: 828 nIndex = -1; 829 } 830 831 return nIndex; 832 } 833 834 835 836 837 void Layouter::Implementation::CalculateGeometricPosition ( 838 InsertPosition& rPosition, 839 const Size& rIndicatorSize, 840 const bool bIsVertical, 841 model::SlideSorterModel& rModel) const 842 { 843 // 1. Determine right/bottom of the leading page and the left/top of the 844 // trailing page object and how to distribute the missing space. 845 sal_Int32 nLeadingLocation (0); 846 sal_Int32 nTrailingLocation (0); 847 bool bIsLeadingFixed (false); 848 bool bIsTrailingFixed (false); 849 sal_Int32 nSecondaryLocation (0); 850 const sal_Int32 nIndex (rPosition.GetIndex()); 851 852 if (rPosition.IsAtRunStart()) 853 { 854 // Place indicator at the top of the column. 855 const Rectangle aOuterBox (GetPageObjectBox(nIndex)); 856 const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex)); 857 if (bIsVertical) 858 { 859 nLeadingLocation = aOuterBox.Top(); 860 nTrailingLocation = aInnerBox.Top(); 861 nSecondaryLocation = aInnerBox.Center().X(); 862 } 863 else 864 { 865 nLeadingLocation = aOuterBox.Left(); 866 nTrailingLocation = aInnerBox.Left(); 867 nSecondaryLocation = aInnerBox.Center().Y(); 868 } 869 bIsLeadingFixed = true; 870 } 871 else if (rPosition.IsAtRunEnd()) 872 { 873 // Place indicator at the bottom/right of the column/row. 874 875 const Rectangle aOuterBox (GetPageObjectBox(nIndex-1)); 876 const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex-1)); 877 if (bIsVertical) 878 { 879 nLeadingLocation = aInnerBox.Bottom(); 880 nTrailingLocation = aOuterBox.Bottom(); 881 nSecondaryLocation = aInnerBox.Center().X(); 882 } 883 else 884 { 885 nLeadingLocation = aInnerBox.Right(); 886 nTrailingLocation = aOuterBox.Right(); 887 nSecondaryLocation = aInnerBox.Center().Y(); 888 } 889 bIsTrailingFixed = true; 890 if ( ! rPosition.IsExtraSpaceNeeded()) 891 bIsLeadingFixed = true; 892 } 893 else 894 { 895 // Place indicator between two rows/columns. 896 const Rectangle aBox1 (GetInnerBoundingBox(rModel, nIndex-1)); 897 const Rectangle aBox2 (GetInnerBoundingBox(rModel, nIndex)); 898 if (bIsVertical) 899 { 900 nLeadingLocation = aBox1.Bottom(); 901 nTrailingLocation = aBox2.Top(); 902 nSecondaryLocation = (aBox1.Center().X() + aBox2.Center().X()) / 2; 903 } 904 else 905 { 906 nLeadingLocation = aBox1.Right(); 907 nTrailingLocation = aBox2.Left(); 908 nSecondaryLocation = (aBox1.Center().Y() + aBox2.Center().Y()) / 2; 909 } 910 } 911 912 // 2. Calculate the location of the insert indicator and the offsets of 913 // leading and trailing pages. 914 const sal_Int32 nAvailableSpace (nTrailingLocation - nLeadingLocation); 915 const sal_Int32 nRequiredSpace (bIsVertical ? rIndicatorSize.Height():rIndicatorSize.Width()); 916 const sal_Int32 nMissingSpace (::std::max(sal_Int32(0), nRequiredSpace - nAvailableSpace)); 917 sal_Int32 nPrimaryLocation (0); 918 sal_Int32 nLeadingOffset (0); 919 sal_Int32 nTrailingOffset (0); 920 if (bIsLeadingFixed) 921 { 922 nPrimaryLocation = nLeadingLocation + nRequiredSpace/2; 923 if ( ! bIsTrailingFixed) 924 nTrailingOffset = nMissingSpace; 925 } 926 else if (bIsTrailingFixed) 927 { 928 nPrimaryLocation = nTrailingLocation - nRequiredSpace/2; 929 nLeadingOffset = -nMissingSpace; 930 } 931 else 932 { 933 nPrimaryLocation = (nLeadingLocation + nTrailingLocation) /2; 934 nLeadingOffset = -nMissingSpace/2; 935 nTrailingOffset = nMissingSpace + nLeadingOffset; 936 } 937 938 if (bIsVertical) 939 { 940 rPosition.SetGeometricalPosition( 941 Point(nSecondaryLocation, nPrimaryLocation), 942 Point(0, nLeadingOffset), 943 Point(0, nTrailingOffset)); 944 } 945 else 946 { 947 rPosition.SetGeometricalPosition( 948 Point(nPrimaryLocation, nSecondaryLocation), 949 Point(nLeadingOffset, 0), 950 Point(nTrailingOffset, 0)); 951 } 952 } 953 954 955 956 957 Rectangle Layouter::Implementation::GetInnerBoundingBox ( 958 model::SlideSorterModel& rModel, 959 const sal_Int32 nIndex) const 960 { 961 model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); 962 if ( ! pDescriptor) 963 return Rectangle(); 964 965 const Point aLocation (pDescriptor->GetLocation(true)); 966 if (pDescriptor->HasState(model::PageDescriptor::ST_Selected)) 967 return mpPageObjectLayouter->GetBoundingBox( 968 aLocation, 969 PageObjectLayouter::PageObject, 970 PageObjectLayouter::ModelCoordinateSystem); 971 else 972 return mpPageObjectLayouter->GetBoundingBox( 973 aLocation, 974 PageObjectLayouter::Preview, 975 PageObjectLayouter::ModelCoordinateSystem); 976 } 977 978 979 980 981 Range Layouter::Implementation::GetValidHorizontalSizeRange (void) const 982 { 983 return Range( 984 mnLeftBorder + maMinimalSize.Width() + mnRightBorder, 985 mnLeftBorder + maMaximalSize.Width() + mnRightBorder); 986 } 987 988 989 990 991 Range Layouter::Implementation::GetValidVerticalSizeRange (void) const 992 { 993 return Range( 994 mnTopBorder + maMinimalSize.Height() + mnBottomBorder, 995 mnTopBorder + maMaximalSize.Height() + mnBottomBorder); 996 } 997 998 999 1000 1001 Range Layouter::Implementation::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const 1002 { 1003 const sal_Int32 nRow0 (GetRowAtPosition(aVisibleArea.Top(), true, GM_NEXT)); 1004 const sal_Int32 nCol0 (GetColumnAtPosition(aVisibleArea.Left(),true, GM_NEXT)); 1005 const sal_Int32 nRow1 (GetRowAtPosition(aVisibleArea.Bottom(), true, GM_PREVIOUS)); 1006 const sal_Int32 nCol1 (GetColumnAtPosition(aVisibleArea.Right(), true, GM_PREVIOUS)); 1007 1008 // When start and end lie in different rows then the range may include 1009 // slides outside (left or right of) the given area. 1010 return Range(GetIndex(nRow0,nCol0,true), GetIndex(nRow1,nCol1,true)); 1011 } 1012 1013 1014 1015 1016 Size Layouter::Implementation::GetTargetSize ( 1017 const Size& rWindowSize, 1018 const Size& rPreviewModelSize, 1019 const bool bCalculateWidth, 1020 const bool bCalculateHeight) const 1021 { 1022 (void)rPreviewModelSize; 1023 1024 if (mnColumnCount<=0 || mnRowCount<=0) 1025 return maPreferredSize; 1026 if ( ! (bCalculateWidth || bCalculateHeight)) 1027 { 1028 OSL_ASSERT(bCalculateWidth || bCalculateHeight); 1029 return maPreferredSize; 1030 } 1031 1032 // Calculate the width of each page object. 1033 Size aTargetSize (0,0); 1034 if (bCalculateWidth) 1035 aTargetSize.setWidth( 1036 (rWindowSize.Width() - mnLeftBorder - mnRightBorder 1037 - (mnColumnCount-1) * mnHorizontalGap) 1038 / mnColumnCount); 1039 else if (bCalculateHeight) 1040 aTargetSize.setHeight( 1041 (rWindowSize.Height() - mnTopBorder - mnBottomBorder 1042 - (mnRowCount-1) * mnVerticalGap) 1043 / mnRowCount); 1044 1045 if (bCalculateWidth) 1046 { 1047 if (aTargetSize.Width() < maMinimalSize.Width()) 1048 aTargetSize.setWidth(maMinimalSize.Width()); 1049 else if (aTargetSize.Width() > maMaximalSize.Width()) 1050 aTargetSize.setWidth(maMaximalSize.Width()); 1051 } 1052 else if (bCalculateHeight) 1053 { 1054 if (aTargetSize.Height() < maMinimalSize.Height()) 1055 aTargetSize.setHeight(maMinimalSize.Height()); 1056 else if (aTargetSize.Height() > maMaximalSize.Height()) 1057 aTargetSize.setHeight(maMaximalSize.Height()); 1058 } 1059 1060 return aTargetSize; 1061 } 1062 1063 1064 1065 1066 sal_Int32 Layouter::Implementation::GetIndex ( 1067 const sal_Int32 nRow, 1068 const sal_Int32 nColumn, 1069 const bool bClampToValidRange) const 1070 { 1071 if (nRow >= 0 && nColumn >= 0) 1072 { 1073 const sal_Int32 nIndex (nRow * mnColumnCount + nColumn); 1074 if (nIndex >= mnPageCount) 1075 if (bClampToValidRange) 1076 return mnPageCount-1; 1077 else 1078 return -1; 1079 else 1080 return nIndex; 1081 } 1082 else if (bClampToValidRange) 1083 return 0; 1084 else 1085 return -1; 1086 } 1087 1088 1089 1090 1091 Rectangle Layouter::Implementation::GetPageObjectBox ( 1092 const sal_Int32 nIndex, 1093 const bool bIncludeBorderAndGap) const 1094 { 1095 const sal_Int32 nRow (nIndex / mnColumnCount); 1096 const sal_Int32 nColumn (nIndex % mnColumnCount); 1097 1098 const Rectangle aBoundingBox (GetPageObjectBox(nRow,nColumn)); 1099 if (bIncludeBorderAndGap) 1100 return AddBorderAndGap(aBoundingBox, nRow, nColumn); 1101 else 1102 return aBoundingBox; 1103 } 1104 1105 1106 1107 1108 Rectangle Layouter::Implementation::GetPageObjectBox ( 1109 const sal_Int32 nRow, 1110 const sal_Int32 nColumn) const 1111 { 1112 return Rectangle( 1113 Point (mnLeftBorder 1114 + nColumn * maPageObjectSize.Width() 1115 + (nColumn>0 ? nColumn : 0) * mnHorizontalGap, 1116 mnTopBorder 1117 + nRow * maPageObjectSize.Height() 1118 + (nRow>0 ? nRow : 0) * mnVerticalGap), 1119 maPageObjectSize); 1120 } 1121 1122 1123 1124 1125 1126 Rectangle Layouter::Implementation::AddBorderAndGap ( 1127 const Rectangle& rBoundingBox, 1128 const sal_Int32 nRow, 1129 const sal_Int32 nColumn) const 1130 { 1131 Rectangle aBoundingBox (rBoundingBox); 1132 1133 if (nColumn == 0) 1134 aBoundingBox.Left() = 0; 1135 else 1136 aBoundingBox.Left() -= mnHorizontalGap/2; 1137 if (nColumn == mnColumnCount-1) 1138 aBoundingBox.Right() += mnRightBorder; 1139 else 1140 aBoundingBox.Right() += mnHorizontalGap/2; 1141 if (nRow == 0) 1142 aBoundingBox.Top() = 0; 1143 else 1144 aBoundingBox.Top() -= mnVerticalGap/2; 1145 if (nRow == mnRowCount-1) 1146 aBoundingBox.Bottom() += mnBottomBorder; 1147 else 1148 aBoundingBox.Bottom() += mnVerticalGap/2; 1149 return aBoundingBox; 1150 } 1151 1152 1153 1154 1155 Rectangle Layouter::Implementation::GetTotalBoundingBox (void) const 1156 { 1157 sal_Int32 nHorizontalSize = 0; 1158 sal_Int32 nVerticalSize = 0; 1159 if (mnColumnCount > 0) 1160 { 1161 sal_Int32 nRowCount = (mnPageCount+mnColumnCount-1) / mnColumnCount; 1162 nHorizontalSize = 1163 mnLeftBorder 1164 + mnRightBorder 1165 + mnColumnCount * maPageObjectSize.Width(); 1166 if (mnColumnCount > 1) 1167 nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap; 1168 nVerticalSize = 1169 mnTopBorder 1170 + mnBottomBorder 1171 + nRowCount * maPageObjectSize.Height(); 1172 if (nRowCount > 1) 1173 nVerticalSize += (nRowCount-1) * mnVerticalGap; 1174 } 1175 1176 return Rectangle ( 1177 Point(0,0), 1178 Size (nHorizontalSize, nVerticalSize) 1179 ); 1180 } 1181 1182 1183 1184 1185 void Layouter::Implementation::CalculateVerticalLogicalInsertPosition ( 1186 const Point& rModelPosition, 1187 InsertPosition& rPosition) const 1188 { 1189 const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; 1190 const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); 1191 const sal_Int32 nRow (::std::min(mnPageCount, nY / nRowHeight)); 1192 rPosition.SetLogicalPosition ( 1193 nRow, 1194 0, 1195 nRow, 1196 (nRow == 0), 1197 (nRow == mnRowCount), 1198 (nRow >= mnMaxRowCount)); 1199 } 1200 1201 1202 1203 1204 //===== HorizontalImplementation ================================================ 1205 1206 HorizontalImplementation::HorizontalImplementation ( 1207 const SharedSdWindow& rpWindow, 1208 const ::boost::shared_ptr<view::Theme>& rpTheme) 1209 : Implementation(rpWindow, rpTheme) 1210 { 1211 } 1212 1213 1214 1215 1216 HorizontalImplementation::HorizontalImplementation (const Implementation& rImplementation) 1217 : Implementation(rImplementation) 1218 { 1219 } 1220 1221 1222 1223 1224 Layouter::Orientation HorizontalImplementation::GetOrientation (void) const 1225 { 1226 return Layouter::HORIZONTAL; 1227 } 1228 1229 1230 1231 1232 void HorizontalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) 1233 { 1234 (void)rWindowSize; 1235 1236 // Row and column count are fixed (for a given page count.) 1237 mnColumnCount = mnPageCount; 1238 mnRowCount = 1; 1239 } 1240 1241 1242 1243 1244 void HorizontalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) 1245 { 1246 mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) 1247 / (maPageObjectSize.Width() + mnHorizontalGap); 1248 mnMaxRowCount = 1; 1249 } 1250 1251 1252 1253 1254 Size HorizontalImplementation::CalculateTargetSize ( 1255 const Size& rWindowSize, 1256 const Size& rPreviewModelSize) const 1257 { 1258 return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, false, true); 1259 } 1260 1261 1262 1263 1264 void HorizontalImplementation::CalculateLogicalInsertPosition ( 1265 const Point& rModelPosition, 1266 InsertPosition& rPosition) const 1267 { 1268 const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; 1269 const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap); 1270 const sal_Int32 nColumn (::std::min(mnPageCount, nX / nColumnWidth)); 1271 rPosition.SetLogicalPosition ( 1272 0, 1273 nColumn, 1274 nColumn, 1275 (nColumn == 0), 1276 (nColumn == mnColumnCount), 1277 (nColumn >= mnMaxColumnCount)); 1278 } 1279 1280 1281 1282 1283 //===== VerticalImplementation ================================================ 1284 1285 VerticalImplementation::VerticalImplementation ( 1286 const SharedSdWindow& rpWindow, 1287 const ::boost::shared_ptr<view::Theme>& rpTheme) 1288 : Implementation(rpWindow, rpTheme) 1289 { 1290 } 1291 1292 1293 1294 1295 VerticalImplementation::VerticalImplementation (const Implementation& rImplementation) 1296 : Implementation(rImplementation) 1297 { 1298 } 1299 1300 1301 1302 1303 Layouter::Orientation VerticalImplementation::GetOrientation (void) const 1304 { 1305 return Layouter::VERTICAL; 1306 } 1307 1308 1309 1310 1311 void VerticalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) 1312 { 1313 (void)rWindowSize; 1314 1315 // Row and column count are fixed (for a given page count.) 1316 mnRowCount = mnPageCount; 1317 mnColumnCount = 1; 1318 1319 } 1320 1321 1322 1323 1324 void VerticalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) 1325 { 1326 mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) 1327 / (maPageObjectSize.Height() + mnVerticalGap); 1328 mnMaxColumnCount = 1; 1329 } 1330 1331 1332 1333 1334 Size VerticalImplementation::CalculateTargetSize ( 1335 const Size& rWindowSize, 1336 const Size& rPreviewModelSize) const 1337 { 1338 return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, false); 1339 } 1340 1341 1342 1343 1344 void VerticalImplementation::CalculateLogicalInsertPosition ( 1345 const Point& rModelPosition, 1346 InsertPosition& rPosition) const 1347 { 1348 return CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition); 1349 } 1350 1351 1352 1353 1354 //===== GridImplementation ================================================ 1355 1356 GridImplementation::GridImplementation ( 1357 const SharedSdWindow& rpWindow, 1358 const ::boost::shared_ptr<view::Theme>& rpTheme) 1359 : Implementation(rpWindow, rpTheme) 1360 { 1361 } 1362 1363 1364 1365 1366 GridImplementation::GridImplementation (const Implementation& rImplementation) 1367 : Implementation(rImplementation) 1368 { 1369 } 1370 1371 1372 1373 1374 Layouter::Orientation GridImplementation::GetOrientation (void) const 1375 { 1376 return Layouter::GRID; 1377 } 1378 1379 1380 1381 1382 void GridImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) 1383 { 1384 // Calculate the column count. 1385 mnColumnCount 1386 = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder) 1387 / (maPreferredSize.Width() + mnHorizontalGap); 1388 if (mnColumnCount < mnMinimalColumnCount) 1389 mnColumnCount = mnMinimalColumnCount; 1390 if (mnColumnCount > mnMaximalColumnCount) 1391 mnColumnCount = mnMaximalColumnCount; 1392 mnRowCount = (mnPageCount + mnColumnCount-1)/mnColumnCount; 1393 } 1394 1395 1396 1397 1398 void GridImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) 1399 { 1400 mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) 1401 / (maPageObjectSize.Width() + mnHorizontalGap); 1402 mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) 1403 / (maPageObjectSize.Height() + mnVerticalGap); 1404 } 1405 1406 1407 1408 1409 1410 Size GridImplementation::CalculateTargetSize ( 1411 const Size& rWindowSize, 1412 const Size& rPreviewModelSize) const 1413 { 1414 return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, true); 1415 } 1416 1417 1418 1419 1420 void GridImplementation::CalculateLogicalInsertPosition ( 1421 const Point& rModelPosition, 1422 InsertPosition& rPosition) const 1423 { 1424 if (mnColumnCount == 1) 1425 { 1426 CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition); 1427 } 1428 else 1429 { 1430 // Handle the general case of more than one column. 1431 sal_Int32 nRow (::std::min( 1432 mnRowCount-1, 1433 GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH))); 1434 const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; 1435 const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap); 1436 sal_Int32 nColumn (::std::min(mnColumnCount, nX / nColumnWidth)); 1437 sal_Int32 nIndex (nRow * mnColumnCount + nColumn); 1438 bool bIsAtRunEnd (nColumn == mnColumnCount); 1439 1440 if (nIndex >= mnPageCount) 1441 { 1442 nIndex = mnPageCount; 1443 nRow = mnRowCount-1; 1444 nColumn = ::std::min(::std::min(mnPageCount, mnColumnCount), nColumn); 1445 bIsAtRunEnd = true; 1446 } 1447 1448 rPosition.SetLogicalPosition ( 1449 nRow, 1450 nColumn, 1451 nIndex, 1452 (nColumn == 0), 1453 bIsAtRunEnd, 1454 (nColumn >= mnMaxColumnCount)); 1455 } 1456 } 1457 1458 1459 1460 1461 //===== InsertPosition ======================================================== 1462 1463 InsertPosition::InsertPosition (void) 1464 : mnRow(-1), 1465 mnColumn(-1), 1466 mnIndex(-1), 1467 mbIsAtRunStart(false), 1468 mbIsAtRunEnd(false), 1469 mbIsExtraSpaceNeeded(false), 1470 maLocation(0,0), 1471 maLeadingOffset(0,0), 1472 maTrailingOffset(0,0) 1473 { 1474 } 1475 1476 1477 1478 1479 InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition) 1480 { 1481 if (this != &rInsertPosition) 1482 { 1483 mnRow = rInsertPosition.mnRow; 1484 mnColumn = rInsertPosition.mnColumn; 1485 mnIndex = rInsertPosition.mnIndex; 1486 mbIsAtRunStart = rInsertPosition.mbIsAtRunStart; 1487 mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd; 1488 mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded; 1489 maLocation = rInsertPosition.maLocation; 1490 maLeadingOffset = rInsertPosition.maLeadingOffset; 1491 maTrailingOffset = rInsertPosition.maTrailingOffset; 1492 } 1493 return *this; 1494 } 1495 1496 1497 1498 1499 bool InsertPosition::operator== (const InsertPosition& rInsertPosition) const 1500 { 1501 // Do not compare the geometrical information (maLocation). 1502 return mnRow==rInsertPosition.mnRow 1503 && mnColumn==rInsertPosition.mnColumn 1504 && mnIndex==rInsertPosition.mnIndex 1505 && mbIsAtRunStart==rInsertPosition.mbIsAtRunStart 1506 && mbIsAtRunEnd==rInsertPosition.mbIsAtRunEnd 1507 && mbIsExtraSpaceNeeded==rInsertPosition.mbIsExtraSpaceNeeded; 1508 } 1509 1510 1511 1512 1513 bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const 1514 { 1515 return !operator==(rInsertPosition); 1516 } 1517 1518 1519 1520 1521 void InsertPosition::SetLogicalPosition ( 1522 const sal_Int32 nRow, 1523 const sal_Int32 nColumn, 1524 const sal_Int32 nIndex, 1525 const bool bIsAtRunStart, 1526 const bool bIsAtRunEnd, 1527 const bool bIsExtraSpaceNeeded) 1528 { 1529 mnRow = nRow; 1530 mnColumn = nColumn; 1531 mnIndex = nIndex; 1532 mbIsAtRunStart = bIsAtRunStart; 1533 mbIsAtRunEnd = bIsAtRunEnd; 1534 mbIsExtraSpaceNeeded = bIsExtraSpaceNeeded; 1535 } 1536 1537 1538 1539 1540 void InsertPosition::SetGeometricalPosition( 1541 const Point aLocation, 1542 const Point aLeadingOffset, 1543 const Point aTrailingOffset) 1544 { 1545 maLocation = aLocation; 1546 maLeadingOffset = aLeadingOffset; 1547 maTrailingOffset = aTrailingOffset; 1548 } 1549 1550 1551 1552 } } } // end of namespace ::sd::slidesorter::namespace 1553