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 "XMLExportDDELinks.hxx"
21 #include <xmloff/xmltoken.hxx>
22 #include <xmloff/xmlnmspe.hxx>
23 #include <sax/tools/converter.hxx>
24 #include "xmlexprt.hxx"
25 #include <unonames.hxx>
26 #include <document.hxx>
27 #include <scmatrix.hxx>
28 #include <com/sun/star/sheet/XDDELink.hpp>
29 #include <com/sun/star/container/XIndexAccess.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 
32 using namespace com::sun::star;
33 using namespace xmloff::token;
34 
ScXMLExportDDELinks(ScXMLExport & rTempExport)35 ScXMLExportDDELinks::ScXMLExportDDELinks(ScXMLExport& rTempExport)
36     : rExport(rTempExport)
37 {
38 }
39 
~ScXMLExportDDELinks()40 ScXMLExportDDELinks::~ScXMLExportDDELinks()
41 {
42 }
43 
WriteCell(const ScMatrixValue & aVal,sal_Int32 nRepeat)44 void ScXMLExportDDELinks::WriteCell(const ScMatrixValue& aVal, sal_Int32 nRepeat)
45 {
46     bool bString = ScMatrix::IsNonValueType(aVal.nType);
47     bool bEmpty = ScMatrix::IsEmptyType(aVal.nType);
48 
49     if (!bEmpty)
50     {
51         if (bString)
52         {
53             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
54             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, aVal.GetString().getString());
55         }
56         else
57         {
58             OUStringBuffer aBuf;
59             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
60             ::sax::Converter::convertDouble(aBuf, aVal.fVal);
61             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aBuf.makeStringAndClear());
62         }
63     }
64 
65     if (nRepeat > 1)
66     {
67         rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, OUString::number(nRepeat));
68     }
69     SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true);
70 }
71 
WriteTable(const sal_Int32 nPos)72 void ScXMLExportDDELinks::WriteTable(const sal_Int32 nPos)
73 {
74     ScDocument* pDoc = rExport.GetDocument();
75     if (!pDoc)
76         return;
77 
78     const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix(static_cast<sal_uInt16>(nPos));
79     if (!pMatrix)
80         return;
81 
82     SCSIZE nCols, nRows;
83     pMatrix->GetDimensions(nCols, nRows);
84 
85     SvXMLElementExport aTableElem(rExport, XML_NAMESPACE_TABLE, XML_TABLE, true, true);
86     if (nCols > 1)
87     {
88         rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, OUString::number(nCols));
89     }
90     {
91         SvXMLElementExport aElemCol(rExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, true, true);
92     }
93 
94     for (SCSIZE nRow = 0; nRow < nRows; ++nRow)
95     {
96         sal_Int32 nRepeat = 0;
97         ScMatrixValue aPrevVal;
98         SvXMLElementExport aElemRow(rExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true);
99         for (SCSIZE nCol = 0; nCol < nCols; ++nCol, ++nRepeat)
100         {
101             ScMatrixValue aVal = pMatrix->Get(nCol, nRow);
102             if (nCol > 0 && aVal != aPrevVal)
103             {
104                 // Cell value differs.  Flush the cell content.
105                 WriteCell(aPrevVal, nRepeat);
106                 nRepeat = 0;
107             }
108             aPrevVal = aVal;
109         }
110 
111         WriteCell(aPrevVal, nRepeat);
112     }
113 }
114 
WriteDDELinks(const uno::Reference<sheet::XSpreadsheetDocument> & xSpreadDoc)115 void ScXMLExportDDELinks::WriteDDELinks(const uno::Reference<sheet::XSpreadsheetDocument>& xSpreadDoc)
116 {
117     uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
118     if (xPropertySet.is())
119     {
120         uno::Reference<container::XIndexAccess> xIndex(xPropertySet->getPropertyValue(SC_UNO_DDELINKS), uno::UNO_QUERY);
121         if (xIndex.is())
122         {
123             sal_Int32 nCount = xIndex->getCount();
124             if (nCount)
125             {
126                 SvXMLElementExport aElemDDEs(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINKS, true, true);
127                 for (sal_Int32 nDDELink = 0; nDDELink < nCount; ++nDDELink)
128                 {
129                     uno::Reference<sheet::XDDELink> xDDELink(xIndex->getByIndex(nDDELink), uno::UNO_QUERY);
130                     if (xDDELink.is())
131                     {
132                         SvXMLElementExport aElemDDE(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINK, true, true);
133                         {
134                             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_APPLICATION, xDDELink->getApplication());
135                             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_TOPIC, xDDELink->getTopic());
136                             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_ITEM, xDDELink->getItem());
137                             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_AUTOMATIC_UPDATE, XML_TRUE);
138                             sal_uInt8 nMode;
139                             if (rExport.GetDocument() &&
140                                 rExport.GetDocument()->GetDdeLinkMode(nDDELink, nMode))
141                             {
142                                 switch (nMode)
143                                 {
144                                     case SC_DDE_ENGLISH :
145                                         rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_INTO_ENGLISH_NUMBER);
146                                     break;
147                                     case SC_DDE_TEXT :
148                                         rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_KEEP_TEXT);
149                                     break;
150                                 }
151                             }
152                             SvXMLElementExport(rExport, XML_NAMESPACE_OFFICE, XML_DDE_SOURCE, true, true);
153                         }
154                         WriteTable(nDDELink);
155                     }
156                 }
157             }
158         }
159     }
160 }
161 
162 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
163