1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 #include "XMLTableShapeImportHelper.hxx"
27 #include "xmlimprt.hxx"
28 #include "XMLConverter.hxx"
29 #include "drwlayer.hxx"
30 #include "xmlannoi.hxx"
31 #include "rangeutl.hxx"
32 #include "docuno.hxx"
33 #include "sheetdata.hxx"
34 #include <xmloff/nmspmap.hxx>
35 #include <xmloff/xmlnmspe.hxx>
36 #include <xmloff/xmluconv.hxx>
37 #include <xmloff/xmltoken.hxx>
38 #include <svx/unoshape.hxx>
39 #include <svx/svdobj.hxx>
40 #include <com/sun/star/drawing/XShape.hpp>
41 #include <com/sun/star/drawing/XShapes.hpp>
42 
43 #define SC_LAYERID "LayerID"
44 
45 using namespace ::com::sun::star;
46 using namespace xmloff::token;
47 using ::rtl::OUString;
48 
XMLTableShapeImportHelper(ScXMLImport & rImp,SvXMLImportPropertyMapper * pImpMapper)49 XMLTableShapeImportHelper::XMLTableShapeImportHelper(
50 		ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper ) :
51 	XMLShapeImportHelper(rImp, rImp.GetModel(), pImpMapper ),
52     pAnnotationContext(NULL),
53 	bOnTable(sal_False)
54 {
55 }
56 
~XMLTableShapeImportHelper()57 XMLTableShapeImportHelper::~XMLTableShapeImportHelper()
58 {
59 }
60 
SetLayer(uno::Reference<drawing::XShape> & rShape,sal_Int16 nLayerID,const rtl::OUString & sType) const61 void XMLTableShapeImportHelper::SetLayer(uno::Reference<drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const
62 {
63     if (sType.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ControlShape"))))
64 		nLayerID = SC_LAYER_CONTROLS;
65     if (nLayerID != -1)
66     {
67 		uno::Reference< beans::XPropertySet > xShapeProp( rShape, uno::UNO_QUERY );
68 		if( xShapeProp.is() )
69 			xShapeProp->setPropertyValue(OUString( RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ) ), uno::makeAny(nLayerID) );
70     }
71 }
72 
finishShape(uno::Reference<drawing::XShape> & rShape,const uno::Reference<xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> & rShapes)73 void XMLTableShapeImportHelper::finishShape(
74 	uno::Reference< drawing::XShape >& rShape,
75 	const uno::Reference< xml::sax::XAttributeList >& xAttrList,
76 	uno::Reference< drawing::XShapes >& rShapes )
77 {
78     bool bNote = false;
79 	XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
80 	static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
81     ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
82 	if (rShapes == rTables.GetCurrentXShapes())
83 	{
84         if (!pAnnotationContext)
85         {
86 		    sal_Int32 nEndX(-1);
87 		    sal_Int32 nEndY(-1);
88 		    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
89 		    table::CellAddress aEndCell;
90 		    rtl::OUString* pRangeList(NULL);
91             sal_Int16 nLayerID(-1);
92 		    for( sal_Int16 i=0; i < nAttrCount; ++i )
93 		    {
94 			    const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
95 			    const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
96 
97 			    rtl::OUString aLocalName;
98 			    sal_uInt16 nPrefix(
99 				    static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName,
100 																    &aLocalName ));
101 			    if(nPrefix == XML_NAMESPACE_TABLE)
102 			    {
103 				    if (IsXMLToken(aLocalName, XML_END_CELL_ADDRESS))
104 				    {
105 					    sal_Int32 nOffset(0);
106 					    ScRangeStringConverter::GetAddressFromString(aEndCell, rValue, static_cast<ScXMLImport&>(mrImporter).GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset);
107 				    }
108 				    else if (IsXMLToken(aLocalName, XML_END_X))
109 					    static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndX, rValue);
110 				    else if (IsXMLToken(aLocalName, XML_END_Y))
111 					    static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndY, rValue);
112 				    else if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
113 					    if (IsXMLToken(rValue, XML_TRUE))
114 						    nLayerID = SC_LAYER_BACK;
115 			    }
116 			    else if(nPrefix == XML_NAMESPACE_DRAW)
117 			    {
118 				    if (IsXMLToken(aLocalName, XML_NOTIFY_ON_UPDATE_OF_RANGES))
119 					    pRangeList = new rtl::OUString(rValue);
120 			    }
121 		    }
122             SetLayer(rShape, nLayerID, rShape->getShapeType());
123 
124 		    if (!bOnTable)
125 		    {
126 			    rTables.AddShape(rShape,
127 				    pRangeList, aStartCell, aEndCell, nEndX, nEndY);
128 			    SvxShape* pShapeImp = SvxShape::getImplementation(rShape);
129 			    if (pShapeImp)
130 			    {
131 				    SdrObject *pSdrObj = pShapeImp->GetSdrObject();
132 				    if (pSdrObj)
133 					    ScDrawLayer::SetAnchor(pSdrObj, SCA_CELL);
134 			    }
135 		    }
136 		    else
137 		    {
138                 if ( pRangeList )
139                 {
140                     // #i78086# If there are notification ranges, the ChartListener must be created
141                     // also when anchored to the sheet
142                     // -> call AddShape with invalid cell position (checked in ScMyShapeResizer::ResizeShapes)
143 
144                     table::CellAddress aInvalidPos( -1, -1, -1 );
145                     rTables.AddShape(rShape,
146                         pRangeList, aInvalidPos, aInvalidPos, 0, 0);
147                 }
148 
149 			    SvxShape* pShapeImp = SvxShape::getImplementation(rShape);
150 			    if (pShapeImp)
151 			    {
152 				    SdrObject *pSdrObj = pShapeImp->GetSdrObject();
153 				    if (pSdrObj)
154 					    ScDrawLayer::SetAnchor(pSdrObj, SCA_PAGE);
155 			    }
156 		    }
157         }
158         else // shape is annotation
159         {
160             // get the style names for stream copying
161             rtl::OUString aStyleName;
162             rtl::OUString aTextStyle;
163             sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
164             for( sal_Int16 i=0; i < nAttrCount; ++i )
165             {
166                 const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
167                 rtl::OUString aLocalName;
168                 sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
169                 if(nPrefix == XML_NAMESPACE_DRAW)
170                 {
171                     if (IsXMLToken(aLocalName, XML_STYLE_NAME))
172                         aStyleName = xAttrList->getValueByIndex( i );
173                     else if (IsXMLToken(aLocalName, XML_TEXT_STYLE_NAME))
174                         aTextStyle = xAttrList->getValueByIndex( i );
175                 }
176             }
177 
178             pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
179             bNote = true;
180         }
181 	}
182     else //#99532# this are grouped shapes which should also get the layerid
183     {
184 		sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
185         sal_Int16 nLayerID(-1);
186 		for( sal_Int16 i=0; i < nAttrCount; ++i )
187 		{
188 			const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
189 			const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
190 
191 			rtl::OUString aLocalName;
192 			sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
193 			if(nPrefix == XML_NAMESPACE_TABLE)
194 			{
195 				if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
196 					if (IsXMLToken(rValue, XML_TRUE))
197 						nLayerID = SC_LAYER_BACK;
198 			}
199 		}
200         SetLayer(rShape, nLayerID, rShape->getShapeType());
201     }
202 
203     if (!bNote)
204     {
205         // any shape other than a note prevents copying the sheet
206         ScSheetSaveData* pSheetData = ScModelObj::getImplementation(mrImporter.GetModel())->GetSheetSaveData();
207         pSheetData->BlockSheet( rTables.GetCurrentSheet() );
208     }
209 
210 	static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
211 }
212