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>
29 #include <xmloff/xmlnamespace.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 
35 constexpr OUStringLiteral SC_LAYERID = u"LayerID";
36 
37 using namespace ::com::sun::star;
38 using namespace xmloff::token;
39 
41  XMLShapeImportHelper(rImp, rImp.GetModel(), nullptr ),
42  pAnnotationContext(nullptr),
43  bOnTable(false)
44 {
45 }
46 
48 {
49 }
50 
51 void 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
65 static 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  {
85  if (!pAnnotationContext)
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;
96  SdrLayerID nLayerID = SDRLAYER_NOTFOUND;
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  }
111  case XML_ELEMENT(TABLE, XML_END_X):
112  {
113  static_cast<ScXMLImport&>(mrImporter).
114  GetMM100UnitConverter().convertMeasureToCore(
115  nEndX, aIter.toView());
116  aAnchor.maEndOffset.setX( nEndX );
117  break;
118  }
119  case XML_ELEMENT(TABLE, XML_END_Y):
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: */
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:461
XML_END_CELL_ADDRESS
SCTAB GetCurrentSheet() const
Definition: xmlsubti.hxx:84
static void SetPageAnchored(SdrObject &)
Definition: drwlayer.cxx:2440
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:2602
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
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)
UNDERLYING_TYPE get() const
static void SetCellAnchored(SdrObject &, const ScDrawObjData &rAnchor)
Definition: drwlayer.cxx:2287
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
SvXMLImport & mrImporter
float u
Point maStartOffset
Definition: userdat.hxx:38
virtual ~XMLTableShapeImportHelper() override
constexpr SdrLayerID SDRLAYER_NOTFOUND(-1)
XML_TEXT_STYLE_NAME
XML_TRUE
TABLE
XML_NOTIFY_ON_UPDATE_OF_RANGES
css::uno::Reference< css::drawing::XShapes > const & GetCurrentXShapes()
Definition: xmlsubti.cxx:230
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:252
constexpr SdrLayerID SC_LAYER_CONTROLS(3)
static void SetLayer(const css::uno::Reference< css::drawing::XShape > &rShape, SdrLayerID nLayerID, std::u16string_view sType)
bool m_bDetectedRangeSegmentation false