123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- import glob
- import os
- import pyclbr
-
- import afxres
- import commctrl
- import pywin.framework.scriptutils
- import regutil
- import win32api
- import win32con
- import win32ui
- from pywin.mfc import dialog
-
- from . import hierlist
-
-
- class HLIErrorItem(hierlist.HierListItem):
- def __init__(self, text):
- self.text = text
- hierlist.HierListItem.__init__(self)
-
- def GetText(self):
- return self.text
-
-
- class HLICLBRItem(hierlist.HierListItem):
- def __init__(self, name, file, lineno, suffix=""):
- # If the 'name' object itself has a .name, use it. Not sure
- # how this happens, but seems pyclbr related.
- # See PyWin32 bug 817035
- self.name = getattr(name, "name", name)
- self.file = file
- self.lineno = lineno
- self.suffix = suffix
-
- def __lt__(self, other):
- return self.name < other.name
-
- def __eq__(self, other):
- return self.name == other.name
-
- def GetText(self):
- return self.name + self.suffix
-
- def TakeDefaultAction(self):
- if self.file:
- pywin.framework.scriptutils.JumpToDocument(
- self.file, self.lineno, bScrollToTop=1
- )
- else:
- win32ui.SetStatusText("The source of this object is unknown")
-
- def PerformItemSelected(self):
- if self.file is None:
- msg = "%s - source can not be located." % (self.name,)
- else:
- msg = "%s defined at line %d of %s" % (self.name, self.lineno, self.file)
- win32ui.SetStatusText(msg)
-
-
- class HLICLBRClass(HLICLBRItem):
- def __init__(self, clbrclass, suffix=""):
- try:
- name = clbrclass.name
- file = clbrclass.file
- lineno = clbrclass.lineno
- self.super = clbrclass.super
- self.methods = clbrclass.methods
- except AttributeError:
- name = clbrclass
- file = lineno = None
- self.super = []
- self.methods = {}
- HLICLBRItem.__init__(self, name, file, lineno, suffix)
-
- def GetSubList(self):
- ret = []
- for c in self.super:
- ret.append(HLICLBRClass(c, " (Parent class)"))
- for meth, lineno in self.methods.items():
- ret.append(HLICLBRMethod(meth, self.file, lineno, " (method)"))
- return ret
-
- def IsExpandable(self):
- return len(self.methods) + len(self.super)
-
- def GetBitmapColumn(self):
- return 21
-
-
- class HLICLBRFunction(HLICLBRClass):
- def GetBitmapColumn(self):
- return 22
-
-
- class HLICLBRMethod(HLICLBRItem):
- def GetBitmapColumn(self):
- return 22
-
-
- class HLIModuleItem(hierlist.HierListItem):
- def __init__(self, path):
- hierlist.HierListItem.__init__(self)
- self.path = path
-
- def GetText(self):
- return os.path.split(self.path)[1] + " (module)"
-
- def IsExpandable(self):
- return 1
-
- def TakeDefaultAction(self):
- win32ui.GetApp().OpenDocumentFile(self.path)
-
- def GetBitmapColumn(self):
- col = 4 # Default
- try:
- if win32api.GetFileAttributes(self.path) & win32con.FILE_ATTRIBUTE_READONLY:
- col = 5
- except win32api.error:
- pass
- return col
-
- def GetSubList(self):
- mod, path = pywin.framework.scriptutils.GetPackageModuleName(self.path)
- win32ui.SetStatusText("Building class list - please wait...", 1)
- win32ui.DoWaitCursor(1)
- try:
- try:
- reader = pyclbr.readmodule_ex # Post 1.5.2 interface.
- extra_msg = " or functions"
- except AttributeError:
- reader = pyclbr.readmodule
- extra_msg = ""
- data = reader(mod, [path])
- if data:
- ret = []
- for item in data.values():
- if (
- item.__class__ != pyclbr.Class
- ): # ie, it is a pyclbr Function instance (only introduced post 1.5.2)
- ret.append(HLICLBRFunction(item, " (function)"))
- else:
- ret.append(HLICLBRClass(item, " (class)"))
- ret.sort()
- return ret
- else:
- return [HLIErrorItem("No Python classes%s in module." % (extra_msg,))]
- finally:
- win32ui.DoWaitCursor(0)
- win32ui.SetStatusText(win32ui.LoadString(afxres.AFX_IDS_IDLEMESSAGE))
-
-
- def MakePathSubList(path):
- ret = []
- for filename in glob.glob(os.path.join(path, "*")):
- if os.path.isdir(filename) and os.path.isfile(
- os.path.join(filename, "__init__.py")
- ):
- ret.append(HLIDirectoryItem(filename, os.path.split(filename)[1]))
- else:
- if os.path.splitext(filename)[1].lower() in [".py", ".pyw"]:
- ret.append(HLIModuleItem(filename))
- return ret
-
-
- class HLIDirectoryItem(hierlist.HierListItem):
- def __init__(self, path, displayName=None, bSubDirs=0):
- hierlist.HierListItem.__init__(self)
- self.path = path
- self.bSubDirs = bSubDirs
- if displayName:
- self.displayName = displayName
- else:
- self.displayName = path
-
- def IsExpandable(self):
- return 1
-
- def GetText(self):
- return self.displayName
-
- def GetSubList(self):
- ret = MakePathSubList(self.path)
- if (
- os.path.split(self.path)[1] == "win32com"
- ): # Complete and utter hack for win32com.
- try:
- path = win32api.GetFullPathName(
- os.path.join(self.path, "..\\win32comext")
- )
- ret = ret + MakePathSubList(path)
- except win32ui.error:
- pass
- return ret
-
-
- class HLIProjectRoot(hierlist.HierListItem):
- def __init__(self, projectName, displayName=None):
- hierlist.HierListItem.__init__(self)
- self.projectName = projectName
- self.displayName = displayName or projectName
-
- def GetText(self):
- return self.displayName
-
- def IsExpandable(self):
- return 1
-
- def GetSubList(self):
- paths = regutil.GetRegisteredNamedPath(self.projectName)
- pathList = paths.split(";")
- if len(pathList) == 1: # Single dir - dont bother putting the dir in
- ret = MakePathSubList(pathList[0])
- else:
- ret = list(map(HLIDirectoryItem, pathList))
- return ret
-
-
- class HLIRoot(hierlist.HierListItem):
- def __init__(self):
- hierlist.HierListItem.__init__(self)
-
- def IsExpandable(self):
- return 1
-
- def GetSubList(self):
- keyStr = regutil.BuildDefaultPythonKey() + "\\PythonPath"
- hKey = win32api.RegOpenKey(regutil.GetRootKey(), keyStr)
- try:
- ret = []
- ret.append(HLIProjectRoot("", "Standard Python Library")) # The core path.
- index = 0
- while 1:
- try:
- ret.append(HLIProjectRoot(win32api.RegEnumKey(hKey, index)))
- index = index + 1
- except win32api.error:
- break
- return ret
- finally:
- win32api.RegCloseKey(hKey)
-
-
- class dynamic_browser(dialog.Dialog):
- style = win32con.WS_OVERLAPPEDWINDOW | win32con.WS_VISIBLE
- cs = (
- win32con.WS_CHILD
- | win32con.WS_VISIBLE
- | commctrl.TVS_HASLINES
- | commctrl.TVS_LINESATROOT
- | commctrl.TVS_HASBUTTONS
- )
-
- dt = [
- ["Python Projects", (0, 0, 200, 200), style, None, (8, "MS Sans Serif")],
- ["SysTreeView32", None, win32ui.IDC_LIST1, (0, 0, 200, 200), cs],
- ]
-
- def __init__(self, hli_root):
- dialog.Dialog.__init__(self, self.dt)
- self.hier_list = hierlist.HierListWithItems(hli_root, win32ui.IDB_BROWSER_HIER)
- self.HookMessage(self.on_size, win32con.WM_SIZE)
-
- def OnInitDialog(self):
- self.hier_list.HierInit(self)
- return dialog.Dialog.OnInitDialog(self)
-
- def on_size(self, params):
- lparam = params[3]
- w = win32api.LOWORD(lparam)
- h = win32api.HIWORD(lparam)
- self.GetDlgItem(win32ui.IDC_LIST1).MoveWindow((0, 0, w, h))
-
-
- def BrowseDialog():
- root = HLIRoot()
- if not root.IsExpandable():
- raise TypeError(
- "Browse() argument must have __dict__ attribute, or be a Browser supported type"
- )
-
- dlg = dynamic_browser(root)
- dlg.CreateWindow()
-
-
- def DockableBrowserCreator(parent):
- root = HLIRoot()
- hl = hierlist.HierListWithItems(root, win32ui.IDB_BROWSER_HIER)
-
- style = (
- win32con.WS_CHILD
- | win32con.WS_VISIBLE
- | win32con.WS_BORDER
- | commctrl.TVS_HASLINES
- | commctrl.TVS_LINESATROOT
- | commctrl.TVS_HASBUTTONS
- )
-
- control = win32ui.CreateTreeCtrl()
- control.CreateWindow(style, (0, 0, 150, 300), parent, win32ui.IDC_LIST1)
- list = hl.HierInit(parent, control)
- return control
-
-
- def DockablePathBrowser():
- import pywin.docking.DockingBar
-
- bar = pywin.docking.DockingBar.DockingBar()
- bar.CreateWindow(
- win32ui.GetMainFrame(), DockableBrowserCreator, "Path Browser", 0x8E0A
- )
- bar.SetBarStyle(
- bar.GetBarStyle()
- | afxres.CBRS_TOOLTIPS
- | afxres.CBRS_FLYBY
- | afxres.CBRS_SIZE_DYNAMIC
- )
- bar.EnableDocking(afxres.CBRS_ALIGN_ANY)
- win32ui.GetMainFrame().DockControlBar(bar)
-
-
- # The "default" entry point
- Browse = DockablePathBrowser
|