diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-01-24 11:38:47 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-01-24 21:27:10 -0500 |
commit | 80ea2822c368e6655d216c32904268fc335ef6a4 (patch) | |
tree | 34576d69618b93399fe40395d3005dd3735bc855 | |
parent | f634bc18a0594cc103c1f8a3e0e34fb6024c666d (diff) |
Optimize copy-n-pasting of single cell replicated over a range.
This is a very common operation. Let's speed it up a bit.
TODO : Handle cell comments.
Change-Id: I5442bf19008475a9427b889c1eb641cacd8ff161
-rw-r--r-- | sc/Library_sc.mk | 3 | ||||
-rw-r--r-- | sc/inc/attarray.hxx | 1 | ||||
-rw-r--r-- | sc/inc/cellvalue.hxx | 1 | ||||
-rw-r--r-- | sc/inc/clipcontext.hxx | 20 | ||||
-rw-r--r-- | sc/inc/column.hxx | 10 | ||||
-rw-r--r-- | sc/inc/document.hxx | 4 | ||||
-rw-r--r-- | sc/inc/table.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/attarray.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/cellvalue.cxx | 24 | ||||
-rw-r--r-- | sc/source/core/data/clipcontext.cxx | 29 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 12 | ||||
-rw-r--r-- | sc/source/core/data/column4.cxx | 124 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 170 | ||||
-rw-r--r-- | sc/source/core/data/table7.cxx | 27 |
16 files changed, 430 insertions, 22 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index d75ce95730b5..1ed89c6d4abb 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -105,6 +105,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/column \ sc/source/core/data/column2 \ sc/source/core/data/column3 \ + sc/source/core/data/column4 \ sc/source/core/data/columniterator \ sc/source/core/data/columnset \ sc/source/core/data/columnspanset \ @@ -124,6 +125,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/documen8 \ sc/source/core/data/documen9 \ sc/source/core/data/document \ + sc/source/core/data/document10 \ sc/source/core/data/documentimport \ sc/source/core/data/documentstreamaccess \ sc/source/core/data/dpdimsave \ @@ -180,6 +182,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/table4 \ sc/source/core/data/table5 \ sc/source/core/data/table6 \ + sc/source/core/data/table7 \ sc/source/core/data/tabprotection \ sc/source/core/data/types \ sc/source/core/data/userdat \ diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index 2d52279d13c7..5b9494d9a9eb 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -154,6 +154,7 @@ public: bool Search( SCROW nRow, SCSIZE& nIndex ) const; bool HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const; + bool IsMerged( SCROW nRow ) const; bool ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow, SCCOL& rPaintCol, SCROW& rPaintRow, bool bRefresh ); diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx index c2606b511e72..94af1469e570 100644 --- a/sc/inc/cellvalue.hxx +++ b/sc/inc/cellvalue.hxx @@ -50,6 +50,7 @@ struct SC_DLLPUBLIC ScCellValue void clear(); + void set( const ScRefCellValue& rCell ); void set( double fValue ); void set( const svl::SharedString& rStr ); void set( const EditTextObject& rEditText ); diff --git a/sc/inc/clipcontext.hxx b/sc/inc/clipcontext.hxx index dd63ba6c36c6..c693c7f533a7 100644 --- a/sc/inc/clipcontext.hxx +++ b/sc/inc/clipcontext.hxx @@ -11,6 +11,7 @@ #define SC_CLIPCONTEXT_HXX #include "address.hxx" +#include <cellvalue.hxx> #include <vector> #include <boost/unordered_map.hpp> @@ -18,6 +19,8 @@ #include <boost/scoped_ptr.hpp> class ScDocument; +class ScColumn; +class ScPatternAttr; namespace sc { @@ -44,9 +47,11 @@ class CopyFromClipContext : public ClipContextBase ScDocument* mpRefUndoDoc; ScDocument* mpClipDoc; sal_uInt16 mnInsertFlag; - bool mbAsLink:1; - bool mbSkipAttrForEmptyCells:1; - bool mbCloneNotes; + ScCellValue maSingleCell; + const ScPatternAttr* mpSinglePattern; + bool mbAsLink:1; + bool mbSkipAttrForEmptyCells:1; + bool mbCloneNotes:1; CopyFromClipContext(); // disabled @@ -65,9 +70,16 @@ public: ScDocument* getUndoDoc(); ScDocument* getClipDoc(); sal_uInt16 getInsertFlag() const; + + ScCellValue& getSingleCell(); + + const ScPatternAttr* getSingleCellPattern() const; + void setSingleCellPattern( const ScPatternAttr* pAttr ); + bool isAsLink() const; bool isSkipAttrForEmptyCells() const; - bool isCloneNotes() const; + bool isCloneNotes() const; + bool isDateCell( const ScColumn& rCol, SCROW nRow ) const; }; class CopyToClipContext : public ClipContextBase diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 3127cf49334c..e08226cd3917 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -177,6 +177,7 @@ public: bool HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const; bool HasAttribSelection( const ScMarkData& rMark, sal_uInt16 nMask ) const; + bool IsMerged( SCROW nRow ) const; bool ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow, SCCOL& rPaintCol, SCROW& rPaintRow, bool bRefresh ); @@ -220,6 +221,9 @@ public: void CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDestCol ); bool InitBlockPosition( sc::ColumnBlockPosition& rBlockPos ); bool InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const; + + void CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2 ); + void CopyFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, long nDy, ScColumn& rColumn ); @@ -509,8 +513,10 @@ public: SCROW GetCellNotesMaxRow() const; SCROW GetCellNotesMinRow() const; - void CopyCellNotesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption = true, - SCROW nRowOffsetDest=0) const; + void CopyCellNotesToDocument( + SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption = true, + SCROW nRowOffsetDest = 0) const; + void DuplicateNotes(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol, sc::ColumnBlockPosition& maDestBlockPos, bool bCloneCaption = true, SCROW nRowOffsetDest=0 ) const; void UpdateNoteCaptions(); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 2f1ecdc160b0..6a980ab298f2 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -917,6 +917,8 @@ public: SC_DLLPUBLIC void SetDrawPageSize(SCTAB nTab); + bool IsMerged( const ScAddress& rPos ) const; + bool ExtendMergeSel( SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW& rEndRow, const ScMarkData& rMark, bool bRefresh = false ); @@ -1192,6 +1194,8 @@ public: bool InitColumnBlockPosition( sc::ColumnBlockPosition& rBlokPos, SCTAB nTab, SCCOL nCol ); + bool CopyOneCellFromClip( + sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ); void CopyBlockFromClip( sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark, SCsCOL nDx, SCsROW nDy ); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index f7d338953e6a..00bddb975f0d 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -409,6 +409,9 @@ public: bool InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol ); + void CopyOneCellFromClip( + sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ); + void CopyFromClip( sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCsCOL nDx, SCsROW nDy, ScTable* pTable ); @@ -560,6 +563,7 @@ public: bool HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uInt16 nMask ) const; bool HasAttribSelection( const ScMarkData& rMark, sal_uInt16 nMask ) const; + bool IsMerged( SCCOL nCol, SCROW nRow ) const; bool ExtendMerge( SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bRefresh ); 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: */ |