File indexing completed on 2024-05-19 04:29:12

0001 /* This file is part of the Krita project
0002  *
0003  * SPDX-FileCopyrightText: 2014 Boudewijn Rempt <boud@valdyas.org>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #ifndef KISDOCUMENT_H
0009 #define KISDOCUMENT_H
0010 
0011 #include <QDateTime>
0012 #include <QTransform>
0013 #include <QList>
0014 #include <QFileInfo>
0015 
0016 #include <klocalizedstring.h>
0017 
0018 #include <kundo2stack.h>
0019 #include <KoColorSet.h>
0020 
0021 #include <kis_image.h>
0022 #include <KisImportExportFilter.h>
0023 #include <kis_properties_configuration.h>
0024 #include <kis_types.h>
0025 #include <kis_painting_assistant.h>
0026 #include <KisReferenceImage.h>
0027 #include <kis_debug.h>
0028 #include <KisImportExportUtils.h>
0029 #include <kis_config.h>
0030 #include "kis_scratch_pad.h"
0031 #include "StoryboardItem.h"
0032 
0033 #include "kritaui_export.h"
0034 
0035 #include <memory>
0036 
0037 class QString;
0038 
0039 class KUndo2Command;
0040 class KoUnit;
0041 
0042 class KoColor;
0043 class KoColorSpace;
0044 class KoShapeControllerBase;
0045 class KoShapeLayer;
0046 class KoStore;
0047 class KoDocumentInfo;
0048 class KoDocumentInfoDlg;
0049 class KisImportExportManager;
0050 class KisUndoStore;
0051 class KisPart;
0052 class KisGridConfig;
0053 class KisGuidesConfig;
0054 class KisMirrorAxisConfig;
0055 class QDomDocument;
0056 class KisReferenceImagesLayer;
0057 
0058 #define KIS_MIME_TYPE "application/x-krita"
0059 
0060 /**
0061  *  KisDocument contains the image and keeps track of loading,
0062  *  modification, undo stack and saving.
0063  */
0064 class KRITAUI_EXPORT KisDocument : public QObject
0065 {
0066     Q_OBJECT
0067 
0068 protected:
0069 
0070     explicit KisDocument(bool addStorage = true);
0071 
0072     /**
0073      * @brief KisDocument makes a deep copy of the document \p rhs.
0074      *        The caller *must* ensure that the image is properly
0075      *        locked and is in consistent state before asking for
0076      *        cloning.
0077      * @param rhs the source document to copy from
0078      */
0079     explicit KisDocument(const KisDocument &rhs, bool addStorage);
0080 
0081 public:
0082     enum OpenFlag {
0083         None = 0,
0084         DontAddToRecent = 0x1,
0085         RecoveryFile = 0x2
0086     };
0087     Q_DECLARE_FLAGS(OpenFlags, OpenFlag)
0088 
0089     /**
0090      *  Destructor.
0091      *
0092      * The destructor does not delete any attached KisView objects and it does not
0093      * delete the attached widget as returned by widget().
0094      */
0095     ~KisDocument();
0096 
0097     /**
0098      * Temporary storage for the resources that are embedded into other
0099      * resources used by the document. E.g. patterns embedded into layer
0100      * styles.
0101      */
0102     QString embeddedResourcesStorageId() const;
0103 
0104     /**
0105      * Persistent storage for the resources that are linked but the resources
0106      * embedded in the document. These resources are not embedded into their own
0107      * container resource, so they should be stored by the document
0108      *
0109      * All these resources are saved into the document itself and loaded
0110      * alongside the document.
0111      */
0112     QString linkedResourcesStorageId() const;
0113 
0114     /**
0115      * @brief creates a clone of the document and returns it. Please make sure that you
0116      * hold all the necessary locks on the image before asking for a clone!
0117      */
0118     KisDocument *clone(bool addStorage = false);
0119 
0120     /**
0121      * @brief openPath Open a Path
0122      * @param path Path to file
0123      * @param flags Control specific behavior
0124      * @return success status
0125      */
0126     bool openPath(const QString &path, OpenFlags flags = None);
0127 
0128     /**
0129      * Opens the document given by @p path, without storing the Path
0130      * in the KisDocument.
0131      * Call this instead of openPath() to implement KisMainWindow's
0132      * File --> Import feature.
0133      *
0134      * @note This will call openPath(). To differentiate this from an ordinary
0135      *       Open operation (in any reimplementation of openPath() or openFile())
0136      *       call isImporting().
0137      */
0138     bool importDocument(const QString &path);
0139 
0140     /**
0141      * Saves the document as @p path without changing the state of the
0142      * KisDocument (Path, modified flag etc.). Call this instead of
0143      * saveAs() to implement KisMainWindow's File --> Export feature.
0144      * Make sure to provide two separate bool parameters otherwise it will mix them
0145      */
0146     bool exportDocument(const QString &path, const QByteArray &mimeType,bool isAdvancedExporting = false, bool showWarnings = false, KisPropertiesConfigurationSP exportConfiguration = 0);
0147     /**
0148      * Exports he document is a synchronous way. The caller must ensure that the
0149      * image is not accessed by any other actors, because the exporting happens
0150      * without holding the image lock.
0151      */
0152     bool exportDocumentSync(const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration = 0);
0153 
0154 private:
0155     bool exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting= false);
0156 
0157 public:
0158     /**
0159      * @brief Sets whether the document can be edited or is read only.
0160      *
0161      * This recursively applied to all child documents and
0162      * KisView::updateReadWrite is called for every attached
0163      * view.
0164      */
0165     void setReadWrite(bool readwrite = true);
0166 
0167     /**
0168      * To be preferred when a document exists. It is fast when calling
0169      * it multiple times since it caches the result that readNativeFormatMimeType()
0170      * delivers.
0171      * This comes from the X-KDE-NativeMimeType key in the .desktop file.
0172      */
0173     static QByteArray nativeFormatMimeType() { return KIS_MIME_TYPE; }
0174 
0175     /// Checks whether a given mimeType can be handled natively.
0176     bool isNativeFormat(const QByteArray& mimeType) const;
0177 
0178     /// Returns a list of the mimeTypes considered "native", i.e. which can
0179     /// be saved by KisDocument without a filter, in *addition* to the main one
0180     static QStringList extraNativeMimeTypes() { return QStringList() << KIS_MIME_TYPE; }
0181 
0182     /**
0183      * Returns the actual mimeType of the document
0184      */
0185     QByteArray mimeType() const;
0186 
0187     /**
0188      * @brief Sets the mime type for the document.
0189      *
0190      * When choosing "save as" this is also the mime type
0191      * selected by default.
0192      */
0193     void setMimeType(const QByteArray & mimeType);
0194 
0195     /**
0196      * @return true if file operations should inhibit the option dialog
0197      */
0198     bool fileBatchMode() const;
0199 
0200     /**
0201      * @param batchMode if true, do not show the option dialog for file operations.
0202      */
0203     void setFileBatchMode(const bool batchMode);
0204 
0205     /**
0206      * Sets the error message to be shown to the user (use i18n()!)
0207      * when loading or saving fails.
0208      * If you asked the user about something and they chose "Cancel",
0209      */
0210     void setErrorMessage(const QString& errMsg);
0211 
0212     /**
0213      * Return the last error message. Usually KisDocument takes care of
0214      * showing it; this method is mostly provided for non-interactive use.
0215      */
0216     QString errorMessage() const;
0217 
0218     /**
0219      * Sets the warning message to be shown to the user (use i18n()!)
0220      * when loading or saving fails.
0221      */
0222     void setWarningMessage(const QString& warningMsg);
0223 
0224     /**
0225      * Return the last warning message set by loading or saving. Warnings
0226      * mean that the document could not be completely loaded, but the errors
0227      * were not absolutely fatal.
0228      */
0229     QString warningMessage() const;
0230 
0231     /**
0232      * @brief Generates a preview picture of the document
0233      * @note The preview is used in the File Dialog and also to create the Thumbnail
0234      */
0235     QPixmap generatePreview(const QSize& size);
0236 
0237     /**
0238      *  @brief Sets the document to empty.
0239      *
0240      *  Used after loading a template
0241      *  (which is not empty, but not the user's input).
0242      *
0243      *  @see isEmpty()
0244      */
0245     void setEmpty(bool empty = true);
0246 
0247     /**
0248      *  Return a correctly created QDomDocument for this KisDocument,
0249      *  including processing instruction, complete DOCTYPE tag (with systemId and publicId), and root element.
0250      *  @param tagName the name of the tag for the root element
0251      *  @param version the DTD version (usually the application's version).
0252      */
0253     QDomDocument createDomDocument(const QString& tagName, const QString& version) const;
0254 
0255     /**
0256      *  Return a correctly created QDomDocument for an old (1.3-style) Krita document,
0257      *  including processing instruction, complete DOCTYPE tag (with systemId and publicId), and root element.
0258      *  This static method can be used e.g. by filters.
0259      *  @param appName the app's instance name, e.g. words, kspread, kpresenter etc.
0260      *  @param tagName the name of the tag for the root element, e.g. DOC for words/kpresenter.
0261      *  @param version the DTD version (usually the application's version).
0262      */
0263     static QDomDocument createDomDocument(const QString& appName, const QString& tagName, const QString& version);
0264 
0265    /**
0266      *  Loads a document in the native format from a given Path.
0267      *  Reimplement if your native format isn't XML.
0268      *
0269      *  @param file the file to load - usually KReadOnlyPart::m_file or the result of a filter
0270      */
0271     bool loadNativeFormat(const QString & file);
0272 
0273     /**
0274      * Set standard autosave interval that is set by a config file
0275      */
0276     void setNormalAutoSaveInterval();
0277 
0278     /**
0279      * Set emergency interval that autosave uses when the image is busy,
0280      * by default it is 10 sec
0281      */
0282     void setEmergencyAutoSaveInterval();
0283 
0284     /**
0285      * Disable autosave
0286      */
0287     void setInfiniteAutoSaveInterval();
0288 
0289     /**
0290      * @return the information concerning this document.
0291      * @see KoDocumentInfo
0292      */
0293     KoDocumentInfo *documentInfo() const;
0294 
0295     /**
0296      * Performs a cleanup of unneeded backup files
0297      */
0298     void removeAutoSaveFiles(const QString &autosaveBaseName, bool wasRecovered);
0299 
0300     /**
0301      * Returns true if this document or any of its internal child documents are modified.
0302      */
0303     bool isModified() const;
0304 
0305     /**
0306      * @return caption of the document
0307      *
0308      * Caption is of the form "[title] - [path]",
0309      * built out of the document info (title) and pretty-printed
0310      * document Path.
0311      * If the title is not present, only the Path it returned.
0312      */
0313     QString caption() const;
0314 
0315     /**
0316      * Sets the document Path to empty Path
0317      * After using loadNativeFormat on a template, one wants
0318      * to set the path to QString()
0319      */
0320     void resetPath();
0321 
0322     /**
0323      * @internal (public for KisMainWindow)
0324      */
0325     void setMimeTypeAfterLoading(const QString& mimeType);
0326 
0327     /**
0328      * Returns the unit used to display all measures/distances.
0329      */
0330     KoUnit unit() const;
0331 
0332     /**
0333      * Sets the unit used to display all measures/distances.
0334      */
0335     void setUnit(const KoUnit &unit);
0336 
0337     KisGridConfig gridConfig() const;
0338     void setGridConfig(const KisGridConfig &config);
0339 
0340     /// returns the guides data for this document.
0341     const KisGuidesConfig& guidesConfig() const;
0342     void setGuidesConfig(const KisGuidesConfig &data);
0343 
0344     /**
0345      * @brief linkedDocumentResources List returns all the resources
0346      * linked to the document, such as palettes
0347      *
0348      * In some cases (e.g. when the document is temporary), the
0349      * underlying document storage will not be registered in the
0350      * resource system, so we cannot get fully initialized resources
0351      * from it (resourceId(), active(), md5() and storageLocation()
0352      * fields will be uninitialized). Therefore we just return
0353      * KoEmbeddedResource which is suitable for saving this data into
0354      * hard drive.
0355      *
0356      * The returned KoResourceLoadResult object can either be in
0357      * EmbeddedResource or FailedLink state. The former means the
0358      * resource has been prepared for embedding, the latter means
0359      * there was some issue with serializing the resource. In the
0360      * latter case the called should check result.signature() to
0361      * find out which resource has failed.
0362      *
0363      * NOTE: the returned result can **NOT** have ExistingResource state!
0364      */
0365     QList<KoResourceLoadResult> linkedDocumentResources();
0366 
0367     /**
0368      * @brief setPaletteList replaces the palettes in the document's local resource storage with the list
0369      * of palettes passed to this function. It will then emit sigPaletteListChanged with both the old and
0370      * the new list, if emitSignal is true.
0371      */
0372     void setPaletteList(const QList<KoColorSetSP> &paletteList, bool emitSignal = false);
0373 
0374     /**
0375      * @brief returns the list of pointers to storyboard Items for the document
0376      */
0377     StoryboardItemList getStoryboardItemList();
0378 
0379     /**
0380      * @brief sets the storyboardItemList in the document, emits empty signal if emitSignal is true.
0381      */
0382     void setStoryboardItemList(const StoryboardItemList &storyboardItemList, bool emitSignal = false);
0383 
0384     /**
0385      * @brief returns the list of comments for the storyboard docker in the document
0386      */
0387     QVector<StoryboardComment> getStoryboardCommentsList();
0388 
0389     /**
0390      * @brief sets the  list of comments for the storyboard docker in the document, emits empty signal if emitSignal is true.
0391      */
0392     void setStoryboardCommentList(const QVector<StoryboardComment> &storyboardCommentList, bool emitSignal = false);
0393 
0394     QVector<QFileInfo> getAudioTracks() const;
0395     void setAudioTracks(QVector<QFileInfo> f);
0396 
0397     void setAudioVolume(qreal level);
0398     qreal getAudioLevel();
0399 
0400     const KisMirrorAxisConfig& mirrorAxisConfig() const;
0401     void setMirrorAxisConfig(const KisMirrorAxisConfig& config);
0402 
0403     void clearUndoHistory();
0404 
0405     /**
0406      *  Sets the modified flag on the document. This means that it has
0407      *  to be saved or not before deleting it.
0408      */
0409     void setModified(bool _mod);
0410 
0411     void setRecovered(bool value);
0412     bool isRecovered() const;
0413 
0414     void updateEditingTime(bool forceStoreElapsed);
0415 
0416     /**
0417      * Returns the global undo stack
0418      */
0419     KUndo2Stack *undoStack();
0420 
0421 
0422     /**
0423      * @brief importExportManager gives access to the internal import/export manager
0424      * @return the document's import/export manager
0425      */
0426     KisImportExportManager *importExportManager() const;
0427 
0428     /**
0429      * @brief serializeToNativeByteArray daves the document into a .kra file written
0430      * to a memory-based byte-array
0431      * @return a byte array containing the .kra file
0432      */
0433     QByteArray serializeToNativeByteArray();
0434 
0435 
0436     /**
0437      * @brief isInSaving shown if the document has any (background) saving process or not
0438      * @return true if there is some saving in action
0439      */
0440     bool isInSaving() const;
0441 
0442 Q_SIGNALS:
0443 
0444     /**
0445      * This signal is emitted when the unit is changed by setUnit().
0446      * It is common to connect views to it, in order to change the displayed units
0447      * (e.g. in the rulers)
0448      */
0449     void unitChanged(const KoUnit &unit);
0450 
0451     /**
0452      * Emitted e.g. at the beginning of a save operation
0453      * This is emitted by KisDocument and used by KisView to display a statusbar message
0454      */
0455     void statusBarMessage(const QString& text, int timeout = 0);
0456 
0457     /**
0458      * Emitted e.g. at the end of a save operation
0459      * This is emitted by KisDocument and used by KisView to clear the statusbar message
0460      */
0461     void clearStatusBarMessage();
0462 
0463     /**
0464     * Emitted when the document is modified
0465     */
0466     void modified(bool);
0467 
0468     void sigReadWriteChanged(bool value);
0469     void sigRecoveredChanged(bool value);
0470     void sigPathChanged(const QString &path);
0471 
0472     void sigLoadingFinished();
0473 
0474     void sigSavingFinished(const QString &filePath);
0475 
0476     void sigGuidesConfigChanged(const KisGuidesConfig &config);
0477 
0478     void sigBackgroundSavingFinished(KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage);
0479 
0480     void sigCompleteBackgroundSaving(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage);
0481 
0482     void sigReferenceImagesChanged();
0483 
0484     void sigMirrorAxisConfigChanged();
0485 
0486     void sigGridConfigChanged(const KisGridConfig &config);
0487 
0488     void sigReferenceImagesLayerChanged(KisSharedPtr<KisReferenceImagesLayer> layer);
0489 
0490     /**
0491      * Emitted when the palette list has changed.
0492      * The pointers in oldPaletteList are to be deleted by the resource server.
0493      **/
0494     void sigPaletteListChanged(const QList<KoColorSetSP> &oldPaletteList, const QList<KoColorSetSP> &newPaletteList);
0495 
0496     void sigAssistantsChanged();
0497 
0498     void sigStoryboardItemListChanged();
0499 
0500     void sigStoryboardCommentListChanged();
0501 
0502     void sigAudioTracksChanged();
0503 
0504     void sigAudioLevelChanged(qreal level);
0505 
0506 private Q_SLOTS:
0507     void finishExportInBackground();
0508     void slotChildCompletedSavingInBackground(KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage);
0509     void slotCompleteAutoSaving(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage);
0510 
0511     void slotCompleteSavingDocument(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage);
0512 
0513     void slotInitiateAsyncAutosaving(KisDocument *clonedDocument);
0514     void slotDocumentCloningCancelled();
0515 
0516     void slotPerformIdleRoutines();
0517 
0518 private:
0519 
0520     friend class KisPart;
0521     friend class SafeSavingLocker;
0522 
0523     KritaUtils::JobResult initiateSavingInBackground(const QString actionName,
0524                                     const QObject *receiverObject, const char *receiverMethod,
0525                                     const KritaUtils::ExportFileJob &job,
0526                                     KisPropertiesConfigurationSP exportConfiguration,
0527                                     std::unique_ptr<KisDocument> &&optionalClonedDocument, bool isAdvancedExporting = false);
0528 
0529     KritaUtils::JobResult initiateSavingInBackground(const QString actionName,
0530                                     const QObject *receiverObject, const char *receiverMethod,
0531                                     const KritaUtils::ExportFileJob &job,
0532                                     KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting =false );
0533 
0534     bool startExportInBackground(const QString &actionName, const QString &location,
0535                                  const QString &realLocation,
0536                                  const QByteArray &mimeType,
0537                                  bool showWarnings,
0538                                  KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting= false);
0539 
0540     /**
0541      * Activate/deactivate/configure the autosave feature.
0542      * @param delay in seconds, 0 to disable
0543      */
0544     void setAutoSaveDelay(int delay);
0545 
0546     /**
0547      * Generate a name for the document.
0548      */
0549     QString newObjectName();
0550 
0551     QString generateAutoSaveFileName(const QString & path) const;
0552 
0553     /**
0554      *  Loads a document
0555      *
0556      *  Applies a filter if necessary, and calls loadNativeFormat in any case
0557      *  You should not have to reimplement, except for very special cases.
0558      *
0559      * NOTE: this method also creates a new KisView instance!
0560      *
0561      * This method is called from the KReadOnlyPart::openPath method.
0562      */
0563     bool openFile();
0564 
0565 public:
0566 
0567     bool isAutosaving() const;
0568 
0569 public:
0570 
0571     QString localFilePath() const;
0572     void setLocalFilePath( const QString &localFilePath );
0573 
0574     KoDocumentInfoDlg* createDocumentInfoDialog(QWidget *parent, KoDocumentInfo *docInfo) const;
0575 
0576     bool isReadWrite() const;
0577 
0578     QString path() const;
0579     void setPath(const QString &path);
0580 
0581     bool closePath(bool promptToSave = true);
0582 
0583     bool saveAs(const QString &path, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration = 0);
0584 
0585     /**
0586      * Create a new image that has this document as a parent and
0587      * replace the current image with this image.
0588      */
0589     bool newImage(const QString& name, qint32 width, qint32 height, const KoColorSpace * cs, const KoColor &bgColor, KisConfig::BackgroundStyle bgStyle,
0590                   int numberOfLayers, const QString &imageDescription, const double imageResolution);
0591 
0592     bool isSaving() const;
0593     void waitForSavingToComplete();
0594 
0595 
0596     KisImageWSP image() const;
0597 
0598     /**
0599      * @brief savingImage provides a detached, shallow copy of the original image that must be used when saving.
0600      * Any strokes in progress will not be applied to this image, so the result might be missing some data. On
0601      * the other hand, it won't block.
0602      *
0603      * @return a shallow copy of the original image, or 0 is saving is not in progress
0604      */
0605     KisImageSP savingImage() const;
0606 
0607     /**
0608      * Set the current image to the specified image and turn undo on.
0609      */
0610     void setCurrentImage(KisImageSP image, bool forceInitialUpdate = true);
0611 
0612     /**
0613      * Set the image of the document preliminary, before the document
0614      * has completed loading. Some of the document items (shapes) may want
0615      * to access image properties (bounds and resolution), so we should provide
0616      * it to them even before the entire image is loaded.
0617      *
0618      * Right now, the only use by KoShapeRegistry::createShapeFromOdf(), remove
0619      * after it is deprecated.
0620      */
0621     void hackPreliminarySetImage(KisImageSP image);
0622 
0623     KisUndoStore* createUndoStore();
0624 
0625     /**
0626      * The shape controller matches internal krita image layers with
0627      * the flake shape hierarchy.
0628      */
0629     KoShapeControllerBase *shapeController() const;
0630 
0631     KoShapeLayer *shapeForNode(KisNodeSP layer) const;
0632 
0633     /**
0634      * Set the list of nodes that was marked as currently active. Used *only*
0635      * for saving loading. Never use it for tools or processing.
0636      */
0637     void setPreActivatedNode(KisNodeSP activatedNode);
0638 
0639     /**
0640      * @return the node that was set as active during loading. Used *only*
0641      * for saving loading. Never use it for tools or processing.
0642      */
0643     KisNodeSP preActivatedNode() const;
0644 
0645     /// @return the list of assistants associated with this document
0646     QList<KisPaintingAssistantSP> assistants() const;
0647 
0648     /// @replace the current list of assistants with @param value
0649     void setAssistants(const QList<KisPaintingAssistantSP> &value);
0650 
0651 
0652     void setAssistantsGlobalColor(QColor color);
0653     QColor assistantsGlobalColor();
0654 
0655 
0656 
0657     /**
0658      * Get existing reference images layer or null if none exists.
0659      */
0660     KisSharedPtr<KisReferenceImagesLayer> referenceImagesLayer() const;
0661 
0662     void setReferenceImagesLayer(KisSharedPtr<KisReferenceImagesLayer> layer, bool updateImage);
0663 
0664     bool save(bool showWarnings, KisPropertiesConfigurationSP exportConfiguration);
0665 
0666     /**
0667      * Return the bounding box of the image and associated elements (e.g. reference images)
0668      */
0669     QRectF documentBounds() const;
0670 
0671     /**
0672      * @brief Start saving when android activity is pushed to the background
0673      */
0674     void autoSaveOnPause();
0675 
0676 Q_SIGNALS:
0677 
0678     void completed();
0679     void canceled(const QString &);
0680 
0681 private Q_SLOTS:
0682 
0683     void setImageModified();
0684     void setImageModifiedWithoutUndo();
0685 
0686     void slotAutoSave();
0687 
0688     void slotUndoStackCleanChanged(bool value);
0689 
0690     void slotConfigChanged();
0691 
0692     void slotImageRootChanged();
0693 
0694 
0695 public:
0696     /**
0697      * @brief try to clone the image. This method handles all the locking for you. If locking
0698      *        has failed, no cloning happens
0699      * @return cloned document on success, null otherwise
0700      */
0701     KisDocument *lockAndCloneForSaving();
0702 
0703     KisDocument *lockAndCreateSnapshot();
0704 
0705     void copyFromDocument(const KisDocument &rhs);
0706 
0707 private:
0708 
0709     enum CopyPolicy {
0710         CONSTRUCT = 0, ///< we are copy-constructing a new KisDocument
0711         REPLACE ///< we are replacing the current KisDocument with another
0712     };
0713 
0714     void copyFromDocumentImpl(const KisDocument &rhs, CopyPolicy policy);
0715 
0716     QString exportErrorToUserMessage(KisImportExportErrorCode status, const QString &errorMessage);
0717 
0718     QString prettyPath() const;
0719 
0720     bool openPathInternal(const QString &path);
0721 
0722     void slotAutoSaveImpl(std::unique_ptr<KisDocument> &&optionalClonedDocument);
0723 
0724     /// Checks whether we are saving a resource we've been editing, and if so,
0725     /// uses the resource server to update the resource.
0726     /// @return true if this was a resource, false if the document needs to be saved
0727     bool resourceSavingFilter(const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration);
0728 
0729     class Private;
0730     Private *const d;
0731 };
0732 
0733 Q_DECLARE_OPERATORS_FOR_FLAGS(KisDocument::OpenFlags)
0734 Q_DECLARE_METATYPE(KisDocument*)
0735 
0736 #endif