cid#1607171 Data race condition
[LibreOffice.git] / sc / source / filter / xml / xmlcoli.cxx
blob5114296d9760c9b86da8954564d9d17f33e56dca
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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>
37 using namespace com::sun::star;
38 using namespace xmloff::token;
40 ScXMLTableColContext::ScXMLTableColContext( ScXMLImport& rImport,
41 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList ) :
42 ScXMLImportContext( rImport ),
43 nColCount(1),
44 sVisibility(GetXMLToken(XML_VISIBLE))
46 if ( !rAttrList.is() )
47 return;
49 for (auto &aIter : *rAttrList)
51 switch (aIter.getToken())
53 case XML_ELEMENT( TABLE, XML_NUMBER_COLUMNS_REPEATED ):
55 if (ScDocument* pDoc = rImport.GetDocument())
57 nColCount = std::max<sal_Int32>(aIter.toInt32(), 1);
58 nColCount = std::min<sal_Int32>(nColCount, pDoc->GetSheetLimits().GetMaxColCount() );
61 break;
62 case XML_ELEMENT( TABLE, XML_STYLE_NAME ):
64 sStyleName = aIter.toString();
66 break;
67 case XML_ELEMENT( TABLE, XML_VISIBILITY ):
69 sVisibility = aIter.toString();
71 break;
72 case XML_ELEMENT( TABLE, XML_DEFAULT_CELL_STYLE_NAME ):
74 sCellStyleName = aIter.toString();
76 break;
81 ScXMLTableColContext::~ScXMLTableColContext()
85 void SAL_CALL ScXMLTableColContext::endFastElement( sal_Int32 /*nElement*/ )
87 ScXMLImport& rXMLImport = GetScImport();
88 ScDocument* pDoc = rXMLImport.GetDocument();
89 SCTAB nSheet = rXMLImport.GetTables().GetCurrentSheet();
90 sal_Int32 nCurrentColumn = rXMLImport.GetTables().GetCurrentColCount();
91 uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
92 if(pDoc && xSheet.is())
94 sal_Int32 nLastColumn(nCurrentColumn + nColCount - 1);
95 if (nLastColumn > pDoc->MaxCol())
96 nLastColumn = pDoc->MaxCol();
97 if (nCurrentColumn > pDoc->MaxCol())
98 nCurrentColumn = pDoc->MaxCol();
99 uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet->getCellRangeByPosition(nCurrentColumn, 0, nLastColumn, 0), uno::UNO_QUERY);
100 if (xColumnRowRange.is())
102 uno::Reference <beans::XPropertySet> xColumnProperties(xColumnRowRange->getColumns(), uno::UNO_QUERY);
103 if (xColumnProperties.is())
105 if (!sStyleName.isEmpty())
107 XMLTableStylesContext *pStyles = static_cast<XMLTableStylesContext *>(rXMLImport.GetAutoStyles());
108 if ( pStyles )
110 XMLTableStyleContext* pStyle = const_cast<XMLTableStyleContext*>(static_cast<const XMLTableStyleContext *>(pStyles->FindStyleChildContext(
111 XmlStyleFamily::TABLE_COLUMN, sStyleName, true)));
112 if (pStyle)
114 pStyle->FillPropertySet(xColumnProperties);
116 if ( nSheet != pStyle->GetLastSheet() )
118 ScSheetSaveData* pSheetData = rXMLImport.GetScModel()->GetSheetSaveData();
119 pSheetData->AddColumnStyle( sStyleName, ScAddress( static_cast<SCCOL>(nCurrentColumn), 0, nSheet ) );
120 pStyle->SetLastSheet(nSheet);
125 bool bValue(true);
126 if (!IsXMLToken(sVisibility, XML_VISIBLE))
127 bValue = false;
128 xColumnProperties->setPropertyValue(SC_UNONAME_CELLVIS, uno::Any(bValue));
133 // #i57915# ScXMLImport::SetStyleToRange can't handle empty style names.
134 // The default for a column if there is no attribute is the style "Default" (programmatic API name).
135 if ( sCellStyleName.isEmpty() )
136 sCellStyleName = "Default";
138 GetScImport().GetTables().AddColStyle(nColCount, sCellStyleName);
141 ScXMLTableColsContext::ScXMLTableColsContext( ScXMLImport& rImport,
142 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
143 const bool bTempHeader, const bool bTempGroup) :
144 ScXMLImportContext( rImport ),
145 nHeaderStartCol(0),
146 nHeaderEndCol(0),
147 nGroupStartCol(0),
148 nGroupEndCol(0),
149 bHeader(bTempHeader),
150 bGroup(bTempGroup),
151 bGroupDisplay(true)
153 // don't have any attributes
154 if (bHeader)
155 nHeaderStartCol = rImport.GetTables().GetCurrentColCount();
156 else if (bGroup)
158 nGroupStartCol = rImport.GetTables().GetCurrentColCount();
159 if ( rAttrList.is() )
161 auto aIter( rAttrList->find( XML_ELEMENT( TABLE, XML_DISPLAY ) ) );
162 if ( aIter != rAttrList->end() && IsXMLToken(aIter, XML_FALSE) )
163 bGroupDisplay = false;
168 ScXMLTableColsContext::~ScXMLTableColsContext()
172 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLTableColsContext::createFastChildContext(
173 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
175 SvXMLImportContext *pContext = nullptr;
176 sax_fastparser::FastAttributeList *pAttribList =
177 &sax_fastparser::castToFastAttributeList( xAttrList );
179 switch (nElement)
181 case XML_ELEMENT( TABLE, XML_TABLE_COLUMN_GROUP ):
182 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
183 false, true );
184 break;
185 case XML_ELEMENT( TABLE, XML_TABLE_HEADER_COLUMNS ):
186 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
187 true, false );
188 break;
189 case XML_ELEMENT( TABLE, XML_TABLE_COLUMNS ):
190 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
191 false, false );
192 break;
193 case XML_ELEMENT( TABLE, XML_TABLE_COLUMN ):
194 pContext = new ScXMLTableColContext( GetScImport(), pAttribList );
195 break;
198 return pContext;
201 void SAL_CALL ScXMLTableColsContext::endFastElement( sal_Int32 /*nElement*/ )
203 ScXMLImport& rXMLImport = GetScImport();
204 if (bHeader)
206 nHeaderEndCol = rXMLImport.GetTables().GetCurrentColCount();
207 nHeaderEndCol--;
208 if (nHeaderStartCol <= nHeaderEndCol)
210 uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
211 if (xPrintAreas.is())
213 if (!xPrintAreas->getPrintTitleColumns())
215 xPrintAreas->setPrintTitleColumns(true);
216 table::CellRangeAddress aColumnHeaderRange;
217 aColumnHeaderRange.StartColumn = nHeaderStartCol;
218 aColumnHeaderRange.EndColumn = nHeaderEndCol;
219 xPrintAreas->setTitleColumns(aColumnHeaderRange);
221 else
223 table::CellRangeAddress aColumnHeaderRange(xPrintAreas->getTitleColumns());
224 aColumnHeaderRange.EndColumn = nHeaderEndCol;
225 xPrintAreas->setTitleColumns(aColumnHeaderRange);
230 else if (bGroup)
232 SCTAB nSheet = rXMLImport.GetTables().GetCurrentSheet();
233 nGroupEndCol = rXMLImport.GetTables().GetCurrentColCount();
234 nGroupEndCol--;
235 if (nGroupStartCol <= nGroupEndCol)
237 ScDocument* pDoc = GetScImport().GetDocument();
238 if (pDoc)
240 ScXMLImport::MutexGuard aGuard(GetScImport());
241 ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable(nSheet, true);
242 if (pOutlineTable)
244 ScOutlineArray& rColArray = pOutlineTable->GetColArray();
245 bool bResized;
246 rColArray.Insert(static_cast<SCCOL>(nGroupStartCol), static_cast<SCCOL>(nGroupEndCol), bResized, !bGroupDisplay);
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */