diff options
author | Noel Power <noel.power@suse.com> | 2013-02-19 17:29:32 +0000 |
---|---|---|
committer | Noel Power <noel.power@suse.com> | 2013-02-19 18:09:24 +0000 |
commit | 2b1aa949539d2fcbb3d349be3c279996630d83fc (patch) | |
tree | 661e8b800eda9c0fcc4b6228e61183e3b05ab033 /sc | |
parent | Avoid infinite recursion (diff) | |
download | core-2b1aa949539d2fcbb3d349be3c279996630d83fc.tar.gz core-2b1aa949539d2fcbb3d349be3c279996630d83fc.zip |
fdo#56276 - resize/reposition rotated shapes in a sensible way
Change-Id: Ifa4f848da21838591daa1f57fb42dfd3f4fa8044
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/document.hxx | 10 | ||||
-rw-r--r-- | sc/inc/drwlayer.hxx | 7 | ||||
-rw-r--r-- | sc/inc/table.hxx | 10 | ||||
-rw-r--r-- | sc/inc/userdat.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/documen3.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 18 | ||||
-rw-r--r-- | sc/source/core/data/drwlayer.cxx | 182 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 18 | ||||
-rw-r--r-- | sc/source/core/data/table5.cxx | 4 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlexprt.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/unoobj/shapeuno.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/view/drawvie3.cxx | 2 |
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) |