44#include <QApplication>
48#include <QDomDocument>
56 return cloneLayer && detachClones ?
57 KisNodeSP(cloneLayer->reincarnateAsPaintLayer()) : node->clone();
65 , m_forceCopy(forceCopy)
108 KisImageReadOnlyBarrierLock lock(
m_image, std::defer_lock);
134 f <<
"application/x-qt-image"
136 <<
"application/x-krita-node-internal-pointer";
144 QRect rc = copiedBounds;
146 QRect offset(0, 0, rc.width(), rc.height());
149 if (rc.isEmpty() && srcImage) {
153 KisImageSP image =
new KisImage(0, rc.width(), rc.height(), nodes.first()->colorSpace(), nodes.first()->name());
161 KisImageReadOnlyBarrierLock lock(srcImage, std::defer_lock);
167 KisNodeSP clonedNode = safeCopyNode(node);
186 QScopedPointer<KisDocument> doc(
createDocument(nodes, srcImage, copiedBounds));
187 QByteArray result = doc->serializeToNativeByteArray();
191 doc->setCurrentImage(0);
195#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
208 if (!QApplication::instance())
return QVariant();
211 Q_ASSERT(m_nodes.size() > 0);
213 if (mimetype ==
"application/x-qt-image") {
216 QScopedPointer<KisDocument> doc(
createDocument(m_nodes, m_image, m_copiedBounds));
219 return doc->image()->projection()->convertToQImage(displayConfig.
profile,
223 else if (mimetype ==
"application/zip") {
229 else if (mimetype ==
"application/x-krita-node-internal-pointer") {
231 QDomDocument doc(
"krita_internal_node_pointer");
232 QDomElement root = doc.createElement(
"pointer");
233 root.setAttribute(
"application_pid", (qint64)QApplication::applicationPid());
234 root.setAttribute(
"force_copy", m_forceCopy);
235 root.setAttribute(
"image_pointer_value", (qint64)m_image.data());
236 doc.appendChild(root);
239 QDomElement element = doc.createElement(
"node");
240 element.setAttribute(
"pointer_value", (qint64)node.
data());
241 root.appendChild(element);
244 return doc.toByteArray();
248 return QMimeData::retrieveData(mimetype, preferredType);
264 || !qFuzzyCompare(dstImage->
yRes(), srcImage->
yRes()))) {
266 const QTransform t = QTransform::fromScale(srcImage->
xRes() / dstImage->
xRes(),
267 srcImage->
yRes() / dstImage->
yRes());
282 bool forceCopy =
false;
286 const KisMimeData *mimedata = qobject_cast<const KisMimeData*>(data);
290 sourceImage = mimedata->
m_image;
294 if (
nodes.isEmpty() && data->hasFormat(
"application/x-krita-node-internal-pointer")) {
295 QByteArray nodeXml = data->data(
"application/x-krita-node-internal-pointer");
298 doc.setContent(nodeXml);
300 QDomElement root = doc.documentElement();
301 qint64 pid = root.attribute(
"application_pid").toLongLong();
302 forceCopy = root.attribute(
"force_copy").toInt();
303 qint64 imagePointerValue = root.attribute(
"image_pointer_value").toLongLong();
304 sourceImage =
reinterpret_cast<KisImage*
>(imagePointerValue);
306 if (pid == QApplication::applicationPid()) {
308 for (e = root.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
309 qint64 pointerValue = e.attribute(
"pointer_value").toLongLong();
311 nodes << reinterpret_cast<KisNode*>(pointerValue);
317 if (!
nodes.isEmpty() && (forceCopy || copyNode || sourceImage != image)) {
318 KisImageReadOnlyBarrierLock lock(sourceImage, std::defer_lock);
325 node = safeCopyNode(node, sourceImage != image);
326 if ((forceCopy || copyNode) && sourceImage == image) {
341 bool doRecenter =
false;
344 if (
nodes.isEmpty() && (data->hasFormat(
"application/x-color") || data->hasFormat(
"krita/x-colorsetentry"))) {
345 QColor color = data->hasColor() ? qvariant_cast<QColor>(data->colorData()) : QColor(255, 0, 255);
346 if (!data->hasColor() && data->hasFormat(
"krita/x-colorsetentry")) {
347 QByteArray byteData = data->data(
"krita/x-colorsetentry");
353 defaultConfig->setProperty(
"color", color);
363 if (
nodes.isEmpty() && data->hasImage()) {
364 QImage qimage = qvariant_cast<QImage>(data->imageData());
376 if (!
nodes.isEmpty() && doRecenter) {
377 const QRect imageBounds = image->
bounds();
382 QPoint pt = imageBounds.center() - layerBounds.center();
397 if (sortedNodes.isEmpty())
return 0;
408 if (sortedNodes.isEmpty())
return 0;
419 if (!parent->allowAsChild(node) || !parent->isEditable(
false)) {
437 (parentDummy->
node()->inherits(
"KisGroupLayer") && parentDummy->
node()->
collapsed())) {
438 aboveThisDummy = parentDummy;
439 parentDummy = parentDummy->
parent();
441 result = (!parentDummy) ?
false :
449 const QMimeData *data,
460 if (
nodes.isEmpty()) {
478 const QPoint offset = preferredCenter - layerBounds.center();
480 node->
setX(node->
x() + offset.x());
481 node->
setY(node->
y() + offset.y());
503 const QPoint newOffset(node->
x() + offset.x(), node->
y() + offset.y());
504 node->
setX(newOffset.x());
505 node->
setY(newOffset.y());
510 if (
nodes.isEmpty())
return false;
521 KisNodeSP aboveThisNode = aboveThisDummy ? aboveThisDummy->
node() : 0;
553 const bool hasDelayedNodes =
556 return bool(dynamic_cast<KisDelayedUpdateNodeInterface*>(node.data()));
559 if (hasDelayedNodes) {
const quint8 OPACITY_OPAQUE_U8
const KoColorProfile * displayProfile(int screen) const
KisDisplayConfig This class keeps track of the color management configuration for image to display....
KoColorConversionTransformation::ConversionFlags conversionFlags
const KoColorProfile * profile
KoColorConversionTransformation::Intent intent
void setCurrentImage(KisImageSP image, bool forceInitialUpdate=true, KisNodeSP preActivatedNode=nullptr)
static KisGeneratorRegistry * instance()
static KisResourcesInterfaceSP instance()
The command for adding a layer.
The command for layer moves inside the layer stack.
void setAllowMasksOnRootNode(bool value)
QString nextLayerName(const QString &baseName="") const
KisSelectionSP globalSelection() const
QRect bounds() const override
void setResolution(double xres, double yres)
static void initializeExternalNode(KisNodeSP *nodes, KisImageSP srcImage, KisImageSP dstImage, KisShapeController *shapeController)
QVariant retrieveData(const QString &mimetype, QMetaType preferredType) const override
static KisDisplayConfig displayConfigForMimePastes()
QList< KisNodeSP > nodes() const
return the node set on this mimedata object – for internal use
QStringList formats() const override
static KisNodeList tryLoadInternalNodes(const QMimeData *data, KisImageSP image, KisShapeController *shapeController, bool ©Node)
static QMimeData * mimeForLayersDeepCopy(const KisNodeList &nodes, KisImageSP image, bool forceCopy)
static QMimeData * mimeForLayers(const KisNodeList &nodes, KisImageSP image, bool forceCopy=false)
static KisNodeList loadNodesFastAndRecenter(const QPoint &preferredCenter, const QMimeData *data, KisImageSP image, KisShapeController *shapeController, bool ©Node)
static KisNodeList loadNodesFast(const QMimeData *data, KisImageSP image, KisShapeController *shapeController, bool ©Node)
KisMimeData(QList< KisNodeSP > nodes, KisImageSP image, bool forceCopy=false)
QList< KisNodeSP > m_nodes
static bool insertMimeLayers(const QMimeData *data, KisImageSP image, KisShapeController *shapeController, KisNodeDummy *parentDummy, KisNodeDummy *aboveThisDummy, bool copyNode, KisNodeInsertionAdapter *nodeInsertionAdapter, bool changeOffset=false, QPointF offset=QPointF(), KisProcessingApplicator *applicator=nullptr)
static KisNodeList loadNonNativeNodes(const QMimeData *data, KisImageWSP image)
KisNodeDummy * parent() const
void addNodes(KisNodeList nodes, KisNodeSP parent, KisNodeSP aboveThis)
void moveNodes(KisNodeList nodes, KisNodeSP parent, KisNodeSP aboveThis)
static KisOpenGLModeProber * instance()
QRect exactBounds() const
void convertFromQImage(const QImage &image, const KoColorProfile *profile, qint32 offsetX=0, qint32 offsetY=0)
static KisPart * instance()
KisDocument * createTemporaryDocument() const
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
static KisSwatch fromByteArray(QByteArray &data, QString &groupName, int &originalRow, int &originalColumn)
void toQColor(QColor *c) const
a convenience method for the above.
const T value(const QString &id) const
void setTransformation(const QTransform &matrix)
QTransform transformation() const
Returns the shapes local transformation matrix.
static bool qFuzzyCompare(half p1, half p2)
#define KIS_SAFE_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
KisDocument * createDocument(QList< KisNodeSP > nodes, KisImageSP srcImage, const QRect &copiedBounds)
QByteArray serializeToByteArray(QList< KisNodeSP > nodes, KisImageSP srcImage, const QRect &copiedBounds)
bool nodeAllowsAsChild(KisNodeSP parent, KisNodeList nodes)
bool correctNewNodeLocation(KisNodeList nodes, KisNodeDummy *&parentDummy, KisNodeDummy *&aboveThisDummy)
KisSharedPtr< KisNode > KisNodeSP
void sortMergeableNodes(KisNodeSP root, KisNodeList &inputNodes, KisNodeList &outputNodes)
QRect recursiveTightNodeVisibleBounds(KisNodeSP rootNode)
void addCopyOfNameTag(KisNodeSP node)
void recursiveApplyNodes(NodePointer node, Functor func)
int getScreenNumberForWidget(const QWidget *w)
virtual KisPaintDeviceSP projection() const =0
virtual QRect exactBounds() const
virtual void setX(qint32)
virtual void setY(qint32)
virtual KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
void setImage(KisImageWSP newImage) override
static KoColorSpaceRegistry * instance()
const KoColorProfile * p709SRGBProfile() const