summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Power <noel.power@suse.com>2013-02-19 17:29:32 +0000
committerNoel Power <noel.power@suse.com>2013-02-19 18:09:24 +0000
commit2b1aa949539d2fcbb3d349be3c279996630d83fc (patch)
tree661e8b800eda9c0fcc4b6228e61183e3b05ab033
parent0d05957cf0c38abab45030ba172025e4ef318f43 (diff)
fdo#56276 - resize/reposition rotated shapes in a sensible way
Change-Id: Ifa4f848da21838591daa1f57fb42dfd3f4fa8044
-rw-r--r--sc/inc/document.hxx10
-rw-r--r--sc/inc/drwlayer.hxx7
-rw-r--r--sc/inc/table.hxx10
-rw-r--r--sc/inc/userdat.hxx1
-rw-r--r--sc/source/core/data/documen3.cxx10
-rw-r--r--sc/source/core/data/document.cxx18
-rw-r--r--sc/source/core/data/drwlayer.cxx182
-rw-r--r--sc/source/core/data/table2.cxx18
-rw-r--r--sc/source/core/data/table5.cxx4
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx2
-rw-r--r--sc/source/ui/unoobj/shapeuno.cxx7
-rw-r--r--sc/source/ui/view/drawvie3.cxx2
12 files changed, 199 insertions, 72 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 4e1014514ad6..0663cb9f6982 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1300,14 +1300,14 @@ public:
sal_uInt16 nNewHeight );
SC_DLLPUBLIC void SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bManual );
- SC_DLLPUBLIC sal_uInt16 GetColWidth( SCCOL nCol, SCTAB nTab ) const;
+ SC_DLLPUBLIC sal_uInt16 GetColWidth( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero = true ) const;
SC_DLLPUBLIC sal_uInt16 GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero = true ) const;
SC_DLLPUBLIC sal_uInt16 GetRowHeight( SCROW nRow, SCTAB nTab, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero = true ) const;
- SC_DLLPUBLIC sal_uLong GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const;
+ SC_DLLPUBLIC sal_uLong GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero = true ) const;
SCROW GetRowForHeight( SCTAB nTab, sal_uLong nHeight ) const;
sal_uLong GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale ) const;
- SC_DLLPUBLIC sal_uLong GetColOffset( SCCOL nCol, SCTAB nTab ) const;
- SC_DLLPUBLIC sal_uLong GetRowOffset( SCROW nRow, SCTAB nTab ) const;
+ SC_DLLPUBLIC sal_uLong GetColOffset( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero = true ) const;
+ SC_DLLPUBLIC sal_uLong GetRowOffset( SCROW nRow, SCTAB nTab, bool bHiddenAsZero = true ) const;
SC_DLLPUBLIC sal_uInt16 GetOriginalWidth( SCCOL nCol, SCTAB nTab ) const;
SC_DLLPUBLIC sal_uInt16 GetOriginalHeight( SCROW nRow, SCTAB nTab ) const;
@@ -1458,7 +1458,7 @@ public:
void RestorePrintRanges( const ScPrintRangeSaver& rSaver );
SC_DLLPUBLIC Rectangle GetMMRect( SCCOL nStartCol, SCROW nStartRow,
- SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const;
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero = true ) const;
SC_DLLPUBLIC ScRange GetRange( SCTAB nTab, const Rectangle& rMMRect ) const;
void UpdStlShtPtrsFrmNms();
diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index 72b980d5fea7..0329f6c7ad5a 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -93,6 +93,7 @@ private:
SCsCOL nDx,SCsROW nDy, bool bUpdateNoteCaptionPos );
void RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos );
+ void ResizeLastRectFromAnchor( SdrObject* pObj, ScDrawObjData& rData, bool bUseLogicRect, bool bNegativePage, bool bCanResize, bool bHiddenAsZero = true );
public:
ScDrawLayer( ScDocument* pDocument, const String& rName );
@@ -169,14 +170,16 @@ public:
static bool IsCellAnchored( const SdrObject& rObj );
static void SetPageAnchored( SdrObject& );
static void SetCellAnchored( SdrObject&, const ScDrawObjData &rAnchor );
+ static void SetVisualCellAnchored( SdrObject&, const ScDrawObjData &rAnchor );
// Updates rAnchor based on position of rObj
- static void GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab );
+ static void GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true, bool bHiddenAsZero = true );
static void SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab );
- static void UpdateCellAnchorFromPositionEnd( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab );
+ static void UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true );
static ScAnchorType GetAnchorType( const SdrObject& );
// positions for detektive lines
static ScDrawObjData* GetObjData( SdrObject* pObj, sal_Bool bCreate=false );
+ static ScDrawObjData* GetNonRotatedObjData( SdrObject* pObj, sal_Bool bCreate=false );
// The sheet information in ScDrawObjData isn't updated when sheets are inserted/deleted.
// Use this method to get an object with positions on the specified sheet (should be the
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index fd2aece5e356..a43c04d3cedf 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -629,12 +629,12 @@ public:
// nPPT to test for modification
void SetManualHeight( SCROW nStartRow, SCROW nEndRow, bool bManual );
- sal_uInt16 GetColWidth( SCCOL nCol ) const;
+ sal_uInt16 GetColWidth( SCCOL nCol, bool bHiddenAsZero = true ) const;
SC_DLLPUBLIC sal_uInt16 GetRowHeight( SCROW nRow, SCROW* pStartRow = NULL, SCROW* pEndRow = NULL, bool bHiddenAsZero = true ) const;
- sal_uLong GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const;
+ sal_uLong GetRowHeight( SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero = true ) const;
sal_uLong GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const;
- sal_uLong GetColOffset( SCCOL nCol ) const;
- sal_uLong GetRowOffset( SCROW nRow ) const;
+ sal_uLong GetColOffset( SCCOL nCol, bool bHiddenAsZero = true ) const;
+ sal_uLong GetRowOffset( SCROW nRow, bool bHiddenAsZero = true ) const;
/**
* Get the last row such that the height of row 0 to the end row is as
@@ -727,7 +727,7 @@ public:
SCROW FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
SCROW LastVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
SCROW CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const;
- sal_uInt32 GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) const;
+ sal_uInt32 GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero = true) const;
SCCOLROW LastHiddenColRow(SCCOLROW nPos, bool bCol) const;
diff --git a/sc/inc/userdat.hxx b/sc/inc/userdat.hxx
index 06939d26210a..29f09b5caffe 100644
--- a/sc/inc/userdat.hxx
+++ b/sc/inc/userdat.hxx
@@ -34,6 +34,7 @@
#define SC_UD_OBJDATA 1
#define SC_UD_IMAPDATA 2
#define SC_UD_MACRODATA 3
+#define SC_UD_ALTOBJDATA 4
//-------------------------------------------------------------------------
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 8e0fa5baacf8..7089599a9d4a 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -1890,7 +1890,7 @@ void ScDocument::SetDrawDefaults()
UpdateDrawDefaults();
}
-Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const
+Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero ) const
{
if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
{
@@ -1902,15 +1902,15 @@ Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol
Rectangle aRect;
for (i=0; i<nStartCol; i++)
- aRect.Left() += GetColWidth(i,nTab);
- aRect.Top() += GetRowHeight( 0, nStartRow-1, nTab);
+ aRect.Left() += GetColWidth(i,nTab, bHiddenAsZero );
+ aRect.Top() += GetRowHeight( 0, nStartRow-1, nTab, bHiddenAsZero );
aRect.Right() = aRect.Left();
aRect.Bottom() = aRect.Top();
for (i=nStartCol; i<=nEndCol; i++)
- aRect.Right() += GetColWidth(i,nTab);
- aRect.Bottom() += GetRowHeight( nStartRow, nEndRow, nTab);
+ aRect.Right() += GetColWidth(i,nTab, bHiddenAsZero);
+ aRect.Bottom() += GetRowHeight( nStartRow, nEndRow, nTab, bHiddenAsZero );
aRect.Left() = (long)(aRect.Left() * HMM_PER_TWIPS);
aRect.Right() = (long)(aRect.Right() * HMM_PER_TWIPS);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 10e92de82dca..c5806353b9c8 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3498,10 +3498,10 @@ void ScDocument::SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bo
}
-sal_uInt16 ScDocument::GetColWidth( SCCOL nCol, SCTAB nTab ) const
+sal_uInt16 ScDocument::GetColWidth( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero ) const
{
if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
- return maTabs[nTab]->GetColWidth( nCol );
+ return maTabs[nTab]->GetColWidth( nCol, bHiddenAsZero );
OSL_FAIL("Falsche Tabellennummer");
return 0;
}
@@ -3552,17 +3552,17 @@ sal_uInt16 ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, SCROW* pStartRow, S
}
-sal_uLong ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const
+sal_uLong ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero ) const
{
if (nStartRow == nEndRow)
- return GetRowHeight( nStartRow, nTab); // faster for a single row
+ return GetRowHeight( nStartRow, nTab, bHiddenAsZero ); // faster for a single row
// check bounds because this method replaces former for(i=start;i<=end;++i) loops
if (nStartRow > nEndRow)
return 0;
if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
- return maTabs[nTab]->GetRowHeight( nStartRow, nEndRow);
+ return maTabs[nTab]->GetRowHeight( nStartRow, nEndRow, bHiddenAsZero );
OSL_FAIL("wrong sheet number");
return 0;
@@ -3600,19 +3600,19 @@ SCROW ScDocument::GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const
}
-sal_uLong ScDocument::GetColOffset( SCCOL nCol, SCTAB nTab ) const
+sal_uLong ScDocument::GetColOffset( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero ) const
{
if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
- return maTabs[nTab]->GetColOffset( nCol );
+ return maTabs[nTab]->GetColOffset( nCol, bHiddenAsZero );
OSL_FAIL("Falsche Tabellennummer");
return 0;
}
-sal_uLong ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab ) const
+sal_uLong ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const
{
if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
- return maTabs[nTab]->GetRowOffset( nRow );
+ return maTabs[nTab]->GetRowOffset( nRow, bHiddenAsZero );
OSL_FAIL("Falsche Tabellennummer");
return 0;
}
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 8ea4fcaa4b9f..4b4198cfe779 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -73,6 +73,7 @@
#include "postit.hxx"
#include "attrib.hxx"
#include "charthelper.hxx"
+#include "basegfx/matrix/b2dhommatrix.hxx"
#include <vcl/field.hxx>
@@ -593,6 +594,41 @@ namespace
static_cast<long>(aRange.getMaxX()), static_cast<long>(aRange.getMaxY()));
}
}
+void ScDrawLayer::ResizeLastRectFromAnchor( SdrObject* pObj, ScDrawObjData& rData, bool bUseLogicRect, bool bNegativePage, bool bCanResize, bool bHiddenAsZero )
+{
+ rData.maLastRect = ( bUseLogicRect ? pObj->GetLogicRect() : pObj->GetSnapRect() );
+ SCCOL nCol1 = rData.maStart.Col();
+ SCROW nRow1 = rData.maStart.Row();
+ SCTAB nTab1 = rData.maStart.Tab();
+ SCCOL nCol2 = rData.maEnd.Col();
+ SCROW nRow2 = rData.maEnd.Row();
+ SCTAB nTab2 = rData.maEnd.Tab();
+ Point aPos( pDoc->GetColOffset( nCol1, nTab1, bHiddenAsZero ), pDoc->GetRowOffset( nRow1, nTab1, bHiddenAsZero ) );
+ TwipsToMM( aPos.X() );
+ TwipsToMM( aPos.Y() );
+ aPos += lcl_calcAvailableDiff(*pDoc, nCol1, nRow1, nTab1, rData.maStartOffset);
+
+ if( bCanResize )
+ {
+ Point aEnd( pDoc->GetColOffset( nCol2, nTab2, bHiddenAsZero ), pDoc->GetRowOffset( nRow2, nTab2, bHiddenAsZero ) );
+ TwipsToMM( aEnd.X() );
+ TwipsToMM( aEnd.Y() );
+ aEnd += lcl_calcAvailableDiff(*pDoc, nCol2, nRow2, nTab2, rData.maEndOffset);
+
+ Rectangle aNew = Rectangle( aPos, aEnd );
+ if ( bNegativePage )
+ MirrorRectRTL( aNew );
+
+ rData.maLastRect = lcl_makeSafeRectangle(aNew);
+ }
+ else
+ {
+ if ( bNegativePage )
+ aPos.X() = -aPos.X() - rData.maLastRect.GetWidth();
+ // shouldn't we initialise maLastRect with the object rectangle ?
+ rData.maLastRect.SetPos( aPos );
+ }
+}
void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos )
{
@@ -751,32 +787,66 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati
bool bCanResize = bValid2 && !pObj->IsResizeProtect();
//First time positioning, must be able to at least move it
+ ScDrawObjData& rNoRotatedAnchor = *GetNonRotatedObjData( pObj, true );
if (rData.maLastRect.IsEmpty())
- rData.maLastRect = pObj->GetLogicRect();
+ {
+ // It's confusing ( but blame that we persist the anchor in terms of unrotated shape )
+ // that the initial anchor we get here is in terms of an unrotated shape ( if the shape is rotated )
+ // we need to save the old anchor ( for persisting ) and also track any resize or repositions that happen.
+
+ // This is an evil hack, having a anchor that is one minute in terms of untransformed object and then later
+ // in terms of the transformed object is not ideal, similary having 2 anchors per object is wasteful, can't
+ // see another way out of this at the moment though.
+ rNoRotatedAnchor.maStart = rData.maStart;
+ rNoRotatedAnchor.maEnd = rData.maEnd;
+ rNoRotatedAnchor.maStartOffset = rData.maStartOffset;
+ rNoRotatedAnchor.maEndOffset = rData.maEndOffset;
+
+ Rectangle aRect = pObj->GetLogicRect();
+
+ // get bounding rectangle of shape ( include any hidden row/columns ), <sigh> we need to do this
+ // because if the shape is rotated the anchor from xml is in terms of the unrotated shape, if
+ // the shape is hidden ( by the rows that contain the shape being hidden ) then our hack of
+ // trying to infer the 'real' e.g. rotated anchor from the SnapRect will fail ( because the LogicRect will
+ // not have the correct position or size ) The only way we can possible do this is to first get the
+ // 'unrotated' shape dimensions from the persisted Anchor (from xml) and then 'create' an Anchor from the
+ // associated rotated shape ( note: we do this by actually setting the LogicRect for the shape temporarily to the
+ // *full* size then grabbing the SnapRect ( which gives the transformed rotated dimensions ), it would be
+ // wonderful if we could do this mathematically without having to temporarily tweak the object... othoh this way
+ // is gauranteed to get consistent results )
+ ResizeLastRectFromAnchor( pObj, rData, true, bNegativePage, bCanResize, false );
+ // aFullRect contains the unrotated size and position of the shape ( regardless of any hidden row/columns )
+ Rectangle aFullRect = rData.maLastRect;
+
+ // get current size and position from the anchor for use later
+ ResizeLastRectFromAnchor( pObj, rNoRotatedAnchor, true, bNegativePage, bCanResize );
+
+ // resize/position the shape to *full* size e.g. how it would be ( if no hidden rows/cols affected things )
+ pObj->SetLogicRect(aFullRect);
+ // capture rotated shape ( if relevant )
+ aRect = pObj->GetSnapRect();
+
+ // Ok, here is more nastyness, from xml the Anchor is in terms of the LogicRect which is the
+ // untransformed unrotated shape, here we swap out that initial anchor and from now on use
+ // an Anchor based on the SnapRect ( which is what you see on the screen )
+ ScDrawLayer::GetCellAnchorFromPosition( *pObj, rData, *pDoc, nTab1, false, false );
+ // reset shape to true 'maybe affected by hidden rows/cols' size calculated previously
+ pObj->SetLogicRect(rNoRotatedAnchor.maLastRect);
+ }
- OSL_ENSURE( bValid1, "ScDrawLayer::RecalcPos - invalid start position" );
- Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
- TwipsToMM( aPos.X() );
- TwipsToMM( aPos.Y() );
- aPos += lcl_calcAvailableDiff(*pDoc, nCol1, nRow1, nTab1, rData.maStartOffset);
+ // update anchor with snap rect
+ ResizeLastRectFromAnchor( pObj, rData, false, bNegativePage, bCanResize );
if( bCanResize )
{
- Point aEnd( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) );
- TwipsToMM( aEnd.X() );
- TwipsToMM( aEnd.Y() );
- aEnd += lcl_calcAvailableDiff(*pDoc, nCol2, nRow2, nTab2, rData.maEndOffset);
+ Rectangle aNew = rData.maLastRect;
- Rectangle aNew( aPos, aEnd );
- if ( bNegativePage )
- MirrorRectRTL( aNew );
- if ( pObj->GetLogicRect() != aNew )
+ if ( pObj->GetSnapRect() != aNew )
{
- Rectangle aOld(pObj->GetLogicRect());
+ Rectangle aOld(pObj->GetSnapRect());
if (bRecording)
AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
- rData.maLastRect = lcl_makeSafeRectangle(aNew);
if (pObj->IsPolyObj())
{
// Polyline objects need special treatment.
@@ -787,23 +857,25 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati
double fYFrac = static_cast<double>(aNew.GetHeight()) / static_cast<double>(aOld.GetHeight());
pObj->NbcResize(aNew.TopLeft(), Fraction(fXFrac), Fraction(fYFrac));
}
-
- pObj->SetLogicRect(rData.maLastRect);
+ // order of these lines is important, modify rData.maLastRect carefully it is used as both
+ // a value and a flag for initialisation
+ rData.maLastRect = lcl_makeSafeRectangle(rData.maLastRect);
+ pObj->SetSnapRect(rData.maLastRect);
+ // update 'unrotated anchor' it's the anchor we persist, it must be kept in sync
+ // with the normal Anchor
+ ResizeLastRectFromAnchor( pObj, rNoRotatedAnchor, true, bNegativePage, bCanResize );
}
}
else
{
- if ( bNegativePage )
- aPos.X() = -aPos.X() - rData.maLastRect.GetWidth();
+ Point aPos( rData.maLastRect.getX(), rData.maLastRect.getY() );
if ( pObj->GetRelativePos() != aPos )
{
if (bRecording)
AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
- rData.maLastRect.SetPos( aPos );
pObj->SetRelativePos( aPos );
}
}
-
/*
* If we were not allowed resize the object, then the end cell anchor
* is possibly incorrect now, and if the object has no end-cell (e.g.
@@ -811,7 +883,12 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati
*/
bool bEndAnchorIsBad = !bValid2 || pObj->IsResizeProtect();
if (bEndAnchorIsBad)
- ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, *pDoc, nTab1);
+ {
+ // update 'rotated' anchor
+ ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, rData, *pDoc, nTab1, false);
+ // update 'unrotated' anchor
+ ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, rNoRotatedAnchor, *pDoc, nTab1 );
+ }
}
}
@@ -1725,6 +1802,15 @@ namespace
}
}
+void ScDrawLayer::SetVisualCellAnchored( SdrObject &rObj, const ScDrawObjData &rAnchor )
+{
+ ScDrawObjData* pAnchor = GetNonRotatedObjData( &rObj, true );
+ pAnchor->maStart = rAnchor.maStart;
+ pAnchor->maEnd = rAnchor.maEnd;
+ pAnchor->maStartOffset = rAnchor.maStartOffset;
+ pAnchor->maEndOffset = rAnchor.maEndOffset;
+}
+
void ScDrawLayer::SetCellAnchored( SdrObject &rObj, const ScDrawObjData &rAnchor )
{
ScDrawObjData* pAnchor = GetObjData( &rObj, true );
@@ -1738,20 +1824,33 @@ void ScDrawLayer::SetCellAnchored( SdrObject &rObj, const ScDrawObjData &rAnchor
void ScDrawLayer::SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab )
{
ScDrawObjData aAnchor;
- GetCellAnchorFromPosition( rObj, aAnchor, rDoc, nTab );
+ // set anchor in terms of the visual ( SnapRect )
+ // object ( e.g. for when object is rotated )
+ GetCellAnchorFromPosition( rObj, aAnchor, rDoc, nTab, false );
SetCellAnchored( rObj, aAnchor );
+ // - keep also an anchor in terms of the Logic ( untransformed ) object
+ // because thats what we stored ( and still do ) to xml
+ ScDrawObjData aVisAnchor;
+ GetCellAnchorFromPosition( rObj, aVisAnchor, rDoc, nTab );
+ SetVisualCellAnchored( rObj, aVisAnchor );
+ // absolutely necessary to set flag that in order to preven ScDrawLayer::RecalcPos
+ // doing an initialisation hack
+ if ( ScDrawObjData* pAnchor = GetObjData( &rObj ) )
+ {
+ pAnchor->maLastRect = rObj.GetSnapRect();
+ }
}
-void ScDrawLayer::GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab )
+void ScDrawLayer::GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect, bool bHiddenAsZero )
{
- Rectangle aObjRect(rObj.GetLogicRect());
+ Rectangle aObjRect( bUseLogicRect ? rObj.GetLogicRect() : rObj.GetSnapRect() );
ScRange aRange = rDoc.GetRange( nTab, aObjRect );
Rectangle aCellRect;
rAnchor.maStart = aRange.aStart;
aCellRect = rDoc.GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(),
- aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab() );
+ aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(), bHiddenAsZero );
rAnchor.maStartOffset.Y() = aObjRect.Top()-aCellRect.Top();
if (!rDoc.IsNegativePage(nTab))
rAnchor.maStartOffset.X() = aObjRect.Left()-aCellRect.Left();
@@ -1760,7 +1859,7 @@ void ScDrawLayer::GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAn
rAnchor.maEnd = aRange.aEnd;
aCellRect = rDoc.GetMMRect( aRange.aEnd.Col(), aRange.aEnd.Row(),
- aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab() );
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(), bHiddenAsZero );
rAnchor.maEndOffset.Y() = aObjRect.Bottom()-aCellRect.Top();
if (!rDoc.IsNegativePage(nTab))
rAnchor.maEndOffset.X() = aObjRect.Right()-aCellRect.Left();
@@ -1769,12 +1868,13 @@ void ScDrawLayer::GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAn
}
-void ScDrawLayer::UpdateCellAnchorFromPositionEnd( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab )
+
+void ScDrawLayer::UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect )
{
- Rectangle aObjRect(rObj.GetLogicRect());
+ Rectangle aObjRect(bUseLogicRect ? rObj.GetLogicRect() : rObj.GetSnapRect());
ScRange aRange = rDoc.GetRange( nTab, aObjRect );
- ScDrawObjData* pAnchor = GetObjData( &rObj, true );
+ ScDrawObjData* pAnchor = &rAnchor;
pAnchor->maEnd = aRange.aEnd;
Rectangle aCellRect;
@@ -1797,6 +1897,7 @@ bool ScDrawLayer::IsCellAnchored( const SdrObject& rObj )
void ScDrawLayer::SetPageAnchored( SdrObject &rObj )
{
DeleteFirstUserDataOfType(&rObj, SC_UD_OBJDATA);
+ DeleteFirstUserDataOfType(&rObj, SC_UD_OBJDATA);
}
ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj )
@@ -1806,6 +1907,25 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj )
return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE;
}
+ScDrawObjData* ScDrawLayer::GetNonRotatedObjData( SdrObject* pObj, sal_Bool bCreate )
+{
+ sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
+ sal_uInt16 nFound = 0;
+ for( sal_uInt16 i = 0; i < nCount; i++ )
+ {
+ SdrObjUserData* pData = pObj->GetUserData( i );
+ if( pData && pData->GetInventor() == SC_DRAWLAYER && pData->GetId() == SC_UD_OBJDATA && ++nFound == 2 )
+ return (ScDrawObjData*)pData;
+ }
+ if( pObj && bCreate )
+ {
+ ScDrawObjData* pData = new ScDrawObjData;
+ pObj->AppendUserData(pData);
+ return pData;
+ }
+ return 0;
+}
+
ScDrawObjData* ScDrawLayer::GetObjData( SdrObject* pObj, sal_Bool bCreate )
{
if (SdrObjUserData *pData = GetFirstUserDataOfType(pObj, SC_UD_OBJDATA))
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 045156126d81..23b7a9a60000 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2591,13 +2591,13 @@ void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, bool bManual )
}
-sal_uInt16 ScTable::GetColWidth( SCCOL nCol ) const
+sal_uInt16 ScTable::GetColWidth( SCCOL nCol, bool bHiddenAsZero ) const
{
OSL_ENSURE(ValidCol(nCol),"Falsche Spaltennummer");
if (ValidCol(nCol) && pColFlags && pColWidth)
{
- if (ColHidden(nCol))
+ if (bHiddenAsZero && ColHidden(nCol))
return 0;
else
return pColWidth[nCol];
@@ -2708,7 +2708,7 @@ sal_uInt16 ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow,
}
-sal_uLong ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const
+sal_uLong ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero ) const
{
OSL_ENSURE(ValidRow(nStartRow) && ValidRow(nEndRow),"Falsche Zeilennummer");
@@ -2719,7 +2719,7 @@ sal_uLong ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const
while (nRow <= nEndRow)
{
SCROW nLastRow = -1;
- if (!RowHidden(nRow, NULL, &nLastRow))
+ if (!( ( RowHidden(nRow, NULL, &nLastRow) ) && bHiddenAsZero ) )
{
if (nLastRow > nEndRow)
nLastRow = nEndRow;
@@ -3370,7 +3370,7 @@ ScRangeName* ScTable::GetRangeName() const
}
-sal_uLong ScTable::GetRowOffset( SCROW nRow ) const
+sal_uLong ScTable::GetRowOffset( SCROW nRow, bool bHiddenAsZero ) const
{
sal_uLong n = 0;
if ( mpHiddenRows && mpRowHeights )
@@ -3378,9 +3378,9 @@ sal_uLong ScTable::GetRowOffset( SCROW nRow ) const
if (nRow == 0)
return 0;
else if (nRow == 1)
- return GetRowHeight(0);
+ return GetRowHeight(0, NULL, NULL, bHiddenAsZero );
- n = GetTotalRowHeight(0, nRow-1);
+ n = GetTotalRowHeight(0, nRow-1, bHiddenAsZero);
#if OSL_DEBUG_LEVEL > 0
if (n == ::std::numeric_limits<unsigned long>::max())
OSL_FAIL("ScTable::GetRowOffset: row heights overflow");
@@ -3420,14 +3420,14 @@ SCROW ScTable::GetRowForHeight(sal_uLong nHeight) const
}
-sal_uLong ScTable::GetColOffset( SCCOL nCol ) const
+sal_uLong ScTable::GetColOffset( SCCOL nCol, bool bHiddenAsZero ) const
{
sal_uLong n = 0;
if ( pColWidth )
{
SCCOL i;
for( i = 0; i < nCol; i++ )
- if (!ColHidden(i))
+ if (!( bHiddenAsZero && ColHidden(i) ))
n += pColWidth[i];
}
else
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index ffbda84c87b6..74af647dc41e 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -725,7 +725,7 @@ SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const
return nCount;
}
-sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) const
+sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero ) const
{
sal_uInt32 nHeight = 0;
SCROW nRow = nStartRow;
@@ -738,7 +738,7 @@ sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) const
if (aData.mnRow2 > nEndRow)
aData.mnRow2 = nEndRow;
- if (!aData.mbValue)
+ if ( !( bHiddenAsZero && aData.mbValue ) )
// visible row range.
nHeight += mpRowHeights->getSumValue(nRow, aData.mnRow2);
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 4be03fce76f0..e49bf0b8e558 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -689,7 +689,7 @@ void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCo
if (!pSdrObj)
continue;
- if (ScDrawObjData *pAnchor = ScDrawLayer::GetObjData(pSdrObj))
+ if (ScDrawObjData *pAnchor = ScDrawLayer::GetNonRotatedObjData(pSdrObj))
{
ScMyShape aMyShape;
aMyShape.aAddress = pAnchor->maStart;
diff --git a/sc/source/ui/unoobj/shapeuno.cxx b/sc/source/ui/unoobj/shapeuno.cxx
index 8ac929416df0..6d6f334a2f13 100644
--- a/sc/source/ui/unoobj/shapeuno.cxx
+++ b/sc/source/ui/unoobj/shapeuno.cxx
@@ -432,9 +432,12 @@ void SAL_CALL ScShapeObj::setPropertyValue(
ScDrawObjData aAnchor;
aAnchor.maStart = ScAddress(aAddress.StartColumn, aAddress.StartRow, aAddress.Sheet);
aAnchor.maStartOffset = Point(aRelPoint.X, aRelPoint.Y);
- ScDrawLayer::SetCellAnchored(*pObj, aAnchor);
+ //Uno sets the Anchor in terms of the unorotated shape, not much we can do
+ //about that since uno also displays the shape geometry in terms of the unrotated
+ //shape. #TODO think about changing the anchoring behaviour here too
//Currently we've only got a start anchor, not an end-anchor, so generate that now
- ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, *pDoc, aAddress.Sheet);
+ ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, aAnchor, *pDoc, aAddress.Sheet);
+ ScDrawLayer::SetCellAnchored(*pObj, aAnchor);
}
}
}
diff --git a/sc/source/ui/view/drawvie3.cxx b/sc/source/ui/view/drawvie3.cxx
index cb3799f8c542..d51f18bbf45a 100644
--- a/sc/source/ui/view/drawvie3.cxx
+++ b/sc/source/ui/view/drawvie3.cxx
@@ -152,7 +152,7 @@ void adjustAnchoredPosition(const SdrHint& rHint, const ScDocument& rDoc, SCTAB
if (pAnchor->meType == ScDrawObjData::CellNote)
return;
- if (pAnchor->maLastRect == pObj->GetLogicRect())
+ if (pAnchor->maLastRect == pObj->GetSnapRect())
return;
if (pAnchor->maStart.Tab() != nTab)