Files
libreoffice/sd/source/ui/slidesorter/view/SlsLayouter.cxx

906 lines
25 KiB
C++

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsLayouter.cxx,v $
* $Revision: 1.11 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#include "precompiled_sd.hxx"
#include "view/SlsLayouter.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "Window.hxx"
#include <basegfx/numeric/ftools.hxx>
namespace sd { namespace slidesorter { namespace view {
Layouter::Layouter (const SharedSdWindow& rpWindow)
: mpWindow(rpWindow),
mnRequestedLeftBorder(5),
mnRequestedRightBorder(5),
mnRequestedTopBorder(5),
mnRequestedBottomBorder(5),
mnLeftBorder(5),
mnRightBorder(5),
mnTopBorder(5),
mnBottomBorder(5),
mnVerticalGap (10),
mnHorizontalGap(10),
mnMinimalWidth(100),
mnPreferredWidth(200),
mnMaximalWidth(300),
mnMinimalColumnCount(1),
mnMaximalColumnCount(4),
mnPageCount(0),
mnColumnCount(1),
mnRowCount(0),
mnMaxColumnCount(0),
mnMaxRowCount(0),
maPageObjectSize(1,1),
mbIsVertical(true)
{
}
Layouter::~Layouter (void)
{
}
::boost::shared_ptr<PageObjectLayouter> Layouter::GetPageObjectLayouter (void) const
{
return mpPageObjectLayouter;
}
void Layouter::SetObjectWidth (
sal_Int32 nMinimalWidth,
sal_Int32 nMaximalWidth,
sal_Int32 nPreferredWidth)
{
if (nMinimalWidth <= nPreferredWidth && nPreferredWidth <= nMaximalWidth)
{
mnMinimalWidth = nMinimalWidth;
mnPreferredWidth = nMaximalWidth;
mnMaximalWidth = nPreferredWidth;
}
}
void Layouter::SetBorders (
sal_Int32 nLeftBorder,
sal_Int32 nRightBorder,
sal_Int32 nTopBorder,
sal_Int32 nBottomBorder)
{
if (nLeftBorder >= 0)
mnRequestedLeftBorder = nLeftBorder;
if (nRightBorder >= 0)
mnRequestedRightBorder = nRightBorder;
if (nTopBorder >= 0)
mnRequestedTopBorder = nTopBorder;
if (nBottomBorder >= 0)
mnRequestedBottomBorder = nBottomBorder;
}
void Layouter::SetGaps (
sal_Int32 nHorizontalGap,
sal_Int32 nVerticalGap)
{
if (nHorizontalGap >= 0)
mnHorizontalGap = nHorizontalGap;
if (nVerticalGap >= 0)
mnVerticalGap = nVerticalGap;
}
void Layouter::SetColumnCount (
sal_Int32 nMinimalColumnCount,
sal_Int32 nMaximalColumnCount)
{
if (nMinimalColumnCount <= nMaximalColumnCount)
{
mnMinimalColumnCount = nMinimalColumnCount;
mnMaximalColumnCount = nMaximalColumnCount;
}
}
bool Layouter::RearrangeHorizontal (
const Size& rWindowSize,
const Size& rPageSize,
const sal_uInt32 nPageCount)
{
OSL_ASSERT(mpWindow);
mbIsVertical = false;
mnPageCount = nPageCount;
if (rWindowSize.Width() > 0
&& rWindowSize.Height() > 0
&& rPageSize.Width() > 0
&& rPageSize.Height() > 0)
{
// Calculate the column count.
mnColumnCount = nPageCount;
mnRowCount = 1;
// Update the border values.
mnLeftBorder = mnRequestedLeftBorder;
mnTopBorder = mnRequestedTopBorder;
mnRightBorder = mnRequestedRightBorder;
mnBottomBorder = mnRequestedBottomBorder;
if (mnColumnCount > 1)
{
int nMinimumBorderWidth = mnHorizontalGap/2;
if (mnLeftBorder < nMinimumBorderWidth)
mnLeftBorder = nMinimumBorderWidth;
if (mnRightBorder < nMinimumBorderWidth)
mnRightBorder = nMinimumBorderWidth;
}
else
{
int nMinimumBorderHeight = mnVerticalGap/2;
if (mnTopBorder < nMinimumBorderHeight)
mnTopBorder = nMinimumBorderHeight;
if (mnBottomBorder < nMinimumBorderHeight)
mnBottomBorder = nMinimumBorderHeight;
}
// Calculate the width of each page object.
sal_uInt32 nTargetHeight = 0;
sal_uInt32 nRowCount = 1;
if (mnColumnCount > 0)
nTargetHeight = (rWindowSize.Height()
- mnTopBorder
- mnBottomBorder
- (nRowCount-1) * mnVerticalGap
)
/ nRowCount;
sal_uInt32 nMinimalHeight (mnMinimalWidth * rPageSize.Height() / rPageSize.Width());
sal_uInt32 nMaximalHeight (mnMaximalWidth * rPageSize.Height() / rPageSize.Width());
if (nTargetHeight < nMinimalHeight)
nTargetHeight = nMinimalHeight;
if (nTargetHeight > nMaximalHeight)
nTargetHeight = nMaximalHeight;
// Setup the page object layouter and ask it for the page object size.
mpPageObjectLayouter.reset(
new PageObjectLayouter(
Size(0, nTargetHeight),
rPageSize,
mpWindow,
nPageCount));
maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize();
mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
/ (maPageObjectSize.Width() + mnHorizontalGap);
mnMaxRowCount = 1;
return true;
}
else
return false;
}
bool Layouter::RearrangeVertical (
const Size& rWindowSize,
const Size& rPreviewModelSize,
const sal_uInt32 nPageCount)
{
OSL_ASSERT(mpWindow);
mbIsVertical = true;
mnPageCount = nPageCount;
if (rWindowSize.Width() > 0
&& rWindowSize.Height() > 0
&& rPreviewModelSize.Width() > 0
&& rPreviewModelSize.Height() > 0)
{
// Calculate the column count.
mnColumnCount = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder)
/ (mnPreferredWidth + mnHorizontalGap);
if (mnColumnCount < mnMinimalColumnCount)
mnColumnCount = mnMinimalColumnCount;
if (mnColumnCount > mnMaximalColumnCount)
mnColumnCount = mnMaximalColumnCount;
mnRowCount = (nPageCount + mnColumnCount-1)/mnColumnCount;
// Update the border values.
mnLeftBorder = mnRequestedLeftBorder;
mnTopBorder = mnRequestedTopBorder;
mnRightBorder = mnRequestedRightBorder;
mnBottomBorder = mnRequestedBottomBorder;
if (mnColumnCount > 1)
{
int nMinimumBorderWidth = mnHorizontalGap/2;
if (mnLeftBorder < nMinimumBorderWidth)
mnLeftBorder = nMinimumBorderWidth;
if (mnRightBorder < nMinimumBorderWidth)
mnRightBorder = nMinimumBorderWidth;
}
else
{
int nMinimumBorderHeight = mnVerticalGap/2;
if (mnTopBorder < nMinimumBorderHeight)
mnTopBorder = nMinimumBorderHeight;
if (mnBottomBorder < nMinimumBorderHeight)
mnBottomBorder = nMinimumBorderHeight;
}
// Calculate the width of each page object.
sal_Int32 nTargetWidth = 0;
if (mnColumnCount > 0)
nTargetWidth = (rWindowSize.Width()
- mnLeftBorder
- mnRightBorder
- (mnColumnCount-1) * mnHorizontalGap
)
/ mnColumnCount;
if (nTargetWidth < mnMinimalWidth)
nTargetWidth = mnMinimalWidth;
if (nTargetWidth > mnMaximalWidth)
nTargetWidth = mnMaximalWidth;
// Setup the page object layouter and ask it for the page object size.
mpPageObjectLayouter.reset(
new PageObjectLayouter(
Size(nTargetWidth, 0),
rPreviewModelSize,
mpWindow,
nPageCount));
maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize();
mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
/ (maPageObjectSize.Width() + mnHorizontalGap);
mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder)
/ (maPageObjectSize.Height() + mnVerticalGap);
return true;
}
else
return false;
}
void Layouter::SetZoom (double nZoomFactor)
{
SetZoom(Fraction(nZoomFactor));
}
void Layouter::SetZoom (Fraction nZoomFactor)
{
OSL_ASSERT(mpWindow);
MapMode aMapMode (mpWindow->GetMapMode());
aMapMode.SetScaleX (nZoomFactor);
aMapMode.SetScaleY (nZoomFactor);
// maPageObjectPixelSize = mpWindow->LogicToPixel (maPageObjectModelSize);
mpWindow->SetMapMode (aMapMode);
}
sal_Int32 Layouter::GetColumnCount (void) const
{
return mnColumnCount;
}
sal_Int32 Layouter::GetRowCount (void) const
{
return mnRowCount;
}
sal_Int32 Layouter::GetRow (const sal_Int32 nIndex) const
{
return nIndex / mnColumnCount;
}
sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const
{
return nIndex % mnColumnCount;
}
sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const
{
const sal_Int32 nIndex (nRow * mnColumnCount + nColumn);
OSL_ASSERT(nIndex>=0);
return ::std::min(nIndex, mnPageCount-1);
}
bool Layouter::IsColumnCountFixed (void) const
{
return mnMinimalColumnCount == mnMaximalColumnCount;
}
Size Layouter::GetPageObjectSize (void) const
{
return maPageObjectSize;
}
Rectangle Layouter::GetPageObjectBox (
const sal_Int32 nIndex,
const bool bIncludeBorderAndGap) const
{
const sal_Int32 nRow (GetRow(nIndex));
const sal_Int32 nColumn (GetColumn(nIndex));
Rectangle aBoundingBox(
Point (mnLeftBorder
+ nColumn * maPageObjectSize.Width()
+ (nColumn>0 ? nColumn : 0) * mnHorizontalGap,
mnTopBorder
+ nRow * maPageObjectSize.Height()
+ (nRow>0 ? nRow : 0) * mnVerticalGap),
maPageObjectSize);
if (bIncludeBorderAndGap)
{
if (nColumn == 0)
aBoundingBox.Left() = 0;
else
aBoundingBox.Left() -= mnHorizontalGap/2;
if (nColumn == mnColumnCount-1)
aBoundingBox.Right() += mnRightBorder;
else
aBoundingBox.Right() += mnHorizontalGap/2;
if (nRow == 0)
aBoundingBox.Top() = 0;
else
aBoundingBox.Top() -= mnVerticalGap/2;
if (nRow == mnRowCount-1)
aBoundingBox.Bottom() += mnBottomBorder;
else
aBoundingBox.Bottom() += mnVerticalGap/2;
}
return aBoundingBox;
}
Rectangle Layouter::GetPageBox (const sal_Int32 nObjectCount) const
{
sal_Int32 nCount (nObjectCount);
if (nCount < 0)
nCount = mnPageCount;
sal_Int32 nHorizontalSize = 0;
sal_Int32 nVerticalSize = 0;
if (mnColumnCount > 0)
{
sal_Int32 nRowCount = (nCount+mnColumnCount-1) / mnColumnCount;
nHorizontalSize =
mnLeftBorder
+ mnRightBorder
+ mnColumnCount * maPageObjectSize.Width();
if (mnColumnCount > 1)
nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap;
nVerticalSize =
mnTopBorder
+ mnBottomBorder
+ nRowCount * maPageObjectSize.Height();
if (nRowCount > 1)
nVerticalSize += (nRowCount-1) * mnVerticalGap;
}
return Rectangle (
Point(0,0),
Size (nHorizontalSize, nVerticalSize)
);
}
InsertPosition Layouter::GetInsertPosition (
const Point& rModelPosition,
const Size& rIndicatorSize,
model::SlideSorterModel& rModel) const
{
InsertPosition aPosition;
CalculateLogicalInsertPosition(rModelPosition, aPosition);
CalculateGeometricPosition(aPosition, rIndicatorSize, GetColumnCount()==1, rModel);
return aPosition;
}
void Layouter::CalculateLogicalInsertPosition (
const Point& rModelPosition,
InsertPosition& rPosition) const
{
// Determine logical position.
if (mnColumnCount == 1)
{
const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2;
const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap);
rPosition.mnRow = ::std::min(mnPageCount, nY / nRowHeight);
rPosition.mnColumn = 0;
rPosition.mnIndex = rPosition.mnRow;
rPosition.mbIsAtRunStart = (rPosition.mnRow == 0);
rPosition.mbIsAtRunEnd = (rPosition.mnRow == mnRowCount);
rPosition.mbIsExtraSpaceNeeded = (rPosition.mnRow >= mnMaxRowCount);
}
else
{
rPosition.mnRow = ::std::min(
mnRowCount-1,
GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH));
const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2;
const sal_Int32 nRowWidth (maPageObjectSize.Width() + mnHorizontalGap);
rPosition.mnColumn = ::std::min(mnColumnCount, nX / nRowWidth);
rPosition.mnIndex = rPosition.mnRow * mnColumnCount + rPosition.mnColumn;
rPosition.mbIsAtRunStart = (rPosition.mnColumn == 0);
rPosition.mbIsAtRunEnd = (rPosition.mnColumn == mnColumnCount);
if (rPosition.mnIndex >= mnPageCount)
{
rPosition.mnIndex = mnPageCount;
rPosition.mnRow = mnRowCount-1;
rPosition.mnColumn = mnPageCount%mnColumnCount;
rPosition.mbIsAtRunEnd = true;
}
rPosition.mbIsExtraSpaceNeeded = (rPosition.mnColumn >= mnMaxColumnCount);
}
}
void Layouter::CalculateGeometricPosition (
InsertPosition& rPosition,
const Size& rIndicatorSize,
const bool bIsVertical,
model::SlideSorterModel& rModel) const
{
// 1. Determine right/bottom of the leading page and the left/top of the
// trailing page object and how to distribute the missing space.
sal_Int32 nLeadingLocation (0);
sal_Int32 nTrailingLocation (0);
bool bIsLeadingFixed (false);
bool bIsTrailingFixed (false);
sal_Int32 nSecondaryLocation (0);
if (rPosition.mbIsAtRunStart)
{
// Place indicator at the top of the column.
const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex));
const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex));
if (bIsVertical)
{
nLeadingLocation = aOuterBox.Top();
nTrailingLocation = aInnerBox.Top();
nSecondaryLocation = aInnerBox.Center().X();
}
else
{
nLeadingLocation = aOuterBox.Left();
nTrailingLocation = aInnerBox.Left();
nSecondaryLocation = aInnerBox.Center().Y();
}
bIsLeadingFixed = true;
}
else if (rPosition.mbIsAtRunEnd)
{
// Place indicator at the bottom/right of the column/row.
const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex-1));
const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex-1));
if (bIsVertical)
{
nLeadingLocation = aInnerBox.Bottom();
nTrailingLocation = aOuterBox.Bottom();
nSecondaryLocation = aInnerBox.Center().X();
}
else
{
nLeadingLocation = aInnerBox.Right();
nTrailingLocation = aOuterBox.Right();
nSecondaryLocation = aInnerBox.Center().Y();
}
bIsTrailingFixed = true;
if ( ! rPosition.mbIsExtraSpaceNeeded)
bIsLeadingFixed = true;
}
else
{
// Place indicator between two rows/columns.
const Rectangle aBox1 (GetInnerBoundingBox(rModel, rPosition.mnIndex-1));
const Rectangle aBox2 (GetInnerBoundingBox(rModel, rPosition.mnIndex));
if (bIsVertical)
{
nLeadingLocation = aBox1.Bottom();
nTrailingLocation = aBox2.Top();
nSecondaryLocation = (aBox1.Center().X() + aBox2.Center().X()) / 2;
}
else
{
nLeadingLocation = aBox1.Right();
nTrailingLocation = aBox2.Left();
nSecondaryLocation = (aBox1.Center().Y() + aBox2.Center().Y()) / 2;
}
}
// 2. Calculate the location of the insert indicator and the offsets of
// leading and trailing pages.
const sal_Int32 nAvailableSpace (nTrailingLocation - nLeadingLocation);
const sal_Int32 nRequiredSpace (bIsVertical ? rIndicatorSize.Height():rIndicatorSize.Width());
const sal_Int32 nMissingSpace (::std::max(sal_Int32(0), nRequiredSpace - nAvailableSpace));
sal_Int32 nPrimaryLocation (0);
sal_Int32 nLeadingOffset (0);
sal_Int32 nTrailingOffset (0);
if (bIsLeadingFixed)
{
nPrimaryLocation = nLeadingLocation + nRequiredSpace/2;
if ( ! bIsTrailingFixed)
nTrailingOffset = nMissingSpace;
}
else if (bIsTrailingFixed)
{
nPrimaryLocation = nTrailingLocation - nRequiredSpace/2;
nLeadingOffset = -nMissingSpace;
}
else
{
nPrimaryLocation = (nLeadingLocation + nTrailingLocation) /2;
nLeadingOffset = -nMissingSpace/2;
nTrailingOffset = nMissingSpace + nLeadingOffset;
}
if (bIsVertical)
{
rPosition.maLocation = Point(nSecondaryLocation, nPrimaryLocation);
rPosition.maLeadingOffset = Point(0, nLeadingOffset);
rPosition.maTrailingOffset = Point(0, nTrailingOffset);
}
else
{
rPosition.maLocation = Point(nPrimaryLocation, nSecondaryLocation);
rPosition.maLeadingOffset = Point(nLeadingOffset, 0);
rPosition.maTrailingOffset = Point(nTrailingOffset, 0);
}
}
Rectangle Layouter::GetInnerBoundingBox (
model::SlideSorterModel& rModel,
const sal_Int32 nIndex) const
{
model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex));
if ( ! pDescriptor)
return Rectangle();
const Point aLocation (pDescriptor->GetLocation(true));
if (pDescriptor->HasState(model::PageDescriptor::ST_Selected))
return GetPageObjectLayouter()->GetBoundingBox(
aLocation,
PageObjectLayouter::PageObject,
PageObjectLayouter::ModelCoordinateSystem);
else
return GetPageObjectLayouter()->GetBoundingBox(
aLocation,
PageObjectLayouter::Preview,
PageObjectLayouter::ModelCoordinateSystem);
}
Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const
{
sal_Int32 nRow0 = GetRowAtPosition (aVisibleArea.Top(), true, GM_BOTH);
sal_Int32 nRow1 = GetRowAtPosition (aVisibleArea.Bottom(),
true, GM_BOTH);
return Range(
::std::min(nRow0 * mnColumnCount, mnPageCount-1),
::std::min((nRow1+1) * mnColumnCount - 1, mnPageCount-1));
}
sal_Int32 Layouter::GetIndexAtPoint (
const Point& rPosition,
const bool bIncludePageBorders) const
{
sal_Int32 nRow = GetRowAtPosition (rPosition.Y(),
bIncludePageBorders,
bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE);
sal_Int32 nColumn = GetColumnAtPosition (rPosition.X(),
bIncludePageBorders,
bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE);
if (nRow >= 0 && nColumn >= 0)
return nRow * mnColumnCount + nColumn;
else
return -1;
}
bool Layouter::IsVertical (void) const
{
return mbIsVertical;
}
sal_Int32 Layouter::GetRowAtPosition (
sal_Int32 nYPosition,
bool bIncludeBordersAndGaps,
GapMembership eGapMembership) const
{
sal_Int32 nRow = -1;
const sal_Int32 nY = nYPosition - mnTopBorder;
if (nY >= 0)
{
// Vertical distance from one row to the next.
const sal_Int32 nRowOffset (maPageObjectSize.Height() + mnVerticalGap);
// Calculate row consisting of page objects and gap below.
nRow = nY / nRowOffset;
const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height());
// When inside the gap below then nYPosition is not over a page
// object.
if (nDistanceIntoGap > 0)
nRow = ResolvePositionInGap (
nDistanceIntoGap,
eGapMembership,
nRow,
mnVerticalGap);
}
else if (bIncludeBordersAndGaps)
{
// We are in the top border area. Set nRow to the first row when
// the top border shall be considered to belong to the first row.
nRow = 0;
}
return nRow;
}
sal_Int32 Layouter::GetColumnAtPosition (
sal_Int32 nXPosition,
bool bIncludeBordersAndGaps,
GapMembership eGapMembership) const
{
sal_Int32 nColumn = -1;
sal_Int32 nX = nXPosition - mnLeftBorder;
if (nX >= 0)
{
// Horizontal distance from one column to the next.
const sal_Int32 nColumnOffset (maPageObjectSize.Width() + mnHorizontalGap);
// Calculate row consisting of page objects and gap below.
nColumn = nX / nColumnOffset;
if (nColumn < 0)
nColumn = 0;
else if (nColumn >= mnColumnCount)
nColumn = mnColumnCount-1;
const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width());
// When inside the gap at the right then nXPosition is not over a
// page object.
if (nDistanceIntoGap > 0)
nColumn = ResolvePositionInGap (
nDistanceIntoGap,
eGapMembership,
nColumn,
mnHorizontalGap);
}
else if (bIncludeBordersAndGaps)
{
// We are in the left border area. Set nColumn to the first column
// when the left border shall be considered to belong to the first
// column.
nColumn = 0;
}
return nColumn;
}
sal_Int32 Layouter::ResolvePositionInGap (
sal_Int32 nDistanceIntoGap,
GapMembership eGapMembership,
sal_Int32 nIndex,
sal_Int32 nGap) const
{
switch (eGapMembership)
{
case GM_NONE:
// The gap is no man's land.
nIndex = -1;
break;
case GM_BOTH:
{
// The lower half of the gap belongs to the next row or column.
sal_Int32 nFirstHalfGapWidth = nGap / 2;
if (nDistanceIntoGap > nFirstHalfGapWidth)
nIndex ++;
break;
}
case GM_PREVIOUS:
// Row or column already at correct value.
break;
case GM_NEXT:
// The complete gap belongs to the next row or column.
nIndex ++;
break;
case GM_PAGE_BORDER:
if (nDistanceIntoGap > 0)
{
if (nDistanceIntoGap > nGap)
{
// Inside the border of the next row or column.
nIndex ++;
}
else
{
// Inside the gap between the page borders.
nIndex = -1;
}
}
break;
default:
nIndex = -1;
}
return nIndex;
}
//===== InsertPosition ========================================================
InsertPosition::InsertPosition (void)
: mnRow(-1),
mnColumn(-1),
mnIndex(-1),
maLocation(0,0),
maLeadingOffset(0,0),
maTrailingOffset(0,0),
mbIsAtRunStart(false),
mbIsAtRunEnd(false),
mbIsExtraSpaceNeeded(false)
{
}
InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition)
{
if (this != &rInsertPosition)
{
mnRow = rInsertPosition.mnRow;
mnColumn = rInsertPosition.mnColumn;
mnIndex = rInsertPosition.mnIndex;
maLocation = rInsertPosition.maLocation;
maLeadingOffset = rInsertPosition.maLeadingOffset;
maTrailingOffset = rInsertPosition.maTrailingOffset;
mbIsAtRunStart = rInsertPosition.mbIsAtRunStart;
mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd;
mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded;
}
return *this;
}
bool InsertPosition::operator== (const InsertPosition& rInsertPosition) const
{
// Do not compare the geometrical information (maLocation).
return mnRow==rInsertPosition.mnRow
&& mnColumn==rInsertPosition.mnColumn
&& mnIndex==rInsertPosition.mnIndex
&& mbIsAtRunStart==rInsertPosition.mbIsAtRunStart
&& mbIsAtRunEnd==rInsertPosition.mbIsAtRunEnd
&& mbIsExtraSpaceNeeded==rInsertPosition.mbIsExtraSpaceNeeded;
}
bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const
{
return !operator==(rInsertPosition);
}
} } } // end of namespace ::sd::slidesorter::namespace