0.1.18
by Michael Ellerman
Split out HunkSelector class. |
1 |
#!/usr/bin/python
|
2 |
||
0.1.48
by Michael Ellerman
Move UserInteractor into a seperate file. |
3 |
from userinteractor import UserInteractor, UserOption |
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
4 |
import copy |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
5 |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
6 |
class HunkSelector: |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
7 |
strings = {} |
8 |
||
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
9 |
def __init__(self, patches): |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
10 |
self.standard_options = [ |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
11 |
UserOption('y', self._selected, self.strings['select_desc'], |
12 |
default=True), |
|
13 |
UserOption('n', self._unselected, self.strings['unselect_desc']), |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
14 |
UserOption('d', UserInteractor.FINISH, 'done, skip to the end.'), |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
15 |
UserOption('i', self._invert, |
0.1.49
by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully |
16 |
'invert the current selection status of all hunks.'), |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
17 |
UserOption('s', self._status, |
18 |
'show selection status of all hunks.'), |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
19 |
UserOption('q', UserInteractor.QUIT, 'quit') |
20 |
]
|
|
21 |
||
22 |
self.end_options = [ |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
23 |
UserOption('y', UserInteractor.FINISH, self.strings['finish_desc'], |
24 |
default=True), |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
25 |
UserOption('r', UserInteractor.RESTART, |
26 |
'restart the hunk selection loop.'), |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
27 |
UserOption('s', self._status, |
28 |
'show selection status of all hunks.'), |
|
29 |
UserOption('i', self._invert, |
|
0.1.49
by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully |
30 |
'invert the current selection status of all hunks.'), |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
31 |
UserOption('q', UserInteractor.QUIT, 'quit') |
32 |
]
|
|
33 |
||
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
34 |
self.patches = patches |
35 |
self.total_hunks = 0 |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
36 |
|
37 |
self.interactor = UserInteractor() |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
38 |
self.interactor.set_item_callback(self._hunk_callback) |
39 |
self.interactor.set_start_callback(self._start_callback) |
|
40 |
self.interactor.set_end_callback(self._end_callback) |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
41 |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
42 |
for patch in patches: |
43 |
for hunk in patch.hunks: |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
44 |
# everything's selected by default
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
45 |
hunk.selected = True |
46 |
self.total_hunks += 1 |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
47 |
# we need a back pointer in the callbacks
|
48 |
hunk.patch = patch |
|
49 |
self.interactor.add_item(hunk) |
|
50 |
||
51 |
# Called at the start of the main loop
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
52 |
def _start_callback(self): |
0.1.51
by Michael Ellerman
Restart after a done was broken, and we weren't resetting the print logic at |
53 |
self.last_printed = -1 |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
54 |
self.interactor.set_prompt(self.strings['prompt']) |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
55 |
self.interactor.set_options(self.standard_options) |
56 |
||
57 |
# Called at the end of the item loop, return False to indicate that the
|
|
58 |
# interaction isn't finished and the confirmation prompt should be displayed
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
59 |
def _end_callback(self): |
60 |
self._status() |
|
61 |
self.interactor.set_prompt(self.strings['end_prompt']) |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
62 |
self.interactor.set_options(self.end_options) |
63 |
return False |
|
64 |
||
65 |
# Called once for each hunk
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
66 |
def _hunk_callback(self, hunk, count): |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
67 |
if self.last_printed != count: |
68 |
print hunk.patch.get_header(), hunk |
|
69 |
self.last_printed = count |
|
70 |
||
71 |
if hunk.selected: |
|
0.1.49
by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully |
72 |
self.interactor.get_option('y').default = True |
73 |
self.interactor.get_option('n').default = False |
|
74 |
else: |
|
75 |
self.interactor.get_option('y').default = False |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
76 |
self.interactor.get_option('n').default = True |
77 |
||
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
78 |
# The user chooses to (un)shelve a hunk
|
79 |
def _selected(self, hunk): |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
80 |
hunk.selected = True |
81 |
return True |
|
82 |
||
83 |
# The user chooses to keep a hunk
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
84 |
def _unselected(self, hunk): |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
85 |
hunk.selected = False |
86 |
return True |
|
87 |
||
88 |
# The user chooses to invert the selection
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
89 |
def _invert(self, hunk): |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
90 |
for patch in self.patches: |
91 |
for hunk in patch.hunks: |
|
92 |
if hunk.__dict__.has_key('selected'): |
|
93 |
hunk.selected = not hunk.selected |
|
94 |
else: |
|
95 |
hunk.selected = True |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
96 |
self._status() |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
97 |
return False |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
98 |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
99 |
# The user wants to see the status
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
100 |
def _status(self, hunk=None): |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
101 |
print '\nStatus:' |
102 |
for patch in self.patches: |
|
103 |
print ' %s' % patch.oldname |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
104 |
selected = 0 |
105 |
unselected = 0 |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
106 |
for hunk in patch.hunks: |
107 |
if hunk.selected: |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
108 |
selected += 1 |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
109 |
else: |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
110 |
unselected += 1 |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
111 |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
112 |
print ' ', self.strings['status_selected'] % selected |
113 |
print ' ', self.strings['status_unselected'] % unselected |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
114 |
print
|
115 |
||
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
116 |
# Tell the interactor we're not done with this item
|
117 |
return False |
|
118 |
||
119 |
def select(self): |
|
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
120 |
if self.total_hunks == 0 or not self.interactor.interact(): |
121 |
# False from interact means they chose to quit
|
|
122 |
return ([], []) |
|
123 |
||
124 |
# Go through each patch and collect all selected/unselected hunks
|
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
125 |
for patch in self.patches: |
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
126 |
patch.selected = [] |
127 |
patch.unselected = [] |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
128 |
for hunk in patch.hunks: |
129 |
if hunk.selected: |
|
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
130 |
patch.selected.append(hunk) |
131 |
else: |
|
132 |
patch.unselected.append(hunk) |
|
133 |
||
134 |
# Now build two lists, one of selected patches the other unselected
|
|
135 |
selected_patches = [] |
|
136 |
unselected_patches = [] |
|
137 |
||
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
138 |
for patch in self.patches: |
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
139 |
if len(patch.selected): |
140 |
tmp = copy.copy(patch) |
|
141 |
tmp.hunks = tmp.selected |
|
142 |
del tmp.selected |
|
143 |
del tmp.unselected |
|
144 |
selected_patches.append(tmp) |
|
145 |
||
146 |
if len(patch.unselected): |
|
147 |
tmp = copy.copy(patch) |
|
148 |
tmp.hunks = tmp.unselected |
|
149 |
del tmp.selected |
|
150 |
del tmp.unselected |
|
151 |
unselected_patches.append(tmp) |
|
152 |
||
153 |
return (selected_patches, unselected_patches) |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
154 |
|
155 |
class ShelveHunkSelector(HunkSelector): |
|
156 |
def __init__(self, patches): |
|
157 |
self.strings = {} |
|
158 |
self.strings['status_selected'] = '%d hunks to be shelved' |
|
159 |
self.strings['status_unselected'] = '%d hunks to be kept' |
|
160 |
self.strings['select_desc'] = 'shelve this change.' |
|
161 |
self.strings['unselect_desc'] = 'keep this change in your tree.' |
|
162 |
self.strings['finish_desc'] = 'shelve selected changes.' |
|
163 |
self.strings['prompt'] = 'Shelve this change? (%(count)d of %(total)d)' |
|
164 |
self.strings['end_prompt'] = 'Shelve these changes?' |
|
165 |
HunkSelector.__init__(self, patches) |
|
166 |
||
167 |
class UnshelveHunkSelector(HunkSelector): |
|
168 |
def __init__(self, patches): |
|
169 |
self.strings = {} |
|
170 |
self.strings['status_selected'] = '%d hunks to be unshelved' |
|
171 |
self.strings['status_unselected'] = '%d hunks left on shelf' |
|
172 |
self.strings['select_desc'] = 'unshelve this change.' |
|
173 |
self.strings['unselect_desc'] = 'leave this change on the shelf.' |
|
174 |
self.strings['finish_desc'] = 'unshelve selected changes.' |
|
175 |
self.strings['prompt'] = 'Unshelve this change? ' \ |
|
176 |
'(%(count)d of %(total)d)' |
|
177 |
self.strings['end_prompt'] = 'Unshelve these changes?' |
|
178 |
HunkSelector.__init__(self, patches) |