summaryrefslogtreecommitdiff
path: root/sc/source/core/data
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data')
-rw-r--r--sc/source/core/data/attarray.cxx10
-rw-r--r--sc/source/core/data/cellvalue.cxx24
-rw-r--r--sc/source/core/data/clipcontext.cxx29
-rw-r--r--sc/source/core/data/column2.cxx8
-rw-r--r--sc/source/core/data/column3.cxx12
-rw-r--r--sc/source/core/data/column4.cxx124
-rw-r--r--sc/source/core/data/document.cxx5
-rw-r--r--sc/source/core/data/document10.cxx170
-rw-r--r--sc/source/core/data/table7.cxx27
9 files changed, 393 insertions, 16 deletions
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index ec2512f96ba1..bcfdb477f059 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -1374,6 +1374,16 @@ bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const
return bFound;
}
+bool ScAttrArray::IsMerged( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ Search(nRow, nIndex);
+ const ScMergeAttr& rItem =
+ static_cast<const ScMergeAttr&>(pData[nIndex].pPattern->GetItem(ATTR_MERGE));
+
+ return rItem.IsMerged();
+}
+
// Area around any given summaries expand and adapt any MergeFlag (bRefresh)
bool ScAttrArray::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
SCCOL& rPaintCol, SCROW& rPaintRow,
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index 12ef30272e62..d963fa31bc5a 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -227,6 +227,30 @@ void ScCellValue::clear()
mfValue = 0.0;
}
+void ScCellValue::set( const ScRefCellValue& rCell )
+{
+ clear();
+
+ meType = rCell.meType;
+ switch (meType)
+ {
+ case CELLTYPE_VALUE:
+ mfValue = rCell.mfValue;
+ break;
+ case CELLTYPE_STRING:
+ mpString = new svl::SharedString(*rCell.mpString);
+ break;
+ case CELLTYPE_EDIT:
+ mpEditText = rCell.mpEditText->Clone();
+ break;
+ case CELLTYPE_FORMULA:
+ mpFormula = rCell.mpFormula->Clone();
+ break;
+ default:
+ ;
+ }
+}
+
void ScCellValue::set( double fValue )
{
clear();
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 8013684867ee..764d66f6ccb0 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -10,6 +10,10 @@
#include "clipcontext.hxx"
#include "document.hxx"
#include "mtvelements.hxx"
+#include <column.hxx>
+#include <scitems.hxx>
+
+#include <svl/intitem.hxx>
namespace sc {
@@ -29,8 +33,9 @@ CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc,
ClipContextBase(rDoc),
mnTabStart(-1), mnTabEnd(-1),
mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc), mnInsertFlag(nInsertFlag),
+ mpSinglePattern(NULL),
mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells),
- mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES) )
+ mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES))
{
}
@@ -69,6 +74,21 @@ sal_uInt16 CopyFromClipContext::getInsertFlag() const
return mnInsertFlag;
}
+ScCellValue& CopyFromClipContext::getSingleCell()
+{
+ return maSingleCell;
+}
+
+const ScPatternAttr* CopyFromClipContext::getSingleCellPattern() const
+{
+ return mpSinglePattern;
+}
+
+void CopyFromClipContext::setSingleCellPattern( const ScPatternAttr* pAttr )
+{
+ mpSinglePattern = pAttr;
+}
+
bool CopyFromClipContext::isAsLink() const
{
return mbAsLink;
@@ -84,6 +104,13 @@ bool CopyFromClipContext::isCloneNotes() const
return mbCloneNotes;
}
+bool CopyFromClipContext::isDateCell( const ScColumn& rCol, SCROW nRow ) const
+{
+ sal_uLong nNumIndex = static_cast<const SfxUInt32Item*>(rCol.GetAttr(nRow, ATTR_VALUE_FORMAT))->GetValue();
+ short nType = mpClipDoc->GetFormatTable()->GetType(nNumIndex);
+ return (nType == NUMBERFORMAT_DATE) || (nType == NUMBERFORMAT_TIME) || (nType == NUMBERFORMAT_DATETIME);
+}
+
CopyToClipContext::CopyToClipContext(
ScDocument& rDoc, bool bKeepScenarioFlags, bool bCloneNotes) :
ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags), mbCloneNotes(bCloneNotes) {}
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index b891276aef32..22fea460b4a1 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1749,7 +1749,8 @@ void ScColumn::CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& r
}
}
-void ScColumn::CopyCellNotesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption, SCROW nRowOffsetDest) const
+void ScColumn::CopyCellNotesToDocument(
+ SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption, SCROW nRowOffsetDest ) const
{
SCCOL nDestCol = rDestCol.GetCol();
SCTAB nDestTab = rDestCol.GetTab();
@@ -1825,7 +1826,6 @@ void ScColumn::CopyCellNotesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDest
vCloned.push_back(pClonedNote);
}
rDestCol.maCellNotes.set(rDestCol.maCellNotes.begin(), nBlockStart + nOffsetInBlock + nRowOffsetDest, vCloned.begin(), vCloned.end());
-
}
}
}
@@ -1833,8 +1833,8 @@ void ScColumn::CopyCellNotesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDest
void ScColumn::DuplicateNotes(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol, sc::ColumnBlockPosition& maDestBlockPos,
bool bCloneCaption, SCROW nRowOffsetDest ) const
{
- CopyCellNotesToDocument(nStartRow, nStartRow + nDataSize -1, rDestCol, bCloneCaption, nRowOffsetDest);
- maDestBlockPos.miCellNotePos = rDestCol.maCellNotes.begin();
+ CopyCellNotesToDocument(nStartRow, nStartRow + nDataSize -1, rDestCol, bCloneCaption, nRowOffsetDest);
+ maDestBlockPos.miCellNotePos = rDestCol.maCellNotes.begin();
}
void ScColumn::SwapCellTextAttrs( SCROW nRow1, SCROW nRow2 )
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 798d5444a570..2301b0f8590f 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -680,14 +680,6 @@ class CopyCellsFromClipHandler
sc::ColumnBlockPosition maDestBlockPos;
sc::ColumnBlockPosition* mpDestBlockPos; // to save it for next iteration.
- bool isDateCell(SCROW nSrcRow) const
- {
- ScDocument* pSrcDoc = mrCxt.getClipDoc(); // clip document is the source.
- sal_uLong nNumIndex = static_cast<const SfxUInt32Item*>(mrSrcCol.GetAttr(nSrcRow, ATTR_VALUE_FORMAT))->GetValue();
- short nType = pSrcDoc->GetFormatTable()->GetType(nNumIndex);
- return (nType == NUMBERFORMAT_DATE) || (nType == NUMBERFORMAT_TIME) || (nType == NUMBERFORMAT_DATETIME);
- }
-
void insertRefCell(SCROW nSrcRow, SCROW nDestRow)
{
ScAddress aSrcPos(mnSrcCol, nSrcRow, mnSrcTab);
@@ -770,7 +762,7 @@ public:
std::advance(itEnd, nDataSize);
for (SCROW nSrcRow = nSrcRow1; it != itEnd; ++it, ++nSrcRow)
{
- bool bCopy = isDateCell(nSrcRow) ? bDateTime : bNumeric;
+ bool bCopy = mrCxt.isDateCell(mrSrcCol, nSrcRow) ? bDateTime : bNumeric;
if (!bCopy)
continue;
@@ -877,7 +869,7 @@ public:
}
else if (rSrcCell.IsValue())
{
- bool bCopy = isDateCell(nSrcRow) ? bDateTime : bNumeric;
+ bool bCopy = mrCxt.isDateCell(mrSrcCol, nSrcRow) ? bDateTime : bNumeric;
if (!bCopy)
continue;
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
new file mode 100644
index 000000000000..48c38267f0d0
--- /dev/null
+++ b/sc/source/core/data/column4.cxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <column.hxx>
+#include <clipcontext.hxx>
+#include <cellvalue.hxx>
+#include <attarray.hxx>
+#include <document.hxx>
+
+#include <svl/sharedstring.hxx>
+
+#include <vector>
+#include <cassert>
+
+bool ScColumn::IsMerged( SCROW nRow ) const
+{
+ return pAttrArray->IsMerged(nRow);
+}
+
+void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2 )
+{
+ assert(nRow1 <= nRow2);
+
+ size_t nDestSize = nRow2 - nRow1 + 1;
+ sc::ColumnBlockPosition* pBlockPos = rCxt.getBlockPosition(nTab, nCol);
+ if (!pBlockPos)
+ return;
+
+ ScCellValue& rSrcCell = rCxt.getSingleCell();
+
+ sal_uInt16 nFlags = rCxt.getInsertFlag();
+
+ if ((nFlags & IDF_ATTRIB) != 0)
+ {
+ if (!rCxt.isSkipAttrForEmptyCells() || rSrcCell.meType != CELLTYPE_NONE)
+ {
+ const ScPatternAttr* pAttr = rCxt.getSingleCellPattern();
+ pAttrArray->SetPatternArea(nRow1, nRow2, pAttr, true);
+ }
+ }
+
+ if ((nFlags & IDF_CONTENTS) != 0)
+ {
+ switch (rSrcCell.meType)
+ {
+ case CELLTYPE_VALUE:
+ {
+ std::vector<double> aVals(nDestSize, rSrcCell.mfValue);
+ pBlockPos->miCellPos =
+ maCells.set(pBlockPos->miCellPos, nRow1, aVals.begin(), aVals.end());
+ CellStorageModified();
+ }
+ break;
+ case CELLTYPE_STRING:
+ {
+ std::vector<svl::SharedString> aStrs(nDestSize, *rSrcCell.mpString);
+ maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+ CellStorageModified();
+ }
+ break;
+ case CELLTYPE_EDIT:
+ {
+ std::vector<EditTextObject*> aStrs;
+ aStrs.reserve(nDestSize);
+ for (size_t i = 0; i < nDestSize; ++i)
+ aStrs.push_back(rSrcCell.mpEditText->Clone());
+
+ pBlockPos->miCellPos =
+ maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+ CellStorageModified();
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ std::vector<ScFormulaCell*> aFormulas;
+ ScAddress aPos(nCol, nRow1, nTab);
+ aFormulas.reserve(nDestSize);
+ ScFormulaCellGroupRef xGroup(new ScFormulaCellGroup);
+ xGroup->setCode(*rSrcCell.mpFormula->GetCode());
+ xGroup->compileCode(*pDocument, aPos, pDocument->GetGrammar());
+ for (size_t i = 0; i < nDestSize; ++i)
+ {
+ ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, xGroup);
+ if (i == 0)
+ {
+ xGroup->mpTopCell = pCell;
+ xGroup->mnLength = nDestSize;
+ }
+ aFormulas.push_back(pCell);
+ aPos.IncRow();
+ }
+
+ pBlockPos->miCellPos =
+ maCells.set(pBlockPos->miCellPos, nRow1, aFormulas.begin(), aFormulas.end());
+
+ // Join the top and bottom of the pasted formula cells as needed.
+ sc::CellStoreType::position_type aPosObj =
+ maCells.position(pBlockPos->miCellPos, nRow1);
+
+ assert(aPosObj.first->type == sc::element_type_formula);
+ ScFormulaCell* pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
+ JoinNewFormulaCell(aPosObj, *pCell);
+
+ aPosObj = maCells.position(aPosObj.first, nRow2);
+ assert(aPosObj.first->type == sc::element_type_formula);
+ pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
+ JoinNewFormulaCell(aPosObj, *pCell);
+
+ CellStorageModified();
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 27b419c20781..1f00bd7ccb13 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -95,6 +95,7 @@
#include "scopetools.hxx"
#include "refupdatecontext.hxx"
#include "formulagroup.hxx"
+#include <tokenarray.hxx>
#include "formula/vectortoken.hxx"
@@ -2690,6 +2691,9 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
DeleteArea(nCol1, nRow1, nCol2, nRow2, rMark, nDelFlag);
+ if (CopyOneCellFromClip(aCxt, nCol1, nRow1, nCol2, nRow2))
+ continue;
+
SCCOL nC1 = nCol1;
SCROW nR1 = nRow1;
SCCOL nC2 = nC1 + nXw;
@@ -5290,7 +5294,6 @@ bool ScDocument::ExtendOverlapped( SCCOL& rStartCol, SCROW& rStartRow,
return bFound;
}
-
bool ScDocument::ExtendMergeSel( SCCOL nStartCol, SCROW nStartRow,
SCCOL& rEndCol, SCROW& rEndRow,
const ScMarkData& rMark, bool bRefresh )
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
new file mode 100644
index 000000000000..1178ce703155
--- /dev/null
+++ b/sc/source/core/data/document10.cxx
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <document.hxx>
+#include <clipcontext.hxx>
+#include <formulacell.hxx>
+#include <clipparam.hxx>
+#include <table.hxx>
+#include <tokenarray.hxx>
+#include <editutil.hxx>
+
+// Add totally brand-new methods to this source file.
+
+bool ScDocument::IsMerged( const ScAddress& rPos ) const
+{
+ const ScTable* pTab = FetchTable(rPos.Tab());
+ if (!pTab)
+ return false;
+
+ return pTab->IsMerged(rPos.Col(), rPos.Row());
+}
+
+bool ScDocument::CopyOneCellFromClip(
+ sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ ScDocument* pClipDoc = rCxt.getClipDoc();
+ ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
+ if (aClipRange.aStart != aClipRange.aEnd)
+ // The source is not really a single cell. Bail out.
+ return false;
+
+ ScAddress aSrcPos = aClipRange.aStart;
+ if (pClipDoc->IsMerged(aSrcPos))
+ // We don't handle merged source cell for this.
+ return false;
+
+ ScTable* pSrcTab = pClipDoc->FetchTable(aSrcPos.Tab());
+ if (!pSrcTab)
+ return false;
+
+ ScCellValue& rSrcCell = rCxt.getSingleCell();
+ if (rCxt.isAsLink())
+ {
+ ScSingleRefData aRef;
+ aRef.InitAddress(aSrcPos);
+ aRef.SetFlag3D(true);
+
+ ScTokenArray aArr;
+ aArr.AddSingleReference(aRef);
+ rSrcCell.set(new ScFormulaCell(pClipDoc, aSrcPos, aArr));
+ }
+ else
+ {
+ rSrcCell.set(pClipDoc->GetRefCellValue(aSrcPos));
+ const ScPatternAttr* pAttr = pClipDoc->GetPattern(aSrcPos);
+ rCxt.setSingleCellPattern(pAttr);
+
+ // Check the paste flag to see whether we want to paste this cell. If the
+ // flag says we don't want to paste this cell, we'll return with true.
+ sal_uInt16 nFlags = rCxt.getInsertFlag();
+ bool bNumeric = (nFlags & IDF_VALUE) != 0;
+ bool bDateTime = (nFlags & IDF_DATETIME) != 0;
+ bool bString = (nFlags & IDF_STRING) != 0;
+ bool bBoolean = (nFlags & IDF_SPECIAL_BOOLEAN) != 0;
+ bool bFormula = (nFlags & IDF_FORMULA) != 0;
+
+ switch (rSrcCell.meType)
+ {
+ case CELLTYPE_VALUE:
+ {
+ bool bPaste = rCxt.isDateCell(pSrcTab->aCol[aSrcPos.Col()], aSrcPos.Row()) ? bDateTime : bNumeric;
+ if (!bPaste)
+ // Don't paste this.
+ return true;
+ }
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ if (!bString)
+ // Skip pasting.
+ return true;
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ if (bBoolean)
+ {
+ // Check if this formula cell is a boolean cell, and if so, go ahead and paste it.
+ ScTokenArray* pCode = rSrcCell.mpFormula->GetCode();
+ if (pCode && pCode->GetLen() == 1)
+ {
+ const formula::FormulaToken* p = pCode->First();
+ if (p->GetOpCode() == ocTrue || p->GetOpCode() == ocFalse)
+ // This is a boolean formula. Good.
+ break;
+ }
+ }
+
+ if (bFormula)
+ // Good.
+ break;
+
+ sal_uInt16 nErr = rSrcCell.mpFormula->GetErrCode();
+ if (nErr)
+ {
+ // error codes are cloned with values
+ if (!bNumeric)
+ // Error code is treated as numeric value. Don't paste it.
+ return true;
+ }
+ else if (rSrcCell.mpFormula->IsValue())
+ {
+ bool bPaste = rCxt.isDateCell(pSrcTab->aCol[aSrcPos.Col()], aSrcPos.Row()) ? bDateTime : bNumeric;
+ if (!bPaste)
+ // Don't paste this.
+ return true;
+
+ // Turn this into a numeric cell.
+ rSrcCell.set(rSrcCell.mpFormula->GetValue());
+ }
+ else if (bString)
+ {
+ svl::SharedString aStr = rSrcCell.mpFormula->GetString();
+ if (aStr.isEmpty())
+ // do not clone empty string
+ return true;
+
+ // Turn this into a string or edit cell.
+ if (rSrcCell.mpFormula->IsMultilineResult())
+ {
+ // TODO : Add shared string support to the edit engine to
+ // make this process simpler.
+ ScFieldEditEngine& rEngine = GetEditEngine();
+ rEngine.SetText(rSrcCell.mpFormula->GetString().getString());
+ boost::scoped_ptr<EditTextObject> pObj(rEngine.CreateTextObject());
+ pObj->NormalizeString(GetSharedStringPool());
+ rSrcCell.set(*pObj);
+ }
+ else
+ rSrcCell.set(rSrcCell.mpFormula->GetString());
+ }
+ else
+ // We don't want to paste this. Bail out.
+ return true;
+ }
+ break;
+ case CELLTYPE_NONE:
+ default:
+ // There is nothing to paste.
+ return true;
+ }
+ }
+
+ // All good. Proceed with the pasting.
+
+ SCTAB nTabEnd = rCxt.getTabEnd();
+ for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < static_cast<SCTAB>(maTabs.size()); ++i)
+ maTabs[i]->CopyOneCellFromClip(rCxt, nCol1, nRow1, nCol2, nRow2);
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
new file mode 100644
index 000000000000..ac036aac2baf
--- /dev/null
+++ b/sc/source/core/data/table7.cxx
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <table.hxx>
+
+bool ScTable::IsMerged( SCCOL nCol, SCROW nRow ) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return aCol[nCol].IsMerged(nRow);
+}
+
+void ScTable::CopyOneCellFromClip(
+ sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ aCol[nCol].CopyOneCellFromClip(rCxt, nRow1, nRow2);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */