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 <formula/errorcodes.hxx>
22 #include <refdata.hxx>
23 
24 namespace sc {
25 
27  mpSet(new ColumnBlockPositionSet(rDoc)) {}
28 
30 
32 {
33  return mpSet->getBlockPosition(nTab, nCol);
34 }
35 
37  ScDocument* pRefUndoDoc, ScDocument* pClipDoc, InsertDeleteFlags nInsertFlag,
38  bool bAsLink, bool bSkipAttrForEmptyCells) :
39  ClipContextBase(rDoc),
40  mnDestCol1(-1), mnDestCol2(-1),
41  mnDestRow1(-1), mnDestRow2(-1),
42  mnTabStart(-1), mnTabEnd(-1),
43  mrDestDoc(rDoc),
44  mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc),
45  mnInsertFlag(nInsertFlag), mnDeleteFlag(InsertDeleteFlags::NONE),
46  mpCondFormatList(nullptr),
47  mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells),
48  mbCloneNotes (mnInsertFlag & (InsertDeleteFlags::NOTE|InsertDeleteFlags::ADDNOTES)),
49  mbTableProtected(false)
50 {
51 }
52 
54 {
55 }
56 
58 {
59  mnTabStart = nStart;
60  mnTabEnd = nEnd;
61 }
62 
64 {
65  return mnTabStart;
66 }
67 
69 {
70  return mnTabEnd;
71 }
72 
73 void CopyFromClipContext::setDestRange( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
74 {
75  mnDestCol1 = nCol1;
76  mnDestRow1 = nRow1;
77  mnDestCol2 = nCol2;
78  mnDestRow2 = nRow2;
79 }
80 
82 {
83  Range aRet;
84  aRet.mnCol1 = mnDestCol1;
85  aRet.mnCol2 = mnDestCol2;
86  aRet.mnRow1 = mnDestRow1;
87  aRet.mnRow2 = mnDestRow2;
88  return aRet;
89 }
90 
92 {
93  return mpRefUndoDoc;
94 }
95 
97 {
98  return mpClipDoc;
99 }
100 
102 {
103  return mnInsertFlag;
104 }
105 
107 {
108  mnDeleteFlag = nFlag;
109 }
110 
112 {
113  return mnDeleteFlag;
114 }
115 
117 {
118  maSingleCells.resize(nSize);
119  maSingleCellAttrs.resize(nSize);
120  maSinglePatterns.resize(nSize, nullptr);
121  maSingleNotes.resize(nSize, nullptr);
122 }
123 
125 {
126  assert(nColOffset < maSingleCells.size());
127  return maSingleCells[nColOffset];
128 }
129 
131 {
132  assert(nColOffset < maSingleCellAttrs.size());
133  return maSingleCellAttrs[nColOffset];
134 }
135 
136 void CopyFromClipContext::setSingleCell( const ScAddress& rSrcPos, const ScColumn& rSrcCol )
137 {
138  SCCOL nColOffset = rSrcPos.Col() - mpClipDoc->GetClipParam().getWholeRange().aStart.Col();
139  ScCellValue& rSrcCell = getSingleCell(nColOffset);
140 
141  const sc::CellTextAttr* pAttr = rSrcCol.GetCellTextAttr(rSrcPos.Row());
142 
143  if (pAttr)
144  {
145  sc::CellTextAttr& rAttr = getSingleCellAttr(nColOffset);
146  rAttr = *pAttr;
147  }
148 
149  if (mbAsLink)
150  {
151  ScSingleRefData aRef;
152  aRef.InitAddress(rSrcPos);
153  aRef.SetFlag3D(true);
154 
156  aArr.AddSingleReference(aRef);
157  rSrcCell.set(new ScFormulaCell(mpClipDoc, rSrcPos, aArr));
158  return;
159  }
160 
161  rSrcCell.assign(*mpClipDoc, rSrcPos);
162 
163  // Check the paste flag to see whether we want to paste this cell. If the
164  // flag says we don't want to paste this cell, we'll return with true.
165  InsertDeleteFlags nFlags = getInsertFlag();
166  bool bNumeric = (nFlags & InsertDeleteFlags::VALUE) != InsertDeleteFlags::NONE;
167  bool bDateTime = (nFlags & InsertDeleteFlags::DATETIME) != InsertDeleteFlags::NONE;
168  bool bString = (nFlags & InsertDeleteFlags::STRING) != InsertDeleteFlags::NONE;
169  bool bBoolean = (nFlags & InsertDeleteFlags::SPECIAL_BOOLEAN) != InsertDeleteFlags::NONE;
170  bool bFormula = (nFlags & InsertDeleteFlags::FORMULA) != InsertDeleteFlags::NONE;
171 
172  switch (rSrcCell.meType)
173  {
174  case CELLTYPE_VALUE:
175  {
176  bool bPaste = isDateCell(rSrcCol, rSrcPos.Row()) ? bDateTime : bNumeric;
177  if (!bPaste)
178  // Don't paste this.
179  rSrcCell.clear();
180  }
181  break;
182  case CELLTYPE_STRING:
183  case CELLTYPE_EDIT:
184  {
185  if (!bString)
186  // Skip pasting.
187  rSrcCell.clear();
188  }
189  break;
190  case CELLTYPE_FORMULA:
191  {
192  if (bBoolean)
193  {
194  // Check if this formula cell is a boolean cell, and if so, go ahead and paste it.
195  const ScTokenArray* pCode = rSrcCell.mpFormula->GetCode();
196  if (pCode && pCode->GetLen() == 1)
197  {
198  const formula::FormulaToken* p = pCode->FirstToken();
199  if (p->GetOpCode() == ocTrue || p->GetOpCode() == ocFalse)
200  // This is a boolean formula. Good.
201  break;
202  }
203  }
204 
205  if (bFormula)
206  // Good.
207  break;
208 
209  FormulaError nErr = rSrcCell.mpFormula->GetErrCode();
210  if (nErr != FormulaError::NONE)
211  {
212  // error codes are cloned with values
213  if (!bNumeric)
214  // Error code is treated as numeric value. Don't paste it.
215  rSrcCell.clear();
216  else
217  {
218  // Turn this into a formula cell with just the error code.
219  ScFormulaCell* pErrCell = new ScFormulaCell(mpClipDoc, rSrcPos);
220  pErrCell->SetErrCode(nErr);
221  rSrcCell.set(pErrCell);
222  }
223  }
224  else if (rSrcCell.mpFormula->IsEmptyDisplayedAsString())
225  {
226  // Empty stays empty and doesn't become 0.
227  rSrcCell.clear();
228  }
229  else if (rSrcCell.mpFormula->IsValue())
230  {
231  bool bPaste = isDateCell(rSrcCol, rSrcPos.Row()) ? bDateTime : bNumeric;
232  if (!bPaste)
233  {
234  // Don't paste this.
235  rSrcCell.clear();
236  break;
237  }
238 
239  // Turn this into a numeric cell.
240  rSrcCell.set(rSrcCell.mpFormula->GetValue());
241  }
242  else if (bString)
243  {
245  if (aStr.isEmpty())
246  {
247  // do not clone empty string
248  rSrcCell.clear();
249  break;
250  }
251 
252  // Turn this into a string or edit cell.
253  if (rSrcCell.mpFormula->IsMultilineResult())
254  {
255  // TODO : Add shared string support to the edit engine to
256  // make this process simpler.
258  rEngine.SetTextCurrentDefaults(rSrcCell.mpFormula->GetString().getString());
259  std::unique_ptr<EditTextObject> pObj(rEngine.CreateTextObject());
260  pObj->NormalizeString(mrDestDoc.GetSharedStringPool());
261  rSrcCell.set(*pObj);
262  }
263  else
264  rSrcCell.set(rSrcCell.mpFormula->GetString());
265  }
266  else
267  // We don't want to paste this.
268  rSrcCell.clear();
269  }
270  break;
271  case CELLTYPE_NONE:
272  default:
273  // There is nothing to paste.
274  rSrcCell.clear();
275  }
276 }
277 
279 {
280  assert(nColOffset < maSinglePatterns.size());
281  return maSinglePatterns[nColOffset];
282 }
283 
284 void CopyFromClipContext::setSingleCellPattern( size_t nColOffset, const ScPatternAttr* pAttr )
285 {
286  assert(nColOffset < maSinglePatterns.size());
287  maSinglePatterns[nColOffset] = pAttr;
288 }
289 
290 const ScPostIt* CopyFromClipContext::getSingleCellNote( size_t nColOffset ) const
291 {
292  assert(nColOffset < maSingleNotes.size());
293  return maSingleNotes[nColOffset];
294 }
295 
296 void CopyFromClipContext::setSingleCellNote( size_t nColOffset, const ScPostIt* pNote )
297 {
298  assert(nColOffset < maSingleNotes.size());
299  maSingleNotes[nColOffset] = pNote;
300 }
301 
303 {
304  mpCondFormatList = pCondFormatList;
305 }
306 
308 {
309  return mpCondFormatList;
310 }
311 
313 {
314  mbTableProtected = b;
315 }
316 
318 {
319  return mbTableProtected;
320 }
321 
323 {
324  return mbAsLink;
325 }
326 
328 {
330 }
331 
333 {
334  return mbCloneNotes;
335 }
336 
337 bool CopyFromClipContext::isDateCell( const ScColumn& rCol, SCROW nRow ) const
338 {
339  sal_uLong nNumIndex = rCol.GetAttr(nRow, ATTR_VALUE_FORMAT).GetValue();
341  return (nType == SvNumFormatType::DATE) || (nType == SvNumFormatType::TIME) || (nType == SvNumFormatType::DATETIME);
342 }
343 
345  ScDocument& rDoc, bool bKeepScenarioFlags) :
346  ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags) {}
347 
349 
351 {
352  return mbKeepScenarioFlags;
353 }
354 
356  ClipContextBase(rDoc), mbStartListening(true) {}
357 
359 
361 {
362  mbStartListening = b;
363 }
364 
366 {
367  return mbStartListening;
368 }
369 
372 
373 }
374 
375 /* 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:38
OUString getString() const
ScAddress aStart
Definition: address.hxx:500
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:563
const SfxPoolItem & GetAttr(SCROW nRow, sal_uInt16 nWhich) const
Definition: column.cxx:374
SCROW Row() const
Definition: address.hxx:262
void setSingleCell(const ScAddress &rSrcPos, const ScColumn &rSrcCol)
Single reference (one address) into the sheet.
Definition: refdata.hxx:30
virtual ~CopyToClipContext() override
void setTabRange(SCTAB nStart, SCTAB nEnd)
Definition: clipcontext.cxx:57
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:2202
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:36
virtual ~ClipContextBase()
Definition: clipcontext.cxx:29
MixDocContext(ScDocument &rDoc)
ScClipParam & GetClipParam()
Definition: document.cxx:2551
ScFormulaCell * mpFormula
Definition: cellvalue.hxx:43
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
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:438
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:559
bool isEmpty() const
void SetFlag3D(bool bVal)
Definition: refdata.hxx:90
void setSingleCellNote(size_t nColOffset, const ScPostIt *pNote)
std::vector< const ScPatternAttr * > maSinglePatterns
Definition: clipcontext.hxx:62
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
Definition: refdata.cxx:27
sal_Int16 SCCOL
Definition: types.hxx:22
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:65
ScDocument * mpRefUndoDoc
Definition: clipcontext.hxx:55
FormulaToken * FirstToken() const
void setDestRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: clipcontext.cxx:73
bool IsEmptyDisplayedAsString()
const ScPatternAttr * getSingleCellPattern(size_t nColOffset) const
CopyToDocContext(ScDocument &rDoc)
void setSingleCellPattern(size_t nColOffset, const ScPatternAttr *pAttr)
FormulaError
SCCOL Col() const
Definition: address.hxx:267
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:63
svl::SharedString GetString()
virtual ~CopyToDocContext() override
ocTrue
sal_Int32 SCROW
Definition: types.hxx:18
ScRange getWholeRange() const
Return a single range that encompasses all individual ranges.
Definition: clipparam.cxx:103
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:68
ScDocument * getUndoDoc()
Definition: clipcontext.cxx:91
SCTAB getTabStart() const
Definition: clipcontext.cxx:63
bool isDateCell(const ScColumn &rCol, SCROW nRow) const
ScDocument * getClipDoc()
Definition: clipcontext.cxx:96
void * p
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:401
InsertDeleteFlags mnDeleteFlag
Definition: clipcontext.hxx:58
InsertDeleteFlags getDeleteFlag() const
void clear() noexcept
Definition: cellvalue.cxx:273
std::unique_ptr< ColumnBlockPositionSet > mpSet
Definition: clipcontext.hxx:33
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:81
const sc::CellTextAttr * GetCellTextAttr(SCROW nRow) const
Definition: column.cxx:793
virtual ~CopyFromClipContext() override
Definition: clipcontext.cxx:53
virtual ~MixDocContext() override
void SetErrCode(FormulaError n)
std::vector< sc::CellTextAttr > maSingleCellAttrs
Definition: clipcontext.hxx:61
aStr
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:454
sal_Int16 SCTAB
Definition: types.hxx:23
ColumnBlockPosition * getBlockPosition(SCTAB nTab, SCCOL nCol)
Definition: clipcontext.cxx:31
std::vector< ScCellValue > maSingleCells
Definition: clipcontext.hxx:60
InsertDeleteFlags mnInsertFlag
Definition: clipcontext.hxx:57
bool isKeepScenarioFlags() const
bool isCloneNotes() const