PageRenderTime 46ms CodeModel.GetById 18ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 1ms

/tortoisehg/hgtk/backout.py

https://bitbucket.org/tortoisehg/hgtk/
Python | 165 lines | 115 code | 30 blank | 20 comment | 9 complexity | 8872a6d30bbec2999afd3ce795a9bd08 MD5 | raw file
  1# backout.py - TortoiseHg's dialog for backing out changeset
  2#
  3# Copyright 2008 TK Soh <teekaysoh@gmail.com>
  4# Copyright 2008 Steve Borho <steve@borho.org>
  5#
  6# This software may be used and distributed according to the terms of the
  7# GNU General Public License version 2, incorporated herein by reference.
  8
  9import gtk
 10import pango
 11
 12from tortoisehg.util.i18n import _
 13from tortoisehg.util import hglib, i18n
 14
 15from tortoisehg.hgtk import csinfo, gdialog, textview, gtklib
 16
 17keep = i18n.keepgettext()
 18
 19class BackoutDialog(gdialog.GDialog):
 20    """ Backout effect of a changeset """
 21    def __init__(self, rev=None):
 22        gdialog.GDialog.__init__(self, resizable=True)
 23        self.rev = rev
 24
 25    ### Start of Overriding Section ###
 26
 27    def get_title(self, reponame):
 28        return _('Backout changeset - %s') % self.rev
 29
 30    def get_icon(self):
 31        return 'menurevert.ico'
 32
 33    def get_defsize(self):
 34        return (600, 400)
 35
 36    def get_setting_name(self):
 37        return 'backout'
 38
 39    def get_body(self, vbox):
 40        # message
 41        self.msgset = keep._('Backed out changeset: ')
 42        self.msgset['id'] += self.rev
 43        self.msgset['str'] += self.rev
 44
 45        # changeset info
 46        style = csinfo.panelstyle(label=_('Changeset Description'),
 47                                  margin=4, padding=2)
 48        self.csetframe = csinfo.create(self.repo, self.rev, style, withupdate=True)
 49        vbox.pack_start(self.csetframe, False, False, 2)
 50
 51        # backout commit message
 52        frame = gtk.Frame(_('Backout commit message'))
 53        frame.set_border_width(4)
 54        msgvbox = gtk.VBox()
 55        msgvbox.set_border_width(4)
 56        frame.add(msgvbox)
 57        vbox.pack_start(frame, True, True, 2)
 58        self.cmsgframe = frame
 59
 60        ## message text area
 61        accelgroup = gtk.AccelGroup()
 62        self.add_accel_group(accelgroup)
 63        self.logview = textview.UndoableTextView(accelgroup=accelgroup)
 64        fontcomment = hglib.getfontconfig()['fontcomment']
 65        self.logview.modify_font(pango.FontDescription(fontcomment))
 66        self.buf = self.logview.get_buffer()
 67        self.buf.set_text(self.msgset['str'])
 68        scrolledwindow = gtk.ScrolledWindow()
 69        scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
 70        scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 71        scrolledwindow.add(self.logview)
 72        msgvbox.pack_start(scrolledwindow)
 73        self.logview.set_editable(False)
 74
 75        ## tooltips
 76        self.tips = gtklib.Tooltips()
 77        self.tips.set_tip(frame,
 78                _('Commit message text for new changeset that reverses the'
 79                '  effect of the change being backed out.'))
 80
 81        ## use English backout message option
 82        self.eng_msg = gtk.CheckButton(_('Use English backout message'))
 83        self.eng_msg.connect('toggled', self.eng_msg_toggled)
 84        engmsg = self.repo.ui.configbool('tortoisehg', 'engmsg', False)
 85        self.eng_msg.set_active(engmsg)
 86        msgvbox.pack_start(self.eng_msg, False, False)
 87
 88        ## merge after backout
 89        self.merge_button = gtk.CheckButton(
 90                _('Commit backout before merging with current working parent'))
 91        self.merge_button.connect('toggled', self.merge_toggeled)
 92        msgvbox.pack_start(self.merge_button, False, False, 4)
 93
 94    def get_buttons(self):
 95        return [('backout', _('Backout'), gtk.RESPONSE_OK),
 96                ('close', gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)]
 97
 98    def get_default_button(self):
 99        return 'backout'
100
101    def get_action_map(self):
102        return {gtk.RESPONSE_OK: self.backout}
103
104    def switch_to(self, normal, *args):
105        self.csetframe.set_sensitive(normal)
106        self.cmsgframe.set_sensitive(normal)
107        self.buttons['backout'].set_property('visible', normal)
108        self.buttons['close'].set_property('visible', normal)
109        if normal:
110            self.buttons['close'].grab_focus()
111
112    def command_done(self, returncode, useraborted, *args):
113        if returncode == 0:
114            self.cmd.set_result(_('Backed out successfully, you must now '
115                                  'commit the results'), style='ok')
116            self.buttons['backout'].set_property('visible', False)
117        elif useraborted:
118            self.cmd.set_result(_('Canceled backout'), style='error')
119        else:
120            self.cmd.set_result(_('Failed to backout'), style='error')
121
122    def load_settings(self):
123        checked = self.settings.get_value('merge', True, True)
124        self.merge_button.set_active(checked)
125
126    def store_settings(self):
127        checked = self.merge_button.get_active()
128        self.settings.set_value('merge', checked)
129        self.settings.write()
130
131    ### End of Overriding Section ###
132
133    def eng_msg_toggled(self, checkbutton):
134        start, end = self.buf.get_bounds()
135        msg = self.buf.get_text(start, end)
136        state = checkbutton.get_active()
137        origmsg = (state and self.msgset['str'] or self.msgset['id'])
138        if msg != origmsg:
139            res = gdialog.Confirm(_('Confirm Discard Message'),
140                    [], self, _('Discard current backout message?')).run()
141            if res != gtk.RESPONSE_YES:
142                checkbutton.handler_block_by_func(self.eng_msg_toggled)
143                checkbutton.set_active(not state)
144                checkbutton.handler_unblock_by_func(self.eng_msg_toggled)
145                return
146        newmsg = (state and self.msgset['id'] or self.msgset['str'])
147        self.buf.set_text(newmsg)
148
149    def merge_toggeled(self, checkbutton):
150        self.logview.set_editable(checkbutton.get_active())
151
152    def backout(self):
153        # do not auto-close when finished
154        self.set_after_done(False)
155
156        # prepare command line
157        cmdline = ['hg', 'backout', '--rev', self.rev]
158        if self.merge_button.get_active():
159            start, end = self.buf.get_bounds()
160            msg = self.buf.get_text(start, end)
161            cmdline += ['--merge']
162            cmdline += ['--message', hglib.fromutf(msg)]
163
164        # start backing out
165        self.execute_command(cmdline)