--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hggtk/recovery.py Fri Jan 04 07:44:17 2008 +0000
@@ -0,0 +1,178 @@
+#
+# Repository recovery dialog for TortoiseHg
+#
+# Copyright (C) 2007 Steve Borho <steve@borho.org>
+# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com>
+#
+
+try:
+ import pygtk
+ pygtk.require("2.0")
+except:
+ pass
+
+import gtk
+import gobject
+import pango
+import Queue
+import os
+import threading
+from mercurial import hg, ui, util
+from mercurial.node import *
+from dialog import error_dialog
+from hglib import HgThread
+from shlib import set_tortoise_icon
+
+class RecoveryDialog(gtk.Dialog):
+ def __init__(self, cwd='', root=''):
+ """ Initialize the Dialog. """
+ gtk.Dialog.__init__(self, parent=None,
+ flags=0,
+ buttons=())
+
+ set_tortoise_icon(self, 'general.ico')
+ self.root = root
+ self.selected_path = None
+
+ self.set_default_size(600, 400)
+
+ self.paths = self._get_paths()
+ name = os.path.basename(os.path.abspath(root))
+ self.set_title("TortoiseHg Recovery - " + name)
+
+ self.connect('delete-event', self._delete)
+ self.connect('response', self._response)
+
+ self._btn_close = gtk.Button("Close")
+ self._btn_close.connect('clicked', self._close_clicked)
+ self.action_area.pack_end(self._btn_close)
+
+ # toolbar
+ self.tbar = gtk.Toolbar()
+ tbuttons = [
+ self._toolbutton(gtk.STOCK_UNDO,
+ 'rollback',
+ self._rollback_clicked),
+ gtk.SeparatorToolItem(),
+ self._toolbutton(gtk.STOCK_CLEAR,
+ 'recover',
+ self._recover_clicked),
+ gtk.SeparatorToolItem(),
+ self._toolbutton(gtk.STOCK_APPLY,
+ 'verify',
+ self._verify_clicked),
+ gtk.SeparatorToolItem(),
+ ]
+ for btn in tbuttons:
+ self.tbar.insert(btn, -1)
+ self.vbox.pack_start(self.tbar, False, False, 2)
+
+ # hg output window
+ scrolledwindow = gtk.ScrolledWindow()
+ scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.textview = gtk.TextView(buffer=None)
+ self.textview.set_editable(False)
+ self.textview.modify_font(pango.FontDescription("Monospace"))
+ scrolledwindow.add(self.textview)
+ self.textview.set_editable(False)
+ self.textbuffer = self.textview.get_buffer()
+ self.vbox.pack_start(scrolledwindow, True, True)
+
+ def _get_paths(self):
+ """ retrieve repo revisions """
+ try:
+ self.repo = hg.repository(ui.ui(), path=self.root)
+ return self.repo.ui.configitems('paths')
+ except hg.RepoError:
+ return None
+
+ def _close_clicked(self, *args):
+ if threading.activeCount() != 1:
+ error_dialog("Can't close now", "command is running")
+ else:
+ self.response(gtk.RESPONSE_CLOSE)
+
+ def _delete(self, widget, event):
+ return True
+
+ def _response(self, widget, response_id):
+ if threading.activeCount() != 1:
+ error_dialog("Can't close now", "command is running")
+ widget.emit_stop_by_name('response')
+ else:
+ gtk.main_quit()
+
+ def _toolbutton(self, stock, label, handler, menu=None, userdata=None):
+ if menu:
+ tbutton = gtk.MenuToolButton(stock)
+ tbutton.set_menu(menu)
+ else:
+ tbutton = gtk.ToolButton(stock)
+
+ tbutton.set_label(label)
+ tbutton.connect('clicked', handler, userdata)
+ return tbutton
+
+ def _rollback_clicked(self, toolbutton, data=None):
+ cmd = ['rollback']
+ self._exec_cmd(cmd)
+
+ def _recover_clicked(self, toolbutton, data=None):
+ cmd = ['recover']
+ self._exec_cmd(cmd)
+
+ def _verify_clicked(self, toolbutton, data=None):
+ cmd = ['verify']
+ self._exec_cmd(cmd)
+
+ def _exec_cmd(self, cmd):
+ cmdline = cmd
+ cmdline.append('--verbose')
+ cmdline.append('--repository')
+ cmdline.append(self.root)
+
+ # show command to be executed
+ self.write("", False)
+ #self.write("$ %s\n" % ' '.join(cmdline))
+
+ # execute command and show output on text widget
+ gobject.timeout_add(10, self.process_queue)
+ self.hgthread = HgThread(cmdline)
+ self.hgthread.start()
+
+ def write(self, msg, append=True):
+ msg = unicode(msg, 'iso-8859-1')
+ if append:
+ enditer = self.textbuffer.get_end_iter()
+ self.textbuffer.insert(enditer, msg)
+ else:
+ self.textbuffer.set_text(msg)
+
+ def process_queue(self):
+ """
+ Handle all the messages currently in the queue (if any).
+ """
+ self.hgthread.process_dialogs()
+ while self.hgthread.getqueue().qsize():
+ try:
+ msg = self.hgthread.getqueue().get(0)
+ self.write(msg)
+ except Queue.Empty:
+ pass
+ if threading.activeCount() == 1:
+ return False # Stop polling this function
+ else:
+ return True
+
+def run(cwd='', root='', **opts):
+ dialog = RecoveryDialog(cwd, root)
+ dialog.show_all()
+ gtk.gdk.threads_init()
+ gtk.gdk.threads_enter()
+ gtk.main()
+ gtk.gdk.threads_leave()
+
+if __name__ == "__main__":
+ import sys
+ run(*sys.argv[1:])