LibreOffice Module sc (master)  1
sheetdata.cxx
Go to the documentation of this file.
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 <rtl/ustring.hxx>
21 #include <osl/diagnose.h>
22 #include <xmloff/families.hxx>
23 #include <xmloff/nmspmap.hxx>
24 
25 #include <algorithm>
26 
27 #include <sheetdata.hxx>
28 
30  mnStartTab( -1 ),
31  mnStartOffset( -1 ),
32  maPreviousNote( OUString(), OUString(), ScAddress::INITIALIZE_INVALID ),
33  mbInSupportedSave( false )
34 {
35 }
36 
38 {
39 }
40 
41 void ScSheetSaveData::AddCellStyle( const OUString& rName, const ScAddress& rCellPos )
42 {
43  maCellStyles.emplace_back( rName, rCellPos );
44 }
45 
46 void ScSheetSaveData::AddColumnStyle( const OUString& rName, const ScAddress& rCellPos )
47 {
48  maColumnStyles.emplace_back( rName, rCellPos );
49 }
50 
51 void ScSheetSaveData::AddRowStyle( const OUString& rName, const ScAddress& rCellPos )
52 {
53  maRowStyles.emplace_back( rName, rCellPos );
54 }
55 
56 void ScSheetSaveData::AddTableStyle( const OUString& rName, const ScAddress& rCellPos )
57 {
58  maTableStyles.emplace_back( rName, rCellPos );
59 }
60 
61 void ScSheetSaveData::HandleNoteStyles( const OUString& rStyleName, const OUString& rTextName, const ScAddress& rCellPos )
62 {
63  // only consecutive duplicates (most common case) are filtered out here,
64  // the others are found when the styles are created
65 
66  if ( rStyleName == maPreviousNote.maStyleName &&
67  rTextName == maPreviousNote.maTextStyle &&
68  rCellPos.Tab() == maPreviousNote.maCellPos.Tab() )
69  {
70  // already stored for the same sheet - ignore
71  return;
72  }
73 
74  ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos );
75  maPreviousNote = aNewEntry;
76  maNoteStyles.push_back( aNewEntry );
77 }
78 
79 void ScSheetSaveData::AddNoteContentStyle( XmlStyleFamily nFamily, const OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
80 {
81  if ( nFamily == XmlStyleFamily::TEXT_PARAGRAPH )
82  maNoteParaStyles.emplace_back( rName, rCellPos, rSelection );
83  else
84  maNoteTextStyles.emplace_back( rName, rCellPos, rSelection );
85 }
86 
87 void ScSheetSaveData::AddTextStyle( const OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
88 {
89  maTextStyles.emplace_back( rName, rCellPos, rSelection );
90 }
91 
93 {
94  if ( nTab >= static_cast<SCTAB>(maBlocked.size()) )
95  maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries
96 
97  maBlocked[nTab] = true;
98 }
99 
101 {
102  if ( nTab < static_cast<SCTAB>(maBlocked.size()) )
103  return maBlocked[nTab];
104  else
105  return false;
106 }
107 
108 void ScSheetSaveData::AddStreamPos( SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
109 {
110  if ( nTab >= static_cast<SCTAB>(maStreamEntries.size()) )
111  maStreamEntries.resize( nTab + 1 );
112 
113  maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
114 }
115 
116 void ScSheetSaveData::StartStreamPos( SCTAB nTab, sal_Int32 nStartOffset )
117 {
118  OSL_ENSURE( mnStartTab < 0, "StartStreamPos without EndStreamPos" );
119 
120  mnStartTab = nTab;
121  mnStartOffset = nStartOffset;
122 }
123 
124 void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset )
125 {
126  if ( mnStartTab >= 0 )
127  {
128  AddStreamPos( mnStartTab, mnStartOffset, nEndOffset );
129  mnStartTab = -1;
130  mnStartOffset = -1;
131  }
132 }
133 
134 void ScSheetSaveData::GetStreamPos( SCTAB nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const
135 {
136  if ( nTab < static_cast<SCTAB>(maStreamEntries.size()) )
137  {
138  const ScStreamEntry& rEntry = maStreamEntries[nTab];
139  rStartOffset = rEntry.mnStartOffset;
140  rEndOffset = rEntry.mnEndOffset;
141  }
142  else
143  rStartOffset = rEndOffset = -1;
144 }
145 
147 {
148  sal_Int32 nStartOffset = -1;
149  sal_Int32 nEndOffset = -1;
150  GetStreamPos( nTab, nStartOffset, nEndOffset );
151  return ( nStartOffset >= 0 && nEndOffset >= 0 );
152 }
153 
155 {
156  maSaveEntries.clear();
157 }
158 
159 void ScSheetSaveData::AddSavePos( SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
160 {
161  if ( nTab >= static_cast<SCTAB>(maSaveEntries.size()) )
162  maSaveEntries.resize( nTab + 1 );
163 
164  maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
165 }
166 
168 {
170 }
171 
173 {
174  // the initial namespaces are just removed from the list of loaded namespaces,
175  // so only an unordered_map of the prefixes is needed.
176 
177  const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
178  for (const auto& rEntry : rNameHash)
179  {
180  maInitialPrefixes.insert( rEntry.first );
181  }
182 }
183 
185 {
186  // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
187 
188  const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
189  for (const auto& [rName, rxEntry] : rNameHash)
190  {
191  // ignore the initial namespaces
192  if ( maInitialPrefixes.find( rName ) == maInitialPrefixes.end() )
193  {
194  maLoadedNamespaces.emplace_back( rxEntry->sPrefix, rxEntry->sName, rxEntry->nKey );
195  }
196  }
197 }
198 
199 static bool lcl_NameInHash( const NameSpaceHash& rNameHash, const OUString& rName )
200 {
201  return std::any_of(rNameHash.begin(), rNameHash.end(),
202  [&rName](const NameSpaceHash::value_type& rEntry) { return rEntry.second->sName == rName; });
203 }
204 
206 {
207  // Add the loaded namespaces to the name space map.
208 
209  // look for conflicts
210  // (if the loaded namespaces were added first, this might not be necessary)
211  const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
212  auto bConflict = std::any_of(maLoadedNamespaces.begin(), maLoadedNamespaces.end(),
213  [&rNameHash](const ScLoadedNamespaceEntry& rLoadedNamespace) {
214  NameSpaceHash::const_iterator aHashIter = rNameHash.find( rLoadedNamespace.maPrefix );
215 
216  // same prefix, but different name: loaded namespaces can't be used
217  bool bNameConflict = (aHashIter != rNameHash.end()) && (aHashIter->second->sName != rLoadedNamespace.maName);
218 
219  // a second prefix for the same name would confuse SvXMLNamespaceMap lookup,
220  // so this is also considered a conflict
221  bool bPrefixConflict = (aHashIter == rNameHash.end()) && lcl_NameInHash(rNameHash, rLoadedNamespace.maName);
222 
223  return bNameConflict || bPrefixConflict;
224  });
225  if (bConflict)
226  return false;
227 
228  // only if there were no conflicts, add the entries that aren't in the map already
229  // (the key is needed if the same namespace is added later within an element)
230  for (const auto& rLoadedNamespace : maLoadedNamespaces)
231  {
232  NameSpaceHash::const_iterator aHashIter = rNameHash.find( rLoadedNamespace.maPrefix );
233  if ( aHashIter == rNameHash.end() )
234  rNamespaces.Add( rLoadedNamespace.maPrefix, rLoadedNamespace.maName, rLoadedNamespace.mnKey );
235  }
236 
237  return true; // success
238 }
239 
241 {
242  mbInSupportedSave = bSet;
243 }
244 
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void HandleNoteStyles(const OUString &rStyleName, const OUString &rTextName, const ScAddress &rCellPos)
Definition: sheetdata.cxx:61
bool HasStreamPos(SCTAB nTab) const
Definition: sheetdata.cxx:146
std::vector< ScTextStyleEntry > maNoteParaStyles
Definition: sheetdata.hxx:115
std::unordered_map< OUString,::rtl::Reference< NameSpaceEntry > > NameSpaceHash
const NameSpaceHash & GetAllEntries() const
void StartStreamPos(SCTAB nTab, sal_Int32 nStartOffset)
Definition: sheetdata.cxx:116
void StoreInitialNamespaces(const SvXMLNamespaceMap &rNamespaces)
Definition: sheetdata.cxx:172
void AddColumnStyle(const OUString &rName, const ScAddress &rCellPos)
Definition: sheetdata.cxx:46
bool AddLoadedNamespaces(SvXMLNamespaceMap &rNamespaces) const
Definition: sheetdata.cxx:205
void AddStreamPos(SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset)
Definition: sheetdata.cxx:108
OUString maTextStyle
Definition: sheetdata.hxx:66
void BlockSheet(SCTAB nTab)
Definition: sheetdata.cxx:92
void UseSaveEntries()
Definition: sheetdata.cxx:167
std::vector< ScLoadedNamespaceEntry > maLoadedNamespaces
Definition: sheetdata.hxx:108
static bool lcl_NameInHash(const NameSpaceHash &rNameHash, const OUString &rName)
Definition: sheetdata.cxx:199
std::vector< ScTextStyleEntry > maNoteTextStyles
Definition: sheetdata.hxx:116
XmlStyleFamily
ScNoteStyleEntry maPreviousNote
Definition: sheetdata.hxx:124
void AddSavePos(SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset)
Definition: sheetdata.cxx:159
void AddTextStyle(const OUString &rName, const ScAddress &rCellPos, const ESelection &rSelection)
Definition: sheetdata.cxx:87
SCTAB Tab() const
Definition: address.hxx:271
std::vector< ScStreamEntry > maStreamEntries
Definition: sheetdata.hxx:119
void ResetSaveEntries()
Definition: sheetdata.cxx:154
void AddTableStyle(const OUString &rName, const ScAddress &rCellPos)
Definition: sheetdata.cxx:56
void AddNoteContentStyle(XmlStyleFamily nFamily, const OUString &rName, const ScAddress &rCellPos, const ESelection &rSelection)
Definition: sheetdata.cxx:79
bool mbInSupportedSave
Definition: sheetdata.hxx:126
void EndStreamPos(sal_Int32 nEndOffset)
Definition: sheetdata.cxx:124
void SetInSupportedSave(bool bSet)
Definition: sheetdata.cxx:240
std::vector< ScTextStyleEntry > maTextStyles
Definition: sheetdata.hxx:117
std::vector< ScStreamEntry > maSaveEntries
Definition: sheetdata.hxx:120
std::vector< ScNoteStyleEntry > maNoteStyles
Definition: sheetdata.hxx:114
sal_Int32 mnStartOffset
Definition: sheetdata.hxx:122
sal_Int32 mnEndOffset
Definition: sheetdata.hxx:36
std::vector< bool > maBlocked
Definition: sheetdata.hxx:118
std::unordered_set< OUString > maInitialPrefixes
Definition: sheetdata.hxx:107
std::vector< ScCellStyleEntry > maTableStyles
Definition: sheetdata.hxx:113
void AddCellStyle(const OUString &rName, const ScAddress &rCellPos)
Definition: sheetdata.cxx:41
std::vector< ScCellStyleEntry > maCellStyles
Definition: sheetdata.hxx:110
void GetStreamPos(SCTAB nTab, sal_Int32 &rStartOffset, sal_Int32 &rEndOffset) const
Definition: sheetdata.cxx:134
sal_uInt16 Add(const OUString &rPrefix, const OUString &rName, sal_uInt16 nKey=XML_NAMESPACE_UNKNOWN)
void StoreLoadedNamespaces(const SvXMLNamespaceMap &rNamespaces)
Definition: sheetdata.cxx:184
ScAddress maCellPos
Definition: sheetdata.hxx:67
sal_Int32 mnStartOffset
Definition: sheetdata.hxx:35
bool IsSheetBlocked(SCTAB nTab) const
Definition: sheetdata.cxx:100
void AddRowStyle(const OUString &rName, const ScAddress &rCellPos)
Definition: sheetdata.cxx:51
std::vector< ScCellStyleEntry > maColumnStyles
Definition: sheetdata.hxx:111
std::vector< ScCellStyleEntry > maRowStyles
Definition: sheetdata.hxx:112
OUString maStyleName
Definition: sheetdata.hxx:65
sal_Int16 SCTAB
Definition: types.hxx:23