Krita Source Code Documentation
Loading...
Searching...
No Matches
KisClipboard Class Reference

#include <kis_clipboard.h>

+ Inheritance diagram for KisClipboard:

Public Types

enum  PasteBehaviour { PASTE_ASSUME_WEB = 0 , PASTE_ASSUME_MONITOR , PASTE_ASK }
 
enum  PasteFormatBehaviour { PASTE_FORMAT_ASK = 0 , PASTE_FORMAT_DOWNLOAD , PASTE_FORMAT_LOCAL , PASTE_FORMAT_CLIP }
 

Signals

void clipChanged ()
 

Public Member Functions

QPair< bool, PasteFormatBehaviouraskUserForSource (const QMimeData *data, bool useClipboardFallback=false) const
 
QPair< bool, PasteFormatBehaviouraskUserForSourceWithData (QImage qimage, const QList< QUrl > urls, bool useClipboardFallback=false) const
 
KisPaintDeviceSP clip (const QRect &imageBounds, bool showPopup, int overridePasteBehaviour=-1, KisTimeSpan *clipRange=nullptr) 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
 
KisPaintDeviceSP clipFromBoardContentsWithData (QImage image, const QList< QUrl > urls, const QRect &imageBounds, bool showPopup, int overridePasteBehaviour=-1, bool useClipboardFallback=false, QPair< bool, PasteFormatBehaviour > source={false, PasteFormatBehaviour::PASTE_FORMAT_ASK}) const
 
KisPaintDeviceSP clipFromKritaLayers (const KoColorSpace *cs) const
 
KisPaintDeviceSP clipFromMimeData (const QMimeData *data, const QRect &imageBounds, bool showPopup, int overridePasteBehaviour=-1, KisTimeSpan *clipRange=nullptr, bool useClipboardFallback=false) const
 
QSize clipSize () const
 
QImage getImageWithFallback (const QMimeData *cbData, bool useClipboardFallback=false) const
 
bool hasClip () const
 
bool hasImage () const
 
bool hasLayers () const
 
bool hasLayerStyles () const
 
bool hasUrls () const
 
 KisClipboard ()
 
const QMimeData * layersMimeData () const
 
void setClip (KisPaintDeviceSP dev, const QPoint &topLeft)
 
void setClip (KisPaintDeviceSP dev, const QPoint &topLeft, const KisTimeSpan &range)
 
void setLayers (KisNodeList nodes, KisImageSP image, bool forceCopy=false)
 
 ~KisClipboard () override
 

Static Public Member Functions

static KisClipboardinstance ()
 

Properties

bool clip
 

Private Slots

void clipboardDataChanged ()
 

Private Member Functions

KisPaintDeviceSP clipFromKritaSelection (const QMimeData *data, const QRect &imageBounds, KisTimeSpan *clipRange) const
 
KisPaintDeviceSP fetchImageByURL (const QUrl &originalUrl) const
 
QImage getImageFromMimeData (const QMimeData *cbData) const
 
 Q_DISABLE_COPY (KisClipboard)
 

Private Attributes

KisClipboardPrivate *const d
 

Detailed Description

The Krita clipboard is a clipboard that can store paint devices instead of just qimage's.

Definition at line 31 of file kis_clipboard.h.

Member Enumeration Documentation

◆ PasteBehaviour

Enumerator
PASTE_ASSUME_WEB 
PASTE_ASSUME_MONITOR 
PASTE_ASK 

Definition at line 38 of file kis_clipboard.h.

◆ PasteFormatBehaviour

Enumerator
PASTE_FORMAT_ASK 
PASTE_FORMAT_DOWNLOAD 
PASTE_FORMAT_LOCAL 
PASTE_FORMAT_CLIP 

Definition at line 40 of file kis_clipboard.h.

Constructor & Destructor Documentation

◆ KisClipboard()

KisClipboard::KisClipboard ( )

Definition at line 67 of file kis_clipboard.cc.

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}
QClipboard * clipboard
void clipboardDataChanged()
KisClipboardPrivate *const d

References KisClipboardPrivate::clipboard, clipboardDataChanged(), and d.

◆ ~KisClipboard()

KisClipboard::~KisClipboard ( )
override

Definition at line 77 of file kis_clipboard.cc.

78{
79 dbgRegistry << "deleting KisClipBoard";
80 delete d;
81}
#define dbgRegistry
Definition kis_debug.h:47

References d, and dbgRegistry.

Member Function Documentation

◆ askUserForSource()

QPair< bool, KisClipboard::PasteFormatBehaviour > KisClipboard::askUserForSource ( const QMimeData * data,
bool useClipboardFallback = false ) const

Given the mimedata for a paste event, ask user which source they'll want to use for the image.

Returns
A pair of bool and PasteFormatBehaviour: The boolean indicates acceptance of the paste event. If set, the PasteFormatBehaviour member indicates the chosen source.

Definition at line 383 of file kis_clipboard.cc.

384{
385 if (!cbData) {
386 return {false, PASTE_FORMAT_ASK};
387 }
388 const QImage qimage = getImageWithFallback(cbData, useClipboardFallback);
389 QList<QUrl> urls = cbData->urls();
390
391 return askUserForSourceWithData(qimage, urls, useClipboardFallback);
392}
QPair< bool, PasteFormatBehaviour > askUserForSourceWithData(QImage qimage, const QList< QUrl > urls, bool useClipboardFallback=false) const
QImage getImageWithFallback(const QMimeData *cbData, bool useClipboardFallback=false) const

References askUserForSourceWithData(), getImageWithFallback(), and PASTE_FORMAT_ASK.

◆ askUserForSourceWithData()

QPair< bool, KisClipboard::PasteFormatBehaviour > KisClipboard::askUserForSourceWithData ( QImage qimage,
const QList< QUrl > urls,
bool useClipboardFallback = false ) const

Definition at line 395 of file kis_clipboard.cc.

396{
397 KisConfig cfg(true);
398
399 bool saveSourceSetting = false;
400
401 auto choice = (PasteFormatBehaviour)cfg.pasteFormat(false);
402
403 if (!qimage.isNull() || !urls.isEmpty()) {
404 bool local = false;
405 bool remote = false;
406 bool isURI = false;
407
408 std::for_each(urls.constBegin(), urls.constEnd(), [&](const QUrl &url) {
409 local |= url.isLocalFile();
410 remote |= !url.isLocalFile();
411 isURI |= url.scheme() == "data";
412 });
413
414 const bool hasMultipleFormatsAvailable = (remote && local)
415 || (remote && !qimage.isNull()) || (local && !qimage.isNull());
416
417 const bool defaultOptionUnavailable =
418 (!remote && choice == PASTE_FORMAT_DOWNLOAD)
419 || (!local && choice == PASTE_FORMAT_LOCAL)
420 || (qimage.isNull() && choice == PASTE_FORMAT_CLIP);
421
422 dbgUI << "Incoming paste event:";
423 dbgUI << "\tHas attached bitmap:" << !qimage.isNull();
424 dbgUI << "\tHas local images:" << local;
425 dbgUI << "\tHas remote images:" << remote;
426 dbgUI << "\tHas multiple formats:" << hasMultipleFormatsAvailable;
427 dbgUI << "\tDefault source preference" << choice;
428 dbgUI << "\tDefault source available:" << !defaultOptionUnavailable;
429 dbgUI << "\tIs data URI:" << isURI;
430
431 if (hasMultipleFormatsAvailable && choice == PASTE_FORMAT_ASK && !isURI) {
432 KisDlgPasteFormat dlg(qApp->activeWindow());
433
434 dlg.setSourceAvailable(PASTE_FORMAT_DOWNLOAD, remote);
435 dlg.setSourceAvailable(PASTE_FORMAT_LOCAL, local);
436 dlg.setSourceAvailable(PASTE_FORMAT_CLIP, !qimage.isNull());
437
438 if (dlg.exec() != KoDialog::Accepted) {
439 return {false, PASTE_FORMAT_ASK};
440 };
441
442 choice = dlg.source();
443
444 saveSourceSetting = dlg.remember();
445 } else if (defaultOptionUnavailable || choice == PASTE_FORMAT_ASK) {
446 if (remote) {
447 choice = PASTE_FORMAT_DOWNLOAD;
448 } else if (local) {
449 choice = PASTE_FORMAT_LOCAL;
450 } else if (!qimage.isNull()) {
451 choice = PASTE_FORMAT_CLIP;
452 } else {
453 return {false, PASTE_FORMAT_ASK};
454 }
455 } else if (isURI) {
456 choice = PASTE_FORMAT_DOWNLOAD;
457 }
458 }
459
460 if (saveSourceSetting) {
461 cfg.setPasteFormat(choice);
462 }
463
464 dbgUI << "Selected source for the paste:" << choice;
465
466 return {true, choice};
467}
#define dbgUI
Definition kis_debug.h:52

References dbgUI, PASTE_FORMAT_ASK, PASTE_FORMAT_CLIP, PASTE_FORMAT_DOWNLOAD, PASTE_FORMAT_LOCAL, KisConfig::pasteFormat(), KisDlgPasteFormat::remember(), KisConfig::setPasteFormat(), KisDlgPasteFormat::setSourceAvailable(), and KisDlgPasteFormat::source().

◆ clip()

KisPaintDeviceSP KisClipboard::clip ( const QRect & imageBounds,
bool showPopup,
int overridePasteBehaviour = -1,
KisTimeSpan * clipRange = nullptr ) const

Get the contents of the clipboard in the form of a paint device.

Definition at line 182 of file kis_clipboard.cc.

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}
KisPaintDeviceSP clipFromMimeData(const QMimeData *data, const QRect &imageBounds, bool showPopup, int overridePasteBehaviour=-1, KisTimeSpan *clipRange=nullptr, bool useClipboardFallback=false) const

References KisClipboardPrivate::clipboard, clipFromMimeData(), d, and dbgUI.

◆ clipboardDataChanged

void KisClipboard::clipboardDataChanged ( )
privateslot

Definition at line 584 of file kis_clipboard.cc.

585{
586 if (!d->pushedClipboard) {
587 const QMimeData *cbData = d->clipboard->mimeData();
588 d->hasClip = d->clipboard->mimeData()->hasImage()
589 || (cbData && cbData->hasFormat("application/x-krita-selection"));
590 }
591 d->pushedClipboard = false;
592 Q_EMIT clipChanged();
593}
void clipChanged()

References KisClipboardPrivate::clipboard, clipChanged(), d, KisClipboardPrivate::hasClip, and KisClipboardPrivate::pushedClipboard.

◆ clipChanged

void KisClipboard::clipChanged ( )
signal

◆ clipFromBoardContents()

KisPaintDeviceSP KisClipboard::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

Definition at line 469 of file kis_clipboard.cc.

475{
476 if (!cbData) {
477 return nullptr;
478 }
479
480 // On wayland opening a dialog invalidates the clipboard data so we cache all the data beforehand
481 const auto &urls = cbData->urls();
482 const QImage qimage = getImageWithFallback(cbData, useClipboardFallback);
483
484 return clipFromBoardContentsWithData(qimage,
485 urls,
486 imageBounds,
487 showPopup,
488 pasteBehaviourOverride,
489 useClipboardFallback,
490 source);
491}
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
KisPaintDeviceSP clipFromBoardContentsWithData(QImage image, const QList< QUrl > urls, const QRect &imageBounds, bool showPopup, int overridePasteBehaviour=-1, bool useClipboardFallback=false, QPair< bool, PasteFormatBehaviour > source={false, PasteFormatBehaviour::PASTE_FORMAT_ASK}) const

References clipFromBoardContentsWithData(), getImageWithFallback(), and source().

◆ clipFromBoardContentsWithData()

KisPaintDeviceSP KisClipboard::clipFromBoardContentsWithData ( QImage image,
const QList< QUrl > urls,
const QRect & imageBounds,
bool showPopup,
int overridePasteBehaviour = -1,
bool useClipboardFallback = false,
QPair< bool, PasteFormatBehaviour > source = {false, PasteFormatBehaviour::PASTE_FORMAT_ASK} ) const

Definition at line 493 of file kis_clipboard.cc.

500{
503
504 if (!source.first) {
505 choice = askUserForSourceWithData(qimage , urls).second;
506 } else {
507 choice = source.second;
508 }
509
510 if (choice == PASTE_FORMAT_CLIP) {
512 {
513 warnKrita << "Clipboard was cleared before loading image";
514 return nullptr;
515 }
516
517 int behaviour = pasteBehaviourOverride;
518 bool saveColorSetting = false;
519
520 KisConfig cfg(true);
521
522 if (pasteBehaviourOverride == -1) {
523 behaviour = cfg.pasteBehaviour();
524 }
525
526 if (behaviour == PASTE_ASK && showPopup) {
527 // Ask user each time.
528 KisDlgMissingColorProfile dlg(qApp->activeWindow());
529
530 if (dlg.exec() != QDialog::Accepted) {
531 return nullptr;
532 }
533
534 behaviour = dlg.source();
535
536 saveColorSetting = dlg.remember(); // should we save this option to the config for next time?
537 }
538
539 const KoColorSpace *cs = nullptr;
540 const KoColorProfile *profile = nullptr;
541 if (!profile && behaviour == PASTE_ASSUME_MONITOR)
543
544 cs = KoColorSpaceRegistry::instance()->rgb8(profile);
545 if (!cs) {
547 profile = cs->profile();
548 }
549
550 clip = new KisPaintDevice(cs);
551 Q_CHECK_PTR(clip);
552 clip->convertFromQImage(qimage, profile);
553
554 // save the user's selection to the configuration if the option is checked
555 if (saveColorSetting) {
556 cfg.setPasteBehaviour(behaviour);
557 }
558 } else {
559 const auto url = std::find_if(urls.constBegin(), urls.constEnd(), [&](const QUrl &url) {
560 if (choice == PASTE_FORMAT_DOWNLOAD) {
561 return !url.isLocalFile();
562 } else if (choice == PASTE_FORMAT_LOCAL) {
563 return url.isLocalFile();
564 } else {
565 return false;
566 }
567 });
568
569 if (url != urls.constEnd()) {
570 clip = fetchImageByURL(*url);
571 }
572 }
573
574 if (clip && !imageBounds.isEmpty()) {
575 QRect clipBounds = clip->exactBounds();
576 QPoint diff = imageBounds.center() - clipBounds.center();
577 clip->setX(diff.x());
578 clip->setY(diff.y());
579 }
580
581 return clip;
582}
KisPaintDeviceSP fetchImageByURL(const QUrl &originalUrl) const
const KoColorProfile * profile
static KisDisplayConfig displayConfigForMimePastes()
virtual const KoColorProfile * profile() const =0
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define warnKrita
Definition kis_debug.h:87
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())

References askUserForSourceWithData(), clip, KisMimeData::displayConfigForMimePastes(), fetchImageByURL(), KoColorSpaceRegistry::instance(), KIS_SAFE_ASSERT_RECOVER, PASTE_ASK, PASTE_ASSUME_MONITOR, PASTE_FORMAT_ASK, PASTE_FORMAT_CLIP, PASTE_FORMAT_LOCAL, KisConfig::pasteBehaviour(), KoColorSpace::profile(), KisDisplayConfig::profile, KisDlgMissingColorProfile::remember(), KoColorSpaceRegistry::rgb8(), KisConfig::setPasteBehaviour(), KisDlgMissingColorProfile::source(), source(), and warnKrita.

◆ clipFromKritaLayers()

KisPaintDeviceSP KisClipboard::clipFromKritaLayers ( const KoColorSpace * cs) const

Definition at line 314 of file kis_clipboard.cc.

315{
316 const QMimeData *data = KisClipboard::instance()->layersMimeData();
317
318 if (!data) {
319 return nullptr;
320 }
321
322 const KisMimeData *mimedata = qobject_cast<const KisMimeData *>(data);
323 if (!mimedata) return 0;
324
325 KisNodeList nodes = mimedata->nodes();
326
327 if (nodes.size() > 1) {
328 // we explicitly include point (0,0) into the bounds since that
329 // is a requirement for the image
330 const QRect bounds =
331 std::accumulate(nodes.begin(), nodes.end(), QRect(0, 0, 1, 1),
333
334 // if no color space provided choose the most used one in the layer data
335 if (cs == nullptr) {
336 QHash<const KoColorSpace *, int> colorSpacesCount;
337
338 Q_FOREACH (KisNodeSP node, nodes) {
339 const KoColorSpace *colorSpace = node->colorSpace();
340 if (colorSpace != nullptr) {
341 colorSpacesCount.insert(colorSpace, colorSpacesCount.value(colorSpace) + 1);
342 }
343 }
344
345 int max = 0;
346 for (auto it = colorSpacesCount.begin(); it != colorSpacesCount.end(); ++it) {
347 if (it.value() > max) {
348 max = it.value();
349 cs = it.key();
350 }
351 }
352
353 // fallback to rgb8 if no color space found
354 // It is likely that this will never be triggered, but it's probably best to handle this just in case
355 if (cs == nullptr) {
357 }
358 }
359
360 KisImageSP tempImage = new KisImage(nullptr,
361 bounds.width(),
362 bounds.height(),
363 cs,
364 "ClipImage");
365
367 for (KisNodeSP node : nodes) {
368 tempImage->addNode(node, tempImage->root());
369 }
370 tempImage->refreshGraphAsync();
371 KisLayerUtils::refreshHiddenAreaAsync(tempImage, tempImage->root(), bounds);
372 tempImage->waitForDone();
373
374 return tempImage->projection();
375 } else if (!nodes.isEmpty()) {
376 return nodes.first()->projection();
377 }
378
379 return nullptr;
380}
static KisClipboard * instance()
const QMimeData * layersMimeData() const
void waitForDone()
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
KisPaintDeviceSP projection() const
QList< KisNodeSP > nodes() const
return the node set on this mimedata object – for internal use
#define bounds(x, a, b)
void filterMergeableNodes(KisNodeList &nodes, bool allowMasks)
void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea)
auto mem_bit_or(MemType Class::*ptr)
mem_bit_or is a binary functor that applies a bitwise-or operator to member of an object and a given ...
Definition KisMpl.h:589
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()
virtual QRect exactBounds() const
virtual const KoColorSpace * colorSpace() const =0
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)

References KisNodeFacade::addNode(), bounds, KisBaseNode::colorSpace(), KisBaseNode::exactBounds(), KisLayerUtils::filterMergeableNodes(), KoColorSpaceRegistry::instance(), instance(), layersMimeData(), kismpl::mem_bit_or(), KisMimeData::nodes(), KisImage::projection(), KisImage::refreshGraphAsync(), KisLayerUtils::refreshHiddenAreaAsync(), KoColorSpaceRegistry::rgb8(), KisNodeFacade::root, and KisImage::waitForDone().

◆ clipFromKritaSelection()

KisPaintDeviceSP KisClipboard::clipFromKritaSelection ( const QMimeData * data,
const QRect & imageBounds,
KisTimeSpan * clipRange ) const
private

Definition at line 222 of file kis_clipboard.cc.

223{
224 const QByteArray mimeType = QByteArrayLiteral("application/x-krita-selection");
225
227
228 if (!cbData) {
229 return nullptr;
230 }
231
232 if (cbData->hasFormat(mimeType)) {
233 QByteArray encodedData = cbData->data(mimeType);
234 QBuffer buffer(&encodedData);
235 QScopedPointer<KoStore> store(KoStore::createStore(&buffer, KoStore::Read, mimeType));
236
237 const KoColorProfile *profile = 0;
238
239 QString csDepth, csModel;
240
241 // ColorSpace id of layer data
242 if (store->hasFile("colormodel")) {
243 store->open("colormodel");
244 csModel = QString(store->read(store->size()));
245 store->close();
246 }
247
248 if (store->hasFile("colordepth")) {
249 store->open("colordepth");
250 csDepth = QString(store->read(store->size()));
251 store->close();
252 }
253
254 if (store->hasFile("profile.icc")) {
255 QByteArray data;
256 store->open("profile.icc");
257 data = store->read(store->size());
258 store->close();
259 profile = KoColorSpaceRegistry::instance()->createColorProfile(csModel, csDepth, data);
260 }
261
262 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(csModel, csDepth, profile);
263 if (cs) {
264 clip = new KisPaintDevice(cs);
265
266 if (store->hasFile("layerdata")) {
267 store->open("layerdata");
268 if (!clip->read(store->device())) {
269 clip = 0;
270 }
271 store->close();
272 }
273
274 if (clip && !imageBounds.isEmpty()) {
275 // load topLeft
276 if (store->hasFile("topLeft")) {
277 store->open("topLeft");
278 QString str = store->read(store->size());
279 store->close();
280 QStringList list = str.split(' ');
281 if (list.size() == 2) {
282 QPoint topLeft(list[0].toInt(), list[1].toInt());
283 clip->setX(topLeft.x());
284 clip->setY(topLeft.y());
285 }
286 }
287
288 QRect clipBounds = clip->exactBounds();
289
290 if (!imageBounds.contains(clipBounds) && !imageBounds.intersects(clipBounds)) {
291 QPoint diff = imageBounds.center() - clipBounds.center();
292 clip->setX(clip->x() + diff.x());
293 clip->setY(clip->y() + diff.y());
294 }
295
296 if (store->hasFile("timeRange") && clipRange) {
297 store->open("timeRange");
298 QString str = store->read(store->size());
299 store->close();
300 QStringList list = str.split(' ');
301 if (list.size() == 2) {
302 KisTimeSpan range = KisTimeSpan::fromTimeToTime(list[0].toInt(), list[1].toInt());
303 *clipRange = range;
304 dbgUI << "Pasted time range" << range;
305 }
306 }
307 }
308 }
309 }
310
311 return clip;
312}
static KisTimeSpan fromTimeToTime(int start, int end)
@ Read
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
int toInt(const QString &str, bool *ok=nullptr)
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
const KoColorProfile * createColorProfile(const QString &colorModelId, const QString &colorDepthId, const QByteArray &rawData)

References clip, KoColorSpaceRegistry::colorSpace(), KoColorSpaceRegistry::createColorProfile(), KoStore::createStore(), dbgUI, KisTimeSpan::fromTimeToTime(), KoColorSpaceRegistry::instance(), and KoStore::Read.

◆ clipFromMimeData()

KisPaintDeviceSP KisClipboard::clipFromMimeData ( const QMimeData * data,
const QRect & imageBounds,
bool showPopup,
int overridePasteBehaviour = -1,
KisTimeSpan * clipRange = nullptr,
bool useClipboardFallback = false ) const

Get the contents of the specified mimedata buffer in the form of a paint device.

Definition at line 198 of file kis_clipboard.cc.

204{
205 if (clipRange) {
206 *clipRange = KisTimeSpan();
207 }
208
209 KisPaintDeviceSP clip = clipFromKritaSelection(cbData, imageBounds, clipRange);
210
211 if (!clip) {
212 clip = clipFromKritaLayers(nullptr);
213 }
214
215 if (!clip) {
216 clip = clipFromBoardContents(cbData, imageBounds, showPopup, overridePasteBehaviour, useClipboardFallback);
217 }
218
219 return clip;
220}
KisPaintDeviceSP clipFromKritaSelection(const QMimeData *data, const QRect &imageBounds, KisTimeSpan *clipRange) const
KisPaintDeviceSP clipFromKritaLayers(const KoColorSpace *cs) 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

References clip, clipFromBoardContents(), clipFromKritaLayers(), and clipFromKritaSelection().

◆ clipSize()

QSize KisClipboard::clipSize ( ) const

Definition at line 611 of file kis_clipboard.cc.

612{
613 const auto mimeType = QByteArrayLiteral("application/x-krita-selection");
614 const QMimeData *cbData = d->clipboard->mimeData();
615
617
618 if (cbData && cbData->hasFormat(mimeType)) {
619 QByteArray encodedData = cbData->data(mimeType);
620 QBuffer buffer(&encodedData);
621 QScopedPointer<KoStore> store(KoStore::createStore(&buffer, KoStore::Read, mimeType));
622 const KoColorProfile *profile = 0;
623 QString csDepth, csModel;
624
625 // ColorSpace id of layer data
626 if (store->hasFile("colormodel")) {
627 store->open("colormodel");
628 csModel = QString(store->read(store->size()));
629 store->close();
630 }
631
632 if (store->hasFile("colordepth")) {
633 store->open("colordepth");
634 csDepth = QString(store->read(store->size()));
635 store->close();
636 }
637
638 if (store->hasFile("profile.icc")) {
639 QByteArray data;
640 store->open("profile.icc");
641 data = store->read(store->size());
642 store->close();
643 profile = KoColorSpaceRegistry::instance()->createColorProfile(csModel, csDepth, data);
644 }
645
646 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(csModel, csDepth, profile);
647 if (!cs) {
649 }
650 clip = new KisPaintDevice(cs);
651
652 if (store->hasFile("layerdata")) {
653 store->open("layerdata");
654 clip->read(store->device());
655 store->close();
656 }
657
658 return clip->exactBounds().size();
659 } else {
660 if (d->clipboard->mimeData()->hasImage()) {
661 QImage qimage = d->clipboard->image();
662 return qimage.size();
663 }
664 }
665 return QSize();
666}

References clip, KisClipboardPrivate::clipboard, KoColorSpaceRegistry::colorSpace(), KoColorSpaceRegistry::createColorProfile(), KoStore::createStore(), d, KoColorSpaceRegistry::instance(), KoStore::Read, and KoColorSpaceRegistry::rgb8().

◆ fetchImageByURL()

KisPaintDeviceSP KisClipboard::fetchImageByURL ( const QUrl & originalUrl) const
private

Definition at line 750 of file kis_clipboard.cc.

751{
752 KisPaintDeviceSP result;
753 QUrl url(originalUrl);
754 QScopedPointer<QTemporaryFile> tmp;
755
756 if (!originalUrl.isLocalFile()) {
757 tmp.reset(new QTemporaryFile());
758 tmp->setAutoRemove(true);
759
760 // download the file and substitute the url
761 KisRemoteFileFetcher fetcher;
762
763 if (!fetcher.fetchFile(originalUrl, tmp.data())) {
764 qWarning() << "Fetching" << originalUrl << "failed";
765 return result;
766 }
767 url = QUrl::fromLocalFile(tmp->fileName());
768 }
769
770 if (url.isLocalFile()) {
771 QFileInfo fileInfo(url.toLocalFile());
772
773 QString type = KisMimeDatabase::mimeTypeForFile(url.toLocalFile());
775
776 if (!mimes.contains(type)) {
778 QMessageBox::warning(KisPart::instance()->currentMainwindow(),
779 i18nc("@title:window", "Krita"),
780 i18n("Could not open %2.\nReason: %1.", msg, url.toDisplayString()));
781 return result;
782 }
783
784 QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
785
786 if (doc->openPath(url.toLocalFile(), KisDocument::DontAddToRecent)) {
787 // Wait for required updates, if any. BUG: 448256
788 KisLayerUtils::forceAllDelayedNodesUpdate(doc->image()->root());
789 doc->image()->waitForDone();
790 result = new KisPaintDevice(*doc->image()->projection());
791 } else {
792 qWarning() << "Failed to import file" << url.toLocalFile();
793 }
794 }
795
796 return result;
797}
static QStringList supportedMimeTypes(Direction direction)
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
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
KisDocument * createDocument(QList< KisNodeSP > nodes, KisImageSP srcImage, const QRect &copiedBounds)
void forceAllDelayedNodesUpdate(KisNodeSP root)

References createDocument(), KisDocument::DontAddToRecent, KisImportExportErrorCode::errorMessage(), KisRemoteFileFetcher::fetchFile(), ImportExportCodes::FileFormatNotSupported, KisLayerUtils::forceAllDelayedNodesUpdate(), KisImportExportManager::Import, KisPart::instance(), KisMimeDatabase::mimeTypeForFile(), and KisImportExportManager::supportedMimeTypes().

◆ getImageFromMimeData()

QImage KisClipboard::getImageFromMimeData ( const QMimeData * cbData) const
private

Definition at line 712 of file kis_clipboard.cc.

713{
714 static const QList<ClipboardImageFormat> supportedFormats = {
715 {{"image/png"}, "PNG"},
716 {{"image/tiff"}, "TIFF"},
717 {{"image/bmp", "image/x-bmp", "image/x-MS-bmp", "image/x-win-bitmap"}, "BMP"}};
718
719 QImage image;
720 QSet<QString> clipboardMimeTypes;
721
722 Q_FOREACH (const QString &format, cbData->formats()) {
723 clipboardMimeTypes << format;
724 }
725
726 Q_FOREACH (const ClipboardImageFormat &item, supportedFormats) {
727 const QSet<QString> &intersection = item.mimeTypes & clipboardMimeTypes;
728 if (intersection.isEmpty()) {
729 continue;
730 }
731
732 const QString &format = *intersection.constBegin();
733 const QByteArray &imageData = cbData->data(format);
734 if (imageData.isEmpty()) {
735 continue;
736 }
737
738 if (image.loadFromData(imageData, item.format.toLatin1())) {
739 break;
740 }
741 }
742
743 if (image.isNull() && cbData->hasImage()) {
744 image = qvariant_cast<QImage>(cbData->imageData());
745 }
746
747 return image;
748}
QSet< QString > mimeTypes

References ClipboardImageFormat::format, and ClipboardImageFormat::mimeTypes.

◆ getImageWithFallback()

QImage KisClipboard::getImageWithFallback ( const QMimeData * cbData,
bool useClipboardFallback = false ) const

Definition at line 595 of file kis_clipboard.cc.

596{
597 QImage qimage = getImageFromMimeData(cbData);
598
599 if (qimage.isNull() && useClipboardFallback) {
600 qimage = d->clipboard->image();
601 }
602
603 return qimage;
604}
QImage getImageFromMimeData(const QMimeData *cbData) const

References KisClipboardPrivate::clipboard, d, and getImageFromMimeData().

◆ hasClip()

bool KisClipboard::hasClip ( ) const

Definition at line 606 of file kis_clipboard.cc.

607{
608 return d->hasClip;
609}

References d, and KisClipboardPrivate::hasClip.

◆ hasImage()

bool KisClipboard::hasImage ( ) const

Definition at line 707 of file kis_clipboard.cc.

708{
709 return d->clipboard->mimeData()->hasImage();
710}

References KisClipboardPrivate::clipboard, and d.

◆ hasLayers()

bool KisClipboard::hasLayers ( ) const

Definition at line 680 of file kis_clipboard.cc.

681{
682 const QByteArray mimeType = QByteArrayLiteral("application/x-krita-node-internal-pointer");
683 return d->clipboard->mimeData()->hasFormat(mimeType);
684}

References KisClipboardPrivate::clipboard, and d.

◆ hasLayerStyles()

bool KisClipboard::hasLayerStyles ( ) const

Definition at line 686 of file kis_clipboard.cc.

687{
688 // NOTE: please don't disable the paste action based on the
689 // result of this function, because we allow pasting
690 // of the layer styles as 'text/plain'
691
692 return d->clipboard->mimeData()->hasFormat("application/x-krita-layer-style");
693}

References KisClipboardPrivate::clipboard, and d.

◆ hasUrls()

bool KisClipboard::hasUrls ( ) const

Definition at line 701 of file kis_clipboard.cc.

702{
703 return d->clipboard->mimeData()->hasUrls();
704}

References KisClipboardPrivate::clipboard, and d.

◆ instance()

KisClipboard * KisClipboard::instance ( )
static

Definition at line 83 of file kis_clipboard.cc.

84{
85 return s_instance;
86}

◆ layersMimeData()

const QMimeData * KisClipboard::layersMimeData ( ) const

Definition at line 695 of file kis_clipboard.cc.

696{
697 const QMimeData *cbData = d->clipboard->mimeData();
698 return cbData->hasFormat("application/x-krita-node-internal-pointer") ? cbData : 0;
699}

References KisClipboardPrivate::clipboard, and d.

◆ Q_DISABLE_COPY()

KisClipboard::Q_DISABLE_COPY ( KisClipboard )
private

◆ setClip() [1/2]

void KisClipboard::setClip ( KisPaintDeviceSP dev,
const QPoint & topLeft )

Sets the clipboard to the contents of the specified paint device; also set the system clipboard to a QImage representation of the specified paint device.

Parameters
devThe paint device that will be stored on the clipboard
topLefta hint about the place where the clip should be pasted by default

Definition at line 177 of file kis_clipboard.cc.

178{
179 setClip(dev, topLeft, KisTimeSpan());
180}
void setClip(KisPaintDeviceSP dev, const QPoint &topLeft)

References setClip().

◆ setClip() [2/2]

void KisClipboard::setClip ( KisPaintDeviceSP dev,
const QPoint & topLeft,
const KisTimeSpan & range )

Definition at line 88 of file kis_clipboard.cc.

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}
A data extension mechanism for Krita.
KisDisplayConfig This class keeps track of the color management configuration for image to display....
KoColorConversionTransformation::ConversionFlags conversionFlags
KoColorConversionTransformation::Intent intent
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
int start() const
int end() const
bool isValid() const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
QString id() const
Definition KoID.cpp:63
@ Write
Definition KoStore.h:29
virtual QByteArray rawData() const
virtual QString type() const

References KisClipboardPrivate::clipboard, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KisPaintDevice::colorSpace(), KisDisplayConfig::conversionFlags, KisPaintDevice::convertToQImage(), KoStore::createStore(), d, KisMimeData::displayConfigForMimePastes(), KisTimeSpan::end(), KisClipboardPrivate::hasClip, KoID::id(), KisDisplayConfig::intent, KisTimeSpan::isValid(), KoColorProfile::name, KoColorSpace::profile(), KisDisplayConfig::profile, KisClipboardPrivate::pushedClipboard, KoColorProfile::rawData(), KisTimeSpan::start(), KoColorProfile::type(), KisPaintDevice::write(), and KoStore::Write.

◆ setLayers()

void KisClipboard::setLayers ( KisNodeList nodes,
KisImageSP image,
bool forceCopy = false )

See a comment in KisMimeData::deepCopyNodes()

Definition at line 668 of file kis_clipboard.cc.

669{
673 QMimeData *data = KisMimeData::mimeForLayersDeepCopy(nodes, image, forceCopy);
674 if (!data)
675 return;
676
677 d->clipboard->setMimeData(data);
678}
static QMimeData * mimeForLayersDeepCopy(const KisNodeList &nodes, KisImageSP image, bool forceCopy)

References KisClipboardPrivate::clipboard, d, and KisMimeData::mimeForLayersDeepCopy().

Member Data Documentation

◆ d

KisClipboardPrivate* const KisClipboard::d
private

Definition at line 144 of file kis_clipboard.h.

Property Documentation

◆ clip

bool KisClipboard::clip
read

Definition at line 35 of file kis_clipboard.h.


The documentation for this class was generated from the following files: