2 from PyQt4
import QtGui
7 from cola
import gitcmd
8 from cola
import gitcmds
9 from cola
import qtutils
10 from cola
import signals
11 from cola
.views
import itemlist
12 from cola
.views
import combo
15 def install_command_wrapper(parent
):
16 wrapper
= CommandWrapper(parent
)
17 cola
.factory().add_command_wrapper(wrapper
)
20 class CommandWrapper(object):
21 def __init__(self
, parent
):
24 signals
.question
: self
._question
,
25 signals
.information
: self
._information
,
28 def _question(self
, title
, msg
):
29 return qtutils
.question(self
.parent
, title
, msg
)
31 def _information(self
, title
, msg
):
32 return qtutils
.information(self
.parent
, title
, msg
)
35 def choose_from_combo(title
, items
):
36 """Quickly choose an item from a list using a combo box"""
37 parent
= QtGui
.QApplication
.instance().activeWindow()
38 return combo
.ComboView(parent
,
40 items
=items
).selected()
43 def choose_from_list(title
, items
=None, dblclick
=None):
44 """Quickly choose an item from a list using a list widget"""
45 parent
= QtGui
.QApplication
.instance().activeWindow()
46 return itemlist
.ListView(parent
,
49 dblclick
=dblclick
).selected()
52 def slot_with_parent(fn
, parent
):
53 """Return an argument-less method for calling fn(parent=parent)
55 :param fn: - Function reference, must accept 'parent' as a keyword
56 :param parent: - Qt parent widget
65 """Launch the 'Delete Branch' dialog."""
66 branch
= choose_from_combo('Delete Branch',
67 cola
.model().local_branches
)
70 cola
.notifier().broadcast(signals
.delete_branch
, branch
)
74 """Diff against an arbitrary revision, branch, tag, etc."""
75 branch
= choose_from_combo('Select Branch, Tag, or Commit-ish',
77 cola
.model().all_branches() +
81 cola
.notifier().broadcast(signals
.diff_mode
, branch
)
85 """Launch the 'Browse Commits' dialog."""
86 from cola
.controllers
.selectcommits
import select_commits
88 revs
, summaries
= gitcmds
.log_helper(all
=True)
89 select_commits('Browse Commits', revs
, summaries
)
93 """Launch the 'Browse Current Branch' dialog."""
94 from cola
.controllers
.repobrowser
import browse_git_branch
96 browse_git_branch(gitcmds
.current_branch())
100 """Prompt for a branch and inspect content at that point in time."""
101 # Prompt for a branch to browse
102 from cola
.controllers
.repobrowser
import browse_git_branch
104 branch
= choose_from_combo('Browse Revision...', gitcmds
.all_refs())
107 # Launch the repobrowser
108 browse_git_branch(branch
)
111 def checkout_branch():
112 """Launch the 'Checkout Branch' dialog."""
113 branch
= choose_from_combo('Checkout Branch',
114 cola
.model().local_branches
)
117 cola
.notifier().broadcast(signals
.checkout_branch
, branch
)
121 """Launch the 'Cherry-Pick' dialog."""
122 from cola
.controllers
.selectcommits
import select_commits
124 revs
, summaries
= gitcmds
.log_helper(all
=True)
125 commits
= select_commits('Cherry-Pick Commit',
126 revs
, summaries
, multiselect
=False)
129 cola
.notifier().broadcast(signals
.cherry_pick
, commits
)
132 def clone_repo(parent
, spawn
=True):
134 Present GUI controls for cloning a repository
136 A new cola session is invoked when 'spawn' is True.
139 url
, ok
= qtutils
.prompt('Path or URL to clone (Env. $VARS okay)')
140 url
= os
.path
.expandvars(url
)
141 if not ok
or not url
:
144 # Pick a suitable basename by parsing the URL
145 newurl
= url
.replace('\\', '/')
146 default
= newurl
.rsplit('/', 1)[-1]
147 if default
== '.git':
148 # The end of the URL is /.git, so assume it's a file path
149 default
= os
.path
.basename(os
.path
.dirname(newurl
))
150 if default
.endswith('.git'):
151 # The URL points to a bare repo
152 default
= default
[:-4]
154 # The URL is the current repo
155 default
= os
.path
.basename(os
.getcwd())
159 cola
.notifier().broadcast(signals
.information
,
161 'Could not parse: "%s"' % url
)
162 qtutils
.log(1, 'Oops, could not parse git url: "%s"' % url
)
165 # Prompt the user for a directory to use as the parent directory
166 msg
= 'Select a parent directory for the new clone'
167 dirname
= qtutils
.opendir_dialog(parent
, msg
, cola
.model().getcwd())
171 destdir
= os
.path
.join(dirname
, default
)
173 if os
.path
.exists(destdir
):
174 # An existing path can be specified
175 msg
= ('"%s" already exists, cola will create a new directory' %
177 cola
.notifier().broadcast(signals
.information
,
178 'Directory Exists', msg
)
180 # Make sure the new destdir doesn't exist
181 while os
.path
.exists(destdir
):
182 destdir
= olddestdir
+ str(count
)
184 cola
.notifier().broadcast(signals
.clone
, url
, destdir
,
189 def export_patches():
190 """Run 'git format-patch' on a list of commits."""
191 from cola
.controllers
.selectcommits
import select_commits
193 revs
, summaries
= gitcmds
.log_helper()
194 to_export
= select_commits('Export Patches', revs
, summaries
)
199 cola
.notifier().broadcast(signals
.format_patch
, to_export
, revs
)
203 """Launches a diff against a branch."""
204 branch
= choose_from_combo('Select Branch, Tag, or Commit-ish',
206 cola
.model().all_branches() +
210 zfiles_str
= gitcmd
.instance().diff(branch
, name_only
=True,
213 files
= zfiles_str
.split('\0')
214 filename
= choose_from_list('Select File', files
)
217 cola
.notifier().broadcast(signals
.branch_mode
, branch
, filename
)
220 def diff_expression():
221 """Diff using an arbitrary expression."""
222 expr
= choose_from_combo('Enter Diff Expression',
223 cola
.model().all_branches() +
227 cola
.notifier().broadcast(signals
.diff_expr_mode
, expr
)
231 """Called when Search -> Grep's right-click 'goto' action."""
232 filename
, line_number
, contents
= line
.split(':', 2)
233 filename
= core
.encode(filename
)
234 cola
.notifier().broadcast(signals
.edit
, [filename
], line_number
=line_number
)
238 """Prompt and use 'git grep' to find the content."""
239 # This should be a command in cola.commands.
240 txt
, ok
= qtutils
.prompt('grep')
243 cola
.notifier().broadcast(signals
.grep
, txt
)
246 def open_repo(parent
):
247 """Spawn a new cola session."""
248 dirname
= qtutils
.opendir_dialog(parent
,
249 'Open Git Repository...',
250 cola
.model().getcwd())
253 cola
.notifier().broadcast(signals
.open_repo
, dirname
)
255 def open_repo_slot(parent
):
256 return slot_with_parent(open_repo
, parent
)
259 def load_commitmsg(parent
):
260 """Load a commit message from a file."""
261 filename
= qtutils
.open_dialog(parent
,
262 'Load Commit Message...',
263 cola
.model().getcwd())
265 cola
.notifier().broadcast(signals
.load_commit_message
, filename
)
267 def load_commitmsg_slot(parent
):
268 return slot_with_parent(load_commitmsg
, parent
)
272 """Rebase onto a branch."""
273 branch
= choose_from_combo('Rebase Branch',
274 cola
.model().all_branches())
278 status
, output
= gitcmd
.instance().rebase(branch
,
281 qtutils
.log(status
, output
)
285 """Diff against an arbitrary revision, branch, tag, etc."""
286 branch
= choose_from_combo('Select Branch, Tag, or Commit-ish',
287 cola
.model().all_branches() +
291 cola
.notifier().broadcast(signals
.review_branch_mode
, branch
)
295 """Launch the 'fetch' remote dialog."""
296 from cola
.controllers
.remote
import remote_action
298 remote_action(parent
, 'fetch')
300 def fetch_slot(parent
):
301 return slot_with_parent(fetch
, parent
)
305 """Launch the 'push' remote dialog."""
306 from cola
.controllers
.remote
import remote_action
308 remote_action(parent
, 'push')
310 def push_slot(parent
):
311 return slot_with_parent(push
, parent
)
315 """Launch the 'pull' remote dialog."""
316 from cola
.controllers
.remote
import remote_action
318 remote_action(parent
, 'pull')
320 def pull_slot(parent
):
321 return slot_with_parent(pull
, parent
)