Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_clipboard.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#include "kis_clipboard.h"
9
10#include <QApplication>
11#include <QBuffer>
12#include <QClipboard>
13#include <QScreen>
14#include <QFileInfo>
15#include <QMessageBox>
16#include <QMimeData>
17#include <QScopedPointer>
18#include <QTemporaryFile>
19
20// kritaglobal
21#include <algorithm>
22#include <kis_assert.h>
23#include <kis_debug.h>
24
25// kritastore
26#include <KoStore.h>
27
28// kritaimage
29#include <kis_annotation.h>
30#include <kis_layer_utils.h>
31#include <kis_paint_device.h>
32#include <kis_time_span.h>
33
34// local
35#include "KisDocument.h"
37#include "KisMainWindow.h"
38#include "KisMimeDatabase.h"
39#include "KisPart.h"
43#include "kis_mimedata.h"
45#include "KisDisplayConfig.h"
46
48
50 QSet<QString> mimeTypes;
51 QString format;
52};
53
54class Q_DECL_HIDDEN KisClipboardPrivate
55{
56public:
58 : clipboard(QApplication::clipboard())
59 {
60 }
61
62 bool hasClip{};
63 bool pushedClipboard{};
64 QClipboard *clipboard;
65};
66
68 : d(new KisClipboardPrivate)
69{
70 // Check that we don't already have a clip ready
72
73 // Make sure we are notified when clipboard changes
74 connect(d->clipboard, &QClipboard::dataChanged, this, &KisClipboard::clipboardDataChanged, Qt::UniqueConnection);
75}
76
78{
79 dbgRegistry << "deleting KisClipBoard";
80 delete d;
81}
82
84{
85 return s_instance;
86}
87
88void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint &topLeft, const KisTimeSpan &range)
89{
90 if (!dev)
91 return;
92
93 d->hasClip = true;
94
95 // We'll create a store (ZIP format) in memory
96 QBuffer buffer;
97 const auto mimeType = QByteArrayLiteral("application/x-krita-selection");
98 QScopedPointer<KoStore> store(KoStore::createStore(&buffer, KoStore::Write, mimeType));
99 KisStorePaintDeviceWriter writer(store.data());
100 Q_ASSERT(store);
101 Q_ASSERT(!store->bad());
102
103 // Layer data
104 if (store->open("layerdata")) {
105 if (!dev->write(writer)) {
106 dev->disconnect();
107 store->close();
108 return;
109 }
110 store->close();
111 }
112
113 // copied frame time limits
114 if (range.isValid() && store->open("timeRange")) {
115 store->write(QString("%1 %2").arg(range.start()).arg(range.end()).toLatin1());
116 store->close();
117 }
118
119 // Coordinates
120 if (store->open("topLeft")) {
121 store->write(QString("%1 %2").arg(topLeft.x()).arg(topLeft.y()).toLatin1());
122 store->close();
123 }
124 // ColorSpace id of layer data
125 if (store->open("colormodel")) {
126 QString csName = dev->colorSpace()->colorModelId().id();
127 store->write(csName.toLatin1());
128 store->close();
129 }
130 if (store->open("colordepth")) {
131 QString csName = dev->colorSpace()->colorDepthId().id();
132 store->write(csName.toLatin1());
133 store->close();
134 }
135
136 if (dev->colorSpace()->profile()) {
137 const KoColorProfile *profile = dev->colorSpace()->profile();
138 KisAnnotationSP annotation;
139
140 if (profile && profile->type() == "icc" && !profile->rawData().isEmpty()) {
141 annotation = new KisAnnotation("icc", profile->name(), profile->rawData());
142
143 if (annotation) {
144 // save layer profile
145 if (store->open("profile.icc")) {
146 store->write(annotation->annotation());
147 store->close();
148 }
149 }
150 }
151 }
152
153 QMimeData *mimeData = new QMimeData;
154 Q_CHECK_PTR(mimeData);
155
156 if (mimeData) {
157 mimeData->setData(mimeType, buffer.buffer());
158 }
159
160 // We also create a QImage so we can interchange with other applications
161 QImage qimage;
163
164 qimage = dev->convertToQImage(displayConfig.profile,
165 displayConfig.intent,
166 displayConfig.conversionFlags);
167 if (!qimage.isNull() && mimeData) {
168 mimeData->setImageData(qimage);
169 }
170
171 if (mimeData) {
172 d->pushedClipboard = true;
173 d->clipboard->setMimeData(mimeData);
174 }
175}
176
177void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint &topLeft)
178{
179 setClip(dev, topLeft, KisTimeSpan());
180}
181
182KisPaintDeviceSP KisClipboard::clip(const QRect &imageBounds, bool showPopup, int overridePasteBehaviour, KisTimeSpan *clipRange) const
183{
184 const QMimeData *cbData = d->clipboard->mimeData();
185
186 if (!cbData) {
187 return nullptr;
188 }
189
190 dbgUI << Q_FUNC_INFO;
191 dbgUI << "\tFormats: " << cbData->formats();
192 dbgUI << "\tUrls: " << cbData->urls();
193 dbgUI << "\tHas images: " << cbData->hasImage();
194
195 return clipFromMimeData(cbData, imageBounds, showPopup, overridePasteBehaviour, clipRange, true);
196}
197
199 const QRect &imageBounds,
200 bool showPopup,
201 int overridePasteBehaviour,
202 KisTimeSpan *clipRange,
203 bool useClipboardFallback) const
204{
205 if (clipRange) {
206 *clipRange = KisTimeSpan();
207 }
208
209 KisPaintDeviceSP clip = clipFromKritaSelection(cbData, imageBounds, clipRange);
210
211 if (!clip) {
212 clip = clipFromBoardContents(cbData, imageBounds, showPopup, overridePasteBehaviour, useClipboardFallback);
213 }
214
215 return clip;
216}
217
218KisPaintDeviceSP KisClipboard::clipFromKritaSelection(const QMimeData *cbData, const QRect &imageBounds, KisTimeSpan *clipRange) const
219{
220 const QByteArray mimeType = QByteArrayLiteral("application/x-krita-selection");
221
223
224 if (!cbData) {
225 return nullptr;
226 }
227
228 if (cbData->hasFormat(mimeType)) {
229 QByteArray encodedData = cbData->data(mimeType);
230 QBuffer buffer(&encodedData);
231 QScopedPointer<KoStore> store(KoStore::createStore(&buffer, KoStore::Read, mimeType));
232
233 const KoColorProfile *profile = 0;
234
235 QString csDepth, csModel;
236
237 // ColorSpace id of layer data
238 if (store->hasFile("colormodel")) {
239 store->open("colormodel");
240 csModel = QString(store->read(store->size()));
241 store->close();
242 }
243
244 if (store->hasFile("colordepth")) {
245 store->open("colordepth");
246 csDepth = QString(store->read(store->size()));
247 store->close();
248 }
249
250 if (store->hasFile("profile.icc")) {
251 QByteArray data;
252 store->open("profile.icc");
253 data = store->read(store->size());
254 store->close();
255 profile = KoColorSpaceRegistry::instance()->createColorProfile(csModel, csDepth, data);
256 }
257
258 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(csModel, csDepth, profile);
259 if (cs) {
260 clip = new KisPaintDevice(cs);
261
262 if (store->hasFile("layerdata")) {
263 store->open("layerdata");
264 if (!clip->read(store->device())) {
265 clip = 0;
266 }
267 store->close();
268 }
269
270 if (clip && !imageBounds.isEmpty()) {
271 // load topLeft
272 if (store->hasFile("topLeft")) {
273 store->open("topLeft");
274 QString str = store->read(store->size());
275 store->close();
276 QStringList list = str.split(' ');
277 if (list.size() == 2) {
278 QPoint topLeft(list[0].toInt(), list[1].toInt());
279 clip->setX(topLeft.x());
280 clip->setY(topLeft.y());
281 }
282 }
283
284 QRect clipBounds = clip->exactBounds();
285
286 if (!imageBounds.contains(clipBounds) && !imageBounds.intersects(clipBounds)) {
287 QPoint diff = imageBounds.center() - clipBounds.center();
288 clip->setX(clip->x() + diff.x());
289 clip->setY(clip->y() + diff.y());
290 }
291
292 if (store->hasFile("timeRange") && clipRange) {
293 store->open("timeRange");
294 QString str = store->read(store->size());
295 store->close();
296 QStringList list = str.split(' ');
297 if (list.size() == 2) {
298 KisTimeSpan range = KisTimeSpan::fromTimeToTime(list[0].toInt(), list[1].toInt());
299 *clipRange = range;
300 dbgUI << "Pasted time range" << range;
301 }
302 }
303 }
304 }
305 }
306
307 return clip;
308}
309
311{
312 const QMimeData *data = KisClipboard::instance()->layersMimeData();
313
314 if (!data) {
315 return nullptr;
316 }
317
318 const KisMimeData *mimedata = qobject_cast<const KisMimeData *>(data);
319 if (!mimedata) return 0;
320
321 KisNodeList nodes = mimedata->nodes();
322
323 if (nodes.size() > 1) {
324 // we explicitly include point (0,0) into the bounds since that
325 // is a requirement for the image
326 QRect bounds = QRect(0, 0, 1, 1);
327 Q_FOREACH (KisNodeSP node, nodes) {
328 bounds |= node->exactBounds();
329 }
330
331 KisImageSP tempImage = new KisImage(nullptr,
332 bounds.width(),
333 bounds.height(),
334 cs,
335 "ClipImage");
336 for (KisNodeSP node : nodes) {
337 tempImage->addNode(node, tempImage->root());
338 }
339 tempImage->refreshGraphAsync();
340 KisLayerUtils::refreshHiddenAreaAsync(tempImage, tempImage->root(), bounds);
341 tempImage->waitForDone();
342
343 return tempImage->projection();
344 } else if (!nodes.isEmpty()) {
345 return nodes.first()->projection();
346 }
347
348 return nullptr;
349}
350
351QPair<bool, KisClipboard::PasteFormatBehaviour>
352KisClipboard::askUserForSource(const QMimeData *cbData,
353 bool useClipboardFallback) const
354{
355 if (!cbData) {
356 return {false, PASTE_FORMAT_ASK};
357 }
358
359 KisConfig cfg(true);
360
361 bool saveSourceSetting = false;
362
363 auto choice = (PasteFormatBehaviour)cfg.pasteFormat(false);
364
365 const QImage qimage = [&]() {
366 QImage qimage = getImageFromMimeData(cbData);
367
368 if (qimage.isNull() && useClipboardFallback) {
369 qimage = d->clipboard->image();
370 }
371
372 return qimage;
373 }();
374
375 if (!qimage.isNull() || cbData->hasUrls()) {
376 const auto &urls = cbData->urls();
377
378 bool local = false;
379 bool remote = false;
380 bool isURI = false;
381
382 std::for_each(urls.constBegin(), urls.constEnd(), [&](const QUrl &url) {
383 local |= url.isLocalFile();
384 remote |= !url.isLocalFile();
385 isURI |= url.scheme() == "data";
386 });
387
388 const bool hasMultipleFormatsAvailable = (remote && local)
389 || (remote && !qimage.isNull()) || (local && !qimage.isNull());
390
391 const bool defaultOptionUnavailable =
392 (!remote && choice == PASTE_FORMAT_DOWNLOAD)
393 || (!local && choice == PASTE_FORMAT_LOCAL)
394 || (qimage.isNull() && choice == PASTE_FORMAT_CLIP);
395
396 dbgUI << "Incoming paste event:";
397 dbgUI << "\tHas attached bitmap:" << cbData->hasImage();
398 dbgUI << "\tHas local images:" << local;
399 dbgUI << "\tHas remote images:" << remote;
400 dbgUI << "\tHas multiple formats:" << hasMultipleFormatsAvailable;
401 dbgUI << "\tDefault source preference" << choice;
402 dbgUI << "\tDefault source available:" << !defaultOptionUnavailable;
403 dbgUI << "\tIs data URI:" << isURI;
404
405 if (hasMultipleFormatsAvailable && choice == PASTE_FORMAT_ASK && !isURI) {
406 KisDlgPasteFormat dlg(qApp->activeWindow());
407
410 dlg.setSourceAvailable(PASTE_FORMAT_CLIP, !qimage.isNull());
411
412 if (dlg.exec() != KoDialog::Accepted) {
413 return {false, PASTE_FORMAT_ASK};
414 };
415
416 choice = dlg.source();
417
418 saveSourceSetting = dlg.remember();
419 } else if (defaultOptionUnavailable || choice == PASTE_FORMAT_ASK) {
420 if (remote) {
421 choice = PASTE_FORMAT_DOWNLOAD;
422 } else if (local) {
423 choice = PASTE_FORMAT_LOCAL;
424 } else if (!qimage.isNull()) {
425 choice = PASTE_FORMAT_CLIP;
426 } else {
427 return {false, PASTE_FORMAT_ASK};
428 }
429 } else if (isURI) {
430 choice = PASTE_FORMAT_DOWNLOAD;
431 }
432 }
433
434 if (saveSourceSetting) {
435 cfg.setPasteFormat(choice);
436 }
437
438 dbgUI << "Selected source for the paste:" << choice;
439
440 return {true, choice};
441}
442
444 const QRect &imageBounds,
445 bool showPopup,
446 int pasteBehaviourOverride,
447 bool useClipboardFallback,
448 QPair<bool, PasteFormatBehaviour> source) const
449{
450 if (!cbData) {
451 return nullptr;
452 }
453
455
457
458 if (!source.first) {
459 choice = askUserForSource(cbData).second;
460 } else {
461 choice = source.second;
462 }
463
464 if (choice == PASTE_FORMAT_CLIP) {
465 const QImage qimage = [&]() {
466 QImage qimage = getImageFromMimeData(cbData);
467
468 if (qimage.isNull() && useClipboardFallback) {
469 qimage = d->clipboard->image();
470 }
471
472 return qimage;
473 }();
474
475 KIS_SAFE_ASSERT_RECOVER(!qimage.isNull())
476 {
477 warnKrita << "Clipboard was cleared before loading image";
478 return nullptr;
479 }
480
481 int behaviour = pasteBehaviourOverride;
482 bool saveColorSetting = false;
483
484 KisConfig cfg(true);
485
486 if (pasteBehaviourOverride == -1) {
487 behaviour = cfg.pasteBehaviour();
488 }
489
490 if (behaviour == PASTE_ASK && showPopup) {
491 // Ask user each time.
492 KisDlgMissingColorProfile dlg(qApp->activeWindow());
493
494 if (dlg.exec() != QDialog::Accepted) {
495 return nullptr;
496 }
497
498 behaviour = dlg.source();
499
500 saveColorSetting = dlg.remember(); // should we save this option to the config for next time?
501 }
502
503 const KoColorSpace *cs = nullptr;
504 const KoColorProfile *profile = nullptr;
505 if (!profile && behaviour == PASTE_ASSUME_MONITOR)
507
508 cs = KoColorSpaceRegistry::instance()->rgb8(profile);
509 if (!cs) {
511 profile = cs->profile();
512 }
513
514 clip = new KisPaintDevice(cs);
515 Q_CHECK_PTR(clip);
516 clip->convertFromQImage(qimage, profile);
517
518 // save the user's selection to the configuration if the option is checked
519 if (saveColorSetting) {
520 cfg.setPasteBehaviour(behaviour);
521 }
522 } else {
523 const auto &urls = cbData->urls();
524 const auto url = std::find_if(urls.constBegin(), urls.constEnd(), [&](const QUrl &url) {
525 if (choice == PASTE_FORMAT_DOWNLOAD) {
526 return !url.isLocalFile();
527 } else if (choice == PASTE_FORMAT_LOCAL) {
528 return url.isLocalFile();
529 } else {
530 return false;
531 }
532 });
533
534 if (url != urls.constEnd()) {
535 clip = fetchImageByURL(*url);
536 }
537 }
538
539 if (clip && !imageBounds.isEmpty()) {
540 QRect clipBounds = clip->exactBounds();
541 QPoint diff = imageBounds.center() - clipBounds.center();
542 clip->setX(diff.x());
543 clip->setY(diff.y());
544 }
545
546 return clip;
547}
548
550{
551 if (!d->pushedClipboard) {
552 const QMimeData *cbData = d->clipboard->mimeData();
553 d->hasClip = d->clipboard->mimeData()->hasImage()
554 || (cbData && cbData->hasFormat("application/x-krita-selection"));
555 }
556 d->pushedClipboard = false;
557 Q_EMIT clipChanged();
558}
559
561{
562 return d->hasClip;
563}
564
566{
567 const auto mimeType = QByteArrayLiteral("application/x-krita-selection");
568 const QMimeData *cbData = d->clipboard->mimeData();
569
571
572 if (cbData && cbData->hasFormat(mimeType)) {
573 QByteArray encodedData = cbData->data(mimeType);
574 QBuffer buffer(&encodedData);
575 QScopedPointer<KoStore> store(KoStore::createStore(&buffer, KoStore::Read, mimeType));
576 const KoColorProfile *profile = 0;
577 QString csDepth, csModel;
578
579 // ColorSpace id of layer data
580 if (store->hasFile("colormodel")) {
581 store->open("colormodel");
582 csModel = QString(store->read(store->size()));
583 store->close();
584 }
585
586 if (store->hasFile("colordepth")) {
587 store->open("colordepth");
588 csDepth = QString(store->read(store->size()));
589 store->close();
590 }
591
592 if (store->hasFile("profile.icc")) {
593 QByteArray data;
594 store->open("profile.icc");
595 data = store->read(store->size());
596 store->close();
597 profile = KoColorSpaceRegistry::instance()->createColorProfile(csModel, csDepth, data);
598 }
599
600 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(csModel, csDepth, profile);
601 if (!cs) {
603 }
604 clip = new KisPaintDevice(cs);
605
606 if (store->hasFile("layerdata")) {
607 store->open("layerdata");
608 clip->read(store->device());
609 store->close();
610 }
611
612 return clip->exactBounds().size();
613 } else {
614 if (d->clipboard->mimeData()->hasImage()) {
615 QImage qimage = d->clipboard->image();
616 return qimage.size();
617 }
618 }
619 return QSize();
620}
621
622void KisClipboard::setLayers(KisNodeList nodes, KisImageSP image, bool forceCopy)
623{
627 QMimeData *data = KisMimeData::mimeForLayersDeepCopy(nodes, image, forceCopy);
628 if (!data)
629 return;
630
631 d->clipboard->setMimeData(data);
632}
633
635{
636 const QByteArray mimeType = QByteArrayLiteral("application/x-krita-node-internal-pointer");
637 return d->clipboard->mimeData()->hasFormat(mimeType);
638}
639
641{
642 // NOTE: please don't disable the paste action based on the
643 // result of this function, because we allow pasting
644 // of the layer styles as 'text/plain'
645
646 return d->clipboard->mimeData()->hasFormat("application/x-krita-layer-style");
647}
648
649const QMimeData *KisClipboard::layersMimeData() const
650{
651 const QMimeData *cbData = d->clipboard->mimeData();
652 return cbData->hasFormat("application/x-krita-node-internal-pointer") ? cbData : 0;
653}
654
656{
657 return d->clipboard->mimeData()->hasUrls();
658}
659
660QImage KisClipboard::getImageFromMimeData(const QMimeData *cbData) const
661{
662 static const QList<ClipboardImageFormat> supportedFormats = {
663 {{"image/png"}, "PNG"},
664 {{"image/tiff"}, "TIFF"},
665 {{"image/bmp", "image/x-bmp", "image/x-MS-bmp", "image/x-win-bitmap"}, "BMP"}};
666
667 QImage image;
668 QSet<QString> clipboardMimeTypes;
669
670 Q_FOREACH (const QString &format, cbData->formats()) {
671 clipboardMimeTypes << format;
672 }
673
674 Q_FOREACH (const ClipboardImageFormat &item, supportedFormats) {
675 const QSet<QString> &intersection = item.mimeTypes & clipboardMimeTypes;
676 if (intersection.isEmpty()) {
677 continue;
678 }
679
680 const QString &format = *intersection.constBegin();
681 const QByteArray &imageData = cbData->data(format);
682 if (imageData.isEmpty()) {
683 continue;
684 }
685
686 if (image.loadFromData(imageData, item.format.toLatin1())) {
687 break;
688 }
689 }
690
691 if (image.isNull() && cbData->hasImage()) {
692 image = qvariant_cast<QImage>(cbData->imageData());
693 }
694
695 return image;
696}
697
699{
700 KisPaintDeviceSP result;
701 QUrl url(originalUrl);
702 QScopedPointer<QTemporaryFile> tmp;
703
704 if (!originalUrl.isLocalFile()) {
705 tmp.reset(new QTemporaryFile());
706 tmp->setAutoRemove(true);
707
708 // download the file and substitute the url
709 KisRemoteFileFetcher fetcher;
710
711 if (!fetcher.fetchFile(originalUrl, tmp.data())) {
712 qWarning() << "Fetching" << originalUrl << "failed";
713 return result;
714 }
715 url = QUrl::fromLocalFile(tmp->fileName());
716 }
717
718 if (url.isLocalFile()) {
719 QFileInfo fileInfo(url.toLocalFile());
720
721 QString type = KisMimeDatabase::mimeTypeForFile(url.toLocalFile());
723
724 if (!mimes.contains(type)) {
726 QMessageBox::warning(KisPart::instance()->currentMainwindow(),
727 i18nc("@title:window", "Krita"),
728 i18n("Could not open %2.\nReason: %1.", msg, url.toDisplayString()));
729 return result;
730 }
731
732 QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
733
734 if (doc->openPath(url.toLocalFile(), KisDocument::DontAddToRecent)) {
735 // Wait for required updates, if any. BUG: 448256
736 KisLayerUtils::forceAllDelayedNodesUpdate(doc->image()->root());
737 doc->image()->waitForDone();
738 result = new KisPaintDevice(*doc->image()->projection());
739 } else {
740 qWarning() << "Failed to import file" << url.toLocalFile();
741 }
742 }
743
744 return result;
745}
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
A data extension mechanism for Krita.
QClipboard * clipboard
void setLayers(KisNodeList nodes, KisImageSP image, bool forceCopy=false)
void clipboardDataChanged()
static KisClipboard * instance()
bool hasClip() const
void clipChanged()
QPair< bool, PasteFormatBehaviour > askUserForSource(const QMimeData *data, bool useClipboardFallback=false) const
KisPaintDeviceSP clipFromKritaSelection(const QMimeData *data, const QRect &imageBounds, KisTimeSpan *clipRange) const
KisPaintDeviceSP clipFromMimeData(const QMimeData *data, const QRect &imageBounds, bool showPopup, int overridePasteBehaviour=-1, KisTimeSpan *clipRange=nullptr, bool useClipboardFallback=false) const
void setClip(KisPaintDeviceSP dev, const QPoint &topLeft)
const QMimeData * layersMimeData() const
QImage getImageFromMimeData(const QMimeData *cbData) const
bool hasLayerStyles() const
KisPaintDeviceSP clipFromKritaLayers(const KoColorSpace *cs) const
bool hasLayers() const
KisPaintDeviceSP fetchImageByURL(const QUrl &originalUrl) const
QSize clipSize() const
KisPaintDeviceSP clipFromBoardContents(const QMimeData *data, const QRect &imageBounds, bool showPopup, int overridePasteBehaviour=-1, bool useClipboardFallback=false, QPair< bool, PasteFormatBehaviour > source={ false, PasteFormatBehaviour::PASTE_FORMAT_ASK}) const
KisClipboardPrivate *const d
~KisClipboard() override
bool hasUrls() const
void setPasteFormat(qint32 format)
qint32 pasteFormat(bool defaultValue) const
qint32 pasteBehaviour(bool defaultValue=false) const
void setPasteBehaviour(qint32 behaviour) const
KisDisplayConfig This class keeps track of the color management configuration for image to display....
KoColorConversionTransformation::ConversionFlags conversionFlags
const KoColorProfile * profile
KoColorConversionTransformation::Intent intent
KisClipboard::PasteBehaviour source() const
KisClipboard::PasteFormatBehaviour source() const
void setSourceAvailable(KisClipboard::PasteFormatBehaviour id, bool value)
void waitForDone()
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
KisPaintDeviceSP projection() const
static QStringList supportedMimeTypes(Direction direction)
static KisDisplayConfig displayConfigForMimePastes()
QList< KisNodeSP > nodes() const
return the node set on this mimedata object – for internal use
static QMimeData * mimeForLayersDeepCopy(const KisNodeList &nodes, KisImageSP image, bool forceCopy)
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
bool write(KisPaintDeviceWriter &store)
const KoColorSpace * colorSpace() const
QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags()) const
static KisPart * instance()
Definition KisPart.cpp:131
The KisRemoteFileFetcher class can fetch a remote file and blocks until the file is downloaded.
bool fetchFile(const QUrl &remote, QIODevice *io)
fetch the image. Shows a progress dialog
int start() const
int end() const
static KisTimeSpan fromTimeToTime(int start, int end)
bool isValid() const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
QString id() const
Definition KoID.cpp:63
@ Read
Definition KoStore.h:29
@ Write
Definition KoStore.h:29
static KoStore * createStore(const QString &fileName, Mode mode, const QByteArray &appIdentification=QByteArray(), Backend backend=Auto, bool writeMimetype=true)
Definition KoStore.cpp:39
This file is part of the Krita application in calligra.
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define bounds(x, a, b)
#define warnKrita
Definition kis_debug.h:87
#define dbgUI
Definition kis_debug.h:52
#define dbgRegistry
Definition kis_debug.h:47
KisDocument * createDocument(QList< KisNodeSP > nodes, KisImageSP srcImage, const QRect &copiedBounds)
void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea)
void forceAllDelayedNodesUpdate(KisNodeSP root)
QSet< QString > mimeTypes
virtual QRect exactBounds() const
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
virtual QByteArray rawData() const
virtual QString type() const
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())
const KoColorProfile * createColorProfile(const QString &colorModelId, const QString &colorDepthId, const QByteArray &rawData)