Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
# changeset.py - Changeset dialog for TortoiseHg## Copyright 2008 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.importosimportgtkimportgobjectimportpangoimportQueueimportbinasciifrommercurialimportcmdutil,util,patch,mdifffromtortoisehg.util.i18nimport_from tortoisehg.util.hglib import *
from tortoisehg.util import shlib, hglib
-from tortoisehg.hgtk import gdialog, gtklib, hgcmd, statusbar
+from tortoisehg.hgtk import csinfo, gdialog, gtklib, hgcmd, statusbar
class ChangeSet(gdialog.GDialog):
'GTK+ based dialog for displaying repository logs'
def__init__(self,ui,repo,cwd,pats,opts,stbar=None):gdialog.GDialog.__init__(self,ui,repo,cwd,pats,opts)self.stbar=stbarself.glog_parent=Noneself.bfile=Noneself.nothing_loaded=Truedefget_title(self):title=_('%s changeset ')%self.get_reponame()rev=self.opts['rev']ifisinstance(rev,str):title+=revelse:title+=rev[0]returntitledefget_icon(self):return'menushowchanged.ico'defget_tbbuttons(self):return[]defparent_toggled(self,button):self.load_details(self.currev)defprepare_display(self):self.currow=Noneself.graphview=Noneself.glog_parent=NoneYnode0,node1=cmdutil.revpair(self.repo,self.opts.get('rev'))self.load_details(self.repo.changelog.rev(node0))defsave_settings(self):settings=gdialog.GDialog.save_settings(self)settings['changeset']=self._hpaned.get_position()returnsettingsdefload_settings(self,settings):gdialog.GDialog.load_settings(self,settings)ifsettingsand'changeset'insettings:self._setting_hpos=settings['changeset']else:self._setting_hpos=-1defdiff_other_parent(self):returnself.other_parent_checkbutton.get_active()defload_details(self,rev):'Load selected changeset details into buffer and filelist'self.currev=revctx=self.repo[rev]ifnotctx:returnifself.nothing_loaded:self.other_parent_box.pack_start(self.other_parent_checkbutton,False,False)self.nothing_loaded=Falseparents=ctx.parents()title=self.get_title()iflen(parents)==2:self.other_parent_box.show_all()ifself.diff_other_parent():title+=':'+str(parents[1].rev())else:title+=':'+str(parents[0].rev())else:self.other_parent_box.hide_all()ifself.other_parent_checkbutton.get_active():# Parent button must be pushed out, but this# will cause load_details to be called again# so we exit out to prevent recursion.self.other_parent_checkbutton.set_active(False)returnifself.clipboard:self.clipboard.set_text(str(ctx))self.set_title(title)ifself.diff_other_parent():parent=parents[1].node()elifparents:parent=parents[0].node()else:parent=self.repo[-1]pats=self.patsifself.graphview:(path,focus)=self.graphview.treeview.get_cursor()ifpath:wfile=self.graphview.get_wfile_at_path(path)ifwfile:pats.append(wfile)self._filelist.clear()self._filelist.append(('*',_('[All Files]'),''))modified,added,removed=self.repo.status(parent,ctx.node())[:3]selrow=Noneforfinmodified:iffinpats:selrow=len(self._filelist)self._filelist.append(('M',toutf(f),f))forfinadded:iffinpats:selrow=len(self._filelist)self._filelist.append(('A',toutf(f),f))forfinremoved:iffinpats:selrow=len(self._filelist)self._filelist.append(('R',toutf(f),f))self.curnodes=(parent,ctx.node())ifselrowisnotNone:self._filesel.select_path((selrow,))eliflen(self._filelist)>1:self._filesel.select_path((1,))else:self._filesel.select_path((0,))defload_patch_details(self,patchfile):'Load specified patch details into buffer and file list'self._filelist.clear()self._filelist.append(('*',_('[All Files]'),''))# append files & collect hunksself.currev=-1self.curphunks={}self.curpatch=patchfilepf=open(self.curpatch)defget_path(a,b):type=(a=='/dev/null')and'A'or'M'type=(b=='/dev/null')and'R'ortyperawpath=(b!='/dev/null')andboraifnot(rawpath.startswith('a/')orrawpath.startswith('b/')):returntype,rawpathreturntype,rawpath.split('/',1)[-1]hunks=[]files=[]map={'MODIFY':'M','ADD':'A','DELETE':'R','RENAME':'','COPY':''}try:try:forstate,valuesinpatch.iterhunks(self.ui,pf):ifstate=='git':forminvalues:f=m.pathself._filelist.append((map[m.op],toutf(f),f))files.append(f)elifstate=='file':type,path=get_path(values[0],values[1])self.curphunks[path]=hunks=['diff']ifpathnotinfiles:self._filelist.append((type,toutf(path),path))files.append(path)elifstate=='hunk':hunks.extend([l.rstrip('\r\n')forlinvalues.hunk])else:raise_('unknown hunk type: %s')%stateexceptpatch.NoHunks:passfinally:pf.close()# select first fileiflen(self._filelist)>1:self._filesel.select_path((1,))else:self._filesel.select_path((0,))deffilelist_rowchanged(self,sel):model,path=sel.get_selected()ifnotpath:returnstatus,file_utf8,file=model[path]ifself.currev!=-1:self.curfile=fileself.generate_change_header()ifself.curfile:self.append_diff(self.curfile)else:for_,_,finmodel:self.append_diff(f)else:self.generate_patch_header()iffile:self.append_patch_diff(file)else: self.append_all_patch_diffs()
def generate_change_header(self):
-buf, rev = self._buffer, self.currev
+ self.csetinfo.update(self.currev)- def pad_right(text):- spaces = ' ' * (12 - len(hglib.tounicode(text)))- return text + spaces-- def title_line(title, text, tag):- utext = toutf(pad_right(title) + text)- buf.insert_with_tags_by_name(eob, utext, tag)- buf.insert(eob, "\n")-+ buf = self._buffer buf.set_text('')
- ctx = self.repo[rev]- eob = buf.get_end_iter()
-date = displaytime(ctx.date())- change = str(rev) + ' (' + str(ctx) + ')'- try:- lines = ctx.description().splitlines()- summary = toutf(lines and lines[0] or '')- except:- summary = ''- tags = ' '.join(ctx.tags())-- branch = ctx.branch()-- utext = toutf(pad_right(_('changeset:')) + change)- buf.insert_with_tags_by_name(eob, utext, 'changeset')- utext = toutf(' ' + summary)- buf.insert_with_tags_by_name(eob, utext, 'changeset-summary')- buf.insert(eob, "\n")-- if branch != 'default':- title_line(_('branch:'), branch, 'greybg')- title_line(_('user:'), ctx.user(), 'changeset')- title_line(_('date:'), date, 'changeset')-- def insert_link(title, ctx, highlight=False):- try:- lines = ctx.description().splitlines()- summary = toutf(lines and lines[0] or '')- except:- summary = ''-- link = str(ctx.rev()) + ' (' + str(ctx) + ')'- if ctx.branch() != branch:- link += ' [' + toutf(ctx.branch()) + ']'-- hl = ''- if highlight:- hl = 'hl'- ins = buf.insert_with_tags_by_name- ins(eob, pad_right(title), 'parent' + hl)- ins(eob, link, 'link' + hl)- ins(eob, ' ' + summary, 'changeset-summary')- buf.insert(eob, "\n")-- ismerge = (len(ctx.parents()) == 2)-- if ismerge and self.diff_other_parent():- parentindex = 1 - else:- parentindex = 0-- for pctx in ctx.parents():- hl = ismerge and pctx == ctx.parents()[parentindex]- insert_link(_('parent:'), pctx, hl)-- for cctx in ctx.children():- insert_link(_('child:'), cctx)-- if tags: - title_line(_('tags:'), tags, 'tag')-- extra = ctx.extra()- try:- ts = extra['transplant_source']- try:- tctx = self.repo[ts]
- insert_link(_('transplant:'), tctx)- except (LookupError, RepoLookupError, RepoError):- title_line(_('transplant:'), binascii.hexlify(ts), 'changeset')- except KeyError:- pass-+ ctx = self.repo[self.currev]
desc = toutf(ctx.description())
buf.insert(eob, '\n' + desc + '\n\n')
defgenerate_patch_header(self):buf=self._bufferbuf.set_text('')eob=buf.get_end_iter()# copy from generate_change_headerdeftitle_line(title,text,tag):pad=' '*(12-len(title))utext=toutf(title+pad+text)buf.insert_with_tags_by_name(eob,utext,tag)buf.insert(eob,'\n')pf=open(self.curpatch)try:data=patch.extract(self.ui,pf)tmp,msg,user,date,branch,node,p1,p2=datatry:# titlepatchtitle=os.path.basename(self.curpatch)ifnode:patchtitle+=' (%s)'%node[:12]title_line(_('patch:'),patchtitle,'changeset')# branchifbranch:title_line(_('branch:'),toutf(branch),'greybg')# userifuser:title_line(_('user:'),toutf(user),'changeset')# dateifdate:title_line(_('date:'),displaytime(util.parsedate(date)),'changeset')# parentsforpnodein(p1,p2):ifpnodeisNone:continuetitle_line(_('parent:'),pnode[:12],'parent')# commit messageifmsg:cmsg='\n'+toutf(msg.rstrip('\r\n'))+'\n\n'buf.insert(eob,cmsg)finally:iftmp:os.unlink(tmp)finally:pf.close()defappend_diff(self,wfile):ifnotwfile:returnbuf,rev=self._buffer,self.currevn1,n2=self.curnodeseob=buf.get_end_iter()offset=eob.get_offset()try:fctx=self.repo[rev].filectx(wfile)exceptLookupError:fctx=Noneiffctxandfctx.size()>getmaxdiffsize(self.ui):lines=['diff',_(' %s is larger than the specified max diff size')%wfile]else:lines=[]m=cmdutil.matchfiles(self.repo,[wfile])opts=mdiff.diffopts(git=True,nodates=True)try:forsinpatch.diff(self.repo,n1,n2,match=m,opts=opts):lines.extend(s.splitlines())except(RepoLookupError,RepoError,LookupError),e:err=_('Repository Error: %s, refresh suggested')%str(e)lines=['diff','',err]tags,lines=self.prepare_diff(lines,offset,wfile)forlinlines:buf.insert(eob,l)# inserts the tagsforname,p0,p1intags:i0=buf.get_iter_at_offset(p0)i1=buf.get_iter_at_offset(p1)buf.apply_tag_by_name(name,i0,i1)sob,eob=buf.get_bounds()pos=buf.get_iter_at_offset(offset)buf.apply_tag_by_name('mono',pos,eob)returnTruedefappend_patch_diff(self,patchfile):ifnotpatchfile:return# append diffsbuf=self._buffereob=buf.get_end_iter()offset=eob.get_offset()lines=self.curphunks[patchfile]tags,lines=self.prepare_diff(lines,offset,patchfile)forlineinlines:buf.insert(eob,line)# insert the tagsforname,p0,p1intags:i0=buf.get_iter_at_offset(p0)i1=buf.get_iter_at_offset(p1)buf.apply_tag_by_name(name,i0,i1)sob,eob=buf.get_bounds()pos=buf.get_iter_at_offset(offset)buf.apply_tag_by_name('mono',pos,eob)defappend_all_patch_diffs(self):model=self._filelistiflen(model)>1:forst,fu,fninmodel:self.append_patch_diff(fn)else:self._buffer.insert(self._buffer.get_end_iter(),'\n'+_('[no hunks to display]'))defprepare_diff(self,difflines,offset,fname):'Borrowed from hgview; parses changeset diffs'defaddtag(name,offset,length):iftagsandtags[-1][0]==nameandtags[-1][2]==offset:tags[-1][2]+=lengthelse:tags.append([name,offset,offset+length])add,rem=0,0forlindifflines[1:]:ifl.startswith('+'):add+=1elifl.startswith('-'):rem+=1outlines=[]tags=[]txt=toutf('=== (+%d,-%d) %s ===\n'%(add,rem,fname))addtag('greybg',offset,len(txt))outlines.append(txt)offset+=len(txt.decode('utf-8'))forl1indifflines[1:]:l=toutf(l1)ifl.startswith('+++'):continueifl.startswith('---'):continueifl.startswith('@@'):tag='blue'elifl.startswith('+'):tag='green'l=diffexpand(l)elifl.startswith('-'):tag='red'l=diffexpand(l)else:tag='black'l=diffexpand(l)l=l+"\n"length=len(l.decode('utf-8'))addtag(tag,offset,length)outlines.append(l)offset+=lengthreturntags,outlinesdeflink_event(self,tag,widget,event,liter):ifevent.type!=gtk.gdk.BUTTON_RELEASE:returntext=self.get_link_text(tag,widget,liter)ifnottext:returnlinkrev=long(text.split(' ')[0])ifself.graphview:self.graphview.set_revision_id(linkrev,load=True)else:self.load_details(linkrev)defget_link_text(self,tag,widget,liter):'handle clicking on a link in a textview'text_buffer=widget.get_buffer()beg=liter.copy()whilenotbeg.begins_tag(tag):beg.backward_char()end=liter.copy()whilenotend.ends_tag(tag):end.forward_char()text=text_buffer.get_text(beg,end)returntextdeffile_context_menu(self):defcreate_menu(label,callback):menuitem=gtk.MenuItem(label,True)menuitem.connect('activate',callback)menuitem.set_border_width(1)returnmenuitemmenu=gtklib.MenuItems()menu.append(create_menu(_('_Visual Diff'),self.diff_file_rev))menu.append(create_menu(_('Diff to _local'),self.diff_to_local))menu.append_sep()menu.append(create_menu(_('_View at Revision'),self.view_file_rev))self.save_menu=create_menu(_('_Save at Revision...'),self.save_file_rev)menu.append(self.save_menu)menu.append_sep()menu.append(create_menu(_('_File History'),self.file_history))self.ann_menu=create_menu(_('_Annotate File'),self.ann_file)menu.append(self.ann_menu)menu.append_sep()menu.append(create_menu(_('_Revert File Contents'),self.revert_file))menu=menu.create_menu()menu.show_all()returnmenudefget_body(self):self.curfile=''ifself.repo.ui.configbool('tortoisehg','copyhash'):sel=(os.name=='nt')and'CLIPBOARD'or'PRIMARY'self.clipboard=gtk.Clipboard(selection=sel)else: self.clipboard = None
self.filemenu = self.file_context_menu()
+ # changeset frame details_frame = gtk.Frame()
details_frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
scroller = gtk.ScrolledWindow()
scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
details_frame.add(scroller)
+ details_box = gtk.VBox()+ scroller.add_with_viewport(details_box)+ scroller.child.set_shadow_type(gtk.SHADOW_NONE)++ ## changeset panel+ style = csinfo.panelstyle(contents=('cset', 'branch', 'user', 'date',+ 'parents', 'children', 'tags', 'transplant'))+ def data_func(widget, item, ctx):+ def revline_data(ctx):+ desc = ctx.description().replace('\0', '')+ summary = hglib.toutf(desc.split('\n')[0][:80])+ return (str(ctx.rev()), str(ctx), summary)+ if item == 'cset':+ return revline_data(ctx)+ elif item == 'branch':+ value = hglib.toutf(ctx.branch())+ return value != 'default' and value or None+ elif item == 'parents':+ return [revline_data(ctx) for ctx in ctx.parents()]+ elif item == 'children':+ return [revline_data(ctx) for ctx in ctx.children()]+ elif item == 'transplant':+ extra = ctx.extra()+ try:+ ts = extra['transplant_source']+ try:+ tctx = self.repo[ts]+ return revline_data(tctx)+ except (LookupError, RepoLookupError, RepoError):+ return binascii.hexlify(ts)+ except KeyError:+ return None+ raise csinfo.UnknownItem(item)+ def label_func(widget, item):+ if item == 'cset':+ return _('changeset:')+ elif item == 'parents':+ return _('parent:')+ elif item == 'children':+ return _('child:')+ elif item == 'transplant':+ return _('transplant:')+ raise csinfo.UnknownItem(item)+ def markup_func(widget, item, value):+ def revline_markup(revnum, revid, summary):+ revnum = gtklib.markup(revnum)+ revid = gtklib.markup(revid, face='monospace', size='9000')+ summary = gtklib.markup(summary)+ return '%s (%s) %s' % (revnum, revid, summary)+ if item in ('cset', 'transplant'):+ if isinstance(value, basestring):+ return gtklib.markup(value, face='monospace', size='9000')+ return revline_markup(*value)+ elif item in ('parents', 'children'):+ return [revline_markup(*data) for data in value]+ raise csinfo.UnknownItem(item)+ custom = csinfo.custom(data=data_func, label=label_func,+ markup=markup_func)+ self.csetinfo = csinfo.create(self.repo, None, style, custom)+ details_box.pack_start(self.csetinfo, False, False)+ details_box.pack_start(gtk.HSeparator(), False, False)++ ## changeset diff details_text = gtk.TextView()
details_text.set_wrap_mode(gtk.WRAP_NONE)
details_text.connect('populate-popup', self.add_to_popup)
details_text.set_editable(False)
details_text.modify_font(pango.FontDescription(self.fontcomment))
-scroller.add(details_text)
+details_box.pack_start(details_text)
self._buffer = gtk.TextBuffer()
self.setup_tags()
details_text.set_buffer(self._buffer)
self.textview = details_text
+ ## file list filelist_tree = gtk.TreeView()
filesel = filelist_tree.get_selection()
filesel.connect('changed', self.filelist_rowchanged)
self._filesel=fileselfilelist_tree.connect('button-release-event',self.file_button_release)filelist_tree.connect('popup-menu',self.file_popup_menu)filelist_tree.connect('row-activated',self.file_row_act)filelist_tree.set_search_equal_func(self.search_filelist)filelist_tree.modify_font(pango.FontDescription(self.fontlist))accelgroup=gtk.AccelGroup()ifself.glog_parent:self.glog_parent.add_accel_group(accelgroup)else:self.add_accel_group(accelgroup)mod=gtklib.get_thg_modifier()key,modifier=gtk.accelerator_parse(mod+'d')filelist_tree.add_accelerator('thg-diff',accelgroup,key,modifier,gtk.ACCEL_VISIBLE)filelist_tree.connect('thg-diff',self.thgdiff)self._filelist=gtk.ListStore(gobject.TYPE_STRING,# MAR statusgobject.TYPE_STRING,# filename (utf-8 encoded)gobject.TYPE_STRING,# filename)filelist_tree.set_model(self._filelist)column=gtk.TreeViewColumn(_('Stat'),gtk.CellRendererText(),text=0)filelist_tree.append_column(column)column=gtk.TreeViewColumn(_('Files'),gtk.CellRendererText(),text=1)filelist_tree.append_column(column)list_frame=gtk.Frame()list_frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)scroller=gtk.ScrolledWindow()scroller.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)scroller.add(filelist_tree)flbox=gtk.VBox()flbox.pack_start(scroller)list_frame.add(flbox)self.other_parent_box=gtk.HBox()flbox.pack_start(self.other_parent_box,False,False)btn=gtk.CheckButton(_('Diff to second Parent'))btn.connect('toggled',self.parent_toggled)# don't pack btn yet to keep it initially invisibleself.other_parent_checkbutton=btnself._hpaned=gtk.HPaned()self._hpaned.pack1(list_frame,True,True)self._hpaned.pack2(details_frame,True,True)self._hpaned.set_position(self._setting_hpos)ifself.stbar:# embedded by changelog browserreturnself._hpanedelse:# add status bar for main appvbox=gtk.VBox()vbox.pack_start(self._hpaned,True,True)self.stbar=statusbar.StatusBar()self.stbar.show()vbox.pack_start(gtk.HSeparator(),False,False)vbox.pack_start(self.stbar,False,False)returnvboxdefsearch_filelist(self,model,column,key,iter):'case insensitive filename search'key=key.lower()ifkeyinmodel.get_value(iter,1).lower():returnFalsereturnTruedefsetup_tags(self):'Creates the tags to be used inside the TextView'defmake_texttag(name,**kwargs):'Helper function generating a TextTag'tag=gtk.TextTag(name)forkey,valueinkwargs.iteritems():key=key.replace("_","-")try:tag.set_property(key,value)exceptTypeError:print"Warning the property %s is unsupported in"%keyprint"this version of pygtk"returntagtag_table=self._buffer.get_tag_table()tag_table.add(make_texttag('changeset',foreground='#000090',paragraph_background='#F0F0F0'))tag_table.add(make_texttag('changeset-summary',foreground='black',paragraph_background='#F0F0F0',family='Sans'))tag_table.add(make_texttag('date',foreground='#000090',paragraph_background='#F0F0F0'))tag_table.add(make_texttag('tag',foreground='#000090',paragraph_background='#F0F0F0'))tag_table.add(make_texttag('files',foreground='#5C5C5C',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'))tag_table.add(make_texttag('red',foreground='red'))tag_table.add(make_texttag('green',foreground='darkgreen'))tag_table.add(make_texttag('black',foreground='black'))tag_table.add(make_texttag('greybg',paragraph_background='grey',weight=pango.WEIGHT_BOLD))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)deffile_button_release(self,widget,event):ifevent.button==3andnot(event.state&(gtk.gdk.SHIFT_MASK|gtk.gdk.CONTROL_MASK)):self.file_popup_menu(widget,event.button,event.time)returnFalsedeffile_popup_menu(self,treeview,button=0,time=0):ifnotself.curfile:returnself.filemenu.popup(None,None,None,button,time)# If the filelog entry this changeset references does not link# back to this changeset, it means this changeset did not# actually change the contents of this file, and thus the file# cannot be annotated at this revision (since this changeset# does not appear in the filelog)ctx=self.repo[self.currev]try:fctx=ctx.filectx(self.curfile)has_filelog=fctx.filelog().linkrev(fctx.filerev())==ctx.rev()exceptLookupError:has_filelog=Falseself.ann_menu.set_sensitive(has_filelog)self.save_menu.set_sensitive(has_filelog)returnTruedefthgdiff(self,treeview):# Do not steal ctrl-d from changelog treeviewifnottreeview.is_focus()andself.glog_parent:w=self.glog_parent.get_focus()ifisinstance(w,gtk.TreeView):w.emit('thg-diff')returnFalseifnotself.curfile:returnFalseopts={'change':str(self.currev),'bundle':self.bfile}self._do_diff([self.curfile],opts)deffile_row_act(self,tree,path,column):'Default action is the first entry in the context menu'self.filemenu.get_children()[0].activate()returnTruedefsave_file_rev(self,menuitem):wfile=util.localpath(self.curfile)wfile,ext=os.path.splitext(os.path.basename(wfile))ifwfile:filename="%s@%d%s"%(wfile,self.currev,ext)else:filename="%s@%d"%(ext,self.currev)result=gtklib.NativeSaveFileDialogWrapper(title=_("Save file to"),initial=self.cwd,filename=filename).run()ifresult:ifos.path.exists(result):res=gdialog.Confirm(_('Confirm Overwrite'),[],self,_('The file "%s" already exists!\n\n''Do you want to overwrite it?')%result).run()ifres!=gtk.RESPONSE_YES:returnos.remove(result)q=Queue.Queue()hgcmd_toq(q,'cat','--rev',str(self.currev),'--output',fromutf(result),self.curfile)defdiff_to_local(self,menuitem):ifnotself.curfile:returnopts={'rev':[str(self.currev)],'bundle':self.bfile}self._do_diff([self.curfile],opts)defdiff_file_rev(self,menuitem):'User selected visual diff file from the file list context menu'ifnotself.curfile:returnrev=self.currevopts={'change':str(rev),'bundle':self.bfile}parents=self.repo[rev].parents()iflen(parents)==2:ifself.diff_other_parent():parent=parents[1].rev()else:parent=parents[0].rev()opts['rev']=[str(parent),str(rev)]self._do_diff([self.curfile],opts)defview_file_rev(self,menuitem):'User selected view file revision from the file list context menu'ifnotself.curfile:returnrev=self.currevparents=[x.rev()forxinself.repo[rev].parents()]iflen(parents)==0:parent=rev-1else:parent=parents[0]pair='%u:%u'%(parent,rev)self._node1,self._node2=cmdutil.revpair(self.repo,[pair])self._view_files([self.curfile],False)defann_file(self,menuitem):'User selected annotate file from the file list context menu'fromtortoisehg.hgtkimportdataminerev=self.currevdialog=datamine.DataMineDialog(self.ui,self.repo,self.cwd,[],{})dialog.display()dialog.close_current_page()dialog.add_annotate_page(self.curfile,str(rev))deffile_history(self,menuitem):'User selected file history from file list context menu'ifself.glog_parent:# If this changeset browser is embedded in glog, send# send this event to the main appopts={'pats':[self.curfile]}self.glog_parent.filtercombo.set_active(1)self.glog_parent.filterentry.set_text(self.curfile)self.glog_parent.custombutton.set_active(True)self.glog_parent.filter='custom'self.glog_parent.reload_log(**opts)else:# Else launch our own glog instancefromtortoisehg.hgtkimporthistorydlg=history.run(self.ui,filehist=self.curfile)dlg.display()defrevert_file(self,menuitem):'User selected file revert from the file list context menu'rev=self.currevdialog=gdialog.Confirm(_('Confirm revert file to old revision'),[],self,_('Revert %s to contents at revision %d?')%(self.curfile,rev))ifdialog.run()==gtk.RESPONSE_NO:returncmdline=['hg','revert','--verbose','--rev',str(rev),self.curfile]dlg=hgcmd.CmdDialog(cmdline)dlg.run()dlg.hide()shlib.shell_notify([self.repo.wjoin(self.curfile)])defadd_to_popup(self,textview,menu):menu_items=(('----',None),(_('Toggle _Wordwrap'),self.toggle_wordwrap),)forlabel,handlerinmenu_items:iflabel=='----':menuitem=gtk.SeparatorMenuItem()else:menuitem=gtk.MenuItem(label)ifhandler:menuitem.connect('activate',handler)menu.append(menuitem)menu.show_all()deftoggle_wordwrap(self,sender):ifself.textview.get_wrap_mode()!=gtk.WRAP_NONE:self.textview.set_wrap_mode(gtk.WRAP_NONE)else:self.textview.set_wrap_mode(gtk.WRAP_WORD)
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.