File: Actions.hh

package info (click to toggle)
cadabra2 2.4.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 78,732 kB
  • sloc: ansic: 133,450; cpp: 92,064; python: 1,530; javascript: 203; sh: 184; xml: 182; objc: 53; makefile: 51
file content (239 lines) | stat: -rw-r--r-- 6,811 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

#pragma once

#include "DataCell.hh"
#include "DocumentThread.hh"

#include <memory>

namespace cadabra {

	class DocumentThread;
	class GUIBase;

	/// \ingroup clientserver
	///
	/// All actions derive from the ActionBase object, which defines
	/// the interface they need to implement. These objects are used to
	/// pass (user) action instructions around.  They can be stored in
	/// undo/redo stacks. All actions run on the GUI thread. The
	/// update_gui members typically call members of the GUIBase class.
	/// Action objects are allowed to modify the DTree document doc,
	/// since they essentially contain code which is part of the
	/// DocumentThread object.
	///
	/// All modifications to the document are done by calling 'perform' with an
	/// action object. This enables us to implement an undo stack. This method
	/// will take care of making the actual change to the DTree document, and
	/// call back on the 'change' methods above to inform the derived class
	/// that a change has been made.


	class ActionBase {
		public:
			ActionBase(DataCell::id_t ref_id);

			/// Perform the action. This should update both the document
			/// tree data structure and the GUI. The latter is updated
			/// by calling relevant methods on the GUIBase object passed
			/// in.

			virtual void execute(DocumentThread&, GUIBase&);

			/// Revert the change to the DTree document and the GUI.

			virtual void revert(DocumentThread&, GUIBase&)=0;

			/// Can this action be undone?
			virtual bool undoable() const;

			DataCell::id_t  ref_id;
		protected:
			DTree::iterator ref;
		};

	/// \ingroup clientserver
	///
	/// Add a cell to the notebook.

	class ActionAddCell : public ActionBase {
		public:
			enum class Position { before, after, child };

			ActionAddCell(DataCell, DataCell::id_t  ref_, Position pos_);
			virtual ~ActionAddCell() {};

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

		private:
			// Keep track of the location where this cell is inserted into
			// the notebook.

			DataCell          newcell;
			DTree::iterator   newref;
			Position          pos;
			int               child_num;
		};


	/// \ingroup clientserver
	///
	/// Position the cursor relative to the indicated cell. If position is 'next' and
	/// there is no input cell following the indicated one, create a new one.

	class ActionPositionCursor : public ActionBase {
		public:
			enum class Position { in, next, previous };

			ActionPositionCursor(DataCell::id_t ref_id_, Position pos_);
			virtual ~ActionPositionCursor() {};

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

		private:
			bool              needed_new_cell;
			DTree::iterator   newref;
			Position          pos;
		};

	/// \ingroup clientserver
	///
	/// Update the running status of the indicated cell.

	class ActionSetRunStatus : public ActionBase {
		public:
			ActionSetRunStatus(DataCell::id_t ref_id_, bool running);
			virtual ~ActionSetRunStatus() {};

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

			virtual bool undoable() const override;
		private:
			DTree::iterator this_cell;
			bool            was_running_, new_running_;
		};


	/// \ingroup clientserver
	///
	/// Remove a cell and all its child cells from the document.

	class ActionRemoveCell : public ActionBase {
		public:
			ActionRemoveCell(DataCell::id_t ref_id_);
			virtual ~ActionRemoveCell();

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

		private:
			// Keep track of the location where this cell (and its child
			// cells) was in the notebook.  We keep a reference to the
			// parent cell and the index of the current cell as child of
			// that parent.

			DTree             removed_tree;
			DTree::iterator   reference_parent_cell;
			size_t            reference_child_index;
		};

	/// \ingroup clientserver
	///
	/// Split a cell into two separate cells, at the point of the cursor.

	class ActionSplitCell : public ActionBase {
		public:
			ActionSplitCell(DataCell::id_t ref_id);
			virtual ~ActionSplitCell();

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

		private:
			DTree::iterator newref; // the newly created cell
		};


	/// \ingroup clientserver
	///
	/// Add a text string (can be just a single character) at the point
	/// of the cursor.
	/// This action is assumed to be triggered from a user change to
	/// the GUI cells, so will not update the GUI itself, only the
	/// underlying DTree. However, the revert method will need to
	/// update the GUI representation.

	class ActionInsertText : public ActionBase {
		public:
			ActionInsertText(DataCell::id_t ref_id, int pos, const std::string&);
			virtual ~ActionInsertText() {};

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

		private:
			DTree::iterator   this_cell;
			int         insert_pos;
			std::string text;
		};

	/// \ingroup clientserver
	///
	/// Complete text at a point in a GUI cell with one or more
	/// alternative.
	/// In contrast to ActionInsertText, this one is triggered from
	/// the server-side, so will update the GUI both for execute
	/// and revert.

	class ActionCompleteText : public ActionBase {
		public:
			ActionCompleteText(DataCell::id_t ref_id, int pos, const std::string&, int alternative);
			virtual ~ActionCompleteText() {};

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

			int length() const;
			int alternative() const;
			
		private:
			DTree::iterator   this_cell;
			int         insert_pos;
			std::string text;
			int         alternative_; // in case there is more than one completion alternative
		};

	/// \ingroup clientserver
	///
	/// Remove a text string starting at the indicated position, and
	/// with the indicated length, from the indicated cell.
	/// This action is assumed to be triggered from a user change to
	/// the GUI cells, so will not update the GUI itself, only the
	/// underlying DTree. However, the revert method will need to
	/// update the GUI representation.

	class ActionEraseText : public ActionBase {
		public:
			ActionEraseText(DataCell::id_t ref_id, int, int);
			virtual ~ActionEraseText() {};

			virtual void execute(DocumentThread&, GUIBase&) override;
			virtual void revert(DocumentThread&,  GUIBase&) override;

		private:
			DTree::iterator   this_cell;
			int from_pos, to_pos;
			std::string removed_text;
		};

	}


//
//       class ActionMergeCells