xref: /trunk/main/sc/source/filter/xml/sheetdata.cxx (revision b3f79822)
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