diff --git a/libs/image/kis_name_server.cpp b/libs/image/kis_name_server.cpp index 4487daa..1df964e 100644 --- a/libs/image/kis_name_server.cpp +++ b/libs/image/kis_name_server.cpp @@ -23,6 +23,11 @@ KisNameServer::KisNameServer(qint32 seed) m_generator = seed; } +KisNameServer::KisNameServer(const KisNameServer &rhs) + : m_generator(rhs.m_generator) +{ +} + KisNameServer::~KisNameServer() { } diff --git a/libs/image/kis_name_server.h b/libs/image/kis_name_server.h index aed1e92..24d10d7 100644 --- a/libs/image/kis_name_server.h +++ b/libs/image/kis_name_server.h @@ -25,6 +25,7 @@ class KRITAIMAGE_EXPORT KisNameServer { public: KisNameServer(qint32 seed = 1); + KisNameServer(const KisNameServer &rhs); ~KisNameServer(); qint32 number(); diff --git a/libs/odf/KoDocumentInfo.cpp b/libs/odf/KoDocumentInfo.cpp index 918a082..147be87 100644 --- a/libs/odf/KoDocumentInfo.cpp +++ b/libs/odf/KoDocumentInfo.cpp @@ -58,6 +58,17 @@ KoDocumentInfo::KoDocumentInfo(QObject *parent) : QObject(parent) .toString(Qt::ISODate)); } +KoDocumentInfo::KoDocumentInfo(const KoDocumentInfo &rhs, QObject *parent) + : QObject(parent), + m_aboutTags(rhs.m_aboutTags), + m_authorTags(rhs.m_authorTags), + m_authorInfo(m_authorInfo), + m_authorInfoOverride(m_authorInfoOverride), + m_aboutInfo(m_aboutInfo), + m_generator(m_generator) +{ +} + KoDocumentInfo::~KoDocumentInfo() { } diff --git a/libs/odf/KoDocumentInfo.h b/libs/odf/KoDocumentInfo.h index c047cfc..884c15e 100644 --- a/libs/odf/KoDocumentInfo.h +++ b/libs/odf/KoDocumentInfo.h @@ -57,6 +57,7 @@ public: * @param parent a pointer to the parent object */ explicit KoDocumentInfo(QObject *parent = 0); + explicit KoDocumentInfo(const KoDocumentInfo &rhs, QObject *parent = 0); /** The destructor */ ~KoDocumentInfo(); diff --git a/libs/ui/KisDocument.cpp b/libs/ui/KisDocument.cpp index 4ce0740..76f0569 100644 --- a/libs/ui/KisDocument.cpp +++ b/libs/ui/KisDocument.cpp @@ -113,6 +113,7 @@ #include "kis_guides_config.h" #include "kis_image_barrier_lock_adapter.h" #include +#include "kis_config_notifier.h" // Define the protocol used here for embedded documents' URL @@ -182,7 +183,8 @@ class UndoStack : public KUndo2Stack { public: UndoStack(KisDocument *doc) - : m_doc(doc) + : KUndo2Stack(doc), + m_doc(doc) { } @@ -245,31 +247,17 @@ private: class Q_DECL_HIDDEN KisDocument::Private { public: - Private() : - docInfo(0), - progressUpdater(0), - progressProxy(0), - importExportManager(0), - isImporting(false), - isExporting(false), - password(QString()), - modifiedAfterAutosave(false), - isAutosaving(false), - backupFile(true), - doNotSaveExtDoc(false), - undoStack(0), - m_saveOk(false), - m_waitForSave(false), - m_duringSaveAs(false), + Private(KisDocument *q) : + docInfo(new KoDocumentInfo(q)), // deleted by QObject + importExportManager(new KisImportExportManager(q)), // deleted manually + undoStack(new UndoStack(q)), // deleted by QObject m_bAutoDetectedMime(false), modified(false), readwrite(true), - disregardAutosaveFailure(false), - nserver(0), - macroNestDepth(0), + firstMod(QDateTime::currentDateTime()), + lastMod(firstMod), + nserver(new KisNameServer(1)), imageIdleWatcher(2000 /*ms*/), - suppressProgress(false), - fileProgressProxy(0), savingLock(&savingMutex) { if (QLocale().measurementSystem() == QLocale::ImperialSystem) { @@ -279,73 +267,84 @@ public: } } + Private(const Private &rhs, KisDocument *q) : + docInfo(new KoDocumentInfo(*rhs.docInfo, q)), + unit(rhs.unit), + importExportManager(new KisImportExportManager(q)), + mimeType(rhs.mimeType), + outputMimeType(rhs.outputMimeType), + undoStack(new UndoStack(q)), + guidesConfig(rhs.guidesConfig), + m_bAutoDetectedMime(rhs.m_bAutoDetectedMime), + m_url(rhs.m_url), + m_file(rhs.m_file), + modified(rhs.modified), + readwrite(rhs.readwrite), + firstMod(rhs.firstMod), + lastMod(rhs.lastMod), + nserver(new KisNameServer(*rhs.nserver)), + preActivatedNode(rhs.preActivatedNode), + imageIdleWatcher(2000 /*ms*/), + assistants(rhs.assistants), // WARNING: assistants should not store pointers to the document! + gridConfig(rhs.gridConfig), + savingLock(&savingMutex) + { + } + ~Private() { // Don't delete m_d->shapeController because it's in a QObject hierarchy. delete nserver; } - KoDocumentInfo *docInfo; + KoDocumentInfo *docInfo = 0; - KoProgressUpdater *progressUpdater; - KoProgressProxy *progressProxy; + KoProgressUpdater *progressUpdater = 0; + KoProgressProxy *progressProxy = 0; KoUnit unit; - KisImportExportManager *importExportManager; // The filter-manager to use when loading/saving [for the options] + KisImportExportManager *importExportManager = 0; // The filter-manager to use when loading/saving [for the options] QByteArray mimeType; // The actual mimetype of the document QByteArray outputMimeType; // The mimetype to use when saving - bool isImporting; - bool isExporting; // File --> Import/Export vs File --> Open/Save - QString password; // The password used to encrypt an encrypted document - QTimer autoSaveTimer; QString lastErrorMessage; // see openFile() QString lastWarningMessage; - int autoSaveDelay {300}; // in seconds, 0 to disable. - bool modifiedAfterAutosave; - bool isAutosaving; - bool backupFile; - bool doNotSaveExtDoc; // makes it possible to save only internally stored child documents + int autoSaveDelay = 300; // in seconds, 0 to disable. + bool modifiedAfterAutosave = false; + bool isAutosaving = false; + bool disregardAutosaveFailure = false; - KUndo2Stack *undoStack; + KUndo2Stack *undoStack = 0; KisGuidesConfig guidesConfig; - QUrl m_originalURL; // for saveAs - QString m_originalFilePath; // for saveAs - bool m_saveOk; - bool m_waitForSave; - bool m_duringSaveAs; - bool m_bAutoDetectedMime; // whether the mimetype in the arguments was detected by the part itself + bool m_bAutoDetectedMime = false; // whether the mimetype in the arguments was detected by the part itself QUrl m_url; // local url - the one displayed to the user. QString m_file; // Local file - the only one the part implementation should deal with. - QEventLoop m_eventLoop; + QMutex savingMutex; - bool modified; - bool readwrite; + bool modified = false; + bool readwrite = false; QDateTime firstMod; QDateTime lastMod; - bool disregardAutosaveFailure; - KisNameServer *nserver; - qint32 macroNestDepth; KisImageSP image; KisImageSP savingImage; KisNodeSP preActivatedNode; - KisShapeController* shapeController; - KoShapeController* koShapeController; + KisShapeController* shapeController = 0; + KoShapeController* koShapeController = 0; KisIdleWatcher imageIdleWatcher; QScopedPointer imageIdleConnection; - bool suppressProgress; - KoProgressProxy* fileProgressProxy; + bool suppressProgress = false; + KoProgressProxy* fileProgressProxy = 0; QList assistants; KisGridConfig gridConfig; @@ -433,37 +432,35 @@ private: }; KisDocument::KisDocument() - : d(new Private()) + : d(new Private(this)) { - d->undoStack = new UndoStack(this); - d->undoStack->setParent(this); - - d->importExportManager = new KisImportExportManager(this); - d->importExportManager->setProgresUpdater(d->progressUpdater); - + connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged())); + connect(d->undoStack, SIGNAL(indexChanged(int)), this, SLOT(slotUndoStackIndexChanged(int))); connect(&d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave())); - KisConfig cfg; - setAutoSaveDelay(cfg.autoSaveInterval()); - setObjectName(newObjectName()); - d->docInfo = new KoDocumentInfo(this); - - d->firstMod = QDateTime::currentDateTime(); - d->lastMod = QDateTime::currentDateTime(); - - // preload the krita resources KisResourceServerProvider::instance(); - d->nserver = new KisNameServer(1); + d->shapeController = new KisShapeController(this, d->nserver), + d->koShapeController = new KoShapeController(0, d->shapeController), - d->shapeController = new KisShapeController(this, d->nserver); - d->koShapeController = new KoShapeController(0, d->shapeController); + slotConfigChanged(); +} - undoStack()->setUndoLimit(KisConfig().undoStackLimit()); +KisDocument::KisDocument(const KisDocument &rhs) + : QObject(), + d(new Private(*rhs.d, this)) +{ + connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged())); connect(d->undoStack, SIGNAL(indexChanged(int)), this, SLOT(slotUndoStackIndexChanged(int))); - setBackupFile(KisConfig().backupFile()); + connect(&d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave())); + setObjectName(rhs.objectName()); + + d->shapeController = new KisShapeController(this, d->nserver), + d->koShapeController = new KoShapeController(0, d->shapeController), + + slotConfigChanged(); } KisDocument::~KisDocument() @@ -530,8 +527,6 @@ bool KisDocument::exportDocument(const QUrl &_url, KisPropertiesConfigurationSP //qDebug() << "exportDocument" << _url.toDisplayString() << "is autosaving" << d->isAutosaving; bool ret; - d->isExporting = true; - // // Preserve a lot of state here because we need to restore it in order to // be able to fake a File --> Export. Can't do this in saveFile() because, @@ -569,8 +564,6 @@ bool KisDocument::exportDocument(const QUrl &_url, KisPropertiesConfigurationSP setModified(wasModified); } - d->isExporting = false; - return ret; } @@ -581,20 +574,18 @@ bool KisDocument::saveAs(const QUrl &url, KisPropertiesConfigurationSP exportCon errKrita << "saveAs: Malformed URL " << url.url() << endl; return false; } - d->m_duringSaveAs = true; - d->m_originalURL = d->m_url; - d->m_originalFilePath = d->m_file; + + QUrl originalURL = d->m_url; + QString originalFilePath = d->m_file; + d->m_url = url; // Store where to upload in saveToURL d->m_file = d->m_url.toLocalFile(); bool result = save(exportConfiguration); // Save local file and upload local file if (!result) { - d->m_url = d->m_originalURL; - d->m_file = d->m_originalFilePath; - d->m_duringSaveAs = false; - d->m_originalURL = QUrl(); - d->m_originalFilePath.clear(); + d->m_url = originalURL; + d->m_file = originalFilePath; } return result; @@ -604,8 +595,6 @@ bool KisDocument::save(KisPropertiesConfigurationSP exportConfiguration) { //qDebug() << "save" << d->m_file << d->m_url << url() << localFilePath(); - d->m_saveOk = false; - if (d->m_file.isEmpty()) { // document was created empty d->m_file = d->m_url.toLocalFile(); } @@ -622,10 +611,6 @@ bool KisDocument::save(KisPropertiesConfigurationSP exportConfiguration) if (ok) { setModified( false ); emit completed(); - d->m_saveOk = true; - d->m_duringSaveAs = false; - d->m_originalURL = QUrl(); - d->m_originalFilePath.clear(); return true; // Nothing to do } else { @@ -656,7 +641,7 @@ QByteArray KisDocument::serializeToNativeByteArray() return byteArray; } -bool KisDocument::saveFile(const QString &filePath, KisPropertiesConfigurationSP exportConfiguration) +bool KisDocument::saveFile(const QString &filePath, bool isExporting, KisPropertiesConfigurationSP exportConfiguration) { if (!prepareLocksForSaving()) { return false; @@ -687,8 +672,9 @@ bool KisDocument::saveFile(const QString &filePath, KisPropertiesConfigurationSP //qDebug() << "saveFile. Is Autosaving?" << isAutosaving() << "url" << filePath << d->outputMimeType; + KisConfig cfg; - if (d->backupFile) { + if (cfg.backupFile()) { Q_ASSERT(url().isLocalFile()); KBackup::backupFile(url().toLocalFile()); } @@ -698,7 +684,7 @@ bool KisDocument::saveFile(const QString &filePath, KisPropertiesConfigurationSP setFileProgressUpdater(i18n("Saving Document")); //qDebug() << "saving to tempory file" << tempororaryFileName; - status = d->importExportManager->exportDocument(localFilePath(), filePath, outputMimeType, !d->isExporting , exportConfiguration); + status = d->importExportManager->exportDocument(localFilePath(), filePath, outputMimeType, !isExporting , exportConfiguration); ret = (status == KisImportExportFilter::OK); suppressErrorDialog = (fileBatchMode() || isAutosaving() || status == KisImportExportFilter::UserCancelled || status == KisImportExportFilter::BadConversionGraph); @@ -803,16 +789,6 @@ void KisDocument::setFileBatchMode(const bool batchMode) d->importExportManager->setBatchMode(batchMode); } -bool KisDocument::isImporting() const -{ - return d->isImporting; -} - -bool KisDocument::isExporting() const -{ - return d->isExporting; -} - void KisDocument::slotAutoSave() { //qDebug() << "slotAutoSave. Modified:" << d->modified << "modifiedAfterAutosave" << d->modified << "url" << url() << localFilePath(); @@ -930,7 +906,6 @@ bool KisDocument::importDocument(const QUrl &_url) bool ret; dbgUI << "url=" << _url.url(); - d->isImporting = true; // open... ret = openUrl(_url); @@ -943,8 +918,6 @@ bool KisDocument::importDocument(const QUrl &_url) setTitleModified(); } - d->isImporting = false; - return ret; } @@ -1315,11 +1288,6 @@ void KisDocument::removeAutoSaveFiles() } } -void KisDocument::setBackupFile(bool saveBackup) -{ - d->backupFile = saveBackup; -} - KoUnit KisDocument::unit() const { return d->unit; @@ -1365,6 +1333,13 @@ void KisDocument::slotUndoStackIndexChanged(int idx) setModified(idx != d->undoStack->cleanIndex()); } +void KisDocument::slotConfigChanged() +{ + KisConfig cfg; + d->undoStack->setUndoLimit(cfg.undoStackLimit()); + setAutoSaveDelay(cfg.autoSaveInterval()); +} + void KisDocument::clearUndoHistory() { d->undoStack->clear(); diff --git a/libs/ui/KisDocument.h b/libs/ui/KisDocument.h index d831511..935bc60 100644 --- a/libs/ui/KisDocument.h +++ b/libs/ui/KisDocument.h @@ -79,6 +79,7 @@ class KRITAUI_EXPORT KisDocument : public QObject, public KoDocumentBase protected: explicit KisDocument(); + explicit KisDocument(const KisDocument &rhs); public: @@ -301,12 +302,6 @@ public: void removeAutoSaveFiles(); /** - * @brief setBackupFile enable/disable saving a backup of the file on saving - * @param saveBackup if true, Krita will save a backup of the file - */ - void setBackupFile(bool saveBackup); - - /** * Returns true if this document or any of its internal child documents are modified. */ bool isModified() const; @@ -477,28 +472,12 @@ private: * 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, KisPropertiesConfigurationSP exportConfiguration = 0); + bool saveFile(const QString &filePath, bool isExporting, KisPropertiesConfigurationSP exportConfiguration = 0); /** @internal */ void setModified(); - /** - * Returns whether or not the current openUrl() or openFile() call is - * actually an import operation (like File --> Import). - * This is for informational purposes only. - */ - bool isImporting() const; - - /** - * Returns whether or not the current saveFile() call is actually an export - * operation (like File --> Export). - * If this function returns true during saveFile() and you are changing - * some sort of state, you _must_ restore it before the end of saveFile(); - * otherwise, File --> Export will not work properly. - */ - bool isExporting() const; - public: bool isAutosaving() const; @@ -607,6 +586,8 @@ private Q_SLOTS: /// Called by the undo stack when undo or redo is called void slotUndoStackIndexChanged(int idx); + void slotConfigChanged(); + private: diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc index 4b72ddc..b3e4998 100644 --- a/libs/ui/dialogs/kis_dlg_preferences.cc +++ b/libs/ui/dialogs/kis_dlg_preferences.cc @@ -1045,17 +1045,6 @@ bool KisDlgPreferences::editPreferences() cfg.setToolOptionsInDocker(dialog->m_general->toolOptionsInDocker()); cfg.setSwitchSelectionCtrlAlt(dialog->m_general->switchSelectionCtrlAlt()); cfg.setConvertToImageColorspaceOnImport(dialog->m_general->convertToImageColorspaceOnImport()); - - KisPart *part = KisPart::instance(); - if (part) { - Q_FOREACH (QPointer doc, part->documents()) { - if (doc) { - doc->setAutoSaveDelay(dialog->m_general->autoSaveInterval()); - doc->setBackupFile(dialog->m_general->m_backupFileCheckBox->isChecked()); - doc->undoStack()->setUndoLimit(dialog->m_general->undoStackSize()); - } - } - } cfg.setUndoStackLimit(dialog->m_general->undoStackSize()); cfg.setFavoritePresets(dialog->m_general->favoritePresets()); diff --git a/plugins/impex/psd/tests/kis_psd_test.cpp b/plugins/impex/psd/tests/kis_psd_test.cpp index 9fb6fa8..efbfbb5 100644 --- a/plugins/impex/psd/tests/kis_psd_test.cpp +++ b/plugins/impex/psd/tests/kis_psd_test.cpp @@ -81,7 +81,6 @@ void KisPSDTest::testTransparencyMask() QImage result = doc->image()->projection()->convertToQImage(0, doc->image()->bounds()); QVERIFY(TestUtil::checkQImageExternal(result, "psd_test", "transparency_masks", "kiki_single")); - doc->setBackupFile(false); doc->setOutputMimeType("image/vnd.adobe.photoshop"); QFileInfo dstFileInfo(QDir::currentPath() + QDir::separator() + "test_tmask.psd"); bool retval = doc->saveAs(QUrl::fromLocalFile(dstFileInfo.absoluteFilePath())); @@ -204,8 +203,6 @@ void KisPSDTest::testSaveLayerStylesWithPatternMulti() QVERIFY(layer->layerStyle()->stroke()->pattern()); QVERIFY(layer->layerStyle()->stroke()->pattern()->valid()); - - doc->setBackupFile(false); doc->setOutputMimeType("image/vnd.adobe.photoshop"); QFileInfo dstFileInfo(QDir::currentPath() + QDir::separator() + "test_save_styles.psd"); bool retval = doc->saveAs(QUrl::fromLocalFile(dstFileInfo.absoluteFilePath())); @@ -302,8 +299,8 @@ void KisPSDTest::testSavingAllFormats() QString baseName = sourceFileInfo.fileName(); - QString originalName = QString("%1_0orig").arg(baseName); - QString resultName = QString("%1_1result").arg(baseName); + //QString originalName = QString("%1_0orig").arg(baseName); + //QString resultName = QString("%1_1result").arg(baseName); QString tempPsdName = QString("%1_3interm.psd").arg(baseName); QImage refImage = doc->image()->projection()->convertToQImage(0, QRect(0,0,100,100)); @@ -311,7 +308,6 @@ void KisPSDTest::testSavingAllFormats() // uncomment to do a visual check // KIS_DUMP_DEVICE_2(doc->image()->projection(), QRect(0,0,100,100), originalName, "dd"); - doc->setBackupFile(false); doc->setOutputMimeType("image/vnd.adobe.photoshop"); QFileInfo dstFileInfo(QDir::currentPath() + QDir::separator() + tempPsdName);