summaryrefslogtreecommitdiffstats
path: root/sc/source/core/data/mtvelements.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/mtvelements.cxx')
-rw-r--r--sc/source/core/data/mtvelements.cxx198
1 files changed, 198 insertions, 0 deletions
diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx
new file mode 100644
index 000000000..2c2c8daa6
--- /dev/null
+++ b/sc/source/core/data/mtvelements.cxx
@@ -0,0 +1,198 @@
+/* -*- 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/.
+ */
+
+#include <mtvelements.hxx>
+#include <document.hxx>
+#include <cellvalue.hxx>
+#include <column.hxx>
+#include <table.hxx>
+
+#include <sstream>
+
+namespace sc {
+
+CellStoreEvent::CellStoreEvent() : mpCol(nullptr) {}
+
+CellStoreEvent::CellStoreEvent(ScColumn* pCol) : mpCol(pCol) {}
+
+void CellStoreEvent::element_block_acquired(const mdds::mtv::base_element_block* block)
+{
+ if (!mpCol)
+ return;
+
+ switch (mdds::mtv::get_block_type(*block))
+ {
+ case sc::element_type_formula:
+ ++mpCol->mnBlkCountFormula;
+ break;
+ default:
+ ;
+ }
+}
+
+void CellStoreEvent::element_block_released(const mdds::mtv::base_element_block* block)
+{
+ if (!mpCol)
+ return;
+
+ switch (mdds::mtv::get_block_type(*block))
+ {
+ case sc::element_type_formula:
+ --mpCol->mnBlkCountFormula;
+ break;
+ default:
+ ;
+ }
+}
+
+void CellStoreEvent::stop()
+{
+ mpCol = nullptr;
+}
+
+void CellStoreEvent::swap(CellStoreEvent& other)
+{
+ std::swap(mpCol, other.mpCol);
+}
+
+const ScColumn* CellStoreEvent::getColumn() const
+{
+ return mpCol;
+}
+
+ColumnBlockPositionSet::ColumnBlockPositionSet(ScDocument& rDoc) : mrDoc(rDoc) {}
+
+ColumnBlockPosition* ColumnBlockPositionSet::getBlockPosition(SCTAB nTab, SCCOL nCol)
+{
+ std::scoped_lock aGuard(maMtxTables);
+
+ TablesType::iterator itTab = maTables.find(nTab);
+ if (itTab == maTables.end())
+ {
+ std::pair<TablesType::iterator,bool> r =
+ maTables.emplace(nTab, ColumnsType());
+ if (!r.second)
+ // insertion failed.
+ return nullptr;
+
+ itTab = r.first;
+ }
+
+ ColumnsType& rCols = itTab->second;
+
+ ColumnsType::iterator it = rCols.find(nCol);
+ if (it != rCols.end())
+ // Block position for this column has already been fetched.
+ return &it->second;
+
+ std::pair<ColumnsType::iterator,bool> r =
+ rCols.emplace(nCol, ColumnBlockPosition());
+
+ if (!r.second)
+ // insertion failed.
+ return nullptr;
+
+ it = r.first;
+
+ if (!mrDoc.InitColumnBlockPosition(it->second, nTab, nCol))
+ return nullptr;
+
+ return &it->second;
+}
+
+void ColumnBlockPositionSet::clear()
+{
+ std::scoped_lock aGuard(maMtxTables);
+ maTables.clear();
+}
+
+struct TableColumnBlockPositionSet::Impl
+{
+ typedef std::unordered_map<SCCOL, ColumnBlockPosition> ColumnsType;
+
+ ScTable* mpTab;
+ ColumnsType maColumns;
+
+ Impl() : mpTab(nullptr) {}
+};
+
+TableColumnBlockPositionSet::TableColumnBlockPositionSet( ScDocument& rDoc, SCTAB nTab ) :
+ mpImpl(std::make_unique<Impl>())
+{
+ mpImpl->mpTab = rDoc.FetchTable(nTab);
+
+ if (!mpImpl->mpTab)
+ {
+ std::ostringstream os;
+ os << "Passed table index " << nTab << " is invalid.";
+ throw std::invalid_argument(os.str());
+ }
+}
+
+TableColumnBlockPositionSet::TableColumnBlockPositionSet( TableColumnBlockPositionSet&& rOther ) noexcept :
+ mpImpl(std::move(rOther.mpImpl)) {}
+
+TableColumnBlockPositionSet::~TableColumnBlockPositionSet() {}
+
+ColumnBlockPosition* TableColumnBlockPositionSet::getBlockPosition( SCCOL nCol )
+{
+ using ColumnsType = Impl::ColumnsType;
+
+ ColumnsType::iterator it = mpImpl->maColumns.find(nCol);
+
+ if (it != mpImpl->maColumns.end())
+ // Block position for this column has already been fetched.
+ return &it->second;
+
+ std::pair<ColumnsType::iterator,bool> r =
+ mpImpl->maColumns.emplace(nCol, ColumnBlockPosition());
+
+ if (!r.second)
+ // insertion failed.
+ return nullptr;
+
+ it = r.first;
+
+ if (!mpImpl->mpTab->InitColumnBlockPosition(it->second, nCol))
+ return nullptr;
+
+ return &it->second;
+}
+
+void TableColumnBlockPositionSet::invalidate()
+{
+ mpImpl->maColumns.clear();
+}
+
+ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset )
+{
+ switch (itPos->type)
+ {
+ case sc::element_type_numeric:
+ // Numeric cell
+ return ScRefCellValue(sc::numeric_block::at(*itPos->data, nOffset));
+ case sc::element_type_string:
+ // String cell
+ return ScRefCellValue(&sc::string_block::at(*itPos->data, nOffset));
+ case sc::element_type_edittext:
+ // Edit cell
+ return ScRefCellValue(sc::edittext_block::at(*itPos->data, nOffset));
+ case sc::element_type_formula:
+ // Formula cell
+ return ScRefCellValue(sc::formula_block::at(*itPos->data, nOffset));
+ default:
+ ;
+ }
+
+ return ScRefCellValue();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */