summaryrefslogtreecommitdiffstats
path: root/sc/source/filter/xml/sheetdata.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/xml/sheetdata.cxx')
-rw-r--r--sc/source/filter/xml/sheetdata.cxx245
1 files changed, 245 insertions, 0 deletions
diff --git a/sc/source/filter/xml/sheetdata.cxx b/sc/source/filter/xml/sheetdata.cxx
new file mode 100644
index 000000000..51ae5c3aa
--- /dev/null
+++ b/sc/source/filter/xml/sheetdata.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+#include <xmloff/families.hxx>
+#include <xmloff/namespacemap.hxx>
+
+#include <algorithm>
+
+#include <sheetdata.hxx>
+
+ScSheetSaveData::ScSheetSaveData() :
+ mnStartTab( -1 ),
+ mnStartOffset( -1 ),
+ maPreviousNote( OUString(), OUString(), ScAddress::INITIALIZE_INVALID ),
+ mbInSupportedSave( false )
+{
+}
+
+ScSheetSaveData::~ScSheetSaveData()
+{
+}
+
+void ScSheetSaveData::AddCellStyle( const OUString& rName, const ScAddress& rCellPos )
+{
+ maCellStyles.emplace_back( rName, rCellPos );
+}
+
+void ScSheetSaveData::AddColumnStyle( const OUString& rName, const ScAddress& rCellPos )
+{
+ maColumnStyles.emplace_back( rName, rCellPos );
+}
+
+void ScSheetSaveData::AddRowStyle( const OUString& rName, const ScAddress& rCellPos )
+{
+ maRowStyles.emplace_back( rName, rCellPos );
+}
+
+void ScSheetSaveData::AddTableStyle( const OUString& rName, const ScAddress& rCellPos )
+{
+ maTableStyles.emplace_back( rName, rCellPos );
+}
+
+void ScSheetSaveData::HandleNoteStyles( const OUString& rStyleName, const OUString& rTextName, const ScAddress& rCellPos )
+{
+ // only consecutive duplicates (most common case) are filtered out here,
+ // the others are found when the styles are created
+
+ if ( rStyleName == maPreviousNote.maStyleName &&
+ rTextName == maPreviousNote.maTextStyle &&
+ rCellPos.Tab() == maPreviousNote.maCellPos.Tab() )
+ {
+ // already stored for the same sheet - ignore
+ return;
+ }
+
+ ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos );
+ maPreviousNote = aNewEntry;
+ maNoteStyles.push_back( aNewEntry );
+}
+
+void ScSheetSaveData::AddNoteContentStyle( XmlStyleFamily nFamily, const OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ if ( nFamily == XmlStyleFamily::TEXT_PARAGRAPH )
+ maNoteParaStyles.emplace_back( rName, rCellPos, rSelection );
+ else
+ maNoteTextStyles.emplace_back( rName, rCellPos, rSelection );
+}
+
+void ScSheetSaveData::AddTextStyle( const OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ maTextStyles.emplace_back( rName, rCellPos, rSelection );
+}
+
+void ScSheetSaveData::BlockSheet( SCTAB nTab )
+{
+ if ( nTab >= static_cast<SCTAB>(maBlocked.size()) )
+ maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries
+
+ maBlocked[nTab] = true;
+}
+
+bool ScSheetSaveData::IsSheetBlocked( SCTAB nTab ) const
+{
+ if ( nTab < static_cast<SCTAB>(maBlocked.size()) )
+ return maBlocked[nTab];
+ else
+ return false;
+}
+
+void ScSheetSaveData::AddStreamPos( SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= static_cast<SCTAB>(maStreamEntries.size()) )
+ maStreamEntries.resize( nTab + 1 );
+
+ maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::StartStreamPos( SCTAB nTab, sal_Int32 nStartOffset )
+{
+ OSL_ENSURE( mnStartTab < 0, "StartStreamPos without EndStreamPos" );
+
+ mnStartTab = nTab;
+ mnStartOffset = nStartOffset;
+}
+
+void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset )
+{
+ if ( mnStartTab >= 0 )
+ {
+ AddStreamPos( mnStartTab, mnStartOffset, nEndOffset );
+ mnStartTab = -1;
+ mnStartOffset = -1;
+ }
+}
+
+void ScSheetSaveData::GetStreamPos( SCTAB nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const
+{
+ if ( nTab < static_cast<SCTAB>(maStreamEntries.size()) )
+ {
+ const ScStreamEntry& rEntry = maStreamEntries[nTab];
+ rStartOffset = rEntry.mnStartOffset;
+ rEndOffset = rEntry.mnEndOffset;
+ }
+ else
+ rStartOffset = rEndOffset = -1;
+}
+
+bool ScSheetSaveData::HasStreamPos( SCTAB nTab ) const
+{
+ sal_Int32 nStartOffset = -1;
+ sal_Int32 nEndOffset = -1;
+ GetStreamPos( nTab, nStartOffset, nEndOffset );
+ return ( nStartOffset >= 0 && nEndOffset >= 0 );
+}
+
+void ScSheetSaveData::ResetSaveEntries()
+{
+ maSaveEntries.clear();
+}
+
+void ScSheetSaveData::AddSavePos( SCTAB nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= static_cast<SCTAB>(maSaveEntries.size()) )
+ maSaveEntries.resize( nTab + 1 );
+
+ maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::UseSaveEntries()
+{
+ maStreamEntries = maSaveEntries;
+}
+
+void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // the initial namespaces are just removed from the list of loaded namespaces,
+ // so only an unordered_map of the prefixes is needed.
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ for (const auto& rEntry : rNameHash)
+ {
+ maInitialPrefixes.insert( rEntry.first );
+ }
+}
+
+void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ for (const auto& [rName, rEntry] : rNameHash)
+ {
+ // ignore the initial namespaces
+ if ( maInitialPrefixes.find( rName ) == maInitialPrefixes.end() )
+ {
+ maLoadedNamespaces.emplace_back( rEntry.sPrefix, rEntry.sName, rEntry.nKey );
+ }
+ }
+}
+
+static bool lcl_NameInHash( const NameSpaceHash& rNameHash, const OUString& rName )
+{
+ return std::any_of(rNameHash.begin(), rNameHash.end(),
+ [&rName](const NameSpaceHash::value_type& rEntry) { return rEntry.second.sName == rName; });
+}
+
+bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const
+{
+ // Add the loaded namespaces to the name space map.
+
+ // look for conflicts
+ // (if the loaded namespaces were added first, this might not be necessary)
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ auto bConflict = std::any_of(maLoadedNamespaces.begin(), maLoadedNamespaces.end(),
+ [&rNameHash](const ScLoadedNamespaceEntry& rLoadedNamespace) {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( rLoadedNamespace.maPrefix );
+
+ // same prefix, but different name: loaded namespaces can't be used
+ bool bNameConflict = (aHashIter != rNameHash.end()) && (aHashIter->second.sName != rLoadedNamespace.maName);
+
+ // a second prefix for the same name would confuse SvXMLNamespaceMap lookup,
+ // so this is also considered a conflict
+ bool bPrefixConflict = (aHashIter == rNameHash.end()) && lcl_NameInHash(rNameHash, rLoadedNamespace.maName);
+
+ return bNameConflict || bPrefixConflict;
+ });
+ if (bConflict)
+ return false;
+
+ // only if there were no conflicts, add the entries that aren't in the map already
+ // (the key is needed if the same namespace is added later within an element)
+ for (const auto& rLoadedNamespace : maLoadedNamespaces)
+ {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( rLoadedNamespace.maPrefix );
+ if ( aHashIter == rNameHash.end() )
+ rNamespaces.Add( rLoadedNamespace.maPrefix, rLoadedNamespace.maName, rLoadedNamespace.mnKey );
+ }
+
+ return true; // success
+}
+
+void ScSheetSaveData::SetInSupportedSave( bool bSet )
+{
+ mbInSupportedSave = bSet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */