Krita Source Code Documentation
Loading...
Searching...
No Matches
KisDocument Class Reference

#include <KisDocument.h>

+ Inheritance diagram for KisDocument:

Public Types

enum  OpenFlag { None = 0 , DontAddToRecent = 0x1 , RecoveryFile = 0x2 }
 

Signals

void canceled (const QString &)
 
void clearStatusBarMessage ()
 
void completed ()
 
void modified (bool)
 
void sigAssistantsChanged ()
 
void sigAudioLevelChanged (qreal level)
 
void sigAudioTracksChanged ()
 
void sigBackgroundSavingFinished (KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
 
void sigCompleteBackgroundSaving (const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
 
void sigGridConfigChanged (const KisGridConfig &config)
 
void sigGuidesConfigChanged (const KisGuidesConfig &config)
 
void sigLoadingFinished ()
 
void sigMirrorAxisConfigChanged ()
 
void sigPaletteListChanged (const QList< KoColorSetSP > &oldPaletteList, const QList< KoColorSetSP > &newPaletteList)
 
void sigPathChanged (const QString &path)
 
void sigReadWriteChanged (bool value)
 
void sigRecoveredChanged (bool value)
 
void sigReferenceImagesChanged ()
 
void sigReferenceImagesLayerChanged (KisSharedPtr< KisReferenceImagesLayer > layer)
 
void sigSavingFinished (const QString &filePath)
 
void sigStoryboardCommentListChanged ()
 
void sigStoryboardItemListChanged ()
 
void statusBarMessage (const QString &text, int timeout=0)
 
void unitChanged (const KoUnit &unit)
 

Public Member Functions

QList< KisPaintingAssistantSPassistants () const
 
QColor assistantsGlobalColor ()
 
void autoSaveOnPause ()
 Start saving when android activity is pushed to the background.
 
QString caption () const
 
void clearUndoHistory ()
 
KisDocumentclone (bool addStorage=false)
 creates a clone of the document and returns it. Please make sure that you hold all the necessary locks on the image before asking for a clone!
 
bool closePath (bool promptToSave=true)
 
QList< KoColorcolorHistoryColors () const
 
KisUniqueColorSetcolorHistoryModel ()
 
void copyFrom (const Private &rhs, KisDocument *q)
 
void copyFromDocument (const KisDocument &rhs)
 
void copyFromImpl (const Private &rhs, KisDocument *q, KisDocument::CopyPolicy policy)
 
KoDocumentInfoDlgcreateDocumentInfoDialog (QWidget *parent, KoDocumentInfo *docInfo) const
 
QDomDocument createDomDocument (const QString &tagName, const QString &version) const
 
KisUndoStorecreateUndoStore ()
 
QRectF documentBounds () const
 
KoDocumentInfodocumentInfo () const
 
QString embeddedResourcesStorageId () const
 
QString errorMessage () const
 
bool exportDocument (const QString &path, const QByteArray &mimeType, bool isAdvancedExporting=false, bool showWarnings=false, KisPropertiesConfigurationSP exportConfiguration=0)
 
bool exportDocumentSync (const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration=0)
 
bool fileBatchMode () const
 
QPixmap generatePreview (const QSize &size)
 Generates a preview picture of the document.
 
qreal getAudioLevel ()
 
QVector< QFileInfo > getAudioTracks () const
 
QVector< StoryboardCommentgetStoryboardCommentsList ()
 returns the list of comments for the storyboard docker in the document
 
StoryboardItemList getStoryboardItemList ()
 returns the list of pointers to storyboard Items for the document
 
KisGridConfig gridConfig () const
 
const KisGuidesConfigguidesConfig () const
 returns the guides data for this document.
 
void hackPreliminarySetImage (KisImageSP image)
 
KisImageWSP image () const
 
bool importDocument (const QString &path)
 
KisImportExportManagerimportExportManager () const
 importExportManager gives access to the internal import/export manager
 
bool isAutoSaveActive ()
 
bool isAutosaving () const
 
bool isInSaving () const
 isInSaving shown if the document has any (background) saving process or not
 
bool isModified () const
 
bool isNativeFormat (const QByteArray &mimeType) const
 Checks whether a given mimeType can be handled natively.
 
bool isReadWrite () const
 
bool isRecovered () const
 
bool isSaving () const
 
QList< KoResourceLoadResultlinkedDocumentResources ()
 linkedDocumentResources List returns all the resources linked to the document, such as palettes
 
QString linkedResourcesStorageId () const
 
bool loadNativeFormat (const QString &file)
 
QString localFilePath () const
 
KisDocumentlockAndCloneForSaving ()
 try to clone the image. This method handles all the locking for you. If locking has failed, no cloning happens
 
KisDocumentlockAndCloneImpl (bool fetchResourcesFromLayers)
 
KisDocumentlockAndCreateSnapshot ()
 
QByteArray mimeType () const
 
const KisMirrorAxisConfigmirrorAxisConfig () const
 
bool newImage (const QString &name, qint32 width, qint32 height, const KoColorSpace *cs, const KoColor &bgColor, KisConfig::BackgroundStyle bgStyle, int numberOfLayers, const QString &imageDescription, const double imageResolution)
 
bool openPath (const QString &path, OpenFlags flags=None)
 openPath Open a Path
 
QString path () const
 
KisNodeSP preActivatedNode () const
 
 Private (const Private &rhs, KisDocument *_q)
 
 Private (KisDocument *_q)
 
KisSharedPtr< KisReferenceImagesLayerreferenceImagesLayer () const
 
void removeAutoSaveFiles (const QString &autosaveBaseName, bool wasRecovered)
 
void resetPath ()
 
bool save (bool showWarnings, KisPropertiesConfigurationSP exportConfiguration)
 
bool saveAs (const QString &path, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration=0)
 
KisImageSP savingImage () const
 savingImage provides a detached, shallow copy of the original image that must be used when saving. Any strokes in progress will not be applied to this image, so the result might be missing some data. On the other hand, it won't block.
 
QByteArray serializeToNativeByteArray ()
 serializeToNativeByteArray daves the document into a .kra file written to a memory-based byte-array
 
void setAssistants (const QList< KisPaintingAssistantSP > &value)
 @replace the current list of assistants with
 
void setAssistantsGlobalColor (QColor color)
 
void setAudioTracks (QVector< QFileInfo > f)
 
void setAudioVolume (qreal level)
 
void setAutoSaveActive (bool autoSaveIsActive)
 
void setColorHistoryColors (const QList< KoColor > &colors)
 
void setCurrentImage (KisImageSP image, bool forceInitialUpdate=true, KisNodeSP preActivatedNode=nullptr)
 
void setEmergencyAutoSaveInterval ()
 
void setEmpty (bool empty=true)
 Sets the document to empty.
 
void setErrorMessage (const QString &errMsg)
 
void setFileBatchMode (const bool batchMode)
 
void setGridConfig (const KisGridConfig &config)
 
void setGuidesConfig (const KisGuidesConfig &data)
 
void setImageAndInitIdleWatcher (KisImageSP _image)
 
void setInfiniteAutoSaveInterval ()
 
void setLocalFilePath (const QString &localFilePath)
 
void setMimeType (const QByteArray &mimeType)
 Sets the mime type for the document.
 
void setMimeTypeAfterLoading (const QString &mimeType)
 
void setMirrorAxisConfig (const KisMirrorAxisConfig &config)
 
void setModified (bool _mod)
 
void setNormalAutoSaveInterval ()
 
void setPaletteList (const QList< KoColorSetSP > &paletteList, bool emitSignal=false)
 setPaletteList replaces the palettes in the document's local resource storage with the list of palettes passed to this function. It will then Q_EMIT sigPaletteListChanged with both the old and the new list, if emitSignal is true.
 
void setPath (const QString &path)
 
void setPreActivatedNode (KisNodeSP activatedNode)
 
void setReadWrite (bool readwrite=true)
 Sets whether the document can be edited or is read only.
 
void setRecovered (bool value)
 
void setReferenceImagesLayer (KisSharedPtr< KisReferenceImagesLayer > layer, bool updateImage)
 
void setStoryboardCommentList (const QVector< StoryboardComment > &storyboardCommentList, bool emitSignal=false)
 sets the list of comments for the storyboard docker in the document, emits empty signal if emitSignal is true.
 
void setStoryboardItemList (const StoryboardItemList &storyboardItemList, bool emitSignal=false)
 sets the storyboardItemList in the document, emits empty signal if emitSignal is true.
 
void setUnit (const KoUnit &unit)
 
void setWarningMessage (const QString &warningMsg)
 
KoShapeControllerBaseshapeController () const
 
KoShapeLayershapeForNode (KisNodeSP layer) const
 
void syncDecorationsWrapperLayerState ()
 
KUndo2StackundoStack ()
 
KoUnit unit () const
 
void updateDocumentMetadataOnSaving (const QString &filePath, const QByteArray &mimeType)
 
void updateEditingTime (bool forceStoreElapsed)
 
void uploadLinkedResourcesFromLayersToStorage ()
 
void waitForSavingToComplete ()
 
QString warningMessage () const
 
 ~KisDocument ()
 
 ~Private ()
 

Static Public Member Functions

static QDomDocument createDomDocument (const QString &appName, const QString &tagName, const QString &version)
 
static QStringList extraNativeMimeTypes ()
 
static QByteArray nativeFormatMimeType ()
 

Public Attributes

QList< KisPaintingAssistantSPassistants
 
qreal audioLevel = 1.0
 
QVector< QFileInfo > audioTracks
 
bool autoSaveActive = true
 
int autoSaveDelay = 300
 
int autoSaveFailureCount = 0
 
QTimer * autoSaveTimer
 
std::unique_ptr< KisDocumentbackgroundSaveDocument
 
KritaUtils::ExportFileJob backgroundSaveJob
 
bool batchMode { false }
 
QFuture< KisImportExportErrorCodechildSavingFuture
 
KisUniqueColorSet colorHistoryModel
 
QMetaObject::Connection completeSavingConnection
 
bool decorationsSyncingDisabled = false
 
bool disregardAutosaveFailure = false
 
KoDocumentInfodocInfo = 0
 
bool documentIsClosing = false
 
QString embeddedResourcesStorageID
 
KisResourceStorageSP embeddedResourceStorage
 
QDateTime firstMod
 
QColor globalAssistantsColor
 
KisGridConfig gridConfig
 
KisGuidesConfig guidesConfig
 
KisImageSP image
 
QScopedPointer< KisSignalAutoConnectionimageIdleConnection
 
KisIdleWatcher imageIdleWatcher
 
bool imageModifiedWithoutUndo = false
 
KisImportExportManagerimportExportManager = 0
 
bool isAutosaving = false
 
bool isRecovered = false
 
KoShapeControllerkoShapeController = 0
 
QString lastErrorMessage
 
QDateTime lastMod
 
QString lastWarningMessage
 
QString linkedResourcesStorageID
 
KisResourceStorageSP linkedResourceStorage
 
bool m_bAutoDetectedMime = false
 
QString m_file
 
QString m_path
 
QVector< StoryboardCommentm_storyboardCommentList
 
StoryboardItemList m_storyboardItemList
 
QByteArray mimeType
 
KisMirrorAxisConfig mirrorAxisConfig
 
bool modified = false
 
bool modifiedAfterAutosave = false
 
bool modifiedWhileSaving = false
 
KisNameServernserver
 
QByteArray outputMimeType
 
KisNodeWSP preActivatedNode
 
KisDocumentq = 0
 
bool readwrite = false
 
KisSignalAutoConnectionsStore referenceLayerConnections
 
KisImageSP savingImage
 
QMutex savingMutex
 
QPointer< KoUpdatersavingUpdater
 
KisShapeControllershapeController = 0
 
KUndo2StackundoStack = 0
 
KoUnit unit
 
bool wasStorageAdded = false
 

Protected Member Functions

 KisDocument (bool addStorage=true)
 
 KisDocument (const KisDocument &rhs, bool addStorage)
 KisDocument makes a deep copy of the document rhs. The caller must ensure that the image is properly locked and is in consistent state before asking for cloning.
 

Private Types

enum  CopyPolicy { CONSTRUCT = 0 , REPLACE }
 

Private Slots

void finishExportInBackground ()
 
void setImageModified ()
 
void setImageModifiedWithoutUndo ()
 
void slotAutoSave ()
 
void slotChildCompletedSavingInBackground (KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
 
void slotCompleteAutoSaving (const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
 
void slotCompleteSavingDocument (const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
 
void slotConfigChanged ()
 
void slotDocumentCloningCancelled ()
 
void slotImageRootChanged ()
 
void slotInitiateAsyncAutosaving (KisDocument *clonedDocument)
 
void slotPerformIdleRoutines ()
 
void slotUndoStackCleanChanged (bool value)
 

Private Member Functions

void copyFromDocumentImpl (const KisDocument &rhs, CopyPolicy policy)
 
bool exportDocumentImpl (const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting=false)
 
QString exportErrorToUserMessage (KisImportExportErrorCode status, const QString &errorMessage)
 
QString generateAutoSaveFileName (const QString &path) const
 
KritaUtils::BackgroudSavingStartResult initiateSavingInBackground (const QString actionName, const QObject *receiverObject, const char *receiverMethod, const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting=false)
 
KritaUtils::BackgroudSavingStartResult initiateSavingInBackground (const QString actionName, const QObject *receiverObject, const char *receiverMethod, const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration, std::unique_ptr< KisDocument > &&optionalClonedDocument, bool isAdvancedExporting=false)
 
QString newObjectName ()
 
bool openFile ()
 
bool openPathInternal (const QString &path)
 
QString prettyPath () const
 
bool resourceSavingFilter (const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration)
 
void setAutoSaveDelay (int delay)
 
void slotAutoSaveImpl (std::unique_ptr< KisDocument > &&optionalClonedDocument)
 
KisImportExportErrorCode startExportInBackground (const QString &actionName, const QString &location, const QString &realLocation, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting=false)
 
- Private Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Private Attributes

Private *const d
 
- Private Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Friends

class KisPart
 
class SafeSavingLocker
 

Detailed Description

KisDocument contains the image and keeps track of loading, modification, undo stack and saving.

Definition at line 295 of file KisDocument.cpp.

Member Enumeration Documentation

◆ CopyPolicy

Enumerator
CONSTRUCT 

we are copy-constructing a new KisDocument

REPLACE 

we are replacing the current KisDocument with another

Definition at line 744 of file KisDocument.h.

744 {
745 CONSTRUCT = 0,
746 REPLACE
747 };
@ CONSTRUCT
we are copy-constructing a new KisDocument
@ REPLACE
we are replacing the current KisDocument with another

◆ OpenFlag

Enumerator
None 
DontAddToRecent 
RecoveryFile 

Definition at line 80 of file KisDocument.h.

80 {
81 None = 0,
82 DontAddToRecent = 0x1,
83 RecoveryFile = 0x2
84 };

Constructor & Destructor Documentation

◆ ~Private()

KisDocument::~Private ( )
inline

Definition at line 338 of file KisDocument.cpp.

338 {
339 // Don't delete m_d->shapeController because it's in a QObject hierarchy.
340 delete nserver;
341 }
KisNameServer * nserver

◆ KisDocument() [1/2]

KisDocument::KisDocument ( bool addStorage = true)
explicitprotected

Definition at line 605 of file KisDocument.cpp.

606 : d(new Private(this))
607{
608 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
609 connect(d->undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(slotUndoStackCleanChanged(bool)));
610 connect(d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
611 setObjectName(newObjectName());
612
613#ifdef Q_OS_MACOS
615 if (bookmarkmngr->isSandboxed()) {
616 connect(this, SIGNAL(sigSavingFinished(const QString&)), bookmarkmngr, SLOT(slotCreateBookmark(const QString&)));
617 }
618#endif
619
620
621 if (addStorage) {
622 d->linkedResourcesStorageID = QUuid::createUuid().toString();
623 d->linkedResourceStorage.reset(new KisResourceStorage(d->linkedResourcesStorageID));
624 KisResourceLocator::instance()->addStorage(d->linkedResourcesStorageID, d->linkedResourceStorage);
625
626 d->embeddedResourcesStorageID = QUuid::createUuid().toString();
627 d->embeddedResourceStorage.reset(new KisResourceStorage(d->embeddedResourcesStorageID));
628 KisResourceLocator::instance()->addStorage(d->embeddedResourcesStorageID, d->embeddedResourceStorage);
629
630 d->wasStorageAdded = true;
631 }
632
633 // preload the krita resources
635
636 d->shapeController = new KisShapeController(d->nserver, d->undoStack, this);
637 d->koShapeController = new KoShapeController(0, d->shapeController);
638
640}
static KisConfigNotifier * instance()
void slotUndoStackCleanChanged(bool value)
void slotAutoSave()
Private *const d
void sigSavingFinished(const QString &filePath)
QString newObjectName()
void slotConfigChanged()
static KisMacosSecurityBookmarkManager * instance()
bool addStorage(const QString &storageLocation, KisResourceStorageSP storage)
addStorage Adds a new resource storage to the database. The storage is will be marked as not pre-inst...
static KisResourceLocator * instance()
static KisResourceServerProvider * instance()

References KisResourceLocator::addStorage(), KisConfigNotifier::instance(), KisMacosSecurityBookmarkManager::instance(), KisResourceLocator::instance(), KisResourceServerProvider::instance(), and KisMacosSecurityBookmarkManager::isSandboxed().

◆ KisDocument() [2/2]

KisDocument::KisDocument ( const KisDocument & rhs,
bool addStorage )
explicitprotected

KisDocument makes a deep copy of the document rhs. The caller must ensure that the image is properly locked and is in consistent state before asking for cloning.

Parameters
rhsthe source document to copy from

Definition at line 642 of file KisDocument.cpp.

643 : QObject(),
644 d(new Private(*rhs.d, this))
645{
647
648 if (addStorage) {
649 KisResourceLocator::instance()->addStorage(d->linkedResourcesStorageID, d->linkedResourceStorage);
650 KisResourceLocator::instance()->addStorage(d->embeddedResourcesStorageID, d->embeddedResourceStorage);
651 d->wasStorageAdded = true;
652 }
653}
void copyFromDocumentImpl(const KisDocument &rhs, CopyPolicy policy)

References KisResourceLocator::addStorage(), CONSTRUCT, copyFromDocumentImpl(), d, and KisResourceLocator::instance().

◆ ~KisDocument()

KisDocument::~KisDocument ( )

Destructor.

The destructor does not delete any attached KisView objects and it does not delete the attached widget as returned by widget().

Push a timebomb, which will try to release the memory after the document has been deleted

WARNING: We should wait for all the internal image jobs to finish before entering KisImage's destructor. The problem is, while execution of KisImage::~KisImage, all the weak shared pointers pointing to the image enter an inconsistent state(!). The shared counter is already zero and destruction has started, but the weak reference doesn't know about it, because KisShared::~KisShared hasn't been executed yet. So all the threads running in background and having weak pointers will enter the KisImage's destructor as well.

Definition at line 655 of file KisDocument.cpp.

656{
657 d->documentIsClosing = true;
658
659 // wait until all the pending operations are in progress
661 d->imageIdleWatcher.setTrackedImage(0);
662
668
669 d->autoSaveTimer->disconnect(this);
670 d->autoSaveTimer->stop();
671
672 delete d->importExportManager;
673
674 // Despite being QObject they needs to be deleted before the image
675 delete d->shapeController;
676
677 delete d->koShapeController;
678
679 if (d->image) {
680 d->image->animationInterface()->blockBackgroundFrameGeneration();
681
682 d->image->notifyAboutToBeDeleted();
683
696 d->image->requestStrokeCancellation();
697 d->image->waitForDone();
698
699 // clear undo commands that can still point to the image
700 d->undoStack->clear();
701 d->image->waitForDone();
702
703 KisImageWSP sanityCheckPointer = d->image;
704 Q_UNUSED(sanityCheckPointer);
705
706 // The following line trigger the deletion of the image
707 d->image.clear();
708
709 // check if the image has actually been deleted
710 KIS_SAFE_ASSERT_RECOVER_NOOP(!sanityCheckPointer.isValid());
711 }
712
713 if (d->wasStorageAdded) {
714 if (KisResourceLocator::instance()->hasStorage(d->linkedResourcesStorageID)) {
715 KisResourceLocator::instance()->removeStorage(d->linkedResourcesStorageID);
716 }
717 if (KisResourceLocator::instance()->hasStorage(d->embeddedResourcesStorageID)) {
718 KisResourceLocator::instance()->removeStorage(d->embeddedResourcesStorageID);
719 }
720 }
721
722 delete d;
723}
void waitForSavingToComplete()
static MemoryReleaseObject * createMemoryReleaseObject()
bool removeStorage(const QString &storageLocation)
removeStorage removes the temporary storage from the database
bool isValid() const
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References KisPaintDevice::createMemoryReleaseObject(), d, KisResourceLocator::instance(), KisWeakSharedPtr< T >::isValid(), KIS_SAFE_ASSERT_RECOVER_NOOP, KisResourceLocator::removeStorage(), and waitForSavingToComplete().

Member Function Documentation

◆ assistants()

QList< KisPaintingAssistantSP > KisDocument::assistants ( ) const
Returns
the list of assistants associated with this document

◆ assistantsGlobalColor()

QColor KisDocument::assistantsGlobalColor ( )

Definition at line 2947 of file KisDocument.cpp.

2948{
2949 return d->globalAssistantsColor;
2950}

References d.

◆ autoSaveOnPause()

void KisDocument::autoSaveOnPause ( )

Start saving when android activity is pushed to the background.

Definition at line 2110 of file KisDocument.cpp.

2111{
2112 if (!d->modified || !d->modifiedAfterAutosave)
2113 return;
2114
2115 const QString autoSaveFileName = generateAutoSaveFileName(localFilePath());
2116
2117 bool started = exportDocumentSync(autoSaveFileName, nativeFormatMimeType());
2118
2119 if (started)
2120 {
2121 d->modifiedAfterAutosave = false;
2122 dbgAndroid << "autoSaveOnPause successful";
2123 }
2124 else
2125 {
2126 qWarning() << "Could not auto-save when paused";
2127 }
2128}
QString localFilePath() const
static QByteArray nativeFormatMimeType()
QString generateAutoSaveFileName(const QString &path) const
bool exportDocumentSync(const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration=0)
#define dbgAndroid
Definition kis_debug.h:62

References d, dbgAndroid, exportDocumentSync(), generateAutoSaveFileName(), localFilePath(), and nativeFormatMimeType().

◆ canceled

void KisDocument::canceled ( const QString & )
signal

◆ caption()

QString KisDocument::caption ( ) const
Returns
caption of the document

Caption is of the form "[title] - [path]", built out of the document info (title) and pretty-printed document Path. If the title is not present, only the Path it returned.

Definition at line 2225 of file KisDocument.cpp.

2226{
2227 QString c;
2228 const QString _url(QFileInfo(path()).fileName());
2229
2230 // if URL is empty...it is probably an unsaved file
2231 if (_url.isEmpty()) {
2232 c = " [" + i18n("Not Saved") + "] ";
2233 } else {
2234 c = _url; // Fall back to document URL
2235 }
2236
2237 return c;
2238}
QString path() const

References path().

◆ clearStatusBarMessage

void KisDocument::clearStatusBarMessage ( )
signal

Emitted e.g. at the end of a save operation This is emitted by KisDocument and used by KisView to clear the statusbar message

◆ clearUndoHistory()

void KisDocument::clearUndoHistory ( )

Definition at line 2373 of file KisDocument.cpp.

2374{
2375 d->undoStack->clear();
2376}

References d.

◆ clone()

KisDocument * KisDocument::clone ( bool addStorage = false)

creates a clone of the document and returns it. Please make sure that you hold all the necessary locks on the image before asking for a clone!

Definition at line 735 of file KisDocument.cpp.

736{
737 return new KisDocument(*this, addStorage);
738}
KisDocument(bool addStorage=true)

References KisDocument().

◆ closePath()

bool KisDocument::closePath ( bool promptToSave = true)

Definition at line 2571 of file KisDocument.cpp.

2572{
2573 if (promptToSave) {
2574 if ( isReadWrite() && isModified()) {
2575 Q_FOREACH (KisView *view, KisPart::instance()->views()) {
2576 if (view && view->document() == this) {
2577 if (!view->queryClose()) {
2578 return false;
2579 }
2580 }
2581 }
2582 }
2583 }
2584 // Not modified => ok and delete temp file.
2585 d->mimeType = QByteArray();
2586
2587 // It always succeeds for a read-only part,
2588 // but the return value exists for reimplementations
2589 // (e.g. pressing cancel for a modified read-write part)
2590 return true;
2591}
bool isReadWrite() const
bool isModified() const
static KisPart * instance()
Definition KisPart.cpp:131
QPointer< KisDocument > document
Definition KisView.cpp:121
bool queryClose()
Definition KisView.cpp:1155

References d, KisView::document, KisPart::instance(), isModified(), isReadWrite(), and KisView::queryClose().

◆ colorHistoryColors()

QList< KoColor > KisDocument::colorHistoryColors ( ) const

Return the per-document history of the last-used colors, from the newest to oldest.

The actual values are stored in the model returned by colorHistoryModel()

Definition at line 2970 of file KisDocument.cpp.

2971{
2972 return d->colorHistoryModel.colorList();
2973}

References d.

◆ colorHistoryModel()

KisUniqueColorSet * KisDocument::colorHistoryModel ( )

Return an internal model for managing the last used colors of the document. The model can be used to manipulate the colors and subscribe to updates.

◆ completed

void KisDocument::completed ( )
signal

◆ copyFrom()

void KisDocument::copyFrom ( const Private & rhs,
KisDocument * q )

◆ copyFromDocument()

void KisDocument::copyFromDocument ( const KisDocument & rhs)

Definition at line 1250 of file KisDocument.cpp.

1251{
1253}

References copyFromDocumentImpl(), and REPLACE.

◆ copyFromDocumentImpl()

void KisDocument::copyFromDocumentImpl ( const KisDocument & rhs,
CopyPolicy policy )
private

Definition at line 1255 of file KisDocument.cpp.

1256{
1257 if (policy == REPLACE) {
1258 d->decorationsSyncingDisabled = true;
1259 d->copyFrom(*(rhs.d), this);
1260 d->decorationsSyncingDisabled = false;
1261
1262 d->undoStack->clear();
1263 } else {
1264 // in CONSTRUCT mode, d should be already initialized
1265 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
1266 connect(d->undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(slotUndoStackCleanChanged(bool)));
1267 connect(d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
1268
1269 d->shapeController = new KisShapeController(d->nserver, d->undoStack, this);
1270 d->koShapeController = new KoShapeController(0, d->shapeController);
1271 }
1272
1273 setObjectName(rhs.objectName());
1274
1276
1277 if (rhs.d->image) {
1278 if (policy == REPLACE) {
1279 d->image->barrierLock(/* readOnly = */ false);
1280 rhs.d->image->barrierLock(/* readOnly = */ true);
1281 d->image->copyFromImage(*(rhs.d->image));
1282 d->image->unlock();
1283 rhs.d->image->unlock();
1284
1285 setCurrentImage(d->image, /* forceInitialUpdate = */ true);
1286 } else {
1287 // clone the image with keeping the GUIDs of the layers intact
1288 // NOTE: we expect the image to be locked!
1289 setCurrentImage(rhs.image()->clone(/* exactCopy = */ true), /* forceInitialUpdate = */ false);
1290 }
1291 }
1292
1293 if (policy == REPLACE) {
1294 d->syncDecorationsWrapperLayerState();
1295 }
1296
1297 if (rhs.d->preActivatedNode) {
1298 QQueue<KisNodeSP> linearizedNodes;
1299 KisLayerUtils::recursiveApplyNodes(rhs.d->image->root(),
1300 [&linearizedNodes](KisNodeSP node) {
1301 linearizedNodes.enqueue(node);
1302 });
1304 [&linearizedNodes, &rhs, this](KisNodeSP node) {
1305 KisNodeSP refNode = linearizedNodes.dequeue();
1306 if (rhs.d->preActivatedNode.data() == refNode.data()) {
1307 d->preActivatedNode = node;
1308 }
1309 });
1310 }
1311
1312 // reinitialize references' signal connection
1313 KisReferenceImagesLayerSP referencesLayer = this->referenceImagesLayer();
1314 if (referencesLayer) {
1315 d->referenceLayerConnections.clear();
1316 d->referenceLayerConnections.addConnection(
1317 referencesLayer, SIGNAL(sigUpdateCanvas(QRectF)),
1318 this, SIGNAL(sigReferenceImagesChanged()));
1319
1320 Q_EMIT sigReferenceImagesLayerChanged(referencesLayer);
1322 }
1323
1324 KisDecorationsWrapperLayerSP decorationsLayer =
1325 KisLayerUtils::findNodeByType<KisDecorationsWrapperLayer>(d->image->root());
1326 if (decorationsLayer) {
1327 decorationsLayer->setDocument(this);
1328 }
1329
1330
1331 if (policy == REPLACE) {
1332 setModified(true);
1333 }
1334}
KisSharedPtr< KisReferenceImagesLayer > referenceImagesLayer() const
KisImageSP image
void setModified(bool _mod)
void sigReferenceImagesLayerChanged(KisSharedPtr< KisReferenceImagesLayer > layer)
void setCurrentImage(KisImageSP image, bool forceInitialUpdate=true, KisNodeSP preActivatedNode=nullptr)
void sigReferenceImagesChanged()
KisImage * clone(bool exactCopy=false)
Definition kis_image.cc:406
void recursiveApplyNodes(NodePointer node, Functor func)

References KisImage::clone(), d, image, KisConfigNotifier::instance(), KisLayerUtils::recursiveApplyNodes(), REPLACE, setCurrentImage(), slotAutoSave(), slotConfigChanged(), and slotUndoStackCleanChanged().

◆ copyFromImpl()

void KisDocument::copyFromImpl ( const Private & rhs,
KisDocument * q,
KisDocument::CopyPolicy policy )

◆ createDocumentInfoDialog()

KoDocumentInfoDlg * KisDocument::createDocumentInfoDialog ( QWidget * parent,
KoDocumentInfo * docInfo ) const

Definition at line 2556 of file KisDocument.cpp.

2557{
2558 return new KoDocumentInfoDlg(parent, docInfo);
2559}
KoDocumentInfo * docInfo
The dialog that shows information about the document.

References docInfo.

◆ createDomDocument() [1/2]

QDomDocument KisDocument::createDomDocument ( const QString & appName,
const QString & tagName,
const QString & version )
static

Return a correctly created QDomDocument for an old (1.3-style) Krita document, including processing instruction, complete DOCTYPE tag (with systemId and publicId), and root element. This static method can be used e.g. by filters.

Parameters
appNamethe app's instance name, e.g. words, kspread, kpresenter etc.
tagNamethe name of the tag for the root element, e.g. DOC for words/kpresenter.
versionthe DTD version (usually the application's version).

Definition at line 2246 of file KisDocument.cpp.

2247{
2248 QDomImplementation impl;
2249 QString url = QString("http://www.calligra.org/DTD/%1-%2.dtd").arg(appName).arg(version);
2250 QDomDocumentType dtype = impl.createDocumentType(tagName,
2251 QString("-//KDE//DTD %1 %2//EN").arg(appName).arg(version),
2252 url);
2253 // The namespace URN doesn't need to include the version number.
2254 QString namespaceURN = QString("http://www.calligra.org/DTD/%1").arg(appName);
2255 QDomDocument doc = impl.createDocument(namespaceURN, tagName, dtype);
2256 doc.insertBefore(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""), doc.documentElement());
2257 return doc;
2258}

◆ createDomDocument() [2/2]

QDomDocument KisDocument::createDomDocument ( const QString & tagName,
const QString & version ) const

Return a correctly created QDomDocument for this KisDocument, including processing instruction, complete DOCTYPE tag (with systemId and publicId), and root element.

Parameters
tagNamethe name of the tag for the root element
versionthe DTD version (usually the application's version).

Definition at line 2240 of file KisDocument.cpp.

2241{
2242 return createDomDocument("krita", tagName, version);
2243}
QDomDocument createDomDocument(const QString &tagName, const QString &version) const

References createDomDocument().

◆ createUndoStore()

KisUndoStore * KisDocument::createUndoStore ( )

Definition at line 2927 of file KisDocument.cpp.

2928{
2929 return new KisDocumentUndoStore(this);
2930}

◆ documentBounds()

QRectF KisDocument::documentBounds ( ) const

Return the bounding box of the image and associated elements (e.g. reference images)

Definition at line 2952 of file KisDocument.cpp.

2953{
2954 QRectF bounds = d->image->bounds();
2955
2957
2958 if (referenceImagesLayer) {
2960 }
2961
2962 return bounds;
2963}
#define bounds(x, a, b)

References KisReferenceImagesLayer::boundingImageRect(), bounds, d, and referenceImagesLayer().

◆ documentInfo()

KoDocumentInfo * KisDocument::documentInfo ( ) const
Returns
the information concerning this document.
See also
KoDocumentInfo

Definition at line 1844 of file KisDocument.cpp.

1845{
1846 return d->docInfo;
1847}

References d.

◆ embeddedResourcesStorageId()

QString KisDocument::embeddedResourcesStorageId ( ) const

Temporary storage for the resources that are embedded into other resources used by the document. E.g. patterns embedded into layer styles.

Definition at line 725 of file KisDocument.cpp.

726{
727 return d->embeddedResourcesStorageID;
728}

References d.

◆ errorMessage()

QString KisDocument::errorMessage ( ) const

Return the last error message. Usually KisDocument takes care of showing it; this method is mostly provided for non-interactive use.

Definition at line 2272 of file KisDocument.cpp.

2273{
2274 return d->lastErrorMessage;
2275}

References d.

◆ exportDocument()

bool KisDocument::exportDocument ( const QString & path,
const QByteArray & mimeType,
bool isAdvancedExporting = false,
bool showWarnings = false,
KisPropertiesConfigurationSP exportConfiguration = 0 )

Saves the document as path without changing the state of the KisDocument (Path, modified flag etc.). Call this instead of saveAs() to implement KisMainWindow's File --> Export feature. Make sure to provide two separate bool parameters otherwise it will mix them

Definition at line 930 of file KisDocument.cpp.

931{
932 using namespace KritaUtils;
933
934 SaveFlags flags = SaveIsExporting;
935 if (showWarnings) {
936 flags |= SaveShowWarnings;
937 }
938
939 KisUsageLogger::log(QString("Exporting Document: %1 as %2. %3 * %4 pixels, %5 layers, %6 frames, %7 "
940 "framerate. Export configuration: %8")
941 .arg(path, QString::fromLatin1(mimeType), QString::number(d->image->width()),
942 QString::number(d->image->height()), QString::number(d->image->nlayers()),
943 QString::number(d->image->animationInterface()->totalLength()),
944 QString::number(d->image->animationInterface()->framerate()),
945 (exportConfiguration ? exportConfiguration->toXML() : "No configuration")));
946
948 mimeType,
949 flags),
950 exportConfiguration, isAdvancedExporting);
951}
QByteArray mimeType
bool exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting=false)
static void log(const QString &message)
Logs with date/time.

References d, exportDocumentImpl(), KisUsageLogger::log(), and mimeType.

◆ exportDocumentImpl()

bool KisDocument::exportDocumentImpl ( const KritaUtils::ExportFileJob & job,
KisPropertiesConfigurationSP exportConfiguration,
bool isAdvancedExporting = false )
private

Definition at line 740 of file KisDocument.cpp.

741{
742 // ANDROID NOTES (other comments in this file reference this one!)
743 //
744 // The Android file system doesn't work like on a real operating system.
745 // Instead of normal file paths, we get to deal with "content URIs", which
746 // can have various kinds of storage providers behind them. For example,
747 // there's a "normal" storage provider, a slightly less normal documents
748 // provider, a Google Drive provider and various kinds of third-party
749 // providers that are mostly just good at losing the data you give them.
750 // For example, we have reports of compression programs that provide a
751 // storage provider to write to ZIP or RAR archives or something. Except
752 // that they don't seem to work at all, they just accept the data with no
753 // error and throw it on the floor.
754 //
755 // The providers are particularly unreliable with regards to permissions,
756 // so calling "isWritable" will just always return false on some of them.
757 // This includes the default provider on some devices, which means checking
758 // whether a file is writable will mean that the user can't save anything!
759 // So, all the Android code skips over the writability check and assumes the
760 // files are writable. If they're not, we'll notice later anyway, by the
761 // fact that writing to them fails.
762 //
763 // Another issue is that it's only possible to overwrite files using File >
764 // Save. Using File > Save As or File > Export can't replace existing
765 // files. The reason for this is that we have to go through the operating
766 // system to request access to a file and the only things you can ask for
767 // is to open an existing file or to create a new file. Out of necessity,
768 // Save As and Export use the latter. If the user selects an existing file,
769 // the operating system "helpfully" appends a number to the path, *after*
770 // the file extension of course, because it hates the living. So that's
771 // another reason we can't go with the "safer" option of assuming that files
772 // aren't writable in some cases, since that would prevent the user from
773 // saving them normally and end up with a lot of "kiki.kra (2)".
774 //
775 // Also, when you request a file from the operating system, it always
776 // creates an empty file. That means checking whether a file exists will
777 // pretty much always succeed, so to know whether a file actually exists
778 // you have to check whether it isn't empty. Of course providers may fail to
779 // implement this correctly, but I'm not aware of any of them botching it
780 // that hard. Well, at least none of the ones that actually save files, as
781 // mentioned above some of them just seem to lose whatever you give them.
782
783 QFileInfo filePathInfo(job.filePath);
784 bool fileExists = filePathInfo.exists();
785#ifdef Q_OS_ANDROID
786 if (fileExists) {
787 fileExists = filePathInfo.size() > 0;
788 }
789#else
790 if (fileExists && !filePathInfo.isWritable()) {
792 i18n("%1 cannot be written to. Please save under a different name.", job.filePath),
793 "");
794 return false;
795 }
796#endif
797
798 KisConfig cfg(true);
799 if (cfg.backupFile() && fileExists) {
800
801 QString backupDir;
802
803 switch(cfg.readEntry<int>("backupfilelocation", 0)) {
804 case 1:
805 backupDir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
806 break;
807 case 2:
808 backupDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
809 break;
810 default:
811#ifdef Q_OS_ANDROID
812 // We deal with URIs, there may or may not be a "directory"
814 QDir().mkpath(backupDir);
815#endif
816
817#ifdef Q_OS_MACOS
819 if (bookmarkmngr->isSandboxed()) {
820 // If the user does not have directory permission force backup
821 // files to be inside Container tmp
822 QUrl fileUrl = QUrl::fromLocalFile(job.filePath);
823 if( !bookmarkmngr->parentDirHasPermissions(fileUrl.path()) ) {
824 backupDir = QDir::tempPath();
825 }
826 }
827#endif
828
829 // Do nothing: the empty string is user file location
830 break;
831 }
832
833 int numOfBackupsKept = cfg.readEntry<int>("numberofbackupfiles", 1);
834 QString suffix = cfg.readEntry<QString>("backupfilesuffix", "~");
835
836 if (numOfBackupsKept == 1) {
837 if (!KisBackup::simpleBackupFile(job.filePath, backupDir, suffix)) {
838 qWarning() << "Failed to create simple backup file!" << job.filePath << backupDir << suffix;
839 KisUsageLogger::log(QString("Failed to create a simple backup for %1 in %2.")
840 .arg(job.filePath, backupDir.isEmpty()
841 ? "the same location as the file"
842 : backupDir));
843 slotCompleteSavingDocument(job, ImportExportCodes::ErrorWhileWriting, i18nc("Saving error message", "Failed to create a backup file"), "");
844 return false;
845 }
846 else {
847 KisUsageLogger::log(QString("Create a simple backup for %1 in %2.")
848 .arg(job.filePath, backupDir.isEmpty()
849 ? "the same location as the file"
850 : backupDir));
851 }
852 }
853 else if (numOfBackupsKept > 1) {
854 if (!KisBackup::numberedBackupFile(job.filePath, backupDir, suffix, numOfBackupsKept)) {
855 qWarning() << "Failed to create numbered backup file!" << job.filePath << backupDir << suffix;
856 KisUsageLogger::log(QString("Failed to create a numbered backup for %2.")
857 .arg(job.filePath, backupDir.isEmpty()
858 ? "the same location as the file"
859 : backupDir));
860 slotCompleteSavingDocument(job, ImportExportCodes::ErrorWhileWriting, i18nc("Saving error message", "Failed to create a numbered backup file"), "");
861 return false;
862 }
863 else {
864 KisUsageLogger::log(QString("Create a simple backup for %1 in %2.")
865 .arg(job.filePath, backupDir.isEmpty()
866 ? "the same location as the file"
867 : backupDir));
868 }
869 }
870 }
871
872 //KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!job.mimeType.isEmpty(), false);
873 if (job.mimeType.isEmpty()) {
875 slotCompleteSavingDocument(job, error, error.errorMessage(), "");
876 return false;
877
878 }
879
880 const QString actionName =
882 i18n("Exporting Document...") :
883 i18n("Saving Document...");
884
888 job, exportConfiguration, isAdvancedExporting);
889
891 QString errorShortLog;
892 QString errorMessage;
894
895 switch (result) {
897 errorShortLog = "another save operation is in progress";
898 errorMessage = i18n("Could not start saving %1. Wait until the current save operation has finished.", job.filePath);
899 errorCode = ImportExportCodes::Failure;
900 break;
902 errorShortLog = "failed to lock and clone the image";
903 errorMessage = i18n("Could not start saving %1. Image is busy", job.filePath);
904 errorCode = ImportExportCodes::Busy;
905 break;
907 errorShortLog = "failed to start background saving";
908 errorMessage = i18n("Could not start saving %1. Unknown failure has happened", job.filePath);
909 errorCode = ImportExportCodes::Failure;
910 break;
913 break;
915 // noop, not possible
916 break;
917 }
918
919 KisUsageLogger::log(QString("Failed to initiate saving %1 in background: %2").arg(job.filePath).arg(errorShortLog));
920
921 slotCompleteSavingDocument(job, errorCode,
923 "");
924 return false;
925 }
926
928}
static bool simpleBackupFile(const QString &filename, const QString &backupDir=QString(), const QString &backupExtension=QStringLiteral("~"))
Definition KisBackup.cpp:24
static bool numberedBackupFile(const QString &filename, const QString &backupDir=QString(), const QString &backupExtension=QStringLiteral("~"), const uint maxBackups=10)
Definition KisBackup.cpp:38
KritaUtils::BackgroudSavingStartResult initiateSavingInBackground(const QString actionName, const QObject *receiverObject, const char *receiverMethod, const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration, std::unique_ptr< KisDocument > &&optionalClonedDocument, bool isAdvancedExporting=false)
QString errorMessage() const
void slotCompleteSavingDocument(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)

References KritaUtils::AnotherSavingInProgress, KisAutoSaveRecoveryDialog::autoSaveLocation(), KisConfig::backupFile(), ImportExportCodes::Busy, ImportExportCodes::Cancelled, KritaUtils::Cancelled, errorMessage(), KisImportExportErrorCode::errorMessage(), ImportExportCodes::ErrorWhileWriting, ImportExportCodes::Failure, KritaUtils::Failure, ImportExportCodes::FileFormatNotSupported, KritaUtils::ExportFileJob::filePath, KritaUtils::ExportFileJob::flags, KritaUtils::ImageLockFailure, initiateSavingInBackground(), KisMacosSecurityBookmarkManager::instance(), KisMacosSecurityBookmarkManager::isSandboxed(), KisUsageLogger::log(), KritaUtils::ExportFileJob::mimeType, ImportExportCodes::NoAccessToWrite, KisBackup::numberedBackupFile(), KisMacosSecurityBookmarkManager::parentDirHasPermissions(), KisConfig::readEntry(), KritaUtils::SaveIsExporting, KisBackup::simpleBackupFile(), slotCompleteSavingDocument(), and KritaUtils::Success.

◆ exportDocumentSync()

bool KisDocument::exportDocumentSync ( const QString & path,
const QByteArray & mimeType,
KisPropertiesConfigurationSP exportConfiguration = 0 )

Exports he document is a synchronous way. The caller must ensure that the image is not accessed by any other actors, because the exporting happens without holding the image lock.

The caller guarantees that no one else uses the document (usually, it is a temporary document created specifically for exporting), so we don't need to copy or lock the document. Instead we should just ensure the barrier lock is synced and then released.

Definition at line 1336 of file KisDocument.cpp.

1337{
1338 {
1345 Private::StrippedSafeSavingLocker locker(&d->savingMutex, d->image);
1346 if (!locker.successfullyLocked()) {
1347 return false;
1348 }
1349 }
1350
1351 d->savingImage = d->image;
1352
1354 d->importExportManager->
1355 exportDocument(path, path, mimeType, false, exportConfiguration);
1356
1357 d->savingImage = 0;
1358
1359 return status.isOk();
1360}
bool exportDocument(const QString &path, const QByteArray &mimeType, bool isAdvancedExporting=false, bool showWarnings=false, KisPropertiesConfigurationSP exportConfiguration=0)

References d, exportDocument(), KisImportExportErrorCode::isOk(), and mimeType.

◆ exportErrorToUserMessage()

QString KisDocument::exportErrorToUserMessage ( KisImportExportErrorCode status,
const QString & errorMessage )
private

Definition at line 2937 of file KisDocument.cpp.

2938{
2939 return errorMessage.isEmpty() ? status.errorMessage() : errorMessage;
2940}

References errorMessage(), and KisImportExportErrorCode::errorMessage().

◆ extraNativeMimeTypes()

static QStringList KisDocument::extraNativeMimeTypes ( )
inlinestatic

Returns a list of the mimeTypes considered "native", i.e. which can be saved by KisDocument without a filter, in addition to the main one

Definition at line 178 of file KisDocument.h.

178{ return QStringList() << KIS_MIME_TYPE; }
#define KIS_MIME_TYPE
Definition KisDocument.h:57
QList< QString > QStringList

References KIS_MIME_TYPE.

◆ fileBatchMode()

bool KisDocument::fileBatchMode ( ) const
Returns
true if file operations should inhibit the option dialog

Definition at line 1145 of file KisDocument.cpp.

1146{
1147 return d->batchMode;
1148}

References d.

◆ finishExportInBackground

void KisDocument::finishExportInBackground ( )
privateslot

Definition at line 1760 of file KisDocument.cpp.

1761{
1762 KIS_SAFE_ASSERT_RECOVER(d->childSavingFuture.isFinished()) {
1764 return;
1765 }
1766
1767 KisImportExportErrorCode status = d->childSavingFuture.result();
1768 QString errorMessage = status.errorMessage();
1769 QString warningMessage = d->lastWarningMessage;
1770
1771 if (!d->lastErrorMessage.isEmpty()) {
1773 errorMessage = d->lastErrorMessage;
1774 } else {
1775 errorMessage += "\n" + d->lastErrorMessage;
1776 }
1777 }
1778
1779 d->savingImage.clear();
1780 d->childSavingFuture = QFuture<KisImportExportErrorCode>();
1781 d->lastErrorMessage.clear();
1782 d->lastWarningMessage.clear();
1783
1784 if (d->savingUpdater) {
1785 d->savingUpdater->setProgress(100);
1786 }
1787
1789}
QString warningMessage() const
void sigBackgroundSavingFinished(KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126

References d, errorMessage(), KisImportExportErrorCode::errorMessage(), ImportExportCodes::Failure, ImportExportCodes::InternalError, KIS_SAFE_ASSERT_RECOVER, sigBackgroundSavingFinished(), and warningMessage().

◆ generateAutoSaveFileName()

QString KisDocument::generateAutoSaveFileName ( const QString & path) const
private

Definition at line 1897 of file KisDocument.cpp.

1898{
1899 QString retval;
1900
1901 // Using the extension allows to avoid relying on the mime magic when opening
1902 const QString extension (".kra");
1903 QString prefix = KisConfig(true).readEntry<bool>("autosavefileshidden") ? QString(".") : QString();
1904 QRegularExpression autosavePattern1("^\\..+-autosave.kra$");
1905 QRegularExpression autosavePattern2("^.+-autosave.kra$");
1906
1907 QFileInfo fi(path);
1908 QString dir = fi.absolutePath();
1909
1910#ifdef Q_OS_ANDROID
1911 // URIs may or may not have a directory backing them, so we save to our default autosave location
1912 if (path.startsWith("content://")) {
1914 QDir().mkpath(dir);
1915 }
1916#endif
1917
1918 QString filename = fi.fileName();
1919
1920 if (path.isEmpty() || autosavePattern1.match(filename).hasMatch() || autosavePattern2.match(filename).hasMatch() || !fi.isWritable()) {
1921 // Never saved?
1922 retval = QString("%1%2%3%4-%5-%6-autosave%7")
1924 .arg('/')
1925 .arg(prefix)
1926 .arg("krita")
1927 .arg(qApp->applicationPid())
1928 .arg(objectName())
1929 .arg(extension);
1930 } else {
1931 // Beware: don't reorder arguments
1932 // otherwise in case of filename = '1-file.kra' it will become '.-file.kra-autosave.kra' instead of '.1-file.kra-autosave.kra'
1933 retval = QString("%1%2%3%4-autosave%5").arg(dir).arg('/').arg(prefix).arg(filename).arg(extension);
1934 }
1935
1936 //qDebug() << "generateAutoSaveFileName() for path" << path << ":" << retval;
1937 return retval;
1938}
T readEntry(const QString &name, const T &defaultValue=T())
Definition kis_config.h:875

References KisAutoSaveRecoveryDialog::autoSaveLocation(), and KisConfig::readEntry().

◆ generatePreview()

QPixmap KisDocument::generatePreview ( const QSize & size)

Generates a preview picture of the document.

Note
The preview is used in the File Dialog and also to create the Thumbnail

Definition at line 1854 of file KisDocument.cpp.

1855{
1856 KisImageSP image = d->image;
1857 if (d->savingImage) image = d->savingImage;
1858
1859 if (image) {
1860 QRect bounds = image->bounds();
1861 QSize originalSize = bounds.size();
1862 // QSize may round down one dimension to zero on extreme aspect rations, so ensure 1px minimum
1863 QSize newSize = originalSize.scaled(size, Qt::KeepAspectRatio).expandedTo({1, 1});
1864
1865 bool pixelArt = false;
1866 // determine if the image is pixel art or not
1867 if (originalSize.width() < size.width() && originalSize.height() < size.height()) {
1868 // the image must be smaller than the requested preview
1869 // the scale must be integer
1870 if (newSize.height()%originalSize.height() == 0 && newSize.width()%originalSize.width() == 0) {
1871 pixelArt = true;
1872 }
1873 }
1874
1875 QPixmap px;
1876 if (pixelArt) {
1877 // do not scale while converting (because it uses Bicubic)
1878 QImage original = image->convertToQImage(originalSize, 0);
1879 // scale using FastTransformation, which is probably Nearest neighbour, suitable for pixel art
1880 QImage scaled = original.scaled(newSize, Qt::KeepAspectRatio, Qt::FastTransformation);
1881 px = QPixmap::fromImage(scaled);
1882 } else {
1883 px = QPixmap::fromImage(image->convertToQImage(newSize, 0));
1884 }
1885 if (px.size() == QSize(0,0)) {
1886 px = QPixmap(newSize);
1887 QPainter gc(&px);
1888 QBrush checkBrush = QBrush(KisCanvasWidgetBase::createCheckersImage(newSize.width() / 5));
1889 gc.fillRect(px.rect(), checkBrush);
1890 gc.end();
1891 }
1892 return px;
1893 }
1894 return QPixmap(size);
1895}
static QImage createCheckersImage(qint32 checkSize=-1)
QImage convertToQImage(qint32 x1, qint32 y1, qint32 width, qint32 height, const KoColorProfile *profile)
QRect bounds() const override
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References KisImage::bounds(), bounds, KisImage::convertToQImage(), KisCanvasWidgetBase::createCheckersImage(), d, and image.

◆ getAudioLevel()

qreal KisDocument::getAudioLevel ( )

Definition at line 2510 of file KisDocument.cpp.

2511{
2512 return d->audioLevel;
2513}

References d.

◆ getAudioTracks()

QVector< QFileInfo > KisDocument::getAudioTracks ( ) const

Definition at line 2494 of file KisDocument.cpp.

2494 {
2495 return d->audioTracks;
2496}

References d.

◆ getStoryboardCommentsList()

QVector< StoryboardComment > KisDocument::getStoryboardCommentsList ( )

returns the list of comments for the storyboard docker in the document

Definition at line 2481 of file KisDocument.cpp.

2482{
2483 return d->m_storyboardCommentList;
2484}

References d.

◆ getStoryboardItemList()

StoryboardItemList KisDocument::getStoryboardItemList ( )

returns the list of pointers to storyboard Items for the document

Definition at line 2468 of file KisDocument.cpp.

2469{
2470 return d->m_storyboardItemList;
2471}

References d.

◆ gridConfig()

KisGridConfig KisDocument::gridConfig ( ) const

◆ guidesConfig()

const KisGuidesConfig & KisDocument::guidesConfig ( ) const

returns the guides data for this document.

◆ hackPreliminarySetImage()

void KisDocument::hackPreliminarySetImage ( KisImageSP image)

Set the image of the document preliminary, before the document has completed loading. Some of the document items (shapes) may want to access image properties (bounds and resolution), so we should provide it to them even before the entire image is loaded.

Right now, the only use by KoShapeRegistry::createShapeFromOdf(), remove after it is deprecated.

Definition at line 2904 of file KisDocument.cpp.

2905{
2907
2908 // we set image without connecting idle-watcher, because loading
2909 // hasn't been finished yet
2910 d->image = image;
2911 d->shapeController->setImage(image);
2912}
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References d, image, and KIS_SAFE_ASSERT_RECOVER_RETURN.

◆ image()

KisImageWSP KisDocument::image ( ) const

◆ importDocument()

bool KisDocument::importDocument ( const QString & path)

Opens the document given by path, without storing the Path in the KisDocument. Call this instead of openPath() to implement KisMainWindow's File --> Import feature.

Note
This will call openPath(). To differentiate this from an ordinary Open operation (in any reimplementation of openPath() or openFile()) call isImporting().

Definition at line 1940 of file KisDocument.cpp.

1941{
1942 bool ret;
1943
1944 dbgUI << "path=" << _path;
1945
1946 // open...
1947 ret = openPath(_path);
1948
1949 // reset url & m_file (kindly? set by KisParts::openUrl()) to simulate a
1950 // File --> Import
1951 if (ret) {
1952 dbgUI << "success, resetting url";
1953 resetPath();
1954 }
1955
1956 return ret;
1957}
bool openPath(const QString &path, OpenFlags flags=None)
openPath Open a Path
#define dbgUI
Definition kis_debug.h:52

References dbgUI, openPath(), and resetPath().

◆ importExportManager()

KisImportExportManager * KisDocument::importExportManager ( ) const

importExportManager gives access to the internal import/export manager

Returns
the document's import/export manager

◆ initiateSavingInBackground() [1/2]

KritaUtils::BackgroudSavingStartResult KisDocument::initiateSavingInBackground ( const QString actionName,
const QObject * receiverObject,
const char * receiverMethod,
const KritaUtils::ExportFileJob & job,
KisPropertiesConfigurationSP exportConfiguration,
bool isAdvancedExporting = false )
private

Definition at line 1363 of file KisDocument.cpp.

1367{
1368 return initiateSavingInBackground(actionName, receiverObject, receiverMethod,
1369 job, exportConfiguration, std::unique_ptr<KisDocument>(), isAdvancedExporting);
1370}

References initiateSavingInBackground().

◆ initiateSavingInBackground() [2/2]

KritaUtils::BackgroudSavingStartResult KisDocument::initiateSavingInBackground ( const QString actionName,
const QObject * receiverObject,
const char * receiverMethod,
const KritaUtils::ExportFileJob & job,
KisPropertiesConfigurationSP exportConfiguration,
std::unique_ptr< KisDocument > && optionalClonedDocument,
bool isAdvancedExporting = false )
private

This lock will later release() when we start the background thread, it means that the ownership is transferred to the background thread

From now on no return statements are allowed, even inside asserts, since the ownership over the saving mutex has already been passed to the background thread.

The cancellation process should go through slotChildCompletedSavingInBackground(), which will unlock the mutex itself.

Definition at line 1372 of file KisDocument.cpp.

1377{
1379
1380 std::unique_ptr<KisDocument> clonedDocument;
1381
1382 if (!optionalClonedDocument) {
1383 clonedDocument.reset(lockAndCloneForSaving());
1384 } else {
1385 clonedDocument.reset(optionalClonedDocument.release());
1386 }
1387
1388 if (!d->savingMutex.tryLock()){
1390 }
1391
1396 std::unique_lock<QMutex> savingMutexLock(d->savingMutex, std::adopt_lock);
1397
1398 if (!clonedDocument) {
1400 }
1401
1402 auto waitForImage = [] (KisImageSP image) {
1404 if (window) {
1405 if (window->viewManager()) {
1407 }
1408 }
1409 };
1410
1411 {
1412 KisNodeSP newRoot = clonedDocument->image()->root();
1415 waitForImage(clonedDocument->image());
1416 }
1417 }
1418
1419 if (clonedDocument->image()->hasOverlaySelectionMask()) {
1420 clonedDocument->image()->setOverlaySelectionMask(0);
1421 waitForImage(clonedDocument->image());
1422 }
1423
1424 KisConfig cfg(true);
1425 if (cfg.trimKra()) {
1426 clonedDocument->image()->cropImage(clonedDocument->image()->bounds());
1427 clonedDocument->image()->purgeUnusedData(false);
1428 waitForImage(clonedDocument->image());
1429 }
1430
1431 KIS_SAFE_ASSERT_RECOVER(clonedDocument->image()->isIdle()) {
1432 waitForImage(clonedDocument->image());
1433 }
1434
1437
1447 savingMutexLock.release();
1448
1449 d->backgroundSaveDocument.reset(clonedDocument.release());
1450 d->backgroundSaveJob = job;
1451 d->modifiedWhileSaving = false;
1452
1453 if (d->backgroundSaveJob.flags & KritaUtils::SaveInAutosaveMode) {
1454 d->backgroundSaveDocument->d->isAutosaving = true;
1455 }
1456
1457 connect(d->backgroundSaveDocument.get(),
1458 SIGNAL(sigBackgroundSavingFinished(KisImportExportErrorCode, QString, QString)),
1459 this,
1461
1462
1463 if (d->completeSavingConnection) {
1464 disconnect(d->completeSavingConnection);
1465 }
1466 d->completeSavingConnection = connect(
1468 receiverObject, receiverMethod);
1469
1471 d->backgroundSaveDocument->startExportInBackground(actionName,
1472 job.filePath,
1473 job.filePath,
1474 job.mimeType,
1476 exportConfiguration, isAdvancedExporting);
1477 if (!error.isOk()) {
1478 // the state should have been deinitialized in slotChildCompletedSavingInBackground()
1479 KIS_SAFE_ASSERT_RECOVER (!d->backgroundSaveDocument && !d->backgroundSaveJob.isValid()) {
1480 d->backgroundSaveDocument.release()->deleteLater();
1481 d->savingMutex.unlock();
1482 d->backgroundSaveJob = KritaUtils::ExportFileJob();
1483 }
1484 if (error.isCancelled()) {
1486 }
1488 }
1489
1491}
KisDocument * lockAndCloneForSaving()
try to clone the image. This method handles all the locking for you. If locking has failed,...
void slotChildCompletedSavingInBackground(KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
void sigCompleteBackgroundSaving(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
Main window for Krita.
KisViewManager * viewManager
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:459
void blockUntilOperationsFinishedForced(KisImageSP image)
blockUntilOperationsFinished blocks the GUI of the application until execution of actions on image is...
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:85
bool hasDelayedNodeWithUpdates(KisNodeSP root)
void forceAllDelayedNodesUpdate(KisNodeSP root)
KisImageWSP image

References KritaUtils::AnotherSavingInProgress, KisViewManager::blockUntilOperationsFinishedForced(), KritaUtils::Cancelled, KisPart::currentMainwindow(), d, KritaUtils::Failure, KritaUtils::ExportFileJob::filePath, KritaUtils::ExportFileJob::flags, KisLayerUtils::forceAllDelayedNodesUpdate(), KisLayerUtils::hasDelayedNodeWithUpdates(), KisBaseNode::image, image, KritaUtils::ImageLockFailure, KisPart::instance(), KisImportExportErrorCode::isCancelled(), KisImportExportErrorCode::isOk(), KritaUtils::ExportFileJob::isValid(), KIS_ASSERT_RECOVER_RETURN_VALUE, KIS_SAFE_ASSERT_RECOVER, lockAndCloneForSaving(), KritaUtils::ExportFileJob::mimeType, KisNodeFacade::root, KritaUtils::SaveInAutosaveMode, KritaUtils::SaveShowWarnings, sigBackgroundSavingFinished(), sigCompleteBackgroundSaving(), slotChildCompletedSavingInBackground(), KritaUtils::Success, KisConfig::trimKra(), and KisMainWindow::viewManager.

◆ isAutoSaveActive()

bool KisDocument::isAutoSaveActive ( )

Indicate if autosave is active or inactive

the value is independent of auto save delay

Definition at line 1839 of file KisDocument.cpp.

1840{
1841 return d->autoSaveActive;
1842}

References d.

◆ isAutosaving()

bool KisDocument::isAutosaving ( ) const

◆ isInSaving()

bool KisDocument::isInSaving ( ) const

isInSaving shown if the document has any (background) saving process or not

Returns
true if there is some saving in action

◆ isModified()

bool KisDocument::isModified ( ) const

Returns true if this document or any of its internal child documents are modified.

Definition at line 1849 of file KisDocument.cpp.

1850{
1851 return d->modified;
1852}

References d.

◆ isNativeFormat()

bool KisDocument::isNativeFormat ( const QByteArray & mimeType) const

Checks whether a given mimeType can be handled natively.

Definition at line 2260 of file KisDocument.cpp.

2261{
2263 return true;
2264 return extraNativeMimeTypes().contains(mimeType);
2265}
static QStringList extraNativeMimeTypes()

References extraNativeMimeTypes(), mimeType, and nativeFormatMimeType().

◆ isReadWrite()

bool KisDocument::isReadWrite ( ) const

Definition at line 2561 of file KisDocument.cpp.

2562{
2563 return d->readwrite;
2564}

References d.

◆ isRecovered()

bool KisDocument::isRecovered ( ) const

◆ isSaving()

bool KisDocument::isSaving ( ) const

Definition at line 2768 of file KisDocument.cpp.

2769{
2770 const bool result = d->savingMutex.tryLock();
2771 if (result) {
2772 d->savingMutex.unlock();
2773 }
2774 return !result;
2775}

References d.

◆ linkedDocumentResources()

QList< KoResourceLoadResult > KisDocument::linkedDocumentResources ( )

linkedDocumentResources List returns all the resources linked to the document, such as palettes

In some cases (e.g. when the document is temporary), the underlying document storage will not be registered in the resource system, so we cannot get fully initialized resources from it (resourceId(), active(), md5() and storageLocation() fields will be uninitialized). Therefore we just return KoEmbeddedResource which is suitable for saving this data into hard drive.

The returned KoResourceLoadResult object can either be in EmbeddedResource or FailedLink state. The former means the resource has been prepared for embedding, the latter means there was some issue with serializing the resource. In the latter case the called should check result.signature() to find out which resource has failed.

NOTE: the returned result can NOT have ExistingResource state!

Definition at line 2396 of file KisDocument.cpp.

2397{
2399 if (!d->linkedResourceStorage) {
2400 return result;
2401 }
2402
2403 Q_FOREACH(const QString &resourceType, KisResourceLoaderRegistry::instance()->resourceTypes()) {
2404 QSharedPointer<KisResourceStorage::ResourceIterator> iter = d->linkedResourceStorage->resources(resourceType);
2405 while (iter->hasNext()) {
2406 iter->next();
2407
2408 QBuffer buf;
2409 buf.open(QBuffer::WriteOnly);
2410 bool exportSuccessful =
2411 d->linkedResourceStorage->exportResource(iter->url(), &buf);
2412
2413 KoResourceSP resource = d->linkedResourceStorage->resource(iter->url());
2414 exportSuccessful &= bool(resource);
2415
2416 const QString name = resource ? resource->name() : QString();
2417 const QString fileName = QFileInfo(iter->url()).fileName();
2418 const KoResourceSignature signature(resourceType,
2419 KoMD5Generator::generateHash(buf.data()),
2420 fileName, name);
2421
2422 if (exportSuccessful) {
2423 result << KoEmbeddedResource(signature, buf.data());
2424 } else {
2425 result << signature;
2426 }
2427 }
2428 }
2429
2430 return result;
2431}
static KisResourceLoaderRegistry * instance()
static QString generateHash(const QString &filename)
generateHash reads the given file and generates a hex-encoded md5sum for the file.
A simple wrapper object for the main information about the resource.
const char * name(StandardAction id)

References d, KoMD5Generator::generateHash(), and KisResourceLoaderRegistry::instance().

◆ linkedResourcesStorageId()

QString KisDocument::linkedResourcesStorageId ( ) const

Persistent storage for the resources that are linked but the resources embedded in the document. These resources are not embedded into their own container resource, so they should be stored by the document

All these resources are saved into the document itself and loaded alongside the document.

Definition at line 730 of file KisDocument.cpp.

731{
732 return d->linkedResourcesStorageID;
733}

References d.

◆ loadNativeFormat()

bool KisDocument::loadNativeFormat ( const QString & file)

Loads a document in the native format from a given Path. Reimplement if your native format isn't XML.

Parameters
filethe file to load - usually KReadOnlyPart::m_file or the result of a filter

Definition at line 2138 of file KisDocument.cpp.

2139{
2140 return openPath(file_);
2141}

References openPath().

◆ localFilePath()

QString KisDocument::localFilePath ( ) const

Definition at line 2606 of file KisDocument.cpp.

2607{
2608 return d->m_file;
2609}

References d.

◆ lockAndCloneForSaving()

KisDocument * KisDocument::lockAndCloneForSaving ( )

try to clone the image. This method handles all the locking for you. If locking has failed, no cloning happens

Returns
cloned document on success, null otherwise

Definition at line 1240 of file KisDocument.cpp.

1241{
1242 return d->lockAndCloneImpl(true);
1243}

References d.

◆ lockAndCloneImpl()

KisDocument * KisDocument::lockAndCloneImpl ( bool fetchResourcesFromLayers)

◆ lockAndCreateSnapshot()

KisDocument * KisDocument::lockAndCreateSnapshot ( )

Definition at line 1245 of file KisDocument.cpp.

1246{
1247 return d->lockAndCloneImpl(false);
1248}

References d.

◆ mimeType()

QByteArray KisDocument::mimeType ( ) const

Returns the actual mimeType of the document

◆ mirrorAxisConfig()

const KisMirrorAxisConfig & KisDocument::mirrorAxisConfig ( ) const

◆ modified

void KisDocument::modified ( bool )
signal

Emitted when the document is modified

◆ nativeFormatMimeType()

static QByteArray KisDocument::nativeFormatMimeType ( )
inlinestatic

To be preferred when a document exists. It is fast when calling it multiple times since it caches the result that readNativeFormatMimeType() delivers. This comes from the X-KDE-NativeMimeType key in the .desktop file.

Definition at line 171 of file KisDocument.h.

171{ return KIS_MIME_TYPE; }

References KIS_MIME_TYPE.

◆ newImage()

bool KisDocument::newImage ( const QString & name,
qint32 width,
qint32 height,
const KoColorSpace * cs,
const KoColor & bgColor,
KisConfig::BackgroundStyle bgStyle,
int numberOfLayers,
const QString & imageDescription,
const double imageResolution )

Create a new image that has this document as a parent and replace the current image with this image.

Preinitialize color history for new documents when possible

Definition at line 2663 of file KisDocument.cpp.

2669{
2670 Q_ASSERT(cs);
2671
2673
2674 if (!cs) return false;
2675
2676 KisCursorOverrideLock cursorLock(Qt::BusyCursor);
2677
2678 image = new KisImage(createUndoStore(), width, height, cs, name);
2679
2680 Q_CHECK_PTR(image);
2681
2682 connect(image, SIGNAL(sigImageModified()), this, SLOT(setImageModified()), Qt::UniqueConnection);
2683 connect(image, SIGNAL(sigImageModifiedWithoutUndo()), this, SLOT(setImageModifiedWithoutUndo()), Qt::UniqueConnection);
2684 image->setResolution(imageResolution, imageResolution);
2685
2687 image->waitForDone();
2688
2689 documentInfo()->setAboutInfo("title", name);
2690 documentInfo()->setAboutInfo("abstract", description);
2691
2692 KisConfig cfg(false);
2693 cfg.defImageWidth(width);
2694 cfg.defImageHeight(height);
2695 cfg.defImageResolution(imageResolution);
2696 if (!cfg.useDefaultColorSpace())
2697 {
2698 cfg.defColorModel(image->colorSpace()->colorModelId().id());
2699 cfg.setDefaultColorDepth(image->colorSpace()->colorDepthId().id());
2700 cfg.defColorProfile(image->colorSpace()->profile()->name());
2701 }
2702
2703 bool autopin = cfg.autoPinLayersToTimeline();
2704
2705 KisLayerSP bgLayer;
2706 if (bgStyle == KisConfig::RASTER_LAYER || bgStyle == KisConfig::FILL_LAYER) {
2707 KoColor strippedAlpha = bgColor;
2708 strippedAlpha.setOpacity(OPACITY_OPAQUE_U8);
2709
2710 if (bgStyle == KisConfig::RASTER_LAYER) {
2711 bgLayer = new KisPaintLayer(image.data(), i18nc("Name for the bottom-most layer in the layerstack", "Background"), OPACITY_OPAQUE_U8, cs);
2712 bgLayer->paintDevice()->setDefaultPixel(strippedAlpha);
2713 bgLayer->setPinnedToTimeline(autopin);
2714 } else if (bgStyle == KisConfig::FILL_LAYER) {
2716 filter_config->setProperty("color", strippedAlpha.toQColor());
2717 filter_config->createLocalResourcesSnapshot();
2718 bgLayer = new KisGeneratorLayer(image.data(), i18nc("Name of automatically created background color fill layer", "Background Fill"), filter_config, image->globalSelection());
2719 }
2720
2721 bgLayer->setOpacity(bgColor.opacityU8());
2722
2723 if (numberOfLayers > 1) {
2724 //Lock bg layer if others are present.
2725 bgLayer->setUserLocked(true);
2726 }
2727 }
2728 else { // KisConfig::CANVAS_COLOR (needs an unlocked starting layer).
2730 bgLayer = new KisPaintLayer(image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8, cs);
2731 }
2732
2733 Q_CHECK_PTR(bgLayer);
2734 image->addNode(bgLayer.data(), image->rootLayer().data());
2735 bgLayer->setDirty(QRect(0, 0, width, height));
2736
2737 // reset mirror axis to default:
2738 d->mirrorAxisConfig.setAxisPosition(QRectF(image->bounds()).center());
2740
2741 for(int i = 1; i < numberOfLayers; ++i) {
2743 layer->setPinnedToTimeline(autopin);
2744 image->addNode(layer, image->root(), i);
2745 layer->setDirty(QRect(0, 0, width, height));
2746 }
2747
2748 {
2750 if (window) {
2755 }
2756 }
2757
2759 QString("Created image \"%1\", %2 * %3 pixels, %4 dpi. Color model: %6 %5 (%7). Layers: %8")
2760 .arg(name, QString::number(width), QString::number(height),
2761 QString::number(imageResolution * 72.0), image->colorSpace()->colorModelId().name(),
2763 QString::number(numberOfLayers)));
2764
2765 return true;
2766}
const quint8 OPACITY_OPAQUE_U8
QList< KoColor > colorHistoryColors() const
KisUndoStore * createUndoStore()
KoDocumentInfo * documentInfo() const
void setImageModified()
void setImageModifiedWithoutUndo()
void setColorHistoryColors(const QList< KoColor > &colors)
static KisGeneratorRegistry * instance()
static KisResourcesInterfaceSP instance()
void waitForDone()
KisGroupLayerSP rootLayer() const
const KoColorSpace * colorSpace() const
QString nextLayerName(const QString &baseName="") const
Definition kis_image.cc:716
bool assignImageProfile(const KoColorProfile *profile, bool blockAllUpdates=false)
void setDefaultProjectionColor(const KoColor &color)
KisSelectionSP globalSelection() const
Definition kis_image.cc:696
void setResolution(double xres, double yres)
void setDefaultPixel(const KoColor &defPixel)
KisCanvasResourceProvider * canvasResourceProvider()
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
quint8 opacityU8() const
Definition KoColor.cpp:341
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
void setAboutInfo(const QString &info, const QString &data)
T get(const QString &id) const
QString name() const
Definition KoID.cpp:68
QString id() const
Definition KoID.cpp:63
void setPinnedToTimeline(bool pinned)
virtual void setUserLocked(bool l)
void setOpacity(quint8 val)
virtual KisPaintDeviceSP paintDevice() const =0
virtual KisFilterConfigurationSP defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
virtual void setDirty()
Definition kis_node.cpp:577

References KisNodeFacade::addNode(), KisImage::assignImageProfile(), KisConfig::autoPinLayersToTimeline(), KisImage::bounds(), KisViewManager::canvasResourceProvider(), KoColorSpace::colorDepthId(), KisCanvasResourceProvider::colorHistoryColors(), KoColorSpace::colorModelId(), KisImage::colorSpace(), createUndoStore(), KisPart::currentMainwindow(), d, KisSharedPtr< T >::data(), KisBaseProcessor::defaultConfiguration(), KisConfig::defColorModel(), KisConfig::defColorProfile(), KisConfig::defImageHeight(), KisConfig::defImageResolution(), KisConfig::defImageWidth(), documentInfo(), KisConfig::FILL_LAYER, KoGenericRegistry< T >::get(), KisImage::globalSelection(), KoID::id(), image, KisGeneratorRegistry::instance(), KisGlobalResourcesInterface::instance(), KisPart::instance(), KisUsageLogger::log(), KoID::name(), KoColorProfile::name, KisImage::nextLayerName(), OPACITY_OPAQUE_U8, KoColor::opacityU8(), KisBaseNode::paintDevice(), KoColorSpace::profile(), KisConfig::RASTER_LAYER, KisNodeFacade::root, KisImage::rootLayer(), KoDocumentInfo::setAboutInfo(), setColorHistoryColors(), setCurrentImage(), KisConfig::setDefaultColorDepth(), KisPaintDevice::setDefaultPixel(), KisImage::setDefaultProjectionColor(), KisNode::setDirty(), setImageModified(), setImageModifiedWithoutUndo(), KoColor::setOpacity(), KisBaseNode::setOpacity(), KisBaseNode::setPinnedToTimeline(), KisImage::setResolution(), KisBaseNode::setUserLocked(), KoColor::toQColor(), KisConfig::useDefaultColorSpace(), KisMainWindow::viewManager, and KisImage::waitForDone().

◆ newObjectName()

QString KisDocument::newObjectName ( )
private

Generate a name for the document.

Definition at line 160 of file KisDocument.cpp.

161{
162 static int s_docIFNumber = 0;
163 QString name; name.setNum(s_docIFNumber++); name.prepend("document_");
164 return name;
165}

◆ openFile()

bool KisDocument::openFile ( )
private

Loads a document

Applies a filter if necessary, and calls loadNativeFormat in any case You should not have to reimplement, except for very special cases.

NOTE: this method also creates a new KisView instance!

This method is called from the KReadOnlyPart::openPath method.

Definition at line 2035 of file KisDocument.cpp.

2036{
2037 //dbgUI <<"for" << localFilePath();
2038 if (!QFile::exists(localFilePath()) && !fileBatchMode()) {
2039 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"), i18n("File %1 does not exist.", localFilePath()));
2040 return false;
2041 }
2042
2043 QString filename = localFilePath();
2044 QString typeName = mimeType();
2045
2046 if (typeName.isEmpty()) {
2047 typeName = KisMimeDatabase::mimeTypeForFile(filename);
2048 }
2049
2050 // Allow to open backup files, don't keep the mimeType application/x-trash.
2051 if (typeName == "application/x-trash") {
2052 QString path = filename;
2053 while (path.length() > 0) {
2054 path.chop(1);
2055 typeName = KisMimeDatabase::mimeTypeForFile(path);
2056 //qDebug() << "\t" << path << typeName;
2057 if (!typeName.isEmpty()) {
2058 break;
2059 }
2060 }
2061 //qDebug() << "chopped" << filename << "to" << path << "Was trash, is" << typeName;
2062 }
2063 dbgUI << localFilePath() << "type:" << typeName;
2064
2066 KoUpdaterPtr updater;
2067 if (window && window->viewManager()) {
2068 updater = window->viewManager()->createUnthreadedUpdater(i18n("Opening document"));
2069 d->importExportManager->setUpdater(updater);
2070 }
2071
2072 KisImportExportErrorCode status = d->importExportManager->importDocument(localFilePath(), typeName);
2073
2074 if (!status.isOk()) {
2075 if (window && window->viewManager()) {
2076 updater->cancel();
2077 }
2078 QString msg = status.errorMessage();
2079 KisUsageLogger::log(QString("Loading %1 failed: %2").arg(prettyPath(), msg));
2080
2081 if (!msg.isEmpty() && !fileBatchMode()) {
2082 DlgLoadMessages dlg(i18nc("@title:window", "Krita"),
2083 i18n("Could not open %1.", prettyPath()),
2084 errorMessage().split("\n", Qt::SkipEmptyParts)
2085 + warningMessage().split("\n", Qt::SkipEmptyParts),
2086 msg);
2087
2088 dlg.exec();
2089 }
2090 return false;
2091 }
2092 else if (!warningMessage().isEmpty() && !fileBatchMode()) {
2093 DlgLoadMessages dlg(i18nc("@title:window", "Krita"),
2094 i18n("There were problems opening %1.", prettyPath()),
2095 warningMessage().split("\n", Qt::SkipEmptyParts));
2096
2097 dlg.exec();
2098 setPath(QString());
2099 }
2100
2101 setMimeTypeAfterLoading(typeName);
2102 d->syncDecorationsWrapperLayerState();
2103 Q_EMIT sigLoadingFinished();
2104
2105 undoStack()->clear();
2106
2107 return true;
2108}
KUndo2Stack * undoStack
void sigLoadingFinished()
void setPath(const QString &path)
bool fileBatchMode() const
void setMimeTypeAfterLoading(const QString &mimeType)
QString prettyPath() const
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
QPointer< KoUpdater > createUnthreadedUpdater(const QString &name)
create a new progress updater
QList< KoSubpath * > split(const KoPathShape &path)

References KUndo2QStack::clear(), KisViewManager::createUnthreadedUpdater(), KisPart::currentMainwindow(), d, dbgUI, errorMessage(), KisImportExportErrorCode::errorMessage(), fileBatchMode(), KisPart::instance(), KisImportExportErrorCode::isOk(), localFilePath(), KisUsageLogger::log(), mimeType, KisMimeDatabase::mimeTypeForFile(), prettyPath(), setMimeTypeAfterLoading(), setPath(), sigLoadingFinished(), undoStack, KisMainWindow::viewManager, and warningMessage().

◆ openPath()

bool KisDocument::openPath ( const QString & path,
OpenFlags flags = None )

openPath Open a Path

Parameters
pathPath to file
flagsControl specific behavior
Returns
success status

Definition at line 1960 of file KisDocument.cpp.

1961{
1962 dbgUI << "path=" << _path;
1963 d->lastErrorMessage.clear();
1964
1965 // Reimplemented, to add a check for autosave files and to improve error reporting
1966 if (_path.isEmpty()) {
1967 d->lastErrorMessage = i18n("Malformed Path\n%1", _path); // ## used anywhere ?
1968 return false;
1969 }
1970
1971 QString path = _path;
1972 QString original = "";
1973 bool autosaveOpened = false;
1974 if (!fileBatchMode()) {
1975 QString file = path;
1976 QString asf = generateAutoSaveFileName(file);
1977 if (QFile::exists(asf)) {
1978 KisApplication *kisApp = static_cast<KisApplication*>(qApp);
1979 kisApp->hideSplashScreen();
1980 //qDebug() <<"asf=" << asf;
1981 // ## TODO compare timestamps ?
1982 KisRecoverNamedAutosaveDialog dlg(0, file, asf);
1983 dlg.exec();
1984 int res = dlg.result();
1985
1986 switch (res) {
1988 original = file;
1989 path = asf;
1990 autosaveOpened = true;
1991 break;
1993 KisUsageLogger::log(QString("Removing autosave file: %1").arg(asf));
1994 QFile::remove(asf);
1995 break;
1996 default: // Cancel
1997 return false;
1998 }
1999 }
2000 }
2001
2002 bool ret = openPathInternal(path);
2003
2004 if (autosaveOpened || flags & RecoveryFile) {
2005 setReadWrite(true); // enable save button
2006 setModified(true);
2007 setRecovered(true);
2008
2009 setPath(original); // since it was an autosave, it will be a local file
2010 setLocalFilePath(original);
2011 }
2012 else {
2013 if (ret) {
2014
2015 if (!(flags & DontAddToRecent)) {
2016 KisPart::instance()->addRecentURLToAllMainWindows(QUrl::fromLocalFile(_path));
2017 }
2018
2019#ifdef Q_OS_ANDROID
2020 // See the comment titled "ANDROID NOTES" in this file for an
2021 // explanation of what this is about. (This is not that comment.)
2022 setReadWrite(true);
2023#else
2024 QFileInfo fi(_path);
2025 setReadWrite(fi.isWritable());
2026#endif
2027 }
2028
2029 setRecovered(false);
2030 }
2031
2032 return ret;
2033}
Base class for the Krita app.
void setLocalFilePath(const QString &localFilePath)
void setRecovered(bool value)
void setReadWrite(bool readwrite=true)
Sets whether the document can be edited or is read only.
bool openPathInternal(const QString &path)
void addRecentURLToAllMainWindows(QUrl url, QUrl oldUrl=QUrl())
Definition KisPart.cpp:574
The KisRecoverNamedAutosaveDialog class is a dialog to recover already existing files from autosave.

References KisPart::addRecentURLToAllMainWindows(), d, dbgUI, DontAddToRecent, fileBatchMode(), generateAutoSaveFileName(), KisApplication::hideSplashScreen(), KisPart::instance(), KisUsageLogger::log(), KisRecoverNamedAutosaveDialog::OpenAutosave, KisRecoverNamedAutosaveDialog::OpenMainFile, openPathInternal(), path(), RecoveryFile, setLocalFilePath(), setModified(), setPath(), setReadWrite(), and setRecovered().

◆ openPathInternal()

bool KisDocument::openPathInternal ( const QString & path)
private

Definition at line 2617 of file KisDocument.cpp.

2618{
2619 if ( path.isEmpty() ) {
2620 return false;
2621 }
2622
2623 if (d->m_bAutoDetectedMime) {
2624 d->mimeType = QByteArray();
2625 d->m_bAutoDetectedMime = false;
2626 }
2627
2628 QByteArray mimeType = d->mimeType;
2629
2630 if ( !closePath() ) {
2631 return false;
2632 }
2633
2634 d->mimeType = mimeType;
2635 setPath(path);
2636
2637 d->m_file.clear();
2638
2639 d->m_file = d->m_path;
2640
2641 bool ret = false;
2642 // set the mimeType only if it was not already set (for example, by the host application)
2643 if (d->mimeType.isEmpty()) {
2644 // get the mimeType of the file
2645 // using findByUrl() to avoid another string -> url conversion
2646 QString mime = KisMimeDatabase::mimeTypeForFile(d->m_path);
2647 d->mimeType = mime.toLocal8Bit();
2648 d->m_bAutoDetectedMime = true;
2649 }
2650
2651 setPath(d->m_path);
2652 ret = openFile();
2653
2654 if (ret) {
2655 Q_EMIT completed();
2656 }
2657 else {
2658 Q_EMIT canceled(QString());
2659 }
2660 return ret;
2661}
void completed()
void canceled(const QString &)
bool closePath(bool promptToSave=true)

References canceled(), closePath(), completed(), d, mimeType, KisMimeDatabase::mimeTypeForFile(), openFile(), and setPath().

◆ path()

QString KisDocument::path ( ) const

Definition at line 2566 of file KisDocument.cpp.

2567{
2568 return d->m_path;
2569}

References d.

◆ preActivatedNode()

KisNodeSP KisDocument::preActivatedNode ( ) const
Returns
the node that was set as active during loading. Used only for saving loading. Never use it for tools or processing.

◆ prettyPath()

QString KisDocument::prettyPath ( ) const
private

Definition at line 2215 of file KisDocument.cpp.

2216{
2217 QString _url(path());
2218#ifdef Q_OS_WIN
2219 _url = QDir::toNativeSeparators(_url);
2220#endif
2221 return _url;
2222}

References path().

◆ Private() [1/2]

KisDocument::Private ( const Private & rhs,
KisDocument * _q )
inline

Definition at line 323 of file KisDocument.cpp.

324 : q(_q)
325 , docInfo(new KoDocumentInfo(*rhs.docInfo, _q))
327 , autoSaveTimer(new QTimer(_q))
328 , undoStack(new UndoStack(_q))
329 , nserver(new KisNameServer(*rhs.nserver))
330 , preActivatedNode(0) // the node is from another hierarchy!
331 , imageIdleWatcher(2000 /*ms*/)
332 , colorHistoryModel(rhs.colorHistoryModel)
333 {
334 copyFromImpl(rhs, _q, CONSTRUCT);
335 connect(&imageIdleWatcher, SIGNAL(startedIdleMode()), q, SLOT(slotPerformIdleRoutines()));
336 }
QTimer * autoSaveTimer
void copyFromImpl(const Private &rhs, KisDocument *q, KisDocument::CopyPolicy policy)
KisImportExportManager * importExportManager
KisDocument * q
KisNodeWSP preActivatedNode
KisIdleWatcher imageIdleWatcher
void slotPerformIdleRoutines()
KisUniqueColorSet colorHistoryModel
The class managing all the filters.
The class containing all meta information about a document.

◆ Private() [2/2]

KisDocument::Private ( KisDocument * _q)
inline

Definition at line 298 of file KisDocument.cpp.

299 : q(_q)
300 , docInfo(new KoDocumentInfo(_q)) // deleted by QObject
301 , importExportManager(new KisImportExportManager(_q)) // deleted manually
302 , autoSaveTimer(new QTimer(_q))
303 , undoStack(new UndoStack(_q)) // deleted by QObject
304 , m_bAutoDetectedMime(false)
305 , modified(false)
306 , readwrite(true)
307 , autoSaveActive(true)
308 , firstMod(QDateTime::currentDateTime())
310 , nserver(new KisNameServer(1))
311 , imageIdleWatcher(2000 /*ms*/)
312 , globalAssistantsColor(KisConfig(true).defaultAssistantsColor())
313 , batchMode(false)
314 {
315 if (QLocale().measurementSystem() == QLocale::ImperialSystem) {
317 } else {
319 }
320 connect(&imageIdleWatcher, SIGNAL(startedIdleMode()), q, SLOT(slotPerformIdleRoutines()));
321 }
bool m_bAutoDetectedMime
QDateTime lastMod
QDateTime firstMod
QColor globalAssistantsColor
@ Centimeter
Definition KoUnit.h:78
@ Inch
Definition KoUnit.h:77

References KoUnit::Centimeter, and KoUnit::Inch.

◆ referenceImagesLayer()

KisReferenceImagesLayerSP KisDocument::referenceImagesLayer ( ) const

Get existing reference images layer or null if none exists.

Definition at line 2809 of file KisDocument.cpp.

2810{
2811 if (!d->image) return KisReferenceImagesLayerSP();
2812
2813 KisReferenceImagesLayerSP referencesLayer =
2814 KisLayerUtils::findNodeByType<KisReferenceImagesLayer>(d->image->root());
2815
2816 return referencesLayer;
2817}
KisSharedPtr< KisReferenceImagesLayer > KisReferenceImagesLayerSP

References d.

◆ removeAutoSaveFiles()

void KisDocument::removeAutoSaveFiles ( const QString & autosaveBaseName,
bool wasRecovered )

Performs a cleanup of unneeded backup files

Definition at line 2288 of file KisDocument.cpp.

2289{
2290 // Eliminate any auto-save file
2291 QString asf = generateAutoSaveFileName(autosaveBaseName); // the one in the current dir
2292 if (QFile::exists(asf)) {
2293 KisUsageLogger::log(QString("Removing autosave file: %1").arg(asf));
2294 QFile::remove(asf);
2295 }
2296 asf = generateAutoSaveFileName(QString()); // and the one in $HOME
2297
2298 if (QFile::exists(asf)) {
2299 KisUsageLogger::log(QString("Removing autosave file: %1").arg(asf));
2300 QFile::remove(asf);
2301 }
2302
2303 QList<QRegularExpression> expressions;
2304
2305 expressions << QRegularExpression("^\\..+-autosave.kra$")
2306 << QRegularExpression("^.+-autosave.kra$");
2307
2308 Q_FOREACH(const QRegularExpression &rex, expressions) {
2309 if (wasRecovered &&
2310 !autosaveBaseName.isEmpty() &&
2311 rex.match(QFileInfo(autosaveBaseName).fileName()).hasMatch() &&
2312 QFile::exists(autosaveBaseName)) {
2313
2314 KisUsageLogger::log(QString("Removing autosave file: %1").arg(autosaveBaseName));
2315 QFile::remove(autosaveBaseName);
2316 }
2317 }
2318}

References generateAutoSaveFileName(), and KisUsageLogger::log().

◆ resetPath()

void KisDocument::resetPath ( )

Sets the document Path to empty Path After using loadNativeFormat on a template, one wants to set the path to QString()

Definition at line 2551 of file KisDocument.cpp.

2551 {
2552 setPath(QString());
2553 setLocalFilePath(QString());
2554}

References setLocalFilePath(), and setPath().

◆ resourceSavingFilter()

bool KisDocument::resourceSavingFilter ( const QString & path,
const QByteArray & mimeType,
KisPropertiesConfigurationSP exportConfiguration )
private

Checks whether we are saving a resource we've been editing, and if so, uses the resource server to update the resource.

Returns
true if this was a resource, false if the document needs to be saved

Definition at line 1577 of file KisDocument.cpp.

1578{
1579 if (QFileInfo(path).absolutePath().startsWith(KisResourceLocator::instance()->resourceLocationBase())) {
1580
1581 QStringList pathParts = QFileInfo(path).absolutePath().split('/');
1582 if (pathParts.size() > 0) {
1583 QString resourceType = pathParts.last();
1584 if (KisResourceLoaderRegistry::instance()->resourceTypes().contains(resourceType)) {
1585
1586 KisResourceModel model(resourceType);
1587 model.setResourceFilter(KisResourceModel::ShowAllResources);
1588
1589 QString tempFileName = QDir::tempPath() + "/" + QFileInfo(path).fileName();
1590
1591 if (QFileInfo(path).exists()) {
1592
1593 int outResourceId;
1594 KoResourceSP res;
1595 if (KisResourceCacheDb::getResourceIdFromVersionedFilename(QFileInfo(path).fileName(), resourceType, "", outResourceId)) {
1596 res = model.resourceForId(outResourceId);
1597 }
1598
1599 if (res) {
1600 d->modifiedWhileSaving = false;
1601
1602 if (!exportConfiguration) {
1603 QScopedPointer<KisImportExportFilter> filter(
1605 if (filter) {
1606 exportConfiguration = filter->defaultConfiguration(nativeFormatMimeType(), mimeType);
1607 }
1608 }
1609
1610 if (exportConfiguration) {
1611 // make sure the name of the resource doesn't change
1612 exportConfiguration->setProperty("name", res->name());
1613 }
1614
1615 if (exportDocumentSync(tempFileName, mimeType, exportConfiguration)) {
1616 QFile f2(tempFileName);
1617 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(f2.open(QFile::ReadOnly), false);
1618
1619 QByteArray ba = f2.readAll();
1620
1621 QBuffer buf(&ba);
1622 buf.open(QBuffer::ReadOnly);
1623
1624
1625
1626 if (res->loadFromDevice(&buf, KisGlobalResourcesInterface::instance())) {
1627 if (model.updateResource(res)) {
1628 const QString filePath =
1630
1631 d->updateDocumentMetadataOnSaving(filePath, mimeType);
1632
1633 return true;
1634 }
1635 }
1636 }
1637 }
1638 }
1639 else {
1640 d->modifiedWhileSaving = false;
1641 if (exportDocumentSync(tempFileName, mimeType, exportConfiguration)) {
1642 KoResourceSP res = model.importResourceFile(tempFileName, false);
1643 if (res) {
1644 const QString filePath =
1646
1647 d->updateDocumentMetadataOnSaving(filePath, mimeType);
1648
1649 return true;
1650 }
1651 }
1652 }
1653 }
1654 }
1655 }
1656 return false;
1657}
static KisImportExportFilter * filterForMimeType(const QString &mimetype, Direction direction)
filterForMimeType loads the relevant import/export plugin and returns it. The caller is responsible f...
static bool getResourceIdFromVersionedFilename(QString filename, QString resourceType, QString storageLocation, int &outResourceId)
Note that here you can put even the original filename - any filename from the versioned_resources - a...
QString filePathForResource(KoResourceSP resource)
The KisResourceModel class provides the main access to resources. It is possible to filter the resour...
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References d, KisImportExportManager::Export, exportDocumentSync(), KisResourceLocator::filePathForResource(), KisImportExportManager::filterForMimeType(), KisResourceCacheDb::getResourceIdFromVersionedFilename(), KisResourceModel::importResourceFile(), KisGlobalResourcesInterface::instance(), KisResourceLoaderRegistry::instance(), KisResourceLocator::instance(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, mimeType, nativeFormatMimeType(), KisResourceModel::resourceForId(), KisResourceModel::setResourceFilter(), KisAbstractResourceFilterInterface::ShowAllResources, and KisResourceModel::updateResource().

◆ save()

bool KisDocument::save ( bool showWarnings,
KisPropertiesConfigurationSP exportConfiguration )

Definition at line 977 of file KisDocument.cpp.

978{
979 return saveAs(path(), mimeType(), showWarnings, exportConfiguration);
980}
bool saveAs(const QString &path, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration=0)

References mimeType, path(), and saveAs().

◆ saveAs()

bool KisDocument::saveAs ( const QString & path,
const QByteArray & mimeType,
bool showWarnings,
KisPropertiesConfigurationSP exportConfiguration = 0 )

Definition at line 953 of file KisDocument.cpp.

954{
955 using namespace KritaUtils;
956
957 KisUsageLogger::log(QString("Saving Document %9 as %1 (mime: %2). %3 * %4 pixels, %5 layers. %6 frames, "
958 "%7 framerate. Export configuration: %8")
959 .arg(_path, QString::fromLatin1(mimeType), QString::number(d->image->width()),
960 QString::number(d->image->height()), QString::number(d->image->nlayers()),
961 QString::number(d->image->animationInterface()->totalLength()),
962 QString::number(d->image->animationInterface()->framerate()),
963 (exportConfiguration ? exportConfiguration->toXML() : "No configuration"),
964 path()));
965
966 // Check whether it's an existing resource were are saving to
967 if (resourceSavingFilter(_path, mimeType, exportConfiguration)) {
968 return true;
969 }
970
972 mimeType,
973 showWarnings ? SaveShowWarnings : SaveNone),
974 exportConfiguration);
975}
bool resourceSavingFilter(const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration)

References d, exportDocumentImpl(), KisUsageLogger::log(), mimeType, path(), and resourceSavingFilter().

◆ savingImage()

KisImageSP KisDocument::savingImage ( ) const

savingImage provides a detached, shallow copy of the original image that must be used when saving. Any strokes in progress will not be applied to this image, so the result might be missing some data. On the other hand, it won't block.

Returns
a shallow copy of the original image, or 0 is saving is not in progress

◆ serializeToNativeByteArray()

QByteArray KisDocument::serializeToNativeByteArray ( )

serializeToNativeByteArray daves the document into a .kra file written to a memory-based byte-array

Returns
a byte array containing the .kra file

Definition at line 982 of file KisDocument.cpp.

983{
984 QBuffer buffer;
985
987 filter->setBatchMode(true);
988 filter->setMimeType(nativeFormatMimeType());
989
990 Private::StrippedSafeSavingLocker locker(&d->savingMutex, d->image);
991 if (!locker.successfullyLocked()) {
992 return buffer.data();
993 }
994
995 d->savingImage = d->image;
996
997 if (!filter->convert(this, &buffer).isOk()) {
998 qWarning() << "serializeToByteArray():: Could not export to our native format";
999 }
1000
1001 return buffer.data();
1002}

References d, KisImportExportManager::Export, KisImportExportManager::filterForMimeType(), and nativeFormatMimeType().

◆ setAssistants()

void KisDocument::setAssistants ( const QList< KisPaintingAssistantSP > & value)

@replace the current list of assistants with

Parameters
value

Definition at line 2800 of file KisDocument.cpp.

2801{
2802 if (d->assistants != value) {
2803 d->assistants = value;
2804 d->syncDecorationsWrapperLayerState();
2805 Q_EMIT sigAssistantsChanged();
2806 }
2807}
float value(const T *src, size_t ch)
void sigAssistantsChanged()

References d, sigAssistantsChanged(), and value().

◆ setAssistantsGlobalColor()

void KisDocument::setAssistantsGlobalColor ( QColor color)

Definition at line 2942 of file KisDocument.cpp.

2943{
2944 d->globalAssistantsColor = color;
2945}

References d.

◆ setAudioTracks()

void KisDocument::setAudioTracks ( QVector< QFileInfo > f)

Definition at line 2498 of file KisDocument.cpp.

2499{
2500 d->audioTracks = f;
2501 Q_EMIT sigAudioTracksChanged();
2502}
void sigAudioTracksChanged()

References d, and sigAudioTracksChanged().

◆ setAudioVolume()

void KisDocument::setAudioVolume ( qreal level)

Definition at line 2504 of file KisDocument.cpp.

2505{
2506 d->audioLevel = level;
2507 Q_EMIT sigAudioLevelChanged(level);
2508}
void sigAudioLevelChanged(qreal level)

References d, and sigAudioLevelChanged().

◆ setAutoSaveActive()

void KisDocument::setAutoSaveActive ( bool autoSaveIsActive)

Allow to activate or deactivate autosave on document, independently of auto save delay

the value is independent of auto save delay

Definition at line 1802 of file KisDocument.cpp.

1803{
1804 const bool changed = autoSaveActive != d->autoSaveActive;
1805
1806 if (changed) {
1807 d->autoSaveActive = autoSaveActive;
1809 }
1810}
void setNormalAutoSaveInterval()

References autoSaveActive, d, and setNormalAutoSaveInterval().

◆ setAutoSaveDelay()

void KisDocument::setAutoSaveDelay ( int delay)
private

Activate/deactivate/configure the autosave feature.

Parameters
delayin seconds, 0 to disable

Definition at line 1812 of file KisDocument.cpp.

1813{
1814 if (isReadWrite() && delay > 0 && d->autoSaveActive) {
1815 d->autoSaveTimer->start(delay * 1000);
1816 } else {
1817 d->autoSaveTimer->stop();
1818 }
1819}

References d, and isReadWrite().

◆ setColorHistoryColors()

void KisDocument::setColorHistoryColors ( const QList< KoColor > & colors)

Replaces the per-document history of the last-used colors, from the newest to oldest.

The actual values are stored in the model returned by colorHistoryModel()

Definition at line 2965 of file KisDocument.cpp.

2966{
2967 d->colorHistoryModel.setColorList(colors);
2968}

References d.

◆ setCurrentImage()

void KisDocument::setCurrentImage ( KisImageSP image,
bool forceInitialUpdate = true,
KisNodeSP preActivatedNode = nullptr )

Set the current image to the specified image and turn undo on.

Definition at line 2874 of file KisDocument.cpp.

2875{
2876 if (d->image) {
2877 // Disconnect existing sig/slot connections
2878 d->image->setUndoStore(new KisDumbUndoStore());
2879 d->image->disconnect(this);
2880 d->shapeController->setImage(0);
2881 d->image = 0;
2882 }
2883
2884 if (!image) return;
2885
2886 if (d->linkedResourceStorage){
2887 d->linkedResourceStorage->setMetaData(KisResourceStorage::s_meta_name, image->objectName());
2888 }
2889
2890 d->setImageAndInitIdleWatcher(image);
2891 d->image->setUndoStore(new KisDocumentUndoStore(this));
2892 d->shapeController->setImage(image, preActivatedNode);
2893 d->image->setMirrorAxesCenter(KisAlgebra2D::absoluteToRelative(d->mirrorAxisConfig.axisPosition(), image->bounds()));
2894 setModified(false);
2895 connect(d->image, SIGNAL(sigImageModified()), this, SLOT(setImageModified()), Qt::UniqueConnection);
2896 connect(d->image, SIGNAL(sigImageModifiedWithoutUndo()), this, SLOT(setImageModifiedWithoutUndo()), Qt::UniqueConnection);
2897 connect(d->image, SIGNAL(sigLayersChangedAsync()), this, SLOT(slotImageRootChanged()));
2898
2899 if (forceInitialUpdate) {
2900 d->image->initialRefreshGraph();
2901 }
2902}
void slotImageRootChanged()
The KisDumbUndoStore class doesn't actually save commands, so you cannot undo or redo!
static const QString s_meta_name
QPointF absoluteToRelative(const QPointF &pt, const QRectF &rc)

References KisAlgebra2D::absoluteToRelative(), KisImage::bounds(), d, image, preActivatedNode, KisResourceStorage::s_meta_name, setImageModified(), setImageModifiedWithoutUndo(), setModified(), and slotImageRootChanged().

◆ setEmergencyAutoSaveInterval()

void KisDocument::setEmergencyAutoSaveInterval ( )

Set emergency interval that autosave uses when the image is busy, by default it is 10 sec

Definition at line 1827 of file KisDocument.cpp.

1828{
1829 const int emergencyAutoSaveInterval = 10; /* sec */
1830 setAutoSaveDelay(emergencyAutoSaveInterval);
1831 d->autoSaveFailureCount++;
1832}
void setAutoSaveDelay(int delay)

References d, and setAutoSaveDelay().

◆ setEmpty()

void KisDocument::setEmpty ( bool empty = true)

Sets the document to empty.

Used after loading a template (which is not empty, but not the user's input).

See also
isEmpty()

◆ setErrorMessage()

void KisDocument::setErrorMessage ( const QString & errMsg)

Sets the error message to be shown to the user (use i18n()!) when loading or saving fails. If you asked the user about something and they chose "Cancel",

Definition at line 2267 of file KisDocument.cpp.

2268{
2269 d->lastErrorMessage = errMsg;
2270}

References d.

◆ setFileBatchMode()

void KisDocument::setFileBatchMode ( const bool batchMode)
Parameters
batchModeif true, do not show the option dialog for file operations.

Definition at line 1150 of file KisDocument.cpp.

1151{
1152 d->batchMode = batchMode;
1153}

References batchMode, and d.

◆ setGridConfig()

void KisDocument::setGridConfig ( const KisGridConfig & config)

Definition at line 2383 of file KisDocument.cpp.

2384{
2385 if (d->gridConfig != config) {
2386 d->gridConfig = config;
2387 d->syncDecorationsWrapperLayerState();
2388 Q_EMIT sigGridConfigChanged(config);
2389
2390 // Store last assigned value as future default...
2391 KisConfig cfg(false);
2392 cfg.setDefaultGridSpacing(config.spacing());
2393 }
2394}
void sigGridConfigChanged(const KisGridConfig &config)
QPoint spacing() const

References d, KisConfig::setDefaultGridSpacing(), sigGridConfigChanged(), and KisGridConfig::spacing().

◆ setGuidesConfig()

void KisDocument::setGuidesConfig ( const KisGuidesConfig & data)

Definition at line 2520 of file KisDocument.cpp.

2521{
2522 if (d->guidesConfig == data) return;
2523
2524 d->guidesConfig = data;
2525 d->syncDecorationsWrapperLayerState();
2526 Q_EMIT sigGuidesConfigChanged(d->guidesConfig);
2527}
void sigGuidesConfigChanged(const KisGuidesConfig &config)

References d, and sigGuidesConfigChanged().

◆ setImageAndInitIdleWatcher()

void KisDocument::setImageAndInitIdleWatcher ( KisImageSP _image)
inline

Definition at line 431 of file KisDocument.cpp.

431 {
432 image = _image;
433
435 }
void setTrackedImage(KisImageSP image)

References KisIdleWatcher::setTrackedImage().

◆ setImageModified

void KisDocument::setImageModified ( )
privateslot

Definition at line 2914 of file KisDocument.cpp.

2915{
2916 // we only set as modified if undo stack is not at clean state
2917 setModified(d->imageModifiedWithoutUndo || !d->undoStack->isClean());
2918}

References d, and setModified().

◆ setImageModifiedWithoutUndo

void KisDocument::setImageModifiedWithoutUndo ( )
privateslot

Definition at line 2920 of file KisDocument.cpp.

2921{
2922 d->imageModifiedWithoutUndo = true;
2924}

References d, and setImageModified().

◆ setInfiniteAutoSaveInterval()

void KisDocument::setInfiniteAutoSaveInterval ( )

Disable autosave

Definition at line 1834 of file KisDocument.cpp.

1835{
1836 setAutoSaveDelay(-1);
1837}

References setAutoSaveDelay().

◆ setLocalFilePath()

void KisDocument::setLocalFilePath ( const QString & localFilePath)

Definition at line 2612 of file KisDocument.cpp.

2613{
2614 d->m_file = localFilePath;
2615}

References d, and localFilePath().

◆ setMimeType()

void KisDocument::setMimeType ( const QByteArray & mimeType)

Sets the mime type for the document.

When choosing "save as" this is also the mime type selected by default.

Definition at line 1140 of file KisDocument.cpp.

1141{
1142 d->mimeType = mimeType;
1143}

References d, and mimeType.

◆ setMimeTypeAfterLoading()

void KisDocument::setMimeTypeAfterLoading ( const QString & mimeType)

Definition at line 2131 of file KisDocument.cpp.

2132{
2133 d->mimeType = mimeType.toLatin1();
2134 d->outputMimeType = d->mimeType;
2135}

References d, and mimeType.

◆ setMirrorAxisConfig()

void KisDocument::setMirrorAxisConfig ( const KisMirrorAxisConfig & config)

Definition at line 2535 of file KisDocument.cpp.

2536{
2537 if (d->mirrorAxisConfig == config) {
2538 return;
2539 }
2540
2541 d->mirrorAxisConfig = config;
2542 if (d->image) {
2543 d->image->setMirrorAxesCenter(KisAlgebra2D::absoluteToRelative(d->mirrorAxisConfig.axisPosition(),
2544 d->image->bounds()));
2545 }
2546 setModified(true);
2547
2549}
void sigMirrorAxisConfigChanged()

References KisAlgebra2D::absoluteToRelative(), d, setModified(), and sigMirrorAxisConfigChanged().

◆ setModified()

void KisDocument::setModified ( bool _mod)

Sets the modified flag on the document. This means that it has to be saved or not before deleting it.

1) Ignore setModified calls due to autosaving 2) When closing a document, QUndoStack emits a lot of modified signals, when clearing itself, so we should ignore all of them.

Definition at line 2143 of file KisDocument.cpp.

2144{
2145 if (mod) {
2146 updateEditingTime(false);
2147 }
2148
2153 if (d->isAutosaving || d->documentIsClosing)
2154 return;
2155
2156 //dbgUI<<" url:" << url.path();
2157 //dbgUI<<" mod="<<mod<<" MParts mod="<<KisParts::ReadWritePart::isModified()<<" isModified="<<isModified();
2158
2159 if (mod && !d->autoSaveTimer->isActive()) {
2160 // First change since last autosave -> start the autosave timer
2162 }
2163 d->modifiedAfterAutosave = mod;
2164 d->modifiedWhileSaving = mod;
2165
2166 if (!mod) {
2167 d->imageModifiedWithoutUndo = mod;
2168 }
2169
2170 if (mod == isModified())
2171 return;
2172
2173 d->modified = mod;
2174
2175 if (mod) {
2177 }
2178
2179 Q_EMIT modified(mod);
2180}
void updateEditingTime(bool forceStoreElapsed)
KoColorSpaceMathsTraits< T >::compositetype mod(T a, T b)

References d, documentInfo(), isModified(), modified, setNormalAutoSaveInterval(), updateEditingTime(), and KoDocumentInfo::updateParameters().

◆ setNormalAutoSaveInterval()

void KisDocument::setNormalAutoSaveInterval ( )

Set standard autosave interval that is set by a config file

Definition at line 1821 of file KisDocument.cpp.

1822{
1823 setAutoSaveDelay(d->autoSaveDelay);
1824 d->autoSaveFailureCount = 0;
1825}

References d, and setAutoSaveDelay().

◆ setPaletteList()

void KisDocument::setPaletteList ( const QList< KoColorSetSP > & paletteList,
bool emitSignal = false )

setPaletteList replaces the palettes in the document's local resource storage with the list of palettes passed to this function. It will then Q_EMIT sigPaletteListChanged with both the old and the new list, if emitSignal is true.

Definition at line 2433 of file KisDocument.cpp.

2434{
2435 QList<KoColorSetSP> oldPaletteList;
2436 if (d->linkedResourceStorage) {
2437 QSharedPointer<KisResourceStorage::ResourceIterator> iter = d->linkedResourceStorage->resources(ResourceType::Palettes);
2438 while (iter->hasNext()) {
2439 iter->next();
2440 KoResourceSP resource = iter->resource();
2441 if (resource && resource->valid()) {
2442 oldPaletteList << resource.dynamicCast<KoColorSet>();
2443 }
2444 }
2445 if (oldPaletteList != paletteList) {
2447 Q_FOREACH(KoColorSetSP palette, oldPaletteList) {
2448 if (!paletteList.contains(palette)) {
2449 resourceModel.setResourceInactive(resourceModel.indexForResource(palette));
2450 }
2451 }
2452 Q_FOREACH(KoColorSetSP palette, paletteList) {
2453 if (!oldPaletteList.contains(palette)) {
2454 resourceModel.addResource(palette, d->linkedResourcesStorageID);
2455 }
2456 else {
2457 palette->setStorageLocation(d->linkedResourcesStorageID);
2458 resourceModel.updateResource(palette);
2459 }
2460 }
2461 if (emitSignal) {
2462 Q_EMIT sigPaletteListChanged(oldPaletteList, paletteList);
2463 }
2464 }
2465 }
2466}
void sigPaletteListChanged(const QList< KoColorSetSP > &oldPaletteList, const QList< KoColorSetSP > &newPaletteList)
const QString Palettes
rgba palette[MAX_PALETTE]
Definition palette.c:35

References KisResourceModel::addResource(), d, KisResourceModel::indexForResource(), palette, ResourceType::Palettes, KisAbstractResourceModel::setResourceInactive(), sigPaletteListChanged(), and KisResourceModel::updateResource().

◆ setPath()

void KisDocument::setPath ( const QString & path)

Definition at line 2595 of file KisDocument.cpp.

2596{
2597 const bool changed = path != d->m_path;
2598
2599 d->m_path = path;
2600
2601 if (changed) {
2602 Q_EMIT sigPathChanged(path);
2603 }
2604}
void sigPathChanged(const QString &path)

References d, path(), and sigPathChanged().

◆ setPreActivatedNode()

void KisDocument::setPreActivatedNode ( KisNodeSP activatedNode)

Set the list of nodes that was marked as currently active. Used only for saving loading. Never use it for tools or processing.

Definition at line 2853 of file KisDocument.cpp.

2854{
2855 d->preActivatedNode = activatedNode;
2856}

References d.

◆ setReadWrite()

void KisDocument::setReadWrite ( bool readwrite = true)

Sets whether the document can be edited or is read only.

This recursively applied to all child documents and KisView::updateReadWrite is called for every attached view.

Definition at line 1791 of file KisDocument.cpp.

1792{
1793 const bool changed = readwrite != d->readwrite;
1794
1795 d->readwrite = readwrite;
1796
1797 if (changed) {
1799 }
1800}
void sigReadWriteChanged(bool value)

References d, readwrite, and sigReadWriteChanged().

◆ setRecovered()

void KisDocument::setRecovered ( bool value)

Definition at line 2182 of file KisDocument.cpp.

2183{
2184 const bool changed = value != d->isRecovered;
2185
2186 d->isRecovered = value;
2187
2188 if (changed) {
2189 Q_EMIT sigRecoveredChanged(value);
2190 }
2191}
void sigRecoveredChanged(bool value)

References d, sigRecoveredChanged(), and value().

◆ setReferenceImagesLayer()

void KisDocument::setReferenceImagesLayer ( KisSharedPtr< KisReferenceImagesLayer > layer,
bool updateImage )

Definition at line 2819 of file KisDocument.cpp.

2820{
2821 KisReferenceImagesLayerSP currentReferenceLayer = referenceImagesLayer();
2822
2823 // updateImage=false inherently means we are not changing the
2824 // reference images layer, but just would like to update its signals.
2825 if (currentReferenceLayer == layer && updateImage) {
2826 return;
2827 }
2828
2829 d->referenceLayerConnections.clear();
2830
2831 if (updateImage) {
2832 if (currentReferenceLayer) {
2833 d->image->removeNode(currentReferenceLayer);
2834 }
2835
2836 if (layer) {
2837 d->image->addNode(layer);
2838 }
2839 }
2840
2841 currentReferenceLayer = layer;
2842
2843 if (currentReferenceLayer) {
2844 d->referenceLayerConnections.addConnection(
2845 currentReferenceLayer, SIGNAL(sigUpdateCanvas(QRectF)),
2846 this, SIGNAL(sigReferenceImagesChanged()));
2847 }
2848
2849 Q_EMIT sigReferenceImagesLayerChanged(layer);
2851}

References d, referenceImagesLayer(), sigReferenceImagesChanged(), and sigReferenceImagesLayerChanged().

◆ setStoryboardCommentList()

void KisDocument::setStoryboardCommentList ( const QVector< StoryboardComment > & storyboardCommentList,
bool emitSignal = false )

sets the list of comments for the storyboard docker in the document, emits empty signal if emitSignal is true.

Definition at line 2486 of file KisDocument.cpp.

2487{
2488 d->m_storyboardCommentList = storyboardCommentList;
2489 if (emitSignal) {
2491 }
2492}
void sigStoryboardCommentListChanged()

References d, and sigStoryboardCommentListChanged().

◆ setStoryboardItemList()

void KisDocument::setStoryboardItemList ( const StoryboardItemList & storyboardItemList,
bool emitSignal = false )

sets the storyboardItemList in the document, emits empty signal if emitSignal is true.

Definition at line 2473 of file KisDocument.cpp.

2474{
2475 d->m_storyboardItemList = storyboardItemList;
2476 if (emitSignal) {
2478 }
2479}
void sigStoryboardItemListChanged()

References d, and sigStoryboardItemListChanged().

◆ setUnit()

void KisDocument::setUnit ( const KoUnit & unit)

Sets the unit used to display all measures/distances.

Definition at line 2325 of file KisDocument.cpp.

2326{
2327 if (d->unit != unit) {
2328 d->unit = unit;
2329 Q_EMIT unitChanged(unit);
2330 }
2331}
void unitChanged(const KoUnit &unit)

References d, unit, and unitChanged().

◆ setWarningMessage()

void KisDocument::setWarningMessage ( const QString & warningMsg)

Sets the warning message to be shown to the user (use i18n()!) when loading or saving fails.

Definition at line 2277 of file KisDocument.cpp.

2278{
2279 d->lastWarningMessage = warningMsg;
2280}

References d.

◆ shapeController()

KoShapeControllerBase * KisDocument::shapeController ( ) const

The shape controller matches internal krita image layers with the flake shape hierarchy.

◆ shapeForNode()

KoShapeLayer * KisDocument::shapeForNode ( KisNodeSP layer) const

Definition at line 2790 of file KisDocument.cpp.

2791{
2792 return d->shapeController->shapeForNode(layer);
2793}

References d.

◆ sigAssistantsChanged

void KisDocument::sigAssistantsChanged ( )
signal

◆ sigAudioLevelChanged

void KisDocument::sigAudioLevelChanged ( qreal level)
signal

◆ sigAudioTracksChanged

void KisDocument::sigAudioTracksChanged ( )
signal

◆ sigBackgroundSavingFinished

void KisDocument::sigBackgroundSavingFinished ( KisImportExportErrorCode status,
const QString & errorMessage,
const QString & warningMessage )
signal

◆ sigCompleteBackgroundSaving

void KisDocument::sigCompleteBackgroundSaving ( const KritaUtils::ExportFileJob & job,
KisImportExportErrorCode status,
const QString & errorMessage,
const QString & warningMessage )
signal

◆ sigGridConfigChanged

void KisDocument::sigGridConfigChanged ( const KisGridConfig & config)
signal

◆ sigGuidesConfigChanged

void KisDocument::sigGuidesConfigChanged ( const KisGuidesConfig & config)
signal

◆ sigLoadingFinished

void KisDocument::sigLoadingFinished ( )
signal

◆ sigMirrorAxisConfigChanged

void KisDocument::sigMirrorAxisConfigChanged ( )
signal

◆ sigPaletteListChanged

void KisDocument::sigPaletteListChanged ( const QList< KoColorSetSP > & oldPaletteList,
const QList< KoColorSetSP > & newPaletteList )
signal

Emitted when the palette list has changed. The pointers in oldPaletteList are to be deleted by the resource server.

◆ sigPathChanged

void KisDocument::sigPathChanged ( const QString & path)
signal

◆ sigReadWriteChanged

void KisDocument::sigReadWriteChanged ( bool value)
signal

◆ sigRecoveredChanged

void KisDocument::sigRecoveredChanged ( bool value)
signal

◆ sigReferenceImagesChanged

void KisDocument::sigReferenceImagesChanged ( )
signal

◆ sigReferenceImagesLayerChanged

void KisDocument::sigReferenceImagesLayerChanged ( KisSharedPtr< KisReferenceImagesLayer > layer)
signal

◆ sigSavingFinished

void KisDocument::sigSavingFinished ( const QString & filePath)
signal

◆ sigStoryboardCommentListChanged

void KisDocument::sigStoryboardCommentListChanged ( )
signal

◆ sigStoryboardItemListChanged

void KisDocument::sigStoryboardItemListChanged ( )
signal

◆ slotAutoSave

void KisDocument::slotAutoSave ( )
privateslot

Definition at line 1659 of file KisDocument.cpp.

1660{
1661 slotAutoSaveImpl(std::unique_ptr<KisDocument>());
1662}
void slotAutoSaveImpl(std::unique_ptr< KisDocument > &&optionalClonedDocument)

References slotAutoSaveImpl().

◆ slotAutoSaveImpl()

void KisDocument::slotAutoSaveImpl ( std::unique_ptr< KisDocument > && optionalClonedDocument)
private

Definition at line 1534 of file KisDocument.cpp.

1535{
1536 if (!d->modified || !d->modifiedAfterAutosave) return;
1537 const QString autoSaveFileName = generateAutoSaveFileName(localFilePath());
1538
1539 Q_EMIT statusBarMessage(i18n("Autosaving... %1", autoSaveFileName), successMessageTimeout);
1540
1541 KisUsageLogger::log(QString("Autosaving: %1").arg(autoSaveFileName));
1542
1543 const bool hadClonedDocument = bool(optionalClonedDocument);
1545
1546 if (d->image->isIdle() || hadClonedDocument) {
1547 result = initiateSavingInBackground(i18n("Autosaving..."),
1550 0,
1551 std::move(optionalClonedDocument));
1552 } else {
1553 Q_EMIT statusBarMessage(i18n("Autosaving postponed: document is busy..."), errorMessageTimeout);
1554 }
1555
1556 if (result != KritaUtils::BackgroudSavingStartResult::Success && !hadClonedDocument && d->autoSaveFailureCount >= 3) {
1558 connect(stroke, SIGNAL(sigDocumentCloned(KisDocument*)),
1560 Qt::BlockingQueuedConnection);
1561 connect(stroke, SIGNAL(sigCloningCancelled()),
1562 this, SLOT(slotDocumentCloningCancelled()),
1563 Qt::BlockingQueuedConnection);
1564
1565 KisStrokeId strokeId = d->image->startStroke(stroke);
1566 d->image->endStroke(strokeId);
1567
1569
1572 } else {
1573 d->modifiedAfterAutosave = false;
1574 }
1575}
void slotInitiateAsyncAutosaving(KisDocument *clonedDocument)
void setEmergencyAutoSaveInterval()
void statusBarMessage(const QString &text, int timeout=0)
void slotDocumentCloningCancelled()
void slotCompleteAutoSaving(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
void setInfiniteAutoSaveInterval()

References d, KritaUtils::Failure, generateAutoSaveFileName(), initiateSavingInBackground(), localFilePath(), KisUsageLogger::log(), nativeFormatMimeType(), KritaUtils::SaveInAutosaveMode, KritaUtils::SaveIsExporting, setEmergencyAutoSaveInterval(), setInfiniteAutoSaveInterval(), slotCompleteAutoSaving(), slotDocumentCloningCancelled(), slotInitiateAsyncAutosaving(), statusBarMessage(), and KritaUtils::Success.

◆ slotChildCompletedSavingInBackground

void KisDocument::slotChildCompletedSavingInBackground ( KisImportExportErrorCode status,
const QString & errorMessage,
const QString & warningMessage )
privateslot

Take back the ownership of the saving mutex and make sure it well be released whatever the result of executing this function will be, even if it asserts.

Definition at line 1494 of file KisDocument.cpp.

1495{
1497
1503 std::unique_lock<QMutex> savingMutexLock(d->savingMutex, std::adopt_lock);
1504
1505 KIS_ASSERT_RECOVER_RETURN(d->backgroundSaveDocument);
1506
1507 if (d->backgroundSaveJob.flags & KritaUtils::SaveInAutosaveMode) {
1508 d->backgroundSaveDocument->d->isAutosaving = false;
1509 }
1510
1511 d->backgroundSaveDocument.release()->deleteLater();
1512
1513 KIS_ASSERT_RECOVER_RETURN(d->backgroundSaveJob.isValid());
1514
1515 const KritaUtils::ExportFileJob job = d->backgroundSaveJob;
1516 d->backgroundSaveJob = KritaUtils::ExportFileJob();
1517
1518 // unlock at the very end
1519 savingMutexLock.unlock();
1520
1521 QFileInfo fi(job.filePath);
1522 KisUsageLogger::log(QString("Completed saving %1 (mime: %2). Result: %3. Warning: %4. Size: %5")
1523 .arg(job.filePath, QString::fromLatin1(job.mimeType),
1524 (!status.isOk() ? errorMessage : "OK"), warningMessage,
1525 QString::number(fi.size())));
1526
1528 // One-shot: disconnect immediately after firing so future save completions
1529 // don't invoke a stale or unrelated slot.
1530 disconnect(d->completeSavingConnection);
1531 d->completeSavingConnection = {};
1532}
bool isSaving() const
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75

References d, errorMessage(), KritaUtils::ExportFileJob::filePath, KisImportExportErrorCode::isOk(), isSaving(), KIS_ASSERT_RECOVER_RETURN, KisUsageLogger::log(), KritaUtils::ExportFileJob::mimeType, KritaUtils::SaveInAutosaveMode, sigCompleteBackgroundSaving(), and warningMessage().

◆ slotCompleteAutoSaving

void KisDocument::slotCompleteAutoSaving ( const KritaUtils::ExportFileJob & job,
KisImportExportErrorCode status,
const QString & errorMessage,
const QString & warningMessage )
privateslot

Definition at line 1686 of file KisDocument.cpp.

1687{
1688 Q_UNUSED(job);
1689 Q_UNUSED(warningMessage);
1690
1691 const QString fileName = QFileInfo(job.filePath).fileName();
1692
1693 if (!status.isOk()) {
1695 Q_EMIT statusBarMessage(i18nc("%1 --- failing file name, %2 --- error message",
1696 "Error during autosaving %1: %2",
1697 fileName,
1698 exportErrorToUserMessage(status, errorMessage)), errorMessageTimeout);
1699 } else {
1700 KisConfig cfg(true);
1701 d->autoSaveDelay = cfg.autoSaveInterval();
1702
1703 if (!d->modifiedWhileSaving) {
1704 d->autoSaveTimer->stop(); // until the next change
1705 d->autoSaveFailureCount = 0;
1706 } else {
1708 }
1709
1710 Q_EMIT statusBarMessage(i18n("Finished autosaving %1", fileName), successMessageTimeout);
1711 }
1712}
QString exportErrorToUserMessage(KisImportExportErrorCode status, const QString &errorMessage)

References KisConfig::autoSaveInterval(), d, errorMessage(), exportErrorToUserMessage(), KritaUtils::ExportFileJob::filePath, KisImportExportErrorCode::isOk(), setEmergencyAutoSaveInterval(), setNormalAutoSaveInterval(), statusBarMessage(), and warningMessage().

◆ slotCompleteSavingDocument

void KisDocument::slotCompleteSavingDocument ( const KritaUtils::ExportFileJob & job,
KisImportExportErrorCode status,
const QString & errorMessage,
const QString & warningMessage )
privateslot

Definition at line 1042 of file KisDocument.cpp.

1043{
1044 if (status.isCancelled())
1045 return;
1046
1047 const QString fileName = QFileInfo(job.filePath).fileName();
1048
1049 if (!status.isOk()) {
1050 Q_EMIT statusBarMessage(i18nc("%1 --- failing file name, %2 --- error message",
1051 "Error during saving %1: %2",
1052 fileName,
1053 errorMessage), errorMessageTimeout);
1054
1055
1056 if (!fileBatchMode()) {
1057 DlgLoadMessages dlg(i18nc("@title:window", "Krita"),
1058 i18n("Could not save %1.", job.filePath),
1059 errorMessage.split("\n", Qt::SkipEmptyParts)
1060 + warningMessage.split("\n", Qt::SkipEmptyParts),
1061 status.errorMessage());
1062
1063 dlg.exec();
1064 }
1065 }
1066 else {
1067 if (!fileBatchMode() && !warningMessage.isEmpty()) {
1068
1069 QStringList reasons = warningMessage.split("\n", Qt::SkipEmptyParts);
1070
1071 DlgLoadMessages dlg(
1072 i18nc("@title:window", "Krita"),
1073 i18nc("dialog box shown to the user if there were warnings while saving the document, "
1074 "%1 is the file path",
1075 "%1 has been saved but is incomplete.",
1076 job.filePath),
1077 reasons,
1078 reasons.isEmpty()
1079 ? ""
1080 : i18nc("dialog box shown to the user if there were warnings while saving the document",
1081 "Some problems were encountered when saving."));
1082 dlg.exec();
1083 }
1084
1085
1086 if (!(job.flags & KritaUtils::SaveIsExporting)) {
1087 const QString existingAutoSaveBaseName = localFilePath();
1088 const bool wasRecovered = isRecovered();
1089
1090 d->updateDocumentMetadataOnSaving(job.filePath, job.mimeType);
1091
1092 removeAutoSaveFiles(existingAutoSaveBaseName, wasRecovered);
1093 }
1094
1095 Q_EMIT completed();
1096 Q_EMIT sigSavingFinished(job.filePath);
1097
1098 Q_EMIT statusBarMessage(i18n("Finished saving %1", fileName), successMessageTimeout);
1099 }
1100}
void removeAutoSaveFiles(const QString &autosaveBaseName, bool wasRecovered)

References completed(), d, errorMessage(), KisImportExportErrorCode::errorMessage(), fileBatchMode(), KritaUtils::ExportFileJob::filePath, KritaUtils::ExportFileJob::flags, KisImportExportErrorCode::isCancelled(), KisImportExportErrorCode::isOk(), isRecovered, localFilePath(), KritaUtils::ExportFileJob::mimeType, removeAutoSaveFiles(), KritaUtils::SaveIsExporting, sigSavingFinished(), statusBarMessage(), and warningMessage().

◆ slotConfigChanged

void KisDocument::slotConfigChanged ( )
privateslot

Definition at line 2348 of file KisDocument.cpp.

2349{
2350 KisConfig cfg(true);
2351
2352 if (d->undoStack->undoLimit() != cfg.undoStackLimit()) {
2353 if (!d->undoStack->isClean()) {
2354 d->undoStack->clear();
2355 // we set this because the document *has* changed, even though the
2356 // undo history was purged.
2358 }
2359 d->undoStack->setUndoLimit(cfg.undoStackLimit());
2360 }
2361 d->undoStack->setUseCumulativeUndoRedo(cfg.useCumulativeUndoRedo());
2362 d->undoStack->setCumulativeUndoData(cfg.cumulativeUndoData());
2363
2364 d->autoSaveDelay = cfg.autoSaveInterval();
2366}

References KisConfig::autoSaveInterval(), KisConfig::cumulativeUndoData(), d, setImageModifiedWithoutUndo(), setNormalAutoSaveInterval(), KisConfig::undoStackLimit(), and KisConfig::useCumulativeUndoRedo().

◆ slotDocumentCloningCancelled

void KisDocument::slotDocumentCloningCancelled ( )
privateslot

Definition at line 1669 of file KisDocument.cpp.

1670{
1672}

References setEmergencyAutoSaveInterval().

◆ slotImageRootChanged

void KisDocument::slotImageRootChanged ( )
privateslot

Definition at line 2368 of file KisDocument.cpp.

2369{
2370 d->syncDecorationsWrapperLayerState();
2371}

References d.

◆ slotInitiateAsyncAutosaving

void KisDocument::slotInitiateAsyncAutosaving ( KisDocument * clonedDocument)
privateslot

Definition at line 1664 of file KisDocument.cpp.

1665{
1666 slotAutoSaveImpl(std::unique_ptr<KisDocument>(clonedDocument));
1667}

References slotAutoSaveImpl().

◆ slotPerformIdleRoutines

void KisDocument::slotPerformIdleRoutines ( )
privateslot

TODO: automatic purging is disabled for now: it modifies data managers without creating a transaction, which breaks undo.

Definition at line 1674 of file KisDocument.cpp.

1675{
1676 d->image->explicitRegenerateLevelOfDetail();
1677
1678
1682
1683 // d->image->purgeUnusedData(true);
1684}

References d.

◆ slotUndoStackCleanChanged

void KisDocument::slotUndoStackCleanChanged ( bool value)
privateslot

Definition at line 2343 of file KisDocument.cpp.

2344{
2345 setModified(!value || d->imageModifiedWithoutUndo);
2346}

References d, setModified(), and value().

◆ startExportInBackground()

KisImportExportErrorCode KisDocument::startExportInBackground ( const QString & actionName,
const QString & location,
const QString & realLocation,
const QByteArray & mimeType,
bool showWarnings,
KisPropertiesConfigurationSP exportConfiguration,
bool isAdvancedExporting = false )
private

Definition at line 1714 of file KisDocument.cpp.

1720{
1721 d->savingImage = d->image;
1722
1724 if (window) {
1725 if (window->viewManager()) {
1726 d->savingUpdater = window->viewManager()->createThreadedUpdater(actionName);
1727 d->importExportManager->setUpdater(d->savingUpdater);
1728 }
1729 }
1730
1731 KisImportExportErrorCode initializationStatus(ImportExportCodes::OK);
1732 d->childSavingFuture =
1733 d->importExportManager->exportDocumentAsync(location,
1734 realLocation,
1735 mimeType,
1736 initializationStatus,
1737 showWarnings,
1738 exportConfiguration,
1739 isAdvancedExporting);
1740
1741 if (!initializationStatus.isOk()) {
1742 if (d->savingUpdater) {
1743 d->savingUpdater->cancel();
1744 }
1745 d->savingImage.clear();
1746 Q_EMIT sigBackgroundSavingFinished(initializationStatus, initializationStatus.errorMessage(), "");
1747 return initializationStatus;
1748 }
1749
1750 typedef QFutureWatcher<KisImportExportErrorCode> StatusWatcher;
1751 StatusWatcher *watcher = new StatusWatcher();
1752 watcher->setFuture(d->childSavingFuture);
1753
1754 connect(watcher, SIGNAL(finished()), SLOT(finishExportInBackground()));
1755 connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater()));
1756
1757 return initializationStatus;
1758}
void finishExportInBackground()
QPointer< KoUpdater > createThreadedUpdater(const QString &name)

References KisViewManager::createThreadedUpdater(), KisPart::currentMainwindow(), d, KisImportExportErrorCode::errorMessage(), finishExportInBackground(), KisPart::instance(), KisImportExportErrorCode::isOk(), mimeType, ImportExportCodes::OK, sigBackgroundSavingFinished(), and KisMainWindow::viewManager.

◆ statusBarMessage

void KisDocument::statusBarMessage ( const QString & text,
int timeout = 0 )
signal

Emitted e.g. at the beginning of a save operation This is emitted by KisDocument and used by KisView to display a statusbar message

◆ syncDecorationsWrapperLayerState()

void KisDocument::syncDecorationsWrapperLayerState ( )

◆ undoStack()

KUndo2Stack * KisDocument::undoStack ( )

Returns the global undo stack

◆ unit()

KoUnit KisDocument::unit ( ) const

Returns the unit used to display all measures/distances.

◆ unitChanged

void KisDocument::unitChanged ( const KoUnit & unit)
signal

This signal is emitted when the unit is changed by setUnit(). It is common to connect views to it, in order to change the displayed units (e.g. in the rulers)

◆ updateDocumentMetadataOnSaving()

void KisDocument::updateDocumentMetadataOnSaving ( const QString & filePath,
const QByteArray & mimeType )

◆ updateEditingTime()

void KisDocument::updateEditingTime ( bool forceStoreElapsed)

Definition at line 2198 of file KisDocument.cpp.

2199{
2200 QDateTime now = QDateTime::currentDateTime();
2201 int firstModDelta = d->firstMod.secsTo(now);
2202 int lastModDelta = d->lastMod.secsTo(now);
2203
2204 if (lastModDelta > 30) {
2205 d->docInfo->setAboutInfo("editing-time", QString::number(d->docInfo->aboutInfo("editing-time").toInt() + d->firstMod.secsTo(d->lastMod)));
2206 d->firstMod = now;
2207 } else if (firstModDelta > 60 || forceStoreElapsed) {
2208 d->docInfo->setAboutInfo("editing-time", QString::number(d->docInfo->aboutInfo("editing-time").toInt() + firstModDelta));
2209 d->firstMod = now;
2210 }
2211
2212 d->lastMod = now;
2213}

References d.

◆ uploadLinkedResourcesFromLayersToStorage()

void KisDocument::uploadLinkedResourcesFromLayersToStorage ( )

◆ waitForSavingToComplete()

void KisDocument::waitForSavingToComplete ( )

Definition at line 2777 of file KisDocument.cpp.

2778{
2779 if (isSaving()) {
2780 KisAsyncActionFeedback f(i18nc("progress dialog message when the user closes the document that is being saved", "Waiting for saving to complete..."), 0);
2781 f.waitForMutex(d->savingMutex);
2782 }
2783}

References d, and isSaving().

◆ warningMessage()

QString KisDocument::warningMessage ( ) const

Return the last warning message set by loading or saving. Warnings mean that the document could not be completely loaded, but the errors were not absolutely fatal.

Definition at line 2282 of file KisDocument.cpp.

2283{
2284 return d->lastWarningMessage;
2285}

References d.

Friends And Related Symbol Documentation

◆ KisPart

friend class KisPart
friend

Definition at line 532 of file KisDocument.h.

◆ SafeSavingLocker

friend class SafeSavingLocker
friend

Definition at line 533 of file KisDocument.h.

Member Data Documentation

◆ assistants

QList< KisPaintingAssistantSP > KisDocument::assistants

Definition at line 392 of file KisDocument.cpp.

◆ audioLevel

qreal KisDocument::audioLevel = 1.0

Definition at line 398 of file KisDocument.cpp.

◆ audioTracks

QVector<QFileInfo> KisDocument::audioTracks

Definition at line 397 of file KisDocument.cpp.

◆ autoSaveActive

bool KisDocument::autoSaveActive = true

Definition at line 376 of file KisDocument.cpp.

◆ autoSaveDelay

int KisDocument::autoSaveDelay = 300

Definition at line 357 of file KisDocument.cpp.

◆ autoSaveFailureCount

int KisDocument::autoSaveFailureCount = 0

Definition at line 361 of file KisDocument.cpp.

◆ autoSaveTimer

QTimer* KisDocument::autoSaveTimer

Definition at line 353 of file KisDocument.cpp.

◆ backgroundSaveDocument

std::unique_ptr<KisDocument> KisDocument::backgroundSaveDocument

Definition at line 407 of file KisDocument.cpp.

◆ backgroundSaveJob

KritaUtils::ExportFileJob KisDocument::backgroundSaveJob

Definition at line 410 of file KisDocument.cpp.

◆ batchMode

bool KisDocument::batchMode { false }

Definition at line 416 of file KisDocument.cpp.

416{ false };

◆ childSavingFuture

QFuture<KisImportExportErrorCode> KisDocument::childSavingFuture

Definition at line 409 of file KisDocument.cpp.

◆ colorHistoryModel

KisUniqueColorSet * KisDocument::colorHistoryModel

Definition at line 401 of file KisDocument.cpp.

◆ completeSavingConnection

QMetaObject::Connection KisDocument::completeSavingConnection

Definition at line 411 of file KisDocument.cpp.

◆ d

Private* const KisDocument::d
private

Definition at line 765 of file KisDocument.h.

◆ decorationsSyncingDisabled

bool KisDocument::decorationsSyncingDisabled = false

Definition at line 417 of file KisDocument.cpp.

◆ disregardAutosaveFailure

bool KisDocument::disregardAutosaveFailure = false

Definition at line 360 of file KisDocument.cpp.

◆ docInfo

KoDocumentInfo* KisDocument::docInfo = 0

Definition at line 344 of file KisDocument.cpp.

◆ documentIsClosing

bool KisDocument::documentIsClosing = false

Definition at line 419 of file KisDocument.cpp.

◆ embeddedResourcesStorageID

QString KisDocument::embeddedResourcesStorageID

Definition at line 426 of file KisDocument.cpp.

◆ embeddedResourceStorage

KisResourceStorageSP KisDocument::embeddedResourceStorage

Definition at line 427 of file KisDocument.cpp.

◆ firstMod

QDateTime KisDocument::firstMod

Definition at line 378 of file KisDocument.cpp.

◆ globalAssistantsColor

QColor KisDocument::globalAssistantsColor

Definition at line 400 of file KisDocument.cpp.

◆ gridConfig

KisGridConfig KisDocument::gridConfig

Definition at line 403 of file KisDocument.cpp.

◆ guidesConfig

const KisGuidesConfig & KisDocument::guidesConfig

Definition at line 365 of file KisDocument.cpp.

◆ image

KisImageWSP KisDocument::image

Definition at line 383 of file KisDocument.cpp.

◆ imageIdleConnection

QScopedPointer<KisSignalAutoConnection> KisDocument::imageIdleConnection

Definition at line 390 of file KisDocument.cpp.

◆ imageIdleWatcher

KisIdleWatcher KisDocument::imageIdleWatcher

Definition at line 389 of file KisDocument.cpp.

◆ imageModifiedWithoutUndo

bool KisDocument::imageModifiedWithoutUndo = false

Definition at line 405 of file KisDocument.cpp.

◆ importExportManager

KisImportExportManager * KisDocument::importExportManager = 0

Definition at line 348 of file KisDocument.cpp.

◆ isAutosaving

bool KisDocument::isAutosaving = false

Definition at line 359 of file KisDocument.cpp.

◆ isRecovered

bool KisDocument::isRecovered = false

Definition at line 414 of file KisDocument.cpp.

◆ koShapeController

KoShapeController* KisDocument::koShapeController = 0

Definition at line 388 of file KisDocument.cpp.

◆ lastErrorMessage

QString KisDocument::lastErrorMessage

Definition at line 354 of file KisDocument.cpp.

◆ lastMod

QDateTime KisDocument::lastMod

Definition at line 379 of file KisDocument.cpp.

◆ lastWarningMessage

QString KisDocument::lastWarningMessage

Definition at line 355 of file KisDocument.cpp.

◆ linkedResourcesStorageID

QString KisDocument::linkedResourcesStorageID

Definition at line 422 of file KisDocument.cpp.

◆ linkedResourceStorage

KisResourceStorageSP KisDocument::linkedResourceStorage

Definition at line 423 of file KisDocument.cpp.

◆ m_bAutoDetectedMime

bool KisDocument::m_bAutoDetectedMime = false

Definition at line 368 of file KisDocument.cpp.

◆ m_file

QString KisDocument::m_file

Definition at line 370 of file KisDocument.cpp.

◆ m_path

QString KisDocument::m_path

Definition at line 369 of file KisDocument.cpp.

◆ m_storyboardCommentList

QVector<StoryboardComment> KisDocument::m_storyboardCommentList

Definition at line 395 of file KisDocument.cpp.

◆ m_storyboardItemList

StoryboardItemList KisDocument::m_storyboardItemList

Definition at line 394 of file KisDocument.cpp.

◆ mimeType

QByteArray KisDocument::mimeType

Definition at line 350 of file KisDocument.cpp.

◆ mirrorAxisConfig

const KisMirrorAxisConfig & KisDocument::mirrorAxisConfig

Definition at line 366 of file KisDocument.cpp.

◆ modified

bool KisDocument::modified = false

Definition at line 374 of file KisDocument.cpp.

◆ modifiedAfterAutosave

bool KisDocument::modifiedAfterAutosave = false

Definition at line 358 of file KisDocument.cpp.

◆ modifiedWhileSaving

bool KisDocument::modifiedWhileSaving = false

Definition at line 406 of file KisDocument.cpp.

◆ nserver

KisNameServer* KisDocument::nserver

Definition at line 381 of file KisDocument.cpp.

◆ outputMimeType

QByteArray KisDocument::outputMimeType

Definition at line 351 of file KisDocument.cpp.

◆ preActivatedNode

KisNodeSP KisDocument::preActivatedNode

Definition at line 386 of file KisDocument.cpp.

◆ q

KisDocument* KisDocument::q = 0

Definition at line 343 of file KisDocument.cpp.

◆ readwrite

bool KisDocument::readwrite = false

Definition at line 375 of file KisDocument.cpp.

◆ referenceLayerConnections

KisSignalAutoConnectionsStore KisDocument::referenceLayerConnections

Definition at line 412 of file KisDocument.cpp.

◆ savingImage

KisImageSP KisDocument::savingImage

Definition at line 384 of file KisDocument.cpp.

◆ savingMutex

QMutex KisDocument::savingMutex

Definition at line 372 of file KisDocument.cpp.

◆ savingUpdater

QPointer<KoUpdater> KisDocument::savingUpdater

Definition at line 408 of file KisDocument.cpp.

◆ shapeController

KoShapeControllerBase * KisDocument::shapeController = 0

Definition at line 387 of file KisDocument.cpp.

◆ undoStack

KUndo2Stack * KisDocument::undoStack = 0

Definition at line 363 of file KisDocument.cpp.

◆ unit

KoUnit KisDocument::unit

Definition at line 346 of file KisDocument.cpp.

◆ wasStorageAdded

bool KisDocument::wasStorageAdded = false

Definition at line 418 of file KisDocument.cpp.


The documentation for this class was generated from the following files: