Kiln » TortoiseHg » TortoiseHg
Clone URL:  
iconoverlay.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Published under the GNU GPL, v2 or later. # Copyright (C) 2007 Henry Ludemann <misc@hl.id.au> # Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> import os import win32api import win32con import win32process from win32com.shell import shell, shellcon import _winreg from mercurial import hg, cmdutil, util import thgutil import sys import threading import cachethg from cachethg import debugf try: from mercurial.error import RepoError except ImportError: from mercurial.repo import RepoError cache_lock = threading.Semaphore() # some misc constants S_OK = 0 S_FALSE = 1 appfiltered = False try: try: # This will fail on windows < NT proc = win32api.GetCurrentProcess() app = win32process.GetModuleFileNameEx(proc, 0) except: app = win32api.GetModuleFileName(0) app = str(os.path.basename(app)).lower() if not app.startswith('tortoisehg'): from _winreg import HKEY_CURRENT_USER, OpenKey, QueryValueEx hkey = OpenKey(HKEY_CURRENT_USER, r"Software\TortoiseHg") filter = str(QueryValueEx(hkey, 'ShellApps')[0]) for f in filter.split(','): f = f.strip().lower() if f == '*': break elif f == app: break else: debugf("app %s filtered, does not match %s", (app, filter)) appfiltered = True except (ImportError, EnvironmentError): pass 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. By utilizing the TortoiseOverlay.dll we can share overlay slots with the other tortoises. """ counter = 0 _com_interfaces_ = [shell.IID_IShellIconOverlayIdentifier] _public_methods_ = [ "GetOverlayInfo", "GetPriority", "IsMemberOf" ] _reg_threading_ = 'Apartment' def GetOverlayInfo(self): return ("", 0, 0) def GetPriority(self): return 0 def IsMemberOf(self, path, attrib): if appfiltered: return S_FALSE global cache_lock try: cache_lock.acquire() tc = win32api.GetTickCount() if cachethg.get_state(path) in self.state: return S_OK return S_FALSE finally: cache_lock.release() debugf("IsMemberOf(%s): _get_state() took %d ticks", (self.state, win32api.GetTickCount() - tc)) def make_icon_overlay(name, icon_type, 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 = "Mercurial icon overlay shell extension for %s files" % name.lower() reg = [ (_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, stringKey="HG", 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 _overlay_classes = [] modified = cachethg.REMOVED + cachethg.DELETED + cachethg.MODIFIED make_icon_overlay("Changed", "Modified", modified, "{4D0F33E1-654C-4A1B-9BE8-E47A98752BAB}") make_icon_overlay("Unchanged", "Normal", cachethg.UNCHANGED, "{4D0F33E2-654C-4A1B-9BE8-E47A98752BAB}") make_icon_overlay("Added", "Added", cachethg.ADDED, "{4D0F33E3-654C-4A1B-9BE8-E47A98752BAB}") make_icon_overlay("Ignored", "Ignored", cachethg.IGNORED, "{4D0F33E4-654C-4A1B-9BE8-E47A98752BAB}") make_icon_overlay("Conflict", "Conflict", cachethg.UNRESOLVED, "{4D0F33E5-654C-4A1B-9BE8-E47A98752BAB}")