50#include <QApplication>
55 const QPointF &shapesOffset,
56 const QRectF &documentRect,
59 QPointF accumulatedFitOffset;
61 Q_FOREACH (
KoShape *shape, shapes) {
64 const QPointF center =
bounds.center() + shapesOffset;
66 const qreal wMargin = (0.5 - fitRatio) *
bounds.width();
67 const qreal hMargin = (0.5 - fitRatio) *
bounds.height();
68 const QRectF allowedRect = documentRect.adjusted(-wMargin, -hMargin, wMargin, hMargin);
72 accumulatedFitOffset += fittedCenter - center;
75 return accumulatedFitOffset;
78bool tryPasteShapes(KisPasteActionFactory::Flags flags,
KisViewManager *view)
92 if (!shapes.isEmpty()) {
100 if (it != topLevelShapes.constEnd()) {
101 const int zIndexOffset = (*it)->zIndex();
106 std::transform(shapes.constBegin(), shapes.constEnd(),
107 std::back_inserter(indexedShapes),
108 [zIndexOffset] (
KoShape *shape) {
109 KoShapeReorderCommand::IndexedShape indexedShape(shape);
110 indexedShape.zIndex += zIndexOffset;
125 if (forceCreateNewLayer) {
126 parentLayer = canvas->
shapeController()->documentBase()->createParentForShapes(shapes,
true, parentCommand);
129 canvas->
shapeController()->addShapesDirect(shapes, parentLayer, parentCommand);
131 QPointF finalShapesOffset;
137 finalShapesOffset = cursorPos - boundingRect.center();
139 }
else if (!forceCreateNewLayer) {
140 bool foundOverlapping =
false;
143 const QPointF offsetStep = 0.1 * QPointF(boundingRect.width(), boundingRect.height());
147 Q_FOREACH (
KoShape *shape, shapes) {
150 bool hasOverlappingShape =
false;
153 hasOverlappingShape =
false;
159 Q_FOREACH (
KoShape *intersectedShape, conflicts) {
160 if (intersectedShape == shape)
continue;
164 const qreal tolerance = 2.0;
166 br1.translate(offsetStep.x(), offsetStep.y());
167 offset += offsetStep;
169 hasOverlappingShape =
true;
170 foundOverlapping =
true;
174 }
while (hasOverlappingShape);
176 if (foundOverlapping)
break;
179 if (foundOverlapping) {
180 finalShapesOffset = offset;
186 if (!forceCreateNewLayer) {
187 finalShapesOffset += getFittingOffset(shapes, finalShapesOffset, documentRect, 0.1);
190 if (!finalShapesOffset.isNull()) {
196 Q_FOREACH (
KoShape *shape, shapes) {
225 if (tryPasteShapes(flags, view)) {
229 const QRect fittingBounds =
230 pasteAtCursorPosition ? QRect() : image->
bounds();
234 const QPointF offsetTopLeft = [&]() -> QPointF {
240 pasteAtCursorPosition =
false;
246 if (pasteAtCursorPosition) {
253 pasteAtCursorPosition =
true;
254 imagePos = QPointF(image->
bounds().center());
258 const QPointF offset =
259 (imagePos - QRectF(clip->
exactBounds()).center()).toPoint();
286 if (pasteAtCursorPosition) {
289 const QPoint offset =
290 (imagePos - QRectF(clip->
exactBounds()).center()).toPoint();
292 clip->
setX(clip->
x() + offset.x());
293 clip->
setY(clip->
y() + offset.y());
298 QString pastedLayerName = renamePastedLayers ? image->
nextLayerName() +
" " + i18n(
"(pasted)") :
317 const QRect rc = clip->
extent();
330 if (
KisConfig(
true).activateTransformToolAfterPaste()) {
346 QRect imageBounds = image->
bounds();
355 if (!clipBounds.intersects(imageBounds))
357 QPoint diff = imageBounds.center() - clipBounds.center();
358 clip->
setX(diff.x());
359 clip->
setY(diff.y());
383 Q_UNUSED(viewManager);
389 if (
rect.isEmpty())
return;
399 QString pastedLayerName = renamePastedLayers ? image->
nextLayerName() +
" " + i18n(
"(pasted)") :
412 win->addViewAndNotifyLoadingCompleted(doc);
418 if (!canvasBase)
return;
421 if (!reference)
return;
438 if (selectedShapes.isEmpty())
return;
440 if (paste.hasShapes()) {
448 if (!shapes.isEmpty()) {
449 KoShape *referenceShape = shapes.first();
const quint8 OPACITY_OPAQUE_U8
KUndo2MagicString text() const
KisCoordinatesConverter * coordinatesConverter
void addCommand(KUndo2Command *command) override
KoShapeManager shapeManager
static KisClipboard * instance()
KisPaintDeviceSP clipFromKritaLayers(const KoColorSpace *cs) 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
QRect bounds() const override
static void adaptClipToImageColorSpace(KisPaintDeviceSP dev, KisImageSP image)
KisKeyframeChannel stores and manages KisKeyframes. Maps units of time to virtual keyframe values....
void addKeyframe(int time, KUndo2Command *parentUndoCmd=nullptr)
Add a new keyframe to the channel at the specified time.
void pasteLayersFromClipboard(bool changeOffset=false, QPointF offset=QPointF(), KisProcessingApplicator *applicator=nullptr)
KisProcessingApplicator * beginAction(KisViewManager *view, const KUndo2MagicString &actionName)
void endAction(KisProcessingApplicator *applicator, const QString &xmlData)
QRect exactBounds() const
const KoColorSpace * colorSpace() const
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 KisRasterKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisRas...
void importFrame(int time, KisPaintDeviceSP sourceDevice, KUndo2Command *parentCommand)
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
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
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
KisKeyframeChannel * getKeyframeChannel(const QString &id, bool create)
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