by
Changes to 28 files · Browse files at eee4b5167d25 Showing diff from parent 0df59976deff a83626cf91c4 Diff from another changeset...
@@ -55,10 +55,10 @@
self.set_website("http://bitbucket.org/tortoisehg/stable/")
self.set_name("TortoiseHg")
- self.set_version("(version %s)" % version.version())
+ self.set_version(_("(version %s)") % version.version())
if hasattr(self, 'set_wrap_license'):
self.set_wrap_license(True)
- self.set_copyright("Copyright 2009 TK Soh and others")
+ self.set_copyright(_("Copyright 2009 TK Soh and others"))
thg_logo = paths.get_tortoise_icon('thg_logo_92x50.png')
thg_icon = paths.get_tortoise_icon('thg_logo.ico')
@@ -74,7 +74,7 @@ license = hgtk.shortlicense.splitlines()[1:]
self.set_license('\n'.join(license))
- self.set_comments("with " + lib_versions + "\n\n" + comment)
+ self.set_comments(_("with %s") % lib_versions + "\n\n" + comment)
self.set_logo(gtk.gdk.pixbuf_new_from_file(thg_logo))
self.set_icon_from_file(thg_icon)
self.connect('response', self.response)
|
|
|
@@ -0,0 +1,210 @@ + # archive.py - TortoiseHg's dialog for archiving a repo revision
+#
+# Copyright 2009 Emmanuel Rosa <goaway1000@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os
+import gtk
+import gobject
+import pango
+
+from mercurial import hg, ui
+
+from thgutil.i18n import _
+from thgutil import hglib, paths
+
+from hggtk import hgcmd, gtklib
+
+_working_dir_parent_ = _('= Working Directory Parent =')
+
+class ArchiveDialog(gtk.Window):
+ """ Dialog to archive a Mercurial repo """
+ def __init__(self, rev=None):
+ """ Initialize the Dialog """
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+ gtklib.set_tortoise_icon(self, 'menucheckout.ico')
+ gtklib.set_tortoise_keys(self)
+
+ self.set_default_size(550, 120)
+ self.notify_func = None
+
+ try:
+ repo = hg.repository(ui.ui(), path=paths.find_root())
+ except hglib.RepoError:
+ gobject.idle_add(self.destroy)
+ return
+
+ title = _('Archive - %s') % hglib.toutf(os.path.basename(repo.root))
+ self.set_title(title)
+
+ vbox = gtk.VBox()
+ self.add(vbox)
+
+ hbox = gtk.HBox()
+ lbl = gtk.Label(_('Archive revision:'))
+ hbox.pack_start(lbl, False, False, 2)
+
+ # revisions editable combo box
+ combo = gtk.combo_box_entry_new_text()
+ hbox.pack_start(combo, True, True, 2)
+ vbox.pack_start(hbox, False, False, 10)
+ if rev:
+ combo.append_text(str(rev))
+ else:
+ combo.append_text(_working_dir_parent_)
+ combo.set_active(0)
+ for b in repo.branchtags():
+ combo.append_text(b)
+ tags = list(repo.tags())
+ tags.sort()
+ tags.reverse()
+ for t in tags:
+ combo.append_text(t)
+
+ vbox.add(self.get_destination_container(self.get_default_path()))
+ vbox.add(self.get_type_container())
+
+ hbbox = gtk.HButtonBox()
+ hbbox.set_layout(gtk.BUTTONBOX_END)
+ vbox.pack_start(hbbox, False, False, 2)
+ close = gtk.Button(_('Close'))
+ close.connect('clicked', lambda x: self.destroy())
+
+ accelgroup = gtk.AccelGroup()
+ self.add_accel_group(accelgroup)
+ key, modifier = gtk.accelerator_parse('Escape')
+ close.add_accelerator('clicked', accelgroup, key, 0,
+ gtk.ACCEL_VISIBLE)
+ hbbox.add(close)
+
+ archive = gtk.Button(_('Archive'))
+ archive.connect('clicked', self.archive, combo, repo)
+ mod = gtklib.get_thg_modifier()
+ key, modifier = gtk.accelerator_parse(mod+'Return')
+ archive.add_accelerator('clicked', accelgroup, key, modifier,
+ gtk.ACCEL_VISIBLE)
+ hbbox.add(archive)
+ archive.grab_focus()
+
+ entry = combo.child
+ entry.connect('activate', self.entry_activated, archive, combo, repo)
+
+ def get_type_container(self):
+ """Return a frame containing the supported archive types"""
+ frame = gtk.Frame(_('Archive type'))
+ vbox = gtk.VBox()
+
+ self.filesradio = gtk.RadioButton(None, _('Directory of files'))
+ self.tarradio = gtk.RadioButton(self.filesradio, _('Uncompressed tar archive'))
+ self.tbz2radio = gtk.RadioButton(self.filesradio, _('Tar archive compressed using bzip2'))
+ self.tgzradio = gtk.RadioButton(self.filesradio, _('Tar archive compressed using gzip'))
+ self.uzipradio = gtk.RadioButton(self.filesradio, _('Uncompressed zip archive'))
+ self.zipradio = gtk.RadioButton(self.filesradio, _('Zip archive compressed using deflate'))
+
+ vbox.pack_start(self.filesradio, True, True, 2)
+ vbox.pack_start(self.tarradio, True, True, 2)
+ vbox.pack_start(self.tbz2radio, True, True, 2)
+ vbox.pack_start(self.tgzradio, True, True, 2)
+ vbox.pack_start(self.uzipradio, True, True, 2)
+ vbox.pack_start(self.zipradio, True, True, 2)
+ frame.add(vbox)
+ frame.set_border_width(2)
+ return frame
+
+ def get_destination_container(self, default_path):
+ """Return an hbox containing the widgets for the destination path"""
+ hbox = gtk.HBox()
+ lbl = gtk.Label(_('Destination Path:'))
+
+ # create drop-down list for source paths
+ self.destlist = gtk.ListStore(str)
+ destcombo = gtk.ComboBoxEntry(self.destlist, 0)
+ self.destentry = destcombo.get_child()
+ self.destentry.set_text(default_path)
+ self.destentry.set_position(-1)
+
+ # replace the drop-down widget so we can modify it's properties
+ destcombo.clear()
+ cell = gtk.CellRendererText()
+ cell.set_property('ellipsize', pango.ELLIPSIZE_MIDDLE)
+ destcombo.pack_start(cell)
+ destcombo.add_attribute(cell, 'text', 0)
+
+ destbrowse = gtk.Button(_('Browse...'))
+ destbrowse.connect('clicked', self.browse_clicked)
+ hbox.pack_start(lbl, False, False)
+ hbox.pack_start(destcombo, True, True, 2)
+ hbox.pack_end(destbrowse, False, False, 5)
+ return hbox
+
+ def get_default_path(self):
+ """Return the default destination path"""
+ return hglib.toutf(os.getcwd())
+
+ def get_save_file_dialog(self, filter):
+ """Return a configured save file dialog"""
+ return gtklib.NativeSaveFileDialogWrapper(
+ InitialDir=self.destentry.get_text(),
+ Title=_('Select Destination File'),
+ Filter=filter)
+
+ def get_selected_archive_type(self):
+ """Return a dictionary describing the selected archive type"""
+ dict = {}
+ if self.tarradio.get_active():
+ dict['type'] = 'tar'
+ dict['filter'] = ((_('Tar archives'), '*.tar'),)
+ elif self.tbz2radio.get_active():
+ dict['type'] = 'tbz2'
+ dict['filter'] = ((_('Bzip2 tar archives'), '*.tbz2'),)
+ elif self.tgzradio.get_active():
+ dict['type'] = 'tgz'
+ dict['filter'] = ((_('Gzip tar archives'), '*.tgz'),)
+ elif self.uzipradio.get_active():
+ dict['type'] = 'uzip'
+ dict['filter'] = ((_('Uncompressed zip archives'), '*.uzip'),)
+ elif self.zipradio.get_active():
+ dict['type'] = 'zip'
+ dict['filter'] = ((_('Compressed zip archives'), '*.zip'),)
+ else:
+ dict['type'] = 'files'
+
+ return dict
+
+ def entry_activated(self, entry, button, combo, repo):
+ self.update(button, combo, repo)
+
+ def browse_clicked(self, button):
+ """Select the destination directory or file"""
+ archive_type = self.get_selected_archive_type()
+ if archive_type['type'] == 'files':
+ response = gtklib.NativeFolderSelectDialog(
+ initial=self.destentry.get_text(),
+ title=_('Select Destination Folder')).run()
+ else:
+ filter = archive_type['filter']
+ response = self.get_save_file_dialog(filter).run()
+
+ if response:
+ self.destentry.set_text(response)
+
+ def archive(self, button, combo, repo):
+ rev = combo.get_active_text()
+
+ cmdline = ['hg', 'archive', '--verbose']
+ if rev != _working_dir_parent_:
+ cmdline.append('--rev')
+ cmdline.append(rev)
+
+ cmdline.append('-t')
+ cmdline.append(self.get_selected_archive_type()['type'])
+ cmdline.append(hglib.fromutf(self.destentry.get_text()))
+
+ dlg = hgcmd.CmdDialog(cmdline)
+ dlg.run()
+ dlg.hide()
+
+def run(ui, *pats, **opts):
+ return ArchiveDialog(opts.get('rev'))
|
@@ -11,9 +11,11 @@ import pango
from mercurial import hg, ui
+
from thgutil.i18n import _
from thgutil import hglib, paths
-from hggtk import gtklib, hgcmd
+
+from hggtk import changesetinfo, gtklib, hgcmd
class BackoutDialog(gtk.Window):
""" Backout effect of a changeset """
@@ -36,11 +38,8 @@ self.add(vbox)
frame = gtk.Frame(_('Changeset Description'))
- lbl = gtk.Label()
- desc = self.revdesc(repo, rev)
- lbl.set_markup(desc)
- lbl.set_alignment(0, 0)
- frame.add(lbl)
+ rev, desc = changesetinfo.changesetinfo(repo, rev)
+ frame.add(desc)
frame.set_border_width(5)
vbox.pack_start(frame, False, False, 2)
@@ -87,23 +86,6 @@
backout.connect('clicked', self.backout, buf, rev)
- def revdesc(self, repo, revid):
- ctx = repo[revid]
- revstr = str(ctx.rev())
- summary = ctx.description().replace('\0', '')
- summary = summary.split('\n')[0]
- escape = gtklib.markup_escape_text
- desc = '<b>' + hglib.fromutf(_('rev')) + '</b>\t\t: %s\n' % escape(revstr)
- desc += '<b>' + hglib.fromutf(_('summary')) + '</b>\t: %s\n' % escape(summary[:80])
- desc += '<b>' + hglib.fromutf(_('user')) + '</b>\t\t: %s\n' % escape(ctx.user())
- desc += '<b>' + hglib.fromutf(_('date')) + '</b>\t\t: %s\n' % escape(hglib.displaytime(ctx.date()))
- node = repo.lookup(revid)
- tags = repo.nodetags(node)
- desc += '<b>' + hglib.fromutf(_('branch')) + '</b>\t: ' + escape(ctx.branch())
- if tags:
- desc += '\n<b>' + hglib.fromutf(_('tags')) + '</b>\t\t: ' + escape(', '.join(tags))
- return hglib.toutf(desc)
-
def set_notify_func(self, func, *args):
self.notify_func = func
self.notify_args = args
|
|
@@ -146,25 +146,40 @@
eob = buf.get_end_iter()
date = displaytime(ctx.date())
- change = str(rev) + ' : ' + str(ctx)
+ change = str(rev) + ' (' + str(ctx) + ')'
tags = ' '.join(ctx.tags())
title_line(_('changeset:'), change, 'changeset')
if ctx.branch() != 'default':
title_line(_('branch:'), ctx.branch(), 'greybg')
title_line(_('user/date:'), ctx.user() + '\t' + date, 'changeset')
+
+ if len(ctx.parents()) == 2 and self.parent_toggle.get_active():
+ parentindex = 1
+ else:
+ parentindex = 0
+
for pctx in ctx.parents():
try:
summary = pctx.description().splitlines()[0]
summary = toutf(summary)
except:
summary = ""
- change = str(pctx.rev()) + ' : ' + str(pctx)
+ change = str(pctx.rev()) + ' (' + str(pctx) + ')'
+ if pctx.branch() != ctx.branch():
+ change += ' [' + toutf(pctx.branch()) + ']'
title = _('parent:')
title += ' ' * (12 - len(title))
- buf.insert_with_tags_by_name(eob, title, 'parent')
- buf.insert_with_tags_by_name(eob, change, 'link')
- buf.insert_with_tags_by_name(eob, ' ' + summary, 'parent')
+
+ if len(ctx.parents()) == 2 and pctx == ctx.parents()[parentindex]:
+ buf.insert_with_tags_by_name(eob, title, 'parenthl')
+ buf.insert_with_tags_by_name(eob, change, 'linkhl')
+ buf.insert_with_tags_by_name(eob, ' ' + summary, 'parenthl')
+ else:
+ buf.insert_with_tags_by_name(eob, title, 'parent')
+ buf.insert_with_tags_by_name(eob, change, 'link')
+ buf.insert_with_tags_by_name(eob, ' ' + summary, 'parent')
+
buf.insert(eob, "\n")
for cctx in ctx.children():
try:
@@ -172,7 +187,9 @@ summary = toutf(summary)
except:
summary = ""
- change = str(cctx.rev()) + ' : ' + str(cctx)
+ change = str(cctx.rev()) + ' (' + str(cctx) + ')'
+ if cctx.branch() != ctx.branch():
+ change += ' [' + toutf(cctx.branch()) + ']'
title = _('child:')
title += ' ' * (12 - len(title))
buf.insert_with_tags_by_name(eob, title, 'parent')
@@ -267,10 +284,9 @@ text = self.get_link_text(tag, widget, liter)
if not text:
return
- linkrev = long(text.split(':')[0])
+ linkrev = long(text.split(' ')[0])
if self.graphview:
- self.graphview.set_revision_id(linkrev)
- self.graphview.scroll_to_revision(linkrev)
+ self.graphview.set_revision_id(linkrev, load=True)
else:
self.load_details(linkrev)
@@ -423,6 +439,9 @@ paragraph_background='#F0F0F0'))
tag_table.add(make_texttag('parent', foreground='#000090',
paragraph_background='#F0F0F0'))
+ tag_table.add(make_texttag('parenthl', foreground='#000090',
+ paragraph_background='#F0F0F0',
+ weight=pango.WEIGHT_BOLD ))
tag_table.add( make_texttag( 'mono', family='Monospace' ))
tag_table.add( make_texttag( 'blue', foreground='blue' ))
@@ -435,8 +454,13 @@ tag_table.add( make_texttag( 'yellowbg', background='yellow' ))
link_tag = make_texttag( 'link', foreground='blue',
underline=pango.UNDERLINE_SINGLE )
+ linkhl_tag = make_texttag( 'linkhl', foreground='blue',
+ underline=pango.UNDERLINE_SINGLE,
+ weight=pango.WEIGHT_BOLD )
link_tag.connect('event', self.link_event )
+ linkhl_tag.connect('event', self.link_event )
tag_table.add( link_tag )
+ tag_table.add( linkhl_tag )
def file_button_release(self, widget, event):
if event.button == 3 and not (event.state & (gtk.gdk.SHIFT_MASK |
@@ -523,7 +547,7 @@ parent = parents[0]
pair = '%u:%u' % (parent, rev)
self._node1, self._node2 = cmdutil.revpair(self.repo, [pair])
- self._view_file('M', self.curfile, force_left=False)
+ self._view_files([self.curfile], False)
def ann_file(self, menuitem):
'User selected annotate file from the file list context menu'
|
|
@@ -0,0 +1,63 @@ + # changesetinfo.py - component for displaying changeset summary
+#
+# Copyright 2009 Yuki KODAMA <endflow.net@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''component for displaying changeset summary'''
+
+import os
+import gtk
+
+from thgutil.i18n import _
+from thgutil import hglib
+
+from hggtk import gtklib
+
+def changesetinfo(repo, revid, head=False):
+ def lbl(str, bold=False, right=False):
+ str = gtklib.markup_escape_text(str)
+ label = gtk.Label()
+ if bold:
+ str = '<b>%s</b>' % str
+ label.set_alignment((1 if right else 0), 0)
+ label.set_markup(str)
+ return label
+ def addrow(table, header=None, value=None):
+ row = table.get_property('n-rows')
+ table.set_property('n-rows', row + 1)
+ if header:
+ if isinstance(header, str):
+ header = lbl(header, True, True)
+ table.attach(header, 0, 1, row, row + 1, gtk.FILL, 0, 4, 1)
+ if value:
+ if isinstance(value, str):
+ value = lbl(value)
+ table.attach(value, 1, 2, row, row + 1, gtk.FILL|gtk.EXPAND, 0, 4, 1)
+
+ # prepare data to display
+ table = gtk.Table(1, 2)
+ ctx = repo[revid]
+ revstr = str(ctx.rev())
+ summary = ctx.description().replace('\0', '').split('\n')[0]
+ node = repo.lookup(revid)
+ tags = repo.nodetags(node)
+
+ # construct gtk.Table
+ addrow(table, _('rev'), revstr)
+ addrow(table, _('summary'), hglib.toutf(summary[:80]))
+ addrow(table, _('user'), hglib.toutf(ctx.user()))
+ addrow(table, _('date'), hglib.displaytime(ctx.date()))
+ addrow(table, _('branch'), hglib.toutf(ctx.branch()))
+ if tags:
+ addrow(table, _('tags'), hglib.toutf(', '.join(tags)))
+ if head and node not in repo.heads():
+ addrow(table, value=lbl(_('Not a head revision!'), True))
+
+ # just for padding
+ vbox = gtk.VBox()
+ vbox.pack_start(table, True, True, 3)
+ hbox = gtk.HBox()
+ hbox.pack_start(vbox, True, True, 4)
+ return revstr, hbox
|
|
|
@@ -26,16 +26,28 @@ from hggtk import gtklib, thgconfig, gdialog, hgcmd
class BranchOperationDialog(gtk.Dialog):
- def __init__(self, branch, close):
+ def __init__(self, branch, close, mergebranches):
gtk.Dialog.__init__(self, parent=None, flags=gtk.DIALOG_MODAL,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OK, gtk.RESPONSE_OK))
gtklib.set_tortoise_keys(self)
- self.connect('response', self.response)
self.set_title(_('Branch Operations'))
self.newbranch = None
self.closebranch = False
+ if mergebranches:
+ lbl = gtk.Label(_('Select branch of merge commit'))
+ branchcombo = gtk.combo_box_new_text()
+ for name in mergebranches:
+ branchcombo.append_text(name)
+ branchcombo.set_active(0)
+ self.vbox.pack_start(lbl, True, True, 2)
+ self.vbox.pack_start(branchcombo, True, True, 2)
+ self.connect('response', self.merge_response, branchcombo)
+ self.show_all()
+ return
+
+ self.connect('response', self.response)
lbl = gtk.Label(_('Changes take effect on next commit'))
nochanges = gtk.RadioButton(None, _('No branch changes'))
self.newbranchradio = gtk.RadioButton(nochanges,
@@ -89,6 +101,14 @@ self.closebranch = False
self.destroy()
+ def merge_response(self, widget, response_id, combo):
+ self.closebranch = False
+ if response_id == gtk.RESPONSE_OK:
+ row = combo.get_active()
+ if row == 1:
+ self.newbranch = combo.get_model()[row][0]
+ self.destroy()
+
class GCommit(GStatus):
"""GTK+ based dialog for displaying repository status and committing
@@ -161,13 +181,13 @@
def get_tbbuttons(self):
tbbuttons = GStatus.get_tbbuttons(self)
- tbbuttons.insert(2, gtk.SeparatorToolItem())
+ tbbuttons.insert(0, gtk.SeparatorToolItem())
self.undo_button = self.make_toolbutton(gtk.STOCK_UNDO, _('_Undo'),
self.undo_clicked, tip=_('undo recent commit'))
self.commit_button = self.make_toolbutton(gtk.STOCK_OK, _('_Commit'),
self.commit_clicked, tip=_('commit'))
- tbbuttons.insert(2, self.undo_button)
- tbbuttons.insert(2, self.commit_button)
+ tbbuttons.insert(0, self.undo_button)
+ tbbuttons.insert(0, self.commit_button)
return tbbuttons
@@ -202,7 +222,11 @@ liststore.append([sumline, msg])
def branch_clicked(self, button):
- dialog = BranchOperationDialog(self.nextbranch, self.closebranch)
+ if self.merging:
+ mb = [p.branch() for p in self.repo.parents()]
+ else:
+ mb = None
+ dialog = BranchOperationDialog(self.nextbranch, self.closebranch, mb)
dialog.run()
self.nextbranch = None
self.closebranch = False
@@ -222,6 +246,10 @@ self.branchbutton = gtk.Button()
self.branchbutton.connect('clicked', self.branch_clicked)
mbox.pack_start(self.branchbutton, False, False, 2)
+ if self.merging:
+ branches = [p.branch() for p in self.repo.parents()]
+ if branches[0] == branches[1]:
+ self.branchbutton.set_sensitive(False)
if hasattr(self.repo, 'mq'):
label = gtk.Label('QNew: ')
@@ -271,22 +299,17 @@ def thgaccept(self, window):
self.commit_clicked(None)
- def get_menu_info(self):
- """Returns menu info in this order: merge, addrem, unknown,
- clean, ignored, deleted
- """
- merge, addrem, unknown, clean, ignored, deleted, unresolved, resolved \
- = GStatus.get_menu_info(self)
- return (merge + ((_('_commit'), self.commit_file),),
- addrem + ((_('_commit'), self.commit_file),),
- unknown + ((_('_commit'), self.commit_file),),
- clean,
- ignored,
- deleted + ((_('_commit'), self.commit_file),),
- unresolved,
- resolved,
- )
-
+ def get_custom_menus(self):
+ def commit(menuitem, files):
+ if self.ready_message():
+ self.hg_commit(files)
+ self.reload_status()
+ abs = [self.repo.wjoin(file) for file in files]
+ shlib.shell_notify(abs)
+ if self.merging:
+ return ()
+ else:
+ return [(_('_commit'), commit, 'MAR'),]
def delete(self, window, event):
if not self.should_live():
@@ -300,14 +323,15 @@ live = False
buf = self.text.get_buffer()
if buf.get_char_count() > 10 and buf.get_modified():
- dialog = gdialog.Confirm(_('Confirm Exit'), [], self,
- _('Save commit message at exit?'))
- res = dialog.run()
- if res == gtk.RESPONSE_YES:
+ # response: 0=Yes, 1=No, 2=Cancel
+ response = gdialog.CustomPrompt(_('Confirm Exit'),
+ _('Save commit message at exit?'), self,
+ (_('&Yes'), _('&No'), _('&Cancel')), 2, 2).run()
+ if response == 0:
begin, end = buf.get_bounds()
self.update_recent_messages(buf.get_text(begin, end))
buf.set_modified(False)
- elif res != gtk.RESPONSE_NO:
+ elif response == 2:
live = True
if not live:
self._destroying(widget)
@@ -342,11 +366,6 @@
def check_merge(self):
- self.get_toolbutton(_('Re_vert')).set_sensitive(not self.merging)
- self.get_toolbutton(_('_Add')).set_sensitive(not self.merging)
- self.get_toolbutton(_('_Remove')).set_sensitive(not self.merging)
- self.get_toolbutton(_('Move')).set_sensitive(not self.merging)
-
if self.merging:
# select all changes if repo is merged
for entry in self.filemodel:
@@ -401,15 +420,15 @@
commitable = 'MAR'
if self.merging:
- commit_list = self.relevant_files(commitable)
+ commit_list = self.relevant_checked_files(commitable)
# merges must be committed without specifying file list.
self.hg_commit([])
else:
- addremove_list = self.relevant_files('?!')
+ addremove_list = self.relevant_checked_files('?!')
if len(addremove_list) and self.should_addremove(addremove_list):
commitable += '?!'
- commit_list = self.relevant_files(commitable)
+ commit_list = self.relevant_checked_files(commitable)
if len(commit_list) > 0:
self.commit_selected(commit_list)
elif len(self.filemodel) == 0 and self.qnew:
@@ -475,13 +494,8 @@ if dopatch:
try:
pfiles = {}
- if patch.patchfile.__bases__:
- # Mercurial 1.3
- patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
+ patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
eolmode=None)
- else:
- # Mercurial 1.2
- patch.internalpatch(fp, ui, 1, repo.root, files=pfiles)
patch.updatedir(ui, repo, pfiles)
except patch.PatchError, err:
s = str(err)
@@ -517,15 +531,6 @@ pass
- def commit_file(self, stat, file):
- if self.ready_message():
- if stat not in '?!' or self.should_addremove([file]):
- self.hg_commit([file])
- self.reload_status()
- shlib.shell_notify([self.repo.wjoin(file)])
- return True
-
-
def undo_clicked(self, toolbutton, data=None):
response = gdialog.Confirm(_('Confirm Undo commit'),
[], self, _('Undo last commit')).run()
@@ -644,20 +649,23 @@ cmdline = ['hg', 'commit', '--verbose', '--repository', self.repo.root]
if self.nextbranch:
+ # response: 0=Yes, 1=No, 2=Cancel
newbranch = hglib.fromutf(self.nextbranch)
if newbranch in self.repo.branchtags():
- if newbranch not in [p.branch() for p in self.repo.parents()]:
- response = gdialog.Confirm(_('Confirm Override Branch'),
- [], self, _('A branch named "%s" already exists,\n'
- 'override?') % self.nextbranch).run()
+ if newbranch in [p.branch() for p in self.repo.parents()]:
+ response = 0
else:
- response = gtk.RESPONSE_YES
+ response = gdialog.CustomPrompt(_('Confirm Override Branch'),
+ _('A branch named "%s" already exists,\n'
+ 'override?') % self.nextbranch, self,
+ (_('&Yes'), _('&No'), _('&Cancel')), 2, 2).run()
else:
- response = gdialog.Confirm(_('Confirm New Branch'), [], self,
- _('Create new named branch "%s"?') % self.nextbranch).run()
- if response == gtk.RESPONSE_YES:
+ response = gdialog.CustomPrompt(_('Confirm New Branch'),
+ _('Create new named branch "%s"?') % self.nextbranch,
+ self, (_('&Yes'), _('&No'), _('&Cancel')), 2, 2).run()
+ if response == 0:
self.repo.dirstate.setbranch(newbranch)
- elif response != gtk.RESPONSE_NO:
+ elif response == 2:
return
elif self.closebranch:
cmdline.append('--close-branch')
|
@@ -222,7 +222,7 @@ search_hbox.pack_start(includes, True, True, 4)
search_hbox.pack_start(gtk.Label(_('Excludes:')), False, False, 4)
search_hbox.pack_start(excludes, True, True, 4)
- search_hbox.pack_start(search, False, False)
+ search_hbox.pack_start(search, False, False, 4)
self.tooltips.set_tip(search, _('Start this search'))
self.tooltips.set_tip(regexp, _('Regular expression search pattern'))
self.tooltips.set_tip(includes, _('Comma separated list of'
@@ -448,8 +448,11 @@ def close_page(self, button, widget):
'''Close page button has been pressed'''
num = self.notebook.page_num(widget)
- if num != -1 and self.notebook.get_n_pages() > 1:
+ if num != -1:
self.notebook.remove_page(num)
+ if self.notebook.get_n_pages() <= 1:
+ self.newpagecount = 1
+ self.add_search_page()
def add_header_context_menu(self, col, menu):
lb = gtk.Label(col.get_title())
|
@@ -46,27 +46,30 @@ class CustomPrompt(gtk.MessageDialog):
''' Custom prompt dialog. Provide a list of choices with ampersands
to delineate response given for each choice (and keyboard
- accelerator). Default must be one of the choice responses.
+ accelerator). Default must be the index of one of the choice responses.
'''
- # ret = CustomPrompt('Title', 'Message', self, ('&Yes', 'N&o'), 'o').run()
- # ret will be (gtk.RESPONSE_DELETE_EVENT, ord('y'), or ord('o'))
- def __init__(self, title, message, parent, choices, default=None):
+ # ret = CustomPrompt('Title', 'Message', self, ('&Yes', 'N&o'), 1).run()
+ # ret will be (gtk.RESPONSE_DELETE_EVENT, 0 (for yes), or 1 (for no)
+ def __init__(self, title, message, parent, choices, default=None, esc=None):
gtk.MessageDialog.__init__(self, parent, gtk.DIALOG_MODAL,
gtk.MESSAGE_QUESTION)
self.set_title(hglib.toutf(title))
self.format_secondary_markup('<b>' + hglib.toutf(message) + '</b>')
accel_group = gtk.AccelGroup()
self.add_accel_group(accel_group)
- for s in choices:
+ for i, s in enumerate(choices):
char = s[s.index('&')+1].lower()
- button = self.add_button(s.replace('&', '_'), ord(char))
+ button = self.add_button(s.replace('&', '_'), i)
button.add_accelerator('clicked', accel_group, ord(char), 0,
gtk.ACCEL_VISIBLE)
if default:
- self.set_default_response(ord(default))
+ self.set_default_response(default)
+ self.esc = esc
def run(self):
response = gtklib.MessageDialog.run(self)
+ if response == gtk.RESPONSE_DELETE_EVENT and self.esc != None:
+ response = self.esc
self.destroy()
return response
@@ -415,7 +418,7 @@ def _diff_file(self, stat, file):
self._do_diff(file and [file] or [], self.opts)
- def _view_file(self, stat, file, force_left=False):
+ def _view_files(self, files, otherparent):
from hggtk import thgconfig
def cleanup():
shutil.rmtree(self.tmproot)
@@ -460,18 +463,20 @@ pathroot = self.repo.root
copynode = None
# if we aren't looking at the wc, copy the node...
- if stat in 'R!' or force_left:
+ if otherparent:
copynode = self._node1
elif self._node2:
copynode = self._node2
if copynode:
- copydir = snapshot_node(self.ui, self.repo,
- [util.pconvert(file)], copynode, self.tmproot)
+ pf = [util.pconvert(f) for f in files]
+ copydir = snapshot_node(self.ui, self.repo, pf,
+ copynode, self.tmproot)
pathroot = os.path.join(self.tmproot, copydir)
- file_path = os.path.join(pathroot, file)
- util.system("%s \"%s\"" % (editor, file_path),
+ paths = ['"'+os.path.join(pathroot, f)+'"' for f in files]
+ command = editor + ' ' + ' '.join(paths)
+ util.system(command,
environ={'HGUSER': self.ui.username()},
onerr=self.ui, errprefix=_('edit failed'))
@@ -492,8 +497,8 @@ self._parse_config()
return
- file = util.localpath(file)
- thread = threading.Thread(target=doedit, name='edit:'+file)
+ lfile = util.localpath(files[0])
+ thread = threading.Thread(target=doedit, name='edit:'+lfile)
thread.setDaemon(True)
thread.start()
|
|
@@ -0,0 +1,57 @@ + # gorev.py - TortoiseHg's dialog for selecting a revision
+#
+# Copyright 2007 TK Soh <teekaysoh@gmail.com>
+# Copyright 2007 Steve Borho <steve@borho.org>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os
+import gtk
+import gobject
+import mercurial
+
+from thgutil.i18n import _
+from hggtk import gtklib, gdialog
+
+
+class GotoRevDialog(gtk.Dialog):
+ 'Dialog for selecting a revision'
+ def __init__(self, gotofunc):
+ super(GotoRevDialog, self).__init__(flags=gtk.DIALOG_MODAL)
+ gtklib.set_tortoise_icon(self, 'menulog.ico')
+ gtklib.set_tortoise_keys(self)
+
+ self._btn_goto = gtk.Button(_('Select'))
+ self._btn_goto.connect('clicked', self._btn_goto_clicked)
+ self.action_area.pack_end(self._btn_goto)
+
+ self.set_title(_('Select Revision'))
+
+ self.gotofunc = gotofunc
+
+ self.tips = gtk.Tooltips()
+
+ hbox = gtk.HBox()
+ self.revEntry = gtk.Entry()
+ self.revEntry.connect('activate', self._btn_goto_clicked)
+ hbox.pack_start(self.revEntry, True, True, 4)
+ eventbox = gtk.EventBox()
+ eventbox.add(hbox)
+ self.tips.set_tip(
+ eventbox, _('revision number, changeset ID, branch or tag'))
+ self.vbox.pack_start(eventbox, False, False, 4)
+
+ self.revEntry.grab_focus()
+
+ self.show_all()
+
+ def _btn_goto_clicked(self, button, data=None):
+ try:
+ revision = self.revEntry.get_text()
+ if self.gotofunc:
+ self.gotofunc(revision)
+ except mercurial.error.RepoError, e:
+ gdialog.Prompt(_('Invalid Revision'), str(e), self).run()
+ self.revEntry.grab_focus()
+ return
|
@@ -224,24 +224,12 @@ self._ccbox.child.set_text(hglib.fromutf(repo.ui.config('email', 'cc', '')))
self._frombox.child.set_text(hglib.fromutf(repo.ui.config('email', 'from', '')))
self._subjbox.child.set_text(hglib.fromutf(repo.ui.config('email', 'subject', '')))
- self._intro = False
- self._in_reply_to = False
- for arg in extensions.find('patchbomb').cmdtable['email'][1]:
- if arg[1] == 'intro':
- self._intro = True
- elif arg[1] == 'in-reply-to':
- self._in_reply_to = True
- if self._intro:
- addtip = ''
- else:
- addtip = ' ' + _('The description field is unused '
- 'when sending a single patch.')
self.tooltips.set_tip(self._eventbox,
_('Patch series description is sent in initial summary'
' email with [PATCH 0 of N] subject. It should describe'
' the effects of the entire patch series. When emailing'
' a bundle, these fields make up the message subject and body.')
- + addtip)
+ )
fill_history(history, self._tolist, 'email.to')
fill_history(history, self._cclist, 'email.cc')
fill_history(history, self._fromlist, 'email.from')
@@ -354,12 +342,12 @@ if self._inline.get_active(): cmdline += ['--inline']
if self._attach.get_active(): cmdline += ['--attach']
if self._diffstat.get_active(): cmdline += ['--diffstat']
- if inreplyto and self._in_reply_to:
+ if inreplyto:
cmdline += ['--in-reply-to', inreplyto]
start = self.descbuffer.get_start_iter()
end = self.descbuffer.get_end_iter()
desc = self.descbuffer.get_text(start, end)
- if desc and self._intro:
+ if desc:
cmdline += ['--intro']
tmpfile = None
try:
|
@@ -430,7 +430,7 @@
? - display help'''
- if not hglib.calliffunc(ui.interactive):
+ if not ui.interactive():
raise util.Abort(_('shelve can only be run interactively'))
forced = opts['force'] or opts['append']
@@ -502,12 +502,7 @@ if dopatch:
ui.debug(_('applying patch\n'))
ui.debug(fp.getvalue())
- if patch.patchfile.__bases__:
- # Mercurial 1.3
- patch.internalpatch(fp, ui, 1, repo.root, eolmode=None)
- else:
- # Mercurial 1.2
- patch.internalpatch(fp, ui, 1, repo.root)
+ patch.internalpatch(fp, ui, 1, repo.root, eolmode=None)
del fp
# 3c. apply filtered patch to clean repo (shelve)
|
@@ -24,14 +24,8 @@ main thread to pickup.
'''
def __init__(self, src=None, outputq=None, errorq=None, dialogq=None,
- responseq=None, parentui=None):
- if parentui:
- # Mercurial 1.2
- super(GtkUi, self).__init__(parentui=parentui)
- src = parentui
- else:
- # Mercurial 1.3
- super(GtkUi, self).__init__(src)
+ responseq=None):
+ super(GtkUi, self).__init__(src)
if src:
self.outputq = src.outputq
self.errorq = src.errorq
@@ -57,28 +51,34 @@ pass
def prompt(self, msg, choices=None, default="y"):
- import re
- if not hglib.calliffunc(self.interactive): return default
- if isinstance(choices, str):
- pat = choices
- choices = None
- else:
- pat = None
- while True:
- try:
- # send request to main thread, await response
- self.dialogq.put( (msg, True, choices, default) )
- r = self.responseq.get(True)
- if r is None:
- raise EOFError
- if not r:
- return default
- if not pat or re.match(pat, r):
- return r
- else:
- self.write(_('unrecognized response\n'))
- except EOFError:
- raise util.Abort(_('response expected'))
+ if not self.interactive(): return default
+ try:
+ # send request to main thread, await response
+ self.dialogq.put( (msg, True, choices, default) )
+ r = self.responseq.get(True)
+ if r is None:
+ raise EOFError
+ if not r:
+ return default
+ if choices:
+ # return char for Mercurial 1.3
+ choice = choices[r]
+ return choice[choice.index("&")+1].lower()
+ return r
+ except EOFError:
+ raise util.Abort(_('response expected'))
+
+ def promptchoice(self, msg, choices, default=0):
+ if not self.interactive(): return default
+ try:
+ # send request to main thread, await response
+ self.dialogq.put( (msg, True, choices, default) )
+ r = self.responseq.get(True)
+ if r is None:
+ raise EOFError
+ return r
+ except EOFError:
+ raise util.Abort(_('response expected'))
def getpass(self, prompt=None, default=None):
# send request to main thread, await response
@@ -143,7 +143,7 @@ if response_id == gtk.RESPONSE_DELETE_EVENT:
self.responseq.put(None)
else:
- self.responseq.put(chr(response_id))
+ self.responseq.put(response_id)
def dialog_response(self, dialog, response_id):
if response_id == gtk.RESPONSE_OK:
@@ -155,26 +155,9 @@
def run(self):
try:
- ret = None
- if hasattr(self.ui, 'copy'):
- # Mercurial 1.3
- for k, v in self.ui.configitems('defaults'):
- self.ui.setconfig('defaults', k, '')
- ret = hglib.dispatch._dispatch(self.ui, self.args)
- else:
- # Mercurial 1.2
- # Some commands create repositories, and thus must create
- # new ui() instances. For those, we monkey-patch ui.ui()
- # as briefly as possible.
- origui = None
- if self.args[0] in ('clone', 'init'):
- origui = ui.ui
- ui.ui = GtkUi
- try:
- ret = hglib.thgdispatch(self.ui, None, self.args)
- finally:
- if origui:
- ui.ui = origui
+ for k, v in self.ui.configitems('defaults'):
+ self.ui.setconfig('defaults', k, '')
+ ret = hglib.dispatch._dispatch(self.ui, self.args)
if ret:
self.ui.write(_('[command returned code %d]\n') % int(ret))
else:
@@ -186,7 +169,5 @@ self.ui.write_err(_('abort: ') + str(e) + '\n')
except (hglib.RepoError, urllib2.HTTPError), e:
self.ui.write_err(str(e) + '\n')
- except Exception, e:
+ except (Exception, OSError, IOError), e:
self.ui.write_err(str(e) + '\n')
- except hglib.WinIOError, e:
- self.ui.write_err(str(e) + '\n')
|
|
|
@@ -57,17 +57,20 @@ opts = {}
opts['cmd'] = ' '.join(sys.argv[1:])
opts['error'] = error
+ opts['nofork'] = True
if gtkmainalive:
dlg = run(u, **opts)
dlg.display()
dlg.show_all()
else:
- gtkrun(run(u, **opts))
+ gtkrun(run, u, **opts)
-def portable_fork():
- if 'THG_HGTK_SPAWN' in os.environ or '--nofork' in sys.argv:
+def portable_fork(ui, opts):
+ if 'THG_HGTK_SPAWN' in os.environ:
return
- if '--repository' in sys.argv or '-R' in sys.argv:
+ if opts.get('nofork') or opts.get('repository'):
+ return
+ if not ui.configbool('tortoisehg', 'hgtkfork', True):
return
# Spawn background process and exit
if hasattr(sys, "frozen"):
@@ -165,11 +168,6 @@def _runcatch(ui, args):
try:
try:
- checkhgversion(hglib.hgversion)
- except util.Abort, inst:
- ui.status(_("abort: %s!\n") % inst)
- return 0
- try:
return runcommand(ui, args)
finally:
ui.flush()
@@ -206,10 +204,12 @@ path = ui.expandpath(options['repository'])
cmdoptions['repository'] = path
os.chdir(path)
+ if options['nofork']:
+ cmdoptions['nofork'] = True
path = paths.find_root(os.getcwd())
if path:
try:
- lui = hasattr(_ui, 'copy') and _ui.copy() or _ui.ui(ui)
+ lui = ui.copy()
lui.readconfig(os.path.join(path, ".hg", "hgrc"))
except IOError:
pass
@@ -226,6 +226,9 @@ extsetup()
_loaded[name] = 1
+ if options['quiet']:
+ ui.quiet = True
+
if cmd not in nonrepo_commands.split() and not path:
raise hglib.RepoError(_("There is no Mercurial repository here"
" (.hg not found)"))
@@ -245,7 +248,11 @@ if mainwindow.should_live(): return
mainwindow.destroy()
-def gtkrun(win):
+def gtkrun(dlgfunc, ui, *args, **opts):
+ portable_fork(ui, opts)
+ win = dlgfunc(ui, *args, **opts)
+ if not win:
+ return
global mainwindow, gtkmainalive
mainwindow = win
if hasattr(win, 'display'):
@@ -264,7 +271,7 @@def about(ui, *pats, **opts):
"""about TortoiseHg"""
from hggtk.about import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def add(ui, *pats, **opts):
"""add files"""
@@ -279,21 +286,11 @@
def clone(ui, *pats, **opts):
"""clone tool"""
- portable_fork()
from hggtk.clone import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def commit(ui, *pats, **opts):
"""commit tool"""
- ct = ui.config('tortoisehg', 'extcommit', None)
- if ct == 'qct':
- from mercurial import dispatch as _dispatch
- try:
- _dispatch.dispatch([ct], *pats)
- except SystemExit:
- pass
- return
- portable_fork()
# move cwd to repo root if repo is merged, so we can show
# all the changed files
repo = hg.repository(ui, path=paths.find_root())
@@ -301,130 +298,117 @@ os.chdir(repo.root)
pats = []
from hggtk.commit import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def shelve(ui, *pats, **opts):
"""shelve/unshelve tool"""
- portable_fork()
from hggtk.thgshelve import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def userconfig(ui, *pats, **opts):
"""user configuration editor"""
- # Import thgconfig first, to check for iniparse
from hggtk.thgconfig import run
- portable_fork()
opts['repomode'] = False
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def repoconfig(ui, *pats, **opts):
"""repository configuration editor"""
- portable_fork()
from hggtk.thgconfig import run
opts['repomode'] = True
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def rename(ui, *pats, **opts):
"""rename a single file or directory"""
- portable_fork()
+ if not pats or len(pats) > 2:
+ from hggtk import gdialog
+ gdialog.Prompt(_('Rename error'),
+ _('rename takes one or two path arguments'), None).run()
+ return
from hggtk.rename import run
- if not pats or len(pats) > 2:
- raise util.Abort(_('rename takes one or two path arguments'))
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def guess(ui, *pats, **opts):
"""guess previous renames or copies"""
- portable_fork()
from hggtk.guess import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def datamine(ui, *pats, **opts):
"""repository search and annotate tool"""
- portable_fork()
from hggtk.datamine import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def hgignore(ui, *pats, **opts):
"""ignore filter editor"""
- portable_fork()
from hggtk.hgignore import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def hginit(ui, *pats, **opts):
"""repository initialization tool"""
- portable_fork()
from hggtk.hginit import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def log(ui, *pats, **opts):
"""changelog viewer"""
- portable_fork()
from hggtk.history import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def merge(ui, *pats, **opts):
"""merge tool"""
- portable_fork()
from hggtk.merge import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def recovery(ui, *pats, **opts):
"""recover, rollback & verify"""
- portable_fork()
from hggtk.recovery import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def remove(ui, *pats, **opts):
"""file status viewer in remove mode"""
- portable_fork()
from hggtk.status import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def revert(ui, *pats, **opts):
"""file status viewer in revert mode"""
- portable_fork()
from hggtk.status import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
+
+def forget(ui, *pats, **opts):
+ """file status viewer in forget mode"""
+ from hggtk.status import run
+ gtkrun(run, ui, *pats, **opts)
def serve(ui, *pats, **opts):
"""web server"""
- portable_fork()
from hggtk.serve import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def status(ui, *pats, **opts):
- """file status viewer"""
- portable_fork()
+ """file status & diff viewer"""
from hggtk.status import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def synch(ui, *pats, **opts):
"""repository synchronization tool"""
- portable_fork()
from hggtk.synch import run
cmd = opts['alias']
if cmd in ('push', 'outgoing', 'email'):
opts['pushmode'] = True
else:
opts['pushmode'] = False
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def update(ui, *pats, **opts):
"""update/checkout tool"""
- portable_fork()
from hggtk.update import run
- gtkrun(run(ui, *pats, **opts))
+ gtkrun(run, ui, *pats, **opts)
def vdiff(ui, *pats, **opts):
"""launch configured visual diff tool"""
- portable_fork()
from hggtk.visdiff import run, rawextdiff
if opts.get('raw'):
rawextdiff(ui, *pats, **opts)
return
- dlg = run(ui, *pats, **opts)
- if dlg:
- gtkrun(dlg)
+ gtkrun(run, ui, *pats, **opts)
### help management, adapted from mercurial.commands.help_()
def help_(ui, name=None, with_version=False, alias=None):
@@ -464,7 +448,7 @@ aliases, i = cmdutil.findcmd(name, table, False)
except hglib.AmbiguousCommand, inst:
select = lambda c: c.lstrip('^').startswith(inst.args[0])
- helplist('list of commands:\n\n', select)
+ helplist(_('list of commands:\n\n'), select)
return
# synopsis
@@ -591,26 +575,6 @@ else:
ui.write("%s\n" % first)
-def checkhgversion(v):
- """range check the Mercurial version"""
- # this is a series of hacks, but Mercurial's versioning scheme
- # doesn't lend itself to a "correct" solution. This will at least
- # catch people who have old Mercurial packages.
- reqver = ['1', '2']
- if not v or v == 'unknown' or len(v) >= 12:
- # can't make any intelligent decisions about unknown or hashes
- return
- vers = v.split('.')[:2]
- if vers == reqver or len(vers) < 2:
- return
- nextver = list(reqver)
- nextver[1] = chr(ord(reqver[1])+1)
- if vers == nextver:
- return
- raise util.Abort(_('This version of TortoiseHg requires Mercurial '
- 'version %s.n to %s.n, but finds %s') % ('.'.join(reqver),
- '.'.join(nextver), v))
-
def version(ui, **opts):
"""output version and copyright information"""
ui.write(_('TortoiseHg Dialogs (version %s), '
@@ -640,10 +604,16 @@ cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
ui.write("%s\n" % "\n".join(sorted(cmdlist)))
+def archive(ui, *pats, **opts):
+ """create an unversioned archive of a repository revision"""
+ from hggtk.archive import run
+ gtkrun(run, ui, *pats, **opts)
+
globalopts = [
('R', 'repository', '',
_('repository root directory or symbolic path name')),
('v', 'verbose', None, _('enable additional output')),
+ ('q', 'quiet', None, _('suppress output')),
('h', 'help', None, _('display help and exit')),
('', 'debugger', None, _('start debugger')),
('', 'nofork', None, _('do not fork GUI process')),
@@ -670,7 +640,7 @@ "^recovery|rollback|verify": (recovery, [], _('hgtk recovery')),
"^shelve|unshelve": (shelve, [], _('hgtk shelve')),
"^synch|pull|push|incoming|outgoing|email": (synch, [], _('hgtk synch')),
- "^status|st": (status,
+ "^status|st|diff": (status,
[('r', 'rev', [], _('revisions to compare'))],
_('hgtk status [FILE]...')),
"^userconfig": (userconfig, [], _('hgtk userconfig')),
@@ -679,6 +649,7 @@ "^remove|rm": (revert, [], _('hgtk remove [FILE]...')),
"^rename|mv": (rename, [], _('hgtk rename SOURCE [DEST]')),
"^revert": (revert, [], _('hgtk revert [FILE]...')),
+ "^forget": (forget, [], _('hgtk forget [FILE]...')),
"^serve":
(serve,
[('', 'webdir-conf', '', _('name of the webdir config file'))],
@@ -706,4 +677,7 @@ [('o', 'options', None, _('show the command options'))],
_('[-o] CMD')),
"help": (help_, [], _('hgtk help [COMMAND]')),
+ "^archive": (archive,
+ [('r', 'rev', '', _('revision to update'))],
+ ('hgtk archive')),
}
|
|
|
@@ -20,8 +20,8 @@ from hggtk.logview import treemodel
from hggtk.logview.treeview import TreeView as LogTreeView
-from hggtk import gdialog, gtklib, hgcmd, datamine, logfilter
-from hggtk import backout, status, hgemail, tagadd, update, merge
+from hggtk import gdialog, gtklib, hgcmd, datamine, logfilter, gorev
+from hggtk import backout, status, hgemail, tagadd, update, merge, archive
from hggtk import changeset
def create_menu(label, callback):
@@ -37,6 +37,8 @@ self.filter = 'all'
self.currow = None
self.curfile = None
+ self.origtip = len(self.repo)
+ self.ready = False
def get_title(self):
return hglib.toutf(os.path.basename(self.repo.root)) + ' log'
@@ -50,22 +52,26 @@
def get_tbbuttons(self):
tbar = [
- self.make_toolbutton(gtk.STOCK_REFRESH,
- _('Re_fresh'),
- self.refresh_clicked,
- tip=_('Reload revision history')),
- gtk.SeparatorToolItem(),
self.make_toolbutton(gtk.STOCK_INDEX,
_('_Filter'),
self.filter_clicked,
- menu=self.filter_menu(),
tip=_('Filter revisions for display')),
gtk.SeparatorToolItem(),
self.make_toolbutton(gtk.STOCK_FIND,
_('_DataMine'),
self.datamine_clicked,
tip=_('Search Repository History')),
- gtk.SeparatorToolItem()
+ gtk.SeparatorToolItem(),
+ self.make_toolbutton(gtk.STOCK_JUMP_TO,
+ _('Select Revision'),
+ self.goto_clicked,
+ tip=_('Select revision')),
+ gtk.SeparatorToolItem(),
+ self.make_toolbutton(gtk.STOCK_REFRESH,
+ _('Re_fresh'),
+ self.refresh_clicked,
+ tip=_('Reload revision history')),
+ gtk.SeparatorToolItem(),
] + self.changeview.get_tbbuttons()
if not self.opts.get('from-synch'):
self.synctb = self.make_toolbutton(gtk.STOCK_NETWORK,
@@ -73,6 +79,16 @@ self.synch_clicked,
tip=_('Launch synchronize tool'))
tbar += [gtk.SeparatorToolItem(), self.synctb]
+
+ sep = gtk.SeparatorToolItem()
+ sep.set_expand(True)
+ sep.set_draw(False)
+ self.nextbutton = self.make_toolbutton(gtk.STOCK_GO_DOWN,
+ _('Load more'), self.more_clicked, tip=_('load more revisions'))
+ self.allbutton = self.make_toolbutton(gtk.STOCK_GOTO_BOTTOM,
+ _('Load all'), self.load_all_clicked, tip=_('load all revisions'))
+ tbar += [sep, self.nextbutton, self.allbutton]
+
return tbar
def synch_clicked(self, toolbutton, data):
@@ -101,11 +117,13 @@ def toggle_view_column(self, button, property):
active = button.get_active()
self.graphview.set_property(property, active)
+ if property in ('branch-color') and self.ready:
+ self.reload_log()
- def more_clicked(self, button):
+ def more_clicked(self, button, data=None):
self.graphview.next_revision_batch(self.limit)
- def load_all_clicked(self, button):
+ def load_all_clicked(self, button, data=None):
self.graphview.load_all_revisions()
self.nextbutton.set_sensitive(False)
self.allbutton.set_sensitive(False)
@@ -194,62 +212,23 @@ button.set_active(self.showcol.get('branch', False))
button.set_draw_as_radio(True)
menu.append(button)
- menu.show_all()
- return menu
-
- def filter_menu(self):
- menu = gtk.Menu()
-
- button = gtk.RadioMenuItem(None, _('Show All Revisions'))
- button.set_active(True)
- button.connect('toggled', self.filter_selected, 'all')
+ button = gtk.CheckMenuItem(_('Color by Branch'))
+ button.connect('toggled', self.toggle_view_column,
+ 'branch-color')
+ button.set_active(self.branch_color)
+ button.set_draw_as_radio(True)
menu.append(button)
-
- self.newbutton = gtk.RadioMenuItem(button, _('Show New Revisions'))
- self.newbutton.connect('toggled', self.filter_selected, 'new')
- menu.append(self.newbutton)
-
- button = gtk.RadioMenuItem(button, _('Show Tagged Revisions'))
- button.connect('toggled', self.filter_selected, 'tagged')
- menu.append(button)
-
- button = gtk.RadioMenuItem(button, _('Show Revision Ancestry'))
- button.connect('toggled', self.filter_selected, 'ancestry')
- menu.append(button)
-
- button = gtk.RadioMenuItem(button, _('Show Working Parents'))
- button.connect('toggled', self.filter_selected, 'parents')
- menu.append(button)
-
- button = gtk.RadioMenuItem(button, _('Show Head Revisions'))
- button.connect('toggled', self.filter_selected, 'heads')
- menu.append(button)
-
- button = gtk.RadioMenuItem(button, _('Show Only Merge Revisions'))
- button.connect('toggled', self.filter_selected, 'only_merges')
- menu.append(button)
-
- button = gtk.RadioMenuItem(button, _('Show Non-Merge Revisions'))
- button.connect('toggled', self.filter_selected, 'no_merges')
- menu.append(button)
-
- self.custombutton = gtk.RadioMenuItem(button, _('Custom Filter'))
- self.custombutton.set_sensitive(False)
- menu.append(self.custombutton)
-
menu.show_all()
return menu
def prepare_display(self):
'Called at end of display() method'
+ self.ready = True
self.opts['rev'] = [] # This option is dangerous - used directly by hg
self.opts['revs'] = None
os.chdir(self.repo.root) # for paths relative to repo root
- origtip = len(self.repo)
- self.graphview.set_property('original-tip-revision', origtip)
- self.origtip = origtip
-
+ self.graphview.set_property('original-tip-revision', self.origtip)
if self.opts.get('orig-tip') is not None:
origtip = self.opts['orig-tip']
if origtip != len(self.repo):
@@ -262,14 +241,15 @@ elif 'revrange' in self.opts:
self.custombutton.set_active(True)
self.graphview.refresh(True, None, self.opts)
- elif self.pats == [self.repo.root] or self.pats == ['']:
+ elif not self.pats:
+ self.reload_log()
+ elif len(self.pats) == 1 and \
+ self.pats[0] in (self.repo.root, self.repo.root+os.sep, ''):
self.pats = []
self.reload_log()
- elif self.pats:
+ else:
self.custombutton.set_active(True)
self.reload_log(pats = self.pats)
- else:
- self.reload_log()
def get_graphlimit(self, suggestion):
limit_opt = self.repo.ui.config('tortoisehg', 'graphlimit', '500')
@@ -287,6 +267,7 @@ settings = gdialog.GDialog.save_settings(self)
settings['glog-vpane'] = self.vpaned.get_position()
settings['glog-hpane'] = self.hpaned.get_position()
+ settings['branch-color'] = self.graphview.get_property('branch-color')
for col in ('rev', 'date', 'id', 'branch', 'utc'):
vis = self.graphview.get_property(col+'-column-visible')
settings['glog-vis-'+col] = vis
@@ -313,10 +294,12 @@ gdialog.GDialog.load_settings(self, settings)
self.setting_vpos = -1
self.setting_hpos = -1
+ self.branch_color = False
self.showcol = {}
try:
self.setting_vpos = settings['glog-vpane']
self.setting_hpos = settings['glog-hpane']
+ self.branch_color = settings.get('branch-color', False)
for col in ('rev', 'date', 'id', 'branch', 'utc'):
vis = settings['glog-vis-'+col]
self.showcol[col] = vis
@@ -347,8 +330,13 @@ self.graphview.refresh(True, branch, self.opts)
else:
self.pats = filteropts.get('pats', [])
- self.graphview.refresh(False, self.pats, self.opts)
+ if len(self.pats) == 1 and not os.path.isdir(self.pats[0]):
+ self.opts['filehist'] = self.pats[0]
+ self.graphview.refresh(True, self.pats, self.opts)
+ else:
+ self.graphview.refresh(False, self.pats, self.opts)
elif self.filter == 'all':
+ self.branchcombo.set_active(-1)
self.graphview.refresh(True, None, self.opts)
elif self.filter == 'new':
self.opts['revrange'] = [len(self.repo)-1, self.origtip]
@@ -356,9 +344,6 @@ elif self.filter == 'only_merges':
self.opts['only_merges'] = True
self.graphview.refresh(False, [], self.opts)
- elif self.filter == 'no_merges':
- self.opts['no_merges'] = True
- self.graphview.refresh(False, [], self.opts)
elif self.filter == 'ancestry':
if not self.currow:
return
@@ -395,11 +380,20 @@ m.append(create_menu(_('e_mail patch'), self.email_patch))
m.append(create_menu(_('_bundle rev:tip'), self.bundle_rev_to_tip))
m.append(create_menu(_('add/remove _tag'), self.add_tag))
- m.append(create_menu(_('backout revision'), self.backout_rev))
+ self.cmenu_backout = create_menu(_('backout revision'),
+ self.backout_rev)
+ m.append(self.cmenu_backout)
m.append(create_menu(_('_revert'), self.revert))
+ m.append(create_menu(_('_archive'), self.archive))
+ # Load extension support for commands which need it
+ extensions.loadall(self.ui)
+
+ # need transplant extension for transplant command
+ extensions.load(self.ui, 'transplant', None)
+ m.append(create_menu(_('transp_lant to local'), self.transplant_rev))
+
# need mq extension for strip command
- extensions.loadall(self.ui)
extensions.load(self.ui, 'mq', None)
m.append(create_menu(_('strip revision'), self.strip_rev))
@@ -421,12 +415,27 @@ self.bundle_revs))
self.cmenu_merge2 = create_menu(_('_merge with'), self.merge)
m.append(self.cmenu_merge2)
+
+ # Load extension support for commands which need it
+ extensions.loadall(self.ui)
+
+ # need transplant extension for transplant command
+ extensions.load(self.ui, 'transplant', None)
+ m.append(create_menu(_('transplant revision range to local'),
+ self.transplant_revs))
+
+ # need rebase extension for rebase command
+ extensions.load(self.ui, 'rebase', None)
+ m.append(create_menu(_('rebase on top of selected'),
+ self.rebase_selected))
+
m.connect_after('selection-done', self.restore_original_selection)
m.show_all()
return m
def get_body(self):
self.filter_dialog = None
+ self.gorev_dialog = None
self._menu = self.tree_context_menu()
self._menu2 = self.tree_diff_context_menu()
@@ -457,32 +466,64 @@ self.tree.connect('thg-parent', self.thgparent)
self.connect('thg-refresh', self.thgrefresh)
- hbox = gtk.HBox()
- hbox.pack_start(self.graphview, True, True, 0)
- vbox = gtk.VBox()
- self.colmenu = gtk.MenuToolButton('')
- self.colmenu.set_menu(self.view_menu())
+ filterbox = gtk.HBox()
+
+ branchcombo = gtk.combo_box_new_text()
+ for name in self.repo.branchtags().keys():
+ branchcombo.append_text(name)
+ branchcombo.connect('changed', self.select_branch)
+ filterbox.pack_start(branchcombo, False)
+ self.branchcombo = branchcombo
+
+ all = gtk.RadioButton(None, _('all'))
+ all.set_active(True)
+ all.connect('toggled', self.filter_selected, 'all')
+ filterbox.pack_start(all, False)
+
+ self.newbutton = gtk.RadioButton(all, _('new'))
+ self.newbutton.connect('toggled', self.filter_selected, 'new')
+ filterbox.pack_start(self.newbutton, False)
+
+ tagged = gtk.RadioButton(all, _('tagged'))
+ tagged.connect('toggled', self.filter_selected, 'tagged')
+ filterbox.pack_start(tagged, False)
+
+ ancestry = gtk.RadioButton(all, _('ancestry'))
+ ancestry.connect('toggled', self.filter_selected, 'ancestry')
+ filterbox.pack_start(ancestry, False)
+
+ parents = gtk.RadioButton(all, _('parents'))
+ parents.connect('toggled', self.filter_selected, 'parents')
+ filterbox.pack_start(parents, False)
+
+ heads = gtk.RadioButton(all, _('heads'))
+ heads.connect('toggled', self.filter_selected, 'heads')
+ filterbox.pack_start(heads, False)
+
+ merges = gtk.RadioButton(all, _('merges'))
+ merges.connect('toggled', self.filter_selected, 'only_merges')
+ filterbox.pack_start(merges, False)
+
+ self.custombutton = gtk.RadioButton(all, _('custom'))
+ self.custombutton.set_sensitive(False)
+ filterbox.pack_start(self.custombutton, False)
+
+ colmenu = gtk.MenuToolButton('')
+ colmenu.set_menu(self.view_menu())
# A MenuToolButton has two parts; a Button and a ToggleButton
# we want to see the togglebutton, but not the button
- b = self.colmenu.child.get_children()[0]
+ b = colmenu.child.get_children()[0]
b.unmap()
b.set_sensitive(False)
- self.nextbutton = gtk.ToolButton(gtk.STOCK_GO_DOWN)
- self.nextbutton.connect('clicked', self.more_clicked)
- self.allbutton = gtk.ToolButton(gtk.STOCK_GOTO_BOTTOM)
- self.allbutton.connect('clicked', self.load_all_clicked)
- vbox.pack_start(self.colmenu, False, False)
- vbox.pack_start(gtk.Label(''), True, True) # expanding blank label
- vbox.pack_start(self.nextbutton, False, False)
- vbox.pack_start(self.allbutton, False, False)
- self.nextbutton.set_tooltip(self.tooltips,
- _('show next %d revisions') % self.limit)
- self.allbutton.set_tooltip(self.tooltips,
- _('show all remaining revisions'))
+ filterbox.pack_start(gtk.Label(''), True, True) # expanding blank label
+ filterbox.pack_start(colmenu, False, False)
- hbox.pack_start(vbox, False, False, 0)
- treeframe.add(hbox)
+ vbox = gtk.VBox()
+ vbox.pack_start(filterbox, False, False, 0)
+ vbox.pack_start(self.graphview, True, True, 0)
+
+ treeframe.add(vbox)
treeframe.show_all()
# Add ChangeSet instance to bottom half of vpane
@@ -515,6 +556,43 @@ parent = self.repo['.'].rev()
self.graphview.set_revision_id(parent)
+ def goto_clicked(self, toolbutton, data=None):
+ if self.gorev_dialog:
+ self.gorev_dialog.show()
+ self.gorev_dialog.present()
+ else:
+ self.show_goto_dialog()
+
+ def select_branch(self, combo):
+ row = combo.get_active()
+ if row >= 0:
+ self.custombutton.set_active(True)
+ self.reload_log(branch=combo.get_model()[row][0])
+
+ def show_goto_dialog(self):
+ 'Launch a modeless goto revision dialog'
+ def goto_rev_(rev):
+ self.goto_rev(rev)
+
+ def response_(dialog, response_id):
+ dialog.hide()
+
+ def delete_event(dialog, event, data=None):
+ # return True to prevent the dialog from being destroyed
+ return True
+
+ dlg = gorev.GotoRevDialog(goto_rev_)
+ dlg.connect('response', response_)
+ dlg.connect('delete-event', delete_event)
+ dlg.set_modal(False)
+ dlg.show()
+
+ self.gorev_dialog = dlg
+
+ def goto_rev(self, revision):
+ rid = self.repo[revision].rev()
+ self.graphview.set_revision_id(rid, load=True)
+
def strip_rev(self, menuitem):
rev = self.currow[treemodel.REVID]
res = gdialog.Confirm(_('Confirm Strip Revision(s)'), [], self,
@@ -614,6 +692,38 @@ dlg.run()
dlg.hide()
+ def rebase_selected(self, menuitem):
+ """Rebase revision on top of selection (1st on top of 2nd)."""
+ revs = list(self.revs)
+ res = gdialog.Confirm(_('Confirm Rebase Revision'), [], self,
+ _('Rebase revision %d on top of %d?') % (revs[0], revs[1])).run()
+ if res != gtk.RESPONSE_YES:
+ return
+ cmdline = ['hg', 'rebase', '--source', str(revs[0]),
+ '--dest', str(revs[1])]
+ dialog = hgcmd.CmdDialog(cmdline)
+ dialog.show_all()
+ dialog.run()
+ dialog.hide()
+ self.repo.invalidate()
+ self.reload_log()
+ self.changeview._buffer.set_text('')
+ self.changeview._filelist.clear()
+
+ def transplant_revs(self, menuitem):
+ """Transplant revision range on top of current revision."""
+ revs = list(self.revs)
+ revs.sort()
+ cmdline = ['hg', 'transplant', '%s:%s' % (str(revs[0]), str(revs[1]))]
+ dialog = hgcmd.CmdDialog(cmdline)
+ dialog.show_all()
+ dialog.run()
+ dialog.hide()
+ self.repo.invalidate()
+ self.reload_log()
+ self.changeview._buffer.set_text('')
+ self.changeview._filelist.clear()
+
def add_tag(self, menuitem):
# save tag info for detecting new tags added
oldtags = self.repo.tagslist()
@@ -746,6 +856,28 @@ elif not oldparents == newparents:
self.refresh_model()
+ def archive(self, menuitem):
+ rev = self.currow[treemodel.REVID]
+ parents = [x.node() for x in self.repo.parents()]
+ dialog = archive.ArchiveDialog(rev)
+ dialog.set_transient_for(self)
+ dialog.show_all()
+ dialog.present()
+ dialog.set_transient_for(None)
+
+ def transplant_rev(self, menuitem):
+ """Transplant selection on top of current revision."""
+ rev = self.currow[treemodel.REVID]
+ cmdline = ['hg', 'transplant', str(rev)]
+ dialog = hgcmd.CmdDialog(cmdline)
+ dialog.show_all()
+ dialog.run()
+ dialog.hide()
+ self.repo.invalidate()
+ self.reload_log()
+ self.changeview._buffer.set_text('')
+ self.changeview._filelist.clear()
+
def selection_changed(self, treeview):
self.currow = self.graphview.get_revision()
rev = self.currow[treemodel.REVID]
@@ -793,6 +925,11 @@ can_merge = selrev not in parents and len(parents) < 2
self.cmenu_merge.set_sensitive(can_merge)
+ op1, op2 = self.repo.dirstate.parents()
+ node = self.repo[selrev].node()
+ a = self.repo.changelog.ancestor(op1, node)
+ self.cmenu_backout.set_sensitive(a == node)
+
# display the context menu
self._menu.popup(None, None, None, button, time)
return True
@@ -820,8 +957,8 @@ 'limit':0, 'rev':[], 'removed':False, 'no_merges':False,
'date':None, 'only_merges':None, 'prune':[], 'git':False,
'verbose':False, 'include':[], 'exclude':[], 'from-synch':False,
- 'orig-tip':None, 'filehist':None
+ 'orig-tip':None, 'filehist':None, 'canonpats':[]
}
cmdoptions.update(opts)
- pats = hglib.canonpaths(pats)
+ pats = hglib.canonpaths(pats) + cmdoptions['canonpats']
return GLog(ui, None, None, pats, cmdoptions)
|
@@ -73,7 +73,7 @@ ascent = pango.PIXELS(metrics.get_ascent())
descent = pango.PIXELS(metrics.get_descent())
- self._box_size = ascent + descent + 6
+ self._box_size = ascent + descent
return self._box_size
def set_colour(self, ctx, colour, bg, fg):
|
@@ -9,12 +9,24 @@ __author__ = "Joel Rosdahl <joel@rosdahl.net>, Steve Borho <steve@borho.org>"
from mercurial.node import nullrev
-from mercurial import cmdutil, util, ui
+from mercurial import cmdutil, util
def __get_parents(repo, rev):
return [x for x in repo.changelog.parentrevs(rev) if x != nullrev]
-def revision_grapher(repo, start_rev, stop_rev, branch=None, noheads=False):
+def _color_of(repo, rev, nextcolor, preferredcolor, branch_color=False):
+ if not branch_color:
+ if preferredcolor[0]:
+ rv = preferredcolor[0]
+ preferredcolor[0] = None
+ else:
+ rv = nextcolor[0]
+ nextcolor[0] = nextcolor[0] + 1
+ return rv
+ else:
+ return sum([ord(c) for c in repo[rev].branch()])
+
+def revision_grapher(repo, start_rev, stop_rev, branch=None, noheads=False, branch_color=False):
"""incremental revision grapher
This generator function walks through the revision history from
@@ -33,7 +45,7 @@ curr_rev = start_rev
revs = []
rev_color = {}
- nextcolor = 0
+ nextcolor = [0]
while curr_rev >= stop_rev:
# Compute revs and next_revs.
if curr_rev not in revs:
@@ -47,30 +59,29 @@ continue
# New head.
revs.append(curr_rev)
- rev_color[curr_rev] = curcolor = nextcolor ; nextcolor += 1
+ rev_color[curr_rev] = _color_of(repo, curr_rev, nextcolor, [None], branch_color)
r = __get_parents(repo, curr_rev)
while r:
r0 = r[0]
if r0 < stop_rev: break
if r0 in rev_color: break
- rev_color[r0] = curcolor
+ if not branch_color:
+ rev_color[r0] = rev_color[curr_rev]
+ else:
+ rev_color[r0] = _color_of(repo, r0, None, None, True)
r = __get_parents(repo, r0)
- curcolor = rev_color[curr_rev]
rev_index = revs.index(curr_rev)
next_revs = revs[:]
# Add parents to next_revs.
parents = __get_parents(repo, curr_rev)
parents_to_add = []
- preferred_color = curcolor
+ preferred_color = [rev_color[curr_rev]]
for parent in parents:
if parent not in next_revs:
parents_to_add.append(parent)
if parent not in rev_color:
- if preferred_color:
- rev_color[parent] = preferred_color; preferred_color = None
- else:
- rev_color[parent] = nextcolor ; nextcolor += 1
+ rev_color[parent] = _color_of(repo, parent, nextcolor, preferred_color, branch_color)
next_revs[rev_index:rev_index + 1] = parents_to_add
lines = []
@@ -83,7 +94,7 @@ color = rev_color[parent]
lines.append( (i, next_revs.index(parent), color) )
- yield (curr_rev, (rev_index, curcolor), lines, parents)
+ yield (curr_rev, (rev_index, rev_color[curr_rev]), lines, parents)
revs = next_revs
curr_rev -= 1
|
|
@@ -84,12 +84,20 @@ 'Show branch',
False,
gobject.PARAM_READWRITE),
+ 'branch-color': (gobject.TYPE_BOOLEAN,
+ 'Branch color',
+ 'Color by branch',
+ False,
+ gobject.PARAM_READWRITE)
}
__gsignals__ = {
'revisions-loaded': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
()),
+ 'batch-loaded': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ()),
'revision-selected': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
())
@@ -111,6 +119,7 @@ self.construct_treeview()
self.pbar = pbar
self.origtip = None
+ self.branch_color = False
def set_repo(self, repo, pbar=None):
self.repo = repo
@@ -160,7 +169,7 @@ start = len(self.repo.changelog) - 1
noheads = opts.get('noheads', False)
self.grapher = revision_grapher(self.repo, start, end, pats,
- noheads)
+ noheads, self.branch_color)
elif opts.get('revs', None):
self.grapher = dumb_log_generator(self.repo, opts['revs'])
else:
@@ -219,9 +228,11 @@ if width > 500:
width = 500
self.graph_column.set_fixed_width(width)
- self.graph_column.set_max_width(width)
+ # Allow the user to set size as they like
+ #self.graph_column.set_max_width(500)
self.graph_column.set_visible(self.show_graph)
+ self.emit('batch-loaded')
if stopped:
self.emit('revisions-loaded')
if revision is not None:
@@ -239,6 +250,8 @@ return self.rev_column.get_visible()
elif property.name == 'branch-column-visible':
return self.branch_column.get_visible()
+ elif property.name == 'branch-color':
+ return self.branch_color
elif property.name == 'utc-column-visible':
return self.utc_column.get_visible()
elif property.name == 'repo':
@@ -261,6 +274,8 @@ self.rev_column.set_visible(value)
elif property.name == 'branch-column-visible':
self.branch_column.set_visible(value)
+ elif property.name == 'branch-color':
+ self.branch_color = value
elif property.name == 'utc-column-visible':
self.utc_column.set_visible(value)
elif property.name == 'repo':
@@ -296,7 +311,7 @@ row = self.index[revid]
self.treeview.scroll_to_cell(row, use_align=True, row_align=0.5)
- def set_revision_id(self, revid):
+ def set_revision_id(self, revid, load=False):
"""Change the currently selected revision.
:param revid: Revision id of revision to display.
@@ -305,6 +320,20 @@ row = self.index[revid]
self.treeview.set_cursor(row)
self.treeview.grab_focus()
+ elif load:
+ handler = None
+
+ def loaded(dummy):
+ if revid in self.index:
+ if handler is not None:
+ self.disconnect(handler)
+ self.set_revision_id(revid)
+ self.scroll_to_revision(revid)
+ else:
+ self.next_revision_batch(self.batchsize)
+
+ handler = self.connect('batch-loaded', loaded)
+ self.next_revision_batch(self.batchsize)
def get_parents(self):
"""Return the parents of the currently selected revision.
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
Loading...