[Libreoffice-commits] core.git: sc/inc sc/source

Noel Power noel.power at suse.com
Tue Feb 19 10:10:10 PST 2013


 sc/inc/document.hxx               |   10 +-
 sc/inc/drwlayer.hxx               |    7 +
 sc/inc/table.hxx                  |   10 +-
 sc/inc/userdat.hxx                |    1 
 sc/source/core/data/documen3.cxx  |   10 +-
 sc/source/core/data/document.cxx  |   18 +--
 sc/source/core/data/drwlayer.cxx  |  182 +++++++++++++++++++++++++++++++-------
 sc/source/core/data/table2.cxx    |   18 +--
 sc/source/core/data/table5.cxx    |    4 
 sc/source/filter/xml/xmlexprt.cxx |    2 
 sc/source/ui/unoobj/shapeuno.cxx  |    7 +
 sc/source/ui/view/drawvie3.cxx    |    2 
 12 files changed, 199 insertions(+), 72 deletions(-)

New commits:
commit 2b1aa949539d2fcbb3d349be3c279996630d83fc
Author: Noel Power <noel.power at suse.com>
Date:   Tue Feb 19 17:29:32 2013 +0000

    fdo#56276 - resize/reposition rotated shapes in a sensible way
    
    Change-Id: Ifa4f848da21838591daa1f57fb42dfd3f4fa8044

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 4e10145..0663cb9 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 72b980d..0329f6c 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 fd2aece..a43c04d 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 06939d2..29f09b5 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 8e0fa5b..7089599 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 10e92de..c580635 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 8ea4fca..4b4198c 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 0451561..23b7a9a 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 ffbda84..74af647 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 4be03fc..e49bf0b 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 8ac9294..6d6f334 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 cb3799f..d51f18b 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)


More information about the Libreoffice-commits mailing list