1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/namespacemap.hxx>
27 #include <sheetdata.hxx>
29 ScSheetSaveData::ScSheetSaveData() :
32 maPreviousNote( OUString(), OUString(), ScAddress::INITIALIZE_INVALID
),
33 mbInSupportedSave( false )
37 ScSheetSaveData::~ScSheetSaveData()
41 void ScSheetSaveData::AddCellStyle( const OUString
& rName
, const ScAddress
& rCellPos
)
43 maCellStyles
.emplace_back( rName
, rCellPos
);
46 void ScSheetSaveData::AddColumnStyle( const OUString
& rName
, const ScAddress
& rCellPos
)
48 maColumnStyles
.emplace_back( rName
, rCellPos
);
51 void ScSheetSaveData::AddRowStyle( const OUString
& rName
, const ScAddress
& rCellPos
)
53 maRowStyles
.emplace_back( rName
, rCellPos
);
56 void ScSheetSaveData::AddTableStyle( const OUString
& rName
, const ScAddress
& rCellPos
)
58 maTableStyles
.emplace_back( rName
, rCellPos
);
61 void ScSheetSaveData::HandleNoteStyles( const OUString
& rStyleName
, const OUString
& rTextName
, const ScAddress
& rCellPos
)
63 // only consecutive duplicates (most common case) are filtered out here,
64 // the others are found when the styles are created
66 if ( rStyleName
== maPreviousNote
.maStyleName
&&
67 rTextName
== maPreviousNote
.maTextStyle
&&
68 rCellPos
.Tab() == maPreviousNote
.maCellPos
.Tab() )
70 // already stored for the same sheet - ignore
74 ScNoteStyleEntry
aNewEntry( rStyleName
, rTextName
, rCellPos
);
75 maPreviousNote
= aNewEntry
;
76 maNoteStyles
.push_back( aNewEntry
);
79 void ScSheetSaveData::AddNoteContentStyle( XmlStyleFamily nFamily
, const OUString
& rName
, const ScAddress
& rCellPos
, const ESelection
& rSelection
)
81 if ( nFamily
== XmlStyleFamily::TEXT_PARAGRAPH
)
82 maNoteParaStyles
.emplace_back( rName
, rCellPos
, rSelection
);
84 maNoteTextStyles
.emplace_back( rName
, rCellPos
, rSelection
);
87 void ScSheetSaveData::AddTextStyle( const OUString
& rName
, const ScAddress
& rCellPos
, const ESelection
& rSelection
)
89 maTextStyles
.emplace_back( rName
, rCellPos
, rSelection
);
92 void ScSheetSaveData::BlockSheet( SCTAB nTab
)
94 if ( nTab
>= static_cast<SCTAB
>(maBlocked
.size()) )
95 maBlocked
.resize( nTab
+ 1, false ); // fill vector with "false" entries
97 maBlocked
[nTab
] = true;
100 bool ScSheetSaveData::IsSheetBlocked( SCTAB nTab
) const
102 if ( nTab
< static_cast<SCTAB
>(maBlocked
.size()) )
103 return maBlocked
[nTab
];
108 void ScSheetSaveData::AddStreamPos( SCTAB nTab
, sal_Int64 nStartOffset
, sal_Int64 nEndOffset
)
110 if ( nTab
>= static_cast<SCTAB
>(maStreamEntries
.size()) )
111 maStreamEntries
.resize( nTab
+ 1 );
113 maStreamEntries
[nTab
] = ScStreamEntry( nStartOffset
, nEndOffset
);
116 void ScSheetSaveData::StartStreamPos( SCTAB nTab
, sal_Int64 nStartOffset
)
118 OSL_ENSURE( mnStartTab
< 0, "StartStreamPos without EndStreamPos" );
121 mnStartOffset
= nStartOffset
;
124 void ScSheetSaveData::EndStreamPos( sal_Int64 nEndOffset
)
126 if ( mnStartTab
>= 0 )
128 AddStreamPos( mnStartTab
, mnStartOffset
, nEndOffset
);
134 void ScSheetSaveData::GetStreamPos( SCTAB nTab
, sal_Int64
& rStartOffset
, sal_Int64
& rEndOffset
) const
136 if ( nTab
< static_cast<SCTAB
>(maStreamEntries
.size()) )
138 const ScStreamEntry
& rEntry
= maStreamEntries
[nTab
];
139 rStartOffset
= rEntry
.mnStartOffset
;
140 rEndOffset
= rEntry
.mnEndOffset
;
143 rStartOffset
= rEndOffset
= -1;
146 bool ScSheetSaveData::HasStreamPos( SCTAB nTab
) const
148 sal_Int64 nStartOffset
= -1;
149 sal_Int64 nEndOffset
= -1;
150 GetStreamPos( nTab
, nStartOffset
, nEndOffset
);
151 return ( nStartOffset
>= 0 && nEndOffset
>= 0 );
154 void ScSheetSaveData::ResetSaveEntries()
156 maSaveEntries
.clear();
159 void ScSheetSaveData::AddSavePos( SCTAB nTab
, sal_Int64 nStartOffset
, sal_Int64 nEndOffset
)
161 if ( nTab
>= static_cast<SCTAB
>(maSaveEntries
.size()) )
162 maSaveEntries
.resize( nTab
+ 1 );
164 maSaveEntries
[nTab
] = ScStreamEntry( nStartOffset
, nEndOffset
);
167 void ScSheetSaveData::UseSaveEntries()
169 maStreamEntries
= maSaveEntries
;
172 void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap
& rNamespaces
)
174 // the initial namespaces are just removed from the list of loaded namespaces,
175 // so only an unordered_map of the prefixes is needed.
177 const NameSpaceHash
& rNameHash
= rNamespaces
.GetAllEntries();
178 for (const auto& rEntry
: rNameHash
)
180 maInitialPrefixes
.insert( rEntry
.first
);
184 void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap
& rNamespaces
)
186 // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
188 const NameSpaceHash
& rNameHash
= rNamespaces
.GetAllEntries();
189 for (const auto& [rName
, rEntry
] : rNameHash
)
191 // ignore the initial namespaces
192 if ( maInitialPrefixes
.find( rName
) == maInitialPrefixes
.end() )
194 maLoadedNamespaces
.emplace_back( rEntry
.m_sPrefix
, rEntry
.m_sName
, rEntry
.m_nKey
);
199 static bool lcl_NameInHash( const NameSpaceHash
& rNameHash
, const OUString
& rName
)
201 return std::any_of(rNameHash
.begin(), rNameHash
.end(),
202 [&rName
](const NameSpaceHash::value_type
& rEntry
) { return rEntry
.second
.m_sName
== rName
; });
205 bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap
& rNamespaces
) const
207 // Add the loaded namespaces to the name space map.
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
);
216 // same prefix, but different name: loaded namespaces can't be used
217 bool bNameConflict
= (aHashIter
!= rNameHash
.end()) && (aHashIter
->second
.m_sName
!= rLoadedNamespace
.maName
);
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
);
223 return bNameConflict
|| bPrefixConflict
;
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
)
232 NameSpaceHash::const_iterator aHashIter
= rNameHash
.find( rLoadedNamespace
.maPrefix
);
233 if ( aHashIter
== rNameHash
.end() )
234 rNamespaces
.Add( rLoadedNamespace
.maPrefix
, rLoadedNamespace
.maName
, rLoadedNamespace
.mnKey
);
237 return true; // success
240 void ScSheetSaveData::SetInSupportedSave( bool bSet
)
242 mbInSupportedSave
= bSet
;
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */