Commit 0793ef42 authored by Tusooa Zhu's avatar Tusooa Zhu

Implement the creation of snapshots

Replacing the current KisDocument with another is
not yet supported. Deleting snapshots is not implemented.
parent b55dff64
......@@ -640,8 +640,7 @@ private Q_SLOTS:
void slotConfigChanged();
private:
public:
/**
* @brief try to clone the image. This method handles all the locking for you. If locking
* has failed, no cloning happens
......@@ -649,6 +648,8 @@ private:
*/
KisDocument *lockAndCloneForSaving();
private:
QString exportErrorToUserMessage(KisImportExportErrorCode status, const QString &errorMessage);
QString prettyPathOrUrl() const;
......
......@@ -20,14 +20,26 @@
#include <QMap>
#include <QList>
#include <QPointer>
#include <QPair>
#include <QString>
#include <KisDocument.h>
#include <KisView.h>
struct KisSnapshotModel::Private
{
Private();
virtual ~Private();
QMap<KisCanvas2 *, QList<KisDocument *> > canvasDocMap;
QPointer<KisDocument> curDocument();
bool switchToDocument(QPointer<KisDocument> doc);
using DocPList = QList<QPair<QString, QPointer<KisDocument> > >;
DocPList curDocList;
QList<DocPList> documentGroups;
QPointer<KisCanvas2> curCanvas;
};
......@@ -35,6 +47,29 @@ KisSnapshotModel::Private::Private()
{
}
KisSnapshotModel::Private::~Private()
{
}
QPointer<KisDocument> KisSnapshotModel::Private::curDocument()
{
if (curCanvas && curCanvas->imageView()) {
return curCanvas->imageView()->document();
}
return 0;
}
bool KisSnapshotModel::Private::switchToDocument(QPointer<KisDocument> doc)
{
if (curCanvas && curCanvas->imageView()) {
KisView *view = curCanvas->imageView();
view->setDocument(doc);
// FIXME: more things need to be done
return true;
}
return false;
}
KisSnapshotModel::KisSnapshotModel()
: QAbstractListModel()
, m_d(new Private)
......@@ -47,16 +82,105 @@ KisSnapshotModel::~KisSnapshotModel()
int KisSnapshotModel::rowCount(const QModelIndex &parent) const
{
return 0;
if (parent.isValid()) {
return 0;
} else {
return m_d->curDocList.size();
}
}
QVariant KisSnapshotModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= rowCount(QModelIndex())) {
return QVariant();
}
int i = index.row();
switch (role) {
case Qt::DisplayRole:
case Qt::EditRole:
return m_d->curDocList[i].first;
break;
}
return QVariant();
}
bool KisSnapshotModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
return false;
}
void KisSnapshotModel::setCanvas(QPointer<KisCanvas2> canvas)
{
if (m_d->curCanvas == canvas) {
return;
}
if (m_d->curCanvas) {
// if any one doc in the group is no longer valid (is closed)
// destroy all other snapshots
bool docValid = true;
Q_FOREACH (auto const &i, m_d->curDocList) {
if (! i.second) {
docValid = false;
break;
}
}
if (docValid) {
m_d->documentGroups << m_d->curDocList;
} else {
Q_FOREACH (auto const &i, m_d->curDocList) {
delete i.second.data();
}
}
}
if (!m_d->curDocList.isEmpty()) {
beginRemoveRows(QModelIndex(), 0, m_d->curDocList.size() - 1);
m_d->curDocList.clear();
endRemoveRows();
}
m_d->curCanvas = canvas;
QPointer<KisDocument> curDoc = m_d->curDocument();
if (curDoc) {
for (int i = 0; i < m_d->documentGroups.size(); ++i) {
const Private::DocPList &docList = m_d->documentGroups[i];
Q_FOREACH (auto const &j, docList) {
if (j.second == curDoc) {
m_d->curDocList = m_d->documentGroups.takeAt(i);
return;
}
}
}
// we have not found any existing group containing the current document
beginInsertRows(QModelIndex(), m_d->curDocList.size(), m_d->curDocList.size());
m_d->curDocList << qMakePair(i18n("Original Document"), curDoc); /// XXX: a better title for it?
endInsertRows();
}
}
bool KisSnapshotModel::slotCreateSnapshot()
{
QPointer<KisDocument> clonedDoc(m_d->curDocument()->lockAndCloneForSaving());
if (clonedDoc) {
beginInsertRows(QModelIndex(), m_d->curDocList.size(), m_d->curDocList.size());
m_d->curDocList << qMakePair(i18n("Snapshot"), clonedDoc);
endInsertRows();
return true;
}
return false;
}
bool KisSnapshotModel::slotRemoveActivatedSnapshot()
{
return false;
}
bool KisSnapshotModel::slotSwitchToActivatedSnapshot(const QModelIndex &index)
{
if (!index.isValid() || index.row() >= m_d->curDocList.size()) {
return false;
}
return m_d->switchToDocument(m_d->curDocList[index.row()].second);
}
......@@ -33,7 +33,14 @@ public:
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
void setCanvas(QPointer<KisCanvas2> canvas);
public Q_SLOTS:
bool slotCreateSnapshot();
bool slotRemoveActivatedSnapshot();
bool slotSwitchToActivatedSnapshot(const QModelIndex &index);
private:
struct Private;
QScopedPointer<Private> m_d;
......
......@@ -32,8 +32,9 @@
struct SnapshotDocker::Private
{
Private();
~Private();
QPointer<KisSnapshotModel> model;
QScopedPointer<KisSnapshotModel> model;
QPointer<QListView> view;
QPointer<KisCanvas2> canvas;
QPointer<QToolButton> bnAdd;
......@@ -49,18 +50,26 @@ SnapshotDocker::Private::Private()
{
}
SnapshotDocker::Private::~Private()
{
}
SnapshotDocker::SnapshotDocker()
: QDockWidget()
, m_d(new Private)
{
QWidget *widget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(widget);
connect(m_d->view, &QListView::activated, m_d->model.data(), &KisSnapshotModel::slotSwitchToActivatedSnapshot);
m_d->view->setModel(m_d->model.data());
mainLayout->addWidget(m_d->view);
QHBoxLayout *buttonsLayout = new QHBoxLayout(widget);
m_d->bnAdd->setIcon(KisIconUtils::loadIcon("addlayer"));
connect(m_d->bnAdd, &QToolButton::clicked, m_d->model.data(), &KisSnapshotModel::slotCreateSnapshot);
buttonsLayout->addWidget(m_d->bnAdd);
m_d->bnRemove->setIcon(KisIconUtils::loadIcon("deletelayer"));
connect(m_d->bnRemove, &QToolButton::clicked, m_d->model.data(), &KisSnapshotModel::slotRemoveActivatedSnapshot);
buttonsLayout->addWidget(m_d->bnRemove);
mainLayout->addLayout(buttonsLayout);
......@@ -81,6 +90,7 @@ void SnapshotDocker::setCanvas(KoCanvasBase *canvas)
}
}
m_d->canvas = c;
m_d->model->setCanvas(c);
}
void SnapshotDocker::unsetCanvas()
......
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