tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / StatisticsDialogs / TableFillingAndNavigationTools.cxx
blobbe843112859ab2fe456e56e94cf48436d605c407
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/.
9 */
11 #include <memory>
13 #include <editeng/editobj.hxx>
14 #include <editeng/wghtitem.hxx>
15 #include <editeng/eeitem.hxx>
17 #include <editutil.hxx>
19 #include <TableFillingAndNavigationTools.hxx>
20 #include <formulacell.hxx>
21 #include <docfunc.hxx>
22 #include <docsh.hxx>
24 FormulaTemplate::FormulaTemplate(ScDocument* pDoc)
25 : mpDoc(pDoc)
26 , mbUse3D(true)
29 void FormulaTemplate::setTemplate(const OUString& aTemplate)
31 mTemplate = aTemplate;
34 void FormulaTemplate::setTemplate(const char* aTemplate)
36 mTemplate = OUString::createFromAscii(aTemplate);
39 const OUString& FormulaTemplate::getTemplate()
41 for (const auto& [rVariable, rRange] : mRangeReplacementMap)
43 applyRange(rVariable, rRange, mbUse3D);
45 for (const auto& [rVariable, rAddress] : mAddressReplacementMap)
47 applyAddress(rVariable, rAddress, mbUse3D);
49 return mTemplate;
52 void FormulaTemplate::autoReplaceRange(const OUString& aVariable, const ScRange& rRange)
54 mRangeReplacementMap[aVariable] = rRange;
57 void FormulaTemplate::autoReplaceAddress(const OUString& aVariable, ScAddress const & aAddress)
60 mAddressReplacementMap[aVariable] = aAddress;
63 void FormulaTemplate::applyRange(std::u16string_view aVariable, const ScRange& aRange, bool b3D)
65 ScRefFlags nFlag = b3D ? ScRefFlags::RANGE_ABS_3D : ScRefFlags::RANGE_ABS;
66 OUString aString = aRange.Format(*mpDoc, nFlag, mpDoc->GetAddressConvention());
67 mTemplate = mTemplate.replaceAll(aVariable, aString);
70 void FormulaTemplate::applyRangeList(std::u16string_view aVariable, const ScRangeList& aRangeList, sal_Unicode cDelimiter)
72 OUString aString;
73 aRangeList.Format(aString, ScRefFlags::RANGE_ABS_3D, *mpDoc, mpDoc->GetAddressConvention(), cDelimiter);
74 mTemplate = mTemplate.replaceAll(aVariable, aString);
77 void FormulaTemplate::applyAddress(std::u16string_view aVariable, const ScAddress& aAddress, bool b3D)
79 ScRefFlags nFlag = b3D ? ScRefFlags::ADDR_ABS_3D : ScRefFlags::ADDR_ABS;
80 OUString aString = aAddress.Format(nFlag, mpDoc, mpDoc->GetAddressConvention());
81 mTemplate = mTemplate.replaceAll(aVariable, aString);
84 void FormulaTemplate::applyString(std::u16string_view aVariable, std::u16string_view aValue)
86 mTemplate = mTemplate.replaceAll(aVariable, aValue);
89 void FormulaTemplate::applyNumber(std::u16string_view aVariable, sal_Int32 aValue)
91 mTemplate = mTemplate.replaceAll(aVariable, OUString::number(aValue));
94 AddressWalker::AddressWalker(const ScAddress& aInitialAddress) :
95 mCurrentAddress(aInitialAddress),
96 mMinimumAddress(aInitialAddress),
97 mMaximumAddress(aInitialAddress)
99 mAddressStack.push_back(mCurrentAddress);
102 void AddressWalker::resetColumn()
104 mCurrentAddress.SetCol(mAddressStack.back().Col());
107 void AddressWalker::resetRow()
109 mCurrentAddress.SetRow(mAddressStack.back().Row());
112 void AddressWalker::reset()
114 mCurrentAddress = mAddressStack.back();
117 void AddressWalker::newLine()
119 resetColumn();
120 nextRow();
123 ScAddress AddressWalker::current(SCCOL aRelCol, SCROW aRelRow, SCTAB aRelTab)
125 return ScAddress(
126 mCurrentAddress.Col() + aRelCol,
127 mCurrentAddress.Row() + aRelRow,
128 mCurrentAddress.Tab() + aRelTab);
131 void AddressWalker::nextColumn()
133 mCurrentAddress.IncCol();
135 if(mMaximumAddress.Col() < mCurrentAddress.Col())
136 mMaximumAddress.SetCol(mCurrentAddress.Col());
139 void AddressWalker::nextRow()
141 mCurrentAddress.IncRow();
142 if(mMaximumAddress.Row() < mCurrentAddress.Row())
143 mMaximumAddress.SetRow(mCurrentAddress.Row());
146 void AddressWalker::push(SCCOL aRelativeCol, SCROW aRelativeRow, SCTAB aRelativeTab)
148 mCurrentAddress = current(aRelativeCol, aRelativeRow, aRelativeTab);
149 mAddressStack.push_back(mCurrentAddress);
152 AddressWalkerWriter::AddressWalkerWriter(const ScAddress& aInitialAddress, ScDocShell* pDocShell, ScDocument& rDocument,
153 formula::FormulaGrammar::Grammar eGrammar ) :
154 AddressWalker(aInitialAddress),
155 mpDocShell(pDocShell),
156 mrDocument(rDocument),
157 meGrammar(eGrammar)
160 void AddressWalkerWriter::writeFormula(const OUString& aFormula)
162 mpDocShell->GetDocFunc().SetFormulaCell(mCurrentAddress,
163 new ScFormulaCell(mrDocument, mCurrentAddress, aFormula, meGrammar), true);
166 void AddressWalkerWriter::writeFormulas(const std::vector<OUString>& rFormulas)
168 size_t nLength = rFormulas.size();
169 if (!nLength)
170 return;
172 const size_t nMaxLen = mpDocShell->GetDocument().MaxRow() - mCurrentAddress.Row() + 1;
173 // If not done already, trim the length to fit.
174 if (nLength > nMaxLen)
175 nLength = nMaxLen;
177 std::vector<ScFormulaCell*> aFormulaCells(nLength);
178 ScAddress aAddr(mCurrentAddress);
179 for (size_t nIdx = 0; nIdx < nLength; ++nIdx)
181 aFormulaCells[nIdx] = new ScFormulaCell(mrDocument, aAddr, rFormulas[nIdx], meGrammar);
182 aAddr.IncRow(1);
185 mpDocShell->GetDocFunc().SetFormulaCells(mCurrentAddress, aFormulaCells, true);
188 void AddressWalkerWriter::writeMatrixFormula(const OUString& aFormula, SCCOL nCols, SCROW nRows)
190 ScRange aRange;
191 aRange.aStart = mCurrentAddress;
192 aRange.aEnd = mCurrentAddress;
193 if (nCols > 1)
194 aRange.aEnd.IncCol(nCols - 1);
195 if (nRows > 1)
196 aRange.aEnd.IncRow(nRows - 1);
197 mpDocShell->GetDocFunc().EnterMatrix(aRange, nullptr, nullptr, aFormula, false, false, OUString(), meGrammar );
200 void AddressWalkerWriter::writeString(const OUString& aString)
202 mpDocShell->GetDocFunc().SetStringCell(mCurrentAddress, aString, true);
205 void AddressWalkerWriter::writeString(const char* aCharArray)
207 writeString(OUString::createFromAscii(aCharArray));
210 void AddressWalkerWriter::writeBoldString(const OUString& aString)
212 ScFieldEditEngine& rEngine = mrDocument.GetEditEngine();
213 rEngine.SetTextCurrentDefaults(aString);
214 SfxItemSet aItemSet = rEngine.GetEmptyItemSet();
215 SvxWeightItem aWeight(WEIGHT_BOLD, EE_CHAR_WEIGHT);
216 aItemSet.Put(aWeight);
217 rEngine.QuickSetAttribs(aItemSet, ESelection(0, 0, 0, aString.getLength()) );
218 std::unique_ptr<EditTextObject> pEditText(rEngine.CreateTextObject());
219 mpDocShell->GetDocFunc().SetEditCell(mCurrentAddress, *pEditText, true);
222 void AddressWalkerWriter::writeValue(double aValue)
224 mpDocShell->GetDocFunc().SetValueCell(mCurrentAddress, aValue, true);
227 // DataCellIterator
229 DataCellIterator::DataCellIterator(const ScRange& aInputRange, bool aByColumn)
230 : mInputRange(aInputRange)
231 , mByColumn(aByColumn)
232 , mCol(0)
233 , mRow(0)
235 if(aByColumn)
236 mCol = aInputRange.aStart.Col();
237 else
238 mRow = aInputRange.aStart.Row();
241 bool DataCellIterator::hasNext() const
243 if(mByColumn)
244 return mCol <= mInputRange.aEnd.Col();
245 else
246 return mRow <= mInputRange.aEnd.Row();
249 void DataCellIterator::next()
251 if(mByColumn)
252 mCol++;
253 else
254 mRow++;
257 ScAddress DataCellIterator::get()
259 return getRelative(0);
262 ScAddress DataCellIterator::getRelative(int aDelta)
264 if(mByColumn)
266 SCCOL aNewColumn = mCol + aDelta;
267 if(aNewColumn < mInputRange.aStart.Col() || aNewColumn > mInputRange.aEnd.Col())
269 ScAddress aResult;
270 aResult.SetInvalid();
271 return aResult;
273 return ScAddress(aNewColumn, mInputRange.aStart.Row(), mInputRange.aStart.Tab());
275 else
277 SCROW aNewRow = mRow + aDelta;
278 if(aNewRow < mInputRange.aStart.Row() || aNewRow > mInputRange.aEnd.Row())
280 ScAddress aResult;
281 aResult.SetInvalid();
282 return aResult;
284 return ScAddress(mInputRange.aStart.Col(), aNewRow, mInputRange.aStart.Tab());
288 // DataRangeIterator
290 DataRangeIterator::DataRangeIterator(const ScRange& aInputRange) :
291 mInputRange(aInputRange),
292 mIndex(0)
295 DataRangeIterator::~DataRangeIterator()
298 sal_Int32 DataRangeIterator::index()
300 return mIndex;
303 // DataRangeByColumnIterator
305 DataRangeByColumnIterator::DataRangeByColumnIterator(const ScRange& aInputRange)
306 : DataRangeIterator(aInputRange)
307 , mCol(aInputRange.aStart.Col())
310 bool DataRangeByColumnIterator::hasNext()
312 return mCol <= mInputRange.aEnd.Col();
315 void DataRangeByColumnIterator::next()
317 mCol++;
318 mIndex++;
321 ScRange DataRangeByColumnIterator::get()
323 return ScRange(
324 ScAddress(mCol, mInputRange.aStart.Row(), mInputRange.aStart.Tab()),
325 ScAddress(mCol, mInputRange.aEnd.Row(), mInputRange.aEnd.Tab())
329 size_t DataRangeByColumnIterator::size()
331 return mInputRange.aEnd.Row() - mInputRange.aStart.Row() + 1;
334 void DataRangeByColumnIterator::reset()
336 mCol = mInputRange.aStart.Col();
339 DataCellIterator DataRangeByColumnIterator::iterateCells()
341 return DataCellIterator(get(), false);
344 // DataRangeByRowIterator
346 DataRangeByRowIterator::DataRangeByRowIterator(const ScRange& aInputRange)
347 : DataRangeIterator(aInputRange)
348 , mRow(aInputRange.aStart.Row())
351 bool DataRangeByRowIterator::hasNext()
353 return mRow <= mInputRange.aEnd.Row();
356 void DataRangeByRowIterator::next()
358 mRow++;
359 mIndex++;
362 ScRange DataRangeByRowIterator::get()
364 return ScRange(
365 ScAddress(mInputRange.aStart.Col(), mRow, mInputRange.aStart.Tab()),
366 ScAddress(mInputRange.aEnd.Col(), mRow, mInputRange.aEnd.Tab())
370 size_t DataRangeByRowIterator::size()
372 return mInputRange.aEnd.Col() - mInputRange.aStart.Col() + 1;
375 void DataRangeByRowIterator::reset()
377 mRow = mInputRange.aStart.Row();
380 DataCellIterator DataRangeByRowIterator::iterateCells()
382 return DataCellIterator(get(), true);
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */