comparison data/model/EventCommands.h @ 1648:86bbccb79c9b single-point

Switch to a single external set of commands for modifying editables with events
author Chris Cannam
date Fri, 15 Mar 2019 10:57:35 +0000
parents
children 9d82b164f264
comparison
equal deleted inserted replaced
1647:29a20719796e 1648:86bbccb79c9b
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006 Chris Cannam.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #ifndef SV_EVENT_COMMANDS_H
17 #define SV_EVENT_COMMANDS_H
18
19 #include "base/Event.h"
20 #include "base/Command.h"
21
22 /**
23 * Interface for classes that can be modified through these commands
24 */
25 class EventEditable
26 {
27 public:
28 virtual void add(Event e) = 0;
29 virtual void remove(Event e) = 0;
30 };
31
32 /**
33 * Command to add an event to an editable containing events, with undo.
34 */
35 class AddEventCommand : public Command
36 {
37 public:
38 AddEventCommand(EventEditable *editable, const Event &e, QString name) :
39 m_editable(editable), m_event(e), m_name(name) { }
40
41 QString getName() const override { return m_name; }
42 Event getEvent() const { return m_event; }
43
44 void execute() override { m_editable->add(m_event); }
45 void unexecute() override { m_editable->remove(m_event); }
46
47 private:
48 EventEditable *m_editable;
49 Event m_event;
50 QString m_name;
51 };
52
53 /**
54 * Command to remove an event from an editable containing events, with
55 * undo.
56 */
57 class RemoveEventCommand : public Command
58 {
59 public:
60 RemoveEventCommand(EventEditable *editable, const Event &e, QString name) :
61 m_editable(editable), m_event(e), m_name(name) { }
62
63 QString getName() const override { return m_name; }
64 Event getEvent() const { return m_event; }
65
66 void execute() override { m_editable->remove(m_event); }
67 void unexecute() override { m_editable->add(m_event); }
68
69 private:
70 EventEditable *m_editable;
71 Event m_event;
72 QString m_name;
73 };
74
75 /**
76 * Command to add or remove a series of events to or from an editable,
77 * with undo. Creates and immediately executes a sub-command for each
78 * add/remove requested. Consecutive add/remove pairs for the same
79 * point are collapsed.
80 */
81 class ChangeEventsCommand : public MacroCommand
82 {
83 public:
84 ChangeEventsCommand(EventEditable *editable, QString name) :
85 MacroCommand(name), m_editable(editable) { }
86
87 void add(Event e) {
88 addCommand(new AddEventCommand(m_editable, e, getName()), true);
89 }
90 void remove(Event e) {
91 addCommand(new RemoveEventCommand(m_editable, e, getName()), true);
92 }
93
94 /**
95 * Stack an arbitrary other command in the same sequence.
96 */
97 void addCommand(Command *command) override { addCommand(command, true); }
98
99 /**
100 * If any points have been added or deleted, return this
101 * command (so the caller can add it to the command history).
102 * Otherwise delete the command and return NULL.
103 */
104 ChangeEventsCommand *finish() {
105 if (!m_commands.empty()) {
106 return this;
107 } else {
108 delete this;
109 return nullptr;
110 }
111 }
112
113 protected:
114 virtual void addCommand(Command *command, bool executeFirst) {
115
116 if (executeFirst) command->execute();
117
118 if (m_commands.empty()) {
119 MacroCommand::addCommand(command);
120 return;
121 }
122
123 RemoveEventCommand *r =
124 dynamic_cast<RemoveEventCommand *>(command);
125 AddEventCommand *a =
126 dynamic_cast<AddEventCommand *>(*m_commands.rbegin());
127 if (r && a) {
128 if (a->getEvent() == r->getEvent()) {
129 deleteCommand(a);
130 return;
131 }
132 }
133
134 MacroCommand::addCommand(command);
135 }
136
137 EventEditable *m_editable;
138 };
139
140 #endif