LibreOffice Module sc (master) 1
XMLTableShapeImportHelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21#include "xmlimprt.hxx"
22#include <drwlayer.hxx>
23#include "xmlannoi.hxx"
24#include <rangeutl.hxx>
25#include <userdat.hxx>
26#include <docuno.hxx>
27#include <sheetdata.hxx>
30#include <xmloff/xmluconv.hxx>
31#include <xmloff/xmltoken.hxx>
32#include <com/sun/star/drawing/XShape.hpp>
33#include <com/sun/star/drawing/XShapes.hpp>
34
35constexpr OUStringLiteral SC_LAYERID = u"LayerID";
36
37using namespace ::com::sun::star;
38using namespace xmloff::token;
39
41 XMLShapeImportHelper(rImp, rImp.GetModel(), nullptr ),
42 pAnnotationContext(nullptr),
43 bOnTable(false)
44{
45}
46
48{
49}
50
51void XMLTableShapeImportHelper::SetLayer(const uno::Reference<drawing::XShape>& rShape, SdrLayerID nLayerID, std::u16string_view sType)
52{
53 if ( sType == u"com.sun.star.drawing.ControlShape" )
54 nLayerID = SC_LAYER_CONTROLS;
55 if (nLayerID != SDRLAYER_NOTFOUND)
56 {
57 uno::Reference< beans::XPropertySet > xShapeProp( rShape, uno::UNO_QUERY );
58 if( xShapeProp.is() )
59 xShapeProp->setPropertyValue( SC_LAYERID, uno::Any(nLayerID.get()) );
60 }
61}
62
63// Attempt to find the topmost parent of the group, this is the one we apply
64// offsets to
65static uno::Reference< drawing::XShape > lcl_getTopLevelParent( const uno::Reference< drawing::XShape >& rShape )
66{
67 uno::Reference< container::XChild > xChild( rShape, uno::UNO_QUERY );
68 uno::Reference< drawing::XShape > xParent( xChild->getParent(), uno::UNO_QUERY );
69 if ( xParent.is() )
70 return lcl_getTopLevelParent( xParent );
71 return rShape;
72}
73
75 uno::Reference< drawing::XShape >& rShape,
76 const uno::Reference< xml::sax::XFastAttributeList >& xAttrList,
77 uno::Reference< drawing::XShapes >& rShapes )
78{
79 bool bNote = false;
80 XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
81 static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
82 ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
83 if (rShapes == rTables.GetCurrentXShapes())
84 {
86 {
87 ScDrawObjData aAnchor;
88 aAnchor.maStart = aStartCell;
89 awt::Point aStartPoint(rShape->getPosition());
90 aAnchor.maStartOffset = Point(aStartPoint.X, aStartPoint.Y);
91 aAnchor.mbResizeWithCell = false;
92
93 sal_Int32 nEndX(-1);
94 sal_Int32 nEndY(-1);
95 std::optional<OUString> xRangeList;
97 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
98 {
99 switch(aIter.getToken())
100 {
102 {
103 sal_Int32 nOffset(0);
104 ScDocument* pDoc = static_cast<ScXMLImport&>(mrImporter).GetDocument();
105 assert(pDoc);
107 // When the cell end address is set, we let the shape resize with the cell
108 aAnchor.mbResizeWithCell = true;
109 break;
110 }
112 {
113 static_cast<ScXMLImport&>(mrImporter).
114 GetMM100UnitConverter().convertMeasureToCore(
115 nEndX, aIter.toView());
116 aAnchor.maEndOffset.setX( nEndX );
117 break;
118 }
120 {
121 static_cast<ScXMLImport&>(mrImporter).
122 GetMM100UnitConverter().convertMeasureToCore(
123 nEndY, aIter.toView());
124 aAnchor.maEndOffset.setY( nEndY );
125 break;
126 }
128 if (IsXMLToken(aIter, XML_TRUE))
129 nLayerID = SC_LAYER_BACK;
130 break;
132 xRangeList = aIter.toString();
133 break;
134 default: ;
135 }
136 }
137 SetLayer(rShape, nLayerID, rShape->getShapeType());
138
139 if (SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape(rShape))
140 {
141 if (!bOnTable)
142 ScDrawLayer::SetCellAnchored(*pSdrObj, aAnchor);
143 else
145 }
146
147 if (xRangeList)
148 {
149 // #i78086# If there are notification ranges, the ChartListener must be created
150 // also when anchored to the sheet
151 // -> call AddOLE with invalid cell position (checked in ScMyShapeResizer::ResizeShapes)
152
153 if (ScMyTables::IsOLE(rShape))
154 rTables.AddOLE(rShape, *xRangeList);
155 }
156 }
157 else // shape is annotation
158 {
159 // get the style names for stream copying
160 OUString aStyleName;
161 OUString aTextStyle;
162 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
163 {
164 const OUString sValue = aIter.toString();
165 switch (aIter.getToken())
166 {
168 aStyleName = sValue;
169 break;
171 aTextStyle = sValue;
172 break;
173 default:;
174 }
175 }
176
177 pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
178 bNote = true;
179 }
180 }
181 else //this are grouped shapes which should also get the layerid
182 {
183 uno::Reference< drawing::XShapes > xGroup( rShape, uno::UNO_QUERY );
184 // ignore the group ( within group ) object if it exists
185 if ( !bOnTable && !xGroup.is() )
186 {
187 // For cell anchored grouped shape we need to set the start
188 // position from the most top and left positioned shape(s) within
189 // the group
190 Point aStartPoint( rShape->getPosition().X,rShape->getPosition().Y );
191 uno::Reference< drawing::XShape > xChild( rShapes, uno::UNO_QUERY );
192 if (xChild)
193 {
195 {
196 if ( ScDrawObjData* pAnchor = ScDrawLayer::GetObjData( pSdrObj ) )
197 {
198 if ( pAnchor->maStartOffset.getX() == 0 && pAnchor->maStartOffset.getY() == 0 )
199 pAnchor->maStartOffset = aStartPoint;
200 if ( aStartPoint.getX() < pAnchor->maStartOffset.getX() )
201 pAnchor->maStartOffset.setX( aStartPoint.getX() );
202 if ( aStartPoint.getY() < pAnchor->maStartOffset.getY() )
203 pAnchor->maStartOffset.setY( aStartPoint.getY() );
204 }
205 }
206 }
207 }
208 SdrLayerID nLayerID = SDRLAYER_NOTFOUND;
209 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
210 {
211 if (aIter.getToken() == XML_ELEMENT(TABLE, XML_TABLE_BACKGROUND))
212 {
213 if (IsXMLToken(aIter, XML_TRUE))
214 nLayerID = SC_LAYER_BACK;
215 break;
216 }
217 }
218 SetLayer(rShape, nLayerID, rShape->getShapeType());
219 }
220
221 if (!bNote)
222 {
223 // any shape other than a note prevents copying the sheet
224 ScSheetSaveData* pSheetData = comphelper::getFromUnoTunnel<ScModelObj>(mrImporter.GetModel())->GetSheetSaveData();
225 pSheetData->BlockSheet( rTables.GetCurrentSheet() );
226 }
227
228 static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
229}
230
231/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
constexpr OUStringLiteral SC_LAYERID
static uno::Reference< drawing::XShape > lcl_getTopLevelParent(const uno::Reference< drawing::XShape > &rShape)
static ScDrawObjData * GetObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2603
static void SetPageAnchored(SdrObject &)
Definition: drwlayer.cxx:2447
static void SetCellAnchored(SdrObject &, const ScDrawObjData &rAnchor)
Definition: drwlayer.cxx:2294
ScAddress maStart
Definition: userdat.hxx:36
Point maStartOffset
Definition: userdat.hxx:38
Point maEndOffset
Definition: userdat.hxx:39
bool mbResizeWithCell
Definition: userdat.hxx:41
ScAddress maEnd
Definition: userdat.hxx:37
SCTAB GetCurrentSheet() const
Definition: xmlsubti.hxx:84
static bool IsOLE(const css::uno::Reference< css::drawing::XShape > &rShape)
Definition: xmlsubti.hxx:77
css::uno::Reference< css::drawing::XShapes > const & GetCurrentXShapes()
Definition: xmlsubti.cxx:230
void AddOLE(const css::uno::Reference< css::drawing::XShape > &rShape, const OUString &rRangeList)
Definition: xmlsubti.cxx:252
static bool GetAddressFromString(ScAddress &rAddress, std::u16string_view rAddressStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Int32 &nOffset, sal_Unicode cSeparator=' ', sal_Unicode cQuote='\'')
String to Range core.
Definition: rangeutl.cxx:461
void BlockSheet(SCTAB nTab)
Definition: sheetdata.cxx:92
void SetShape(const css::uno::Reference< css::drawing::XShape > &rxShape, const css::uno::Reference< css::drawing::XShapes > &rxShapes, const OUString &rStyleName, const OUString &rTextStyle)
Definition: xmlannoi.cxx:157
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
const css::uno::Reference< css::frame::XModel > & GetModel() const
SvXMLImport & mrImporter
virtual void finishShape(css::uno::Reference< css::drawing::XShape > &rShape, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > &rShapes)
virtual ~XMLTableShapeImportHelper() override
static void SetLayer(const css::uno::Reference< css::drawing::XShape > &rShape, SdrLayerID nLayerID, std::u16string_view sType)
XMLTableShapeImportHelper(ScXMLImport &rImp)
ScXMLAnnotationContext * pAnnotationContext
virtual void finishShape(css::uno::Reference< css::drawing::XShape > &rShape, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > &rShapes) override
float u
DRAW
constexpr SdrLayerID SC_LAYER_BACK(1)
constexpr SdrLayerID SC_LAYER_CONTROLS(3)
TABLE
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
XML_TEXT_STYLE_NAME
XML_TRUE
XML_TABLE_BACKGROUND
XML_STYLE_NAME
XML_END_CELL_ADDRESS
XML_END_X
XML_END_Y
XML_NOTIFY_ON_UPDATE_OF_RANGES
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
UNDERLYING_TYPE get() const
constexpr SdrLayerID SDRLAYER_NOTFOUND(-1)
#define XML_ELEMENT(prefix, name)