Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

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

Fix crash when changing reference image embedding

Crash happened, when a reference was set to embedded, the file was saved
and the linked option was selected.

This fix makes the code more robust by separating the external and
internal (in .kra) filenames.
parent 3929649e
......@@ -35,7 +35,12 @@
struct KisReferenceImage::Private {
KisReferenceImage *q;
QString src;
// Filename within .kra (for embedding)
QString internalFilename;
// File on disk (for linking)
QString externalFilename;
QImage image;
QImage cachedImage;
......@@ -49,9 +54,8 @@ struct KisReferenceImage::Private {
{}
bool loadFromFile() {
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(src.startsWith("file://"), false);
QString filename = src.mid(7);
return image.load(filename);
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!externalFilename.isEmpty(), false);
return image.load(externalFilename);
}
void updateCache() {
......@@ -122,7 +126,7 @@ KisReferenceImage::~KisReferenceImage()
KisReferenceImage * KisReferenceImage::fromFile(const QString &filename, const KisCoordinatesConverter &converter, QWidget *parent)
{
KisReferenceImage *reference = new KisReferenceImage();
reference->d->src = QString("file://") + filename;
reference->d->externalFilename = filename;
bool ok = reference->d->loadFromFile();
if (ok) {
......@@ -178,7 +182,7 @@ qreal KisReferenceImage::saturation() const
void KisReferenceImage::setEmbed(bool embed)
{
KIS_SAFE_ASSERT_RECOVER_RETURN(embed || d->src.startsWith("file://"));
KIS_SAFE_ASSERT_RECOVER_RETURN(embed || !d->externalFilename.isEmpty());
d->embed = embed;
}
......@@ -189,17 +193,23 @@ bool KisReferenceImage::embed()
bool KisReferenceImage::hasLocalFile()
{
return d->src.startsWith("file://");
return !d->externalFilename.isEmpty();
}
QString KisReferenceImage::url() const
QString KisReferenceImage::filename() const
{
return d->src;
return d->externalFilename;
}
void KisReferenceImage::setUrl(const QString &url)
QString KisReferenceImage::internalFile() const
{
d->src = url;
return d->internalFilename;
}
void KisReferenceImage::setFilename(const QString &filename)
{
d->externalFilename = filename;
d->embed = false;
}
......@@ -225,9 +235,11 @@ void KisReferenceImage::saveXml(QDomDocument &document, QDomElement &parentEleme
QDomElement element = document.createElement("referenceimage");
if (d->embed) {
d->src = QString("reference_images/%1.png").arg(id);
d->internalFilename = QString("reference_images/%1.png").arg(id);
}
element.setAttribute("src", d->src);
const QString src = d->embed ? d->internalFilename : (QString("file://") + d->externalFilename);
element.setAttribute("src", src);
const QSizeF &shapeSize = size();
element.setAttribute("width", KisDomUtils::toString(shapeSize.width()));
......@@ -246,8 +258,14 @@ KisReferenceImage * KisReferenceImage::fromXml(const QDomElement &elem)
auto *reference = new KisReferenceImage();
const QString &src = elem.attribute("src");
reference->d->src = src;
reference->d->embed = !src.startsWith("file://");
if (src.startsWith("file://")) {
reference->d->externalFilename = src.mid(7);
reference->d->embed = false;
} else {
reference->d->internalFilename = src;
reference->d->embed = true;
}
qreal width = KisDomUtils::toDouble(elem.attribute("width", "100"));
qreal height = KisDomUtils::toDouble(elem.attribute("height", "100"));
......@@ -270,7 +288,7 @@ bool KisReferenceImage::saveImage(KoStore *store) const
{
if (!d->embed) return true;
if (!store->open(d->src)) {
if (!store->open(d->internalFilename)) {
return false;
}
......@@ -286,11 +304,11 @@ bool KisReferenceImage::saveImage(KoStore *store) const
bool KisReferenceImage::loadImage(KoStore *store)
{
if (d->src.startsWith("file://")) {
if (!d->embed) {
return d->loadFromFile();
}
if (!store->open(d->src)) {
if (!store->open(d->internalFilename)) {
return false;
}
......
......@@ -71,8 +71,9 @@ public:
bool embed();
bool hasLocalFile();
void setUrl(const QString &url);
QString url() const;
void setFilename(const QString &filename);
QString filename() const;
QString internalFile() const;
void paint(QPainter &gc, const KoViewConverter &converter, KoShapePaintingContext &paintcontext) override;
......
......@@ -139,15 +139,15 @@ bool KisKraLoadVisitor::visit(KisExternalLayer * layer)
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(reference, false);
while (!reference->loadImage(m_store)) {
if (!reference->hasLocalFile()) {
m_errorMessages << i18n("Could not load embedded reference image %1 ", reference->url());
if (reference->embed()) {
m_errorMessages << i18n("Could not load embedded reference image %1 ", reference->internalFile());
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());
"Do you want to select another location?", reference->filename());
int locateManually = QMessageBox::warning(0, i18nc("@title:window", "File not found"), msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
......@@ -161,7 +161,7 @@ bool KisKraLoadVisitor::visit(KisExternalLayer * layer)
if (url.isEmpty()) {
break;
} else {
reference->setUrl(QString("file://") + url);
reference->setFilename(url);
}
}
}
......
......@@ -100,7 +100,7 @@ bool KisKraSaveVisitor::visit(KisExternalLayer * layer)
KIS_ASSERT_RECOVER_RETURN_VALUE(reference, false);
bool saved = reference->saveImage(m_store);
if (!saved) {
m_errorMessages << i18n("Failed to save reference image %1.", reference->url());
m_errorMessages << i18n("Failed to save reference image %1.", reference->internalFile());
result = false;
}
}
......
......@@ -93,7 +93,7 @@ bool KisReferenceImageCollection::load(QIODevice *io)
if (reference->loadImage(store.data())) {
references.append(reference);
} else {
failures << reference->url();
failures << (reference->embed() ? reference->internalFile() : reference->filename());
delete reference;
}
element = element.nextSiblingElement("referenceimage");
......
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