Commit bb5db7ce authored by Dmitry Kazakov's avatar Dmitry Kazakov

Implement asynchronous saving of Krita documents

Now all the saving operations work in the following way:
1) Make a shallow copy of the image
2) Create a separate document with it
3) Save it in a separate thread in background

The functionality basically works, except the following parts:

1) Cloning the image "forgets" some image stuff. I don't have a list of what
   is forgotten yet (layer styles?).
2) Closing the image while Krita is saving will most probably cause a crash.
3) D&D of layers is not tested, though it should work.
4) There was some option to provide "real name" for json export plugin,
   it is not supported anymore.
parent 97087ccd
...@@ -44,7 +44,7 @@ void KisProjectionBenchmark::benchmarkProjection() ...@@ -44,7 +44,7 @@ void KisProjectionBenchmark::benchmarkProjection()
KisDocument *doc = KisPart::instance()->createDocument(); KisDocument *doc = KisPart::instance()->createDocument();
doc->loadNativeFormat(QString(FILES_DATA_DIR) + QDir::separator() + "load_test.kra"); doc->loadNativeFormat(QString(FILES_DATA_DIR) + QDir::separator() + "load_test.kra");
doc->image()->refreshGraph(); doc->image()->refreshGraph();
doc->exportDocument(QUrl::fromLocalFile(QString(FILES_OUTPUT_DIR) + QDir::separator() + "save_test.kra")); doc->exportDocument(QUrl::fromLocalFile(QString(FILES_OUTPUT_DIR) + QDir::separator() + "save_test.kra"), doc->mimeType());
delete doc; delete doc;
} }
} }
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <kis_shape_layer.h> #include <kis_shape_layer.h>
#include <kis_filter_configuration.h> #include <kis_filter_configuration.h>
#include <kis_selection.h> #include <kis_selection.h>
#include <KisMimeDatabase.h>
#include <KoColorSpace.h> #include <KoColorSpace.h>
#include <KoColorProfile.h> #include <KoColorProfile.h>
...@@ -382,7 +383,11 @@ void Document::crop(int x, int y, int w, int h) ...@@ -382,7 +383,11 @@ void Document::crop(int x, int y, int w, int h)
bool Document::exportImage(const QString &filename, const InfoObject &exportConfiguration) bool Document::exportImage(const QString &filename, const InfoObject &exportConfiguration)
{ {
if (!d->document) return false; if (!d->document) return false;
return d->document->exportDocument(QUrl::fromLocalFile(filename), exportConfiguration.configuration());
const QString outputFormatString = KisMimeDatabase::mimeTypeForFile(filename);
const QByteArray outputFormat = outputFormatString.toLatin1();
return d->document->exportDocument(QUrl::fromLocalFile(filename), outputFormat, exportConfiguration.configuration());
} }
void Document::flatten() void Document::flatten()
...@@ -412,7 +417,11 @@ bool Document::save() ...@@ -412,7 +417,11 @@ bool Document::save()
bool Document::saveAs(const QString &filename) bool Document::saveAs(const QString &filename)
{ {
if (!d->document) return false; if (!d->document) return false;
return d->document->saveAs(QUrl::fromLocalFile(filename), true);
const QString outputFormatString = KisMimeDatabase::mimeTypeForFile(filename);
const QByteArray outputFormat = outputFormatString.toLatin1();
return d->document->saveAs(QUrl::fromLocalFile(filename), outputFormat, true);
} }
Node* Document::createNode(const QString &name, const QString &nodeType) Node* Document::createNode(const QString &name, const QString &nodeType)
......
...@@ -444,7 +444,7 @@ bool Node::save(const QString &filename, double xRes, double yRes) ...@@ -444,7 +444,7 @@ bool Node::save(const QString &filename, double xRes, double yRes)
KisPaintDeviceSP projection = d->node->projection(); KisPaintDeviceSP projection = d->node->projection();
QRect bounds = d->node->exactBounds(); QRect bounds = d->node->exactBounds();
QString mimefilter = KisMimeDatabase::mimeTypeForFile(filename);; QString mimeType = KisMimeDatabase::mimeTypeForFile(filename);
QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument()); QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
KisImageSP dst = new KisImage(doc->createUndoStore(), KisImageSP dst = new KisImage(doc->createUndoStore(),
...@@ -459,9 +459,8 @@ bool Node::save(const QString &filename, double xRes, double yRes) ...@@ -459,9 +459,8 @@ bool Node::save(const QString &filename, double xRes, double yRes)
paintLayer->paintDevice()->makeCloneFrom(projection, bounds); paintLayer->paintDevice()->makeCloneFrom(projection, bounds);
dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0)); dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0));
dst->initialRefreshGraph(); dst->initialRefreshGraph();
doc->setOutputMimeType(mimefilter.toLatin1());
bool r = doc->exportDocument(QUrl::fromLocalFile(filename)); bool r = doc->exportDocument(QUrl::fromLocalFile(filename), mimeType.toLatin1());
if (!r) { if (!r) {
qWarning() << doc->errorMessage(); qWarning() << doc->errorMessage();
} }
......
...@@ -94,17 +94,6 @@ public: ...@@ -94,17 +94,6 @@ public:
virtual void setMimeType(const QByteArray & mimeType) = 0; virtual void setMimeType(const QByteArray & mimeType) = 0;
virtual QString localFilePath() const = 0; virtual QString localFilePath() const = 0;
/**
* @brief Set the format in which the document should be saved.
*
* This is called on loading, and in "save as", so you shouldn't
* have to call it.
*
* @param mimeType the mime type (format) to use.
*/
virtual void setOutputMimeType(const QByteArray & mimeType) = 0;
virtual QByteArray outputMimeType() const = 0;
private: private:
class Private; class Private;
......
...@@ -330,6 +330,7 @@ set(kritaui_LIB_SRCS ...@@ -330,6 +330,7 @@ set(kritaui_LIB_SRCS
KisImportExportFilter.cpp KisImportExportFilter.cpp
KisFilterEntry.cpp KisFilterEntry.cpp
KisImportExportManager.cpp KisImportExportManager.cpp
KisImportExportUtils.cpp
kis_async_action_feedback.cpp kis_async_action_feedback.cpp
KisMainWindow.cpp KisMainWindow.cpp
KisOpenPane.cpp KisOpenPane.cpp
......
...@@ -467,8 +467,7 @@ bool KisApplication::start(const KisApplicationArguments &args) ...@@ -467,8 +467,7 @@ bool KisApplication::start(const KisApplicationArguments &args)
qApp->processEvents(); // For vector layers to be updated qApp->processEvents(); // For vector layers to be updated
doc->setFileBatchMode(true); doc->setFileBatchMode(true);
doc->setOutputMimeType(outputMimetype.toLatin1()); if (!doc->exportDocument(QUrl::fromLocalFile(exportFileName), outputMimetype.toLatin1())) {
if (!doc->exportDocument(QUrl::fromLocalFile(exportFileName))) {
dbgKrita << "Could not export " << fileName << "to" << exportFileName << ":" << doc->errorMessage(); dbgKrita << "Could not export " << fileName << "to" << exportFileName << ":" << doc->errorMessage();
} }
nPrinted++; nPrinted++;
......
This diff is collapsed.
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <kis_types.h> #include <kis_types.h>
#include <kis_painting_assistant.h> #include <kis_painting_assistant.h>
#include <kis_debug.h> #include <kis_debug.h>
#include <KisImportExportUtils.h>
#include "kritaui_export.h" #include "kritaui_export.h"
...@@ -138,7 +139,9 @@ public: ...@@ -138,7 +139,9 @@ public:
* KisParts::ReadWritePart::saveAs() to implement KisMainWindow's * KisParts::ReadWritePart::saveAs() to implement KisMainWindow's
* File --> Export feature. * File --> Export feature.
*/ */
bool exportDocument(const QUrl &url, KisPropertiesConfigurationSP exportConfiguration = 0); bool exportDocument(const QUrl &url, const QByteArray &mimeType, bool showWarnings = false, KisPropertiesConfigurationSP exportConfiguration = 0);
bool exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration);
/** /**
* @brief Sets whether the document can be edited or is read only. * @brief Sets whether the document can be edited or is read only.
...@@ -177,17 +180,6 @@ public: ...@@ -177,17 +180,6 @@ public:
*/ */
void setMimeType(const QByteArray & mimeType); void setMimeType(const QByteArray & mimeType);
/**
* @brief Set the format in which the document should be saved.
*
* This is called on loading, and in "save as", so you shouldn't
* have to call it.
*
* @param mimeType the mime type (format) to use.
*/
void setOutputMimeType(const QByteArray & mimeType);
QByteArray outputMimeType() const;
/** /**
* @return true if file operations should inhibit the option dialog * @return true if file operations should inhibit the option dialog
*/ */
...@@ -451,18 +443,31 @@ Q_SIGNALS: ...@@ -451,18 +443,31 @@ Q_SIGNALS:
void sigGuidesConfigChanged(const KisGuidesConfig &config); void sigGuidesConfigChanged(const KisGuidesConfig &config);
void sigBackgroundSavingFinished(KisImportExportFilter::ConversionStatus status); void sigBackgroundSavingFinished(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void sigCompleteBackgroundSaving(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
private Q_SLOTS: private Q_SLOTS:
void finishExportInBackground(); void finishExportInBackground();
void slotChildCompletedSavingInBackground(KisImportExportFilter::ConversionStatus status); void slotChildCompletedSavingInBackground(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void slotCompleteAutoSaving(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void slotCompleteSavingDocument(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
private: private:
friend class KisPart; friend class KisPart;
friend class SafeSavingLocker; friend class SafeSavingLocker;
bool startExportInBackground(const QUrl &url, bool initiateSavingInBackground(const QString statusMessage,
const QByteArray &mimeType); const QObject *receiverObject, const char *receiverMethod,
const KritaUtils::ExportFileJob &job,
KisPropertiesConfigurationSP exportConfiguration);
bool startExportInBackground(const QString &location,
const QString &realLocation,
const QByteArray &mimeType,
bool showWarnings,
KisPropertiesConfigurationSP exportConfiguration);
/** /**
* Generate a name for the document. * Generate a name for the document.
...@@ -483,15 +488,6 @@ private: ...@@ -483,15 +488,6 @@ private:
*/ */
bool openFile(); bool openFile();
/**
* Saves a document
*
* Applies a filter if necessary, and calls exportDocument in any case
* You should not have to reimplement, except for very special cases.
*/
bool saveFile(const QString &filePath, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration = 0);
/** @internal */ /** @internal */
void setModified(); void setModified();
...@@ -513,7 +509,7 @@ public: ...@@ -513,7 +509,7 @@ public:
bool closeUrl(bool promptToSave = true); bool closeUrl(bool promptToSave = true);
bool saveAs(const QUrl &url, bool showWarnings, KisPropertiesConfigurationSP exportConfigration = 0); bool saveAs(const QUrl &url, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfigration = 0);
/** /**
* Create a new image that has this document as a parent and * Create a new image that has this document as a parent and
...@@ -600,17 +596,16 @@ private Q_SLOTS: ...@@ -600,17 +596,16 @@ private Q_SLOTS:
void slotAutoSave(); void slotAutoSave();
/// Called by the undo stack when undo or redo is called void slotUndoStackCleanChanged(bool value);
void slotUndoStackIndexChanged(int idx);
void slotConfigChanged(); void slotConfigChanged();
private: private:
bool prepareLocksForSaving(); KisDocument *safeCreateClone();
void unlockAfterSaving(); QString exportErrorToUserMessage(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
QString prettyPathOrUrl() const; QString prettyPathOrUrl() const;
......
...@@ -314,7 +314,7 @@ KisImportExportManager::ConversionResult KisImportExportManager::convert(KisImpo ...@@ -314,7 +314,7 @@ KisImportExportManager::ConversionResult KisImportExportManager::convert(KisImpo
// async importing is not yet supported! // async importing is not yet supported!
KIS_SAFE_ASSERT_RECOVER_NOOP(!isAsync); KIS_SAFE_ASSERT_RECOVER_NOOP(!isAsync);
if (!batchMode()) { if (0 && !batchMode()) {
KisAsyncActionFeedback f(i18n("Opening document..."), 0); KisAsyncActionFeedback f(i18n("Opening document..."), 0);
result = f.runAction(std::bind(&KisImportExportManager::doImport, this, location, filter)); result = f.runAction(std::bind(&KisImportExportManager::doImport, this, location, filter));
} else { } else {
......
/*
* Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "KisImportExportUtils.h"
namespace KritaUtils {
}
/*
* Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KISIMPORTEXPORTUTILS_H
#define KISIMPORTEXPORTUTILS_H
#include <QFlags>
#include <QString>
namespace KritaUtils {
enum SaveFlag {
SaveNone = 0,
SaveShowWarnings = 0x1,
SaveIsExporting = 0x2
};
Q_DECLARE_FLAGS(SaveFlags, SaveFlag)
Q_DECLARE_OPERATORS_FOR_FLAGS(SaveFlags)
struct ExportFileJob {
ExportFileJob()
: flags(SaveNone)
{
}
ExportFileJob(QString _filePath, QByteArray _mimeType, SaveFlags _flags = SaveNone)
: filePath(_filePath), mimeType(_mimeType), flags(_flags)
{
}
bool isValid() const {
return !filePath.isEmpty();
}
QString filePath;
QByteArray mimeType;
SaveFlags flags;
};
}
#endif // KISIMPORTEXPORTUTILS_H
...@@ -697,17 +697,23 @@ void KisMainWindow::updateCaption() ...@@ -697,17 +697,23 @@ void KisMainWindow::updateCaption()
updateCaption(QString(), false); updateCaption(QString(), false);
} }
else if (d->activeView && d->activeView->document()){ else if (d->activeView && d->activeView->document()){
QString caption( d->activeView->document()->caption() ); KisDocument *doc = d->activeView->document();
QString caption(doc->caption());
if (d->readOnly) { if (d->readOnly) {
caption += ' ' + i18n("(write protected)"); caption += ' ' + i18n("(write protected)");
} }
if (doc->isRecovered()) {
caption += ' ' + i18n("[RECOVERED]");
}
d->activeView->setWindowTitle(caption); d->activeView->setWindowTitle(caption);
updateCaption(caption, d->activeView->document()->isModified()); updateCaption(caption, doc->isModified());
if (!d->activeView->document()->url().fileName().isEmpty()) if (!doc->url().fileName().isEmpty())
d->saveAction->setToolTip(i18n("Save as %1", d->activeView->document()->url().fileName())); d->saveAction->setToolTip(i18n("Save as %1", doc->url().fileName()));
else else
d->saveAction->setToolTip(i18n("Save")); d->saveAction->setToolTip(i18n("Save"));
} }
...@@ -926,8 +932,8 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo ...@@ -926,8 +932,8 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo
QUrl oldURL = document->url(); QUrl oldURL = document->url();
QString oldFile = document->localFilePath(); QString oldFile = document->localFilePath();
QByteArray _native_format = document->nativeFormatMimeType(); QByteArray nativeFormat = document->nativeFormatMimeType();
QByteArray oldOutputFormat = document->outputMimeType(); QByteArray oldMimeFormat = document->mimeType();
QUrl suggestedURL = document->url(); QUrl suggestedURL = document->url();
...@@ -935,8 +941,8 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo ...@@ -935,8 +941,8 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo
mimeFilter = KisImportExportManager::mimeFilter(KisImportExportManager::Export); mimeFilter = KisImportExportManager::mimeFilter(KisImportExportManager::Export);
if (!mimeFilter.contains(oldOutputFormat) && !isExporting) { if (!mimeFilter.contains(oldMimeFormat) && !isExporting) {
dbgUI << "KisMainWindow::saveDocument no export filter for" << oldOutputFormat; dbgUI << "KisMainWindow::saveDocument no export filter for" << oldMimeFormat;
// --- don't setOutputMimeType in case the user cancels the Save As // --- don't setOutputMimeType in case the user cancels the Save As
// dialog and then tries to just plain Save --- // dialog and then tries to just plain Save ---
...@@ -947,7 +953,7 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo ...@@ -947,7 +953,7 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo
if (!suggestedFilename.isEmpty()) { // ".kra" looks strange for a name if (!suggestedFilename.isEmpty()) { // ".kra" looks strange for a name
int c = suggestedFilename.lastIndexOf('.'); int c = suggestedFilename.lastIndexOf('.');
const QString ext = KisMimeDatabase::suffixesForMimeType(_native_format).first(); const QString ext = KisMimeDatabase::suffixesForMimeType(nativeFormat).first();
if (!ext.isEmpty()) { if (!ext.isEmpty()) {
if (c < 0) if (c < 0)
suggestedFilename = suggestedFilename + "." + ext; suggestedFilename = suggestedFilename + "." + ext;
...@@ -984,13 +990,13 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo ...@@ -984,13 +990,13 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo
dialog.setDefaultDir(suggestedURL.toLocalFile()); dialog.setDefaultDir(suggestedURL.toLocalFile());
} }
// Default to all supported file types if user is exporting, otherwise use Krita default // Default to all supported file types if user is exporting, otherwise use Krita default
dialog.setMimeTypeFilters(mimeFilter, QString(_native_format)); dialog.setMimeTypeFilters(mimeFilter, QString(nativeFormat));
QUrl newURL = QUrl::fromUserInput(dialog.filename()); QUrl newURL = QUrl::fromUserInput(dialog.filename());
if (newURL.isLocalFile()) { if (newURL.isLocalFile()) {
QString fn = newURL.toLocalFile(); QString fn = newURL.toLocalFile();
if (QFileInfo(fn).completeSuffix().isEmpty()) { if (QFileInfo(fn).completeSuffix().isEmpty()) {
fn.append(KisMimeDatabase::suffixesForMimeType(_native_format).first()); fn.append(KisMimeDatabase::suffixesForMimeType(nativeFormat).first());
newURL = QUrl::fromLocalFile(fn); newURL = QUrl::fromLocalFile(fn);
} }
} }
...@@ -1001,7 +1007,7 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo ...@@ -1001,7 +1007,7 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo
document->documentInfo()->setAboutInfo("title", info.baseName()); document->documentInfo()->setAboutInfo("title", info.baseName());
} }
QByteArray outputFormat = _native_format; QByteArray outputFormat = nativeFormat;
QString outputFormatString = KisMimeDatabase::mimeTypeForFile(newURL.toLocalFile()); QString outputFormatString = KisMimeDatabase::mimeTypeForFile(newURL.toLocalFile());
outputFormat = outputFormatString.toLatin1(); outputFormat = outputFormatString.toLatin1();
...@@ -1052,9 +1058,8 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo ...@@ -1052,9 +1058,8 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo
// //
// - Clarence // - Clarence
// //
document->setOutputMimeType(outputFormat);
if (!isExporting) { // Save As if (!isExporting) { // Save As
ret = document->saveAs(newURL, true); ret = document->saveAs(newURL, outputFormat, true);
if (ret) { if (ret) {
dbgUI << "Successful Save As!"; dbgUI << "Successful Save As!";
...@@ -1064,19 +1069,15 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo ...@@ -1064,19 +1069,15 @@ bool KisMainWindow::saveDocument(KisDocument *document, bool saveas, bool isExpo
dbgUI << "Failed Save As!"; dbgUI << "Failed Save As!";
document->setUrl(oldURL); document->setUrl(oldURL);
document->setLocalFilePath(oldFile); document->setLocalFilePath(oldFile);
document->setOutputMimeType(oldOutputFormat);
} }
} else { // Export } else { // Export
ret = document->exportDocument(newURL); ret = document->exportDocument(newURL, outputFormat);
if (ret) { if (ret) {
// a few file dialog convenience things // a few file dialog convenience things
d->lastExportUrl = newURL; d->lastExportUrl = newURL;
d->lastExportedFormat = outputFormat; d->lastExportedFormat = outputFormat;
} }
// always restore output format
document->setOutputMimeType(oldOutputFormat);
} }
} // if (wantToSave) { } // if (wantToSave) {
...@@ -2220,12 +2221,8 @@ void KisMainWindow::applyDefaultSettings(QPrinter &printer) { ...@@ -2220,12 +2221,8 @@ void KisMainWindow::applyDefaultSettings(QPrinter &printer) {
QString title = d->activeView->document()->documentInfo()->aboutInfo("title"); QString title = d->activeView->document()->documentInfo()->aboutInfo("title");
if (title.isEmpty()) { if (title.isEmpty()) {
title = d->activeView->document()->url().fileName(); QFileInfo info(d->activeView->document()->url().fileName());
// strip off the native extension (I don't want foobar.kwd.ps when printing into a file) title = info.baseName();
QString extension = KisMimeDatabase::suffixesForMimeType(d->activeView->document()->outputMimeType()).first();
if (title.endsWith(extension)) {
title.chop(extension.length());
}
} }
if (title.isEmpty()) { if (title.isEmpty()) {
......
...@@ -115,12 +115,13 @@ bool KisSaveGroupVisitor::visit(KisGroupLayer *layer) ...@@ -115,12 +115,13 @@ bool KisSaveGroupVisitor::visit(KisGroupLayer *layer)
dst->refreshGraph(); dst->refreshGraph();
exportDocument->setOutputMimeType(m_mimeFilter.toLatin1());
exportDocument->setFileBatchMode(true);
QString path = m_path + "/" + m_baseName + "_" + layer->name().replace(' ', '_') + '.' + m_extension; QString path = m_path + "/" + m_baseName + "_" + layer->name().replace(' ', '_') + '.' + m_extension;
QUrl url = QUrl::fromLocalFile(path); QUrl url = QUrl::fromLocalFile(path);
exportDocument->exportDocument(url);
exportDocument->setFileBatchMode(true);
exportDocument->exportDocument(url, m_mimeFilter.toLatin1());
if (!m_saveTopLevelOnly) { if (!m_saveTopLevelOnly) {
KisGroupLayerSP child = dynamic_cast<KisGroupLayer*>(layer->firstChild().data()); KisGroupLayerSP child = dynamic_cast<KisGroupLayer*>(layer->firstChild().data());
......
...@@ -207,7 +207,7 @@ void KisTemplateCreateDia::createTemplate(const QString &templatesResourcePath, ...@@ -207,7 +207,7 @@ void KisTemplateCreateDia::createTemplate(const QString &templatesResourcePath,
} }
fileName = tempFile.fileName(); fileName = tempFile.fileName();
} }
bool retval = document->exportDocument(QUrl::fromLocalFile(fileName)); bool retval = document->exportDocument(QUrl::fromLocalFile(fileName), document->mimeType());
if (!retval) { if (!retval) {
qWarning("Could not save template"); qWarning("Could not save template");
return; return;
......
...@@ -713,7 +713,7 @@ bool KisView::queryClose() ...@@ -713,7 +713,7 @@ bool KisView::queryClose()
switch (res) { switch (res) {
case QMessageBox::Yes : { case QMessageBox::Yes : {
bool isNative = (document()->outputMimeType() == document()->nativeFormatMimeType()); bool isNative = (document()->mimeType() == document()->nativeFormatMimeType());
if (!viewManager()->mainWindow()->saveDocument(document(), !isNative, false)) if (!viewManager()->mainWindow()->saveDocument(document(), !isNative, false))
return false; return false;
break; break;
......
...@@ -871,6 +871,7 @@ void KisViewManager::slotSaveIncremental() ...@@ -871,6 +871,7 @@ void KisViewManager::slotSaveIncremental()
} }
version.remove(0, 1); // Trim "_" version.remove(0, 1); // Trim "_"
} else { } else {
// TODO: this will not work with files extensions like jp2
// ...else, simply add a version to it so the next loop works // ...else, simply add a version to it so the next loop works
QRegExp regex2("[.][a-z]{2,4}$"); // Heuristic to find file extension QRegExp regex2("[.][a-z]{2,4}$"); // Heuristic to find file extension
regex2.indexIn(fileName); regex2.indexIn(fileName);
...@@ -917,7 +918,7 @@ void KisViewManager::slotSaveIncremental() ...@@ -917,7 +918,7 @@ void KisViewManager::slotSaveIncremental()
return; return;
} }
document()->setFileBatchMode(true); document()->setFileBatchMode(true);
document()->saveAs(QUrl::fromUserInput(fileName), true); document()->saveAs(QUrl::fromUserInput(fileName), document()->mimeType(), true);
document()->setFileBatchMode(false); document()->setFileBatchMode(false);
if (mainWindow()) { if (mainWindow()) {
...@@ -988,7 +989,7 @@ void KisViewManager::slotSaveIncrementalBackup() ...@@ -988,7 +989,7 @@ void KisViewManager::slotSaveIncrementalBackup()
return; return;
} }