1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27 // INCLUDE ---------------------------------------------------------------
28
29 #include <xmloff/families.hxx>
30 #include <xmloff/xmlaustp.hxx>
31 #include <xmloff/nmspmap.hxx>
32 #include <tools/string.hxx>
33 #include <tools/debug.hxx>
34
35 #include "sheetdata.hxx"
36
37 // -----------------------------------------------------------------------
38
ScSheetSaveData()39 ScSheetSaveData::ScSheetSaveData() :
40 mnStartTab( -1 ),
41 mnStartOffset( -1 ),
42 maPreviousNote( rtl::OUString(), rtl::OUString(), ScAddress(ScAddress::INITIALIZE_INVALID) ),
43 mbInSupportedSave( false )
44 {
45 }
46
~ScSheetSaveData()47 ScSheetSaveData::~ScSheetSaveData()
48 {
49 }
50
AddCellStyle(const rtl::OUString & rName,const ScAddress & rCellPos)51 void ScSheetSaveData::AddCellStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
52 {
53 maCellStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
54 }
55
AddColumnStyle(const rtl::OUString & rName,const ScAddress & rCellPos)56 void ScSheetSaveData::AddColumnStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
57 {
58 maColumnStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
59 }
60
AddRowStyle(const rtl::OUString & rName,const ScAddress & rCellPos)61 void ScSheetSaveData::AddRowStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
62 {
63 maRowStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
64 }
65
AddTableStyle(const rtl::OUString & rName,const ScAddress & rCellPos)66 void ScSheetSaveData::AddTableStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
67 {
68 maTableStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
69 }
70
HandleNoteStyles(const rtl::OUString & rStyleName,const rtl::OUString & rTextName,const ScAddress & rCellPos)71 void ScSheetSaveData::HandleNoteStyles( const rtl::OUString& rStyleName, const rtl::OUString& rTextName, const ScAddress& rCellPos )
72 {
73 // only consecutive duplicates (most common case) are filtered out here,
74 // the others are found when the styles are created
75
76 if ( rStyleName == maPreviousNote.maStyleName &&
77 rTextName == maPreviousNote.maTextStyle &&
78 rCellPos.Tab() == maPreviousNote.maCellPos.Tab() )
79 {
80 // already stored for the same sheet - ignore
81 return;
82 }
83
84 ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos );
85 maPreviousNote = aNewEntry;
86 maNoteStyles.push_back( aNewEntry );
87 }
88
AddNoteContentStyle(sal_uInt16 nFamily,const rtl::OUString & rName,const ScAddress & rCellPos,const ESelection & rSelection)89 void ScSheetSaveData::AddNoteContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
90 {
91 if ( nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH )
92 maNoteParaStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
93 else
94 maNoteTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
95 }
96
AddTextStyle(const rtl::OUString & rName,const ScAddress & rCellPos,const ESelection & rSelection)97 void ScSheetSaveData::AddTextStyle( const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
98 {
99 maTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
100 }
101
BlockSheet(sal_Int32 nTab)102 void ScSheetSaveData::BlockSheet( sal_Int32 nTab )
103 {
104 if ( nTab >= (sal_Int32)maBlocked.size() )
105 maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries
106
107 maBlocked[nTab] = true;
108 }
109
IsSheetBlocked(sal_Int32 nTab) const110 bool ScSheetSaveData::IsSheetBlocked( sal_Int32 nTab ) const
111 {
112 if ( nTab < (sal_Int32)maBlocked.size() )
113 return maBlocked[nTab];
114 else
115 return false;
116 }
117
AddStreamPos(sal_Int32 nTab,sal_Int32 nStartOffset,sal_Int32 nEndOffset)118 void ScSheetSaveData::AddStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
119 {
120 if ( nTab >= (sal_Int32)maStreamEntries.size() )
121 maStreamEntries.resize( nTab + 1 );
122
123 maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
124 }
125
StartStreamPos(sal_Int32 nTab,sal_Int32 nStartOffset)126 void ScSheetSaveData::StartStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset )
127 {
128 DBG_ASSERT( mnStartTab < 0, "StartStreamPos without EndStreamPos" );
129
130 mnStartTab = nTab;
131 mnStartOffset = nStartOffset;
132 }
133
EndStreamPos(sal_Int32 nEndOffset)134 void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset )
135 {
136 if ( mnStartTab >= 0 )
137 {
138 AddStreamPos( mnStartTab, mnStartOffset, nEndOffset );
139 mnStartTab = -1;
140 mnStartOffset = -1;
141 }
142 }
143
GetStreamPos(sal_Int32 nTab,sal_Int32 & rStartOffset,sal_Int32 & rEndOffset) const144 void ScSheetSaveData::GetStreamPos( sal_Int32 nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const
145 {
146 if ( nTab < (sal_Int32)maStreamEntries.size() )
147 {
148 const ScStreamEntry& rEntry = maStreamEntries[nTab];
149 rStartOffset = rEntry.mnStartOffset;
150 rEndOffset = rEntry.mnEndOffset;
151 }
152 else
153 rStartOffset = rEndOffset = -1;
154 }
155
HasStreamPos(sal_Int32 nTab) const156 bool ScSheetSaveData::HasStreamPos( sal_Int32 nTab ) const
157 {
158 sal_Int32 nStartOffset = -1;
159 sal_Int32 nEndOffset = -1;
160 GetStreamPos( nTab, nStartOffset, nEndOffset );
161 return ( nStartOffset >= 0 && nEndOffset >= 0 );
162 }
163
ResetSaveEntries()164 void ScSheetSaveData::ResetSaveEntries()
165 {
166 maSaveEntries.clear();
167 }
168
AddSavePos(sal_Int32 nTab,sal_Int32 nStartOffset,sal_Int32 nEndOffset)169 void ScSheetSaveData::AddSavePos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
170 {
171 if ( nTab >= (sal_Int32)maSaveEntries.size() )
172 maSaveEntries.resize( nTab + 1 );
173
174 maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
175 }
176
UseSaveEntries()177 void ScSheetSaveData::UseSaveEntries()
178 {
179 maStreamEntries = maSaveEntries;
180 }
181
StoreInitialNamespaces(const SvXMLNamespaceMap & rNamespaces)182 void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces )
183 {
184 // the initial namespaces are just removed from the list of loaded namespaces,
185 // so only a hash_set of the prefixes is needed.
186
187 const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
188 NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
189 while (aIter != aEnd)
190 {
191 maInitialPrefixes.insert( aIter->first );
192 ++aIter;
193 }
194 }
195
StoreLoadedNamespaces(const SvXMLNamespaceMap & rNamespaces)196 void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces )
197 {
198 // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
199
200 const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
201 NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
202 while (aIter != aEnd)
203 {
204 // ignore the initial namespaces
205 if ( maInitialPrefixes.find( aIter->first ) == maInitialPrefixes.end() )
206 {
207 const NameSpaceEntry& rEntry = aIter->second.getBody();
208 maLoadedNamespaces.push_back( ScLoadedNamespaceEntry( rEntry.sPrefix, rEntry.sName, rEntry.nKey ) );
209 }
210 ++aIter;
211 }
212 }
213
lcl_NameInHash(const NameSpaceHash & rNameHash,const rtl::OUString & rName)214 bool lcl_NameInHash( const NameSpaceHash& rNameHash, const rtl::OUString& rName )
215 {
216 NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
217 while (aIter != aEnd)
218 {
219 if ( aIter->second->sName == rName )
220 return true;
221
222 ++aIter;
223 }
224 return false; // not found
225 }
226
AddLoadedNamespaces(SvXMLNamespaceMap & rNamespaces) const227 bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const
228 {
229 // Add the loaded namespaces to the name space map.
230
231 // first loop: only look for conflicts
232 // (if the loaded namespaces were added first, this might not be necessary)
233 const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
234 std::vector<ScLoadedNamespaceEntry>::const_iterator aIter = maLoadedNamespaces.begin();
235 std::vector<ScLoadedNamespaceEntry>::const_iterator aEnd = maLoadedNamespaces.end();
236 while (aIter != aEnd)
237 {
238 NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
239 if ( aHashIter == rNameHash.end() )
240 {
241 if ( lcl_NameInHash( rNameHash, aIter->maName ) )
242 {
243 // a second prefix for the same name would confuse SvXMLNamespaceMap lookup,
244 // so this is also considered a conflict
245 return false;
246 }
247 }
248 else if ( aHashIter->second->sName != aIter->maName )
249 {
250 // same prefix, but different name: loaded namespaces can't be used
251 return false;
252 }
253 ++aIter;
254 }
255
256 // only if there were no conflicts, add the entries that aren't in the map already
257 // (the key is needed if the same namespace is added later within an element)
258 aIter = maLoadedNamespaces.begin();
259 while (aIter != aEnd)
260 {
261 NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
262 if ( aHashIter == rNameHash.end() )
263 rNamespaces.Add( aIter->maPrefix, aIter->maName, aIter->mnKey );
264 ++aIter;
265 }
266
267 return true; // success
268 }
269
IsInSupportedSave() const270 bool ScSheetSaveData::IsInSupportedSave() const
271 {
272 return mbInSupportedSave;
273 }
274
SetInSupportedSave(bool bSet)275 void ScSheetSaveData::SetInSupportedSave( bool bSet )
276 {
277 mbInSupportedSave = bSet;
278 }
279
280