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 bSkipEmptyCells) :
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), mbSkipEmptyCells(bSkipEmptyCells),
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  maSingleSparkline.resize(nSize);
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 
303 std::shared_ptr<sc::Sparkline> const& CopyFromClipContext::getSingleSparkline(size_t nColOffset) const
304 {
305  assert(nColOffset < maSingleSparkline.size());
306  return maSingleSparkline[nColOffset];
307 }
308 
309 void CopyFromClipContext::setSingleSparkline(size_t nColOffset, std::shared_ptr<sc::Sparkline> const& pSparkline)
310 {
311  assert(nColOffset < maSingleSparkline.size());
312  maSingleSparkline[nColOffset] = pSparkline;
313 }
314 
316 {
317  mpCondFormatList = pCondFormatList;
318 }
319 
321 {
322  return mpCondFormatList;
323 }
324 
326 {
327  mbTableProtected = b;
328 }
329 
331 {
332  return mbTableProtected;
333 }
334 
336 {
337  return mbAsLink;
338 }
339 
341 {
342  return mbSkipEmptyCells;
343 }
344 
346 {
348 }
349 
351 {
353 }
354 
355 bool CopyFromClipContext::isDateCell( const ScColumn& rCol, SCROW nRow ) const
356 {
357  sal_uLong nNumIndex = rCol.GetAttr(nRow, ATTR_VALUE_FORMAT).GetValue();
359  return (nType == SvNumFormatType::DATE) || (nType == SvNumFormatType::TIME) || (nType == SvNumFormatType::DATETIME);
360 }
361 
363  ScDocument& rDoc, bool bKeepScenarioFlags) :
364  ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags) {}
365 
367 
369 {
370  return mbKeepScenarioFlags;
371 }
372 
374  ClipContextBase(rDoc), mbStartListening(true) {}
375 
377 
379 {
380  mbStartListening = b;
381 }
382 
384 {
385  return mbStartListening;
386 }
387 
390 
391 }
392 
393 /* 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:497
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:584
SCROW Row() const
Definition: address.hxx:274
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:57
ScTokenArray * GetCode()
sal_uIntPtr sal_uLong
bool isStartListening() const
const SfxPoolItem & GetAttr(SCROW nRow, sal_uInt16 nWhich) const
Definition: column.hxx:959
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
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:2592
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
std::vector< std::shared_ptr< sc::Sparkline > > maSingleSparkline
Definition: clipcontext.hxx:64
Internal use only (copy from clip): do not delete existing cell contents when pasting notes...
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:459
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:616
bool isEmpty() const
std::shared_ptr< sc::Sparkline > const & getSingleSparkline(size_t nColOffset) const
bool isCloneSparklines() 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:62
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:147
CopyToClipContext(ScDocument &rDoc, bool bKeepScenarioFlags)
CAUTION! The following defines must be in the same namespace as the respective type.
const SvxPageUsage aArr[]
std::unique_ptr< EditTextObject > CreateTextObject()
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
SvNumFormatType
ScConditionalFormatList * mpCondFormatList
Definition: clipcontext.hxx:66
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)
const svl::SharedString & GetString()
FormulaError
SCCOL Col() const
Definition: address.hxx:279
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
virtual ~CopyToDocContext() override
ocTrue
bool isSkipEmptyCells() const
Get the flag that indicates whether the "skip empty cells" paste option is selected.
sal_Int32 SCROW
Definition: types.hxx:17
ScRange getWholeRange() const
Return a single range that encompasses all individual ranges.
Definition: clipparam.cxx:109
void setSingleSparkline(size_t nColOffset, std::shared_ptr< sc::Sparkline > const &pSparkline)
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:398
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:700
virtual ~CopyFromClipContext() override
Definition: clipcontext.cxx:53
virtual ~MixDocContext() override
void SetErrCode(FormulaError n)
std::vector< sc::CellTextAttr > maSingleCellAttrs
Definition: clipcontext.hxx:61
aStr
Strings (and string results if InsertDeleteFlags::FORMULA is not set).
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:475
sal_Int16 SCTAB
Definition: types.hxx:22
ColumnBlockPosition * getBlockPosition(SCTAB nTab, SCCOL nCol)
Definition: clipcontext.cxx:32
std::vector< ScCellValue > maSingleCells
Definition: clipcontext.hxx:60
bool m_bDetectedRangeSegmentation false
InsertDeleteFlags mnInsertFlag
Definition: clipcontext.hxx:57
Sheet / outlining (grouping) information.
bool isKeepScenarioFlags() const
bool isCloneNotes() const