3 from PyQt4
.QtGui
import QDialog
4 from PyQt4
.QtGui
import QFont
7 from ugit
import qtutils
8 from ugit
.model
import Model
9 from ugit
.views
import BranchGUI
10 from ugit
.views
import CommitGUI
11 from ugit
.views
import OptionsGUI
12 from ugit
.views
import OutputGUI
13 from ugit
.qobserver
import QObserver
15 def set_diff_font(model
, widget
):
16 if model
.has_param('global_ugit_fontdiff'):
17 font
= model
.get_param('global_ugit_fontdiff')
23 def choose_branch(title
, parent
, branches
):
24 dlg
= BranchGUI(parent
,branches
)
25 dlg
.setWindowTitle(dlg
.tr(title
))
26 return dlg
.get_selected()
28 def select_commits(model
, parent
, title
, revs
, summaries
):
29 '''Use the CommitGUI to select commits from a list.'''
31 model
.set_revisions(revs
)
32 model
.set_summaries(summaries
)
33 view
= CommitGUI(parent
, title
)
34 ctl
= SelectCommitsController(model
, view
)
35 return ctl
.select_commits()
37 class SelectCommitsController(QObserver
):
38 def __init__(self
, model
, view
):
39 QObserver
.__init
__(self
, model
, view
)
40 set_diff_font(model
, self
.view
.commit_text
)
41 self
.connect(view
.commit_list
, 'itemSelectionChanged()',
42 self
.commit_sha1_selected
)
44 def select_commits(self
):
45 summaries
= self
.model
.get_summaries()
47 msg
= self
.tr('No commits exist in this branch.')
48 qtutils
.show_output(msg
)
50 qtutils
.set_items(self
.view
.commit_list
, summaries
)
52 if self
.view
.exec_() != QDialog
.Accepted
:
54 revs
= self
.model
.get_revisions()
55 list_widget
= self
.view
.commit_list
56 return qtutils
.get_selection_list(list_widget
, revs
)
58 def commit_sha1_selected(self
):
59 row
, selected
= qtutils
.get_selected_row(self
.view
.commit_list
)
61 self
.view
.commit_text
.setText('')
62 self
.view
.revision
.setText('')
65 # Get the sha1 and put it in the revision line
66 sha1
= self
.model
.get_revision_sha1(row
)
67 self
.view
.revision
.setText(sha1
)
68 self
.view
.revision
.selectAll()
70 # Lookup the sha1's commit
71 commit_diff
= self
.model
.get_commit_diff(sha1
)
72 self
.view
.commit_text
.setText(commit_diff
)
74 # Copy the sha1 into the clipboard
75 qtutils
.set_clipboard(sha1
)
77 def search_revisions(model
, parent
):
79 view
= CommitGUI(parent
, 'Search Revisions')
80 ctl
= SearchRevisionsController(model
, view
)
82 view
.revision
.setFocus()
83 return view
.exec_() == QDialog
.Accepted
85 class SearchRevisionsController(QObserver
):
86 def __init__(self
, model
, view
):
87 QObserver
.__init
__(self
,model
,view
)
88 set_diff_font(model
, self
.view
.commit_text
)
90 self
.add_observables('revision')
91 self
.add_actions('revision', self
.search_revisions
)
92 self
.connect(view
.commit_list
, 'itemSelectionChanged()',
94 self
.connect(view
.commit_text
, 'cursorPositionChanged()',
96 self
.connect(view
.commit_list
,
97 'itemDoubleClicked(QListWidgetItem*)',
98 self
.doubleclick_format_patch
)
99 self
.last_time
= time
.time()
100 self
.updates_enabled
= True
102 (self
.revisions
, self
.summaries
) = \
103 self
.model
.log_helper(all
=True)
105 def search_revisions(self
, *rest
):
106 if time
.time() - self
.last_time
< 0.2:
107 self
.last_time
= time
.time()
109 if not self
.updates_enabled
:
113 revision
= self
.model
.get_revision()
114 if len(revision
) < 2: return
116 for idx
, rev
in enumerate(self
.revisions
):
117 if rev
.startswith(revision
):
118 self
.found
.append(idx
)
120 self
.view
.commit_list
.clear()
121 for idx
in self
.found
:
122 summary
= self
.summaries
[idx
]
123 self
.view
.commit_list
.addItem(summary
)
125 def _get_sha1_from_gui_index(self
, gui_idx
):
128 idx
= self
.found
[gui_idx
]
129 summary
= self
.summaries
[idx
]
130 revision
= self
.revisions
[idx
]
133 def show_revision(self
, gui_idx
):
134 revision
= self
._get
_sha
1_from
_gui
_index
(gui_idx
)
135 qtutils
.set_clipboard(revision
)
136 diff
= self
.model
.get_commit_diff(revision
)
137 self
.updates_enabled
= False
138 self
.view
.commit_text
.setText(diff
)
139 self
.updates_enabled
= True
141 def select_summary(self
,*args
):
142 if not self
.updates_enabled
: return
143 row
, selected
= qtutils
.get_selected_row(
144 self
.view
.commit_list
)
145 if not selected
or row
>= len(self
.found
):
147 revision
= self
._get
_sha
1_from
_gui
_index
(row
)
150 # Inhibit doing a new search when we set the revision field
152 self
.updates_enabled
= False
154 self
.view
.revision
.setText(revision
)
155 self
.view
.revision
.selectAll()
156 self
.view
.revision
.setFocus()
157 self
.show_revision(row
)
159 self
.updates_enabled
= True
161 def doubleclick_format_patch(self
, item
):
162 row
= self
.view
.commit_list
.row(item
)
163 idx
= self
.found
[row
]
164 revision
= self
.revisions
[idx
]
165 output
= self
.model
.format_patch_helper(revision
)
166 qtutils
.log(output
, quiet
=False, doraise
=True)
168 def update_options(model
, parent
):
169 view
= OptionsGUI(parent
)
170 ctl
= OptionsController(model
,view
)
172 return view
.exec_() == QDialog
.Accepted
174 class OptionsController(QObserver
):
176 This controller assumes that the view's widgets are named
177 the same as the model parameters.'''
179 def __init__(self
,model
,view
):
181 # used for telling about interactive font changes
182 self
.original_model
= model
183 model
= model
.clone()
185 QObserver
.__init
__(self
,model
,view
)
186 self
.add_observables(
189 'local_merge_summary',
190 'local_merge_diffstat',
191 'local_merge_verbosity',
192 'local_gui_diffcontext',
195 'global_merge_summary',
196 'global_merge_diffstat',
197 'global_merge_verbosity',
198 'global_gui_diffcontext',
199 'global_ugit_fontdiff_size',
200 'global_ugit_fontdiff',
201 'global_ugit_fontui_size',
202 'global_ugit_fontui',
203 'global_ugit_historybrowser',
204 'global_ugit_savewindowsettings',
205 'global_ugit_saveatexit',
207 self
.add_actions('global_ugit_fontdiff_size', self
.update_size
)
208 self
.add_actions('global_ugit_fontui_size', self
.update_size
)
209 self
.add_actions('global_ugit_fontdiff', self
.tell_parent_model
)
210 self
.add_actions('global_ugit_fontui', self
.tell_parent_model
)
211 self
.add_callbacks(save_button
= self
.save_settings
)
212 self
.connect(self
.view
, 'rejected()', self
.restore_settings
)
215 self
.backup_model
= self
.model
.clone()
217 def refresh_view(self
):
218 font
= self
.model
.get_param('global_ugit_fontui')
220 size
= int(font
.split(',')[1])
221 self
.view
.global_ugit_fontui_size
.setValue(size
)
222 self
.model
.set_global_ugit_fontui_size(size
)
224 fontui
.fromString(font
)
225 self
.view
.global_ugit_fontui
.setCurrentFont(fontui
)
227 font
= self
.model
.get_global_ugit_fontdiff()
229 size
= int(font
.split(',')[1])
230 self
.view
.global_ugit_fontdiff_size
.setValue(size
)
231 self
.model
.set_global_ugit_fontdiff_size(size
)
233 fontdiff
.fromString(font
)
234 self
.view
.global_ugit_fontdiff
.setCurrentFont(fontdiff
)
236 self
.view
.local_groupbox
.setTitle(
237 unicode(self
.tr('%s Repository'))
238 % self
.model
.get_project())
239 QObserver
.refresh_view(self
)
242 def save_settings(self
):
244 params
= self
.model
.get_config_params()
246 value
= self
.model
.get_param(param
)
247 backup
= self
.backup_model
.get_param(param
)
249 params_to_save
.append(param
)
250 for param
in params_to_save
:
251 self
.model
.save_config_param(param
)
253 self
.original_model
.copy_params(self
.model
, params_to_save
)
254 self
.view
.done(QDialog
.Accepted
)
256 # cancel button -> undo changes
257 def restore_settings(self
):
258 params
= self
.backup_model
.get_config_params()
259 self
.model
.copy_params(self
.backup_model
, params
)
260 self
.tell_parent_model()
262 def tell_parent_model(self
,*rest
):
264 'global_ugit_fontdiff',
265 'global_ugit_fontui',
266 'global_ugit_fontdiff_size',
267 'global_ugit_fontui_size',
268 'global_ugit_savewindowsettings',
269 'global_ugit_saveatexit',
272 self
.original_model
.set_param(
273 param
, self
.model
.get_param(param
))
275 def update_size(self
, *rest
):
276 combo
= self
.view
.global_ugit_fontui
277 param
= str(combo
.objectName())
278 default
= str(combo
.currentFont().toString())
279 self
.model
.apply_font_size(param
, default
)
281 combo
= self
.view
.global_ugit_fontdiff
282 param
= str(combo
.objectName())
283 default
= str(combo
.currentFont().toString())
284 self
.model
.apply_font_size(param
, default
)
286 self
.tell_parent_model()
288 def log_window(parent
):
289 model
= Model( search_text
= '' )
290 view
= OutputGUI(parent
)
291 ctl
= LogWindowController(model
,view
)
294 class LogWindowController(QObserver
):
295 def __init__(self
, model
, view
):
296 QObserver
.__init
__(self
, model
, view
)
298 self
.add_observables('search_text')
299 self
.add_actions('search_text', self
.insta_search
)
301 clear_button
= self
.clear
,
302 next_button
= self
.next
,
303 prev_button
= self
.prev
,
305 self
.connect(self
.view
.output_text
,
306 'cursorPositionChanged()',
307 self
.cursor_position_changed
)
308 self
.search_offset
= 0
310 def insta_search(self
,*rest
):
311 self
.search_offset
= 0
312 txt
= self
.model
.get_search_text().lower()
316 cursor
= self
.view
.output_text
.textCursor()
317 cursor
.clearSelection()
318 self
.view
.output_text
.setTextCursor(cursor
)
321 self
.view
.output_text
.clear()
322 self
.search_offset
= 0
325 text
= self
.model
.get_search_text().lower().strip()
327 output
= str(self
.view
.output_text
.toPlainText())
328 if self
.search_offset
+ len(text
) > len(output
):
329 answer
= qtutils
.question(
331 unicode(self
.tr("%s not found")) % text
,
333 "Could not find '%s'.\n"
334 "Search from the beginning?"
339 self
.search_offset
= 0
343 find_in
= output
[self
.search_offset
:].lower()
345 index
= find_in
.index(text
)
347 self
.search_offset
= 0
348 answer
= qtutils
.question(
350 unicode(self
.tr("%s not found")) % text
,
352 "Could not find '%s'.\n"
353 "Search from the beginning?"
359 cursor
= self
.view
.output_text
.textCursor()
360 offset
= self
.search_offset
+ index
361 new_offset
= offset
+ len(text
)
363 cursor
.setPosition(offset
)
364 cursor
.setPosition(new_offset
, cursor
.KeepAnchor
)
366 self
.view
.output_text
.setTextCursor(cursor
)
367 self
.search_offset
= new_offset
370 text
= self
.model
.get_search_text().lower().strip()
372 output
= str(self
.view
.output_text
.toPlainText())
373 if self
.search_offset
== 0:
374 self
.search_offset
= len(output
)
376 find_in
= output
[:self
.search_offset
].lower()
378 offset
= find_in
.rindex(text
)
380 self
.search_offset
= 0
383 unicode(self
.tr("%s not found")) % text
,
384 unicode(self
.tr("Could not find '%s'.\n"
385 "Search from the end?"
389 cursor
= self
.view
.output_text
.textCursor()
390 new_offset
= offset
+ len(text
)
392 cursor
.setPosition(offset
)
393 cursor
.setPosition(new_offset
, cursor
.KeepAnchor
)
395 self
.view
.output_text
.setTextCursor(cursor
)
396 self
.search_offset
= offset
398 def cursor_position_changed(self
):
399 cursor
= self
.view
.output_text
.textCursor()
400 self
.search_offset
= cursor
.selectionStart()