spacepaste

  1.  
  2. import os
  3. import wx
  4. import wx.lib.customtreectrl as customtree
  5. try:
  6. from agw import customtreectrl as CT
  7. except ImportError: # if it's not there locally, try the wxPython lib.
  8. import wx.lib.agw.customtreectrl as CT
  9. #---- Recipe Code ----#
  10. class FileBrowser(customtree.CustomTreeCtrl):
  11. FOLDER, \
  12. ERROR, \
  13. FILE = range(3)
  14. def __init__(self, parent, rootdir, *args, **kwargs):
  15. super(FileBrowser, self).__init__(parent,
  16. *args,
  17. **kwargs)
  18. assert os.path.exists(rootdir),\
  19. "Invalid Root Directory!"
  20. assert os.path.isdir(rootdir),\
  21. "rootdir must be a Directory!"
  22. # Attributes
  23. self._il = wx.ImageList(16, 16)
  24. self._root = rootdir
  25. self._rnode = None
  26. rootdir = '../work'
  27. # Setup
  28. for art in (wx.ART_FOLDER, wx.ART_ERROR,
  29. wx.ART_NORMAL_FILE):
  30. bmp = wx.ArtProvider.GetBitmap(art, size=(16,16))
  31. self._il.Add(bmp)
  32. self.SetImageList(self._il)
  33. self._rnode = self.AddRoot(os.path.basename(rootdir),
  34. image=FileBrowser.FOLDER,
  35. data=self._root)
  36. self.SetItemHasChildren(self._rnode, True)
  37. # Use Windows Vista style selections
  38. # self.EnableSelectionVista(True)
  39. # Event Handlers
  40. self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnExpanding)
  41. self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnCollapsed)
  42. def _GetFiles(self, path):
  43. try:
  44. files = [fname for fname in os.listdir(path)
  45. if fname not in ('.', '..')]
  46. except OSError:
  47. files = None
  48. return files
  49. def OnCollapsed(self, event):
  50. item = event.GetItem()
  51. self.DeleteChildren(item)
  52. def OnCompareItems(self, item1, item2):
  53. pydata1 = self.GetPyData(item1)
  54. pydata2 = self.GetPyData(item2)
  55. if os.path.isdir(pydata1) and os.path.isdir(pydata2):
  56. return cmp(pydata1, pydata2)
  57. elif os.path.isdir(pydata1) and os.path.isfile(pydata2):
  58. return -1
  59. elif os.path.isfile(pydata1) and os.path.isdir(pydata2):
  60. return 1
  61. return cmp(pydata1, pydata2)
  62. def OnExpanding(self, event):
  63. item = event.GetItem()
  64. path = self.GetPyData(item)
  65. files = self._GetFiles(path)
  66. if files is None:
  67. self.SetItemImage(item, FileBrowser.ERROR)
  68. self.SetItemHasChildren(item, False)
  69. return
  70. for fname in files:
  71. fullpath = os.path.join(path, fname)
  72. if os.path.isdir(fullpath):
  73. self.AppendDir(item, fullpath)
  74. else:
  75. self.AppendFile(item, fullpath)
  76. self.SortChildren(item)
  77. # pt = self.GetPosition();
  78. # item, flags = self.HitTest(pt)
  79. # if item:
  80. # parent = self.GetItemParent(item)
  81. # if parent.IsOk():
  82. # self.SortChildren(parent)
  83. def AppendDir(self, item, path):
  84. """Add a directory node"""
  85. assert os.path.isdir(path), "Not a valid directory!"
  86. name = os.path.basename(path)
  87. nitem = self.AppendItem(item, name,
  88. image=FileBrowser.FOLDER,
  89. data=path)
  90. self.SetItemHasChildren(nitem, True)
  91. def AppendFile(self, item, path):
  92. """Add a file to a node"""
  93. assert os.path.isfile(path), "Not a valid file!"
  94. name = os.path.basename(path)
  95. self.AppendItem(item, name,
  96. image=FileBrowser.FILE,
  97. data=path)
  98. def GetSelectedPath(self):
  99. """Get the selected path"""
  100. sel = self.GetSelection()
  101. path = self.GetItemPyData(sel)
  102. return path
  103. def GetSelectedPaths(self):
  104. """Get a list of selected paths"""
  105. sels = self.GetSelections()
  106. paths = [self.GetItemPyData(sel)
  107. for sel in sels ]
  108. return paths
  109. #---- End Recipe Code ----#
  110. #---- Sample Application ----#
  111. class MyApp(wx.App):
  112. def OnInit(self):
  113. self.frame = MyFrame(None, title="CustomTreeCtrl", size=(300,400))
  114. self.SetTopWindow(self.frame)
  115. self.frame.Show()
  116. return True
  117. class MyFrame(wx.Frame):
  118. def __init__(self, parent, *args, **kwargs):
  119. super(MyFrame, self).__init__(parent, *args, **kwargs)
  120. # Attributes
  121. self.panel = MyPanel(self)
  122. # Layout
  123. sizer = wx.BoxSizer(wx.VERTICAL)
  124. sizer.Add(self.panel, 1, wx.EXPAND)
  125. self.SetSizer(sizer)
  126. self.CreateStatusBar()
  127. class MyPanel(wx.Panel):
  128. def __init__(self, parent):
  129. super(MyPanel, self).__init__(parent)
  130. # Attributes
  131. self.browser = FileBrowser(self, wx.GetHomeDir())
  132. # Setup
  133. # Layout
  134. sizer = wx.BoxSizer(wx.VERTICAL)
  135. sizer.Add(self.browser, 1, wx.EXPAND)
  136. self.SetSizer(sizer)
  137. # Event Handlers
  138. self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
  139. def OnItemActivated(self, event):
  140. path = self.browser.GetSelectedPath()
  141. self.GetTopLevelParent().PushStatusText(path)
  142. if __name__ == "__main__":
  143. app = MyApp(False)
  144. app.MainLoop()
  145.