1// Aseprite
2// Copyright (C) 2019 Igara Studio S.A.
3// Copyright (C) 2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifndef APP_TX_H_INCLUDED
9#define APP_TX_H_INCLUDED
10#pragma once
11
12#include "app/app.h"
13#include "app/context.h"
14#include "app/doc.h"
15#include "app/transaction.h"
16
17#include <stdexcept>
18
19namespace app {
20
21 // Wrapper to create a new transaction or get the current
22 // transaction in the context.
23 class Tx {
24 public:
25 Tx(Context* ctx,
26 const std::string& label = "Transaction",
27 Modification mod = ModifyDocument)
28 {
29 m_doc = ctx->activeDocument();
30 if (!m_doc)
31 throw std::runtime_error("No active document to execute a transaction");
32
33 m_transaction = m_doc->transaction();
34 if (m_transaction)
35 m_owner = false;
36 else {
37 m_transaction = new Transaction(ctx, m_doc, label, mod);
38 m_doc->setTransaction(m_transaction);
39 m_owner = true;
40 }
41 }
42
43 // Use the default App context
44 Tx(const std::string& label = "Transaction", Modification mod = ModifyDocument)
45 : Tx(App::instance()->context(), label, mod) {
46 }
47
48 ~Tx() {
49 if (m_owner) {
50 m_doc->setTransaction(nullptr);
51 delete m_transaction;
52 }
53 }
54
55 void commit() {
56 if (m_owner)
57 m_transaction->commit();
58 }
59
60 void setNewDocRange(const DocRange& range) {
61 m_transaction->setNewDocRange(range);
62 }
63
64 void rollbackAndStartAgain() {
65 m_transaction->rollbackAndStartAgain();
66 }
67
68 // If the command cannot be executed, it will be deleted anyway.
69 void operator()(Cmd* cmd) {
70 m_transaction->execute(cmd);
71 }
72
73 operator Transaction&() {
74 return *m_transaction;
75 }
76
77 operator CmdTransaction*() {
78 return m_transaction->cmds();
79 }
80
81 private:
82 Doc* m_doc;
83 Transaction* m_transaction;
84 bool m_owner; // Owner of the transaction
85 };
86
87} // namespace app
88
89#endif
90