121
class GTKCommand(Command):
122
"""Abstract class providing GTK specific run commands."""
126
dialog = self.get_gtk_dialog(os.path.abspath('.'))
130
class cmd_gbranch(GTKCommand):
135
def get_gtk_dialog(self, path):
136
from bzrlib.plugins.gtk.branch import BranchDialog
137
return BranchDialog(path)
140
class cmd_gcheckout(GTKCommand):
145
def get_gtk_dialog(self, path):
146
from bzrlib.plugins.gtk.checkout import CheckoutDialog
147
return CheckoutDialog(path)
151
class cmd_gpush(GTKCommand):
155
takes_args = [ "location?" ]
157
def run(self, location="."):
158
(br, path) = branch.Branch.open_containing(location)
160
from bzrlib.plugins.gtk.push import PushDialog
161
dialog = PushDialog(br.repository, br.last_revision(), br)
165
class cmd_gloom(GTKCommand):
169
takes_args = [ "location?" ]
171
def run(self, location="."):
173
(tree, path) = workingtree.WorkingTree.open_containing(location)
175
except NoWorkingTree, e:
176
(br, path) = branch.Branch.open_containing(location)
179
from bzrlib.plugins.gtk.loom import LoomDialog
180
dialog = LoomDialog(br, tree)
184
class cmd_gdiff(GTKCommand):
185
"""Show differences in working tree in a GTK+ Window.
187
Otherwise, all changes for the tree are listed.
189
takes_args = ['filename?']
190
takes_options = ['revision']
193
def run(self, revision=None, filename=None):
195
wt = workingtree.WorkingTree.open_containing(".")[0]
199
if revision is not None:
200
if len(revision) == 1:
202
revision_id = revision[0].as_revision_id(tree1.branch)
203
tree2 = branch.repository.revision_tree(revision_id)
204
elif len(revision) == 2:
205
revision_id_0 = revision[0].as_revision_id(branch)
206
tree2 = branch.repository.revision_tree(revision_id_0)
207
revision_id_1 = revision[1].as_revision_id(branch)
208
tree1 = branch.repository.revision_tree(revision_id_1)
211
tree2 = tree1.basis_tree()
213
from diff import DiffWindow
215
window = DiffWindow()
216
window.connect("destroy", gtk.main_quit)
217
window.set_diff("Working Tree", tree1, tree2)
218
if filename is not None:
219
tree_filename = wt.relpath(filename)
221
window.set_file(tree_filename)
223
if (tree1.path2id(tree_filename) is None and
224
tree2.path2id(tree_filename) is None):
225
raise NotVersionedError(filename)
226
raise BzrCommandError('No changes found for file "%s"' %
235
def start_viz_window(branch, revisions, limit=None):
236
"""Start viz on branch with revision revision.
238
:return: The viz window object.
240
from bzrlib.plugins.gtk.viz import BranchWindow
241
return BranchWindow(branch, revisions, limit)
244
class cmd_visualise(Command):
245
"""Graphically visualise this branch.
247
Opens a graphical window to allow you to see the history of the branch
248
and relationships between revisions in a visual manner,
250
The default starting point is latest revision on the branch, you can
251
specify a starting point with -r revision.
255
Option('limit', "Maximum number of revisions to display.",
257
takes_args = [ "locations*" ]
258
aliases = [ "visualize", "vis", "viz" ]
260
def run(self, locations_list, revision=None, limit=None):
262
if locations_list is None:
263
locations_list = ["."]
265
for location in locations_list:
266
(br, path) = branch.Branch.open_containing(location)
268
revids.append(br.last_revision())
270
revids.append(revision[0].as_revision_id(br))
272
pp = start_viz_window(br, revids, limit)
273
pp.connect("destroy", lambda w: gtk.main_quit())
278
class cmd_gannotate(GTKCommand):
281
Browse changes to FILENAME line by line in a GTK+ window.
284
takes_args = ["filename", "line?"]
286
Option("all", help="Show annotations on all lines."),
287
Option("plain", help="Don't highlight annotation lines."),
288
Option("line", type=int, argname="lineno",
289
help="Jump to specified line number."),
292
aliases = ["gblame", "gpraise"]
294
def run(self, filename, all=False, plain=False, line='1', revision=None):
300
raise BzrCommandError('Line argument ("%s") is not a number.' %
303
from annotate.gannotate import GAnnotateWindow
304
from annotate.config import GAnnotateConfig
305
from bzrlib.bzrdir import BzrDir
307
wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
311
tree = br.basis_tree()
313
file_id = tree.path2id(path)
316
raise NotVersionedError(filename)
317
if revision is not None:
318
if len(revision) != 1:
319
raise BzrCommandError("Only 1 revion may be specified.")
320
revision_id = revision[0].as_revision_id(br)
321
tree = br.repository.revision_tree(revision_id)
323
revision_id = getattr(tree, 'get_revision_id', lambda: None)()
325
window = GAnnotateWindow(all, plain, branch=br)
326
window.connect("destroy", lambda w: gtk.main_quit())
327
config = GAnnotateConfig(window)
333
window.annotate(tree, br, file_id)
334
window.jump_to_line(line)
343
class cmd_gcommit(GTKCommand):
344
"""GTK+ commit dialog
346
Graphical user interface for committing revisions"""
352
def run(self, filename=None):
355
from commit import CommitDialog
356
from bzrlib.errors import (BzrCommandError,
363
(wt, path) = workingtree.WorkingTree.open_containing(filename)
365
except NoWorkingTree, e:
366
from dialog import error_dialog
367
error_dialog(_i18n('Directory does not have a working tree'),
368
_i18n('Operation aborted.'))
369
return 1 # should this be retval=3?
371
# It is a good habit to keep things locked for the duration, but it
372
# could cause difficulties if someone wants to do things in another
373
# window... We could lock_read() until we actually go to commit
374
# changes... Just a thought.
377
dlg = CommitDialog(wt)
383
class cmd_gstatus(GTKCommand):
384
"""GTK+ status dialog
386
Graphical user interface for showing status
390
takes_args = ['PATH?']
391
takes_options = ['revision']
393
def run(self, path='.', revision=None):
396
from bzrlib.plugins.gtk.status import StatusWindow
397
(wt, wt_path) = workingtree.WorkingTree.open_containing(path)
399
if revision is not None:
401
revision_id = revision[0].as_revision_id(wt.branch)
403
from bzrlib.errors import BzrError
404
raise BzrError('Revision %r doesn\'t exist'
405
% revision[0].user_spec )
409
status = StatusWindow(wt, wt_path, revision_id)
410
status.connect("destroy", gtk.main_quit)
415
class cmd_gsend(GTKCommand):
416
"""GTK+ send merge directive.
420
(br, path) = branch.Branch.open_containing(".")
422
from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
423
from StringIO import StringIO
424
dialog = SendMergeDirectiveDialog(br)
425
if dialog.run() == gtk.RESPONSE_OK:
427
outf.writelines(dialog.get_merge_directive().to_lines())
428
mail_client = br.get_config().get_mail_client()
429
mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]",
435
class cmd_gconflicts(GTKCommand):
438
Select files from the list of conflicts and run an external utility to
442
(wt, path) = workingtree.WorkingTree.open_containing('.')
444
from bzrlib.plugins.gtk.conflicts import ConflictsDialog
445
dialog = ConflictsDialog(wt)
449
class cmd_gpreferences(GTKCommand):
450
""" GTK+ preferences dialog.
455
from bzrlib.plugins.gtk.preferences import PreferencesWindow
456
dialog = PreferencesWindow()
460
class cmd_ginfo(Command):
465
from bzrlib import workingtree
466
from bzrlib.plugins.gtk.olive.info import InfoDialog
467
wt = workingtree.WorkingTree.open_containing('.')[0]
468
info = InfoDialog(wt.branch)
473
class cmd_gmerge(Command):
474
""" GTK+ merge dialog
477
takes_args = ["merge_from_path?"]
478
def run(self, merge_from_path=None):
479
from bzrlib import workingtree
480
from bzrlib.plugins.gtk.dialog import error_dialog
481
from bzrlib.plugins.gtk.merge import MergeDialog
483
(wt, path) = workingtree.WorkingTree.open_containing('.')
484
old_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
485
delta = wt.changes_from(old_tree)
486
if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
487
error_dialog(_i18n('There are local changes in the branch'),
488
_i18n('Please commit or revert the changes before merging.'))
490
parent_branch_path = wt.branch.get_parent()
491
merge = MergeDialog(wt, path, parent_branch_path)
492
response = merge.run()
496
class cmd_gmissing(Command):
497
""" GTK+ missing revisions dialog.
500
takes_args = ["other_branch?"]
501
def run(self, other_branch=None):
502
pygtk = import_pygtk()
505
except RuntimeError, e:
506
if str(e) == "could not open display":
509
from bzrlib.plugins.gtk.missing import MissingWindow
510
from bzrlib.branch import Branch
512
local_branch = Branch.open_containing(".")[0]
513
if other_branch is None:
514
other_branch = local_branch.get_parent()
516
if other_branch is None:
517
raise errors.BzrCommandError("No peer location known or specified.")
518
remote_branch = Branch.open_containing(other_branch)[0]
520
local_branch.lock_read()
522
remote_branch.lock_read()
524
dialog = MissingWindow(local_branch, remote_branch)
527
remote_branch.unlock()
529
local_branch.unlock()
532
class cmd_ginit(GTKCommand):
535
from initialize import InitDialog
536
dialog = InitDialog(os.path.abspath(os.path.curdir))
540
class cmd_gtags(GTKCommand):
542
br = branch.Branch.open_containing('.')[0]
545
from tags import TagsWindow
546
window = TagsWindow(br)
107
"gannotate": ["gblame", "gpraise"],
123
"visualise": ["visualize", "vis", "viz"],
571
127
from bzrlib.plugins import loom
572
128
except ImportError:
573
129
pass # Loom plugin doesn't appear to be present
575
commands.append(cmd_gloom)
578
register_command(cmd)
581
class cmd_gselftest(GTKCommand):
582
"""Version of selftest that displays a notification at the end"""
584
takes_args = builtins.cmd_selftest.takes_args
585
takes_options = builtins.cmd_selftest.takes_options
586
_see_also = ['selftest']
588
def run(self, *args, **kwargs):
591
default_encoding = sys.getdefaultencoding()
592
# prevent gtk from blowing up later
594
# prevent gtk from messing with default encoding
596
if sys.getdefaultencoding() != default_encoding:
598
sys.setdefaultencoding(default_encoding)
599
result = builtins.cmd_selftest().run(*args, **kwargs)
602
body = 'Selftest succeeded in "%s"' % os.getcwd()
605
body = 'Selftest failed in "%s"' % os.getcwd()
606
pynotify.init("bzr gselftest")
607
note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
608
note.set_timeout(pynotify.EXPIRES_NEVER)
612
register_command(cmd_gselftest)
131
commands["gloom"] = []
133
for cmd, aliases in commands.iteritems():
134
plugin_cmds.register_lazy("cmd_%s" % cmd, aliases, "bzrlib.plugins.gtk.commands")