Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / sc / source / core / data / mtvelements.cxx
blob9f5399701d31dcc21b467f5bd747380c058540fe
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <mtvelements.hxx>
11 #include <document.hxx>
12 #include <cellvalue.hxx>
13 #include <column.hxx>
14 #include <table.hxx>
16 #include <sstream>
18 namespace sc {
20 CellStoreEvent::CellStoreEvent() : mpCol(nullptr) {}
22 CellStoreEvent::CellStoreEvent(ScColumn* pCol) : mpCol(pCol) {}
24 void CellStoreEvent::element_block_acquired(const mdds::mtv::base_element_block* block)
26 if (!mpCol)
27 return;
29 switch (mdds::mtv::get_block_type(*block))
31 case sc::element_type_formula:
32 ++mpCol->mnBlkCountFormula;
33 break;
34 case sc::element_type_cellnote:
35 ++mpCol->mnBlkCountCellNotes;
36 break;
37 default:
42 void CellStoreEvent::element_block_released(const mdds::mtv::base_element_block* block)
44 if (!mpCol)
45 return;
47 switch (mdds::mtv::get_block_type(*block))
49 case sc::element_type_formula:
50 --mpCol->mnBlkCountFormula;
51 break;
52 case sc::element_type_cellnote:
53 --mpCol->mnBlkCountCellNotes;
54 break;
55 default:
60 void CellStoreEvent::stop()
62 mpCol = nullptr;
65 void CellStoreEvent::swap(CellStoreEvent& other)
67 std::swap(mpCol, other.mpCol);
70 const ScColumn* CellStoreEvent::getColumn() const
72 return mpCol;
75 ColumnBlockPositionSet::ColumnBlockPositionSet(ScDocument& rDoc) : mrDoc(rDoc) {}
77 ColumnBlockPosition* ColumnBlockPositionSet::getBlockPosition(SCTAB nTab, SCCOL nCol)
79 std::scoped_lock aGuard(maMtxTables);
81 TablesType::iterator itTab = maTables.find(nTab);
82 if (itTab == maTables.end())
84 std::pair<TablesType::iterator,bool> r =
85 maTables.emplace(nTab, ColumnsType());
86 if (!r.second)
87 // insertion failed.
88 return nullptr;
90 itTab = r.first;
93 ColumnsType& rCols = itTab->second;
95 ColumnsType::iterator it = rCols.find(nCol);
96 if (it != rCols.end())
97 // Block position for this column has already been fetched.
98 return &it->second;
100 std::pair<ColumnsType::iterator,bool> r =
101 rCols.emplace(nCol, ColumnBlockPosition());
103 if (!r.second)
104 // insertion failed.
105 return nullptr;
107 it = r.first;
109 if (!mrDoc.InitColumnBlockPosition(it->second, nTab, nCol))
110 return nullptr;
112 return &it->second;
115 void ColumnBlockPositionSet::clear()
117 std::scoped_lock aGuard(maMtxTables);
118 maTables.clear();
121 struct TableColumnBlockPositionSet::Impl
123 typedef std::unordered_map<SCCOL, ColumnBlockPosition> ColumnsType;
125 ScTable* mpTab;
126 ColumnsType maColumns;
128 Impl() : mpTab(nullptr) {}
131 TableColumnBlockPositionSet::TableColumnBlockPositionSet( ScDocument& rDoc, SCTAB nTab ) :
132 mpImpl(std::make_unique<Impl>())
134 mpImpl->mpTab = rDoc.FetchTable(nTab);
136 if (!mpImpl->mpTab)
138 std::ostringstream os;
139 os << "Passed table index " << nTab << " is invalid.";
140 throw std::invalid_argument(os.str());
144 TableColumnBlockPositionSet::TableColumnBlockPositionSet( TableColumnBlockPositionSet&& rOther ) noexcept :
145 mpImpl(std::move(rOther.mpImpl)) {}
147 TableColumnBlockPositionSet::~TableColumnBlockPositionSet() {}
149 ColumnBlockPosition* TableColumnBlockPositionSet::getBlockPosition( SCCOL nCol )
151 using ColumnsType = Impl::ColumnsType;
153 ColumnsType::iterator it = mpImpl->maColumns.find(nCol);
155 if (it != mpImpl->maColumns.end())
156 // Block position for this column has already been fetched.
157 return &it->second;
159 std::pair<ColumnsType::iterator,bool> r =
160 mpImpl->maColumns.emplace(nCol, ColumnBlockPosition());
162 if (!r.second)
163 // insertion failed.
164 return nullptr;
166 it = r.first;
168 if (!mpImpl->mpTab->InitColumnBlockPosition(it->second, nCol))
169 return nullptr;
171 return &it->second;
174 void TableColumnBlockPositionSet::invalidate()
176 mpImpl->maColumns.clear();
179 ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset )
181 switch (itPos->type)
183 case sc::element_type_numeric:
184 // Numeric cell
185 return ScRefCellValue(sc::numeric_block::get_value(*itPos->data, nOffset));
186 case sc::element_type_string:
187 // String cell
188 return ScRefCellValue(&sc::string_block::at(*itPos->data, nOffset));
189 case sc::element_type_edittext:
190 // Edit cell
191 return ScRefCellValue(sc::edittext_block::get_value(*itPos->data, nOffset));
192 case sc::element_type_formula:
193 // Formula cell
194 return ScRefCellValue(sc::formula_block::get_value(*itPos->data, nOffset));
195 default:
199 return ScRefCellValue();
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */