3 from PyQt4
.QtGui
import QDialog
4 from PyQt4
.QtGui
import QFont
7 from qobserver
import QObserver
8 from views
import BranchGUI
9 from views
import CommitGUI
10 from views
import OptionsGUI
11 from views
import OutputGUI
12 from model
import Model
14 def set_diff_font(model
, widget
):
15 if model
.has_param('global_ugit_fontdiff'):
16 font
= model
.get_param('global_ugit_fontdiff')
22 def choose_branch(title
, parent
, branches
):
23 dlg
= BranchGUI(parent
,branches
)
24 dlg
.setWindowTitle(dlg
.tr(title
))
25 return dlg
.get_selected()
27 def select_commits(model
, parent
, title
, revs
, summaries
):
28 '''Use the CommitGUI to select commits from a list.'''
30 model
.set_revisions(revs
)
31 model
.set_summaries(summaries
)
32 view
= CommitGUI(parent
, title
)
33 ctl
= SelectCommitsController(model
, view
)
34 return ctl
.select_commits()
36 class SelectCommitsController(QObserver
):
37 def __init__(self
, model
, view
):
38 QObserver
.__init
__(self
, model
, view
)
39 set_diff_font(model
, self
.view
.commit_text
)
40 self
.connect(view
.commit_list
, 'itemSelectionChanged()',
41 self
.commit_sha1_selected
)
43 def select_commits(self
):
44 summaries
= self
.model
.get_summaries()
46 msg
= self
.tr('No commits exist in this branch.')
47 qtutils
.show_output(msg
)
49 qtutils
.set_items(self
.view
.commit_list
, summaries
)
51 if self
.view
.exec_() != QDialog
.Accepted
:
53 revs
= self
.model
.get_revisions()
54 list_widget
= self
.view
.commit_list
55 return qtutils
.get_selection_list(list_widget
, revs
)
57 def commit_sha1_selected(self
):
58 row
, selected
= qtutils
.get_selected_row(self
.view
.commit_list
)
60 self
.view
.commit_text
.setText('')
61 self
.view
.revision
.setText('')
64 # Get the sha1 and put it in the revision line
65 sha1
= self
.model
.get_revision_sha1(row
)
66 self
.view
.revision
.setText(sha1
)
67 self
.view
.revision
.selectAll()
69 # Lookup the sha1's commit
70 commit_diff
= self
.model
.get_commit_diff(sha1
)
71 self
.view
.commit_text
.setText(commit_diff
)
73 # Copy the sha1 into the clipboard
74 qtutils
.set_clipboard(sha1
)
76 def search_revisions(model
, parent
):
78 view
= CommitGUI(parent
, 'Search Revisions')
79 ctl
= SearchRevisionsController(model
, view
)
81 view
.revision
.setFocus()
82 return view
.exec_() == QDialog
.Accepted
84 class SearchRevisionsController(QObserver
):
85 def __init__(self
, model
, view
):
86 QObserver
.__init
__(self
,model
,view
)
87 set_diff_font(model
, self
.view
.commit_text
)
89 self
.add_observables('revision')
90 self
.add_actions('revision', self
.search_revisions
)
91 self
.connect(view
.commit_list
, 'itemSelectionChanged()',
93 self
.connect(view
.commit_text
, 'cursorPositionChanged()',
95 self
.connect(view
.commit_list
,
96 'itemDoubleClicked(QListWidgetItem*)',
97 self
.doubleclick_format_patch
)
98 self
.last_time
= time
.time()
99 self
.updates_enabled
= True
101 (self
.revisions
, self
.summaries
) = \
102 self
.model
.log_helper(all
=True)
104 def search_revisions(self
, *rest
):
105 if time
.time() - self
.last_time
< 0.2:
106 self
.last_time
= time
.time()
108 if not self
.updates_enabled
:
112 revision
= self
.model
.get_revision()
113 if len(revision
) < 2: return
115 for idx
, rev
in enumerate(self
.revisions
):
116 if rev
.startswith(revision
):
117 self
.found
.append(idx
)
119 self
.view
.commit_list
.clear()
120 for idx
in self
.found
:
121 summary
= self
.summaries
[idx
]
122 self
.view
.commit_list
.addItem(summary
)
124 def _get_sha1_from_gui_index(self
, gui_idx
):
127 idx
= self
.found
[gui_idx
]
128 summary
= self
.summaries
[idx
]
129 revision
= self
.revisions
[idx
]
132 def show_revision(self
, gui_idx
):
133 revision
= self
._get
_sha
1_from
_gui
_index
(gui_idx
)
134 qtutils
.set_clipboard(revision
)
135 diff
= self
.model
.get_commit_diff(revision
)
136 self
.updates_enabled
= False
137 self
.view
.commit_text
.setText(diff
)
138 self
.updates_enabled
= True
140 def select_summary(self
,*args
):
141 if not self
.updates_enabled
: return
142 row
, selected
= qtutils
.get_selected_row(
143 self
.view
.commit_list
)
144 if not selected
or row
>= len(self
.found
):
146 revision
= self
._get
_sha
1_from
_gui
_index
(row
)
149 # Inhibit doing a new search when we set the revision field
151 self
.updates_enabled
= False
153 self
.view
.revision
.setText(revision
)
154 self
.view
.revision
.selectAll()
155 self
.view
.revision
.setFocus()
156 self
.show_revision(row
)
158 self
.updates_enabled
= True
160 def doubleclick_format_patch(self
, item
):
161 row
= self
.view
.commit_list
.row(item
)
162 idx
= self
.found
[row
]
163 revision
= self
.revisions
[idx
]
164 output
= self
.model
.format_patch_helper(revision
)
165 qtutils
.log(output
, quiet
=False, doraise
=True)
167 def update_options(model
, parent
):
168 view
= OptionsGUI(parent
)
169 ctl
= OptionsController(model
,view
)
171 return view
.exec_() == QDialog
.Accepted
173 class OptionsController(QObserver
):
175 This controller assumes that the view's widgets are named
176 the same as the model parameters.'''
178 def __init__(self
,model
,view
):
180 # used for telling about interactive font changes
181 self
.original_model
= model
182 model
= model
.clone()
184 QObserver
.__init
__(self
,model
,view
)
185 self
.add_observables(
188 'local_merge_summary',
189 'local_merge_diffstat',
190 'local_merge_verbosity',
191 'local_gui_diffcontext',
194 'global_merge_summary',
195 'global_merge_diffstat',
196 'global_merge_verbosity',
197 'global_gui_diffcontext',
198 'global_ugit_fontdiff_size',
199 'global_ugit_fontdiff',
200 'global_ugit_fontui_size',
201 'global_ugit_fontui',
202 'global_ugit_historybrowser',
203 'global_ugit_savewindowsettings',
204 'global_ugit_saveatexit',
206 self
.add_actions('global_ugit_fontdiff_size', self
.update_size
)
207 self
.add_actions('global_ugit_fontui_size', self
.update_size
)
208 self
.add_actions('global_ugit_fontdiff', self
.tell_parent_model
)
209 self
.add_actions('global_ugit_fontui', self
.tell_parent_model
)
210 self
.add_callbacks(save_button
= self
.save_settings
)
211 self
.connect(self
.view
, 'rejected()', self
.restore_settings
)
214 self
.backup_model
= self
.model
.clone()
216 def refresh_view(self
):
217 font
= self
.model
.get_param('global_ugit_fontui')
219 size
= int(font
.split(',')[1])
220 self
.view
.global_ugit_fontui_size
.setValue(size
)
221 self
.model
.set_global_ugit_fontui_size(size
)
223 fontui
.fromString(font
)
224 self
.view
.global_ugit_fontui
.setCurrentFont(fontui
)
226 font
= self
.model
.get_global_ugit_fontdiff()
228 size
= int(font
.split(',')[1])
229 self
.view
.global_ugit_fontdiff_size
.setValue(size
)
230 self
.model
.set_global_ugit_fontdiff_size(size
)
232 fontdiff
.fromString(font
)
233 self
.view
.global_ugit_fontdiff
.setCurrentFont(fontdiff
)
235 self
.view
.local_groupbox
.setTitle(
236 unicode(self
.tr('%s Repository'))
237 % self
.model
.get_project())
238 QObserver
.refresh_view(self
)
241 def save_settings(self
):
243 params
= self
.model
.get_config_params()
245 value
= self
.model
.get_param(param
)
246 backup
= self
.backup_model
.get_param(param
)
248 params_to_save
.append(param
)
249 for param
in params_to_save
:
250 self
.model
.save_config_param(param
)
252 self
.original_model
.copy_params(self
.model
, params_to_save
)
253 self
.view
.done(QDialog
.Accepted
)
255 # cancel button -> undo changes
256 def restore_settings(self
):
257 params
= self
.backup_model
.get_config_params()
258 self
.model
.copy_params(self
.backup_model
, params
)
259 self
.tell_parent_model()
261 def tell_parent_model(self
,*rest
):
263 'global_ugit_fontdiff',
264 'global_ugit_fontui',
265 'global_ugit_fontdiff_size',
266 'global_ugit_fontui_size',
267 'global_ugit_savewindowsettings',
268 'global_ugit_saveatexit',
271 self
.original_model
.set_param(
272 param
, self
.model
.get_param(param
))
274 def update_size(self
, *rest
):
275 combo
= self
.view
.global_ugit_fontui
276 param
= str(combo
.objectName())
277 default
= str(combo
.currentFont().toString())
278 self
.model
.apply_font_size(param
, default
)
280 combo
= self
.view
.global_ugit_fontdiff
281 param
= str(combo
.objectName())
282 default
= str(combo
.currentFont().toString())
283 self
.model
.apply_font_size(param
, default
)
285 self
.tell_parent_model()
287 def log_window(parent
):
288 model
= Model( search_text
= '' )
289 view
= OutputGUI(parent
)
290 ctl
= LogWindowController(model
,view
)
293 class LogWindowController(QObserver
):
294 def __init__(self
, model
, view
):
295 QObserver
.__init
__(self
, model
, view
)
297 self
.add_observables('search_text')
298 self
.add_actions('search_text', self
.insta_search
)
300 clear_button
= self
.clear
,
301 next_button
= self
.next
,
302 prev_button
= self
.prev
,
304 self
.connect(self
.view
.output_text
,
305 'cursorPositionChanged()',
306 self
.cursor_position_changed
)
307 self
.search_offset
= 0
309 def insta_search(self
,*rest
):
310 self
.search_offset
= 0
311 txt
= self
.model
.get_search_text().lower()
315 cursor
= self
.view
.output_text
.textCursor()
316 cursor
.clearSelection()
317 self
.view
.output_text
.setTextCursor(cursor
)
320 self
.view
.output_text
.clear()
321 self
.search_offset
= 0
324 text
= self
.model
.get_search_text().lower().strip()
326 output
= str(self
.view
.output_text
.toPlainText())
327 if self
.search_offset
+ len(text
) > len(output
):
328 answer
= qtutils
.question(
330 unicode(self
.tr("%s not found")) % text
,
332 "Could not find '%s'.\n"
333 "Search from the beginning?"
338 self
.search_offset
= 0
342 find_in
= output
[self
.search_offset
:].lower()
344 index
= find_in
.index(text
)
346 self
.search_offset
= 0
347 answer
= qtutils
.question(
349 unicode(self
.tr("%s not found")) % text
,
351 "Could not find '%s'.\n"
352 "Search from the beginning?"
358 cursor
= self
.view
.output_text
.textCursor()
359 offset
= self
.search_offset
+ index
360 new_offset
= offset
+ len(text
)
362 cursor
.setPosition(offset
)
363 cursor
.setPosition(new_offset
, cursor
.KeepAnchor
)
365 self
.view
.output_text
.setTextCursor(cursor
)
366 self
.search_offset
= new_offset
369 text
= self
.model
.get_search_text().lower().strip()
371 output
= str(self
.view
.output_text
.toPlainText())
372 if self
.search_offset
== 0:
373 self
.search_offset
= len(output
)
375 find_in
= output
[:self
.search_offset
].lower()
377 offset
= find_in
.rindex(text
)
379 self
.search_offset
= 0
382 unicode(self
.tr("%s not found")) % text
,
383 unicode(self
.tr("Could not find '%s'.\n"
384 "Search from the end?"
388 cursor
= self
.view
.output_text
.textCursor()
389 new_offset
= offset
+ len(text
)
391 cursor
.setPosition(offset
)
392 cursor
.setPosition(new_offset
, cursor
.KeepAnchor
)
394 self
.view
.output_text
.setTextCursor(cursor
)
395 self
.search_offset
= offset
397 def cursor_position_changed(self
):
398 cursor
= self
.view
.output_text
.textCursor()
399 self
.search_offset
= cursor
.selectionStart()