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>
28 #include <xmloff/namespacemap.hxx>
29 #include <xmloff/xmlnamespace.hxx>
30 #include <xmloff/xmluconv.hxx>
31 #include <xmloff/xmltoken.hxx>
32 #include <svx/unoshape.hxx>
33 #include <com/sun/star/drawing/XShape.hpp>
34 #include <com/sun/star/drawing/XShapes.hpp>
35 
36 constexpr OUStringLiteral SC_LAYERID = u"LayerID";
37 
38 using namespace ::com::sun::star;
39 using namespace xmloff::token;
40 
42  XMLShapeImportHelper(rImp, rImp.GetModel(), nullptr ),
43  pAnnotationContext(nullptr),
44  bOnTable(false)
45 {
46 }
47 
49 {
50 }
51 
52 void XMLTableShapeImportHelper::SetLayer(const uno::Reference<drawing::XShape>& rShape, SdrLayerID nLayerID, std::u16string_view sType)
53 {
54  if ( sType == u"com.sun.star.drawing.ControlShape" )
55  nLayerID = SC_LAYER_CONTROLS;
56  if (nLayerID != SDRLAYER_NOTFOUND)
57  {
58  uno::Reference< beans::XPropertySet > xShapeProp( rShape, uno::UNO_QUERY );
59  if( xShapeProp.is() )
60  xShapeProp->setPropertyValue( SC_LAYERID, uno::makeAny<sal_uInt16>(sal_uInt8(nLayerID)) );
61  }
62 }
63 
64 // Attempt to find the topmost parent of the group, this is the one we apply
65 // offsets to
66 static uno::Reference< drawing::XShape > lcl_getTopLevelParent( const uno::Reference< drawing::XShape >& rShape )
67 {
68  uno::Reference< container::XChild > xChild( rShape, uno::UNO_QUERY );
69  uno::Reference< drawing::XShape > xParent( xChild->getParent(), uno::UNO_QUERY );
70  if ( xParent.is() )
71  return lcl_getTopLevelParent( xParent );
72  return rShape;
73 }
74 
76  uno::Reference< drawing::XShape >& rShape,
77  const uno::Reference< xml::sax::XFastAttributeList >& xAttrList,
78  uno::Reference< drawing::XShapes >& rShapes )
79 {
80  bool bNote = false;
81  XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
82  static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
83  ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
84  if (rShapes == rTables.GetCurrentXShapes())
85  {
86  if (!pAnnotationContext)
87  {
88  ScDrawObjData aAnchor;
89  aAnchor.maStart = aStartCell;
90  awt::Point aStartPoint(rShape->getPosition());
91  aAnchor.maStartOffset = Point(aStartPoint.X, aStartPoint.Y);
92  aAnchor.mbResizeWithCell = false;
93 
94  sal_Int32 nEndX(-1);
95  sal_Int32 nEndY(-1);
96  std::optional<OUString> xRangeList;
97  SdrLayerID nLayerID = SDRLAYER_NOTFOUND;
98  for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
99  {
100  switch(aIter.getToken())
101  {
103  {
104  sal_Int32 nOffset(0);
105  ScDocument* pDoc = static_cast<ScXMLImport&>(mrImporter).GetDocument();
106  assert(pDoc);
108  // When the cell end address is set, we let the shape resize with the cell
109  aAnchor.mbResizeWithCell = true;
110  break;
111  }
112  case XML_ELEMENT(TABLE, XML_END_X):
113  {
114  static_cast<ScXMLImport&>(mrImporter).
115  GetMM100UnitConverter().convertMeasureToCore(
116  nEndX, aIter.toView());
117  aAnchor.maEndOffset.setX( nEndX );
118  break;
119  }
120  case XML_ELEMENT(TABLE, XML_END_Y):
121  {
122  static_cast<ScXMLImport&>(mrImporter).
123  GetMM100UnitConverter().convertMeasureToCore(
124  nEndY, aIter.toView());
125  aAnchor.maEndOffset.setY( nEndY );
126  break;
127  }
129  if (IsXMLToken(aIter, XML_TRUE))
130  nLayerID = SC_LAYER_BACK;
131  break;
133  xRangeList = aIter.toString();
134  break;
135  default: ;
136  }
137  }
138  SetLayer(rShape, nLayerID, rShape->getShapeType());
139 
140  if (SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape(rShape))
141  {
142  if (!bOnTable)
143  ScDrawLayer::SetCellAnchored(*pSdrObj, aAnchor);
144  else
146  }
147 
148  if (xRangeList)
149  {
150  // #i78086# If there are notification ranges, the ChartListener must be created
151  // also when anchored to the sheet
152  // -> call AddOLE with invalid cell position (checked in ScMyShapeResizer::ResizeShapes)
153 
154  if (ScMyTables::IsOLE(rShape))
155  rTables.AddOLE(rShape, *xRangeList);
156  }
157  }
158  else // shape is annotation
159  {
160  // get the style names for stream copying
161  OUString aStyleName;
162  OUString aTextStyle;
163  for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
164  {
165  const OUString sValue = aIter.toString();
166  switch (aIter.getToken())
167  {
169  aStyleName = sValue;
170  break;
172  aTextStyle = sValue;
173  break;
174  default:;
175  }
176  }
177 
178  pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
179  bNote = true;
180  }
181  }
182  else //this are grouped shapes which should also get the layerid
183  {
184  uno::Reference< drawing::XShapes > xGroup( rShape, uno::UNO_QUERY );
185  // ignore the group ( within group ) object if it exists
186  if ( !bOnTable && !xGroup.is() )
187  {
188  // For cell anchored grouped shape we need to set the start
189  // position from the most top and left positioned shape(s) within
190  // the group
191  Point aStartPoint( rShape->getPosition().X,rShape->getPosition().Y );
192  uno::Reference< drawing::XShape > xChild( rShapes, uno::UNO_QUERY );
193  if (xChild)
194  {
196  {
197  if ( ScDrawObjData* pAnchor = ScDrawLayer::GetObjData( pSdrObj ) )
198  {
199  if ( pAnchor->maStartOffset.getX() == 0 && pAnchor->maStartOffset.getY() == 0 )
200  pAnchor->maStartOffset = aStartPoint;
201  if ( aStartPoint.getX() < pAnchor->maStartOffset.getX() )
202  pAnchor->maStartOffset.setX( aStartPoint.getX() );
203  if ( aStartPoint.getY() < pAnchor->maStartOffset.getY() )
204  pAnchor->maStartOffset.setY( aStartPoint.getY() );
205  }
206  }
207  }
208  }
209  SdrLayerID nLayerID = SDRLAYER_NOTFOUND;
210  for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
211  {
212  if (aIter.getToken() == XML_ELEMENT(TABLE, XML_TABLE_BACKGROUND))
213  {
214  if (IsXMLToken(aIter, XML_TRUE))
215  nLayerID = SC_LAYER_BACK;
216  break;
217  }
218  }
219  SetLayer(rShape, nLayerID, rShape->getShapeType());
220  }
221 
222  if (!bNote)
223  {
224  // any shape other than a note prevents copying the sheet
225  ScSheetSaveData* pSheetData = comphelper::getFromUnoTunnel<ScModelObj>(mrImporter.GetModel())->GetSheetSaveData();
226  pSheetData->BlockSheet( rTables.GetCurrentSheet() );
227  }
228 
229  static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
230 }
231 
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool GetAddressFromString(ScAddress &rAddress, const OUString &rAddressStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Int32 &nOffset, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
String to Range core.
Definition: rangeutl.cxx:453
XML_END_CELL_ADDRESS
SCTAB GetCurrentSheet() const
Definition: xmlsubti.hxx:84
static void SetPageAnchored(SdrObject &)
Definition: drwlayer.cxx:2433
XML_END_Y
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
static ScDrawObjData * GetObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2595
ScXMLAnnotationContext * pAnnotationContext
XML_END_X
constexpr SdrLayerID SC_LAYER_BACK(1)
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
ScAddress maStart
Definition: userdat.hxx:36
void BlockSheet(SCTAB nTab)
Definition: sheetdata.cxx:92
DRAW
static bool IsOLE(const css::uno::Reference< css::drawing::XShape > &rShape)
Definition: xmlsubti.hxx:77
constexpr SdrLayerID SDRLAYER_NOTFOUND(0xff)
Point maEndOffset
Definition: userdat.hxx:39
constexpr OUStringLiteral SC_LAYERID
static uno::Reference< drawing::XShape > lcl_getTopLevelParent(const uno::Reference< drawing::XShape > &rShape)
bool mbResizeWithCell
Definition: userdat.hxx:41
XMLTableShapeImportHelper(ScXMLImport &rImp)
static void SetCellAnchored(SdrObject &, const ScDrawObjData &rAnchor)
Definition: drwlayer.cxx:2280
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:159
SvXMLImport & mrImporter
float u
Point maStartOffset
Definition: userdat.hxx:38
virtual ~XMLTableShapeImportHelper() override
XML_TEXT_STYLE_NAME
XML_TRUE
TABLE
XML_NOTIFY_ON_UPDATE_OF_RANGES
unsigned char sal_uInt8
css::uno::Reference< css::drawing::XShapes > const & GetCurrentXShapes()
Definition: xmlsubti.cxx:231
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
#define XML_ELEMENT(prefix, name)
const css::uno::Reference< css::frame::XModel > & GetModel() const
XML_STYLE_NAME
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
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)
ScAddress maEnd
Definition: userdat.hxx:37
XML_TABLE_BACKGROUND
void AddOLE(const css::uno::Reference< css::drawing::XShape > &rShape, const OUString &rRangeList)
Definition: xmlsubti.cxx:253
constexpr SdrLayerID SC_LAYER_CONTROLS(3)
static void SetLayer(const css::uno::Reference< css::drawing::XShape > &rShape, SdrLayerID nLayerID, std::u16string_view sType)