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(const OUString& 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(const OUString& aVariable, const ScRangeList& aRangeList, sal_Unicode cDelimiter)
71 {
72  OUString aString;
74  mTemplate = mTemplate.replaceAll(aVariable, aString);
75 }
76 
77 void FormulaTemplate::applyAddress(const OUString& 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(const OUString& aVariable, const OUString& aValue)
85 {
86  mTemplate = mTemplate.replaceAll(aVariable, aValue);
87 }
88 
89 void FormulaTemplate::applyNumber(const OUString& 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* pDocument,
154  AddressWalker(aInitialAddress),
155  mpDocShell(pDocShell),
156  mpDocument(pDocument),
157  meGrammar(eGrammar)
158 {}
159 
160 void AddressWalkerWriter::writeFormula(const OUString& aFormula)
161 {
163  new ScFormulaCell(mpDocument, 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 = 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(mpDocument, 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 
245 {
246  if(mByColumn)
247  return mCol <= mInputRange.aEnd.Col();
248  else
249  return mRow <= mInputRange.aEnd.Row();
250 }
251 
253 {
254  if(mByColumn)
255  mCol++;
256  else
257  mRow++;
258 }
259 
261 {
262  return getRelative(0);
263 }
264 
266 {
267  if(mByColumn)
268  {
269  SCCOL aNewColumn = mCol + aDelta;
270  if(aNewColumn < mInputRange.aStart.Col() || aNewColumn > mInputRange.aEnd.Col())
271  {
272  ScAddress aResult;
273  aResult.SetInvalid();
274  return aResult;
275  }
276  return ScAddress(aNewColumn, mInputRange.aStart.Row(), mInputRange.aStart.Tab());
277  }
278  else
279  {
280  SCROW aNewRow = mRow + aDelta;
281  if(aNewRow < mInputRange.aStart.Row() || aNewRow > mInputRange.aEnd.Row())
282  {
283  ScAddress aResult;
284  aResult.SetInvalid();
285  return aResult;
286  }
287  return ScAddress(mInputRange.aStart.Col(), aNewRow, mInputRange.aStart.Tab());
288  }
289 }
290 
291 // DataRangeIterator
292 
294  mInputRange(aInputRange),
295  mIndex(0)
296 {}
297 
299 {}
300 
302 {
303  return mIndex;
304 }
305 
306 // DataRangeByColumnIterator
307 
309  : DataRangeIterator(aInputRange)
310  , mCol(aInputRange.aStart.Col())
311 {}
312 
314 {
315  return mCol <= mInputRange.aEnd.Col();
316 }
317 
319 {
320  mCol++;
321  mIndex++;
322 }
323 
325 {
326  return ScRange(
329  );
330 }
331 
333 {
334  return mInputRange.aEnd.Row() - mInputRange.aStart.Row() + 1;
335 }
336 
338 {
340 }
341 
343 {
344  return DataCellIterator(get(), false);
345 }
346 
347 // DataRangeByRowIterator
348 
350  : DataRangeIterator(aInputRange)
351  , mRow(aInputRange.aStart.Row())
352 {}
353 
355 {
356  return mRow <= mInputRange.aEnd.Row();
357 }
358 
360 {
361  mRow++;
362  mIndex++;
363 }
364 
366 {
367  return ScRange(
370  );
371 }
372 
374 {
375  return mInputRange.aEnd.Col() - mInputRange.aStart.Col() + 1;
376 }
377 
379 {
381 }
382 
384 {
385  return DataCellIterator(get(), true);
386 }
387 
388 
389 /* 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:2111
void applyNumber(const OUString &aVariable, sal_Int32 aValue)
ScAddress aStart
Definition: address.hxx:500
void writeFormula(const OUString &aFormula)
SCROW Row() const
Definition: address.hxx:262
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:914
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:146
void writeString(const OUString &aString)
ScAddress aEnd
Definition: address.hxx:501
const sal_Unicode cDelimiter
Definition: tpusrlst.cxx:44
RangeReplacementMap mRangeReplacementMap
AddressWalkerWriter(const ScAddress &aInitialAddress, ScDocShell *pDocShell, ScDocument *pDocument, formula::FormulaGrammar::Grammar eGrammar)
void applyRangeList(const OUString &aVariable, const ScRangeList &aRangeList, sal_Unicode cDelimiter)
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:475
DataRangeByRowIterator(const ScRange &aInputRange)
WEIGHT_BOLD
sal_uInt16 sal_Unicode
void writeBoldString(const OUString &aString)
void writeMatrixFormula(const OUString &aFormula, SCCOL nCols=1, SCROW nRows=1)
const SCROW MAXROW
Definition: address.hxx:69
SCTAB Tab() const
Definition: address.hxx:271
void SetRow(SCROW nRowP)
Definition: address.hxx:275
bool SetEditCell(const ScAddress &rPos, const EditTextObject &rStr, bool bInteraction)
Definition: docfunc.cxx:951
void SetCol(SCCOL nColP)
Definition: address.hxx:279
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:845
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:559
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:304
sal_Int16 SCCOL
Definition: types.hxx:22
SC_DLLPUBLIC 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:2207
std::unique_ptr< EditTextObject > CreateTextObject()
void IncRow(SCROW nDelta=1)
Definition: address.hxx:300
void applyAddress(const OUString &aVariable, const ScAddress &aAddress, bool b3D=true)
DataRangeIterator(const ScRange &aInputRange)
void applyRange(const OUString &aVariable, const ScRange &aRange, bool b3D=true)
void autoReplaceRange(const OUString &aVariable, const ScRange &rRange)
AddressWalker(const ScAddress &aInitialAddress)
SCCOL Col() const
Definition: address.hxx:267
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:18
bool SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell, bool bInteraction)
Below two methods take ownership of the formula cell instance(s).
Definition: docfunc.cxx:1001
void autoReplaceAddress(const OUString &aVariable, ScAddress const &aAddress)
bool SetFormulaCells(const ScAddress &rPos, std::vector< ScFormulaCell * > &rCells, bool bInteraction)
Definition: docfunc.cxx:1050
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:4310
void QuickSetAttribs(const SfxItemSet &rSet, const ESelection &rSel)
void SetInvalid()
Definition: address.hxx:287
virtual DataCellIterator iterateCells() override
void applyString(const OUString &aVariable, const OUString &aValue)
AddressReplacementMap mAddressReplacementMap
sal_Int32 nLength
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:218
ScRefFlags
Definition: address.hxx:145
void setTemplate(const OUString &aTemplate)
DataRangeByColumnIterator(const ScRange &aInputRange)
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:454
sal_Int16 SCTAB
Definition: types.hxx:23
DataCellIterator(const ScRange &aInputRange, bool aByColumn)
void writeFormulas(const std::vector< OUString > &rFormulas)