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