LibreOffice Module sc (master)  1
TableFillingAndNavigationTools.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  *
9  */
10 
11 #include <memory>
12 
13 #include <editeng/editobj.hxx>
14 #include <editeng/wghtitem.hxx>
15 #include <editeng/eeitem.hxx>
16 
17 #include <editutil.hxx>
18 
20 #include <formulacell.hxx>
21 #include <docfunc.hxx>
22 #include <docsh.hxx>
23 
25  : mpDoc(pDoc)
26  , mbUse3D(true)
27 {}
28 
29 void FormulaTemplate::setTemplate(const OUString& aTemplate)
30 {
31  mTemplate = aTemplate;
32 }
33 
34 void FormulaTemplate::setTemplate(const char* aTemplate)
35 {
36  mTemplate = OUString::createFromAscii(aTemplate);
37 }
38 
40 {
41  for (const auto& [rVariable, rRange] : mRangeReplacementMap)
42  {
43  applyRange(rVariable, rRange, mbUse3D);
44  }
45  for (const auto& [rVariable, rAddress] : mAddressReplacementMap)
46  {
47  applyAddress(rVariable, rAddress, mbUse3D);
48  }
49  return mTemplate;
50 }
51 
52 void FormulaTemplate::autoReplaceRange(const OUString& aVariable, const ScRange& rRange)
53 {
54  mRangeReplacementMap[aVariable] = rRange;
55 }
56 
57 void FormulaTemplate::autoReplaceAddress(const OUString& aVariable, ScAddress const & aAddress)
58 {
59 
60  mAddressReplacementMap[aVariable] = aAddress;
61 }
62 
63 void FormulaTemplate::applyRange(std::u16string_view aVariable, const ScRange& aRange, bool b3D)
64 {
66  OUString aString = aRange.Format(*mpDoc, nFlag, mpDoc->GetAddressConvention());
67  mTemplate = mTemplate.replaceAll(aVariable, aString);
68 }
69 
70 void FormulaTemplate::applyRangeList(std::u16string_view aVariable, const ScRangeList& aRangeList, sal_Unicode cDelimiter)
71 {
72  OUString aString;
74  mTemplate = mTemplate.replaceAll(aVariable, aString);
75 }
76 
77 void FormulaTemplate::applyAddress(std::u16string_view aVariable, const ScAddress& aAddress, bool b3D)
78 {
80  OUString aString = aAddress.Format(nFlag, mpDoc, mpDoc->GetAddressConvention());
81  mTemplate = mTemplate.replaceAll(aVariable, aString);
82 }
83 
84 void FormulaTemplate::applyString(std::u16string_view aVariable, std::u16string_view aValue)
85 {
86  mTemplate = mTemplate.replaceAll(aVariable, aValue);
87 }
88 
89 void FormulaTemplate::applyNumber(std::u16string_view aVariable, sal_Int32 aValue)
90 {
91  mTemplate = mTemplate.replaceAll(aVariable, OUString::number(aValue));
92 }
93 
94 AddressWalker::AddressWalker(const ScAddress& aInitialAddress) :
95  mCurrentAddress(aInitialAddress),
96  mMinimumAddress(aInitialAddress),
97  mMaximumAddress(aInitialAddress)
98 {
99  mAddressStack.push_back(mCurrentAddress);
100 }
101 
103 {
104  mCurrentAddress.SetCol(mAddressStack.back().Col());
105 }
106 
108 {
109  mCurrentAddress.SetRow(mAddressStack.back().Row());
110 }
111 
113 {
115 }
116 
118 {
119  resetColumn();
120  nextRow();
121 }
122 
124 {
125  return ScAddress(
126  mCurrentAddress.Col() + aRelCol,
127  mCurrentAddress.Row() + aRelRow,
128  mCurrentAddress.Tab() + aRelTab);
129 }
130 
132 {
134 
137 }
138 
140 {
144 }
145 
146 void AddressWalker::push(SCCOL aRelativeCol, SCROW aRelativeRow, SCTAB aRelativeTab)
147 {
148  mCurrentAddress = current(aRelativeCol, aRelativeRow, aRelativeTab);
149  mAddressStack.push_back(mCurrentAddress);
150 }
151 
152 AddressWalkerWriter::AddressWalkerWriter(const ScAddress& aInitialAddress, ScDocShell* pDocShell, ScDocument& rDocument,
154  AddressWalker(aInitialAddress),
155  mpDocShell(pDocShell),
156  mrDocument(rDocument),
157  meGrammar(eGrammar)
158 {}
159 
160 void AddressWalkerWriter::writeFormula(const OUString& aFormula)
161 {
163  new ScFormulaCell(mrDocument, mCurrentAddress, aFormula, meGrammar), true);
164 }
165 
166 void AddressWalkerWriter::writeFormulas(const std::vector<OUString>& rFormulas)
167 {
168  size_t nLength = rFormulas.size();
169  if (!nLength)
170  return;
171 
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;
176 
177  std::vector<ScFormulaCell*> aFormulaCells(nLength);
178  ScAddress aAddr(mCurrentAddress);
179  for (size_t nIdx = 0; nIdx < nLength; ++nIdx)
180  {
181  aFormulaCells[nIdx] = new ScFormulaCell(mrDocument, aAddr, rFormulas[nIdx], meGrammar);
182  aAddr.IncRow(1);
183  }
184 
185  mpDocShell->GetDocFunc().SetFormulaCells(mCurrentAddress, aFormulaCells, true);
186 }
187 
188 void AddressWalkerWriter::writeMatrixFormula(const OUString& aFormula, SCCOL nCols, SCROW nRows)
189 {
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 );
198 }
199 
200 void AddressWalkerWriter::writeString(const OUString& aString)
201 {
203 }
204 
205 void AddressWalkerWriter::writeString(const char* aCharArray)
206 {
207  writeString(OUString::createFromAscii(aCharArray));
208 }
209 
210 void AddressWalkerWriter::writeBoldString(const OUString& aString)
211 {
213  rEngine.SetTextCurrentDefaults(aString);
214  SfxItemSet aItemSet = rEngine.GetEmptyItemSet();
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);
220 }
221 
223 {
225 }
226 
227 // DataCellIterator
228 
229 DataCellIterator::DataCellIterator(const ScRange& aInputRange, bool aByColumn)
230  : mInputRange(aInputRange)
231  , mByColumn(aByColumn)
232  , mCol(0)
233  , mRow(0)
234 {
235  if(aByColumn)
236  mCol = aInputRange.aStart.Col();
237  else
238  mRow = aInputRange.aStart.Row();
239 }
240 
242 {
243  if(mByColumn)
244  return mCol <= mInputRange.aEnd.Col();
245  else
246  return mRow <= mInputRange.aEnd.Row();
247 }
248 
250 {
251  if(mByColumn)
252  mCol++;
253  else
254  mRow++;
255 }
256 
258 {
259  return getRelative(0);
260 }
261 
263 {
264  if(mByColumn)
265  {
266  SCCOL aNewColumn = mCol + aDelta;
267  if(aNewColumn < mInputRange.aStart.Col() || aNewColumn > mInputRange.aEnd.Col())
268  {
269  ScAddress aResult;
270  aResult.SetInvalid();
271  return aResult;
272  }
273  return ScAddress(aNewColumn, mInputRange.aStart.Row(), mInputRange.aStart.Tab());
274  }
275  else
276  {
277  SCROW aNewRow = mRow + aDelta;
278  if(aNewRow < mInputRange.aStart.Row() || aNewRow > mInputRange.aEnd.Row())
279  {
280  ScAddress aResult;
281  aResult.SetInvalid();
282  return aResult;
283  }
284  return ScAddress(mInputRange.aStart.Col(), aNewRow, mInputRange.aStart.Tab());
285  }
286 }
287 
288 // DataRangeIterator
289 
291  mInputRange(aInputRange),
292  mIndex(0)
293 {}
294 
296 {}
297 
299 {
300  return mIndex;
301 }
302 
303 // DataRangeByColumnIterator
304 
306  : DataRangeIterator(aInputRange)
307  , mCol(aInputRange.aStart.Col())
308 {}
309 
311 {
312  return mCol <= mInputRange.aEnd.Col();
313 }
314 
316 {
317  mCol++;
318  mIndex++;
319 }
320 
322 {
323  return ScRange(
326  );
327 }
328 
330 {
331  return mInputRange.aEnd.Row() - mInputRange.aStart.Row() + 1;
332 }
333 
335 {
337 }
338 
340 {
341  return DataCellIterator(get(), false);
342 }
343 
344 // DataRangeByRowIterator
345 
347  : DataRangeIterator(aInputRange)
348  , mRow(aInputRange.aStart.Row())
349 {}
350 
352 {
353  return mRow <= mInputRange.aEnd.Row();
354 }
355 
357 {
358  mRow++;
359  mIndex++;
360 }
361 
363 {
364  return ScRange(
367  );
368 }
369 
371 {
372  return mInputRange.aEnd.Col() - mInputRange.aStart.Col() + 1;
373 }
374 
376 {
378 }
379 
381 {
382  return DataCellIterator(get(), true);
383 }
384 
385 
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
void applyAddress(std::u16string_view aVariable, const ScAddress &aAddress, bool b3D=true)
ScAddress aStart
Definition: address.hxx:497
void writeFormula(const OUString &aFormula)
SCROW Row() const
Definition: address.hxx:274
ScAddress getRelative(int aDelta)
std::vector< ScAddress > mAddressStack
const SfxItemSet & GetEmptyItemSet() const
bool SetStringCell(const ScAddress &rPos, const OUString &rStr, bool bInteraction)
Definition: docfunc.cxx:936
void Format(OUString &, ScRefFlags nFlags, const ScDocument &, formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_OOO, sal_Unicode cDelimiter=0, bool bFullAddressNotation=false) const
Definition: rangelst.cxx:132
void writeString(const OUString &aString)
void applyRange(std::u16string_view aVariable, const ScRange &aRange, bool b3D=true)
ScAddress aEnd
Definition: address.hxx:498
const sal_Unicode cDelimiter
Definition: tpusrlst.cxx:45
RangeReplacementMap mRangeReplacementMap
AddressWalkerWriter(const ScAddress &aInitialAddress, ScDocShell *pDocShell, ScDocument &rDocument, formula::FormulaGrammar::Grammar eGrammar)
void push(SCCOL aRelativeCol=0, SCROW aRelativeRow=0, SCTAB aRelativeTab=0)
virtual DataCellIterator iterateCells() override
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:494
DataRangeByRowIterator(const ScRange &aInputRange)
WEIGHT_BOLD
sal_uInt16 sal_Unicode
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:891
void writeBoldString(const OUString &aString)
void writeMatrixFormula(const OUString &aFormula, SCCOL nCols=1, SCROW nRows=1)
SCTAB Tab() const
Definition: address.hxx:283
void SetRow(SCROW nRowP)
Definition: address.hxx:287
bool SetEditCell(const ScAddress &rPos, const EditTextObject &rStr, bool bInteraction)
Definition: docfunc.cxx:973
void SetCol(SCCOL nColP)
Definition: address.hxx:291
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT(EE_CHAR_START+4)
formula::FormulaGrammar::Grammar meGrammar
ScAddress current(SCCOL aRelativeCol=0, SCROW aRelativeRow=0, SCTAB aRelativeTab=0)
bool SetValueCell(const ScAddress &rPos, double fVal, bool bInteraction)
Definition: docfunc.cxx:867
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:616
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:316
sal_Int16 SCCOL
Definition: types.hxx:21
OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2170
std::unique_ptr< EditTextObject > CreateTextObject()
void IncRow(SCROW nDelta=1)
Definition: address.hxx:312
DataRangeIterator(const ScRange &aInputRange)
void applyRangeList(std::u16string_view aVariable, const ScRangeList &aRangeList, sal_Unicode cDelimiter)
void autoReplaceRange(const OUString &aVariable, const ScRange &rRange)
AddressWalker(const ScAddress &aInitialAddress)
SCCOL Col() const
Definition: address.hxx:279
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:17
bool SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell, bool bInteraction)
Below two methods take ownership of the formula cell instance(s).
Definition: docfunc.cxx:1023
void autoReplaceAddress(const OUString &aVariable, ScAddress const &aAddress)
bool SetFormulaCells(const ScAddress &rPos, std::vector< ScFormulaCell * > &rCells, bool bInteraction)
Definition: docfunc.cxx:1072
SC_DLLPUBLIC bool EnterMatrix(const ScRange &rRange, const ScMarkData *pTabMark, const ScTokenArray *pTokenArray, const OUString &rString, bool bApi, bool bEnglish, const OUString &rFormulaNmsp, const formula::FormulaGrammar::Grammar)
Definition: docfunc.cxx:4316
void QuickSetAttribs(const SfxItemSet &rSet, const ESelection &rSel)
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
void SetInvalid()
Definition: address.hxx:299
void applyNumber(std::u16string_view aVariable, sal_Int32 aValue)
virtual DataCellIterator iterateCells() override
void applyString(std::u16string_view aVariable, std::u16string_view aValue)
AddressReplacementMap mAddressReplacementMap
sal_Int32 nLength
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:222
ScRefFlags
Definition: address.hxx:157
void setTemplate(const OUString &aTemplate)
DataRangeByColumnIterator(const ScRange &aInputRange)
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:475
sal_Int16 SCTAB
Definition: types.hxx:22
DataCellIterator(const ScRange &aInputRange, bool aByColumn)
void writeFormulas(const std::vector< OUString > &rFormulas)