Commit f1ced4cb authored by Tusooa Zhu's avatar Tusooa Zhu 🔼

Reuse copyFromDocument() in KisDocument copy-ctor

parent ddf6465d
......@@ -253,31 +253,15 @@ public:
Private(const Private &rhs, KisDocument *q)
: docInfo(new KoDocumentInfo(*rhs.docInfo, q))
, unit(rhs.unit)
, importExportManager(new KisImportExportManager(q))
, mimeType(rhs.mimeType)
, outputMimeType(rhs.outputMimeType)
, autoSaveTimer(new QTimer(q))
, undoStack(new UndoStack(q))
, guidesConfig(rhs.guidesConfig)
, mirrorAxisConfig(rhs.mirrorAxisConfig)
, m_bAutoDetectedMime(rhs.m_bAutoDetectedMime)
, m_url(rhs.m_url)
, m_file(rhs.m_file)
, modified(rhs.modified)
, readwrite(rhs.readwrite)
, firstMod(rhs.firstMod)
, lastMod(rhs.lastMod)
, nserver(new KisNameServer(*rhs.nserver))
, preActivatedNode(0) // the node is from another hierarchy!
, imageIdleWatcher(2000 /*ms*/)
, assistants(KisPaintingAssistant::cloneAssistantList(rhs.assistants)) // WARNING: assistants should not store pointers to the document!
, globalAssistantsColor(rhs.globalAssistantsColor)
, paletteList(rhs.paletteList)
, gridConfig(rhs.gridConfig)
, savingLock(&savingMutex)
, batchMode(rhs.batchMode)
{
copyFromImpl(rhs, q, CONSTRUCT);
}
~Private() {
......@@ -368,44 +352,74 @@ public:
}
void copyFrom(const Private &rhs, KisDocument *q);
void copyFromImpl(const Private &rhs, KisDocument *q, KisDocument::CopyPolicy policy);
/// clones the palette list oldList
/// the ownership of the returned KoColorSet * belongs to the caller
QList<KoColorSet *> clonePaletteList(const QList<KoColorSet *> &oldList);
class StrippedSafeSavingLocker;
};
void KisDocument::Private::copyFrom(const Private &rhs, KisDocument *q)
{
delete docInfo;
copyFromImpl(rhs, q, KisDocument::REPLACE);
}
void KisDocument::Private::copyFromImpl(const Private &rhs, KisDocument *q, KisDocument::CopyPolicy policy)
{
if (policy == REPLACE) {
delete docInfo;
}
docInfo = (new KoDocumentInfo(*rhs.docInfo, q));
unit = rhs.unit;
mimeType = rhs.mimeType;
outputMimeType = rhs.outputMimeType;
// TODO: undo stacks may store pointers to the document and/or image
// we *have* to destroy the original one
//delete undoStack;
//undoStack = new UndoStack(q);
q->setGuidesConfig(rhs.guidesConfig);
q->setMirrorAxisConfig(rhs.mirrorAxisConfig);
if (policy == REPLACE) {
q->setGuidesConfig(rhs.guidesConfig);
q->setMirrorAxisConfig(rhs.mirrorAxisConfig);
q->setModified(rhs.modified);
q->setAssistants(KisPaintingAssistant::cloneAssistantList(rhs.assistants));
q->setGridConfig(rhs.gridConfig);
} else {
// in CONSTRUCT mode, we cannot use the functions of KisDocument
// because KisDocument does not yet have a pointer to us.
guidesConfig = rhs.guidesConfig;
mirrorAxisConfig = rhs.mirrorAxisConfig;
modified = rhs.modified;
assistants = KisPaintingAssistant::cloneAssistantList(rhs.assistants);
gridConfig = rhs.gridConfig;
}
m_bAutoDetectedMime = rhs.m_bAutoDetectedMime;
m_url = rhs.m_url;
m_file = rhs.m_file;
q->setModified(rhs.modified);
readwrite = rhs.readwrite;
firstMod = rhs.firstMod;
lastMod = rhs.lastMod;
// XXX: the display properties will be shared between different snapshots
q->setAssistants(KisPaintingAssistant::cloneAssistantList(rhs.assistants));
globalAssistantsColor = rhs.globalAssistantsColor;
QList<KoColorSet *> newPaletteList;
Q_FOREACH (KoColorSet *palette, rhs.paletteList) {
newPaletteList << new KoColorSet(*palette);
if (policy == REPLACE) {
QList<KoColorSet *> newPaletteList = clonePaletteList(rhs.paletteList);
q->setPaletteList(newPaletteList, /* emitSignal = */ true);
// we still do not own palettes if we did not
} else {
paletteList = rhs.paletteList;
}
q->setPaletteList(newPaletteList, /* emitSignal = */ true);
q->setGridConfig(rhs.gridConfig);
batchMode = rhs.batchMode;
}
QList<KoColorSet *> KisDocument::Private::clonePaletteList(const QList<KoColorSet *> &oldList)
{
QList<KoColorSet *> newList;
Q_FOREACH (KoColorSet *palette, oldList) {
newList << new KoColorSet(*palette);
}
return newList;
}
class KisDocument::Private::StrippedSafeSavingLocker {
public:
StrippedSafeSavingLocker(QMutex *savingMutex, KisImageSP image)
......@@ -475,30 +489,7 @@ KisDocument::KisDocument(const KisDocument &rhs)
: QObject(),
d(new Private(*rhs.d, this))
{
connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
connect(d->undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(slotUndoStackCleanChanged(bool)));
connect(d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
setObjectName(rhs.objectName());
d->shapeController = new KisShapeController(this, d->nserver);
d->koShapeController = new KoShapeController(0, d->shapeController);
d->shapeController->resourceManager()->setGlobalShapeController(d->koShapeController);
slotConfigChanged();
// clone the image with keeping the GUIDs of the layers intact
// NOTE: we expect the image to be locked!
setCurrentImage(rhs.image()->clone(true), false);
if (rhs.d->preActivatedNode) {
// since we clone uuid's, we can use them for lacating new
// nodes. Otherwise we would need to use findSymmetricClone()
d->preActivatedNode =
KisLayerUtils::findNodeByUuid(d->image->root(), rhs.d->preActivatedNode->uuid());
}
KisNodeSP foundNode = KisLayerUtils::recursiveFindNode(image()->rootLayer(), [](KisNodeSP node) -> bool { return dynamic_cast<KisReferenceImagesLayer *>(node.data()); });
KisReferenceImagesLayer *refLayer = dynamic_cast<KisReferenceImagesLayer *>(foundNode.data());
setReferenceImagesLayer(refLayer, /* updateImage = */ false);
copyFromDocumentImpl(rhs, CONSTRUCT);
}
KisDocument::~KisDocument()
......@@ -811,9 +802,7 @@ KisDocument *KisDocument::lockAndCreateSnapshot()
KisDocument *doc = lockAndCloneForSaving();
if (doc) {
// clone palette list
for (KoColorSet *&cs : doc->d->paletteList) {
cs = new KoColorSet(*cs);
}
doc->d->paletteList = doc->d->clonePaletteList(doc->d->paletteList);
doc->d->ownsPaletteList = true;
}
return doc;
......@@ -821,20 +810,43 @@ KisDocument *KisDocument::lockAndCreateSnapshot()
void KisDocument::copyFromDocument(const KisDocument &rhs)
{
d->copyFrom(*(rhs.d), this);
copyFromDocumentImpl(rhs, REPLACE);
}
void KisDocument::copyFromDocumentImpl(const KisDocument &rhs, CopyPolicy policy)
{
if (policy == REPLACE) {
d->copyFrom(*(rhs.d), this);
d->undoStack->clear();
} else {
// in CONSTRUCT mode, d should be already initialized
connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
connect(d->undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(slotUndoStackCleanChanged(bool)));
connect(d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
d->shapeController = new KisShapeController(this, d->nserver);
d->koShapeController = new KoShapeController(0, d->shapeController);
d->shapeController->resourceManager()->setGlobalShapeController(d->koShapeController);
}
d->undoStack->clear();
setObjectName(rhs.objectName());
slotConfigChanged();
if (rhs.d->image) {
d->image->barrierLock(/* readOnly = */ false);
rhs.d->image->barrierLock(/* readOnly = */ true);
d->image->copyFromImage(*(rhs.d->image));
d->image->unlock();
rhs.d->image->unlock();
setCurrentImage(d->image, /* forceInitialUpdate = */ true);
if (policy == REPLACE) {
d->image->barrierLock(/* readOnly = */ false);
rhs.d->image->barrierLock(/* readOnly = */ true);
d->image->copyFromImage(*(rhs.d->image));
d->image->unlock();
rhs.d->image->unlock();
setCurrentImage(d->image, /* forceInitialUpdate = */ true);
} else {
// clone the image with keeping the GUIDs of the layers intact
// NOTE: we expect the image to be locked!
setCurrentImage(rhs.image()->clone(/* exactCopy = */ true), /* forceInitialUpdate = */ false);
}
}
if (rhs.d->preActivatedNode) {
......@@ -851,11 +863,14 @@ void KisDocument::copyFromDocument(const KisDocument &rhs)
}
});
}
KisNodeSP foundNode = KisLayerUtils::recursiveFindNode(image()->rootLayer(), [](KisNodeSP node) -> bool { return dynamic_cast<KisReferenceImagesLayer *>(node.data()); });
KisReferenceImagesLayer *refLayer = dynamic_cast<KisReferenceImagesLayer *>(foundNode.data());
setReferenceImagesLayer(refLayer, /* updateImage = */ false);
setModified(true);
if (policy == REPLACE) {
setModified(true);
}
}
bool KisDocument::exportDocumentSync(const QUrl &url, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration)
......
......@@ -667,6 +667,13 @@ public:
private:
enum CopyPolicy {
CONSTRUCT = 0, ///< we are copy-constructing a new KisDocument
REPLACE ///< we are replacing the current KisDocument with another
};
void copyFromDocumentImpl(const KisDocument &rhs, CopyPolicy policy);
QString exportErrorToUserMessage(KisImportExportErrorCode status, const QString &errorMessage);
QString prettyPathOrUrl() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment