codekingpro/portable-devtools
114k
1import glob2import os3import pyclbr4 5import afxres6import commctrl7import pywin.framework.scriptutils8import regutil9import win32api10import win32con11import win32ui12from pywin.mfc import dialog13 14from . import hierlist15 16 17class HLIErrorItem(hierlist.HierListItem):18 def __init__(self, text):19 self.text = text20 hierlist.HierListItem.__init__(self)21 22 def GetText(self):23 return self.text24 25 26class HLICLBRItem(hierlist.HierListItem):27 def __init__(self, name, file, lineno, suffix=""):28 # If the 'name' object itself has a .name, use it. Not sure29 # how this happens, but seems pyclbr related.30 # See PyWin32 bug 81703531 self.name = getattr(name, "name", name)32 self.file = file33 self.lineno = lineno34 self.suffix = suffix35 36 def __lt__(self, other):37 return self.name < other.name38 39 def __eq__(self, other):40 return self.name == other.name41 42 def GetText(self):43 return self.name + self.suffix44 45 def TakeDefaultAction(self):46 if self.file:47 pywin.framework.scriptutils.JumpToDocument(48 self.file, self.lineno, bScrollToTop=149 )50 else:51 win32ui.SetStatusText("The source of this object is unknown")52 53 def PerformItemSelected(self):54 if self.file is None:55 msg = "%s - source can not be located." % (self.name,)56 else:57 msg = "%s defined at line %d of %s" % (self.name, self.lineno, self.file)58 win32ui.SetStatusText(msg)59 60 61class HLICLBRClass(HLICLBRItem):62 def __init__(self, clbrclass, suffix=""):63 try:64 name = clbrclass.name65 file = clbrclass.file66 lineno = clbrclass.lineno67 self.super = clbrclass.super68 self.methods = clbrclass.methods69 except AttributeError:70 name = clbrclass71 file = lineno = None72 self.super = []73 self.methods = {}74 HLICLBRItem.__init__(self, name, file, lineno, suffix)75 76 def GetSubList(self):77 ret = []78 for c in self.super:79 ret.append(HLICLBRClass(c, " (Parent class)"))80 for meth, lineno in self.methods.items():81 ret.append(HLICLBRMethod(meth, self.file, lineno, " (method)"))82 return ret83 84 def IsExpandable(self):85 return len(self.methods) + len(self.super)86 87 def GetBitmapColumn(self):88 return 2189 90 91class HLICLBRFunction(HLICLBRClass):92 def GetBitmapColumn(self):93 return 2294 95 96class HLICLBRMethod(HLICLBRItem):97 def GetBitmapColumn(self):98 return 2299 100 101class HLIModuleItem(hierlist.HierListItem):102 def __init__(self, path):103 hierlist.HierListItem.__init__(self)104 self.path = path105 106 def GetText(self):107 return os.path.split(self.path)[1] + " (module)"108 109 def IsExpandable(self):110 return 1111 112 def TakeDefaultAction(self):113 win32ui.GetApp().OpenDocumentFile(self.path)114 115 def GetBitmapColumn(self):116 col = 4 # Default117 try:118 if win32api.GetFileAttributes(self.path) & win32con.FILE_ATTRIBUTE_READONLY:119 col = 5120 except win32api.error:121 pass122 return col123 124 def GetSubList(self):125 mod, path = pywin.framework.scriptutils.GetPackageModuleName(self.path)126 win32ui.SetStatusText("Building class list - please wait...", 1)127 win32ui.DoWaitCursor(1)128 try:129 try:130 reader = pyclbr.readmodule_ex # Post 1.5.2 interface.131 extra_msg = " or functions"132 except AttributeError:133 reader = pyclbr.readmodule134 extra_msg = ""135 data = reader(mod, [path])136 if data:137 ret = []138 for item in data.values():139 if (140 item.__class__ != pyclbr.Class141 ): # ie, it is a pyclbr Function instance (only introduced post 1.5.2)142 ret.append(HLICLBRFunction(item, " (function)"))143 else:144 ret.append(HLICLBRClass(item, " (class)"))145 ret.sort()146 return ret147 else:148 return [HLIErrorItem("No Python classes%s in module." % (extra_msg,))]149 finally:150 win32ui.DoWaitCursor(0)151 win32ui.SetStatusText(win32ui.LoadString(afxres.AFX_IDS_IDLEMESSAGE))152 153 154def MakePathSubList(path):155 ret = []156 for filename in glob.glob(os.path.join(path, "*")):157 if os.path.isdir(filename) and os.path.isfile(158 os.path.join(filename, "__init__.py")159 ):160 ret.append(HLIDirectoryItem(filename, os.path.split(filename)[1]))161 else:162 if os.path.splitext(filename)[1].lower() in [".py", ".pyw"]:163 ret.append(HLIModuleItem(filename))164 return ret165 166 167class HLIDirectoryItem(hierlist.HierListItem):168 def __init__(self, path, displayName=None, bSubDirs=0):169 hierlist.HierListItem.__init__(self)170 self.path = path171 self.bSubDirs = bSubDirs172 if displayName:173 self.displayName = displayName174 else:175 self.displayName = path176 177 def IsExpandable(self):178 return 1179 180 def GetText(self):181 return self.displayName182 183 def GetSubList(self):184 ret = MakePathSubList(self.path)185 if (186 os.path.split(self.path)[1] == "win32com"187 ): # Complete and utter hack for win32com.188 try:189 path = win32api.GetFullPathName(190 os.path.join(self.path, "..\\win32comext")191 )192 ret = ret + MakePathSubList(path)193 except win32ui.error:194 pass195 return ret196 197 198class HLIProjectRoot(hierlist.HierListItem):199 def __init__(self, projectName, displayName=None):200 hierlist.HierListItem.__init__(self)201 self.projectName = projectName202 self.displayName = displayName or projectName203 204 def GetText(self):205 return self.displayName206 207 def IsExpandable(self):208 return 1209 210 def GetSubList(self):211 paths = regutil.GetRegisteredNamedPath(self.projectName)212 pathList = paths.split(";")213 if len(pathList) == 1: # Single dir - dont bother putting the dir in214 ret = MakePathSubList(pathList[0])215 else:216 ret = list(map(HLIDirectoryItem, pathList))217 return ret218 219 220class HLIRoot(hierlist.HierListItem):221 def __init__(self):222 hierlist.HierListItem.__init__(self)223 224 def IsExpandable(self):225 return 1226 227 def GetSubList(self):228 keyStr = regutil.BuildDefaultPythonKey() + "\\PythonPath"229 hKey = win32api.RegOpenKey(regutil.GetRootKey(), keyStr)230 try:231 ret = []232 ret.append(HLIProjectRoot("", "Standard Python Library")) # The core path.233 index = 0234 while 1:235 try:236 ret.append(HLIProjectRoot(win32api.RegEnumKey(hKey, index)))237 index = index + 1238 except win32api.error:239 break240 return ret241 finally:242 win32api.RegCloseKey(hKey)243 244 245class dynamic_browser(dialog.Dialog):246 style = win32con.WS_OVERLAPPEDWINDOW | win32con.WS_VISIBLE247 cs = (248 win32con.WS_CHILD249 | win32con.WS_VISIBLE250 | commctrl.TVS_HASLINES251 | commctrl.TVS_LINESATROOT252 | commctrl.TVS_HASBUTTONS253 )254 255 dt = [256 ["Python Projects", (0, 0, 200, 200), style, None, (8, "MS Sans Serif")],257 ["SysTreeView32", None, win32ui.IDC_LIST1, (0, 0, 200, 200), cs],258 ]259 260 def __init__(self, hli_root):261 dialog.Dialog.__init__(self, self.dt)262 self.hier_list = hierlist.HierListWithItems(hli_root, win32ui.IDB_BROWSER_HIER)263 self.HookMessage(self.on_size, win32con.WM_SIZE)264 265 def OnInitDialog(self):266 self.hier_list.HierInit(self)267 return dialog.Dialog.OnInitDialog(self)268 269 def on_size(self, params):270 lparam = params[3]271 w = win32api.LOWORD(lparam)272 h = win32api.HIWORD(lparam)273 self.GetDlgItem(win32ui.IDC_LIST1).MoveWindow((0, 0, w, h))274 275 276def BrowseDialog():277 root = HLIRoot()278 if not root.IsExpandable():279 raise TypeError(280 "Browse() argument must have __dict__ attribute, or be a Browser supported type"281 )282 283 dlg = dynamic_browser(root)284 dlg.CreateWindow()285 286 287def DockableBrowserCreator(parent):288 root = HLIRoot()289 hl = hierlist.HierListWithItems(root, win32ui.IDB_BROWSER_HIER)290 291 style = (292 win32con.WS_CHILD293 | win32con.WS_VISIBLE294 | win32con.WS_BORDER295 | commctrl.TVS_HASLINES296 | commctrl.TVS_LINESATROOT297 | commctrl.TVS_HASBUTTONS298 )299 300 control = win32ui.CreateTreeCtrl()301 control.CreateWindow(style, (0, 0, 150, 300), parent, win32ui.IDC_LIST1)302 list = hl.HierInit(parent, control)303 return control304 305 306def DockablePathBrowser():307 import pywin.docking.DockingBar308 309 bar = pywin.docking.DockingBar.DockingBar()310 bar.CreateWindow(311 win32ui.GetMainFrame(), DockableBrowserCreator, "Path Browser", 0x8E0A312 )313 bar.SetBarStyle(314 bar.GetBarStyle()315 | afxres.CBRS_TOOLTIPS316 | afxres.CBRS_FLYBY317 | afxres.CBRS_SIZE_DYNAMIC318 )319 bar.EnableDocking(afxres.CBRS_ALIGN_ANY)320 win32ui.GetMainFrame().DockControlBar(bar)321 322 323# The "default" entry point324Browse = DockablePathBrowser325 