mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-04 11:00:07 +01:00
362 lines
10 KiB
Python
362 lines
10 KiB
Python
#!/usr/bin/env python
|
|
|
|
import sys
|
|
import os
|
|
import wx
|
|
import time
|
|
import datetime
|
|
import operator
|
|
|
|
from wx.lib.embeddedimage import PyEmbeddedImage
|
|
|
|
import images
|
|
|
|
try:
|
|
dirName = os.path.dirname(os.path.abspath(__file__))
|
|
except:
|
|
dirName = os.path.dirname(os.path.abspath(sys.argv[0]))
|
|
|
|
sys.path.append(os.path.split(dirName)[0])
|
|
|
|
try:
|
|
from agw import ultimatelistctrl as ULC
|
|
except ImportError: # if it's not there locally, try the wxPython lib.
|
|
from wx.lib.agw import ultimatelistctrl as ULC
|
|
|
|
bitmapDir = os.path.join(dirName, 'bitmaps')
|
|
sys.path.append(os.path.split(dirName)[0])
|
|
|
|
convert = str
|
|
|
|
|
|
def FormatFileSize(size):
|
|
|
|
for x in ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB']:
|
|
|
|
if size < 1024.0:
|
|
return "%3.2f %s" % (size, x)
|
|
|
|
size /= 1024.0
|
|
|
|
|
|
class FirstColumnRenderer(object):
|
|
|
|
def __init__(self, parent, fileName):
|
|
|
|
self.parent = parent
|
|
self.fileName = fileName
|
|
|
|
self.normalFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
|
|
self.normalFont.SetPointSize(self.normalFont.GetPointSize() + 1)
|
|
self.smallerFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
|
|
|
|
self.greyColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)
|
|
|
|
if os.path.isdir(fileName):
|
|
self.text = fileName
|
|
bitmap = wx.Bitmap(os.path.join(bitmapDir, "folder.png"), wx.BITMAP_TYPE_PNG)
|
|
self.icon = wx.Icon(bitmap)
|
|
self.description = ""
|
|
return
|
|
|
|
self.text = os.path.split(fileName)[1]
|
|
extension = os.path.splitext(fileName)[1]
|
|
|
|
if not extension:
|
|
self.text = fileName
|
|
bitmap = wx.Bitmap(os.path.join(bitmapDir, "empty_icon.png"), wx.BITMAP_TYPE_PNG)
|
|
self.icon = wx.Icon(bitmap)
|
|
self.description = "File"
|
|
return
|
|
|
|
fileType = wx.TheMimeTypesManager.GetFileTypeFromExtension(extension)
|
|
|
|
bmp = wx.Bitmap(os.path.join(bitmapDir, "empty_icon.png"), wx.BITMAP_TYPE_PNG)
|
|
bmp = wx.Icon(bmp)
|
|
|
|
if not fileType:
|
|
icon = wx.Icon(wx.IconLocation(fileName))
|
|
if not icon.IsOk():
|
|
self.icon = bmp
|
|
else:
|
|
self.icon = icon
|
|
|
|
self.description = "%s File"%extension[1:].upper()
|
|
return
|
|
|
|
#------- Icon info
|
|
info = fileType.GetIconInfo()
|
|
icon = None
|
|
|
|
if info is not None:
|
|
icon, file, idx = info
|
|
if icon.IsOk():
|
|
bmp = icon
|
|
else:
|
|
icon = None
|
|
|
|
if icon is None:
|
|
icon = wx.Icon(wx.IconLocation(fileName))
|
|
if icon.IsOk():
|
|
bmp = icon
|
|
else:
|
|
command = fileType.GetOpenCommand(fileName)
|
|
command = " ".join(command.split()[0:-1])
|
|
command = command.replace('"', "")
|
|
if " -" in command:
|
|
command = command[0:command.index(" -")]
|
|
|
|
icon = wx.Icon(wx.IconLocation(command))
|
|
if icon.IsOk():
|
|
bmp = icon
|
|
|
|
self.icon = bmp
|
|
self.description = convert(fileType.GetDescription())
|
|
|
|
if not self.description:
|
|
self.description = "%s File"%extension[1:].upper()
|
|
|
|
|
|
def DrawSubItem(self, dc, rect, line, highlighted, enabled):
|
|
"""Draw a custom progress bar using double buffering to prevent flicker"""
|
|
|
|
bmpWidth, bmpHeight = self.icon.GetWidth(), self.icon.GetHeight()
|
|
dc.DrawIcon(self.icon, rect.x+5, rect.y+(rect.height-bmpHeight)//2)
|
|
|
|
dc.SetFont(self.normalFont)
|
|
|
|
textWidth, textHeight = dc.GetTextExtent(self.text)
|
|
dc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNTEXT))
|
|
dc.DrawText(self.text, rect.x+bmpWidth+10, rect.y+(rect.height - textHeight)//4)
|
|
|
|
if not self.description:
|
|
return
|
|
|
|
dc.SetFont(self.smallerFont)
|
|
|
|
dummy1, dummy2= dc.GetTextExtent("Type: ")
|
|
textWidth, textHeight = dc.GetTextExtent("Type: " + self.description)
|
|
|
|
dc.SetTextForeground(self.greyColour)
|
|
dc.DrawText("Type: ", rect.x+bmpWidth+10, rect.y+3*(rect.height - textHeight)//4)
|
|
|
|
dc.SetTextForeground(wx.BLACK)
|
|
dc.DrawText(self.description, rect.x+bmpWidth+dummy1+10, rect.y+3*(rect.height - textHeight)//4)
|
|
|
|
|
|
def GetLineHeight(self):
|
|
|
|
dc = wx.MemoryDC()
|
|
dc.SelectObject(wx.Bitmap(100, 20))
|
|
|
|
bmpWidth, bmpHeight = self.icon.GetWidth(), self.icon.GetHeight()
|
|
dc.SetFont(self.normalFont)
|
|
|
|
textWidth, textHeight = dc.GetTextExtent(self.text)
|
|
|
|
dc.SetFont(self.smallerFont)
|
|
dummy1, dummy2= dc.GetTextExtent("Type: ")
|
|
textWidth, textHeight = dc.GetTextExtent("Type: " + self.description)
|
|
|
|
dc.SelectObject(wx.NullBitmap)
|
|
|
|
return max(2*textHeight, bmpHeight) + 20
|
|
|
|
|
|
def GetSubItemWidth(self):
|
|
|
|
return 250
|
|
|
|
|
|
class SecondColumnRenderer(object):
|
|
|
|
def __init__(self, parent, fileName):
|
|
|
|
self.parent = parent
|
|
self.fileName = fileName
|
|
|
|
self.smallerFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
|
|
|
|
self.greyColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)
|
|
|
|
t = os.path.getmtime(fileName)
|
|
date = datetime.datetime.fromtimestamp(t)
|
|
self.date = date.strftime("%d/%m/%Y %H:%M")
|
|
|
|
if os.path.isdir(fileName):
|
|
self.size = ""
|
|
return
|
|
|
|
s = os.path.getsize(fileName)
|
|
self.size = FormatFileSize(s)
|
|
|
|
|
|
def DrawSubItem(self, dc, rect, line, highlighted, enabled):
|
|
"""Draw a custom progress bar using double buffering to prevent flicker"""
|
|
|
|
dc.SetFont(self.smallerFont)
|
|
|
|
date = self.date
|
|
dummy1, dummy2= dc.GetTextExtent("Date modified: ")
|
|
textWidth, textHeight = dc.GetTextExtent("Date modified: " + date)
|
|
|
|
dc.SetTextForeground(self.greyColour)
|
|
dc.DrawText("Date modified: ", rect.x+5, rect.y+(rect.height - textHeight)//4)
|
|
|
|
dc.SetTextForeground(wx.BLACK)
|
|
dc.DrawText(date, rect.x+dummy1+5, rect.y+(rect.height - textHeight)//4)
|
|
|
|
if not self.size:
|
|
return
|
|
|
|
dummy1, dummy2= dc.GetTextExtent("Size: ")
|
|
|
|
dc.SetTextForeground(self.greyColour)
|
|
dc.DrawText("Size: ", rect.x+5, rect.y+3*(rect.height - textHeight)//4)
|
|
|
|
dc.SetTextForeground(wx.BLACK)
|
|
dc.DrawText(self.size, rect.x+dummy1+5, rect.y+3*(rect.height - textHeight)//4)
|
|
|
|
|
|
def GetLineHeight(self):
|
|
|
|
dc = wx.MemoryDC()
|
|
dc.SelectObject(wx.Bitmap(100, 20))
|
|
textWidth, textHeight, d1, d2 = dc.GetFullTextExtent("Date modified: %s"%self.date,
|
|
self.smallerFont)
|
|
|
|
dc.SelectObject(wx.NullBitmap)
|
|
return 2*textHeight + 20
|
|
|
|
|
|
def GetSubItemWidth(self):
|
|
|
|
dc = wx.MemoryDC()
|
|
dc.SelectObject(wx.Bitmap(100, 20))
|
|
|
|
textWidth, textHeight, d1, d2 = dc.GetFullTextExtent("Date modified: %s"%self.date,
|
|
self.smallerFont)
|
|
|
|
dc.SelectObject(wx.NullBitmap)
|
|
|
|
return textWidth+10
|
|
|
|
|
|
class Windows7Explorer(ULC.UltimateListCtrl):
|
|
|
|
def __init__(self, parent, log):
|
|
|
|
ULC.UltimateListCtrl.__init__(self, parent, -1, style=wx.BORDER_THEME,
|
|
agwStyle=wx.LC_REPORT|wx.LC_NO_HEADER|wx.LC_HRULES|
|
|
ULC.ULC_HAS_VARIABLE_ROW_HEIGHT)
|
|
|
|
self.EnableSelectionVista()
|
|
self.PopulateList()
|
|
|
|
|
|
def PopulateList(self, path=""):
|
|
|
|
self.ClearAll()
|
|
|
|
self.InsertColumn(0, "Column 1")
|
|
self.InsertColumn(1, "Column 2")
|
|
|
|
if not path.strip():
|
|
path = os.getcwd()
|
|
|
|
os.chdir(path)
|
|
files1 = os.listdir(path)
|
|
files1.sort()
|
|
|
|
files = []
|
|
for file in files1:
|
|
kind = not os.path.isdir(file)
|
|
name = os.path.split(file)[1]
|
|
files.append((kind, name, name.lower()))
|
|
|
|
files = sorted(files, key=operator.itemgetter(0, 2))
|
|
dummy_log = wx.LogNull()
|
|
|
|
for kind, file, lower in files:
|
|
index = self.InsertStringItem(sys.maxsize, "")
|
|
|
|
klass = FirstColumnRenderer(self, file)
|
|
self.SetItemCustomRenderer(index, 0, klass)
|
|
|
|
self.SetStringItem(index, 1, "")
|
|
klass = SecondColumnRenderer(self, file)
|
|
self.SetItemCustomRenderer(index, 1, klass)
|
|
|
|
self.SetColumnWidth(0, ULC.ULC_AUTOSIZE_FILL)
|
|
self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
class TestFrame(wx.Frame):
|
|
|
|
def __init__(self, parent, log):
|
|
|
|
wx.Frame.__init__(self, parent, -1, "UltimateListCtrl - Windows 7 Explorer", size=(800, 600))
|
|
|
|
self.log = log
|
|
|
|
panel = wx.Panel(self)
|
|
panelSizer = wx.BoxSizer(wx.VERTICAL)
|
|
|
|
font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
|
|
font.SetWeight(wx.FONTWEIGHT_BOLD)
|
|
|
|
static = wx.StaticText(panel, -1, "Choose a folder to display:")
|
|
static.SetFont(font)
|
|
panelSizer.Add(static, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 10)
|
|
|
|
dp1 = wx.DirPickerCtrl(panel, path=os.getcwd(), style=wx.DIRP_USE_TEXTCTRL)
|
|
dp1.SetTextCtrlProportion(2)
|
|
panelSizer.Add(dp1, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 10)
|
|
|
|
# Create the CustomTreeCtrl, using a derived class defined below
|
|
self.ulc = Windows7Explorer(panel, self.log)
|
|
|
|
panelSizer.Add(self.ulc, 1, wx.EXPAND|wx.ALL, 10)
|
|
panel.SetSizer(panelSizer)
|
|
|
|
self.Bind(wx.EVT_DIRPICKER_CHANGED, self.OnPickDir, dp1)
|
|
|
|
self.ulc.SetFocus()
|
|
self.SetIcon(images.Mondrian.GetIcon())
|
|
self.CenterOnScreen()
|
|
self.Show()
|
|
|
|
|
|
def OnPickDir(self, event):
|
|
|
|
wx.BeginBusyCursor()
|
|
self.Freeze()
|
|
path = event.GetPath()
|
|
|
|
try:
|
|
self.ulc.PopulateList(path)
|
|
except OSError:
|
|
self.log.write("You dont have permission to access folder: %s"%path)
|
|
wx.EndBusyCursor()
|
|
self.Thaw()
|
|
return
|
|
|
|
self.Layout()
|
|
self.SendSizeEvent()
|
|
self.Thaw()
|
|
|
|
self.ulc.DoLayout()
|
|
wx.EndBusyCursor()
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
app = wx.App(0)
|
|
frame = TestFrame(None, sys.stdout)
|
|
frame.Show(True)
|
|
app.MainLoop()
|