1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <cliputil.hxx>
12 #include <viewdata.hxx>
13 #include <tabvwsh.hxx>
14 #include <transobj.hxx>
15 #include <document.hxx>
16 #include <dpobject.hxx>
17 #include <globstr.hrc>
18 #include <clipparam.hxx>
19 #include <clipoptions.hxx>
20 #include <rangelst.hxx>
21 #include <viewutil.hxx>
22 #include <markdata.hxx>
23 #include <gridwin.hxx>
24 #include <scitems.hxx>
26 #include <sfx2/classificationhelper.hxx>
27 #include <comphelper/lok.hxx>
32 /// Paste only if SfxClassificationHelper recommends so.
33 bool lcl_checkClassification(ScDocument
* pSourceDoc
, const ScDocument
& rDestinationDoc
)
38 ScClipOptions
* pSourceOptions
= pSourceDoc
->GetClipOptions();
39 ScDocShell
* pDestinationShell
= rDestinationDoc
.GetDocumentShell();
40 if (!pSourceOptions
|| !pDestinationShell
)
43 SfxClassificationCheckPasteResult eResult
= SfxClassificationHelper::CheckPaste(pSourceOptions
->m_xDocumentProperties
, pDestinationShell
->getDocProperties());
44 return SfxClassificationHelper::ShowPasteInfo(eResult
);
49 void ScClipUtil::PasteFromClipboard( ScViewData
& rViewData
, ScTabViewShell
* pTabViewShell
, bool bShowDialog
)
51 const ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard(ScTabViewShell::GetClipData(rViewData
.GetActiveWin()));
52 ScDocument
& rThisDoc
= rViewData
.GetDocument();
53 SCCOL nThisCol
= rViewData
.GetCurX();
54 SCROW nThisRow
= rViewData
.GetCurY();
55 SCTAB nThisTab
= rViewData
.GetTabNo();
56 ScDPObject
* pDPObj
= rThisDoc
.GetDPAtCursor( nThisCol
, nThisRow
, nThisTab
);
58 if ( pOwnClip
&& pDPObj
)
60 // paste from Calc into DataPilot table: sort (similar to drag & drop)
62 ScDocument
* pClipDoc
= pOwnClip
->GetDocument();
63 SCTAB nSourceTab
= pOwnClip
->GetVisibleTab();
69 pClipDoc
->GetClipStart( nClipStartX
, nClipStartY
);
70 pClipDoc
->GetClipArea( nClipEndX
, nClipEndY
, true );
71 nClipEndX
= nClipEndX
+ nClipStartX
;
72 nClipEndY
= nClipEndY
+ nClipStartY
; // GetClipArea returns the difference
74 ScRange
aSource( nClipStartX
, nClipStartY
, nSourceTab
, nClipEndX
, nClipEndY
, nSourceTab
);
75 bool bDone
= pTabViewShell
->DataPilotMove( aSource
, rViewData
.GetCurPos() );
77 pTabViewShell
->ErrorMessage( STR_ERR_DATAPILOT_INPUT
);
82 weld::WaitObject
aWait( rViewData
.GetDialogParent() );
85 pTabViewShell
->PasteFromSystem();
86 // Anchor To Cell rather than To Page
87 ScDrawView
* pDrawView
= pTabViewShell
->GetScDrawView();
90 const SdrMarkList
& rMarkList
= pDrawView
->GetMarkedObjectList();
91 if (1 == rMarkList
.GetMarkCount())
93 SdrObject
* pPickObj
= rMarkList
.GetMark(0)->GetMarkedSdrObj();
96 ScDrawLayer::SetCellAnchoredFromPosition( *pPickObj
, rThisDoc
, nThisTab
, false );
103 ScDocument
* pClipDoc
= pOwnClip
->GetDocument();
104 InsertDeleteFlags nFlags
= InsertDeleteFlags::ALL
;
105 if (pClipDoc
->GetClipParam().isMultiRange())
106 // For multi-range paste, we paste values by default.
107 nFlags
&= ~InsertDeleteFlags::FORMULA
;
109 if (lcl_checkClassification(pClipDoc
, rThisDoc
))
110 pTabViewShell
->PasteFromClip( nFlags
, pClipDoc
,
111 ScPasteFunc::NONE
, false, false, false, INS_NONE
, InsertDeleteFlags::NONE
,
112 bShowDialog
); // allow warning dialog
115 if (comphelper::LibreOfficeKit::isActive())
117 bool entireColumnOrRowSelected
= false;
120 ScClipParam clipParam
= pOwnClip
->GetDocument()->GetClipParam();
121 if (clipParam
.maRanges
.size() > 0)
123 if (clipParam
.maRanges
[0].aEnd
.Col() == pOwnClip
->GetDocument()->MaxCol()
124 || clipParam
.maRanges
[0].aEnd
.Row() == pOwnClip
->GetDocument()->MaxRow())
126 entireColumnOrRowSelected
= true;
130 const SfxBoolItem
* pItem
= rThisDoc
.GetAttr(nThisCol
, nThisRow
, nThisTab
, ATTR_LINEBREAK
);
131 if (pItem
->GetValue() || entireColumnOrRowSelected
)
133 pTabViewShell
->OnLOKSetWidthOrHeight(nThisCol
, true);
134 pTabViewShell
->OnLOKSetWidthOrHeight(nThisRow
, false);
136 ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
137 pTabViewShell
, true /* bColumns */, true /* bRows */, true /* bSizes*/,
138 true /* bHidden */, true /* bFiltered */, true /* bGroups */, nThisTab
);
141 pTabViewShell
->CellContentChanged(); // => PasteFromSystem() ???
144 bool ScClipUtil::CheckDestRanges(
145 const ScDocument
& rDoc
, SCCOL nSrcCols
, SCROW nSrcRows
, const ScMarkData
& rMark
, const ScRangeList
& rDest
)
147 for (size_t i
= 0, n
= rDest
.size(); i
< n
; ++i
)
149 ScRange aTest
= rDest
[i
];
150 // Check for filtered rows in all selected sheets.
151 for (const auto& rTab
: rMark
)
153 aTest
.aStart
.SetTab(rTab
);
154 aTest
.aEnd
.SetTab(rTab
);
155 if (ScViewUtil::HasFiltered(aTest
, rDoc
))
157 // I don't know how to handle pasting into filtered rows yet.
162 // Destination range must be an exact multiple of the source range.
163 SCROW nRows
= aTest
.aEnd
.Row() - aTest
.aStart
.Row() + 1;
164 SCCOL nCols
= aTest
.aEnd
.Col() - aTest
.aStart
.Col() + 1;
165 SCROW nRowTest
= (nRows
/ nSrcRows
) * nSrcRows
;
166 SCCOL nColTest
= (nCols
/ nSrcCols
) * nSrcCols
;
167 if ( rDest
.size() > 1 && ( nRows
!= nRowTest
|| nCols
!= nColTest
) )
169 // Destination range is not a multiple of the source range. Bail out.
176 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */