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