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