LCOV - code coverage report
Current view: top level - libreoffice/sd/source/ui/slidesorter/view - SlsLayouter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 404 0.0 %
Date: 2012-12-27 Functions: 0 67 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10