Kaydet (Commit) b2f11209 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Got the normal paste to work. Still no undo etc.

üst ecc52491
......@@ -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);
......
......@@ -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();
......
......@@ -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 );
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment