LibreOffice Module sc (master)  1
clipcontext.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 #include <memory>
11 #include <clipcontext.hxx>
12 #include <document.hxx>
13 #include <mtvelements.hxx>
14 #include <column.hxx>
15 #include <scitems.hxx>
16 #include <tokenarray.hxx>
17 #include <editutil.hxx>
18 #include <clipparam.hxx>
19 
20 #include <svl/intitem.hxx>
21 #include <svl/numformat.hxx>
22 #include <formula/errorcodes.hxx>
23 #include <refdata.hxx>
24 
25 namespace sc {
26 
28  mpSet(new ColumnBlockPositionSet(rDoc)) {}
29 
31 
33 {
34  return mpSet->getBlockPosition(nTab, nCol);
35 }
36 
38  ScDocument* pRefUndoDoc, ScDocument* pClipDoc, InsertDeleteFlags nInsertFlag,
39  bool bAsLink, bool bSkipAttrForEmptyCells) :
40  ClipContextBase(rDoc),
41  mnDestCol1(-1), mnDestCol2(-1),
42  mnDestRow1(-1), mnDestRow2(-1),
43  mnTabStart(-1), mnTabEnd(-1),
44  mrDestDoc(rDoc),
45  mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc),
46  mnInsertFlag(nInsertFlag), mnDeleteFlag(InsertDeleteFlags::NONE),
47  mpCondFormatList(nullptr),
48  mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells),
49  mbCloneNotes (mnInsertFlag & (InsertDeleteFlags::NOTE|InsertDeleteFlags::ADDNOTES)),
50  mbTableProtected(false)
51 {
52 }
53 
55 {
56 }
57 
59 {
60  mnTabStart = nStart;
61  mnTabEnd = nEnd;
62 }
63 
65 {
66  return mnTabStart;
67 }
68 
70 {
71  return mnTabEnd;
72 }
73 
74 void CopyFromClipContext::setDestRange( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
75 {
76  mnDestCol1 = nCol1;
77  mnDestRow1 = nRow1;
78  mnDestCol2 = nCol2;
79  mnDestRow2 = nRow2;
80 }
81 
83 {
84  Range aRet;
85  aRet.mnCol1 = mnDestCol1;
86  aRet.mnCol2 = mnDestCol2;
87  aRet.mnRow1 = mnDestRow1;
88  aRet.mnRow2 = mnDestRow2;
89  return aRet;
90 }
91 
93 {
94  return mpRefUndoDoc;
95 }
96 
98 {
99  return mpClipDoc;
100 }
101 
103 {
104  return mnInsertFlag;
105 }
106 
108 {
109  mnDeleteFlag = nFlag;
110 }
111 
113 {
114  return mnDeleteFlag;
115 }
116 
118 {
119  maSingleCells.resize(nSize);
120  maSingleCellAttrs.resize(nSize);
121  maSinglePatterns.resize(nSize, nullptr);
122  maSingleNotes.resize(nSize, nullptr);
123 }
124 
126 {
127  assert(nColOffset < maSingleCells.size());
128  return maSingleCells[nColOffset];
129 }
130 
132 {
133  assert(nColOffset < maSingleCellAttrs.size());
134  return maSingleCellAttrs[nColOffset];
135 }
136 
137 void CopyFromClipContext::setSingleCell( const ScAddress& rSrcPos, const ScColumn& rSrcCol )
138 {
139  SCCOL nColOffset = rSrcPos.Col() - mpClipDoc->GetClipParam().getWholeRange().aStart.Col();
140  ScCellValue& rSrcCell = getSingleCell(nColOffset);
141 
142  const sc::CellTextAttr* pAttr = rSrcCol.GetCellTextAttr(rSrcPos.Row());
143 
144  if (pAttr)
145  {
146  sc::CellTextAttr& rAttr = getSingleCellAttr(nColOffset);
147  rAttr = *pAttr;
148  }
149 
150  if (mbAsLink)
151  {
152  ScSingleRefData aRef;
153  aRef.InitAddress(rSrcPos);
154  aRef.SetFlag3D(true);
155 
157  aArr.AddSingleReference(aRef);
158  rSrcCell.set(new ScFormulaCell(*mpClipDoc, rSrcPos, aArr));
159  return;
160  }
161 
162  rSrcCell.assign(*mpClipDoc, rSrcPos);
163 
164  // Check the paste flag to see whether we want to paste this cell. If the
165  // flag says we don't want to paste this cell, we'll return with true.
166  InsertDeleteFlags nFlags = getInsertFlag();
167  bool bNumeric = (nFlags & InsertDeleteFlags::VALUE) != InsertDeleteFlags::NONE;
168  bool bDateTime = (nFlags & InsertDeleteFlags::DATETIME) != InsertDeleteFlags::NONE;
169  bool bString = (nFlags & InsertDeleteFlags::STRING) != InsertDeleteFlags::NONE;
170  bool bBoolean = (nFlags & InsertDeleteFlags::SPECIAL_BOOLEAN) != InsertDeleteFlags::NONE;
171  bool bFormula = (nFlags & InsertDeleteFlags::FORMULA) != InsertDeleteFlags::NONE;
172 
173  switch (rSrcCell.meType)
174  {
175  case CELLTYPE_VALUE:
176  {
177  bool bPaste = isDateCell(rSrcCol, rSrcPos.Row()) ? bDateTime : bNumeric;
178  if (!bPaste)
179  // Don't paste this.
180  rSrcCell.clear();
181  }
182  break;
183  case CELLTYPE_STRING:
184  case CELLTYPE_EDIT:
185  {
186  if (!bString)
187  // Skip pasting.
188  rSrcCell.clear();
189  }
190  break;
191  case CELLTYPE_FORMULA:
192  {
193  if (bBoolean)
194  {
195  // Check if this formula cell is a boolean cell, and if so, go ahead and paste it.
196  const ScTokenArray* pCode = rSrcCell.mpFormula->GetCode();
197  if (pCode && pCode->GetLen() == 1)
198  {
199  const formula::FormulaToken* p = pCode->FirstToken();
200  if (p->GetOpCode() == ocTrue || p->GetOpCode() == ocFalse)
201  // This is a boolean formula. Good.
202  break;
203  }
204  }
205 
206  if (bFormula)
207  // Good.
208  break;
209 
210  FormulaError nErr = rSrcCell.mpFormula->GetErrCode();
211  if (nErr != FormulaError::NONE)
212  {
213  // error codes are cloned with values
214  if (!bNumeric)
215  // Error code is treated as numeric value. Don't paste it.
216  rSrcCell.clear();
217  else
218  {
219  // Turn this into a formula cell with just the error code.
220  ScFormulaCell* pErrCell = new ScFormulaCell(*mpClipDoc, rSrcPos);
221  pErrCell->SetErrCode(nErr);
222  rSrcCell.set(pErrCell);
223  }
224  }
225  else if (rSrcCell.mpFormula->IsEmptyDisplayedAsString())
226  {
227  // Empty stays empty and doesn't become 0.
228  rSrcCell.clear();
229  }
230  else if (rSrcCell.mpFormula->IsValue())
231  {
232  bool bPaste = isDateCell(rSrcCol, rSrcPos.Row()) ? bDateTime : bNumeric;
233  if (!bPaste)
234  {
235  // Don't paste this.
236  rSrcCell.clear();
237  break;
238  }
239 
240  // Turn this into a numeric cell.
241  rSrcCell.set(rSrcCell.mpFormula->GetValue());
242  }
243  else if (bString)
244  {
246  if (aStr.isEmpty())
247  {
248  // do not clone empty string
249  rSrcCell.clear();
250  break;
251  }
252 
253  // Turn this into a string or edit cell.
254  if (rSrcCell.mpFormula->IsMultilineResult())
255  {
256  // TODO : Add shared string support to the edit engine to
257  // make this process simpler.
259  rEngine.SetTextCurrentDefaults(rSrcCell.mpFormula->GetString().getString());
260  std::unique_ptr<EditTextObject> pObj(rEngine.CreateTextObject());
261  pObj->NormalizeString(mrDestDoc.GetSharedStringPool());
262  rSrcCell.set(*pObj);
263  }
264  else
265  rSrcCell.set(rSrcCell.mpFormula->GetString());
266  }
267  else
268  // We don't want to paste this.
269  rSrcCell.clear();
270  }
271  break;
272  case CELLTYPE_NONE:
273  default:
274  // There is nothing to paste.
275  rSrcCell.clear();
276  }
277 }
278 
280 {
281  assert(nColOffset < maSinglePatterns.size());
282  return maSinglePatterns[nColOffset];
283 }
284 
285 void CopyFromClipContext::setSingleCellPattern( size_t nColOffset, const ScPatternAttr* pAttr )
286 {
287  assert(nColOffset < maSinglePatterns.size());
288  maSinglePatterns[nColOffset] = pAttr;
289 }
290 
291 const ScPostIt* CopyFromClipContext::getSingleCellNote( size_t nColOffset ) const
292 {
293  assert(nColOffset < maSingleNotes.size());
294  return maSingleNotes[nColOffset];
295 }
296 
297 void CopyFromClipContext::setSingleCellNote( size_t nColOffset, const ScPostIt* pNote )
298 {
299  assert(nColOffset < maSingleNotes.size());
300  maSingleNotes[nColOffset] = pNote;
301 }
302 
304 {
305  mpCondFormatList = pCondFormatList;
306 }
307 
309 {
310  return mpCondFormatList;
311 }
312 
314 {
315  mbTableProtected = b;
316 }
317 
319 {
320  return mbTableProtected;
321 }
322 
324 {
325  return mbAsLink;
326 }
327 
329 {
331 }
332 
334 {
335  return mbCloneNotes;
336 }
337 
338 bool CopyFromClipContext::isDateCell( const ScColumn& rCol, SCROW nRow ) const
339 {
340  sal_uLong nNumIndex = rCol.GetAttr(nRow, ATTR_VALUE_FORMAT).GetValue();
342  return (nType == SvNumFormatType::DATE) || (nType == SvNumFormatType::TIME) || (nType == SvNumFormatType::DATETIME);
343 }
344 
346  ScDocument& rDoc, bool bKeepScenarioFlags) :
347  ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags) {}
348 
350 
352 {
353  return mbKeepScenarioFlags;
354 }
355 
357  ClipContextBase(rDoc), mbStartListening(true) {}
358 
360 
362 {
363  mbStartListening = b;
364 }
365 
367 {
368  return mbStartListening;
369 }
370 
373 
374 }
375 
376 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Numeric values (and numeric results if InsertDeleteFlags::FORMULA is not set).
void set(double fValue)
Definition: cellvalue.cxx:295
CellType meType
Definition: cellvalue.hxx:37
OUString getString() const
ScAddress aStart
Definition: address.hxx:499
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:566
const SfxPoolItem & GetAttr(SCROW nRow, sal_uInt16 nWhich) const
Definition: column.cxx:376
SCROW Row() const
Definition: address.hxx:261
void setSingleCell(const ScAddress &rSrcPos, const ScColumn &rSrcCol)
Single reference (one address) into the sheet.
Definition: refdata.hxx:29
virtual ~CopyToClipContext() override
void setTabRange(SCTAB nStart, SCTAB nEnd)
Definition: clipcontext.cxx:58
ScTokenArray * GetCode()
sal_uIntPtr sal_uLong
bool isStartListening() const
SvNumFormatType GetType(sal_uInt32 nFIndex) const
formula::FormulaToken * AddSingleReference(const ScSingleRefData &rRef)
ScSingleRefToken with ocPush.
Definition: token.cxx:2271
Store position data for column array storage.
InsertDeleteFlags getInsertFlag() const
bool isSkipAttrForEmptyCells() const
OpCode GetOpCode() const
bool isTableProtected() const
ClipContextBase()=delete
bool IsMultilineResult()
Determines whether or not the result string contains more than one paragraph.
NONE
Store arbitrary cell value of any kind.
Definition: cellvalue.hxx:35
virtual ~ClipContextBase()
Definition: clipcontext.cxx:30
MixDocContext(ScDocument &rDoc)
ScClipParam & GetClipParam()
Definition: document.cxx:2565
ScFormulaCell * mpFormula
Definition: cellvalue.hxx:42
Additional class containing cell annotation data.
Definition: postit.hxx:160
ScConditionalFormatList * getCondFormatList()
double GetValue()
FormulaError GetErrCode()
void setCondFormatList(ScConditionalFormatList *pCondFormatList)
void setDeleteFlag(InsertDeleteFlags nFlag)
void setStartListening(bool b)
sal_uInt16 GetLen() const
Internal use only (copy from clip): do not delete existing cell contents when pasting notes...
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:441
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:596
bool isEmpty() const
void SetFlag3D(bool bVal)
Definition: refdata.hxx:89
void setSingleCellNote(size_t nColOffset, const ScPostIt *pNote)
std::vector< const ScPatternAttr * > maSinglePatterns
Definition: clipcontext.hxx:61
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
Definition: refdata.cxx:27
sal_Int16 SCCOL
Definition: types.hxx:21
InsertDeleteFlags
Definition: global.hxx:158
CopyToClipContext(ScDocument &rDoc, bool bKeepScenarioFlags)
const SvxPageUsage aArr[]
std::unique_ptr< EditTextObject > CreateTextObject()
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
SvNumFormatType
ScConditionalFormatList * mpCondFormatList
Definition: clipcontext.hxx:64
ScDocument * mpRefUndoDoc
Definition: clipcontext.hxx:54
FormulaToken * FirstToken() const
void setDestRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: clipcontext.cxx:74
bool IsEmptyDisplayedAsString()
const ScPatternAttr * getSingleCellPattern(size_t nColOffset) const
CopyToDocContext(ScDocument &rDoc)
void setSingleCellPattern(size_t nColOffset, const ScPatternAttr *pAttr)
const svl::SharedString & GetString()
FormulaError
SCCOL Col() const
Definition: address.hxx:266
ScCellValue & getSingleCell(size_t nColOffset)
ocFalse
void setTableProtected(bool b)
Internal use only (undo etc.): do not copy/delete caption objects of cell notes.
const ScPostIt * getSingleCellNote(size_t nColOffset) const
std::vector< const ScPostIt * > maSingleNotes
Definition: clipcontext.hxx:62
virtual ~CopyToDocContext() override
ocTrue
sal_Int32 SCROW
Definition: types.hxx:17
ScRange getWholeRange() const
Return a single range that encompasses all individual ranges.
Definition: clipparam.cxx:109
sc::CellTextAttr & getSingleCellAttr(size_t nColOffset)
void assign(const ScDocument &rDoc, const ScAddress &rPos)
Take cell value from specified position in specified document.
Definition: cellvalue.cxx:330
Dates, times, datetime values.
SCTAB getTabEnd() const
Definition: clipcontext.cxx:69
ScDocument * getUndoDoc()
Definition: clipcontext.cxx:92
SCTAB getTabStart() const
Definition: clipcontext.cxx:64
bool isDateCell(const ScColumn &rCol, SCROW nRow) const
ScDocument * getClipDoc()
Definition: clipcontext.cxx:97
void * p
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
InsertDeleteFlags mnDeleteFlag
Definition: clipcontext.hxx:57
InsertDeleteFlags getDeleteFlag() const
void clear() noexcept
Definition: cellvalue.cxx:273
std::unique_ptr< ColumnBlockPositionSet > mpSet
Definition: clipcontext.hxx:32
void setSingleCellColumnSize(size_t nSize)
Set the column size of a "single cell" row, which is used when copying a single row of cells in a cli...
Range getDestRange() const
Definition: clipcontext.cxx:82
const sc::CellTextAttr * GetCellTextAttr(SCROW nRow) const
Definition: column.cxx:795
virtual ~CopyFromClipContext() override
Definition: clipcontext.cxx:54
virtual ~MixDocContext() override
void SetErrCode(FormulaError n)
std::vector< sc::CellTextAttr > maSingleCellAttrs
Definition: clipcontext.hxx:60
aStr
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:457
sal_Int16 SCTAB
Definition: types.hxx:22
ColumnBlockPosition * getBlockPosition(SCTAB nTab, SCCOL nCol)
Definition: clipcontext.cxx:32
std::vector< ScCellValue > maSingleCells
Definition: clipcontext.hxx:59
InsertDeleteFlags mnInsertFlag
Definition: clipcontext.hxx:56
bool isKeepScenarioFlags() const
bool isCloneNotes() const