by
Changes to 11 files · Browse files at 8dfdb81dfbb4 Showing diff from parent a6dcece59dec 8ccb624da558 Diff from another changeset...
@@ -11,3 +11,4 @@ 864497951b6b801cfacbac16eec5b7edb4f1be3c 0.4rc4
f627244263631682216716cde477d05bebc0d934 0.4
491a94666fc3498827066b8aa65aab34d3a3e623 0.4.1
+93df004457accaba3651c6534115aa4b98d94ce7 0.5
|
@@ -6,11 +6,43 @@ what bugs have been fixed, and what features have been added in the current
version.
-New features and improvement in 0.4.1
+New features and improvement in 0.5:
+
+ * Explorer shell extensions:
+ - share overlay icons with TortoiseSVN 1.5.x via TortoiseSVN's
+ TortoiseOverlays project (by Peer Sommerlund)
+
+ * New mercurial-like command line syntax for hgtk, with help support.
+
+ * The gPyFm merge-tool is not longer bundled (see bug 2119067)
+
+ * Interal commit dialog:
+ - show number of files selected (also apply to Status dialog)
+ - add 'Undo' button to rollback last commit.
+ - do not clear commit message window if commit fails
+ - accept commit message in multi-byte charset (fix bug 2116362)
+
+ * Synchronize dialog:
+ - load patchbomb extension automatically (by Peer Sommerlund)
+
+
+Bug fixes in 0.5:
+
+ * [ 2119138 ] Merge-tool priority fix (by Mads Kiilerich)
+ * [ 2116362 ] Internal commit tool not support gbk comment
+ * [ 2113989 ] Can't create repository via Explorer context menu (when
+ a file is selected)
+ * [ 2103749 ] Changelog viewer doesn't refresh after making local tag
+
+ * nautilus: fix error when there is no repo in the current directory
+ (by Germ�n P�o-Caama�o)
+
+
+New features and improvement in 0.4.1:
* Installer-only release to link with Mercurial 1.0.2
-New features and improvement in 0.4
+New features and improvement in 0.4:
* Updated to work, and link, with Mercurial 1.0.1
|
@@ -29,6 +29,7 @@ from gtools import cmdtable
from status import GStatus
from hgcmd import CmdDialog
+from hglib import fromutf
class GCommit(GStatus):
"""GTK+ based dialog for displaying repository status and committing changes.
@@ -324,7 +325,7 @@ cmdline = ["hg", "commit", "--verbose", "--repository", self.repo.root]
if self.opts['addremove']:
cmdline += ['--addremove']
- cmdline += ['--message', self.opts['message']]
+ cmdline += ['--message', fromutf(self.opts['message'])]
cmdline += [self.repo.wjoin(x) for x in files]
dialog = CmdDialog(cmdline, True)
dialog.set_transient_for(self)
@@ -332,11 +333,12 @@ dialog.hide()
# refresh overlay icons and commit dialog
- self.text.set_buffer(gtk.TextBuffer())
- self._update_recent_messages(self.opts['message'])
- shell_notify([self.cwd] + files)
- self._last_commit_id = self._get_tip_rev(True)
- self.reload_status()
+ if dialog.return_code() == 0:
+ self.text.set_buffer(gtk.TextBuffer())
+ self._update_recent_messages(self.opts['message'])
+ shell_notify([self.cwd] + files)
+ self._last_commit_id = self._get_tip_rev(True)
+ self.reload_status()
def _get_tip_rev(self, refresh=False):
if refresh:
|
@@ -149,6 +149,9 @@ self.last_pbar_update = tm
self.pbar.pulse()
+ def return_code(self):
+ return self.hgthread.return_code()
+
def run(cmdline=[], gui=True, **opts):
if not gui:
q = Queue.Queue()
|
@@ -203,13 +203,7 @@ self.repo = None
return
- for name, module in extensions.extensions():
- if name == 'patchbomb':
- break
- else:
- error_dialog(self, 'Email not enabled',
- 'You must enable the patchbomb extension to use this tool')
- self.response(gtk.RESPONSE_CANCEL)
+ extensions.load(self.repo.ui, 'patchbomb', None)
if initial:
# Only zap these fields at startup
|
@@ -457,17 +457,18 @@ # save tag info for detecting new tags added
oldtags = self.repo.tagslist()
+ def refresh(*args):
+ self.repo.invalidate()
+ newtags = self.repo.tagslist()
+ if newtags != oldtags:
+ self.reload_log()
+
dialog = TagAddDialog(self.repo.root, rev=str(rev))
dialog.set_transient_for(self)
+ dialog.connect('destroy', refresh)
dialog.show_all()
dialog.present()
dialog.set_transient_for(None)
-
- # refresh if new tags added
- self.repo.invalidate()
- newtags = self.repo.tagslist()
- if newtags != oldtags:
- self.reload_log()
def _show_status(self, menuitem):
rev = self.currow[treemodel.REVID]
|
@@ -254,9 +254,12 @@ def refresh(self, graphcol, pats, opts):
self.repo.invalidate()
self.repo.dirstate.invalidate()
- self.create_log_generator(graphcol, pats, opts)
- self.pbar.begin()
- gobject.idle_add(self.populate, self.get_revision())
+ if self.repo.changelog.count() > 0:
+ self.create_log_generator(graphcol, pats, opts)
+ self.pbar.begin()
+ gobject.idle_add(self.populate, self.get_revision())
+ else:
+ self.pbar.set_status_text('Repository is empty')
def construct_treeview(self):
self.treeview = gtk.TreeView()
|
@@ -53,7 +53,7 @@ "icon_resources": [(1, "icons/tortoise/python.ico")]}
]
extra['com_server'] = ["tortoisehg"]
- extra['console'] = ["contrib/hg"]
+ extra['console'] = ["contrib/hg", "contrib/hgtk"]
opts = {
"py2exe" : {
|
@@ -129,12 +129,24 @@ ]
registry_keys = [
- (_winreg.HKEY_CLASSES_ROOT, r"*\shellex\ContextMenuHandlers\TortoiseHg"),
- (_winreg.HKEY_CLASSES_ROOT, r"Directory\Background\shellex\ContextMenuHandlers\TortoiseHg"),
- (_winreg.HKEY_CLASSES_ROOT, r"Directory\shellex\ContextMenuHandlers\TortoiseHg"),
- (_winreg.HKEY_CLASSES_ROOT, r"Folder\shellex\ContextMenuHandlers\TortoiseHg"),
- (_winreg.HKEY_CLASSES_ROOT, r"Directory\shellex\DragDropHandlers\TortoiseHg"),
- (_winreg.HKEY_CLASSES_ROOT, r"Folder\shellex\DragDropHandlers\TortoiseHg"),
+ (_winreg.HKEY_CLASSES_ROOT,
+ r"*\shellex\ContextMenuHandlers\TortoiseHg",
+ [(None, _reg_clsid_)]),
+ (_winreg.HKEY_CLASSES_ROOT,
+ r"Directory\Background\shellex\ContextMenuHandlers\TortoiseHg",
+ [(None, _reg_clsid_)]),
+ (_winreg.HKEY_CLASSES_ROOT,
+ r"Directory\shellex\ContextMenuHandlers\TortoiseHg",
+ [(None, _reg_clsid_)]),
+ (_winreg.HKEY_CLASSES_ROOT,
+ r"Folder\shellex\ContextMenuHandlers\TortoiseHg",
+ [(None, _reg_clsid_)]),
+ (_winreg.HKEY_CLASSES_ROOT,
+ r"Directory\shellex\DragDropHandlers\TortoiseHg",
+ [(None, _reg_clsid_)]),
+ (_winreg.HKEY_CLASSES_ROOT,
+ r"Folder\shellex\DragDropHandlers\TortoiseHg",
+ [(None, _reg_clsid_)]),
]
def __init__(self):
@@ -514,6 +526,9 @@
def _init(self, parent_window):
dest = self._folder or self._filenames[0]
+ if os.path.isfile(dest):
+ dest = os.path.dirname(dest)
+
msg = "Create Hg repository in %s?" % (dest)
title = "Mercurial: init"
rv = win32ui.MessageBox(msg, title, win32con.MB_OKCANCEL)
|
@@ -52,12 +52,14 @@ class IconOverlayExtension(object):
"""
Class to implement icon overlays for source controlled files.
+ Specialized classes are created for each overlay icon.
Displays a different icon based on version control status.
NOTE: The system allocates only 15 slots in _total_ for all
icon overlays; we (will) use 6, tortoisecvs uses 7... not a good
- recipe for a happy system.
+ recipe for a happy system. By utilizing the TortoiseOverlay.dll
+ we can share overlay slots with the other tortoises.
"""
counter = 0
@@ -69,31 +71,10 @@ _reg_threading_ = 'Apartment'
def GetOverlayInfo(self):
- icon = thgutil.get_icon_path("status", self.icon)
- print "icon = ", icon
-
- if icon:
- return (icon, 0, shellcon.ISIOI_ICONFILE)
- else:
- return ("", 0, 0)
+ return ("", 0, 0)
def GetPriority(self):
return 0
-
- def _get_installed_overlays():
- key = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE,
- "Software\\Microsoft\\Windows\\" +
- "CurrentVersion\\Explorer\\" +
- "ShellIconOverlayIdentifiers",
- 0,
- win32con.KEY_READ)
- keys = win32api.RegEnumKeyEx(key)
- handlercount = len(keys)
- print "number of overlay handlers installed = %d" % handlercount
- for i, k in enumerate(keys):
- print i, k
- win32api.RegCloseKey(key)
- return handlercount
def _get_state(self, upath):
"""
@@ -222,7 +203,7 @@ print "IsMemberOf: _get_state() took %d ticks" % \
(win32api.GetTickCount() - tc)
-def make_icon_overlay(name, icon, state, clsid):
+def make_icon_overlay(name, icon_type, state, clsid):
"""
Make an icon overlay COM class.
@@ -234,11 +215,14 @@ prog_id = "Mercurial.ShellExtension.%s" % classname
desc = "Mercurial icon overlay shell extension for %s files" % name.lower()
reg = [
- (_winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\%s" % name) ]
+ (_winreg.HKEY_LOCAL_MACHINE,
+ r"Software\TortoiseOverlays\%s" % icon_type,
+ [("TortoiseHg", clsid)])
+ ]
cls = type(
classname,
(IconOverlayExtension, ),
- dict(_reg_clsid_=clsid, _reg_progid_=prog_id, _reg_desc_=desc, registry_keys=reg, icon=icon, state=state))
+ dict(_reg_clsid_=clsid, _reg_progid_=prog_id, _reg_desc_=desc, registry_keys=reg, stringKey="HG", state=state))
_overlay_classes.append(cls)
# We need to register the class as global, as pythoncom will
@@ -246,12 +230,6 @@ globals()[classname] = cls
_overlay_classes = []
-make_icon_overlay("Changed", "changed.ico", MODIFIED, "{102C6A24-5F38-4186-B64A-237011809FAB}")
-make_icon_overlay("Unchanged", "unchanged.ico", UNCHANGED, "{00FEE959-5773-424B-88AC-A01BFC8E4555}")
-make_icon_overlay("Added", "added.ico", ADDED, "{8447DB75-5875-4BA8-9F38-A727DAA484A0}")
-
-def get_overlay_classes():
- """
- Get a list of all registerable icon overlay classes
- """
- return _overlay_classes
+make_icon_overlay("Changed", "Modified", MODIFIED, "{4D0F33E1-654C-4A1B-9BE8-E47A98752BAB}")
+make_icon_overlay("Unchanged", "Normal", UNCHANGED, "{4D0F33E2-654C-4A1B-9BE8-E47A98752BAB}")
+make_icon_overlay("Added", "Added", ADDED, "{4D0F33E3-654C-4A1B-9BE8-E47A98752BAB}")
|
@@ -26,6 +26,16 @@ bin_path = os.path.dirname(os.path.join(os.getcwd(), sys.argv[0]))
print "bin path = ", bin_path
+def check_tortoise_overlays():
+ # TortoiseOverlays must be installed, and we must be able to write there.
+ try:
+ hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
+ r"Software\TortoiseOverlays", 0,
+ _winreg.KEY_ALL_ACCESS)
+ except WindowsError:
+ print "TortoiseOverlays is not installed."
+ sys.exit(1)
+
# TortoiseHg registry setup
def register_tortoise_path(unregister=False):
key = r"Software\TortoiseHg"
@@ -39,6 +49,7 @@
# for COM registration via py2exe
def DllRegisterServer():
+ check_tortoise_overlays()
RegisterServer(ContextMenuExtension)
RegisterServer(ChangedOverlay)
RegisterServer(AddedOverlay)
@@ -71,8 +82,11 @@ pass
# Add the appropriate shell extension registry keys
- for category, keyname in cls.registry_keys:
- _winreg.SetValue(category, keyname, _winreg.REG_SZ, cls._reg_clsid_)
+ for category, keyname, values in cls.registry_keys:
+ hkey = _winreg.CreateKey(category, keyname)
+ for (name, val) in values:
+ # todo: handle ints?
+ _winreg.SetValueEx(hkey, name, 0, _winreg.REG_SZ, val)
# register the extension on Approved list
try:
@@ -85,13 +99,14 @@ print cls._reg_desc_, "registration complete."
def UnregisterServer(cls):
- for category, keyname in cls.registry_keys:
- try:
- _winreg.DeleteKey(category, keyname)
- except WindowsError, details:
- import errno
- if details.errno != errno.ENOENT:
- raise
+ for category, keyname, values in cls.registry_keys:
+ hkey = _winreg.OpenKey(category, keyname, 0, _winreg.KEY_ALL_ACCESS)
+ for (name, val) in values:
+ # todo: handle ints?
+ try:
+ _winreg.DeleteValue(hkey, name)
+ except WindowsError, exc:
+ print "Failed to remove registry key %s: %s" % (keyname, exc)
# unregister the extension from Approved list
try:
@@ -104,6 +119,8 @@ print cls._reg_desc_, "unregistration complete."
if __name__=='__main__':
+ check_tortoise_overlays()
+
from win32com.server import register
register.UseCommandLine(ContextMenuExtension,
finalize_register = lambda: RegisterServer(ContextMenuExtension),
|
Loading...