/tortoisehg/hgtk/backout.py

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