diff options
Diffstat (limited to 'sc')
28 files changed, 166 insertions, 51 deletions
diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx index 92fc4f0449df..123463855a25 100644 --- a/sc/inc/drwlayer.hxx +++ b/sc/inc/drwlayer.hxx @@ -80,6 +80,7 @@ class ScUndoAnchorData : public SdrUndoObj { private: bool mbWasCellAnchored; + bool mbWasResizeWithCell; ScDocument* mpDoc; SCTAB mnTab; public: @@ -174,12 +175,13 @@ public: void EnsureGraphicNames(); static bool IsCellAnchored( const SdrObject& rObj ); + static bool IsResizeWithCell( 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( const 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 SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab, bool bResizeWithCell ); static void UpdateCellAnchorFromPositionEnd( const SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true ); static ScAnchorType GetAnchorType( const SdrObject& ); std::map<SCROW, std::vector<SdrObject*>> GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow); diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 78600a827954..06087e2f1e3a 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -382,8 +382,9 @@ enum ScVObjMode // output modes of objects on a page enum ScAnchorType // anchor of a character object { - SCA_CELL, - SCA_PAGE, + SCA_CELL, // anchor to cell, move with cell + SCA_CELL_RESIZE, // anchor to cell, move and resize with cell + SCA_PAGE, // anchor to page, independent of any cells SCA_DONTKNOW // for multi selection }; diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 71be34add605..64ee13afc73c 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -406,8 +406,9 @@ #define DRAW_BAR_START (RID_INPUTBAR_END) #define SID_ANCHOR_PAGE (DRAW_BAR_START+24) #define SID_ANCHOR_CELL (DRAW_BAR_START+25) -#define SID_ANCHOR_TOGGLE (DRAW_BAR_START+26) -#define SID_ORIGINALSIZE (DRAW_BAR_START+27) +#define SID_ANCHOR_CELL_RESIZE (DRAW_BAR_START+26) +#define SID_ANCHOR_TOGGLE (DRAW_BAR_START+27) +#define SID_ORIGINALSIZE (DRAW_BAR_START+28) #define DRAW_BAR_END (DRAW_BAR_START+50) diff --git a/sc/inc/strings.hrc b/sc/inc/strings.hrc index c46331886c8f..02596e6bccdd 100644 --- a/sc/inc/strings.hrc +++ b/sc/inc/strings.hrc @@ -331,6 +331,7 @@ #define STR_ENABLE_CONTENT NC_("STR_ENABLE_CONTENT", "Enable Content") /*Insert image dialog*/ #define STR_ANCHOR_TO_CELL NC_("STR_ANCHOR_TO_CELL", "To cell") +#define STR_ANCHOR_TO_CELL_RESIZE NC_("STR_ANCHOR_TO_CELL_RESIZE", "To cell (resize with cell)") #define STR_ANCHOR_TO_PAGE NC_("STR_ANCHOR_TO_PAGE", "To page") #endif diff --git a/sc/inc/userdat.hxx b/sc/inc/userdat.hxx index edd73b39c574..fd903dfc1010 100644 --- a/sc/inc/userdat.hxx +++ b/sc/inc/userdat.hxx @@ -42,6 +42,7 @@ public: Point maEndOffset; Type meType; tools::Rectangle maLastRect; + bool mbResizeWithCell = false; explicit ScDrawObjData(); diff --git a/sc/qa/extras/anchor.cxx b/sc/qa/extras/anchor.cxx index 4cdc766c7ffb..5d79caad7df9 100644 --- a/sc/qa/extras/anchor.cxx +++ b/sc/qa/extras/anchor.cxx @@ -99,7 +99,7 @@ void ScAnchorTest::testUndoAnchor() CPPUNIT_ASSERT(pDrawView->AreObjectsMarked() ); // Set Cell Anchor - ScDrawLayer::SetCellAnchoredFromPosition(*pObject, rDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObject, rDoc, 0, false); // Check state ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObject); CPPUNIT_ASSERT_EQUAL(SCA_CELL, oldType); @@ -169,7 +169,7 @@ void ScAnchorTest::testTdf76183() SdrCircObj* pObj = new SdrCircObj(OBJ_CIRC, aOrigRect); pPage->InsertObject(pObj); // Anchor to cell - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, 0, false); const tools::Rectangle& rNewRect = pObj->GetLogicRect(); // Set word wrap to true diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 47ed37c4ee76..3d93aac63cb3 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -3514,7 +3514,7 @@ void ScExportTest::testMoveCellAnchoredShapesODS() // Check cell anchor state ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObj); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL, oldType); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL_RESIZE, oldType); // Get anchor data ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj); @@ -3576,7 +3576,7 @@ void ScExportTest::testMoveCellAnchoredShapesODS() // Check cell anchor state oldType = ScDrawLayer::GetAnchorType(*pObj); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL, oldType); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL_RESIZE, oldType); // Get anchor data pData = ScDrawLayer::GetObjData(pObj); @@ -3637,7 +3637,7 @@ void ScExportTest::testMoveCellAnchoredShapesODS() // Check cell anchor state oldType = ScDrawLayer::GetAnchorType(*pObj); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL, oldType); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL_RESIZE, oldType); // Get anchor data pData = ScDrawLayer::GetObjData(pObj); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 4310cc3020fb..d2544ab010fd 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -2726,7 +2726,7 @@ void Test::testGraphicsInGroup() CPPUNIT_ASSERT_EQUAL_MESSAGE("Should not change when page anchored", const_cast<const tools::Rectangle &>(aOrigRect), rNewRect); - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0, true); CPPUNIT_ASSERT_EQUAL_MESSAGE("That shouldn't change size or positioning", const_cast<const tools::Rectangle &>(aOrigRect), rNewRect); @@ -2751,7 +2751,7 @@ void Test::testGraphicsInGroup() CPPUNIT_ASSERT_EQUAL_MESSAGE("Position and size of the circle shouldn't change when inserted into the page.", const_cast<const tools::Rectangle &>(aOrigRect), rNewRect); - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0, false); CPPUNIT_ASSERT_EQUAL_MESSAGE("Size changed when cell anchored. Not good.", const_cast<const tools::Rectangle &>(aOrigRect), rNewRect); @@ -2784,7 +2784,7 @@ void Test::testGraphicsInGroup() CPPUNIT_ASSERT_EQUAL_MESSAGE("Size differ.", const_cast<const tools::Rectangle &>(aOrigRect), rNewRect); - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0, false); CPPUNIT_ASSERT_EQUAL_MESSAGE("Size changed when cell-anchored. Not good.", const_cast<const tools::Rectangle &>(aOrigRect), rNewRect); @@ -2820,7 +2820,7 @@ void Test::testGraphicsOnSheetMove() tools::Rectangle aObjRect(2,2,100,100); SdrObject* pObj = new SdrRectObj(aObjRect); pPage->InsertObject(pObj); - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0, false); CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be one object on the 1st sheet.", static_cast<size_t>(1), pPage->GetObjCount()); @@ -5652,7 +5652,7 @@ void Test::testAnchoredRotatedShape() double nCos=cos(nAngle*nPi180); pObj->Rotate(aRef1,nAngle,nSin,nCos); - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0, true); tools::Rectangle aSnap = pObj->GetSnapRect(); CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRotRect.GetHeight(), aSnap.GetHeight(), TOLERANCE ) ); @@ -6419,7 +6419,7 @@ void Test::testUndoDataAnchor() tools::Rectangle aObjRect(2,1000,100,1100); SdrObject* pObj = new SdrRectObj(aObjRect); pPage->InsertObject(pObj); - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0, false); // Get anchor data ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj); diff --git a/sc/qa/unit/ucalc_sort.cxx b/sc/qa/unit/ucalc_sort.cxx index 825c608f3643..2aa4a441ab0c 100644 --- a/sc/qa/unit/ucalc_sort.cxx +++ b/sc/qa/unit/ucalc_sort.cxx @@ -1916,7 +1916,7 @@ void Test::testSortImages() CPPUNIT_ASSERT(pPage); pPage->InsertObject(pObj); // Anchor to cell - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0, false); // Move to cell B2 ScAddress aCellPos(1, 1, 0); pDrawLayer->MoveObject(pObj, aCellPos); diff --git a/sc/sdi/drawsh.sdi b/sc/sdi/drawsh.sdi index cfd8108f85b8..feaa7ba0280c 100644 --- a/sc/sdi/drawsh.sdi +++ b/sc/sdi/drawsh.sdi @@ -161,6 +161,7 @@ interface TableDraw SID_ANCHOR_PAGE [ ExecMethod = ExecDrawFunc; StateMethod = GetState; Export = FALSE; ] SID_ANCHOR_TOGGLE [ ExecMethod = ExecDrawFunc; StateMethod = GetDrawFuncState; Export = FALSE; ] SID_ANCHOR_CELL [ ExecMethod = ExecDrawFunc; StateMethod = GetState; Export = FALSE; ] + SID_ANCHOR_CELL_RESIZE [ ExecMethod = ExecDrawFunc; StateMethod = GetState; Export = FALSE; ] // FontWork: SID_FONTWORK [ ExecMethod = ExecDrawFunc; StateMethod = GetState; Export = FALSE; ] SID_FORMTEXT_STYLE [ ExecMethod = ExecFormText; StateMethod = GetFormTextState; Export = FALSE; ] diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index 216aeebc7bc9..8ef6851af217 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -4662,6 +4662,24 @@ SfxVoidItem SetAnchorToCell SID_ANCHOR_CELL ] +SfxVoidItem SetAnchorToCellResize SID_ANCHOR_CELL_RESIZE +() +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = FALSE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::Format; +] + + SfxVoidItem SetAnchorToPage SID_ANCHOR_PAGE () [ diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 9ed0568b45fe..d15cd9d84108 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -146,6 +146,7 @@ ScUndoAnchorData::ScUndoAnchorData( SdrObject* pObjP, ScDocument* pDoc, SCTAB nT mnTab( nTab ) { mbWasCellAnchored = ScDrawLayer::IsCellAnchored( *pObjP ); + mbWasResizeWithCell = ScDrawLayer::IsResizeWithCell( *pObjP ); } ScUndoAnchorData::~ScUndoAnchorData() @@ -162,7 +163,7 @@ void ScUndoAnchorData::Undo() } if (mbWasCellAnchored) - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *mpDoc, mnTab); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *mpDoc, mnTab, mbWasResizeWithCell); else ScDrawLayer::SetPageAnchored( *pObj ); } @@ -172,7 +173,7 @@ void ScUndoAnchorData::Redo() if (mbWasCellAnchored) ScDrawLayer::SetPageAnchored( *pObj ); else - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *mpDoc, mnTab); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *mpDoc, mnTab, mbWasResizeWithCell); // Trigger Object Change if (pObj->IsInserted() && pObj->GetPage() && pObj->GetModel()) @@ -816,14 +817,15 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati // Prevent multiple broadcasts during the series of changes. SdrDelayBroadcastObjectChange aDelayBroadcastObjectChange(*pObj); - bool bCanResize = bValid2 && !pObj->IsResizeProtect(); + bool bCanResize = bValid2 && !pObj->IsResizeProtect() && rData.mbResizeWithCell; //First time positioning, must be able to at least move it ScDrawObjData& rNoRotatedAnchor = *GetNonRotatedObjData( pObj, true ); if (rData.maLastRect.IsEmpty()) { // Every shape it is saved with an negative offset relative to cell - if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL) + ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObj); + if (aAnchorType == SCA_CELL || aAnchorType == SCA_CELL_RESIZE) { double fRotate(0.0); double fShearX(0.0); @@ -1888,6 +1890,7 @@ void ScDrawLayer::SetVisualCellAnchored( SdrObject &rObj, const ScDrawObjData &r pAnchor->maEnd = rAnchor.maEnd; pAnchor->maStartOffset = rAnchor.maStartOffset; pAnchor->maEndOffset = rAnchor.maEndOffset; + pAnchor->mbResizeWithCell = rAnchor.mbResizeWithCell; } void ScDrawLayer::SetCellAnchored( SdrObject &rObj, const ScDrawObjData &rAnchor ) @@ -1897,19 +1900,23 @@ void ScDrawLayer::SetCellAnchored( SdrObject &rObj, const ScDrawObjData &rAnchor pAnchor->maEnd = rAnchor.maEnd; pAnchor->maStartOffset = rAnchor.maStartOffset; pAnchor->maEndOffset = rAnchor.maEndOffset; + pAnchor->mbResizeWithCell = rAnchor.mbResizeWithCell; } -void ScDrawLayer::SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab ) +void ScDrawLayer::SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab, + bool bResizeWithCell ) { ScDrawObjData aAnchor; // set anchor in terms of the visual ( SnapRect ) // object ( e.g. for when object is rotated ) GetCellAnchorFromPosition( rObj, aAnchor, rDoc, nTab, false ); + aAnchor.mbResizeWithCell = bResizeWithCell; SetCellAnchored( rObj, aAnchor ); // - keep also an anchor in terms of the Logic ( untransformed ) object // because that's what we stored ( and still do ) to xml ScDrawObjData aVisAnchor; GetCellAnchorFromPosition( rObj, aVisAnchor, rDoc, nTab ); + aVisAnchor.mbResizeWithCell = bResizeWithCell; SetVisualCellAnchored( rObj, aVisAnchor ); // absolutely necessary to set flag that in order to prevent ScDrawLayer::RecalcPos // doing an initialisation hack @@ -1971,6 +1978,17 @@ bool ScDrawLayer::IsCellAnchored( const SdrObject& rObj ) return GetFirstUserDataOfType(&rObj, SC_UD_OBJDATA) != nullptr; } +bool ScDrawLayer::IsResizeWithCell( const SdrObject& rObj ) +{ + // Cell anchored object always has a user data, to store the anchor cell + // info. If it doesn't then it's page-anchored. + ScDrawObjData* pDrawObjData = GetObjData(const_cast<SdrObject*>(&rObj)); + if (!pDrawObjData) + return false; + + return pDrawObjData->mbResizeWithCell; +} + void ScDrawLayer::SetPageAnchored( SdrObject &rObj ) { DeleteFirstUserDataOfType(&rObj, SC_UD_OBJDATA); @@ -1981,7 +1999,17 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj ) { //If this object has a cell anchor associated with it //then its cell-anchored, otherwise its page-anchored - return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE; + const ScDrawObjData* pObjData = ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)); + + // When there is no cell anchor, it is page anchored. + if (!pObjData) + return SCA_PAGE; + + // It's cell-anchored, check if the object resizes with the cell + if (pObjData->mbResizeWithCell) + return SCA_CELL_RESIZE; + + return SCA_CELL; } std::map<SCROW, std::vector<SdrObject*>> diff --git a/sc/source/core/data/userdat.cxx b/sc/source/core/data/userdat.cxx index 0e4177647ce5..53dd575dd4ca 100644 --- a/sc/source/core/data/userdat.cxx +++ b/sc/source/core/data/userdat.cxx @@ -26,7 +26,8 @@ ScDrawObjData::ScDrawObjData() : SdrObjUserData( SdrInventor::ScOrSwDraw, SC_UD_OBJDATA ), maStart( ScAddress::INITIALIZE_INVALID ), maEnd( ScAddress::INITIALIZE_INVALID ), - meType( DrawingObject ) + meType( DrawingObject ), + mbResizeWithCell( false ) { } diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index 947fc2598ae3..8ba239b0862d 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -3592,7 +3592,7 @@ SdrObject* XclImpDffConverter::FinalizeObj(DffObjData& rDffObjData, SdrObject* p { // cell anchoring if ( !rDffObjData.bPageAnchor ) - ScDrawLayer::SetCellAnchoredFromPosition( *xSdrObj, GetDoc(), xDrawObj->GetTab() ); + ScDrawLayer::SetCellAnchoredFromPosition( *xSdrObj, GetDoc(), xDrawObj->GetTab(), false ); } return xSdrObj.release(); diff --git a/sc/source/filter/inc/drawingbase.hxx b/sc/source/filter/inc/drawingbase.hxx index ae1662bf6ab2..bfb474bbd75b 100644 --- a/sc/source/filter/inc/drawingbase.hxx +++ b/sc/source/filter/inc/drawingbase.hxx @@ -71,8 +71,11 @@ public: { ANCHOR_INVALID, /// Anchor type is unknown. ANCHOR_ABSOLUTE, /// Absolute anchor (top-left corner and size in absolute units). + /// Matches our "Page" anchor -> ScAnchorType::SCA_PAGE ANCHOR_ONECELL, /// One-cell anchor (top-left corner at cell, size in absolute units). + /// Matches our "Cell" anchor -> ScAnchorType::SCA_CELL ANCHOR_TWOCELL, /// Two-cell anchor (top-left and bottom-right corner at cell). + /// Matches our "Cell (resize with cell)" anchor -> ScAnchorType::SCA_CELL_RESIZE ANCHOR_VML }; explicit ShapeAnchor( const WorksheetHelper& rHelper ); diff --git a/sc/source/filter/oox/drawingbase.cxx b/sc/source/filter/oox/drawingbase.cxx index a89dc360e3f4..15b6da334777 100644 --- a/sc/source/filter/oox/drawingbase.cxx +++ b/sc/source/filter/oox/drawingbase.cxx @@ -92,6 +92,8 @@ void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttrib meEditAs = ANCHOR_ABSOLUTE; else if ( sEditAs.equalsIgnoreAsciiCase("oneCell") ) meEditAs = ANCHOR_ONECELL; + else if (sEditAs.equalsIgnoreAsciiCase("twoCell") ) + meEditAs = ANCHOR_TWOCELL; } } break; diff --git a/sc/source/filter/oox/drawingfragment.cxx b/sc/source/filter/oox/drawingfragment.cxx index 8a9ddf098291..5ad5f48a7b02 100644 --- a/sc/source/filter/oox/drawingfragment.cxx +++ b/sc/source/filter/oox/drawingfragment.cxx @@ -293,7 +293,8 @@ void DrawingFragment::onEndElement() SdrObject* pObj = SdrObject::getSdrObjectFromXShape( mxShape->getXShape() ); if ( pObj ) { - ScDrawLayer::SetCellAnchoredFromPosition( *pObj, getScDocument(), getSheetIndex() ); + bool bResizeWithCell = mxAnchor->getEditAs() == ShapeAnchor::ANCHOR_TWOCELL; + ScDrawLayer::SetCellAnchoredFromPosition( *pObj, getScDocument(), getSheetIndex(), bResizeWithCell ); } } } diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index 22e0c9772778..9f1ea2f6d05d 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -1052,11 +1052,15 @@ GetEditAs( const XclObjAny& rObj ) { if( const SdrObject* pShape = EscherEx::GetSdrObject( rObj.GetShape() ) ) { - // OOXTODO: returning "twoCell" switch( ScDrawLayer::GetAnchorType( *pShape ) ) { - case SCA_CELL: return "oneCell"; - default: break; + case SCA_CELL: + return "oneCell"; + case SCA_CELL_RESIZE: + return "twoCell"; + default: + case SCA_PAGE: + break; // absolute } } return "absolute"; diff --git a/sc/source/filter/xml/XMLExportIterator.hxx b/sc/source/filter/xml/XMLExportIterator.hxx index 494551f2bb94..11d88f004f01 100644 --- a/sc/source/filter/xml/XMLExportIterator.hxx +++ b/sc/source/filter/xml/XMLExportIterator.hxx @@ -63,6 +63,7 @@ struct ScMyShape ScAddress aEndAddress; sal_Int32 nEndX; sal_Int32 nEndY; + bool bResizeWithCell; css::uno::Reference<css::drawing::XShape> xShape; bool operator<(const ScMyShape& aShape) const; diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.cxx b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx index eeceb168ecdf..ff9f68af4448 100644 --- a/sc/source/filter/xml/XMLTableShapeImportHelper.cxx +++ b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx @@ -92,6 +92,7 @@ void XMLTableShapeImportHelper::finishShape( aAnchor.maStart = aStartCell; awt::Point aStartPoint(rShape->getPosition()); aAnchor.maStartOffset = Point(aStartPoint.X, aStartPoint.Y); + aAnchor.mbResizeWithCell = false; sal_Int32 nEndX(-1); sal_Int32 nEndY(-1); @@ -113,6 +114,8 @@ void XMLTableShapeImportHelper::finishShape( { sal_Int32 nOffset(0); ScRangeStringConverter::GetAddressFromString(aAnchor.maEnd, rValue, static_cast<ScXMLImport&>(mrImporter).GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset); + // When the cell end address is set, we let the shape resize with the cell + aAnchor.mbResizeWithCell = true; } else if (IsXMLToken(aLocalName, XML_END_X)) { diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index baf55bb3213e..1289cd238473 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -558,6 +558,7 @@ void ScXMLExport::CollectSharedData(SCTAB& nTableCount, sal_Int32& nShapesCount) aMyShape.nEndX = pAnchor->maEndOffset.X(); aMyShape.nEndY = pAnchor->maEndOffset.Y(); aMyShape.xShape = xShape; + aMyShape.bResizeWithCell = ScDrawLayer::IsResizeWithCell(*pSdrObj); pSharedData->AddNewShape(aMyShape); pSharedData->SetLastColumn(nTable, pAnchor->maStart.Col()); pSharedData->SetLastRow(nTable, pAnchor->maStart.Row()); @@ -3532,7 +3533,10 @@ void ScXMLExport::WriteShapes(const ScMyCell& rMyCell) { if (bNegativePage) aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X; - if ( aItr->xShape->getShapeType() != "com.sun.star.drawing.CaptionShape" ) + + // We only write the end address if we want the shape to resize with the cell + if ( aItr->bResizeWithCell && + aItr->xShape->getShapeType() != "com.sun.star.drawing.CaptionShape" ) { OUString sEndAddress; ScRangeStringConverter::GetStringFromAddress(sEndAddress, aItr->aEndAddress, pDoc, FormulaGrammar::CONV_OOO); diff --git a/sc/source/ui/drawfunc/drawsh2.cxx b/sc/source/ui/drawfunc/drawsh2.cxx index 676fe57a4cd4..9f2f0f2975e3 100644 --- a/sc/source/ui/drawfunc/drawsh2.cxx +++ b/sc/source/ui/drawfunc/drawsh2.cxx @@ -101,6 +101,7 @@ void ScDrawShell::GetState( SfxItemSet& rSet ) // Conditions / Toggles bDisableAnchor = true; rSet.DisableItem( SID_ANCHOR_PAGE ); rSet.DisableItem( SID_ANCHOR_CELL ); + rSet.DisableItem( SID_ANCHOR_CELL_RESIZE ); } } @@ -111,16 +112,25 @@ void ScDrawShell::GetState( SfxItemSet& rSet ) // Conditions / Toggles case SCA_PAGE: rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, true ) ); rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, false ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_CELL_RESIZE, false ) ); break; case SCA_CELL: - rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, false ) ); - rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, true ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, false ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, true ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_CELL_RESIZE, false ) ); + break; + + case SCA_CELL_RESIZE: + rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, false ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, false ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_CELL_RESIZE, true ) ); break; default: - rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, false ) ); - rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, false ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, false ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, false ) ); + rSet.Put( SfxBoolItem( SID_ANCHOR_CELL_RESIZE, false ) ); break; } } diff --git a/sc/source/ui/drawfunc/drawsh5.cxx b/sc/source/ui/drawfunc/drawsh5.cxx index b42df285c509..892895bb27fd 100644 --- a/sc/source/ui/drawfunc/drawsh5.cxx +++ b/sc/source/ui/drawfunc/drawsh5.cxx @@ -351,28 +351,41 @@ void ScDrawShell::ExecDrawFunc( SfxRequest& rReq ) pView->SetPageAnchored(); rBindings.Invalidate( SID_ANCHOR_PAGE ); rBindings.Invalidate( SID_ANCHOR_CELL ); + rBindings.Invalidate( SID_ANCHOR_CELL_RESIZE ); break; case SID_ANCHOR_CELL: - pView->SetCellAnchored(); + pView->SetCellAnchored(false); rBindings.Invalidate( SID_ANCHOR_PAGE ); rBindings.Invalidate( SID_ANCHOR_CELL ); + rBindings.Invalidate( SID_ANCHOR_CELL_RESIZE ); break; + case SID_ANCHOR_CELL_RESIZE: + pView->SetCellAnchored(true); + rBindings.Invalidate( SID_ANCHOR_PAGE ); + rBindings.Invalidate( SID_ANCHOR_CELL ); + rBindings.Invalidate( SID_ANCHOR_CELL_RESIZE ); + break; + + // TODO: This toggle should probably be converted to a dropdown, + // since we now have three states, not two. case SID_ANCHOR_TOGGLE: { switch( pView->GetAnchorType() ) { case SCA_CELL: + case SCA_CELL_RESIZE: pView->SetPageAnchored(); break; default: - pView->SetCellAnchored(); + pView->SetCellAnchored(false); break; } } rBindings.Invalidate( SID_ANCHOR_PAGE ); rBindings.Invalidate( SID_ANCHOR_CELL ); + rBindings.Invalidate( SID_ANCHOR_CELL_RESIZE ); break; case SID_OBJECT_ROTATE: diff --git a/sc/source/ui/drawfunc/fuins1.cxx b/sc/source/ui/drawfunc/fuins1.cxx index fd3cd6d7c700..a688f4fe268d 100644 --- a/sc/source/ui/drawfunc/fuins1.cxx +++ b/sc/source/ui/drawfunc/fuins1.cxx @@ -99,7 +99,7 @@ void ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage ) static void lcl_InsertGraphic( const Graphic& rGraphic, const OUString& rFileName, const OUString& rFilterName, bool bAsLink, bool bApi, ScTabViewShell* pViewSh, const vcl::Window* pWindow, SdrView* pView, - bool bAnchorToCell=true ) + ScAnchorType aAnchorType = SCA_CELL ) { ScDrawView* pDrawView = pViewSh->GetScDrawView(); @@ -171,8 +171,9 @@ static void lcl_InsertGraphic( const Graphic& rGraphic, OUString aName = pLayer->GetNewGraphicName(); // "Graphics" pObj->SetName(aName); - if (bAnchorToCell) - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *(rData.GetDocument()), rData.GetTabNo()); + if (aAnchorType == SCA_CELL || aAnchorType == SCA_CELL_RESIZE) + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *(rData.GetDocument()), rData.GetTabNo(), + aAnchorType == SCA_CELL_RESIZE); // don't select if from (dispatch) API, to allow subsequent cell operations SdrInsertFlags nInsOptions = bApi ? SdrInsertFlags::DONTMARK : SdrInsertFlags::NONE; @@ -272,6 +273,7 @@ FuInsertGraphic::FuInsertGraphic( ScTabViewShell* pViewSh, sal_Int16 nSelect = 0; Sequence<OUString> aListBoxEntries { ScResId(STR_ANCHOR_TO_CELL), + ScResId(STR_ANCHOR_TO_CELL_RESIZE), ScResId(STR_ANCHOR_TO_PAGE) }; try @@ -314,9 +316,18 @@ FuInsertGraphic::FuInsertGraphic( ScTabViewShell* pViewSh, ui::dialogs::ListboxControlActions::GET_SELECTED_ITEM ); OUString sAnchor; aAnchorValue >>= sAnchor; - bool bAnchorToCell = sAnchor == ScResId(STR_ANCHOR_TO_CELL); - lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, false, pViewSh, pWindow, pView, bAnchorToCell ); + ScAnchorType aAnchorType; + if (sAnchor == ScResId(STR_ANCHOR_TO_CELL)) + aAnchorType = SCA_CELL; + else if (sAnchor == ScResId(STR_ANCHOR_TO_CELL_RESIZE)) + aAnchorType = SCA_CELL_RESIZE; + else if (sAnchor == ScResId(STR_ANCHOR_TO_PAGE)) + aAnchorType = SCA_PAGE; + else + aAnchorType = SCA_DONTKNOW; + + lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, false, pViewSh, pWindow, pView, aAnchorType ); // append items for recording rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) ); diff --git a/sc/source/ui/inc/drawview.hxx b/sc/source/ui/inc/drawview.hxx index 1479f0c7e042..7a1066db82a3 100644 --- a/sc/source/ui/inc/drawview.hxx +++ b/sc/source/ui/inc/drawview.hxx @@ -100,7 +100,7 @@ public: void CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const; void SetPageAnchored(); - void SetCellAnchored(); + void SetCellAnchored(bool bResizeWithCell); ScAnchorType GetAnchorType() const; void UpdateIMap( SdrObject* pObj ); diff --git a/sc/source/ui/view/drawvie3.cxx b/sc/source/ui/view/drawvie3.cxx index 37ea3244b0e2..b49acf847132 100644 --- a/sc/source/ui/view/drawvie3.cxx +++ b/sc/source/ui/view/drawvie3.cxx @@ -80,7 +80,7 @@ void ScDrawView::SetPageAnchored() } } -void ScDrawView::SetCellAnchored() +void ScDrawView::SetCellAnchored(bool bResizeWithCell) { if (!pDoc) return; @@ -95,7 +95,7 @@ void ScDrawView::SetCellAnchored() { SdrObject* pObj = pMark->GetMark(i)->GetMarkedSdrObj(); AddUndo (new ScUndoAnchorData( pObj, pDoc, nTab )); - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *pDoc, nTab); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *pDoc, nTab, bResizeWithCell); } EndUndo(); @@ -111,6 +111,7 @@ ScAnchorType ScDrawView::GetAnchorType() const { bool bPage = false; bool bCell = false; + bool bCellResize = false; if( AreObjectsMarked() ) { const SdrMarkList* pMark = &GetMarkedObjectList(); @@ -118,16 +119,21 @@ ScAnchorType ScDrawView::GetAnchorType() const for( size_t i=0; i<nCount; ++i ) { const SdrObject* pObj = pMark->GetMark(i)->GetMarkedSdrObj(); - if( ScDrawLayer::GetAnchorType( *pObj ) == SCA_CELL ) + const ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType( *pObj ); + if( aAnchorType == SCA_CELL ) bCell =true; + else if (aAnchorType == SCA_CELL_RESIZE) + bCellResize = true; else bPage = true; } } - if( bPage && !bCell ) + if( bPage && !bCell && !bCellResize ) return SCA_PAGE; - if( !bPage && bCell ) + if( !bPage && bCell && !bCellResize ) return SCA_CELL; + if( !bPage && !bCell && bCellResize ) + return SCA_CELL_RESIZE; return SCA_DONTKNOW; } @@ -162,7 +168,7 @@ void adjustAnchoredPosition(const SdrHint& rHint, const ScDocument& rDoc, SCTAB // anchored on all selected sheets. return; - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, pAnchor->maStart.Tab()); + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, pAnchor->maStart.Tab(), pAnchor->mbResizeWithCell); } } diff --git a/sc/source/ui/view/viewfun7.cxx b/sc/source/ui/view/viewfun7.cxx index 57b56692f1fa..e1f521ce992f 100644 --- a/sc/source/ui/view/viewfun7.cxx +++ b/sc/source/ui/view/viewfun7.cxx @@ -171,7 +171,8 @@ void ScViewFunc::PasteDraw( const Point& rLogicPos, SdrModel* pModel, pScDrawView->AddUndo(new SdrUndoInsertObj( *pNewObj )); if (ScDrawLayer::IsCellAnchored(*pNewObj)) - ScDrawLayer::SetCellAnchoredFromPosition(*pNewObj, *GetViewData().GetDocument(), nTab); + ScDrawLayer::SetCellAnchoredFromPosition(*pNewObj, *GetViewData().GetDocument(), nTab, + ScDrawLayer::IsResizeWithCell(*pNewObj)); } } @@ -238,7 +239,8 @@ void ScViewFunc::PasteDraw( const Point& rLogicPos, SdrModel* pModel, pObject->NbcSetLayer(SC_LAYER_CONTROLS); if (ScDrawLayer::IsCellAnchored(*pObject)) - ScDrawLayer::SetCellAnchoredFromPosition(*pObject, *GetViewData().GetDocument(), nTab); + ScDrawLayer::SetCellAnchoredFromPosition(*pObject, *GetViewData().GetDocument(), nTab, + ScDrawLayer::IsResizeWithCell(*pObject)); pObject = aIter.Next(); } diff --git a/sc/uiconfig/scalc/popupmenu/anchor.xml b/sc/uiconfig/scalc/popupmenu/anchor.xml index c269bef3ad16..6268cd0b9ae8 100644 --- a/sc/uiconfig/scalc/popupmenu/anchor.xml +++ b/sc/uiconfig/scalc/popupmenu/anchor.xml @@ -8,6 +8,7 @@ * --> <menu:menupopup xmlns:menu="http://openoffice.org/2001/menu"> - <menu:menuitem menu:id=".uno:SetAnchorToPage" menu:style="radio"/> <menu:menuitem menu:id=".uno:SetAnchorToCell" menu:style="radio"/> + <menu:menuitem menu:id=".uno:SetAnchorToCellResize" menu:style="radio"/> + <menu:menuitem menu:id=".uno:SetAnchorToPage" menu:style="radio"/> </menu:menupopup> |