Commit 951a8211 authored by Amy spark's avatar Amy spark 👉
Browse files

KisClipboard: decouple source selection and allow for manual import of single URLs

BUG: 455671
(cherry picked from commit ad2bbd1f)
parent 057b6e89
Pipeline #198554 passed with stage
in 49 minutes and 15 seconds
......@@ -520,38 +520,115 @@ void KisView::dropEvent(QDropEvent *event)
const KisCanvasDrop::Action action = dlgAction.dropAs(*data, callPos);
if (action == KisCanvasDrop::INSERT_AS_NEW_LAYER) {
KisPaintDeviceSP clip = KisClipboard::instance()->clipFromMimeData(data, QRect(), true);
const QPair<bool, KisClipboard::PasteFormatBehaviour> source =
KisClipboard::instance()->askUserForSource(data);
if (!source.first) {
dbgUI << "Paste event cancelled";
return;
}
if (source.second != KisClipboard::PASTE_FORMAT_CLIP) {
const QList<QUrl> &urls = data->urls();
const auto url = std::find_if(
urls.constBegin(),
urls.constEnd(),
[&](const QUrl &url) {
if (source.second
== KisClipboard::PASTE_FORMAT_DOWNLOAD) {
return !url.isLocalFile();
} else if (source.second
== KisClipboard::PASTE_FORMAT_LOCAL) {
return url.isLocalFile();
} else {
return false;
}
});
if (url != urls.constEnd()) {
QScopedPointer<QTemporaryFile> tmp(new QTemporaryFile());
tmp->setAutoRemove(true);
const QUrl localUrl = [&]() -> QUrl {
if (!url->isLocalFile()) {
// download the file and substitute the url
KisRemoteFileFetcher fetcher;
tmp->setFileName(url->fileName());
if (!fetcher.fetchFile(*url, tmp.data())) {
warnUI << "Fetching" << *url << "failed";
return {};
}
return QUrl::fromLocalFile(tmp->fileName());
}
return *url;
}();
if (localUrl.isLocalFile()) {
this->mainWindow()
->viewManager()
->imageManager()
->importImage(localUrl);
this->activateWindow();
return;
}
}
}
KisPaintDeviceSP clip =
KisClipboard::instance()->clipFromBoardContents(data,
QRect(),
true,
-1,
false,
source);
if (clip) {
const auto pos = this->viewConverter()->imageToDocument(imgCursorPos).toPoint();
const auto pos = this->viewConverter()
->imageToDocument(imgCursorPos)
.toPoint();
clip->moveTo(pos.x(), pos.y());
KisImportCatcher::adaptClipToImageColorSpace(clip, this->image());
KisImportCatcher::adaptClipToImageColorSpace(clip,
this->image());
KisPaintLayerSP layer = new KisPaintLayer(
this->image(),
this->image()->nextLayerName() + " " + i18n("(pasted)"),
OPACITY_OPAQUE_U8,
clip);
KisNodeCommandsAdapter adapter(this->mainWindow()->viewManager());
adapter.addNode(layer,
this->mainWindow()->viewManager()->activeNode()->parent(),
this->mainWindow()->viewManager()->activeNode());
KisNodeCommandsAdapter adapter(
this->mainWindow()->viewManager());
adapter.addNode(
layer,
this->mainWindow()->viewManager()->activeNode()->parent(),
this->mainWindow()->viewManager()->activeNode());
this->activateWindow();
return;
}
} else if (action == KisCanvasDrop::INSERT_AS_REFERENCE_IMAGE) {
KisPaintDeviceSP clip = KisClipboard::instance()->clipFromMimeData(data, QRect(), true);
KisPaintDeviceSP clip =
KisClipboard::instance()->clipFromMimeData(data, QRect(), true);
if (clip) {
KisImportCatcher::adaptClipToImageColorSpace(clip, this->image());
KisImportCatcher::adaptClipToImageColorSpace(clip,
this->image());
auto *reference = KisReferenceImage::fromPaintDevice(clip, *this->viewConverter(), this);
auto *reference =
KisReferenceImage::fromPaintDevice(clip,
*this->viewConverter(),
this);
if (reference) {
const auto pos = this->canvasBase()->coordinatesConverter()->widgetToImage(event->pos());
reference->setPosition((*this->viewConverter()).imageToDocument(pos));
this->canvasBase()->referenceImagesDecoration()->addReferenceImage(reference);
KoToolManager::instance()->switchToolRequested("ToolReferenceImages");
const auto pos = this->canvasBase()
->coordinatesConverter()
->widgetToImage(event->pos());
reference->setPosition(
(*this->viewConverter()).imageToDocument(pos));
this->canvasBase()
->referenceImagesDecoration()
->addReferenceImage(reference);
KoToolManager::instance()->switchToolRequested(
"ToolReferenceImages");
return;
}
}
......@@ -576,51 +653,85 @@ void KisView::dropEvent(QDropEvent *event)
if (url.isLocalFile()) {
if (action == KisCanvasDrop::INSERT_MANY_LAYERS) {
this->mainWindow()->viewManager()->imageManager()->importImage(url);
this->mainWindow()
->viewManager()
->imageManager()
->importImage(url);
this->activateWindow();
} else if (action == KisCanvasDrop::INSERT_MANY_FILE_LAYERS
|| action == KisCanvasDrop::INSERT_AS_NEW_FILE_LAYER) {
KisNodeCommandsAdapter adapter(this->mainWindow()->viewManager());
|| action
== KisCanvasDrop::INSERT_AS_NEW_FILE_LAYER) {
KisNodeCommandsAdapter adapter(
this->mainWindow()->viewManager());
QFileInfo fileInfo(url.toLocalFile());
QString type = KisMimeDatabase::mimeTypeForFile(url.toLocalFile());
QStringList mimes = KisImportExportManager::supportedMimeTypes(KisImportExportManager::Import);
QString type =
KisMimeDatabase::mimeTypeForFile(url.toLocalFile());
QStringList mimes =
KisImportExportManager::supportedMimeTypes(
KisImportExportManager::Import);
if (!mimes.contains(type)) {
QString msg =
KisImportExportErrorCode(ImportExportCodes::FileFormatNotSupported).errorMessage();
QMessageBox::warning(this,
i18nc("@title:window", "Krita"),
i18n("Could not open %2.\nReason: %1.", msg, url.toDisplayString()));
KisImportExportErrorCode(
ImportExportCodes::FileFormatNotSupported)
.errorMessage();
QMessageBox::warning(
this,
i18nc("@title:window", "Krita"),
i18n("Could not open %2.\nReason: %1.",
msg,
url.toDisplayString()));
continue;
}
KisFileLayer *fileLayer = new KisFileLayer(this->image(),
"",
url.toLocalFile(),
KisFileLayer::None,
fileInfo.fileName(),
OPACITY_OPAQUE_U8);
KisLayerSP above = this->mainWindow()->viewManager()->activeLayer();
KisNodeSP parent = above ? above->parent() : this->mainWindow()->viewManager()->image()->root();
KisFileLayer *fileLayer =
new KisFileLayer(this->image(),
"",
url.toLocalFile(),
KisFileLayer::None,
fileInfo.fileName(),
OPACITY_OPAQUE_U8);
KisLayerSP above =
this->mainWindow()->viewManager()->activeLayer();
KisNodeSP parent = above ? above->parent()
: this->mainWindow()
->viewManager()
->image()
->root();
adapter.addNode(fileLayer, parent, above);
} else if (action == KisCanvasDrop::OPEN_IN_NEW_DOCUMENT
|| action == KisCanvasDrop::OPEN_MANY_DOCUMENTS) {
|| action
== KisCanvasDrop::OPEN_MANY_DOCUMENTS) {
if (this->mainWindow()) {
this->mainWindow()->openDocument(url.toLocalFile(), KisMainWindow::None);
this->mainWindow()->openDocument(
url.toLocalFile(),
KisMainWindow::None);
}
} else if (action == KisCanvasDrop::INSERT_AS_REFERENCE_IMAGES
|| action == KisCanvasDrop::INSERT_AS_REFERENCE_IMAGE) {
auto *reference = KisReferenceImage::fromFile(url.toLocalFile(), *this->viewConverter(), this);
} else if (action
== KisCanvasDrop::INSERT_AS_REFERENCE_IMAGES
|| action
== KisCanvasDrop::
INSERT_AS_REFERENCE_IMAGE) {
auto *reference =
KisReferenceImage::fromFile(url.toLocalFile(),
*this->viewConverter(),
this);
if (reference) {
const auto pos = this->canvasBase()->coordinatesConverter()->widgetToImage(imgCursorPos);
reference->setPosition((*this->viewConverter()).imageToDocument(pos));
this->canvasBase()->referenceImagesDecoration()->addReferenceImage(reference);
KoToolManager::instance()->switchToolRequested("ToolReferenceImages");
const auto pos = this->canvasBase()
->coordinatesConverter()
->widgetToImage(imgCursorPos);
reference->setPosition(
(*this->viewConverter()).imageToDocument(pos));
this->canvasBase()
->referenceImagesDecoration()
->addReferenceImage(reference);
KoToolManager::instance()->switchToolRequested(
"ToolReferenceImages");
}
}
}
......
......@@ -339,16 +339,12 @@ KisPaintDeviceSP KisClipboard::clipFromKritaLayers(const QRect &imageBounds,
return tempImage->projection();
}
KisPaintDeviceSP KisClipboard::clipFromBoardContents(const QMimeData *cbData,
const QRect &imageBounds,
bool showPopup,
int pasteBehaviourOverride,
bool useClipboardFallback) const
QPair<bool, KisClipboard::PasteFormatBehaviour>
KisClipboard::askUserForSource(const QMimeData *cbData,
bool useClipboardFallback) const
{
KisPaintDeviceSP clip;
if (!cbData) {
return nullptr;
return {false, PASTE_FORMAT_ASK};
}
KisConfig cfg(true);
......@@ -402,7 +398,7 @@ KisPaintDeviceSP KisClipboard::clipFromBoardContents(const QMimeData *cbData,
dlg.setSourceAvailable(PASTE_FORMAT_CLIP, !qimage.isNull());
if (dlg.exec() != KoDialog::Accepted) {
return nullptr;
return {false, PASTE_FORMAT_ASK};
};
choice = dlg.source();
......@@ -416,7 +412,7 @@ KisPaintDeviceSP KisClipboard::clipFromBoardContents(const QMimeData *cbData,
} else if (cbData->hasImage()) {
choice = PASTE_FORMAT_CLIP;
} else {
return nullptr;
return {false, PASTE_FORMAT_ASK};
}
}
}
......@@ -427,12 +423,49 @@ KisPaintDeviceSP KisClipboard::clipFromBoardContents(const QMimeData *cbData,
dbgUI << "Selected source for the paste:" << choice;
return {true, choice};
}
KisPaintDeviceSP KisClipboard::clipFromBoardContents(
const QMimeData *cbData,
const QRect &imageBounds,
bool showPopup,
int pasteBehaviourOverride,
bool useClipboardFallback,
QPair<bool, PasteFormatBehaviour> source) const
{
if (!cbData) {
return nullptr;
}
KisPaintDeviceSP clip;
PasteFormatBehaviour choice = PASTE_FORMAT_ASK;
if (!source.first) {
choice = askUserForSource(cbData).second;
} else {
choice = source.second;
}
if (choice == PASTE_FORMAT_CLIP) {
const QImage qimage = [&]() {
QImage qimage = getImageFromMimeData(cbData);
if (qimage.isNull() && useClipboardFallback) {
qimage = d->clipboard->image();
}
return qimage;
}();
KIS_ASSERT(!qimage.isNull());
int behaviour = pasteBehaviourOverride;
bool saveColorSetting = false;
KisConfig cfg(true);
if (pasteBehaviourOverride == -1) {
behaviour = cfg.pasteBehaviour();
}
......
......@@ -64,6 +64,10 @@ public:
int overridePasteBehaviour = -1,
KisTimeSpan *clipRange = nullptr) const;
QPair<bool, PasteFormatBehaviour>
askUserForSource(const QMimeData *data,
bool useClipboardFallback = false) const;
/**
* Get the contents of the specified mimedata buffer in the form of a paint device.
*/
......@@ -77,6 +81,16 @@ public:
KisPaintDeviceSP clipFromKritaLayers(const QRect &imageBounds,
const KoColorSpace *cs) const;
KisPaintDeviceSP
clipFromBoardContents(const QMimeData *data,
const QRect &imageBounds,
bool showPopup,
int overridePasteBehaviour = -1,
bool useClipboardFallback = false,
QPair<bool, PasteFormatBehaviour> source = {
true,
PasteFormatBehaviour::PASTE_FORMAT_ASK}) const;
bool hasClip() const;
QSize clipSize() const;
......@@ -104,12 +118,6 @@ private:
KisPaintDeviceSP
clipFromKritaSelection(const QMimeData *data, const QRect &imageBounds, KisTimeSpan *clipRange) const;
KisPaintDeviceSP clipFromBoardContents(const QMimeData *data,
const QRect &imageBounds,
bool showPopup,
int overridePasteBehaviour = -1,
bool useClipboardFallback = false) const;
KisPaintDeviceSP fetchImageByURL(const QUrl &originalUrl) const;
QImage getImageFromMimeData(const QMimeData *cbData) const;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment