import os import win32api import win32con from win32com.shell import shell, shellcon import _winreg class IconOverlayExtension(object): _com_interfaces_ = [shell.IID_IShellIconOverlayIdentifier] _public_methods_ = [ "GetOverlayInfo", "GetPriority", "IsMemberOf" ] def GetOverlayInfo(self): return ("", 0, 0) def GetPriority(self): return 0 def IsMemberOf(self, path, attrib): return S_FALSE def make_icon_overlay(name, icon, state, clsid): """ Make an icon overlay COM class. Used to create different COM server classes for highlighting the files with different source controlled states (eg: unchanged, modified, ...). """ classname = "%sOverlay" % name prog_id = "Mercurial.ShellExtension.%s" % classname desc = "Merucurial icon overlay shell extension for %s files" % name.lower() reg = [ (_winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\%s" % name) ] cls = type( classname, (IconOverlayExtension, ), dict(_reg_clsid_=clsid, _reg_progid_=prog_id, _reg_desc_=desc, registry_keys=reg, icon=icon, state=state)) _overlay_classes.append(cls) # We need to register the class as global, as pythoncom will # create an instance of it. globals()[classname] = cls def RegisterServer(cls): 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_) 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 print cls._reg_desc_, "unregistration complete." _overlay_classes = [] make_icon_overlay("Changed", "changed.ico", "MODIFIED", "{102C6A24-5F38-4186-B64A-237011809FAB}") if __name__=='__main__': from win32com.server import register register.UseCommandLine(ChangedOverlay, finalize_register = lambda: RegisterServer(ChangedOverlay), finalize_unregister = lambda: UnregisterServer(ChangedOverlay))