tortoisehg.py
author Germán Póo-Caamaño <gpoo@calcifer.org>
Sun, 20 Jul 2008 09:33:06 -0400
changeset 1179 15415a973353
parent 1176 997eb001c711
permissions -rw-r--r--
setup: add support for non-windows platforms

#
# Simple TortoiseSVN-like Mercurial plugin for the Windows Shell
# Published under the GNU GPL, v2 or later.
# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
# Copyright (C) 2007 Henry Ludemann <misc@hl.id.au>
# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com>
#

import os
import sys
import _winreg

if hasattr(sys, "frozen") and sys.frozen == 'dll':
    import win32traceutil

# specify version string, otherwise 'hg identify' will be used:
version = ''

import tortoise.version
tortoise.version.remember_version(version)

# shell extension classes
from tortoise.contextmenu import ContextMenuExtension
from tortoise.iconoverlay import ChangedOverlay, AddedOverlay, UnchangedOverlay

bin_path = os.path.dirname(os.path.join(os.getcwd(), sys.argv[0]))
print "bin path = ", bin_path

# TortoiseHg registry setup
def register_tortoise_path(unregister=False):
    key = r"Software\TortoiseHg"
    cat = _winreg.HKEY_LOCAL_MACHINE
    if (unregister):
        _winreg.DeleteKey(cat, key)
        print "TortoiseHg unregistered"
    else:
        _winreg.SetValue(cat, key, _winreg.REG_SZ, bin_path)
        print "TortoiseHg registered"

# for COM registration via py2exe
def DllRegisterServer():
    RegisterServer(ContextMenuExtension)
    RegisterServer(ChangedOverlay)
    RegisterServer(AddedOverlay)
    RegisterServer(UnchangedOverlay)
    register_tortoise_path()

# for COM registration via py2exe
def DllUnregisterServer():
    UnregisterServer(ContextMenuExtension)
    UnregisterServer(ChangedOverlay)
    UnregisterServer(AddedOverlay)
    UnregisterServer(UnchangedOverlay)
    register_tortoise_path(unregister=True)

def RegisterServer(cls):
    # Add mercurial to the library path
    try:
        import mercurial
    except ImportError:
        from win32com.server import register
        register.UnregisterClasses(cls)
        raise "Error: Failed to find mercurial module!"

    hg_path = os.path.dirname(os.path.dirname(mercurial.__file__))
    try:
        key = "CLSID\\%s\\PythonCOMPath" % cls._reg_clsid_
        path = _winreg.QueryValue(_winreg.HKEY_CLASSES_ROOT, key)
        _winreg.SetValue(_winreg.HKEY_CLASSES_ROOT, key, _winreg.REG_SZ, "%s;%s" % (path, hg_path))
    except:
        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_)
        
    # register the extension on Approved list
    try:
        apath = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved'
        key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, apath, 0, _winreg.KEY_WRITE)
        _winreg.SetValueEx(key, cls._reg_clsid_, 0, _winreg.REG_SZ, 'TortoiseHg')
    except:
        pass

    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

    # unregister the extension from Approved list
    try:
        apath = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved'
        key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, apath, 0, _winreg.KEY_WRITE)
        _winreg.DeleteValue(key, cls._reg_clsid_)
    except:
        pass

    print cls._reg_desc_, "unregistration complete."

if __name__=='__main__':
    from win32com.server import register
    register.UseCommandLine(ContextMenuExtension,
            finalize_register = lambda: RegisterServer(ContextMenuExtension),
            finalize_unregister = lambda: UnregisterServer(ContextMenuExtension))
    
    for cls in (ChangedOverlay, AddedOverlay, UnchangedOverlay):
        register.UseCommandLine(cls,
                finalize_register = lambda: RegisterServer(cls),
                finalize_unregister = lambda: UnregisterServer(cls))

    if "--unregister" in sys.argv[1:]:
        register_tortoise_path(unregister=True)
    else:
        register_tortoise_path()