Mercurial > hg > svcore
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 |