Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / xml / sheetdata.cxx
blobc8796d9f691a9a244eda6a585c7b08d279c1c795
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 <rtl/ustring.hxx>
21 #include <osl/diagnose.h>
22 #include <xmloff/families.hxx>
23 #include <xmloff/nmspmap.hxx>
25 #include <sheetdata.hxx>
27 ScSheetSaveData::ScSheetSaveData() :
28 mnStartTab( -1 ),
29 mnStartOffset( -1 ),
30 maPreviousNote( OUString(), OUString(), ScAddress::INITIALIZE_INVALID ),
31 mbInSupportedSave( false )
35 ScSheetSaveData::~ScSheetSaveData()
39 void ScSheetSaveData::AddCellStyle( const OUString& rName, const ScAddress& rCellPos )
41 maCellStyles.emplace_back( rName, rCellPos );
44 void ScSheetSaveData::AddColumnStyle( const OUString& rName, const ScAddress& rCellPos )
46 maColumnStyles.emplace_back( rName, rCellPos );
49 void ScSheetSaveData::AddRowStyle( const OUString& rName, const ScAddress& rCellPos )
51 maRowStyles.emplace_back( rName, rCellPos );
54 void ScSheetSaveData::AddTableStyle( const OUString& rName, const ScAddress& rCellPos )
56 maTableStyles.emplace_back( rName, rCellPos );
59 void ScSheetSaveData::HandleNoteStyles( const OUString& rStyleName, const OUString& rTextName, const ScAddress& rCellPos )
61 // only consecutive duplicates (most common case) are filtered out here,
62 // the others are found when the styles are created
64 if ( rStyleName == maPreviousNote.maStyleName &&
65 rTextName == maPreviousNote.maTextStyle &&
66 rCellPos.Tab() == maPreviousNote.maCellPos.Tab() )
68 // already stored for the same sheet - ignore
69 return;
72 ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos );
73 maPreviousNote = aNewEntry;
74 maNoteStyles.push_back( aNewEntry );
77 void ScSheetSaveData::AddNoteContentStyle( sal_uInt16 nFamily, const OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
79 if ( nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH )
80 maNoteParaStyles.emplace_back( rName, rCellPos, rSelection );
81 else
82 maNoteTextStyles.emplace_back( rName, rCellPos, rSelection );
85 void ScSheetSaveData::AddTextStyle( const OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
87 maTextStyles.emplace_back( rName, rCellPos, rSelection );
90 void ScSheetSaveData::BlockSheet( SCTAB nTab )
92 if ( nTab >= static_cast<SCTAB>(maBlocked.size()) )
93 maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries
95 maBlocked[nTab] = true;
98 bool ScSheetSaveData::IsSheetBlocked( SCTAB nTab ) const
100 if ( nTab < static_cast<SCTAB>(maBlocked.size()) )
101 return maBlocked[nTab];
102 else
103 return false;
106 void ScSheetSaveData::AddStreamPos( SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
108 if ( nTab >= static_cast<SCTAB>(maStreamEntries.size()) )
109 maStreamEntries.resize( nTab + 1 );
111 maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
114 void ScSheetSaveData::StartStreamPos( SCTAB nTab, sal_Int32 nStartOffset )
116 OSL_ENSURE( mnStartTab < 0, "StartStreamPos without EndStreamPos" );
118 mnStartTab = nTab;
119 mnStartOffset = nStartOffset;
122 void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset )
124 if ( mnStartTab >= 0 )
126 AddStreamPos( mnStartTab, mnStartOffset, nEndOffset );
127 mnStartTab = -1;
128 mnStartOffset = -1;
132 void ScSheetSaveData::GetStreamPos( SCTAB nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const
134 if ( nTab < static_cast<SCTAB>(maStreamEntries.size()) )
136 const ScStreamEntry& rEntry = maStreamEntries[nTab];
137 rStartOffset = rEntry.mnStartOffset;
138 rEndOffset = rEntry.mnEndOffset;
140 else
141 rStartOffset = rEndOffset = -1;
144 bool ScSheetSaveData::HasStreamPos( SCTAB nTab ) const
146 sal_Int32 nStartOffset = -1;
147 sal_Int32 nEndOffset = -1;
148 GetStreamPos( nTab, nStartOffset, nEndOffset );
149 return ( nStartOffset >= 0 && nEndOffset >= 0 );
152 void ScSheetSaveData::ResetSaveEntries()
154 maSaveEntries.clear();
157 void ScSheetSaveData::AddSavePos( SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
159 if ( nTab >= static_cast<SCTAB>(maSaveEntries.size()) )
160 maSaveEntries.resize( nTab + 1 );
162 maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
165 void ScSheetSaveData::UseSaveEntries()
167 maStreamEntries = maSaveEntries;
170 void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces )
172 // the initial namespaces are just removed from the list of loaded namespaces,
173 // so only an unordered_map of the prefixes is needed.
175 const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
176 for (const auto& rEntry : rNameHash)
178 maInitialPrefixes.insert( rEntry.first );
182 void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces )
184 // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
186 const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
187 for (const auto& [rName, rxEntry] : rNameHash)
189 // ignore the initial namespaces
190 if ( maInitialPrefixes.find( rName ) == maInitialPrefixes.end() )
192 maLoadedNamespaces.emplace_back( rxEntry->sPrefix, rxEntry->sName, rxEntry->nKey );
197 static bool lcl_NameInHash( const NameSpaceHash& rNameHash, const OUString& rName )
199 return std::any_of(rNameHash.begin(), rNameHash.end(),
200 [&rName](const NameSpaceHash::value_type& rEntry) { return rEntry.second->sName == rName; });
203 bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const
205 // Add the loaded namespaces to the name space map.
207 // look for conflicts
208 // (if the loaded namespaces were added first, this might not be necessary)
209 const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
210 auto bConflict = std::any_of(maLoadedNamespaces.begin(), maLoadedNamespaces.end(),
211 [&rNameHash](const ScLoadedNamespaceEntry& rLoadedNamespace) {
212 NameSpaceHash::const_iterator aHashIter = rNameHash.find( rLoadedNamespace.maPrefix );
214 // same prefix, but different name: loaded namespaces can't be used
215 bool bNameConflict = (aHashIter != rNameHash.end()) && (aHashIter->second->sName != rLoadedNamespace.maName);
217 // a second prefix for the same name would confuse SvXMLNamespaceMap lookup,
218 // so this is also considered a conflict
219 bool bPrefixConflict = (aHashIter == rNameHash.end()) && lcl_NameInHash(rNameHash, rLoadedNamespace.maName);
221 return bNameConflict || bPrefixConflict;
223 if (bConflict)
224 return false;
226 // only if there were no conflicts, add the entries that aren't in the map already
227 // (the key is needed if the same namespace is added later within an element)
228 for (const auto& rLoadedNamespace : maLoadedNamespaces)
230 NameSpaceHash::const_iterator aHashIter = rNameHash.find( rLoadedNamespace.maPrefix );
231 if ( aHashIter == rNameHash.end() )
232 rNamespaces.Add( rLoadedNamespace.maPrefix, rLoadedNamespace.maName, rLoadedNamespace.mnKey );
235 return true; // success
238 void ScSheetSaveData::SetInSupportedSave( bool bSet )
240 mbInSupportedSave = bSet;
243 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */