45#include <klocalizedstring.h>
50#include <kdesktopfile.h>
51#include <kconfiggroup.h>
55#include <QTextBrowser>
56#include <QApplication>
58#include <QStandardPaths>
60#include <QDomDocument>
68#include <QScopedPointer>
75#include <QFutureWatcher>
133#define STORE_PROTOCOL "tar"
135#define INTERNAL_PROTOCOL "intern"
136#define INTERNAL_PREFIX "intern:/"
148constexpr int errorMessageTimeout = 5000;
149constexpr int successMessageTimeout = 1000;
162 static int s_docIFNumber = 0;
163 QString name; name.setNum(s_docIFNumber++); name.prepend(
"document_");
192 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
210 Q_ASSERT(currentImage);
302 , autoSaveTimer(new QTimer(_q))
304 , m_bAutoDetectedMime(false)
307 , autoSaveActive(true)
308 , firstMod(QDateTime::currentDateTime())
311 , imageIdleWatcher(2000 )
312 , globalAssistantsColor(
KisConfig(true).defaultAssistantsColor())
315 if (QLocale().measurementSystem() == QLocale::ImperialSystem) {
320 connect(&imageIdleWatcher, SIGNAL(startedIdleMode()), q, SLOT(slotPerformIdleRoutines()));
327 , autoSaveTimer(new QTimer(_q))
330 , preActivatedNode(0)
331 , imageIdleWatcher(2000 )
332 , colorHistoryModel(rhs.colorHistoryModel)
334 copyFromImpl(rhs, _q, CONSTRUCT);
335 connect(&imageIdleWatcher, SIGNAL(startedIdleMode()), q, SLOT(slotPerformIdleRoutines()));
357 int autoSaveDelay = 300;
358 bool modifiedAfterAutosave =
false;
359 bool isAutosaving =
false;
360 bool disregardAutosaveFailure =
false;
361 int autoSaveFailureCount = 0;
368 bool m_bAutoDetectedMime =
false;
374 bool modified =
false;
375 bool readwrite =
false;
376 bool autoSaveActive =
true;
398 qreal audioLevel = 1.0;
405 bool imageModifiedWithoutUndo =
false;
406 bool modifiedWhileSaving =
false;
414 bool isRecovered =
false;
416 bool batchMode {
false };
417 bool decorationsSyncingDisabled =
false;
418 bool wasStorageAdded =
false;
419 bool documentIsClosing =
false;
447 class StrippedSafeSavingLocker;
451void KisDocument::Private::syncDecorationsWrapperLayerState()
453 if (!this->image || this->decorationsSyncingDisabled)
return;
457 KisLayerUtils::findNodeByType<KisDecorationsWrapperLayer>(image->
root());
459 const bool needsDecorationsWrapper =
460 gridConfig.showGrid() || (guidesConfig.showGuides() && guidesConfig.hasGuides()) || !assistants.isEmpty();
463 SyncDecorationsWrapperStroke(
KisDocument *document,
bool needsDecorationsWrapper)
466 m_document(document),
467 m_needsDecorationsWrapper(needsDecorationsWrapper)
476 KisLayerUtils::findNodeByType<KisDecorationsWrapperLayer>(m_document->image()->root());
478 if (m_needsDecorationsWrapper && !decorationsLayer) {
480 }
else if (!m_needsDecorationsWrapper && decorationsLayer) {
481 m_document->image()->removeNode(decorationsLayer);
487 bool m_needsDecorationsWrapper =
false;
501 if (policy == REPLACE) {
506 mimeType = rhs.mimeType;
507 outputMimeType = rhs.outputMimeType;
509 if (policy == REPLACE) {
519 colorHistoryModel.setColorList(rhs.colorHistoryModel.colorList());
523 guidesConfig = rhs.guidesConfig;
524 mirrorAxisConfig = rhs.mirrorAxisConfig;
525 modified = rhs.modified;
528 m_storyboardCommentList = rhs.m_storyboardCommentList;
529 audioTracks = rhs.audioTracks;
530 audioLevel = rhs.audioLevel;
531 gridConfig = rhs.gridConfig;
533 imageModifiedWithoutUndo = rhs.imageModifiedWithoutUndo;
534 m_bAutoDetectedMime = rhs.m_bAutoDetectedMime;
537 readwrite = rhs.readwrite;
538 autoSaveActive = rhs.autoSaveActive;
539 firstMod = rhs.firstMod;
540 lastMod = rhs.lastMod;
542 globalAssistantsColor = rhs.globalAssistantsColor;
543 batchMode = rhs.batchMode;
546 if (rhs.linkedResourceStorage) {
547 linkedResourceStorage = rhs.linkedResourceStorage->clone();
550 if (rhs.embeddedResourceStorage) {
551 embeddedResourceStorage = rhs.embeddedResourceStorage->clone();
578 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
601 QMutex *m_savingLock;
602 KisImageReadOnlyBarrierLock m_imageLock;
609 connect(d->undoStack, SIGNAL(cleanChanged(
bool)),
this, SLOT(slotUndoStackCleanChanged(
bool)));
610 connect(d->autoSaveTimer, SIGNAL(timeout()),
this, SLOT(slotAutoSave()));
611 setObjectName(newObjectName());
616 connect(
this, SIGNAL(sigSavingFinished(
const QString&)), bookmarkmngr, SLOT(slotCreateBookmark(
const QString&)));
622 d->linkedResourcesStorageID = QUuid::createUuid().toString();
626 d->embeddedResourcesStorageID = QUuid::createUuid().toString();
627 d->embeddedResourceStorage.reset(
new KisResourceStorage(d->embeddedResourcesStorageID));
630 d->wasStorageAdded =
true;
651 d->wasStorageAdded =
true;
657 d->documentIsClosing =
true;
661 d->imageIdleWatcher.setTrackedImage(0);
669 d->autoSaveTimer->disconnect(
this);
670 d->autoSaveTimer->stop();
672 delete d->importExportManager;
675 delete d->shapeController;
677 delete d->koShapeController;
680 d->image->animationInterface()->blockBackgroundFrameGeneration();
682 d->image->notifyAboutToBeDeleted();
696 d->image->requestStrokeCancellation();
697 d->image->waitForDone();
700 d->undoStack->clear();
701 d->image->waitForDone();
704 Q_UNUSED(sanityCheckPointer);
713 if (
d->wasStorageAdded) {
727 return d->embeddedResourcesStorageID;
732 return d->linkedResourcesStorageID;
783 QFileInfo filePathInfo(job.
filePath);
784 bool fileExists = filePathInfo.exists();
787 fileExists = filePathInfo.size() > 0;
790 if (fileExists && !filePathInfo.isWritable()) {
792 i18n(
"%1 cannot be written to. Please save under a different name.", job.
filePath),
803 switch(cfg.
readEntry<
int>(
"backupfilelocation", 0)) {
805 backupDir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
808 backupDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
814 QDir().mkpath(backupDir);
822 QUrl fileUrl = QUrl::fromLocalFile(job.
filePath);
824 backupDir = QDir::tempPath();
833 int numOfBackupsKept = cfg.
readEntry<
int>(
"numberofbackupfiles", 1);
834 QString suffix = cfg.
readEntry<QString>(
"backupfilesuffix",
"~");
836 if (numOfBackupsKept == 1) {
838 qWarning() <<
"Failed to create simple backup file!" << job.
filePath << backupDir << suffix;
840 .arg(job.
filePath, backupDir.isEmpty()
841 ?
"the same location as the file"
848 .arg(job.
filePath, backupDir.isEmpty()
849 ?
"the same location as the file"
853 else if (numOfBackupsKept > 1) {
855 qWarning() <<
"Failed to create numbered backup file!" << job.
filePath << backupDir << suffix;
857 .arg(job.
filePath, backupDir.isEmpty()
858 ?
"the same location as the file"
865 .arg(job.
filePath, backupDir.isEmpty()
866 ?
"the same location as the file"
880 const QString actionName =
882 i18n(
"Exporting Document...") :
883 i18n(
"Saving Document...");
888 job, exportConfiguration, isAdvancedExporting);
891 QString errorShortLog;
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);
902 errorShortLog =
"failed to lock and clone the image";
907 errorShortLog =
"failed to start background saving";
934 SaveFlags flags = SaveIsExporting;
936 flags |= SaveShowWarnings;
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")));
950 exportConfiguration, isAdvancedExporting);
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"),
973 showWarnings ? SaveShowWarnings : SaveNone),
974 exportConfiguration);
987 filter->setBatchMode(
true);
990 Private::StrippedSafeSavingLocker locker(&
d->savingMutex,
d->image);
991 if (!locker.successfullyLocked()) {
992 return buffer.data();
995 d->savingImage =
d->image;
997 if (!filter->convert(
this, &buffer).isOk()) {
998 qWarning() <<
"serializeToByteArray():: Could not export to our native format";
1001 return buffer.data();
1008 const QString &message,
1010 const QString &details = {})
1011 : QMessageBox(QMessageBox::Warning, title, message, QMessageBox::Ok, qApp->activeWindow())
1013 if (!details.isEmpty()) {
1014 setInformativeText(details);
1016 if (!warnings.isEmpty()) {
1024 QMessageBox::setDetailedText(text.first());
1026 QTextEdit *messageBox = findChild<QTextEdit *>();
1029 messageBox->setAcceptRichText(
true);
1031 QString warning =
"<html><body><ul>";
1032 Q_FOREACH (
const QString &i, text) {
1033 warning +=
"\n<li>" + i +
"</li>";
1035 warning +=
"</ul></body></html>";
1037 messageBox->setText(warning);
1047 const QString fileName = QFileInfo(job.
filePath).fileName();
1049 if (!status.
isOk()) {
1050 Q_EMIT
statusBarMessage(i18nc(
"%1 --- failing file name, %2 --- error message",
1051 "Error during saving %1: %2",
1058 i18n(
"Could not save %1.", job.
filePath),
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.",
1080 : i18nc(
"dialog box shown to the user if there were warnings while saving the document",
1081 "Some problems were encountered when saving."));
1098 Q_EMIT
statusBarMessage(i18n(
"Finished saving %1", fileName), successMessageTimeout);
1102void KisDocument::Private::updateDocumentMetadataOnSaving(
const QString &filePath,
const QByteArray &mimeType)
1114 QFileInfo fi(filePath);
1118 if (!modifiedWhileSaving) {
1125 if (undoStack->isClean()) {
1128 imageModifiedWithoutUndo =
false;
1129 undoStack->setClean();
1147 return d->batchMode;
1155void KisDocument::Private::uploadLinkedResourcesFromLayersToStorage()
1166 if (KisNodeFilterInterface *layer = dynamic_cast<KisNodeFilterInterface*>(node.data())) {
1167 KisFilterConfigurationSP filterConfig = layer->filter();
1168 if (!filterConfig) return;
1170 QList<KoResourceLoadResult> linkedResources = filterConfig->linkedResources(KisGlobalResourcesInterface::instance());
1172 Q_FOREACH (const KoResourceLoadResult &result, linkedResources) {
1173 KIS_SAFE_ASSERT_RECOVER(result.type() != KoResourceLoadResult::EmbeddedResource) { continue; }
1175 KoResourceSP resource = result.resource();
1178 qWarning() <<
"WARNING: KisDocument::lockAndCloneForSaving failed to fetch a resource" << result.signature();
1183 buf.open(QBuffer::WriteOnly);
1185 KisResourceModel model(resource->resourceType().first);
1186 bool res = model.exportResource(resource, &buf);
1191 qWarning() <<
"WARNING: KisDocument::lockAndCloneForSaving failed to export resource" << result.signature();
1195 buf.open(QBuffer::ReadOnly);
1197 res = doc->d->linkedResourceStorage->importResource(resource->resourceType().first +
"/" + resource->filename(), &buf);
1202 qWarning() <<
"WARNING: KisDocument::lockAndCloneForSaving failed to import resource" << result.signature();
1211KisDocument *KisDocument::Private::lockAndCloneImpl(
bool fetchResourcesFromLayers)
1214 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1226 Private::StrippedSafeSavingLocker locker(&savingMutex, image);
1227 if (!locker.successfullyLocked()) {
1233 if (fetchResourcesFromLayers) {
1234 doc->
d->uploadLinkedResourcesFromLayersToStorage();
1242 return d->lockAndCloneImpl(
true);
1247 return d->lockAndCloneImpl(
false);
1258 d->decorationsSyncingDisabled =
true;
1259 d->copyFrom(*(rhs.
d),
this);
1260 d->decorationsSyncingDisabled =
false;
1262 d->undoStack->clear();
1267 connect(
d->autoSaveTimer, SIGNAL(timeout()),
this, SLOT(
slotAutoSave()));
1273 setObjectName(rhs.objectName());
1279 d->image->barrierLock(
false);
1280 rhs.
d->image->barrierLock(
true);
1281 d->image->copyFromImage(*(rhs.
d->image));
1283 rhs.
d->image->unlock();
1294 d->syncDecorationsWrapperLayerState();
1297 if (rhs.
d->preActivatedNode) {
1298 QQueue<KisNodeSP> linearizedNodes;
1301 linearizedNodes.enqueue(node);
1304 [&linearizedNodes, &rhs,
this](
KisNodeSP node) {
1305 KisNodeSP refNode = linearizedNodes.dequeue();
1306 if (rhs.d->preActivatedNode.data() == refNode.data()) {
1307 d->preActivatedNode = node;
1314 if (referencesLayer) {
1315 d->referenceLayerConnections.clear();
1316 d->referenceLayerConnections.addConnection(
1317 referencesLayer, SIGNAL(sigUpdateCanvas(QRectF)),
1318 this, SIGNAL(sigReferenceImagesChanged()));
1320 Q_EMIT sigReferenceImagesLayerChanged(referencesLayer);
1321 Q_EMIT sigReferenceImagesChanged();
1325 KisLayerUtils::findNodeByType<KisDecorationsWrapperLayer>(
d->image->root());
1326 if (decorationsLayer) {
1327 decorationsLayer->setDocument(
this);
1331 if (policy == REPLACE) {
1345 Private::StrippedSafeSavingLocker locker(&
d->savingMutex,
d->image);
1346 if (!locker.successfullyLocked()) {
1351 d->savingImage =
d->image;
1354 d->importExportManager->
1359 return status.
isOk();
1364 const QObject *receiverObject,
const char *receiverMethod,
1369 job, exportConfiguration, std::unique_ptr<KisDocument>(), isAdvancedExporting);
1373 const QObject *receiverObject,
const char *receiverMethod,
1376 std::unique_ptr<KisDocument> &&optionalClonedDocument,
bool isAdvancedExporting)
1380 std::unique_ptr<KisDocument> clonedDocument;
1382 if (!optionalClonedDocument) {
1385 clonedDocument.reset(optionalClonedDocument.release());
1388 if (!
d->savingMutex.tryLock()){
1396 std::unique_lock<QMutex> savingMutexLock(
d->savingMutex, std::adopt_lock);
1398 if (!clonedDocument) {
1415 waitForImage(clonedDocument->image());
1419 if (clonedDocument->image()->hasOverlaySelectionMask()) {
1420 clonedDocument->image()->setOverlaySelectionMask(0);
1421 waitForImage(clonedDocument->image());
1426 clonedDocument->image()->cropImage(clonedDocument->image()->bounds());
1427 clonedDocument->image()->purgeUnusedData(
false);
1428 waitForImage(clonedDocument->image());
1432 waitForImage(clonedDocument->image());
1447 savingMutexLock.release();
1449 d->backgroundSaveDocument.reset(clonedDocument.release());
1450 d->backgroundSaveJob = job;
1451 d->modifiedWhileSaving =
false;
1454 d->backgroundSaveDocument->d->isAutosaving =
true;
1457 connect(
d->backgroundSaveDocument.get(),
1463 if (
d->completeSavingConnection) {
1464 disconnect(
d->completeSavingConnection);
1466 d->completeSavingConnection = connect(
1468 receiverObject, receiverMethod);
1471 d->backgroundSaveDocument->startExportInBackground(actionName,
1476 exportConfiguration, isAdvancedExporting);
1477 if (!error.
isOk()) {
1480 d->backgroundSaveDocument.release()->deleteLater();
1481 d->savingMutex.unlock();
1503 std::unique_lock<QMutex> savingMutexLock(
d->savingMutex, std::adopt_lock);
1508 d->backgroundSaveDocument->d->isAutosaving =
false;
1511 d->backgroundSaveDocument.release()->deleteLater();
1519 savingMutexLock.unlock();
1522 KisUsageLogger::log(QString(
"Completed saving %1 (mime: %2). Result: %3. Warning: %4. Size: %5")
1525 QString::number(fi.size())));
1530 disconnect(
d->completeSavingConnection);
1531 d->completeSavingConnection = {};
1536 if (!
d->modified || !
d->modifiedAfterAutosave)
return;
1539 Q_EMIT
statusBarMessage(i18n(
"Autosaving... %1", autoSaveFileName), successMessageTimeout);
1543 const bool hadClonedDocument = bool(optionalClonedDocument);
1546 if (
d->image->isIdle() || hadClonedDocument) {
1551 std::move(optionalClonedDocument));
1553 Q_EMIT
statusBarMessage(i18n(
"Autosaving postponed: document is busy..."), errorMessageTimeout);
1558 connect(stroke, SIGNAL(sigDocumentCloned(
KisDocument*)),
1560 Qt::BlockingQueuedConnection);
1561 connect(stroke, SIGNAL(sigCloningCancelled()),
1563 Qt::BlockingQueuedConnection);
1566 d->image->endStroke(strokeId);
1573 d->modifiedAfterAutosave =
false;
1581 QStringList pathParts = QFileInfo(path).absolutePath().split(
'/');
1582 if (pathParts.size() > 0) {
1583 QString resourceType = pathParts.last();
1589 QString tempFileName = QDir::tempPath() +
"/" + QFileInfo(path).fileName();
1591 if (QFileInfo(path).exists()) {
1600 d->modifiedWhileSaving =
false;
1602 if (!exportConfiguration) {
1603 QScopedPointer<KisImportExportFilter> filter(
1610 if (exportConfiguration) {
1612 exportConfiguration->setProperty(
"name", res->name());
1616 QFile f2(tempFileName);
1619 QByteArray ba = f2.readAll();
1622 buf.open(QBuffer::ReadOnly);
1628 const QString filePath =
1631 d->updateDocumentMetadataOnSaving(filePath,
mimeType);
1640 d->modifiedWhileSaving =
false;
1644 const QString filePath =
1647 d->updateDocumentMetadataOnSaving(filePath,
mimeType);
1676 d->image->explicitRegenerateLevelOfDetail();
1691 const QString fileName = QFileInfo(job.
filePath).fileName();
1693 if (!status.
isOk()) {
1695 Q_EMIT
statusBarMessage(i18nc(
"%1 --- failing file name, %2 --- error message",
1696 "Error during autosaving %1: %2",
1703 if (!
d->modifiedWhileSaving) {
1704 d->autoSaveTimer->stop();
1705 d->autoSaveFailureCount = 0;
1710 Q_EMIT
statusBarMessage(i18n(
"Finished autosaving %1", fileName), successMessageTimeout);
1715 const QString &location,
1716 const QString &realLocation,
1717 const QByteArray &mimeType,
1721 d->savingImage =
d->image;
1727 d->importExportManager->setUpdater(
d->savingUpdater);
1732 d->childSavingFuture =
1733 d->importExportManager->exportDocumentAsync(location,
1736 initializationStatus,
1738 exportConfiguration,
1739 isAdvancedExporting);
1741 if (!initializationStatus.
isOk()) {
1742 if (
d->savingUpdater) {
1743 d->savingUpdater->cancel();
1745 d->savingImage.clear();
1747 return initializationStatus;
1750 typedef QFutureWatcher<KisImportExportErrorCode> StatusWatcher;
1751 StatusWatcher *watcher =
new StatusWatcher();
1752 watcher->setFuture(
d->childSavingFuture);
1755 connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater()));
1757 return initializationStatus;
1771 if (!
d->lastErrorMessage.isEmpty()) {
1779 d->savingImage.clear();
1781 d->lastErrorMessage.clear();
1782 d->lastWarningMessage.clear();
1784 if (
d->savingUpdater) {
1785 d->savingUpdater->setProgress(100);
1793 const bool changed =
readwrite !=
d->readwrite;
1815 d->autoSaveTimer->start(delay * 1000);
1817 d->autoSaveTimer->stop();
1824 d->autoSaveFailureCount = 0;
1829 const int emergencyAutoSaveInterval = 10;
1831 d->autoSaveFailureCount++;
1841 return d->autoSaveActive;
1857 if (
d->savingImage)
image =
d->savingImage;
1861 QSize originalSize =
bounds.size();
1863 QSize newSize = originalSize.scaled(size, Qt::KeepAspectRatio).expandedTo({1, 1});
1865 bool pixelArt =
false;
1867 if (originalSize.width() < size.width() && originalSize.height() < size.height()) {
1870 if (newSize.height()%originalSize.height() == 0 && newSize.width()%originalSize.width() == 0) {
1880 QImage scaled = original.scaled(newSize, Qt::KeepAspectRatio, Qt::FastTransformation);
1881 px = QPixmap::fromImage(scaled);
1885 if (px.size() == QSize(0,0)) {
1886 px = QPixmap(newSize);
1889 gc.fillRect(px.rect(), checkBrush);
1894 return QPixmap(size);
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$");
1908 QString dir = fi.absolutePath();
1912 if (path.startsWith(
"content://")) {
1918 QString filename = fi.fileName();
1920 if (path.isEmpty() || autosavePattern1.match(filename).hasMatch() || autosavePattern2.match(filename).hasMatch() || !fi.isWritable()) {
1922 retval = QString(
"%1%2%3%4-%5-%6-autosave%7")
1927 .arg(qApp->applicationPid())
1933 retval = QString(
"%1%2%3%4-autosave%5").arg(dir).arg(
'/').arg(prefix).arg(filename).arg(extension);
1944 dbgUI <<
"path=" << _path;
1952 dbgUI <<
"success, resetting url";
1962 dbgUI <<
"path=" << _path;
1963 d->lastErrorMessage.clear();
1966 if (_path.isEmpty()) {
1967 d->lastErrorMessage = i18n(
"Malformed Path\n%1", _path);
1971 QString path = _path;
1972 QString original =
"";
1973 bool autosaveOpened =
false;
1975 QString file =
path;
1977 if (QFile::exists(asf)) {
1984 int res = dlg.result();
1990 autosaveOpened =
true;
2024 QFileInfo fi(_path);
2039 QMessageBox::critical(qApp->activeWindow(), i18nc(
"@title:window",
"Krita"), i18n(
"File %1 does not exist.",
localFilePath()));
2046 if (typeName.isEmpty()) {
2051 if (typeName ==
"application/x-trash") {
2052 QString path = filename;
2053 while (path.length() > 0) {
2057 if (!typeName.isEmpty()) {
2069 d->importExportManager->setUpdater(updater);
2074 if (!status.
isOk()) {
2094 i18n(
"There were problems opening %1.",
prettyPath()),
2102 d->syncDecorationsWrapperLayerState();
2112 if (!
d->modified || !
d->modifiedAfterAutosave)
2121 d->modifiedAfterAutosave =
false;
2126 qWarning() <<
"Could not auto-save when paused";
2134 d->outputMimeType =
d->mimeType;
2153 if (
d->isAutosaving ||
d->documentIsClosing)
2159 if (mod && !
d->autoSaveTimer->isActive()) {
2163 d->modifiedAfterAutosave = mod;
2164 d->modifiedWhileSaving = mod;
2167 d->imageModifiedWithoutUndo = mod;
2184 const bool changed =
value !=
d->isRecovered;
2195 return d->isRecovered;
2200 QDateTime now = QDateTime::currentDateTime();
2201 int firstModDelta =
d->firstMod.secsTo(now);
2202 int lastModDelta =
d->lastMod.secsTo(now);
2204 if (lastModDelta > 30) {
2205 d->docInfo->setAboutInfo(
"editing-time", QString::number(
d->docInfo->aboutInfo(
"editing-time").toInt() +
d->firstMod.secsTo(
d->lastMod)));
2207 }
else if (firstModDelta > 60 || forceStoreElapsed) {
2208 d->docInfo->setAboutInfo(
"editing-time", QString::number(
d->docInfo->aboutInfo(
"editing-time").toInt() + firstModDelta));
2217 QString _url(
path());
2219 _url = QDir::toNativeSeparators(_url);
2228 const QString _url(QFileInfo(
path()).fileName());
2231 if (_url.isEmpty()) {
2232 c =
" [" + i18n(
"Not Saved") +
"] ";
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),
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());
2269 d->lastErrorMessage = errMsg;
2274 return d->lastErrorMessage;
2279 d->lastWarningMessage = warningMsg;
2284 return d->lastWarningMessage;
2292 if (QFile::exists(asf)) {
2298 if (QFile::exists(asf)) {
2305 expressions << QRegularExpression(
"^\\..+-autosave.kra$")
2306 << QRegularExpression(
"^.+-autosave.kra$");
2308 Q_FOREACH(
const QRegularExpression &rex, expressions) {
2310 !autosaveBaseName.isEmpty() &&
2311 rex.match(QFileInfo(autosaveBaseName).fileName()).hasMatch() &&
2312 QFile::exists(autosaveBaseName)) {
2315 QFile::remove(autosaveBaseName);
2327 if (
d->unit !=
unit) {
2335 return d->undoStack;
2340 return d->importExportManager;
2353 if (!
d->undoStack->isClean()) {
2354 d->undoStack->clear();
2370 d->syncDecorationsWrapperLayerState();
2375 d->undoStack->clear();
2380 return d->gridConfig;
2385 if (
d->gridConfig != config) {
2386 d->gridConfig = config;
2387 d->syncDecorationsWrapperLayerState();
2399 if (!
d->linkedResourceStorage) {
2405 while (iter->hasNext()) {
2409 buf.open(QBuffer::WriteOnly);
2410 bool exportSuccessful =
2411 d->linkedResourceStorage->exportResource(iter->url(), &buf);
2413 KoResourceSP resource =
d->linkedResourceStorage->resource(iter->url());
2414 exportSuccessful &= bool(resource);
2416 const QString name = resource ? resource->name() : QString();
2417 const QString fileName = QFileInfo(iter->url()).fileName();
2422 if (exportSuccessful) {
2425 result << signature;
2436 if (
d->linkedResourceStorage) {
2438 while (iter->hasNext()) {
2441 if (resource && resource->valid()) {
2442 oldPaletteList << resource.dynamicCast<
KoColorSet>();
2445 if (oldPaletteList != paletteList) {
2448 if (!paletteList.contains(
palette)) {
2453 if (!oldPaletteList.contains(
palette)) {
2457 palette->setStorageLocation(
d->linkedResourcesStorageID);
2470 return d->m_storyboardItemList;
2475 d->m_storyboardItemList = storyboardItemList;
2483 return d->m_storyboardCommentList;
2488 d->m_storyboardCommentList = storyboardCommentList;
2495 return d->audioTracks;
2506 d->audioLevel = level;
2512 return d->audioLevel;
2517 return d->guidesConfig;
2522 if (
d->guidesConfig == data)
return;
2524 d->guidesConfig = data;
2525 d->syncDecorationsWrapperLayerState();
2532 return d->mirrorAxisConfig;
2537 if (
d->mirrorAxisConfig == config) {
2541 d->mirrorAxisConfig = config;
2544 d->image->bounds()));
2563 return d->readwrite;
2576 if (view && view->
document() ==
this) {
2585 d->mimeType = QByteArray();
2597 const bool changed = path !=
d->m_path;
2619 if ( path.isEmpty() ) {
2623 if (
d->m_bAutoDetectedMime) {
2624 d->mimeType = QByteArray();
2625 d->m_bAutoDetectedMime =
false;
2639 d->m_file =
d->m_path;
2643 if (
d->mimeType.isEmpty()) {
2647 d->mimeType = mime.toLocal8Bit();
2648 d->m_bAutoDetectedMime =
true;
2664 qint32 width, qint32 height,
2668 const QString &description,
const double imageResolution)
2674 if (!cs)
return false;
2676 KisCursorOverrideLock cursorLock(Qt::BusyCursor);
2707 KoColor strippedAlpha = bgColor;
2716 filter_config->setProperty(
"color", strippedAlpha.
toQColor());
2717 filter_config->createLocalResourcesSnapshot();
2723 if (numberOfLayers > 1) {
2733 Q_CHECK_PTR(bgLayer);
2735 bgLayer->
setDirty(QRect(0, 0, width, height));
2738 d->mirrorAxisConfig.setAxisPosition(QRectF(
image->
bounds()).center());
2741 for(
int i = 1; i < numberOfLayers; ++i) {
2745 layer->
setDirty(QRect(0, 0, width, height));
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),
2763 QString::number(numberOfLayers)));
2770 const bool result =
d->savingMutex.tryLock();
2772 d->savingMutex.unlock();
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);
2787 return d->shapeController;
2792 return d->shapeController->shapeForNode(layer);
2797 return d->assistants;
2802 if (
d->assistants !=
value) {
2804 d->syncDecorationsWrapperLayerState();
2814 KisLayerUtils::findNodeByType<KisReferenceImagesLayer>(
d->image->root());
2816 return referencesLayer;
2825 if (currentReferenceLayer == layer && updateImage) {
2829 d->referenceLayerConnections.clear();
2832 if (currentReferenceLayer) {
2833 d->image->removeNode(currentReferenceLayer);
2837 d->image->addNode(layer);
2841 currentReferenceLayer = layer;
2843 if (currentReferenceLayer) {
2844 d->referenceLayerConnections.addConnection(
2845 currentReferenceLayer, SIGNAL(sigUpdateCanvas(QRectF)),
2855 d->preActivatedNode = activatedNode;
2860 return d->preActivatedNode;
2870 return d->savingImage;
2879 d->image->disconnect(
this);
2880 d->shapeController->setImage(0);
2886 if (
d->linkedResourceStorage){
2890 d->setImageAndInitIdleWatcher(
image);
2895 connect(
d->image, SIGNAL(sigImageModified()),
this, SLOT(
setImageModified()), Qt::UniqueConnection);
2899 if (forceInitialUpdate) {
2900 d->image->initialRefreshGraph();
2911 d->shapeController->setImage(
image);
2917 setModified(
d->imageModifiedWithoutUndo || !
d->undoStack->isClean());
2922 d->imageModifiedWithoutUndo =
true;
2934 return d->isAutosaving;
2944 d->globalAssistantsColor = color;
2949 return d->globalAssistantsColor;
2954 QRectF
bounds =
d->image->bounds();
2958 if (referenceImagesLayer) {
2967 d->colorHistoryModel.setColorList(colors);
2972 return d->colorHistoryModel.colorList();
2977 return &
d->colorHistoryModel;
float value(const T *src, size_t ch)
KisSharedPtr< KisReferenceImagesLayer > KisReferenceImagesLayerSP
const quint8 OPACITY_OPAQUE_U8
void setDetailedText(const QStringList &text)
DlgLoadMessages(const QString &title, const QString &message, const QStringList &warnings={}, const QString &details={})
virtual void setIndex(int idx)
bool setResourceInactive(const QModelIndex &index)
Base class for the Krita app.
static QString autoSaveLocation()
static bool simpleBackupFile(const QString &filename, const QString &backupDir=QString(), const QString &backupExtension=QStringLiteral("~"))
static bool numberedBackupFile(const QString &filename, const QString &backupDir=QString(), const QString &backupExtension=QStringLiteral("~"), const uint maxBackups=10)
QList< KoColor > colorHistoryColors() const
static KisConfigNotifier * instance()
bool backupFile(bool defaultValue=false) const
qint32 defImageHeight(bool defaultValue=false) const
qint32 defImageWidth(bool defaultValue=false) const
bool useDefaultColorSpace(bool defaultvalue=false) const
void setDefaultColorDepth(const QString &depth) const
void setDefaultGridSpacing(QPoint gridSpacing)
qreal defImageResolution(bool defaultValue=false) const
bool useCumulativeUndoRedo(bool defaultValue=false) const
QString defColorProfile(bool defaultValue=false) const
KisCumulativeUndoData cumulativeUndoData(bool defaultValue=false) const
bool autoPinLayersToTimeline(bool defaultValue=false) const
bool trimKra(bool defaultValue=false) const
T readEntry(const QString &name, const T &defaultValue=T())
int autoSaveInterval(bool defaultValue=false) const
QString defColorModel(bool defaultValue=false) const
int undoStackLimit(bool defaultValue=false) const
~StrippedSafeSavingLocker()
StrippedSafeSavingLocker(QMutex *savingMutex, KisImageSP image)
KisImageReadOnlyBarrierLock m_imageLock
bool successfullyLocked() const
QScopedPointer< KisSignalAutoConnection > imageIdleConnection
void slotImageRootChanged()
void setAssistants(const QList< KisPaintingAssistantSP > &value)
@replace the current list of assistants with
void waitForSavingToComplete()
QRectF documentBounds() const
QString warningMessage() const
void copyFrom(const Private &rhs, KisDocument *q)
void removeAutoSaveFiles(const QString &autosaveBaseName, bool wasRecovered)
KisUndoStore * createUndoStore()
void slotInitiateAsyncAutosaving(KisDocument *clonedDocument)
void updateDocumentMetadataOnSaving(const QString &filePath, const QByteArray &mimeType)
void sigStoryboardCommentListChanged()
QFuture< KisImportExportErrorCode > childSavingFuture
void setEmergencyAutoSaveInterval()
void setFileBatchMode(const bool batchMode)
KisMirrorAxisConfig mirrorAxisConfig
KisSharedPtr< KisReferenceImagesLayer > referenceImagesLayer() const
bool exportDocument(const QString &path, const QByteArray &mimeType, bool isAdvancedExporting=false, bool showWarnings=false, KisPropertiesConfigurationSP exportConfiguration=0)
KoDocumentInfo * documentInfo() const
void syncDecorationsWrapperLayerState()
void hackPreliminarySetImage(KisImageSP image)
void sigBackgroundSavingFinished(KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
QString linkedResourcesStorageId() const
void copyFromImpl(const Private &rhs, KisDocument *q, KisDocument::CopyPolicy policy)
QPixmap generatePreview(const QSize &size)
Generates a preview picture of the document.
KisShapeController * shapeController
static QStringList extraNativeMimeTypes()
KisSignalAutoConnectionsStore referenceLayerConnections
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)
bool save(bool showWarnings, KisPropertiesConfigurationSP exportConfiguration)
KisImportExportManager * importExportManager
void statusBarMessage(const QString &text, int timeout=0)
bool isNativeFormat(const QByteArray &mimeType) const
Checks whether a given mimeType can be handled natively.
void setAudioTracks(QVector< QFileInfo > f)
void sigAudioLevelChanged(qreal level)
KisDocument * lockAndCloneImpl(bool fetchResourcesFromLayers)
void uploadLinkedResourcesFromLayersToStorage()
void slotUndoStackCleanChanged(bool value)
QString localFilePath() const
void sigAssistantsChanged()
void setErrorMessage(const QString &errMsg)
void setMirrorAxisConfig(const KisMirrorAxisConfig &config)
QList< KoColor > colorHistoryColors() const
KoDocumentInfoDlg * createDocumentInfoDialog(QWidget *parent, KoDocumentInfo *docInfo) const
void sigStoryboardItemListChanged()
KisImportExportErrorCode startExportInBackground(const QString &actionName, const QString &location, const QString &realLocation, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting=false)
QString exportErrorToUserMessage(KisImportExportErrorCode status, const QString &errorMessage)
void setAssistantsGlobalColor(QColor color)
bool loadNativeFormat(const QString &file)
void updateEditingTime(bool forceStoreElapsed)
void sigPaletteListChanged(const QList< KoColorSetSP > &oldPaletteList, const QList< KoColorSetSP > &newPaletteList)
void setModified(bool _mod)
void setMimeType(const QByteArray &mimeType)
Sets the mime type for the document.
QDomDocument createDomDocument(const QString &tagName, const QString &version) const
void sigLoadingFinished()
KisDocument * lockAndCloneForSaving()
try to clone the image. This method handles all the locking for you. If locking has failed,...
void sigReadWriteChanged(bool value)
void finishExportInBackground()
void copyFromDocument(const KisDocument &rhs)
void slotDocumentCloningCancelled()
void setWarningMessage(const QString &warningMsg)
std::unique_ptr< KisDocument > backgroundSaveDocument
void setUnit(const KoUnit &unit)
void setPath(const QString &path)
bool saveAs(const QString &path, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration=0)
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)
void setLocalFilePath(const QString &localFilePath)
QList< KoResourceLoadResult > linkedDocumentResources()
linkedDocumentResources List returns all the resources linked to the document, such as palettes
KisDocument * lockAndCreateSnapshot()
void setAutoSaveDelay(int delay)
void setPreActivatedNode(KisNodeSP activatedNode)
QString lastWarningMessage
void sigGuidesConfigChanged(const KisGuidesConfig &config)
void setRecovered(bool value)
void slotChildCompletedSavingInBackground(KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
Private(const Private &rhs, KisDocument *_q)
bool importDocument(const QString &path)
QString errorMessage() const
KritaUtils::ExportFileJob backgroundSaveJob
QColor globalAssistantsColor
KisResourceStorageSP embeddedResourceStorage
static QByteArray nativeFormatMimeType()
void sigAudioTracksChanged()
void setReferenceImagesLayer(KisSharedPtr< KisReferenceImagesLayer > layer, bool updateImage)
bool resourceSavingFilter(const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration)
KisDocument(bool addStorage=true)
void canceled(const QString &)
void setReadWrite(bool readwrite=true)
Sets whether the document can be edited or is read only.
void setImageModifiedWithoutUndo()
void setColorHistoryColors(const QList< KoColor > &colors)
void sigGridConfigChanged(const KisGridConfig &config)
QColor assistantsGlobalColor()
QPointer< KoUpdater > savingUpdater
void autoSaveOnPause()
Start saving when android activity is pushed to the background.
StoryboardItemList getStoryboardItemList()
returns the list of pointers to storyboard Items for the document
QString embeddedResourcesStorageId() const
QString linkedResourcesStorageID
void sigSavingFinished(const QString &filePath)
QString generateAutoSaveFileName(const QString &path) const
KisResourceStorageSP linkedResourceStorage
QMetaObject::Connection completeSavingConnection
KisNodeWSP preActivatedNode
void setNormalAutoSaveInterval()
void slotCompleteSavingDocument(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
void unitChanged(const KoUnit &unit)
KoShapeLayer * shapeForNode(KisNodeSP layer) const
bool exportDocumentSync(const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration=0)
void setGridConfig(const KisGridConfig &config)
bool closePath(bool promptToSave=true)
void sigPathChanged(const QString &path)
QByteArray serializeToNativeByteArray()
serializeToNativeByteArray daves the document into a .kra file written to a memory-based byte-array
QList< KisPaintingAssistantSP > assistants
void setImageAndInitIdleWatcher(KisImageSP _image)
void setAudioVolume(qreal level)
void setAutoSaveActive(bool autoSaveIsActive)
@ CONSTRUCT
we are copy-constructing a new KisDocument
@ REPLACE
we are replacing the current KisDocument with another
void setGuidesConfig(const KisGuidesConfig &data)
bool openPathInternal(const QString &path)
KisIdleWatcher imageIdleWatcher
bool fileBatchMode() const
QByteArray outputMimeType
QVector< StoryboardComment > getStoryboardCommentsList()
returns the list of comments for the storyboard docker in the document
void setMimeTypeAfterLoading(const QString &mimeType)
void sigCompleteBackgroundSaving(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
void copyFromDocumentImpl(const KisDocument &rhs, CopyPolicy policy)
void sigReferenceImagesLayerChanged(KisSharedPtr< KisReferenceImagesLayer > layer)
void slotPerformIdleRoutines()
StoryboardItemList m_storyboardItemList
void slotAutoSaveImpl(std::unique_ptr< KisDocument > &&optionalClonedDocument)
void setCurrentImage(KisImageSP image, bool forceInitialUpdate=true, KisNodeSP preActivatedNode=nullptr)
void sigRecoveredChanged(bool value)
QVector< StoryboardComment > m_storyboardCommentList
QVector< QFileInfo > getAudioTracks() const
KisUniqueColorSet colorHistoryModel
bool exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration, bool isAdvancedExporting=false)
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...
void setPaletteList(const QList< KoColorSetSP > &paletteList, bool emitSignal=false)
setPaletteList replaces the palettes in the document's local resource storage with the list of palett...
void slotCompleteAutoSaving(const KritaUtils::ExportFileJob &job, KisImportExportErrorCode status, const QString &errorMessage, const QString &warningMessage)
KisDocument * clone(bool addStorage=false)
creates a clone of the document and returns it. Please make sure that you hold all the necessary lock...
void setInfiniteAutoSaveInterval()
void sigReferenceImagesChanged()
QString embeddedResourcesStorageID
void setStoryboardItemList(const StoryboardItemList &storyboardItemList, bool emitSignal=false)
sets the storyboardItemList in the document, emits empty signal if emitSignal is true.
bool openPath(const QString &path, OpenFlags flags=None)
openPath Open a Path
KisGuidesConfig guidesConfig
QVector< QFileInfo > audioTracks
void sigMirrorAxisConfigChanged()
QString prettyPath() const
The KisDumbUndoStore class doesn't actually save commands, so you cannot undo or redo!
static KisGeneratorRegistry * instance()
static KisResourcesInterfaceSP instance()
void setTrackedImage(KisImageSP image)
QImage convertToQImage(qint32 x1, qint32 y1, qint32 width, qint32 height, const KoColorProfile *profile)
KisGroupLayerSP rootLayer() const
UndoResult tryUndoUnfinishedLod0Stroke()
const KoColorSpace * colorSpace() const
void requestUndoDuringStroke()
QString nextLayerName(const QString &baseName="") const
bool assignImageProfile(const KoColorProfile *profile, bool blockAllUpdates=false)
KisImage * clone(bool exactCopy=false)
void setDefaultProjectionColor(const KoColor &color)
void requestStrokeCancellation()
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
KisSelectionSP globalSelection() const
QRect bounds() const override
bool tryBarrierLock(bool readOnly=false)
Tries to lock the image without waiting for the jobs to finish.
void endStroke(KisStrokeId id) override
void requestRedoDuringStroke()
void setResolution(double xres, double yres)
QString errorMessage() const
The class managing all the filters.
static KisImportExportFilter * filterForMimeType(const QString &mimetype, Direction direction)
filterForMimeType loads the relevant import/export plugin and returns it. The caller is responsible f...
static KisMacosSecurityBookmarkManager * instance()
bool parentDirHasPermissions(const QString &path)
KisViewManager * viewManager
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
The KisMirrorAxisConfig class stores configuration for the KisMirrorAxis canvas decoration....
void setDefaultPixel(const KoColor &defPixel)
static MemoryReleaseObject * createMemoryReleaseObject()
static QList< KisPaintingAssistantSP > cloneAssistantList(const QList< KisPaintingAssistantSP > &list)
void addRecentURLToAllMainWindows(QUrl url, QUrl oldUrl=QUrl())
static KisPart * instance()
KisMainWindow * currentMainwindow() const
The KisRecoverNamedAutosaveDialog class is a dialog to recover already existing files from autosave.
QRectF boundingImageRect() const
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...
static KisResourceLoaderRegistry * instance()
bool removeStorage(const QString &storageLocation)
removeStorage removes the temporary storage from the database
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...
QString filePathForResource(KoResourceSP resource)
static KisResourceLocator * instance()
The KisResourceModel class provides the main access to resources. It is possible to filter the resour...
KoResourceSP resourceForId(int id) const
KoResourceSP importResourceFile(const QString &filename, const bool allowOverwrite, const QString &storageId=QString("")) override
importResourceFile
bool updateResource(KoResourceSP resource) override
updateResource creates a new version of the resource in the storage and in the database....
bool addResource(KoResourceSP resource, const QString &storageId=QString("")) override
addResource adds the given resource to the database and storage. If the resource already exists in th...
void setResourceFilter(ResourceFilter filter) override
QModelIndex indexForResource(KoResourceSP resource) const override
indexFromResource
static KisResourceServerProvider * instance()
static const QString s_meta_name
void enableJob(JobType type, bool enable=true, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
virtual void initStrokeCallback()
void setClearsRedoOnStart(bool value)
void setRequestsOtherStrokesToEnd(bool value)
static void log(const QString &message)
Logs with date/time.
bool blockUntilOperationsFinished(KisImageSP image)
blockUntilOperationsFinished blocks the GUI of the application until execution of actions on image is...
QPointer< KoUpdater > createThreadedUpdater(const QString &name)
void blockUntilOperationsFinishedForced(KisImageSP image)
blockUntilOperationsFinished blocks the GUI of the application until execution of actions on image is...
QPointer< KoUpdater > createUnthreadedUpdater(const QString &name)
create a new progress updater
KisCanvasResourceProvider * canvasResourceProvider()
QPointer< KisDocument > document
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
void setOpacity(quint8 alpha)
void toQColor(QColor *c) const
a convenience method for the above.
The dialog that shows information about the document.
The class containing all meta information about a document.
void setAboutInfo(const QString &info, const QString &data)
T get(const QString &id) const
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.
static StoryboardItemList cloneStoryboardItemList(const StoryboardItemList &list)
QQueue< PostponedJob > m_postponedJobs
void notifySetIndexChangedOneCommand() override
UndoStack(KisDocument *doc)
void processPostponedJobs()
void setIndex(int idx) override
void setIndexImpl(int idx)
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
KUndo2MagicString kundo2_noi18n(const QString &text)
QPointF absoluteToRelative(const QPointF &pt, const QRectF &rc)
bool hasDelayedNodeWithUpdates(KisNodeSP root)
void recursiveApplyNodes(NodePointer node, Functor func)
void forceAllDelayedNodesUpdate(KisNodeSP root)
BackgroudSavingStartResult
@ AnotherSavingInProgress
rgba palette[MAX_PALETTE]
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)