Changeset eb78193ced0d…
Parent 15a872634252…
by
Changes to 2 files · Browse files at eb78193ced0d Showing diff from parent 15a872634252 Diff from another changeset...
@@ -281,9 +281,8 @@
def add(ui, *pats, **opts):
"""add files"""
- from mercurial import dispatch as _dispatch
- _dispatch.dispatch(['add'] + list(pats))
- shlib.shell_notify([os.getcwd()])
+ from tortoisehg.hgtk.quickop import run
+ gtkrun(run, ui, *pats, **opts)
def thgstatus(ui, *pats, **opts):
"""update TortoiseHg status cache"""
@@ -370,17 +369,17 @@
def remove(ui, *pats, **opts):
"""file status viewer in remove mode"""
- from tortoisehg.hgtk.status import run
+ from tortoisehg.hgtk.quickop import run
gtkrun(run, ui, *pats, **opts)
def revert(ui, *pats, **opts):
"""file status viewer in revert mode"""
- from tortoisehg.hgtk.status import run
+ from tortoisehg.hgtk.quickop import run
gtkrun(run, ui, *pats, **opts)
def forget(ui, *pats, **opts):
"""file status viewer in forget mode"""
- from tortoisehg.hgtk.status import run
+ from tortoisehg.hgtk.quickop import run
gtkrun(run, ui, *pats, **opts)
def serve(ui, *pats, **opts):
|
|
|
@@ -0,0 +1,242 @@ + # quickop.py - TortoiseHg's dialog for quick dirstate operations
+#
+# Copyright 2009 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.
+
+import os
+import gtk
+import gobject
+import pango
+
+from mercurial import hg, ui, cmdutil
+
+from tortoisehg.util.i18n import _
+from tortoisehg.util import hglib, paths, shlib
+from tortoisehg.util.hglib import RepoError
+
+from tortoisehg.hgtk import hgcmd, gtklib, gdialog
+
+MODE_NORMAL = 'normal'
+MODE_WORKING = 'working'
+
+class QuickOpDialog(gtk.Dialog):
+ 'Dialog for performing quick dirstate operations'
+ def __init__(self, command, pats):
+ gtk.Dialog.__init__(self)
+ gtklib.set_tortoise_icon(self, 'hg.ico')
+ gtklib.set_tortoise_keys(self)
+ self.set_resizable(False)
+ self.set_size_request(450, 300)
+ self.set_has_separator(False)
+ self.connect('response', self.dialog_response)
+
+ try:
+ repo = hg.repository(ui.ui(), path=paths.find_root())
+ except hglib.RepoError:
+ gobject.idle_add(self.destroy)
+ return
+
+ os.chdir(repo.root)
+ self.repo = repo
+ self.set_title(hglib.get_reponame(repo) + ' ' + command)
+ self.command = command
+
+ # add dialog buttons
+ self.gobutton = self.add_button(command.capitalize(), gtk.RESPONSE_OK)
+ self.closebtn = self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CLOSE)
+
+ lbl = gtk.Label(_('Select files to ') + command)
+ lbl.set_alignment(0, 0)
+ self.vbox.pack_start(lbl, False, False, 8)
+
+ def keypressed(tree, event):
+ 'Make spacebar toggle selected rows'
+ if event.keyval != 32:
+ return False
+ def toggler(model, path, bufiter):
+ model[path][0] = not model[path][0]
+ selection = tree.get_selection()
+ selection.selected_foreach(toggler)
+ return True
+
+ # add file list treeview
+ fm = gtk.ListStore(bool, # Checked
+ str, # Path
+ str, # Path-UTF8
+ str) # Status
+ self.filetree = gtk.TreeView(fm)
+ self.filetree.connect('key-press-event', keypressed)
+ self.filetree.set_headers_clickable(True)
+ self.filetree.set_reorderable(False)
+ if hasattr(self.filetree, 'set_rubber_banding'):
+ self.filetree.set_rubber_banding(True)
+ fontlist = repo.ui.config('gtools', 'fontlist', 'MS UI Gothic 9')
+ self.filetree.modify_font(pango.FontDescription(fontlist))
+
+ def select_toggle(cell, path):
+ fm[path][0] = not fm[path][0]
+
+ # file selection checkboxes
+ toggle_cell = gtk.CellRendererToggle()
+ toggle_cell.connect('toggled', select_toggle)
+ toggle_cell.set_property('activatable', True)
+
+ col = gtk.TreeViewColumn('', toggle_cell, active=0)
+ col.set_resizable(False)
+ self.filetree.append_column(col)
+
+ col = gtk.TreeViewColumn(_('status'), gtk.CellRendererText(), text=3)
+ self.filetree.append_column(col)
+
+ col = gtk.TreeViewColumn(_('path'), gtk.CellRendererText(), text=2)
+ self.filetree.append_column(col)
+
+ scroller = gtk.ScrolledWindow()
+ scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scroller.add(self.filetree)
+ self.vbox.pack_start(scroller, True, True, 8)
+
+ def toggleall(button):
+ for row in self.filetree.get_model():
+ row[0] = not row[0]
+
+ hbox = gtk.HBox()
+ tb = gtk.Button(_('Toggle all selections'))
+ tb.connect('pressed', toggleall)
+ self.toggleall = tb
+ hbox.pack_start(tb, False, False, 0)
+ self.vbox.pack_start(hbox, False, False, 2)
+
+ types = { 'add' : 'I?',
+ 'forget' : 'MAR!C',
+ 'revert' : 'MAR!',
+ 'remove' : 'MAR!CI?', 'rm' : 'MAR!CI?',
+ }
+ filetypes = types[command]
+
+ try:
+ matcher = cmdutil.match(repo, pats)
+ status = repo.status(match=matcher,
+ clean='C' in filetypes,
+ ignored='I' in filetypes,
+ unknown='?' in filetypes)
+ except IOError:
+ pass
+
+ (modified, added, removed, deleted, unknown, ignored, clean) = status
+ if 'M' in filetypes:
+ for f in modified:
+ fm.append([True, f, hglib.toutf(f), _('modified')])
+ if 'A' in filetypes:
+ for f in added:
+ fm.append([True, f, hglib.toutf(f), _('added')])
+ if 'R' in filetypes:
+ for f in removed:
+ fm.append([True, f, hglib.toutf(f), _('removed')])
+ if '!' in filetypes:
+ for f in deleted:
+ fm.append([True, f, hglib.toutf(f), _('missing')])
+ if '?' in filetypes:
+ for f in unknown:
+ fm.append([True, f, hglib.toutf(f), _('unknown')])
+ if 'I' in filetypes:
+ for f in ignored:
+ if f in pats:
+ fm.append([True, f, hglib.toutf(f), _('ignored')])
+ if 'C' in filetypes:
+ for f in clean:
+ if f in pats:
+ fm.append([True, f, hglib.toutf(f), _('clean')])
+
+ if not len(fm):
+ gdialog.Prompt(_('No appropriate files'),
+ _('No files found for this operation'), self).run()
+ gobject.idle_add(self.destroy)
+ self.hide()
+ return
+
+ # prepare to show
+ self.gobutton.grab_focus()
+ gobject.idle_add(self.after_init)
+
+ def after_init(self):
+ # CmdWidget
+ self.cmd = hgcmd.CmdWidget()
+ self.cmd.show_all()
+ self.cmd.hide()
+ self.vbox.pack_start(self.cmd, True, True, 6)
+
+ # abort button
+ self.abortbtn = self.add_button(_('Abort'), gtk.RESPONSE_CANCEL)
+ self.abortbtn.hide()
+
+ def abort(self):
+ self.cmd.stop()
+ self.cmd.show_log()
+ self.switch_to(MODE_NORMAL, cmd=False)
+
+ def dialog_response(self, dialog, response_id):
+ # go button
+ if response_id == gtk.RESPONSE_OK:
+ self.operation(self.repo)
+ # Close button or dialog closing by the user
+ elif response_id in (gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT):
+ if hasattr(self, 'cmd') and self.cmd.is_alive():
+ ret = gdialog.Confirm(_('Confirm Abort'), [], self,
+ _('Do you want to abort?')).run()
+ if ret == gtk.RESPONSE_YES:
+ self.abort()
+ else:
+ return # close dialog
+ # Abort button
+ elif response_id == gtk.RESPONSE_CANCEL:
+ self.abort()
+ else:
+ raise _('unexpected response id: %s') % response_id
+
+ self.run() # don't close dialog
+
+ def switch_to(self, mode, cmd=True):
+ if mode == MODE_NORMAL:
+ normal = True
+ self.closebtn.grab_focus()
+ elif mode == MODE_WORKING:
+ normal = False
+ self.abortbtn.grab_focus()
+ else:
+ raise _('unknown mode name: %s') % mode
+ working = not normal
+
+ self.filetree.set_sensitive(normal)
+ self.toggleall.set_sensitive(normal)
+ self.gobutton.set_property('visible', normal)
+ self.closebtn.set_property('visible', normal)
+ if cmd:
+ self.cmd.set_property('visible', working)
+ self.abortbtn.set_property('visible', working)
+
+ def operation(self, repo):
+ fm = self.filetree.get_model()
+ list = [row[1] for row in fm if row[0]]
+ if not list:
+ gdialog.Prompt(_('No files selected'),
+ _('No operation to perform'), self).run()
+ return
+ cmdline = ['hg', self.command, '--verbose'] + list
+
+ def cmd_done(returncode):
+ self.switch_to(MODE_NORMAL, cmd=False)
+ if returncode == 0:
+ shlib.shell_notify(list)
+ if not self.cmd.is_show_log():
+ self.destroy()
+ self.switch_to(MODE_WORKING)
+ self.cmd.execute(cmdline, cmd_done)
+
+def run(ui, *pats, **opts):
+ pats = hglib.canonpaths(pats)
+ if opts.get('canonpats'):
+ pats = list(pats) + opts['canonpats']
+ return QuickOpDialog(opts.get('alias'), pats)
|
Loading...