2 Maps Qt signals to Command objects.
4 The command factory listens to the global notifier and
5 creates commands objects as registered signals are
8 The factory itself is undoable in that it responds to
9 the undo and redo signals and manages the undo/redo stack.
13 from cola
import signals
18 """Return a static instance of the command factory."""
22 _factory
= CommandFactory()
26 def SLOT(signal
, *args
, **opts
):
28 Returns a callback that broadcasts a message over the notifier.
31 def broadcast(*local_args
, **opts
):
32 cola
.notifier().broadcast(signal
, *args
, **opts
)
36 class CommandFactory(object):
38 """Setup the undo/redo stacks and register for notifications."""
42 self
.signal_to_command
= {}
44 cola
.notifier().listen(signals
.undo
, self
.undo
)
45 cola
.notifier().listen(signals
.redo
, self
.redo
)
47 self
.model
= cola
.model()
48 self
.model
.add_observer(self
)
50 def add_command(self
, signal
, command
):
51 """Register a signal/command pair."""
52 self
.signal_to_command
[signal
] = command
53 cola
.notifier().listen(signal
, self
.cmdrunner(signal
))
55 def notify(self
, *params
):
57 Observe model changes.
59 This captures model parameters and maps them to signals that
60 are observed by the UIs.
64 'diff_text': SLOT(signals
.diff_text
, self
.model
.diff_text
),
65 'commitmsg': SLOT(signals
.editor_text
, self
.model
.commitmsg
),
66 'mode': SLOT(signals
.mode
, self
.model
.mode
),
69 action
= actions
.get(param
, lambda: None)
73 """Clear the undo and redo stacks."""
77 def cmdrunner(self
, signal
):
78 """Return a function to create and run a signal's command."""
79 def run(*args
, **opts
):
80 return self
.do(signal
, *args
, **opts
)
83 def do(self
, signal
, *args
, **opts
):
84 """Given a signal and arguments, run its corresponding command."""
85 cmdclass
= self
.signal_to_command
[signal
]
86 cmdobj
= cmdclass(*args
, **opts
)
87 # TODO we disable undo/redo for now; views just need to
88 # inspect the stack and add menu entries when we enable it.
89 if self
.undoable
and cmdobj
.is_undoable():
90 self
.undostack
.append(cmdobj
)
94 """Undo the last command and add it to the redo stack."""
96 cmdobj
= self
.undostack
.pop()
98 self
.redostack
.append(cmdobj
)
100 print 'warning: undo stack is empty, doing nothing'
103 """Redo the last command and add it to the undo stack."""
105 cmdobj
= self
.redostack
.pop()
107 self
.undo
.append(cmd
)
109 print 'warning: redo stack is empty, doing nothing'
111 def is_undoable(self
):
112 """Does the undo stack contain any commands?"""
113 return bool(self
.undostack
)
115 def is_redoable(self
):
116 """Does the redo stack contain any commands?"""
117 return bool(self
.redostack
)