Line data Source code
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 :
20 : #include "XMLTableShapeImportHelper.hxx"
21 : #include "xmlimprt.hxx"
22 : #include "XMLConverter.hxx"
23 : #include "drwlayer.hxx"
24 : #include "xmlannoi.hxx"
25 : #include "rangeutl.hxx"
26 : #include "userdat.hxx"
27 : #include "docuno.hxx"
28 : #include "sheetdata.hxx"
29 : #include <xmloff/nmspmap.hxx>
30 : #include <xmloff/xmlnmspe.hxx>
31 : #include <xmloff/xmluconv.hxx>
32 : #include <xmloff/xmltoken.hxx>
33 : #include <svx/unoshape.hxx>
34 : #include <svx/svdobj.hxx>
35 : #include <com/sun/star/drawing/XShape.hpp>
36 : #include <com/sun/star/drawing/XShapes.hpp>
37 :
38 : #define SC_LAYERID "LayerID"
39 :
40 : using namespace ::com::sun::star;
41 : using namespace xmloff::token;
42 : using ::rtl::OUString;
43 :
44 : using rtl::OUString;
45 :
46 132 : XMLTableShapeImportHelper::XMLTableShapeImportHelper(
47 : ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper ) :
48 132 : XMLShapeImportHelper(rImp, rImp.GetModel(), pImpMapper ),
49 : pAnnotationContext(NULL),
50 132 : bOnTable(false)
51 : {
52 132 : }
53 :
54 264 : XMLTableShapeImportHelper::~XMLTableShapeImportHelper()
55 : {
56 264 : }
57 :
58 4 : void XMLTableShapeImportHelper::SetLayer(uno::Reference<drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const
59 : {
60 4 : if ( sType == "com.sun.star.drawing.ControlShape" )
61 0 : nLayerID = SC_LAYER_CONTROLS;
62 4 : if (nLayerID != -1)
63 : {
64 0 : uno::Reference< beans::XPropertySet > xShapeProp( rShape, uno::UNO_QUERY );
65 0 : if( xShapeProp.is() )
66 0 : xShapeProp->setPropertyValue(OUString( RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ) ), uno::makeAny(nLayerID) );
67 : }
68 4 : }
69 :
70 : // Attempt to find the topmost parent of the group, this is the one we apply
71 : // offsets to
72 0 : static uno::Reference< drawing::XShape > lcl_getTopLevelParent( const uno::Reference< drawing::XShape >& rShape )
73 : {
74 0 : uno::Reference< container::XChild > xChild( rShape, uno::UNO_QUERY );
75 0 : uno::Reference< drawing::XShape > xParent( xChild->getParent(), uno::UNO_QUERY );
76 0 : if ( xParent.is() )
77 0 : return lcl_getTopLevelParent( xParent );
78 0 : return rShape;
79 : }
80 :
81 6 : void XMLTableShapeImportHelper::finishShape(
82 : uno::Reference< drawing::XShape >& rShape,
83 : const uno::Reference< xml::sax::XAttributeList >& xAttrList,
84 : uno::Reference< drawing::XShapes >& rShapes )
85 : {
86 6 : bool bNote = false;
87 6 : XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
88 6 : static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
89 6 : ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
90 6 : if (rShapes == rTables.GetCurrentXShapes())
91 : {
92 6 : if (!pAnnotationContext)
93 : {
94 4 : ScDrawObjData aAnchor;
95 4 : aAnchor.maStart = ScAddress(aStartCell.Column, aStartCell.Row, aStartCell.Sheet);
96 4 : awt::Point aStartPoint(rShape->getPosition());
97 4 : aAnchor.maStartOffset = Point(aStartPoint.X, aStartPoint.Y);
98 :
99 4 : sal_Int32 nEndX(-1);
100 4 : sal_Int32 nEndY(-1);
101 4 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
102 4 : table::CellAddress aEndCell;
103 4 : rtl::OUString* pRangeList(NULL);
104 4 : sal_Int16 nLayerID(-1);
105 44 : for( sal_Int16 i=0; i < nAttrCount; ++i )
106 : {
107 40 : const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
108 40 : const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
109 :
110 40 : rtl::OUString aLocalName;
111 : sal_uInt16 nPrefix(
112 40 : static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName,
113 40 : &aLocalName ));
114 40 : if(nPrefix == XML_NAMESPACE_TABLE)
115 : {
116 12 : if (IsXMLToken(aLocalName, XML_END_CELL_ADDRESS))
117 : {
118 4 : sal_Int32 nOffset(0);
119 4 : ScRangeStringConverter::GetAddressFromString(aEndCell, rValue, static_cast<ScXMLImport&>(mrImporter).GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset);
120 4 : aAnchor.maEnd = ScAddress(aEndCell.Column, aEndCell.Row, aEndCell.Sheet);
121 : }
122 8 : else if (IsXMLToken(aLocalName, XML_END_X))
123 : {
124 : static_cast<ScXMLImport&>(mrImporter).
125 4 : GetMM100UnitConverter().convertMeasureToCore(
126 4 : nEndX, rValue);
127 4 : aAnchor.maEndOffset.X() = nEndX;
128 : }
129 4 : else if (IsXMLToken(aLocalName, XML_END_Y))
130 : {
131 : static_cast<ScXMLImport&>(mrImporter).
132 4 : GetMM100UnitConverter().convertMeasureToCore(
133 4 : nEndY, rValue);
134 4 : aAnchor.maEndOffset.Y() = nEndY;
135 : }
136 0 : else if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
137 0 : if (IsXMLToken(rValue, XML_TRUE))
138 0 : nLayerID = SC_LAYER_BACK;
139 : }
140 28 : else if(nPrefix == XML_NAMESPACE_DRAW)
141 : {
142 12 : if (IsXMLToken(aLocalName, XML_NOTIFY_ON_UPDATE_OF_RANGES))
143 0 : pRangeList = new rtl::OUString(rValue);
144 : }
145 40 : }
146 4 : SetLayer(rShape, nLayerID, rShape->getShapeType());
147 :
148 4 : if (SvxShape* pShapeImp = SvxShape::getImplementation(rShape))
149 : {
150 4 : if (SdrObject *pSdrObj = pShapeImp->GetSdrObject())
151 : {
152 4 : if (!bOnTable)
153 4 : ScDrawLayer::SetCellAnchored(*pSdrObj, aAnchor);
154 : else
155 0 : ScDrawLayer::SetPageAnchored(*pSdrObj);
156 : }
157 : }
158 :
159 4 : if (pRangeList)
160 : {
161 : // #i78086# If there are notification ranges, the ChartListener must be created
162 : // also when anchored to the sheet
163 : // -> call AddOLE with invalid cell position (checked in ScMyShapeResizer::ResizeShapes)
164 :
165 0 : if (rTables.IsOLE(rShape))
166 0 : rTables.AddOLE(rShape, *pRangeList);
167 : }
168 :
169 4 : delete pRangeList;
170 : }
171 : else // shape is annotation
172 : {
173 : // get the style names for stream copying
174 2 : rtl::OUString aStyleName;
175 2 : rtl::OUString aTextStyle;
176 2 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
177 18 : for( sal_Int16 i=0; i < nAttrCount; ++i )
178 : {
179 16 : const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
180 16 : rtl::OUString aLocalName;
181 16 : sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
182 16 : if(nPrefix == XML_NAMESPACE_DRAW)
183 : {
184 8 : if (IsXMLToken(aLocalName, XML_STYLE_NAME))
185 2 : aStyleName = xAttrList->getValueByIndex( i );
186 6 : else if (IsXMLToken(aLocalName, XML_TEXT_STYLE_NAME))
187 2 : aTextStyle = xAttrList->getValueByIndex( i );
188 : }
189 16 : }
190 :
191 2 : pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
192 2 : bNote = true;
193 : }
194 : }
195 : else //this are grouped shapes which should also get the layerid
196 : {
197 0 : uno::Reference< drawing::XShapes > xGroup( rShape, uno::UNO_QUERY );
198 : // ignore the group ( within group ) object it it exists
199 0 : if ( !bOnTable && !xGroup.is() )
200 : {
201 : // For cell anchored grouped shape we need to set the start
202 : // position from the most top and left positioned shape(s) within
203 : // the group
204 0 : Point aStartPoint( rShape->getPosition().X,rShape->getPosition().Y );
205 0 : uno::Reference< drawing::XShape > xChild( rShapes, uno::UNO_QUERY );
206 0 : if (SvxShape* pGroupShapeImp = SvxShape::getImplementation( lcl_getTopLevelParent( xChild ) ))
207 : {
208 0 : if (SdrObject *pSdrObj = pGroupShapeImp->GetSdrObject())
209 : {
210 0 : if ( ScDrawObjData* pAnchor = ScDrawLayer::GetObjData( pSdrObj ) )
211 : {
212 0 : if ( pAnchor->maStartOffset.getX() == 0 && pAnchor->maStartOffset.getY() == 0 )
213 0 : pAnchor->maStartOffset = aStartPoint;
214 0 : if ( aStartPoint.getX() < pAnchor->maStartOffset.getX() )
215 0 : pAnchor->maStartOffset.setX( aStartPoint.getX() );
216 0 : if ( aStartPoint.getY() < pAnchor->maStartOffset.getY() )
217 0 : pAnchor->maStartOffset.setY( aStartPoint.getY() );
218 : }
219 : }
220 0 : }
221 : }
222 0 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
223 0 : sal_Int16 nLayerID(-1);
224 0 : for( sal_Int16 i=0; i < nAttrCount; ++i )
225 : {
226 0 : const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
227 0 : const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
228 :
229 0 : rtl::OUString aLocalName;
230 0 : sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
231 0 : if(nPrefix == XML_NAMESPACE_TABLE)
232 : {
233 0 : if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
234 0 : if (IsXMLToken(rValue, XML_TRUE))
235 0 : nLayerID = SC_LAYER_BACK;
236 : }
237 0 : }
238 0 : SetLayer(rShape, nLayerID, rShape->getShapeType());
239 : }
240 :
241 6 : if (!bNote)
242 : {
243 : // any shape other than a note prevents copying the sheet
244 4 : ScSheetSaveData* pSheetData = ScModelObj::getImplementation(mrImporter.GetModel())->GetSheetSaveData();
245 4 : pSheetData->BlockSheet( rTables.GetCurrentSheet() );
246 : }
247 :
248 6 : static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
249 6 : }
250 :
251 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|