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.
# thgmq.py - embeddable widget for MQ extension## 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.importosimportgtkimportgtk.keysymsimportgobjectimportpangofrommercurialimporterrorfromtortoisehg.util.i18nimport_fromtortoisehg.utilimporthglibfromtortoisehg.hgtkimportgdialog,gtklib,hgcmd# MQ patches row enumerationsMQ_INDEX=0MQ_STATUS=1MQ_NAME=2MQ_SUMMARY=3MQ_ESCAPED=4# Special patch indicesINDEX_SEPARATOR=-1INDEX_QPARENT=-2# Move patch operationsMOVE_TOP=1MOVE_UP=2MOVE_DOWN=3MOVE_BOTTOM=4# DnD target constansMQ_DND_URI_LIST=1024classMQWidget(gtk.VBox):__gproperties__={'index-column-visible':(gobject.TYPE_BOOLEAN,'Index','Show index column',False,gobject.PARAM_READWRITE),'status-column-visible':(gobject.TYPE_BOOLEAN,'Status','Show status column',False,gobject.PARAM_READWRITE),'name-column-visible':(gobject.TYPE_BOOLEAN,'Name','Show name column',False,gobject.PARAM_READWRITE),'summary-column-visible':(gobject.TYPE_BOOLEAN,'Summary','Show summary column',False,gobject.PARAM_READWRITE),'editable-cell':(gobject.TYPE_BOOLEAN,'EditableCell','Enable editable cells',False,gobject.PARAM_READWRITE),'show-qparent':(gobject.TYPE_BOOLEAN,'ShowQParent',"Show 'qparent'",False,gobject.PARAM_READWRITE)}__gsignals__={'repo-invalidated':(gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,()),'patch-selected':(gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,(int,# revision numberstr)),# patch name'files-dropped':(gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,(object,# list of dropped files/dirsstr))# raw string data}def__init__(self,repo,accelgroup=None,tooltips=None):gtk.VBox.__init__(self)self.repo=repoself.mqloaded=hasattr(repo,'mq')# top toolbartbar=gtklib.SlimToolbar(tooltips)## buttonsself.btn={}popallbtn=tbar.append_button(gtk.STOCK_GOTO_TOP,_('Unapply all patches'))popallbtn.connect('clicked',self.popall_clicked)self.btn['popall']=popallbtnpopbtn=tbar.append_button(gtk.STOCK_GO_UP,_('Unapply last patch'))popbtn.connect('clicked',self.pop_clicked)self.btn['pop']=popbtnpushbtn=tbar.append_button(gtk.STOCK_GO_DOWN,_('Apply next patch'))pushbtn.connect('clicked',self.push_clicked)self.btn['push']=pushbtnpushallbtn=tbar.append_button(gtk.STOCK_GOTO_BOTTOM,_('Apply all patches'))pushallbtn.connect('clicked',self.pushall_clicked)self.btn['pushall']=pushallbtn## separatortbar.append_space()## drop-down menumenubtn=gtk.MenuToolButton('')menubtn.set_menu(self.create_view_menu())tbar.append_widget(menubtn,padding=0)self.btn['menu']=menubtndefafter_init():menubtn.child.get_children()[0].hide()gtklib.idle_add_single_call(after_init)self.pack_start(tbar,False,False)# center panemainbox=gtk.VBox()self.pack_start(mainbox,True,True)## scrolled panepane=gtk.ScrolledWindow()pane.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)pane.set_shadow_type(gtk.SHADOW_IN)mainbox.pack_start(pane)### patch listself.model=gtk.ListStore(int,# patch indexstr,# patch statusstr,# patch namestr,# summary (utf-8)str)# escaped summary (utf-8)self.list=gtk.TreeView(self.model)self.list.set_row_separator_func(self.row_sep_func) # To support old PyGTK (<2.12)
if hasattr(self.list, 'set_tooltip_column'):
self.list.set_tooltip_column(MQ_ESCAPED)
+ self.list.get_selection().set_mode(gtk.SELECTION_MULTIPLE)+ if hasattr(self.list, 'set_rubber_banding'):+ self.list.set_rubber_banding(True) self.list.connect('cursor-changed', self.list_sel_changed)
self.list.connect('button-press-event', self.list_pressed)
self.list.connect('button-release-event', self.list_released)
self.list.connect('row-activated',self.list_row_activated)self.list.connect('size-allocate',self.list_size_allocated)### dnd setup for patch listtargets=[('text/uri-list',0,MQ_DND_URI_LIST)]self.list.drag_dest_set(gtk.DEST_DEFAULT_MOTION| \
gtk.DEST_DEFAULT_DROP,targets,gtk.gdk.ACTION_MOVE)self.list.connect('drag-data-received',self.dnd_received)self.cols={}self.cells={}defaddcol(header,col_idx,right=False,resizable=False,editable=False,editfunc=None):header=(rightand'%s 'or' %s')%headercell=gtk.CellRendererText()ifeditfunc:cell.set_property('editable',editable)cell.connect('edited',editfunc)col=gtk.TreeViewColumn(header,cell)col.add_attribute(cell,'text',col_idx)col.set_cell_data_func(cell,self.cell_data_func)col.set_resizable(resizable)col.set_visible(self.get_property(self.col_to_prop(col_idx)))ifright:col.set_alignment(1)cell.set_property('xalign',1)self.list.append_column(col)self.cols[col_idx]=colself.cells[col_idx]=celldefcell_edited(cell,path,newname):row=self.model[path]ifrow[MQ_INDEX]<0:returnpatchname=row[MQ_NAME]ifnewname!=patchname:self.qrename(newname,patch=patchname)addcol(_('#'),MQ_INDEX,right=True)addcol(_('st'),MQ_STATUS)addcol(_('Patch'),MQ_NAME,editfunc=cell_edited)addcol(_('Summary'),MQ_SUMMARY,resizable=True)pane.add(self.list)## command widgetself.cmd=hgcmd.CmdWidget(style=hgcmd.STYLE_COMPACT,tooltips=tooltips)mainbox.pack_start(self.cmd,False,False)# acceleratorsifaccelgroup:key,mod=gtk.accelerator_parse('F2')self.list.add_accelerator('thg-rename',accelgroup,key,mod,gtk.ACCEL_VISIBLE)defthgrename(list):sel=self.list.get_selection()ifsel.count_selected_rows()==1:model,paths=sel.get_selected_rows()self.qrename_ui(model[paths[0]][MQ_NAME])self.list.connect('thg-rename',thgrename)mod=gtk.gdk.CONTROL_MASKdefadd(name,key,func,*args):self.list.add_accelerator(name,accelgroup,key,mod,0)self.list.connect(name,lambda*a:func(*args))add('mq-move-top',gtk.keysyms.Page_Up,self.qmove_ui,MOVE_TOP)add('mq-move-up',gtk.keysyms.Up,self.qmove_ui,MOVE_UP)add('mq-move-down',gtk.keysyms.Down,self.qmove_ui,MOVE_DOWN)add('mq-move-bottom',gtk.keysyms.Page_Down,self.qmove_ui,MOVE_BOTTOM)add('mq-pop',gtk.keysyms.Left,self.qpop)add('mq-push',gtk.keysyms.Right,self.qpush)### public functions ###defrefresh(self):""" Refresh the list of patches. This operation will try to keep selection state. """ifnotself.mqloaded:return# store selected patch nameselname=Nonemodel,paths=self.list.get_selection().get_selected_rows()iflen(paths)>0:selname=model[paths[0]][MQ_NAME]# clear model dataself.model.clear()# insert 'qparent' rowtop=Noneifself.get_property('show-qparent'):top=self.model.append((INDEX_QPARENT,None,None,None,None))# add patchesfromhgextimportmqq=self.repo.mqq.parse_series()applied=set([p.nameforpinq.applied])forindex,patchnameinenumerate(q.series):stat=patchnameinappliedand'A'or'U'try:msg=hglib.toutf(mq.patchheader(q.join(patchname)).message[0])msg_esc=gtklib.markup_escape_text(msg)exceptIndexError:msg=msg_esc=Noneiter=self.model.append((index,stat,patchname,msg,msg_esc))ifstat=='A':top=iter# insert separatoriftop:row=self.model.insert_after(top,(INDEX_SEPARATOR,None,None,None,None))self.separator_pos=self.model.get_path(row)[0]# restore patch selectionifselname:iter=self.get_iter_by_patchname(selname)ifiter:self.list.get_selection().select_iter(iter)# update UI sensitivesself.update_sensitives()defset_repo(self,repo):self.repo=repodefqgoto(self,patch):""" [MQ] Execute 'qgoto' command. patch: the patch name or an index to specify the patch. """ifnotself.is_operable():returncmdline=['hg','qgoto',patch]self.cmd.execute(cmdline,self.cmd_done)defqpop(self,all=False):""" [MQ] Execute 'qpop' command. all: if True, use '--all' option. (default: False) """ifnotself.is_operable():returncmdline=['hg','qpop']ifall:cmdline.append('--all')self.cmd.execute(cmdline,self.cmd_done)defqpush(self,all=False):""" [MQ] Execute 'qpush' command. all: if True, use '--all' option. (default: False) """ifnotself.is_operable():returncmdline=['hg','qpush']ifall:cmdline.append('--all')self.cmd.execute(cmdline,self.cmd_done)defqdelete(self,patch,keep=False):""" [MQ] Execute 'qdelete' command. patch: a patch name or an index number, or its list. keep: if True, use '--keep' option. (default: False) """ifnotpatchornotself.has_patch():returnifisinstance(patch,(basestring,int,long)):patch=[patch]unapplied=[pforpinpatchifnotself.is_applied(p)]ifnotunapplied:returnifnotkeep:ret=gdialog.CustomPrompt(_('Confirm Delete'),_('Do you want to delete?'),None,(_('&Yes'),_('Yes (&keep)'),_('&Cancel')),default=2,esc=2).run()ifret==0:passelifret==1:keep=Trueelse:returncmdline=['hg','qdelete']+unappliedifkeep:cmdline.append('--keep')self.cmd.execute(cmdline,self.cmd_done,noemit=True)defqrename(self,name,patch='qtip'):""" [MQ] Execute 'qrename' command. If 'patch' param isn't specified, renaming should be applied 'qtip' (current) patch. name: the new patch name for renaming. patch: the target patch name or index. (default: 'qtip') """ifnotnameornotself.has_patch():returncmdline=['hg','qrename',patch,name]self.cmd.execute(cmdline,self.cmd_done)defqrename_ui(self,patch='qtip'):""" Prepare the user interface for renaming the patch. If 'patch' param isn't specified, renaming should be started 'qtip' (current) patch. Return True if succeed to prepare; otherwise False. patch: the target patch name or index. (default: 'qtip') """ifnotself.mqloadedor \
patch=='qtip'and'qtip'inself.repo.tags():returnFalsetarget=self.repo.mq.lookup(patch)ifnottarget:returnFalsepath=self.get_path_by_patchname(target)ifnotpath:returnFalse# make the cell editablecell=self.cells[MQ_NAME]ifnotcell.get_property('editable'):cell.set_property('editable',True)defcanceled(cell,*arg):cell.disconnect(cancel_id)cell.disconnect(edited_id)cell.set_property('editable',False)cancel_id=cell.connect('editing-canceled',canceled)edited_id=cell.connect('edited',canceled)# start editing patchname cellself.list.set_cursor_on_cell(path,self.cols[MQ_NAME],None,True)returnTruedefqfinish(self,applied=False):""" [MQ] Execute 'qfinish' command. applied: if True, enable '--applied' option. (default: False) """ifnotself.has_applied():returncmdline=['hg','qfinish']ifapplied:cmdline.append('--applied')self.cmd.execute(cmdline,self.cmd_done)defqfold(self,patch):""" [MQ] Execute 'qfold' command. patch: a patch name or an index number, or its list. """ifnotpatchornotself.has_applied():returnifisinstance(patch,(basestring,int,long)):patch=[patch]unapplied=[pforpinpatchifnotself.is_applied(p)]ifnotunapplied:returndata=dict(qtip=self.get_qtip_patchname())iflen(unapplied)==1:data.update(target=unapplied[0])ret=gdialog.Confirm(_('Confirm Fold'),[],None,_("Do you want to fold un-applied patch '%(target)s'"" into current patch '%(qtip)s'?")%data).run()else:ret=gdialog.Confirm(_('Confirm Fold'),unapplied,None,_("Do you want to fold following un-applied patches"" into the current patch '%(qtip)s'?")%data).run()ifret!=gtk.RESPONSE_YES:returncmdline=['hg','qfold']+unappliedself.cmd.execute(cmdline,self.cmd_done)defqmove(self,patch,op):""" [MQ] Move patch. This is NOT standard API of MQ. patch: the patch name or an index to specify the patch. op: the operator for moving the patch: MOVE_TOP, MOVE_UP, MOVE_DOWN or MOVE_BOTTOM. """ifnotself.is_operable()orself.is_applied(patch):returnFalse# get current index in the listoldrow=self.get_row_by_patchname(patch)foriinrange(len(self.model)):ifself.model[i][MQ_NAME]==oldrow[MQ_NAME]:oldidx=ibreakelse:returnFalse# get new index in the listminval=self.separator_pos+1maxval=len(self.model)-1ifop==MOVE_TOP:newidx=minvalelifop==MOVE_UP:newidx=oldidx-1elifop==MOVE_DOWN:newidx=oldidx+1elifop==MOVE_BOTTOM:newidx=maxvalifnewidx==oldidxornewidx<minvalormaxval<newidx:returnFalse# Update seriesq=self.repo.mqoldrow=self.model[oldidx]newrow=self.model[newidx]oldpos=q.find_series(oldrow[MQ_NAME])newpos=q.find_series(newrow[MQ_NAME])olditem=q.full_series[oldpos]delq.full_series[oldpos]q.full_series.insert(newpos,olditem)q.series_dirty=Trueq.save_dirty()# Update TreeViewifnewidx<oldidx:self.model.move_before(oldrow.iter,newrow.iter)else:self.model.move_after(oldrow.iter,newrow.iter)begin=min(oldidx,newidx)offset=min(oldrow[MQ_INDEX],newrow[MQ_INDEX])-beginforiinxrange(begin,max(oldidx,newidx)+1):self.model[i][MQ_INDEX]=i+offsetdefqmove_ui(self,op):""" [MQ] Move selected patch in the list. Return True if succeed to move; otherwise False. op: the operator for moving the patch: MOVE_TOP, MOVE_UP, MOVE_DOWN or MOVE_BOTTOM. """sel=self.list.get_selection()ifsel.count_selected_rows()==1:model,paths=sel.get_selected_rows()patch=model[paths[0]][MQ_NAME]ifpatch:returnself.qmove(patch,op)returnFalsedefhas_mq(self):returnself.mqloadedandos.path.isdir(self.repo.mq.path)defhas_patch(self):""" return True if MQ has applicable patches """returnbool(self.get_num_patches())defhas_applied(self):""" return True if MQ has applied patches """returnbool(self.get_num_applied())defget_num_patches(self):""" return the number of patches in patch queue """ifself.mqloaded:returnlen(self.repo.mq.series)return0defget_num_applied(self):""" return the number of applied patches """ifself.mqloaded:returnlen(self.repo.mq.applied)return0defget_num_unapplied(self):""" return the number of unapplied patches """ifself.mqloaded:returnself.get_num_patches()-self.get_num_applied()return0defis_operable(self):""" return True if MQ is operable """ifself.mqloaded:repo=self.repoif'qtip'inself.repo.tags():returnrepo['.']==repo['qtip']returnlen(repo.mq.series)>0returnFalsedefis_applied(self,name):ifself.mqloaded:returnself.repo.mq.isapplied(name)returnFalsedefis_qtip(self,name):ifname:returnname==self.get_qtip_patchname()returnFalse### internal functions ###defget_iter_by_patchname(self,name):""" return iter has specified patch name """ifname:forrowinself.model:ifrow[MQ_NAME]==name:returnrow.iterreturnNonedefget_path_by_patchname(self,name):""" return path has specified patch name """iter=self.get_iter_by_patchname(name)ifiter:returnself.model.get_path(iter)returnNonedefget_row_by_patchname(self,name):""" return row has specified patch name """path=self.get_path_by_patchname(name)ifpath:returnself.model[path]returnNonedefget_qtip_patchname(self):ifself.mqloadedandself.get_num_applied()>0 \
and'qtip'inself.repo.tags():returnself.repo.mq.applied[-1].namereturnNonedefupdate_sensitives(self):""" Update the sensitives of entire UI """defdisable_mqmoves():fornamein('popall','pop','push','pushall'):self.btn[name].set_sensitive(False)ifself.mqloaded:self.list.set_sensitive(True)self.btn['menu'].set_sensitive(True)ifself.is_operable():q=self.repo.mqin_bottom=len(q.applied)==0in_top=len(q.unapplied(self.repo))==0self.btn['popall'].set_sensitive(notin_bottom)self.btn['pop'].set_sensitive(notin_bottom)self.btn['push'].set_sensitive(notin_top)self.btn['pushall'].set_sensitive(notin_top)else:disable_mqmoves()else:self.list.set_sensitive(False)self.btn['menu'].set_sensitive(False)disable_mqmoves()defscroll_to_current(self):""" Scroll to current patch in the patch list. If the patch is selected, it will do nothing. """ifself.list.get_selection().count_selected_rows()>0:returnqtipname=self.get_qtip_patchname()ifnotqtipname:returnpath=self.get_path_by_patchname(qtipname)ifpath:self.list.scroll_to_cell(path)defcell_data_func(self,column,cell,model,iter):row=model[iter]ifrow[MQ_INDEX]==INDEX_QPARENT:ifcolumn==self.cols[MQ_INDEX]:cell.set_property('text','')elifcolumn==self.cols[MQ_NAME]:cell.set_property('text','[qparent]')stat=row[MQ_STATUS]ifstat=='A':cell.set_property('foreground','blue')elifstat=='U':cell.set_property('foreground','#909090')else:cell.set_property('foreground','black')patchname=row[MQ_NAME]ifself.is_qtip(patchname):cell.set_property('weight',pango.WEIGHT_BOLD)else:cell.set_property('weight',pango.WEIGHT_NORMAL)defrow_sep_func(self,model,iter,data=None):returnmodel[iter][MQ_INDEX]==INDEX_SEPARATORdefshow_patch_cmenu(self,path):row=self.model[path]ifrow[MQ_INDEX]==INDEX_SEPARATOR:returnm=gtklib.MenuBuilder()defappend(*args):m.append(*args,**dict(args=[row]))is_operable=self.is_operable()has_patch=self.has_patch()has_applied=self.has_applied()is_qtip=self.is_qtip(row[MQ_NAME])is_qparent=row[MQ_INDEX]==INDEX_QPARENTis_applied=row[MQ_STATUS]=='A'ifis_operableandnotis_qtipand(notis_qparentorhas_applied):append(_('_Goto'),self.goto_activated,gtk.STOCK_JUMP_TO)ifhas_patchandnotis_qparent:append(_('_Rename'),self.rename_activated,gtk.STOCK_EDIT)ifhas_appliedandnotis_qparent:append(_('_Finish Applied'),self.finish_activated,gtk.STOCK_APPLY)ifnotis_appliedandnotis_qparent:append(_('_Delete'),self.delete_activated,gtk.STOCK_DELETE)ifhas_appliedandnotis_qparent:append(_('F_old'),self.fold_activated,gtk.STOCK_DIRECTORY)ifself.get_num_unapplied()>1:sub=gtklib.MenuBuilder()sub.append(_('Top'),lambda*a:self.qmove_ui(MOVE_TOP),gtk.STOCK_GOTO_TOP,args=[row])sub.append(_('Up'),lambda*a:self.qmove_ui(MOVE_UP),gtk.STOCK_GO_UP,args=[row])sub.append(_('Down'),lambda*a:self.qmove_ui(MOVE_DOWN),gtk.STOCK_GO_DOWN,args=[row])sub.append(_('Bottom'),lambda*a:self.qmove_ui(MOVE_BOTTOM),gtk.STOCK_GOTO_BOTTOM,args=[row])m.append_submenu(_('Move'),sub.build(),gtk.STOCK_INDEX)menu=m.build()iflen(menu.get_children())>0: menu.show_all()
menu.popup(None, None, None, 0, 0)
+ def show_patches_cmenu(self):+ sel = self.list.get_selection()+ patches = []+ for path in sel.get_selected_rows()[1]:+ row = self.model[path]+ if row[MQ_INDEX] in (INDEX_SEPARATOR, INDEX_QPARENT):+ continue+ patches.append(row[MQ_NAME])++ incl_applied, incl_unapplied = False, False+ for patch in patches:+ if self.is_applied(patch):+ incl_applied = True+ else:+ incl_unapplied = True++ m = gtklib.MenuBuilder()+ if incl_unapplied:+ m.append(_('_Delete'), lambda *a: self.qdelete(patches),+ gtk.STOCK_DELETE)+ if self.has_applied() and incl_unapplied:+ m.append(_('F_old'), lambda *a: self.qfold(patches),+ gtk.STOCK_DIRECTORY)++ menu = m.build()+ if len(menu.get_children()) > 0:+ menu.show_all()+ menu.popup(None, None, None, 0, 0)+ def create_view_menu(self):
self.vmenu = {}
m = gtklib.MenuBuilder()
defcolappend(label,col_idx,active=True):defhandler(menuitem):col=self.cols[col_idx]col.set_visible(menuitem.get_active())propname=self.col_to_prop(col_idx)item=m.append(label,handler,ascheck=True,check=active)self.vmenu[propname]=itemcolappend(_('Show Index'),MQ_INDEX)colappend(_('Show Status'),MQ_STATUS,active=False)colappend(_('Show Summary'),MQ_SUMMARY,active=False)m.append_sep()defenable_editable(item):self.cells[MQ_NAME].set_property('editable',item.get_active())item=m.append(_('Enable editable cells'),enable_editable,ascheck=True,check=False)self.vmenu['editable-cell']=itemitem=m.append(_("Show 'qparent'"),lambdaitem:self.refresh(),ascheck=True,check=True)self.vmenu['show-qparent']=itemmenu=m.build()menu.show_all()returnmenudefqgoto_by_row(self,row):ifself.get_qtip_patchname()==row[MQ_NAME]:returnifrow[MQ_INDEX]==INDEX_QPARENT:self.qpop(all=True)else:self.qgoto(row[MQ_NAME])defcmd_done(self,returncode,useraborted,noemit=False):ifreturncode==0:ifself.cmd.get_pbar():self.cmd.set_result(_('Succeed'),style='ok')elifuseraborted:self.cmd.set_result(_('Canceled'),style='error')else:self.cmd.set_result(_('Failed'),style='error')hglib.invalidaterepo(self.repo)self.refresh()ifnotnoemit:self.emit('repo-invalidated')defdo_get_property(self,property):ifproperty.name=='name-column-visible':returnTruetry:returnself.vmenu[property.name].get_active()except:raiseAttributeError,'unknown property %s'%property.namedefdo_set_property(self,property,value):try:self.vmenu[property.name].set_active(value)except:raiseAttributeError,'unknown property %s'%property.namedefcol_to_prop(self,col_idx):ifcol_idx==MQ_INDEX:return'index-column-visible'ifcol_idx==MQ_STATUS:return'status-column-visible'elifcol_idx==MQ_NAME:return'name-column-visible'elifcol_idx==MQ_SUMMARY:return'summary-column-visible'return''### signal handlers ### def list_pressed(self, list, event):
x, y = int(event.x), int(event.y)
pathinfo = list.get_path_at_pos(x, y)
+ if event.button == 1:
if not pathinfo:
# HACK: clear selection after this function calling,
# against selection by getting focusdefunselect():selection=list.get_selection() selection.unselect_all()
gtklib.idle_add_single_call(unselect)
+ elif event.button == 3 and pathinfo:+ sel = list.get_selection()+ sel_rows = sel.get_selected_rows()[1] # list of paths+ if pathinfo[0] not in sel_rows:+ sel.unselect_all()+ sel.select_path(pathinfo[0])+ return True+ def list_released(self, list, event):
if event.button != 3:
return
- x, y = int(event.x), int(event.y)
- pathinfo = list.get_path_at_pos(x, y)
- if pathinfo:
+ sel = list.get_selection()+ count = sel.count_selected_rows()+ if count == 1:+ x, y = int(event.x), int(event.y)
+pathinfo = list.get_path_at_pos(x, y)
+if not pathinfo:
+ return self.show_patch_cmenu(pathinfo[0])
+ elif 1 < count:+ self.show_patches_cmenu()+ def list_sel_changed(self, list):
path, focus = list.get_cursor()
row = self.model[path]
ifrow[MQ_INDEX]<0:returnpatchname=row[MQ_NAME]try:ctx=self.repo[patchname]revid=ctx.rev()except(error.RepoError,error.RepoLookupError):revid=-1self.emit('patch-selected',revid,patchname)deflist_row_activated(self,list,path,column):self.qgoto_by_row(self.model[path])deflist_size_allocated(self,list,req):ifself.mqloadedandself.has_applied():self.scroll_to_current()defpopall_clicked(self,toolbutton):self.qpop(all=True)defpop_clicked(self,toolbutton):self.qpop()defpush_clicked(self,toolbutton):self.qpush()defpushall_clicked(self,toolbutton):self.qpush(all=True)defdnd_received(self,widget,context,x,y,sel,target,*args):iftarget==MQ_DND_URI_LIST:paths=gtklib.normalize_dnd_paths(sel.data)ifpaths:self.emit('files-dropped',paths,sel.data)### context menu signal handlers ###defgoto_activated(self,menuitem,row):self.qgoto_by_row(row)defdelete_activated(self,menuitem,row):self.qdelete(row[MQ_NAME])defrename_activated(self,menuitem,row):self.qrename_ui(row[MQ_NAME])deffinish_activated(self,menuitem,row):self.qfinish(applied=True)deffold_activated(self,menuitem,row):self.qfold(row[MQ_NAME])
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.