diff options
author | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-09-09 16:30:46 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-09-12 13:22:03 -0400 |
commit | b2f1120984b60715c01b6c743e980b89835bc135 (patch) | |
tree | 51bf62e01f651fff7721fc315c360893fcb77a9f /sc/source | |
parent | ecc5249190af915d98856939281afcd648eaac2b (diff) |
Got the normal paste to work. Still no undo etc.
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/core/tool/rangelst.cxx | 25 | ||||
-rw-r--r-- | sc/source/ui/inc/viewfunc.hxx | 12 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun3.cxx | 159 |
3 files changed, 183 insertions, 13 deletions
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(); |