#	Programmer:	Daniel Pozmanter
#	E-mail:		drpython@bluebottle.com
#	Note:		You must reply to the verification e-mail to get through.
#
#	Copyright 2003-2005 Daniel Pozmanter
#
#	Distributed under the terms of the GPL (GNU Public License)
#
#	DrPython is free software; you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation; either version 2 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with this program; if not, write to the Free Software
#	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
	
#File Dialog

import os, os.path, re, stat, time, sys, locale
import wx
import drScrolledMessageDialog
import lnkDecoderRing
import drEncoding

class FileListCtrl(wx.ListView):
	def __init__(self, parent, id, fsize, fstyle):
		wx.ListView.__init__(self, parent, id, size=fsize, style=fstyle)
		
		bDir = parent.parent.bitmapdirectory + '/16/'
			
		self.parent = parent
		
		self.grandparent = parent.parent	
		
		self.IsDetailed = False
		
		self.pywfilter = re.compile('.*\.pyw$')
		self.pyfilter = re.compile('.*\.py$')
				
		self.imagelist = wx.ImageList(16, 16)
		self.images = [wx.BitmapFromImage(wx.Image(bDir+'folder.png', wx.BITMAP_TYPE_PNG)), \
		wx.BitmapFromImage(wx.Image(bDir+'py.png', wx.BITMAP_TYPE_PNG)), \
		wx.BitmapFromImage(wx.Image(bDir+'pyw.png', wx.BITMAP_TYPE_PNG)), \
		wx.BitmapFromImage(wx.Image(bDir+'unknown.png', wx.BITMAP_TYPE_PNG)), \
		wx.BitmapFromImage(wx.Image(bDir+'up.png', wx.BITMAP_TYPE_PNG)), \
		wx.BitmapFromImage(wx.Image(bDir+'down.png', wx.BITMAP_TYPE_PNG))]
		
		self.isWindows = sys.platform == "win32"
		
		map(self.imagelist.Add, self.images)
		
		self.AssignImageList(self.imagelist, wx.IMAGE_LIST_SMALL)
		
		self.directories = ['']
		self.dirposition = -1
		
		self.ShowHiddenFiles = False
		
		self.DataArray = []
		self.currentcolumn = 0
		self.direction = [0, -1, -1, -1, -1]
		
		self.timeformat = '%m/%d/%Y %H:%M:%S'
				
		self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColumnClick)
		self.Bind(wx.EVT_SIZE, self.OnSize)

	def GetDirectory(self):
		try:
			return self.directories[self.dirposition]
		except:
			return self.directories[0]

	def GoBack(self, filter):
		self.dirposition = self.dirposition - 1		
		if self.dirposition < 0:			
			self.dirposition = 0
		self.SetDirectoryTo(self.directories[self.dirposition], filter, False)

	def GoForward(self, filter):
		self.dirposition = self.dirposition + 1		
		if self.dirposition >= len(self.directories):
			self.dirposition = len(self.directories) - 1
		self.SetDirectoryTo(self.directories[self.dirposition], filter, False) 

	def IsDirectory(self, index):
		return self.DataArray[index][2] == '<Dir>'
	
	def OnColumnClick(self, event):
		oldcol = self.currentcolumn
		self.currentcolumn = event.GetColumn()
		self.ClearColumnImage(oldcol)
		if oldcol != self.currentcolumn:
			self.direction[oldcol] = -1
		if self.direction[self.currentcolumn] == -1:
			self.direction[self.currentcolumn] = 1
			self.SetColumnImage(self.currentcolumn, 5)
		else:
			self.direction[self.currentcolumn] = not self.direction[self.currentcolumn]
			if self.direction[self.currentcolumn]:
				self.SetColumnImage(self.currentcolumn, 5)
			else:
				self.SetColumnImage(self.currentcolumn, 4)
		self.SortItems(self.SortData)	
	
	def OnSize(self, event):
		if self.IsDetailed:
			width = self.GetSizeTuple()[0]
			self.SetColumnWidth(0, int(width * .4))
			self.SetColumnWidth(1, int(width * .15))
			self.SetColumnWidth(2, int(width * .15))
			self.SetColumnWidth(3, int(width * .15))
			self.SetColumnWidth(4, int(width * .15))
		if event is not None:
			event.Skip()
					
	def SetDirectoryTo(self, directory, filter="*", updatedirectories=True):
		self.parent.cboFile.SetValue('')
		self.parent.cboFile.Clear()
		directory = os.path.normpath(directory).replace('\\', '/').replace('//', '/')
		if not os.path.exists(directory):
			return
		self.parent.txtDirectory.SetValue(directory)
				
		try:
			if wx.USE_UNICODE:	
				uthelist = os.listdir(directory)
				thelist = []
				if (len(self.grandparent.prefs.defaultencoding) > 0) and self.grandparent.PLATFORM_IS_WIN:
					for u in uthelist:
						try:
							thelist.append(unicode(u, self.grandparent.prefs.defaultencoding))
						except:
							print 'Error Decoding Directory Entry with default encoding:', self.grandparent.prefs.defaultencoding
				else:
					for u in uthelist:
						if not drEncoding.CheckAscii(u):
							print 'Error Decoding Directory Entry:  Not Ascii.'
						else:				
							thelist.append(u)
			else:
				thelist = os.listdir(directory)
		
			if updatedirectories:
				self.directories = self.directories[:self.dirposition+1]
				self.directories.append(directory)
				self.dirposition = self.dirposition + 1
			dirs = []
			l = len(thelist)
			x = 0
			while x < l:
				if os.path.isdir(directory + '/' + thelist[x]):			
					dirs.append(thelist.pop(x))
					x = x - 1
					l = l - 1
				x = x + 1

			self.DeleteAllItems()
			thelist.sort()
			dirs.sort()
			
			filter = filter + ";" + self.parent.parent.prefs.constantwildcard
			
			filter = filter.replace('.', '\.').replace('*', '.*').replace(';', '$|') + '$'
			refilter = re.compile(filter)
	
			dirs.insert(0, '..')
					
			for item in dirs:
				additem = True
				if not self.ShowHiddenFiles:
					if item[0] == '.':
						if item != '..':
							additem = False
				if additem:
					i = self.GetItemCount()
					self.InsertStringItem(i, item)
					self.SetItemImage(i, 0, 0)
					if self.IsDetailed:
						self.SetItemData(i, i)
						st = os.stat(directory + '/' + item)
						
						mtime = time.strftime(self.timeformat ,time.localtime(st.st_mtime))
						mmode = str(oct(stat.S_IMODE(st.st_mode)))
						
						self.DataArray.append((item, '', '<Dir>', mtime, mmode))
						
						self.SetStringItem(i, 1, '')
						self.SetStringItem(i, 2, '<Dir>')
						self.SetStringItem(i, 3, mtime)
						self.SetStringItem(i, 4, mmode)
			for item in thelist:
				additem = True
				if not self.ShowHiddenFiles:
					if item[0] == '.':
						additem = False
				if additem:
					if refilter.match(item):
						self.parent.cboFile.Append(item)
						i = self.GetItemCount()
						self.InsertStringItem(i, item)
						if self.pywfilter.match(item):
							self.SetItemImage(i, 2, 2)
						elif self.pyfilter.match(item):
							self.SetItemImage(i, 1, 1)
						else:
							self.SetItemImage(i, 3, 3)
						if self.IsDetailed:
							self.SetItemData(i, i)
							st = os.stat(directory + '/' + item)	
							size = str(st.st_size)				
							mtime = time.strftime(self.timeformat ,time.localtime(st.st_mtime))
							mmode = str(oct(stat.S_IMODE(st.st_mode)))
							type = item.rfind('.')
							if type > -1:
								type = item[type+1:]
							else:
								type = ''
								
							self.DataArray.append((item, size, type, mtime, mmode))	
							
							self.SetStringItem(i, 1, str(size))
							self.SetStringItem(i, 2, type)
							self.SetStringItem(i, 3, mtime)
							self.SetStringItem(i, 4, mmode)
		except:
			self.grandparent.ShowMessage('Error Setting Directory To:' + directory, 'File Dialog Error')

	def SetShowHiddenFiles(self, showhidden):
		self.ShowHiddenFiles = showhidden

	def SetViewDetailed(self, fstyle = 0):
		self.DeleteAllItems()
		self.SetWindowStyleFlag(fstyle|wx.LC_REPORT)
		self.IsDetailed = True
		self.InsertColumn(0, 'Name')
		self.InsertColumn(1, 'Size')
		self.InsertColumn(2, 'Type')
		self.InsertColumn(3, 'Modified')
		self.InsertColumn(4, 'Permissions')
		
		self.SetColumnImage(0, 5)
		
		self.OnSize(None)		
		
	def SetViewList(self, fstyle = 0):
		self.DeleteAllItems()
		self.SetWindowStyleFlag(fstyle|wx.LC_LIST)
		self.IsDetailed = False

	def SortData(self, item1, item2):
		i1 = self.DataArray[item1][self.currentcolumn]
		i2 = self.DataArray[item2][self.currentcolumn]
		i1isdir = self.IsDirectory(item1)
		i2isdir = self.IsDirectory(item2)
		if i1isdir and not i2isdir:
			if self.direction[self.currentcolumn]:
				return 1
			else:
				return -1
		elif not i1isdir and i2isdir:
			if self.direction[self.currentcolumn]:
				return -1
			else:
				return 1
		elif i1isdir and i2isdir:
			if self.currentcolumn == 1:
				i1 = self.DataArray[item1][0]
				i2 = self.DataArray[item2][0]
			elif self.currentcolumn == 3:
				it1 = time.strptime(i1, self.timeformat)
				it2 = time.strptime(i2, self.timeformat)
				
				i2 = it1[0]
				i1 = it2[0]
				x = 1
				while (i1 == i2) and (x < 6):
					i2 = it1[x]
					i1 = it2[x]
					x = x + 1
			if self.direction[self.currentcolumn]:
				if i1 < i2:
					return 1
				if i1 > i2:
					return -1
			else:
				if i1 < i2:
					return -1
				if i1 > i2:
					return 1
		if self.currentcolumn == 1:
			try:
				i1 = int(i1)
			except:
				i1 = 0
			try:
				i2 = int(i2)
			except:
				i1 = 0
		elif self.currentcolumn == 3:
			it1 = time.strptime(i1, self.timeformat)
			it2 = time.strptime(i2, self.timeformat)
			
			i1 = it1[0]
			i2 = it2[0]
			x = 1
			while (i1 == i2) and (x < 6):
				i1 = it1[x]
				i2 = it2[x]
				x = x + 1
			
		if self.direction[self.currentcolumn]:
			if i1 < i2:
				return -1
			if i1 > i2:
				return 1
		else:
			if i1 < i2:
				return 1
			if i1 > i2:
				return -1			
		return 0

class DirPanel(wx.Dialog):
	def __init__(self, parent, id, pos, size):
		wx.Dialog.__init__(self, parent, id, 'Look In:', pos, size)
		
		self.parent = parent
		
		self.ID_CLOSE = 3031
				
		self.dirControl = wx.GenericDirCtrl(self, -1, size=size, style=wx.DIRCTRL_DIR_ONLY)
		
		self.btnClose = wx.Button(self, self.ID_CLOSE, 'Close')
				
		self.theSizer = wx.BoxSizer(wx.VERTICAL)
		self.theSizer.Add(self.dirControl, 1, wx.EXPAND)
		self.theSizer.Add(self.btnClose, 0, wx.SHAPED | wx.ALIGN_CENTER)
		
		self.SetAutoLayout(True)
		self.SetSizerAndFit(self.theSizer)		
		
		self.Bind(wx.EVT_BUTTON, self.OnClose, id=self.ID_CLOSE)
	
	def GetPath(self):
		return self.dirControl.GetPath()
		
	def OnClose(self, event):
		self.EndModal(0)

class drFileDialog(wx.Dialog):
	def __init__(self, parent, title, wildcard, point=wx.DefaultPosition, size=wx.DefaultSize, IsASaveDialog=0, MultipleSelection=0, ShowRecentFiles=0):
		wx.Dialog.__init__(self, parent, -1, title, point, size, wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)
		
		self.parent = parent					
	
		self.IsASaveDialog = IsASaveDialog
		self.MultipleSelection = MultipleSelection
		if IsASaveDialog:
			self.MultipleSelection = False
		
		#Constants:
		
		self.ID_BOOKMARKS = 3001
		self.ID_DISPLAY_LIST = 3002
		self.ID_DISPLAY_DETAILED = 3003
		self.ID_BACK = 3004
		self.ID_FORWARD = 3005
		self.ID_UP = 3006
		self.ID_HOME = 3011
		self.ID_REFRESH = 3007
		self.ID_NEW_DIRECTORY = 3008
		self.ID_DELETE_FILE = 3009
		
		self.ID_BROWSE = 3010
		
		self.ID_SHOW_HIDDEN_FILES = 3011
		
		self.ID_LIST_FILES =  3015
		
		self.ID_DIR = 3020
		self.ID_FILE = 3030
		self.ID_EXTENSION = 3031
		self.ID_SHOW_READONLY = 3032
		self.ID_ENCODING = 3035
		
		self.ID_OK = 3040
		self.ID_CANCEL = 3041
		
		self.ID_BOOKMARK_MENU = 3100
		
		self.ID_BOOKMARK_ADD = 3101
		self.ID_BOOKMARK_FILE = 3102
		
		self.ID_EDIT_BOOKMARKS = 3103
		
		self.ID_BOOKMARK_BASE = 3150
		
		#/Constants
		
		#Components:

		#ShowRecentFiles is not used anymore.
		self.cboFile = wx.ComboBox(self, self.ID_FILE, size=wx.Size(500, -1))

		self.btnOk = wx.Button(self, self.ID_OK, "  &Ok  ")

		self.cboExtension = wx.ComboBox(self, self.ID_EXTENSION, size=wx.Size(250, -1))
		
		try:
			defaultlocale = locale.getdefaultlocale()[1]
		except:
			defaultlocale = None
		if defaultlocale is not None:
			encodings = ['<Default Encoding>', defaultlocale, 'ascii', 'latin-1', 'utf-8', 'utf-16']
		else:
			encodings = ['<Default Encoding>', 'ascii', 'latin-1', 'utf-8', 'utf-16']
		
		self.cboEncoding = wx.ComboBox(self, self.ID_ENCODING, size=wx.Size(250, -1), choices=encodings)

		if not self.parent.PLATFORM_IS_WIN:
			self.chkShowHiddenFiles = wx.CheckBox(self, self.ID_SHOW_HIDDEN_FILES, '  Show Hidden Files  ')

		self.btnCancel = wx.Button(self, self.ID_CANCEL, "  &Cancel  ")
		
		bDir = self.parent.bitmapdirectory + '/24/'
				
		self.btnDisplayList = wx.BitmapButton(self, self.ID_DISPLAY_LIST, wx.BitmapFromImage(wx.Image(bDir+'list.png', wx.BITMAP_TYPE_PNG)))
		self.btnDisplayDetailed = wx.BitmapButton(self, self.ID_DISPLAY_DETAILED, wx.BitmapFromImage(wx.Image(bDir+'detailed.png', wx.BITMAP_TYPE_PNG)))
		self.btnBack = wx.BitmapButton(self, self.ID_BACK, wx.BitmapFromImage(wx.Image(bDir+'back.png', wx.BITMAP_TYPE_PNG)))
		self.btnForward = wx.BitmapButton(self, self.ID_FORWARD, wx.BitmapFromImage(wx.Image(bDir+'forward.png', wx.BITMAP_TYPE_PNG)))
		self.btnUp = wx.BitmapButton(self, self.ID_UP, wx.BitmapFromImage(wx.Image(bDir+'up.png', wx.BITMAP_TYPE_PNG)))
		self.btnHome = wx.BitmapButton(self, self.ID_HOME, wx.BitmapFromImage(wx.Image(bDir+'home.png', wx.BITMAP_TYPE_PNG)))
		self.btnRefresh = wx.BitmapButton(self, self.ID_REFRESH, wx.BitmapFromImage(wx.Image(bDir+'Reload File.png', wx.BITMAP_TYPE_PNG)))
		self.btnBookmarks = wx.BitmapButton(self, self.ID_BOOKMARKS, wx.BitmapFromImage(wx.Image(bDir+'bookmarks.png', wx.BITMAP_TYPE_PNG)))
		self.btnDir = wx.BitmapButton(self, self.ID_BROWSE, wx.BitmapFromImage(wx.Image(bDir+'folder.png', wx.BITMAP_TYPE_PNG)))
		self.btnNewDirectory = wx.BitmapButton(self, self.ID_NEW_DIRECTORY, wx.BitmapFromImage(wx.Image(bDir+'new directory.png', wx.BITMAP_TYPE_PNG)))
		self.btnDeleteFile = wx.BitmapButton(self, self.ID_DELETE_FILE, wx.BitmapFromImage(wx.Image(bDir+'Delete.png', wx.BITMAP_TYPE_PNG)))
		
		self.btnDisplayList.SetToolTipString('List View')
		self.btnDisplayDetailed.SetToolTipString('Detailed View')
		self.btnBookmarks.SetToolTipString('Bookmarks')
		self.btnBack.SetToolTipString('Back')
		self.btnForward.SetToolTipString('Forward')
		self.btnUp.SetToolTipString('Up')
		self.btnHome.SetToolTipString('Home')
		self.btnRefresh.SetToolTipString('Refresh')
		self.btnDir.SetToolTipString('Look In')
		self.btnNewDirectory.SetToolTipString('New Directory')
		self.btnDeleteFile.SetToolTipString('Delete')
		
		self.txtDirectory = wx.TextCtrl(self, self.ID_DIR, '', size=wx.Size(350, -1), style=wx.TE_PROCESS_ENTER)
		
		if MultipleSelection:
			self.lstFiles = FileListCtrl(self, self.ID_LIST_FILES, wx.Size(500, 230), wx.LC_LIST)
		else:
			self.lstFiles = FileListCtrl(self, self.ID_LIST_FILES, wx.Size(500, 230), wx.LC_LIST | wx.LC_SINGLE_SEL)
		
		
		self.btnOk.SetDefault()
		self.cboFile.SetFocus()
				
		#/Components
		
		#Data
		
		swildcards = wildcard.split('|')
		self.wildcards = []
		x = 0
		l = len(swildcards) - 1
		while x < l:
			self.cboExtension.Append(swildcards[x])
			self.wildcards.append(swildcards[x+1])
			x = x + 2	
		
		self.cboExtension.SetValue(swildcards[0])
		wx.CallAfter (self.cboExtension.SetMark, 0, 0)
		
		if len(self.parent.prefs.defaultencoding) > 0:
			if not self.parent.prefs.defaultencoding in encodings:
				self.cboEncoding.Append(self.parent.prefs.defaultencoding)
			self.cboEncoding.SetSelection(encodings.index(self.parent.prefs.defaultencoding))
		else:
			self.cboEncoding.SetSelection(0)
		
		self.currentextension = 0
				
		self.lstFiles.SetDirectoryTo(self.parent.ddirectory, self.wildcards[self.currentextension])
		
		self.bookmarks = []
		
		#lnk Replace Table:
		if not self.parent.PLATFORM_IS_WIN:
			self.lnkReplaceA = []
			self.lnkReplaceB = []
			replacestrings = self.parent.prefs.windowsshortcutreplacetable.split('#')
			for rstring in replacestrings:
				if len(rstring) > 0:
					a, b = rstring.split(',')
					self.lnkReplaceA.append(a)
					self.lnkReplaceB.append(b)		
		#/Data
		
		#Sizer:
						
		self.theSizer = wx.BoxSizer(wx.VERTICAL)
		
		self.commandSizer = wx.BoxSizer(wx.HORIZONTAL)
		
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		self.commandSizer.Add(self.btnDisplayList, 0, wx.SHAPED)
		self.commandSizer.Add(self.btnDisplayDetailed, 0, wx.SHAPED)
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		self.commandSizer.Add(self.btnBack, 0, wx.SHAPED)
		self.commandSizer.Add(self.btnForward, 0, wx.SHAPED)
		self.commandSizer.Add(self.btnUp, 0, wx.SHAPED)
		self.commandSizer.Add(self.btnHome, 0, wx.SHAPED)
		self.commandSizer.Add(self.btnRefresh, 0, wx.SHAPED)
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		self.commandSizer.Add(self.btnBookmarks, 0, wx.SHAPED)
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)
		self.commandSizer.Add(self.btnDir, 0, wx.SHAPED)		
		
		if not self.parent.PLATFORM_IS_WIN:
			self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED | wx.ALIGN_RIGHT)
			self.commandSizer.Add(self.chkShowHiddenFiles, 1, wx.SHAPED | wx.ALIGN_RIGHT)
		else:
			self.commandSizer.Add(wx.StaticText(self, -1, '   '), 1, wx.EXPAND)
		
		self.commandSizer.Add(self.btnNewDirectory, 0, wx.SHAPED)
		self.commandSizer.Add(self.btnDeleteFile, 0, wx.SHAPED)
		self.commandSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.SHAPED)

		self.dirSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.dirSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.dirSizer.Add(self.txtDirectory, 9, wx.EXPAND)
		self.dirSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		
		self.listSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.listSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.listSizer.Add(self.lstFiles, 9, wx.EXPAND)
		self.listSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		
		self.OkSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.OkSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.OkSizer.Add(self.cboFile, 9, wx.EXPAND | wx.ALIGN_LEFT)
		self.OkSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.OkSizer.Add(self.btnOk, 0, wx.ALIGN_RIGHT)
		self.OkSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
				
		self.CancelSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.CancelSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.CancelSizer.Add(self.cboExtension, 2, wx.EXPAND)
		self.CancelSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.CancelSizer.Add(self.cboEncoding, 2, wx.EXPAND)
		self.CancelSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.CancelSizer.Add(self.btnCancel, 0, wx.ALIGN_RIGHT)
		self.CancelSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
				
		self.theSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.theSizer.Add(self.commandSizer, 0, wx.EXPAND | wx.ALIGN_CENTER)
		self.theSizer.Add(self.dirSizer, 0, wx.EXPAND)
		self.theSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.theSizer.Add(self.listSizer, 9, wx.EXPAND)
		self.theSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.theSizer.Add(self.OkSizer, 0, wx.EXPAND)
		self.theSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
		self.theSizer.Add(self.CancelSizer, 0, wx.EXPAND)
		self.theSizer.Add(wx.StaticText(self, -1, '   '), 0, wx.EXPAND)
				
		self.SetAutoLayout(True)
		self.SetSizerAndFit(self.theSizer)
		
		#/Sizer
		
		#Events:

		self.Bind(wx.EVT_BUTTON, self.OnbtnUp, id=self.ID_UP)
		self.Bind(wx.EVT_BUTTON, self.OnbtnBack, id=self.ID_BACK)
		self.Bind(wx.EVT_BUTTON, self.OnbtnForward, id=self.ID_FORWARD)
		self.Bind(wx.EVT_BUTTON, self.OnbtnHome, id=self.ID_HOME)
		self.Bind(wx.EVT_BUTTON, self.OnbtnRefresh, id=self.ID_REFRESH)
		self.Bind(wx.EVT_BUTTON, self.OnbtnBookmarks, id=self.ID_BOOKMARKS)
		
		self.Bind(wx.EVT_BUTTON, self.OnbtnNewDirectory, id=self.ID_NEW_DIRECTORY)
		self.Bind(wx.EVT_BUTTON, self.OnbtnDelete, id=self.ID_DELETE_FILE)
		
		self.Bind(wx.EVT_BUTTON, self.OnbtnDisplayList, id=self.ID_DISPLAY_LIST)
		self.Bind(wx.EVT_BUTTON, self.OnbtnDisplayDetailed, id=self.ID_DISPLAY_DETAILED)
		
		self.Bind(wx.EVT_BUTTON, self.OnbtnCancel, id=self.ID_CANCEL)
		self.Bind(wx.EVT_BUTTON, self.OnbtnOk, id=self.ID_OK)
		
		self.Bind(wx.EVT_COMBOBOX, self.OnExtension, id=self.ID_EXTENSION)
		
		if not self.parent.PLATFORM_IS_WIN:
			self.Bind(wx.EVT_CHECKBOX, self.OnShowHiddenFiles, id=self.ID_SHOW_HIDDEN_FILES)
		
		self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnFileSelected, id=self.ID_LIST_FILES)
		self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnFileActivated, id=self.ID_LIST_FILES)
		self.Bind(wx.EVT_TEXT_ENTER, self.OnDir, id=self.ID_DIR)
		self.Bind(wx.EVT_TEXT_ENTER, self.OnbtnOk, id=self.ID_FILE)
		self.Bind(wx.EVT_CHAR, self.OnChar)
		self.cboFile.Bind(wx.EVT_CHAR, self.OnChar)
		self.Bind(wx.EVT_BUTTON, self.OnBrowse, id=self.ID_BROWSE)
		
		#/Events
				
		self.parent.LoadDialogSizeAndPosition(self, 'filedialog.sizeandposition.dat')
		
	def OnCloseW(self, event):
		self.parent.SaveDialogSizeAndPosition(self, 'filedialog.sizeandposition.dat')
		if event is not None:
			event.Skip()
	
	def EndAndCheck(self, value):
		if self.IsASaveDialog:
			filename = self.GetPath()
			if os.path.exists(filename):
				msg = 'File "' + filename + '" already exists.  Overwrite?'
				d = wx.MessageDialog(self, msg, "OverWrite File?", wx.YES_NO | wx.ICON_QUESTION)
				answer = d.ShowModal()
				d.Destroy()
				if answer == wx.ID_NO:
					return
		self.OnCloseW(None)
		self.EndModal(value)
	
	def GetEncoding(self):
		return self.cboEncoding.GetValue()
	
	def getNormedPath(self, filename):
		if filename.find(".lnk") > -1:
			filename = self.HandleLnk(filename)
		else:
			filename = filename.replace('\\', '/')
		return filename
	
	def GetPath(self):
		path = self.getNormedPath(self.cboFile.GetValue())
		if self.IsASaveDialog and self.parent.prefs.defaultextension:
			if path.find('.') == -1:
				path += '.py'
		return path
	
	def GetPaths(self):
		i = self.lstFiles.GetFirstSelected()
		if i == -1:
			return [self.getNormedPath(self.cboFile.GetValue())]
		
		if (self.lstFiles.GetItemText(i) != self.cboFile.GetValue()) and (self.lstFiles.GetNextSelected(i) == -1):
			return [self.getNormedPath(self.cboFile.GetValue())]
				
		dir = self.lstFiles.GetDirectory()
		filelist = [self.getNormedPath(os.path.join(dir, self.lstFiles.GetItemText(i)).replace('\\', '/'))]
		
		y = i
		y = self.lstFiles.GetNextSelected(y)
		while y != -1:
			filelist.append(self.getNormedPath(os.path.join(dir, self.lstFiles.GetItemText(y)).replace('\\', '/')))
			y = self.lstFiles.GetNextSelected(y)
		currentfile = self.getNormedPath(self.cboFile.GetValue().replace('\\', '/'))
		if not (currentfile in filelist):
			filelist.insert(0, currentfile)
		return filelist
	
	def HandleLnk(self, filename):
		filename = lnkDecoderRing.ReadLink(filename)
		if self.parent.PLATFORM_IS_WIN:
			return filename
		else:
			x = 0
			for rA in self.lnkReplaceA:
				result = re.match(rA + '\:', filename)
				resultA = re.match(rA, filename)
				if result is not None:
					if self.lnkReplaceB[x].find('@') > 0:
						return filename.replace(result.group(), self.lnkReplaceB[x].replace('@', resultA.group().lower()))
					elif self.lnkReplaceB[x].find('@') > 0:
						return filename.replace(result.group(), self.lnkReplaceB[x].replace('@', resultA.group()))					
					else:
						return filename.replace(result.group(), self.lnkReplaceB[x])
				x += 1
		self.parent.ShowMessage('Windows Shortcut Error:\n\nCould not Find: "%s".' % (filename), 'Error')
		return None		
	
	def HandleDesktop(self, filename):
		f = file(filename, 'rb')
		lines = f.read().split()
		f.close()
		
		for line in lines:
			if line.find('URL=') > -1:
				return line[4:]
			
		return None
	
	def OnAddBookmark(self, event):
		try:
			bookfile = self.parent.userpreferencesdirectory + "/bookmarks.dat"
			
			f = file(bookfile, 'rb')
			text = f.read()
			f.close()
			
			text = text.strip()
			
			cdir = self.lstFiles.GetDirectory()
			
			text = text + '\n\t' + cdir + '\n'
			
			f = file(bookfile, 'wb')
			f.write(text)
			f.close()
			
			self.parent.bookmarksmenu.reloadBookmarks()
			
			if self.parent.prefs.enablefeedback:
				self.parent.ShowMessage('Successfully Added ' + cdir, 'Success')
		except:
			self.parent.ShowMessage('Error Adding Bookmark', 'Error')
	
	def OnBookmark(self, event):
		bookmarkindex = event.GetId() - self.ID_BOOKMARK_BASE
		if not (os.path.exists(self.bookmarks[bookmarkindex])):
			drScrolledMessageDialog.ShowMessage(self.parent, ("Error with: " + self.bookmarks[bookmarkindex] + "\nBookmark does not actually exist.\n"), "Error")
			return
		if os.path.isdir(self.bookmarks[bookmarkindex]):
			self.lstFiles.SetDirectoryTo(self.bookmarks[bookmarkindex], self.wildcards[self.currentextension])
			return
		self.cboFile.SetValue(self.bookmarks[bookmarkindex])
	
	def OnbtnBack(self, event):
		self.lstFiles.GoBack(self.wildcards[self.currentextension])	
	
	def OnbtnBookmarks(self, event):
		bookfile = self.parent.userpreferencesdirectory + "/bookmarks.dat"
		bookmarksmenu = wx.Menu()
		
		bookmarksmenu.Append(self.ID_BOOKMARK_ADD, 'Bookmark Current Directory')
		bookmarksmenu.Append(self.ID_BOOKMARK_FILE, 'File Current Directory...')
		bookmarksmenu.Append(self.ID_EDIT_BOOKMARKS, 'Edit Bookmarks...')
		bookmarksmenu.AppendSeparator()
		
		self.Bind(wx.EVT_MENU, self.OnAddBookmark, id=self.ID_BOOKMARK_ADD)
		self.Bind(wx.EVT_MENU, self.OnFileBookmark, id=self.ID_BOOKMARK_FILE)
		self.Bind(wx.EVT_MENU, self.parent.OnEditBookmarks, id=self.ID_EDIT_BOOKMARKS)
		
		self.bookmarks = []
		if (os.path.exists(bookfile)):
			try:
				#Read from the file
				f = open(bookfile, 'r')
				folders = [bookmarksmenu]
				folderindex = 0
				menuTitles = []
				menuTitleindex = -1
				lastCount = 1
				bookmarkcount = 0
				#Skip the First Line
				line = f.readline()
				#Initialize
				line = f.readline()
				while (len(line) > 0):
					c = line.count('\t')
					line = line[c:].rstrip()
					while (lastCount > c):
						folders[(folderindex - 1)].AppendMenu(self.ID_BOOKMARK_MENU, menuTitles.pop(), folders.pop())					
						folderindex = folderindex - 1
						menuTitleindex = menuTitleindex - 1
						lastCount = lastCount - 1
					if (line[0] == '>'):
						folders.append(wx.Menu())
						menuTitles.append(line[1:])
						folderindex = folderindex + 1
						menuTitleindex = menuTitleindex + 1
						c = c + 1
					else:
						self.bookmarks.append(line)
						self.Bind(wx.EVT_MENU, self.OnBookmark, id=(self.ID_BOOKMARK_BASE + bookmarkcount))
						folders[folderindex].Append((self.ID_BOOKMARK_BASE + bookmarkcount), line)
						bookmarkcount = bookmarkcount + 1
					lastCount = c
					line = f.readline()
				f.close()
				#Add any menus not yet added:
				c = 1
				while (lastCount > c):
					folders[(folderindex - 1)].AppendMenu(self.ID_BOOKMARK_MENU, menuTitles.pop(), folders.pop())					
					folderindex = folderindex - 1
					menuTitleindex = menuTitleindex - 1
					lastCount = lastCount - 1
				
			except:
				drScrolledMessageDialog.ShowMessage(self, ("Your bookmarks file is a tad messed up.\n"), "Error")
				return
		else:
			f = file(bookfile, 'wb')
			f.write('>Bookmarks\n')
			f.close()
			
		posX, posY = self.btnBookmarks.GetPosition()
		posY = posY + self.btnBookmarks.GetSize()[1]			
		self.PopupMenu(bookmarksmenu, (posX, posY))
		bookmarksmenu.Destroy()				

	def OnBrowse(self, event):
		posX, posY = self.btnDir.GetPosition()
		posY = posY + self.btnDir.GetSize()[1]
		d = DirPanel(self, -1, (posX, posY), (250, 300))
		d.ShowModal()
		self.lstFiles.SetDirectoryTo(d.GetPath(), self.wildcards[self.currentextension])
		d.Destroy()		
				
	def OnbtnCancel(self, event):
		self.EndModal(wx.ID_CANCEL)
	
	def OnbtnDelete(self, event):
		filename = self.cboFile.GetValue()
		if os.path.exists(filename) and not os.path.isdir(filename):
			msg = 'Delete "' + filename + '"?'
			d = wx.MessageDialog(self, msg, "Delete File?", wx.YES_NO | wx.ICON_QUESTION)
			answer = d.ShowModal()
			d.Destroy()
			if answer == wx.ID_YES:
				try:
					os.remove(filename)
					self.cboFile.SetValue('')
					self.OnbtnRefresh(None)
				except:
					drScrolledMessageDialog.ShowMessage(self, 'Error Removing "' + filename + '".', "Error")								
	
	def OnbtnDisplayDetailed(self, event):
		if self.MultipleSelection:
			self.lstFiles.SetViewDetailed()
		else:
			self.lstFiles.SetViewDetailed(wx.LC_SINGLE_SEL)
		self.lstFiles.SetDirectoryTo(self.lstFiles.GetDirectory(), self.wildcards[self.currentextension])		

	def OnbtnDisplayList(self, event):
		if self.MultipleSelection:			
			self.lstFiles.SetViewList()
		else:
			self.lstFiles.SetViewList(wx.LC_SINGLE_SEL)
		self.lstFiles.SetDirectoryTo(self.lstFiles.GetDirectory(), self.wildcards[self.currentextension])		
		
	def OnbtnForward(self, event):
		self.lstFiles.GoForward(self.wildcards[self.currentextension])
	
	def OnbtnHome(self, event):
		try:
			self.lstFiles.SetDirectoryTo(os.path.expanduser('~'), self.wildcards[self.currentextension])
		except:		
			drScrolledMessageDialog.ShowMessage(self, 'Error Setting Current Directory to Home', "DrPython Error")
	
	def OnbtnNewDirectory(self, event):
		d = wx.TextEntryDialog(self, "Enter New Directory:", "New Directory", "")
		answer = d.ShowModal()
		v = d.GetValue()
		d.Destroy()
		if (answer == wx.ID_OK):
			if len(v) > 0:
				os.mkdir(self.lstFiles.GetDirectory() + '/' + v)
				self.OnbtnRefresh(None)
		
	def OnbtnOk(self, event):
		filename = self.cboFile.GetValue()
		if not os.path.isabs(filename):
			fname = self.txtDirectory.GetValue()
			if not fname.endswith ('/'):
				fname += '/'
			filename = fname + filename
		if filename.find(".lnk") > -1:
			filename = self.HandleLnk(filename)
			if filename == None:
				return
		elif filename.find('.desktop') > -1:
			filename = self.HandleDesktop(filename)
			if filename == None:
				return		
		if not self.IsASaveDialog:
			if not os.path.exists(filename):
				self.parent.ShowMessage('"' + filename + '" does not exist.', 'Error')
				return
		if os.path.isdir(filename):
			self.cboFile.SetValue('')
			self.lstFiles.SetDirectoryTo(filename, self.wildcards[self.currentextension])
		else:			
			self.cboFile.SetValue(filename)
			self.EndAndCheck(wx.ID_OK)
	
	def OnbtnRefresh(self, event):
		self.lstFiles.SetDirectoryTo(self.lstFiles.GetDirectory(), self.wildcards[self.currentextension])
	
	def OnbtnUp(self, event):
		cdir = os.path.split(self.lstFiles.GetDirectory())[0]
		self.lstFiles.SetDirectoryTo(cdir, self.wildcards[self.currentextension])
	
	def OnChar(self, event):
		if (event.GetKeyCode() == wx.WXK_ESCAPE):
			self.OnbtnCancel(None)
		elif (event.GetKeyCode() == wx.WXK_RETURN):
			self.OnbtnOk(None)
		else:
			event.Skip()
	
	def OnDir(self, event):
		directory = self.txtDirectory.GetValue()
		if os.path.exists(directory):
			self.lstFiles.SetDirectoryTo(directory, self.wildcards[self.currentextension])
		else:
			self.parent.ShowMessage('"%s" does not exist.' % (directory), 'Error')
	
	def OnExtension(self, event):
		self.currentextension = self.cboExtension.GetSelection()
		self.lstFiles.SetDirectoryTo(self.lstFiles.GetDirectory(), self.wildcards[self.currentextension])
	
	def OnFileActivated(self, event):
		seltext = event.GetLabel()
		filename = self.lstFiles.GetDirectory() + '/' + seltext
		if filename.find(".lnk") > -1:
			filename = self.HandleLnk(filename)
			if filename == None:
				return
		elif filename.find('.desktop') > -1:
			filename = self.HandleDesktop(filename)
			if filename == None:
				return
		if not self.IsASaveDialog:
			if not os.path.exists(filename):
				self.parent.ShowMessage('"' + filename + '" does not exist.', 'Error')
				return
		if os.path.isdir(filename):
			self.lstFiles.SetDirectoryTo(filename, self.wildcards[self.currentextension])
		else:
			self.EndAndCheck(wx.ID_OK)
	
	def OnFileBookmark(self, event):
		try:
			bookfile = self.parent.userpreferencesdirectory + "/bookmarks.dat"
			
			f = file(bookfile, 'rb')
			text = f.read()
			f.close()
			
			lines = text.strip().split('\n')
			
			x = 0
			folders = []
			linenumbers = []
			
			for line in lines:
				c = line.count('\t')
				pre = line[:c].replace('\t', '    ')
				line = line[c:].rstrip()
				if (line[0] == '>'):
					folders.append(pre + line[1:])
					linenumbers.append(x)
				x += 1
									
			cdir = self.lstFiles.GetDirectory()
						
			d = wx.SingleChoiceDialog(self.parent, 'Select Bookmark Folder:', "File Bookmark", folders, wx.CHOICEDLG_STYLE)
			answer = d.ShowModal()
			result = d.GetSelection()
			
			if answer == wx.ID_OK:
				target = linenumbers[result]								
				
				f = file(bookfile, 'wb')
								
				x = 0
				for line in lines:
					f.write(line + '\n')
					if x == target:
						c = line.count('\t')
						istring = '\t'
						for a in range(c):
							istring += '\t'
						f.write(istring + cdir + '\n')
					x += 1
				f.close()
				
				self.parent.bookmarksmenu.reloadBookmarks()
				
				if self.parent.prefs.enablefeedback:
					self.parent.ShowMessage('Successfully Added ' + cdir, 'Success')
		except:
			self.parent.ShowMessage('Error Filing Bookmark', 'Error')
		
	def OnFileSelected(self, event):
		seltext = event.GetLabel()
		filename = self.lstFiles.GetDirectory() 
		if not filename.endswith ('/'):
			filename += '/'
		filename += seltext
		if not os.path.isdir(filename):
			self.cboFile.SetValue(filename)
	
	def OnShowHiddenFiles(self, event):
		showhidden = self.chkShowHiddenFiles.GetValue()
		self.lstFiles.SetShowHiddenFiles(showhidden)
		self.OnbtnRefresh(None)
			
	def SetDirectory(self, directory):
		if not os.path.exists(directory):
			directory = self.parent.userhomedirectory
		self.lstFiles.SetDirectoryTo(directory, self.wildcards[self.currentextension])

class drWxFileDialog(wx.FileDialog):
	def __init__(self, parent, title, message, defaultdir, wildcard, style):
		wx.FileDialog.__init__(self, parent, title, message, defaultdir, wildcard, style)
		
	def GetEncoding(self):
		return '<Default Encoding>'

#Wrapper for drFileDialog
def FileDialog(parent, title, wildcard, point=(0, 0), size=wx.DefaultSize, IsASaveDialog=0, MultipleSelection=0, ShowRecentFiles=0):
		if parent.prefs.usewxfiledialog:
			if IsASaveDialog:
				return drWxFileDialog(parent, title, "", "", wildcard, wx.SAVE|wx.HIDE_READONLY|wx.OVERWRITE_PROMPT)
			else:
				return drWxFileDialog(parent, title, "", "", wildcard, wx.OPEN|wx.HIDE_READONLY|wx.MULTIPLE)
		else:
			return drFileDialog(parent, title, wildcard, point, size, IsASaveDialog, MultipleSelection, ShowRecentFiles)

syntax highlighted by Code2HTML, v. 0.9.1