31 from classes.logger
import log
37 import simplejson
as json
47 raise NotImplementedError(
"updateStatus() not implemented in UpdateWatcher implementer.")
58 raise NotImplementedError(
"changed() not implemented in UpdateInterface implementer.")
65 def __init__(self, type=None, key=[], values=None, partial_update=False):
77 def json(self, is_array=False, only_value=False):
83 data_dict = {
"type": self.
type,
91 update_action_dict = data_dict
94 update_action_dict = [data_dict]
97 return json.dumps(update_action_dict)
104 update_action_dict = json.loads(value)
107 self.
type = update_action_dict.get(
"type")
108 self.
key = update_action_dict.get(
"key")
109 self.
values = update_action_dict.get(
"value")
110 self.
old_values = update_action_dict.get(
"old_values")
131 self.redoHistory.clear()
132 self.actionHistory.clear()
135 history = project.get([
"history"])
138 for actionDict
in history.get(
"redo", []):
140 action.load_json(json.dumps(actionDict))
141 self.redoHistory.append(action)
142 for actionDict
in history.get(
"undo", []):
144 action.load_json(json.dumps(actionDict))
145 self.actionHistory.append(action)
157 history_length_int = int(history_length)
158 for action
in self.
redoHistory[-history_length_int:]:
159 redo_list.append(json.loads(action.json()))
161 undo_list.append(json.loads(action.json()))
165 self.
update([
"history"], {
"redo": redo_list,
"undo": undo_list})
171 self.actionHistory.clear()
172 self.redoHistory.clear()
181 self.updateListeners.append(listener)
184 self.updateListeners.insert(index, listener)
186 log.warning(
"Listener already added.")
193 self.statusWatchers.append(watcher)
195 log.warning(
"Watcher already added.")
204 watcher.updateStatusChanged(*new_status)
216 reverse =
UpdateAction(action.type, action.key, action.values, action.partial_update)
218 if action.type ==
"insert":
219 reverse.type =
"delete"
222 id = action.values[
"id"]
223 action.key.append({
"id": id})
226 elif action.type ==
"delete":
227 reverse.type =
"insert"
229 if reverse.type ==
"insert" and isinstance(reverse.key[-1], dict)
and "id" in reverse.key[-1]:
230 reverse.key = reverse.key[:-1]
234 reverse.old_values = action.values
235 reverse.values = action.old_values
246 last_action = copy.deepcopy(self.actionHistory.pop())
248 self.redoHistory.append(last_action)
259 next_action = copy.deepcopy(self.redoHistory.pop())
262 if next_action.type ==
"insert" and isinstance(next_action.key[-1], dict)
and "id" in next_action.key[-1]:
263 next_action.key = next_action.key[:-1]
265 self.actionHistory.append(next_action)
278 listener.changed(action)
280 except Exception
as ex:
281 log.error(
"Couldn't apply '{}' to update listener: {}\n{}".format(action.type, listener, ex))
290 self.redoHistory.clear()
301 self.redoHistory.clear()
308 def update(self, key, values, partial_update=False):
311 self.redoHistory.clear()
321 self.redoHistory.clear()
330 self.last_action.set_old_values(previous_value)
def insert
Insert a new UpdateAction into the UpdateManager (this action will then be distributed to all listene...
def apply_last_action_to_history
Apply the last action to the history.
This class is used to track and distribute changes to listeners.
def add_watcher
Add a new watcher (which will invoke the updateStatusChanged() method each time a 'redo' or 'undo' ac...
def save_history
Save history to project.
def json
Get the JSON string representing this UpdateAction.
def update
Update the UpdateManager with an UpdateAction (this action will then be distributed to all listeners)...
def load_json
Load this UpdateAction from a JSON string.
def add_listener
Add a new listener (which will invoke the changed(action) method each time an UpdateAction is availab...
def dispatch_action
Distribute changes to all listeners (by calling their changed() method)
A data structure representing a single update manager action, including any necessary data to reverse...
def load_history
Load history from project.
def delete
Delete an item from the UpdateManager with an UpdateAction (this action will then be distributed to a...
def reset
Reset the UpdateManager, and clear all UpdateActions and History.
def redo
Redo the last UpdateAction (and notify all listeners and watchers)
def load
Load all project data via an UpdateAction into the UpdateManager (this action will then be distribute...
Interface for classes that listen for 'undo' and 'redo' events.
def get_reverse_action
Convert an UpdateAction into the opposite type (i.e.
def updateStatusChanged
Easily be notified each time there are 'undo' or 'redo' actions available in the UpdateManager.
def update_watchers
Notify all watchers if any 'undo' or 'redo' actions are available.
def undo
Undo the last UpdateAction (and notify all listeners and watchers)
def changed
This method is invoked each time the UpdateManager is changed.
Interface for classes that listen for changes (insert, update, and delete).