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 "xmlcoli.hxx"
21 #include "xmlimprt.hxx"
22 #include "xmlstyli.hxx"
23 #include <document.hxx>
24 #include <docuno.hxx>
25 #include <olinetab.hxx>
26 #include <sheetdata.hxx>
27 #include <unonames.hxx>
28
29 #include <xmloff/xmlnamespace.hxx>
30 #include <xmloff/families.hxx>
31 #include <xmloff/xmltoken.hxx>
32 #include <com/sun/star/sheet/XSpreadsheet.hpp>
33 #include <com/sun/star/table/XColumnRowRange.hpp>
34 #include <com/sun/star/sheet/XPrintAreas.hpp>
35 #include <comphelper/servicehelper.hxx>
36
37 using namespace com::sun::star;
38 using namespace xmloff::token;
39
ScXMLTableColContext(ScXMLImport & rImport,const rtl::Reference<sax_fastparser::FastAttributeList> & rAttrList)40 ScXMLTableColContext::ScXMLTableColContext( ScXMLImport& rImport,
41 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList ) :
42 ScXMLImportContext( rImport ),
43 nColCount(1),
44 sVisibility(GetXMLToken(XML_VISIBLE))
45 {
46 if ( !rAttrList.is() )
47 return;
48
49 for (auto &aIter : *rAttrList)
50 {
51 switch (aIter.getToken())
52 {
53 case XML_ELEMENT( TABLE, XML_NUMBER_COLUMNS_REPEATED ):
54 {
55 nColCount = std::max<sal_Int32>(aIter.toInt32(), 1);
56 nColCount = std::min<sal_Int32>(nColCount, MAXCOLCOUNT);
57 }
58 break;
59 case XML_ELEMENT( TABLE, XML_STYLE_NAME ):
60 {
61 sStyleName = aIter.toString();
62 }
63 break;
64 case XML_ELEMENT( TABLE, XML_VISIBILITY ):
65 {
66 sVisibility = aIter.toString();
67 }
68 break;
69 case XML_ELEMENT( TABLE, XML_DEFAULT_CELL_STYLE_NAME ):
70 {
71 sCellStyleName = aIter.toString();
72 }
73 break;
74 }
75 }
76 }
77
~ScXMLTableColContext()78 ScXMLTableColContext::~ScXMLTableColContext()
79 {
80 }
81
endFastElement(sal_Int32)82 void SAL_CALL ScXMLTableColContext::endFastElement( sal_Int32 /*nElement*/ )
83 {
84 ScXMLImport& rXMLImport = GetScImport();
85 ScDocument* pDoc = rXMLImport.GetDocument();
86 SCTAB nSheet = rXMLImport.GetTables().GetCurrentSheet();
87 sal_Int32 nCurrentColumn = rXMLImport.GetTables().GetCurrentColCount();
88 uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
89 if(xSheet.is())
90 {
91 sal_Int32 nLastColumn(nCurrentColumn + nColCount - 1);
92 if (nLastColumn > pDoc->MaxCol())
93 nLastColumn = pDoc->MaxCol();
94 if (nCurrentColumn > pDoc->MaxCol())
95 nCurrentColumn = pDoc->MaxCol();
96 pDoc->CreateColumnIfNotExists(nSheet, nLastColumn);
97 uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet->getCellRangeByPosition(nCurrentColumn, 0, nLastColumn, 0), uno::UNO_QUERY);
98 if (xColumnRowRange.is())
99 {
100 uno::Reference <beans::XPropertySet> xColumnProperties(xColumnRowRange->getColumns(), uno::UNO_QUERY);
101 if (xColumnProperties.is())
102 {
103 if (!sStyleName.isEmpty())
104 {
105 XMLTableStylesContext *pStyles = static_cast<XMLTableStylesContext *>(rXMLImport.GetAutoStyles());
106 if ( pStyles )
107 {
108 XMLTableStyleContext* pStyle = const_cast<XMLTableStyleContext*>(static_cast<const XMLTableStyleContext *>(pStyles->FindStyleChildContext(
109 XmlStyleFamily::TABLE_COLUMN, sStyleName, true)));
110 if (pStyle)
111 {
112 pStyle->FillPropertySet(xColumnProperties);
113
114 if ( nSheet != pStyle->GetLastSheet() )
115 {
116 ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(rXMLImport.GetModel())->GetSheetSaveData();
117 pSheetData->AddColumnStyle( sStyleName, ScAddress( static_cast<SCCOL>(nCurrentColumn), 0, nSheet ) );
118 pStyle->SetLastSheet(nSheet);
119 }
120 }
121 }
122 }
123 bool bValue(true);
124 if (!IsXMLToken(sVisibility, XML_VISIBLE))
125 bValue = false;
126 xColumnProperties->setPropertyValue(SC_UNONAME_CELLVIS, uno::makeAny(bValue));
127 }
128 }
129 }
130
131 // #i57915# ScXMLImport::SetStyleToRange can't handle empty style names.
132 // The default for a column if there is no attribute is the style "Default" (programmatic API name).
133 if ( sCellStyleName.isEmpty() )
134 sCellStyleName = "Default";
135
136 GetScImport().GetTables().AddColStyle(nColCount, sCellStyleName);
137 }
138
ScXMLTableColsContext(ScXMLImport & rImport,const rtl::Reference<sax_fastparser::FastAttributeList> & rAttrList,const bool bTempHeader,const bool bTempGroup)139 ScXMLTableColsContext::ScXMLTableColsContext( ScXMLImport& rImport,
140 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
141 const bool bTempHeader, const bool bTempGroup) :
142 ScXMLImportContext( rImport ),
143 nHeaderStartCol(0),
144 nHeaderEndCol(0),
145 nGroupStartCol(0),
146 nGroupEndCol(0),
147 bHeader(bTempHeader),
148 bGroup(bTempGroup),
149 bGroupDisplay(true)
150 {
151 // don't have any attributes
152 if (bHeader)
153 nHeaderStartCol = rImport.GetTables().GetCurrentColCount();
154 else if (bGroup)
155 {
156 nGroupStartCol = rImport.GetTables().GetCurrentColCount();
157 if ( rAttrList.is() )
158 {
159 auto aIter( rAttrList->find( XML_ELEMENT( TABLE, XML_DISPLAY ) ) );
160 if ( aIter != rAttrList->end() && IsXMLToken(aIter, XML_FALSE) )
161 bGroupDisplay = false;
162 }
163 }
164 }
165
~ScXMLTableColsContext()166 ScXMLTableColsContext::~ScXMLTableColsContext()
167 {
168 }
169
createFastChildContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> & xAttrList)170 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLTableColsContext::createFastChildContext(
171 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
172 {
173 SvXMLImportContext *pContext = nullptr;
174 sax_fastparser::FastAttributeList *pAttribList =
175 &sax_fastparser::castToFastAttributeList( xAttrList );
176
177 switch (nElement)
178 {
179 case XML_ELEMENT( TABLE, XML_TABLE_COLUMN_GROUP ):
180 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
181 false, true );
182 break;
183 case XML_ELEMENT( TABLE, XML_TABLE_HEADER_COLUMNS ):
184 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
185 true, false );
186 break;
187 case XML_ELEMENT( TABLE, XML_TABLE_COLUMNS ):
188 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
189 false, false );
190 break;
191 case XML_ELEMENT( TABLE, XML_TABLE_COLUMN ):
192 pContext = new ScXMLTableColContext( GetScImport(), pAttribList );
193 break;
194 }
195
196 return pContext;
197 }
198
endFastElement(sal_Int32)199 void SAL_CALL ScXMLTableColsContext::endFastElement( sal_Int32 /*nElement*/ )
200 {
201 ScXMLImport& rXMLImport = GetScImport();
202 if (bHeader)
203 {
204 nHeaderEndCol = rXMLImport.GetTables().GetCurrentColCount();
205 nHeaderEndCol--;
206 if (nHeaderStartCol <= nHeaderEndCol)
207 {
208 uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
209 if (xPrintAreas.is())
210 {
211 if (!xPrintAreas->getPrintTitleColumns())
212 {
213 xPrintAreas->setPrintTitleColumns(true);
214 table::CellRangeAddress aColumnHeaderRange;
215 aColumnHeaderRange.StartColumn = nHeaderStartCol;
216 aColumnHeaderRange.EndColumn = nHeaderEndCol;
217 xPrintAreas->setTitleColumns(aColumnHeaderRange);
218 }
219 else
220 {
221 table::CellRangeAddress aColumnHeaderRange(xPrintAreas->getTitleColumns());
222 aColumnHeaderRange.EndColumn = nHeaderEndCol;
223 xPrintAreas->setTitleColumns(aColumnHeaderRange);
224 }
225 }
226 }
227 }
228 else if (bGroup)
229 {
230 SCTAB nSheet = rXMLImport.GetTables().GetCurrentSheet();
231 nGroupEndCol = rXMLImport.GetTables().GetCurrentColCount();
232 nGroupEndCol--;
233 if (nGroupStartCol <= nGroupEndCol)
234 {
235 ScDocument* pDoc = GetScImport().GetDocument();
236 if (pDoc)
237 {
238 ScXMLImport::MutexGuard aGuard(GetScImport());
239 ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable(nSheet, true);
240 if (pOutlineTable)
241 {
242 ScOutlineArray& rColArray = pOutlineTable->GetColArray();
243 bool bResized;
244 rColArray.Insert(static_cast<SCCOL>(nGroupStartCol), static_cast<SCCOL>(nGroupEndCol), bResized, !bGroupDisplay);
245 }
246 }
247 }
248 }
249 }
250
251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
252