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.
# hgemail.py - TortoiseHg's dialog for sending patches via email## 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.importosimportsysimportgobjectimportgtkimportpangoimporttempfilefrommercurialimporthg,ui,extensionsfromthgutil.i18nimport_fromthgutilimporthglib,settingsfromhggtkimportgtklib,dialog,thgconfig,hgcmdclassEmailDialog(gtk.Window):""" Send patches or bundles via email """def__init__(self,root='',revargs=[]):""" Initialize the Dialog """gtk.Window.__init__(self,gtk.WINDOW_TOPLEVEL)gtklib.set_tortoise_icon(self,'hg.ico')gtklib.set_tortoise_keys(self)self.root=rootself.revargs=revargsself.tbar=gtk.Toolbar() self.tips = gtk.Tooltips()
tbuttons = [
- self._toolbutton(gtk.STOCK_GOTO_LAST, _('send'),
+ self._toolbutton(gtk.STOCK_GOTO_LAST, _('Send'),
self._on_send_clicked,
_('Send email(s)')),
- self._toolbutton(gtk.STOCK_FIND, _('test'),
+ self._toolbutton(gtk.STOCK_FIND, _('Test'),
self._on_test_clicked,
_('Show email(s) which would be sent')),
gtk.SeparatorToolItem(),
- self._toolbutton(gtk.STOCK_PREFERENCES, _('configure'),
+ self._toolbutton(gtk.STOCK_PREFERENCES, _('Configure'),
self._on_conf_clicked,
_('Configure email settings'))
]
forbtnintbuttons:self.tbar.insert(btn,-1)mainvbox=gtk.VBox()self.add(mainvbox)mainvbox.pack_start(self.tbar,False,False,2)# set dialog titleifrevargs[0]in('--outgoing','-o'):self.set_title(_('Email outgoing changes'))elifrevargs[0]in('--rev','-r'):self.set_title(_('Email revision(s) ')+' '.join(revargs[1:]))else:self.set_title(_('Email Mercurial Patches'))self.set_default_size(650,450)hbox=gtk.HBox()envframe=gtk.Frame(_('Envelope'))flagframe=gtk.Frame(_('Options'))hbox.pack_start(envframe,True,True,4)hbox.pack_start(flagframe,False,False,4)mainvbox.pack_start(hbox,False,True,4)vbox=gtk.VBox()envframe.add(vbox)# To: combo boxhbox=gtk.HBox()self._tolist=gtk.ListStore(str)self._tobox=gtk.ComboBoxEntry(self._tolist,0)lbl=gtk.Label(_('To:'))lbl.set_property('width-chars',10)lbl.set_alignment(1.0,0.5)hbox.pack_start(lbl,False,False,4)hbox.pack_start(self._tobox,True,True,4)vbox.pack_start(hbox,False,False,4)# Cc: combo boxhbox=gtk.HBox()self._cclist=gtk.ListStore(str)self._ccbox=gtk.ComboBoxEntry(self._cclist,0)lbl=gtk.Label(_('Cc:'))lbl.set_property('width-chars',10)lbl.set_alignment(1.0,0.5)hbox.pack_start(lbl,False,False,4)hbox.pack_start(self._ccbox,True,True,4)vbox.pack_start(hbox,False,False,4)# From: combo boxhbox=gtk.HBox()self._fromlist=gtk.ListStore(str)self._frombox=gtk.ComboBoxEntry(self._fromlist,0)lbl=gtk.Label(_('From:'))lbl.set_property('width-chars',10)lbl.set_alignment(1.0,0.5)hbox.pack_start(lbl,False,False,4)hbox.pack_start(self._frombox,True,True,4)vbox.pack_start(hbox,False,False,4)hbox=gtk.HBox()self._replyto=gtk.Entry()lbl=gtk.Label(_('In-Reply-To:'))lbl.set_property('width-chars',10)lbl.set_alignment(1.0,0.5)hbox.pack_start(lbl,False,False,4)hbox.pack_start(self._replyto,True,True,4)vbox.pack_start(hbox,False,False,4)self.tips.set_tip(self._replyto,_('Message identifier to reply to, for threading'))vbox=gtk.VBox()flagframe.add(vbox)self.tooltips=gtk.Tooltips()self._normal=gtk.RadioButton(None,_('Send changesets as HG patches'))vbox.pack_start(self._normal,True,True,4)self.tooltips.set_tip(self._normal,_('HG patches (as generated by export command) are compatible'' with most patch programs. They include a header which'' contains the most important changeset metadata.'))self._git=gtk.RadioButton(self._normal,_('Use extended (git) patch format'))vbox.pack_start(self._git,True,True,4)self.tooltips.set_tip(self._git,_('Git patches can describe binary files, copies, and'' permission changes, but recipients may not be able to'' use them if they are not using git or Mercurial.'))self._plain=gtk.RadioButton(self._normal,_('Plain, do not prepend HG header'))vbox.pack_start(self._plain,True,True,4)self.tooltips.set_tip(self._plain,_('Stripping Mercurial header removes username and parent'' information. Only useful if recipient is not using'' Mercurial (and does not like to see the headers).'))self._bundle=gtk.RadioButton(self._normal,_('Send single binary bundle, not patches'))vbox.pack_start(self._bundle,True,True,4)self.tooltips.set_tip(self._bundle,_('Bundles store complete changesets in binary form.'' Upstream users can pull from them. This is the safest'' way to send changes to recipient Mercurial users.'))hbox=gtk.HBox()vbox.pack_start(hbox,False,False,2)self._attach=gtk.CheckButton(_('attach'))self.tooltips.set_tip(self._attach,_('send patches as attachments'))self._inline=gtk.CheckButton(_('inline'))self.tooltips.set_tip(self._inline,_('send patches as inline attachments'))self._diffstat=gtk.CheckButton(_('diffstat'))self.tooltips.set_tip(self._diffstat,_('add diffstat output to messages'))hbox.pack_start(self._attach,True,True,2)hbox.pack_start(self._inline,True,True,2)hbox.pack_start(self._diffstat,True,True,2)vbox=gtk.VBox()hbox=gtk.HBox()self._subjlist=gtk.ListStore(str)self._subjbox=gtk.ComboBoxEntry(self._subjlist,0)hbox.pack_start(gtk.Label(_('Subject:')),False,False,4)hbox.pack_start(self._subjbox,True,True,4)# --flags was added after hg 1.3hasflags=Falseforarginextensions.find('patchbomb').emailopts:ifarg[1]=='flag':hasflags=Truebreakself._flaglist=gtk.ListStore(str)self._flagbox=gtk.ComboBoxEntry(self._flaglist,0)ifhasflags:hbox.pack_start(gtk.Label(_('Flags:')),False,False,4)hbox.pack_start(self._flagbox,False,False,4)vbox.pack_start(hbox,False,False,4)self.descview=gtk.TextView(buffer=None)self.descview.set_editable(True)self.descview.modify_font(pango.FontDescription('Monospace'))self.descbuffer=self.descview.get_buffer()scrolledwindow=gtk.ScrolledWindow()scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)scrolledwindow.add(self.descview)frame=gtk.Frame(_('Patch Series (Bundle) Description'))frame.set_border_width(4)vbox.pack_start(scrolledwindow,True,True,4)vbox.set_border_width(4)eventbox=gtk.EventBox()eventbox.add(vbox)frame.add(eventbox)self._eventbox=eventboxmainvbox.pack_start(frame,True,True,4)gobject.idle_add(self._refresh,True)def_toolbutton(self,stock,label,handler,tip):tbutton=gtk.ToolButton(stock)tbutton.set_label(label)tbutton.set_tooltip(self.tips,tip)tbutton.connect('clicked',handler)returntbuttondef_refresh(self,initial):deffill_history(history,vlist,cpath):vlist.clear()ifcpathnotinhistory.get_keys():returnforvinhistory.get_value(cpath):vlist.append([v])history=settings.Settings('email')try:repo=hg.repository(ui.ui(),path=self.root)self.repo=repoexcepthglib.RepoError:self.repo=Nonereturnextensions.load(self.repo.ui,'patchbomb',None)ifinitial:# Only zap these fields at startupself._tobox.child.set_text(hglib.fromutf(repo.ui.config('email','to','')))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.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. Flags is a comma separated list of tags'' which are inserted into the message header.'))gtklib.addspellcheck(self.descview,self.repo.ui)fill_history(history,self._tolist,'email.to')fill_history(history,self._cclist,'email.cc')fill_history(history,self._fromlist,'email.from')fill_history(history,self._subjlist,'email.subject')fill_history(history,self._flaglist,'email.flags')iflen(self._flaglist)==0:self._flaglist.append(['STABLE'])# See if user has set flags in defaults.emailself._git.set_sensitive(True)self._bundle.set_sensitive(True)self._plain.set_sensitive(True)self._inline.set_sensitive(True)self._attach.set_sensitive(True)self._diffstat.set_sensitive(True)defaults=repo.ui.config('defaults','email','').split()forflagindefaults:ifflagin('-g','--git'):self._git.set_active(True)self._git.set_sensitive(False)ifflagin('-b','--bundle'):self._bundle.set_active(True)self._bundle.set_sensitive(False)ifflagin('--plain'):self._plain.set_active(True)self._plain.set_sensitive(False)ifflagin('i','--inline'):self._inline.set_active(True)self._inline.set_sensitive(False)ifflagin('a','--attach'):self._attach.set_active(True)self._attach.set_sensitive(False)ifflagin('d','--diffstat'):self._diffstat.set_active(True)self._diffstat.set_sensitive(False)def_on_conf_clicked(self,button):dlg=thgconfig.ConfigDialog(False)dlg.show_all()dlg.focus_field('email.from')dlg.run()dlg.hide()self._refresh(False)def_on_send_clicked(self,button):self.send()def_on_test_clicked(self,button):self.send(True)defsend(self,test=False):defrecord_new_value(cpath,history,newvalue):ifnotnewvalue:returnifcpathnotinhistory.get_keys():history.set_value(cpath,[])elifnewvalueinhistory.get_value(cpath):history.get_value(cpath).remove(newvalue)history.get_value(cpath).insert(0,newvalue)totext=hglib.fromutf(self._tobox.child.get_text())cctext=hglib.fromutf(self._ccbox.child.get_text())fromtext=hglib.fromutf(self._frombox.child.get_text())subjtext=hglib.fromutf(self._subjbox.child.get_text())flagtext=hglib.fromutf(self._flagbox.child.get_text())inreplyto=hglib.fromutf(self._replyto.get_text())ifnottotext:dialog.info_dialog(self,_('Info required'),_('You must specify a recipient'))self._tobox.grab_focus()returnifnotfromtext:dialog.info_dialog(self,_('Info required'),_('You must specify a sender address'))self._frombox.grab_focus()returnifnotself.repo:returnifself.repo.ui.config('email','method','smtp')=='smtp'andnottest:ifnotself.repo.ui.config('smtp','host'):dialog.info_dialog(self,_('Info required'),_('You must configure SMTP'))dlg=thgconfig.ConfigDialog(False)dlg.show_all()dlg.focus_field('smtp.host')dlg.run()dlg.hide()self._refresh(False)returnifnottest:history=settings.Settings('email')record_new_value('email.to',history,totext)record_new_value('email.cc',history,cctext)record_new_value('email.from',history,fromtext)record_new_value('email.subject',history,subjtext)record_new_value('email.flags',history,flagtext)history.write()cmdline=['hg','email','-f',fromtext,'-t',totext,'-c',cctext]oldpager=os.environ.get('PAGER')iftest:ifoldpager:delos.environ['PAGER']cmdline.insert(2,'--test')ifflagtext:flags=[f.split()forfinflagtext.split(',')]forfinflags:cmdline+=['--flag',f]ifsubjtext:cmdline+=['--subject',subjtext]ifself._bundle.get_active():cmdline+=['--bundle']if'--outgoing'inself.revargs:self.revargs.remove('--outgoing')elifself._plain.get_active():cmdline+=['--plain']elifself._git.get_active():cmdline+=['--git']ifself._inline.get_active():cmdline+=['--inline']ifself._attach.get_active():cmdline+=['--attach']ifself._diffstat.get_active():cmdline+=['--diffstat']ifinreplyto:cmdline+=['--in-reply-to',inreplyto]start=self.descbuffer.get_start_iter()end=self.descbuffer.get_end_iter()desc=self.descbuffer.get_text(start,end)ifdesc:cmdline+=['--intro']tmpfile=Nonetry:fd,tmpfile=tempfile.mkstemp(prefix="thg_emaildesc_")os.write(fd,desc)os.close(fd)cmdline+=['--desc',tmpfile]cmdline.extend(self.revargs)dlg=hgcmd.CmdDialog(cmdline)dlg.show_all()dlg.run()dlg.hide()finally:ifoldpager:os.environ['PAGER']=oldpageriftmpfile:os.unlink(tmpfile)
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.