summaryrefslogtreecommitdiffstats
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2011-09-09 16:30:46 -0400
committerKohei Yoshida <kohei.yoshida@suse.com>2011-09-12 13:22:03 -0400
commitb2f1120984b60715c01b6c743e980b89835bc135 (patch)
tree51bf62e01f651fff7721fc315c360893fcb77a9f /sc
parentRevert "n#676858: added new menu entry for headers/footers edit mode" (diff)
downloadcore-b2f1120984b60715c01b6c743e980b89835bc135.tar.gz
core-b2f1120984b60715c01b6c743e980b89835bc135.zip
Got the normal paste to work. Still no undo etc.
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/rangelst.hxx2
-rw-r--r--sc/source/core/tool/rangelst.cxx25
-rw-r--r--sc/source/ui/inc/viewfunc.hxx12
-rw-r--r--sc/source/ui/view/viewfun3.cxx159
4 files changed, 185 insertions, 13 deletions
diff --git a/sc/inc/rangelst.hxx b/sc/inc/rangelst.hxx
index b07c7c90044b..cc2c83abea88 100644
--- a/sc/inc/rangelst.hxx
+++ b/sc/inc/rangelst.hxx
@@ -78,6 +78,8 @@ public:
ScRange* Remove(size_t nPos);
void RemoveAll();
+ ScRange Combine() const;
+
bool empty() const;
size_t size() const;
ScRange* operator[](size_t idx);
diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx
index cadd0d1ff19b..7a5f0a29c96a 100644
--- a/sc/source/core/tool/rangelst.cxx
+++ b/sc/source/core/tool/rangelst.cxx
@@ -466,6 +466,31 @@ void ScRangeList::RemoveAll()
maRanges.clear();
}
+ScRange ScRangeList::Combine() const
+{
+ if (maRanges.empty())
+ return ScRange();
+
+ vector<ScRange*>::const_iterator itr = maRanges.begin(), itrEnd = maRanges.end();
+ ScRange aRet = **itr;
+ ++itr;
+ for (; itr != itrEnd; ++itr)
+ {
+ const ScRange& r = **itr;
+ SCROW nRow1 = r.aStart.Row(), nRow2 = r.aEnd.Row();
+ SCROW nCol1 = r.aStart.Col(), nCol2 = r.aEnd.Col();
+ if (aRet.aStart.Row() > nRow1)
+ aRet.aStart.SetRow(nRow1);
+ if (aRet.aStart.Col() > nCol1)
+ aRet.aStart.SetCol(nCol1);
+ if (aRet.aEnd.Row() < nRow2)
+ aRet.aEnd.SetRow(nRow2);
+ if (aRet.aEnd.Col() < nCol2)
+ aRet.aEnd.SetCol(nCol2);
+ }
+ return aRet;
+}
+
bool ScRangeList::empty() const
{
return maRanges.empty();
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index c11c77f174c4..e8b265123f95 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -358,9 +358,15 @@ private:
void PasteRTF( SCCOL nCol, SCROW nStartRow,
const ::com::sun::star::uno::Reference<
::com::sun::star::datatransfer::XTransferable >& rxTransferable );
- bool PasteMultiRangesFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
- bool bSkipEmpty, bool bTranspos, bool bAsLink, bool bAllowDialogs,
- InsCellCmd eMoveMode, sal_uInt16 nCondFlags, sal_uInt16 nUndoFlags );
+
+ bool PasteMultiRangesFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
+ bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, sal_uInt16 nUndoFlags );
+
+ bool PasteFromClipToMultiRanges( sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
+ bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, sal_uInt16 nUndoFlags );
+
void PostPasteFromClip(const ScRange& rPasteRange, const ScMarkData& rMark);
sal_uInt16 GetOptimalColWidth( SCCOL nCol, SCTAB nTab, sal_Bool bFormula );
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index 62dcdbe04ad0..f253c771ca49 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -907,14 +907,20 @@ private:
ScViewFunc* mpViewFunc;
};
-bool lcl_checkDestRangeForOverwrite(const ScRange& rDestRange, const ScDocument* pDoc, const ScMarkData& rMark, Window* pParentWnd)
+bool checkDestRangeForOverwrite(const ScRangeList& rDestRanges, const ScDocument* pDoc, const ScMarkData& rMark, Window* pParentWnd)
{
bool bIsEmpty = true;
- ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
- for (; itr != itrEnd && bIsEmpty; ++itr)
+ ScMarkData::const_iterator itrTab = rMark.begin(), itrTabEnd = rMark.end();
+ size_t nRangeSize = rDestRanges.size();
+ for (; itrTab != itrTabEnd && bIsEmpty; ++itrTab)
{
- bIsEmpty = pDoc->IsBlockEmpty(*itr, rDestRange.aStart.Col(), rDestRange.aStart.Row(),
- rDestRange.aEnd.Col(), rDestRange.aEnd.Row());
+ for (size_t i = 0; i < nRangeSize && bIsEmpty; ++i)
+ {
+ const ScRange& rRange = *rDestRanges[i];
+ bIsEmpty = pDoc->IsBlockEmpty(
+ *itrTab, rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row());
+ }
}
if (!bIsEmpty)
@@ -958,9 +964,21 @@ bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
ScClipParam& rClipParam = pClipDoc->GetClipParam();
if (rClipParam.isMultiRange())
+ {
+ // Source data is multi-range.
return PasteMultiRangesFromClip(
nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
- eMoveMode, nContFlags, nUndoFlags);
+ eMoveMode, nUndoFlags);
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if (rMark.IsMultiMarked())
+ {
+ // Source data is single-range but destination is multi-range.
+ return PasteFromClipToMultiRanges(
+ nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
+ eMoveMode, nUndoFlags);
+ }
bool bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc
bool bIncludeFiltered = bCutMode;
@@ -1016,7 +1034,6 @@ bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
ScDocument* pDoc = GetViewData()->GetDocument();
ScDocShell* pDocSh = GetViewData()->GetDocShell();
- ScMarkData& rMark = GetViewData()->GetMarkData();
::svl::IUndoManager* pUndoMgr = pDocSh->GetUndoManager();
const bool bRecord(pDoc->IsUndoEnabled());
@@ -1202,7 +1219,9 @@ bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
if ( bAskIfNotEmpty )
{
- if (!lcl_checkDestRangeForOverwrite(aUserRange, pDoc, aFilteredMark, GetViewData()->GetDialogParent()))
+ ScRangeList aTestRanges;
+ aTestRanges.Append(aUserRange);
+ if (!checkDestRangeForOverwrite(aTestRanges, pDoc, aFilteredMark, GetViewData()->GetDialogParent()))
return false;
}
}
@@ -1516,7 +1535,7 @@ bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
bool ScViewFunc::PasteMultiRangesFromClip(
sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
- InsCellCmd eMoveMode, sal_uInt16 /*nContFlags*/, sal_uInt16 nUndoFlags)
+ InsCellCmd eMoveMode, sal_uInt16 nUndoFlags)
{
ScViewData& rViewData = *GetViewData();
ScDocument* pDoc = rViewData.GetDocument();
@@ -1575,7 +1594,9 @@ bool ScViewFunc::PasteMultiRangesFromClip(
if (bAskIfNotEmpty)
{
- if (!lcl_checkDestRangeForOverwrite(aMarkedRange, pDoc, aMark, rViewData.GetDialogParent()))
+ ScRangeList aTestRanges;
+ aTestRanges.Append(aMarkedRange);
+ if (!checkDestRangeForOverwrite(aTestRanges, pDoc, aMark, rViewData.GetDialogParent()))
return false;
}
@@ -1673,6 +1694,124 @@ bool ScViewFunc::PasteMultiRangesFromClip(
return true;
}
+bool ScViewFunc::PasteFromClipToMultiRanges(
+ sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
+ bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, sal_uInt16 nUndoFlags )
+{
+ if (bTranspose)
+ {
+ // We don't allow transpose for this yet.
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return false;
+ }
+
+ if (eMoveMode != INS_NONE)
+ {
+ // We don't allow insertion mode either. Too complicated.
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return false;
+ }
+
+ ScViewData& rViewData = *GetViewData();
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ if (rClipParam.mbCutMode)
+ {
+ // No cut and paste with this, please.
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return false;
+ }
+
+ const ScAddress& rCurPos = rViewData.GetCurPos();
+ ScDocument* pDoc = rViewData.GetDocument();
+
+ ScRange aSrcRange = rClipParam.getWholeRange();
+ SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
+ SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
+
+ if (!ValidCol(rCurPos.Col()+nColSize-1) || !ValidRow(rCurPos.Row()+nRowSize-1))
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return false;
+ }
+
+ ScMarkData aMark(rViewData.GetMarkData());
+
+ ScRangeList aRanges;
+ aMark.MarkToSimple();
+ aMark.FillRangeListWithMarks(&aRanges, false);
+ for (size_t i = 0, n = aRanges.size(); i < n; ++i)
+ {
+ ScRange aTest = *aRanges[i];
+ // Check for filtered rows in all selected sheets.
+ ScMarkData::const_iterator itrTab = aMark.begin(), itrTabEnd = aMark.end();
+ for (; itrTab != itrTabEnd; ++itrTab)
+ {
+ aTest.aStart.SetTab(*itrTab);
+ aTest.aEnd.SetTab(*itrTab);
+ if (ScViewUtil::HasFiltered(aTest, pDoc))
+ {
+ // I don't know how to handle pasting into filtered rows yet.
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return false;
+ }
+ }
+
+ SCROW nRows = aTest.aEnd.Row() - aTest.aStart.Row() + 1;
+ SCCOL nCols = aTest.aEnd.Col() - aTest.aStart.Col() + 1;
+ if (nRows != nRowSize || nCols != nColSize)
+ {
+ // Source and destination sizes don't match. Bail out.
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return false;
+ }
+ }
+
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+
+ ScDocShellModificator aModificator(*pDocSh);
+
+ bool bAskIfNotEmpty =
+ bAllowDialogs && (nFlags & IDF_CONTENTS) &&
+ nFunction == PASTE_NOFUNC && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
+
+ if (bAskIfNotEmpty)
+ {
+ if (!checkDestRangeForOverwrite(aRanges, pDoc, aMark, rViewData.GetDialogParent()))
+ return false;
+ }
+
+ // First, paste everything but the drawing objects.
+ for (size_t i = 0, n = aRanges.size(); i < n; ++i)
+ {
+ pDoc->CopyFromClip(
+ *aRanges[i], aMark, (nFlags & ~IDF_OBJECTS), NULL, pClipDoc,
+ true, false, true, bSkipEmpty, NULL);
+ }
+
+ AdjustBlockHeight(); // update row heights before pasting objects
+
+ // Then paste the objects.
+ if (nFlags & IDF_OBJECTS)
+ {
+ for (size_t i = 0, n = aRanges.size(); i < n; ++i)
+ {
+ pDoc->CopyFromClip(
+ *aRanges[i], aMark, IDF_OBJECTS, NULL, pClipDoc,
+ true, false, true, bSkipEmpty, NULL);
+ }
+ }
+
+ // Refresh the range that includes all pasted ranges. We only need to
+ // refresh the current sheet.
+ ScRange aRefreshRange = aRanges.Combine();
+ aRefreshRange.aStart.SetTab(rViewData.GetTabNo());
+ aRefreshRange.aEnd.SetTab(rViewData.GetTabNo());
+ pDocSh->PostPaint(aRefreshRange, PAINT_GRID);
+
+ return false;
+}
+
void ScViewFunc::PostPasteFromClip(const ScRange& rPasteRange, const ScMarkData& rMark)
{
ScViewData* pViewData = GetViewData();