Changeset eeb2b2b45492…
Parent 2cc1199b3314…
by
Changes to 3 files · Browse files at eeb2b2b45492 Showing diff from parent 2cc1199b3314 Diff from another changeset...
|
@@ -25,7 +25,7 @@ from tortoisehg.hgtk import gdialog, gtklib, hgcmd, gorev, thgstrip
from tortoisehg.hgtk import backout, status, hgemail, tagadd, update, merge
from tortoisehg.hgtk import archive, changeset, thgconfig, thgmq, histdetails
-from tortoisehg.hgtk import statusbar, bookmark
+from tortoisehg.hgtk import statusbar, bookmark, thgimport
def create_menu(label, callback=None):
menuitem = gtk.MenuItem(label, True)
@@ -304,9 +304,6 @@ dict(text=_('Stop'), name='stop', sensitive=False,
func=self.stop_clicked, icon=gtk.STOCK_STOP),
dict(text='----'),
- dict(text=_('Add Bundle...'), name='add-bundle',
- sensitive=not bool(self.bfile),
- func=self.add_bundle_clicked, icon=gtk.STOCK_ADD),
dict(text=_('Accept Bundle'), name='accept',
sensitive=bool(self.bfile),
func=self.apply_clicked, icon=gtk.STOCK_APPLY),
@@ -314,6 +311,12 @@ sensitive=bool(self.bfile),
func=self.reject_clicked, icon=gtk.STOCK_DIALOG_ERROR),
dict(text='----'),
+ dict(text=_('Import...'), name='import',
+ func=self.import_clicked, icon='menuimport.ico'),
+ dict(text=_('Add Bundle...'), name='add-bundle',
+ sensitive=not bool(self.bfile),
+ func=self.add_bundle_clicked, icon=gtk.STOCK_ADD),
+ dict(text='----'),
dict(text=_('Use proxy server'), name='use-proxy-server',
ascheck=True, func=toggle_proxy),
dict(text=_('Force push'), ascheck=True, func=toggle_force),
@@ -1580,6 +1583,17 @@ def stop_clicked(self, toolbutton):
self.runner.stop()
+ def import_clicked(self, toolbutton):
+ oldlen = len(self.repo)
+ def import_completed():
+ self.repo.invalidate()
+ self.changeview.clear()
+ if oldlen < len(self.repo):
+ self.reload_log()
+ dialog = thgimport.ImportDialog(self.repo)
+ dialog.set_notify_func(import_completed)
+ self.show_dialog(dialog)
+
def update_urllist(self):
urllist = self.urlcombo.get_model()
urllist.clear()
|
|
|
@@ -0,0 +1,242 @@ + # thgimport.py - TortoiseHg's dialog for (q)importing patches
+#
+# Copyright 2009 Yuki KODAMA <endflow.net@gmail.com>
+#
+# 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
+
+from mercurial import hg, ui
+
+from tortoisehg.util.i18n import _
+from tortoisehg.util import hglib, paths
+
+from tortoisehg.hgtk import hgcmd, gtklib, gdialog, cslist
+
+MODE_NORMAL = 'normal'
+MODE_WORKING = 'working'
+
+class ImportDialog(gtk.Dialog):
+ """ Dialog to import patches """
+
+ def __init__(self, repo=None):
+ """ Initialize the Dialog """
+ gtk.Dialog.__init__(self)
+ gtklib.set_tortoise_icon(self, 'menuimport.ico')
+ gtklib.set_tortoise_keys(self)
+ self.set_resizable(False)
+ self.set_has_separator(False)
+
+ # buttons
+ self.importbtn = self.add_button(_('Import'), gtk.RESPONSE_OK)
+ self.closebtn = self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
+
+ if not repo:
+ try:
+ repo = hg.repository(ui.ui(), path=paths.find_root())
+ except hglib.RepoError:
+ gtklib.idle_add_single_call(self.destroy)
+ return
+ self.repo = repo
+ self.set_title(_('Import - %s') % hglib.get_reponame(repo))
+ self.done = False
+
+ # layout table
+ self.table = table = gtklib.LayoutTable()
+ self.vbox.pack_start(table, True, True, 2)
+
+ ## source path entry & browse button
+ self.source_entry = gtk.Entry()
+ self.files_btn = gtk.Button(_('Files...'))
+ self.dir_btn = gtk.Button(_('Directory...'))
+ table.add_row(_('Source:'), self.source_entry, 1,
+ self.files_btn, self.dir_btn, expand=0)
+
+ # copy form thgstrip.py
+ def createlabel():
+ label = gtk.Label()
+ label.set_alignment(0, 0.5)
+ label.set_size_request(-1, 24)
+ label.size_request()
+ return label
+
+ ## info label
+ self.infolbl = createlabel()
+ table.add_row(_('Preview:'), self.infolbl, padding=False)
+
+ ## patch preview
+ self.cslist = cslist.ChangesetList()
+ table.add_row(None, self.cslist, padding=False)
+ self.cslist.set_dnd_enable(True)
+ self.cslist.set_checkbox_enable(True)
+
+ # signal handlers
+ self.connect('response', self.dialog_response)
+ self.files_btn.connect('clicked', self.files_clicked)
+ self.dir_btn.connect('clicked', self.dir_clicked)
+ self.cslist.connect('list-updated', self.list_updated)
+ self.source_entry.connect('changed', lambda e: self.preview(queue=True))
+
+ # prepare to show
+ self.cslist.clear()
+ gtklib.idle_add_single_call(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 files_clicked(self, button):
+ initdir = self.get_initial_dir()
+ result = gtklib.NativeSaveFileDialogWrapper(title=_('Select Patches'),
+ initial=initdir, open=True, multi=True).run()
+ if result and result != initdir:
+ if not isinstance(result, basestring):
+ result = os.pathsep.join(result)
+ self.source_entry.set_text(result)
+ self.preview()
+
+ def dir_clicked(self, button):
+ initdir = self.get_initial_dir()
+ result = gtklib.NativeFolderSelectDialog(
+ title=_('Select Directory contains patches:'),
+ initial=initdir).run()
+ if result and result != initdir:
+ self.source_entry.set_text(result)
+ self.preview()
+
+ def list_updated(self, cslist, total, sel, *args):
+ self.update_status(sel)
+
+ def dialog_response(self, dialog, response_id):
+ def abort():
+ self.cmd.stop()
+ self.cmd.show_log()
+ self.switch_to(MODE_NORMAL, cmd=False)
+ # Import button
+ if response_id == gtk.RESPONSE_OK:
+ self.doimport()
+ # Close button or dialog closing by the user
+ elif response_id in (gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT):
+ if self.cmd.is_alive():
+ ret = gdialog.Confirm(_('Confirm Abort'), [], self,
+ _('Do you want to abort?')).run()
+ if ret == gtk.RESPONSE_YES:
+ abort()
+ elif len(self.cslist.get_items()) != 0 and not self.done:
+ ret = gdialog.Confirm(_('Confirm Close'), [], self,
+ _('Do you want to close?')).run()
+ if ret == gtk.RESPONSE_YES:
+ self.destroy()
+ return # close dialog
+ else:
+ self.destroy()
+ return # close dialog
+ # Abort button
+ elif response_id == gtk.RESPONSE_CANCEL:
+ abort()
+ else:
+ raise _('unexpected response id: %s') % response_id
+
+ self.run() # don't close dialog
+
+ def get_initial_dir(self):
+ src = self.source_entry.get_text()
+ if src and os.path.exists(src):
+ if os.path.isdir(src):
+ return src
+ parent = os.path.dirname(src)
+ if parent and os.path.exists(parent):
+ return parent
+ return None
+
+ def update_status(self, count):
+ if count:
+ info = _('<span weight="bold">%s patches</span> will'
+ ' be imported') % count
+ else:
+ info = '<span weight="bold" foreground="#880000">%s</span>' \
+ % _('Nothing to import')
+ self.infolbl.set_markup(info)
+ self.importbtn.set_sensitive(bool(count))
+
+ def get_filepaths(self):
+ src = self.source_entry.get_text()
+ if not src:
+ return []
+ files = []
+ for path in src.split(os.pathsep):
+ path = path.strip('\r\n\t ')
+ if not os.path.exists(path):
+ continue
+ if os.path.isdir(path):
+ entries = os.listdir(path)
+ for entry in entries:
+ file = os.path.join(path, entry)
+ if os.path.isfile(file):
+ files.append(file)
+ elif os.path.isfile(path):
+ files.append(path)
+ return files
+
+ def preview(self, queue=False):
+ files = self.get_filepaths()
+ if files:
+ self.cslist.update(files, self.repo, queue=queue)
+ else:
+ self.cslist.clear()
+
+ def set_notify_func(self, func, *args, **kargs):
+ self.notify_func = func
+ self.notify_args = args
+ self.notify_kargs = kargs
+
+ 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.table.set_sensitive(normal)
+ self.importbtn.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 doimport(self):
+ items = self.cslist.get_items(sel=True)
+ files = [file for file, sel in items if sel]
+ if not files:
+ return
+ cmdline = ['hg', 'import', '--verbose']
+ cmdline.extend(files)
+
+ def cmd_done(returncode, useraborted):
+ self.done = True
+ self.switch_to(MODE_NORMAL, cmd=False)
+ if hasattr(self, 'notify_func'):
+ self.notify_func(*self.notify_args, **self.notify_kargs)
+ if returncode == 0:
+ if not self.cmd.is_show_log():
+ self.response(gtk.RESPONSE_CLOSE)
+ self.cmd.set_result(_('Imported successfully'), style='ok')
+ elif useraborted:
+ self.cmd.set_result(_('Canceled importing'), style='error')
+ else:
+ self.cmd.set_result(_('Failed to import'), style='error')
+ self.switch_to(MODE_WORKING)
+ self.cmd.execute(cmdline, cmd_done)
|
Loading...