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 44 : XMLTableShapeImportHelper::XMLTableShapeImportHelper(
47 : ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper ) :
48 44 : XMLShapeImportHelper(rImp, rImp.GetModel(), pImpMapper ),
49 : pAnnotationContext(NULL),
50 44 : bOnTable(false)
51 : {
52 44 : }
53 :
54 88 : XMLTableShapeImportHelper::~XMLTableShapeImportHelper()
55 : {
56 88 : }
57 :
58 2 : void XMLTableShapeImportHelper::SetLayer(uno::Reference<drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const
59 : {
60 2 : if ( sType == "com.sun.star.drawing.ControlShape" )
61 0 : nLayerID = SC_LAYER_CONTROLS;
62 2 : 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 2 : }
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 3 : 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 3 : bool bNote = false;
87 3 : XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
88 3 : static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
89 3 : ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
90 3 : if (rShapes == rTables.GetCurrentXShapes())
91 : {
92 3 : if (!pAnnotationContext)
93 : {
94 2 : ScDrawObjData aAnchor;
95 2 : aAnchor.maStart = ScAddress(aStartCell.Column, aStartCell.Row, aStartCell.Sheet);
96 2 : awt::Point aStartPoint(rShape->getPosition());
97 2 : aAnchor.maStartOffset = Point(aStartPoint.X, aStartPoint.Y);
98 :
99 2 : sal_Int32 nEndX(-1);
100 2 : sal_Int32 nEndY(-1);
101 2 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
102 2 : table::CellAddress aEndCell;
103 2 : rtl::OUString* pRangeList(NULL);
104 2 : sal_Int16 nLayerID(-1);
105 22 : for( sal_Int16 i=0; i < nAttrCount; ++i )
106 : {
107 20 : const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
108 20 : const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
109 :
110 20 : rtl::OUString aLocalName;
111 : sal_uInt16 nPrefix(
112 20 : static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName,
113 20 : &aLocalName ));
114 20 : if(nPrefix == XML_NAMESPACE_TABLE)
115 : {
116 6 : if (IsXMLToken(aLocalName, XML_END_CELL_ADDRESS))
117 : {
118 2 : sal_Int32 nOffset(0);
119 2 : ScRangeStringConverter::GetAddressFromString(aEndCell, rValue, static_cast<ScXMLImport&>(mrImporter).GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset);
120 2 : aAnchor.maEnd = ScAddress(aEndCell.Column, aEndCell.Row, aEndCell.Sheet);
121 : }
122 4 : else if (IsXMLToken(aLocalName, XML_END_X))
123 : {
124 : static_cast<ScXMLImport&>(mrImporter).
125 2 : GetMM100UnitConverter().convertMeasureToCore(
126 2 : nEndX, rValue);
127 2 : aAnchor.maEndOffset.X() = nEndX;
128 : }
129 2 : else if (IsXMLToken(aLocalName, XML_END_Y))
130 : {
131 : static_cast<ScXMLImport&>(mrImporter).
132 2 : GetMM100UnitConverter().convertMeasureToCore(
133 2 : nEndY, rValue);
134 2 : 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 14 : else if(nPrefix == XML_NAMESPACE_DRAW)
141 : {
142 6 : if (IsXMLToken(aLocalName, XML_NOTIFY_ON_UPDATE_OF_RANGES))
143 0 : pRangeList = new rtl::OUString(rValue);
144 : }
145 20 : }
146 2 : SetLayer(rShape, nLayerID, rShape->getShapeType());
147 :
148 2 : if (SvxShape* pShapeImp = SvxShape::getImplementation(rShape))
149 : {
150 2 : if (SdrObject *pSdrObj = pShapeImp->GetSdrObject())
151 : {
152 2 : if (!bOnTable)
153 2 : ScDrawLayer::SetCellAnchored(*pSdrObj, aAnchor);
154 : else
155 0 : ScDrawLayer::SetPageAnchored(*pSdrObj);
156 : }
157 : }
158 :
159 2 : 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 2 : delete pRangeList;
170 : }
171 : else // shape is annotation
172 : {
173 : // get the style names for stream copying
174 1 : rtl::OUString aStyleName;
175 1 : rtl::OUString aTextStyle;
176 1 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
177 9 : for( sal_Int16 i=0; i < nAttrCount; ++i )
178 : {
179 8 : const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
180 8 : rtl::OUString aLocalName;
181 8 : sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
182 8 : if(nPrefix == XML_NAMESPACE_DRAW)
183 : {
184 4 : if (IsXMLToken(aLocalName, XML_STYLE_NAME))
185 1 : aStyleName = xAttrList->getValueByIndex( i );
186 3 : else if (IsXMLToken(aLocalName, XML_TEXT_STYLE_NAME))
187 1 : aTextStyle = xAttrList->getValueByIndex( i );
188 : }
189 8 : }
190 :
191 1 : pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
192 1 : 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 3 : if (!bNote)
242 : {
243 : // any shape other than a note prevents copying the sheet
244 2 : ScSheetSaveData* pSheetData = ScModelObj::getImplementation(mrImporter.GetModel())->GetSheetSaveData();
245 2 : pSheetData->BlockSheet( rTables.GetCurrentSheet() );
246 : }
247 :
248 3 : static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
249 3 : }
250 :
251 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|