50#include <QApplication>
56 const QPointF &shapesOffset,
57 const QRectF &documentRect,
60 QPointF accumulatedFitOffset;
62 Q_FOREACH (
KoShape *shape, shapes) {
65 const QPointF center =
bounds.center() + shapesOffset;
67 const qreal wMargin = (0.5 - fitRatio) *
bounds.width();
68 const qreal hMargin = (0.5 - fitRatio) *
bounds.height();
69 const QRectF allowedRect = documentRect.adjusted(-wMargin, -hMargin, wMargin, hMargin);
73 accumulatedFitOffset += fittedCenter - center;
76 return accumulatedFitOffset;
79bool tryPasteShapes(KisPasteActionFactory::Flags flags,
KisViewManager *view)
93 if (!shapes.isEmpty()) {
101 if (it != topLevelShapes.constEnd()) {
102 const int zIndexOffset = (*it)->zIndex();
107 std::transform(shapes.constBegin(), shapes.constEnd(),
108 std::back_inserter(indexedShapes),
109 [zIndexOffset] (
KoShape *shape) {
110 KoShapeReorderCommand::IndexedShape indexedShape(shape);
111 indexedShape.zIndex += zIndexOffset;
126 if (forceCreateNewLayer) {
127 parentLayer = canvas->
shapeController()->documentBase()->createParentForShapes(shapes,
true, parentCommand);
130 canvas->
shapeController()->addShapesDirect(shapes, parentLayer, parentCommand);
132 QPointF finalShapesOffset;
138 finalShapesOffset = cursorPos - boundingRect.center();
140 }
else if (!forceCreateNewLayer) {
141 bool foundOverlapping =
false;
144 const QPointF offsetStep = 0.1 * QPointF(boundingRect.width(), boundingRect.height());
148 Q_FOREACH (
KoShape *shape, shapes) {
151 bool hasOverlappingShape =
false;
154 hasOverlappingShape =
false;
160 Q_FOREACH (
KoShape *intersectedShape, conflicts) {
161 if (intersectedShape == shape)
continue;
165 const qreal tolerance = 2.0;
167 br1.translate(offsetStep.x(), offsetStep.y());
168 offset += offsetStep;
170 hasOverlappingShape =
true;
171 foundOverlapping =
true;
175 }
while (hasOverlappingShape);
177 if (foundOverlapping)
break;
180 if (foundOverlapping) {
181 finalShapesOffset = offset;
187 if (!forceCreateNewLayer) {
188 finalShapesOffset += getFittingOffset(shapes, finalShapesOffset, documentRect, 0.1);
191 if (!finalShapesOffset.isNull()) {
197 Q_FOREACH (
KoShape *shape, shapes) {
212 const bool pasteAtCursorPosition = flags.testFlag(
PasteAtCursor);
226 if (tryPasteShapes(flags, view)) {
232 const std::optional<QPoint> preferredClipCenter = pasteAtCursorPosition
256 if (pasteAtCursorPosition) {
263 QString pastedLayerName = renamePastedLayers ? image->
nextLayerName() +
" " + i18n(
"(pasted)") :
271 const QRect rc = clip->
extent();
283 if (
KisConfig(
true).activateTransformToolAfterPaste()) {
318 Q_UNUSED(viewManager);
321 if (!clipImage)
return;
331 QString pastedLayerName = renamePastedLayers ? image->
nextLayerName() +
" " + i18n(
"(pasted)") :
344 win->addViewAndNotifyLoadingCompleted(doc);
350 if (!canvasBase)
return;
353 if (!reference)
return;
370 if (selectedShapes.isEmpty())
return;
372 if (paste.hasShapes()) {
380 if (!shapes.isEmpty()) {
381 KoShape *referenceShape = shapes.first();
const quint8 OPACITY_OPAQUE_U8
KUndo2MagicString text() const
KisCoordinatesConverter * coordinatesConverter
void addCommand(KUndo2Command *command) override
KoShapeManager shapeManager
static KisClipboard * instance()
KisImageSP clipImageFromBoardContents(bool showPopup, int overridePasteBehaviour, QPair< bool, PasteFormatBehaviour > source={false, PasteFormatBehaviour::PASTE_FORMAT_ASK}) const
KisImageSP clipImage(bool showPopup, int overridePasteBehaviour=-1) const
bool renamePastedLayers(bool defaultValue=false) const
_Private::Traits< T >::Result documentToImage(const T &obj) const
KisUndoStore * createUndoStore()
KoDocumentInfo * documentInfo() const
void setCurrentImage(KisImageSP image, bool forceInitialUpdate=true, KisNodeSP preActivatedNode=nullptr)
The command for adding a layer.
KisGroupLayerSP rootLayer() const
const KoColorSpace * colorSpace() const
QString nextLayerName(const QString &baseName="") const
KisPaintDeviceSP projection() const
QRect bounds() const override
static void adaptClipToImageColorSpace(KisPaintDeviceSP dev, KisImageSP image)
void pasteLayersFromClipboard(std::optional< QPoint > preferredClipCenter=std::nullopt, KisProcessingApplicator *applicator=nullptr)
void endAction(KisProcessingApplicator *applicator, const QString &xmlData)
KisProcessingApplicator * beginAction(KisViewManager *view, const KUndo2MagicString &actionName, Flags flags=Normal)
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
static KisPart * instance()
void addDocument(KisDocument *document, bool notify=true)
KisDocument * createDocument() const
static void runSingleCommandStroke(KisImageSP image, KUndo2Command *cmd, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
runSingleCommandStroke creates a stroke and runs cmd in it. The text() field of cmd is used as a titl...
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
The KisReferenceImage class represents a single reference image.
static KisReferenceImage * fromClipboard(const KisCoordinatesConverter &converter)
static KUndo2Command * addReferenceImages(KisDocument *document, QList< KoShape * > referenceImages)
KisMainWindow * mainWindow() const
KisDocument * document() const
KisCanvas2 * canvasBase() const
Return the canvas base class.
KisSelectionSP selection()
KisLayerSP activeLayer()
Convenience method to get at the active layer.
KisPaintDeviceSP activeDevice()
Convenience method to get at the active paint device.
KisNodeManager * nodeManager() const
The node manager handles everything about nodes.
KisImageWSP image() const
Return the image this view is displaying.
QPointer< KoShapeController > shapeController
virtual KoShapeManager * shapeManager() const =0
virtual void addCommand(KUndo2Command *command)=0
KoCanvasController * canvasController() const
virtual KoSelectedShapesProxy * selectedShapesProxy() const =0
selectedShapesProxy() is a special interface for keeping a persistent connections to selectionChanged...
virtual QPointF currentCursorPosition() const =0
void setAboutInfo(const QString &info, const QString &data)
virtual KoSelection * selection()=0
void deselectAll()
clear the selections list
void select(KoShape *shape)
const QList< KoShape * > selectedEditableShapes() const
The undo / redo command for setting the shape background.
QList< KoShape * > topLevelShapes() const
QList< KoShape * > shapes
The undo / redo command for shape moving.
This command allows you to change the zIndex of a number of shapes.
static QList< KoShapeReorderCommand::IndexedShape > homogenizeZIndexesLazy(QList< IndexedShape > shapes)
The undo / redo command for setting the shape stroke.
virtual KoShapeStrokeModelSP stroke() const
static bool compareShapeZIndex(KoShape *s1, KoShape *s2)
virtual QRectF boundingRect() const
Get the bounding box of the shape.
virtual QSharedPointer< KoShapeBackground > background() const
KUndo2MagicString kundo2_i18n(const char *text)
QAction * paste(const QObject *recvr, const char *slot, QObject *parent)
bool fuzzyCompareRects(const Rect &r1, const Rect &r2, Difference tolerance)
Point clampPoint(Point pt, const Rect &bounds)
bool isEditable(bool checkVisibility=true) const
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
KisPaintDeviceSP paintDevice
void run(Flags flags, KisViewManager *view)
void run(KisViewManager *view) override
void run(KisViewManager *view) override
void run(KisViewManager *view) override
void run(KisViewManager *view) override