1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 
33 // INCLUDE ---------------------------------------------------------------
34 #include "XMLExportDDELinks.hxx"
35 #include <xmloff/xmltoken.hxx>
36 #include <xmloff/xmlnmspe.hxx>
37 #include <xmloff/nmspmap.hxx>
38 #include <xmloff/xmluconv.hxx>
39 #include "xmlexprt.hxx"
40 #include "unonames.hxx"
41 #include "document.hxx"
42 #include "scmatrix.hxx"
43 #include <com/sun/star/sheet/XDDELink.hpp>
44 
45 class ScMatrix;
46 
47 using namespace com::sun::star;
48 using namespace xmloff::token;
49 
50 ScXMLExportDDELinks::ScXMLExportDDELinks(ScXMLExport& rTempExport)
51 	: rExport(rTempExport)
52 {
53 }
54 
55 ScXMLExportDDELinks::~ScXMLExportDDELinks()
56 {
57 }
58 
59 sal_Bool ScXMLExportDDELinks::CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
60 		 			const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue)
61 {
62 	if (bEmpty == bPrevEmpty)
63 		if (bEmpty)
64 			return sal_True;
65 		else if (bString == bPrevString)
66 			if (bString)
67 				return (sPrevValue == sValue);
68 			else
69 				return (fPrevValue == fValue);
70 		else
71 			return sal_False;
72 	else
73 		return sal_False;
74 }
75 
76 void ScXMLExportDDELinks::WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat)
77 {
78 	rtl::OUStringBuffer sBuffer;
79 	if (!bEmpty)
80 	{
81 		if (bString)
82 		{
83 			rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
84 			rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, rtl::OUString(sValue));
85 		}
86 		else
87 		{
88 			rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
89 			rExport.GetMM100UnitConverter().convertDouble(sBuffer, fValue);
90 			rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sBuffer.makeStringAndClear());
91 		}
92 	}
93 	if (nRepeat > 1)
94 	{
95 		rExport.GetMM100UnitConverter().convertNumber(sBuffer, nRepeat);
96 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, sBuffer.makeStringAndClear());
97 	}
98 	SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
99 }
100 
101 void ScXMLExportDDELinks::WriteTable(const sal_Int32 nPos)
102 {
103     const ScMatrix* pMatrix(NULL);
104     if (rExport.GetDocument())
105         pMatrix = rExport.GetDocument()->GetDdeLinkResultMatrix( static_cast<sal_uInt16>(nPos) );
106     if (pMatrix)
107 	{
108         SCSIZE nuCol;
109         SCSIZE nuRow;
110         pMatrix->GetDimensions( nuCol, nuRow );
111         sal_Int32 nRowCount = static_cast<sal_Int32>(nuRow);
112         sal_Int32 nColCount = static_cast<sal_Int32>(nuCol);
113 		SvXMLElementExport aTableElem(rExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True);
114 		rtl::OUStringBuffer sBuffer;
115 		if (nColCount > 1)
116 		{
117 			rExport.GetMM100UnitConverter().convertNumber(sBuffer, nColCount);
118 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, sBuffer.makeStringAndClear());
119 		}
120 		{
121 			SvXMLElementExport aElemCol(rExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True);
122 		}
123 		sal_Bool bPrevString(sal_True);
124 		sal_Bool bPrevEmpty(sal_True);
125 		double fPrevValue;
126 		String sPrevValue;
127 		sal_Int32 nRepeatColsCount(1);
128 		for(sal_Int32 nRow = 0; nRow < nRowCount; ++nRow)
129 		{
130 			SvXMLElementExport aElemRow(rExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
131 			for(sal_Int32 nColumn = 0; nColumn < nColCount; ++nColumn)
132 			{
133                 ScMatValType nType = SC_MATVAL_VALUE;
134                 const ScMatrixValue* pMatVal = pMatrix->Get( static_cast<SCSIZE>(nColumn), static_cast<SCSIZE>(nRow), nType );
135                 sal_Bool bIsString = ScMatrix::IsNonValueType( nType);
136 
137 				if (nColumn == 0)
138                 {
139                     bPrevEmpty = !pMatVal;
140                     bPrevString = bIsString;
141                     if( bIsString )
142                         sPrevValue = pMatVal->GetString();
143                     else
144                         fPrevValue = pMatVal->fVal;
145                 }
146 				else
147 				{
148 					double fValue;
149 					String sValue;
150                     sal_Bool bEmpty(!pMatVal);
151                     sal_Bool bString(bIsString);
152                     if( bIsString )
153                         sValue = pMatVal->GetString();
154                     else
155                         fValue = pMatVal->fVal;
156 
157 					if (CellsEqual(bPrevEmpty, bPrevString, sPrevValue, fPrevValue,
158 								bEmpty, bString, sValue, fValue))
159 						++nRepeatColsCount;
160 					else
161 					{
162 						WriteCell(bPrevEmpty, bPrevString, sPrevValue, fPrevValue, nRepeatColsCount);
163 						nRepeatColsCount = 1;
164 						bPrevEmpty = bEmpty;
165 						fPrevValue = fValue;
166 						sPrevValue = sValue;
167 					}
168 				}
169 			}
170 			WriteCell(bPrevEmpty, bPrevString, sPrevValue, fPrevValue, nRepeatColsCount);
171 			nRepeatColsCount = 1;
172 		}
173 	}
174 }
175 
176 void ScXMLExportDDELinks::WriteDDELinks(uno::Reference<sheet::XSpreadsheetDocument>& xSpreadDoc)
177 {
178 	uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
179 	if (xPropertySet.is())
180 	{
181         uno::Reference<container::XIndexAccess> xIndex(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DDELINKS))), uno::UNO_QUERY);
182 		if (xIndex.is())
183 		{
184 			sal_Int32 nCount = xIndex->getCount();
185 			if (nCount)
186 			{
187 				SvXMLElementExport aElemDDEs(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINKS, sal_True, sal_True);
188 				for (sal_uInt16 nDDELink = 0; nDDELink < nCount; ++nDDELink)
189 				{
190                     uno::Reference<sheet::XDDELink> xDDELink(xIndex->getByIndex(nDDELink), uno::UNO_QUERY);
191 					if (xDDELink.is())
192 					{
193 						SvXMLElementExport aElemDDE(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINK, sal_True, sal_True);
194 						{
195 							rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_APPLICATION, xDDELink->getApplication());
196 							rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_TOPIC, xDDELink->getTopic());
197 							rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_ITEM, xDDELink->getItem());
198 							rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_AUTOMATIC_UPDATE, XML_TRUE);
199                             sal_uInt8 nMode;
200 							if (rExport.GetDocument() &&
201 								rExport.GetDocument()->GetDdeLinkMode(nDDELink, nMode))
202 							{
203 								switch (nMode)
204 								{
205 									case SC_DDE_ENGLISH :
206 										rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_INTO_ENGLISH_NUMBER);
207 									break;
208 									case SC_DDE_TEXT :
209 										rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_KEEP_TEXT);
210 									break;
211 								}
212 							}
213 							SvXMLElementExport(rExport, XML_NAMESPACE_OFFICE, XML_DDE_SOURCE, sal_True, sal_True);
214 						}
215 						WriteTable(nDDELink);
216 					}
217 				}
218 			}
219 		}
220 	}
221 }
222