tdf#114552 Add a third anchor type for calc graphics
This allows to have two cell anchored types: * Only cell anchored (moves with the cell when sorting etc) * Cell anchored, also resizes with the cell Beforehand, all cell anchored images would resize with the cell, which was often not what users expected. The new default (when inserting images) is now that inserted images are only anchored to the cell, but don't resize with the cell. This makes use of the ODF elements table:end-cell-address, table:end-x, table:end-y. When images should resize with the cell, the end address is written (it has always been written earlier, so documents would still import correctly). If not, they are omitted. Also implements xlsx import & export Change-Id: I5f96242f88943ed77a0fd12b7f39b444e1380df7 Reviewed-on: https://gerrit.libreoffice.org/49490 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
This commit is contained in:
@@ -1965,6 +1965,9 @@
|
||||
<prop oor:name="ContextLabel" oor:type="xs:string">
|
||||
<value xml:lang="en-US">To P~age</value>
|
||||
</prop>
|
||||
<prop oor:name="TooltipLabel" oor:type="xs:string">
|
||||
<value xml:lang="en-US">Anchor to p~age</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name=".uno:SetAnchorToCell" oor:op="replace">
|
||||
<prop oor:name="Label" oor:type="xs:string">
|
||||
@@ -1973,6 +1976,20 @@
|
||||
<prop oor:name="ContextLabel" oor:type="xs:string">
|
||||
<value xml:lang="en-US">To ~Cell</value>
|
||||
</prop>
|
||||
<prop oor:name="TooltipLabel" oor:type="xs:string">
|
||||
<value xml:lang="en-US">Anchor to ~cell (move with cell)</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name=".uno:SetAnchorToCellResize" oor:op="replace">
|
||||
<prop oor:name="Label" oor:type="xs:string">
|
||||
<value xml:lang="en-US">Anchor: To Cell (~resize with cell)</value>
|
||||
</prop>
|
||||
<prop oor:name="ContextLabel" oor:type="xs:string">
|
||||
<value xml:lang="en-US">To Cell (~resize with cell)</value>
|
||||
</prop>
|
||||
<prop oor:name="TooltipLabel" oor:type="xs:string">
|
||||
<value xml:lang="en-US">Anchor to cell (move and ~resize with cell)</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name=".uno:SendMailDocAsMS" oor:op="replace">
|
||||
<prop oor:name="Label" oor:type="xs:string">
|
||||
|
||||
+3
-1
@@ -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);
|
||||
|
||||
+3
-2
@@ -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
|
||||
};
|
||||
|
||||
|
||||
+3
-2
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
Point maEndOffset;
|
||||
Type meType;
|
||||
tools::Rectangle maLastRect;
|
||||
bool mbResizeWithCell = false;
|
||||
|
||||
explicit ScDrawObjData();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; ]
|
||||
|
||||
@@ -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
|
||||
()
|
||||
[
|
||||
|
||||
@@ -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*>>
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user