Commit e0cede28 authored by Jouni Pentikäinen's avatar Jouni Pentikäinen

Handle failure to load reference images

CCBUG: 396143
parent c16dbaee
......@@ -20,13 +20,13 @@
#include "KisReferenceImage.h"
#include <QImage>
#include <QMessageBox>
#include <QPainter>
#include <kundo2command.h>
#include <KoStore.h>
#include <KoStoreDevice.h>
#include <KoTosContainer_p.h>
#include <krita_utils.h>
#include <kis_coordinates_converter.h>
#include <kis_dom_utils.h>
......@@ -48,10 +48,10 @@ struct KisReferenceImage::Private {
: q(q)
{}
void loadFromFile() {
KIS_SAFE_ASSERT_RECOVER_RETURN(src.startsWith("file://"));
bool loadFromFile() {
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(src.startsWith("file://"), false);
QString filename = src.mid(7);
image.load(filename);
return image.load(filename);
}
void updateCache() {
......@@ -119,15 +119,25 @@ KisReferenceImage::KisReferenceImage(const KisReferenceImage &rhs)
KisReferenceImage::~KisReferenceImage()
{}
KisReferenceImage * KisReferenceImage::fromFile(const QString &filename, const KisCoordinatesConverter &converter)
KisReferenceImage * KisReferenceImage::fromFile(const QString &filename, const KisCoordinatesConverter &converter, QWidget *parent)
{
KisReferenceImage *reference = new KisReferenceImage();
reference->d->src = QString("file://") + filename;
reference->d->loadFromFile();
bool ok = reference->d->loadFromFile();
if (ok) {
QRect r = QRect(QPoint(), reference->d->image.size());
QSizeF shapeSize = converter.imageToDocument(r).size();
reference->setSize(shapeSize);
} else {
delete reference;
if (parent) {
QMessageBox::critical(parent, i18nc("@title:window", "Krita"), i18n("Could not load %1.", filename));
}
QRect r = QRect(QPoint(), reference->d->image.size());
QSizeF shapeSize = converter.imageToDocument(r).size();
reference->setSize(shapeSize);
return nullptr;
}
return reference;
}
......@@ -182,6 +192,17 @@ bool KisReferenceImage::hasLocalFile()
return d->src.startsWith("file://");
}
QString KisReferenceImage::url() const
{
return d->src;
}
void KisReferenceImage::setUrl(const QString &url)
{
d->src = url;
d->embed = false;
}
QColor KisReferenceImage::getPixel(QPointF position)
{
const QSizeF shapeSize = size();
......@@ -268,8 +289,7 @@ bool KisReferenceImage::saveImage(KoStore *store) const
bool KisReferenceImage::loadImage(KoStore *store)
{
if (d->src.startsWith("file://")) {
d->loadFromFile();
return true;
return d->loadFromFile();
}
if (!store->open(d->src)) {
......
......@@ -57,7 +57,12 @@ public:
KoShape *cloneShape() const override;
static KisReferenceImage * fromFile(const QString &filename, const KisCoordinatesConverter &converter);
/**
* Load a reference image from specified file.
* If parent is provided and the image cannot be loaded, a warning message will be displayed to user.
* @return reference image or null if one could not be loaded
*/
static KisReferenceImage * fromFile(const QString &filename, const KisCoordinatesConverter &converter, QWidget *parent /*= nullptr*/);
void setSaturation(qreal saturation);
qreal saturation() const;
......@@ -66,6 +71,9 @@ public:
bool embed();
bool hasLocalFile();
void setUrl(const QString &url);
QString url() const;
void paint(QPainter &gc, const KoViewConverter &converter, KoShapePaintingContext &paintcontext) override;
bool loadOdf(const KoXmlElement &/*element*/, KoShapeLoadingContext &/*context*/) override { return false; }
......
......@@ -582,11 +582,14 @@ void KisView::dropEvent(QDropEvent *event)
}
}
else if (action == insertAsReferenceImage || action == insertAsReferenceImages) {
auto *reference = KisReferenceImage::fromFile(url.toLocalFile(), d->viewConverter);
reference->setPosition(d->viewConverter.imageToDocument(cursorPos));
d->referenceImagesDecoration->addReferenceImage(reference);
auto *reference = KisReferenceImage::fromFile(url.toLocalFile(), d->viewConverter, this);
KoToolManager::instance()->switchToolRequested("ToolReferenceImages");
if (reference) {
reference->setPosition(d->viewConverter.imageToDocument(cursorPos));
d->referenceImagesDecoration->addReferenceImage(reference);
KoToolManager::instance()->switchToolRequested("ToolReferenceImages");
}
}
}
......
......@@ -22,13 +22,16 @@
#include "flake/kis_shape_layer.h"
#include "flake/KisReferenceImagesLayer.h"
#include "KisReferenceImage.h"
#include <KisImportExportManager.h>
#include <QRect>
#include <QBuffer>
#include <QByteArray>
#include <QMessageBox>
#include <KoColorSpaceRegistry.h>
#include <KoColorProfile.h>
#include <KoFileDialog.h>
#include <KoStore.h>
#include <KoColorSpace.h>
......@@ -134,7 +137,34 @@ bool KisKraLoadVisitor::visit(KisExternalLayer * layer)
Q_FOREACH(KoShape *shape, referencesLayer->shapes()) {
auto *reference = dynamic_cast<KisReferenceImage*>(shape);
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(reference, false);
reference->loadImage(m_store);
while (!reference->loadImage(m_store)) {
if (!reference->hasLocalFile()) {
m_errorMessages << i18n("Could not load embedded reference image %1 ", reference->url());
break;
} else {
QString msg = i18nc(
"@info",
"A reference image linked to an external file could not be loaded.\n\n"
"Path: %1\n\n"
"Do you want to select another location?", reference->url());
int locateManually = QMessageBox::warning(0, i18nc("@title:window", "File not found"), msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
QString url;
if (locateManually == QMessageBox::Yes) {
KoFileDialog dialog(0, KoFileDialog::OpenFile, "OpenDocument");
dialog.setMimeTypeFilters(KisImportExportManager::supportedMimeTypes(KisImportExportManager::Import));
url = dialog.filename();
}
if (url.isEmpty()) {
break;
} else {
reference->setUrl(QString("file://") + url);
}
}
}
}
} else if (KisShapeLayer *shapeLayer = dynamic_cast<KisShapeLayer*>(layer)) {
......
......@@ -18,6 +18,7 @@
#include "KisReferenceImageCollection.h"
#include <QIODevice>
#include <QMessageBox>
#include <libs/store/KoStore.h>
#include <KisReferenceImage.h>
......@@ -83,14 +84,30 @@ bool KisReferenceImageCollection::load(QIODevice *io)
doc.setContent(xml);
QDomElement root = doc.documentElement();
QStringList failures;
QDomElement element = root.firstChildElement("referenceimage");
while (!element.isNull()) {
KisReferenceImage *reference = KisReferenceImage::fromXml(element);
reference->loadImage(store.data());
references.append(reference);
if (reference->loadImage(store.data())) {
references.append(reference);
} else {
failures << reference->url();
delete reference;
}
element = element.nextSiblingElement("referenceimage");
}
if (!failures.isEmpty()) {
QMessageBox::warning(
0,
i18nc("@title:window", "Krita"),
"The following reference images could not be loaded:\n" + failures.join('\n'),
QMessageBox::Ok, QMessageBox::Ok
);
}
return true;
}
......@@ -100,10 +100,12 @@ void ToolReferenceImages::addReferenceImage()
if (filename.isEmpty()) return;
if (!QFileInfo(filename).exists()) return;
auto *reference = KisReferenceImage::fromFile(filename, *kisCanvas->coordinatesConverter());
auto *reference = KisReferenceImage::fromFile(filename, *kisCanvas->coordinatesConverter(), canvas()->canvasWidget());
KisDocument *doc = document();
doc->addCommand(KisReferenceImagesLayer::addReferenceImages(doc, {reference}));
if (reference) {
KisDocument *doc = document();
doc->addCommand(KisReferenceImagesLayer::addReferenceImages(doc, {reference}));
}
}
void ToolReferenceImages::removeAllReferenceImages()
......
Markdown is supported
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