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 : #include "clipcontext.hxx"
11 : #include "document.hxx"
12 : #include "mtvelements.hxx"
13 : #include <column.hxx>
14 : #include <scitems.hxx>
15 : #include <tokenarray.hxx>
16 : #include <editutil.hxx>
17 : #include <clipparam.hxx>
18 :
19 : #include <svl/intitem.hxx>
20 :
21 : namespace sc {
22 :
23 1259 : ClipContextBase::ClipContextBase(ScDocument& rDoc) :
24 1259 : mpSet(new ColumnBlockPositionSet(rDoc)) {}
25 :
26 1259 : ClipContextBase::~ClipContextBase() {}
27 :
28 192910 : ColumnBlockPosition* ClipContextBase::getBlockPosition(SCTAB nTab, SCCOL nCol)
29 : {
30 192910 : return mpSet->getBlockPosition(nTab, nCol);
31 : }
32 :
33 78 : CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc,
34 : ScDocument* pRefUndoDoc, ScDocument* pClipDoc, InsertDeleteFlags nInsertFlag,
35 : bool bAsLink, bool bSkipAttrForEmptyCells) :
36 : ClipContextBase(rDoc),
37 : mnDestCol1(-1), mnDestCol2(-1),
38 : mnDestRow1(-1), mnDestRow2(-1),
39 : mnTabStart(-1), mnTabEnd(-1),
40 : mrDestDoc(rDoc),
41 : mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc),
42 : mnInsertFlag(nInsertFlag), mnDeleteFlag(IDF_NONE),
43 : mpCondFormatList(NULL),
44 : mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells),
45 156 : mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES)),
46 234 : mbTableProtected(false)
47 : {
48 78 : }
49 :
50 78 : CopyFromClipContext::~CopyFromClipContext()
51 : {
52 78 : }
53 :
54 78 : void CopyFromClipContext::setTabRange(SCTAB nStart, SCTAB nEnd)
55 : {
56 78 : mnTabStart = nStart;
57 78 : mnTabEnd = nEnd;
58 78 : }
59 :
60 137 : SCTAB CopyFromClipContext::getTabStart() const
61 : {
62 137 : return mnTabStart;
63 : }
64 :
65 86 : SCTAB CopyFromClipContext::getTabEnd() const
66 : {
67 86 : return mnTabEnd;
68 : }
69 :
70 2 : void CopyFromClipContext::setDestRange( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
71 : {
72 2 : mnDestCol1 = nCol1;
73 2 : mnDestRow1 = nRow1;
74 2 : mnDestCol2 = nCol2;
75 2 : mnDestRow2 = nRow2;
76 2 : }
77 :
78 6 : CopyFromClipContext::Range CopyFromClipContext::getDestRange() const
79 : {
80 : Range aRet;
81 6 : aRet.mnCol1 = mnDestCol1;
82 6 : aRet.mnCol2 = mnDestCol2;
83 6 : aRet.mnRow1 = mnDestRow1;
84 6 : aRet.mnRow2 = mnDestRow2;
85 6 : return aRet;
86 : }
87 :
88 50 : ScDocument* CopyFromClipContext::getUndoDoc()
89 : {
90 50 : return mpRefUndoDoc;
91 : }
92 :
93 510 : ScDocument* CopyFromClipContext::getClipDoc()
94 : {
95 510 : return mpClipDoc;
96 : }
97 :
98 904 : InsertDeleteFlags CopyFromClipContext::getInsertFlag() const
99 : {
100 904 : return mnInsertFlag;
101 : }
102 :
103 77 : void CopyFromClipContext::setDeleteFlag( InsertDeleteFlags nFlag )
104 : {
105 77 : mnDeleteFlag = nFlag;
106 77 : }
107 :
108 3 : InsertDeleteFlags CopyFromClipContext::getDeleteFlag() const
109 : {
110 3 : return mnDeleteFlag;
111 : }
112 :
113 12 : void CopyFromClipContext::setSingleCellColumnSize( size_t nSize )
114 : {
115 12 : maSingleCells.resize(nSize);
116 12 : maSingleCellAttrs.resize(nSize);
117 12 : maSinglePatterns.resize(nSize, NULL);
118 12 : maSingleNotes.resize(nSize, NULL);
119 12 : }
120 :
121 34 : ScCellValue& CopyFromClipContext::getSingleCell( size_t nColOffset )
122 : {
123 : assert(nColOffset < maSingleCells.size());
124 34 : return maSingleCells[nColOffset];
125 : }
126 :
127 30 : sc::CellTextAttr& CopyFromClipContext::getSingleCellAttr( size_t nColOffset )
128 : {
129 : assert(nColOffset < maSingleCellAttrs.size());
130 30 : return maSingleCellAttrs[nColOffset];
131 : }
132 :
133 17 : void CopyFromClipContext::setSingleCell( const ScAddress& rSrcPos, const ScColumn& rSrcCol )
134 : {
135 17 : SCCOL nColOffset = rSrcPos.Col() - mpClipDoc->GetClipParam().getWholeRange().aStart.Col();
136 17 : ScCellValue& rSrcCell = getSingleCell(nColOffset);
137 :
138 17 : const sc::CellTextAttr* pAttr = rSrcCol.GetCellTextAttr(rSrcPos.Row());
139 :
140 17 : if (pAttr)
141 : {
142 13 : sc::CellTextAttr& rAttr = getSingleCellAttr(nColOffset);
143 13 : rAttr = *pAttr;
144 : }
145 :
146 17 : if (mbAsLink)
147 : {
148 : ScSingleRefData aRef;
149 0 : aRef.InitAddress(rSrcPos);
150 0 : aRef.SetFlag3D(true);
151 :
152 0 : ScTokenArray aArr;
153 0 : aArr.AddSingleReference(aRef);
154 0 : rSrcCell.set(new ScFormulaCell(mpClipDoc, rSrcPos, aArr));
155 17 : return;
156 : }
157 :
158 17 : rSrcCell.assign(*mpClipDoc, rSrcPos);
159 :
160 : // Check the paste flag to see whether we want to paste this cell. If the
161 : // flag says we don't want to paste this cell, we'll return with true.
162 17 : InsertDeleteFlags nFlags = getInsertFlag();
163 17 : bool bNumeric = (nFlags & IDF_VALUE) != IDF_NONE;
164 17 : bool bDateTime = (nFlags & IDF_DATETIME) != IDF_NONE;
165 17 : bool bString = (nFlags & IDF_STRING) != IDF_NONE;
166 17 : bool bBoolean = (nFlags & IDF_SPECIAL_BOOLEAN) != IDF_NONE;
167 17 : bool bFormula = (nFlags & IDF_FORMULA) != IDF_NONE;
168 :
169 17 : switch (rSrcCell.meType)
170 : {
171 : case CELLTYPE_VALUE:
172 : {
173 2 : bool bPaste = isDateCell(rSrcCol, rSrcPos.Row()) ? bDateTime : bNumeric;
174 2 : if (!bPaste)
175 : // Don't paste this.
176 0 : rSrcCell.clear();
177 : }
178 2 : break;
179 : case CELLTYPE_STRING:
180 : case CELLTYPE_EDIT:
181 : {
182 4 : if (!bString)
183 : // Skip pasting.
184 0 : rSrcCell.clear();
185 : }
186 4 : break;
187 : case CELLTYPE_FORMULA:
188 : {
189 7 : if (bBoolean)
190 : {
191 : // Check if this formula cell is a boolean cell, and if so, go ahead and paste it.
192 0 : ScTokenArray* pCode = rSrcCell.mpFormula->GetCode();
193 0 : if (pCode && pCode->GetLen() == 1)
194 : {
195 0 : const formula::FormulaToken* p = pCode->First();
196 0 : if (p->GetOpCode() == ocTrue || p->GetOpCode() == ocFalse)
197 : // This is a boolean formula. Good.
198 0 : break;
199 : }
200 : }
201 :
202 7 : if (bFormula)
203 : // Good.
204 7 : break;
205 :
206 0 : sal_uInt16 nErr = rSrcCell.mpFormula->GetErrCode();
207 0 : if (nErr)
208 : {
209 : // error codes are cloned with values
210 0 : if (!bNumeric)
211 : // Error code is treated as numeric value. Don't paste it.
212 0 : rSrcCell.clear();
213 : }
214 0 : else if (rSrcCell.mpFormula->IsValue())
215 : {
216 0 : bool bPaste = isDateCell(rSrcCol, rSrcPos.Row()) ? bDateTime : bNumeric;
217 0 : if (!bPaste)
218 : {
219 : // Don't paste this.
220 0 : rSrcCell.clear();
221 0 : break;
222 : }
223 :
224 : // Turn this into a numeric cell.
225 0 : rSrcCell.set(rSrcCell.mpFormula->GetValue());
226 : }
227 0 : else if (bString)
228 : {
229 0 : svl::SharedString aStr = rSrcCell.mpFormula->GetString();
230 0 : if (aStr.isEmpty())
231 : {
232 : // do not clone empty string
233 0 : rSrcCell.clear();
234 0 : break;
235 : }
236 :
237 : // Turn this into a string or edit cell.
238 0 : if (rSrcCell.mpFormula->IsMultilineResult())
239 : {
240 : // TODO : Add shared string support to the edit engine to
241 : // make this process simpler.
242 0 : ScFieldEditEngine& rEngine = mrDestDoc.GetEditEngine();
243 0 : rEngine.SetText(rSrcCell.mpFormula->GetString().getString());
244 0 : boost::scoped_ptr<EditTextObject> pObj(rEngine.CreateTextObject());
245 0 : pObj->NormalizeString(mrDestDoc.GetSharedStringPool());
246 0 : rSrcCell.set(*pObj);
247 : }
248 : else
249 0 : rSrcCell.set(rSrcCell.mpFormula->GetString());
250 : }
251 : else
252 : // We don't want to paste this.
253 0 : rSrcCell.clear();
254 : }
255 0 : break;
256 : case CELLTYPE_NONE:
257 : default:
258 : // There is nothing to paste.
259 4 : rSrcCell.clear();
260 : }
261 : }
262 :
263 15 : const ScPatternAttr* CopyFromClipContext::getSingleCellPattern( size_t nColOffset ) const
264 : {
265 : assert(nColOffset < maSinglePatterns.size());
266 15 : return maSinglePatterns[nColOffset];
267 : }
268 :
269 17 : void CopyFromClipContext::setSingleCellPattern( size_t nColOffset, const ScPatternAttr* pAttr )
270 : {
271 : assert(nColOffset < maSinglePatterns.size());
272 17 : maSinglePatterns[nColOffset] = pAttr;
273 17 : }
274 :
275 17 : const ScPostIt* CopyFromClipContext::getSingleCellNote( size_t nColOffset ) const
276 : {
277 : assert(nColOffset < maSingleNotes.size());
278 17 : return maSingleNotes[nColOffset];
279 : }
280 :
281 17 : void CopyFromClipContext::setSingleCellNote( size_t nColOffset, const ScPostIt* pNote )
282 : {
283 : assert(nColOffset < maSingleNotes.size());
284 17 : maSingleNotes[nColOffset] = pNote;
285 17 : }
286 :
287 2 : void CopyFromClipContext::setCondFormatList( ScConditionalFormatList* pCondFormatList )
288 : {
289 2 : mpCondFormatList = pCondFormatList;
290 2 : }
291 :
292 5 : ScConditionalFormatList* CopyFromClipContext::getCondFormatList()
293 : {
294 5 : return mpCondFormatList;
295 : }
296 :
297 2 : void CopyFromClipContext::setTableProtected( bool b )
298 : {
299 2 : mbTableProtected = b;
300 2 : }
301 :
302 5 : bool CopyFromClipContext::isTableProtected() const
303 : {
304 5 : return mbTableProtected;
305 : }
306 :
307 336 : bool CopyFromClipContext::isAsLink() const
308 : {
309 336 : return mbAsLink;
310 : }
311 :
312 142 : bool CopyFromClipContext::isSkipAttrForEmptyCells() const
313 : {
314 142 : return mbSkipAttrForEmptyCells;
315 : }
316 :
317 217 : bool CopyFromClipContext::isCloneNotes() const
318 : {
319 217 : return mbCloneNotes;
320 : }
321 :
322 160 : bool CopyFromClipContext::isDateCell( const ScColumn& rCol, SCROW nRow ) const
323 : {
324 160 : sal_uLong nNumIndex = static_cast<const SfxUInt32Item*>(rCol.GetAttr(nRow, ATTR_VALUE_FORMAT))->GetValue();
325 160 : short nType = mpClipDoc->GetFormatTable()->GetType(nNumIndex);
326 160 : return (nType == css::util::NumberFormat::DATE) || (nType == css::util::NumberFormat::TIME) || (nType == css::util::NumberFormat::DATETIME);
327 : }
328 :
329 55 : CopyToClipContext::CopyToClipContext(
330 : ScDocument& rDoc, bool bKeepScenarioFlags, bool bCloneNotes) :
331 55 : ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags), mbCloneNotes(bCloneNotes) {}
332 :
333 55 : CopyToClipContext::~CopyToClipContext() {}
334 :
335 80 : bool CopyToClipContext::isKeepScenarioFlags() const
336 : {
337 80 : return mbKeepScenarioFlags;
338 : }
339 :
340 80 : bool CopyToClipContext::isCloneNotes() const
341 : {
342 80 : return mbCloneNotes;
343 : }
344 :
345 1124 : CopyToDocContext::CopyToDocContext(ScDocument& rDoc) :
346 1124 : ClipContextBase(rDoc), mbStartListening(true) {}
347 :
348 1124 : CopyToDocContext::~CopyToDocContext() {}
349 :
350 710 : void CopyToDocContext::setStartListening( bool b )
351 : {
352 710 : mbStartListening = b;
353 710 : }
354 :
355 192683 : bool CopyToDocContext::isStartListening() const
356 : {
357 192683 : return mbStartListening;
358 : }
359 :
360 2 : MixDocContext::MixDocContext(ScDocument& rDoc) : ClipContextBase(rDoc) {}
361 2 : MixDocContext::~MixDocContext() {}
362 :
363 156 : }
364 :
365 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|