Line data Source code
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 <boost/scoped_ptr.hpp>
12 :
13 : #include <editeng/editobj.hxx>
14 : #include <editeng/wghtitem.hxx>
15 : #include <editeng/eeitem.hxx>
16 :
17 : #include "editutil.hxx"
18 :
19 : #include "TableFillingAndNavigationTools.hxx"
20 :
21 0 : FormulaTemplate::FormulaTemplate(ScDocument* pDoc) : mpDoc(pDoc) {}
22 :
23 0 : void FormulaTemplate::setTemplate(const OUString& aTemplate)
24 : {
25 0 : mTemplate = aTemplate;
26 0 : }
27 :
28 0 : void FormulaTemplate::setTemplate(const char* aTemplate)
29 : {
30 0 : mTemplate = OUString::createFromAscii(aTemplate);
31 0 : }
32 :
33 0 : const OUString& FormulaTemplate::getTemplate()
34 : {
35 0 : RangeReplacementMap::iterator itRange;
36 0 : for (itRange = mRangeReplacementMap.begin(); itRange != mRangeReplacementMap.end(); ++itRange)
37 : {
38 0 : applyRange(itRange->first, itRange->second);
39 : }
40 0 : AddressReplacementMap::iterator itAddress;
41 0 : for (itAddress = mAddressReplacementMap.begin(); itAddress != mAddressReplacementMap.end(); ++itAddress)
42 : {
43 0 : applyAddress(itAddress->first, itAddress->second);
44 : }
45 0 : return mTemplate;
46 : }
47 :
48 0 : void FormulaTemplate::autoReplaceRange(const OUString& aVariable, const ScRange& rRange)
49 : {
50 0 : mRangeReplacementMap.insert ( std::pair<OUString, ScRange>(aVariable, rRange) );
51 0 : }
52 :
53 0 : void FormulaTemplate::autoReplaceAddress(const OUString& aVariable, ScAddress aAddress)
54 : {
55 0 : mAddressReplacementMap.insert ( std::pair<OUString, ScAddress>(aVariable, aAddress) );
56 0 : }
57 :
58 0 : void FormulaTemplate::applyRange(const OUString& aVariable, const ScRange& aRange, bool b3D)
59 : {
60 0 : sal_uInt16 nFlag = b3D ? SCR_ABS_3D : SCR_ABS;
61 0 : OUString aString = aRange.Format(nFlag, mpDoc, mpDoc->GetAddressConvention());
62 0 : mTemplate = mTemplate.replaceAll(aVariable, aString);
63 0 : }
64 :
65 0 : void FormulaTemplate::applyRangeList(const OUString& aVariable, const ScRangeList& aRangeList, bool b3D)
66 : {
67 0 : sal_uInt16 nFlag = b3D ? SCR_ABS_3D : SCR_ABS;
68 0 : OUString aString;
69 0 : aRangeList.Format(aString, nFlag, mpDoc, mpDoc->GetAddressConvention());
70 0 : mTemplate = mTemplate.replaceAll(aVariable, aString);
71 0 : }
72 :
73 0 : void FormulaTemplate::applyAddress(const OUString& aVariable, const ScAddress& aAddress, bool b3D)
74 : {
75 0 : sal_uInt16 nFlag = b3D ? SCA_ABS_3D : SCA_ABS;
76 0 : OUString aString = aAddress.Format(nFlag, mpDoc, mpDoc->GetAddressConvention());
77 0 : mTemplate = mTemplate.replaceAll(aVariable, aString);
78 0 : }
79 :
80 0 : void FormulaTemplate::applyString(const OUString& aVariable, const OUString& aValue)
81 : {
82 0 : mTemplate = mTemplate.replaceAll(aVariable, aValue);
83 0 : }
84 :
85 0 : void FormulaTemplate::applyNumber(const OUString& aVariable, sal_Int32 aValue)
86 : {
87 0 : mTemplate = mTemplate.replaceAll(aVariable, OUString::number(aValue));
88 0 : }
89 :
90 0 : AddressWalker::AddressWalker(ScAddress aInitialAddress, bool aTrackRange) :
91 : mCurrentAddress(aInitialAddress),
92 : mMinimumAddress(aInitialAddress),
93 : mMaximumAddress(aInitialAddress),
94 0 : mTrackRange(aTrackRange)
95 : {
96 0 : mAddressStack.push_back(mCurrentAddress);
97 0 : }
98 :
99 0 : void AddressWalker::resetColumn()
100 : {
101 0 : mCurrentAddress.SetCol(mAddressStack.back().Col());
102 0 : }
103 :
104 0 : void AddressWalker::resetRow()
105 : {
106 0 : mCurrentAddress.SetRow(mAddressStack.back().Row());
107 0 : }
108 :
109 0 : void AddressWalker::reset()
110 : {
111 0 : mCurrentAddress = mAddressStack.back();
112 0 : }
113 :
114 0 : void AddressWalker::newLine()
115 : {
116 0 : resetColumn();
117 0 : nextRow();
118 0 : }
119 :
120 0 : ScAddress AddressWalker::current(SCCOL aRelCol, SCROW aRelRow, SCTAB aRelTab)
121 : {
122 : return ScAddress(
123 0 : mCurrentAddress.Col() + aRelCol,
124 0 : mCurrentAddress.Row() + aRelRow,
125 0 : mCurrentAddress.Tab() + aRelTab);
126 : }
127 :
128 0 : void AddressWalker::nextColumn()
129 : {
130 0 : mCurrentAddress.IncCol();
131 :
132 0 : if (mTrackRange)
133 : {
134 0 : if(mMaximumAddress.Col() < mCurrentAddress.Col())
135 0 : mMaximumAddress.SetCol(mCurrentAddress.Col());
136 : }
137 0 : }
138 :
139 0 : void AddressWalker::nextRow()
140 : {
141 0 : mCurrentAddress.IncRow();
142 0 : if (mTrackRange)
143 : {
144 0 : if(mMaximumAddress.Row() < mCurrentAddress.Row())
145 0 : mMaximumAddress.SetRow(mCurrentAddress.Row());
146 : }
147 0 : }
148 :
149 0 : void AddressWalker::push(SCCOL aRelativeCol, SCROW aRelativeRow, SCTAB aRelativeTab)
150 : {
151 0 : mCurrentAddress = current(aRelativeCol, aRelativeRow, aRelativeTab);
152 0 : mAddressStack.push_back(mCurrentAddress);
153 0 : }
154 :
155 0 : AddressWalkerWriter::AddressWalkerWriter(ScAddress aInitialAddress, ScDocShell* pDocShell, ScDocument* pDocument,
156 : formula::FormulaGrammar::Grammar eGrammar ) :
157 : AddressWalker(aInitialAddress, true),
158 : mpDocShell(pDocShell),
159 : mpDocument(pDocument),
160 0 : meGrammar(eGrammar)
161 0 : {}
162 :
163 0 : void AddressWalkerWriter::writeFormula(const OUString& aFormula)
164 : {
165 0 : mpDocShell->GetDocFunc().SetFormulaCell(mCurrentAddress,
166 0 : new ScFormulaCell(mpDocument, mCurrentAddress, aFormula, meGrammar), true);
167 0 : }
168 :
169 0 : void AddressWalkerWriter::writeMatrixFormula(const OUString& aFormula)
170 : {
171 0 : ScRange aRange;
172 0 : aRange.aStart = mCurrentAddress;
173 0 : aRange.aEnd = mCurrentAddress;
174 0 : mpDocShell->GetDocFunc().EnterMatrix(aRange, NULL, NULL, aFormula, false, false, OUString(), meGrammar );
175 0 : }
176 :
177 0 : void AddressWalkerWriter::writeString(const OUString& aString)
178 : {
179 0 : mpDocShell->GetDocFunc().SetStringCell(mCurrentAddress, aString, true);
180 0 : }
181 :
182 0 : void AddressWalkerWriter::writeString(const char* aCharArray)
183 : {
184 0 : writeString(OUString::createFromAscii(aCharArray));
185 0 : }
186 :
187 0 : void AddressWalkerWriter::writeBoldString(const OUString& aString)
188 : {
189 0 : ScFieldEditEngine& rEngine = mpDocument->GetEditEngine();
190 0 : rEngine.SetText(aString);
191 0 : SfxItemSet aItemSet = rEngine.GetEmptyItemSet();
192 0 : SvxWeightItem aWeight(WEIGHT_BOLD, EE_CHAR_WEIGHT);
193 0 : aItemSet.Put(aWeight);
194 0 : rEngine.QuickSetAttribs(aItemSet, ESelection(0, 0, 0, aString.getLength()) );
195 0 : boost::scoped_ptr<EditTextObject> pEditText(rEngine.CreateTextObject());
196 0 : mpDocShell->GetDocFunc().SetEditCell(mCurrentAddress, *pEditText, true);
197 0 : }
198 :
199 0 : void AddressWalkerWriter::writeValue(double aValue)
200 : {
201 0 : mpDocShell->GetDocFunc().SetValueCell(mCurrentAddress, aValue, true);
202 0 : }
203 :
204 : // DataCellIterator
205 :
206 0 : DataCellIterator::DataCellIterator(ScRange aInputRange, bool aByColumn)
207 : : mInputRange(aInputRange)
208 : , mByColumn(aByColumn)
209 : , mCol(0)
210 0 : , mRow(0)
211 : {
212 0 : if(aByColumn)
213 0 : mCol = aInputRange.aStart.Col();
214 : else
215 0 : mRow = aInputRange.aStart.Row();
216 0 : }
217 :
218 0 : DataCellIterator::~DataCellIterator()
219 0 : {}
220 :
221 0 : bool DataCellIterator::hasNext()
222 : {
223 0 : if(mByColumn)
224 0 : return mCol <= mInputRange.aEnd.Col();
225 : else
226 0 : return mRow <= mInputRange.aEnd.Row();
227 : }
228 :
229 0 : void DataCellIterator::next()
230 : {
231 0 : if(mByColumn)
232 0 : mCol++;
233 : else
234 0 : mRow++;
235 0 : }
236 :
237 0 : ScAddress DataCellIterator::get()
238 : {
239 0 : return getRelative(0);
240 : }
241 :
242 0 : ScAddress DataCellIterator::getRelative(int aDelta)
243 : {
244 0 : if(mByColumn)
245 : {
246 0 : SCCOL aNewColumn = mCol + aDelta;
247 0 : if(aNewColumn < mInputRange.aStart.Col() || aNewColumn > mInputRange.aEnd.Col())
248 : {
249 0 : ScAddress aResult;
250 0 : aResult.SetInvalid();
251 0 : return aResult;
252 : }
253 0 : return ScAddress(aNewColumn, mInputRange.aStart.Row(), mInputRange.aStart.Tab());
254 : }
255 : else
256 : {
257 0 : SCROW aNewRow = mRow + aDelta;
258 0 : if(aNewRow < mInputRange.aStart.Row() || aNewRow > mInputRange.aEnd.Row())
259 : {
260 0 : ScAddress aResult;
261 0 : aResult.SetInvalid();
262 0 : return aResult;
263 : }
264 0 : return ScAddress(mInputRange.aStart.Col(), aNewRow, mInputRange.aStart.Tab());
265 : }
266 : }
267 :
268 : // DataRangeIterator
269 :
270 0 : DataRangeIterator::DataRangeIterator(ScRange aInputRange) :
271 : mInputRange(aInputRange),
272 0 : mIndex(0)
273 0 : {}
274 :
275 0 : DataRangeIterator::~DataRangeIterator()
276 0 : {}
277 :
278 0 : sal_Int32 DataRangeIterator::index()
279 : {
280 0 : return mIndex;
281 : }
282 :
283 : // DataRangeByColumnIterator
284 :
285 0 : DataRangeByColumnIterator::DataRangeByColumnIterator(ScRange aInputRange) :
286 : DataRangeIterator(aInputRange),
287 0 : mCol(aInputRange.aStart.Col())
288 0 : {}
289 :
290 0 : bool DataRangeByColumnIterator::hasNext()
291 : {
292 0 : return mCol <= mInputRange.aEnd.Col();
293 : }
294 :
295 0 : void DataRangeByColumnIterator::next()
296 : {
297 0 : mCol++;
298 0 : mIndex++;
299 0 : }
300 :
301 0 : ScRange DataRangeByColumnIterator::get()
302 : {
303 : return ScRange(
304 0 : ScAddress(mCol, mInputRange.aStart.Row(), mInputRange.aStart.Tab()),
305 0 : ScAddress(mCol, mInputRange.aEnd.Row(), mInputRange.aEnd.Tab())
306 0 : );
307 : }
308 :
309 0 : void DataRangeByColumnIterator::reset()
310 : {
311 0 : mCol = mInputRange.aStart.Col();
312 0 : }
313 :
314 0 : DataCellIterator DataRangeByColumnIterator::iterateCells()
315 : {
316 0 : return DataCellIterator(get(), false);
317 : }
318 :
319 : // DataRangeByRowIterator
320 :
321 0 : DataRangeByRowIterator::DataRangeByRowIterator(ScRange aInputRange) :
322 : DataRangeIterator(aInputRange),
323 0 : mRow(aInputRange.aStart.Row())
324 0 : {}
325 :
326 0 : bool DataRangeByRowIterator::hasNext()
327 : {
328 0 : return mRow <= mInputRange.aEnd.Row();
329 : }
330 :
331 0 : void DataRangeByRowIterator::next()
332 : {
333 0 : mRow++;
334 0 : mIndex++;
335 0 : }
336 :
337 0 : ScRange DataRangeByRowIterator::get()
338 : {
339 : return ScRange(
340 0 : ScAddress(mInputRange.aStart.Col(), mRow, mInputRange.aStart.Tab()),
341 0 : ScAddress(mInputRange.aEnd.Col(), mRow, mInputRange.aEnd.Tab())
342 0 : );
343 : }
344 :
345 0 : void DataRangeByRowIterator::reset()
346 : {
347 0 : mRow = mInputRange.aStart.Row();
348 0 : }
349 :
350 0 : DataCellIterator DataRangeByRowIterator::iterateCells()
351 : {
352 0 : return DataCellIterator(get(), true);
353 156 : }
354 :
355 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|