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):
81 data_dict = copy.deepcopy(self.
values)
83 data_dict = {
"type": self.
type,
85 "value": copy.deepcopy(self.
values),
90 if "history" in data_dict:
91 data_dict.pop(
"history")
95 update_action_dict = data_dict
98 update_action_dict = [data_dict]
101 return json.dumps(update_action_dict)
108 update_action_dict = json.loads(value)
111 self.
type = update_action_dict.get(
"type")
112 self.
key = update_action_dict.get(
"key")
113 self.
values = update_action_dict.get(
"value")
114 self.
old_values = update_action_dict.get(
"old_values")
135 self.redoHistory.clear()
136 self.actionHistory.clear()
139 history = project.get([
"history"])
142 for actionDict
in history.get(
"redo", []):
143 if "history" not in actionDict.keys():
145 action.load_json(json.dumps(actionDict))
146 self.redoHistory.append(action)
147 for actionDict
in history.get(
"undo", []):
148 if "history" not in actionDict.keys():
150 action.load_json(json.dumps(actionDict))
151 self.actionHistory.append(action)
163 history_length_int = int(history_length)
164 for action
in self.
redoHistory[-history_length_int:]:
165 redo_list.append(json.loads(action.json()))
167 undo_list.append(json.loads(action.json()))
171 self.
update([
"history"], {
"redo": redo_list,
"undo": undo_list})
177 self.actionHistory.clear()
178 self.redoHistory.clear()
187 self.updateListeners.append(listener)
190 self.updateListeners.insert(index, listener)
192 log.warning(
"Listener already added.")
199 self.statusWatchers.append(watcher)
201 log.warning(
"Watcher already added.")
210 watcher.updateStatusChanged(*new_status)
222 reverse =
UpdateAction(action.type, action.key, action.values, action.partial_update)
224 if action.type ==
"insert":
225 reverse.type =
"delete"
228 id = action.values[
"id"]
229 action.key.append({
"id": id})
232 elif action.type ==
"delete":
233 reverse.type =
"insert"
235 if reverse.type ==
"insert" and isinstance(reverse.key[-1], dict)
and "id" in reverse.key[-1]:
236 reverse.key = reverse.key[:-1]
240 reverse.old_values = action.values
241 reverse.values = action.old_values
252 last_action = copy.deepcopy(self.actionHistory.pop())
254 self.redoHistory.append(last_action)
265 next_action = copy.deepcopy(self.redoHistory.pop())
268 if next_action.type ==
"insert" and isinstance(next_action.key[-1], dict)
and "id" in next_action.key[-1]:
269 next_action.key = next_action.key[:-1]
271 self.actionHistory.append(next_action)
284 listener.changed(action)
286 except Exception
as ex:
287 log.error(
"Couldn't apply '{}' to update listener: {}\n{}".format(action.type, listener, ex))
296 self.redoHistory.clear()
305 self.redoHistory.clear()
312 def update(self, key, values, partial_update=False):
315 self.redoHistory.clear()
325 self.redoHistory.clear()
334 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).